Char/Misc and other driver changes for 6.7-rc1

Here is the big set of char/misc and other small driver subsystem
 changes for 6.7-rc1.  Included in here are:
   - IIO subsystem driver updates and additions (largest part of this
     pull request)
   - FPGA subsystem driver updates
   - Counter subsystem driver updates
   - ICC subsystem driver updates
   - extcon subsystem driver updates
   - mei driver updates and additions
   - nvmem subsystem driver updates and additions
   - comedi subsystem dependency fixes
   - parport driver fixups
   - cdx subsystem driver and core updates
   - splice support for /dev/zero and /dev/full
   - other smaller driver cleanups
 
 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-----
 
 iG0EABECAC0WIQT0tgzFv3jCIUoxPcsxR9QN2y37KQUCZUTSzg8cZ3JlZ0Brcm9h
 aC5jb20ACgkQMUfUDdst+ylH3QCfbZuG8MiglEZUd4slRLUNqcRQ5tQAn1yKpDFo
 l3KLkxo1UTLMXbJBWe+b
 =gafK
 -----END PGP SIGNATURE-----

Merge tag 'char-misc-6.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc

Pull char/misc updates from Greg KH:
 "Here is the big set of char/misc and other small driver subsystem
  changes for 6.7-rc1. Included in here are:

   - IIO subsystem driver updates and additions (largest part of this
     pull request)

   - FPGA subsystem driver updates

   - Counter subsystem driver updates

   - ICC subsystem driver updates

   - extcon subsystem driver updates

   - mei driver updates and additions

   - nvmem subsystem driver updates and additions

   - comedi subsystem dependency fixes

   - parport driver fixups

   - cdx subsystem driver and core updates

   - splice support for /dev/zero and /dev/full

   - other smaller driver cleanups

  All of these have been in linux-next for a while with no reported
  issues"

* tag 'char-misc-6.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: (326 commits)
  cdx: add sysfs for subsystem, class and revision
  cdx: add sysfs for bus reset
  cdx: add support for bus enable and disable
  cdx: Register cdx bus as a device on cdx subsystem
  cdx: Create symbol namespaces for cdx subsystem
  cdx: Introduce lock to protect controller ops
  cdx: Remove cdx controller list from cdx bus system
  dts: ti: k3-am625-beagleplay: Add beaglecc1352
  greybus: Add BeaglePlay Linux Driver
  dt-bindings: net: Add ti,cc1352p7
  dt-bindings: eeprom: at24: allow NVMEM cells based on old syntax
  dt-bindings: nvmem: SID: allow NVMEM cells based on old syntax
  Revert "nvmem: add new config option"
  MAINTAINERS: coresight: Add missing Coresight files
  misc: pci_endpoint_test: Add deviceID for J721S2 PCIe EP device support
  firmware: xilinx: Move EXPORT_SYMBOL_GPL next to zynqmp_pm_feature definition
  uacce: make uacce_class constant
  ocxl: make ocxl_class constant
  cxl: make cxl_class constant
  misc: phantom: make phantom_class constant
  ...
This commit is contained in:
Linus Torvalds 2023-11-03 14:51:08 -10:00
commit d99b91a99b
363 changed files with 13498 additions and 3654 deletions

View File

@ -28,14 +28,57 @@ Description:
of a device manufacturer.
Combination of Vendor ID and Device ID identifies a device.
What: /sys/bus/cdx/devices/.../subsystem_vendor
Date: July 2023
Contact: puneet.gupta@amd.com
Description:
Subsystem Vendor ID for this CDX device, in hexadecimal.
Subsystem Vendor ID is 16 bit identifier specific to the
card manufacturer.
What: /sys/bus/cdx/devices/.../subsystem_device
Date: July 2023
Contact: puneet.gupta@amd.com
Description:
Subsystem Device ID for this CDX device, in hexadecimal
Subsystem Device ID is 16 bit identifier specific to the
card manufacturer.
What: /sys/bus/cdx/devices/.../class
Date: July 2023
Contact: puneet.gupta@amd.com
Description:
This file contains the class of the CDX device, in hexadecimal.
Class is 24 bit identifier specifies the functionality of the device.
What: /sys/bus/cdx/devices/.../revision
Date: July 2023
Contact: puneet.gupta@amd.com
Description:
This file contains the revision field of the CDX device, in hexadecimal.
Revision is 8 bit revision identifier of the device.
What: /sys/bus/cdx/devices/.../enable
Date: October 2023
Contact: abhijit.gangurde@amd.com
Description:
CDX bus should be disabled before updating the devices in FPGA.
Writing n/0/off will attempt to disable the CDX bus and.
writing y/1/on will attempt to enable the CDX bus. Reading this file
gives the current state of the bus, 1 for enabled and 0 for disabled.
For example::
# echo 1 > /sys/bus/cdx/.../enable
What: /sys/bus/cdx/devices/.../reset
Date: March 2023
Contact: nipun.gupta@amd.com
Description:
Writing y/1/on to this file resets the CDX device.
On resetting the device, the corresponding driver is notified
twice, once before the device is being reset, and again after
the reset has been complete.
Writing y/1/on to this file resets the CDX device or all devices
on the bus. On resetting the device, the corresponding driver is
notified twice, once before the device is being reset, and again
after the reset has been complete.
For example::
@ -54,3 +97,18 @@ Description:
For example::
# echo 1 > /sys/bus/cdx/devices/.../remove
What: /sys/bus/cdx/devices/.../modalias
Date: July 2023
Contact: nipun.gupta@amd.com
Description:
This attribute indicates the CDX ID of the device.
That is in the format:
cdx:vXXXXdXXXXsvXXXXsdXXXXcXXXXXX,
where:
- vXXXX contains the vendor ID;
- dXXXX contains the device ID;
- svXXXX contains the subsystem vendor ID;
- sdXXXX contains the subsystem device ID;
- cXXXXXX contains the device class.

View File

@ -279,6 +279,35 @@ Description:
but should match other such assignments on device).
Units after application of scale and offset are m/s^2.
What: /sys/bus/iio/devices/iio:deviceX/in_deltaangl_x_raw
What: /sys/bus/iio/devices/iio:deviceX/in_deltaangl_y_raw
What: /sys/bus/iio/devices/iio:deviceX/in_deltaangl_z_raw
KernelVersion: 6.5
Contact: linux-iio@vger.kernel.org
Description:
Angular displacement between two consecutive samples on x, y or
z (may be arbitrarily assigned but should match other such
assignments on device).
In order to compute the total angular displacement during a
desired period of time, the application should sum-up the delta
angle samples acquired during that time.
Units after application of scale and offset are radians.
What: /sys/bus/iio/devices/iio:deviceX/in_deltavelocity_x_raw
What: /sys/bus/iio/devices/iio:deviceX/in_deltavelocity_y_raw
What: /sys/bus/iio/devices/iio:deviceX/in_deltavelocity_z_raw
KernelVersion: 6.5
Contact: linux-iio@vger.kernel.org
Description:
The linear velocity change between two consecutive samples on x,
y or z (may be arbitrarily assigned but should match other such
assignments on device).
In order to compute the total linear velocity change during a
desired period of time, the application should sum-up the delta
velocity samples acquired during that time.
Units after application of scale and offset are meters per
second.
What: /sys/bus/iio/devices/iio:deviceX/in_angl_raw
What: /sys/bus/iio/devices/iio:deviceX/in_anglY_raw
KernelVersion: 4.17
@ -461,6 +490,8 @@ What: /sys/bus/iio/devices/iio:deviceX/in_humidityrelative_scale
What: /sys/bus/iio/devices/iio:deviceX/in_velocity_sqrt(x^2+y^2+z^2)_scale
What: /sys/bus/iio/devices/iio:deviceX/in_illuminance_scale
What: /sys/bus/iio/devices/iio:deviceX/in_countY_scale
What: /sys/bus/iio/devices/iio:deviceX/in_deltaangl_scale
What: /sys/bus/iio/devices/iio:deviceX/in_deltavelocity_scale
What: /sys/bus/iio/devices/iio:deviceX/in_angl_scale
What: /sys/bus/iio/devices/iio:deviceX/in_intensity_x_scale
What: /sys/bus/iio/devices/iio:deviceX/in_intensity_y_scale
@ -1332,6 +1363,12 @@ Description:
What: /sys/.../iio:deviceX/bufferY/in_accel_x_en
What: /sys/.../iio:deviceX/bufferY/in_accel_y_en
What: /sys/.../iio:deviceX/bufferY/in_accel_z_en
What: /sys/.../iio:deviceX/bufferY/in_deltaangl_x_en
What: /sys/.../iio:deviceX/bufferY/in_deltaangl_y_en
What: /sys/.../iio:deviceX/bufferY/in_deltaangl_z_en
What: /sys/.../iio:deviceX/bufferY/in_deltavelocity_x_en
What: /sys/.../iio:deviceX/bufferY/in_deltavelocity_y_en
What: /sys/.../iio:deviceX/bufferY/in_deltavelocity_z_en
What: /sys/.../iio:deviceX/bufferY/in_anglvel_x_en
What: /sys/.../iio:deviceX/bufferY/in_anglvel_y_en
What: /sys/.../iio:deviceX/bufferY/in_anglvel_z_en
@ -1362,6 +1399,8 @@ Description:
Scan element control for triggered data capture.
What: /sys/.../iio:deviceX/bufferY/in_accel_type
What: /sys/.../iio:deviceX/bufferY/in_deltaangl_type
What: /sys/.../iio:deviceX/bufferY/in_deltavelocity_type
What: /sys/.../iio:deviceX/bufferY/in_anglvel_type
What: /sys/.../iio:deviceX/bufferY/in_magn_type
What: /sys/.../iio:deviceX/bufferY/in_incli_type
@ -1416,6 +1455,12 @@ What: /sys/.../iio:deviceX/bufferY/in_voltage_q_index
What: /sys/.../iio:deviceX/bufferY/in_accel_x_index
What: /sys/.../iio:deviceX/bufferY/in_accel_y_index
What: /sys/.../iio:deviceX/bufferY/in_accel_z_index
What: /sys/.../iio:deviceX/bufferY/in_deltaangl_x_index
What: /sys/.../iio:deviceX/bufferY/in_deltaangl_y_index
What: /sys/.../iio:deviceX/bufferY/in_deltaangl_z_index
What: /sys/.../iio:deviceX/bufferY/in_deltavelocity_x_index
What: /sys/.../iio:deviceX/bufferY/in_deltavelocity_y_index
What: /sys/.../iio:deviceX/bufferY/in_deltavelocity_z_index
What: /sys/.../iio:deviceX/bufferY/in_anglvel_x_index
What: /sys/.../iio:deviceX/bufferY/in_anglvel_y_index
What: /sys/.../iio:deviceX/bufferY/in_anglvel_z_index
@ -2179,3 +2224,33 @@ Contact: linux-iio@vger.kernel.org
Description:
Number of conditions that must occur, during a running
period, before an event is generated.
What: /sys/bus/iio/devices/iio:deviceX/in_colortemp_raw
KernelVersion: 6.7
Contact: linux-iio@vger.kernel.org
Description:
Represents light color temperature, which measures light color
temperature in Kelvin.
What: /sys/bus/iio/devices/iio:deviceX/in_chromaticity_x_raw
What: /sys/bus/iio/devices/iio:deviceX/in_chromaticity_y_raw
KernelVersion: 6.7
Contact: linux-iio@vger.kernel.org
Description:
The x and y light color coordinate on the CIE 1931 chromaticity
diagram.
What: /sys/bus/iio/devices/iio:deviceX/events/in_altvoltageY_mag_either_label
What: /sys/bus/iio/devices/iio:deviceX/events/in_altvoltageY_mag_rising_label
What: /sys/bus/iio/devices/iio:deviceX/events/in_altvoltageY_thresh_falling_label
What: /sys/bus/iio/devices/iio:deviceX/events/in_altvoltageY_thresh_rising_label
What: /sys/bus/iio/devices/iio:deviceX/events/in_anglvelY_mag_rising_label
What: /sys/bus/iio/devices/iio:deviceX/events/in_anglY_thresh_rising_label
What: /sys/bus/iio/devices/iio:deviceX/events/in_phaseY_mag_rising_label
KernelVersion: 6.7
Contact: linux-iio@vger.kernel.org
Description:
Optional symbolic label to a device channel event.
If a label is defined for this event add that to the event
specific attributes. This is useful for userspace to be able to
better identify an individual event.

View File

@ -0,0 +1,53 @@
What: /sys/bus/iio/devices/iio:deviceX/boost_current_gain
KernelVersion: 6.4
Contact: linux-iio@vger.kernel.org
Description:
This attribute is used to set the gain of the biasing current
circuit of the Delta-Sigma modulator. The different BOOST
settings are applied to the entire modulator circuit, including
the voltage reference buffers.
What: /sys/bus/iio/devices/iio:deviceX/boost_current_gain_available
KernelVersion: 6.4
Contact: linux-iio@vger.kernel.org
Description:
Reading returns a list with the possible gain values for
the current biasing circuit of the Delta-Sigma modulator.
What: /sys/bus/iio/devices/iio:deviceX/auto_zeroing_mux_enable
KernelVersion: 6.4
Contact: linux-iio@vger.kernel.org
Description:
This attribute is used to enable the analog input multiplexer
auto-zeroing algorithm (the input multiplexer and the ADC
include an offset cancellation algorithm that cancels the offset
contribution of the ADC). When the offset cancellation algorithm
is enabled, ADC takes two conversions, one with the differential
input as VIN+/VIN-, one with VIN+/VIN- inverted. In this case the
conversion time is multiplied by two compared to the default
case where the algorithm is disabled. This technique allows the
cancellation of the ADC offset error and the achievement of
ultra-low offset without any digital calibration. The resulting
offset is the residue of the difference between the two
conversions, which is on the order of magnitude of the noise
floor. This offset is effectively canceled at every conversion,
so the residual offset error temperature drift is extremely low.
Write '1' to enable it, write '0' to disable it.
What: /sys/bus/iio/devices/iio:deviceX/auto_zeroing_ref_enable
KernelVersion: 6.4
Contact: linux-iio@vger.kernel.org
Description:
This attribute is used to enable the chopping algorithm for the
internal voltage reference buffer. This setting has no effect
when external voltage reference is selected.
Internal voltage reference buffer injects a certain quantity of
1/f noise into the system that can be modulated with the
incoming input signals and can limit the SNR performance at
higher Oversampling Ratio values (over 256). To overcome this
limitation, the buffer includes an auto-zeroing algorithm that
greatly reduces (cancels out) the 1/f noise and cancels the
offset value of the reference buffer. As a result, the SNR of
the system is not affected by this 1/f noise component of the
reference buffer, even at maximum oversampling ratio values.
Write '1' to enable it, write '0' to disable it.

View File

@ -0,0 +1,27 @@
What: /sys/bus/iio/devices/iio:deviceX/events/in_altvoltage0_mag_rising_reset_max
KernelVersion: 6.7
Contact: linux-iio@vger.kernel.org
Description:
Reading returns the current Degradation of Signal Reset Maximum
Threshold value in millivolts. Writing sets the value.
What: /sys/bus/iio/devices/iio:deviceX/events/in_altvoltage0_mag_rising_reset_max_available
KernelVersion: 6.7
Contact: linux-iio@vger.kernel.org
Description:
Reading returns the allowable voltage range for
in_altvoltage0_mag_rising_reset_max.
What: /sys/bus/iio/devices/iio:deviceX/events/in_altvoltage0_mag_rising_reset_min
KernelVersion: 6.7
Contact: linux-iio@vger.kernel.org
Description:
Reading returns the current Degradation of Signal Reset Minimum
Threshold value in millivolts. Writing sets the value.
What: /sys/bus/iio/devices/iio:deviceX/events/in_altvoltage0_mag_rising_reset_min_available
KernelVersion: 6.7
Contact: linux-iio@vger.kernel.org
Description:
Reading returns the allowable voltage range for
in_altvoltage0_mag_rising_reset_min.

View File

@ -12,6 +12,7 @@ maintainers:
allOf:
- $ref: /schemas/nvmem/nvmem.yaml
- $ref: /schemas/nvmem/nvmem-deprecated-cells.yaml
select:
properties:

View File

@ -4,19 +4,23 @@
$id: http://devicetree.org/schemas/iio/accel/kionix,kx022a.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: ROHM/Kionix KX022A Accelerometer
title: ROHM/Kionix KX022A, KX132-1211 and KX132ACR-LBZ Accelerometers
maintainers:
- Matti Vaittinen <mazziesaccount@gmail.com>
description: |
KX022A is a 3-axis accelerometer supporting +/- 2G, 4G, 8G and 16G ranges,
output data-rates from 0.78Hz to 1600Hz and a hardware-fifo buffering.
KX022A can be accessed either via I2C or SPI.
KX022A, KX132ACR-LBZ and KX132-1211 are 3-axis accelerometers supporting
+/- 2G, 4G, 8G and 16G ranges, variable output data-rates and a
hardware-fifo buffering. These accelerometers can be accessed either
via I2C or SPI.
properties:
compatible:
const: kionix,kx022a
enum:
- kionix,kx022a
- kionix,kx132-1211
- rohm,kx132acr-lbz
reg:
maxItems: 1

View File

@ -4,21 +4,31 @@
$id: http://devicetree.org/schemas/iio/adc/lltc,ltc2497.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Linear Technology / Analog Devices LTC2497 ADC
title: Linear Technology / Analog Devices LTC2497 and LTC2309 ADC
maintainers:
- Michael Hennerich <michael.hennerich@analog.com>
- Liam Beguin <liambeguin@gmail.com>
description: |
16bit ADC supporting up to 16 single ended or 8 differential inputs.
I2C interface.
LTC2309:
low noise, low power, 8-channel, 12-bit successive approximation ADC with an
I2C compatible serial interface.
https://www.analog.com/media/en/technical-documentation/data-sheets/2497fb.pdf
https://www.analog.com/media/en/technical-documentation/data-sheets/2499fe.pdf
https://www.analog.com/media/en/technical-documentation/data-sheets/2309fd.pdf
LTC2497:
LTC2499:
16bit ADC supporting up to 16 single ended or 8 differential inputs.
I2C interface.
https://www.analog.com/media/en/technical-documentation/data-sheets/2497fb.pdf
https://www.analog.com/media/en/technical-documentation/data-sheets/2499fe.pdf
properties:
compatible:
enum:
- lltc,ltc2309
- lltc,ltc2497
- lltc,ltc2499

View File

