mirror of
https://github.com/torvalds/linux.git
synced 2026-05-12 16:18:45 +02:00
Char/Misc/IIO/and others driver updates for 7.1-rc1
Here is the char/misc/iio and other smaller driver subsystem updates for
7.1-rc1. Lots of stuff in here, all tiny, but relevant for the
different drivers they touch. Major points in here is:
- the usual large set of new IIO drivers and updates for that
subsystem (the large majority of this diffstat)
- lots of comedi driver updates and bugfixes
- coresight driver updates
- interconnect driver updates and additions
- mei driver updates
- binder (both rust and C versions) updates and fixes
- lots of other smaller driver subsystem updates and additions
All of these have been in linux-next for a while with no reported
issues.
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-----BEGIN PGP SIGNATURE-----
iG0EABECAC0WIQT0tgzFv3jCIUoxPcsxR9QN2y37KQUCaes/Ng8cZ3JlZ0Brcm9h
aC5jb20ACgkQMUfUDdst+ymRBQCeOqRduhONI6LPIIvDDTaircoSib0AnRD8WwML
RxHo3/WjEd7FEUqwHA+H
=Heza
-----END PGP SIGNATURE-----
Merge tag 'char-misc-7.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc
Pull char / misc / IIO / and others driver updates from Greg KH:
"Here is the char/misc/iio and other smaller driver subsystem updates
for 7.1-rc1. Lots of stuff in here, all tiny, but relevant for the
different drivers they touch. Major points in here is:
- the usual large set of new IIO drivers and updates for that
subsystem (the large majority of this diffstat)
- lots of comedi driver updates and bugfixes
- coresight driver updates
- interconnect driver updates and additions
- mei driver updates
- binder (both rust and C versions) updates and fixes
- lots of other smaller driver subsystem updates and additions
All of these have been in linux-next for a while with no reported
issues"
* tag 'char-misc-7.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: (405 commits)
coresight: tpdm: fix invalid MMIO access issue
mei: me: add nova lake point H DID
mei: lb: add late binding version 2
mei: bus: add mei_cldev_uuid
w1: ds2490: drop redundant device reference
bus: mhi: host: pci_generic: Add Telit FE912C04 modem support
mei: csc: wake device while reading firmware status
mei: csc: support controller with separate PCI device
mei: convert PCI error to common errno
mei: trace: print return value of pci_cfg_read
mei: me: move trace into firmware status read
mei: fix idle print specifiers
mei: me: use PCI_DEVICE_DATA macro
sonypi: Convert ACPI driver to a platform one
misc: apds990x: fix all kernel-doc warnings
most: usb: Use kzalloc_objs for endpoint address array
hpet: Convert ACPI driver to a platform one
misc: vmw_vmci: Fix spelling mistakes in comments
parport: Remove completed item from to-do list
char: remove unnecessary module_init/exit functions
...
This commit is contained in:
commit
cb4eb6771c
1
.mailmap
1
.mailmap
|
|
@ -587,6 +587,7 @@ Michel Lespinasse <michel@lespinasse.org> <walken@google.com>
|
|||
Michel Lespinasse <michel@lespinasse.org> <walken@zoy.org>
|
||||
Mickaël Salaün <mic@digikod.net> <mic@linux.microsoft.com>
|
||||
Miguel Ojeda <ojeda@kernel.org> <miguel.ojeda.sandonis@gmail.com>
|
||||
Mike Leach <mike.leach@arm.com> <mike.leach@linaro.org>
|
||||
Mike Rapoport <rppt@kernel.org> <mike@compulab.co.il>
|
||||
Mike Rapoport <rppt@kernel.org> <mike.rapoport@gmail.com>
|
||||
Mike Rapoport <rppt@kernel.org> <rppt@linux.ibm.com>
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@ What: /sys/accessibility/speakup/bleeps
|
|||
KernelVersion: 2.6
|
||||
Contact: speakup@linux-speakup.org
|
||||
Description: This controls whether one hears beeps through the PC speaker
|
||||
when using speakup's review commands.
|
||||
TODO: what values does it accept?
|
||||
when using speakup's review commands. Range: 0-3. 0 = off, 1 = beeps
|
||||
only, 2 = announcements only, 3 = beeps and announcements (default).
|
||||
|
||||
What: /sys/accessibility/speakup/bleep_time
|
||||
KernelVersion: 2.6
|
||||
|
|
|
|||
|
|
@ -278,3 +278,13 @@ Date: Aug 2025
|
|||
KernelVersion 6.18
|
||||
Contact: Mao Jinlong <quic_jinlmao@quicinc.com>
|
||||
Description: (Read) Show hardware context information of device.
|
||||
|
||||
What: /sys/bus/coresight/devices/<tpdm-name>/traceid
|
||||
Date: March 2026
|
||||
KernelVersion: 7.1
|
||||
Contact: Jie Gan <jie.gan@oss.qualcomm.com>
|
||||
Description:
|
||||
(R) Show the trace ID that will appear in the trace stream
|
||||
coming from this TPDM. The trace ID is inherited from the
|
||||
connected TPDA device and is fixed for the lifetime of the
|
||||
device. Returns -EINVAL if the device has not been enabled yet.
|
||||
|
|
|
|||
|
|
@ -1428,7 +1428,7 @@ KernelVersion: 2.6.35
|
|||
Contact: linux-iio@vger.kernel.org
|
||||
Description:
|
||||
The name of the trigger source being used, as per string given
|
||||
in /sys/class/iio/triggerY/name.
|
||||
in /sys/bus/iio/devices/triggerY/name.
|
||||
|
||||
What: /sys/bus/iio/devices/iio:deviceX/bufferY/length
|
||||
KernelVersion: 5.11
|
||||
|
|
|
|||
|
|
@ -42,6 +42,9 @@ properties:
|
|||
description:
|
||||
A port node to link the usb controller for the dual role switch.
|
||||
|
||||
connector:
|
||||
$ref: /schemas/connector/usb-connector.yaml#
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- interrupts
|
||||
|
|
|
|||
|
|
@ -4,20 +4,23 @@
|
|||
$id: http://devicetree.org/schemas/iio/accel/adi,adxl372.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Analog Devices ADXL372 3-Axis, +/-(200g) Digital Accelerometer
|
||||
title: Analog Devices ADXL371/ADXL372 3-Axis, +/-(200g) Digital Accelerometer
|
||||
|
||||
maintainers:
|
||||
- Marcelo Schmitt <marcelo.schmitt@analog.com>
|
||||
- Nuno Sá <nuno.sa@analog.com>
|
||||
- Antoniu Miclaus <antoniu.miclaus@analog.com>
|
||||
|
||||
description: |
|
||||
Analog Devices ADXL372 3-Axis, +/-(200g) Digital Accelerometer that supports
|
||||
both I2C & SPI interfaces
|
||||
Analog Devices ADXL371/ADXL372 3-Axis, +/-(200g) Digital Accelerometer that
|
||||
supports both I2C & SPI interfaces
|
||||
https://www.analog.com/en/products/adxl371.html
|
||||
https://www.analog.com/en/products/adxl372.html
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- adi,adxl371
|
||||
- adi,adxl372
|
||||
|
||||
reg:
|
||||
|
|
|
|||
|
|
@ -16,25 +16,27 @@ description:
|
|||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
# bmc150-accel driver in Linux
|
||||
- bosch,bma222
|
||||
- bosch,bma222e
|
||||
- bosch,bma250e
|
||||
- bosch,bma253
|
||||
- bosch,bma254
|
||||
- bosch,bma255
|
||||
- bosch,bma280
|
||||
- bosch,bmc150_accel
|
||||
- bosch,bmc156_accel
|
||||
- bosch,bmi055_accel
|
||||
oneOf:
|
||||
- enum:
|
||||
- bosch,bma222
|
||||
- bosch,bma222e
|
||||
- bosch,bma250e
|
||||
- bosch,bma253
|
||||
- bosch,bma254
|
||||
- bosch,bma255
|
||||
- bosch,bma280
|
||||
- bosch,bmc150_accel
|
||||
- bosch,bmc156_accel
|
||||
- bosch,bmi055_accel
|
||||
|
||||
# bma180 driver in Linux
|
||||
- bosch,bma023
|
||||
- bosch,bma150
|
||||
- bosch,bma180
|
||||
- bosch,bma250
|
||||
- bosch,smb380
|
||||
- bosch,bma023
|
||||
- bosch,bma150
|
||||
- bosch,bma180
|
||||
- bosch,bma250
|
||||
- bosch,smb380
|
||||
- items:
|
||||
- const: bosch,bmx055-accel
|
||||
- const: bosch,bmc150_accel
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
|
|
|||
|
|
@ -19,6 +19,10 @@ description: |
|
|||
* https://www.analog.com/media/en/technical-documentation/data-sheets/ad4030-24-4032-24.pdf
|
||||
* https://www.analog.com/media/en/technical-documentation/data-sheets/ad4630-24_ad4632-24.pdf
|
||||
* https://www.analog.com/media/en/technical-documentation/data-sheets/ad4630-16-4632-16.pdf
|
||||
* https://www.analog.com/media/en/technical-documentation/data-sheets/adaq4216.pdf
|
||||
* https://www.analog.com/media/en/technical-documentation/data-sheets/adaq4224.pdf
|
||||
|
||||
$ref: /schemas/spi/spi-peripheral-props.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
|
|
@ -29,6 +33,8 @@ properties:
|
|||
- adi,ad4630-24
|
||||
- adi,ad4632-16
|
||||
- adi,ad4632-24
|
||||
- adi,adaq4216
|
||||
- adi,adaq4224
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
|
@ -60,6 +66,14 @@ properties:
|
|||
description:
|
||||
Internal buffered Reference. Used when ref-supply is not connected.
|
||||
|
||||
vddh-supply:
|
||||
description:
|
||||
PGIA Positive Power Supply.
|
||||
|
||||
vdd-fda-supply:
|
||||
description:
|
||||
FDA Positive Power Supply.
|
||||
|
||||
cnv-gpios:
|
||||
description:
|
||||
The Convert Input (CNV). It initiates the sampling conversions.
|
||||
|
|
@ -70,6 +84,17 @@ properties:
|
|||
The Reset Input (/RST). Used for asynchronous device reset.
|
||||
maxItems: 1
|
||||
|
||||
pga-gpios:
|
||||
description:
|
||||
A0 and A1 pins for gain selection. For devices that have PGA configuration
|
||||
input pins, pga-gpios should be defined.
|
||||
minItems: 2
|
||||
maxItems: 2
|
||||
|
||||
pwms:
|
||||
description: PWM signal connected to the CNV pin.
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
description:
|
||||
The BUSY pin is used to signal that the conversions results are available
|
||||
|
|
@ -107,6 +132,22 @@ allOf:
|
|||
properties:
|
||||
spi-rx-bus-width:
|
||||
maxItems: 1
|
||||
# ADAQ devices require a gain property to indicate how hardware PGA is set
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
pattern: ^adi,adaq
|
||||
then:
|
||||
required:
|
||||
- vddh-supply
|
||||
- vdd-fda-supply
|
||||
- pga-gpios
|
||||
properties:
|
||||
ref-supply: false
|
||||
else:
|
||||
properties:
|
||||
pga-gpios: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
|
|
@ -148,3 +189,26 @@ examples:
|
|||
reset-gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
};
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
|
||||
spi {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
adc@0 {
|
||||
compatible = "adi,adaq4216";
|
||||
reg = <0>;
|
||||
spi-max-frequency = <80000000>;
|
||||
vdd-5v-supply = <&supply_5V>;
|
||||
vdd-1v8-supply = <&supply_1_8V>;
|
||||
vio-supply = <&supply_1_8V>;
|
||||
refin-supply = <&refin_sup>;
|
||||
vddh-supply = <&vddh>;
|
||||
vdd-fda-supply = <&vdd_fda>;
|
||||
cnv-gpios = <&gpio0 0 GPIO_ACTIVE_HIGH>;
|
||||
reset-gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
|
||||
pga-gpios = <&gpio0 2 GPIO_ACTIVE_HIGH>,
|
||||
<&gpio0 3 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -27,10 +27,13 @@ properties:
|
|||
enum:
|
||||
- adi,ad4080
|
||||
- adi,ad4081
|
||||
- adi,ad4082
|
||||
- adi,ad4083
|
||||
- adi,ad4084
|
||||
- adi,ad4085
|
||||
- adi,ad4086
|
||||
- adi,ad4087
|
||||
- adi,ad4088
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
|
|
|||
|
|
@ -62,6 +62,11 @@ properties:
|
|||
spi-cpol: true
|
||||
spi-cpha: true
|
||||
|
||||
spi-rx-bus-width:
|
||||
maxItems: 4
|
||||
items:
|
||||
maximum: 1
|
||||
|
||||
vcc-supply:
|
||||
description: A 3V to 3.6V supply that powers the chip.
|
||||
|
||||
|
|
@ -160,6 +165,23 @@ patternProperties:
|
|||
unevaluatedProperties: false
|
||||
|
||||
allOf:
|
||||
# 2-channel chips only have two SDO lines
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- adi,ad7380
|
||||
- adi,ad7381
|
||||
- adi,ad7383
|
||||
- adi,ad7384
|
||||
- adi,ad7386
|
||||
- adi,ad7387
|
||||
- adi,ad7388
|
||||
then:
|
||||
properties:
|
||||
spi-rx-bus-width:
|
||||
maxItems: 2
|
||||
|
||||
# pseudo-differential chips require common mode voltage supplies,
|
||||
# true differential chips don't use them
|
||||
- if:
|
||||
|
|
@ -284,6 +306,7 @@ examples:
|
|||
spi-cpol;
|
||||
spi-cpha;
|
||||
spi-max-frequency = <80000000>;
|
||||
spi-rx-bus-width = <1>, <1>, <1>, <1>;
|
||||
|
||||
interrupts = <27 IRQ_TYPE_EDGE_FALLING>;
|
||||
interrupt-parent = <&gpio0>;
|
||||
|
|
|
|||
|
|
@ -27,7 +27,11 @@ properties:
|
|||
- amlogic,meson-gxm-saradc
|
||||
- amlogic,meson-axg-saradc
|
||||
- amlogic,meson-g12a-saradc
|
||||
# Usage of this generic fallback is not allowed for new devices
|
||||
- const: amlogic,meson-saradc
|
||||
- items:
|
||||
- const: amlogic,meson-s4-saradc
|
||||
- const: amlogic,meson-g12a-saradc
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
|
|
|||
|
|
@ -11,6 +11,12 @@ maintainers:
|
|||
- Liam Beguin <liambeguin@gmail.com>
|
||||
|
||||
description: |
|
||||
LTC2305:
|
||||
low noise, low power, 2-channel, 12-bit successive approximation ADC with an
|
||||
I2C compatible serial interface.
|
||||
|
||||
https://www.analog.com/media/en/technical-documentation/data-sheets/23015fb.pdf
|
||||
|
||||
LTC2309:
|
||||
low noise, low power, 8-channel, 12-bit successive approximation ADC with an
|
||||
I2C compatible serial interface.
|
||||
|
|
@ -28,6 +34,7 @@ description: |
|
|||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- lltc,ltc2305
|
||||
- lltc,ltc2309
|
||||
- lltc,ltc2497
|
||||
- lltc,ltc2499
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ properties:
|
|||
enum:
|
||||
- motorola,cpcap-adc
|
||||
- motorola,mapphone-cpcap-adc
|
||||
- motorola,mot-cpcap-adc
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
|
|
|||
|
|
@ -0,0 +1,151 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/iio/adc/qcom,spmi-adc5-gen3.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm's SPMI PMIC ADC5 Gen3
|
||||
|
||||
maintainers:
|
||||
- Jishnu Prakash <jishnu.prakash@oss.qualcomm.com>
|
||||
|
||||
description: |
|
||||
SPMI PMIC5 Gen3 voltage ADC (ADC) provides interface to clients to read
|
||||
voltage. It is a 16-bit sigma-delta ADC. It also performs the same thermal
|
||||
monitoring function as the existing ADC_TM devices.
|
||||
|
||||
The interface is implemented on SDAM (Shared Direct Access Memory) peripherals
|
||||
on the master PMIC rather than a dedicated ADC peripheral. The number of PMIC
|
||||
SDAM peripherals allocated for ADC is not correlated with the PMIC used, it is
|
||||
programmed in FW (PBS) and is fixed per SOC, based on the SOC requirements.
|
||||
All boards using a particular (SOC + master PMIC) combination will have the
|
||||
same number of ADC SDAMs supported on that PMIC.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,spmi-adc5-gen3
|
||||
|
||||
reg:
|
||||
items:
|
||||
- description: SDAM0 base address in the SPMI PMIC register map
|
||||
- description: SDAM1 base address
|
||||
minItems: 1
|
||||
|
||||
"#address-cells":
|
||||
const: 1
|
||||
|
||||
"#size-cells":
|
||||
const: 0
|
||||
|
||||
"#io-channel-cells":
|
||||
const: 1
|
||||
|
||||
"#thermal-sensor-cells":
|
||||
const: 1
|
||||
|
||||
interrupts:
|
||||
items:
|
||||
- description: SDAM0 end of conversion (EOC) interrupt
|
||||
- description: SDAM1 EOC interrupt
|
||||
minItems: 1
|
||||
|
||||
patternProperties:
|
||||
"^channel@[0-9a-f]+$":
|
||||
type: object
|
||||
unevaluatedProperties: false
|
||||
$ref: /schemas/iio/adc/qcom,spmi-vadc-common.yaml
|
||||
description:
|
||||
Represents the external channels which are connected to the ADC.
|
||||
|
||||
properties:
|
||||
qcom,decimation:
|
||||
enum: [ 85, 340, 1360 ]
|
||||
default: 1360
|
||||
|
||||
qcom,hw-settle-time:
|
||||
enum: [ 15, 100, 200, 300, 400, 500, 600, 700,
|
||||
1000, 2000, 4000, 8000, 16000, 32000, 64000, 128000 ]
|
||||
default: 15
|
||||
|
||||
qcom,avg-samples:
|
||||
enum: [ 1, 2, 4, 8, 16 ]
|
||||
default: 1
|
||||
|
||||
qcom,adc-tm:
|
||||
description:
|
||||
ADC_TM is a threshold monitoring feature in HW which can be enabled
|
||||
on any ADC channel, to trigger an IRQ for threshold violation. In
|
||||
earlier ADC generations, it was implemented in a separate device
|
||||
(documented in Documentation/devicetree/bindings/thermal/qcom-spmi-adc-tm5.yaml.)
|
||||
In Gen3, this feature can be enabled in the same ADC device for any
|
||||
channel and threshold monitoring and IRQ triggering are handled in FW
|
||||
(PBS) instead of another dedicated HW block.
|
||||
This property indicates ADC_TM monitoring is done on this channel.
|
||||
type: boolean
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- "#address-cells"
|
||||
- "#size-cells"
|
||||
- "#io-channel-cells"
|
||||
- interrupts
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
|
||||
pmic {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
adc@9000 {
|
||||
compatible = "qcom,spmi-adc5-gen3";
|
||||
reg = <0x9000>, <0x9100>;
|
||||
interrupts = <0x0 0x90 0x1 IRQ_TYPE_EDGE_RISING>,
|
||||
<0x0 0x91 0x1 IRQ_TYPE_EDGE_RISING>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
#io-channel-cells = <1>;
|
||||
#thermal-sensor-cells = <1>;
|
||||
|
||||
/* PMK8550 Channel nodes */
|
||||
channel@3 {
|
||||
reg = <0x3>;
|
||||
label = "pmk8550_die_temp";
|
||||
qcom,pre-scaling = <1 1>;
|
||||
};
|
||||
|
||||
channel@44 {
|
||||
reg = <0x44>;
|
||||
label = "pmk8550_xo_therm";
|
||||
qcom,pre-scaling = <1 1>;
|
||||
qcom,ratiometric;
|
||||
qcom,hw-settle-time = <200>;
|
||||
qcom,adc-tm;
|
||||
};
|
||||
|
||||
/* PM8550 Channel nodes */
|
||||
channel@103 {
|
||||
reg = <0x103>;
|
||||
label = "pm8550_die_temp";
|
||||
qcom,pre-scaling = <1 1>;
|
||||
};
|
||||
|
||||
/* PM8550B Channel nodes */
|
||||
channel@78f {
|
||||
reg = <0x78f>;
|
||||
label = "pm8550b_vbat_sns_qbg";
|
||||
qcom,pre-scaling = <1 3>;
|
||||
};
|
||||
|
||||
/* PM8550VS_C Channel nodes */
|
||||
channel@203 {
|
||||
reg = <0x203>;
|
||||
label = "pm8550vs_c_die_temp";
|
||||
qcom,pre-scaling = <1 1>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/iio/adc/qcom,spmi-vadc-common.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm Technologies, Inc. SPMI PMIC ADC channels
|
||||
|
||||
maintainers:
|
||||
- Jishnu Prakash <jishnu.prakash@oss.qualcomm.com>
|
||||
|
||||
description:
|
||||
This defines the common properties used to define Qualcomm VADC channels.
|
||||
|
||||
properties:
|
||||
reg:
|
||||
description:
|
||||
ADC channel number (PMIC-specific for versions after PMIC5 ADC).
|
||||
maxItems: 1
|
||||
|
||||
label:
|
||||
description:
|
||||
ADC input of the platform as seen in the schematics.
|
||||
For thermistor inputs connected to generic AMUX or GPIO inputs
|
||||
these can vary across platform for the same pins. Hence select
|
||||
the platform schematics name for this channel.
|
||||
|
||||
qcom,decimation:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description:
|
||||
This parameter is used to decrease ADC sampling rate.
|
||||
Quicker measurements can be made by reducing decimation ratio.
|
||||
|
||||
qcom,pre-scaling:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
description:
|
||||
Used for scaling the channel input signal before the signal is
|
||||
fed to VADC. The configuration for this node is to know the
|
||||
pre-determined ratio and use it for post scaling. It is a pair of
|
||||
integers, denoting the numerator and denominator of the fraction by which
|
||||
input signal is multiplied. For example, <1 3> indicates the signal is scaled
|
||||
down to 1/3 of its value before ADC measurement.
|
||||
If property is not found default value depending on chip will be used.
|
||||
oneOf:
|
||||
- items:
|
||||
- const: 1
|
||||
- enum: [ 1, 3, 4, 6, 20, 8, 10, 16 ]
|
||||
- items:
|
||||
- const: 10
|
||||
- const: 81
|
||||
|
||||
qcom,ratiometric:
|
||||
type: boolean
|
||||
description: |
|
||||
Channel calibration type.
|
||||
- For compatible property "qcom,spmi-vadc", if this property is
|
||||
specified VADC will use the VDD reference (1.8V) and GND for
|
||||
channel calibration. If property is not found, channel will be
|
||||
calibrated with 0.625V and 1.25V reference channels, also
|
||||
known as absolute calibration.
|
||||
- For other compatible properties, if this property is specified
|
||||
VADC will use the VDD reference (1.875V) and GND for channel
|
||||
calibration. If property is not found, channel will be calibrated
|
||||
with 0V and 1.25V reference channels, also known as absolute calibration.
|
||||
|
||||
qcom,hw-settle-time:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description: |
|
||||
Time between AMUX getting configured and the ADC starting
|
||||
conversion. The 'hw_settle_time' is an index used from valid values
|
||||
and programmed in hardware to achieve the hardware settling delay.
|
||||
|
||||
qcom,avg-samples:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description: |
|
||||
Number of samples to be used for measurement.
|
||||
Averaging provides the option to obtain a single measurement
|
||||
from the ADC that is an average of multiple samples. The value
|
||||
selected is 2^(value).
|
||||
|
||||
required:
|
||||
- reg
|
||||
|
||||
additionalProperties: true
|
||||
|
|
@ -15,6 +15,8 @@ description: |
|
|||
voltage. The VADC is a 15-bit sigma-delta ADC.
|
||||
SPMI PMIC5/PMIC7 voltage ADC (ADC) provides interface to clients to read
|
||||
voltage. The VADC is a 16-bit sigma-delta ADC.
|
||||
Note that PMIC7 ADC is the generation between PMIC5 and PMIC5 Gen3 ADC,
|
||||
it can be considered like PMIC5 Gen2.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
|
|
@ -56,7 +58,7 @@ required:
|
|||
patternProperties:
|
||||
"^channel@[0-9a-f]+$":
|
||||
type: object
|
||||
additionalProperties: false
|
||||
unevaluatedProperties: false
|
||||
description: |
|
||||
Represents the external channels which are connected to the ADC.
|
||||
For compatible property "qcom,spmi-vadc" following channels, also known as
|
||||
|
|
@ -64,79 +66,7 @@ patternProperties:
|
|||
configuration nodes should be defined:
|
||||
VADC_REF_625MV and/or VADC_SPARE1(based on PMIC version) VADC_REF_1250MV,
|
||||
VADC_GND_REF and VADC_VDD_VADC.
|
||||
|
||||
properties:
|
||||
reg:
|
||||
maxItems: 1
|
||||
description: |
|
||||
ADC channel number.
|
||||
See include/dt-bindings/iio/qcom,spmi-vadc.h
|
||||
For PMIC7 ADC, the channel numbers are specified separately per PMIC
|
||||
in the PMIC-specific files in include/dt-bindings/iio/.
|
||||
|
||||
label:
|
||||
description: |
|
||||
ADC input of the platform as seen in the schematics.
|
||||
For thermistor inputs connected to generic AMUX or GPIO inputs
|
||||
these can vary across platform for the same pins. Hence select
|
||||
the platform schematics name for this channel.
|
||||
|
||||
qcom,decimation:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description: |
|
||||
This parameter is used to decrease ADC sampling rate.
|
||||
Quicker measurements can be made by reducing decimation ratio.
|
||||
|
||||
qcom,pre-scaling:
|
||||
description: |
|
||||
Used for scaling the channel input signal before the signal is
|
||||
fed to VADC. The configuration for this node is to know the
|
||||
pre-determined ratio and use it for post scaling. It is a pair of
|
||||
integers, denoting the numerator and denominator of the fraction by which
|
||||
input signal is multiplied. For example, <1 3> indicates the signal is scaled
|
||||
down to 1/3 of its value before ADC measurement.
|
||||
If property is not found default value depending on chip will be used.
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
oneOf:
|
||||
- items:
|
||||
- const: 1
|
||||
- enum: [ 1, 3, 4, 6, 20, 8, 10, 16 ]
|
||||
- items:
|
||||
- const: 10
|
||||
- const: 81
|
||||
|
||||
qcom,ratiometric:
|
||||
description: |
|
||||
Channel calibration type.
|
||||
- For compatible property "qcom,spmi-vadc", if this property is
|
||||
specified VADC will use the VDD reference (1.8V) and GND for
|
||||
channel calibration. If property is not found, channel will be
|
||||
calibrated with 0.625V and 1.25V reference channels, also
|
||||
known as absolute calibration.
|
||||
- For compatible property "qcom,spmi-adc5", "qcom,spmi-adc7" and
|
||||
"qcom,spmi-adc-rev2", if this property is specified VADC will use
|
||||
the VDD reference (1.875V) and GND for channel calibration. If
|
||||
property is not found, channel will be calibrated with 0V and 1.25V
|
||||
reference channels, also known as absolute calibration.
|
||||
type: boolean
|
||||
|
||||
qcom,hw-settle-time:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description: |
|
||||
Time between AMUX getting configured and the ADC starting
|
||||
conversion. The 'hw_settle_time' is an index used from valid values
|
||||
and programmed in hardware to achieve the hardware settling delay.
|
||||
|
||||
qcom,avg-samples:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description: |
|
||||
Number of samples to be used for measurement.
|
||||
Averaging provides the option to obtain a single measurement
|
||||
from the ADC that is an average of multiple samples. The value
|
||||
selected is 2^(value).
|
||||
|
||||
required:
|
||||
- reg
|
||||
$ref: /schemas/iio/adc/qcom,spmi-vadc-common.yaml
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
|
|
|
|||
101
Documentation/devicetree/bindings/iio/amplifiers/adi,ad8366.yaml
Normal file
101
Documentation/devicetree/bindings/iio/amplifiers/adi,ad8366.yaml
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/iio/amplifiers/adi,ad8366.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: AD8366 and similar Gain Amplifiers and Digital Attenuators
|
||||
|
||||
maintainers:
|
||||
- Michael Hennerich <michael.hennerich@analog.com>
|
||||
- Rodrigo Alencar <rodrigo.alencar@analog.com>
|
||||
|
||||
description:
|
||||
Digital Variable Gain Amplifiers (VGAs) and Digital Attenuators with
|
||||
SPI interface.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- adi,ad8366
|
||||
- adi,ada4961
|
||||
- adi,adl5240
|
||||
- adi,adrf5702
|
||||
- adi,adrf5703
|
||||
- adi,adrf5720
|
||||
- adi,adrf5730
|
||||
- adi,adrf5731
|
||||
- adi,hmc271a
|
||||
- adi,hmc792a
|
||||
- adi,hmc1018a
|
||||
- adi,hmc1019a
|
||||
- adi,hmc1119
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
vcc-supply:
|
||||
description: Regulator that provides power to the device.
|
||||
|
||||
reset-gpios:
|
||||
maxItems: 1
|
||||
|
||||
enable-gpios:
|
||||
maxItems: 1
|
||||
description: Power-up or Serial Mode Enable GPIO.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- vcc-supply
|
||||
|
||||
allOf:
|
||||
- $ref: /schemas/spi/spi-peripheral-props.yaml#
|
||||
- if:
|
||||
not:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: adi,hmc271a
|
||||
then:
|
||||
properties:
|
||||
reset-gpios: false
|
||||
- if:
|
||||
not:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
anyOf:
|
||||
- const: adi,ad8366
|
||||
- const: adi,ada4961
|
||||
- const: adi,adrf5702
|
||||
- const: adi,adrf5703
|
||||
- const: adi,adrf5720
|
||||
- const: adi,adrf5730
|
||||
- const: adi,adrf5731
|
||||
- const: adi,hmc792a
|
||||
- const: adi,hmc1018a
|
||||
- const: adi,hmc1019a
|
||||
- const: adi,hmc1119
|
||||
then:
|
||||
properties:
|
||||
enable-gpios: false
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
spi {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
amplifier@0 {
|
||||
compatible = "adi,ad8366";
|
||||
reg = <0>;
|
||||
spi-max-frequency = <1000000>;
|
||||
vcc-supply = <&vcc_3v3>;
|
||||
enable-gpios = <&gpio 0 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
};
|
||||
...
|
||||
|
|
@ -4,36 +4,49 @@
|
|||
$id: http://devicetree.org/schemas/iio/dac/lltc,ltc2632.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Linear Technology LTC263x 12-/10-/8-Bit Rail-to-Rail DAC
|
||||
title: Linear Technology LTC263x and LTC2654 Rail-to-Rail DAC
|
||||
|
||||
maintainers:
|
||||
- Michael Hennerich <michael.hennerich@analog.com>
|
||||
|
||||
description: |
|
||||
Bindings for the Linear Technology LTC2632/2634/2636 DAC
|
||||
Datasheet can be found here: https://www.analog.com/media/en/technical-documentation/data-sheets/LTC263[246].pdf
|
||||
Bindings for the Linear Technology LTC2632/2634/2636/2654 DAC
|
||||
Datasheet can be found here:
|
||||
https://www.analog.com/media/en/technical-documentation/data-sheets/LTC263[246].pdf
|
||||
https://www.analog.com/media/en/technical-documentation/data-sheets/2654f.pdf
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- lltc,ltc2632-l12
|
||||
- lltc,ltc2632-l10
|
||||
- lltc,ltc2632-l8
|
||||
- lltc,ltc2632-h12
|
||||
- lltc,ltc2632-h10
|
||||
- lltc,ltc2632-h8
|
||||
- lltc,ltc2634-l12
|
||||
- lltc,ltc2634-l10
|
||||
- lltc,ltc2634-l8
|
||||
- lltc,ltc2634-h12
|
||||
- lltc,ltc2634-h10
|
||||
- lltc,ltc2634-h8
|
||||
- lltc,ltc2636-l12
|
||||
- lltc,ltc2636-l10
|
||||
- lltc,ltc2636-l8
|
||||
- lltc,ltc2636-h12
|
||||
- lltc,ltc2636-h10
|
||||
- lltc,ltc2636-h8
|
||||
oneOf:
|
||||
- enum:
|
||||
- lltc,ltc2632-l12
|
||||
- lltc,ltc2632-l10
|
||||
- lltc,ltc2632-l8
|
||||
- lltc,ltc2632-h12
|
||||
- lltc,ltc2632-h10
|
||||
- lltc,ltc2632-h8
|
||||
- lltc,ltc2634-l12
|
||||
- lltc,ltc2634-l10
|
||||
- lltc,ltc2634-l8
|
||||
- lltc,ltc2634-h12
|
||||
- lltc,ltc2634-h10
|
||||
- lltc,ltc2634-h8
|
||||
- lltc,ltc2636-l12
|
||||
- lltc,ltc2636-l10
|
||||
- lltc,ltc2636-l8
|
||||
- lltc,ltc2636-h12
|
||||
- lltc,ltc2636-h10
|
||||
- lltc,ltc2636-h8
|
||||
- lltc,ltc2654-l16
|
||||
- lltc,ltc2654-h16
|
||||
- items:
|
||||
- enum:
|
||||
- lltc,ltc2654-l12
|
||||
- const: lltc,ltc2634-l12
|
||||
- items:
|
||||
- enum:
|
||||
- lltc,ltc2654-h12
|
||||
- const: lltc,ltc2634-h12
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
|
|
|||
|
|
@ -4,18 +4,21 @@
|
|||
$id: http://devicetree.org/schemas/iio/dac/maxim,ds4424.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Maxim Integrated DS4422/DS4424 7-bit Sink/Source Current DAC
|
||||
title: Maxim Integrated DS4402/DS4404 and DS4422/DS4424 Current DACs
|
||||
|
||||
maintainers:
|
||||
- Ismail Kose <ihkose@gmail.com>
|
||||
|
||||
description: |
|
||||
Datasheet publicly available at:
|
||||
Datasheets publicly available at:
|
||||
https://datasheets.maximintegrated.com/en/ds/DS4402-DS4404.pdf
|
||||
https://datasheets.maximintegrated.com/en/ds/DS4422-DS4424.pdf
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- maxim,ds4402
|
||||
- maxim,ds4404
|
||||
- maxim,ds4422
|
||||
- maxim,ds4424
|
||||
|
||||
|
|
@ -24,9 +27,43 @@ properties:
|
|||
|
||||
vcc-supply: true
|
||||
|
||||
maxim,rfs-ohms:
|
||||
description: |
|
||||
Array of resistance values in Ohms for the external Rfs resistors
|
||||
connected to the FS pins. These values determine the full-scale
|
||||
output current. The actual resistance depends on the chip variant
|
||||
and specific hardware design requirements.
|
||||
minItems: 2
|
||||
maxItems: 4
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- maxim,rfs-ohms
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- maxim,ds4402
|
||||
- maxim,ds4422
|
||||
then:
|
||||
properties:
|
||||
maxim,rfs-ohms:
|
||||
maxItems: 2
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- maxim,ds4404
|
||||
- maxim,ds4424
|
||||
then:
|
||||
properties:
|
||||
maxim,rfs-ohms:
|
||||
minItems: 4
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
|
|
@ -40,6 +77,7 @@ examples:
|
|||
compatible = "maxim,ds4424";
|
||||
reg = <0x10>; /* When A0, A1 pins are ground */
|
||||
vcc-supply = <&vcc_3v3>;
|
||||
maxim,rfs-ohms = <40000>, <40000>, <40000>, <40000>;
|
||||
};
|
||||
};
|
||||
...
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ title: Texas Instruments DAC7612 family of DACs
|
|||
description:
|
||||
The DAC7612 is a dual, 12-bit digital-to-analog converter (DAC) with
|
||||
guaranteed 12-bit monotonicity performance over the industrial temperature
|
||||
range. Is is programmable through an SPI interface.
|
||||
range. It is programmable through an SPI interface.
|
||||
|
||||
maintainers:
|
||||
- Ricardo Ribalda Delgado <ricardo@ribalda.com>
|
||||
|
|
|
|||
|
|
@ -11,10 +11,14 @@ maintainers:
|
|||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- bosch,bmg160
|
||||
- bosch,bmi055_gyro
|
||||
- bosch,bmi088_gyro
|
||||
oneOf:
|
||||
- enum:
|
||||
- bosch,bmg160
|
||||
- bosch,bmi055_gyro
|
||||
- bosch,bmi088_gyro
|
||||
- items:
|
||||
- const: bosch,bmx055-gyro
|
||||
- const: bosch,bmg160
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
|
|
|||
|
|
@ -18,16 +18,32 @@ allOf:
|
|||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- vishay,vcnl4000
|
||||
- vishay,vcnl4010
|
||||
- vishay,vcnl4020
|
||||
- vishay,vcnl4040
|
||||
- vishay,vcnl4200
|
||||
oneOf:
|
||||
- enum:
|
||||
- capella,cm36672p
|
||||
- vishay,vcnl4000
|
||||
- vishay,vcnl4010
|
||||
- vishay,vcnl4020
|
||||
- vishay,vcnl4040
|
||||
- vishay,vcnl4200
|
||||
- items:
|
||||
- const: capella,cm36686
|
||||
- const: vishay,vcnl4040
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
vdd-supply:
|
||||
description: Regulator providing power to the "VDD" pin.
|
||||
|
||||
vio-supply:
|
||||
description: Regulator providing power for pull-up of the I/O lines.
|
||||
Does not connect to the sensor directly, but is needed for the
|
||||
correct operation of the I2C and interrupt lines.
|
||||
|
||||
vled-supply:
|
||||
description: Regulator providing power to the IR anode pin.
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
|
|
@ -49,6 +65,9 @@ examples:
|
|||
compatible = "vishay,vcnl4200";
|
||||
reg = <0x51>;
|
||||
proximity-near-level = <220>;
|
||||
vdd-supply = <®_vdd>;
|
||||
vio-supply = <®_vio>;
|
||||
vled-supply = <®_vled>;
|
||||
};
|
||||
};
|
||||
...
|
||||
|
|
|
|||
|
|
@ -21,11 +21,15 @@ properties:
|
|||
description:
|
||||
Note the bmm150_magn is a deprecated compatible as this part contains only
|
||||
a magnetometer.
|
||||
enum:
|
||||
- bosch,bmc150_magn
|
||||
- bosch,bmc156_magn
|
||||
- bosch,bmm150
|
||||
- bosch,bmm150_magn
|
||||
oneOf:
|
||||
- enum:
|
||||
- bosch,bmc150_magn
|
||||
- bosch,bmc156_magn
|
||||
- bosch,bmm150
|
||||
- bosch,bmm150_magn
|
||||
- items:
|
||||
- const: bosch,bmx055-magn
|
||||
- const: bosch,bmc150_magn
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
|
|
|||
|
|
@ -4,14 +4,17 @@
|
|||
$id: http://devicetree.org/schemas/iio/proximity/st,vl53l0x.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: ST VL53L0X ToF ranging sensor
|
||||
title: ST VL53L0X/VL53L1X ToF ranging sensor
|
||||
|
||||
maintainers:
|
||||
- Song Qiang <songqiang1304521@gmail.com>
|
||||
- Siratul Islam <email@sirat.me>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: st,vl53l0x
|
||||
enum:
|
||||
- st,vl53l0x
|
||||
- st,vl53l1x
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
|
@ -21,6 +24,8 @@ properties:
|
|||
|
||||
reset-gpios:
|
||||
maxItems: 1
|
||||
description:
|
||||
Phandle to the XSHUT GPIO. Used for hardware reset.
|
||||
|
||||
vdd-supply: true
|
||||
|
||||
|
|
@ -28,6 +33,16 @@ required:
|
|||
- compatible
|
||||
- reg
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: st,vl53l1x
|
||||
then:
|
||||
required:
|
||||
- vdd-supply
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
|
|
@ -38,8 +53,9 @@ examples:
|
|||
#size-cells = <0>;
|
||||
|
||||
proximity@29 {
|
||||
compatible = "st,vl53l0x";
|
||||
compatible = "st,vl53l1x";
|
||||
reg = <0x29>;
|
||||
vdd-supply = <®_3v3>;
|
||||
interrupt-parent = <&gpio>;
|
||||
interrupts = <23 IRQ_TYPE_EDGE_FALLING>;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -28,6 +28,9 @@ properties:
|
|||
|
||||
vdd-supply: true
|
||||
|
||||
firmware-name:
|
||||
maxItems: 1
|
||||
|
||||
"#address-cells":
|
||||
const: 1
|
||||
|
||||
|
|
@ -65,6 +68,7 @@ examples:
|
|||
interrupt-parent = <&pio>;
|
||||
interrupts = <16 IRQ_TYPE_EDGE_FALLING>;
|
||||
vdd-supply = <&pp1800_prox>;
|
||||
firmware-name = "hx9023s.bin";
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
$id: http://devicetree.org/schemas/interconnect/qcom,glymur-rpmh.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm RPMh Network-On-Chip Interconnect on GLYMUR
|
||||
title: Qualcomm RPMh Network-On-Chip Interconnect on Glymur and Mahua SoCs
|
||||
|
||||
maintainers:
|
||||
- Raviteja Laggyshetty <raviteja.laggyshetty@oss.qualcomm.com>
|
||||
|
|
@ -21,28 +21,98 @@ description: |
|
|||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,glymur-aggre1-noc
|
||||
- qcom,glymur-aggre2-noc
|
||||
- qcom,glymur-aggre3-noc
|
||||
- qcom,glymur-aggre4-noc
|
||||
- qcom,glymur-clk-virt
|
||||
- qcom,glymur-cnoc-cfg
|
||||
- qcom,glymur-cnoc-main
|
||||
- qcom,glymur-hscnoc
|
||||
- qcom,glymur-lpass-ag-noc
|
||||
- qcom,glymur-lpass-lpiaon-noc
|
||||
- qcom,glymur-lpass-lpicx-noc
|
||||
- qcom,glymur-mc-virt
|
||||
- qcom,glymur-mmss-noc
|
||||
- qcom,glymur-nsinoc
|
||||
- qcom,glymur-nsp-noc
|
||||
- qcom,glymur-oobm-ss-noc
|
||||
- qcom,glymur-pcie-east-anoc
|
||||
- qcom,glymur-pcie-east-slv-noc
|
||||
- qcom,glymur-pcie-west-anoc
|
||||
- qcom,glymur-pcie-west-slv-noc
|
||||
- qcom,glymur-system-noc
|
||||
oneOf:
|
||||
- items:
|
||||
- enum:
|
||||
- qcom,mahua-aggre1-noc
|
||||
- const: qcom,glymur-aggre1-noc
|
||||
- items:
|
||||
- enum:
|
||||
- qcom,mahua-aggre2-noc
|
||||
- const: qcom,glymur-aggre2-noc
|
||||
- items:
|
||||
- enum:
|
||||
- qcom,mahua-aggre3-noc
|
||||
- const: qcom,glymur-aggre3-noc
|
||||
- items:
|
||||
- enum:
|
||||
- qcom,mahua-aggre4-noc
|
||||
- const: qcom,glymur-aggre4-noc
|
||||
- items:
|
||||
- enum:
|
||||
- qcom,mahua-clk-virt
|
||||
- const: qcom,glymur-clk-virt
|
||||
- items:
|
||||
- enum:
|
||||
- qcom,mahua-cnoc-main
|
||||
- const: qcom,glymur-cnoc-main
|
||||
- items:
|
||||
- enum:
|
||||
- qcom,mahua-lpass-ag-noc
|
||||
- const: qcom,glymur-lpass-ag-noc
|
||||
- items:
|
||||
- enum:
|
||||
- qcom,mahua-lpass-lpiaon-noc
|
||||
- const: qcom,glymur-lpass-lpiaon-noc
|
||||
- items:
|
||||
- enum:
|
||||
- qcom,mahua-lpass-lpicx-noc
|
||||
- const: qcom,glymur-lpass-lpicx-noc
|
||||
- items:
|
||||
- enum:
|
||||
- qcom,mahua-mmss-noc
|
||||
- const: qcom,glymur-mmss-noc
|
||||
- items:
|
||||
- enum:
|
||||
- qcom,mahua-nsinoc
|
||||
- const: qcom,glymur-nsinoc
|
||||
- items:
|
||||
- enum:
|
||||
- qcom,mahua-nsp-noc
|
||||
- const: qcom,glymur-nsp-noc
|
||||
- items:
|
||||
- enum:
|
||||
- qcom,mahua-oobm-ss-noc
|
||||
- const: qcom,glymur-oobm-ss-noc
|
||||
- items:
|
||||
- enum:
|
||||
- qcom,mahua-pcie-east-anoc
|
||||
- const: qcom,glymur-pcie-east-anoc
|
||||
- items:
|
||||
- enum:
|
||||
- qcom,mahua-pcie-east-slv-noc
|
||||
- const: qcom,glymur-pcie-east-slv-noc
|
||||
- items:
|
||||
- enum:
|
||||
- qcom,mahua-system-noc
|
||||
- const: qcom,glymur-system-noc
|
||||
- enum:
|
||||
- qcom,glymur-aggre1-noc
|
||||
- qcom,glymur-aggre2-noc
|
||||
- qcom,glymur-aggre3-noc
|
||||
- qcom,glymur-aggre4-noc
|
||||
- qcom,glymur-clk-virt
|
||||
- qcom,glymur-cnoc-cfg
|
||||
- qcom,glymur-cnoc-main
|
||||
- qcom,glymur-hscnoc
|
||||
- qcom,glymur-lpass-ag-noc
|
||||
- qcom,glymur-lpass-lpiaon-noc
|
||||
- qcom,glymur-lpass-lpicx-noc
|
||||
- qcom,glymur-mc-virt
|
||||
- qcom,glymur-mmss-noc
|
||||
- qcom,glymur-nsinoc
|
||||
- qcom,glymur-nsp-noc
|
||||
- qcom,glymur-oobm-ss-noc
|
||||
- qcom,glymur-pcie-east-anoc
|
||||
- qcom,glymur-pcie-east-slv-noc
|
||||
- qcom,glymur-pcie-west-anoc
|
||||
- qcom,glymur-pcie-west-slv-noc
|
||||
- qcom,glymur-system-noc
|
||||
- qcom,mahua-cnoc-cfg
|
||||
- qcom,mahua-hscnoc
|
||||
- qcom,mahua-mc-virt
|
||||
- qcom,mahua-pcie-west-anoc
|
||||
- qcom,mahua-pcie-west-slv-noc
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
|
@ -63,6 +133,7 @@ allOf:
|
|||
enum:
|
||||
- qcom,glymur-clk-virt
|
||||
- qcom,glymur-mc-virt
|
||||
- qcom,mahua-mc-virt
|
||||
then:
|
||||
properties:
|
||||
reg: false
|
||||
|
|
@ -85,6 +156,20 @@ allOf:
|
|||
- description: aggre PCIE_4 WEST AXI clock
|
||||
- description: aggre PCIE_6 WEST AXI clock
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,mahua-pcie-west-anoc
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
items:
|
||||
- description: aggre PCIE_3B WEST AXI clock
|
||||
- description: aggre PCIE_4 WEST AXI clock
|
||||
- description: aggre PCIE_6 WEST AXI clock
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
|
|
@ -131,10 +216,11 @@ allOf:
|
|||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,glymur-pcie-west-anoc
|
||||
- qcom,glymur-pcie-east-anoc
|
||||
- qcom,glymur-aggre2-noc
|
||||
- qcom,glymur-aggre4-noc
|
||||
- qcom,glymur-pcie-east-anoc
|
||||
- qcom,glymur-pcie-west-anoc
|
||||
- qcom,mahua-pcie-west-anoc
|
||||
then:
|
||||
required:
|
||||
- clocks
|
||||
|
|
|
|||
|
|
@ -26,27 +26,34 @@ properties:
|
|||
- qcom,msm8974-pnoc
|
||||
- qcom,msm8974-snoc
|
||||
|
||||
'#interconnect-cells':
|
||||
const: 1
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: bus
|
||||
- const: bus_a
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: Bus Clock
|
||||
- description: Bus A Clock
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- '#interconnect-cells'
|
||||
- clock-names
|
||||
- clocks
|
||||
|
||||
additionalProperties: false
|
||||
unevaluatedProperties: false
|
||||
|
||||
allOf:
|
||||
- $ref: qcom,rpm-common.yaml#
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,msm8974-mmssnoc
|
||||
then:
|
||||
required:
|
||||
- clocks
|
||||
- clock-names
|
||||
else:
|
||||
properties:
|
||||
clocks: false
|
||||
clock-names: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
|
|
@ -56,7 +63,4 @@ examples:
|
|||
reg = <0xfc380000 0x6a000>;
|
||||
compatible = "qcom,msm8974-bimc";
|
||||
#interconnect-cells = <1>;
|
||||
clock-names = "bus", "bus_a";
|
||||
clocks = <&rpmcc RPM_SMD_BIMC_CLK>,
|
||||
<&rpmcc RPM_SMD_BIMC_A_CLK>;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ properties:
|
|||
- qcom,sm6375-cpucp-l3
|
||||
- qcom,sm8250-epss-l3
|
||||
- qcom,sm8350-epss-l3
|
||||
- qcom,sm8550-epss-l3
|
||||
- qcom,sm8650-epss-l3
|
||||
- const: qcom,epss-l3
|
||||
- items:
|
||||
|
|
|
|||
|
|
@ -34,6 +34,13 @@ properties:
|
|||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: aggre UFS PHY AXI clock
|
||||
- description: aggre USB2 SEC AXI clock
|
||||
- description: aggre USB3 PRIM AXI clock
|
||||
- description: RPMH CC IPA clock
|
||||
|
||||
required:
|
||||
- compatible
|
||||
|
||||
|
|
@ -53,6 +60,22 @@ allOf:
|
|||
required:
|
||||
- reg
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,qcs615-camnoc-virt
|
||||
- qcom,qcs615-config-noc
|
||||
- qcom,qcs615-dc-noc
|
||||
- qcom,qcs615-gem-noc
|
||||
- qcom,qcs615-mc-virt
|
||||
- qcom,qcs615-mmss-noc
|
||||
- qcom,qcs615-system-noc
|
||||
then:
|
||||
properties:
|
||||
clocks: false
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
|
|
|
|||
|
|
@ -35,6 +35,10 @@ properties:
|
|||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
minItems: 1
|
||||
maxItems: 4
|
||||
|
||||
required:
|
||||
- compatible
|
||||
|
||||
|
|
@ -54,6 +58,64 @@ allOf:
|
|||
required:
|
||||
- reg
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,qcs8300-aggre1-noc
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
items:
|
||||
- description: aggre UFS PHY AXI clock
|
||||
- description: aggre QUP PRIM AXI clock
|
||||
- description: aggre USB2 PRIM AXI clock
|
||||
- description: aggre USB3 PRIM AXI clock
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,qcs8300-aggre2-noc
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
items:
|
||||
- description: RPMH CC IPA clock
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,qcs8300-gem-noc
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
items:
|
||||
- description: GCC DDRSS GPU AXI clock
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,qcs8300-clk-virt
|
||||
- qcom,qcs8300-config-noc
|
||||
- qcom,qcs8300-dc-noc
|
||||
- qcom,qcs8300-gpdsp-anoc
|
||||
- qcom,qcs8300-lpass-ag-noc
|
||||
- qcom,qcs8300-mc-virt
|
||||
- qcom,qcs8300-mmss-noc
|
||||
- qcom,qcs8300-nspa-noc
|
||||
- qcom,qcs8300-pcie-anoc
|
||||
- qcom,qcs8300-system-noc
|
||||
then:
|
||||
properties:
|
||||
clocks: false
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
|
|
@ -63,6 +125,7 @@ examples:
|
|||
reg = <0x9100000 0xf7080>;
|
||||
#interconnect-cells = <2>;
|
||||
qcom,bcm-voters = <&apps_bcm_voter>;
|
||||
clocks = <&gcc_ddrss_gpu_axi_clk>;
|
||||
};
|
||||
|
||||
clk_virt: interconnect-0 {
|
||||
|
|
|
|||
|
|
@ -135,6 +135,7 @@ patternProperties:
|
|||
"^adc@[0-9a-f]+$":
|
||||
type: object
|
||||
oneOf:
|
||||
- $ref: /schemas/iio/adc/qcom,spmi-adc5-gen3.yaml#
|
||||
- $ref: /schemas/iio/adc/qcom,spmi-iadc.yaml#
|
||||
- $ref: /schemas/iio/adc/qcom,spmi-rradc.yaml#
|
||||
- $ref: /schemas/iio/adc/qcom,spmi-vadc.yaml#
|
||||
|
|
|
|||
|
|
@ -18,9 +18,14 @@ description: |
|
|||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,kaanapali-fastrpc
|
||||
- qcom,fastrpc
|
||||
oneOf:
|
||||
- enum:
|
||||
- qcom,kaanapali-fastrpc
|
||||
- qcom,fastrpc
|
||||
- items:
|
||||
- enum:
|
||||
- qcom,glymur-fastrpc
|
||||
- const: qcom,kaanapali-fastrpc
|
||||
|
||||
label:
|
||||
enum:
|
||||
|
|
|
|||
|
|
@ -53,6 +53,22 @@ patternProperties:
|
|||
|
||||
unevaluatedProperties: false
|
||||
|
||||
"^led@1[4-b]$":
|
||||
$ref: /schemas/leds/common.yaml#
|
||||
description: Output GPIO line with advanced LED features enabled.
|
||||
|
||||
properties:
|
||||
reg:
|
||||
minimum: 0x14
|
||||
maximum: 0x1b
|
||||
description:
|
||||
GPIO line ID
|
||||
|
||||
required:
|
||||
- reg
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
|
@ -89,6 +105,11 @@ examples:
|
|||
#size-cells = <0>;
|
||||
reg = <1>;
|
||||
};
|
||||
|
||||
led@14 {
|
||||
reg = <0x14>;
|
||||
label = "phy0:green:indicator";
|
||||
};
|
||||
};
|
||||
};
|
||||
...
|
||||
|
|
|
|||
|
|
@ -19,12 +19,7 @@ select: false
|
|||
|
||||
properties:
|
||||
compatible:
|
||||
oneOf:
|
||||
- items:
|
||||
- enum:
|
||||
- kontron,sa67-vpd
|
||||
- const: kontron,sl28-vpd
|
||||
- const: kontron,sl28-vpd
|
||||
const: kontron,sl28-vpd
|
||||
|
||||
serial-number:
|
||||
type: object
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ properties:
|
|||
- qcom,ipq8064-qfprom
|
||||
- qcom,ipq8074-qfprom
|
||||
- qcom,ipq9574-qfprom
|
||||
- qcom,kaanapali-qfprom
|
||||
- qcom,msm8226-qfprom
|
||||
- qcom,msm8916-qfprom
|
||||
- qcom,msm8917-qfprom
|
||||
|
|
|
|||
|
|
@ -14,6 +14,9 @@ properties:
|
|||
enum:
|
||||
- rockchip,px30-otp
|
||||
- rockchip,rk3308-otp
|
||||
- rockchip,rk3528-otp
|
||||
- rockchip,rk3562-otp
|
||||
- rockchip,rk3568-otp
|
||||
- rockchip,rk3576-otp
|
||||
- rockchip,rk3588-otp
|
||||
|
||||
|
|
@ -26,19 +29,15 @@ properties:
|
|||
|
||||
clock-names:
|
||||
minItems: 3
|
||||
items:
|
||||
- const: otp
|
||||
- const: apb_pclk
|
||||
- const: phy
|
||||
- const: arb
|
||||
maxItems: 4
|
||||
|
||||
resets:
|
||||
minItems: 1
|
||||
maxItems: 3
|
||||
maxItems: 4
|
||||
|
||||
reset-names:
|
||||
minItems: 1
|
||||
maxItems: 3
|
||||
maxItems: 4
|
||||
|
||||
required:
|
||||
- compatible
|
||||
|
|
@ -64,13 +63,68 @@ allOf:
|
|||
clocks:
|
||||
maxItems: 3
|
||||
clock-names:
|
||||
maxItems: 3
|
||||
items:
|
||||
- const: otp
|
||||
- const: apb_pclk
|
||||
- const: phy
|
||||
resets:
|
||||
maxItems: 1
|
||||
reset-names:
|
||||
items:
|
||||
- const: phy
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- rockchip,rk3528-otp
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
maxItems: 3
|
||||
clock-names:
|
||||
items:
|
||||
- const: otp
|
||||
- const: apb_pclk
|
||||
- const: sbpi
|
||||
resets:
|
||||
minItems: 3
|
||||
maxItems: 3
|
||||
reset-names:
|
||||
items:
|
||||
- const: otp
|
||||
- const: apb
|
||||
- const: sbpi
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- rockchip,rk3562-otp
|
||||
- rockchip,rk3568-otp
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
minItems: 4
|
||||
maxItems: 4
|
||||
clock-names:
|
||||
items:
|
||||
- const: otp
|
||||
- const: apb_pclk
|
||||
- const: phy
|
||||
- const: sbpi
|
||||
resets:
|
||||
minItems: 4
|
||||
maxItems: 4
|
||||
reset-names:
|
||||
items:
|
||||
- const: otp
|
||||
- const: apb
|
||||
- const: phy
|
||||
- const: sbpi
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
|
|
@ -82,7 +136,10 @@ allOf:
|
|||
clocks:
|
||||
maxItems: 3
|
||||
clock-names:
|
||||
maxItems: 3
|
||||
items:
|
||||
- const: otp
|
||||
- const: apb_pclk
|
||||
- const: phy
|
||||
resets:
|
||||
minItems: 2
|
||||
maxItems: 2
|
||||
|
|
@ -101,10 +158,16 @@ allOf:
|
|||
properties:
|
||||
clocks:
|
||||
minItems: 4
|
||||
maxItems: 4
|
||||
clock-names:
|
||||
minItems: 4
|
||||
items:
|
||||
- const: otp
|
||||
- const: apb_pclk
|
||||
- const: phy
|
||||
- const: arb
|
||||
resets:
|
||||
minItems: 3
|
||||
maxItems: 3
|
||||
reset-names:
|
||||
items:
|
||||
- const: otp
|
||||
|
|
|
|||
|
|
@ -92,6 +92,45 @@ Interleaved mode
|
|||
In this mode, both channels conversion results are bit interleaved one SDO line.
|
||||
As such the wiring is the same as `One lane mode`_.
|
||||
|
||||
SPI offload wiring
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. code-block::
|
||||
|
||||
+-------------+ +-------------+
|
||||
| CNV |<-----+--| GPIO |
|
||||
| | +--| PWM0 |
|
||||
| | | |
|
||||
| | +--| PWM1 |
|
||||
| | | +-------------+
|
||||
| | +->| TRIGGER |
|
||||
| CS |<--------| CS |
|
||||
| | | |
|
||||
| ADC | | SPI |
|
||||
| | | |
|
||||
| SDI |<--------| SDO |
|
||||
| SDO |-------->| SDI |
|
||||
| SCLK |<--------| SCLK |
|
||||
+-------------+ +-------------+
|
||||
|
||||
In this mode, both the ``cnv-gpios`` and a ``pwms`` properties are required.
|
||||
The ``pwms`` property specifies the PWM that is connected to the ADC CNV pin.
|
||||
The SPI offload will have a ``trigger-sources`` property to indicate the SPI
|
||||
offload (PWM) trigger source. For AD4030 and similar ADCs, there are two
|
||||
possible data transfer zones for sample N. One of them (zone 1) starts after the
|
||||
data conversion for sample N is complete while the other one (zone 2) starts 9.8
|
||||
nanoseconds after the rising edge of CNV for sample N + 1.
|
||||
|
||||
The configuration depicted in the above diagram is intended to perform data
|
||||
transfer in zone 2. To achieve high sample rates while meeting ADC timing
|
||||
requirements, an offset is added between the rising edges of PWM0 and PWM1 to
|
||||
delay the SPI transfer until 9.8 nanoseconds after CNV rising edge. This
|
||||
requires a specialized PWM controller that can provide such an offset.
|
||||
The `AD4630-FMC HDL project`_, for example, can be configured to sample AD4030
|
||||
data during zone 2 data read window.
|
||||
|
||||
.. _AD4630-FMC HDL project: https://analogdevicesinc.github.io/hdl/projects/ad4630_fmc/index.html
|
||||
|
||||
SPI Clock mode
|
||||
--------------
|
||||
|
||||
|
|
|
|||
|
|
@ -63,11 +63,11 @@ Clock Configuration
|
|||
|
||||
The AD7191 supports both internal and external clock sources:
|
||||
|
||||
- When CLKSEL pin is tied LOW: Uses internal 4.92MHz clock (no clock property
|
||||
- When CLKSEL pin is ACTIVE: Uses internal 4.92MHz clock (no clock property
|
||||
needed)
|
||||
- When CLKSEL pin is tied HIGH: Requires external clock source
|
||||
- When CLKSEL pin is INACTIVE: Requires external clock source
|
||||
- Can be a crystal between MCLK1 and MCLK2 pins
|
||||
- Or a CMOS-compatible clock driving MCLK2 pin
|
||||
- Or a CMOS-compatible clock driving MCLK1 pin and MCLK2 left unconnected
|
||||
- Must specify the "clocks" property in device tree when using external clock
|
||||
|
||||
SPI Interface Requirements
|
||||
|
|
|
|||
|
|
@ -12,16 +12,21 @@ This driver supports Analog Device's ADXL345/375 on SPI/I2C bus.
|
|||
* `ADXL345 <https://www.analog.com/ADXL345>`_
|
||||
* `ADXL375 <https://www.analog.com/ADXL375>`_
|
||||
|
||||
The ADXL345 is a generic purpose low power, 3-axis accelerometer with selectable
|
||||
measurement ranges. The ADXL345 supports the ±2 g, ±4 g, ±8 g, and ±16 g ranges.
|
||||
The ADXL345 is a general-purpose, low-power, 3-axis accelerometer with selectable
|
||||
measurement ranges. The ADXL345 supports the following ranges:
|
||||
|
||||
- ±2g (approx. ±19.61 m/s^2)
|
||||
- ±4g (approx. ±39.23 m/s^2)
|
||||
- ±8g (approx. ±78.45 m/s^2)
|
||||
- ±16g (approx. ±156.91 m/s^2)
|
||||
|
||||
2. Device Attributes
|
||||
====================
|
||||
|
||||
Each IIO device, has a device folder under ``/sys/bus/iio/devices/iio:deviceX``,
|
||||
Each IIO device has a device folder under ``/sys/bus/iio/devices/iio:deviceX``,
|
||||
where X is the IIO index of the device. Under these folders reside a set of
|
||||
device files, depending on the characteristics and features of the hardware
|
||||
device in questions. These files are consistently generalized and documented in
|
||||
device in question. These files are consistently generalized and documented in
|
||||
the IIO ABI documentation.
|
||||
|
||||
The following table shows the ADXL345 related device files, found in the
|
||||
|
|
@ -42,7 +47,7 @@ specific device folder path ``/sys/bus/iio/devices/iio:deviceX``.
|
|||
+-------------------------------------------+----------------------------------------------------------+
|
||||
| in_accel_x_raw | Raw X-axis accelerometer channel value. |
|
||||
+-------------------------------------------+----------------------------------------------------------+
|
||||
| in_accel_y_calibbias | y-axis acceleration offset correction |
|
||||
| in_accel_y_calibbias | Y-axis acceleration offset correction |
|
||||
+-------------------------------------------+----------------------------------------------------------+
|
||||
| in_accel_y_raw | Raw Y-axis accelerometer channel value. |
|
||||
+-------------------------------------------+----------------------------------------------------------+
|
||||
|
|
@ -68,7 +73,7 @@ present, simply assume its value is 0.
|
|||
+-------------------------------------+---------------------------+
|
||||
| Channel type | Measurement unit |
|
||||
+-------------------------------------+---------------------------+
|
||||
| Acceleration on X, Y, and Z axis | Meters per second squared |
|
||||
| Acceleration on X, Y, and Z axes | Meters per second squared |
|
||||
+-------------------------------------+---------------------------+
|
||||
|
||||
Sensor Events
|
||||
|
|
@ -78,8 +83,8 @@ Specific IIO events are triggered by their corresponding interrupts. The sensor
|
|||
driver supports either none or a single active interrupt (INT) line, selectable
|
||||
from the two available options: INT1 or INT2. The active INT line should be
|
||||
specified in the device tree. If no INT line is configured, the sensor defaults
|
||||
to FIFO bypass mode, where event detection is disabled and only X, Y, and Z axis
|
||||
measurements are available.
|
||||
to FIFO bypass mode, where event detection is disabled and only individual
|
||||
X, Y, and Z axis measurements are available.
|
||||
|
||||
The table below lists the ADXL345-related device files located in the
|
||||
device-specific path: ``/sys/bus/iio/devices/iio:deviceX/events``.
|
||||
|
|
@ -90,38 +95,52 @@ listed.
|
|||
+---------------------------------------------+---------------------------------------------+
|
||||
| Event handle | Description |
|
||||
+---------------------------------------------+---------------------------------------------+
|
||||
| in_accel_gesture_doubletap_en | Enable double tap detection on all axis |
|
||||
| in_accel_gesture_doubletap_en | Enable double tap detection on all axes |
|
||||
+---------------------------------------------+---------------------------------------------+
|
||||
| in_accel_gesture_doubletap_reset_timeout | Double tap window in [us] |
|
||||
+---------------------------------------------+---------------------------------------------+
|
||||
| in_accel_gesture_doubletap_tap2_min_delay | Double tap latent in [us] |
|
||||
| in_accel_gesture_doubletap_scale | Double tap gesture threshold scale. |
|
||||
+---------------------------------------------+---------------------------------------------+
|
||||
| in_accel_gesture_doubletap_tap2_min_delay | Double tap latency in [us] |
|
||||
+---------------------------------------------+---------------------------------------------+
|
||||
| in_accel_gesture_doubletap_value | Double tap threshold value |
|
||||
+---------------------------------------------+---------------------------------------------+
|
||||
| in_accel_gesture_singletap_scale | Single tap gesture threshold scale. |
|
||||
+---------------------------------------------+---------------------------------------------+
|
||||
| in_accel_gesture_singletap_timeout | Single tap duration in [us] |
|
||||
+---------------------------------------------+---------------------------------------------+
|
||||
| in_accel_gesture_singletap_value | Single tap threshold value in 62.5/LSB |
|
||||
+---------------------------------------------+---------------------------------------------+
|
||||
| in_accel_mag_falling_period | Inactivity time in seconds |
|
||||
+---------------------------------------------+---------------------------------------------+
|
||||
| in_accel_mag_falling_value | Inactivity threshold value in 62.5/LSB |
|
||||
+---------------------------------------------+---------------------------------------------+
|
||||
| in_accel_mag_adaptive_rising_en | Enable AC coupled activity on X axis |
|
||||
| in_accel_gesture_singletap_value | Single tap threshold value |
|
||||
+---------------------------------------------+---------------------------------------------+
|
||||
| in_accel_mag_adaptive_falling_period | AC coupled inactivity time in seconds |
|
||||
+---------------------------------------------+---------------------------------------------+
|
||||
| in_accel_mag_adaptive_falling_value | AC coupled inactivity threshold in 62.5/LSB |
|
||||
| in_accel_mag_adaptive_falling_scale | AC coupled inactivity threshold scale. |
|
||||
+---------------------------------------------+---------------------------------------------+
|
||||
| in_accel_mag_adaptive_rising_value | AC coupled activity threshold in 62.5/LSB |
|
||||
| in_accel_mag_adaptive_falling_value | AC coupled inactivity threshold |
|
||||
+---------------------------------------------+---------------------------------------------+
|
||||
| in_accel_mag_adaptive_rising_en | Enable AC coupled activity on X axis |
|
||||
+---------------------------------------------+---------------------------------------------+
|
||||
| in_accel_mag_adaptive_rising_scale | AC coupled activity threshold scale. |
|
||||
+---------------------------------------------+---------------------------------------------+
|
||||
| in_accel_mag_adaptive_rising_value | AC coupled activity threshold |
|
||||
+---------------------------------------------+---------------------------------------------+
|
||||
| in_accel_mag_falling_period | Inactivity time in seconds |
|
||||
+---------------------------------------------+---------------------------------------------+
|
||||
| in_accel_mag_falling_scale | DC coupled inactivity threshold scale. |
|
||||
+---------------------------------------------+---------------------------------------------+
|
||||
| in_accel_mag_falling_value | Inactivity threshold value |
|
||||
+---------------------------------------------+---------------------------------------------+
|
||||
| in_accel_mag_rising_en | Enable activity detection on X axis |
|
||||
+---------------------------------------------+---------------------------------------------+
|
||||
| in_accel_mag_rising_value | Activity threshold value in 62.5/LSB |
|
||||
| in_accel_mag_rising_scale | DC coupled activity threshold scale. |
|
||||
+---------------------------------------------+---------------------------------------------+
|
||||
| in_accel_mag_rising_value | Activity threshold value |
|
||||
+---------------------------------------------+---------------------------------------------+
|
||||
| in_accel_x&y&z_mag_adaptive_falling_en | Enable AC coupled inactivity on all axes |
|
||||
+---------------------------------------------+---------------------------------------------+
|
||||
| in_accel_x&y&z_mag_falling_en | Enable inactivity detection on all axes |
|
||||
+---------------------------------------------+---------------------------------------------+
|
||||
| in_accel_x_gesture_singletap_en | Enable single tap detection on X axis |
|
||||
+---------------------------------------------+---------------------------------------------+
|
||||
| in_accel_x&y&z_mag_falling_en | Enable inactivity detection on all axis |
|
||||
+---------------------------------------------+---------------------------------------------+
|
||||
| in_accel_x&y&z_mag_adaptive_falling_en | Enable AC coupled inactivity on all axis |
|
||||
+---------------------------------------------+---------------------------------------------+
|
||||
| in_accel_y_gesture_singletap_en | Enable single tap detection on Y axis |
|
||||
+---------------------------------------------+---------------------------------------------+
|
||||
| in_accel_z_gesture_singletap_en | Enable single tap detection on Z axis |
|
||||
|
|
@ -140,8 +159,8 @@ When changing the **g range** configuration, the driver attempts to estimate
|
|||
appropriate activity and inactivity thresholds by scaling the default values
|
||||
based on the ratio of the previous range to the new one. The resulting threshold
|
||||
will never be zero and will always fall between 1 and 255, corresponding to up
|
||||
to 62.5 g/LSB as specified in the datasheet. However, you can override these
|
||||
estimated thresholds by setting explicit values.
|
||||
to 62.5 mg/LSB (0.612915 m/s^2/LSB) as specified in the datasheet. However,
|
||||
you can override these estimated thresholds by setting explicit values.
|
||||
|
||||
When **activity** and **inactivity** events are enabled, the driver
|
||||
automatically manages hysteresis behavior by setting the **link** and
|
||||
|
|
@ -270,13 +289,13 @@ Scale range configuration:
|
|||
.. code-block:: bash
|
||||
|
||||
root:/sys/bus/iio/devices/iio:device0> cat ./in_accel_scale
|
||||
0.478899
|
||||
0.004789
|
||||
root:/sys/bus/iio/devices/iio:device0> cat ./in_accel_scale_available
|
||||
0.478899 0.957798 1.915595 3.831190
|
||||
0.004789 0.009578 0.019156 0.038312
|
||||
|
||||
root:/sys/bus/iio/devices/iio:device0> echo 1.915595 > ./in_accel_scale
|
||||
root:/sys/bus/iio/devices/iio:device0> echo 0.019156 > ./in_accel_scale
|
||||
root:/sys/bus/iio/devices/iio:device0> cat ./in_accel_scale
|
||||
1.915595
|
||||
0.019156
|
||||
|
||||
Set output data rate (ODR):
|
||||
|
||||
|
|
@ -312,10 +331,14 @@ Configure one or several events:
|
|||
|
||||
root:/sys/bus/iio/devices/iio:device0> echo 24 > ./buffer0/length
|
||||
|
||||
## AC coupled activity, threshold [62.5/LSB]
|
||||
## Check the event scale factor (0.0625 * 9.80665)
|
||||
root:/sys/bus/iio/devices/iio:device0> cat ./events/in_accel_gesture_doubletap_scale
|
||||
0.612915
|
||||
|
||||
## AC coupled activity, threshold [0.612915 m/s^2/LSB]
|
||||
root:/sys/bus/iio/devices/iio:device0> echo 6 > ./events/in_accel_mag_adaptive_rising_value
|
||||
|
||||
## AC coupled inactivity, threshold, [62.5/LSB]
|
||||
## AC coupled inactivity, threshold, [0.612915 m/s^2/LSB]
|
||||
root:/sys/bus/iio/devices/iio:device0> echo 4 > ./events/in_accel_mag_adaptive_falling_value
|
||||
|
||||
## AC coupled inactivity, time [s]
|
||||
|
|
@ -330,7 +353,7 @@ Configure one or several events:
|
|||
## doubletap, window [us]
|
||||
root:/sys/bus/iio/devices/iio:device0> echo 0.025 > ./events/in_accel_gesture_doubletap_reset_timeout
|
||||
|
||||
## doubletap, latent [us]
|
||||
## doubletap, latency [us]
|
||||
root:/sys/bus/iio/devices/iio:device0> echo 0.025 > ./events/in_accel_gesture_doubletap_tap2_min_delay
|
||||
|
||||
## AC coupled activity, enable
|
||||
|
|
|
|||
44
MAINTAINERS
44
MAINTAINERS
|
|
@ -640,8 +640,11 @@ W: https://ez.analog.com/linux-software-drivers
|
|||
F: Documentation/devicetree/bindings/iio/accel/adi,adxl367.yaml
|
||||
F: drivers/iio/accel/adxl367*
|
||||
|
||||
ADXL372 THREE-AXIS DIGITAL ACCELEROMETER DRIVER
|
||||
ADXL371/ADXL372 THREE-AXIS DIGITAL ACCELEROMETER DRIVER
|
||||
M: Michael Hennerich <michael.hennerich@analog.com>
|
||||
M: Marcelo Schmitt <marcelo.schmitt@analog.com>
|
||||
M: Nuno Sá <nuno.sa@analog.com>
|
||||
M: Antoniu Miclaus <antoniu.miclaus@analog.com>
|
||||
S: Supported
|
||||
W: https://ez.analog.com/linux-software-drivers
|
||||
F: Documentation/devicetree/bindings/iio/accel/adi,adxl372.yaml
|
||||
|
|
@ -1582,6 +1585,15 @@ W: https://ez.analog.com/linux-software-drivers
|
|||
F: Documentation/devicetree/bindings/iio/adc/adi,ad7780.yaml
|
||||
F: drivers/iio/adc/ad7780.c
|
||||
|
||||
ANALOG DEVICES INC AD8366 DRIVER
|
||||
M: Michael Hennerich <Michael.Hennerich@analog.com>
|
||||
M: Rodrigo Alencar <rodrigo.alencar@analog.com>
|
||||
L: linux-iio@vger.kernel.org
|
||||
S: Supported
|
||||
W: https://ez.analog.com/linux-software-drivers
|
||||
F: Documentation/devicetree/bindings/iio/amplifiers/adi,ad8366.yaml
|
||||
F: drivers/iio/amplifiers/ad8366.c
|
||||
|
||||
ANALOG DEVICES INC AD9467 DRIVER
|
||||
M: Michael Hennerich <Michael.Hennerich@analog.com>
|
||||
M: Nuno Sa <nuno.sa@analog.com>
|
||||
|
|
@ -1690,6 +1702,14 @@ S: Supported
|
|||
W: https://ez.analog.com/linux-software-drivers
|
||||
F: Documentation/devicetree/bindings/iio/imu/adi,adis16550.yaml
|
||||
|
||||
ANALOG DEVICES INC ADL8113 DRIVER
|
||||
M: Antoniu Miclaus <antoniu.miclaus@analog.com>
|
||||
L: linux-iio@vger.kernel.org
|
||||
S: Supported
|
||||
W: https://ez.analog.com/linux-software-drivers
|
||||
F: Documentation/devicetree/bindings/iio/amplifiers/adi,adl8113.yaml
|
||||
F: drivers/iio/amplifiers/adl8113.c
|
||||
|
||||
ANALOG DEVICES INC ADM1177 DRIVER
|
||||
M: Michael Hennerich <Michael.Hennerich@analog.com>
|
||||
L: linux-hwmon@vger.kernel.org
|
||||
|
|
@ -2700,8 +2720,9 @@ N: digicolor
|
|||
|
||||
ARM/CORESIGHT FRAMEWORK AND DRIVERS
|
||||
M: Suzuki K Poulose <suzuki.poulose@arm.com>
|
||||
R: Mike Leach <mike.leach@linaro.org>
|
||||
R: Mike Leach <mike.leach@arm.com>
|
||||
R: James Clark <james.clark@linaro.org>
|
||||
R: Leo Yan <leo.yan@arm.com>
|
||||
L: coresight@lists.linaro.org (moderated for non-subscribers)
|
||||
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
||||
S: Maintained
|
||||
|
|
@ -13380,6 +13401,12 @@ F: include/linux/interconnect-clk.h
|
|||
F: include/linux/interconnect-provider.h
|
||||
F: include/linux/interconnect.h
|
||||
|
||||
INTERCONNECT KUNIT TESTS
|
||||
M: Kuan-Wei Chiu <visitorckw@gmail.com>
|
||||
L: linux-pm@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/interconnect/icc-kunit.c
|
||||
|
||||
INTERRUPT COUNTER DRIVER
|
||||
M: Oleksij Rempel <o.rempel@pengutronix.de>
|
||||
R: Pengutronix Kernel Team <kernel@pengutronix.de>
|
||||
|
|
@ -19373,8 +19400,8 @@ F: drivers/net/dsa/ocelot/ocelot_ext.c
|
|||
F: include/linux/mfd/ocelot.h
|
||||
|
||||
OCXL (Open Coherent Accelerator Processor Interface OpenCAPI) DRIVER
|
||||
M: Frederic Barrat <fbarrat@linux.ibm.com>
|
||||
M: Andrew Donnellan <ajd@linux.ibm.com>
|
||||
M: Mahesh J Salgaonkar <mahesh@linux.ibm.com>
|
||||
R: Andrew Donnellan <andrew+kernel@donnellan.id.au>
|
||||
L: linuxppc-dev@lists.ozlabs.org
|
||||
S: Odd Fixes
|
||||
F: Documentation/userspace-api/accelerators/ocxl.rst
|
||||
|
|
@ -20859,7 +20886,7 @@ PERFORMANCE EVENTS TOOLING ARM64
|
|||
R: John Garry <john.g.garry@oracle.com>
|
||||
R: Will Deacon <will@kernel.org>
|
||||
R: James Clark <james.clark@linaro.org>
|
||||
R: Mike Leach <mike.leach@linaro.org>
|
||||
R: Mike Leach <mike.leach@arm.com>
|
||||
R: Leo Yan <leo.yan@linux.dev>
|
||||
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
||||
S: Supported
|
||||
|
|
@ -25294,6 +25321,13 @@ S: Maintained
|
|||
F: Documentation/devicetree/bindings/iio/proximity/st,vl53l0x.yaml
|
||||
F: drivers/iio/proximity/vl53l0x-i2c.c
|
||||
|
||||
ST VL53L1X ToF RANGER(I2C) IIO DRIVER
|
||||
M: Siratul Islam <email@sirat.me>
|
||||
L: linux-iio@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/iio/proximity/st,vl53l0x.yaml
|
||||
F: drivers/iio/proximity/vl53l1x-i2c.c
|
||||
|
||||
STABLE BRANCH
|
||||
M: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
M: Sasha Levin <sashal@kernel.org>
|
||||
|
|
|
|||
|
|
@ -3117,7 +3117,7 @@ static void binder_transaction(struct binder_proc *proc,
|
|||
t->start_time = t_start_time;
|
||||
t->from_pid = proc->pid;
|
||||
t->from_tid = thread->pid;
|
||||
t->sender_euid = task_euid(proc->tsk);
|
||||
t->sender_euid = current_euid();
|
||||
t->code = tr->code;
|
||||
t->flags = tr->flags;
|
||||
t->priority = task_nice(current);
|
||||
|
|
|
|||
|
|
@ -56,7 +56,6 @@ pub(crate) struct Allocation {
|
|||
pub(crate) process: Arc<Process>,
|
||||
allocation_info: Option<AllocationInfo>,
|
||||
free_on_drop: bool,
|
||||
pub(crate) oneway_spam_detected: bool,
|
||||
#[allow(dead_code)]
|
||||
pub(crate) debug_id: usize,
|
||||
}
|
||||
|
|
@ -68,7 +67,6 @@ pub(crate) fn new(
|
|||
offset: usize,
|
||||
size: usize,
|
||||
ptr: usize,
|
||||
oneway_spam_detected: bool,
|
||||
) -> Self {
|
||||
Self {
|
||||
process,
|
||||
|
|
@ -76,7 +74,6 @@ pub(crate) fn new(
|
|||
size,
|
||||
ptr,
|
||||
debug_id,
|
||||
oneway_spam_detected,
|
||||
allocation_info: None,
|
||||
free_on_drop: true,
|
||||
}
|
||||
|
|
@ -208,6 +205,7 @@ pub(crate) fn translate_fds(&mut self) -> Result<TranslatedFds> {
|
|||
let res = FileDescriptorReservation::get_unused_fd_flags(bindings::O_CLOEXEC)?;
|
||||
let fd = res.reserved_fd();
|
||||
self.write::<u32>(file_info.buffer_offset, &fd)?;
|
||||
crate::trace::trace_transaction_fd_recv(self.debug_id, fd, file_info.buffer_offset);
|
||||
|
||||
reservations.push(
|
||||
Reservation {
|
||||
|
|
@ -260,19 +258,22 @@ fn drop(&mut self) {
|
|||
}
|
||||
}
|
||||
|
||||
for &fd in &info.file_list.close_on_free {
|
||||
let closer = match DeferredFdCloser::new(GFP_KERNEL) {
|
||||
Ok(closer) => closer,
|
||||
Err(kernel::alloc::AllocError) => {
|
||||
// Ignore allocation failures.
|
||||
break;
|
||||
}
|
||||
};
|
||||
if self.process.task == kernel::current!().group_leader() {
|
||||
for &fd in &info.file_list.close_on_free {
|
||||
let closer = match DeferredFdCloser::new(GFP_KERNEL) {
|
||||
Ok(closer) => closer,
|
||||
Err(kernel::alloc::AllocError) => {
|
||||
// Ignore allocation failures.
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
// Here, we ignore errors. The operation can fail if the fd is not valid, or if the
|
||||
// method is called from a kthread. However, this is always called from a syscall,
|
||||
// so the latter case cannot happen, and we don't care about the first case.
|
||||
let _ = closer.close_fd(fd);
|
||||
// Here, we ignore errors. The operation can fail if the fd is not valid, or if
|
||||
// the method is called from a kthread. However, this is always called from a
|
||||
// syscall, so the latter case cannot happen, and we don't care about the first
|
||||
// case.
|
||||
let _ = closer.close_fd(fd);
|
||||
}
|
||||
}
|
||||
|
||||
if info.clear_on_free {
|
||||
|
|
|
|||
|
|
@ -94,6 +94,17 @@ pub(crate) fn deregister_process(self: &Arc<Self>, proc: &Arc<Process>) {
|
|||
}
|
||||
let mut manager = self.manager.lock();
|
||||
manager.all_procs.retain(|p| !Arc::ptr_eq(p, proc));
|
||||
|
||||
// Shrink the vector if it has significant unused capacity to avoid memory waste,
|
||||
// but use a conservative strategy to prevent shrink-then-regrow oscillation.
|
||||
// Only shrink when length drops below 1/4 of capacity, and shrink to twice the length.
|
||||
let len = manager.all_procs.len();
|
||||
let cap = manager.all_procs.capacity();
|
||||
if len < cap / 4 {
|
||||
// Shrink to twice the current length. Ignore allocation failures since this
|
||||
// is just an optimization; the vector remains valid even if shrinking fails.
|
||||
let _ = manager.all_procs.shrink_to(len * 2, GFP_KERNEL);
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn set_manager_node(&self, node_ref: NodeRef) -> Result {
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
/// errno.
|
||||
pub(crate) struct BinderError {
|
||||
pub(crate) reply: u32,
|
||||
source: Option<Error>,
|
||||
pub(crate) source: Option<Error>,
|
||||
}
|
||||
|
||||
impl BinderError {
|
||||
|
|
@ -41,14 +41,6 @@ pub(crate) fn new_frozen_oneway() -> Self {
|
|||
pub(crate) fn is_dead(&self) -> bool {
|
||||
self.reply == BR_DEAD_REPLY
|
||||
}
|
||||
|
||||
pub(crate) fn as_errno(&self) -> kernel::ffi::c_int {
|
||||
self.source.unwrap_or(EINVAL).to_errno()
|
||||
}
|
||||
|
||||
pub(crate) fn should_pr_warn(&self) -> bool {
|
||||
self.source.is_some()
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert an errno into a `BinderError` and store the errno used to construct it. The errno
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@
|
|||
range_alloc::{RangeAllocator, ReserveNew, ReserveNewArgs},
|
||||
stats::BinderStats,
|
||||
thread::{PushWorkRes, Thread},
|
||||
transaction::TransactionInfo,
|
||||
BinderfsProcFile, DArc, DLArc, DTRWrap, DeliverToRead,
|
||||
};
|
||||
|
||||
|
|
@ -681,7 +682,7 @@ pub(crate) fn get_work_or_register<'a>(
|
|||
fn get_current_thread(self: ArcBorrow<'_, Self>) -> Result<Arc<Thread>> {
|
||||
let id = {
|
||||
let current = kernel::current!();
|
||||
if !core::ptr::eq(current.group_leader(), &*self.task) {
|
||||
if self.task != current.group_leader() {
|
||||
pr_err!("get_current_thread was called from the wrong process.");
|
||||
return Err(EINVAL);
|
||||
}
|
||||
|
|
@ -1003,16 +1004,15 @@ pub(crate) fn buffer_alloc(
|
|||
self: &Arc<Self>,
|
||||
debug_id: usize,
|
||||
size: usize,
|
||||
is_oneway: bool,
|
||||
from_pid: i32,
|
||||
info: &mut TransactionInfo,
|
||||
) -> BinderResult<NewAllocation> {
|
||||
use kernel::page::PAGE_SIZE;
|
||||
|
||||
let mut reserve_new_args = ReserveNewArgs {
|
||||
debug_id,
|
||||
size,
|
||||
is_oneway,
|
||||
pid: from_pid,
|
||||
is_oneway: info.is_oneway(),
|
||||
pid: info.from_pid,
|
||||
..ReserveNewArgs::default()
|
||||
};
|
||||
|
||||
|
|
@ -1028,13 +1028,13 @@ pub(crate) fn buffer_alloc(
|
|||
reserve_new_args = alloc_request.make_alloc()?;
|
||||
};
|
||||
|
||||
info.oneway_spam_suspect = new_alloc.oneway_spam_detected;
|
||||
let res = Allocation::new(
|
||||
self.clone(),
|
||||
debug_id,
|
||||
new_alloc.offset,
|
||||
size,
|
||||
addr + new_alloc.offset,
|
||||
new_alloc.oneway_spam_detected,
|
||||
);
|
||||
|
||||
// This allocation will be marked as in use until the `Allocation` is used to free it.
|
||||
|
|
@ -1066,7 +1066,7 @@ pub(crate) fn buffer_get(self: &Arc<Self>, ptr: usize) -> Option<Allocation> {
|
|||
let mapping = inner.mapping.as_mut()?;
|
||||
let offset = ptr.checked_sub(mapping.address)?;
|
||||
let (size, debug_id, odata) = mapping.alloc.reserve_existing(offset).ok()?;
|
||||
let mut alloc = Allocation::new(self.clone(), debug_id, offset, size, ptr, false);
|
||||
let mut alloc = Allocation::new(self.clone(), debug_id, offset, size, ptr);
|
||||
if let Some(data) = odata {
|
||||
alloc.set_info(data);
|
||||
}
|
||||
|
|
@ -1414,8 +1414,7 @@ fn deferred_release(self: Arc<Self>) {
|
|||
.alloc
|
||||
.take_for_each(|offset, size, debug_id, odata| {
|
||||
let ptr = offset + address;
|
||||
let mut alloc =
|
||||
Allocation::new(self.clone(), debug_id, offset, size, ptr, false);
|
||||
let mut alloc = Allocation::new(self.clone(), debug_id, offset, size, ptr);
|
||||
if let Some(data) = odata {
|
||||
alloc.set_info(data);
|
||||
}
|
||||
|
|
@ -1443,6 +1442,9 @@ pub(crate) fn drop_outstanding_txn(&self) {
|
|||
}
|
||||
}
|
||||
|
||||
// #[export_name] is a temporary workaround so that ps output does not become unreadable from
|
||||
// mangled symbol names.
|
||||
#[export_name = "rust_binder_freeze"]
|
||||
pub(crate) fn ioctl_freeze(&self, info: &BinderFreezeInfo) -> Result {
|
||||
if info.enable == 0 {
|
||||
let msgs = self.prepare_freeze_messages()?;
|
||||
|
|
@ -1657,11 +1659,14 @@ pub(crate) fn ioctl(this: ArcBorrow<'_, Process>, file: &File, cmd: u32, arg: us
|
|||
|
||||
const _IOC_READ_WRITE: u32 = _IOC_READ | _IOC_WRITE;
|
||||
|
||||
match _IOC_DIR(cmd) {
|
||||
let res = match _IOC_DIR(cmd) {
|
||||
_IOC_WRITE => Self::ioctl_write_only(this, file, cmd, &mut user_slice.reader()),
|
||||
_IOC_READ_WRITE => Self::ioctl_write_read(this, file, cmd, user_slice),
|
||||
_ => Err(EINVAL),
|
||||
}
|
||||
};
|
||||
|
||||
crate::trace::trace_ioctl_done(res);
|
||||
res
|
||||
}
|
||||
|
||||
pub(crate) fn mmap(
|
||||
|
|
@ -1670,7 +1675,7 @@ pub(crate) fn mmap(
|
|||
vma: &mm::virt::VmaNew,
|
||||
) -> Result {
|
||||
// We don't allow mmap to be used in a different process.
|
||||
if !core::ptr::eq(kernel::current!().group_leader(), &*this.task) {
|
||||
if this.task != kernel::current!().group_leader() {
|
||||
return Err(EINVAL);
|
||||
}
|
||||
if vma.start() == 0 {
|
||||
|
|
|
|||
|
|
@ -99,4 +99,9 @@ static inline size_t rust_binder_node_debug_id(rust_binder_node t)
|
|||
return *(size_t *) (t + RUST_BINDER_LAYOUT.n.debug_id);
|
||||
}
|
||||
|
||||
static inline binder_uintptr_t rust_binder_node_ptr(rust_binder_node t)
|
||||
{
|
||||
return *(binder_uintptr_t *) (t + RUST_BINDER_LAYOUT.n.ptr);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
#include <linux/tracepoint.h>
|
||||
|
||||
TRACE_EVENT(rust_binder_ioctl,
|
||||
TRACE_EVENT(binder_ioctl,
|
||||
TP_PROTO(unsigned int cmd, unsigned long arg),
|
||||
TP_ARGS(cmd, arg),
|
||||
|
||||
|
|
@ -30,7 +30,46 @@ TRACE_EVENT(rust_binder_ioctl,
|
|||
TP_printk("cmd=0x%x arg=0x%lx", __entry->cmd, __entry->arg)
|
||||
);
|
||||
|
||||
TRACE_EVENT(rust_binder_transaction,
|
||||
DECLARE_EVENT_CLASS(binder_function_return_class,
|
||||
TP_PROTO(int ret),
|
||||
TP_ARGS(ret),
|
||||
TP_STRUCT__entry(
|
||||
__field(int, ret)
|
||||
),
|
||||
TP_fast_assign(
|
||||
__entry->ret = ret;
|
||||
),
|
||||
TP_printk("ret=%d", __entry->ret)
|
||||
);
|
||||
|
||||
#define DEFINE_RBINDER_FUNCTION_RETURN_EVENT(name) \
|
||||
DEFINE_EVENT(binder_function_return_class, name, \
|
||||
TP_PROTO(int ret), \
|
||||
TP_ARGS(ret))
|
||||
|
||||
DEFINE_RBINDER_FUNCTION_RETURN_EVENT(binder_ioctl_done);
|
||||
DEFINE_RBINDER_FUNCTION_RETURN_EVENT(binder_read_done);
|
||||
DEFINE_RBINDER_FUNCTION_RETURN_EVENT(binder_write_done);
|
||||
|
||||
TRACE_EVENT(binder_wait_for_work,
|
||||
TP_PROTO(bool proc_work, bool transaction_stack, bool thread_todo),
|
||||
TP_ARGS(proc_work, transaction_stack, thread_todo),
|
||||
TP_STRUCT__entry(
|
||||
__field(bool, proc_work)
|
||||
__field(bool, transaction_stack)
|
||||
__field(bool, thread_todo)
|
||||
),
|
||||
TP_fast_assign(
|
||||
__entry->proc_work = proc_work;
|
||||
__entry->transaction_stack = transaction_stack;
|
||||
__entry->thread_todo = thread_todo;
|
||||
),
|
||||
TP_printk("proc_work=%d transaction_stack=%d thread_todo=%d",
|
||||
__entry->proc_work, __entry->transaction_stack,
|
||||
__entry->thread_todo)
|
||||
);
|
||||
|
||||
TRACE_EVENT(binder_transaction,
|
||||
TP_PROTO(bool reply, rust_binder_transaction t, struct task_struct *thread),
|
||||
TP_ARGS(reply, t, thread),
|
||||
TP_STRUCT__entry(
|
||||
|
|
@ -60,6 +99,84 @@ TRACE_EVENT(rust_binder_transaction,
|
|||
__entry->reply, __entry->flags, __entry->code)
|
||||
);
|
||||
|
||||
TRACE_EVENT(binder_transaction_received,
|
||||
TP_PROTO(rust_binder_transaction t),
|
||||
TP_ARGS(t),
|
||||
TP_STRUCT__entry(
|
||||
__field(int, debug_id)
|
||||
),
|
||||
TP_fast_assign(
|
||||
__entry->debug_id = rust_binder_transaction_debug_id(t);
|
||||
),
|
||||
TP_printk("transaction=%d", __entry->debug_id)
|
||||
);
|
||||
|
||||
TRACE_EVENT(binder_transaction_fd_send,
|
||||
TP_PROTO(int t_debug_id, int fd, size_t offset),
|
||||
TP_ARGS(t_debug_id, fd, offset),
|
||||
TP_STRUCT__entry(
|
||||
__field(int, debug_id)
|
||||
__field(int, fd)
|
||||
__field(size_t, offset)
|
||||
),
|
||||
TP_fast_assign(
|
||||
__entry->debug_id = t_debug_id;
|
||||
__entry->fd = fd;
|
||||
__entry->offset = offset;
|
||||
),
|
||||
TP_printk("transaction=%d src_fd=%d offset=%zu",
|
||||
__entry->debug_id, __entry->fd, __entry->offset)
|
||||
);
|
||||
|
||||
TRACE_EVENT(binder_transaction_fd_recv,
|
||||
TP_PROTO(int t_debug_id, int fd, size_t offset),
|
||||
TP_ARGS(t_debug_id, fd, offset),
|
||||
TP_STRUCT__entry(
|
||||
__field(int, debug_id)
|
||||
__field(int, fd)
|
||||
__field(size_t, offset)
|
||||
),
|
||||
TP_fast_assign(
|
||||
__entry->debug_id = t_debug_id;
|
||||
__entry->fd = fd;
|
||||
__entry->offset = offset;
|
||||
),
|
||||
TP_printk("transaction=%d dest_fd=%d offset=%zu",
|
||||
__entry->debug_id, __entry->fd, __entry->offset)
|
||||
);
|
||||
|
||||
TRACE_EVENT(binder_command,
|
||||
TP_PROTO(uint32_t cmd),
|
||||
TP_ARGS(cmd),
|
||||
TP_STRUCT__entry(
|
||||
__field(uint32_t, cmd)
|
||||
),
|
||||
TP_fast_assign(
|
||||
__entry->cmd = cmd;
|
||||
),
|
||||
TP_printk("cmd=0x%x %s",
|
||||
__entry->cmd,
|
||||
_IOC_NR(__entry->cmd) < ARRAY_SIZE(binder_command_strings) ?
|
||||
binder_command_strings[_IOC_NR(__entry->cmd)] :
|
||||
"unknown")
|
||||
);
|
||||
|
||||
TRACE_EVENT(binder_return,
|
||||
TP_PROTO(uint32_t cmd),
|
||||
TP_ARGS(cmd),
|
||||
TP_STRUCT__entry(
|
||||
__field(uint32_t, cmd)
|
||||
),
|
||||
TP_fast_assign(
|
||||
__entry->cmd = cmd;
|
||||
),
|
||||
TP_printk("cmd=0x%x %s",
|
||||
__entry->cmd,
|
||||
_IOC_NR(__entry->cmd) < ARRAY_SIZE(binder_return_strings) ?
|
||||
binder_return_strings[_IOC_NR(__entry->cmd)] :
|
||||
"unknown")
|
||||
);
|
||||
|
||||
#endif /* _RUST_BINDER_TRACE_H */
|
||||
|
||||
/* This part must be outside protection */
|
||||
|
|
|
|||
|
|
@ -118,6 +118,7 @@ fn new(writer: UserSliceWriter, thread: &'a Thread) -> Self {
|
|||
/// Write a return code back to user space.
|
||||
/// Should be a `BR_` constant from [`defs`] e.g. [`defs::BR_TRANSACTION_COMPLETE`].
|
||||
fn write_code(&mut self, code: u32) -> Result {
|
||||
crate::trace::trace_return(code);
|
||||
stats::GLOBAL_STATS.inc_br(code);
|
||||
self.thread.process.stats.inc_br(code);
|
||||
self.writer.write(&code)
|
||||
|
|
@ -294,8 +295,6 @@ fn init(_module: &'static kernel::ThisModule) -> Result<Self> {
|
|||
// SAFETY: The module initializer never runs twice, so we only call this once.
|
||||
unsafe { crate::context::CONTEXTS.init() };
|
||||
|
||||
pr_warn!("Loaded Rust Binder.");
|
||||
|
||||
BINDER_SHRINKER.register(c"android-binder")?;
|
||||
|
||||
// SAFETY: The module is being loaded, so we can initialize binderfs.
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
sync::poll::{PollCondVar, PollTable},
|
||||
sync::{aref::ARef, Arc, SpinLock},
|
||||
task::Task,
|
||||
uaccess::UserSlice,
|
||||
uaccess::{UserPtr, UserSlice, UserSliceReader},
|
||||
uapi,
|
||||
};
|
||||
|
||||
|
|
@ -30,7 +30,7 @@
|
|||
process::{GetWorkOrRegister, Process},
|
||||
ptr_align,
|
||||
stats::GLOBAL_STATS,
|
||||
transaction::Transaction,
|
||||
transaction::{Transaction, TransactionInfo},
|
||||
BinderReturnWriter, DArc, DLArc, DTRWrap, DeliverCode, DeliverToRead,
|
||||
};
|
||||
|
||||
|
|
@ -513,6 +513,9 @@ pub(crate) fn has_current_transaction(&self) -> bool {
|
|||
/// Attempts to fetch a work item from the thread-local queue. The behaviour if the queue is
|
||||
/// empty depends on `wait`: if it is true, the function waits for some work to be queued (or a
|
||||
/// signal); otherwise it returns indicating that none is available.
|
||||
// #[export_name] is a temporary workaround so that ps output does not become unreadable from
|
||||
// mangled symbol names.
|
||||
#[export_name = "rust_binder_waitlcl"]
|
||||
fn get_work_local(self: &Arc<Self>, wait: bool) -> Result<Option<DLArc<dyn DeliverToRead>>> {
|
||||
{
|
||||
let mut inner = self.inner.lock();
|
||||
|
|
@ -551,6 +554,9 @@ fn get_work_local(self: &Arc<Self>, wait: bool) -> Result<Option<DLArc<dyn Deliv
|
|||
///
|
||||
/// This must only be called when the thread is not participating in a transaction chain. If it
|
||||
/// is, the local version (`get_work_local`) should be used instead.
|
||||
// #[export_name] is a temporary workaround so that ps output does not become unreadable from
|
||||
// mangled symbol names.
|
||||
#[export_name = "rust_binder_wait"]
|
||||
fn get_work(self: &Arc<Self>, wait: bool) -> Result<Option<DLArc<dyn DeliverToRead>>> {
|
||||
// Try to get work from the thread's work queue, using only a local lock.
|
||||
{
|
||||
|
|
@ -706,6 +712,7 @@ fn translate_object(
|
|||
core::mem::offset_of!(uapi::binder_fd_object, __bindgen_anon_1.fd);
|
||||
|
||||
let field_offset = offset + FD_FIELD_OFFSET;
|
||||
crate::trace::trace_transaction_fd_send(view.alloc.debug_id, fd, field_offset);
|
||||
|
||||
view.alloc.info_add_fd(file, field_offset, false)?;
|
||||
}
|
||||
|
|
@ -945,13 +952,11 @@ fn apply_sg(&self, alloc: &mut Allocation, sg_state: &mut ScatterGatherState) ->
|
|||
pub(crate) fn copy_transaction_data(
|
||||
&self,
|
||||
to_process: Arc<Process>,
|
||||
tr: &BinderTransactionDataSg,
|
||||
info: &mut TransactionInfo,
|
||||
debug_id: usize,
|
||||
allow_fds: bool,
|
||||
txn_security_ctx_offset: Option<&mut usize>,
|
||||
) -> BinderResult<NewAllocation> {
|
||||
let trd = &tr.transaction_data;
|
||||
let is_oneway = trd.flags & TF_ONE_WAY != 0;
|
||||
let mut secctx = if let Some(offset) = txn_security_ctx_offset {
|
||||
let secid = self.process.cred.get_secid();
|
||||
let ctx = match security::SecurityCtx::from_secid(secid) {
|
||||
|
|
@ -966,10 +971,10 @@ pub(crate) fn copy_transaction_data(
|
|||
None
|
||||
};
|
||||
|
||||
let data_size = trd.data_size.try_into().map_err(|_| EINVAL)?;
|
||||
let data_size = info.data_size;
|
||||
let aligned_data_size = ptr_align(data_size).ok_or(EINVAL)?;
|
||||
let offsets_size: usize = trd.offsets_size.try_into().map_err(|_| EINVAL)?;
|
||||
let buffers_size: usize = tr.buffers_size.try_into().map_err(|_| EINVAL)?;
|
||||
let offsets_size = info.offsets_size;
|
||||
let buffers_size = info.buffers_size;
|
||||
let aligned_secctx_size = match secctx.as_ref() {
|
||||
Some((_offset, ctx)) => ptr_align(ctx.len()).ok_or(EINVAL)?,
|
||||
None => 0,
|
||||
|
|
@ -992,32 +997,25 @@ pub(crate) fn copy_transaction_data(
|
|||
size_of::<u64>(),
|
||||
);
|
||||
let secctx_off = aligned_data_size + offsets_size + buffers_size;
|
||||
let mut alloc =
|
||||
match to_process.buffer_alloc(debug_id, len, is_oneway, self.process.task.pid()) {
|
||||
Ok(alloc) => alloc,
|
||||
Err(err) => {
|
||||
pr_warn!(
|
||||
"Failed to allocate buffer. len:{}, is_oneway:{}",
|
||||
len,
|
||||
is_oneway
|
||||
);
|
||||
return Err(err);
|
||||
}
|
||||
};
|
||||
let mut alloc = match to_process.buffer_alloc(debug_id, len, info) {
|
||||
Ok(alloc) => alloc,
|
||||
Err(err) => {
|
||||
pr_warn!(
|
||||
"Failed to allocate buffer. len:{}, is_oneway:{}",
|
||||
len,
|
||||
info.is_oneway(),
|
||||
);
|
||||
return Err(err);
|
||||
}
|
||||
};
|
||||
|
||||
// SAFETY: This accesses a union field, but it's okay because the field's type is valid for
|
||||
// all bit-patterns.
|
||||
let trd_data_ptr = unsafe { &trd.data.ptr };
|
||||
let mut buffer_reader =
|
||||
UserSlice::new(UserPtr::from_addr(trd_data_ptr.buffer as _), data_size).reader();
|
||||
let mut buffer_reader = UserSlice::new(info.data_ptr, data_size).reader();
|
||||
let mut end_of_previous_object = 0;
|
||||
let mut sg_state = None;
|
||||
|
||||
// Copy offsets if there are any.
|
||||
if offsets_size > 0 {
|
||||
let mut offsets_reader =
|
||||
UserSlice::new(UserPtr::from_addr(trd_data_ptr.offsets as _), offsets_size)
|
||||
.reader();
|
||||
let mut offsets_reader = UserSlice::new(info.offsets_ptr, offsets_size).reader();
|
||||
|
||||
let offsets_start = aligned_data_size;
|
||||
let offsets_end = aligned_data_size + offsets_size;
|
||||
|
|
@ -1192,37 +1190,92 @@ fn top_of_transaction_stack(&self) -> Result<Option<DArc<Transaction>>> {
|
|||
}
|
||||
}
|
||||
|
||||
fn transaction<T>(self: &Arc<Self>, tr: &BinderTransactionDataSg, inner: T)
|
||||
where
|
||||
T: FnOnce(&Arc<Self>, &BinderTransactionDataSg) -> BinderResult,
|
||||
{
|
||||
if let Err(err) = inner(self, tr) {
|
||||
if err.should_pr_warn() {
|
||||
let mut ee = self.inner.lock().extended_error;
|
||||
ee.command = err.reply;
|
||||
ee.param = err.as_errno();
|
||||
pr_warn!(
|
||||
"Transaction failed: {:?} my_pid:{}",
|
||||
err,
|
||||
self.process.pid_in_current_ns()
|
||||
);
|
||||
// No inlining avoids allocating stack space for `BinderTransactionData` for the entire
|
||||
// duration of `transaction()`.
|
||||
#[inline(never)]
|
||||
fn read_transaction_info(
|
||||
&self,
|
||||
cmd: u32,
|
||||
reader: &mut UserSliceReader,
|
||||
info: &mut TransactionInfo,
|
||||
) -> Result<()> {
|
||||
let td = match cmd {
|
||||
BC_TRANSACTION | BC_REPLY => {
|
||||
reader.read::<BinderTransactionData>()?.with_buffers_size(0)
|
||||
}
|
||||
BC_TRANSACTION_SG | BC_REPLY_SG => reader.read::<BinderTransactionDataSg>()?,
|
||||
_ => return Err(EINVAL),
|
||||
};
|
||||
|
||||
// SAFETY: Above `read` call initializes all bytes, so this union read is ok.
|
||||
let trd_data_ptr = unsafe { &td.transaction_data.data.ptr };
|
||||
|
||||
info.is_reply = matches!(cmd, BC_REPLY | BC_REPLY_SG);
|
||||
info.from_pid = self.process.task.pid();
|
||||
info.from_tid = self.id;
|
||||
info.code = td.transaction_data.code;
|
||||
info.flags = td.transaction_data.flags;
|
||||
info.data_ptr = UserPtr::from_addr(trd_data_ptr.buffer as usize);
|
||||
info.data_size = td.transaction_data.data_size as usize;
|
||||
info.offsets_ptr = UserPtr::from_addr(trd_data_ptr.offsets as usize);
|
||||
info.offsets_size = td.transaction_data.offsets_size as usize;
|
||||
info.buffers_size = td.buffers_size as usize;
|
||||
// SAFETY: Above `read` call initializes all bytes, so this union read is ok.
|
||||
info.target_handle = unsafe { td.transaction_data.target.handle };
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
fn transaction(self: &Arc<Self>, cmd: u32, reader: &mut UserSliceReader) -> Result<()> {
|
||||
let mut info = TransactionInfo::zeroed();
|
||||
self.read_transaction_info(cmd, reader, &mut info)?;
|
||||
|
||||
let ret = if info.is_reply {
|
||||
self.reply_inner(&mut info)
|
||||
} else if info.is_oneway() {
|
||||
self.oneway_transaction_inner(&mut info)
|
||||
} else {
|
||||
self.transaction_inner(&mut info)
|
||||
};
|
||||
|
||||
if let Err(err) = ret {
|
||||
if err.reply != BR_TRANSACTION_COMPLETE {
|
||||
info.reply = err.reply;
|
||||
}
|
||||
|
||||
self.push_return_work(err.reply);
|
||||
if let Some(source) = &err.source {
|
||||
info.errno = source.to_errno();
|
||||
info.reply = err.reply;
|
||||
|
||||
{
|
||||
let mut ee = self.inner.lock().extended_error;
|
||||
ee.command = err.reply;
|
||||
ee.param = source.to_errno();
|
||||
}
|
||||
|
||||
pr_warn!(
|
||||
"{}:{} transaction to {} failed: {source:?}",
|
||||
info.from_pid,
|
||||
info.from_tid,
|
||||
info.to_pid
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn transaction_inner(self: &Arc<Self>, tr: &BinderTransactionDataSg) -> BinderResult {
|
||||
// SAFETY: Handle's type has no invalid bit patterns.
|
||||
let handle = unsafe { tr.transaction_data.target.handle };
|
||||
let node_ref = self.process.get_transaction_node(handle)?;
|
||||
fn transaction_inner(self: &Arc<Self>, info: &mut TransactionInfo) -> BinderResult {
|
||||
let node_ref = self.process.get_transaction_node(info.target_handle)?;
|
||||
info.to_pid = node_ref.node.owner.task.pid();
|
||||
security::binder_transaction(&self.process.cred, &node_ref.node.owner.cred)?;
|
||||
// TODO: We need to ensure that there isn't a pending transaction in the work queue. How
|
||||
// could this happen?
|
||||
let top = self.top_of_transaction_stack()?;
|
||||
let list_completion = DTRWrap::arc_try_new(DeliverCode::new(BR_TRANSACTION_COMPLETE))?;
|
||||
let completion = list_completion.clone_arc();
|
||||
let transaction = Transaction::new(node_ref, top, self, tr)?;
|
||||
let transaction = Transaction::new(node_ref, top, self, info)?;
|
||||
|
||||
// Check that the transaction stack hasn't changed while the lock was released, then update
|
||||
// it with the new transaction.
|
||||
|
|
@ -1238,7 +1291,7 @@ fn transaction_inner(self: &Arc<Self>, tr: &BinderTransactionDataSg) -> BinderRe
|
|||
inner.push_work_deferred(list_completion);
|
||||
}
|
||||
|
||||
if let Err(e) = transaction.submit() {
|
||||
if let Err(e) = transaction.submit(info) {
|
||||
completion.skip();
|
||||
// Define `transaction` first to drop it after `inner`.
|
||||
let transaction;
|
||||
|
|
@ -1251,18 +1304,21 @@ fn transaction_inner(self: &Arc<Self>, tr: &BinderTransactionDataSg) -> BinderRe
|
|||
}
|
||||
}
|
||||
|
||||
fn reply_inner(self: &Arc<Self>, tr: &BinderTransactionDataSg) -> BinderResult {
|
||||
fn reply_inner(self: &Arc<Self>, info: &mut TransactionInfo) -> BinderResult {
|
||||
let orig = self.inner.lock().pop_transaction_to_reply(self)?;
|
||||
if !orig.from.is_current_transaction(&orig) {
|
||||
return Err(EINVAL.into());
|
||||
}
|
||||
|
||||
info.to_tid = orig.from.id;
|
||||
info.to_pid = orig.from.process.task.pid();
|
||||
|
||||
// We need to complete the transaction even if we cannot complete building the reply.
|
||||
let out = (|| -> BinderResult<_> {
|
||||
let completion = DTRWrap::arc_try_new(DeliverCode::new(BR_TRANSACTION_COMPLETE))?;
|
||||
let process = orig.from.process.clone();
|
||||
let allow_fds = orig.flags & TF_ACCEPT_FDS != 0;
|
||||
let reply = Transaction::new_reply(self, process, tr, allow_fds)?;
|
||||
let reply = Transaction::new_reply(self, process, info, allow_fds)?;
|
||||
self.inner.lock().push_work(completion);
|
||||
orig.from.deliver_reply(Ok(reply), &orig);
|
||||
Ok(())
|
||||
|
|
@ -1283,16 +1339,12 @@ fn reply_inner(self: &Arc<Self>, tr: &BinderTransactionDataSg) -> BinderResult {
|
|||
out
|
||||
}
|
||||
|
||||
fn oneway_transaction_inner(self: &Arc<Self>, tr: &BinderTransactionDataSg) -> BinderResult {
|
||||
// SAFETY: The `handle` field is valid for all possible byte values, so reading from the
|
||||
// union is okay.
|
||||
let handle = unsafe { tr.transaction_data.target.handle };
|
||||
let node_ref = self.process.get_transaction_node(handle)?;
|
||||
fn oneway_transaction_inner(self: &Arc<Self>, info: &mut TransactionInfo) -> BinderResult {
|
||||
let node_ref = self.process.get_transaction_node(info.target_handle)?;
|
||||
info.to_pid = node_ref.node.owner.task.pid();
|
||||
security::binder_transaction(&self.process.cred, &node_ref.node.owner.cred)?;
|
||||
let transaction = Transaction::new(node_ref, None, self, tr)?;
|
||||
let code = if self.process.is_oneway_spam_detection_enabled()
|
||||
&& transaction.oneway_spam_detected
|
||||
{
|
||||
let transaction = Transaction::new(node_ref, None, self, info)?;
|
||||
let code = if self.process.is_oneway_spam_detection_enabled() && info.oneway_spam_suspect {
|
||||
BR_ONEWAY_SPAM_SUSPECT
|
||||
} else {
|
||||
BR_TRANSACTION_COMPLETE
|
||||
|
|
@ -1300,7 +1352,7 @@ fn oneway_transaction_inner(self: &Arc<Self>, tr: &BinderTransactionDataSg) -> B
|
|||
let list_completion = DTRWrap::arc_try_new(DeliverCode::new(code))?;
|
||||
let completion = list_completion.clone_arc();
|
||||
self.inner.lock().push_work(list_completion);
|
||||
match transaction.submit() {
|
||||
match transaction.submit(info) {
|
||||
Ok(()) => Ok(()),
|
||||
Err(err) => {
|
||||
completion.skip();
|
||||
|
|
@ -1318,32 +1370,12 @@ fn write(self: &Arc<Self>, req: &mut BinderWriteRead) -> Result {
|
|||
while reader.len() >= size_of::<u32>() && self.inner.lock().return_work.is_unused() {
|
||||
let before = reader.len();
|
||||
let cmd = reader.read::<u32>()?;
|
||||
crate::trace::trace_command(cmd);
|
||||
GLOBAL_STATS.inc_bc(cmd);
|
||||
self.process.stats.inc_bc(cmd);
|
||||
match cmd {
|
||||
BC_TRANSACTION => {
|
||||
let tr = reader.read::<BinderTransactionData>()?.with_buffers_size(0);
|
||||
if tr.transaction_data.flags & TF_ONE_WAY != 0 {
|
||||
self.transaction(&tr, Self::oneway_transaction_inner);
|
||||
} else {
|
||||
self.transaction(&tr, Self::transaction_inner);
|
||||
}
|
||||
}
|
||||
BC_TRANSACTION_SG => {
|
||||
let tr = reader.read::<BinderTransactionDataSg>()?;
|
||||
if tr.transaction_data.flags & TF_ONE_WAY != 0 {
|
||||
self.transaction(&tr, Self::oneway_transaction_inner);
|
||||
} else {
|
||||
self.transaction(&tr, Self::transaction_inner);
|
||||
}
|
||||
}
|
||||
BC_REPLY => {
|
||||
let tr = reader.read::<BinderTransactionData>()?.with_buffers_size(0);
|
||||
self.transaction(&tr, Self::reply_inner)
|
||||
}
|
||||
BC_REPLY_SG => {
|
||||
let tr = reader.read::<BinderTransactionDataSg>()?;
|
||||
self.transaction(&tr, Self::reply_inner)
|
||||
BC_TRANSACTION | BC_TRANSACTION_SG | BC_REPLY | BC_REPLY_SG => {
|
||||
self.transaction(cmd, &mut reader)?;
|
||||
}
|
||||
BC_FREE_BUFFER => {
|
||||
let buffer = self.process.buffer_get(reader.read()?);
|
||||
|
|
@ -1407,11 +1439,18 @@ fn read(self: &Arc<Self>, req: &mut BinderWriteRead, wait: bool) -> Result {
|
|||
UserSlice::new(UserPtr::from_addr(read_start as _), read_len as _).writer(),
|
||||
self,
|
||||
);
|
||||
let (in_pool, use_proc_queue) = {
|
||||
let (in_pool, has_transaction, thread_todo, use_proc_queue) = {
|
||||
let inner = self.inner.lock();
|
||||
(inner.is_looper(), inner.should_use_process_work_queue())
|
||||
(
|
||||
inner.is_looper(),
|
||||
inner.current_transaction.is_some(),
|
||||
!inner.work_list.is_empty(),
|
||||
inner.should_use_process_work_queue(),
|
||||
)
|
||||
};
|
||||
|
||||
crate::trace::trace_wait_for_work(use_proc_queue, has_transaction, thread_todo);
|
||||
|
||||
let getter = if use_proc_queue {
|
||||
Self::get_work
|
||||
} else {
|
||||
|
|
@ -1477,6 +1516,7 @@ pub(crate) fn write_read(self: &Arc<Self>, data: UserSlice, wait: bool) -> Resul
|
|||
let mut ret = Ok(());
|
||||
if req.write_size > 0 {
|
||||
ret = self.write(&mut req);
|
||||
crate::trace::trace_write_done(ret);
|
||||
if let Err(err) = ret {
|
||||
pr_warn!(
|
||||
"Write failure {:?} in pid:{}",
|
||||
|
|
@ -1493,6 +1533,7 @@ pub(crate) fn write_read(self: &Arc<Self>, data: UserSlice, wait: bool) -> Resul
|
|||
// Go through the work queue.
|
||||
if req.read_size > 0 {
|
||||
ret = self.read(&mut req, wait);
|
||||
crate::trace::trace_read_done(ret);
|
||||
if ret.is_err() && ret != Err(EINTR) {
|
||||
pr_warn!(
|
||||
"Read failure {:?} in pid:{}",
|
||||
|
|
|
|||
|
|
@ -5,13 +5,23 @@
|
|||
use crate::transaction::Transaction;
|
||||
|
||||
use kernel::bindings::{rust_binder_transaction, task_struct};
|
||||
use kernel::ffi::{c_uint, c_ulong};
|
||||
use kernel::error::Result;
|
||||
use kernel::ffi::{c_int, c_uint, c_ulong};
|
||||
use kernel::task::Task;
|
||||
use kernel::tracepoint::declare_trace;
|
||||
|
||||
declare_trace! {
|
||||
unsafe fn rust_binder_ioctl(cmd: c_uint, arg: c_ulong);
|
||||
unsafe fn rust_binder_transaction(reply: bool, t: rust_binder_transaction, thread: *mut task_struct);
|
||||
unsafe fn binder_ioctl(cmd: c_uint, arg: c_ulong);
|
||||
unsafe fn binder_ioctl_done(ret: c_int);
|
||||
unsafe fn binder_read_done(ret: c_int);
|
||||
unsafe fn binder_write_done(ret: c_int);
|
||||
unsafe fn binder_wait_for_work(proc_work: bool, transaction_stack: bool, thread_todo: bool);
|
||||
unsafe fn binder_transaction(reply: bool, t: rust_binder_transaction, thread: *mut task_struct);
|
||||
unsafe fn binder_transaction_received(t: rust_binder_transaction);
|
||||
unsafe fn binder_transaction_fd_send(t_debug_id: c_int, fd: c_int, offset: usize);
|
||||
unsafe fn binder_transaction_fd_recv(t_debug_id: c_int, fd: c_int, offset: usize);
|
||||
unsafe fn binder_command(cmd: u32);
|
||||
unsafe fn binder_return(ret: u32);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
@ -19,10 +29,40 @@ fn raw_transaction(t: &Transaction) -> rust_binder_transaction {
|
|||
t as *const Transaction as rust_binder_transaction
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn to_errno(ret: Result) -> i32 {
|
||||
match ret {
|
||||
Ok(()) => 0,
|
||||
Err(err) => err.to_errno(),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn trace_ioctl(cmd: u32, arg: usize) {
|
||||
// SAFETY: Always safe to call.
|
||||
unsafe { rust_binder_ioctl(cmd, arg as c_ulong) }
|
||||
unsafe { binder_ioctl(cmd, arg as c_ulong) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn trace_ioctl_done(ret: Result) {
|
||||
// SAFETY: Always safe to call.
|
||||
unsafe { binder_ioctl_done(to_errno(ret)) }
|
||||
}
|
||||
#[inline]
|
||||
pub(crate) fn trace_read_done(ret: Result) {
|
||||
// SAFETY: Always safe to call.
|
||||
unsafe { binder_read_done(to_errno(ret)) }
|
||||
}
|
||||
#[inline]
|
||||
pub(crate) fn trace_write_done(ret: Result) {
|
||||
// SAFETY: Always safe to call.
|
||||
unsafe { binder_write_done(to_errno(ret)) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn trace_wait_for_work(proc_work: bool, transaction_stack: bool, thread_todo: bool) {
|
||||
// SAFETY: Always safe to call.
|
||||
unsafe { binder_wait_for_work(proc_work, transaction_stack, thread_todo) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
@ -33,5 +73,33 @@ pub(crate) fn trace_transaction(reply: bool, t: &Transaction, thread: Option<&Ta
|
|||
};
|
||||
// SAFETY: The raw transaction is valid for the duration of this call. The thread pointer is
|
||||
// valid or null.
|
||||
unsafe { rust_binder_transaction(reply, raw_transaction(t), thread) }
|
||||
unsafe { binder_transaction(reply, raw_transaction(t), thread) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn trace_transaction_received(t: &Transaction) {
|
||||
// SAFETY: The raw transaction is valid for the duration of this call.
|
||||
unsafe { binder_transaction_received(raw_transaction(t)) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn trace_transaction_fd_send(t_debug_id: usize, fd: u32, offset: usize) {
|
||||
// SAFETY: This function is always safe to call.
|
||||
unsafe { binder_transaction_fd_send(t_debug_id as c_int, fd as c_int, offset) }
|
||||
}
|
||||
#[inline]
|
||||
pub(crate) fn trace_transaction_fd_recv(t_debug_id: usize, fd: u32, offset: usize) {
|
||||
// SAFETY: This function is always safe to call.
|
||||
unsafe { binder_transaction_fd_recv(t_debug_id as c_int, fd as c_int, offset) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn trace_command(cmd: u32) {
|
||||
// SAFETY: This function is always safe to call.
|
||||
unsafe { binder_command(cmd) }
|
||||
}
|
||||
#[inline]
|
||||
pub(crate) fn trace_return(ret: u32) {
|
||||
// SAFETY: This function is always safe to call.
|
||||
unsafe { binder_return(ret) }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
seq_print,
|
||||
sync::atomic::{ordering::Relaxed, Atomic},
|
||||
sync::{Arc, SpinLock},
|
||||
task::Kuid,
|
||||
task::{Kuid, Pid},
|
||||
time::{Instant, Monotonic},
|
||||
types::ScopeGuard,
|
||||
};
|
||||
|
|
@ -24,6 +24,33 @@
|
|||
BinderReturnWriter, DArc, DLArc, DTRWrap, DeliverToRead,
|
||||
};
|
||||
|
||||
#[derive(Zeroable)]
|
||||
pub(crate) struct TransactionInfo {
|
||||
pub(crate) from_pid: Pid,
|
||||
pub(crate) from_tid: Pid,
|
||||
pub(crate) to_pid: Pid,
|
||||
pub(crate) to_tid: Pid,
|
||||
pub(crate) code: u32,
|
||||
pub(crate) flags: u32,
|
||||
pub(crate) data_ptr: UserPtr,
|
||||
pub(crate) data_size: usize,
|
||||
pub(crate) offsets_ptr: UserPtr,
|
||||
pub(crate) offsets_size: usize,
|
||||
pub(crate) buffers_size: usize,
|
||||
pub(crate) target_handle: u32,
|
||||
pub(crate) errno: i32,
|
||||
pub(crate) reply: u32,
|
||||
pub(crate) oneway_spam_suspect: bool,
|
||||
pub(crate) is_reply: bool,
|
||||
}
|
||||
|
||||
impl TransactionInfo {
|
||||
#[inline]
|
||||
pub(crate) fn is_oneway(&self) -> bool {
|
||||
self.flags & TF_ONE_WAY != 0
|
||||
}
|
||||
}
|
||||
|
||||
use core::mem::offset_of;
|
||||
use kernel::bindings::rb_transaction_layout;
|
||||
pub(crate) const TRANSACTION_LAYOUT: rb_transaction_layout = rb_transaction_layout {
|
||||
|
|
@ -52,7 +79,6 @@ pub(crate) struct Transaction {
|
|||
data_address: usize,
|
||||
sender_euid: Kuid,
|
||||
txn_security_ctx_off: Option<usize>,
|
||||
pub(crate) oneway_spam_detected: bool,
|
||||
start_time: Instant<Monotonic>,
|
||||
}
|
||||
|
||||
|
|
@ -65,17 +91,16 @@ pub(crate) fn new(
|
|||
node_ref: NodeRef,
|
||||
from_parent: Option<DArc<Transaction>>,
|
||||
from: &Arc<Thread>,
|
||||
tr: &BinderTransactionDataSg,
|
||||
info: &mut TransactionInfo,
|
||||
) -> BinderResult<DLArc<Self>> {
|
||||
let debug_id = super::next_debug_id();
|
||||
let trd = &tr.transaction_data;
|
||||
let allow_fds = node_ref.node.flags & FLAT_BINDER_FLAG_ACCEPTS_FDS != 0;
|
||||
let txn_security_ctx = node_ref.node.flags & FLAT_BINDER_FLAG_TXN_SECURITY_CTX != 0;
|
||||
let mut txn_security_ctx_off = if txn_security_ctx { Some(0) } else { None };
|
||||
let to = node_ref.node.owner.clone();
|
||||
let mut alloc = match from.copy_transaction_data(
|
||||
to.clone(),
|
||||
tr,
|
||||
info,
|
||||
debug_id,
|
||||
allow_fds,
|
||||
txn_security_ctx_off.as_mut(),
|
||||
|
|
@ -88,15 +113,14 @@ pub(crate) fn new(
|
|||
return Err(err);
|
||||
}
|
||||
};
|
||||
let oneway_spam_detected = alloc.oneway_spam_detected;
|
||||
if trd.flags & TF_ONE_WAY != 0 {
|
||||
if info.is_oneway() {
|
||||
if from_parent.is_some() {
|
||||
pr_warn!("Oneway transaction should not be in a transaction stack.");
|
||||
return Err(EINVAL.into());
|
||||
}
|
||||
alloc.set_info_oneway_node(node_ref.node.clone());
|
||||
}
|
||||
if trd.flags & TF_CLEAR_BUF != 0 {
|
||||
if info.flags & TF_CLEAR_BUF != 0 {
|
||||
alloc.set_info_clear_on_drop();
|
||||
}
|
||||
let target_node = node_ref.node.clone();
|
||||
|
|
@ -107,18 +131,17 @@ pub(crate) fn new(
|
|||
debug_id,
|
||||
target_node: Some(target_node),
|
||||
from_parent,
|
||||
sender_euid: from.process.task.euid(),
|
||||
sender_euid: Kuid::current_euid(),
|
||||
from: from.clone(),
|
||||
to,
|
||||
code: trd.code,
|
||||
flags: trd.flags,
|
||||
data_size: trd.data_size as _,
|
||||
offsets_size: trd.offsets_size as _,
|
||||
code: info.code,
|
||||
flags: info.flags,
|
||||
data_size: info.data_size,
|
||||
offsets_size: info.offsets_size,
|
||||
data_address,
|
||||
allocation <- kernel::new_spinlock!(Some(alloc.success()), "Transaction::new"),
|
||||
is_outstanding: Atomic::new(false),
|
||||
txn_security_ctx_off,
|
||||
oneway_spam_detected,
|
||||
start_time: Instant::now(),
|
||||
}))?)
|
||||
}
|
||||
|
|
@ -126,39 +149,36 @@ pub(crate) fn new(
|
|||
pub(crate) fn new_reply(
|
||||
from: &Arc<Thread>,
|
||||
to: Arc<Process>,
|
||||
tr: &BinderTransactionDataSg,
|
||||
info: &mut TransactionInfo,
|
||||
allow_fds: bool,
|
||||
) -> BinderResult<DLArc<Self>> {
|
||||
let debug_id = super::next_debug_id();
|
||||
let trd = &tr.transaction_data;
|
||||
let mut alloc = match from.copy_transaction_data(to.clone(), tr, debug_id, allow_fds, None)
|
||||
{
|
||||
Ok(alloc) => alloc,
|
||||
Err(err) => {
|
||||
pr_warn!("Failure in copy_transaction_data: {:?}", err);
|
||||
return Err(err);
|
||||
}
|
||||
};
|
||||
let oneway_spam_detected = alloc.oneway_spam_detected;
|
||||
if trd.flags & TF_CLEAR_BUF != 0 {
|
||||
let mut alloc =
|
||||
match from.copy_transaction_data(to.clone(), info, debug_id, allow_fds, None) {
|
||||
Ok(alloc) => alloc,
|
||||
Err(err) => {
|
||||
pr_warn!("Failure in copy_transaction_data: {:?}", err);
|
||||
return Err(err);
|
||||
}
|
||||
};
|
||||
if info.flags & TF_CLEAR_BUF != 0 {
|
||||
alloc.set_info_clear_on_drop();
|
||||
}
|
||||
Ok(DTRWrap::arc_pin_init(pin_init!(Transaction {
|
||||
debug_id,
|
||||
target_node: None,
|
||||
from_parent: None,
|
||||
sender_euid: from.process.task.euid(),
|
||||
sender_euid: Kuid::current_euid(),
|
||||
from: from.clone(),
|
||||
to,
|
||||
code: trd.code,
|
||||
flags: trd.flags,
|
||||
data_size: trd.data_size as _,
|
||||
offsets_size: trd.offsets_size as _,
|
||||
code: info.code,
|
||||
flags: info.flags,
|
||||
data_size: info.data_size,
|
||||
offsets_size: info.offsets_size,
|
||||
data_address: alloc.ptr,
|
||||
allocation <- kernel::new_spinlock!(Some(alloc.success()), "Transaction::new"),
|
||||
is_outstanding: Atomic::new(false),
|
||||
txn_security_ctx_off: None,
|
||||
oneway_spam_detected,
|
||||
start_time: Instant::now(),
|
||||
}))?)
|
||||
}
|
||||
|
|
@ -248,7 +268,7 @@ fn drop_outstanding_txn(&self) {
|
|||
/// stack, otherwise uses the destination process.
|
||||
///
|
||||
/// Not used for replies.
|
||||
pub(crate) fn submit(self: DLArc<Self>) -> BinderResult {
|
||||
pub(crate) fn submit(self: DLArc<Self>, info: &mut TransactionInfo) -> BinderResult {
|
||||
// Defined before `process_inner` so that the destructor runs after releasing the lock.
|
||||
let mut _t_outdated;
|
||||
|
||||
|
|
@ -298,6 +318,7 @@ pub(crate) fn submit(self: DLArc<Self>) -> BinderResult {
|
|||
}
|
||||
|
||||
let res = if let Some(thread) = self.find_target_thread() {
|
||||
info.to_tid = thread.id;
|
||||
crate::trace::trace_transaction(false, &self, Some(&thread.task));
|
||||
match thread.push_work(self) {
|
||||
PushWorkRes::Ok => Ok(()),
|
||||
|
|
@ -430,6 +451,8 @@ fn do_work(
|
|||
|
||||
self.drop_outstanding_txn();
|
||||
|
||||
crate::trace::trace_transaction_received(&self);
|
||||
|
||||
// When this is not a reply and not a oneway transaction, update `current_transaction`. If
|
||||
// it's a reply, `current_transaction` has already been updated appropriately.
|
||||
if self.target_node.is_some() && tr_sec.transaction_data.flags & TF_ONE_WAY == 0 {
|
||||
|
|
|
|||
|
|
@ -367,7 +367,7 @@ static void mhi_ep_read_completion(struct mhi_ep_buf_info *buf_info)
|
|||
ret = mhi_ep_send_completion_event(mhi_cntrl, ring, el,
|
||||
MHI_TRE_DATA_GET_LEN(el),
|
||||
MHI_EV_CC_EOB);
|
||||
if (ret < 0) {
|
||||
if (ret) {
|
||||
dev_err(&mhi_chan->mhi_dev->dev,
|
||||
"Error sending transfer compl. event\n");
|
||||
goto err_free_tre_buf;
|
||||
|
|
@ -383,7 +383,7 @@ static void mhi_ep_read_completion(struct mhi_ep_buf_info *buf_info)
|
|||
ret = mhi_ep_send_completion_event(mhi_cntrl, ring, el,
|
||||
MHI_TRE_DATA_GET_LEN(el),
|
||||
MHI_EV_CC_EOT);
|
||||
if (ret < 0) {
|
||||
if (ret) {
|
||||
dev_err(&mhi_chan->mhi_dev->dev,
|
||||
"Error sending transfer compl. event\n");
|
||||
goto err_free_tre_buf;
|
||||
|
|
@ -449,7 +449,7 @@ static int mhi_ep_read_channel(struct mhi_ep_cntrl *mhi_cntrl,
|
|||
|
||||
dev_dbg(dev, "Reading %zd bytes from channel (%u)\n", tr_len, ring->ch_id);
|
||||
ret = mhi_cntrl->read_async(mhi_cntrl, &buf_info);
|
||||
if (ret < 0) {
|
||||
if (ret) {
|
||||
dev_err(&mhi_chan->mhi_dev->dev, "Error reading from channel\n");
|
||||
goto err_free_buf_addr;
|
||||
}
|
||||
|
|
@ -494,7 +494,7 @@ static int mhi_ep_process_ch_ring(struct mhi_ep_ring *ring)
|
|||
} else {
|
||||
/* UL channel */
|
||||
ret = mhi_ep_read_channel(mhi_cntrl, ring);
|
||||
if (ret < 0) {
|
||||
if (ret) {
|
||||
dev_err(&mhi_chan->mhi_dev->dev, "Failed to read channel\n");
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -591,7 +591,7 @@ int mhi_ep_queue_skb(struct mhi_ep_device *mhi_dev, struct sk_buff *skb)
|
|||
|
||||
dev_dbg(dev, "Writing %zd bytes to channel (%u)\n", tr_len, ring->ch_id);
|
||||
ret = mhi_cntrl->write_async(mhi_cntrl, &buf_info);
|
||||
if (ret < 0) {
|
||||
if (ret) {
|
||||
dev_err(dev, "Error writing to the channel\n");
|
||||
goto err_exit;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ static int __mhi_ep_cache_ring(struct mhi_ep_ring *ring, size_t end)
|
|||
buf_info.dev_addr = &ring->ring_cache[start];
|
||||
|
||||
ret = mhi_cntrl->read_sync(mhi_cntrl, &buf_info);
|
||||
if (ret < 0)
|
||||
if (ret)
|
||||
return ret;
|
||||
} else {
|
||||
buf_info.size = (ring->ring_size - start) * sizeof(struct mhi_ring_element);
|
||||
|
|
@ -57,7 +57,7 @@ static int __mhi_ep_cache_ring(struct mhi_ep_ring *ring, size_t end)
|
|||
buf_info.dev_addr = &ring->ring_cache[start];
|
||||
|
||||
ret = mhi_cntrl->read_sync(mhi_cntrl, &buf_info);
|
||||
if (ret < 0)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (end) {
|
||||
|
|
@ -66,7 +66,7 @@ static int __mhi_ep_cache_ring(struct mhi_ep_ring *ring, size_t end)
|
|||
buf_info.size = end * sizeof(struct mhi_ring_element);
|
||||
|
||||
ret = mhi_cntrl->read_sync(mhi_cntrl, &buf_info);
|
||||
if (ret < 0)
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -308,7 +308,6 @@ static void mhi_free_bhi_buffer(struct mhi_controller *mhi_cntrl,
|
|||
struct mhi_buf *mhi_buf = image_info->mhi_buf;
|
||||
|
||||
dma_free_coherent(mhi_cntrl->cntrl_dev, mhi_buf->len, mhi_buf->buf, mhi_buf->dma_addr);
|
||||
kfree(image_info->mhi_buf);
|
||||
kfree(image_info);
|
||||
}
|
||||
|
||||
|
|
@ -322,7 +321,6 @@ void mhi_free_bhie_table(struct mhi_controller *mhi_cntrl,
|
|||
dma_free_coherent(mhi_cntrl->cntrl_dev, mhi_buf->len,
|
||||
mhi_buf->buf, mhi_buf->dma_addr);
|
||||
|
||||
kfree(image_info->mhi_buf);
|
||||
kfree(image_info);
|
||||
}
|
||||
|
||||
|
|
@ -333,15 +331,10 @@ static int mhi_alloc_bhi_buffer(struct mhi_controller *mhi_cntrl,
|
|||
struct image_info *img_info;
|
||||
struct mhi_buf *mhi_buf;
|
||||
|
||||
img_info = kzalloc_obj(*img_info);
|
||||
img_info = kzalloc_flex(*img_info, mhi_buf, 1);
|
||||
if (!img_info)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Allocate memory for entry */
|
||||
img_info->mhi_buf = kzalloc_obj(*img_info->mhi_buf);
|
||||
if (!img_info->mhi_buf)
|
||||
goto error_alloc_mhi_buf;
|
||||
|
||||
/* Allocate and populate vector table */
|
||||
mhi_buf = img_info->mhi_buf;
|
||||
|
||||
|
|
@ -358,8 +351,6 @@ static int mhi_alloc_bhi_buffer(struct mhi_controller *mhi_cntrl,
|
|||
return 0;
|
||||
|
||||
error_alloc_segment:
|
||||
kfree(mhi_buf);
|
||||
error_alloc_mhi_buf:
|
||||
kfree(img_info);
|
||||
|
||||
return -ENOMEM;
|
||||
|
|
@ -375,14 +366,11 @@ int mhi_alloc_bhie_table(struct mhi_controller *mhi_cntrl,
|
|||
struct image_info *img_info;
|
||||
struct mhi_buf *mhi_buf;
|
||||
|
||||
img_info = kzalloc_obj(*img_info);
|
||||
img_info = kzalloc_flex(*img_info, mhi_buf, segments);
|
||||
if (!img_info)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Allocate memory for entries */
|
||||
img_info->mhi_buf = kzalloc_objs(*img_info->mhi_buf, segments);
|
||||
if (!img_info->mhi_buf)
|
||||
goto error_alloc_mhi_buf;
|
||||
img_info->entries = segments;
|
||||
|
||||
/* Allocate and populate vector table */
|
||||
mhi_buf = img_info->mhi_buf;
|
||||
|
|
@ -402,7 +390,6 @@ int mhi_alloc_bhie_table(struct mhi_controller *mhi_cntrl,
|
|||
}
|
||||
|
||||
img_info->bhi_vec = img_info->mhi_buf[segments - 1].buf;
|
||||
img_info->entries = segments;
|
||||
*image_info = img_info;
|
||||
|
||||
return 0;
|
||||
|
|
@ -411,9 +398,6 @@ int mhi_alloc_bhie_table(struct mhi_controller *mhi_cntrl,
|
|||
for (--i, --mhi_buf; i >= 0; i--, mhi_buf--)
|
||||
dma_free_coherent(mhi_cntrl->cntrl_dev, mhi_buf->len,
|
||||
mhi_buf->buf, mhi_buf->dma_addr);
|
||||
kfree(img_info->mhi_buf);
|
||||
|
||||
error_alloc_mhi_buf:
|
||||
kfree(img_info);
|
||||
|
||||
return -ENOMEM;
|
||||
|
|
|
|||
|
|
@ -253,6 +253,13 @@ static const struct mhi_channel_config mhi_qcom_qdu100_channels[] = {
|
|||
MHI_CHANNEL_CONFIG_DL(41, "MHI_PHC", 32, 4),
|
||||
MHI_CHANNEL_CONFIG_UL(46, "IP_SW0", 256, 5),
|
||||
MHI_CHANNEL_CONFIG_DL(47, "IP_SW0", 256, 5),
|
||||
MHI_CHANNEL_CONFIG_UL(48, "IP_SW1", 256, 6),
|
||||
MHI_CHANNEL_CONFIG_DL(49, "IP_SW1", 256, 6),
|
||||
MHI_CHANNEL_CONFIG_UL(50, "IP_ETH0", 256, 7),
|
||||
MHI_CHANNEL_CONFIG_DL(51, "IP_ETH0", 256, 7),
|
||||
MHI_CHANNEL_CONFIG_UL(52, "IP_ETH1", 256, 8),
|
||||
MHI_CHANNEL_CONFIG_DL(53, "IP_ETH1", 256, 8),
|
||||
|
||||
};
|
||||
|
||||
static struct mhi_event_config mhi_qcom_qdu100_events[] = {
|
||||
|
|
@ -268,6 +275,7 @@ static struct mhi_event_config mhi_qcom_qdu100_events[] = {
|
|||
MHI_EVENT_CONFIG_SW_DATA(5, 512),
|
||||
MHI_EVENT_CONFIG_SW_DATA(6, 512),
|
||||
MHI_EVENT_CONFIG_SW_DATA(7, 512),
|
||||
MHI_EVENT_CONFIG_SW_DATA(8, 512),
|
||||
};
|
||||
|
||||
static const struct mhi_controller_config mhi_qcom_qdu100_config = {
|
||||
|
|
@ -407,6 +415,16 @@ static const struct mhi_pci_dev_info mhi_qcom_sdx55_info = {
|
|||
.sideband_wake = false,
|
||||
};
|
||||
|
||||
static const struct mhi_pci_dev_info mhi_qcom_sdx35_info = {
|
||||
.name = "qcom-sdx35m",
|
||||
.config = &modem_qcom_v2_mhiv_config,
|
||||
.bar_num = MHI_PCI_DEFAULT_BAR_NUM,
|
||||
.dma_data_width = 32,
|
||||
.mru_default = 32768,
|
||||
.sideband_wake = false,
|
||||
.edl_trigger = true,
|
||||
};
|
||||
|
||||
static const struct mhi_pci_dev_info mhi_qcom_sdx24_info = {
|
||||
.name = "qcom-sdx24",
|
||||
.edl = "qcom/prog_firehose_sdx24.mbn",
|
||||
|
|
@ -788,6 +806,8 @@ static const struct mhi_channel_config mhi_telit_fn990_channels[] = {
|
|||
MHI_CHANNEL_CONFIG_DL(33, "DUN", 32, 0),
|
||||
MHI_CHANNEL_CONFIG_UL(92, "DUN2", 32, 1),
|
||||
MHI_CHANNEL_CONFIG_DL(93, "DUN2", 32, 1),
|
||||
MHI_CHANNEL_CONFIG_UL(94, "NMEA", 32, 1),
|
||||
MHI_CHANNEL_CONFIG_DL(95, "NMEA", 32, 1),
|
||||
MHI_CHANNEL_CONFIG_HW_UL(100, "IP_HW0_MBIM", 128, 2),
|
||||
MHI_CHANNEL_CONFIG_HW_DL(101, "IP_HW0_MBIM", 128, 3),
|
||||
};
|
||||
|
|
@ -839,6 +859,8 @@ static const struct mhi_channel_config mhi_telit_fn920c04_channels[] = {
|
|||
MHI_CHANNEL_CONFIG_DL_FP(35, "FIREHOSE", 32, 0),
|
||||
MHI_CHANNEL_CONFIG_UL(92, "DUN2", 32, 1),
|
||||
MHI_CHANNEL_CONFIG_DL(93, "DUN2", 32, 1),
|
||||
MHI_CHANNEL_CONFIG_UL(94, "NMEA", 32, 1),
|
||||
MHI_CHANNEL_CONFIG_DL(95, "NMEA", 32, 1),
|
||||
MHI_CHANNEL_CONFIG_HW_UL(100, "IP_HW0", 128, 2),
|
||||
MHI_CHANNEL_CONFIG_HW_DL(101, "IP_HW0", 128, 3),
|
||||
};
|
||||
|
|
@ -882,6 +904,16 @@ static const struct mhi_pci_dev_info mhi_telit_fe990b40_info = {
|
|||
.edl_trigger = true,
|
||||
};
|
||||
|
||||
static const struct mhi_pci_dev_info mhi_telit_fe912c04_info = {
|
||||
.name = "telit-fe912c04",
|
||||
.config = &modem_telit_fn920c04_config,
|
||||
.bar_num = MHI_PCI_DEFAULT_BAR_NUM,
|
||||
.dma_data_width = 32,
|
||||
.sideband_wake = false,
|
||||
.mru_default = 32768,
|
||||
.edl_trigger = true,
|
||||
};
|
||||
|
||||
static const struct mhi_pci_dev_info mhi_netprisma_lcur57_info = {
|
||||
.name = "netprisma-lcur57",
|
||||
.edl = "qcom/prog_firehose_sdx24.mbn",
|
||||
|
|
@ -909,6 +941,11 @@ static const struct pci_device_id mhi_pci_id_table[] = {
|
|||
/* Telit FN920C04 (sdx35) */
|
||||
{PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x011a, 0x1c5d, 0x2020),
|
||||
.driver_data = (kernel_ulong_t) &mhi_telit_fn920c04_info },
|
||||
/* Telit FE912C04 (sdx35) */
|
||||
{ PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x011a, 0x1c5d, 0x2045),
|
||||
.driver_data = (kernel_ulong_t) &mhi_telit_fe912c04_info },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_QCOM, 0x011a),
|
||||
.driver_data = (kernel_ulong_t) &mhi_qcom_sdx35_info },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_QCOM, 0x0304),
|
||||
.driver_data = (kernel_ulong_t) &mhi_qcom_sdx24_info },
|
||||
{ PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x0306, PCI_VENDOR_ID_QCOM, 0x010c),
|
||||
|
|
@ -1393,7 +1430,7 @@ static int mhi_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
|||
goto err_unregister;
|
||||
}
|
||||
|
||||
err = mhi_sync_power_up(mhi_cntrl);
|
||||
err = mhi_async_power_up(mhi_cntrl);
|
||||
if (err) {
|
||||
dev_err(&pdev->dev, "failed to power up MHI controller\n");
|
||||
goto err_unprepare;
|
||||
|
|
@ -1428,6 +1465,7 @@ static void mhi_pci_remove(struct pci_dev *pdev)
|
|||
struct mhi_pci_device *mhi_pdev = pci_get_drvdata(pdev);
|
||||
struct mhi_controller *mhi_cntrl = &mhi_pdev->mhi_cntrl;
|
||||
|
||||
pm_runtime_forbid(&pdev->dev);
|
||||
pci_disable_sriov(pdev);
|
||||
|
||||
if (pdev->is_physfn)
|
||||
|
|
|
|||
|
|
@ -323,18 +323,6 @@ int agp_try_unsupported_boot;
|
|||
EXPORT_SYMBOL(agp_off);
|
||||
EXPORT_SYMBOL(agp_try_unsupported_boot);
|
||||
|
||||
static int __init agp_init(void)
|
||||
{
|
||||
if (!agp_off)
|
||||
printk(KERN_INFO "Linux agpgart interface v%d.%d\n",
|
||||
AGPGART_VERSION_MAJOR, AGPGART_VERSION_MINOR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit agp_exit(void)
|
||||
{
|
||||
}
|
||||
|
||||
#ifndef MODULE
|
||||
static __init int agp_setup(char *s)
|
||||
{
|
||||
|
|
@ -351,7 +339,3 @@ MODULE_AUTHOR("Dave Jones, Jeff Hartmann");
|
|||
MODULE_DESCRIPTION("AGP GART driver");
|
||||
MODULE_LICENSE("GPL and additional rights");
|
||||
MODULE_ALIAS_MISCDEV(AGPGART_MINOR);
|
||||
|
||||
module_init(agp_init);
|
||||
module_exit(agp_exit);
|
||||
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
#include <linux/io.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/hpet.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <asm/current.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/div64.h>
|
||||
|
|
@ -973,8 +974,9 @@ static acpi_status hpet_resources(struct acpi_resource *res, void *data)
|
|||
return AE_OK;
|
||||
}
|
||||
|
||||
static int hpet_acpi_add(struct acpi_device *device)
|
||||
static int hpet_acpi_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct acpi_device *device = ACPI_COMPANION(&pdev->dev);
|
||||
acpi_status result;
|
||||
struct hpet_data data;
|
||||
|
||||
|
|
@ -1002,12 +1004,12 @@ static const struct acpi_device_id hpet_device_ids[] = {
|
|||
{"", 0},
|
||||
};
|
||||
|
||||
static struct acpi_driver hpet_acpi_driver = {
|
||||
.name = "hpet",
|
||||
.ids = hpet_device_ids,
|
||||
.ops = {
|
||||
.add = hpet_acpi_add,
|
||||
},
|
||||
static struct platform_driver hpet_acpi_driver = {
|
||||
.probe = hpet_acpi_probe,
|
||||
.driver = {
|
||||
.name = "hpet_acpi",
|
||||
.acpi_match_table = hpet_device_ids,
|
||||
},
|
||||
};
|
||||
|
||||
static struct miscdevice hpet_misc = { HPET_MINOR, "hpet", &hpet_fops };
|
||||
|
|
@ -1022,7 +1024,7 @@ static int __init hpet_init(void)
|
|||
|
||||
sysctl_header = register_sysctl("dev/hpet", hpet_table);
|
||||
|
||||
result = acpi_bus_register_driver(&hpet_acpi_driver);
|
||||
result = platform_driver_register(&hpet_acpi_driver);
|
||||
if (result < 0) {
|
||||
unregister_sysctl_table(sysctl_header);
|
||||
misc_deregister(&hpet_misc);
|
||||
|
|
|
|||
|
|
@ -121,20 +121,6 @@ EXPORT_SYMBOL(nsc_gpio_write);
|
|||
EXPORT_SYMBOL(nsc_gpio_read);
|
||||
EXPORT_SYMBOL(nsc_gpio_dump);
|
||||
|
||||
static int __init nsc_gpio_init(void)
|
||||
{
|
||||
printk(KERN_DEBUG NAME " initializing\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit nsc_gpio_cleanup(void)
|
||||
{
|
||||
printk(KERN_DEBUG NAME " cleanup\n");
|
||||
}
|
||||
|
||||
module_init(nsc_gpio_init);
|
||||
module_exit(nsc_gpio_cleanup);
|
||||
|
||||
MODULE_AUTHOR("Jim Cromie <jim.cromie@gmail.com>");
|
||||
MODULE_DESCRIPTION("NatSemi GPIO Common Methods");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
|||
|
|
@ -1115,15 +1115,17 @@ static int sonypi_disable(void)
|
|||
}
|
||||
|
||||
#ifdef CONFIG_ACPI
|
||||
static int sonypi_acpi_add(struct acpi_device *device)
|
||||
static int sonypi_acpi_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct acpi_device *device = ACPI_COMPANION(&pdev->dev);
|
||||
|
||||
sonypi_acpi_device = device;
|
||||
strcpy(acpi_device_name(device), "Sony laptop hotkeys");
|
||||
strcpy(acpi_device_class(device), "sony/hotkey");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sonypi_acpi_remove(struct acpi_device *device)
|
||||
static void sonypi_acpi_remove(struct platform_device *pdev)
|
||||
{
|
||||
sonypi_acpi_device = NULL;
|
||||
}
|
||||
|
|
@ -1133,13 +1135,12 @@ static const struct acpi_device_id sonypi_device_ids[] = {
|
|||
{"", 0},
|
||||
};
|
||||
|
||||
static struct acpi_driver sonypi_acpi_driver = {
|
||||
.name = "sonypi",
|
||||
.class = "hkey",
|
||||
.ids = sonypi_device_ids,
|
||||
.ops = {
|
||||
.add = sonypi_acpi_add,
|
||||
.remove = sonypi_acpi_remove,
|
||||
static struct platform_driver sonypi_acpi_driver = {
|
||||
.probe = sonypi_acpi_probe,
|
||||
.remove = sonypi_acpi_remove,
|
||||
.driver = {
|
||||
.name = "sonypi_acpi",
|
||||
.acpi_match_table = sonypi_device_ids,
|
||||
},
|
||||
};
|
||||
#endif
|
||||
|
|
@ -1518,8 +1519,8 @@ static int __init sonypi_init(void)
|
|||
goto err_free_device;
|
||||
|
||||
#ifdef CONFIG_ACPI
|
||||
if (acpi_bus_register_driver(&sonypi_acpi_driver) >= 0)
|
||||
acpi_driver_registered = 1;
|
||||
error = platform_driver_register(&sonypi_acpi_driver);
|
||||
acpi_driver_registered = !error;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
|
|
@ -1535,7 +1536,7 @@ static void __exit sonypi_exit(void)
|
|||
{
|
||||
#ifdef CONFIG_ACPI
|
||||
if (acpi_driver_registered)
|
||||
acpi_bus_unregister_driver(&sonypi_acpi_driver);
|
||||
platform_driver_unregister(&sonypi_acpi_driver);
|
||||
#endif
|
||||
platform_device_unregister(sonypi_platform_device);
|
||||
platform_driver_unregister(&sonypi_driver);
|
||||
|
|
|
|||
|
|
@ -405,20 +405,20 @@ config COMEDI_FL512
|
|||
called fl512.
|
||||
|
||||
config COMEDI_AIO_AIO12_8
|
||||
tristate "I/O Products PC/104 AIO12-8 Analog I/O Board support"
|
||||
tristate "ACCES I/O Products PC/104 AIO12-8 Analog I/O Board support"
|
||||
select COMEDI_8254
|
||||
select COMEDI_8255
|
||||
help
|
||||
Enable support for I/O Products PC/104 AIO12-8 Analog I/O Board
|
||||
Enable support for ACCES I/O Products PC/104 AIO12-8 Analog I/O Board
|
||||
|
||||
To compile this driver as a module, choose M here: the module will be
|
||||
called aio_aio12_8.
|
||||
|
||||
config COMEDI_AIO_IIRO_16
|
||||
tristate "I/O Products PC/104 IIRO16 Board support"
|
||||
tristate "ACCES I/O Products PC/104 IIRO16 Board support"
|
||||
help
|
||||
Enable support for I/O Products PC/104 IIRO16 Relay And Isolated
|
||||
Input Board
|
||||
Enable support for ACCES I/O Products PC/104 IIRO16 Relay And
|
||||
Isolated Input Board
|
||||
|
||||
To compile this driver as a module, choose M here: the module will be
|
||||
called aio_iiro_16.
|
||||
|
|
|
|||
|
|
@ -211,17 +211,6 @@ void comedi_pci_driver_unregister(struct comedi_driver *comedi_driver,
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(comedi_pci_driver_unregister);
|
||||
|
||||
static int __init comedi_pci_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
module_init(comedi_pci_init);
|
||||
|
||||
static void __exit comedi_pci_exit(void)
|
||||
{
|
||||
}
|
||||
module_exit(comedi_pci_exit);
|
||||
|
||||
MODULE_AUTHOR("https://www.comedi.org");
|
||||
MODULE_DESCRIPTION("Comedi PCI interface module");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
|||
|
|
@ -192,17 +192,6 @@ void comedi_pcmcia_driver_unregister(struct comedi_driver *comedi_driver,
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(comedi_pcmcia_driver_unregister);
|
||||
|
||||
static int __init comedi_pcmcia_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
module_init(comedi_pcmcia_init);
|
||||
|
||||
static void __exit comedi_pcmcia_exit(void)
|
||||
{
|
||||
}
|
||||
module_exit(comedi_pcmcia_exit);
|
||||
|
||||
MODULE_AUTHOR("https://www.comedi.org");
|
||||
MODULE_DESCRIPTION("Comedi PCMCIA interface module");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
|||
|
|
@ -134,17 +134,6 @@ void comedi_usb_driver_unregister(struct comedi_driver *comedi_driver,
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(comedi_usb_driver_unregister);
|
||||
|
||||
static int __init comedi_usb_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
module_init(comedi_usb_init);
|
||||
|
||||
static void __exit comedi_usb_exit(void)
|
||||
{
|
||||
}
|
||||
module_exit(comedi_usb_exit);
|
||||
|
||||
MODULE_AUTHOR("https://www.comedi.org");
|
||||
MODULE_DESCRIPTION("Comedi USB interface module");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
|||
|
|
@ -933,19 +933,24 @@ int comedi_load_firmware(struct comedi_device *dev,
|
|||
EXPORT_SYMBOL_GPL(comedi_load_firmware);
|
||||
|
||||
/**
|
||||
* __comedi_request_region() - Request an I/O region for a legacy driver
|
||||
* __comedi_check_request_region() - Request an I/O region for a legacy driver
|
||||
* @dev: COMEDI device.
|
||||
* @start: Base address of the I/O region.
|
||||
* @len: Length of the I/O region.
|
||||
* @minstart: Minimum allowed start address of region.
|
||||
* @maxend: Maximum allowed region end address of region.
|
||||
* @minalign: Required alignment for base address.
|
||||
*
|
||||
* Requests the specified I/O port region which must start at a non-zero
|
||||
* address.
|
||||
* address, must fall within specified bounds, and must be correctly aligned.
|
||||
*
|
||||
* Returns 0 on success, -EINVAL if @start is 0, or -EIO if the request
|
||||
* fails.
|
||||
*/
|
||||
int __comedi_request_region(struct comedi_device *dev,
|
||||
unsigned long start, unsigned long len)
|
||||
int __comedi_check_request_region(struct comedi_device *dev,
|
||||
unsigned long start, unsigned long len,
|
||||
unsigned long minstart, unsigned long maxend,
|
||||
unsigned long minalign)
|
||||
{
|
||||
if (!start) {
|
||||
dev_warn(dev->class_dev,
|
||||
|
|
@ -954,6 +959,19 @@ int __comedi_request_region(struct comedi_device *dev,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (start < minstart || start > maxend || maxend - start < len - 1) {
|
||||
dev_warn(dev->class_dev,
|
||||
"%s: I/O base address or length out of range\n",
|
||||
dev->board_name);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (!IS_ALIGNED(start, minalign)) {
|
||||
dev_warn(dev->class_dev,
|
||||
"%s: I/O base address not correctly aligned\n",
|
||||
dev->board_name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!request_region(start, len, dev->board_name)) {
|
||||
dev_warn(dev->class_dev, "%s: I/O port conflict (%#lx,%lu)\n",
|
||||
dev->board_name, start, len);
|
||||
|
|
@ -962,16 +980,19 @@ int __comedi_request_region(struct comedi_device *dev,
|
|||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(__comedi_request_region);
|
||||
EXPORT_SYMBOL_GPL(__comedi_check_request_region);
|
||||
|
||||
/**
|
||||
* comedi_request_region() - Request an I/O region for a legacy driver
|
||||
* comedi_check_request_region() - Request an I/O region for a legacy driver
|
||||
* @dev: COMEDI device.
|
||||
* @start: Base address of the I/O region.
|
||||
* @len: Length of the I/O region.
|
||||
* @minstart: Minimum allowed start address of region.
|
||||
* @maxend: Maximum allowed region end address of region.
|
||||
* @minalign: Required alignment for base address.
|
||||
*
|
||||
* Requests the specified I/O port region which must start at a non-zero
|
||||
* address.
|
||||
* address, must fall within specified bounds, and must be correctly aligned.
|
||||
*
|
||||
* On success, @dev->iobase is set to the base address of the region and
|
||||
* @dev->iolen is set to its length.
|
||||
|
|
@ -979,12 +1000,15 @@ EXPORT_SYMBOL_GPL(__comedi_request_region);
|
|||
* Returns 0 on success, -EINVAL if @start is 0, or -EIO if the request
|
||||
* fails.
|
||||
*/
|
||||
int comedi_request_region(struct comedi_device *dev,
|
||||
unsigned long start, unsigned long len)
|
||||
int comedi_check_request_region(struct comedi_device *dev,
|
||||
unsigned long start, unsigned long len,
|
||||
unsigned long minstart, unsigned long maxend,
|
||||
unsigned long minalign)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = __comedi_request_region(dev, start, len);
|
||||
ret = __comedi_check_request_region(dev, start, len, minstart, maxend,
|
||||
minalign);
|
||||
if (ret == 0) {
|
||||
dev->iobase = start;
|
||||
dev->iolen = len;
|
||||
|
|
@ -992,7 +1016,7 @@ int comedi_request_region(struct comedi_device *dev,
|
|||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(comedi_request_region);
|
||||
EXPORT_SYMBOL_GPL(comedi_check_request_region);
|
||||
|
||||
/**
|
||||
* comedi_legacy_detach() - A generic (*detach) function for legacy drivers
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ static int dev_8255_attach(struct comedi_device *dev,
|
|||
struct comedi_devconfig *it)
|
||||
{
|
||||
struct comedi_subdevice *s;
|
||||
unsigned long iobase;
|
||||
unsigned int iobase;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
|
|
@ -70,13 +70,15 @@ static int dev_8255_attach(struct comedi_device *dev,
|
|||
iobase = it->options[i];
|
||||
|
||||
/*
|
||||
* __comedi_request_region() does not set dev->iobase.
|
||||
* __comedi_check_request_region() does not set dev->iobase.
|
||||
*
|
||||
* For 8255 devices that are manually attached using
|
||||
* comedi_config, the 'iobase' is the actual I/O port
|
||||
* base address of the chip.
|
||||
* base address of the chip. It should be aligned on
|
||||
* a 4-byte boundary.
|
||||
*/
|
||||
ret = __comedi_request_region(dev, iobase, I8255_SIZE);
|
||||
ret = __comedi_check_request_region(dev, iobase, I8255_SIZE,
|
||||
0, UINT_MAX, 4);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = subdev_8255_io_init(dev, s, iobase);
|
||||
|
|
|
|||
|
|
@ -124,17 +124,6 @@ int addi_watchdog_init(struct comedi_subdevice *s, unsigned long iobase)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(addi_watchdog_init);
|
||||
|
||||
static int __init addi_watchdog_module_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
module_init(addi_watchdog_module_init);
|
||||
|
||||
static void __exit addi_watchdog_module_exit(void)
|
||||
{
|
||||
}
|
||||
module_exit(addi_watchdog_module_exit);
|
||||
|
||||
MODULE_DESCRIPTION("ADDI-DATA Watchdog subdevice");
|
||||
MODULE_AUTHOR("H Hartley Sweeten <hsweeten@visionengravers.com>");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
|||
|
|
@ -179,7 +179,8 @@ static int adq12b_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
|||
struct comedi_subdevice *s;
|
||||
int ret;
|
||||
|
||||
ret = comedi_request_region(dev, it->options[0], 0x10);
|
||||
ret = comedi_check_request_region(dev, it->options[0], 0x10,
|
||||
0x300, 0x3af, 0x20);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,17 +1,17 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* aio_aio12_8.c
|
||||
* Driver for Access I/O Products PC-104 AIO12-8 Analog I/O Board
|
||||
* Driver for ACCES I/O Products PC-104 AIO12-8 Analog I/O Board
|
||||
* Copyright (C) 2006 C&C Technologies, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Driver: aio_aio12_8
|
||||
* Description: Access I/O Products PC-104 AIO12-8 Analog I/O Board
|
||||
* Description: ACCES I/O Products PC-104 AIO12-8 Analog I/O Board
|
||||
* Author: Pablo Mejia <pablo.mejia@cctechnol.com>
|
||||
* Devices: [Access I/O] PC-104 AIO12-8 (aio_aio12_8),
|
||||
* [Access I/O] PC-104 AI12-8 (aio_ai12_8),
|
||||
* [Access I/O] PC-104 AO12-4 (aio_ao12_4)
|
||||
* Devices: [ACCES I/O] PC-104 AIO12-8 (aio_aio12_8),
|
||||
* [ACCES I/O] PC-104 AI12-8 (aio_ai12_8),
|
||||
* [ACCES I/O] PC-104 AO12-4 (aio_ao12_4)
|
||||
* Status: experimental
|
||||
*
|
||||
* Configuration Options:
|
||||
|
|
@ -202,7 +202,8 @@ static int aio_aio12_8_attach(struct comedi_device *dev,
|
|||
struct comedi_subdevice *s;
|
||||
int ret;
|
||||
|
||||
ret = comedi_request_region(dev, it->options[0], 32);
|
||||
ret = comedi_check_request_region(dev, it->options[0], 32,
|
||||
0x100, 0x3ff, 32);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
@ -272,5 +273,5 @@ static struct comedi_driver aio_aio12_8_driver = {
|
|||
module_comedi_driver(aio_aio12_8_driver);
|
||||
|
||||
MODULE_AUTHOR("Comedi https://www.comedi.org");
|
||||
MODULE_DESCRIPTION("Comedi driver for Access I/O AIO12-8 Analog I/O Board");
|
||||
MODULE_DESCRIPTION("Comedi driver for ACCES I/O AIO12-8 Analog I/O Board");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
|||
|
|
@ -1,15 +1,15 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* aio_iiro_16.c
|
||||
* Comedi driver for Access I/O Products 104-IIRO-16 board
|
||||
* Comedi driver for ACCES I/O Products 104-IIRO-16 board
|
||||
* Copyright (C) 2006 C&C Technologies, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Driver: aio_iiro_16
|
||||
* Description: Access I/O Products PC/104 Isolated Input/Relay Output Board
|
||||
* Description: ACCES I/O Products PC/104 Isolated Input/Relay Output Board
|
||||
* Author: Zachary Ware <zach.ware@cctechnol.com>
|
||||
* Devices: [Access I/O] 104-IIRO-16 (aio_iiro_16)
|
||||
* Devices: [ACCES I/O] 104-IIRO-16 (aio_iiro_16)
|
||||
* Status: experimental
|
||||
*
|
||||
* Configuration Options:
|
||||
|
|
@ -167,7 +167,8 @@ static int aio_iiro_16_attach(struct comedi_device *dev,
|
|||
struct comedi_subdevice *s;
|
||||
int ret;
|
||||
|
||||
ret = comedi_request_region(dev, it->options[0], 0x8);
|
||||
ret = comedi_check_request_region(dev, it->options[0], 0x8,
|
||||
0x100, 0x3ff, 0x8);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
@ -231,5 +232,5 @@ static struct comedi_driver aio_iiro_16_driver = {
|
|||
module_comedi_driver(aio_iiro_16_driver);
|
||||
|
||||
MODULE_AUTHOR("Comedi https://www.comedi.org");
|
||||
MODULE_DESCRIPTION("Comedi driver for Access I/O Products 104-IIRO-16 board");
|
||||
MODULE_DESCRIPTION("Comedi driver for ACCES I/O Products 104-IIRO-16 board");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
|||
|
|
@ -242,7 +242,8 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
|||
{
|
||||
int ret;
|
||||
|
||||
ret = comedi_request_region(dev, it->options[0], 0x20);
|
||||
ret = comedi_check_request_region(dev, it->options[0], 0x20,
|
||||
0, 0xfff, 0x20);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
|
|||
|
|
@ -901,17 +901,6 @@ int amplc_dio200_common_attach(struct comedi_device *dev, unsigned int irq,
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(amplc_dio200_common_attach);
|
||||
|
||||
static int __init amplc_dio200_common_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
module_init(amplc_dio200_common_init);
|
||||
|
||||
static void __exit amplc_dio200_common_exit(void)
|
||||
{
|
||||
}
|
||||
module_exit(amplc_dio200_common_exit);
|
||||
|
||||
MODULE_AUTHOR("Comedi https://www.comedi.org");
|
||||
MODULE_DESCRIPTION("Comedi helper for amplc_dio200 and amplc_dio200_pci");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
|||
|
|
@ -45,7 +45,8 @@ static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
|||
if (!devpriv)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = comedi_request_region(dev, it->options[0], 0x4);
|
||||
ret = comedi_check_request_region(dev, it->options[0], 0x4,
|
||||
0, 0xfff, 4);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
|
|||
|
|
@ -176,17 +176,6 @@ int amplc_pc236_common_attach(struct comedi_device *dev, unsigned long iobase,
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(amplc_pc236_common_attach);
|
||||
|
||||
static int __init amplc_pc236_common_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
module_init(amplc_pc236_common_init);
|
||||
|
||||
static void __exit amplc_pc236_common_exit(void)
|
||||
{
|
||||
}
|
||||
module_exit(amplc_pc236_common_exit);
|
||||
|
||||
MODULE_AUTHOR("Comedi https://www.comedi.org");
|
||||
MODULE_DESCRIPTION("Comedi helper for amplc_pc236 and amplc_pci236");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
|||
|
|
@ -61,7 +61,8 @@ static int pc263_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
|||
struct comedi_subdevice *s;
|
||||
int ret;
|
||||
|
||||
ret = comedi_request_region(dev, it->options[0], 0x2);
|
||||
ret = comedi_check_request_region(dev, it->options[0], 0x2,
|
||||
0, 0x7ff, 2);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
|
|||
|
|
@ -239,9 +239,11 @@ static int c6xdigio_attach(struct comedi_device *dev,
|
|||
struct comedi_devconfig *it)
|
||||
{
|
||||
struct comedi_subdevice *s;
|
||||
unsigned int iobase = it->options[0];
|
||||
int ret;
|
||||
|
||||
ret = comedi_request_region(dev, it->options[0], 0x03);
|
||||
ret = comedi_check_request_region(dev, iobase, 0x03,
|
||||
0, UINT_MAX, 4);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
|
|||
|
|
@ -724,17 +724,6 @@ struct comedi_8254 *comedi_8254_mm_alloc(void __iomem *mmio,
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(comedi_8254_mm_alloc);
|
||||
|
||||
static int __init comedi_8254_module_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
module_init(comedi_8254_module_init);
|
||||
|
||||
static void __exit comedi_8254_module_exit(void)
|
||||
{
|
||||
}
|
||||
module_exit(comedi_8254_module_exit);
|
||||
|
||||
MODULE_AUTHOR("H Hartley Sweeten <hsweeten@visionengravers.com>");
|
||||
MODULE_DESCRIPTION("Comedi: Generic 8254 timer/counter support");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
|||
|
|
@ -259,17 +259,6 @@ unsigned long subdev_8255_regbase(struct comedi_subdevice *s)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(subdev_8255_regbase);
|
||||
|
||||
static int __init comedi_8255_module_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
module_init(comedi_8255_module_init);
|
||||
|
||||
static void __exit comedi_8255_module_exit(void)
|
||||
{
|
||||
}
|
||||
module_exit(comedi_8255_module_exit);
|
||||
|
||||
MODULE_AUTHOR("Comedi https://www.comedi.org");
|
||||
MODULE_DESCRIPTION("Comedi: Generic 8255 digital I/O support");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
|||
|
|
@ -161,14 +161,10 @@ struct comedi_isadma *comedi_isadma_alloc(struct comedi_device *dev,
|
|||
if (n_desc < 1 || n_desc > 2)
|
||||
goto no_dma;
|
||||
|
||||
dma = kzalloc_obj(*dma);
|
||||
dma = kzalloc_flex(*dma, desc, n_desc);
|
||||
if (!dma)
|
||||
goto no_dma;
|
||||
|
||||
desc = kzalloc_objs(*desc, n_desc);
|
||||
if (!desc)
|
||||
goto no_dma;
|
||||
dma->desc = desc;
|
||||
dma->n_desc = n_desc;
|
||||
if (dev->hw_dev) {
|
||||
dma->dev = dev->hw_dev;
|
||||
|
|
@ -231,15 +227,12 @@ void comedi_isadma_free(struct comedi_isadma *dma)
|
|||
if (!dma)
|
||||
return;
|
||||
|
||||
if (dma->desc) {
|
||||
for (i = 0; i < dma->n_desc; i++) {
|
||||
desc = &dma->desc[i];
|
||||
if (desc->virt_addr)
|
||||
dma_free_coherent(dma->dev, desc->maxsize,
|
||||
desc->virt_addr,
|
||||
desc->hw_addr);
|
||||
}
|
||||
kfree(dma->desc);
|
||||
for (i = 0; i < dma->n_desc; i++) {
|
||||
desc = &dma->desc[i];
|
||||
if (desc->virt_addr)
|
||||
dma_free_coherent(dma->dev, desc->maxsize,
|
||||
desc->virt_addr,
|
||||
desc->hw_addr);
|
||||
}
|
||||
if (dma->chan2 && dma->chan2 != dma->chan)
|
||||
free_dma(dma->chan2);
|
||||
|
|
@ -249,17 +242,6 @@ void comedi_isadma_free(struct comedi_isadma *dma)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(comedi_isadma_free);
|
||||
|
||||
static int __init comedi_isadma_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
module_init(comedi_isadma_init);
|
||||
|
||||
static void __exit comedi_isadma_exit(void)
|
||||
{
|
||||
}
|
||||
module_exit(comedi_isadma_exit);
|
||||
|
||||
MODULE_AUTHOR("H Hartley Sweeten <hsweeten@visionengravers.com>");
|
||||
MODULE_DESCRIPTION("Comedi ISA DMA support");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
|||
|
|
@ -225,9 +225,11 @@ static int parport_attach(struct comedi_device *dev,
|
|||
struct comedi_devconfig *it)
|
||||
{
|
||||
struct comedi_subdevice *s;
|
||||
unsigned int iobase = it->options[0];
|
||||
int ret;
|
||||
|
||||
ret = comedi_request_region(dev, it->options[0], 0x03);
|
||||
ret = comedi_check_request_region(dev, iobase, 0x03,
|
||||
0, UINT_MAX, 4);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
|
|||
|
|
@ -103,7 +103,8 @@ static int dac02_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
|||
struct comedi_subdevice *s;
|
||||
int ret;
|
||||
|
||||
ret = comedi_request_region(dev, it->options[0], 0x08);
|
||||
ret = comedi_check_request_region(dev, it->options[0], 0x08,
|
||||
0x200, 0x3ff, 8);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
|
|||
|
|
@ -453,17 +453,6 @@ int das08_common_attach(struct comedi_device *dev, unsigned long iobase)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(das08_common_attach);
|
||||
|
||||
static int __init das08_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
module_init(das08_init);
|
||||
|
||||
static void __exit das08_exit(void)
|
||||
{
|
||||
}
|
||||
module_exit(das08_exit);
|
||||
|
||||
MODULE_AUTHOR("Comedi https://www.comedi.org");
|
||||
MODULE_DESCRIPTION("Comedi common DAS08 support module");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
|||
|
|
@ -167,7 +167,8 @@ static int das08_isa_attach(struct comedi_device *dev,
|
|||
if (!devpriv)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = comedi_request_region(dev, it->options[0], board->iosize);
|
||||
ret = comedi_check_request_region(dev, it->options[0], board->iosize,
|
||||
0, 0x3ff, board->iosize);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
|
|||
|
|
@ -1018,6 +1018,7 @@ static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
|||
const struct das16_board *board = dev->board_ptr;
|
||||
struct das16_private_struct *devpriv;
|
||||
struct comedi_subdevice *s;
|
||||
unsigned int iobase = it->options[0];
|
||||
unsigned int osc_base;
|
||||
unsigned int status;
|
||||
int ret;
|
||||
|
|
@ -1037,11 +1038,25 @@ static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
|||
devpriv->dev = dev;
|
||||
|
||||
if (board->size < 0x400) {
|
||||
ret = comedi_request_region(dev, it->options[0], board->size);
|
||||
unsigned int size = board->size;
|
||||
|
||||
if (size > 0x10 && (iobase & 0x10) != 0) {
|
||||
/*
|
||||
* The board has more than 0x10 registers and is
|
||||
* being placed on an odd 16-byte boundary. The
|
||||
* board has some jumpers to configure this mode,
|
||||
* disabling the 8255 at offset 0x10, so only 0x10
|
||||
* registers will need to be mapped in this mode.
|
||||
*/
|
||||
size = 0x10;
|
||||
}
|
||||
ret = comedi_check_request_region(dev, iobase, size,
|
||||
0, 0x3ff, 16);
|
||||
if (ret)
|
||||
return ret;
|
||||
} else {
|
||||
ret = comedi_request_region(dev, it->options[0], 0x10);
|
||||
ret = comedi_check_request_region(dev, iobase, 0x10,
|
||||
0, 0x3ff, 16);
|
||||
if (ret)
|
||||
return ret;
|
||||
/* Request an additional region for the 8255 */
|
||||
|
|
@ -1146,9 +1161,15 @@ static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
|||
/* 8255 Digital I/O subdevice */
|
||||
if (board->has_8255) {
|
||||
s = &dev->subdevices[4];
|
||||
ret = subdev_8255_io_init(dev, s, board->i8255_offset);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (board->i8255_offset == 0x10 && (dev->iobase & 0x10) != 0) {
|
||||
dev_info(dev->class_dev,
|
||||
"Disabling 8255 subdevice on unsupported base address\n");
|
||||
s->type = COMEDI_SUBD_UNUSED;
|
||||
} else {
|
||||
ret = subdev_8255_io_init(dev, s, board->i8255_offset);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
das16_reset(dev);
|
||||
|
|
|
|||
|
|
@ -511,7 +511,8 @@ static int das16m1_attach(struct comedi_device *dev,
|
|||
if (!devpriv)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = comedi_request_region(dev, it->options[0], 0x10);
|
||||
ret = comedi_check_request_region(dev, it->options[0], 0x10,
|
||||
0, 0x3ff, 16);
|
||||
if (ret)
|
||||
return ret;
|
||||
/* Request an additional region for the 8255 and 3rd 8254 */
|
||||
|
|
|
|||
|
|
@ -1172,7 +1172,8 @@ static int das1800_attach(struct comedi_device *dev,
|
|||
if (!devpriv)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = comedi_request_region(dev, it->options[0], DAS1800_SIZE);
|
||||
ret = comedi_check_request_region(dev, it->options[0], DAS1800_SIZE,
|
||||
0, 0x3ff, 16);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
|
|||
|
|
@ -560,7 +560,8 @@ static int das6402_attach(struct comedi_device *dev,
|
|||
if (!devpriv)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = comedi_request_region(dev, it->options[0], 0x10);
|
||||
ret = comedi_check_request_region(dev, it->options[0], 0x10,
|
||||
0, 0x3ff, 16);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
|
|||
|
|
@ -655,7 +655,8 @@ static int das800_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
|||
if (!devpriv)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = comedi_request_region(dev, it->options[0], 0x8);
|
||||
ret = comedi_check_request_region(dev, it->options[0], 0x8,
|
||||
0, 0x3ff, 8);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
|
|||
|
|
@ -572,11 +572,27 @@ static int dmm32at_attach(struct comedi_device *dev,
|
|||
struct comedi_devconfig *it)
|
||||
{
|
||||
struct comedi_subdevice *s;
|
||||
unsigned int iobase = it->options[0];
|
||||
int ret;
|
||||
|
||||
ret = comedi_request_region(dev, it->options[0], 0x10);
|
||||
if (ret)
|
||||
return ret;
|
||||
switch (iobase) {
|
||||
case 0x100:
|
||||
case 0x140:
|
||||
case 0x180:
|
||||
case 0x200:
|
||||
case 0x280:
|
||||
case 0x300:
|
||||
case 0x340:
|
||||
case 0x380:
|
||||
ret = comedi_request_region(dev, iobase, 0x10);
|
||||
if (ret)
|
||||
return ret;
|
||||
break;
|
||||
default:
|
||||
dev_err(dev->class_dev, "unsupported base address %#x\n",
|
||||
iobase);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = dmm32at_reset(dev);
|
||||
if (ret) {
|
||||
|
|
|
|||
|
|
@ -540,7 +540,8 @@ static int dt2801_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
|||
int ret = 0;
|
||||
int n_ai_chans;
|
||||
|
||||
ret = comedi_request_region(dev, it->options[0], 0x2);
|
||||
ret = comedi_check_request_region(dev, it->options[0], 0x2,
|
||||
0x200, 0x3ff, 2);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
|
|||
|
|
@ -556,7 +556,8 @@ static int dt2811_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
|||
if (!devpriv)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = comedi_request_region(dev, it->options[0], 0x8);
|
||||
ret = comedi_check_request_region(dev, it->options[0], 0x8,
|
||||
0x200, 0x3ff, 8);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
|
|||
|
|
@ -305,7 +305,8 @@ static int dt2814_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
|||
struct comedi_subdevice *s;
|
||||
int ret;
|
||||
|
||||
ret = comedi_request_region(dev, it->options[0], 0x2);
|
||||
ret = comedi_check_request_region(dev, it->options[0], 0x2,
|
||||
0x200, 0x3ff, 2);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
|
|||
|
|
@ -144,7 +144,8 @@ static int dt2815_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
|||
const struct comedi_lrange *current_range_type, *voltage_range_type;
|
||||
int ret;
|
||||
|
||||
ret = comedi_request_region(dev, it->options[0], 0x2);
|
||||
ret = comedi_check_request_region(dev, it->options[0], 0x2,
|
||||
0x200, 0x3ff, 2);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
|
|||
|
|
@ -103,7 +103,8 @@ static int dt2817_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
|||
int ret;
|
||||
struct comedi_subdevice *s;
|
||||
|
||||
ret = comedi_request_region(dev, it->options[0], 0x5);
|
||||
ret = comedi_check_request_region(dev, it->options[0], 0x5,
|
||||
0x200, 0x3ff, 8);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
|
|||
|
|
@ -1064,7 +1064,12 @@ static int dt282x_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
|||
struct comedi_subdevice *s;
|
||||
int ret;
|
||||
|
||||
ret = comedi_request_region(dev, it->options[0], 0x10);
|
||||
/*
|
||||
* Although it has only 16 bytes (8 16-bit registers), it needs to
|
||||
* start on a 32-byte boundary in range 0x200 to 0x3E0.
|
||||
*/
|
||||
ret = comedi_check_request_region(dev, it->options[0], 0x10,
|
||||
0x200, 0x3ff, 32);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
|
|||
|
|
@ -98,9 +98,15 @@ static int fl512_ao_insn_write(struct comedi_device *dev,
|
|||
static int fl512_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
{
|
||||
struct comedi_subdevice *s;
|
||||
unsigned int iobase = it->options[0];
|
||||
int ret;
|
||||
|
||||
ret = comedi_request_region(dev, it->options[0], 0x10);
|
||||
/*
|
||||
* FIXME: Don't know the allowed range, but assume it needs to be
|
||||
* on a 16-byte boundary - Ian Abbott
|
||||
*/
|
||||
ret = comedi_check_request_region(dev, iobase, 0x10,
|
||||
0, UINT_MAX, 16);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
|
|||
|
|
@ -921,17 +921,6 @@ void mite_detach(struct mite *mite)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(mite_detach);
|
||||
|
||||
static int __init mite_module_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
module_init(mite_module_init);
|
||||
|
||||
static void __exit mite_module_exit(void)
|
||||
{
|
||||
}
|
||||
module_exit(mite_module_exit);
|
||||
|
||||
MODULE_AUTHOR("Comedi https://www.comedi.org");
|
||||
MODULE_DESCRIPTION("Comedi helper for NI Mite PCI interface chip");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
|||
|
|
@ -237,7 +237,8 @@ static int mpc624_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
|||
struct comedi_subdevice *s;
|
||||
int ret;
|
||||
|
||||
ret = comedi_request_region(dev, it->options[0], 0x10);
|
||||
ret = comedi_check_request_region(dev, it->options[0], 0x10,
|
||||
0, 0x3ff, 16);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
|
|||
|
|
@ -259,7 +259,8 @@ static int multiq3_attach(struct comedi_device *dev,
|
|||
int ret;
|
||||
int i;
|
||||
|
||||
ret = comedi_request_region(dev, it->options[0], 0x10);
|
||||
ret = comedi_check_request_region(dev, it->options[0], 0x10,
|
||||
0, 0x3ff, 16);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
|
|||
|
|
@ -694,7 +694,8 @@ static int a2150_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
|||
if (!devpriv)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = comedi_request_region(dev, it->options[0], 0x1c);
|
||||
ret = comedi_check_request_region(dev, it->options[0], 0x1c,
|
||||
0, 0x3ff, 32);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
|
|||
|
|
@ -295,7 +295,8 @@ static int atao_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
|||
struct comedi_subdevice *s;
|
||||
int ret;
|
||||
|
||||
ret = comedi_request_region(dev, it->options[0], 0x20);
|
||||
ret = comedi_check_request_region(dev, it->options[0], 0x20,
|
||||
0, 0x3ff, 32);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user