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:
Linus Torvalds 2026-04-24 13:23:50 -07:00
commit cb4eb6771c
356 changed files with 12763 additions and 4261 deletions

View File

@ -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>

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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:

View File

@ -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

View File

@ -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>;
};
};

View File

@ -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

View File

@ -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>;

View File

@ -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

View File

@ -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

View File

@ -19,6 +19,7 @@ properties:
enum:
- motorola,cpcap-adc
- motorola,mapphone-cpcap-adc
- motorola,mot-cpcap-adc
interrupts:
maxItems: 1

View File

@ -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>;
};
};
};

View File

@ -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

View File

@ -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:

View 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>;
};
};
...

View File

@ -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

View File

@ -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>;
};
};
...

View File

@ -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>

View File

@ -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

View File

@ -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 = <&reg_vdd>;
vio-supply = <&reg_vio>;
vled-supply = <&reg_vled>;
};
};
...

View File

@ -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

View File

@ -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 = <&reg_3v3>;
interrupt-parent = <&gpio>;
interrupts = <23 IRQ_TYPE_EDGE_FALLING>;
};

View File

@ -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>;

View File

@ -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

View File

@ -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>;
};

View File

@ -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:

View File

@ -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:

View File

@ -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 {

View File

@ -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#

View File

@ -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:

View File

@ -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";
};
};
};
...

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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
--------------

View File

@ -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

View File

@ -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.5g/LSB as specified in the datasheet. However, you can override these
estimated thresholds by setting explicit values.
to 62.5mg/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

View File

@ -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>

View File

@ -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);

View File

@ -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 {

View File

@ -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 {

View File

@ -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

View File

@ -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 {

View File

@ -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

View File

@ -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 */

View File

@ -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.

View File

@ -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:{}",

View File

@ -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) }
}

View File

@ -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 {

View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -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;

View File

@ -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)

View File

@ -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);

View File

@ -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);

View File

@ -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");

View File

@ -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);

View File

@ -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.

View File

@ -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");

View File

@ -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");

View File

@ -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");

View File

@ -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

View File

@ -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);

View File

@ -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");

View File

@ -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;

View File

@ -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");

View File

@ -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");

View File

@ -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;

View File

@ -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");

View File

@ -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;

View File

@ -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");

View File

@ -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;

View File

@ -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;

View File

@ -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");

View File

@ -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");

View File

@ -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");

View File

@ -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;

View File

@ -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;

View File

@ -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");

View File

@ -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;

View File

@ -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);

View File

@ -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 */

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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) {

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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");

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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