@ -0,0 +1,205 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/adc/microchip,mcp3564.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Microchip MCP346X and MCP356X ADC Family
maintainers:
- Marius Cristea <marius.cristea@microchip.com>
description: |
Bindings for the Microchip family of 153.6 ksps, Low-Noise 16/24-Bit
Delta-Sigma ADCs with an SPI interface. Datasheet can be found here:
Datasheet for MCP3561, MCP3562, MCP3564 can be found here:
https://ww1.microchip.com/downloads/aemDocuments/documents/MSLD/ProductDocuments/DataSheets/MCP3561-2-4-Family-Data-Sheet-DS20006181C.pdf
Datasheet for MCP3561R, MCP3562R, MCP3564R can be found here:
https://ww1.microchip.com/downloads/aemDocuments/documents/APID/ProductDocuments/DataSheets/MCP3561_2_4R-Data-Sheet-DS200006391C.pdf
Datasheet for MCP3461, MCP3462, MCP3464 can be found here:
https://ww1.microchip.com/downloads/aemDocuments/documents/APID/ProductDocuments/DataSheets/MCP3461-2-4-Two-Four-Eight-Channel-153.6-ksps-Low-Noise-16-Bit-Delta-Sigma-ADC-Data-Sheet-20006180D.pdf
Datasheet for MCP3461R, MCP3462R, MCP3464R can be found here:
https://ww1.microchip.com/downloads/aemDocuments/documents/APID/ProductDocuments/DataSheets/MCP3461-2-4R-Family-Data-Sheet-DS20006404C.pdf
properties:
compatible:
enum:
- microchip,mcp3461
- microchip,mcp3462
- microchip,mcp3464
- microchip,mcp3461r
- microchip,mcp3462r
- microchip,mcp3464r
- microchip,mcp3561
- microchip,mcp3562
- microchip,mcp3564
- microchip,mcp3561r
- microchip,mcp3562r
- microchip,mcp3564r
reg:
maxItems: 1
spi-max-frequency:
maximum: 20000000
spi-cpha: true
spi-cpol: true
vdd-supply: true
avdd-supply: true
clocks:
description:
Phandle and clock identifier for external sampling clock.
If not specified, the internal crystal oscillator will be used.
maxItems: 1
interrupts:
description: IRQ line of the ADC
maxItems: 1
drive-open-drain:
description:
Whether to drive the IRQ signal as push-pull (default) or open-drain. Note
that the device requires this pin to become "high", otherwise it will stop
converting.
type: boolean
vref-supply:
description:
Some devices have a specific reference voltage supplied on a different
pin to the other supplies. Needed to be able to establish channel scaling
unless there is also an internal reference available (e.g. mcp3564r). In
case of "r" devices (e. g. mcp3564r), if it does not exists the internal
reference will be used.
microchip,hw-device-address:
$ref: /schemas/types.yaml#/definitions/uint32
minimum: 0
maximum: 3
description:
The address is set on a per-device basis by fuses in the factory,
configured on request. If not requested, the fuses are set for 0x1.
The device address is part of the device markings to avoid
potential confusion. This address is coded on two bits, so four possible
addresses are available when multiple devices are present on the same
SPI bus with only one Chip Select line for all devices.
Each device communication starts by a CS falling edge, followed by the
clocking of the device address (BITS[7:6] - top two bits of COMMAND BYTE
which is first one on the wire).
"#io-channel-cells":
const: 1
"#address-cells":
const: 1
"#size-cells":
const: 0
patternProperties:
"^channel@([0-9]|([1-7][0-9]))$":
$ref: adc.yaml
type: object
unevaluatedProperties: false
description: Represents the external channels which are connected to the ADC.
properties:
reg:
description: The channel number in single-ended and differential mode.
minimum: 0
maximum: 79
required:
- reg
dependencies:
spi-cpol: [ spi-cpha ]
spi-cpha: [ spi-cpol ]
required:
- compatible
- reg
- microchip,hw-device-address
- spi-max-frequency
allOf:
- $ref: /schemas/spi/spi-peripheral-props.yaml#
- # External vref, no internal reference
if:
properties:
compatible:
contains:
enum:
- microchip,mcp3461
- microchip,mcp3462
- microchip,mcp3464
- microchip,mcp3561
- microchip,mcp3562
- microchip,mcp3564
then:
required:
- vref-supply
unevaluatedProperties: false
examples:
- |
spi {
#address-cells = <1>;
#size-cells = <0>;
adc@0 {
compatible = "microchip,mcp3564r";
reg = <0>;
vref-supply = <&vref_reg>;
spi-cpha;
spi-cpol;
spi-max-frequency = <10000000>;
microchip,hw-device-address = <1>;
#address-cells = <1>;
#size-cells = <0>;
channel@0 {
/* CH0 to AGND */
reg = <0>;
label = "CH0";
};
channel@1 {
/* CH1 to AGND */
reg = <1>;
label = "CH1";
};
/* diff-channels */
channel@11 {
reg = <11>;
/* CN0, CN1 */
diff-channels = <0 1>;
label = "CH0_CH1";
};
channel@22 {
reg = <0x22>;
/* CN1, CN2 */
diff-channels = <1 2>;
label = "CH1_CH3";
};
channel@23 {
reg = <0x23>;
/* CN1, CN3 */
diff-channels = <1 3>;
label = "CH1_CH3";
};
};
};
...

View File

@ -18,7 +18,13 @@ description: |
properties:
compatible:
enum:
- microchip,mcp3910
- microchip,mcp3911
- microchip,mcp3912
- microchip,mcp3913
- microchip,mcp3914
- microchip,mcp3918
- microchip,mcp3919
reg:
maxItems: 1

View File

@ -23,6 +23,9 @@ properties:
reg:
maxItems: 1
interrupts:
maxItems: 1
"#address-cells":
const: 1

View File

@ -0,0 +1,43 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/adc/ti,twl6030-gpadc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: GPADC subsystem in the TWL6030 power module
maintainers:
- Andreas Kemnade <andreas@kemnade.info>
description:
The GPADC subsystem in the TWL603X consists of a 10-bit ADC
combined with a 15-input analog multiplexer in the TWL6030 resp. a
19-input analog muliplexer in the TWL6032.
properties:
compatible:
enum:
- ti,twl6030-gpadc
- ti,twl6032-gpadc
interrupts:
maxItems: 1
"#io-channel-cells":
const: 1
required:
- compatible
- interrupts
- "#io-channel-cells"
additionalProperties: false
examples:
- |
gpadc {
compatible = "ti,twl6030-gpadc";
interrupts = <3>;
#io-channel-cells = <1>;
};
...

View File

@ -4,20 +4,26 @@
$id: http://devicetree.org/schemas/iio/amplifiers/adi,hmc425a.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: HMC425A 6-bit Digital Step Attenuator
title: Analog Devices HMC425A and similar Digital Step Attenuators
maintainers:
- Michael Hennerich <michael.hennerich@analog.com>
description: |
Digital Step Attenuator IIO device with gpio interface.
Digital Step Attenuator IIO devices with gpio interface.
Offer various frequency and attenuation ranges.
HMC425A 0.5 dB LSB GaAs MMIC 6-BIT DIGITAL POSITIVE CONTROL ATTENUATOR, 2.2 - 8.0 GHz
https://www.analog.com/media/en/technical-documentation/data-sheets/hmc425A.pdf
https://www.analog.com/media/en/technical-documentation/data-sheets/hmc425A.pdf
HMC540S 1 dB LSB Silicon MMIC 4-Bit Digital Positive Control Attenuator, 0.1 - 8 GHz
https://www.analog.com/media/en/technical-documentation/data-sheets/hmc540s.pdf
properties:
compatible:
enum:
- adi,hmc425a
- adi,hmc540s
vcc-supply: true

View File

@ -48,6 +48,11 @@ properties:
mount-matrix: true
invensense,level-shifter:
type: boolean
description: |
From ancient platform data struct: false: VLogic, true: VDD
i2c-gate:
$ref: /schemas/i2c/i2c-controller.yaml
unevaluatedProperties: false

View File

@ -93,6 +93,9 @@ properties:
wakeup-source:
$ref: /schemas/types.yaml#/definitions/flag
mount-matrix:
description: an optional 3x3 mounting rotation matrix
required:
- compatible
- reg

View File

@ -0,0 +1,52 @@
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/pressure/rohm,bm1390.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: ROHM BM1390 pressure sensor
maintainers:
- Matti Vaittinen <mazziesaccount@gmail.com>
description:
BM1390GLV-Z is a pressure sensor which performs internal temperature
compensation for the MEMS. Pressure range is from 300 hPa to 1300 hPa
and sample averaging and IIR filtering is built in. Temperature
measurement is also supported.
properties:
compatible:
const: rohm,bm1390glv-z
reg:
maxItems: 1
interrupts:
maxItems: 1
vdd-supply: true
required:
- compatible
- reg
- vdd-supply
additionalProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/irq.h>
i2c {
#address-cells = <1>;
#size-cells = <0>;
pressure-sensor@5d {
compatible = "rohm,bm1390glv-z";
reg = <0x5d>;
interrupt-parent = <&gpio1>;
interrupts = <29 IRQ_TYPE_LEVEL_LOW>;
vdd-supply = <&vdd>;
};
};

View File

@ -0,0 +1,177 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/resolver/adi,ad2s1210.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Analog Devices AD2S1210 Resolver-to-Digital Converter
maintainers:
- Michael Hennerich <michael.hennerich@analog.com>
description: |
The AD2S1210 is a complete 10-bit to 16-bit resolution tracking
resolver-to-digital converter, integrating an on-board programmable
sinusoidal oscillator that provides sine wave excitation for
resolvers.
The AD2S1210 allows the user to read the angular position or the
angular velocity data directly from the parallel outputs or through
the serial interface.
The mode of operation of the communication channel (parallel or serial) is
selected by the A0 and A1 input pins. In normal mode, data is latched by
toggling the SAMPLE line and can then be read directly. In configuration mode,
data is read or written using a register access scheme (address byte with
read/write flag and data byte).
A1 A0 Result
0 0 Normal mode - position output
0 1 Normal mode - velocity output
1 0 Reserved
1 1 Configuration mode
In normal mode, the resolution of the digital output is selected using
the RES0 and RES1 input pins. In configuration mode, the resolution is
selected by setting the RES0 and RES1 bits in the control register.
RES1 RES0 Resolution (Bits)
0 0 10
0 1 12
1 0 14
1 1 16
Note on SPI connections: The CS line on the AD2S1210 should hard-wired to
logic low and the WR/FSYNC line on the AD2S1210 should be connected to the
SPI CSn output of the SPI controller.
Datasheet:
https://www.analog.com/media/en/technical-documentation/data-sheets/ad2s1210.pdf
properties:
compatible:
const: adi,ad2s1210
reg:
maxItems: 1
spi-max-frequency:
maximum: 25000000
spi-cpha: true
avdd-supply:
description:
A 4.75 to 5.25 V regulator that powers the Analog Supply Voltage (AVDD)
pin.
dvdd-supply:
description:
A 4.75 to 5.25 V regulator that powers the Digital Supply Voltage (DVDD)
pin.
vdrive-supply:
description:
A 2.3 to 5.25 V regulator that powers the Logic Power Supply Input
(VDrive) pin.
clocks:
maxItems: 1
description: External oscillator clock (CLKIN).
reset-gpios:
description:
GPIO connected to the /RESET pin. As the line needs to be low for the
reset to be active, it should be configured as GPIO_ACTIVE_LOW.
maxItems: 1
sample-gpios:
description:
GPIO connected to the /SAMPLE pin. As the line needs to be low to trigger
a sample, it should be configured as GPIO_ACTIVE_LOW.
maxItems: 1
mode-gpios:
description:
GPIO lines connected to the A0 and A1 pins. These pins select the data
transfer mode.
minItems: 2
maxItems: 2
resolution-gpios:
description:
GPIO lines connected to the RES0 and RES1 pins. These pins select the
resolution of the digital output. If omitted, it is assumed that the
RES0 and RES1 pins are hard-wired to match the assigned-resolution-bits
property.
minItems: 2
maxItems: 2
fault-gpios:
description:
GPIO lines connected to the LOT and DOS pins. These pins combined indicate
the type of fault present, if any. As these pins a pulled low to indicate
a fault condition, they should be configured as GPIO_ACTIVE_LOW.
minItems: 2
maxItems: 2
adi,fixed-mode:
description:
This is used to indicate the selected mode if A0 and A1 are hard-wired
instead of connected to GPIOS (i.e. mode-gpios is omitted).
$ref: /schemas/types.yaml#/definitions/string
enum: [config, velocity, position]
assigned-resolution-bits:
description:
Resolution of the digital output required by the application. This
determines the precision of the angle and/or the maximum speed that can
be measured. If resolution-gpios is omitted, it is assumed that RES0 and
RES1 are hard-wired to match this value.
enum: [10, 12, 14, 16]
required:
- compatible
- reg
- spi-cpha
- avdd-supply
- dvdd-supply
- vdrive-supply
- clocks
- sample-gpios
- assigned-resolution-bits
oneOf:
- required:
- mode-gpios
- required:
- adi,fixed-mode
allOf:
- $ref: /schemas/spi/spi-peripheral-props.yaml#
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/gpio/gpio.h>
spi {
#address-cells = <1>;
#size-cells = <0>;
resolver@0 {
compatible = "adi,ad2s1210";
reg = <0>;
spi-max-frequency = <20000000>;
spi-cpha;
avdd-supply = <&avdd_regulator>;
dvdd-supply = <&dvdd_regulator>;
vdrive-supply = <&vdrive_regulator>;
clocks = <&ext_osc>;
sample-gpios = <&gpio0 90 GPIO_ACTIVE_LOW>;
mode-gpios = <&gpio0 86 0>, <&gpio0 87 0>;
resolution-gpios = <&gpio0 88 0>, <&gpio0 89 0>;
assigned-resolution-bits = <16>;
};
};

View File

@ -0,0 +1,74 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/interconnect/qcom,msm8939.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm MSM8939 Network-On-Chip interconnect
maintainers:
- Konrad Dybcio <konradybcio@kernel.org>
description: |
The Qualcomm MSM8939 interconnect providers support adjusting the
bandwidth requirements between the various NoC fabrics.
allOf:
- $ref: qcom,rpm-common.yaml#
properties:
compatible:
enum:
- qcom,msm8939-bimc
- qcom,msm8939-pcnoc
- qcom,msm8939-snoc
reg:
maxItems: 1
patternProperties:
'^interconnect-[a-z0-9\-]+$':
type: object
$ref: qcom,rpm-common.yaml#
description:
The interconnect providers do not have a separate QoS register space,
but share parent's space.
allOf:
- $ref: qcom,rpm-common.yaml#
properties:
compatible:
const: qcom,msm8939-snoc-mm
required:
- compatible
unevaluatedProperties: false
required:
- compatible
- reg
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/clock/qcom,rpmcc.h>
snoc: interconnect@580000 {
compatible = "qcom,msm8939-snoc";
reg = <0x00580000 0x14000>;
#interconnect-cells = <1>;
};
bimc: interconnect@400000 {
compatible = "qcom,msm8939-bimc";
reg = <0x00400000 0x62000>;
#interconnect-cells = <1>;
snoc_mm: interconnect-snoc {
compatible = "qcom,msm8939-snoc-mm";
#interconnect-cells = <1>;
};
};

View File

@ -0,0 +1,126 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/interconnect/qcom,msm8996.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm MSM8996 Network-On-Chip interconnect
maintainers:
- Konrad Dybcio <konradybcio@kernel.org>
description: |
The Qualcomm MSM8996 interconnect providers support adjusting the
bandwidth requirements between the various NoC fabrics.
properties:
compatible:
enum:
- qcom,msm8996-a0noc
- qcom,msm8996-a1noc
- qcom,msm8996-a2noc
- qcom,msm8996-bimc
- qcom,msm8996-cnoc
- qcom,msm8996-mnoc
- qcom,msm8996-pnoc
- qcom,msm8996-snoc
reg:
maxItems: 1
clock-names:
minItems: 1
maxItems: 3
clocks:
minItems: 1
maxItems: 3
power-domains:
maxItems: 1
required:
- compatible
- reg
unevaluatedProperties: false
allOf:
- $ref: qcom,rpm-common.yaml#
- if:
properties:
compatible:
const: qcom,msm8996-a0noc
then:
properties:
clocks:
items:
- description: Aggregate0 System NoC AXI Clock.
- description: Aggregate0 Config NoC AHB Clock.
- description: Aggregate0 NoC MPU Clock.
clock-names:
items:
- const: aggre0_snoc_axi
- const: aggre0_cnoc_ahb
- const: aggre0_noc_mpu_cfg
required:
- power-domains
- if:
properties:
compatible:
const: qcom,msm8996-mnoc
then:
properties:
clocks:
items:
- description: CPU-NoC High-performance Bus Clock.
clock-names:
const: iface
- if:
properties:
compatible:
const: qcom,msm8996-a2noc
then:
properties:
clocks:
items:
- description: Aggregate2 NoC UFS AXI Clock
- description: UFS AXI Clock
clock-names:
items:
- const: aggre2_ufs_axi
- const: ufs_axi
examples:
- |
#include <dt-bindings/clock/qcom,gcc-msm8996.h>
#include <dt-bindings/clock/qcom,mmcc-msm8996.h>
#include <dt-bindings/clock/qcom,rpmcc.h>
bimc: interconnect@408000 {
compatible = "qcom,msm8996-bimc";
reg = <0x00408000 0x5a000>;
#interconnect-cells = <1>;
};
a0noc: interconnect@543000 {
compatible = "qcom,msm8996-a0noc";
reg = <0x00543000 0x6000>;
#interconnect-cells = <1>;
clocks = <&gcc GCC_AGGRE0_SNOC_AXI_CLK>,
<&gcc GCC_AGGRE0_CNOC_AHB_CLK>,
<&gcc GCC_AGGRE0_NOC_MPU_CFG_AHB_CLK>;
clock-names = "aggre0_snoc_axi",
"aggre0_cnoc_ahb",
"aggre0_noc_mpu_cfg";
power-domains = <&gcc AGGRE0_NOC_GDSC>;
};

View File

@ -13,6 +13,9 @@ description: |
The Qualcomm QCM2290 interconnect providers support adjusting the
bandwidth requirements between the various NoC fabrics.
allOf:
- $ref: qcom,rpm-common.yaml#
properties:
reg:
maxItems: 1
@ -23,19 +26,6 @@ properties:
- qcom,qcm2290-cnoc
- qcom,qcm2290-snoc
'#interconnect-cells':
const: 1
clock-names:
items:
- const: bus
- const: bus_a
clocks:
items:
- description: Bus Clock
- description: Bus A Clock
# Child node's properties
patternProperties:
'^interconnect-[a-z0-9]+$':
@ -44,6 +34,9 @@ patternProperties:
The interconnect providers do not have a separate QoS register space,
but share parent's space.
allOf:
- $ref: qcom,rpm-common.yaml#
properties:
compatible:
enum:
@ -51,35 +44,16 @@ patternProperties:
- qcom,qcm2290-mmrt-virt
- qcom,qcm2290-mmnrt-virt
'#interconnect-cells':
const: 1
clock-names:
items:
- const: bus
- const: bus_a
clocks:
items:
- description: Bus Clock
- description: Bus A Clock
required:
- compatible
- '#interconnect-cells'
- clock-names
- clocks
additionalProperties: false
unevaluatedProperties: false
required:
- compatible
- reg
- '#interconnect-cells'
- clock-names
- clocks
additionalProperties: false
unevaluatedProperties: false
examples:
- |
@ -89,32 +63,20 @@ examples:
compatible = "qcom,qcm2290-snoc";
reg = <0x01880000 0x60200>;
#interconnect-cells = <1>;
clock-names = "bus", "bus_a";
clocks = <&rpmcc RPM_SMD_SNOC_CLK>,
<&rpmcc RPM_SMD_SNOC_A_CLK>;
qup_virt: interconnect-qup {
compatible = "qcom,qcm2290-qup-virt";
#interconnect-cells = <1>;
clock-names = "bus", "bus_a";
clocks = <&rpmcc RPM_SMD_QUP_CLK>,
<&rpmcc RPM_SMD_QUP_A_CLK>;
};
mmnrt_virt: interconnect-mmnrt {
compatible = "qcom,qcm2290-mmnrt-virt";
#interconnect-cells = <1>;
clock-names = "bus", "bus_a";
clocks = <&rpmcc RPM_SMD_MMNRT_CLK>,
<&rpmcc RPM_SMD_MMNRT_A_CLK>;
};
mmrt_virt: interconnect-mmrt {
compatible = "qcom,qcm2290-mmrt-virt";
#interconnect-cells = <1>;
clock-names = "bus", "bus_a";
clocks = <&rpmcc RPM_SMD_MMRT_CLK>,
<&rpmcc RPM_SMD_MMRT_A_CLK>;
};
};
@ -122,16 +84,10 @@ examples:
compatible = "qcom,qcm2290-cnoc";
reg = <0x01900000 0x8200>;
#interconnect-cells = <1>;
clock-names = "bus", "bus_a";
clocks = <&rpmcc RPM_SMD_CNOC_CLK>,
<&rpmcc RPM_SMD_CNOC_A_CLK>;
};
bimc: interconnect@4480000 {
compatible = "qcom,qcm2290-bimc";
reg = <0x04480000 0x80000>;
#interconnect-cells = <1>;
clock-names = "bus", "bus_a";
clocks = <&rpmcc RPM_SMD_BIMC_CLK>,
<&rpmcc RPM_SMD_BIMC_A_CLK>;
};

View File

@ -0,0 +1,28 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/interconnect/qcom,rpm-common.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm RPMh Network-On-Chip Interconnect
maintainers:
- Konrad Dybcio <konradybcio@kernel.org>
description:
RPM interconnect providers support for managing system bandwidth requirements
through manual requests based on either predefined values or as indicated by
the bus monitor hardware. Each provider node represents a NoC bus master,
driven by a dedicated clock source.
properties:
'#interconnect-cells':
oneOf:
- const: 2
- const: 1
deprecated: true
required:
- '#interconnect-cells'
additionalProperties: true

View File

@ -7,13 +7,16 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm RPM Network-On-Chip Interconnect
maintainers:
- Georgi Djakov <georgi.djakov@linaro.org>
- Georgi Djakov <djakov@kernel.org>
description: |
RPM interconnect providers support system bandwidth requirements through
RPM processor. The provider is able to communicate with the RPM through
the RPM shared memory device.
allOf:
- $ref: qcom,rpm-common.yaml#
properties:
reg:
maxItems: 1
@ -23,259 +26,22 @@ properties:
- qcom,msm8916-bimc
- qcom,msm8916-pcnoc
- qcom,msm8916-snoc
- qcom,msm8939-bimc
- qcom,msm8939-pcnoc
- qcom,msm8939-snoc
- qcom,msm8996-a0noc
- qcom,msm8996-a1noc
- qcom,msm8996-a2noc
- qcom,msm8996-bimc
- qcom,msm8996-cnoc
- qcom,msm8996-mnoc
- qcom,msm8996-pnoc
- qcom,msm8996-snoc
- qcom,qcs404-bimc
- qcom,qcs404-pcnoc
- qcom,qcs404-snoc
- qcom,sdm660-a2noc
- qcom,sdm660-bimc
- qcom,sdm660-cnoc
- qcom,sdm660-gnoc
- qcom,sdm660-mnoc
- qcom,sdm660-snoc
'#interconnect-cells':
description: |
Value: <1> is one cell in an interconnect specifier for the
interconnect node id, <2> requires the interconnect node id and an
extra path tag.
enum: [ 1, 2 ]
clocks:
minItems: 2
maxItems: 7
clock-names:
minItems: 2
maxItems: 7
power-domains:
maxItems: 1
# Child node's properties
patternProperties:
'^interconnect-[a-z0-9]+$':
type: object
additionalProperties: false
description:
snoc-mm is a child of snoc, sharing snoc's register address space.
properties:
compatible:
enum:
- qcom,msm8939-snoc-mm
'#interconnect-cells':
const: 1
clock-names:
items:
- const: bus
- const: bus_a
clocks:
items:
- description: Bus Clock
- description: Bus A Clock
required:
- compatible
- '#interconnect-cells'
- clock-names
- clocks
required:
- compatible
- reg
- '#interconnect-cells'
- clock-names
- clocks
additionalProperties: false
allOf:
- if:
properties:
compatible:
contains:
enum:
- qcom,msm8916-bimc
- qcom,msm8916-pcnoc
- qcom,msm8916-snoc
- qcom,msm8939-bimc
- qcom,msm8939-pcnoc
- qcom,msm8939-snoc
- qcom,msm8996-a1noc
- qcom,msm8996-bimc
- qcom,msm8996-cnoc
- qcom,msm8996-pnoc
- qcom,msm8996-snoc
- qcom,qcs404-bimc
- qcom,qcs404-pcnoc
- qcom,qcs404-snoc
- qcom,sdm660-bimc
- qcom,sdm660-cnoc
- qcom,sdm660-gnoc
- qcom,sdm660-snoc
then:
properties:
clock-names:
items:
- const: bus
- const: bus_a
clocks:
items:
- description: Bus Clock
- description: Bus A Clock
- if:
properties:
compatible:
contains:
enum:
- qcom,msm8996-mnoc
- qcom,sdm660-mnoc
then:
properties:
clock-names:
items:
- const: bus
- const: bus_a
- const: iface
clocks:
items:
- description: Bus Clock.
- description: Bus A Clock.
- description: CPU-NoC High-performance Bus Clock.
- if:
properties:
compatible:
contains:
enum:
- qcom,msm8996-a0noc
then:
properties:
clock-names:
items:
- const: aggre0_snoc_axi
- const: aggre0_cnoc_ahb
- const: aggre0_noc_mpu_cfg
clocks:
items:
- description: Aggregate0 System NoC AXI Clock.
- description: Aggregate0 Config NoC AHB Clock.
- description: Aggregate0 NoC MPU Clock.
required:
- power-domains
- if:
properties:
compatible:
contains:
enum:
- qcom,msm8996-a2noc
then:
properties:
clock-names:
items:
- const: bus
- const: bus_a
- const: aggre2_ufs_axi
- const: ufs_axi
clocks:
items:
- description: Bus Clock
- description: Bus A Clock
- description: Aggregate2 NoC UFS AXI Clock
- description: UFS AXI Clock
- if:
properties:
compatible:
contains:
enum:
- qcom,sdm660-a2noc
then:
properties:
clock-names:
items:
- const: bus
- const: bus_a
- const: ipa
- const: ufs_axi
- const: aggre2_ufs_axi
- const: aggre2_usb3_axi
- const: cfg_noc_usb2_axi
clocks:
items:
- description: Bus Clock.
- description: Bus A Clock.
- description: IPA Clock.
- description: UFS AXI Clock.
- description: Aggregate2 UFS AXI Clock.
- description: Aggregate2 USB3 AXI Clock.
- description: Config NoC USB2 AXI Clock.
- if:
not:
properties:
compatible:
contains:
enum:
- qcom,msm8939-snoc
then:
patternProperties:
'^interconnect-[a-z0-9]+$': false
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/clock/qcom,rpmcc.h>
bimc: interconnect@400000 {
compatible = "qcom,msm8916-bimc";
reg = <0x00400000 0x62000>;
#interconnect-cells = <1>;
clock-names = "bus", "bus_a";
clocks = <&rpmcc RPM_SMD_BIMC_CLK>,
<&rpmcc RPM_SMD_BIMC_A_CLK>;
};
pcnoc: interconnect@500000 {
compatible = "qcom,msm8916-pcnoc";
reg = <0x00500000 0x11000>;
#interconnect-cells = <1>;
clock-names = "bus", "bus_a";
clocks = <&rpmcc RPM_SMD_PCNOC_CLK>,
<&rpmcc RPM_SMD_PCNOC_A_CLK>;
};
snoc: interconnect@580000 {
compatible = "qcom,msm8916-snoc";
reg = <0x00580000 0x14000>;
#interconnect-cells = <1>;
clock-names = "bus", "bus_a";
clocks = <&rpmcc RPM_SMD_SNOC_CLK>,
<&rpmcc RPM_SMD_SNOC_A_CLK>;
compatible = "qcom,msm8916-bimc";
reg = <0x00400000 0x62000>;
#interconnect-cells = <1>;
};

View File

@ -113,6 +113,7 @@ allOf:
properties:
compatible:
enum:
- qcom,sdx65-mc-virt
- qcom,sm8250-qup-virt
then:
required:

View File

@ -0,0 +1,108 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/interconnect/qcom,sdm660.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm SDM660 Network-On-Chip interconnect
maintainers:
- Konrad Dybcio <konradybcio@kernel.org>
description: |
The Qualcomm SDM660 interconnect providers support adjusting the
bandwidth requirements between the various NoC fabrics.
properties:
compatible:
enum:
- qcom,sdm660-a2noc
- qcom,sdm660-bimc
- qcom,sdm660-cnoc
- qcom,sdm660-gnoc
- qcom,sdm660-mnoc
- qcom,sdm660-snoc
reg:
maxItems: 1
clock-names:
minItems: 1
maxItems: 5
clocks:
minItems: 1
maxItems: 5
required:
- compatible
- reg
unevaluatedProperties: false
allOf:
- $ref: qcom,rpm-common.yaml#
- if:
properties:
compatible:
const: qcom,sdm660-mnoc
then:
properties:
clocks:
items:
- description: CPU-NoC High-performance Bus Clock.
clock-names:
const: iface
- if:
properties:
compatible:
const: qcom,sdm660-a2noc
then:
properties:
clocks:
items:
- description: IPA Clock.
- description: UFS AXI Clock.
- description: Aggregate2 UFS AXI Clock.
- description: Aggregate2 USB3 AXI Clock.
- description: Config NoC USB2 AXI Clock.
clock-names:
items:
- const: ipa
- const: ufs_axi
- const: aggre2_ufs_axi
- const: aggre2_usb3_axi
- const: cfg_noc_usb2_axi
examples:
- |
#include <dt-bindings/clock/qcom,gcc-sdm660.h>
#include <dt-bindings/clock/qcom,mmcc-sdm660.h>
#include <dt-bindings/clock/qcom,rpmcc.h>
bimc: interconnect@1008000 {
compatible = "qcom,sdm660-bimc";
reg = <0x01008000 0x78000>;
#interconnect-cells = <1>;
};
a2noc: interconnect@1704000 {
compatible = "qcom,sdm660-a2noc";
reg = <0x01704000 0xc100>;
#interconnect-cells = <1>;
clocks = <&rpmcc RPM_SMD_IPA_CLK>,
<&gcc GCC_UFS_AXI_CLK>,
<&gcc GCC_AGGRE2_UFS_AXI_CLK>,
<&gcc GCC_AGGRE2_USB3_AXI_CLK>,
<&gcc GCC_CFG_NOC_USB2_AXI_CLK>;
clock-names = "ipa",
"ufs_axi",
"aggre2_ufs_axi",
"aggre2_usb3_axi",
"cfg_noc_usb2_axi";
};

View File

@ -0,0 +1,92 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/interconnect/qcom,sdx75-rpmh.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm RPMh Network-On-Chip Interconnect on SDX75
maintainers:
- Rohit Agarwal <quic_rohiagar@quicinc.com>
description:
RPMh interconnect providers support system bandwidth requirements through
RPMh hardware accelerators known as Bus Clock Manager (BCM). The provider is
able to communicate with the BCM through the Resource State Coordinator (RSC)
associated with each execution environment. Provider nodes must point to at
least one RPMh device child node pertaining to their RSC and each provider
can map to multiple RPMh resources.
properties:
compatible:
enum:
- qcom,sdx75-clk-virt
- qcom,sdx75-dc-noc
- qcom,sdx75-gem-noc
- qcom,sdx75-mc-virt
- qcom,sdx75-pcie-anoc
- qcom,sdx75-system-noc
'#interconnect-cells': true
reg:
maxItems: 1
clocks:
maxItems: 1
required:
- compatible
allOf:
- $ref: qcom,rpmh-common.yaml#
- if:
properties:
compatible:
contains:
enum:
- qcom,sdx75-clk-virt
- qcom,sdx75-mc-virt
then:
properties:
reg: false
else:
required:
- reg
- if:
properties:
compatible:
contains:
enum:
- qcom,sdx75-clk-virt
then:
properties:
clocks:
items:
- description: RPMH CC QPIC Clock
required:
- clocks
else:
properties:
clocks: false
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/clock/qcom,rpmh.h>
clk_virt: interconnect-0 {
compatible = "qcom,sdx75-clk-virt";
#interconnect-cells = <2>;
qcom,bcm-voters = <&apps_bcm_voter>;
clocks = <&rpmhcc RPMH_QPIC_CLK>;
};
system_noc: interconnect@1640000 {
compatible = "qcom,sdx75-system-noc";
reg = <0x1640000 0x4b400>;
#interconnect-cells = <2>;
qcom,bcm-voters = <&apps_bcm_voter>;
};

View File

@ -43,7 +43,12 @@ patternProperties:
deprecated: true
"^otp(-[0-9]+)?$":
$ref: ../nvmem/nvmem.yaml#
type: object
allOf:
- $ref: ../nvmem/nvmem.yaml#
- $ref: ../nvmem/nvmem-deprecated-cells.yaml#
unevaluatedProperties: false
description: |

View File

@ -19,6 +19,7 @@ maintainers:
allOf:
- $ref: /schemas/mtd/partitions/partition.yaml#
- $ref: /schemas/nvmem/nvmem.yaml#
- $ref: /schemas/nvmem/nvmem-deprecated-cells.yaml#
properties:
compatible:

View File

@ -0,0 +1,51 @@
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/net/ti,cc1352p7.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Texas Instruments Simplelink CC1352P7 wireless MCU
description:
The CC1352P7 MCU can be connected via SPI or UART.
maintainers:
- Ayush Singh <ayushdevel1325@gmail.com>
properties:
compatible:
const: ti,cc1352p7
clocks:
items:
- description: high-frequency main system (MCU and peripherals) clock
- description: low-frequency system clock
clock-names:
items:
- const: sclk_hf
- const: sclk_lf
reset-gpios:
maxItems: 1
vdds-supply: true
required:
- compatible
additionalProperties: false
examples:
- |
#include <dt-bindings/gpio/gpio.h>
serial {
mcu {
compatible = "ti,cc1352p7";
clocks = <&sclk_hf 0>, <&sclk_lf 25>;
clock-names = "sclk_hf", "sclk_lf";
reset-gpios = <&pio 35 GPIO_ACTIVE_LOW>;
vdds-supply = <&vdds>;
};
};

View File

@ -12,6 +12,7 @@ maintainers:
allOf:
- $ref: nvmem.yaml#
- $ref: nvmem-deprecated-cells.yaml#
properties:
compatible:

View File

@ -11,6 +11,7 @@ maintainers:
allOf:
- $ref: nvmem.yaml#
- $ref: nvmem-deprecated-cells.yaml#
properties:
compatible:

View File

@ -12,6 +12,7 @@ maintainers:
allOf:
- $ref: nvmem.yaml#
- $ref: nvmem-deprecated-cells.yaml#
properties:
compatible:

View File

@ -16,6 +16,7 @@ maintainers:
allOf:
- $ref: nvmem.yaml#
- $ref: nvmem-deprecated-cells.yaml#
properties:
compatible:

View File

@ -16,6 +16,7 @@ description: |
allOf:
- $ref: nvmem.yaml#
- $ref: nvmem-deprecated-cells.yaml#
properties:
compatible:

View File

@ -16,6 +16,7 @@ maintainers:
allOf:
- $ref: nvmem.yaml#
- $ref: nvmem-deprecated-cells.yaml#
properties:
$nodename:

View File

@ -16,6 +16,7 @@ description: |
allOf:
- $ref: nvmem.yaml#
- $ref: nvmem-deprecated-cells.yaml#
properties:
compatible:

View File

@ -11,6 +11,7 @@ maintainers:
allOf:
- $ref: nvmem.yaml#
- $ref: nvmem-deprecated-cells.yaml#
properties:
compatible:

View File

@ -0,0 +1,28 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/nvmem/nvmem-deprecated-cells.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: NVMEM old syntax for fixed cells
maintainers:
- Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
description: |
Before introducing NVMEM layouts all NVMEM (fixed) cells were defined
as direct device subnodes. That syntax was replaced by "fixed-layout"
and is deprecated now. No new bindings should use it.
patternProperties:
"@[0-9a-f]+(,[0-7])?$":
type: object
allOf:
- $ref: layouts/fixed-cell.yaml
- properties:
compatible: false
deprecated: true
additionalProperties: true
...

View File

@ -46,15 +46,6 @@ properties:
container may reference more advanced (dynamic) layout
parsers.
patternProperties:
"@[0-9a-f]+(,[0-7])?$":
type: object
allOf:
- $ref: layouts/fixed-cell.yaml
- properties:
compatible: false
deprecated: true
additionalProperties: true
examples:

View File

@ -11,6 +11,7 @@ maintainers:
allOf:
- $ref: nvmem.yaml#
- $ref: nvmem-deprecated-cells.yaml#
properties:
compatible:

View File

@ -16,6 +16,7 @@ description:
allOf:
- $ref: nvmem.yaml#
- $ref: nvmem-deprecated-cells.yaml#
properties:
compatible:

View File

@ -16,6 +16,7 @@ description: |
allOf:
- $ref: nvmem.yaml#
- $ref: nvmem-deprecated-cells.yaml#
properties:
compatible:

View File

@ -49,6 +49,7 @@ required:
allOf:
- $ref: nvmem.yaml#
- $ref: nvmem-deprecated-cells.yaml#
- if:
properties:

View File

@ -11,6 +11,7 @@ maintainers:
allOf:
- $ref: nvmem.yaml#
- $ref: nvmem-deprecated-cells.yaml#
properties:
compatible:

View File

@ -12,6 +12,7 @@ maintainers:
allOf:
- $ref: nvmem.yaml#
- $ref: nvmem-deprecated-cells.yaml#
properties:
compatible:

View File

@ -12,6 +12,7 @@ maintainers:
allOf:
- $ref: nvmem.yaml#
- $ref: nvmem-deprecated-cells.yaml#
properties:
compatible:

View File

@ -51,6 +51,8 @@ properties:
ethaddr:
type: object
description: Ethernet interfaces base MAC address.
additionalProperties: false
properties:
"#nvmem-cell-cells":
description: The first argument is a MAC address offset.

View File

@ -13,6 +13,7 @@ maintainers:
allOf:
- $ref: rtc.yaml#
- $ref: /schemas/nvmem/nvmem.yaml#
- $ref: /schemas/nvmem/nvmem-deprecated-cells.yaml#
properties:
compatible:

View File

@ -346,6 +346,8 @@ properties:
# Silicon Labs SI3210 Programmable CMOS SLIC/CODEC with SPI interface
- silabs,si3210
# Relative Humidity and Temperature Sensors
- silabs,si7005
# Relative Humidity and Temperature Sensors
- silabs,si7020
# Skyworks SKY81452: Six-Channel White LED Driver with Touch Panel Bias Supply
- skyworks,sky81452

View File

@ -0,0 +1,82 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
# Copyright 2023 Realtek Semiconductor Corporation
%YAML 1.2
---
$id: http://devicetree.org/schemas/usb/realtek,rtd-type-c.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Realtek DHC RTD SoCs USB Type-C Connector detection
maintainers:
- Stanley Chang <stanley_chang@realtek.com>
description:
Realtek digital home center (DHC) RTD series SoCs include a type c module.
This module is able to detect the state of type c connector.
properties:
compatible:
enum:
- realtek,rtd1295-type-c
- realtek,rtd1312c-type-c
- realtek,rtd1315e-type-c
- realtek,rtd1319-type-c
- realtek,rtd1319d-type-c
- realtek,rtd1395-type-c
- realtek,rtd1619-type-c
- realtek,rtd1619b-type-c
reg:
maxItems: 1
interrupts:
maxItems: 1
nvmem-cell-names:
items:
- const: usb-cal
nvmem-cells:
maxItems: 1
description:
The phandle to nvmem cell that contains the trimming data.
The type c parameter trimming data specified via efuse.
If unspecified, default value is used.
realtek,rd-ctrl-gpios:
description: The gpio node to control external Rd on board.
maxItems: 1
connector:
$ref: /schemas/connector/usb-connector.yaml#
description: Properties for usb c connector.
type: object
required:
- compatible
- reg
- interrupts
additionalProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/irq.h>
type-c@7220 {
compatible = "realtek,rtd1619b-type-c";
reg = <0x7220 0x20>;
interrupts = <0 60 IRQ_TYPE_LEVEL_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <&usb_cc1_pins>, <&usb_cc2_pins>;
nvmem-cells = <&otp_usb_cal>;
nvmem-cell-names = "usb-cal";
connector {
compatible = "usb-c-connector";
label = "USB-C";
data-role = "dual";
power-role = "dual";
};
};

View File

@ -1,107 +0,0 @@
====================
Kernel driver eeprom
====================
Supported chips:
* Any EEPROM chip in the designated address range
Prefix: 'eeprom'
Addresses scanned: I2C 0x50 - 0x57
Datasheets: Publicly available from:
Atmel (www.atmel.com),
Catalyst (www.catsemi.com),
Fairchild (www.fairchildsemi.com),
Microchip (www.microchip.com),
Philips (www.semiconductor.philips.com),
Rohm (www.rohm.com),
ST (www.st.com),
Xicor (www.xicor.com),
and others.
========= ============= ============================================
Chip Size (bits) Address
========= ============= ============================================
24C01 1K 0x50 (shadows at 0x51 - 0x57)
24C01A 1K 0x50 - 0x57 (Typical device on DIMMs)
24C02 2K 0x50 - 0x57
24C04 4K 0x50, 0x52, 0x54, 0x56
(additional data at 0x51, 0x53, 0x55, 0x57)
24C08 8K 0x50, 0x54 (additional data at 0x51, 0x52,
0x53, 0x55, 0x56, 0x57)
24C16 16K 0x50 (additional data at 0x51 - 0x57)
Sony 2K 0x57
Atmel 34C02B 2K 0x50 - 0x57, SW write protect at 0x30-37
Catalyst 34FC02 2K 0x50 - 0x57, SW write protect at 0x30-37
Catalyst 34RC02 2K 0x50 - 0x57, SW write protect at 0x30-37
Fairchild 34W02 2K 0x50 - 0x57, SW write protect at 0x30-37
Microchip 24AA52 2K 0x50 - 0x57, SW write protect at 0x30-37
ST M34C02 2K 0x50 - 0x57, SW write protect at 0x30-37
========= ============= ============================================
Authors:
- Frodo Looijaard <frodol@dds.nl>,
- Philip Edelbrock <phil@netroedge.com>,
- Jean Delvare <jdelvare@suse.de>,
- Greg Kroah-Hartman <greg@kroah.com>,
- IBM Corp.
Description
-----------
This is a simple EEPROM module meant to enable reading the first 256 bytes
of an EEPROM (on a SDRAM DIMM for example). However, it will access serial
EEPROMs on any I2C adapter. The supported devices are generically called
24Cxx, and are listed above; however the numbering for these
industry-standard devices may vary by manufacturer.
This module was a programming exercise to get used to the new project
organization laid out by Frodo, but it should be at least completely
effective for decoding the contents of EEPROMs on DIMMs.
DIMMS will typically contain a 24C01A or 24C02, or the 34C02 variants.
The other devices will not be found on a DIMM because they respond to more
than one address.
DDC Monitors may contain any device. Often a 24C01, which responds to all 8
addresses, is found.
Recent Sony Vaio laptops have an EEPROM at 0x57. We couldn't get the
specification, so it is guess work and far from being complete.
The Microchip 24AA52/24LCS52, ST M34C02, and others support an additional
software write protect register at 0x30 - 0x37 (0x20 less than the memory
location). The chip responds to "write quick" detection at this address but
does not respond to byte reads. If this register is present, the lower 128
bytes of the memory array are not write protected. Any byte data write to
this address will write protect the memory array permanently, and the
device will no longer respond at the 0x30-37 address. The eeprom driver
does not support this register.
Lacking functionality
---------------------
* Full support for larger devices (24C04, 24C08, 24C16). These are not
typically found on a PC. These devices will appear as separate devices at
multiple addresses.
* Support for really large devices (24C32, 24C64, 24C128, 24C256, 24C512).
These devices require two-byte address fields and are not supported.
* Enable Writing. Again, no technical reason why not, but making it easy
to change the contents of the EEPROMs (on DIMMs anyway) also makes it easy
to disable the DIMMs (potentially preventing the computer from booting)
until the values are restored somehow.
Use
---
After inserting the module (and any other required SMBus/i2c modules), you
should have some EEPROM directories in ``/sys/bus/i2c/devices/*`` of names such
as "0-0050". Inside each of these is a series of files, the eeprom file
contains the binary data from EEPROM.

View File

@ -17,7 +17,6 @@ fit into other categories.
ad525x_dpot
apds990x
bh1770glc
eeprom
c2port
dw-xdata-pcie
ibmvmc

View File

@ -101,6 +101,19 @@ comment:
git cherry-pick fd21073
git cherry-pick <this commit>
Note that for a patch series, you do not have to list as prerequisites the
patches present in the series itself. For example, if you have the following
patch series:
.. code-block:: none
patch1
patch2
where patch2 depends on patch1, you do not have to list patch1 as
prerequisite of patch2 if you have already marked patch1 for stable
inclusion.
* For patches that may have kernel version prerequisites specify them using
the following format in the sign-off area:

View File

@ -1119,7 +1119,7 @@ ANALOG DEVICES INC AD4130 DRIVER
M: Cosmin Tanislav <cosmin.tanislav@analog.com>
L: linux-iio@vger.kernel.org
S: Supported
W: http://ez.analog.com/community/linux-device-drivers
W: https://ez.analog.com/linux-software-drivers
F: Documentation/ABI/testing/sysfs-bus-iio-adc-ad4130
F: Documentation/devicetree/bindings/iio/adc/adi,ad4130.yaml
F: drivers/iio/adc/ad4130.c
@ -1152,7 +1152,7 @@ ANALOG DEVICES INC AD74115 DRIVER
M: Cosmin Tanislav <cosmin.tanislav@analog.com>
L: linux-iio@vger.kernel.org
S: Supported
W: http://ez.analog.com/community/linux-device-drivers
W: https://ez.analog.com/linux-software-drivers
F: Documentation/devicetree/bindings/iio/addac/adi,ad74115.yaml
F: drivers/iio/addac/ad74115.c
@ -2075,12 +2075,16 @@ F: Documentation/trace/coresight/*
F: drivers/hwtracing/coresight/*
F: include/dt-bindings/arm/coresight-cti-dt.h
F: include/linux/coresight*
F: include/uapi/linux/coresight*
F: samples/coresight/*
F: tools/perf/Documentation/arm-coresight.txt
F: tools/perf/arch/arm/util/auxtrace.c
F: tools/perf/arch/arm/util/cs-etm.c
F: tools/perf/arch/arm/util/cs-etm.h
F: tools/perf/arch/arm/util/pmu.c
F: tools/perf/tests/shell/*coresight*
F: tools/perf/tests/shell/coresight/*
F: tools/perf/tests/shell/lib/*coresight*
F: tools/perf/util/cs-etm-decoder/*
F: tools/perf/util/cs-etm.*
@ -9076,6 +9080,13 @@ F: drivers/staging/greybus/sdio.c
F: drivers/staging/greybus/spi.c
F: drivers/staging/greybus/spilib.c
GREYBUS BEAGLEPLAY DRIVERS
M: Ayush Singh <ayushdevel1325@gmail.com>
L: greybus-dev@lists.linaro.org (moderated for non-subscribers)
S: Maintained
F: Documentation/devicetree/bindings/net/ti,cc1352p7.yaml
F: drivers/greybus/gb-beagleplay.c
GREYBUS SUBSYSTEM
M: Johan Hovold <johan@kernel.org>
M: Alex Elder <elder@kernel.org>
@ -11993,12 +12004,6 @@ F: drivers/leds/
F: include/dt-bindings/leds/
F: include/linux/leds.h
LEGACY EEPROM DRIVER
M: Jean Delvare <jdelvare@suse.com>
S: Maintained
F: Documentation/misc-devices/eeprom.rst
F: drivers/misc/eeprom/eeprom.c
LEGO MINDSTORMS EV3
R: David Lechner <david@lechnology.com>
S: Maintained
@ -12925,7 +12930,7 @@ MAX31827 TEMPERATURE SWITCH DRIVER
M: Daniel Matyas <daniel.matyas@analog.com>
L: linux-hwmon@vger.kernel.org
S: Supported
W: http://ez.analog.com/community/linux-device-drivers
W: https://ez.analog.com/linux-software-drivers
F: Documentation/devicetree/bindings/hwmon/adi,max31827.yaml
F: Documentation/hwmon/max31827.rst
F: drivers/hwmon/max31827.c
@ -14126,6 +14131,13 @@ S: Supported
F: Documentation/devicetree/bindings/regulator/mcp16502-regulator.txt
F: drivers/regulator/mcp16502.c
MICROCHIP MCP3564 ADC DRIVER
M: Marius Cristea <marius.cristea@microchip.com>
L: linux-iio@vger.kernel.org
S: Supported
F: Documentation/devicetree/bindings/iio/adc/microchip,mcp3564.yaml
F: drivers/iio/adc/mcp3564.c
MICROCHIP MCP3911 ADC DRIVER
M: Marcus Folkesson <marcus.folkesson@gmail.com>
M: Kent Gustavsson <kent@minoris.se>
@ -18695,6 +18707,12 @@ S: Maintained
F: Documentation/devicetree/bindings/iio/light/bh1750.yaml
F: drivers/iio/light/bh1750.c
ROHM BM1390 PRESSURE SENSOR DRIVER
M: Matti Vaittinen <mazziesaccount@gmail.com>
L: linux-iio@vger.kernel.org
S: Supported
F: drivers/iio/pressure/rohm-bm1390.c
ROHM BU270xx LIGHT SENSOR DRIVERs
M: Matti Vaittinen <mazziesaccount@gmail.com>
L: linux-iio@vger.kernel.org

View File

@ -896,6 +896,12 @@ &main_uart6 {
pinctrl-names = "default";
pinctrl-0 = <&wifi_debug_uart_pins_default>;
status = "okay";
mcu {
compatible = "ti,cc1352p7";
reset-gpios = <&main_gpio0 72 GPIO_ACTIVE_LOW>;
vdds-supply = <&vdd_3v3>;
};
};
&dss {

View File

@ -413,27 +413,24 @@ static ssize_t synth_direct_store(struct kobject *kobj,
struct kobj_attribute *attr,
const char *buf, size_t count)
{
u_char tmp[256];
int len;
int bytes;
const char *ptr = buf;
char *unescaped;
unsigned long flags;
if (!synth)
return -EPERM;
len = strlen(buf);
unescaped = kstrdup(buf, GFP_KERNEL);
if (!unescaped)
return -ENOMEM;
string_unescape_any_inplace(unescaped);
spin_lock_irqsave(&speakup_info.spinlock, flags);
while (len > 0) {
bytes = min_t(size_t, len, 250);
strncpy(tmp, ptr, bytes);
tmp[bytes] = '\0';
string_unescape_any_inplace(tmp);
synth_printf("%s", tmp);
ptr += bytes;
len -= bytes;
}
synth_write(unescaped, strlen(unescaped));
spin_unlock_irqrestore(&speakup_info.spinlock, flags);
kfree(unescaped);
return count;
}

View File

@ -93,7 +93,7 @@ bool is_binderfs_device(const struct inode *inode)
/**
* binderfs_binder_device_create - allocate inode from super block of a
* binderfs mount
* @ref_inode: inode from wich the super block will be taken
* @ref_inode: inode from which the super block will be taken
* @userp: buffer to copy information about new device for userspace to
* @req: struct binderfs_device as copied from userspace
*

View File

@ -5,4 +5,6 @@
# Copyright (C) 2022-2023, Advanced Micro Devices, Inc.
#
ccflags-y += -DDEFAULT_SYMBOL_NAMESPACE=CDX_BUS
obj-$(CONFIG_CDX_BUS) += cdx.o controller/

View File

@ -60,7 +60,7 @@
#include <linux/of_device.h>
#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/xarray.h>
#include <linux/idr.h>
#include <linux/cdx/cdx_bus.h>
#include <linux/iommu.h>
#include <linux/dma-map-ops.h>
@ -70,8 +70,12 @@
#define CDX_DEFAULT_DMA_MASK (~0ULL)
#define MAX_CDX_CONTROLLERS 16
/* CDX controllers registered with the CDX bus */
static DEFINE_XARRAY_ALLOC(cdx_controllers);
/* IDA for CDX controllers registered with the CDX bus */
static DEFINE_IDA(cdx_controller_ida);
/* Lock to protect controller ops */
static DEFINE_MUTEX(cdx_controller_lock);
static char *compat_node_name = "xlnx,versal-net-cdx";
/**
* cdx_dev_reset - Reset a CDX device
@ -106,6 +110,20 @@ int cdx_dev_reset(struct device *dev)
}
EXPORT_SYMBOL_GPL(cdx_dev_reset);
/**
* reset_cdx_device - Reset a CDX device
* @dev: CDX device
* @data: This is always passed as NULL, and is not used in this API,
* but is required here as the device_for_each_child() API expects
* the passed function to have this as an argument.
*
* Return: -errno on failure, 0 on success.
*/
static int reset_cdx_device(struct device *dev, void *data)
{
return cdx_dev_reset(dev);
}
/**
* cdx_unregister_device - Unregister a CDX device
* @dev: CDX device
@ -120,9 +138,17 @@ static int cdx_unregister_device(struct device *dev,
void *data)
{
struct cdx_device *cdx_dev = to_cdx_device(dev);
struct cdx_controller *cdx = cdx_dev->cdx;
if (cdx_dev->is_bus) {
device_for_each_child(dev, NULL, cdx_unregister_device);
if (cdx_dev->enabled && cdx->ops->bus_disable)
cdx->ops->bus_disable(cdx, cdx_dev->bus_num);
} else {
kfree(cdx_dev->driver_override);
cdx_dev->driver_override = NULL;
}
kfree(cdx_dev->driver_override);
cdx_dev->driver_override = NULL;
/*
* Do not free cdx_dev here as it would be freed in
* cdx_device_release() called from within put_device().
@ -153,7 +179,10 @@ cdx_match_one_device(const struct cdx_device_id *id,
{
/* Use vendor ID and device ID for matching */
if ((id->vendor == CDX_ANY_ID || id->vendor == dev->vendor) &&
(id->device == CDX_ANY_ID || id->device == dev->device))
(id->device == CDX_ANY_ID || id->device == dev->device) &&
(id->subvendor == CDX_ANY_ID || id->subvendor == dev->subsystem_vendor) &&
(id->subdevice == CDX_ANY_ID || id->subdevice == dev->subsystem_device) &&
!((id->class ^ dev->class) & id->class_mask))
return id;
return NULL;
}
@ -229,6 +258,9 @@ static int cdx_bus_match(struct device *dev, struct device_driver *drv)
const struct cdx_device_id *found_id = NULL;
const struct cdx_device_id *ids;
if (cdx_dev->is_bus)
return false;
ids = cdx_drv->match_id_table;
/* When driver_override is set, only bind to the matching driver */
@ -293,10 +325,11 @@ static int cdx_dma_configure(struct device *dev)
{
struct cdx_driver *cdx_drv = to_cdx_driver(dev->driver);
struct cdx_device *cdx_dev = to_cdx_device(dev);
struct cdx_controller *cdx = cdx_dev->cdx;
u32 input_id = cdx_dev->req_id;
int ret;
ret = of_dma_configure_id(dev, dev->parent->of_node, 0, &input_id);
ret = of_dma_configure_id(dev, cdx->dev->of_node, 0, &input_id);
if (ret && ret != -EPROBE_DEFER) {
dev_err(dev, "of_dma_configure_id() failed\n");
return ret;
@ -331,6 +364,10 @@ static DEVICE_ATTR_RO(field)
cdx_config_attr(vendor, "0x%04x\n");
cdx_config_attr(device, "0x%04x\n");
cdx_config_attr(subsystem_vendor, "0x%04x\n");
cdx_config_attr(subsystem_device, "0x%04x\n");
cdx_config_attr(revision, "0x%02x\n");
cdx_config_attr(class, "0x%06x\n");
static ssize_t remove_store(struct device *dev,
struct device_attribute *attr,
@ -359,6 +396,7 @@ static DEVICE_ATTR_WO(remove);
static ssize_t reset_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
struct cdx_device *cdx_dev = to_cdx_device(dev);
bool val;
int ret;
@ -368,14 +406,27 @@ static ssize_t reset_store(struct device *dev, struct device_attribute *attr,
if (!val)
return -EINVAL;
ret = cdx_dev_reset(dev);
if (ret)
return ret;
if (cdx_dev->is_bus)
/* Reset all the devices attached to cdx bus */
ret = device_for_each_child(dev, NULL, reset_cdx_device);
else
ret = cdx_dev_reset(dev);
return count;
return ret < 0 ? ret : count;
}
static DEVICE_ATTR_WO(reset);
static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
struct cdx_device *cdx_dev = to_cdx_device(dev);
return sprintf(buf, "cdx:v%04Xd%04Xsv%04Xsd%04Xc%06X\n", cdx_dev->vendor,
cdx_dev->device, cdx_dev->subsystem_vendor, cdx_dev->subsystem_device,
cdx_dev->class);
}
static DEVICE_ATTR_RO(modalias);
static ssize_t driver_override_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
@ -402,21 +453,107 @@ static ssize_t driver_override_show(struct device *dev,
}
static DEVICE_ATTR_RW(driver_override);
static ssize_t enable_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
struct cdx_device *cdx_dev = to_cdx_device(dev);
struct cdx_controller *cdx = cdx_dev->cdx;
bool enable;
int ret;
if (kstrtobool(buf, &enable) < 0)
return -EINVAL;
if (enable == cdx_dev->enabled)
return count;
if (enable && cdx->ops->bus_enable)
ret = cdx->ops->bus_enable(cdx, cdx_dev->bus_num);
else if (!enable && cdx->ops->bus_disable)
ret = cdx->ops->bus_disable(cdx, cdx_dev->bus_num);
else
ret = -EOPNOTSUPP;
if (!ret)
cdx_dev->enabled = enable;
return ret < 0 ? ret : count;
}
static ssize_t enable_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct cdx_device *cdx_dev = to_cdx_device(dev);
return sysfs_emit(buf, "%u\n", cdx_dev->enabled);
}
static DEVICE_ATTR_RW(enable);
static umode_t cdx_dev_attrs_are_visible(struct kobject *kobj, struct attribute *a, int n)
{
struct device *dev = kobj_to_dev(kobj);
struct cdx_device *cdx_dev;
cdx_dev = to_cdx_device(dev);
if (!cdx_dev->is_bus)
return a->mode;
return 0;
}
static umode_t cdx_bus_attrs_are_visible(struct kobject *kobj, struct attribute *a, int n)
{
struct device *dev = kobj_to_dev(kobj);
struct cdx_device *cdx_dev;
cdx_dev = to_cdx_device(dev);
if (cdx_dev->is_bus)
return a->mode;
return 0;
}
static struct attribute *cdx_dev_attrs[] = {
&dev_attr_remove.attr,
&dev_attr_reset.attr,
&dev_attr_vendor.attr,
&dev_attr_device.attr,
&dev_attr_subsystem_vendor.attr,
&dev_attr_subsystem_device.attr,
&dev_attr_class.attr,
&dev_attr_revision.attr,
&dev_attr_modalias.attr,
&dev_attr_driver_override.attr,
NULL,
};
ATTRIBUTE_GROUPS(cdx_dev);
static const struct attribute_group cdx_dev_group = {
.attrs = cdx_dev_attrs,
.is_visible = cdx_dev_attrs_are_visible,
};
static struct attribute *cdx_bus_dev_attrs[] = {
&dev_attr_enable.attr,
&dev_attr_reset.attr,
NULL,
};
static const struct attribute_group cdx_bus_dev_group = {
.attrs = cdx_bus_dev_attrs,
.is_visible = cdx_bus_attrs_are_visible,
};
static const struct attribute_group *cdx_dev_groups[] = {
&cdx_dev_group,
&cdx_bus_dev_group,
NULL,
};
static ssize_t rescan_store(const struct bus_type *bus,
const char *buf, size_t count)
{
struct cdx_controller *cdx;
unsigned long index;
struct platform_device *pd;
struct device_node *np;
bool val;
if (kstrtobool(buf, &val) < 0)
@ -425,18 +562,29 @@ static ssize_t rescan_store(const struct bus_type *bus,
if (!val)
return -EINVAL;
mutex_lock(&cdx_controller_lock);
/* Unregister all the devices on the bus */
cdx_unregister_devices(&cdx_bus_type);
/* Rescan all the devices */
xa_for_each(&cdx_controllers, index, cdx) {
int ret;
for_each_compatible_node(np, NULL, compat_node_name) {
if (!np)
return -EINVAL;
ret = cdx->ops->scan(cdx);
if (ret)
dev_err(cdx->dev, "cdx bus scanning failed\n");
pd = of_find_device_by_node(np);
if (!pd)
return -EINVAL;
cdx = platform_get_drvdata(pd);
if (cdx && cdx->controller_registered && cdx->ops->scan)
cdx->ops->scan(cdx);
put_device(&pd->dev);
}
mutex_unlock(&cdx_controller_lock);
return count;
}
static BUS_ATTR_WO(rescan);
@ -495,7 +643,6 @@ static void cdx_device_release(struct device *dev)
int cdx_device_add(struct cdx_dev_params *dev_params)
{
struct cdx_controller *cdx = dev_params->cdx;
struct device *parent = cdx->dev;
struct cdx_device *cdx_dev;
int ret;
@ -512,6 +659,10 @@ int cdx_device_add(struct cdx_dev_params *dev_params)
cdx_dev->req_id = dev_params->req_id;
cdx_dev->vendor = dev_params->vendor;
cdx_dev->device = dev_params->device;
cdx_dev->subsystem_vendor = dev_params->subsys_vendor;
cdx_dev->subsystem_device = dev_params->subsys_device;
cdx_dev->class = dev_params->class;
cdx_dev->revision = dev_params->revision;
cdx_dev->bus_num = dev_params->bus_num;
cdx_dev->dev_num = dev_params->dev_num;
cdx_dev->cdx = dev_params->cdx;
@ -519,7 +670,7 @@ int cdx_device_add(struct cdx_dev_params *dev_params)
/* Initialize generic device */
device_initialize(&cdx_dev->dev);
cdx_dev->dev.parent = parent;
cdx_dev->dev.parent = dev_params->parent;
cdx_dev->dev.bus = &cdx_bus_type;
cdx_dev->dev.dma_mask = &cdx_dev->dma_mask;
cdx_dev->dev.release = cdx_device_release;
@ -546,37 +697,94 @@ int cdx_device_add(struct cdx_dev_params *dev_params)
return ret;
}
EXPORT_SYMBOL_GPL(cdx_device_add);
EXPORT_SYMBOL_NS_GPL(cdx_device_add, CDX_BUS_CONTROLLER);
struct device *cdx_bus_add(struct cdx_controller *cdx, u8 bus_num)
{
struct cdx_device *cdx_dev;
int ret;
cdx_dev = kzalloc(sizeof(*cdx_dev), GFP_KERNEL);
if (!cdx_dev)
return NULL;
device_initialize(&cdx_dev->dev);
cdx_dev->cdx = cdx;
cdx_dev->dev.parent = cdx->dev;
cdx_dev->dev.bus = &cdx_bus_type;
cdx_dev->dev.release = cdx_device_release;
cdx_dev->is_bus = true;
cdx_dev->bus_num = bus_num;
dev_set_name(&cdx_dev->dev, "cdx-%02x",
((cdx->id << CDX_CONTROLLER_ID_SHIFT) | (bus_num & CDX_BUS_NUM_MASK)));
ret = device_add(&cdx_dev->dev);
if (ret) {
dev_err(&cdx_dev->dev, "cdx bus device add failed: %d\n", ret);
goto device_add_fail;
}
if (cdx->ops->bus_enable) {
ret = cdx->ops->bus_enable(cdx, bus_num);
if (ret && ret != -EALREADY) {
dev_err(cdx->dev, "cdx bus enable failed: %d\n", ret);
goto bus_enable_fail;
}
}
cdx_dev->enabled = true;
return &cdx_dev->dev;
bus_enable_fail:
device_del(&cdx_dev->dev);
device_add_fail:
put_device(&cdx_dev->dev);
return NULL;
}
EXPORT_SYMBOL_NS_GPL(cdx_bus_add, CDX_BUS_CONTROLLER);
int cdx_register_controller(struct cdx_controller *cdx)
{
int ret;
ret = xa_alloc(&cdx_controllers, &cdx->id, cdx,
XA_LIMIT(0, MAX_CDX_CONTROLLERS - 1), GFP_KERNEL);
if (ret) {
ret = ida_alloc_range(&cdx_controller_ida, 0, MAX_CDX_CONTROLLERS - 1, GFP_KERNEL);
if (ret < 0) {
dev_err(cdx->dev,
"No free index available. Maximum controllers already registered\n");
cdx->id = (u8)MAX_CDX_CONTROLLERS;
return ret;
}
mutex_lock(&cdx_controller_lock);
cdx->id = ret;
/* Scan all the devices */
cdx->ops->scan(cdx);
if (cdx->ops->scan)
cdx->ops->scan(cdx);
cdx->controller_registered = true;
mutex_unlock(&cdx_controller_lock);
return 0;
}
EXPORT_SYMBOL_GPL(cdx_register_controller);
EXPORT_SYMBOL_NS_GPL(cdx_register_controller, CDX_BUS_CONTROLLER);
void cdx_unregister_controller(struct cdx_controller *cdx)
{
if (cdx->id >= MAX_CDX_CONTROLLERS)
return;
mutex_lock(&cdx_controller_lock);
cdx->controller_registered = false;
device_for_each_child(cdx->dev, NULL, cdx_unregister_device);
xa_erase(&cdx_controllers, cdx->id);
ida_free(&cdx_controller_ida, cdx->id);
mutex_unlock(&cdx_controller_lock);
}
EXPORT_SYMBOL_GPL(cdx_unregister_controller);
EXPORT_SYMBOL_NS_GPL(cdx_unregister_controller, CDX_BUS_CONTROLLER);
static int __init cdx_bus_init(void)
{

View File

@ -13,24 +13,33 @@
/**
* struct cdx_dev_params - CDX device parameters
* @cdx: CDX controller associated with the device
* @parent: Associated CDX controller
* @parent: Associated CDX Bus device
* @vendor: Vendor ID for CDX device
* @device: Device ID for CDX device
* @subsys_vendor: Sub vendor ID for CDX device
* @subsys_device: Sub device ID for CDX device
* @bus_num: Bus number for this CDX device
* @dev_num: Device number for this device
* @res: array of MMIO region entries
* @res_count: number of valid MMIO regions
* @req_id: Requestor ID associated with CDX device
* @class: Class of the CDX Device
* @revision: Revision of the CDX device
*/
struct cdx_dev_params {
struct cdx_controller *cdx;
struct device *parent;
u16 vendor;
u16 device;
u16 subsys_vendor;
u16 subsys_device;
u8 bus_num;
u8 dev_num;
struct resource res[MAX_CDX_DEV_RESOURCES];
u8 res_count;
u32 req_id;
u32 class;
u8 revision;
};
/**
@ -59,4 +68,15 @@ void cdx_unregister_controller(struct cdx_controller *cdx);
*/
int cdx_device_add(struct cdx_dev_params *dev_params);
/**
* cdx_bus_add - Add a CDX bus. This function adds a bus on the CDX bus
* subsystem. It creates a CDX device for the corresponding bus and
* also registers an associated Linux generic device.
* @cdx: Associated CDX controller
* @us_num: Bus number
*
* Return: associated Linux generic device pointer on success or NULL on failure.
*/
struct device *cdx_bus_add(struct cdx_controller *cdx, u8 bus_num);
#endif /* _CDX_H_ */

View File

@ -33,6 +33,16 @@ static const struct cdx_mcdi_ops mcdi_ops = {
.mcdi_request = cdx_mcdi_request,
};
static int cdx_bus_enable(struct cdx_controller *cdx, u8 bus_num)
{
return cdx_mcdi_bus_enable(cdx->priv, bus_num);
}
static int cdx_bus_disable(struct cdx_controller *cdx, u8 bus_num)
{
return cdx_mcdi_bus_disable(cdx->priv, bus_num);
}
void cdx_rpmsg_post_probe(struct cdx_controller *cdx)
{
/* Register CDX controller with CDX bus driver */
@ -83,8 +93,14 @@ static int cdx_scan_devices(struct cdx_controller *cdx)
num_cdx_bus = (u8)ret;
for (bus_num = 0; bus_num < num_cdx_bus; bus_num++) {
struct device *bus_dev;
u8 num_cdx_dev;
/* Add the bus on cdx subsystem */
bus_dev = cdx_bus_add(cdx, bus_num);
if (!bus_dev)
continue;
/* MCDI FW Read: Fetch the number of devices present */
ret = cdx_mcdi_get_num_devs(cdx_mcdi, bus_num);
if (ret < 0) {
@ -107,6 +123,7 @@ static int cdx_scan_devices(struct cdx_controller *cdx)
continue;
}
dev_params.cdx = cdx;
dev_params.parent = bus_dev;
/* Add the device to the cdx bus */
ret = cdx_device_add(&dev_params);
@ -125,6 +142,8 @@ static int cdx_scan_devices(struct cdx_controller *cdx)
}
static struct cdx_ops cdx_ops = {
.bus_enable = cdx_bus_enable,
.bus_disable = cdx_bus_disable,
.scan = cdx_scan_devices,
.dev_configure = cdx_configure_device,
};
@ -233,3 +252,4 @@ module_exit(cdx_controller_exit);
MODULE_AUTHOR("AMD Inc.");
MODULE_DESCRIPTION("CDX controller for AMD devices");
MODULE_LICENSE("GPL");
MODULE_IMPORT_NS(CDX_BUS_CONTROLLER);

View File

@ -455,6 +455,60 @@
#define MC_CMD_CDX_BUS_GET_DEVICE_CONFIG_OUT_REQUESTER_ID_OFST 84
#define MC_CMD_CDX_BUS_GET_DEVICE_CONFIG_OUT_REQUESTER_ID_LEN 4
/***********************************/
/*
* MC_CMD_CDX_BUS_DOWN
* Asserting reset on the CDX bus causes all devices on the bus to be quiesced.
* DMA bus mastering is disabled and any pending DMA request are flushed. Once
* the response is returned, the devices are guaranteed to no longer issue DMA
* requests or raise MSI interrupts. Further device MMIO accesses may have
* undefined results. While the bus reset is asserted, any of the enumeration
* or device configuration MCDIs will fail with EAGAIN. It is only legal to
* reload the relevant PL region containing CDX devices if the corresponding CDX
* bus is in reset. Depending on the implementation, the firmware may or may
* not enforce this restriction and it is up to the caller to make sure this
* requirement is satisfied.
*/
#define MC_CMD_CDX_BUS_DOWN 0x4
#define MC_CMD_CDX_BUS_DOWN_MSGSET 0x4
/* MC_CMD_CDX_BUS_DOWN_IN msgrequest */
#define MC_CMD_CDX_BUS_DOWN_IN_LEN 4
/* Bus number to put in reset, in range 0 to BUS_COUNT-1 */
#define MC_CMD_CDX_BUS_DOWN_IN_BUS_OFST 0
#define MC_CMD_CDX_BUS_DOWN_IN_BUS_LEN 4
/*
* MC_CMD_CDX_BUS_DOWN_OUT msgresponse: The bus is quiesced, no further
* upstream traffic for devices on this bus.
*/
#define MC_CMD_CDX_BUS_DOWN_OUT_LEN 0
/***********************************/
/*
* MC_CMD_CDX_BUS_UP
* After bus reset is de-asserted, devices are in a state which is functionally
* equivalent to each device having been reset with MC_CMD_CDX_DEVICE_RESET. In
* other words, device logic is reset in a hardware-specific way, MMIO accesses
* are forwarded to the device, DMA bus mastering is disabled and needs to be
* re-enabled with MC_CMD_CDX_DEVICE_DMA_ENABLE once the driver is ready to
* start servicing DMA. If the underlying number of devices or device resources
* changed (e.g. if PL was reloaded) while the bus was in reset, the bus driver
* is expected to re-enumerate the bus. Returns EALREADY if the bus was already
* up before the call.
*/
#define MC_CMD_CDX_BUS_UP 0x5
#define MC_CMD_CDX_BUS_UP_MSGSET 0x5
/* MC_CMD_CDX_BUS_UP_IN msgrequest */
#define MC_CMD_CDX_BUS_UP_IN_LEN 4
/* Bus number to take out of reset, in range 0 to BUS_COUNT-1 */
#define MC_CMD_CDX_BUS_UP_IN_BUS_OFST 0
#define MC_CMD_CDX_BUS_UP_IN_BUS_LEN 4
/* MC_CMD_CDX_BUS_UP_OUT msgresponse: The bus can now be enumerated. */
#define MC_CMD_CDX_BUS_UP_OUT_LEN 0
/***********************************/
/*
* MC_CMD_CDX_DEVICE_RESET

View File

@ -120,10 +120,41 @@ int cdx_mcdi_get_dev_config(struct cdx_mcdi *cdx,
dev_params->vendor = MCDI_WORD(outbuf, CDX_BUS_GET_DEVICE_CONFIG_OUT_VENDOR_ID);
dev_params->device = MCDI_WORD(outbuf, CDX_BUS_GET_DEVICE_CONFIG_OUT_DEVICE_ID);
dev_params->subsys_vendor = MCDI_WORD(outbuf,
CDX_BUS_GET_DEVICE_CONFIG_OUT_SUBSYS_VENDOR_ID);
dev_params->subsys_device = MCDI_WORD(outbuf,
CDX_BUS_GET_DEVICE_CONFIG_OUT_SUBSYS_DEVICE_ID);
dev_params->class = MCDI_DWORD(outbuf,
CDX_BUS_GET_DEVICE_CONFIG_OUT_DEVICE_CLASS) & 0xFFFFFF;
dev_params->revision = MCDI_BYTE(outbuf, CDX_BUS_GET_DEVICE_CONFIG_OUT_DEVICE_REVISION);
return 0;
}
int cdx_mcdi_bus_enable(struct cdx_mcdi *cdx, u8 bus_num)
{
MCDI_DECLARE_BUF(inbuf, MC_CMD_CDX_BUS_UP_IN_LEN);
int ret;
MCDI_SET_DWORD(inbuf, CDX_BUS_UP_IN_BUS, bus_num);
ret = cdx_mcdi_rpc(cdx, MC_CMD_CDX_BUS_UP, inbuf, sizeof(inbuf),
NULL, 0, NULL);
return ret;
}
int cdx_mcdi_bus_disable(struct cdx_mcdi *cdx, u8 bus_num)
{
MCDI_DECLARE_BUF(inbuf, MC_CMD_CDX_BUS_DOWN_IN_LEN);
int ret;
MCDI_SET_DWORD(inbuf, CDX_BUS_DOWN_IN_BUS, bus_num);
ret = cdx_mcdi_rpc(cdx, MC_CMD_CDX_BUS_DOWN, inbuf, sizeof(inbuf),
NULL, 0, NULL);
return ret;
}
int cdx_mcdi_reset_device(struct cdx_mcdi *cdx, u8 bus_num, u8 dev_num)
{
MCDI_DECLARE_BUF(inbuf, MC_CMD_CDX_DEVICE_RESET_IN_LEN);

View File

@ -47,6 +47,24 @@ int cdx_mcdi_get_dev_config(struct cdx_mcdi *cdx,
u8 bus_num, u8 dev_num,
struct cdx_dev_params *dev_params);
/**
* cdx_mcdi_bus_enable - Enable CDX bus represented by bus_num
* @cdx: pointer to MCDI interface.
* @bus_num: Bus number.
*
* Return: 0 on success, <0 on failure
*/
int cdx_mcdi_bus_enable(struct cdx_mcdi *cdx, u8 bus_num);
/**
* cdx_mcdi_bus_disable - Disable CDX bus represented by bus_num
* @cdx: pointer to MCDI interface.
* @bus_num: Bus number.
*
* Return: 0 on success, <0 on failure
*/
int cdx_mcdi_bus_disable(struct cdx_mcdi *cdx, u8 bus_num);
/**
* cdx_mcdi_reset_device - Reset cdx device represented by bus_num:dev_num
* @cdx: pointer to MCDI interface.

View File

@ -92,7 +92,7 @@ struct hpets {
unsigned long hp_delta;
unsigned int hp_ntimer;
unsigned int hp_which;
struct hpet_dev hp_dev[];
struct hpet_dev hp_dev[] __counted_by(hp_ntimer);
};
static struct hpets *hpets;

View File

@ -628,6 +628,7 @@ static int open_port(struct inode *inode, struct file *filp)
#define full_lseek null_lseek
#define write_zero write_null
#define write_iter_zero write_iter_null
#define splice_write_zero splice_write_null
#define open_mem open_port
static const struct file_operations __maybe_unused mem_fops = {
@ -665,6 +666,8 @@ static const struct file_operations zero_fops = {
.read_iter = read_iter_zero,
.read = read_zero,
.write_iter = write_iter_zero,
.splice_read = copy_splice_read,
.splice_write = splice_write_zero,
.mmap = mmap_zero,
.get_unmapped_area = get_unmapped_area_zero,
#ifndef CONFIG_MMU
@ -676,6 +679,7 @@ static const struct file_operations full_fops = {
.llseek = full_lseek,
.read_iter = read_iter_zero,
.write = write_full,
.splice_read = copy_splice_read,
};
static const struct memdev {

View File

@ -84,18 +84,13 @@
#include <linux/sysctl.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/slab.h>
#include <linux/io.h>
#include <linux/uaccess.h>
#ifdef CONFIG_OF
/* For open firmware. */
#include <linux/of_address.h>
#include <linux/of_device.h>
#include <linux/of_platform.h>
#endif
#include "xilinx_hwicap.h"
#include "buffer_icap.h"
#include "fifo_icap.h"
@ -601,14 +596,14 @@ static const struct file_operations hwicap_fops = {
.llseek = noop_llseek,
};
static int hwicap_setup(struct device *dev, int id,
const struct resource *regs_res,
static int hwicap_setup(struct platform_device *pdev, int id,
const struct hwicap_driver_config *config,
const struct config_registers *config_regs)
{
dev_t devt;
struct hwicap_drvdata *drvdata = NULL;
int retval = 0;
struct device *dev = &pdev->dev;
int retval;
dev_info(dev, "Xilinx icap port driver\n");
@ -636,72 +631,39 @@ static int hwicap_setup(struct device *dev, int id,
devt = MKDEV(XHWICAP_MAJOR, XHWICAP_MINOR + id);
drvdata = kzalloc(sizeof(struct hwicap_drvdata), GFP_KERNEL);
drvdata = devm_kzalloc(dev, sizeof(struct hwicap_drvdata), GFP_KERNEL);
if (!drvdata) {
retval = -ENOMEM;
goto failed0;
goto failed;
}
dev_set_drvdata(dev, (void *)drvdata);
if (!regs_res) {
dev_err(dev, "Couldn't get registers resource\n");
retval = -EFAULT;
goto failed1;
}
drvdata->mem_start = regs_res->start;
drvdata->mem_end = regs_res->end;
drvdata->mem_size = resource_size(regs_res);
if (!request_mem_region(drvdata->mem_start,
drvdata->mem_size, DRIVER_NAME)) {
dev_err(dev, "Couldn't lock memory region at %Lx\n",
(unsigned long long) regs_res->start);
retval = -EBUSY;
goto failed1;
drvdata->base_address = devm_platform_ioremap_resource(pdev, 0);
if (!drvdata->base_address) {
retval = -ENODEV;
goto failed;
}
drvdata->devt = devt;
drvdata->dev = dev;
drvdata->base_address = ioremap(drvdata->mem_start, drvdata->mem_size);
if (!drvdata->base_address) {
dev_err(dev, "ioremap() failed\n");
retval = -ENOMEM;
goto failed2;
}
drvdata->config = config;
drvdata->config_regs = config_regs;
mutex_init(&drvdata->sem);
drvdata->is_open = 0;
dev_info(dev, "ioremap %llx to %p with size %llx\n",
(unsigned long long) drvdata->mem_start,
drvdata->base_address,
(unsigned long long) drvdata->mem_size);
cdev_init(&drvdata->cdev, &hwicap_fops);
drvdata->cdev.owner = THIS_MODULE;
retval = cdev_add(&drvdata->cdev, devt, 1);
if (retval) {
dev_err(dev, "cdev_add() failed\n");
goto failed3;
goto failed;
}
device_create(&icap_class, dev, devt, NULL, "%s%d", DRIVER_NAME, id);
return 0; /* success */
failed3:
iounmap(drvdata->base_address);
failed2:
release_mem_region(regs_res->start, drvdata->mem_size);
failed1:
kfree(drvdata);
failed0:
failed:
mutex_lock(&icap_sem);
probed_devices[id] = 0;
mutex_unlock(&icap_sem);
@ -723,75 +685,22 @@ static struct hwicap_driver_config fifo_icap_config = {
.reset = fifo_icap_reset,
};
#ifdef CONFIG_OF
static int hwicap_of_probe(struct platform_device *op,
const struct hwicap_driver_config *config)
{
struct resource res;
const unsigned int *id;
const char *family;
int rc;
const struct config_registers *regs;
rc = of_address_to_resource(op->dev.of_node, 0, &res);
if (rc) {
dev_err(&op->dev, "invalid address\n");
return rc;
}
id = of_get_property(op->dev.of_node, "port-number", NULL);
/* It's most likely that we're using V4, if the family is not
* specified
*/
regs = &v4_config_registers;
family = of_get_property(op->dev.of_node, "xlnx,family", NULL);
if (family) {
if (!strcmp(family, "virtex2p"))
regs = &v2_config_registers;
else if (!strcmp(family, "virtex4"))
regs = &v4_config_registers;
else if (!strcmp(family, "virtex5"))
regs = &v5_config_registers;
else if (!strcmp(family, "virtex6"))
regs = &v6_config_registers;
}
return hwicap_setup(&op->dev, id ? *id : -1, &res, config,
regs);
}
#else
static inline int hwicap_of_probe(struct platform_device *op,
const struct hwicap_driver_config *config)
{
return -EINVAL;
}
#endif /* CONFIG_OF */
static const struct of_device_id hwicap_of_match[];
static int hwicap_drv_probe(struct platform_device *pdev)
{
const struct of_device_id *match;
struct resource *res;
const struct config_registers *regs;
const struct hwicap_driver_config *config;
const char *family;
int id = -1;
match = of_match_device(hwicap_of_match, &pdev->dev);
if (match)
return hwicap_of_probe(pdev, match->data);
config = device_get_match_data(&pdev->dev);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res)
return -ENODEV;
of_property_read_u32(pdev->dev.of_node, "port-number", &id);
/* It's most likely that we're using V4, if the family is not
* specified
*/
regs = &v4_config_registers;
family = pdev->dev.platform_data;
if (family) {
if (!of_property_read_string(pdev->dev.of_node, "xlnx,family", &family)) {
if (!strcmp(family, "virtex2p"))
regs = &v2_config_registers;
else if (!strcmp(family, "virtex4"))
@ -801,9 +710,7 @@ static int hwicap_drv_probe(struct platform_device *pdev)
else if (!strcmp(family, "virtex6"))
regs = &v6_config_registers;
}
return hwicap_setup(&pdev->dev, pdev->id, res,
&buffer_icap_config, regs);
return hwicap_setup(pdev, id, config, regs);
}
static void hwicap_drv_remove(struct platform_device *pdev)
@ -815,16 +722,12 @@ static void hwicap_drv_remove(struct platform_device *pdev)
device_destroy(&icap_class, drvdata->devt);
cdev_del(&drvdata->cdev);
iounmap(drvdata->base_address);
release_mem_region(drvdata->mem_start, drvdata->mem_size);
kfree(drvdata);
mutex_lock(&icap_sem);
probed_devices[MINOR(dev->devt)-XHWICAP_MINOR] = 0;
mutex_unlock(&icap_sem);
}
#ifdef CONFIG_OF
/* Match table for device tree binding */
static const struct of_device_id hwicap_of_match[] = {
{ .compatible = "xlnx,opb-hwicap-1.00.b", .data = &buffer_icap_config},
@ -832,9 +735,6 @@ static const struct of_device_id hwicap_of_match[] = {
{},
};
MODULE_DEVICE_TABLE(of, hwicap_of_match);
#else
#define hwicap_of_match NULL
#endif
static struct platform_driver hwicap_platform_driver = {
.probe = hwicap_drv_probe,

View File

@ -67,6 +67,7 @@ config COMEDI_TEST
config COMEDI_PARPORT
tristate "Parallel port support"
depends on HAS_IOPORT
help
Enable support for the standard parallel port.
A cheap and easy way to get a few more digital I/O lines. Steal
@ -79,6 +80,7 @@ config COMEDI_PARPORT
config COMEDI_SSV_DNP
tristate "SSV Embedded Systems DIL/Net-PC support"
depends on X86_32 || COMPILE_TEST
depends on HAS_IOPORT
help
Enable support for SSV Embedded Systems DIL/Net-PC
@ -89,6 +91,8 @@ endif # COMEDI_MISC_DRIVERS
menuconfig COMEDI_ISA_DRIVERS
bool "Comedi ISA and PC/104 drivers"
depends on ISA || ISA_BUS || PC104
depends on HAS_IOPORT
help
Enable comedi ISA and PC/104 drivers to be built
@ -589,6 +593,7 @@ config COMEDI_8255_PCI
config COMEDI_ADDI_WATCHDOG
tristate
depends on HAS_IOPORT
help
Provides support for the watchdog subdevice found on many ADDI-DATA
boards. This module will be automatically selected when needed. The
@ -596,6 +601,7 @@ config COMEDI_ADDI_WATCHDOG
config COMEDI_ADDI_APCI_1032
tristate "ADDI-DATA APCI_1032 support"
depends on HAS_IOPORT
help
Enable support for ADDI-DATA APCI_1032 cards
@ -604,6 +610,7 @@ config COMEDI_ADDI_APCI_1032
config COMEDI_ADDI_APCI_1500
tristate "ADDI-DATA APCI_1500 support"
depends on HAS_IOPORT
help
Enable support for ADDI-DATA APCI_1500 cards
@ -612,6 +619,7 @@ config COMEDI_ADDI_APCI_1500
config COMEDI_ADDI_APCI_1516
tristate "ADDI-DATA APCI-1016/1516/2016 support"
depends on HAS_IOPORT
select COMEDI_ADDI_WATCHDOG
help
Enable support for ADDI-DATA APCI-1016, APCI-1516 and APCI-2016 boards.
@ -623,6 +631,7 @@ config COMEDI_ADDI_APCI_1516
config COMEDI_ADDI_APCI_1564
tristate "ADDI-DATA APCI_1564 support"
depends on HAS_IOPORT
select COMEDI_ADDI_WATCHDOG
help
Enable support for ADDI-DATA APCI_1564 cards
@ -632,6 +641,7 @@ config COMEDI_ADDI_APCI_1564
config COMEDI_ADDI_APCI_16XX
tristate "ADDI-DATA APCI_16xx support"
depends on HAS_IOPORT
help
Enable support for ADDI-DATA APCI_16xx cards
@ -640,6 +650,7 @@ config COMEDI_ADDI_APCI_16XX
config COMEDI_ADDI_APCI_2032
tristate "ADDI-DATA APCI_2032 support"
depends on HAS_IOPORT
select COMEDI_ADDI_WATCHDOG
help
Enable support for ADDI-DATA APCI_2032 cards
@ -649,6 +660,7 @@ config COMEDI_ADDI_APCI_2032
config COMEDI_ADDI_APCI_2200
tristate "ADDI-DATA APCI_2200 support"
depends on HAS_IOPORT
select COMEDI_ADDI_WATCHDOG
help
Enable support for ADDI-DATA APCI_2200 cards
@ -658,6 +670,7 @@ config COMEDI_ADDI_APCI_2200
config COMEDI_ADDI_APCI_3120
tristate "ADDI-DATA APCI_3120/3001 support"
depends on HAS_IOPORT
depends on HAS_DMA
help
Enable support for ADDI-DATA APCI_3120/3001 cards
@ -667,6 +680,7 @@ config COMEDI_ADDI_APCI_3120
config COMEDI_ADDI_APCI_3501
tristate "ADDI-DATA APCI_3501 support"
depends on HAS_IOPORT
help
Enable support for ADDI-DATA APCI_3501 cards
@ -675,6 +689,7 @@ config COMEDI_ADDI_APCI_3501
config COMEDI_ADDI_APCI_3XXX
tristate "ADDI-DATA APCI_3xxx support"
depends on HAS_IOPORT
help
Enable support for ADDI-DATA APCI_3xxx cards
@ -683,6 +698,7 @@ config COMEDI_ADDI_APCI_3XXX
config COMEDI_ADL_PCI6208
tristate "ADLink PCI-6208A support"
depends on HAS_IOPORT
help
Enable support for ADLink PCI-6208A cards
@ -691,6 +707,7 @@ config COMEDI_ADL_PCI6208
config COMEDI_ADL_PCI7X3X
tristate "ADLink PCI-723X/743X isolated digital i/o board support"
depends on HAS_IOPORT
help
Enable support for ADlink PCI-723X/743X isolated digital i/o boards.
Supported boards include the 32-channel PCI-7230 (16 in/16 out),
@ -702,6 +719,7 @@ config COMEDI_ADL_PCI7X3X
config COMEDI_ADL_PCI8164
tristate "ADLink PCI-8164 4 Axes Motion Control board support"
depends on HAS_IOPORT
help
Enable support for ADlink PCI-8164 4 Axes Motion Control board
@ -710,6 +728,7 @@ config COMEDI_ADL_PCI8164
config COMEDI_ADL_PCI9111
tristate "ADLink PCI-9111HR support"
depends on HAS_IOPORT
select COMEDI_8254
help
Enable support for ADlink PCI9111 cards
@ -719,6 +738,7 @@ config COMEDI_ADL_PCI9111
config COMEDI_ADL_PCI9118
tristate "ADLink PCI-9118DG, PCI-9118HG, PCI-9118HR support"
depends on HAS_IOPORT
depends on HAS_DMA
select COMEDI_8254
help
@ -729,6 +749,7 @@ config COMEDI_ADL_PCI9118
config COMEDI_ADV_PCI1710
tristate "Advantech PCI-171x and PCI-1731 support"
depends on HAS_IOPORT
select COMEDI_8254
help
Enable support for Advantech PCI-1710, PCI-1710HG, PCI-1711,
@ -739,6 +760,7 @@ config COMEDI_ADV_PCI1710
config COMEDI_ADV_PCI1720
tristate "Advantech PCI-1720 support"
depends on HAS_IOPORT
help
Enable support for Advantech PCI-1720 Analog Output board.
@ -747,6 +769,7 @@ config COMEDI_ADV_PCI1720
config COMEDI_ADV_PCI1723
tristate "Advantech PCI-1723 support"
depends on HAS_IOPORT
help
Enable support for Advantech PCI-1723 cards
@ -755,6 +778,7 @@ config COMEDI_ADV_PCI1723
config COMEDI_ADV_PCI1724
tristate "Advantech PCI-1724U support"
depends on HAS_IOPORT
help
Enable support for Advantech PCI-1724U cards. These are 32-channel
analog output cards with voltage and current loop output ranges and
@ -765,6 +789,7 @@ config COMEDI_ADV_PCI1724
config COMEDI_ADV_PCI1760
tristate "Advantech PCI-1760 support"
depends on HAS_IOPORT
help
Enable support for Advantech PCI-1760 board.
@ -773,6 +798,7 @@ config COMEDI_ADV_PCI1760
config COMEDI_ADV_PCI_DIO
tristate "Advantech PCI DIO card support"
depends on HAS_IOPORT
select COMEDI_8254
select COMEDI_8255
help
@ -796,6 +822,7 @@ config COMEDI_AMPLC_DIO200_PCI
config COMEDI_AMPLC_PC236_PCI
tristate "Amplicon PCI236 DIO board support"
depends on HAS_IOPORT
select COMEDI_AMPLC_PC236
help
Enable support for Amplicon PCI236 DIO board.
@ -805,6 +832,7 @@ config COMEDI_AMPLC_PC236_PCI
config COMEDI_AMPLC_PC263_PCI
tristate "Amplicon PCI263 relay board support"
depends on HAS_IOPORT
help
Enable support for Amplicon PCI263 relay board. This is a PCI board
with 16 reed relay output channels.
@ -814,6 +842,7 @@ config COMEDI_AMPLC_PC263_PCI
config COMEDI_AMPLC_PCI224
tristate "Amplicon PCI224 and PCI234 support"
depends on HAS_IOPORT
select COMEDI_8254
help
Enable support for Amplicon PCI224 and PCI234 AO boards
@ -823,6 +852,7 @@ config COMEDI_AMPLC_PCI224
config COMEDI_AMPLC_PCI230
tristate "Amplicon PCI230 and PCI260 support"
depends on HAS_IOPORT
select COMEDI_8254
select COMEDI_8255
help
@ -834,6 +864,7 @@ config COMEDI_AMPLC_PCI230
config COMEDI_CONTEC_PCI_DIO
tristate "Contec PIO1616L digital I/O board support"
depends on HAS_IOPORT
help
Enable support for the Contec PIO1616L digital I/O board
@ -842,6 +873,7 @@ config COMEDI_CONTEC_PCI_DIO
config COMEDI_DAS08_PCI
tristate "DAS-08 PCI support"
depends on HAS_IOPORT
select COMEDI_DAS08
help
Enable support for PCI DAS-08 cards.
@ -861,6 +893,7 @@ config COMEDI_DT3000
config COMEDI_DYNA_PCI10XX
tristate "Dynalog PCI DAQ series support"
depends on HAS_IOPORT
help
Enable support for Dynalog PCI DAQ series
PCI-1050
@ -911,6 +944,7 @@ config COMEDI_JR3_PCI
config COMEDI_KE_COUNTER
tristate "Kolter-Electronic PCI Counter 1 card support"
depends on HAS_IOPORT
help
Enable support for Kolter-Electronic PCI Counter 1 cards
@ -929,6 +963,7 @@ config COMEDI_CB_PCIDAS64
config COMEDI_CB_PCIDAS
tristate "MeasurementComputing PCI-DAS support"
depends on HAS_IOPORT
select COMEDI_8254
select COMEDI_8255
help
@ -942,6 +977,7 @@ config COMEDI_CB_PCIDAS
config COMEDI_CB_PCIDDA
tristate "MeasurementComputing PCI-DDA series support"
depends on HAS_IOPORT
select COMEDI_8255
help
Enable support for ComputerBoards/MeasurementComputing PCI-DDA
@ -953,6 +989,7 @@ config COMEDI_CB_PCIDDA
config COMEDI_CB_PCIMDAS
tristate "MeasurementComputing PCIM-DAS1602/16, PCIe-DAS1602/16 support"
depends on HAS_IOPORT
select COMEDI_8254
select COMEDI_8255
help
@ -964,6 +1001,7 @@ config COMEDI_CB_PCIMDAS
config COMEDI_CB_PCIMDDA
tristate "MeasurementComputing PCIM-DDA06-16 support"
depends on HAS_IOPORT
select COMEDI_8255
help
Enable support for ComputerBoards/MeasurementComputing PCIM-DDA06-16
@ -973,6 +1011,7 @@ config COMEDI_CB_PCIMDDA
config COMEDI_ME4000
tristate "Meilhaus ME-4000 support"
depends on HAS_IOPORT
select COMEDI_8254
help
Enable support for Meilhaus PCI data acquisition cards
@ -1042,7 +1081,6 @@ config COMEDI_NI_PCIDIO
tristate "NI PCI-DIO32HS, PCI-6533, PCI-6534 support"
depends on HAS_DMA
select COMEDI_MITE
select COMEDI_8255
help
Enable support for National Instruments PCI-DIO-32HS, PXI-6533,
PCI-6533 and PCI-6534
@ -1103,7 +1141,7 @@ endif # COMEDI_PCI_DRIVERS
menuconfig COMEDI_PCMCIA_DRIVERS
tristate "Comedi PCMCIA drivers"
depends on PCMCIA
depends on PCMCIA && HAS_IOPORT
help
Enable support for comedi PCMCIA drivers.
@ -1254,6 +1292,7 @@ config COMEDI_8255
config COMEDI_8255_SA
tristate "Standalone 8255 support"
depends on HAS_IOPORT
select COMEDI_8255
help
Enable support for 8255 digital I/O as a standalone driver.
@ -1290,10 +1329,12 @@ config COMEDI_AMPLC_DIO200
config COMEDI_AMPLC_PC236
tristate
depends on HAS_IOPORT
select COMEDI_8255
config COMEDI_DAS08
tristate
depends on HAS_IOPORT
select COMEDI_8254
select COMEDI_8255

View File

@ -177,7 +177,8 @@ static void comedi_device_detach_cleanup(struct comedi_device *dev)
dev->n_subdevices = 0;
}
kfree(dev->private);
kfree(dev->pacer);
if (!IS_ERR(dev->pacer))
kfree(dev->pacer);
dev->private = NULL;
dev->pacer = NULL;
dev->driver = NULL;

View File

@ -80,7 +80,7 @@ static int dev_8255_attach(struct comedi_device *dev,
if (ret) {
s->type = COMEDI_SUBD_UNUSED;
} else {
ret = subdev_8255_init(dev, s, NULL, iobase);
ret = subdev_8255_io_init(dev, s, iobase);
if (ret) {
/*
* Release the I/O port region here, as the

View File

@ -57,6 +57,7 @@
#include <linux/comedi/comedi_8255.h>
enum pci_8255_boardid {
#ifdef CONFIG_HAS_IOPORT
BOARD_ADLINK_PCI7224,
BOARD_ADLINK_PCI7248,
BOARD_ADLINK_PCI7296,
@ -65,6 +66,7 @@ enum pci_8255_boardid {
BOARD_CB_PCIDIO48H_OLD,
BOARD_CB_PCIDIO48H_NEW,
BOARD_CB_PCIDIO96H,
#endif /* CONFIG_HAS_IOPORT */
BOARD_NI_PCIDIO96,
BOARD_NI_PCIDIO96B,
BOARD_NI_PXI6508,
@ -82,6 +84,7 @@ struct pci_8255_boardinfo {
};
static const struct pci_8255_boardinfo pci_8255_boards[] = {
#ifdef CONFIG_HAS_IOPORT
[BOARD_ADLINK_PCI7224] = {
.name = "adl_pci-7224",
.dio_badr = 2,
@ -122,6 +125,7 @@ static const struct pci_8255_boardinfo pci_8255_boards[] = {
.dio_badr = 2,
.n_8255 = 4,
},
#endif /* CONFIG_HAS_IOPORT */
[BOARD_NI_PCIDIO96] = {
.name = "ni_pci-dio-96",
.dio_badr = 1,
@ -219,8 +223,11 @@ static int pci_8255_auto_attach(struct comedi_device *dev,
dev->mmio = pci_ioremap_bar(pcidev, board->dio_badr);
if (!dev->mmio)
return -ENOMEM;
} else {
} else if (IS_ENABLED(CONFIG_HAS_IOPORT)) {
dev->iobase = pci_resource_start(pcidev, board->dio_badr);
} else {
dev_err(dev->class_dev, "error! need I/O port support\n");
return -ENXIO;
}
/*
@ -235,9 +242,9 @@ static int pci_8255_auto_attach(struct comedi_device *dev,
for (i = 0; i < board->n_8255; i++) {
s = &dev->subdevices[i];
if (dev->mmio)
ret = subdev_8255_mm_init(dev, s, NULL, i * I8255_SIZE);
ret = subdev_8255_mm_init(dev, s, i * I8255_SIZE);
else
ret = subdev_8255_init(dev, s, NULL, i * I8255_SIZE);
ret = subdev_8255_io_init(dev, s, i * I8255_SIZE);
if (ret)
return ret;
}
@ -259,6 +266,7 @@ static int pci_8255_pci_probe(struct pci_dev *dev,
}
static const struct pci_device_id pci_8255_pci_table[] = {
#ifdef CONFIG_HAS_IOPORT
{ PCI_VDEVICE(ADLINK, 0x7224), BOARD_ADLINK_PCI7224 },
{ PCI_VDEVICE(ADLINK, 0x7248), BOARD_ADLINK_PCI7248 },
{ PCI_VDEVICE(ADLINK, 0x7296), BOARD_ADLINK_PCI7296 },
@ -269,6 +277,7 @@ static const struct pci_device_id pci_8255_pci_table[] = {
{ PCI_DEVICE_SUB(PCI_VENDOR_ID_CB, 0x000b, PCI_VENDOR_ID_CB, 0x000b),
.driver_data = BOARD_CB_PCIDIO48H_NEW },
{ PCI_VDEVICE(CB, 0x0017), BOARD_CB_PCIDIO96H },
#endif /* CONFIG_HAS_IOPORT */
{ PCI_VDEVICE(NI, 0x0160), BOARD_NI_PCIDIO96 },
{ PCI_VDEVICE(NI, 0x1630), BOARD_NI_PCIDIO96B },
{ PCI_VDEVICE(NI, 0x13c0), BOARD_NI_PXI6508 },

View File

@ -647,10 +647,10 @@ static int pci9111_auto_attach(struct comedi_device *dev,
dev->irq = pcidev->irq;
}
dev->pacer = comedi_8254_init(dev->iobase + PCI9111_8254_BASE_REG,
I8254_OSC_BASE_2MHZ, I8254_IO16, 0);
if (!dev->pacer)
return -ENOMEM;
dev->pacer = comedi_8254_io_alloc(dev->iobase + PCI9111_8254_BASE_REG,
I8254_OSC_BASE_2MHZ, I8254_IO16, 0);
if (IS_ERR(dev->pacer))
return PTR_ERR(dev->pacer);
ret = comedi_alloc_subdevices(dev, 4);
if (ret)

View File

@ -1524,10 +1524,10 @@ static int pci9118_common_attach(struct comedi_device *dev,
devpriv->iobase_a = pci_resource_start(pcidev, 0);
dev->iobase = pci_resource_start(pcidev, 2);
dev->pacer = comedi_8254_init(dev->iobase + PCI9118_TIMER_BASE,
I8254_OSC_BASE_4MHZ, I8254_IO32, 0);
if (!dev->pacer)
return -ENOMEM;
dev->pacer = comedi_8254_io_alloc(dev->iobase + PCI9118_TIMER_BASE,
I8254_OSC_BASE_4MHZ, I8254_IO32, 0);
if (IS_ERR(dev->pacer))
return PTR_ERR(dev->pacer);
pci9118_reset(dev);

View File

@ -767,10 +767,10 @@ static int pci1710_auto_attach(struct comedi_device *dev,
return ret;
dev->iobase = pci_resource_start(pcidev, 2);
dev->pacer = comedi_8254_init(dev->iobase + PCI171X_TIMER_BASE,
I8254_OSC_BASE_10MHZ, I8254_IO16, 0);
if (!dev->pacer)
return -ENOMEM;
dev->pacer = comedi_8254_io_alloc(dev->iobase + PCI171X_TIMER_BASE,
I8254_OSC_BASE_10MHZ, I8254_IO16, 0);
if (IS_ERR(dev->pacer))
return PTR_ERR(dev->pacer);
n_subdevices = 1; /* all boards have analog inputs */
if (board->has_ao)

View File

@ -642,8 +642,8 @@ static int pci_dio_auto_attach(struct comedi_device *dev,
for (j = 0; j < d->chans; j++) {
s = &dev->subdevices[subdev++];
ret = subdev_8255_init(dev, s, NULL,
d->addr + j * I8255_SIZE);
ret = subdev_8255_io_init(dev, s,
d->addr + j * I8255_SIZE);
if (ret)
return ret;
}
@ -664,11 +664,11 @@ static int pci_dio_auto_attach(struct comedi_device *dev,
if (board->timer_regbase) {
s = &dev->subdevices[subdev++];
dev->pacer = comedi_8254_init(dev->iobase +
board->timer_regbase,
0, I8254_IO8, 0);
if (!dev->pacer)
return -ENOMEM;
dev->pacer =
comedi_8254_io_alloc(dev->iobase + board->timer_regbase,
0, I8254_IO8, 0);
if (IS_ERR(dev->pacer))
return PTR_ERR(dev->pacer);
comedi_8254_subdevice_init(s, dev->pacer);
}

View File

@ -206,10 +206,10 @@ static int aio_aio12_8_attach(struct comedi_device *dev,
if (ret)
return ret;
dev->pacer = comedi_8254_init(dev->iobase + AIO12_8_8254_BASE_REG,
0, I8254_IO8, 0);
if (!dev->pacer)
return -ENOMEM;
dev->pacer = comedi_8254_io_alloc(dev->iobase + AIO12_8_8254_BASE_REG,
0, I8254_IO8, 0);
if (IS_ERR(dev->pacer))
return PTR_ERR(dev->pacer);
ret = comedi_alloc_subdevices(dev, 4);
if (ret)
@ -247,7 +247,7 @@ static int aio_aio12_8_attach(struct comedi_device *dev,
/* Digital I/O subdevice (8255) */
s = &dev->subdevices[2];
ret = subdev_8255_init(dev, s, NULL, AIO12_8_8255_BASE_REG);
ret = subdev_8255_io_init(dev, s, AIO12_8_8255_BASE_REG);
if (ret)
return ret;

View File

@ -86,6 +86,70 @@ struct dio200_subdev_intr {
unsigned int active:1;
};
#ifdef CONFIG_HAS_IOPORT
static unsigned char dio200___read8(struct comedi_device *dev,
unsigned int offset)
{
if (dev->mmio)
return readb(dev->mmio + offset);
return inb(dev->iobase + offset);
}
static void dio200___write8(struct comedi_device *dev,
unsigned int offset, unsigned char val)
{
if (dev->mmio)
writeb(val, dev->mmio + offset);
else
outb(val, dev->iobase + offset);
}
static unsigned int dio200___read32(struct comedi_device *dev,
unsigned int offset)
{
if (dev->mmio)
return readl(dev->mmio + offset);
return inl(dev->iobase + offset);
}
static void dio200___write32(struct comedi_device *dev,
unsigned int offset, unsigned int val)
{
if (dev->mmio)
writel(val, dev->mmio + offset);
else
outl(val, dev->iobase + offset);
}
#else /* CONFIG_HAS_IOPORT */
static unsigned char dio200___read8(struct comedi_device *dev,
unsigned int offset)
{
return readb(dev->mmio + offset);
}
static void dio200___write8(struct comedi_device *dev,
unsigned int offset, unsigned char val)
{
writeb(val, dev->mmio + offset);
}
static unsigned int dio200___read32(struct comedi_device *dev,
unsigned int offset)
{
return readl(dev->mmio + offset);
}
static void dio200___write32(struct comedi_device *dev,
unsigned int offset, unsigned int val)
{
writel(val, dev->mmio + offset);
}
#endif /* CONFIG_HAS_IOPORT */
static unsigned char dio200_read8(struct comedi_device *dev,
unsigned int offset)
{
@ -94,9 +158,7 @@ static unsigned char dio200_read8(struct comedi_device *dev,
if (board->is_pcie)
offset <<= 3;
if (dev->mmio)
return readb(dev->mmio + offset);
return inb(dev->iobase + offset);
return dio200___read8(dev, offset);
}
static void dio200_write8(struct comedi_device *dev,
@ -107,10 +169,7 @@ static void dio200_write8(struct comedi_device *dev,
if (board->is_pcie)
offset <<= 3;
if (dev->mmio)
writeb(val, dev->mmio + offset);
else
outb(val, dev->iobase + offset);
dio200___write8(dev, offset, val);
}
static unsigned int dio200_read32(struct comedi_device *dev,
@ -121,9 +180,7 @@ static unsigned int dio200_read32(struct comedi_device *dev,
if (board->is_pcie)
offset <<= 3;
if (dev->mmio)
return readl(dev->mmio + offset);
return inl(dev->iobase + offset);
return dio200___read32(dev, offset);
}
static void dio200_write32(struct comedi_device *dev,
@ -134,10 +191,7 @@ static void dio200_write32(struct comedi_device *dev,
if (board->is_pcie)
offset <<= 3;
if (dev->mmio)
writel(val, dev->mmio + offset);
else
outl(val, dev->iobase + offset);
dio200___write32(dev, offset, val);
}
static unsigned int dio200_subdev_8254_offset(struct comedi_device *dev,
@ -149,9 +203,9 @@ static unsigned int dio200_subdev_8254_offset(struct comedi_device *dev,
/* get the offset that was passed to comedi_8254_*_init() */
if (dev->mmio)
offset = i8254->mmio - dev->mmio;
offset = (void __iomem *)i8254->context - dev->mmio;
else
offset = i8254->iobase - dev->iobase;
offset = i8254->context - dev->iobase;
/* remove the shift that was added for PCIe boards */
if (board->is_pcie)
@ -556,14 +610,14 @@ static int dio200_subdev_8254_init(struct comedi_device *dev,
}
if (dev->mmio) {
i8254 = comedi_8254_mm_init(dev->mmio + offset,
0, I8254_IO8, regshift);
i8254 = comedi_8254_mm_alloc(dev->mmio + offset,
0, I8254_IO8, regshift);
} else {
i8254 = comedi_8254_init(dev->iobase + offset,
0, I8254_IO8, regshift);
i8254 = comedi_8254_io_alloc(dev->iobase + offset,
0, I8254_IO8, regshift);
}
if (!i8254)
return -ENOMEM;
if (IS_ERR(i8254))
return PTR_ERR(i8254);
comedi_8254_subdevice_init(s, i8254);
@ -779,6 +833,12 @@ int amplc_dio200_common_attach(struct comedi_device *dev, unsigned int irq,
unsigned int n;
int ret;
if (!IS_ENABLED(CONFIG_HAS_IOPORT) && !dev->mmio) {
dev_err(dev->class_dev,
"error! need I/O port support\n");
return -ENXIO;
}
ret = comedi_alloc_subdevices(dev, board->n_subdevs);
if (ret)
return ret;

View File

@ -223,14 +223,17 @@
*/
enum dio200_pci_model {
#ifdef CONFIG_HAS_IOPORT
pci215_model,
pci272_model,
#endif /* CONFIG_HAS_IOPORT */
pcie215_model,
pcie236_model,
pcie296_model
};
static const struct dio200_board dio200_pci_boards[] = {
#ifdef CONFIG_HAS_IOPORT
[pci215_model] = {
.name = "pci215",
.mainbar = 2,
@ -252,6 +255,7 @@ static const struct dio200_board dio200_pci_boards[] = {
.sdinfo = { 0x00, 0x08, 0x10, 0x3f },
.has_int_sce = true,
},
#endif /* CONFIG_HAS_IOPORT */
[pcie215_model] = {
.name = "pcie215",
.mainbar = 1,
@ -364,8 +368,12 @@ static int dio200_pci_auto_attach(struct comedi_device *dev,
"error! cannot remap registers\n");
return -ENOMEM;
}
} else {
} else if (IS_ENABLED(CONFIG_HAS_IOPORT)) {
dev->iobase = pci_resource_start(pci_dev, bar);
} else {
dev_err(dev->class_dev,
"error! need I/O port support\n");
return -ENXIO;
}
if (board->is_pcie) {
@ -385,8 +393,10 @@ static struct comedi_driver dio200_pci_comedi_driver = {
};
static const struct pci_device_id dio200_pci_table[] = {
#ifdef CONFIG_HAS_IOPORT
{ PCI_VDEVICE(AMPLICON, 0x000b), pci215_model },
{ PCI_VDEVICE(AMPLICON, 0x000a), pci272_model },
#endif /* CONFIG_HAS_IOPORT */
{ PCI_VDEVICE(AMPLICON, 0x0011), pcie236_model },
{ PCI_VDEVICE(AMPLICON, 0x0012), pcie215_model },
{ PCI_VDEVICE(AMPLICON, 0x0014), pcie296_model },

View File

@ -147,7 +147,7 @@ int amplc_pc236_common_attach(struct comedi_device *dev, unsigned long iobase,
s = &dev->subdevices[0];
/* digital i/o subdevice (8255) */
ret = subdev_8255_init(dev, s, NULL, 0x00);
ret = subdev_8255_io_init(dev, s, 0x00);
if (ret)
return ret;

View File

@ -1051,10 +1051,10 @@ pci224_auto_attach(struct comedi_device *dev, unsigned long context_model)
outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
dev->iobase + PCI224_DACCON);
dev->pacer = comedi_8254_init(devpriv->iobase1 + PCI224_Z2_BASE,
I8254_OSC_BASE_10MHZ, I8254_IO8, 0);
if (!dev->pacer)
return -ENOMEM;
dev->pacer = comedi_8254_io_alloc(devpriv->iobase1 + PCI224_Z2_BASE,
I8254_OSC_BASE_10MHZ, I8254_IO8, 0);
if (IS_ERR(dev->pacer))
return PTR_ERR(dev->pacer);
ret = comedi_alloc_subdevices(dev, 1);
if (ret)

View File

@ -2475,10 +2475,10 @@ static int pci230_auto_attach(struct comedi_device *dev,
dev->irq = pci_dev->irq;
}
dev->pacer = comedi_8254_init(dev->iobase + PCI230_Z2_CT_BASE,
0, I8254_IO8, 0);
if (!dev->pacer)
return -ENOMEM;
dev->pacer = comedi_8254_io_alloc(dev->iobase + PCI230_Z2_CT_BASE,
0, I8254_IO8, 0);
if (IS_ERR(dev->pacer))
return PTR_ERR(dev->pacer);
rc = comedi_alloc_subdevices(dev, 3);
if (rc)
@ -2529,7 +2529,7 @@ static int pci230_auto_attach(struct comedi_device *dev,
s = &dev->subdevices[2];
/* digital i/o subdevice */
if (board->have_dio) {
rc = subdev_8255_init(dev, s, NULL, PCI230_PPI_X_BASE);
rc = subdev_8255_io_init(dev, s, PCI230_PPI_X_BASE);
if (rc)
return rc;
} else {

View File

@ -363,10 +363,10 @@ static int das16cs_auto_attach(struct comedi_device *dev,
if (!devpriv)
return -ENOMEM;
dev->pacer = comedi_8254_init(dev->iobase + DAS16CS_TIMER_BASE,
I8254_OSC_BASE_10MHZ, I8254_IO16, 0);
if (!dev->pacer)
return -ENOMEM;
dev->pacer = comedi_8254_io_alloc(dev->iobase + DAS16CS_TIMER_BASE,
I8254_OSC_BASE_10MHZ, I8254_IO16, 0);
if (IS_ERR(dev->pacer))
return PTR_ERR(dev->pacer);
ret = comedi_alloc_subdevices(dev, 4);
if (ret)

View File

@ -1288,16 +1288,16 @@ static int cb_pcidas_auto_attach(struct comedi_device *dev,
}
dev->irq = pcidev->irq;
dev->pacer = comedi_8254_init(dev->iobase + PCIDAS_AI_8254_BASE,
I8254_OSC_BASE_10MHZ, I8254_IO8, 0);
if (!dev->pacer)
return -ENOMEM;
dev->pacer = comedi_8254_io_alloc(dev->iobase + PCIDAS_AI_8254_BASE,
I8254_OSC_BASE_10MHZ, I8254_IO8, 0);
if (IS_ERR(dev->pacer))
return PTR_ERR(dev->pacer);
devpriv->ao_pacer = comedi_8254_init(dev->iobase + PCIDAS_AO_8254_BASE,
I8254_OSC_BASE_10MHZ,
I8254_IO8, 0);
if (!devpriv->ao_pacer)
return -ENOMEM;
devpriv->ao_pacer =
comedi_8254_io_alloc(dev->iobase + PCIDAS_AO_8254_BASE,
I8254_OSC_BASE_10MHZ, I8254_IO8, 0);
if (IS_ERR(devpriv->ao_pacer))
return PTR_ERR(devpriv->ao_pacer);
ret = comedi_alloc_subdevices(dev, 7);
if (ret)
@ -1352,7 +1352,7 @@ static int cb_pcidas_auto_attach(struct comedi_device *dev,
/* 8255 */
s = &dev->subdevices[2];
ret = subdev_8255_init(dev, s, NULL, PCIDAS_8255_BASE);
ret = subdev_8255_io_init(dev, s, PCIDAS_8255_BASE);
if (ret)
return ret;
@ -1453,7 +1453,8 @@ static void cb_pcidas_detach(struct comedi_device *dev)
if (devpriv->amcc)
outl(INTCSR_INBOX_INTR_STATUS,
devpriv->amcc + AMCC_OP_REG_INTCSR);
kfree(devpriv->ao_pacer);
if (!IS_ERR(devpriv->ao_pacer))
kfree(devpriv->ao_pacer);
}
comedi_pci_detach(dev);
}

View File

@ -3877,11 +3877,10 @@ static int setup_subdevices(struct comedi_device *dev)
s = &dev->subdevices[4];
if (board->has_8255) {
if (board->layout == LAYOUT_4020) {
ret = subdev_8255_init(dev, s, dio_callback_4020,
I8255_4020_REG);
ret = subdev_8255_cb_init(dev, s, dio_callback_4020,
I8255_4020_REG);
} else {
ret = subdev_8255_mm_init(dev, s, NULL,
DIO_8255_OFFSET);
ret = subdev_8255_mm_init(dev, s, DIO_8255_OFFSET);
}
if (ret)
return ret;

View File

@ -365,7 +365,7 @@ static int cb_pcidda_auto_attach(struct comedi_device *dev,
/* two 8255 digital io subdevices */
for (i = 0; i < 2; i++) {
s = &dev->subdevices[1 + i];
ret = subdev_8255_init(dev, s, NULL, i * I8255_SIZE);
ret = subdev_8255_io_init(dev, s, i * I8255_SIZE);
if (ret)
return ret;
}

View File

@ -364,11 +364,11 @@ static int cb_pcimdas_auto_attach(struct comedi_device *dev,
devpriv->BADR3 = pci_resource_start(pcidev, 3);
dev->iobase = pci_resource_start(pcidev, 4);
dev->pacer = comedi_8254_init(devpriv->BADR3 + PCIMDAS_8254_BASE,
cb_pcimdas_pacer_clk(dev),
I8254_IO8, 0);
if (!dev->pacer)
return -ENOMEM;
dev->pacer = comedi_8254_io_alloc(devpriv->BADR3 + PCIMDAS_8254_BASE,
cb_pcimdas_pacer_clk(dev),
I8254_IO8, 0);
if (IS_ERR(dev->pacer))
return PTR_ERR(dev->pacer);
ret = comedi_alloc_subdevices(dev, 6);
if (ret)
@ -405,7 +405,7 @@ static int cb_pcimdas_auto_attach(struct comedi_device *dev,
/* Digital I/O subdevice */
s = &dev->subdevices[2];
ret = subdev_8255_init(dev, s, NULL, PCIMDAS_8255_BASE);
ret = subdev_8255_io_init(dev, s, PCIMDAS_8255_BASE);
if (ret)
return ret;

View File

@ -154,7 +154,7 @@ static int cb_pcimdda_auto_attach(struct comedi_device *dev,
s = &dev->subdevices[1];
/* digital i/o subdevice */
return subdev_8255_init(dev, s, NULL, PCIMDDA_8255_BASE_REG);
return subdev_8255_io_init(dev, s, PCIMDDA_8255_BASE_REG);
}
static struct comedi_driver cb_pcimdda_driver = {

View File

@ -24,14 +24,17 @@
*
* This module provides the following basic functions:
*
* comedi_8254_init() / comedi_8254_mm_init()
* comedi_8254_io_alloc() / comedi_8254_mm_alloc()
* Initializes this module to access the 8254 registers. The _mm version
* sets up the module for MMIO register access the other for PIO access.
* The pointer returned from these functions is normally stored in the
* comedi_device dev->pacer and will be freed by the comedi core during
* the driver (*detach). If a driver has multiple 8254 devices, they need
* to be stored in the drivers private data and freed when the driver is
* detached.
* sets up the module for MMIO register access; the _io version sets it
* up for PIO access. These functions return a pointer to a struct
* comedi_8254 on success, or an ERR_PTR value on failure. The pointer
* returned from these functions is normally stored in the comedi_device
* dev->pacer and will be freed by the comedi core during the driver
* (*detach). If a driver has multiple 8254 devices, they need to be
* stored in the drivers private data and freed when the driver is
* detached. If the ERR_PTR value is stored, code should check the
* pointer value with !IS_ERR(pointer) before freeing.
*
* NOTE: The counters are reset by setting them to I8254_MODE0 as part of
* this initialization.
@ -119,61 +122,103 @@
#include <linux/comedi/comedidev.h>
#include <linux/comedi/comedi_8254.h>
#ifdef CONFIG_HAS_IOPORT
static unsigned int i8254_io8_cb(struct comedi_8254 *i8254, int dir,
unsigned int reg, unsigned int val)
{
unsigned long iobase = i8254->context;
unsigned int reg_offset = (reg * I8254_IO8) << i8254->regshift;
if (dir) {
outb(val, iobase + reg_offset);
return 0;
} else {
return inb(iobase + reg_offset);
}
}
static unsigned int i8254_io16_cb(struct comedi_8254 *i8254, int dir,
unsigned int reg, unsigned int val)
{
unsigned long iobase = i8254->context;
unsigned int reg_offset = (reg * I8254_IO16) << i8254->regshift;
if (dir) {
outw(val, iobase + reg_offset);
return 0;
} else {
return inw(iobase + reg_offset);
}
}
static unsigned int i8254_io32_cb(struct comedi_8254 *i8254, int dir,
unsigned int reg, unsigned int val)
{
unsigned long iobase = i8254->context;
unsigned int reg_offset = (reg * I8254_IO32) << i8254->regshift;
if (dir) {
outl(val, iobase + reg_offset);
return 0;
} else {
return inl(iobase + reg_offset);
}
}
#endif /* CONFIG_HAS_IOPORT */
static unsigned int i8254_mmio8_cb(struct comedi_8254 *i8254, int dir,
unsigned int reg, unsigned int val)
{
void __iomem *mmiobase = (void __iomem *)i8254->context;
unsigned int reg_offset = (reg * I8254_IO8) << i8254->regshift;
if (dir) {
writeb(val, mmiobase + reg_offset);
return 0;
} else {
return readb(mmiobase + reg_offset);
}
}
static unsigned int i8254_mmio16_cb(struct comedi_8254 *i8254, int dir,
unsigned int reg, unsigned int val)
{
void __iomem *mmiobase = (void __iomem *)i8254->context;
unsigned int reg_offset = (reg * I8254_IO16) << i8254->regshift;
if (dir) {
writew(val, mmiobase + reg_offset);
return 0;
} else {
return readw(mmiobase + reg_offset);
}
}
static unsigned int i8254_mmio32_cb(struct comedi_8254 *i8254, int dir,
unsigned int reg, unsigned int val)
{
void __iomem *mmiobase = (void __iomem *)i8254->context;
unsigned int reg_offset = (reg * I8254_IO32) << i8254->regshift;
if (dir) {
writel(val, mmiobase + reg_offset);
return 0;
} else {
return readl(mmiobase + reg_offset);
}
}
static unsigned int __i8254_read(struct comedi_8254 *i8254, unsigned int reg)
{
unsigned int reg_offset = (reg * i8254->iosize) << i8254->regshift;
unsigned int val;
switch (i8254->iosize) {
default:
case I8254_IO8:
if (i8254->mmio)
val = readb(i8254->mmio + reg_offset);
else
val = inb(i8254->iobase + reg_offset);
break;
case I8254_IO16:
if (i8254->mmio)
val = readw(i8254->mmio + reg_offset);
else
val = inw(i8254->iobase + reg_offset);
break;
case I8254_IO32:
if (i8254->mmio)
val = readl(i8254->mmio + reg_offset);
else
val = inl(i8254->iobase + reg_offset);
break;
}
return val & 0xff;
return 0xff & i8254->iocb(i8254, 0, reg, 0);
}
static void __i8254_write(struct comedi_8254 *i8254,
unsigned int val, unsigned int reg)
{
unsigned int reg_offset = (reg * i8254->iosize) << i8254->regshift;
switch (i8254->iosize) {
default:
case I8254_IO8:
if (i8254->mmio)
writeb(val, i8254->mmio + reg_offset);
else
outb(val, i8254->iobase + reg_offset);
break;
case I8254_IO16:
if (i8254->mmio)
writew(val, i8254->mmio + reg_offset);
else
outw(val, i8254->iobase + reg_offset);
break;
case I8254_IO32:
if (i8254->mmio)
writel(val, i8254->mmio + reg_offset);
else
outl(val, i8254->iobase + reg_offset);
break;
}
i8254->iocb(i8254, 1, reg, val);
}
/**
@ -571,8 +616,8 @@ void comedi_8254_subdevice_init(struct comedi_subdevice *s,
}
EXPORT_SYMBOL_GPL(comedi_8254_subdevice_init);
static struct comedi_8254 *__i8254_init(unsigned long iobase,
void __iomem *mmio,
static struct comedi_8254 *__i8254_init(comedi_8254_iocb_fn *iocb,
unsigned long context,
unsigned int osc_base,
unsigned int iosize,
unsigned int regshift)
@ -583,14 +628,17 @@ static struct comedi_8254 *__i8254_init(unsigned long iobase,
/* sanity check that the iosize is valid */
if (!(iosize == I8254_IO8 || iosize == I8254_IO16 ||
iosize == I8254_IO32))
return NULL;
return ERR_PTR(-EINVAL);
if (!iocb)
return ERR_PTR(-EINVAL);
i8254 = kzalloc(sizeof(*i8254), GFP_KERNEL);
if (!i8254)
return NULL;
return ERR_PTR(-ENOMEM);
i8254->iobase = iobase;
i8254->mmio = mmio;
i8254->iocb = iocb;
i8254->context = context;
i8254->iosize = iosize;
i8254->regshift = regshift;
@ -604,39 +652,77 @@ static struct comedi_8254 *__i8254_init(unsigned long iobase,
return i8254;
}
#ifdef CONFIG_HAS_IOPORT
/**
* comedi_8254_init - allocate and initialize the 8254 device for pio access
* comedi_8254_io_alloc - allocate and initialize the 8254 device for pio access
* @iobase: port I/O base address
* @osc_base: base time of the counter in ns
* OPTIONAL - only used by comedi_8254_cascade_ns_to_timer()
* @iosize: I/O register size
* @regshift: register gap shift
*
* Return: A pointer to a struct comedi_8254 or an ERR_PTR value.
*/
struct comedi_8254 *comedi_8254_init(unsigned long iobase,
unsigned int osc_base,
unsigned int iosize,
unsigned int regshift)
struct comedi_8254 *comedi_8254_io_alloc(unsigned long iobase,
unsigned int osc_base,
unsigned int iosize,
unsigned int regshift)
{
return __i8254_init(iobase, NULL, osc_base, iosize, regshift);
comedi_8254_iocb_fn *iocb;
switch (iosize) {
case I8254_IO8:
iocb = i8254_io8_cb;
break;
case I8254_IO16:
iocb = i8254_io16_cb;
break;
case I8254_IO32:
iocb = i8254_io32_cb;
break;
default:
return ERR_PTR(-EINVAL);
}
return __i8254_init(iocb, iobase, osc_base, iosize, regshift);
}
EXPORT_SYMBOL_GPL(comedi_8254_init);
EXPORT_SYMBOL_GPL(comedi_8254_io_alloc);
#endif /* CONFIG_HAS_IOPORT */
/**
* comedi_8254_mm_init - allocate and initialize the 8254 device for mmio access
* comedi_8254_mm_alloc - allocate and initialize the 8254 device for mmio access
* @mmio: memory mapped I/O base address
* @osc_base: base time of the counter in ns
* OPTIONAL - only used by comedi_8254_cascade_ns_to_timer()
* @iosize: I/O register size
* @regshift: register gap shift
*
* Return: A pointer to a struct comedi_8254 or an ERR_PTR value.
*/
struct comedi_8254 *comedi_8254_mm_init(void __iomem *mmio,
unsigned int osc_base,
unsigned int iosize,
unsigned int regshift)
struct comedi_8254 *comedi_8254_mm_alloc(void __iomem *mmio,
unsigned int osc_base,
unsigned int iosize,
unsigned int regshift)
{
return __i8254_init(0, mmio, osc_base, iosize, regshift);
comedi_8254_iocb_fn *iocb;
switch (iosize) {
case I8254_IO8:
iocb = i8254_mmio8_cb;
break;
case I8254_IO16:
iocb = i8254_mmio16_cb;
break;
case I8254_IO32:
iocb = i8254_mmio32_cb;
break;
default:
return ERR_PTR(-EINVAL);
}
return __i8254_init(iocb, (unsigned long)mmio, osc_base, iosize, regshift);
}
EXPORT_SYMBOL_GPL(comedi_8254_mm_init);
EXPORT_SYMBOL_GPL(comedi_8254_mm_alloc);
static int __init comedi_8254_module_init(void)
{

View File

@ -33,11 +33,13 @@
#include <linux/comedi/comedi_8255.h>
struct subdev_8255_private {
unsigned long regbase;
unsigned long context;
int (*io)(struct comedi_device *dev, int dir, int port, int data,
unsigned long regbase);
unsigned long context);
};
#ifdef CONFIG_HAS_IOPORT
static int subdev_8255_io(struct comedi_device *dev,
int dir, int port, int data, unsigned long regbase)
{
@ -48,6 +50,8 @@ static int subdev_8255_io(struct comedi_device *dev,
return inb(dev->iobase + regbase + port);
}
#endif /* CONFIG_HAS_IOPORT */
static int subdev_8255_mmio(struct comedi_device *dev,
int dir, int port, int data, unsigned long regbase)
{
@ -64,7 +68,7 @@ static int subdev_8255_insn(struct comedi_device *dev,
unsigned int *data)
{
struct subdev_8255_private *spriv = s->private;
unsigned long regbase = spriv->regbase;
unsigned long context = spriv->context;
unsigned int mask;
unsigned int v;
@ -72,18 +76,18 @@ static int subdev_8255_insn(struct comedi_device *dev,
if (mask) {
if (mask & 0xff)
spriv->io(dev, 1, I8255_DATA_A_REG,
s->state & 0xff, regbase);
s->state & 0xff, context);
if (mask & 0xff00)
spriv->io(dev, 1, I8255_DATA_B_REG,
(s->state >> 8) & 0xff, regbase);
(s->state >> 8) & 0xff, context);
if (mask & 0xff0000)
spriv->io(dev, 1, I8255_DATA_C_REG,
(s->state >> 16) & 0xff, regbase);
(s->state >> 16) & 0xff, context);
}
v = spriv->io(dev, 0, I8255_DATA_A_REG, 0, regbase);
v |= (spriv->io(dev, 0, I8255_DATA_B_REG, 0, regbase) << 8);
v |= (spriv->io(dev, 0, I8255_DATA_C_REG, 0, regbase) << 16);
v = spriv->io(dev, 0, I8255_DATA_A_REG, 0, context);
v |= (spriv->io(dev, 0, I8255_DATA_B_REG, 0, context) << 8);
v |= (spriv->io(dev, 0, I8255_DATA_C_REG, 0, context) << 16);
data[1] = v;
@ -94,7 +98,7 @@ static void subdev_8255_do_config(struct comedi_device *dev,
struct comedi_subdevice *s)
{
struct subdev_8255_private *spriv = s->private;
unsigned long regbase = spriv->regbase;
unsigned long context = spriv->context;
int config;
config = I8255_CTRL_CW;
@ -108,7 +112,7 @@ static void subdev_8255_do_config(struct comedi_device *dev,
if (!(s->io_bits & 0xf00000))
config |= I8255_CTRL_C_HI_IO;
spriv->io(dev, 1, I8255_CTRL_REG, config, regbase);
spriv->io(dev, 1, I8255_CTRL_REG, config, context);
}
static int subdev_8255_insn_config(struct comedi_device *dev,
@ -142,23 +146,19 @@ static int __subdev_8255_init(struct comedi_device *dev,
struct comedi_subdevice *s,
int (*io)(struct comedi_device *dev,
int dir, int port, int data,
unsigned long regbase),
unsigned long regbase,
bool is_mmio)
unsigned long context),
unsigned long context)
{
struct subdev_8255_private *spriv;
if (!io)
return -EINVAL;
spriv = comedi_alloc_spriv(s, sizeof(*spriv));
if (!spriv)
return -ENOMEM;
if (io)
spriv->io = io;
else if (is_mmio)
spriv->io = subdev_8255_mmio;
else
spriv->io = subdev_8255_io;
spriv->regbase = regbase;
spriv->context = context;
s->type = COMEDI_SUBD_DIO;
s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
@ -173,89 +173,88 @@ static int __subdev_8255_init(struct comedi_device *dev,
return 0;
}
#ifdef CONFIG_HAS_IOPORT
/**
* subdev_8255_init - initialize DIO subdevice for driving I/O mapped 8255
* subdev_8255_io_init - initialize DIO subdevice for driving I/O mapped 8255
* @dev: comedi device owning subdevice
* @s: comedi subdevice to initialize
* @io: (optional) register I/O call-back function
* @regbase: offset of 8255 registers from dev->iobase, or call-back context
* @regbase: offset of 8255 registers from dev->iobase
*
* Initializes a comedi subdevice as a DIO subdevice driving an 8255 chip.
*
* If the optional I/O call-back function is provided, its prototype is of
* the following form:
*
* int my_8255_callback(struct comedi_device *dev, int dir, int port,
* int data, unsigned long regbase);
*
* where 'dev', and 'regbase' match the values passed to this function,
* 'port' is the 8255 port number 0 to 3 (including the control port), 'dir'
* is the direction (0 for read, 1 for write) and 'data' is the value to be
* written. It should return 0 if writing or the value read if reading.
*
* If the optional I/O call-back function is not provided, an internal
* call-back function is used which uses consecutive I/O port addresses
* starting at dev->iobase + regbase.
*
* Return: -ENOMEM if failed to allocate memory, zero on success.
*/
int subdev_8255_init(struct comedi_device *dev, struct comedi_subdevice *s,
int (*io)(struct comedi_device *dev, int dir, int port,
int data, unsigned long regbase),
int subdev_8255_io_init(struct comedi_device *dev, struct comedi_subdevice *s,
unsigned long regbase)
{
return __subdev_8255_init(dev, s, io, regbase, false);
return __subdev_8255_init(dev, s, subdev_8255_io, regbase);
}
EXPORT_SYMBOL_GPL(subdev_8255_init);
EXPORT_SYMBOL_GPL(subdev_8255_io_init);
#endif /* CONFIG_HAS_IOPORT */
/**
* subdev_8255_mm_init - initialize DIO subdevice for driving mmio-mapped 8255
* @dev: comedi device owning subdevice
* @s: comedi subdevice to initialize
* @io: (optional) register I/O call-back function
* @regbase: offset of 8255 registers from dev->mmio, or call-back context
* @regbase: offset of 8255 registers from dev->mmio
*
* Initializes a comedi subdevice as a DIO subdevice driving an 8255 chip.
*
* If the optional I/O call-back function is provided, its prototype is of
* the following form:
*
* int my_8255_callback(struct comedi_device *dev, int dir, int port,
* int data, unsigned long regbase);
*
* where 'dev', and 'regbase' match the values passed to this function,
* 'port' is the 8255 port number 0 to 3 (including the control port), 'dir'
* is the direction (0 for read, 1 for write) and 'data' is the value to be
* written. It should return 0 if writing or the value read if reading.
*
* If the optional I/O call-back function is not provided, an internal
* call-back function is used which uses consecutive MMIO virtual addresses
* starting at dev->mmio + regbase.
*
* Return: -ENOMEM if failed to allocate memory, zero on success.
*/
int subdev_8255_mm_init(struct comedi_device *dev, struct comedi_subdevice *s,
int (*io)(struct comedi_device *dev, int dir, int port,
int data, unsigned long regbase),
unsigned long regbase)
{
return __subdev_8255_init(dev, s, io, regbase, true);
return __subdev_8255_init(dev, s, subdev_8255_mmio, regbase);
}
EXPORT_SYMBOL_GPL(subdev_8255_mm_init);
/**
* subdev_8255_cb_init - initialize DIO subdevice for driving callback-mapped 8255
* @dev: comedi device owning subdevice
* @s: comedi subdevice to initialize
* @io: register I/O call-back function
* @context: call-back context
*
* Initializes a comedi subdevice as a DIO subdevice driving an 8255 chip.
*
* The prototype of the I/O call-back function is of the following form:
*
* int my_8255_callback(struct comedi_device *dev, int dir, int port,
* int data, unsigned long context);
*
* where 'dev', and 'context' match the values passed to this function,
* 'port' is the 8255 port number 0 to 3 (including the control port), 'dir'
* is the direction (0 for read, 1 for write) and 'data' is the value to be
* written. It should return 0 if writing or the value read if reading.
*
*
* Return: -ENOMEM if failed to allocate memory, zero on success.
*/
int subdev_8255_cb_init(struct comedi_device *dev, struct comedi_subdevice *s,
int (*io)(struct comedi_device *dev, int dir, int port,
int data, unsigned long context),
unsigned long context)
{
return __subdev_8255_init(dev, s, io, context);
}
EXPORT_SYMBOL_GPL(subdev_8255_cb_init);
/**
* subdev_8255_regbase - get offset of 8255 registers or call-back context
* @s: comedi subdevice
*
* Returns the 'regbase' parameter that was previously passed to
* subdev_8255_init() or subdev_8255_mm_init() to set up the subdevice.
* Only valid if the subdevice was set up successfully.
* Returns the 'regbase' or 'context' parameter that was previously passed to
* subdev_8255_io_init(), subdev_8255_mm_init(), or subdev_8255_cb_init() to
* set up the subdevice. Only valid if the subdevice was set up successfully.
*/
unsigned long subdev_8255_regbase(struct comedi_subdevice *s)
{
struct subdev_8255_private *spriv = s->private;
return spriv->regbase;
return spriv->context;
}
EXPORT_SYMBOL_GPL(subdev_8255_regbase);

View File

@ -738,8 +738,8 @@ static int db2k_auto_attach(struct comedi_device *dev, unsigned long context)
return result;
s = &dev->subdevices[2];
return subdev_8255_init(dev, s, db2k_8255_cb,
DB2K_REG_DIO_P2_EXP_IO_8_BIT);
return subdev_8255_cb_init(dev, s, db2k_8255_cb,
DB2K_REG_DIO_P2_EXP_IO_8_BIT);
}
static void db2k_detach(struct comedi_device *dev)

View File

@ -429,7 +429,7 @@ int das08_common_attach(struct comedi_device *dev, unsigned long iobase)
s = &dev->subdevices[4];
/* 8255 */
if (board->i8255_offset != 0) {
ret = subdev_8255_init(dev, s, NULL, board->i8255_offset);
ret = subdev_8255_io_init(dev, s, board->i8255_offset);
if (ret)
return ret;
} else {
@ -439,10 +439,11 @@ int das08_common_attach(struct comedi_device *dev, unsigned long iobase)
/* Counter subdevice (8254) */
s = &dev->subdevices[5];
if (board->i8254_offset) {
dev->pacer = comedi_8254_init(dev->iobase + board->i8254_offset,
0, I8254_IO8, 0);
if (!dev->pacer)
return -ENOMEM;
dev->pacer =
comedi_8254_io_alloc(dev->iobase + board->i8254_offset,
0, I8254_IO8, 0);
if (IS_ERR(dev->pacer))
return PTR_ERR(dev->pacer);
comedi_8254_subdevice_init(s, dev->pacer);
} else {

View File

@ -1067,10 +1067,10 @@ static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it)
osc_base = I8254_OSC_BASE_1MHZ / it->options[3];
}
dev->pacer = comedi_8254_init(dev->iobase + DAS16_TIMER_BASE_REG,
osc_base, I8254_IO8, 0);
if (!dev->pacer)
return -ENOMEM;
dev->pacer = comedi_8254_io_alloc(dev->iobase + DAS16_TIMER_BASE_REG,
osc_base, I8254_IO8, 0);
if (IS_ERR(dev->pacer))
return PTR_ERR(dev->pacer);
das16_alloc_dma(dev, it->options[2]);
@ -1145,7 +1145,7 @@ 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_init(dev, s, NULL, board->i8255_offset);
ret = subdev_8255_io_init(dev, s, board->i8255_offset);
if (ret)
return ret;
}

View File

@ -529,15 +529,16 @@ static int das16m1_attach(struct comedi_device *dev,
dev->irq = it->options[1];
}
dev->pacer = comedi_8254_init(dev->iobase + DAS16M1_8254_IOBASE2,
I8254_OSC_BASE_10MHZ, I8254_IO8, 0);
if (!dev->pacer)
return -ENOMEM;
dev->pacer = comedi_8254_io_alloc(dev->iobase + DAS16M1_8254_IOBASE2,
I8254_OSC_BASE_10MHZ, I8254_IO8, 0);
if (IS_ERR(dev->pacer))
return PTR_ERR(dev->pacer);
devpriv->counter = comedi_8254_init(dev->iobase + DAS16M1_8254_IOBASE1,
0, I8254_IO8, 0);
if (!devpriv->counter)
return -ENOMEM;
devpriv->counter =
comedi_8254_io_alloc(dev->iobase + DAS16M1_8254_IOBASE1,
0, I8254_IO8, 0);
if (IS_ERR(devpriv->counter))
return PTR_ERR(devpriv->counter);
ret = comedi_alloc_subdevices(dev, 4);
if (ret)
@ -582,7 +583,7 @@ static int das16m1_attach(struct comedi_device *dev,
/* Digital I/O subdevice (8255) */
s = &dev->subdevices[3];
ret = subdev_8255_init(dev, s, NULL, DAS16M1_8255_IOBASE);
ret = subdev_8255_io_init(dev, s, DAS16M1_8255_IOBASE);
if (ret)
return ret;
@ -603,7 +604,8 @@ static void das16m1_detach(struct comedi_device *dev)
if (devpriv) {
if (devpriv->extra_iobase)
release_region(devpriv->extra_iobase, DAS16M1_SIZE2);
kfree(devpriv->counter);
if (!IS_ERR(devpriv->counter))
kfree(devpriv->counter);
}
comedi_legacy_detach(dev);
}

View File

@ -1233,10 +1233,10 @@ static int das1800_attach(struct comedi_device *dev,
if (!devpriv->fifo_buf)
return -ENOMEM;
dev->pacer = comedi_8254_init(dev->iobase + DAS1800_COUNTER,
I8254_OSC_BASE_5MHZ, I8254_IO8, 0);
if (!dev->pacer)
return -ENOMEM;
dev->pacer = comedi_8254_io_alloc(dev->iobase + DAS1800_COUNTER,
I8254_OSC_BASE_5MHZ, I8254_IO8, 0);
if (IS_ERR(dev->pacer))
return PTR_ERR(dev->pacer);
ret = comedi_alloc_subdevices(dev, 4);
if (ret)

View File

@ -590,10 +590,10 @@ static int das6402_attach(struct comedi_device *dev,
}
}
dev->pacer = comedi_8254_init(dev->iobase + DAS6402_TIMER_BASE,
I8254_OSC_BASE_10MHZ, I8254_IO8, 0);
if (!dev->pacer)
return -ENOMEM;
dev->pacer = comedi_8254_io_alloc(dev->iobase + DAS6402_TIMER_BASE,
I8254_OSC_BASE_10MHZ, I8254_IO8, 0);
if (IS_ERR(dev->pacer))
return PTR_ERR(dev->pacer);
ret = comedi_alloc_subdevices(dev, 4);
if (ret)

View File

@ -672,10 +672,10 @@ static int das800_attach(struct comedi_device *dev, struct comedi_devconfig *it)
dev->irq = irq;
}
dev->pacer = comedi_8254_init(dev->iobase + DAS800_8254,
I8254_OSC_BASE_1MHZ, I8254_IO8, 0);
if (!dev->pacer)
return -ENOMEM;
dev->pacer = comedi_8254_io_alloc(dev->iobase + DAS800_8254,
I8254_OSC_BASE_1MHZ, I8254_IO8, 0);
if (IS_ERR(dev->pacer))
return PTR_ERR(dev->pacer);
ret = comedi_alloc_subdevices(dev, 3);
if (ret)

View File

@ -599,7 +599,8 @@ static int dmm32at_attach(struct comedi_device *dev,
/* Digital I/O subdevice */
s = &dev->subdevices[2];
return subdev_8255_init(dev, s, dmm32at_8255_io, DMM32AT_8255_IOBASE);
return subdev_8255_cb_init(dev, s, dmm32at_8255_io,
DMM32AT_8255_IOBASE);
}
static struct comedi_driver dmm32at_driver = {

View File

@ -1209,9 +1209,9 @@ static int me4000_auto_attach(struct comedi_device *dev,
if (!timer_base)
return -ENODEV;
dev->pacer = comedi_8254_init(timer_base, 0, I8254_IO8, 0);
if (!dev->pacer)
return -ENOMEM;
dev->pacer = comedi_8254_io_alloc(timer_base, 0, I8254_IO8, 0);
if (IS_ERR(dev->pacer))
return PTR_ERR(dev->pacer);
comedi_8254_subdevice_init(s, dev->pacer);
} else {

View File

@ -707,10 +707,10 @@ static int a2150_attach(struct comedi_device *dev, struct comedi_devconfig *it)
/* an IRQ and DMA are required to support async commands */
a2150_alloc_irq_and_dma(dev, it);
dev->pacer = comedi_8254_init(dev->iobase + I8253_BASE_REG,
0, I8254_IO8, 0);
if (!dev->pacer)
return -ENOMEM;
dev->pacer = comedi_8254_io_alloc(dev->iobase + I8253_BASE_REG,
0, I8254_IO8, 0);
if (IS_ERR(dev->pacer))
return PTR_ERR(dev->pacer);
ret = comedi_alloc_subdevices(dev, 1);
if (ret)

View File

@ -303,10 +303,10 @@ static int atao_attach(struct comedi_device *dev, struct comedi_devconfig *it)
if (!devpriv)
return -ENOMEM;
dev->pacer = comedi_8254_init(dev->iobase + ATAO_82C53_BASE,
0, I8254_IO8, 0);
if (!dev->pacer)
return -ENOMEM;
dev->pacer = comedi_8254_io_alloc(dev->iobase + ATAO_82C53_BASE,
0, I8254_IO8, 0);
if (IS_ERR(dev->pacer))
return PTR_ERR(dev->pacer);
ret = comedi_alloc_subdevices(dev, 4);
if (ret)

View File

@ -677,7 +677,7 @@ static int atmio16d_attach(struct comedi_device *dev,
/* 8255 subdevice */
s = &dev->subdevices[3];
if (board->has_8255) {
ret = subdev_8255_init(dev, s, NULL, 0x00);
ret = subdev_8255_io_init(dev, s, 0x00);
if (ret)
return ret;
} else {

View File

@ -45,7 +45,7 @@ static int dio24_auto_attach(struct comedi_device *dev,
/* 8255 dio */
s = &dev->subdevices[0];
return subdev_8255_init(dev, s, NULL, 0x00);
return subdev_8255_io_init(dev, s, 0x00);
}
static struct comedi_driver driver_dio24 = {

Some files were not shown because too many files have changed in this diff Show More