diff options
436 files changed, 11422 insertions, 7211 deletions
@@ -1942,6 +1942,10 @@ S: Post Office Box 611311 S: San Jose, California 95161-1311 S: USA +N: Hartmut Knaack +E: knaack.h@gmx.de +D: IIO subsystem and drivers + N: Thorsten Knabe E: Thorsten Knabe <tek@rbg.informatik.tu-darmstadt.de> E: Thorsten Knabe <tek01@hrzpub.tu-darmstadt.de> diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio index 5c62bfb0f3f5..a9d51810a3ba 100644 --- a/Documentation/ABI/testing/sysfs-bus-iio +++ b/Documentation/ABI/testing/sysfs-bus-iio @@ -40,6 +40,7 @@ Description: buffered samples and events for device X. What: /sys/bus/iio/devices/iio:deviceX/sampling_frequency +What: /sys/bus/iio/devices/iio:deviceX/in_intensity_sampling_frequency What: /sys/bus/iio/devices/iio:deviceX/buffer/sampling_frequency What: /sys/bus/iio/devices/triggerX/sampling_frequency KernelVersion: 2.6.35 @@ -49,12 +50,13 @@ Description: resulting sampling frequency. In many devices this parameter has an effect on input filters etc. rather than simply controlling when the input is sampled. As this - effects data ready triggers, hardware buffers and the sysfs + affects data ready triggers, hardware buffers and the sysfs direct access interfaces, it may be found in any of the - relevant directories. If it effects all of the above + relevant directories. If it affects all of the above then it is to be found in the base device directory. What: /sys/bus/iio/devices/iio:deviceX/sampling_frequency_available +What: /sys/bus/iio/devices/iio:deviceX/in_intensity_sampling_frequency_available What: /sys/bus/iio/devices/iio:deviceX/in_proximity_sampling_frequency_available What: /sys/.../iio:deviceX/buffer/sampling_frequency_available What: /sys/bus/iio/devices/triggerX/sampling_frequency_available @@ -374,6 +376,9 @@ 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_angl_scale +What: /sys/bus/iio/devices/iio:deviceX/in_intensity_x_scale +What: /sys/bus/iio/devices/iio:deviceX/in_intensity_y_scale +What: /sys/bus/iio/devices/iio:deviceX/in_intensity_z_scale KernelVersion: 2.6.35 Contact: linux-iio@vger.kernel.org Description: @@ -401,21 +406,21 @@ Description: Hardware applied calibration offset (assumed to fix production inaccuracies). -What /sys/bus/iio/devices/iio:deviceX/in_voltageY_calibscale -What /sys/bus/iio/devices/iio:deviceX/in_voltageY_supply_calibscale -What /sys/bus/iio/devices/iio:deviceX/in_voltageY_i_calibscale -What /sys/bus/iio/devices/iio:deviceX/in_voltageY_q_calibscale -What /sys/bus/iio/devices/iio:deviceX/in_voltage_i_calibscale -What /sys/bus/iio/devices/iio:deviceX/in_voltage_q_calibscale -What /sys/bus/iio/devices/iio:deviceX/in_voltage_calibscale -What /sys/bus/iio/devices/iio:deviceX/in_accel_x_calibscale -What /sys/bus/iio/devices/iio:deviceX/in_accel_y_calibscale -What /sys/bus/iio/devices/iio:deviceX/in_accel_z_calibscale -What /sys/bus/iio/devices/iio:deviceX/in_anglvel_x_calibscale -What /sys/bus/iio/devices/iio:deviceX/in_anglvel_y_calibscale -What /sys/bus/iio/devices/iio:deviceX/in_anglvel_z_calibscale -what /sys/bus/iio/devices/iio:deviceX/in_illuminance0_calibscale -what /sys/bus/iio/devices/iio:deviceX/in_proximity0_calibscale +What: /sys/bus/iio/devices/iio:deviceX/in_voltageY_calibscale +What: /sys/bus/iio/devices/iio:deviceX/in_voltageY_supply_calibscale +What: /sys/bus/iio/devices/iio:deviceX/in_voltageY_i_calibscale +What: /sys/bus/iio/devices/iio:deviceX/in_voltageY_q_calibscale +What: /sys/bus/iio/devices/iio:deviceX/in_voltage_i_calibscale +What: /sys/bus/iio/devices/iio:deviceX/in_voltage_q_calibscale +What: /sys/bus/iio/devices/iio:deviceX/in_voltage_calibscale +What: /sys/bus/iio/devices/iio:deviceX/in_accel_x_calibscale +What: /sys/bus/iio/devices/iio:deviceX/in_accel_y_calibscale +What: /sys/bus/iio/devices/iio:deviceX/in_accel_z_calibscale +What: /sys/bus/iio/devices/iio:deviceX/in_anglvel_x_calibscale +What: /sys/bus/iio/devices/iio:deviceX/in_anglvel_y_calibscale +What: /sys/bus/iio/devices/iio:deviceX/in_anglvel_z_calibscale +What: /sys/bus/iio/devices/iio:deviceX/in_illuminance0_calibscale +What: /sys/bus/iio/devices/iio:deviceX/in_proximity0_calibscale What: /sys/bus/iio/devices/iio:deviceX/in_pressureY_calibscale What: /sys/bus/iio/devices/iio:deviceX/in_pressure_calibscale What: /sys/bus/iio/devices/iio:deviceX/in_illuminance_calibscale @@ -483,7 +488,8 @@ Description: If a discrete set of scale values is available, they are listed in this attribute. -What /sys/bus/iio/devices/iio:deviceX/out_voltageY_hardwaregain +What: /sys/bus/iio/devices/iio:deviceX/out_voltageY_hardwaregain +What: /sys/bus/iio/devices/iio:deviceX/in_intensity_hardwaregain What: /sys/bus/iio/devices/iio:deviceX/in_intensity_red_hardwaregain What: /sys/bus/iio/devices/iio:deviceX/in_intensity_green_hardwaregain What: /sys/bus/iio/devices/iio:deviceX/in_intensity_blue_hardwaregain @@ -494,6 +500,13 @@ Description: Hardware applied gain factor. If shared across all channels, <type>_hardwaregain is used. +What: /sys/bus/iio/devices/iio:deviceX/in_intensity_hardwaregain_available +KernelVersion: 5.10 +Contact: linux-iio@vger.kernel.org +Description: + Lists all available hardware applied gain factors. Shared across all + channels. + What: /sys/.../in_accel_filter_low_pass_3db_frequency What: /sys/.../in_magn_filter_low_pass_3db_frequency What: /sys/.../in_anglvel_filter_low_pass_3db_frequency @@ -750,9 +763,9 @@ What: /sys/.../events/in_voltageY_raw_thresh_falling_value What: /sys/.../events/in_tempY_raw_thresh_rising_value What: /sys/.../events/in_tempY_raw_thresh_falling_value What: /sys/.../events/in_illuminance0_thresh_falling_value -what: /sys/.../events/in_illuminance0_thresh_rising_value -what: /sys/.../events/in_proximity0_thresh_falling_value -what: /sys/.../events/in_proximity0_thresh_rising_value +What: /sys/.../events/in_illuminance0_thresh_rising_value +What: /sys/.../events/in_proximity0_thresh_falling_value +What: /sys/.../events/in_proximity0_thresh_rising_value What: /sys/.../events/in_illuminance_thresh_rising_value What: /sys/.../events/in_illuminance_thresh_falling_value KernelVersion: 2.6.37 @@ -832,11 +845,11 @@ What: /sys/.../events/in_tempY_thresh_rising_hysteresis What: /sys/.../events/in_tempY_thresh_falling_hysteresis What: /sys/.../events/in_tempY_thresh_either_hysteresis What: /sys/.../events/in_illuminance0_thresh_falling_hysteresis -what: /sys/.../events/in_illuminance0_thresh_rising_hysteresis -what: /sys/.../events/in_illuminance0_thresh_either_hysteresis -what: /sys/.../events/in_proximity0_thresh_falling_hysteresis -what: /sys/.../events/in_proximity0_thresh_rising_hysteresis -what: /sys/.../events/in_proximity0_thresh_either_hysteresis +What: /sys/.../events/in_illuminance0_thresh_rising_hysteresis +What: /sys/.../events/in_illuminance0_thresh_either_hysteresis +What: /sys/.../events/in_proximity0_thresh_falling_hysteresis +What: /sys/.../events/in_proximity0_thresh_rising_hysteresis +What: /sys/.../events/in_proximity0_thresh_either_hysteresis KernelVersion: 3.13 Contact: linux-iio@vger.kernel.org Description: @@ -1013,7 +1026,7 @@ What: /sys/.../events/in_activity_running_thresh_falling_en KernelVersion: 3.19 Contact: linux-iio@vger.kernel.org Description: - Enables or disables activitity events. Depending on direction + Enables or disables activity events. Depending on direction an event is generated when sensor ENTERS or LEAVES a given state. What: /sys/.../events/in_activity_still_thresh_rising_value @@ -1333,6 +1346,7 @@ Description: standardised CIE Erythemal Action Spectrum. UV index values range from 0 (low) to >=11 (extreme). +What: /sys/.../iio:deviceX/in_intensity_integration_time What: /sys/.../iio:deviceX/in_intensity_red_integration_time What: /sys/.../iio:deviceX/in_intensity_green_integration_time What: /sys/.../iio:deviceX/in_intensity_blue_integration_time @@ -1342,7 +1356,8 @@ KernelVersion: 3.12 Contact: linux-iio@vger.kernel.org Description: This attribute is used to get/set the integration time in - seconds. + seconds. If shared across all channels of a given type, + <type>_integration_time is used. What: /sys/.../iio:deviceX/in_velocity_sqrt(x^2+y^2+z^2)_integration_time KernelVersion: 4.0 @@ -1564,6 +1579,8 @@ What: /sys/bus/iio/devices/iio:deviceX/in_concentration_ethanol_raw What: /sys/bus/iio/devices/iio:deviceX/in_concentrationX_ethanol_raw What: /sys/bus/iio/devices/iio:deviceX/in_concentration_h2_raw What: /sys/bus/iio/devices/iio:deviceX/in_concentrationX_h2_raw +What: /sys/bus/iio/devices/iio:deviceX/in_concentration_o2_raw +What: /sys/bus/iio/devices/iio:deviceX/in_concentrationX_o2_raw What: /sys/bus/iio/devices/iio:deviceX/in_concentration_voc_raw What: /sys/bus/iio/devices/iio:deviceX/in_concentrationX_voc_raw KernelVersion: 4.3 @@ -1740,3 +1757,20 @@ KernelVersion: 5.5 Contact: linux-iio@vger.kernel.org Description: One of the following thermocouple types: B, E, J, K, N, R, S, T. + +What: /sys/bus/iio/devices/iio:deviceX/in_temp_object_calibambient +What: /sys/bus/iio/devices/iio:deviceX/in_tempX_object_calibambient +KernelVersion: 5.10 +Contact: linux-iio@vger.kernel.org +Description: + Calibrated ambient temperature for object temperature + calculation in milli degrees Celsius. + +What: /sys/bus/iio/devices/iio:deviceX/in_intensity_x_raw +What: /sys/bus/iio/devices/iio:deviceX/in_intensity_y_raw +What: /sys/bus/iio/devices/iio:deviceX/in_intensity_z_raw +KernelVersion: 5.10 +Contact: linux-iio@vger.kernel.org +Description: + Unscaled light intensity according to CIE 1931/DIN 5033 color space. + Units after application of scale are nano nanowatts per square meter. diff --git a/Documentation/ABI/testing/sysfs-bus-iio-accel-adxl372 b/Documentation/ABI/testing/sysfs-bus-iio-accel-adxl372 new file mode 100644 index 000000000000..47e34f865ca1 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-bus-iio-accel-adxl372 @@ -0,0 +1,7 @@ +What: /sys/bus/iio/devices/triggerX/name = "adxl372-devX-peak" +KernelVersion: +Contact: linux-iio@vger.kernel.org +Description: + The adxl372 accelerometer kernel module provides an additional trigger, + which sets the device in a mode in which it will record only the peak acceleration + sensed over the set period of time in the events sysfs. diff --git a/Documentation/ABI/testing/sysfs-bus-iio-humidity-hdc2010 b/Documentation/ABI/testing/sysfs-bus-iio-humidity-hdc2010 new file mode 100644 index 000000000000..5b78af5f341d --- /dev/null +++ b/Documentation/ABI/testing/sysfs-bus-iio-humidity-hdc2010 @@ -0,0 +1,9 @@ +What: /sys/bus/iio/devices/iio:deviceX/out_current_heater_raw +What: /sys/bus/iio/devices/iio:deviceX/out_current_heater_raw_available +KernelVersion: 5.3.8 +Contact: linux-iio@vger.kernel.org +Description: + Controls the heater device within the humidity sensor to get + rid of excess condensation. + + Valid control values are 0 = OFF, and 1 = ON. diff --git a/drivers/staging/iio/Documentation/light/sysfs-bus-iio-light-tsl2x7x b/Documentation/ABI/testing/sysfs-bus-iio-light-tsl2772 index b2798b258bf7..b2798b258bf7 100644 --- a/drivers/staging/iio/Documentation/light/sysfs-bus-iio-light-tsl2x7x +++ b/Documentation/ABI/testing/sysfs-bus-iio-light-tsl2772 diff --git a/Documentation/devicetree/bindings/iio/adc/ad7949.txt b/Documentation/devicetree/bindings/iio/adc/ad7949.txt deleted file mode 100644 index c7f5057356b1..000000000000 --- a/Documentation/devicetree/bindings/iio/adc/ad7949.txt +++ /dev/null @@ -1,16 +0,0 @@ -* Analog Devices AD7949/AD7682/AD7689 - -Required properties: - - compatible: Should be one of - * "adi,ad7949" - * "adi,ad7682" - * "adi,ad7689" - - reg: spi chip select number for the device - - vref-supply: The regulator supply for ADC reference voltage - -Example: -adc@0 { - compatible = "adi,ad7949"; - reg = <0>; - vref-supply = <&vdd_supply>; -}; diff --git a/Documentation/devicetree/bindings/iio/adc/adi,ad7291.yaml b/Documentation/devicetree/bindings/iio/adc/adi,ad7291.yaml new file mode 100644 index 000000000000..6feafb7e531e --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/adi,ad7291.yaml @@ -0,0 +1,46 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/adi,ad7291.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: AD7291 8-Channel, I2C, 12-Bit SAR ADC with Temperature Sensor + +maintainers: + - Michael Auchter <michael.auchter@ni.com> + +description: | + Analog Devices AD7291 8-Channel I2C 12-Bit SAR ADC with Temperature Sensor + https://www.analog.com/media/en/technical-documentation/data-sheets/ad7291.pdf + +properties: + compatible: + enum: + - adi,ad7291 + + reg: + maxItems: 1 + + vref-supply: + description: | + The regulator supply for ADC reference voltage. + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + i2c { + #address-cells = <1>; + #size-cells = <0>; + + ad7291: adc@0 { + compatible = "adi,ad7291"; + reg = <0>; + vref-supply = <&adc_vref>; + }; + }; +...
\ No newline at end of file diff --git a/Documentation/devicetree/bindings/iio/adc/adi,ad7768-1.txt b/Documentation/devicetree/bindings/iio/adc/adi,ad7768-1.txt deleted file mode 100644 index 9f5b88cf680d..000000000000 --- a/Documentation/devicetree/bindings/iio/adc/adi,ad7768-1.txt +++ /dev/null @@ -1,41 +0,0 @@ -Analog Devices AD7768-1 ADC device driver - -Required properties for the AD7768-1: - -- compatible: Must be "adi,ad7768-1" -- reg: SPI chip select number for the device -- spi-max-frequency: Max SPI frequency to use - see: Documentation/devicetree/bindings/spi/spi-bus.txt -- clocks: phandle to the master clock (mclk) - see: Documentation/devicetree/bindings/clock/clock-bindings.txt -- clock-names: Must be "mclk". -- interrupts: IRQ line for the ADC - see: Documentation/devicetree/bindings/interrupt-controller/interrupts.txt -- vref-supply: vref supply can be used as reference for conversion -- adi,sync-in-gpios: must be the device tree identifier of the SYNC-IN pin. Enables - synchronization of multiple devices that require simultaneous sampling. - A pulse is always required if the configuration is changed in any way, for example - if the filter decimation rate changes. As the line is active low, it should - be marked GPIO_ACTIVE_LOW. - -Optional properties: - - - reset-gpios : GPIO spec for the RESET pin. If specified, it will be asserted during - driver probe. As the line is active low, it should be marked GPIO_ACTIVE_LOW. - -Example: - - adc@0 { - compatible = "adi,ad7768-1"; - reg = <0>; - spi-max-frequency = <2000000>; - spi-cpol; - spi-cpha; - vref-supply = <&adc_vref>; - interrupts = <25 IRQ_TYPE_EDGE_RISING>; - interrupt-parent = <&gpio>; - adi,sync-in-gpios = <&gpio 22 GPIO_ACTIVE_LOW>; - reset-gpios = <&gpio 27 GPIO_ACTIVE_LOW>; - clocks = <&ad7768_mclk>; - clock-names = "mclk"; - }; diff --git a/Documentation/devicetree/bindings/iio/adc/adi,ad7768-1.yaml b/Documentation/devicetree/bindings/iio/adc/adi,ad7768-1.yaml new file mode 100644 index 000000000000..d3733ad8785a --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/adi,ad7768-1.yaml @@ -0,0 +1,89 @@ +# SPDX-License-Identifier: GPL-2.0 +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/adi,ad7768-1.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Analog Devices AD7768-1 ADC device driver + +maintainers: + - Michael Hennerich <michael.hennerich@analog.com> + +description: | + Datasheet at: + https://www.analog.com/media/en/technical-documentation/data-sheets/ad7768-1.pdf + +properties: + compatible: + const: adi,ad7768-1 + + reg: + maxItems: 1 + + clocks: + maxItems: 1 + + clock-names: + const: mclk + + interrupts: + maxItems: 1 + + vref-supply: + description: + ADC reference voltage supply + + adi,sync-in-gpios: + description: + Enables synchronization of multiple devices that require simultaneous + sampling. A pulse is always required if the configuration is changed + in any way, for example if the filter decimation rate changes. + As the line is active low, it should be marked GPIO_ACTIVE_LOW. + + reset-gpios: + maxItems: 1 + + spi-max-frequency: true + + spi-cpol: true + spi-cpha : true + + "#io-channel-cells": + const: 1 + +required: + - compatible + - reg + - clocks + - clock-names + - vref-supply + - spi-cpol + - spi-cpha + - adi,sync-in-gpios + +additionalProperties: false + +examples: + - | + #include <dt-bindings/interrupt-controller/irq.h> + #include <dt-bindings/gpio/gpio.h> + spi { + #address-cells = <1>; + #size-cells = <0>; + + adc@0 { + compatible = "adi,ad7768-1"; + reg = <0>; + spi-max-frequency = <2000000>; + spi-cpol; + spi-cpha; + vref-supply = <&adc_vref>; + interrupts = <25 IRQ_TYPE_EDGE_RISING>; + interrupt-parent = <&gpio>; + adi,sync-in-gpios = <&gpio 22 GPIO_ACTIVE_LOW>; + reset-gpios = <&gpio 27 GPIO_ACTIVE_LOW>; + clocks = <&ad7768_mclk>; + clock-names = "mclk"; + }; + }; +... diff --git a/Documentation/devicetree/bindings/iio/adc/adi,ad7949.yaml b/Documentation/devicetree/bindings/iio/adc/adi,ad7949.yaml new file mode 100644 index 000000000000..9b56bd4d5510 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/adi,ad7949.yaml @@ -0,0 +1,57 @@ +# SPDX-License-Identifier: GPL-2.0 +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/adi,ad7949.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Analog Devices AD7949/AD7682/AD7689 analog to digital converters + +maintainers: + - Charles-Antoine Couret <charles-antoine.couret@essensium.com> + +description: | + Specifications on the converters can be found at: + AD7949: + https://www.analog.com/media/en/technical-documentation/data-sheets/AD7949.pdf + AD7682/AD7698: + https://www.analog.com/media/en/technical-documentation/data-sheets/AD7682_7689.pdf + +properties: + compatible: + enum: + - adi,ad7682 + - adi,ad7689 + - adi,ad7949 + + reg: + maxItems: 1 + + vref-supply: + description: + ADC reference voltage supply + + spi-max-frequency: true + + "#io-channel-cells": + const: 1 + +required: + - compatible + - reg + - vref-supply + +additionalProperties: false + +examples: + - | + spi { + #address-cells = <1>; + #size-cells = <0>; + + adc@0 { + compatible = "adi,ad7949"; + reg = <0>; + vref-supply = <&vdd_supply>; + }; + }; +... diff --git a/Documentation/devicetree/bindings/iio/adc/adi,ad9467.yaml b/Documentation/devicetree/bindings/iio/adc/adi,ad9467.yaml index c4f57fa6aad1..b5aed40d8a50 100644 --- a/Documentation/devicetree/bindings/iio/adc/adi,ad9467.yaml +++ b/Documentation/devicetree/bindings/iio/adc/adi,ad9467.yaml @@ -4,21 +4,30 @@ $id: http://devicetree.org/schemas/iio/adc/adi,ad9467.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# -title: Analog Devices AD9467 High-Speed ADC +title: Analog Devices AD9467 and similar High-Speed ADCs maintainers: - Michael Hennerich <michael.hennerich@analog.com> - Alexandru Ardelean <alexandru.ardelean@analog.com> description: | - The AD9467 is a 16-bit, monolithic, IF sampling analog-to-digital - converter (ADC). + The AD9467 and the parts similar with it, are high-speed analog-to-digital + converters (ADCs), operating in the range of 100 to 500 mega samples + per second (MSPS). Some parts support higher MSPS and some + lower MSPS, suitable for the intended application of each part. + All the parts support the register map described by Application Note AN-877 + https://www.analog.com/media/en/technical-documentation/application-notes/AN-877.pdf + + https://www.analog.com/media/en/technical-documentation/data-sheets/AD9265.pdf + https://www.analog.com/media/en/technical-documentation/data-sheets/AD9434.pdf https://www.analog.com/media/en/technical-documentation/data-sheets/AD9467.pdf properties: compatible: enum: + - adi,ad9265 + - adi,ad9434 - adi,ad9467 reg: diff --git a/Documentation/devicetree/bindings/iio/adc/ads1015.txt b/Documentation/devicetree/bindings/iio/adc/ads1015.txt deleted file mode 100644 index 918a507d1159..000000000000 --- a/Documentation/devicetree/bindings/iio/adc/ads1015.txt +++ /dev/null @@ -1,73 +0,0 @@ -ADS1015 (I2C) - -This device is a 12-bit A-D converter with 4 inputs. - -The inputs can be used single ended or in certain differential combinations. - -For configuration all possible combinations are mapped to 8 channels: - 0: Voltage over AIN0 and AIN1. - 1: Voltage over AIN0 and AIN3. - 2: Voltage over AIN1 and AIN3. - 3: Voltage over AIN2 and AIN3. - 4: Voltage over AIN0 and GND. - 5: Voltage over AIN1 and GND. - 6: Voltage over AIN2 and GND. - 7: Voltage over AIN3 and GND. - -Each channel can be configured individually: - - pga is the programmable gain amplifier (values are full scale) - 0: +/- 6.144 V - 1: +/- 4.096 V - 2: +/- 2.048 V (default) - 3: +/- 1.024 V - 4: +/- 0.512 V - 5: +/- 0.256 V - - data_rate in samples per second - 0: 128 - 1: 250 - 2: 490 - 3: 920 - 4: 1600 (default) - 5: 2400 - 6: 3300 - -1) The /ads1015 node - - Required properties: - - - compatible : must be "ti,ads1015" - - reg : I2C bus address of the device - - #address-cells : must be <1> - - #size-cells : must be <0> - - The node contains child nodes for each channel that the platform uses. - - Example ADS1015 node: - - ads1015@49 { - compatible = "ti,ads1015"; - reg = <0x49>; - #address-cells = <1>; - #size-cells = <0>; - - [ child node definitions... ] - } - -2) channel nodes - - Required properties: - - - reg : the channel number - - Optional properties: - - - ti,gain : the programmable gain amplifier setting - - ti,datarate : the converter data rate - - Example ADS1015 channel node: - - channel@4 { - reg = <4>; - ti,gain = <3>; - ti,datarate = <5>; - }; diff --git a/Documentation/devicetree/bindings/iio/adc/amlogic,meson-saradc.txt b/Documentation/devicetree/bindings/iio/adc/amlogic,meson-saradc.txt deleted file mode 100644 index d57e9df25f4f..000000000000 --- a/Documentation/devicetree/bindings/iio/adc/amlogic,meson-saradc.txt +++ /dev/null @@ -1,48 +0,0 @@ -* Amlogic Meson SAR (Successive Approximation Register) A/D converter - -Required properties: -- compatible: depending on the SoC this should be one of: - - "amlogic,meson8-saradc" for Meson8 - - "amlogic,meson8b-saradc" for Meson8b - - "amlogic,meson8m2-saradc" for Meson8m2 - - "amlogic,meson-gxbb-saradc" for GXBB - - "amlogic,meson-gxl-saradc" for GXL - - "amlogic,meson-gxm-saradc" for GXM - - "amlogic,meson-axg-saradc" for AXG - - "amlogic,meson-g12a-saradc" for AXG - along with the generic "amlogic,meson-saradc" -- reg: the physical base address and length of the registers -- interrupts: the interrupt indicating end of sampling -- clocks: phandle and clock identifier (see clock-names) -- clock-names: mandatory clocks: - - "clkin" for the reference clock (typically XTAL) - - "core" for the SAR ADC core clock - optional clocks: - - "adc_clk" for the ADC (sampling) clock - - "adc_sel" for the ADC (sampling) clock mux -- vref-supply: the regulator supply for the ADC reference voltage -- #io-channel-cells: must be 1, see ../iio-bindings.txt - -Optional properties: -- amlogic,hhi-sysctrl: phandle to the syscon which contains the 5th bit - of the TSC (temperature sensor coefficient) on - Meson8b and Meson8m2 (which used to calibrate the - temperature sensor) -- nvmem-cells: phandle to the temperature_calib eFuse cells -- nvmem-cell-names: if present (to enable the temperature sensor - calibration) this must contain "temperature_calib" - - -Example: - saradc: adc@8680 { - compatible = "amlogic,meson-gxl-saradc", "amlogic,meson-saradc"; - #io-channel-cells = <1>; - reg = <0x0 0x8680 0x0 0x34>; - interrupts = <GIC_SPI 73 IRQ_TYPE_EDGE_RISING>; - clocks = <&xtal>, - <&clkc CLKID_SAR_ADC>, - <&clkc CLKID_SANA>, - <&clkc CLKID_SAR_ADC_CLK>, - <&clkc CLKID_SAR_ADC_SEL>; - clock-names = "clkin", "core", "sana", "adc_clk", "adc_sel"; - }; diff --git a/Documentation/devicetree/bindings/iio/adc/amlogic,meson-saradc.yaml b/Documentation/devicetree/bindings/iio/adc/amlogic,meson-saradc.yaml new file mode 100644 index 000000000000..3be8955587e4 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/amlogic,meson-saradc.yaml @@ -0,0 +1,149 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/amlogic,meson-saradc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Amlogic Meson SAR (Successive Approximation Register) A/D converter + +maintainers: + - Martin Blumenstingl <martin.blumenstingl@googlemail.com> + +description: + Binding covers a range of ADCs found on Amlogic Meson SoCs. + +properties: + compatible: + oneOf: + - const: amlogic,meson-saradc + - items: + - enum: + - amlogic,meson8-saradc + - amlogic,meson8b-saradc + - amlogic,meson8m2-saradc + - amlogic,meson-gxbb-saradc + - amlogic,meson-gxl-saradc + - amlogic,meson-gxm-saradc + - amlogic,meson-axg-saradc + - amlogic,meson-g12a-saradc + - const: amlogic,meson-saradc + + reg: + maxItems: 1 + + interrupts: + description: Interrupt indicates end of sampling. + maxItems: 1 + + clocks: + minItems: 2 + maxItems: 4 + + clock-names: + minItems: 2 + maxItems: 4 + items: + - const: clkin + - const: core + - const: adc_clk + - const: adc_sel + + vref-supply: true + + "#io-channel-cells": + const: 1 + + amlogic,hhi-sysctrl: + $ref: /schemas/types.yaml#/definitions/phandle + description: + Syscon which contains the 5th bit of the TSC (temperature sensor + coefficient) on Meson8b and Meson8m2 (which used to calibrate the + temperature sensor) + + nvmem-cells: + description: phandle to the temperature_calib eFuse cells + maxItems: 1 + + nvmem-cell-names: + const: temperature_calib + +allOf: + - if: + properties: + compatible: + contains: + enum: + - amlogic,meson8-saradc + - amlogic,meson8b-saradc + - amlogic,meson8m2-saradc + then: + properties: + clocks: + maxItems: 2 + clock-names: + maxItems: 2 + else: + properties: + nvmem-cells: false + mvmem-cel-names: false + clocks: + minItems: 4 + clock-names: + minItems: 4 + + - if: + properties: + compatible: + contains: + enum: + - amlogic,meson8b-saradc + - amlogic,meson8m2-saradc + then: + properties: + amlogic,hhi-sysctrl: true + else: + properties: + amlogic,hhi-sysctrl: false + +required: + - compatible + - reg + - interrupts + - clocks + - clock-names + - "#io-channel-cells" + +additionalProperties: false + +examples: + - | + #include <dt-bindings/interrupt-controller/irq.h> + #include <dt-bindings/clock/gxbb-clkc.h> + #include <dt-bindings/interrupt-controller/arm-gic.h> + soc { + #address-cells = <2>; + #size-cells = <2>; + adc@8680 { + compatible = "amlogic,meson-gxl-saradc", "amlogic,meson-saradc"; + #io-channel-cells = <1>; + reg = <0x0 0x8680 0x0 0x34>; + interrupts = <GIC_SPI 73 IRQ_TYPE_EDGE_RISING>; + clocks = <&xtal>, + <&clkc CLKID_SAR_ADC>, + <&clkc CLKID_SAR_ADC_CLK>, + <&clkc CLKID_SAR_ADC_SEL>; + clock-names = "clkin", "core", "adc_clk", "adc_sel"; + }; + adc@9680 { + compatible = "amlogic,meson8b-saradc", "amlogic,meson-saradc"; + #io-channel-cells = <1>; + reg = <0x0 0x9680 0x0 0x34>; + interrupts = <GIC_SPI 73 IRQ_TYPE_EDGE_RISING>; + clocks = <&xtal>, <&clkc CLKID_SAR_ADC>; + clock-names = "clkin", "core"; + nvmem-cells = <&tsens_caldata>; + nvmem-cell-names = "temperature_calib"; + amlogic,hhi-sysctrl = <&hhi>; + }; + }; +... diff --git a/Documentation/devicetree/bindings/iio/adc/aspeed,ast2400-adc.yaml b/Documentation/devicetree/bindings/iio/adc/aspeed,ast2400-adc.yaml new file mode 100644 index 000000000000..7f534a933e92 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/aspeed,ast2400-adc.yaml @@ -0,0 +1,55 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/aspeed,ast2400-adc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: ADC that forms part of an ASPEED server management processor. + +maintainers: + - Joel Stanley <joel@jms.id.au> + +description: + This device is a 10-bit converter for 16 voltage channels. All inputs are + single ended. + +properties: + compatible: + enum: + - aspeed,ast2400-adc + - aspeed,ast2500-adc + + reg: + maxItems: 1 + + clocks: + description: + Input clock used to derive the sample clock. Expected to be the + SoC's APB clock. + + resets: + maxItems: 1 + + "#io-channel-cells": + const: 1 + +required: + - compatible + - reg + - clocks + - resets + - "#io-channel-cells" + +additionalProperties: false + +examples: + - | + #include <dt-bindings/clock/aspeed-clock.h> + adc@1e6e9000 { + compatible = "aspeed,ast2400-adc"; + reg = <0x1e6e9000 0xb0>; + clocks = <&syscon ASPEED_CLK_APB>; + resets = <&syscon ASPEED_RESET_ADC>; + #io-channel-cells = <1>; + }; +... diff --git a/Documentation/devicetree/bindings/iio/adc/aspeed_adc.txt b/Documentation/devicetree/bindings/iio/adc/aspeed_adc.txt deleted file mode 100644 index 034fc2ba100e..000000000000 --- a/Documentation/devicetree/bindings/iio/adc/aspeed_adc.txt +++ /dev/null @@ -1,22 +0,0 @@ -Aspeed ADC - -This device is a 10-bit converter for 16 voltage channels. All inputs are -single ended. - -Required properties: -- compatible: Should be "aspeed,ast2400-adc" or "aspeed,ast2500-adc" -- reg: memory window mapping address and length -- clocks: Input clock used to derive the sample clock. Expected to be the - SoC's APB clock. -- resets: Reset controller phandle -- #io-channel-cells: Must be set to <1> to indicate channels are selected - by index. - -Example: - adc@1e6e9000 { - compatible = "aspeed,ast2400-adc"; - reg = <0x1e6e9000 0xb0>; - clocks = <&syscon ASPEED_CLK_APB>; - resets = <&syscon ASPEED_RESET_ADC>; - #io-channel-cells = <1>; - }; diff --git a/Documentation/devicetree/bindings/iio/adc/berlin2_adc.txt b/Documentation/devicetree/bindings/iio/adc/berlin2_adc.txt deleted file mode 100644 index 908334c6b07f..000000000000 --- a/Documentation/devicetree/bindings/iio/adc/berlin2_adc.txt +++ /dev/null @@ -1,19 +0,0 @@ -* Berlin Analog to Digital Converter (ADC) - -The Berlin ADC has 8 channels, with one connected to a temperature sensor. -It is part of the system controller register set. The ADC node should be a -sub-node of the system controller node. - -Required properties: -- compatible: must be "marvell,berlin2-adc" -- interrupts: the interrupts for the ADC and the temperature sensor -- interrupt-names: should be "adc" and "tsen" - -Example: - -adc: adc { - compatible = "marvell,berlin2-adc"; - interrupt-parent = <&sic>; - interrupts = <12>, <14>; - interrupt-names = "adc", "tsen"; -}; diff --git a/Documentation/devicetree/bindings/iio/adc/cc10001_adc.txt b/Documentation/devicetree/bindings/iio/adc/cc10001_adc.txt deleted file mode 100644 index 904f76de9055..000000000000 --- a/Documentation/devicetree/bindings/iio/adc/cc10001_adc.txt +++ /dev/null @@ -1,22 +0,0 @@ -* Cosmic Circuits - Analog to Digital Converter (CC-10001-ADC) - -Required properties: - - compatible: Should be "cosmic,10001-adc" - - reg: Should contain adc registers location and length. - - clock-names: Should contain "adc". - - clocks: Should contain a clock specifier for each entry in clock-names - - vref-supply: The regulator supply ADC reference voltage. - -Optional properties: - - adc-reserved-channels: Bitmask of reserved channels, - i.e. channels that cannot be used by the OS. - -Example: -adc: adc@18101600 { - compatible = "cosmic,10001-adc"; - reg = <0x18101600 0x24>; - adc-reserved-channels = <0x2>; - clocks = <&adc_clk>; - clock-names = "adc"; - vref-supply = <®_1v8>; -}; diff --git a/Documentation/devicetree/bindings/iio/adc/cosmic,10001-adc.yaml b/Documentation/devicetree/bindings/iio/adc/cosmic,10001-adc.yaml new file mode 100644 index 000000000000..5d92b477e23f --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/cosmic,10001-adc.yaml @@ -0,0 +1,59 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/cosmic,10001-adc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Cosmic Circuits CC-10001 ADC + +maintainers: + - Jonathan Cameron <jic23@kernel.org> + +description: + Cosmic Circuits 10001 10-bit ADC device. + +properties: + compatible: + const: cosmic,10001-adc + + reg: + maxItems: 1 + + adc-reserved-channels: + $ref: /schemas/types.yaml#/definitions/uint32 + description: + Bitmask of reserved channels, i.e. channels that cannot be + used by the OS. + + clocks: + maxItems: 1 + + clock-names: + const: adc + + vref-supply: true + + "#io-channel-cells": + const: 1 + + +required: + - compatible + - reg + - clocks + - clock-names + - vref-supply + +additionalProperties: false + +examples: + - | + adc@18101600 { + compatible = "cosmic,10001-adc"; + reg = <0x18101600 0x24>; + adc-reserved-channels = <0x2>; + clocks = <&adc_clk>; + clock-names = "adc"; + vref-supply = <®_1v8>; + }; +... diff --git a/Documentation/devicetree/bindings/iio/adc/cpcap-adc.txt b/Documentation/devicetree/bindings/iio/adc/cpcap-adc.txt deleted file mode 100644 index ec04008e8f4f..000000000000 --- a/Documentation/devicetree/bindings/iio/adc/cpcap-adc.txt +++ /dev/null @@ -1,17 +0,0 @@ -Motorola CPCAP PMIC ADC binding - -Required properties: -- compatible: Should be "motorola,cpcap-adc" or "motorola,mapphone-cpcap-adc" -- interrupts: The interrupt number for the ADC device -- interrupt-names: Should be "adcdone" -- #io-channel-cells: Number of cells in an IIO specifier - -Example: - -cpcap_adc: adc { - compatible = "motorola,mapphone-cpcap-adc"; - interrupt-parent = <&cpcap>; - interrupts = <8 IRQ_TYPE_NONE>; - interrupt-names = "adcdone"; - #io-channel-cells = <1>; -}; diff --git a/Documentation/devicetree/bindings/iio/adc/da9150-gpadc.txt b/Documentation/devicetree/bindings/iio/adc/da9150-gpadc.txt deleted file mode 100644 index c07228da92ac..000000000000 --- a/Documentation/devicetree/bindings/iio/adc/da9150-gpadc.txt +++ /dev/null @@ -1,16 +0,0 @@ -Dialog Semiconductor DA9150 IIO GPADC bindings - -Required properties: -- compatible: "dlg,da9150-gpadc" for DA9150 IIO GPADC -- #io-channel-cells: Should be set to <1> - (See Documentation/devicetree/bindings/iio/iio-bindings.txt for further info) - -For further information on GPADC channels, see device datasheet. - - -Example: - - gpadc: da9150-gpadc { - compatible = "dlg,da9150-gpadc"; - #io-channel-cells = <1>; - }; diff --git a/Documentation/devicetree/bindings/iio/adc/dlg,da9150-gpadc.yaml b/Documentation/devicetree/bindings/iio/adc/dlg,da9150-gpadc.yaml new file mode 100644 index 000000000000..cc29a2f2111a --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/dlg,da9150-gpadc.yaml @@ -0,0 +1,35 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/dlg,da9150-gpadc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Dialog Semiconductor DA9150 IIO GPADC + +maintainers: + - Adam Thomson <Adam.Thomson.Opensource@diasemi.com> + +description: + This patch adds support for general purpose ADC within the + DA9150 Charger & Fuel-Gauge IC. + +properties: + compatible: + const: dlg,da9150-gpadc + + "#io-channel-cells": + const: 1 + +required: + - compatible + - "#io-channel-cells" + +additionalProperties: false + +examples: + - | + adc { + compatible = "dlg,da9150-gpadc"; + #io-channel-cells = <1>; + }; +... diff --git a/Documentation/devicetree/bindings/iio/adc/fsl,imx25-gcq.txt b/Documentation/devicetree/bindings/iio/adc/fsl,imx25-gcq.txt deleted file mode 100644 index eebdcec3dab5..000000000000 --- a/Documentation/devicetree/bindings/iio/adc/fsl,imx25-gcq.txt +++ /dev/null @@ -1,57 +0,0 @@ -Freescale i.MX25 ADC GCQ device - -This is a generic conversion queue device that can convert any of the -analog inputs using the ADC unit of the i.MX25. - -Required properties: - - compatible: Should be "fsl,imx25-gcq". - - reg: Should be the register range of the module. - - interrupts: Should be the interrupt number of the module. - Typically this is <1>. - - #address-cells: Should be <1> (setting for the subnodes) - - #size-cells: Should be <0> (setting for the subnodes) - -Optional properties: - - vref-ext-supply: The regulator supplying the ADC reference voltage. - Required when at least one subnode uses the this reference. - - vref-xp-supply: The regulator supplying the ADC reference voltage on pin XP. - Required when at least one subnode uses this reference. - - vref-yp-supply: The regulator supplying the ADC reference voltage on pin YP. - Required when at least one subnode uses this reference. - -Sub-nodes: -Optionally you can define subnodes which define the reference voltage -for the analog inputs. - -Required properties for subnodes: - - reg: Should be the number of the analog input. - 0: xp - 1: yp - 2: xn - 3: yn - 4: wiper - 5: inaux0 - 6: inaux1 - 7: inaux2 -Optional properties for subnodes: - - fsl,adc-refp: specifies the positive reference input as defined in - <dt-bindings/iio/adc/fsl-imx25-gcq.h> - - fsl,adc-refn: specifies the negative reference input as defined in - <dt-bindings/iio/adc/fsl-imx25-gcq.h> - -Example: - - adc: adc@50030800 { - compatible = "fsl,imx25-gcq"; - reg = <0x50030800 0x60>; - interrupt-parent = <&tscadc>; - interrupts = <1>; - #address-cells = <1>; - #size-cells = <0>; - - inaux@5 { - reg = <5>; - fsl,adc-refp = <MX25_ADC_REFP_INT>; - fsl,adc-refn = <MX25_ADC_REFN_NGND>; - }; - }; diff --git a/Documentation/devicetree/bindings/iio/adc/fsl,imx25-gcq.yaml b/Documentation/devicetree/bindings/iio/adc/fsl,imx25-gcq.yaml new file mode 100644 index 000000000000..e9103497e3a4 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/fsl,imx25-gcq.yaml @@ -0,0 +1,131 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/fsl,imx25-gcq.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Freescale ADC GCQ device + +description: + This is a generic conversion queue device that can convert any of the + analog inputs using the ADC unit of the i.MX25. + +maintainers: + - Jonathan Cameron <jic23@kernel.org> + +properties: + compatible: + const: fsl,imx25-gcq + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + vref-ext-supply: + description: + The regulator supplying the ADC reference voltage. + Required when at least one subnode uses the this reference. + + vref-xp-supply: + description: + The regulator supplying the ADC reference voltage on pin XP. + Required when at least one subnode uses this reference. + + vref-yp-supply: + description: + The regulator supplying the ADC reference voltage on pin YP. + Required when at least one subnode uses this reference. + + "#io-channel-cells": + const: 1 + + "#address-cells": + const: 1 + + "#size-cells": + const: 0 + +required: + - compatible + - reg + - interrupts + - "#address-cells" + - "#size-cells" + +patternProperties: + "[a-z][a-z0-9]+@[0-9a-f]+$": + type: object + description: + Child nodes used to define the reference voltages used for each channel + + properties: + reg: + description: | + Number of the analog input. + 0: xp + 1: yp + 2: xn + 3: yn + 4: wiper + 5: inaux0 + 6: inaux1 + 7: inaux2 + items: + - minimum: 0 + maximum: 7 + + fsl,adc-refp: + $ref: /schemas/types.yaml#/definitions/uint32 + description: | + Specifies the positive reference input as defined in + <dt-bindings/iio/adc/fsl-imx25-gcq.h> + 0: YP voltage reference + 1: XP voltage reference + 2: External voltage reference + 3: Internal voltage reference (default) + minimum: 0 + maximum: 3 + + fsl,adc-refn: + $ref: /schemas/types.yaml#/definitions/uint32 + description: | + Specifies the negative reference input as defined in + <dt-bindings/iio/adc/fsl-imx25-gcq.h> + 0: XN ground reference + 1: YN ground reference + 2: Internal ground reference + 3: External ground reference (default) + minimum: 0 + maximum: 3 + + required: + - reg + + additionalProperties: false + +additionalProperties: false + +examples: + - | + #include <dt-bindings/iio/adc/fsl-imx25-gcq.h> + soc { + #address-cells = <1>; + #size-cells = <1>; + adc@50030800 { + compatible = "fsl,imx25-gcq"; + reg = <0x50030800 0x60>; + interrupt-parent = <&tscadc>; + interrupts = <1>; + #address-cells = <1>; + #size-cells = <0>; + + inaux@5 { + reg = <5>; + fsl,adc-refp = <MX25_ADC_REFP_INT>; + fsl,adc-refn = <MX25_ADC_REFN_NGND>; + }; + }; + }; +... diff --git a/Documentation/devicetree/bindings/iio/adc/fsl,imx7d-adc.yaml b/Documentation/devicetree/bindings/iio/adc/fsl,imx7d-adc.yaml new file mode 100644 index 000000000000..afc5cc48a0ce --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/fsl,imx7d-adc.yaml @@ -0,0 +1,62 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/fsl,imx7d-adc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Freescale ADC found on the imx7d SoC + +maintainers: + - Haibo Chen <haibo.chen@nxp.com> + +properties: + compatible: + const: fsl,imx7d-adc + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + maxItems: 1 + + clock-names: + const: adc + + vref-supply: true + + "#io-channel-cells": + const: 1 + +required: + - compatible + - reg + - interrupts + - clocks + - clock-names + - vref-supply + - "#io-channel-cells" + +additionalProperties: false + +examples: + - | + #include <dt-bindings/interrupt-controller/irq.h> + #include <dt-bindings/clock/imx7d-clock.h> + #include <dt-bindings/interrupt-controller/arm-gic.h> + soc { + #address-cells = <1>; + #size-cells = <1>; + adc@30610000 { + compatible = "fsl,imx7d-adc"; + reg = <0x30610000 0x10000>; + interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clks IMX7D_ADC_ROOT_CLK>; + clock-names = "adc"; + vref-supply = <®_vcc_3v3_mcu>; + #io-channel-cells = <1>; + }; + }; +... diff --git a/Documentation/devicetree/bindings/iio/adc/fsl,vf610-adc.yaml b/Documentation/devicetree/bindings/iio/adc/fsl,vf610-adc.yaml new file mode 100644 index 000000000000..1ca571056ea9 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/fsl,vf610-adc.yaml @@ -0,0 +1,81 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/fsl,vf610-adc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: ADC found on Freescale vf610 and similar SoCs + +maintainers: + - Fugang Duan <fugang.duan@nxp.com> + +description: + ADCs found on vf610/i.MX6slx and upward SoCs from Freescale. + +properties: + compatible: + const: fsl,vf610-adc + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + description: ADC source clock (ipg clock) + maxItems: 1 + + clock-names: + const: adc + + vref-supply: + description: ADC reference voltage supply. + + fsl,adck-max-frequency: + $ref: /schemas/types.yaml#/definitions/uint32-array + minItems: 3 + maxItems: 3 + description: | + Maximum frequencies from datasheet operating requirements. + Three values necessary to cover the 3 conversion modes. + * Frequency in normal mode (ADLPC=0, ADHSC=0) + * Frequency in high-speed mode (ADLPC=0, ADHSC=1) + * Frequency in low-power mode (ADLPC=1, ADHSC=0) + + min-sample-time: + $ref: /schemas/types.yaml#/definitions/uint32 + description: + Minimum sampling time in nanoseconds. This value has + to be chosen according to the conversion mode and the connected analog + source resistance (R_as) and capacitance (C_as). Refer the datasheet's + operating requirements. A safe default across a wide range of R_as and + C_as as well as conversion modes is 1000ns. + + "#io-channel-cells": + const: 1 + +required: + - compatible + - reg + - interrupts + - clocks + - clock-names + - vref-supply + +additionalProperties: false + +examples: + - | + #include <dt-bindings/clock/vf610-clock.h> + adc@4003b000 { + compatible = "fsl,vf610-adc"; + reg = <0x4003b000 0x1000>; + interrupts = <0 53 0x04>; + clocks = <&clks VF610_CLK_ADC0>; + clock-names = "adc"; + fsl,adck-max-frequency = <30000000>, <40000000>, <20000000>; + vref-supply = <®_vcc_3v3_mcu>; + min-sample-time = <10000>; + }; +... diff --git a/Documentation/devicetree/bindings/iio/adc/hi8435.txt b/Documentation/devicetree/bindings/iio/adc/hi8435.txt deleted file mode 100644 index 3b0348c5e516..000000000000 --- a/Documentation/devicetree/bindings/iio/adc/hi8435.txt +++ /dev/null @@ -1,21 +0,0 @@ -Holt Integrated Circuits HI-8435 threshold detector bindings - -Required properties: - - compatible: should be "holt,hi8435" - - reg: spi chip select number for the device - -Recommended properties: - - spi-max-frequency: definition as per - Documentation/devicetree/bindings/spi/spi-bus.txt - -Optional properties: - - gpios: GPIO used for controlling the reset pin - -Example: -sensor@0 { - compatible = "holt,hi8435"; - reg = <0>; - gpios = <&gpio6 1 0>; - - spi-max-frequency = <1000000>; -}; diff --git a/Documentation/devicetree/bindings/iio/adc/holt,hi8435.yaml b/Documentation/devicetree/bindings/iio/adc/holt,hi8435.yaml new file mode 100644 index 000000000000..9514c3381c42 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/holt,hi8435.yaml @@ -0,0 +1,50 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/holt,hi8435.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Holt Integrated Circuits HI-8435 SPI threshold detector + +maintainers: + - Vladimir Barinov <vladimir.barinov@cogentembedded.com> + +description: | + Datasheet: http://www.holtic.com/documents/427-hi-8435_v-rev-lpdf.do + +properties: + compatible: + const: holt,hi8435 + + reg: + maxItems: 1 + + gpios: + description: + GPIO used for controlling the reset pin + maxItems: 1 + + spi-max-frequency: true + + "#io-channel-cells": + const: 1 + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + spi { + #address-cells = <1>; + #size-cells = <0>; + threshold-detector@0 { + compatible = "holt,hi8435"; + reg = <0>; + gpios = <&gpio6 1 0>; + spi-max-frequency = <1000000>; + }; + }; +... diff --git a/Documentation/devicetree/bindings/iio/adc/imx7d-adc.txt b/Documentation/devicetree/bindings/iio/adc/imx7d-adc.txt deleted file mode 100644 index f1f3a552459b..000000000000 --- a/Documentation/devicetree/bindings/iio/adc/imx7d-adc.txt +++ /dev/null @@ -1,24 +0,0 @@ -Freescale imx7d ADC bindings - -The devicetree bindings are for the ADC driver written for -imx7d SoC. - -Required properties: -- compatible: Should be "fsl,imx7d-adc" -- reg: Offset and length of the register set for the ADC device -- interrupts: The interrupt number for the ADC device -- clocks: The root clock of the ADC controller -- clock-names: Must contain "adc", matching entry in the clocks property -- vref-supply: The regulator supply ADC reference voltage -- #io-channel-cells: Must be 1 as per ../iio-bindings.txt - -Example: -adc1: adc@30610000 { - compatible = "fsl,imx7d-adc"; - reg = <0x30610000 0x10000>; - interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&clks IMX7D_ADC_ROOT_CLK>; - clock-names = "adc"; - vref-supply = <®_vcc_3v3_mcu>; - #io-channel-cells = <1>; -}; diff --git a/Documentation/devicetree/bindings/iio/adc/lltc,ltc2497.yaml b/Documentation/devicetree/bindings/iio/adc/lltc,ltc2497.yaml new file mode 100644 index 000000000000..6a176f551d75 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/lltc,ltc2497.yaml @@ -0,0 +1,44 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$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 + +maintainers: + - Michael Hennerich <michael.hennerich@analog.com> + +description: | + 16bit ADC supporting up to 16 single ended or 8 differential inputs. + I2C interface. + +properties: + compatible: + const: + lltc,ltc2497 + + reg: true + vref-supply: true + "#io-channel-cells": + const: 1 + +required: + - compatible + - reg + - vref-supply + +examples: + - | + i2c { + #address-cells = <1>; + #size-cells = <0>; + + adc@76 { + compatible = "lltc,ltc2497"; + reg = <0x76>; + vref-supply = <<c2497_reg>; + #io-channel-cells = <1>; + }; + }; +... diff --git a/Documentation/devicetree/bindings/iio/adc/lpc1850-adc.txt b/Documentation/devicetree/bindings/iio/adc/lpc1850-adc.txt deleted file mode 100644 index 9ada5abd45fa..000000000000 --- a/Documentation/devicetree/bindings/iio/adc/lpc1850-adc.txt +++ /dev/null @@ -1,20 +0,0 @@ -NXP LPC1850 ADC bindings - -Required properties: -- compatible: Should be "nxp,lpc1850-adc" -- reg: Offset and length of the register set for the ADC device -- interrupts: The interrupt number for the ADC device -- clocks: The root clock of the ADC controller -- vref-supply: The regulator supply ADC reference voltage -- resets: phandle to reset controller and line specifier - -Example: - -adc0: adc@400e3000 { - compatible = "nxp,lpc1850-adc"; - reg = <0x400e3000 0x1000>; - interrupts = <17>; - clocks = <&ccu1 CLK_APB3_ADC0>; - vref-supply = <®_vdda>; - resets = <&rgu 40>; -}; diff --git a/Documentation/devicetree/bindings/iio/adc/lpc32xx-adc.txt b/Documentation/devicetree/bindings/iio/adc/lpc32xx-adc.txt deleted file mode 100644 index 3a1bc669bd51..000000000000 --- a/Documentation/devicetree/bindings/iio/adc/lpc32xx-adc.txt +++ /dev/null @@ -1,21 +0,0 @@ -* NXP LPC32xx SoC ADC controller - -Required properties: -- compatible: must be "nxp,lpc3220-adc" -- reg: physical base address of the controller and length of memory mapped - region. -- interrupts: The ADC interrupt - -Optional: - - vref-supply: The regulator supply ADC reference voltage, optional - for legacy reason, but highly encouraging to us in new device tree - -Example: - - adc@40048000 { - compatible = "nxp,lpc3220-adc"; - reg = <0x40048000 0x1000>; - interrupt-parent = <&mic>; - interrupts = <39 0>; - vref-supply = <&vcc>; - }; diff --git a/Documentation/devicetree/bindings/iio/adc/ltc2497.txt b/Documentation/devicetree/bindings/iio/adc/ltc2497.txt deleted file mode 100644 index a237ed99c0d8..000000000000 --- a/Documentation/devicetree/bindings/iio/adc/ltc2497.txt +++ /dev/null @@ -1,13 +0,0 @@ -* Linear Technology / Analog Devices LTC2497 ADC - -Required properties: - - compatible: Must be "lltc,ltc2497" - - reg: Must contain the ADC I2C address - - vref-supply: The regulator supply for ADC reference voltage - -Example: - ltc2497: adc@76 { - compatible = "lltc,ltc2497"; - reg = <0x76>; - vref-supply = <<c2497_reg>; - }; diff --git a/Documentation/devicetree/bindings/iio/adc/marvell,berlin2-adc.yaml b/Documentation/devicetree/bindings/iio/adc/marvell,berlin2-adc.yaml new file mode 100644 index 000000000000..b3b292fb1c59 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/marvell,berlin2-adc.yaml @@ -0,0 +1,50 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/marvell,berlin2-adc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Berlin 2 Analog to Digital Converter (ADC) + +maintainers: + - Antoine Tenart <antoine.tenart@free-electrons.com> + +description: + The Berlin ADC has 8 channels, with one connected to a temperature sensor. + It is part of the system controller register set. The ADC node should be a + sub-node of the system controller node. + +properties: + compatible: + const: marvell,berlin2-adc + + interrupts: + minItems: 2 + maxItems: 2 + + interrupt-names: + items: + - const: adc + - const: tsen + + "#io-channel-cells": + const: 1 + +required: + - compatible + - interrupts + - interrupt-names + +additionalProperties: false + +examples: + - | + sysctrl { + adc { + compatible = "marvell,berlin2-adc"; + interrupt-parent = <&sic>; + interrupts = <12>, <14>; + interrupt-names = "adc", "tsen"; + }; + }; +... diff --git a/Documentation/devicetree/bindings/iio/adc/max11100.txt b/Documentation/devicetree/bindings/iio/adc/max11100.txt deleted file mode 100644 index b7f7177b8aca..000000000000 --- a/Documentation/devicetree/bindings/iio/adc/max11100.txt +++ /dev/null @@ -1,18 +0,0 @@ -* Maxim max11100 Analog to Digital Converter (ADC) - -Required properties: - - compatible: Should be "maxim,max11100" - - reg: the adc unit address - - vref-supply: phandle to the regulator that provides reference voltage - -Optional properties: - - spi-max-frequency: SPI maximum frequency - -Example: - -max11100: adc@0 { - compatible = "maxim,max11100"; - reg = <0>; - vref-supply = <&adc0_vref>; - spi-max-frequency = <240000>; -}; diff --git a/Documentation/devicetree/bindings/iio/adc/max1118.txt b/Documentation/devicetree/bindings/iio/adc/max1118.txt deleted file mode 100644 index cf33d0b15a6d..000000000000 --- a/Documentation/devicetree/bindings/iio/adc/max1118.txt +++ /dev/null @@ -1,21 +0,0 @@ -* MAX1117/MAX1118/MAX1119 8-bit, dual-channel ADCs - -Required properties: - - compatible: Should be one of - * "maxim,max1117" - * "maxim,max1118" - * "maxim,max1119" - - reg: spi chip select number for the device - - (max1118 only) vref-supply: The regulator supply for ADC reference voltage - -Recommended properties: - - spi-max-frequency: Definition as per - Documentation/devicetree/bindings/spi/spi-bus.txt - -Example: -adc@0 { - compatible = "maxim,max1118"; - reg = <0>; - vref-supply = <&vdd_supply>; - spi-max-frequency = <1000000>; -}; diff --git a/Documentation/devicetree/bindings/iio/adc/max9611.txt b/Documentation/devicetree/bindings/iio/adc/max9611.txt deleted file mode 100644 index ab4f43145ae5..000000000000 --- a/Documentation/devicetree/bindings/iio/adc/max9611.txt +++ /dev/null @@ -1,27 +0,0 @@ -* Maxim max9611/max9612 current sense amplifier with 12-bits ADC interface - -Maxim max9611/max9612 is an high-side current sense amplifier with integrated -12-bits ADC communicating over I2c bus. -The device node for this driver shall be a child of a I2c controller. - -Required properties - - compatible: Should be "maxim,max9611" or "maxim,max9612" - - reg: The 7-bits long I2c address of the device - - shunt-resistor-micro-ohms: Value, in micro Ohms, of the current sense shunt - resistor - -Example: - -&i2c4 { - csa: adc@7c { - compatible = "maxim,max9611"; - reg = <0x7c>; - - shunt-resistor-micro-ohms = <5000>; - }; -}; - -This device node describes a current sense amplifier sitting on I2c4 bus -with address 0x7c (read address is 0xf9, write address is 0xf8). -A sense resistor of 0,005 Ohm is installed between RS+ and RS- current-sensing -inputs. diff --git a/Documentation/devicetree/bindings/iio/adc/maxim,max11100.yaml b/Documentation/devicetree/bindings/iio/adc/maxim,max11100.yaml new file mode 100644 index 000000000000..0cf87556ef82 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/maxim,max11100.yaml @@ -0,0 +1,49 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/maxim,max11100.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Maxim MAX11100 ADC + +maintainers: + - Jacopo Mondi <jacopo@jmondi.org> + +description: | + Single channel 16 bit ADC with SPI interface. + +properties: + compatible: + const: maxim,max11100 + + reg: + maxItems: 1 + + vref-supply: + description: External reference, needed to establish input scaling. + + spi-max-frequency: + minimum: 100000 + maximum: 4800000 + +additionalProperties: false + +required: + - compatible + - reg + - vref-supply + +examples: + - | + spi { + #address-cells = <1>; + #size-cells = <0>; + + adc@0 { + compatible = "maxim,max11100"; + reg = <0>; + vref-supply = <&adc_vref>; + spi-max-frequency = <240000>; + }; + }; +... diff --git a/Documentation/devicetree/bindings/iio/adc/maxim,max1118.yaml b/Documentation/devicetree/bindings/iio/adc/maxim,max1118.yaml new file mode 100644 index 000000000000..e948b3e37b0c --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/maxim,max1118.yaml @@ -0,0 +1,62 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/maxim,max1118.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Maxim MAX1118 and similar ADCs + +maintainers: + - Akinobu Mita <akinobu.mita@gmail.com> + +description: | + Dual channel 8bit ADCs. + +properties: + compatible: + enum: + - maxim,max1117 + - maxim,max1118 + - maxim,max1119 + + reg: + maxItems: 1 + + spi-max-frequency: + maximum: 5000000 + + vref-supply: + description: External reference, needed to establish input scaling + +if: + properties: + compatible: + contains: + const: maxim,max1118 +then: + required: + - vref-supply +else: + properties: + vref-supply: false + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + spi { + #address-cells = <1>; + #size-cells = <0>; + + adc@0 { + compatible = "maxim,max1118"; + reg = <0>; + vref-supply = <&adc_vref>; + spi-max-frequency = <1000000>; + }; + }; +... diff --git a/Documentation/devicetree/bindings/iio/adc/maxim,max9611.yaml b/Documentation/devicetree/bindings/iio/adc/maxim,max9611.yaml new file mode 100644 index 000000000000..9475a9e6e920 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/maxim,max9611.yaml @@ -0,0 +1,51 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/maxim,max9611.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Maxim MAX9611 and similar current sense amplifiers with integrated ADCs + +maintainers: + - Jacopo Mondi <jacopo@jmondi.org> + +description: | + These devices combine a high-side current sense amplifier with a 12 bit ADC. + They have an i2c interface. + +properties: + compatible: + enum: + - maxim,max9611 + - maxim,max9612 + + reg: + maxItems: 1 + + shunt-resistor-micro-ohms: + $ref: /schemas/types.yaml#/definitions/uint32 + description: | + Value in micro Ohms of the shunt resistor connected between the RS+ and + RS- inputs, across which the current is measured. Value needed to compute + the scaling of the measured current. + +additionalProperties: false + +required: + - compatible + - reg + - shunt-resistor-micro-ohms + +examples: + - | + i2c { + #address-cells = <1>; + #size-cells = <0>; + + adc@7c { + compatible = "maxim,max9611"; + reg = <0x7c>; + shunt-resistor-micro-ohms = <5000>; + }; + }; +... diff --git a/Documentation/devicetree/bindings/iio/adc/mcp320x.txt b/Documentation/devicetree/bindings/iio/adc/mcp320x.txt deleted file mode 100644 index 56373d643f76..000000000000 --- a/Documentation/devicetree/bindings/iio/adc/mcp320x.txt +++ /dev/null @@ -1,57 +0,0 @@ -* Microchip Analog to Digital Converter (ADC) - -The node for this driver must be a child node of a SPI controller, hence -all mandatory properties described in - - Documentation/devicetree/bindings/spi/spi-bus.txt - -must be specified. - -Required properties: - - compatible: Must be one of the following, depending on the - model: - "mcp3001" (DEPRECATED) - "mcp3002" (DEPRECATED) - "mcp3004" (DEPRECATED) - "mcp3008" (DEPRECATED) - "mcp3201" (DEPRECATED) - "mcp3202" (DEPRECATED) - "mcp3204" (DEPRECATED) - "mcp3208" (DEPRECATED) - "mcp3301" (DEPRECATED) - - "microchip,mcp3001" - "microchip,mcp3002" - "microchip,mcp3004" - "microchip,mcp3008" - "microchip,mcp3201" - "microchip,mcp3202" - "microchip,mcp3204" - "microchip,mcp3208" - "microchip,mcp3301" - "microchip,mcp3550-50" - "microchip,mcp3550-60" - "microchip,mcp3551" - "microchip,mcp3553" - - NOTE: The use of the compatibles with no vendor prefix - is deprecated and only listed because old DT use them. - - - spi-cpha, spi-cpol (boolean): - Either SPI mode (0,0) or (1,1) must be used, so specify - none or both of spi-cpha, spi-cpol. The MCP3550/1/3 - is more efficient in mode (1,1) as only 3 instead of - 4 bytes need to be read from the ADC, but not all SPI - masters support it. - - - vref-supply: Phandle to the external reference voltage supply. - -Examples: -spi_controller { - mcp3x0x@0 { - compatible = "microchip,mcp3002"; - reg = <0>; - spi-max-frequency = <1000000>; - vref-supply = <&vref_reg>; - }; -}; diff --git a/Documentation/devicetree/bindings/iio/adc/mcp3422.txt b/Documentation/devicetree/bindings/iio/adc/mcp3422.txt deleted file mode 100644 index 82bcce07255d..000000000000 --- a/Documentation/devicetree/bindings/iio/adc/mcp3422.txt +++ /dev/null @@ -1,19 +0,0 @@ -* Microchip mcp3421/2/3/4/6/7/8 chip family (ADC) - -Required properties: - - compatible: Should be - "microchip,mcp3421" or - "microchip,mcp3422" or - "microchip,mcp3423" or - "microchip,mcp3424" or - "microchip,mcp3425" or - "microchip,mcp3426" or - "microchip,mcp3427" or - "microchip,mcp3428" - - reg: I2C address for the device - -Example: -adc@0 { - compatible = "microchip,mcp3424"; - reg = <0x68>; -}; diff --git a/Documentation/devicetree/bindings/iio/adc/microchip,mcp3201.yaml b/Documentation/devicetree/bindings/iio/adc/microchip,mcp3201.yaml new file mode 100644 index 000000000000..cbbac4ce56d6 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/microchip,mcp3201.yaml @@ -0,0 +1,77 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/microchip,mcp3201.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Microchip mcp3201 and similar ADCs + +maintainers: + - Oskar Andero <oskar.andero@gmail.com> + +description: | + Family of simple ADCs with an I2C inteface. + +properties: + compatible: + enum: + - microchip,mcp3001 + - microchip,mcp3002 + - microchip,mcp3004 + - microchip,mcp3008 + - microchip,mcp3201 + - microchip,mcp3202 + - microchip,mcp3204 + - microchip,mcp3208 + - microchip,mcp3301 + - microchip,mcp3550-50 + - microchip,mcp3550-60 + - microchip,mcp3551 + - microchip,mcp3553 + + reg: + maxItems: 1 + + spi-max-frequency: true + spi-cpha: true + spi-cpol: true + + vref-supply: + description: External reference. + + "#io-channel-cells": + const: 1 + +dependencies: + spi-cpol: [ spi-cpha ] + spi-cpha: [ spi-cpol ] + +required: + - compatible + - reg + - vref-supply + +additionalProperties: false + +examples: + - | + spi { + #address-cells = <1>; + #size-cells = <0>; + + adc@0 { + compatible = "microchip,mcp3002"; + reg = <0>; + vref-supply = <&vref_reg>; + spi-cpha; + spi-cpol; + #io-channel-cells = <1>; + }; + adc@1 { + compatible = "microchip,mcp3002"; + reg = <1>; + vref-supply = <&vref_reg>; + spi-max-frequency = <1500000>; + }; + }; +... diff --git a/Documentation/devicetree/bindings/iio/adc/motorola,cpcap-adc.yaml b/Documentation/devicetree/bindings/iio/adc/motorola,cpcap-adc.yaml new file mode 100644 index 000000000000..a6cb857a232d --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/motorola,cpcap-adc.yaml @@ -0,0 +1,53 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/motorola,cpcap-adc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Motorola CPCAP PMIC ADC binding + +maintainers: + - Tony Lindgren <tony@atomide.com> + +description: + On Motorola phones like droid 4 there is a custom CPCAP PMIC. This PMIC + has ADCs that are used for battery charging and USB PHY VBUS and ID pin + detection. + +properties: + compatible: + enum: + - motorola,cpcap-adc + - motorola,mapphone-cpcap-adc + + interrupts: + maxItems: 1 + + interrupt-names: + const: adcdone + + "#io-channel-cells": + const: 1 + +required: + - compatible + - interrupts + - "#io-channel-cells" + +additionalProperties: false + +examples: + - | + #include <dt-bindings/interrupt-controller/irq.h> + pmic { + #address-cells = <1>; + #size-cells = <0>; + adc { + compatible = "motorola,mapphone-cpcap-adc"; + interrupt-parent = <&cpcap>; + interrupts = <8 IRQ_TYPE_NONE>; + interrupt-names = "adcdone"; + #io-channel-cells = <1>; + }; + }; +... diff --git a/Documentation/devicetree/bindings/iio/adc/nuvoton,nau7802.yaml b/Documentation/devicetree/bindings/iio/adc/nuvoton,nau7802.yaml new file mode 100644 index 000000000000..04566ff02eb6 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/nuvoton,nau7802.yaml @@ -0,0 +1,50 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/nuvoton,nau7802.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Nuvoton NAU7802 I2c Analog to Digital Converter (ADC) + +maintainers: + - Alexandre Belloni <alexandre.belloni@bootlin.com> + - Maxime Ripard <mripard@kernel.org> + +properties: + compatible: + const: nuvoton,nau7802 + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + nuvoton,vldo: + $ref: /schemas/types.yaml#/definitions/uint32 + description: + Internal reference voltage in millivolts to be configured. + minimum: 2400 + maximum: 4500 + + "#io-channel-cells": + const: 1 + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + i2c { + #address-cells = <1>; + #size-cells = <0>; + nau7802@2a { + compatible = "nuvoton,nau7802"; + reg = <0x2a>; + nuvoton,vldo = <3000>; + }; + }; +... diff --git a/Documentation/devicetree/bindings/iio/adc/nuvoton,npcm-adc.txt b/Documentation/devicetree/bindings/iio/adc/nuvoton,npcm-adc.txt deleted file mode 100644 index ef8eeec1a997..000000000000 --- a/Documentation/devicetree/bindings/iio/adc/nuvoton,npcm-adc.txt +++ /dev/null @@ -1,26 +0,0 @@ -Nuvoton NPCM Analog to Digital Converter (ADC) - -The NPCM ADC is a 10-bit converter for eight channel inputs. - -Required properties: -- compatible: "nuvoton,npcm750-adc" for the NPCM7XX BMC. -- reg: specifies physical base address and size of the registers. -- interrupts: Contain the ADC interrupt with flags for falling edge. -- resets : phandle to the reset control for this device. - -Optional properties: -- clocks: phandle of ADC reference clock, in case the clock is not - added the ADC will use the default ADC sample rate. -- vref-supply: The regulator supply ADC reference voltage, in case the - vref-supply is not added the ADC will use internal voltage - reference. - -Example: - -adc: adc@f000c000 { - compatible = "nuvoton,npcm750-adc"; - reg = <0xf000c000 0x8>; - interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&clk NPCM7XX_CLK_ADC>; - resets = <&rstc NPCM7XX_RESET_IPSRST1 NPCM7XX_RESET_ADC>; -}; diff --git a/Documentation/devicetree/bindings/iio/adc/nuvoton,npcm750-adc.yaml b/Documentation/devicetree/bindings/iio/adc/nuvoton,npcm750-adc.yaml new file mode 100644 index 000000000000..001cf263b7d5 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/nuvoton,npcm750-adc.yaml @@ -0,0 +1,64 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/nuvoton,npcm750-adc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Nuvoton NPCM BMC Analog to Digital Converter (ADC) + +maintainers: + - Tomer Maimon <tmaimon77@gmail.com> + +description: + The NPCM ADC is a 10-bit converter for eight channel inputs. + +properties: + compatible: + const: nuvoton,npcm750-adc + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + description: ADC interrupt, should be set for falling edge. + + resets: + maxItems: 1 + + clocks: + maxItems: 1 + description: If not provided the defulat ADC sample rate will be used. + + vref-supply: + description: If not supplied, the internal voltage reference will be used. + + "#io-channel-cells": + const: 1 + +required: + - compatible + - reg + - interrupts + - resets + +additionalProperties: false + +examples: + - | + #include <dt-bindings/interrupt-controller/irq.h> + #include <dt-bindings/interrupt-controller/arm-gic.h> + #include <dt-bindings/clock/nuvoton,npcm7xx-clock.h> + #include <dt-bindings/reset/nuvoton,npcm7xx-reset.h> + soc { + #address-cells = <1>; + #size-cells = <1>; + adc@f000c000 { + compatible = "nuvoton,npcm750-adc"; + reg = <0xf000c000 0x8>; + interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk NPCM7XX_CLK_ADC>; + resets = <&rstc NPCM7XX_RESET_IPSRST1 NPCM7XX_RESET_ADC>; + }; + }; +... diff --git a/Documentation/devicetree/bindings/iio/adc/nuvoton-nau7802.txt b/Documentation/devicetree/bindings/iio/adc/nuvoton-nau7802.txt deleted file mode 100644 index e9582e6fe350..000000000000 --- a/Documentation/devicetree/bindings/iio/adc/nuvoton-nau7802.txt +++ /dev/null @@ -1,18 +0,0 @@ -* Nuvoton NAU7802 Analog to Digital Converter (ADC) - -Required properties: - - compatible: Should be "nuvoton,nau7802" - - reg: Should contain the ADC I2C address - -Optional properties: - - nuvoton,vldo: Internal reference voltage in millivolts to be - configured valid values are between 2400 mV and 4500 mV. - - interrupts: IRQ line for the ADC. If not used the driver will use - polling. - -Example: -adc2: nau7802@2a { - compatible = "nuvoton,nau7802"; - reg = <0x2a>; - nuvoton,vldo = <3000>; -}; diff --git a/Documentation/devicetree/bindings/iio/adc/nxp,lpc1850-adc.yaml b/Documentation/devicetree/bindings/iio/adc/nxp,lpc1850-adc.yaml new file mode 100644 index 000000000000..6404fb73f8ed --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/nxp,lpc1850-adc.yaml @@ -0,0 +1,61 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/nxp,lpc1850-adc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: NXP LPC1850 ADC bindings + +maintainers: + - Joachim Eastwood <manabian@gmail.com> + +description: + Supports the ADC found on the LPC1850 SoC. + +properties: + compatible: + const: nxp,lpc1850-adc + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + maxItems: 1 + + vref-supply: true + + resets: + maxItems: 1 + + "#io-channel-cells": + const: 1 + +required: + - compatible + - reg + - interrupts + - clocks + - vref-supply + - resets + +additionalProperties: false + +examples: + - | + #include <dt-bindings/clock/lpc18xx-ccu.h> + soc { + #address-cells = <1>; + #size-cells = <1>; + adc@400e3000 { + compatible = "nxp,lpc1850-adc"; + reg = <0x400e3000 0x1000>; + interrupts = <17>; + clocks = <&ccu1 CLK_APB3_ADC0>; + vref-supply = <®_vdda>; + resets = <&rgu 40>; + }; + }; +... diff --git a/Documentation/devicetree/bindings/iio/adc/nxp,lpc3220-adc.yaml b/Documentation/devicetree/bindings/iio/adc/nxp,lpc3220-adc.yaml new file mode 100644 index 000000000000..2c5032be83bd --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/nxp,lpc3220-adc.yaml @@ -0,0 +1,50 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/nxp,lpc3220-adc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: NXP LPC3220 SoC ADC controller + +maintainers: + - Gregory Clement <gregory.clement@bootlin.com> + +description: + This hardware block has been used on several LPC32XX SoCs. + +properties: + compatible: + const: nxp,lpc3220-adc + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + vref-supply: true + + "#io-channel-cells": + const: 1 + +required: + - compatible + - reg + - interrupts + +additionalProperties: false + +examples: + - | + soc { + #address-cells = <1>; + #size-cells = <1>; + adc@40048000 { + compatible = "nxp,lpc3220-adc"; + reg = <0x40048000 0x1000>; + interrupt-parent = <&mic>; + interrupts = <39 0>; + vref-supply = <&vcc>; + }; + }; +... diff --git a/Documentation/devicetree/bindings/iio/adc/samsung,exynos-adc.yaml b/Documentation/devicetree/bindings/iio/adc/samsung,exynos-adc.yaml index 7ed6afc36228..5ebb0ab250bd 100644 --- a/Documentation/devicetree/bindings/iio/adc/samsung,exynos-adc.yaml +++ b/Documentation/devicetree/bindings/iio/adc/samsung,exynos-adc.yaml @@ -41,7 +41,10 @@ properties: maxItems: 2 interrupts: - maxItems: 1 + description: + ADC interrupt followed by optional touchscreen interrupt. + minItems: 1 + maxItems: 2 "#io-channel-cells": const: 1 @@ -83,7 +86,6 @@ allOf: - samsung,exynos-adc-v2 - samsung,exynos3250-adc - samsung,exynos4212-adc - - samsung,s5pv210-adc then: required: - samsung,syscon-phandle @@ -112,6 +114,15 @@ allOf: items: - const: adc + - if: + required: + - has-touchscreen + then: + properties: + interrupts: + minItems: 2 + maxItems: 2 + examples: - | adc: adc@12d10000 { diff --git a/Documentation/devicetree/bindings/iio/adc/sprd,sc2720-adc.yaml b/Documentation/devicetree/bindings/iio/adc/sprd,sc2720-adc.yaml new file mode 100644 index 000000000000..caa3ee0b4b8c --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/sprd,sc2720-adc.yaml @@ -0,0 +1,72 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/sprd,sc2720-adc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Spreadtrum SC27XX series PMICs ADC binding + +maintainers: + - Baolin Wang <baolin.wang7@gmail.com> + +description: + Supports the ADC found on these PMICs. + +properties: + compatible: + enum: + - sprd,sc2720-adc + - sprd,sc2721-adc + - sprd,sc2723-adc + - sprd,sc2730-adc + - sprd,sc2731-adc + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + "#io-channel-cells": + const: 1 + + hwlocks: + maxItems: 1 + + nvmem-cells: + maxItems: 2 + + nvmem-cell-names: + items: + - const: big_scale_calib + - const: small_scale_calib + +required: + - compatible + - reg + - interrupts + - "#io-channel-cells" + - hwlocks + - nvmem-cells + - nvmem-cell-names + +additionalProperties: false + +examples: + - | + #include <dt-bindings/interrupt-controller/irq.h> + pmic { + #address-cells = <1>; + #size-cells = <0>; + adc@480 { + compatible = "sprd,sc2731-adc"; + reg = <0x480>; + interrupt-parent = <&sc2731_pmic>; + interrupts = <0 IRQ_TYPE_LEVEL_HIGH>; + #io-channel-cells = <1>; + hwlocks = <&hwlock 4>; + nvmem-cells = <&adc_big_scale>, <&adc_small_scale>; + nvmem-cell-names = "big_scale_calib", "small_scale_calib"; + }; + }; +... diff --git a/Documentation/devicetree/bindings/iio/adc/sprd,sc27xx-adc.txt b/Documentation/devicetree/bindings/iio/adc/sprd,sc27xx-adc.txt deleted file mode 100644 index b4daa15dcf15..000000000000 --- a/Documentation/devicetree/bindings/iio/adc/sprd,sc27xx-adc.txt +++ /dev/null @@ -1,40 +0,0 @@ -Spreadtrum SC27XX series PMICs ADC binding - -Required properties: -- compatible: Should be one of the following. - "sprd,sc2720-adc" - "sprd,sc2721-adc" - "sprd,sc2723-adc" - "sprd,sc2730-adc" - "sprd,sc2731-adc" -- reg: The address offset of ADC controller. -- interrupt-parent: The interrupt controller. -- interrupts: The interrupt number for the ADC device. -- #io-channel-cells: Number of cells in an IIO specifier. -- hwlocks: Reference to a phandle of a hwlock provider node. -- nvmem-cells: A phandle to the calibration cells provided by eFuse device. -- nvmem-cell-names: Should be "big_scale_calib", "small_scale_calib". - -Example: - - sc2731_pmic: pmic@0 { - compatible = "sprd,sc2731"; - reg = <0>; - spi-max-frequency = <26000000>; - interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>; - interrupt-controller; - #interrupt-cells = <2>; - #address-cells = <1>; - #size-cells = <0>; - - pmic_adc: adc@480 { - compatible = "sprd,sc2731-adc"; - reg = <0x480>; - interrupt-parent = <&sc2731_pmic>; - interrupts = <0 IRQ_TYPE_LEVEL_HIGH>; - #io-channel-cells = <1>; - hwlocks = <&hwlock 4>; - nvmem-cells = <&adc_big_scale>, <&adc_small_scale>; - nvmem-cell-names = "big_scale_calib", "small_scale_calib"; - }; - }; diff --git a/Documentation/devicetree/bindings/iio/adc/st,stmpe-adc.yaml b/Documentation/devicetree/bindings/iio/adc/st,stmpe-adc.yaml new file mode 100644 index 000000000000..9049c699152f --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/st,stmpe-adc.yaml @@ -0,0 +1,45 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/st,stmpe-adc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: ADC on an STMPE multifunction device. + +maintainers: + - Stefan Agner <stefan@agner.ch> + +description: + This ADC forms part of an ST microelectronics STMPE multifunction device . + The ADC is shared with the STMPE touchscreen. As a result some ADC related + settings are specified in the parent node. + The node name myst be stmpe_adc and should be a child node of the stmpe node + to which it belongs. + +properties: + compatible: + const: st,stmpe-adc + + st,norequest-mask: + $ref: /schemas/types.yaml#/definitions/uint32 + description: + Bitmask specifying which ADC channels should _not_ be + requestable due to different usage (e.g. touch). + + "#io-channel-cells": + const: 1 + +required: + - compatible + +additionalProperties: false + +examples: + - | + stmpe { + stmpe_adc { + compatible = "st,stmpe-adc"; + st,norequest-mask = <0x0F>; /* dont use ADC CH3-0 */ + }; + }; +... diff --git a/Documentation/devicetree/bindings/iio/adc/stmpe-adc.txt b/Documentation/devicetree/bindings/iio/adc/stmpe-adc.txt deleted file mode 100644 index 480e66422625..000000000000 --- a/Documentation/devicetree/bindings/iio/adc/stmpe-adc.txt +++ /dev/null @@ -1,21 +0,0 @@ -STMPE ADC driver ----------------- - -Required properties: - - compatible: "st,stmpe-adc" - -Optional properties: -Note that the ADC is shared with the STMPE touchscreen. ADC related settings -have to be done in the mfd. -- st,norequest-mask: bitmask specifying which ADC channels should _not_ be - requestable due to different usage (e.g. touch) - -Node name must be stmpe_adc and should be child node of stmpe node to -which it belongs. - -Example: - - stmpe_adc { - compatible = "st,stmpe-adc"; - st,norequest-mask = <0x0F>; /* dont use ADC CH3-0 */ - }; diff --git a/Documentation/devicetree/bindings/iio/adc/ti,adc0832.yaml b/Documentation/devicetree/bindings/iio/adc/ti,adc0832.yaml new file mode 100644 index 000000000000..f5a923cc847f --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/ti,adc0832.yaml @@ -0,0 +1,56 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/ti,adc0832.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Texas Instruments ADC0832 and similar ADCs + +maintainers: + - Akinobu Mita <akinobu.mita@gmail.com> + +description: | + 8 bit ADCs with 1, 2, 4 or 8 inputs for single ended or differential + conversion. + +properties: + compatible: + enum: + - ti,adc0831 + - ti,adc0832 + - ti,adc0834 + - ti,adc0838 + + reg: + maxItems: 1 + + spi-max-frequency: true + + vref-supply: + description: External reference, needed to establish input scaling + + "#io-channel-cells": + const: 1 + +required: + - compatible + - reg + - vref-supply + +additionalProperties: false + +examples: + - | + spi { + #address-cells = <1>; + #size-cells = <0>; + + adc@0 { + compatible = "ti,adc0832"; + reg = <0>; + vref-supply = <&vdd_supply>; + spi-max-frequency = <200000>; + #io-channel-cells = <1>; + }; + }; +... diff --git a/Documentation/devicetree/bindings/iio/adc/ti,adc108s102.yaml b/Documentation/devicetree/bindings/iio/adc/ti,adc108s102.yaml new file mode 100644 index 000000000000..54955f03df93 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/ti,adc108s102.yaml @@ -0,0 +1,47 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/ti,adc108s102.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Texas Instruments ADC108S102 and ADC128S102 + +maintainers: + - Bogdan Pricop <bogdan.pricop@emutex.com> + +description: | + Family of 8 channel, 10/12 bit, SPI, single ended ADCs. + +properties: + compatible: + const: + ti,adc108s102 + + reg: true + vref-supply: true + spi-max-frequency: true + "#io-channel-cells": + const: 1 + +required: + - compatible + - reg + - vref-supply + +additionalProperties: false + +examples: + - | + spi { + #address-cells= <1>; + #size-cells = <0>; + + adc@0 { + compatible = "ti,adc108s102"; + reg = <0>; + vref-supply = <&vdd_supply>; + spi-max-frequency = <1000000>; + #io-channel-cells = <1>; + }; + }; +... diff --git a/Documentation/devicetree/bindings/iio/adc/ti,adc12138.yaml b/Documentation/devicetree/bindings/iio/adc/ti,adc12138.yaml new file mode 100644 index 000000000000..ec3b2edf1fb7 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/ti,adc12138.yaml @@ -0,0 +1,86 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/ti,adc12138.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Texas Instruments ADC12138 and similar self-calibrating ADCs + +maintainers: + - Akinobu Mita <akinobu.mita@gmail.com> + +description: | + 13 bit ADCs with 1, 2 or 8 inputs and self calibrating circuitry to + correct for linearity, zero and full scale errors. + +properties: + compatible: + enum: + - ti,adc12130 + - ti,adc12132 + - ti,adc12138 + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + description: End of Conversion (EOC) interrupt + + clocks: + maxItems: 1 + description: Conversion clock input. + + spi-max-frequency: true + + vref-p-supply: + description: The regulator supply for positive analog voltage reference + + vref-n-supply: + description: | + The regulator supply for negative analog voltage reference + (Note that this must not go below GND or exceed vref-p) + If not specified, this is assumed to be analog ground. + + ti,acquisition-time: + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [ 6, 10, 18, 34 ] + description: | + The number of conversion clock periods for the S/H's acquisition time. + For high source impedances, this value can be increased to 18 or 34. + For less ADC accuracy and/or slower CCLK frequencies this value may be + decreased to 6. See section 6.0 INPUT SOURCE RESISTANCE in the + datasheet for details. + + "#io-channel-cells": + const: 1 + +required: + - compatible + - reg + - interrupts + - clocks + - vref-p-supply + +additionalProperties: false + +examples: + - | + #include <dt-bindings/interrupt-controller/irq.h> + spi { + #address-cells = <1>; + #size-cells = <0>; + + adc@0 { + compatible = "ti,adc12138"; + reg = <0>; + interrupts = <28 IRQ_TYPE_EDGE_RISING>; + interrupt-parent = <&gpio1>; + clocks = <&cclk>; + vref-p-supply = <&ldo4_reg>; + spi-max-frequency = <5000000>; + ti,acquisition-time = <6>; + #io-channel-cells = <1>; + }; + }; +... diff --git a/Documentation/devicetree/bindings/iio/adc/ti,adc128s052.yaml b/Documentation/devicetree/bindings/iio/adc/ti,adc128s052.yaml new file mode 100644 index 000000000000..d54a0183f024 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/ti,adc128s052.yaml @@ -0,0 +1,59 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/ti,adc128s052.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Texas Instruments ADC128S052 and similar ADCs + +maintainers: + - Angelo Compagnucci <angelo.compagnucci@gmail.com> + +description: | + Family of 12 bit SPI ADCs with 2 to 8 channels with a range of different + target sample rates. + +properties: + compatible: + enum: + - ti,adc122s021 + - ti,adc122s051 + - ti,adc122s101 + - ti,adc124s021 + - ti,adc124s051 + - ti,adc124s101 + - ti,adc128s052 + + reg: + maxItems: 1 + + spi-max-frequency: true + + vref-supply: true + + "#io-channel-cells": + const: 1 + +required: + - compatible + - reg + - vref-supply + +additionalProperties: false + +examples: + - | + #include <dt-bindings/interrupt-controller/irq.h> + spi { + #address-cells = <1>; + #size-cells = <0>; + + adc@0 { + compatible = "ti,adc128s052"; + reg = <0>; + vref-supply = <&vdd_supply>; + spi-max-frequency = <1000000>; + #io-channel-cells = <1>; + }; + }; +... diff --git a/Documentation/devicetree/bindings/iio/adc/ti,adc161s626.yaml b/Documentation/devicetree/bindings/iio/adc/ti,adc161s626.yaml new file mode 100644 index 000000000000..3f4f334d6f73 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/ti,adc161s626.yaml @@ -0,0 +1,51 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/ti,adc161s626.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Texas Instruments ADC141S626 and ADC161S626 ADCs + +maintainers: + - Matt Ranostay <matt.ranostay@konsulko.com> + +description: | + Single channel 14/16bit differential ADCs + +properties: + compatible: + enum: + - ti,adc141s626 + - ti,adc161s626 + + reg: + maxItems: 1 + + spi-max-frequency: true + + vdda-supply: true + + "#io-channel-cells": + const: 1 + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + spi { + #address-cells = <1>; + #size-cells = <0>; + + adc@0 { + compatible = "ti,adc161s626"; + vdda-supply = <&vdda_fixed>; + reg = <0>; + spi-max-frequency = <4300000>; + #io-channel-cells = <1>; + }; + }; +... diff --git a/Documentation/devicetree/bindings/iio/adc/ti,ads1015.yaml b/Documentation/devicetree/bindings/iio/adc/ti,ads1015.yaml new file mode 100644 index 000000000000..2c2d01bbc296 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/ti,ads1015.yaml @@ -0,0 +1,112 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/ti,ads1015.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: TI ADS1015 4 channel I2C analog to digital converter + +maintainers: + - Daniel Baluta <daniel.baluta@nxp.com> + +description: | + Datasheet at: https://www.ti.com/lit/gpn/ads1015 + Supports both single ended and differential channels. + +properties: + compatible: + const: ti,ads1015 + + reg: + maxItems: 1 + + "#address-cells": + const: 1 + + "#size-cells": + const: 0 + + "#io-channel-cells": + const: 1 + +required: + - compatible + - reg + - "#address-cells" + - "#size-cells" + +additionalProperties: false + +patternProperties: + "^channel@[0-7]+$": + type: object + description: + Child nodes needed for each channel that the platform uses. + + properties: + reg: + description: | + 0: Voltage over AIN0 and AIN1. + 1: Voltage over AIN0 and AIN3. + 2: Voltage over AIN1 and AIN3. + 3: Voltage over AIN2 and AIN3. + 4: Voltage over AIN0 and GND. + 5: Voltage over AIN1 and GND. + 6: Voltage over AIN2 and GND. + 7: Voltage over AIN3 and GND. + items: + - minimum: 0 + maximum: 7 + + ti,gain: + $ref: /schemas/types.yaml#/definitions/uint32 + minimum: 0 + maximum: 5 + description: | + pga is the programmable gain amplifier (values are full scale) + 0: +/- 6.144 V + 1: +/- 4.096 V + 2: +/- 2.048 V (default) + 3: +/- 1.024 V + 4: +/- 0.512 V + 5: +/- 0.256 V + + ti,datarate: + $ref: /schemas/types.yaml#/definitions/uint32 + minimum: 0 + maximum: 6 + description: | + Data acquisition rate in samples per second + 0: 128 + 1: 250 + 2: 490 + 3: 920 + 4: 1600 (default) + 5: 2400 + 6: 3300 + + required: + - reg + +examples: + - | + i2c { + #address-cells = <1>; + #size-cells = <0>; + + adc@49 { + compatible = "ti,ads1015"; + reg = <0x49>; + #address-cells = <1>; + #size-cells = <0>; + channel@0 { + reg = <0>; + }; + channel@4 { + reg = <4>; + ti,gain = <3>; + ti,datarate = <5>; + }; + }; + }; +... diff --git a/Documentation/devicetree/bindings/iio/adc/ti,ads7950.yaml b/Documentation/devicetree/bindings/iio/adc/ti,ads7950.yaml new file mode 100644 index 000000000000..5ab5027be97e --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/ti,ads7950.yaml @@ -0,0 +1,65 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/ti,ads7950.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Texas Instruments ADS7950 and similar ADCs + +maintainers: + - David Lechner <david@lechnology.com> + +description: | + Family of 4-16 channel, 8-12 bit ADCs with SPI interface. + +properties: + compatible: + enum: + - ti,ads7950 + - ti,ads7951 + - ti,ads7952 + - ti,ads7953 + - ti,ads7954 + - ti,ads7955 + - ti,ads7956 + - ti,ads7957 + - ti,ads7958 + - ti,ads7959 + - ti,ads7960 + - ti,ads7961 + + reg: + maxItems: 1 + + spi-max-frequency: + maximum: 20000000 + + vref-supply: + description: Supplies the 2.5V or 5V reference voltage + + "#io-channel-cells": + const: 1 + +required: + - compatible + - reg + - vref-supply + - "#io-channel-cells" + +additionalProperties: false + +examples: + - | + spi { + #address-cells = <1>; + #size-cells = <0>; + + adc@0 { + compatible = "ti,ads7957"; + reg = <0>; + vref-supply = <&refin_supply>; + spi-max-frequency = <10000000>; + #io-channel-cells = <1>; + }; + }; +... diff --git a/Documentation/devicetree/bindings/iio/adc/ti,ads8344.yaml b/Documentation/devicetree/bindings/iio/adc/ti,ads8344.yaml new file mode 100644 index 000000000000..b8c398187d5c --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/ti,ads8344.yaml @@ -0,0 +1,51 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/ti,ads8344.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Texas Instruments ADS8344 ADC + +maintainers: + - Gregory Clement <gregory.clement@bootlin.com> + +description: | + 16bit 8-channel ADC with single ended inputs. + +properties: + compatible: + const: ti,ads8344 + + reg: + maxItems: 1 + + spi-max-frequency: true + + vref-supply: + description: Supply the 2.5V or 5V reference voltage + + "#io-channel-cells": + const: 1 + +required: + - compatible + - reg + - vref-supply + +additionalProperties: false + +examples: + - | + spi { + #address-cells = <1>; + #size-cells = <0>; + + adc@0 { + compatible = "ti,ads8344"; + reg = <0>; + vref-supply = <&refin_supply>; + spi-max-frequency = <10000000>; + #io-channel-cells = <1>; + }; + }; +... diff --git a/Documentation/devicetree/bindings/iio/adc/ti,tlc4541.yaml b/Documentation/devicetree/bindings/iio/adc/ti,tlc4541.yaml new file mode 100644 index 000000000000..6c2539b3d707 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/ti,tlc4541.yaml @@ -0,0 +1,52 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/ti,tlc4541.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Texas Instruments TLC4541 and similar ADCs + +maintainers: + - Phil Reid <preid@electromag.com.au> + +description: | + 14/16bit single channel ADC with SPI interface. + +properties: + compatible: + enum: + - ti,tlc3541 + - ti,tlc4541 + + reg: + maxItems: 1 + + spi-max-frequency: true + + vref-supply: true + + "#io-channel-cells": + const: 1 + +required: + - compatible + - reg + - vref-supply + +additionalProperties: false + +examples: + - | + spi { + #address-cells = <1>; + #size-cells = <0>; + + adc@0 { + compatible = "ti,tlc4541"; + reg = <0>; + vref-supply = <&vdd_supply>; + spi-max-frequency = <200000>; + #io-channel-cells = <1>; + }; + }; +... diff --git a/Documentation/devicetree/bindings/iio/adc/ti,twl4030-madc.yaml b/Documentation/devicetree/bindings/iio/adc/ti,twl4030-madc.yaml new file mode 100644 index 000000000000..6781ad2f0f51 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/ti,twl4030-madc.yaml @@ -0,0 +1,48 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/ti,twl4030-madc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: MADC subsystem in the TWL4030 power module + +maintainers: + - Sebastian Reichel <sre@kernel.org> + +description: + The MADC subsystem in the TWL4030 consists of a 10-bit ADC + combined with a 16-input analog multiplexer. + +properties: + compatible: + const: ti,twl4030-madc + + interrupts: + maxItems: 1 + + ti,system-uses-second-madc-irq: + type: boolean + description: + Set if the second madc irq register should be used, which is intended + to be used by Co-Processors (e.g. a modem). + + "#io-channel-cells": + const: 1 + +required: + - compatible + - interrupts + - "#io-channel-cells" + +additionalProperties: false + +examples: + - | + twl { + madc { + compatible = "ti,twl4030-madc"; + interrupts = <3>; + #io-channel-cells = <1>; + }; + }; +... diff --git a/Documentation/devicetree/bindings/iio/adc/ti-adc0832.txt b/Documentation/devicetree/bindings/iio/adc/ti-adc0832.txt deleted file mode 100644 index d91130587d01..000000000000 --- a/Documentation/devicetree/bindings/iio/adc/ti-adc0832.txt +++ /dev/null @@ -1,19 +0,0 @@ -* Texas Instruments' ADC0831/ADC0832/ADC0832/ADC0838 - -Required properties: - - compatible: Should be one of - * "ti,adc0831" - * "ti,adc0832" - * "ti,adc0834" - * "ti,adc0838" - - reg: spi chip select number for the device - - vref-supply: The regulator supply for ADC reference voltage - - spi-max-frequency: Max SPI frequency to use (< 400000) - -Example: -adc@0 { - compatible = "ti,adc0832"; - reg = <0>; - vref-supply = <&vdd_supply>; - spi-max-frequency = <200000>; -}; diff --git a/Documentation/devicetree/bindings/iio/adc/ti-adc108s102.txt b/Documentation/devicetree/bindings/iio/adc/ti-adc108s102.txt deleted file mode 100644 index bbbbb4a9f58f..000000000000 --- a/Documentation/devicetree/bindings/iio/adc/ti-adc108s102.txt +++ /dev/null @@ -1,18 +0,0 @@ -* Texas Instruments' ADC108S102 and ADC128S102 ADC chip - -Required properties: - - compatible: Should be "ti,adc108s102" - - reg: spi chip select number for the device - - vref-supply: The regulator supply for ADC reference voltage - -Recommended properties: - - spi-max-frequency: Definition as per - Documentation/devicetree/bindings/spi/spi-bus.txt - -Example: -adc@0 { - compatible = "ti,adc108s102"; - reg = <0>; - vref-supply = <&vdd_supply>; - spi-max-frequency = <1000000>; -}; diff --git a/Documentation/devicetree/bindings/iio/adc/ti-adc12138.txt b/Documentation/devicetree/bindings/iio/adc/ti-adc12138.txt deleted file mode 100644 index 049a1d36f013..000000000000 --- a/Documentation/devicetree/bindings/iio/adc/ti-adc12138.txt +++ /dev/null @@ -1,37 +0,0 @@ -* Texas Instruments' ADC12130/ADC12132/ADC12138 - -Required properties: - - compatible: Should be one of - * "ti,adc12130" - * "ti,adc12132" - * "ti,adc12138" - - reg: SPI chip select number for the device - - interrupts: Should contain interrupt for EOC (end of conversion) - - clocks: phandle to conversion clock input - - spi-max-frequency: Definision as per - Documentation/devicetree/bindings/spi/spi-bus.txt - - vref-p-supply: The regulator supply for positive analog voltage reference - -Optional properties: - - vref-n-supply: The regulator supply for negative analog voltage reference - (Note that this must not go below GND or exceed vref-p) - If not specified, this is assumed to be analog ground. - - ti,acquisition-time: The number of conversion clock periods for the S/H's - acquisition time. Should be one of 6, 10, 18, 34. If not specified, - default value of 10 is used. - For high source impedances, this value can be increased to 18 or 34. - For less ADC accuracy and/or slower CCLK frequencies this value may be - decreased to 6. See section 6.0 INPUT SOURCE RESISTANCE in the - datasheet for details. - -Example: -adc@0 { - compatible = "ti,adc12138"; - reg = <0>; - interrupts = <28 IRQ_TYPE_EDGE_RISING>; - interrupt-parent = <&gpio1>; - clocks = <&cclk>; - vref-p-supply = <&ldo4_reg>; - spi-max-frequency = <5000000>; - ti,acquisition-time = <6>; -}; diff --git a/Documentation/devicetree/bindings/iio/adc/ti-adc128s052.txt b/Documentation/devicetree/bindings/iio/adc/ti-adc128s052.txt deleted file mode 100644 index c07ce1a3f5c4..000000000000 --- a/Documentation/devicetree/bindings/iio/adc/ti-adc128s052.txt +++ /dev/null @@ -1,25 +0,0 @@ -* Texas Instruments' ADC128S052, ADC122S021 and ADC124S021 ADC chip - -Required properties: - - compatible: Should be one of: - - "ti,adc128s052" - - "ti,adc122s021" - - "ti,adc122s051" - - "ti,adc122s101" - - "ti,adc124s021" - - "ti,adc124s051" - - "ti,adc124s101" - - reg: spi chip select number for the device - - vref-supply: The regulator supply for ADC reference voltage - -Recommended properties: - - spi-max-frequency: Definition as per - Documentation/devicetree/bindings/spi/spi-bus.txt - -Example: -adc@0 { - compatible = "ti,adc128s052"; - reg = <0>; - vref-supply = <&vdd_supply>; - spi-max-frequency = <1000000>; -}; diff --git a/Documentation/devicetree/bindings/iio/adc/ti-adc161s626.txt b/Documentation/devicetree/bindings/iio/adc/ti-adc161s626.txt deleted file mode 100644 index 3d25011f0c99..000000000000 --- a/Documentation/devicetree/bindings/iio/adc/ti-adc161s626.txt +++ /dev/null @@ -1,18 +0,0 @@ -* Texas Instruments ADC141S626 and ADC161S626 chips - -Required properties: - - compatible: Should be "ti,adc141s626" or "ti,adc161s626" - - reg: spi chip select number for the device - - vdda-supply: supply voltage to VDDA pin - -Recommended properties: - - spi-max-frequency: Definition as per - Documentation/devicetree/bindings/spi/spi-bus.txt - -Example: -adc@0 { - compatible = "ti,adc161s626"; - vdda-supply = <&vdda_fixed>; - reg = <0>; - spi-max-frequency = <4300000>; -}; diff --git a/Documentation/devicetree/bindings/iio/adc/ti-ads7950.txt b/Documentation/devicetree/bindings/iio/adc/ti-ads7950.txt deleted file mode 100644 index e77a6f7e1001..000000000000 --- a/Documentation/devicetree/bindings/iio/adc/ti-ads7950.txt +++ /dev/null @@ -1,23 +0,0 @@ -* Texas Instruments ADS7950 family of A/DC chips - -Required properties: - - compatible: Must be one of "ti,ads7950", "ti,ads7951", "ti,ads7952", - "ti,ads7953", "ti,ads7954", "ti,ads7955", "ti,ads7956", "ti,ads7957", - "ti,ads7958", "ti,ads7959", "ti,ads7960", or "ti,ads7961" - - reg: SPI chip select number for the device - - #io-channel-cells: Must be 1 as per ../iio-bindings.txt - - vref-supply: phandle to a regulator node that supplies the 2.5V or 5V - reference voltage - -Recommended properties: - - spi-max-frequency: Definition as per - Documentation/devicetree/bindings/spi/spi-bus.txt - -Example: -adc@0 { - compatible = "ti,ads7957"; - reg = <0>; - #io-channel-cells = <1>; - vref-supply = <&refin_supply>; - spi-max-frequency = <10000000>; -}; diff --git a/Documentation/devicetree/bindings/iio/adc/ti-ads8344.txt b/Documentation/devicetree/bindings/iio/adc/ti-ads8344.txt deleted file mode 100644 index e47c3759a82b..000000000000 --- a/Documentation/devicetree/bindings/iio/adc/ti-ads8344.txt +++ /dev/null @@ -1,19 +0,0 @@ -* Texas Instruments ADS8344 A/DC chip - -Required properties: - - compatible: Must be "ti,ads8344" - - reg: SPI chip select number for the device - - vref-supply: phandle to a regulator node that supplies the - reference voltage - -Recommended properties: - - spi-max-frequency: Definition as per - Documentation/devicetree/bindings/spi/spi-bus.txt - -Example: -adc@0 { - compatible = "ti,ads8344"; - reg = <0>; - vref-supply = <&refin_supply>; - spi-max-frequency = <10000000>; -}; diff --git a/Documentation/devicetree/bindings/iio/adc/twl4030-madc.txt b/Documentation/devicetree/bindings/iio/adc/twl4030-madc.txt deleted file mode 100644 index 6bdd21404b57..000000000000 --- a/Documentation/devicetree/bindings/iio/adc/twl4030-madc.txt +++ /dev/null @@ -1,24 +0,0 @@ -* TWL4030 Monitoring Analog to Digital Converter (MADC) - -The MADC subsystem in the TWL4030 consists of a 10-bit ADC -combined with a 16-input analog multiplexer. - -Required properties: - - compatible: Should contain "ti,twl4030-madc". - - interrupts: IRQ line for the MADC submodule. - - #io-channel-cells: Should be set to <1>. - -Optional properties: - - ti,system-uses-second-madc-irq: boolean, set if the second madc irq register - should be used, which is intended to be used - by Co-Processors (e.g. a modem). - -Example: - -&twl { - madc { - compatible = "ti,twl4030-madc"; - interrupts = <3>; - #io-channel-cells = <1>; - }; -}; diff --git a/Documentation/devicetree/bindings/iio/adc/vf610-adc.txt b/Documentation/devicetree/bindings/iio/adc/vf610-adc.txt deleted file mode 100644 index 1aad0514e647..000000000000 --- a/Documentation/devicetree/bindings/iio/adc/vf610-adc.txt +++ /dev/null @@ -1,36 +0,0 @@ -Freescale vf610 Analog to Digital Converter bindings - -The devicetree bindings are for the new ADC driver written for -vf610/i.MX6slx and upward SoCs from Freescale. - -Required properties: -- compatible: Should contain "fsl,vf610-adc" -- reg: Offset and length of the register set for the device -- interrupts: Should contain the interrupt for the device -- clocks: The clock is needed by the ADC controller, ADC clock source is ipg clock. -- clock-names: Must contain "adc", matching entry in the clocks property. -- vref-supply: The regulator supply ADC reference voltage. - -Recommended properties: -- fsl,adck-max-frequency: Maximum frequencies according to datasheets operating - requirements. Three values are required, depending on conversion mode: - - Frequency in normal mode (ADLPC=0, ADHSC=0) - - Frequency in high-speed mode (ADLPC=0, ADHSC=1) - - Frequency in low-power mode (ADLPC=1, ADHSC=0) -- min-sample-time: Minimum sampling time in nanoseconds. This value has - to be chosen according to the conversion mode and the connected analog - source resistance (R_as) and capacitance (C_as). Refer the datasheet's - operating requirements. A safe default across a wide range of R_as and - C_as as well as conversion modes is 1000ns. - -Example: -adc0: adc@4003b000 { - compatible = "fsl,vf610-adc"; - reg = <0x4003b000 0x1000>; - interrupts = <0 53 0x04>; - clocks = <&clks VF610_CLK_ADC0>; - clock-names = "adc"; - fsl,adck-max-frequency = <30000000>, <40000000>, - <20000000>; - vref-supply = <®_vcc_3v3_mcu>; -}; diff --git a/Documentation/devicetree/bindings/iio/chemical/atlas,sensor.yaml b/Documentation/devicetree/bindings/iio/chemical/atlas,sensor.yaml index 9a89b34bdd8f..4646deeb6f7b 100644 --- a/Documentation/devicetree/bindings/iio/chemical/atlas,sensor.yaml +++ b/Documentation/devicetree/bindings/iio/chemical/atlas,sensor.yaml @@ -19,6 +19,8 @@ description: | http://www.atlas-scientific.com/_files/_datasheets/_oem/pH_oem_datasheet.pdf http://www.atlas-scientific.com/_files/_datasheets/_oem/RTD_oem_datasheet.pdf http://www.atlas-scientific.com/_files/_datasheets/_probe/EZO_CO2_Datasheet.pdf + https://www.atlas-scientific.com/files/EZO_O2_datasheet.pdf + https://www.atlas-scientific.com/files/EZO_HUM_Datasheet.pdf properties: compatible: @@ -29,6 +31,8 @@ properties: - atlas,ph-sm - atlas,rtd-sm - atlas,co2-ezo + - atlas,o2-ezo + - atlas,hum-ezo reg: maxItems: 1 diff --git a/Documentation/devicetree/bindings/iio/dac/lltc,ltc2632.yaml b/Documentation/devicetree/bindings/iio/dac/lltc,ltc2632.yaml new file mode 100644 index 000000000000..edf804d0aca2 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/dac/lltc,ltc2632.yaml @@ -0,0 +1,77 @@ +# SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause +%YAML 1.2 +--- +$id: "http://devicetree.org/schemas/iio/dac/lltc,ltc2632.yaml#" +$schema: "http://devicetree.org/meta-schemas/core.yaml#" + +title: Linear Technology LTC263x 12-/10-/8-Bit Rail-to-Rail DAC + +maintainers: + - Michael Hennerich <michael.hennerich@analog.com> + +description: | + Bindings for the Linear Technology LTC2632/2634/2636 DAC + Datasheet can be found here: https://www.analog.com/media/en/technical-documentation/data-sheets/LTC263[246].pdf + +properties: + compatible: + enum: + - lltc,ltc2632-l12 + - lltc,ltc2632-l10 + - lltc,ltc2632-l8 + - lltc,ltc2632-h12 + - lltc,ltc2632-h10 + - lltc,ltc2632-h8 + - lltc,ltc2634-l12 + - lltc,ltc2634-l10 + - lltc,ltc2634-l8 + - lltc,ltc2634-h12 + - lltc,ltc2634-h10 + - lltc,ltc2634-h8 + - lltc,ltc2636-l12 + - lltc,ltc2636-l10 + - lltc,ltc2636-l8 + - lltc,ltc2636-h12 + - lltc,ltc2636-h10 + - lltc,ltc2636-h8 + + reg: + maxItems: 1 + + spi-max-frequency: + maximum: 2000000 + + vref-supply: + description: + Phandle to the external reference voltage supply. This should + only be set if there is an external reference voltage connected to the VREF + pin. If the property is not set the internal reference is used. + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + vref: regulator-vref { + compatible = "regulator-fixed"; + regulator-name = "vref-ltc2632"; + regulator-min-microvolt = <1250000>; + regulator-max-microvolt = <1250000>; + regulator-always-on; + }; + + spi { + #address-cells = <1>; + #size-cells = <0>; + + dac@0 { + compatible = "lltc,ltc2632"; + reg = <0>; /* CS0 */ + spi-max-frequency = <1000000>; + vref-supply = <&vref>; + }; + }; +... diff --git a/Documentation/devicetree/bindings/iio/dac/ltc2632.txt b/Documentation/devicetree/bindings/iio/dac/ltc2632.txt deleted file mode 100644 index 1ab9570cf219..000000000000 --- a/Documentation/devicetree/bindings/iio/dac/ltc2632.txt +++ /dev/null @@ -1,49 +0,0 @@ -Linear Technology LTC2632/2634/2636 DAC - -Required properties: - - compatible: Has to contain one of the following: - lltc,ltc2632-l12 - lltc,ltc2632-l10 - lltc,ltc2632-l8 - lltc,ltc2632-h12 - lltc,ltc2632-h10 - lltc,ltc2632-h8 - lltc,ltc2634-l12 - lltc,ltc2634-l10 - lltc,ltc2634-l8 - lltc,ltc2634-h12 - lltc,ltc2634-h10 - lltc,ltc2634-h8 - lltc,ltc2636-l12 - lltc,ltc2636-l10 - lltc,ltc2636-l8 - lltc,ltc2636-h12 - lltc,ltc2636-h10 - lltc,ltc2636-h8 - -Property rules described in Documentation/devicetree/bindings/spi/spi-bus.txt -apply. In particular, "reg" and "spi-max-frequency" properties must be given. - -Optional properties: - - vref-supply: Phandle to the external reference voltage supply. This should - only be set if there is an external reference voltage connected to the VREF - pin. If the property is not set the internal reference is used. - -Example: - - vref: regulator-vref { - compatible = "regulator-fixed"; - regulator-name = "vref-ltc2632"; - regulator-min-microvolt = <1250000>; - regulator-max-microvolt = <1250000>; - regulator-always-on; - }; - - spi_master { - dac: ltc2632@0 { - compatible = "lltc,ltc2632-l12"; - reg = <0>; /* CS0 */ - spi-max-frequency = <1000000>; - vref-supply = <&vref>; /* optional */ - }; - }; diff --git a/Documentation/devicetree/bindings/iio/gyroscope/adi,adxrs290.yaml b/Documentation/devicetree/bindings/iio/gyroscope/adi,adxrs290.yaml new file mode 100644 index 000000000000..662ec59ca0af --- /dev/null +++ b/Documentation/devicetree/bindings/iio/gyroscope/adi,adxrs290.yaml @@ -0,0 +1,59 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +# Copyright 2020 Analog Devices Inc. +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/gyroscope/adi,adxrs290.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Analog Devices ADXRS290 Dual-Axis MEMS Gyroscope + +maintainers: + - Nishant Malpani <nish.malpani25@gmail.com> + +description: | + Bindings for the Analog Devices ADXRS290 dual-axis MEMS gyroscope device. + https://www.analog.com/media/en/technical-documentation/data-sheets/ADXRS290.pdf + +properties: + compatible: + const: adi,adxrs290 + + reg: + maxItems: 1 + + spi-max-frequency: + maximum: 5000000 + + spi-cpol: true + + spi-cpha: true + + interrupts: + maxItems: 1 + +required: + - compatible + - reg + - spi-max-frequency + - spi-cpol + - spi-cpha + +additionalProperties: false + +examples: + - | + #include <dt-bindings/interrupt-controller/irq.h> + spi { + #address-cells = <1>; + #size-cells = <0>; + gyro@0 { + compatible = "adi,adxrs290"; + reg = <0>; + spi-max-frequency = <5000000>; + spi-cpol; + spi-cpha; + interrupt-parent = <&gpio>; + interrupts = <25 IRQ_TYPE_EDGE_RISING>; + }; + }; +... diff --git a/Documentation/devicetree/bindings/iio/humidity/ti,hdc2010.yaml b/Documentation/devicetree/bindings/iio/humidity/ti,hdc2010.yaml new file mode 100644 index 000000000000..dc870eb2875f --- /dev/null +++ b/Documentation/devicetree/bindings/iio/humidity/ti,hdc2010.yaml @@ -0,0 +1,45 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/humidity/ti,hdc2010.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: HDC2010/HDC2080 humidity and temperature iio sensors + +maintainers: + - Eugene Zaikonnikov <ez@norophonic.com> + +description: | + Relative humidity and tempereature sensors on I2C bus + + Datasheets are available at: + http://www.ti.com/product/HDC2010/datasheet + http://www.ti.com/product/HDC2080/datasheet + +properties: + compatible: + enum: + - ti,hdc2010 + - ti,hdc2080 + + vdd-supply: + maxItems: 1 + + reg: + maxItems: 1 + +required: + - compatible + - reg + +examples: + - | + i2c0 { + #address-cells = <1>; + #size-cells = <0>; + + humidity@40 { + compatible = "ti,hdc2010"; + reg = <0x40>; + }; + }; diff --git a/Documentation/devicetree/bindings/iio/light/ams,as73211.yaml b/Documentation/devicetree/bindings/iio/light/ams,as73211.yaml new file mode 100644 index 000000000000..0e8cd02759b3 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/light/ams,as73211.yaml @@ -0,0 +1,54 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/light/ams,as73211.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: AMS AS73211 JENCOLOR(R) Digital XYZ Sensor + +maintainers: + - Christian Eggers <ceggers@arri.de> + +description: | + XYZ True Color Sensor with I2C Interface + https://ams.com/documents/20143/36005/AS73211_DS000556_3-01.pdf/a65474c0-b302-c2fd-e30a-c98df87616df + +properties: + compatible: + enum: + - ams,as73211 + + reg: + description: + I2C address of the device (0x74...0x77). + maxItems: 1 + + interrupts: + description: + Interrupt specifier for the READY interrupt generated by the device. + maxItems: 1 + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + #include <dt-bindings/interrupt-controller/irq.h> + + i2c { + #address-cells = <1>; + #size-cells = <0>; + + as73211@74 { + compatible = "ams,as73211"; + reg = <0x74>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_color_sensor>; + interrupt-parent = <&gpio2>; + interrupts = <19 IRQ_TYPE_EDGE_RISING>; /* READY */ + }; + }; +... diff --git a/Documentation/devicetree/bindings/iio/light/vishay,vcnl4000.yaml b/Documentation/devicetree/bindings/iio/light/vishay,vcnl4000.yaml index 58887a4f9c15..4d1a225e8868 100644 --- a/Documentation/devicetree/bindings/iio/light/vishay,vcnl4000.yaml +++ b/Documentation/devicetree/bindings/iio/light/vishay,vcnl4000.yaml @@ -24,6 +24,10 @@ properties: - vishay,vcnl4020 - vishay,vcnl4040 - vishay,vcnl4200 + + interrupts: + maxItems: 1 + reg: maxItems: 1 diff --git a/Documentation/devicetree/bindings/iio/proximity/semtech,sx9310.yaml b/Documentation/devicetree/bindings/iio/proximity/semtech,sx9310.yaml new file mode 100644 index 000000000000..5739074d3592 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/proximity/semtech,sx9310.yaml @@ -0,0 +1,65 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/proximity/semtech,sx9310.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Semtech's SX9310 capacitive proximity sensor + +maintainers: + - Daniel Campello <campello@chromium.org> + +description: | + Semtech's SX9310/SX9311 capacitive proximity/button solution. + + Specifications about the devices can be found at: + https://www.semtech.com/products/smart-sensing/sar-sensors/sx9310 + +properties: + compatible: + enum: + - semtech,sx9310 + - semtech,sx9311 + + reg: + maxItems: 1 + + interrupts: + description: + The sole interrupt generated by the device used to announce the + preceding reading request has finished and that data is + available or that a close/far proximity event has happened. + maxItems: 1 + + vdd-supply: + description: Main power supply + + svdd-supply: + description: Host interface power supply + + "#io-channel-cells": + const: 1 + +required: + - compatible + - reg + - "#io-channel-cells" + +additionalProperties: false + +examples: + - | + #include <dt-bindings/interrupt-controller/irq.h> + i2c { + #address-cells = <1>; + #size-cells = <0>; + proximity@28 { + compatible = "semtech,sx9310"; + reg = <0x28>; + interrupt-parent = <&pio>; + interrupts = <5 IRQ_TYPE_LEVEL_LOW 5>; + vdd-supply = <&pp3300_a>; + svdd-supply = <&pp1800_prox>; + #io-channel-cells = <1>; + }; + }; diff --git a/Documentation/devicetree/bindings/iio/proximity/vl53l0x.txt b/Documentation/devicetree/bindings/iio/proximity/vl53l0x.txt index aac5f621f8dc..dfe00eb961cd 100644 --- a/Documentation/devicetree/bindings/iio/proximity/vl53l0x.txt +++ b/Documentation/devicetree/bindings/iio/proximity/vl53l0x.txt @@ -4,9 +4,15 @@ Required properties: - compatible: must be "st,vl53l0x" - reg: i2c address where to find the device +Optional properties: + - interrupts: Interrupt for notifying that new measurement is ready. + If no interrupt is specified, polling is used. + Example: vl53l0x@29 { compatible = "st,vl53l0x"; reg = <0x29>; + interrupt-parent = <&gpio>; + interrupts = <23 IRQ_TYPE_EDGE_FALLING>; }; diff --git a/Documentation/devicetree/bindings/trivial-devices.yaml b/Documentation/devicetree/bindings/trivial-devices.yaml index 45902783adec..ab623ba930d5 100644 --- a/Documentation/devicetree/bindings/trivial-devices.yaml +++ b/Documentation/devicetree/bindings/trivial-devices.yaml @@ -132,6 +132,22 @@ properties: - mcube,mc3230 # MEMSIC 2-axis 8-bit digital accelerometer - memsic,mxc6225 + # Microchip differential I2C ADC, 1 Channel, 18 bit + - microchip,mcp3421 + # Microchip differential I2C ADC, 2 Channel, 18 bit + - microchip,mcp3422 + # Microchip differential I2C ADC, 2 Channel, 18 bit + - microchip,mcp3423 + # Microchip differential I2C ADC, 4 Channel, 18 bit + - microchip,mcp3424 + # Microchip differential I2C ADC, 1 Channel, 16 bit + - microchip,mcp3425 + # Microchip differential I2C ADC, 2 Channel, 16 bit + - microchip,mcp3426 + # Microchip differential I2C ADC, 2 Channel, 16 bit + - microchip,mcp3427 + # Microchip differential I2C ADC, 4 Channel, 16 bit + - microchip,mcp3428 # Microchip 7-bit Single I2C Digital POT (5k) - microchip,mcp4017-502 # Microchip 7-bit Single I2C Digital POT (10k) diff --git a/MAINTAINERS b/MAINTAINERS index 7100c51adf25..7473a33386fa 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -950,37 +950,12 @@ S: Supported F: arch/arm64/boot/dts/amd/amd-seattle-xgbe*.dtsi F: drivers/net/ethernet/amd/xgbe/ -ANALOG DEVICES INC AD5686 DRIVER -M: Michael Hennerich <Michael.Hennerich@analog.com> -L: linux-pm@vger.kernel.org -S: Supported -W: http://ez.analog.com/community/linux-device-drivers -F: drivers/iio/dac/ad5686* -F: drivers/iio/dac/ad5696* - -ANALOG DEVICES INC AD5758 DRIVER -M: Michael Hennerich <Michael.Hennerich@analog.com> -L: linux-iio@vger.kernel.org -S: Supported -W: http://ez.analog.com/community/linux-device-drivers -F: Documentation/devicetree/bindings/iio/dac/ad5758.txt -F: drivers/iio/dac/ad5758.c - -ANALOG DEVICES INC AD7091R5 DRIVER -M: Beniamin Bia <beniamin.bia@analog.com> -L: linux-iio@vger.kernel.org -S: Supported -W: http://ez.analog.com/community/linux-device-drivers -F: Documentation/devicetree/bindings/iio/adc/adi,ad7091r5.yaml -F: drivers/iio/adc/ad7091r5.c - -ANALOG DEVICES INC AD7124 DRIVER -M: Michael Hennerich <Michael.Hennerich@analog.com> +AMS AS73211 DRIVER +M: Christian Eggers <ceggers@arri.de> L: linux-iio@vger.kernel.org -S: Supported -W: http://ez.analog.com/community/linux-device-drivers -F: Documentation/devicetree/bindings/iio/adc/adi,ad7124.yaml -F: drivers/iio/adc/ad7124.c +S: Maintained +F: Documentation/devicetree/bindings/iio/light/ams,as73211.yaml +F: drivers/iio/light/as73211.c ANALOG DEVICES INC AD7192 DRIVER M: Alexandru Tachici <alexandru.tachici@analog.com> @@ -998,15 +973,6 @@ W: http://ez.analog.com/community/linux-device-drivers F: Documentation/devicetree/bindings/iio/adc/adi,ad7292.yaml F: drivers/iio/adc/ad7292.c -ANALOG DEVICES INC AD7606 DRIVER -M: Michael Hennerich <Michael.Hennerich@analog.com> -M: Beniamin Bia <beniamin.bia@analog.com> -L: linux-iio@vger.kernel.org -S: Supported -W: http://ez.analog.com/community/linux-device-drivers -F: Documentation/devicetree/bindings/iio/adc/adi,ad7606.yaml -F: drivers/iio/adc/ad7606.c - ANALOG DEVICES INC AD7768-1 DRIVER M: Michael Hennerich <Michael.Hennerich@analog.com> L: linux-iio@vger.kernel.org @@ -1068,7 +1034,6 @@ F: drivers/iio/imu/adis16475.c F: Documentation/devicetree/bindings/iio/imu/adi,adis16475.yaml ANALOG DEVICES INC ADM1177 DRIVER -M: Beniamin Bia <beniamin.bia@analog.com> M: Michael Hennerich <Michael.Hennerich@analog.com> L: linux-hwmon@vger.kernel.org S: Supported @@ -1115,6 +1080,13 @@ L: linux-media@vger.kernel.org S: Maintained F: drivers/media/i2c/adv7842* +ANALOG DEVICES INC ADXRS290 DRIVER +M: Nishant Malpani <nish.malpani25@gmail.com> +L: linux-iio@vger.kernel.org +S: Supported +F: drivers/iio/gyro/adxrs290.c +F: Documentation/devicetree/bindings/iio/gyroscope/adi,adxrs290.yaml + ANALOG DEVICES INC ASOC CODEC DRIVERS M: Lars-Peter Clausen <lars@metafoo.de> M: Nuno Sá <nuno.sa@analog.com> @@ -1135,15 +1107,6 @@ S: Supported W: http://ez.analog.com/community/linux-device-drivers F: drivers/dma/dma-axi-dmac.c -ANALOG DEVICES INC HMC425A DRIVER -M: Beniamin Bia <beniamin.bia@analog.com> -M: Michael Hennerich <michael.hennerich@analog.com> -L: linux-iio@vger.kernel.org -S: Supported -W: http://ez.analog.com/community/linux-device-drivers -F: Documentation/devicetree/bindings/iio/amplifiers/adi,hmc425a.yaml -F: drivers/iio/amplifiers/hmc425a.c - ANALOG DEVICES INC IIO DRIVERS M: Lars-Peter Clausen <lars@metafoo.de> M: Michael Hennerich <Michael.Hennerich@analog.com> @@ -1152,8 +1115,11 @@ W: http://wiki.analog.com/ W: http://ez.analog.com/community/linux-device-drivers F: Documentation/ABI/testing/sysfs-bus-iio-frequency-ad9523 F: Documentation/ABI/testing/sysfs-bus-iio-frequency-adf4350 +F: Documentation/devicetree/bindings/iio/*/adi,* +F: Documentation/devicetree/bindings/iio/dac/ad5758.txt F: drivers/iio/*/ad* F: drivers/iio/adc/ltc249* +F: drivers/iio/amplifiers/hmc425a.c F: drivers/staging/iio/*/ad* X: drivers/iio/*/adjd* @@ -7944,6 +7910,12 @@ F: drivers/crypto/hisilicon/sec2/sec_crypto.c F: drivers/crypto/hisilicon/sec2/sec_crypto.h F: drivers/crypto/hisilicon/sec2/sec_main.c +HISILICON STAGING DRIVERS FOR HIKEY 960/970 +M: Mauro Carvalho Chehab <mchehab+huawei@kernel.org> +L: devel@driverdev.osuosl.org +S: Maintained +F: drivers/staging/hikey9xx/ + HISILICON TRUE RANDOM NUMBER GENERATOR V2 SUPPORT M: Zaibo Xu <xuzaibo@huawei.com> S: Maintained @@ -8521,7 +8493,6 @@ F: drivers/iio/multiplexer/iio-mux.c IIO SUBSYSTEM AND DRIVERS M: Jonathan Cameron <jic23@kernel.org> -R: Hartmut Knaack <knaack.h@gmx.de> R: Lars-Peter Clausen <lars@metafoo.de> R: Peter Meerwald-Stadler <pmeerw@pmeerw.net> L: linux-iio@vger.kernel.org @@ -16533,7 +16504,6 @@ F: drivers/staging/rtl8712/ STAGING - SEPS525 LCD CONTROLLER DRIVERS M: Michael Hennerich <michael.hennerich@analog.com> -M: Beniamin Bia <beniamin.bia@analog.com> L: linux-fbdev@vger.kernel.org S: Supported F: Documentation/devicetree/bindings/iio/adc/adi,ad7606.yaml diff --git a/drivers/counter/microchip-tcb-capture.c b/drivers/counter/microchip-tcb-capture.c index b7b252c5addf..039c54a78aa5 100644 --- a/drivers/counter/microchip-tcb-capture.c +++ b/drivers/counter/microchip-tcb-capture.c @@ -253,7 +253,7 @@ static struct counter_count mchp_tc_counts[] = { }, }; -static struct counter_ops mchp_tc_ops = { +static const struct counter_ops mchp_tc_ops = { .signal_read = mchp_tc_count_signal_read, .count_read = mchp_tc_count_read, .function_get = mchp_tc_count_function_get, diff --git a/drivers/counter/ti-eqep.c b/drivers/counter/ti-eqep.c index 1ff07faef27f..e27771df8e23 100644 --- a/drivers/counter/ti-eqep.c +++ b/drivers/counter/ti-eqep.c @@ -439,7 +439,7 @@ static int ti_eqep_remove(struct platform_device *pdev) struct device *dev = &pdev->dev; counter_unregister(&priv->counter); - pm_runtime_put_sync(dev), + pm_runtime_put_sync(dev); pm_runtime_disable(dev); return 0; diff --git a/drivers/iio/Kconfig b/drivers/iio/Kconfig index d5c073a8aa3e..267553386c71 100644 --- a/drivers/iio/Kconfig +++ b/drivers/iio/Kconfig @@ -63,7 +63,7 @@ config IIO_SW_TRIGGER using the API provided. config IIO_TRIGGERED_EVENT - tristate + tristate "Enable triggered events support" select IIO_TRIGGER help Provides helper functions for setting up triggered events. diff --git a/drivers/iio/accel/adis16201.c b/drivers/iio/accel/adis16201.c index 59a24c355a1a..f955cccb3e77 100644 --- a/drivers/iio/accel/adis16201.c +++ b/drivers/iio/accel/adis16201.c @@ -281,34 +281,15 @@ static int adis16201_probe(struct spi_device *spi) if (ret) return ret; - ret = adis_setup_buffer_and_trigger(st, indio_dev, NULL); + ret = devm_adis_setup_buffer_and_trigger(st, indio_dev, NULL); if (ret) return ret; ret = adis_initial_startup(st); if (ret) - goto error_cleanup_buffer_trigger; - - ret = iio_device_register(indio_dev); - if (ret < 0) - goto error_cleanup_buffer_trigger; - - return 0; - -error_cleanup_buffer_trigger: - adis_cleanup_buffer_and_trigger(st, indio_dev); - return ret; -} - -static int adis16201_remove(struct spi_device *spi) -{ - struct iio_dev *indio_dev = spi_get_drvdata(spi); - struct adis *st = iio_priv(indio_dev); - - iio_device_unregister(indio_dev); - adis_cleanup_buffer_and_trigger(st, indio_dev); + return ret; - return 0; + return devm_iio_device_register(&spi->dev, indio_dev); } static struct spi_driver adis16201_driver = { @@ -316,7 +297,6 @@ static struct spi_driver adis16201_driver = { .name = "adis16201", }, .probe = adis16201_probe, - .remove = adis16201_remove, }; module_spi_driver(adis16201_driver); diff --git a/drivers/iio/accel/adis16209.c b/drivers/iio/accel/adis16209.c index 3d5538e2f76e..4a841aec6268 100644 --- a/drivers/iio/accel/adis16209.c +++ b/drivers/iio/accel/adis16209.c @@ -291,33 +291,15 @@ static int adis16209_probe(struct spi_device *spi) if (ret) return ret; - ret = adis_setup_buffer_and_trigger(st, indio_dev, NULL); + ret = devm_adis_setup_buffer_and_trigger(st, indio_dev, NULL); if (ret) return ret; ret = adis_initial_startup(st); if (ret) - goto error_cleanup_buffer_trigger; - ret = iio_device_register(indio_dev); - if (ret) - goto error_cleanup_buffer_trigger; - - return 0; - -error_cleanup_buffer_trigger: - adis_cleanup_buffer_and_trigger(st, indio_dev); - return ret; -} - -static int adis16209_remove(struct spi_device *spi) -{ - struct iio_dev *indio_dev = spi_get_drvdata(spi); - struct adis *st = iio_priv(indio_dev); - - iio_device_unregister(indio_dev); - adis_cleanup_buffer_and_trigger(st, indio_dev); + return ret; - return 0; + return devm_iio_device_register(&spi->dev, indio_dev); } static struct spi_driver adis16209_driver = { @@ -325,7 +307,6 @@ static struct spi_driver adis16209_driver = { .name = "adis16209", }, .probe = adis16209_probe, - .remove = adis16209_remove, }; module_spi_driver(adis16209_driver); diff --git a/drivers/iio/accel/adxl372.c b/drivers/iio/accel/adxl372.c index e7e316b75e87..aed2a4930fb0 100644 --- a/drivers/iio/accel/adxl372.c +++ b/drivers/iio/accel/adxl372.c @@ -5,6 +5,7 @@ * Copyright 2018 Analog Devices Inc. */ +#include <linux/bitfield.h> #include <linux/bitops.h> #include <linux/interrupt.h> #include <linux/irq.h> @@ -113,6 +114,11 @@ #define ADXL372_STATUS_1_AWAKE(x) (((x) >> 6) & 0x1) #define ADXL372_STATUS_1_ERR_USR_REGS(x) (((x) >> 7) & 0x1) +/* ADXL372_STATUS_2 */ +#define ADXL372_STATUS_2_INACT(x) (((x) >> 4) & 0x1) +#define ADXL372_STATUS_2_ACT(x) (((x) >> 5) & 0x1) +#define ADXL372_STATUS_2_AC2(x) (((x) >> 6) & 0x1) + /* ADXL372_INT1_MAP */ #define ADXL372_INT1_MAP_DATA_RDY_MSK BIT(0) #define ADXL372_INT1_MAP_DATA_RDY_MODE(x) (((x) & 0x1) << 0) @@ -131,8 +137,17 @@ #define ADXL372_INT1_MAP_LOW_MSK BIT(7) #define ADXL372_INT1_MAP_LOW_MODE(x) (((x) & 0x1) << 7) +/* ADX372_THRESH */ +#define ADXL372_THRESH_VAL_H_MSK GENMASK(10, 3) +#define ADXL372_THRESH_VAL_H_SEL(x) FIELD_GET(ADXL372_THRESH_VAL_H_MSK, x) +#define ADXL372_THRESH_VAL_L_MSK GENMASK(2, 0) +#define ADXL372_THRESH_VAL_L_SEL(x) FIELD_GET(ADXL372_THRESH_VAL_L_MSK, x) + /* The ADXL372 includes a deep, 512 sample FIFO buffer */ #define ADXL372_FIFO_SIZE 512 +#define ADXL372_X_AXIS_EN(x) ((x) & BIT(0)) +#define ADXL372_Y_AXIS_EN(x) ((x) & BIT(1)) +#define ADXL372_Z_AXIS_EN(x) ((x) & BIT(2)) /* * At +/- 200g with 12-bit resolution, scale is computed as: @@ -222,6 +237,20 @@ static const struct adxl372_axis_lookup adxl372_axis_lookup_table[] = { { BIT(0) | BIT(1) | BIT(2), ADXL372_XYZ_FIFO }, }; +static const struct iio_event_spec adxl372_events[] = { + { + .type = IIO_EV_TYPE_THRESH, + .dir = IIO_EV_DIR_RISING, + .mask_separate = BIT(IIO_EV_INFO_VALUE), + .mask_shared_by_all = BIT(IIO_EV_INFO_PERIOD) | BIT(IIO_EV_INFO_ENABLE), + }, { + .type = IIO_EV_TYPE_THRESH, + .dir = IIO_EV_DIR_FALLING, + .mask_separate = BIT(IIO_EV_INFO_VALUE), + .mask_shared_by_all = BIT(IIO_EV_INFO_PERIOD) | BIT(IIO_EV_INFO_ENABLE), + }, +}; + #define ADXL372_ACCEL_CHANNEL(index, reg, axis) { \ .type = IIO_ACCEL, \ .address = reg, \ @@ -239,6 +268,8 @@ static const struct adxl372_axis_lookup adxl372_axis_lookup_table[] = { .shift = 4, \ .endianness = IIO_BE, \ }, \ + .event_spec = adxl372_events, \ + .num_event_specs = ARRAY_SIZE(adxl372_events) \ } static const struct iio_chan_spec adxl372_channels[] = { @@ -252,8 +283,10 @@ struct adxl372_state { struct device *dev; struct regmap *regmap; struct iio_trigger *dready_trig; + struct iio_trigger *peak_datardy_trig; enum adxl372_fifo_mode fifo_mode; enum adxl372_fifo_format fifo_format; + unsigned int fifo_axis_mask; enum adxl372_op_mode op_mode; enum adxl372_act_proc_mode act_proc_mode; enum adxl372_odr odr; @@ -261,10 +294,12 @@ struct adxl372_state { u32 act_time_ms; u32 inact_time_ms; u8 fifo_set_size; - u8 int1_bitmask; - u8 int2_bitmask; + unsigned long int1_bitmask; + unsigned long int2_bitmask; u16 watermark; __be16 fifo_buf[ADXL372_FIFO_SIZE]; + bool peak_fifo_mode_en; + struct mutex threshold_m; /* lock for threshold */ }; static const unsigned long adxl372_channel_masks[] = { @@ -276,6 +311,46 @@ static const unsigned long adxl372_channel_masks[] = { 0 }; +static ssize_t adxl372_read_threshold_value(struct iio_dev *indio_dev, unsigned int addr, + u16 *threshold) +{ + struct adxl372_state *st = iio_priv(indio_dev); + __be16 raw_regval; + u16 regval; + int ret; + + ret = regmap_bulk_read(st->regmap, addr, &raw_regval, sizeof(raw_regval)); + if (ret < 0) + return ret; + + regval = be16_to_cpu(raw_regval); + regval >>= 5; + + *threshold = regval; + + return 0; +} + +static ssize_t adxl372_write_threshold_value(struct iio_dev *indio_dev, unsigned int addr, + u16 threshold) +{ + struct adxl372_state *st = iio_priv(indio_dev); + int ret; + + mutex_lock(&st->threshold_m); + ret = regmap_write(st->regmap, addr, ADXL372_THRESH_VAL_H_SEL(threshold)); + if (ret < 0) + goto unlock; + + ret = regmap_update_bits(st->regmap, addr + 1, GENMASK(7, 5), + ADXL372_THRESH_VAL_L_SEL(threshold) << 5); + +unlock: + mutex_unlock(&st->threshold_m); + + return ret; +} + static int adxl372_read_axis(struct adxl372_state *st, u8 addr) { __be16 regval; @@ -453,8 +528,8 @@ static int adxl372_set_inactivity_time_ms(struct adxl372_state *st, } static int adxl372_set_interrupts(struct adxl372_state *st, - unsigned char int1_bitmask, - unsigned char int2_bitmask) + unsigned long int1_bitmask, + unsigned long int2_bitmask) { int ret; @@ -523,6 +598,39 @@ static int adxl372_get_status(struct adxl372_state *st, return ret; } +static void adxl372_arrange_axis_data(struct adxl372_state *st, __be16 *sample) +{ + __be16 axis_sample[3]; + int i = 0; + + memset(axis_sample, 0, 3 * sizeof(__be16)); + if (ADXL372_X_AXIS_EN(st->fifo_axis_mask)) + axis_sample[i++] = sample[0]; + if (ADXL372_Y_AXIS_EN(st->fifo_axis_mask)) + axis_sample[i++] = sample[1]; + if (ADXL372_Z_AXIS_EN(st->fifo_axis_mask)) + axis_sample[i++] = sample[2]; + + memcpy(sample, axis_sample, 3 * sizeof(__be16)); +} + +static void adxl372_push_event(struct iio_dev *indio_dev, s64 timestamp, u8 status2) +{ + unsigned int ev_dir = IIO_EV_DIR_NONE; + + if (ADXL372_STATUS_2_ACT(status2)) + ev_dir = IIO_EV_DIR_RISING; + + if (ADXL372_STATUS_2_INACT(status2)) + ev_dir = IIO_EV_DIR_FALLING; + + if (ev_dir != IIO_EV_DIR_NONE) + iio_push_event(indio_dev, + IIO_MOD_EVENT_CODE(IIO_ACCEL, 0, IIO_MOD_X_OR_Y_OR_Z, + IIO_EV_TYPE_THRESH, ev_dir), + timestamp); +} + static irqreturn_t adxl372_trigger_handler(int irq, void *p) { struct iio_poll_func *pf = p; @@ -536,6 +644,8 @@ static irqreturn_t adxl372_trigger_handler(int irq, void *p) if (ret < 0) goto err; + adxl372_push_event(indio_dev, iio_get_time_ns(indio_dev), status2); + if (st->fifo_mode != ADXL372_FIFO_BYPASSED && ADXL372_STATUS_1_FIFO_FULL(status1)) { /* @@ -554,8 +664,12 @@ static irqreturn_t adxl372_trigger_handler(int irq, void *p) goto err; /* Each sample is 2 bytes */ - for (i = 0; i < fifo_entries; i += st->fifo_set_size) + for (i = 0; i < fifo_entries; i += st->fifo_set_size) { + /* filter peak detection data */ + if (st->peak_fifo_mode_en) + adxl372_arrange_axis_data(st, &st->fifo_buf[i]); iio_push_to_buffers(indio_dev, &st->fifo_buf[i]); + } } err: iio_trigger_notify_done(indio_dev->trig); @@ -723,6 +837,129 @@ static int adxl372_write_raw(struct iio_dev *indio_dev, } } +static int adxl372_read_event_value(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, + enum iio_event_type type, enum iio_event_direction dir, + enum iio_event_info info, int *val, int *val2) +{ + struct adxl372_state *st = iio_priv(indio_dev); + unsigned int addr; + u16 raw_value; + int ret; + + switch (info) { + case IIO_EV_INFO_VALUE: + switch (dir) { + case IIO_EV_DIR_RISING: + addr = ADXL372_X_THRESH_ACT_H + 2 * chan->scan_index; + ret = adxl372_read_threshold_value(indio_dev, addr, &raw_value); + if (ret < 0) + return ret; + *val = raw_value * ADXL372_USCALE; + *val2 = 1000000; + return IIO_VAL_FRACTIONAL; + case IIO_EV_DIR_FALLING: + addr = ADXL372_X_THRESH_INACT_H + 2 * chan->scan_index; + ret = adxl372_read_threshold_value(indio_dev, addr, &raw_value); + if (ret < 0) + return ret; + *val = raw_value * ADXL372_USCALE; + *val2 = 1000000; + return IIO_VAL_FRACTIONAL; + default: + return -EINVAL; + } + case IIO_EV_INFO_PERIOD: + switch (dir) { + case IIO_EV_DIR_RISING: + *val = st->act_time_ms; + *val2 = 1000; + return IIO_VAL_FRACTIONAL; + case IIO_EV_DIR_FALLING: + *val = st->inact_time_ms; + *val2 = 1000; + return IIO_VAL_FRACTIONAL; + default: + return -EINVAL; + } + default: + return -EINVAL; + } +} + +static int adxl372_write_event_value(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, + enum iio_event_type type, enum iio_event_direction dir, + enum iio_event_info info, int val, int val2) +{ + struct adxl372_state *st = iio_priv(indio_dev); + unsigned int val_ms; + unsigned int addr; + u16 raw_val; + + switch (info) { + case IIO_EV_INFO_VALUE: + raw_val = DIV_ROUND_UP(val * 1000000, ADXL372_USCALE); + switch (dir) { + case IIO_EV_DIR_RISING: + addr = ADXL372_X_THRESH_ACT_H + 2 * chan->scan_index; + return adxl372_write_threshold_value(indio_dev, addr, raw_val); + case IIO_EV_DIR_FALLING: + addr = ADXL372_X_THRESH_INACT_H + 2 * chan->scan_index; + return adxl372_write_threshold_value(indio_dev, addr, raw_val); + default: + return -EINVAL; + } + case IIO_EV_INFO_PERIOD: + val_ms = val * 1000 + DIV_ROUND_UP(val2, 1000); + switch (dir) { + case IIO_EV_DIR_RISING: + return adxl372_set_activity_time_ms(st, val_ms); + case IIO_EV_DIR_FALLING: + return adxl372_set_inactivity_time_ms(st, val_ms); + default: + return -EINVAL; + } + default: + return -EINVAL; + } +} + +static int adxl372_read_event_config(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, + enum iio_event_type type, enum iio_event_direction dir) +{ + struct adxl372_state *st = iio_priv(indio_dev); + + switch (dir) { + case IIO_EV_DIR_RISING: + return FIELD_GET(ADXL372_INT1_MAP_ACT_MSK, st->int1_bitmask); + case IIO_EV_DIR_FALLING: + return FIELD_GET(ADXL372_INT1_MAP_INACT_MSK, st->int1_bitmask); + default: + return -EINVAL; + } +} + +static int adxl372_write_event_config(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, + enum iio_event_type type, enum iio_event_direction dir, + int state) +{ + struct adxl372_state *st = iio_priv(indio_dev); + + switch (dir) { + case IIO_EV_DIR_RISING: + set_mask_bits(&st->int1_bitmask, ADXL372_INT1_MAP_ACT_MSK, + ADXL372_INT1_MAP_ACT_MODE(state)); + break; + case IIO_EV_DIR_FALLING: + set_mask_bits(&st->int1_bitmask, ADXL372_INT1_MAP_INACT_MSK, + ADXL372_INT1_MAP_INACT_MODE(state)); + break; + default: + return -EINVAL; + } + + return adxl372_set_interrupts(st, st->int1_bitmask, 0); +} + static ssize_t adxl372_show_filter_freq_avail(struct device *dev, struct device_attribute *attr, char *buf) @@ -795,7 +1032,8 @@ static int adxl372_buffer_postenable(struct iio_dev *indio_dev) unsigned int mask; int i, ret; - ret = adxl372_set_interrupts(st, ADXL372_INT1_MAP_FIFO_FULL_MSK, 0); + st->int1_bitmask |= ADXL372_INT1_MAP_FIFO_FULL_MSK; + ret = adxl372_set_interrupts(st, st->int1_bitmask, 0); if (ret < 0) return ret; @@ -810,13 +1048,22 @@ static int adxl372_buffer_postenable(struct iio_dev *indio_dev) return -EINVAL; st->fifo_format = adxl372_axis_lookup_table[i].fifo_format; + st->fifo_axis_mask = adxl372_axis_lookup_table[i].bits; st->fifo_set_size = bitmap_weight(indio_dev->active_scan_mask, indio_dev->masklength); + + /* Configure the FIFO to store sets of impact event peak. */ + if (st->peak_fifo_mode_en) { + st->fifo_set_size = 3; + st->fifo_format = ADXL372_XYZ_PEAK_FIFO; + } + /* * The 512 FIFO samples can be allotted in several ways, such as: * 170 sample sets of concurrent 3-axis data * 256 sample sets of concurrent 2-axis data (user selectable) * 512 sample sets of single-axis data + * 170 sets of impact event peak (x, y, z) */ if ((st->watermark * st->fifo_set_size) > ADXL372_FIFO_SIZE) st->watermark = (ADXL372_FIFO_SIZE / st->fifo_set_size); @@ -826,7 +1073,8 @@ static int adxl372_buffer_postenable(struct iio_dev *indio_dev) ret = adxl372_configure_fifo(st); if (ret < 0) { st->fifo_mode = ADXL372_FIFO_BYPASSED; - adxl372_set_interrupts(st, 0, 0); + st->int1_bitmask &= ~ADXL372_INT1_MAP_FIFO_FULL_MSK; + adxl372_set_interrupts(st, st->int1_bitmask, 0); return ret; } @@ -837,7 +1085,8 @@ static int adxl372_buffer_predisable(struct iio_dev *indio_dev) { struct adxl372_state *st = iio_priv(indio_dev); - adxl372_set_interrupts(st, 0, 0); + st->int1_bitmask &= ~ADXL372_INT1_MAP_FIFO_FULL_MSK; + adxl372_set_interrupts(st, st->int1_bitmask, 0); st->fifo_mode = ADXL372_FIFO_BYPASSED; adxl372_configure_fifo(st); @@ -854,12 +1103,11 @@ static int adxl372_dready_trig_set_state(struct iio_trigger *trig, { struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig); struct adxl372_state *st = iio_priv(indio_dev); - unsigned long int mask = 0; if (state) - mask = ADXL372_INT1_MAP_FIFO_FULL_MSK; + st->int1_bitmask |= ADXL372_INT1_MAP_FIFO_FULL_MSK; - return adxl372_set_interrupts(st, mask, 0); + return adxl372_set_interrupts(st, st->int1_bitmask, 0); } static int adxl372_validate_trigger(struct iio_dev *indio_dev, @@ -867,7 +1115,7 @@ static int adxl372_validate_trigger(struct iio_dev *indio_dev, { struct adxl372_state *st = iio_priv(indio_dev); - if (st->dready_trig != trig) + if (st->dready_trig != trig && st->peak_datardy_trig != trig) return -EINVAL; return 0; @@ -878,6 +1126,25 @@ static const struct iio_trigger_ops adxl372_trigger_ops = { .set_trigger_state = adxl372_dready_trig_set_state, }; +static int adxl372_peak_dready_trig_set_state(struct iio_trigger *trig, + bool state) +{ + struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig); + struct adxl372_state *st = iio_priv(indio_dev); + + if (state) + st->int1_bitmask |= ADXL372_INT1_MAP_FIFO_FULL_MSK; + + st->peak_fifo_mode_en = state; + + return adxl372_set_interrupts(st, st->int1_bitmask, 0); +} + +static const struct iio_trigger_ops adxl372_peak_data_trigger_ops = { + .validate_device = &iio_trigger_validate_own_device, + .set_trigger_state = adxl372_peak_dready_trig_set_state, +}; + static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("400 800 1600 3200 6400"); static IIO_DEVICE_ATTR(in_accel_filter_low_pass_3db_frequency_available, 0444, adxl372_show_filter_freq_avail, NULL, 0); @@ -897,6 +1164,10 @@ static const struct iio_info adxl372_info = { .attrs = &adxl372_attrs_group, .read_raw = adxl372_read_raw, .write_raw = adxl372_write_raw, + .read_event_config = adxl372_read_event_config, + .write_event_config = adxl372_write_event_config, + .read_event_value = adxl372_read_event_value, + .write_event_value = adxl372_write_event_value, .debugfs_reg_access = &adxl372_reg_access, .hwfifo_set_watermark = adxl372_set_watermark, }; @@ -925,6 +1196,8 @@ int adxl372_probe(struct device *dev, struct regmap *regmap, st->regmap = regmap; st->irq = irq; + mutex_init(&st->threshold_m); + indio_dev->channels = adxl372_channels; indio_dev->num_channels = ARRAY_SIZE(adxl372_channels); indio_dev->available_scan_masks = adxl372_channel_masks; @@ -955,13 +1228,27 @@ int adxl372_probe(struct device *dev, struct regmap *regmap, if (st->dready_trig == NULL) return -ENOMEM; + st->peak_datardy_trig = devm_iio_trigger_alloc(dev, + "%s-dev%d-peak", + indio_dev->name, + indio_dev->id); + if (!st->peak_datardy_trig) + return -ENOMEM; + st->dready_trig->ops = &adxl372_trigger_ops; + st->peak_datardy_trig->ops = &adxl372_peak_data_trigger_ops; st->dready_trig->dev.parent = dev; + st->peak_datardy_trig->dev.parent = dev; iio_trigger_set_drvdata(st->dready_trig, indio_dev); + iio_trigger_set_drvdata(st->peak_datardy_trig, indio_dev); ret = devm_iio_trigger_register(dev, st->dready_trig); if (ret < 0) return ret; + ret = devm_iio_trigger_register(dev, st->peak_datardy_trig); + if (ret < 0) + return ret; + indio_dev->trig = iio_trigger_get(st->dready_trig); ret = devm_request_threaded_irq(dev, st->irq, diff --git a/drivers/iio/accel/adxl372_i2c.c b/drivers/iio/accel/adxl372_i2c.c index e1affe480c77..9a07ab3d151a 100644 --- a/drivers/iio/accel/adxl372_i2c.c +++ b/drivers/iio/accel/adxl372_i2c.c @@ -6,6 +6,7 @@ */ #include <linux/i2c.h> +#include <linux/mod_devicetable.h> #include <linux/module.h> #include <linux/regmap.h> @@ -46,9 +47,16 @@ static const struct i2c_device_id adxl372_i2c_id[] = { }; MODULE_DEVICE_TABLE(i2c, adxl372_i2c_id); +static const struct of_device_id adxl372_of_match[] = { + { .compatible = "adi,adxl372" }, + { } +}; +MODULE_DEVICE_TABLE(of, adxl372_of_match); + static struct i2c_driver adxl372_i2c_driver = { .driver = { .name = "adxl372_i2c", + .of_match_table = adxl372_of_match, }, .probe = adxl372_i2c_probe, .id_table = adxl372_i2c_id, diff --git a/drivers/iio/accel/adxl372_spi.c b/drivers/iio/accel/adxl372_spi.c index 3ef7e3a4804e..1f1352fee99a 100644 --- a/drivers/iio/accel/adxl372_spi.c +++ b/drivers/iio/accel/adxl372_spi.c @@ -40,8 +40,8 @@ static const struct spi_device_id adxl372_spi_id[] = { MODULE_DEVICE_TABLE(spi, adxl372_spi_id); static const struct of_device_id adxl372_of_match[] = { - { .compatible = "adi,adxl372" }, - { }, + { .compatible = "adi,adxl372" }, + { } }; MODULE_DEVICE_TABLE(of, adxl372_of_match); diff --git a/drivers/iio/accel/bma180.c b/drivers/iio/accel/bma180.c index 5b7a467c7b27..6b74c2b04c15 100644 --- a/drivers/iio/accel/bma180.c +++ b/drivers/iio/accel/bma180.c @@ -673,7 +673,7 @@ static const struct iio_chan_spec_ext_info bma023_ext_info[] = { }; static const struct iio_chan_spec_ext_info bma180_ext_info[] = { - IIO_ENUM("power_mode", true, &bma180_power_mode_enum), + IIO_ENUM("power_mode", IIO_SHARED_BY_TYPE, &bma180_power_mode_enum), IIO_ENUM_AVAILABLE("power_mode", &bma180_power_mode_enum), IIO_MOUNT_MATRIX(IIO_SHARED_BY_DIR, bma180_accel_get_mount_matrix), { } @@ -1000,19 +1000,15 @@ static int bma180_probe(struct i2c_client *client, return ret; data->vdd_supply = devm_regulator_get(dev, "vdd"); - if (IS_ERR(data->vdd_supply)) { - if (PTR_ERR(data->vdd_supply) != -EPROBE_DEFER) - dev_err(dev, "Failed to get vdd regulator %d\n", - (int)PTR_ERR(data->vdd_supply)); - return PTR_ERR(data->vdd_supply); - } + if (IS_ERR(data->vdd_supply)) + return dev_err_probe(dev, PTR_ERR(data->vdd_supply), + "Failed to get vdd regulator\n"); + data->vddio_supply = devm_regulator_get(dev, "vddio"); - if (IS_ERR(data->vddio_supply)) { - if (PTR_ERR(data->vddio_supply) != -EPROBE_DEFER) - dev_err(dev, "Failed to get vddio regulator %d\n", - (int)PTR_ERR(data->vddio_supply)); - return PTR_ERR(data->vddio_supply); - } + if (IS_ERR(data->vddio_supply)) + return dev_err_probe(dev, PTR_ERR(data->vddio_supply), + "Failed to get vddio regulator\n"); + /* Typical voltage 2.4V these are min and max */ ret = regulator_set_voltage(data->vdd_supply, 1620000, 3600000); if (ret) diff --git a/drivers/iio/accel/bma220_spi.c b/drivers/iio/accel/bma220_spi.c index da8b36cc8628..3c9b0c6954e6 100644 --- a/drivers/iio/accel/bma220_spi.c +++ b/drivers/iio/accel/bma220_spi.c @@ -2,16 +2,18 @@ /** * BMA220 Digital triaxial acceleration sensor driver * - * Copyright (c) 2016, Intel Corporation. + * Copyright (c) 2016,2020 Intel Corporation. */ -#include <linux/acpi.h> +#include <linux/bits.h> #include <linux/kernel.h> +#include <linux/mod_devicetable.h> #include <linux/module.h> +#include <linux/spi/spi.h> + #include <linux/iio/buffer.h> #include <linux/iio/iio.h> #include <linux/iio/sysfs.h> -#include <linux/spi/spi.h> #include <linux/iio/trigger_consumer.h> #include <linux/iio/triggered_buffer.h> @@ -23,14 +25,13 @@ #define BMA220_REG_SUSPEND 0x18 #define BMA220_CHIP_ID 0xDD -#define BMA220_READ_MASK 0x80 -#define BMA220_RANGE_MASK 0x03 +#define BMA220_READ_MASK BIT(7) +#define BMA220_RANGE_MASK GENMASK(1, 0) #define BMA220_DATA_SHIFT 2 #define BMA220_SUSPEND_SLEEP 0xFF #define BMA220_SUSPEND_WAKE 0x00 #define BMA220_DEVICE_NAME "bma220" -#define BMA220_SCALE_AVAILABLE "0.623 1.248 2.491 4.983" #define BMA220_ACCEL_CHANNEL(index, reg, axis) { \ .type = IIO_ACCEL, \ @@ -55,19 +56,8 @@ enum bma220_axis { AXIS_Z, }; -static IIO_CONST_ATTR(in_accel_scale_available, BMA220_SCALE_AVAILABLE); - -static struct attribute *bma220_attributes[] = { - &iio_const_attr_in_accel_scale_available.dev_attr.attr, - NULL, -}; - -static const struct attribute_group bma220_attribute_group = { - .attrs = bma220_attributes, -}; - -static const int bma220_scale_table[][4] = { - {0, 623000}, {1, 248000}, {2, 491000}, {4, 983000} +static const int bma220_scale_table[][2] = { + {0, 623000}, {1, 248000}, {2, 491000}, {4, 983000}, }; struct bma220_data { @@ -182,10 +172,26 @@ static int bma220_write_raw(struct iio_dev *indio_dev, return -EINVAL; } +static int bma220_read_avail(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + const int **vals, int *type, int *length, + long mask) +{ + switch (mask) { + case IIO_CHAN_INFO_SCALE: + *vals = (int *)bma220_scale_table; + *type = IIO_VAL_INT_PLUS_MICRO; + *length = ARRAY_SIZE(bma220_scale_table) * 2; + return IIO_AVAIL_LIST; + default: + return -EINVAL; + } +} + static const struct iio_info bma220_info = { .read_raw = bma220_read_raw, .write_raw = bma220_write_raw, - .attrs = &bma220_attribute_group, + .read_avail = bma220_read_avail, }; static int bma220_init(struct spi_device *spi) @@ -198,10 +204,12 @@ static int bma220_init(struct spi_device *spi) /* Make sure the chip is powered on */ ret = bma220_read_reg(spi, BMA220_REG_SUSPEND); + if (ret == BMA220_SUSPEND_WAKE) + ret = bma220_read_reg(spi, BMA220_REG_SUSPEND); if (ret < 0) return ret; - else if (ret == BMA220_SUSPEND_WAKE) - return bma220_read_reg(spi, BMA220_REG_SUSPEND); + if (ret == BMA220_SUSPEND_WAKE) + return -EBUSY; return 0; } @@ -212,10 +220,12 @@ static int bma220_deinit(struct spi_device *spi) /* Make sure the chip is powered off */ ret = bma220_read_reg(spi, BMA220_REG_SUSPEND); + if (ret == BMA220_SUSPEND_SLEEP) + ret = bma220_read_reg(spi, BMA220_REG_SUSPEND); if (ret < 0) return ret; - else if (ret == BMA220_SUSPEND_SLEEP) - return bma220_read_reg(spi, BMA220_REG_SUSPEND); + if (ret == BMA220_SUSPEND_SLEEP) + return -EBUSY; return 0; } @@ -245,7 +255,7 @@ static int bma220_probe(struct spi_device *spi) indio_dev->available_scan_masks = bma220_accel_scan_masks; ret = bma220_init(data->spi_device); - if (ret < 0) + if (ret) return ret; ret = iio_triggered_buffer_setup(indio_dev, iio_pollfunc_store_time, @@ -278,56 +288,43 @@ static int bma220_remove(struct spi_device *spi) return bma220_deinit(spi); } -#ifdef CONFIG_PM_SLEEP -static int bma220_suspend(struct device *dev) +static __maybe_unused int bma220_suspend(struct device *dev) { - struct bma220_data *data = - iio_priv(spi_get_drvdata(to_spi_device(dev))); + struct bma220_data *data = iio_priv(dev_get_drvdata(dev)); /* The chip can be suspended/woken up by a simple register read. */ return bma220_read_reg(data->spi_device, BMA220_REG_SUSPEND); } -static int bma220_resume(struct device *dev) +static __maybe_unused int bma220_resume(struct device *dev) { - struct bma220_data *data = - iio_priv(spi_get_drvdata(to_spi_device(dev))); + struct bma220_data *data = iio_priv(dev_get_drvdata(dev)); return bma220_read_reg(data->spi_device, BMA220_REG_SUSPEND); } - static SIMPLE_DEV_PM_OPS(bma220_pm_ops, bma220_suspend, bma220_resume); -#define BMA220_PM_OPS (&bma220_pm_ops) -#else -#define BMA220_PM_OPS NULL -#endif - static const struct spi_device_id bma220_spi_id[] = { {"bma220", 0}, {} }; -#ifdef CONFIG_ACPI static const struct acpi_device_id bma220_acpi_id[] = { {"BMA0220", 0}, {} }; - MODULE_DEVICE_TABLE(spi, bma220_spi_id); -#endif static struct spi_driver bma220_driver = { .driver = { .name = "bma220_spi", - .pm = BMA220_PM_OPS, - .acpi_match_table = ACPI_PTR(bma220_acpi_id), + .pm = &bma220_pm_ops, + .acpi_match_table = bma220_acpi_id, }, .probe = bma220_probe, .remove = bma220_remove, .id_table = bma220_spi_id, }; - module_spi_driver(bma220_driver); MODULE_AUTHOR("Tiberiu Breana <tiberiu.a.breana@intel.com>"); diff --git a/drivers/iio/accel/cros_ec_accel_legacy.c b/drivers/iio/accel/cros_ec_accel_legacy.c index b6f3471b62dc..8f1232c38e0d 100644 --- a/drivers/iio/accel/cros_ec_accel_legacy.c +++ b/drivers/iio/accel/cros_ec_accel_legacy.c @@ -215,7 +215,7 @@ static int cros_ec_accel_legacy_probe(struct platform_device *pdev) return -ENOMEM; ret = cros_ec_sensors_core_init(pdev, indio_dev, true, - cros_ec_sensors_capture, NULL); + cros_ec_sensors_capture, NULL, false); if (ret) return ret; diff --git a/drivers/iio/accel/mma8452.c b/drivers/iio/accel/mma8452.c index 853febc29488..bf1d2c8afdbd 100644 --- a/drivers/iio/accel/mma8452.c +++ b/drivers/iio/accel/mma8452.c @@ -1543,22 +1543,14 @@ static int mma8452_probe(struct i2c_client *client, data->chip_info = match->data; data->vdd_reg = devm_regulator_get(&client->dev, "vdd"); - if (IS_ERR(data->vdd_reg)) { - if (PTR_ERR(data->vdd_reg) == -EPROBE_DEFER) - return -EPROBE_DEFER; - - dev_err(&client->dev, "failed to get VDD regulator!\n"); - return PTR_ERR(data->vdd_reg); - } + if (IS_ERR(data->vdd_reg)) + return dev_err_probe(&client->dev, PTR_ERR(data->vdd_reg), + "failed to get VDD regulator!\n"); data->vddio_reg = devm_regulator_get(&client->dev, "vddio"); - if (IS_ERR(data->vddio_reg)) { - if (PTR_ERR(data->vddio_reg) == -EPROBE_DEFER) - return -EPROBE_DEFER; - - dev_err(&client->dev, "failed to get VDDIO regulator!\n"); - return PTR_ERR(data->vddio_reg); - } + if (IS_ERR(data->vddio_reg)) + return dev_err_probe(&client->dev, PTR_ERR(data->vddio_reg), + "failed to get VDDIO regulator!\n"); ret = regulator_enable(data->vdd_reg); if (ret) { diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index d94dc800b842..91ae90514aff 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -340,7 +340,7 @@ config AXP288_ADC config BCM_IPROC_ADC tristate "Broadcom IPROC ADC driver" - depends on ARCH_BCM_IPROC || COMPILE_TEST + depends on (ARCH_BCM_IPROC && OF) || COMPILE_TEST depends on MFD_SYSCON default ARCH_BCM_CYGNUS help @@ -863,7 +863,7 @@ config RN5T618_ADC config ROCKCHIP_SARADC tristate "Rockchip SARADC driver" - depends on ARCH_ROCKCHIP || (ARM && COMPILE_TEST) + depends on ARCH_ROCKCHIP || COMPILE_TEST depends on RESET_CONTROLLER select IIO_BUFFER select IIO_TRIGGERED_BUFFER diff --git a/drivers/iio/adc/ad7291.c b/drivers/iio/adc/ad7291.c index 62fde2aad282..2301a0e27f23 100644 --- a/drivers/iio/adc/ad7291.c +++ b/drivers/iio/adc/ad7291.c @@ -20,8 +20,6 @@ #include <linux/iio/sysfs.h> #include <linux/iio/events.h> -#include <linux/platform_data/ad7291.h> - /* * Simplified handling * @@ -465,7 +463,6 @@ static const struct iio_info ad7291_info = { static int ad7291_probe(struct i2c_client *client, const struct i2c_device_id *id) { - struct ad7291_platform_data *pdata = client->dev.platform_data; struct ad7291_chip_info *chip; struct iio_dev *indio_dev; int ret; @@ -475,16 +472,6 @@ static int ad7291_probe(struct i2c_client *client, return -ENOMEM; chip = iio_priv(indio_dev); - if (pdata && pdata->use_external_ref) { - chip->reg = devm_regulator_get(&client->dev, "vref"); - if (IS_ERR(chip->reg)) - return PTR_ERR(chip->reg); - - ret = regulator_enable(chip->reg); - if (ret) - return ret; - } - mutex_init(&chip->state_lock); /* this is only used for device removal purposes */ i2c_set_clientdata(client, indio_dev); @@ -495,8 +482,21 @@ static int ad7291_probe(struct i2c_client *client, AD7291_T_SENSE_MASK | /* Tsense always enabled */ AD7291_ALERT_POLARITY; /* set irq polarity low level */ - if (pdata && pdata->use_external_ref) + chip->reg = devm_regulator_get_optional(&client->dev, "vref"); + if (IS_ERR(chip->reg)) { + if (PTR_ERR(chip->reg) != -ENODEV) + return PTR_ERR(chip->reg); + + chip->reg = NULL; + } + + if (chip->reg) { + ret = regulator_enable(chip->reg); + if (ret) + return ret; + chip->command |= AD7291_EXT_REF; + } indio_dev->name = id->name; indio_dev->channels = ad7291_channels; @@ -567,9 +567,16 @@ static const struct i2c_device_id ad7291_id[] = { MODULE_DEVICE_TABLE(i2c, ad7291_id); +static const struct of_device_id ad7291_of_match[] = { + { .compatible = "adi,ad7291" }, + {} +}; +MODULE_DEVICE_TABLE(of, ad7291_of_match); + static struct i2c_driver ad7291_driver = { .driver = { .name = KBUILD_MODNAME, + .of_match_table = ad7291_of_match, }, .probe = ad7291_probe, .remove = ad7291_remove, diff --git a/drivers/iio/adc/ad7292.c b/drivers/iio/adc/ad7292.c index 2eafbe7ac7c7..ab204e9199e9 100644 --- a/drivers/iio/adc/ad7292.c +++ b/drivers/iio/adc/ad7292.c @@ -310,8 +310,10 @@ static int ad7292_probe(struct spi_device *spi) for_each_available_child_of_node(spi->dev.of_node, child) { diff_channels = of_property_read_bool(child, "diff-channels"); - if (diff_channels) + if (diff_channels) { + of_node_put(child); break; + } } if (diff_channels) { diff --git a/drivers/iio/adc/ad7949.c b/drivers/iio/adc/ad7949.c index d9566a83988a..5d597e5050f6 100644 --- a/drivers/iio/adc/ad7949.c +++ b/drivers/iio/adc/ad7949.c @@ -39,7 +39,7 @@ static const struct ad7949_adc_spec ad7949_adc_spec[] = { * struct ad7949_adc_chip - AD ADC chip * @lock: protects write sequences * @vref: regulator generating Vref - * @iio_dev: reference to iio structure + * @indio_dev: reference to iio structure * @spi: reference to spi structure * @resolution: resolution of the chip * @cfg: copy of the configuration register diff --git a/drivers/iio/adc/ad9467.c b/drivers/iio/adc/ad9467.c index 1e8fd83b9bc2..19a45dd43796 100644 --- a/drivers/iio/adc/ad9467.c +++ b/drivers/iio/adc/ad9467.c @@ -77,6 +77,22 @@ #define AN877_ADC_DCO_DELAY_ENABLE 0x80 /* + * Analog Devices AD9265 16-Bit, 125/105/80 MSPS ADC + */ + +#define CHIPID_AD9265 0x64 +#define AD9265_DEF_OUTPUT_MODE 0x40 +#define AD9265_REG_VREF_MASK 0xC0 + +/* + * Analog Devices AD9434 12-Bit, 370/500 MSPS ADC + */ + +#define CHIPID_AD9434 0x6A +#define AD9434_DEF_OUTPUT_MODE 0x00 +#define AD9434_REG_VREF_MASK 0xC0 + +/* * Analog Devices AD9467 16-Bit, 200/250 MSPS ADC */ @@ -85,9 +101,20 @@ #define AD9467_REG_VREF_MASK 0x0F enum { + ID_AD9265, + ID_AD9434, ID_AD9467, }; +struct ad9467_chip_info { + struct adi_axi_adc_chip_info axi_adc_info; + unsigned int default_output_mode; + unsigned int vref_mask; +}; + +#define to_ad9467_chip_info(_info) \ + container_of(_info, struct ad9467_chip_info, axi_adc_info) + struct ad9467_state { struct spi_device *spi; struct clk *clk; @@ -149,6 +176,17 @@ static int ad9467_reg_access(struct adi_axi_adc_conv *conv, unsigned int reg, return 0; } +static const unsigned int ad9265_scale_table[][2] = { + {1250, 0x00}, {1500, 0x40}, {1750, 0x80}, {2000, 0xC0}, +}; + +static const unsigned int ad9434_scale_table[][2] = { + {1600, 0x1C}, {1580, 0x1D}, {1550, 0x1E}, {1520, 0x1F}, {1500, 0x00}, + {1470, 0x01}, {1440, 0x02}, {1420, 0x03}, {1390, 0x04}, {1360, 0x05}, + {1340, 0x06}, {1310, 0x07}, {1280, 0x08}, {1260, 0x09}, {1230, 0x0A}, + {1200, 0x0B}, {1180, 0x0C}, +}; + static const unsigned int ad9467_scale_table[][2] = { {2000, 0}, {2100, 6}, {2200, 7}, {2300, 8}, {2400, 9}, {2500, 10}, @@ -182,39 +220,63 @@ static void __ad9467_get_scale(struct adi_axi_adc_conv *conv, int index, }, \ } +static const struct iio_chan_spec ad9434_channels[] = { + AD9467_CHAN(0, 0, 12, 'S'), +}; + static const struct iio_chan_spec ad9467_channels[] = { AD9467_CHAN(0, 0, 16, 'S'), }; -static const struct adi_axi_adc_chip_info ad9467_chip_tbl[] = { +static const struct ad9467_chip_info ad9467_chip_tbl[] = { + [ID_AD9265] = { + .axi_adc_info = { + .id = CHIPID_AD9265, + .max_rate = 125000000UL, + .scale_table = ad9265_scale_table, + .num_scales = ARRAY_SIZE(ad9265_scale_table), + .channels = ad9467_channels, + .num_channels = ARRAY_SIZE(ad9467_channels), + }, + .default_output_mode = AD9265_DEF_OUTPUT_MODE, + .vref_mask = AD9265_REG_VREF_MASK, + }, + [ID_AD9434] = { + .axi_adc_info = { + .id = CHIPID_AD9434, + .max_rate = 500000000UL, + .scale_table = ad9434_scale_table, + .num_scales = ARRAY_SIZE(ad9434_scale_table), + .channels = ad9434_channels, + .num_channels = ARRAY_SIZE(ad9434_channels), + }, + .default_output_mode = AD9434_DEF_OUTPUT_MODE, + .vref_mask = AD9434_REG_VREF_MASK, + }, [ID_AD9467] = { - .id = CHIPID_AD9467, - .max_rate = 250000000UL, - .scale_table = ad9467_scale_table, - .num_scales = ARRAY_SIZE(ad9467_scale_table), - .channels = ad9467_channels, - .num_channels = ARRAY_SIZE(ad9467_channels), + .axi_adc_info = { + .id = CHIPID_AD9467, + .max_rate = 250000000UL, + .scale_table = ad9467_scale_table, + .num_scales = ARRAY_SIZE(ad9467_scale_table), + .channels = ad9467_channels, + .num_channels = ARRAY_SIZE(ad9467_channels), + }, + .default_output_mode = AD9467_DEF_OUTPUT_MODE, + .vref_mask = AD9467_REG_VREF_MASK, }, }; static int ad9467_get_scale(struct adi_axi_adc_conv *conv, int *val, int *val2) { const struct adi_axi_adc_chip_info *info = conv->chip_info; + const struct ad9467_chip_info *info1 = to_ad9467_chip_info(info); struct ad9467_state *st = adi_axi_adc_conv_priv(conv); - unsigned int i, vref_val, vref_mask; + unsigned int i, vref_val; vref_val = ad9467_spi_read(st->spi, AN877_ADC_REG_VREF); - switch (info->id) { - case CHIPID_AD9467: - vref_mask = AD9467_REG_VREF_MASK; - break; - default: - vref_mask = 0xFFFF; - break; - } - - vref_val &= vref_mask; + vref_val &= info1->vref_mask; for (i = 0; i < info->num_scales; i++) { if (vref_val == info->scale_table[i][1]) @@ -316,18 +378,6 @@ static int ad9467_preenable_setup(struct adi_axi_adc_conv *conv) return ad9467_outputmode_set(st->spi, st->output_mode); } -static int ad9467_setup(struct ad9467_state *st, unsigned int chip_id) -{ - switch (chip_id) { - case CHIPID_AD9467: - st->output_mode = AD9467_DEF_OUTPUT_MODE | - AN877_ADC_OUTPUT_MODE_TWOS_COMPLEMENT; - return 0; - default: - return -EINVAL; - } -} - static void ad9467_clk_disable(void *data) { struct ad9467_state *st = data; @@ -337,7 +387,7 @@ static void ad9467_clk_disable(void *data) static int ad9467_probe(struct spi_device *spi) { - const struct adi_axi_adc_chip_info *info; + const struct ad9467_chip_info *info; struct adi_axi_adc_conv *conv; struct ad9467_state *st; unsigned int id; @@ -386,11 +436,12 @@ static int ad9467_probe(struct spi_device *spi) spi_set_drvdata(spi, st); - conv->chip_info = info; + conv->chip_info = &info->axi_adc_info; id = ad9467_spi_read(spi, AN877_ADC_REG_CHIP_ID); if (id != conv->chip_info->id) { - dev_err(&spi->dev, "Unrecognized CHIP_ID 0x%X\n", id); + dev_err(&spi->dev, "Mismatch CHIP_ID, got 0x%X, expected 0x%X\n", + id, conv->chip_info->id); return -ENODEV; } @@ -399,10 +450,15 @@ static int ad9467_probe(struct spi_device *spi) conv->read_raw = ad9467_read_raw; conv->preenable_setup = ad9467_preenable_setup; - return ad9467_setup(st, id); + st->output_mode = info->default_output_mode | + AN877_ADC_OUTPUT_MODE_TWOS_COMPLEMENT; + + return 0; } static const struct of_device_id ad9467_of_match[] = { + { .compatible = "adi,ad9265", .data = &ad9467_chip_tbl[ID_AD9265], }, + { .compatible = "adi,ad9434", .data = &ad9467_chip_tbl[ID_AD9434], }, { .compatible = "adi,ad9467", .data = &ad9467_chip_tbl[ID_AD9467], }, {} }; diff --git a/drivers/iio/adc/adi-axi-adc.c b/drivers/iio/adc/adi-axi-adc.c index 86b6b65916ee..9109da2d2e15 100644 --- a/drivers/iio/adc/adi-axi-adc.c +++ b/drivers/iio/adc/adi-axi-adc.c @@ -276,7 +276,7 @@ static struct attribute *adi_axi_adc_attributes[] = { static umode_t axi_adc_attr_is_visible(struct kobject *kobj, struct attribute *attr, int n) { - struct device *dev = container_of(kobj, struct device, kobj); + struct device *dev = kobj_to_dev(kobj); struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct adi_axi_adc_state *st = iio_priv(indio_dev); struct adi_axi_adc_conv *conv = &st->client->conv; diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c index de9583d6cddd..b917a4714a9c 100644 --- a/drivers/iio/adc/at91-sama5d2_adc.c +++ b/drivers/iio/adc/at91-sama5d2_adc.c @@ -884,7 +884,7 @@ static bool at91_adc_current_chan_is_touch(struct iio_dev *indio_dev) AT91_SAMA5D2_MAX_CHAN_IDX + 1); } -static int at91_adc_buffer_preenable(struct iio_dev *indio_dev) +static int at91_adc_buffer_prepare(struct iio_dev *indio_dev) { int ret; u8 bit; @@ -901,7 +901,7 @@ static int at91_adc_buffer_preenable(struct iio_dev *indio_dev) /* we continue with the triggered buffer */ ret = at91_adc_dma_start(indio_dev); if (ret) { - dev_err(&indio_dev->dev, "buffer postenable failed\n"); + dev_err(&indio_dev->dev, "buffer prepare failed\n"); return ret; } @@ -989,7 +989,6 @@ static int at91_adc_buffer_postdisable(struct iio_dev *indio_dev) } static const struct iio_buffer_setup_ops at91_buffer_setup_ops = { - .preenable = &at91_adc_buffer_preenable, .postdisable = &at91_adc_buffer_postdisable, }; @@ -1563,6 +1562,7 @@ static void at91_adc_dma_disable(struct platform_device *pdev) static int at91_adc_set_watermark(struct iio_dev *indio_dev, unsigned int val) { struct at91_adc_state *st = iio_priv(indio_dev); + int ret; if (val > AT91_HWFIFO_MAX_SIZE) return -EINVAL; @@ -1586,7 +1586,15 @@ static int at91_adc_set_watermark(struct iio_dev *indio_dev, unsigned int val) else if (val > 1) at91_adc_dma_init(to_platform_device(&indio_dev->dev)); - return 0; + /* + * We can start the DMA only after setting the watermark and + * having the DMA initialization completed + */ + ret = at91_adc_buffer_prepare(indio_dev); + if (ret) + at91_adc_dma_disable(to_platform_device(&indio_dev->dev)); + + return ret; } static int at91_adc_update_scan_mode(struct iio_dev *indio_dev, @@ -1764,17 +1772,13 @@ static int at91_adc_probe(struct platform_device *pdev) mutex_init(&st->lock); INIT_WORK(&st->touch_st.workq, at91_adc_workq_handler); - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) - return -EINVAL; + st->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); + if (IS_ERR(st->base)) + return PTR_ERR(st->base); /* if we plan to use DMA, we need the physical address of the regs */ st->dma_st.phys_addr = res->start; - st->base = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(st->base)) - return PTR_ERR(st->base); - st->irq = platform_get_irq(pdev, 0); if (st->irq <= 0) { if (!st->irq) diff --git a/drivers/iio/adc/axp20x_adc.c b/drivers/iio/adc/axp20x_adc.c index 798ff2d89691..3e0c0233b431 100644 --- a/drivers/iio/adc/axp20x_adc.c +++ b/drivers/iio/adc/axp20x_adc.c @@ -9,10 +9,10 @@ #include <linux/interrupt.h> #include <linux/io.h> #include <linux/module.h> -#include <linux/of.h> -#include <linux/of_device.h> +#include <linux/mod_devicetable.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> +#include <linux/property.h> #include <linux/regmap.h> #include <linux/thermal.h> @@ -67,7 +67,7 @@ struct axp_data; struct axp20x_adc_iio { struct regmap *regmap; - struct axp_data *data; + const struct axp_data *data; }; enum axp20x_adc_channel_v { @@ -670,15 +670,15 @@ static int axp20x_probe(struct platform_device *pdev) info->regmap = axp20x_dev->regmap; indio_dev->modes = INDIO_DIRECT_MODE; - if (!pdev->dev.of_node) { + if (!dev_fwnode(&pdev->dev)) { const struct platform_device_id *id; id = platform_get_device_id(pdev); - info->data = (struct axp_data *)id->driver_data; + info->data = (const struct axp_data *)id->driver_data; } else { struct device *dev = &pdev->dev; - info->data = (struct axp_data *)of_device_get_match_data(dev); + info->data = device_get_match_data(dev); } indio_dev->name = platform_get_device_id(pdev)->name; @@ -742,7 +742,7 @@ static int axp20x_remove(struct platform_device *pdev) static struct platform_driver axp20x_adc_driver = { .driver = { .name = "axp20x-adc", - .of_match_table = of_match_ptr(axp20x_adc_of_match), + .of_match_table = axp20x_adc_of_match, }, .id_table = axp20x_adc_id_match, .probe = axp20x_probe, diff --git a/drivers/iio/adc/bcm_iproc_adc.c b/drivers/iio/adc/bcm_iproc_adc.c index 936da32faa9d..44e1e53ada72 100644 --- a/drivers/iio/adc/bcm_iproc_adc.c +++ b/drivers/iio/adc/bcm_iproc_adc.c @@ -4,7 +4,7 @@ */ #include <linux/module.h> -#include <linux/of.h> +#include <linux/mod_devicetable.h> #include <linux/io.h> #include <linux/clk.h> #include <linux/mfd/syscon.h> @@ -617,7 +617,7 @@ static struct platform_driver iproc_adc_driver = { .remove = iproc_adc_remove, .driver = { .name = "iproc-static-adc", - .of_match_table = of_match_ptr(iproc_adc_of_match), + .of_match_table = iproc_adc_of_match, }, }; module_platform_driver(iproc_adc_driver); diff --git a/drivers/iio/adc/envelope-detector.c b/drivers/iio/adc/envelope-detector.c index 2a4fd3bb64cf..d73eac36153f 100644 --- a/drivers/iio/adc/envelope-detector.c +++ b/drivers/iio/adc/envelope-detector.c @@ -348,11 +348,9 @@ static int envelope_detector_probe(struct platform_device *pdev) indio_dev->num_channels = 1; env->dac = devm_iio_channel_get(dev, "dac"); - if (IS_ERR(env->dac)) { - if (PTR_ERR(env->dac) != -EPROBE_DEFER) - dev_err(dev, "failed to get dac input channel\n"); - return PTR_ERR(env->dac); - } + if (IS_ERR(env->dac)) + return dev_err_probe(dev, PTR_ERR(env->dac), + "failed to get dac input channel\n"); env->comp_irq = platform_get_irq_byname(pdev, "comp"); if (env->comp_irq < 0) @@ -360,11 +358,9 @@ static int envelope_detector_probe(struct platform_device *pdev) ret = devm_request_irq(dev, env->comp_irq, envelope_detector_comp_isr, 0, "envelope-detector", env); - if (ret) { - if (ret != -EPROBE_DEFER) - dev_err(dev, "failed to request interrupt\n"); - return ret; - } + if (ret) + return dev_err_probe(dev, ret, "failed to request interrupt\n"); + env->comp_irq_trigger = irq_get_trigger_type(env->comp_irq); if (env->comp_irq_trigger & IRQF_TRIGGER_RISING) env->comp_irq_trigger_inv |= IRQF_TRIGGER_FALLING; diff --git a/drivers/iio/adc/exynos_adc.c b/drivers/iio/adc/exynos_adc.c index 7d23b6c33284..99f4404e9fd1 100644 --- a/drivers/iio/adc/exynos_adc.c +++ b/drivers/iio/adc/exynos_adc.c @@ -138,6 +138,16 @@ struct exynos_adc { bool read_ts; u32 ts_x; u32 ts_y; + + /* + * Lock to protect from potential concurrent access to the + * completion callback during a manual conversion. For this driver + * a wait-callback is used to wait for the conversion result, + * so in the meantime no other read request (or conversion start) + * must be performed, otherwise it would interfere with the + * current conversion result. + */ + struct mutex lock; }; struct exynos_adc_data { @@ -542,7 +552,7 @@ static int exynos_read_raw(struct iio_dev *indio_dev, return -EINVAL; } - mutex_lock(&indio_dev->mlock); + mutex_lock(&info->lock); reinit_completion(&info->completion); /* Select the channel to be used and Trigger conversion */ @@ -562,7 +572,7 @@ static int exynos_read_raw(struct iio_dev *indio_dev, ret = IIO_VAL_INT; } - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&info->lock); return ret; } @@ -573,7 +583,7 @@ static int exynos_read_s3c64xx_ts(struct iio_dev *indio_dev, int *x, int *y) unsigned long timeout; int ret; - mutex_lock(&indio_dev->mlock); + mutex_lock(&info->lock); info->read_ts = true; reinit_completion(&info->completion); @@ -598,7 +608,7 @@ static int exynos_read_s3c64xx_ts(struct iio_dev *indio_dev, int *x, int *y) } info->read_ts = false; - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&info->lock); return ret; } @@ -844,13 +854,9 @@ static int exynos_adc_probe(struct platform_device *pdev) } info->vdd = devm_regulator_get(&pdev->dev, "vdd"); - if (IS_ERR(info->vdd)) { - if (PTR_ERR(info->vdd) != -EPROBE_DEFER) - dev_err(&pdev->dev, - "failed getting regulator, err = %ld\n", - PTR_ERR(info->vdd)); - return PTR_ERR(info->vdd); - } + if (IS_ERR(info->vdd)) + return dev_err_probe(&pdev->dev, PTR_ERR(info->vdd), + "failed getting regulator"); ret = regulator_enable(info->vdd); if (ret) @@ -872,6 +878,8 @@ static int exynos_adc_probe(struct platform_device *pdev) indio_dev->channels = exynos_adc_iio_channels; indio_dev->num_channels = info->data->num_channels; + mutex_init(&info->lock); + ret = request_irq(info->irq, exynos_adc_isr, 0, dev_name(&pdev->dev), info); if (ret < 0) { diff --git a/drivers/iio/adc/fsl-imx25-gcq.c b/drivers/iio/adc/fsl-imx25-gcq.c index 8cb51cf7a816..ab5139e911c3 100644 --- a/drivers/iio/adc/fsl-imx25-gcq.c +++ b/drivers/iio/adc/fsl-imx25-gcq.c @@ -40,6 +40,15 @@ struct mx25_gcq_priv { int irq; struct regulator *vref[4]; u32 channel_vref_mv[MX25_NUM_CFGS]; + /* + * Lock to protect the device state during a potential concurrent + * read access from userspace. Reading a raw value requires a sequence + * of register writes, then a wait for a completion callback, + * and finally a register read, during which userspace could issue + * another read request. This lock protects a read access from + * ocurring before another one has finished. + */ + struct mutex lock; }; #define MX25_CQG_CHAN(chan, id) {\ @@ -137,9 +146,9 @@ static int mx25_gcq_read_raw(struct iio_dev *indio_dev, switch (mask) { case IIO_CHAN_INFO_RAW: - mutex_lock(&indio_dev->mlock); + mutex_lock(&priv->lock); ret = mx25_gcq_get_raw_value(&indio_dev->dev, chan, priv, val); - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&priv->lock); return ret; case IIO_CHAN_INFO_SCALE: @@ -314,6 +323,8 @@ static int mx25_gcq_probe(struct platform_device *pdev) return PTR_ERR(priv->regs); } + mutex_init(&priv->lock); + init_completion(&priv->completed); ret = mx25_gcq_setup_cfgs(pdev, priv); diff --git a/drivers/iio/adc/ltc2497-core.c b/drivers/iio/adc/ltc2497-core.c index 9b8fd9c32364..2a485c8a1940 100644 --- a/drivers/iio/adc/ltc2497-core.c +++ b/drivers/iio/adc/ltc2497-core.c @@ -180,13 +180,9 @@ int ltc2497core_probe(struct device *dev, struct iio_dev *indio_dev) return ret; ddata->ref = devm_regulator_get(dev, "vref"); - if (IS_ERR(ddata->ref)) { - if (PTR_ERR(ddata->ref) != -EPROBE_DEFER) - dev_err(dev, "Failed to get vref regulator: %pe\n", - ddata->ref); - - return PTR_ERR(ddata->ref); - } + if (IS_ERR(ddata->ref)) + return dev_err_probe(dev, PTR_ERR(ddata->ref), + "Failed to get vref regulator\n"); ret = regulator_enable(ddata->ref); if (ret < 0) { diff --git a/drivers/iio/adc/meson_saradc.c b/drivers/iio/adc/meson_saradc.c index 1a9189ba69ae..e03988698755 100644 --- a/drivers/iio/adc/meson_saradc.c +++ b/drivers/iio/adc/meson_saradc.c @@ -719,11 +719,8 @@ static int meson_sar_adc_temp_sensor_init(struct iio_dev *indio_dev) if (ret == -ENODEV) return 0; - if (ret != -EPROBE_DEFER) - dev_err(indio_dev->dev.parent, - "failed to get temperature_calib cell\n"); - - return ret; + return dev_err_probe(indio_dev->dev.parent, ret, + "failed to get temperature_calib cell\n"); } priv->tsc_regmap = @@ -1153,16 +1150,13 @@ static const struct of_device_id meson_sar_adc_of_match[] = { { .compatible = "amlogic,meson8-saradc", .data = &meson_sar_adc_meson8_data, - }, - { + }, { .compatible = "amlogic,meson8b-saradc", .data = &meson_sar_adc_meson8b_data, - }, - { + }, { .compatible = "amlogic,meson8m2-saradc", .data = &meson_sar_adc_meson8m2_data, - }, - { + }, { .compatible = "amlogic,meson-gxbb-saradc", .data = &meson_sar_adc_gxbb_data, }, { @@ -1178,7 +1172,7 @@ static const struct of_device_id meson_sar_adc_of_match[] = { .compatible = "amlogic,meson-g12a-saradc", .data = &meson_sar_adc_g12a_data, }, - {}, + { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, meson_sar_adc_of_match); diff --git a/drivers/iio/adc/palmas_gpadc.c b/drivers/iio/adc/palmas_gpadc.c index 1ca6570be66a..889b88768b63 100644 --- a/drivers/iio/adc/palmas_gpadc.c +++ b/drivers/iio/adc/palmas_gpadc.c @@ -834,18 +834,7 @@ static struct platform_driver palmas_gpadc_driver = { .of_match_table = of_palmas_gpadc_match_tbl, }, }; - -static int __init palmas_gpadc_init(void) -{ - return platform_driver_register(&palmas_gpadc_driver); -} -module_init(palmas_gpadc_init); - -static void __exit palmas_gpadc_exit(void) -{ - platform_driver_unregister(&palmas_gpadc_driver); -} -module_exit(palmas_gpadc_exit); +module_platform_driver(palmas_gpadc_driver); MODULE_DESCRIPTION("palmas GPADC driver"); MODULE_AUTHOR("Pradeep Goudagunta<pgoudagunta@nvidia.com>"); diff --git a/drivers/iio/adc/rcar-gyroadc.c b/drivers/iio/adc/rcar-gyroadc.c index d2c1419e72a0..9f38cf3c7dc2 100644 --- a/drivers/iio/adc/rcar-gyroadc.c +++ b/drivers/iio/adc/rcar-gyroadc.c @@ -357,7 +357,7 @@ static int rcar_gyroadc_parse_subdevs(struct iio_dev *indio_dev) num_channels = ARRAY_SIZE(rcar_gyroadc_iio_channels_3); break; default: - return -EINVAL; + goto err_e_inval; } /* @@ -374,7 +374,7 @@ static int rcar_gyroadc_parse_subdevs(struct iio_dev *indio_dev) dev_err(dev, "Failed to get child reg property of ADC \"%pOFn\".\n", child); - return ret; + goto err_of_node_put; } /* Channel number is too high. */ @@ -382,7 +382,7 @@ static int rcar_gyroadc_parse_subdevs(struct iio_dev *indio_dev) dev_err(dev, "Only %i channels supported with %pOFn, but reg = <%i>.\n", num_channels, child, reg); - return -EINVAL; + goto err_e_inval; } } @@ -391,7 +391,7 @@ static int rcar_gyroadc_parse_subdevs(struct iio_dev *indio_dev) dev_err(dev, "Channel %i uses different ADC mode than the rest.\n", reg); - return -EINVAL; + goto err_e_inval; } /* Channel is valid, grab the regulator. */ @@ -401,7 +401,8 @@ static int rcar_gyroadc_parse_subdevs(struct iio_dev *indio_dev) if (IS_ERR(vref)) { dev_dbg(dev, "Channel %i 'vref' supply not connected.\n", reg); - return PTR_ERR(vref); + ret = PTR_ERR(vref); + goto err_of_node_put; } priv->vref[reg] = vref; @@ -425,8 +426,10 @@ static int rcar_gyroadc_parse_subdevs(struct iio_dev *indio_dev) * attached to the GyroADC at a time, so if we found it, * we can stop parsing here. */ - if (childmode == RCAR_GYROADC_MODE_SELECT_1_MB88101A) + if (childmode == RCAR_GYROADC_MODE_SELECT_1_MB88101A) { + of_node_put(child); break; + } } if (first) { @@ -435,6 +438,12 @@ static int rcar_gyroadc_parse_subdevs(struct iio_dev *indio_dev) } return 0; + +err_e_inval: + ret = -EINVAL; +err_of_node_put: + of_node_put(child); + return ret; } static void rcar_gyroadc_deinit_supplies(struct iio_dev *indio_dev) @@ -495,12 +504,9 @@ static int rcar_gyroadc_probe(struct platform_device *pdev) return PTR_ERR(priv->regs); priv->clk = devm_clk_get(dev, "fck"); - if (IS_ERR(priv->clk)) { - ret = PTR_ERR(priv->clk); - if (ret != -EPROBE_DEFER) - dev_err(dev, "Failed to get IF clock (ret=%i)\n", ret); - return ret; - } + if (IS_ERR(priv->clk)) + return dev_err_probe(dev, PTR_ERR(priv->clk), + "Failed to get IF clock\n"); ret = rcar_gyroadc_parse_subdevs(indio_dev); if (ret) diff --git a/drivers/iio/adc/stm32-adc-core.c b/drivers/iio/adc/stm32-adc-core.c index 0e2068ec068b..cd870c089182 100644 --- a/drivers/iio/adc/stm32-adc-core.c +++ b/drivers/iio/adc/stm32-adc-core.c @@ -582,11 +582,9 @@ static int stm32_adc_core_switches_probe(struct device *dev, priv->syscfg = syscon_regmap_lookup_by_phandle(np, "st,syscfg"); if (IS_ERR(priv->syscfg)) { ret = PTR_ERR(priv->syscfg); - if (ret != -ENODEV) { - if (ret != -EPROBE_DEFER) - dev_err(dev, "Can't probe syscfg: %d\n", ret); - return ret; - } + if (ret != -ENODEV) + return dev_err_probe(dev, ret, "Can't probe syscfg\n"); + priv->syscfg = NULL; } @@ -596,12 +594,9 @@ static int stm32_adc_core_switches_probe(struct device *dev, priv->booster = devm_regulator_get_optional(dev, "booster"); if (IS_ERR(priv->booster)) { ret = PTR_ERR(priv->booster); - if (ret != -ENODEV) { - if (ret != -EPROBE_DEFER) - dev_err(dev, "can't get booster %d\n", - ret); - return ret; - } + if (ret != -ENODEV) + return dev_err_probe(dev, ret, "can't get booster\n"); + priv->booster = NULL; } } @@ -612,11 +607,9 @@ static int stm32_adc_core_switches_probe(struct device *dev, priv->vdd = devm_regulator_get_optional(dev, "vdd"); if (IS_ERR(priv->vdd)) { ret = PTR_ERR(priv->vdd); - if (ret != -ENODEV) { - if (ret != -EPROBE_DEFER) - dev_err(dev, "can't get vdd %d\n", ret); - return ret; - } + if (ret != -ENODEV) + return dev_err_probe(dev, ret, "can't get vdd\n"); + priv->vdd = NULL; } } @@ -669,42 +662,24 @@ static int stm32_adc_probe(struct platform_device *pdev) priv->common.phys_base = res->start; priv->vdda = devm_regulator_get(&pdev->dev, "vdda"); - if (IS_ERR(priv->vdda)) { - ret = PTR_ERR(priv->vdda); - if (ret != -EPROBE_DEFER) - dev_err(&pdev->dev, "vdda get failed, %d\n", ret); - return ret; - } + if (IS_ERR(priv->vdda)) + return dev_err_probe(&pdev->dev, PTR_ERR(priv->vdda), + "vdda get failed\n"); priv->vref = devm_regulator_get(&pdev->dev, "vref"); - if (IS_ERR(priv->vref)) { - ret = PTR_ERR(priv->vref); - if (ret != -EPROBE_DEFER) - dev_err(&pdev->dev, "vref get failed, %d\n", ret); - return ret; - } + if (IS_ERR(priv->vref)) + return dev_err_probe(&pdev->dev, PTR_ERR(priv->vref), + "vref get failed\n"); - priv->aclk = devm_clk_get(&pdev->dev, "adc"); - if (IS_ERR(priv->aclk)) { - ret = PTR_ERR(priv->aclk); - if (ret != -ENOENT) { - if (ret != -EPROBE_DEFER) - dev_err(&pdev->dev, "Can't get 'adc' clock\n"); - return ret; - } - priv->aclk = NULL; - } + priv->aclk = devm_clk_get_optional(&pdev->dev, "adc"); + if (IS_ERR(priv->aclk)) + return dev_err_probe(&pdev->dev, PTR_ERR(priv->aclk), + "Can't get 'adc' clock\n"); - priv->bclk = devm_clk_get(&pdev->dev, "bus"); - if (IS_ERR(priv->bclk)) { - ret = PTR_ERR(priv->bclk); - if (ret != -ENOENT) { - if (ret != -EPROBE_DEFER) - dev_err(&pdev->dev, "Can't get 'bus' clock\n"); - return ret; - } - priv->bclk = NULL; - } + priv->bclk = devm_clk_get_optional(&pdev->dev, "bus"); + if (IS_ERR(priv->bclk)) + return dev_err_probe(&pdev->dev, PTR_ERR(priv->bclk), + "Can't get 'bus' clock\n"); ret = stm32_adc_core_switches_probe(dev, priv); if (ret) @@ -794,6 +769,13 @@ static int stm32_adc_core_runtime_resume(struct device *dev) { return stm32_adc_core_hw_start(dev); } + +static int stm32_adc_core_runtime_idle(struct device *dev) +{ + pm_runtime_mark_last_busy(dev); + + return 0; +} #endif static const struct dev_pm_ops stm32_adc_core_pm_ops = { @@ -801,7 +783,7 @@ static const struct dev_pm_ops stm32_adc_core_pm_ops = { pm_runtime_force_resume) SET_RUNTIME_PM_OPS(stm32_adc_core_runtime_suspend, stm32_adc_core_runtime_resume, - NULL) + stm32_adc_core_runtime_idle) }; static const struct stm32_adc_priv_cfg stm32f4_adc_priv_cfg = { diff --git a/drivers/iio/adc/stm32-adc.c b/drivers/iio/adc/stm32-adc.c index 3eb9ebe8372f..b3f31f147347 100644 --- a/drivers/iio/adc/stm32-adc.c +++ b/drivers/iio/adc/stm32-adc.c @@ -1805,13 +1805,9 @@ static int stm32_adc_dma_request(struct device *dev, struct iio_dev *indio_dev) adc->dma_chan = dma_request_chan(dev, "rx"); if (IS_ERR(adc->dma_chan)) { ret = PTR_ERR(adc->dma_chan); - if (ret != -ENODEV) { - if (ret != -EPROBE_DEFER) - dev_err(dev, - "DMA channel request failed with %d\n", - ret); - return ret; - } + if (ret != -ENODEV) + return dev_err_probe(dev, ret, + "DMA channel request failed with\n"); /* DMA is optional: fall back to IRQ mode */ adc->dma_chan = NULL; diff --git a/drivers/iio/adc/stm32-dfsdm-adc.c b/drivers/iio/adc/stm32-dfsdm-adc.c index 5e10fb4f3704..c7e0109315f8 100644 --- a/drivers/iio/adc/stm32-dfsdm-adc.c +++ b/drivers/iio/adc/stm32-dfsdm-adc.c @@ -1473,13 +1473,9 @@ static int stm32_dfsdm_adc_init(struct device *dev, struct iio_dev *indio_dev) /* Optionally request DMA */ ret = stm32_dfsdm_dma_request(dev, indio_dev); if (ret) { - if (ret != -ENODEV) { - if (ret != -EPROBE_DEFER) - dev_err(dev, - "DMA channel request failed with %d\n", - ret); - return ret; - } + if (ret != -ENODEV) + return dev_err_probe(dev, ret, + "DMA channel request failed with\n"); dev_dbg(dev, "No DMA support\n"); return 0; diff --git a/drivers/iio/adc/stm32-dfsdm-core.c b/drivers/iio/adc/stm32-dfsdm-core.c index 26e2011c5868..42a7377704a4 100644 --- a/drivers/iio/adc/stm32-dfsdm-core.c +++ b/drivers/iio/adc/stm32-dfsdm-core.c @@ -226,16 +226,13 @@ static int stm32_dfsdm_parse_of(struct platform_device *pdev, if (!node) return -EINVAL; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(&pdev->dev, "Failed to get memory resource\n"); - return -ENODEV; - } - priv->dfsdm.phys_base = res->start; - priv->dfsdm.base = devm_ioremap_resource(&pdev->dev, res); + priv->dfsdm.base = devm_platform_get_and_ioremap_resource(pdev, 0, + &res); if (IS_ERR(priv->dfsdm.base)) return PTR_ERR(priv->dfsdm.base); + priv->dfsdm.phys_base = res->start; + /* * "dfsdm" clock is mandatory for DFSDM peripheral clocking. * "dfsdm" or "audio" clocks can be used as source clock for @@ -243,12 +240,9 @@ static int stm32_dfsdm_parse_of(struct platform_device *pdev, * on use case. */ priv->clk = devm_clk_get(&pdev->dev, "dfsdm"); - if (IS_ERR(priv->clk)) { - ret = PTR_ERR(priv->clk); - if (ret != -EPROBE_DEFER) - dev_err(&pdev->dev, "Failed to get clock (%d)\n", ret); - return ret; - } + if (IS_ERR(priv->clk)) + return dev_err_probe(&pdev->dev, PTR_ERR(priv->clk), + "Failed to get clock\n"); priv->aclk = devm_clk_get(&pdev->dev, "audio"); if (IS_ERR(priv->aclk)) diff --git a/drivers/iio/adc/ti-adc081c.c b/drivers/iio/adc/ti-adc081c.c index cf63983a54d9..b64718daa201 100644 --- a/drivers/iio/adc/ti-adc081c.c +++ b/drivers/iio/adc/ti-adc081c.c @@ -19,7 +19,6 @@ #include <linux/i2c.h> #include <linux/module.h> #include <linux/mod_devicetable.h> -#include <linux/acpi.h> #include <linux/iio/iio.h> #include <linux/iio/buffer.h> @@ -158,17 +157,7 @@ static int adc081c_probe(struct i2c_client *client, if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WORD_DATA)) return -EOPNOTSUPP; - if (ACPI_COMPANION(&client->dev)) { - const struct acpi_device_id *ad_id; - - ad_id = acpi_match_device(client->dev.driver->acpi_match_table, - &client->dev); - if (!ad_id) - return -ENODEV; - model = &adcxx1c_models[ad_id->driver_data]; - } else { - model = &adcxx1c_models[id->driver_data]; - } + model = &adcxx1c_models[id->driver_data]; iio = devm_iio_device_alloc(&client->dev, sizeof(*adc)); if (!iio) @@ -243,21 +232,10 @@ static const struct of_device_id adc081c_of_match[] = { }; MODULE_DEVICE_TABLE(of, adc081c_of_match); -#ifdef CONFIG_ACPI -static const struct acpi_device_id adc081c_acpi_match[] = { - { "ADC081C", ADC081C }, - { "ADC101C", ADC101C }, - { "ADC121C", ADC121C }, - { } -}; -MODULE_DEVICE_TABLE(acpi, adc081c_acpi_match); -#endif - static struct i2c_driver adc081c_driver = { .driver = { .name = "adc081c", .of_match_table = adc081c_of_match, - .acpi_match_table = ACPI_PTR(adc081c_acpi_match), }, .probe = adc081c_probe, .remove = adc081c_remove, diff --git a/drivers/iio/adc/ti-adc0832.c b/drivers/iio/adc/ti-adc0832.c index c7a085dce1f4..0261b3cfc92b 100644 --- a/drivers/iio/adc/ti-adc0832.c +++ b/drivers/iio/adc/ti-adc0832.c @@ -29,6 +29,12 @@ struct adc0832 { struct regulator *reg; struct mutex lock; u8 mux_bits; + /* + * Max size needed: 16x 1 byte ADC data + 8 bytes timestamp + * May be shorter if not all channels are enabled subject + * to the timestamp remaining 8 byte aligned. + */ + u8 data[24] __aligned(8); u8 tx_buf[2] ____cacheline_aligned; u8 rx_buf[2]; @@ -200,7 +206,6 @@ static irqreturn_t adc0832_trigger_handler(int irq, void *p) struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf->indio_dev; struct adc0832 *adc = iio_priv(indio_dev); - u8 data[24] = { }; /* 16x 1 byte ADC data + 8 bytes timestamp */ int scan_index; int i = 0; @@ -218,10 +223,10 @@ static irqreturn_t adc0832_trigger_handler(int irq, void *p) goto out; } - data[i] = ret; + adc->data[i] = ret; i++; } - iio_push_to_buffers_with_timestamp(indio_dev, data, + iio_push_to_buffers_with_timestamp(indio_dev, adc->data, iio_get_time_ns(indio_dev)); out: mutex_unlock(&adc->lock); diff --git a/drivers/iio/adc/ti-adc108s102.c b/drivers/iio/adc/ti-adc108s102.c index 9b9b27415c93..183b2245e89b 100644 --- a/drivers/iio/adc/ti-adc108s102.c +++ b/drivers/iio/adc/ti-adc108s102.c @@ -20,6 +20,7 @@ #include <linux/iio/trigger_consumer.h> #include <linux/interrupt.h> #include <linux/module.h> +#include <linux/mod_devicetable.h> #include <linux/property.h> #include <linux/regulator/consumer.h> #include <linux/spi/spi.h> @@ -299,13 +300,11 @@ static int adc108s102_remove(struct spi_device *spi) return 0; } -#ifdef CONFIG_OF static const struct of_device_id adc108s102_of_match[] = { { .compatible = "ti,adc108s102" }, { } }; MODULE_DEVICE_TABLE(of, adc108s102_of_match); -#endif #ifdef CONFIG_ACPI static const struct acpi_device_id adc108s102_acpi_ids[] = { @@ -324,7 +323,7 @@ MODULE_DEVICE_TABLE(spi, adc108s102_id); static struct spi_driver adc108s102_driver = { .driver = { .name = "adc108s102", - .of_match_table = of_match_ptr(adc108s102_of_match), + .of_match_table = adc108s102_of_match, .acpi_match_table = ACPI_PTR(adc108s102_acpi_ids), }, .probe = adc108s102_probe, diff --git a/drivers/iio/adc/ti-adc12138.c b/drivers/iio/adc/ti-adc12138.c index e485719cd2c4..fcd5d39dd03e 100644 --- a/drivers/iio/adc/ti-adc12138.c +++ b/drivers/iio/adc/ti-adc12138.c @@ -47,6 +47,12 @@ struct adc12138 { struct completion complete; /* The number of cclk periods for the S/H's acquisition time */ unsigned int acquisition_time; + /* + * Maximum size needed: 16x 2 bytes ADC data + 8 bytes timestamp. + * Less may be need if not all channels are enabled, as long as + * the 8 byte alignment of the timestamp is maintained. + */ + __be16 data[20] __aligned(8); u8 tx_buf[2] ____cacheline_aligned; u8 rx_buf[2]; @@ -329,7 +335,6 @@ static irqreturn_t adc12138_trigger_handler(int irq, void *p) struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf->indio_dev; struct adc12138 *adc = iio_priv(indio_dev); - __be16 data[20] = { }; /* 16x 2 bytes ADC data + 8 bytes timestamp */ __be16 trash; int ret; int scan_index; @@ -345,7 +350,7 @@ static irqreturn_t adc12138_trigger_handler(int irq, void *p) reinit_completion(&adc->complete); ret = adc12138_start_and_read_conv(adc, scan_chan, - i ? &data[i - 1] : &trash); + i ? &adc->data[i - 1] : &trash); if (ret) { dev_warn(&adc->spi->dev, "failed to start conversion\n"); @@ -362,7 +367,7 @@ static irqreturn_t adc12138_trigger_handler(int irq, void *p) } if (i) { - ret = adc12138_read_conv_data(adc, &data[i - 1]); + ret = adc12138_read_conv_data(adc, &adc->data[i - 1]); if (ret) { dev_warn(&adc->spi->dev, "failed to get conversion data\n"); @@ -370,7 +375,7 @@ static irqreturn_t adc12138_trigger_handler(int irq, void *p) } } - iio_push_to_buffers_with_timestamp(indio_dev, data, + iio_push_to_buffers_with_timestamp(indio_dev, adc->data, iio_get_time_ns(indio_dev)); out: mutex_unlock(&adc->lock); diff --git a/drivers/iio/adc/ti-adc128s052.c b/drivers/iio/adc/ti-adc128s052.c index e86f55ce093f..3143f35a6509 100644 --- a/drivers/iio/adc/ti-adc128s052.c +++ b/drivers/iio/adc/ti-adc128s052.c @@ -13,6 +13,7 @@ #include <linux/err.h> #include <linux/spi/spi.h> #include <linux/module.h> +#include <linux/mod_devicetable.h> #include <linux/iio/iio.h> #include <linux/property.h> #include <linux/regulator/consumer.h> @@ -220,7 +221,7 @@ MODULE_DEVICE_TABLE(acpi, adc128_acpi_match); static struct spi_driver adc128_driver = { .driver = { .name = "adc128s052", - .of_match_table = of_match_ptr(adc128_of_match), + .of_match_table = adc128_of_match, .acpi_match_table = ACPI_PTR(adc128_acpi_match), }, .probe = adc128_probe, diff --git a/drivers/iio/afe/iio-rescale.c b/drivers/iio/afe/iio-rescale.c index 69c0f277ada0..e42ea2b1707d 100644 --- a/drivers/iio/afe/iio-rescale.c +++ b/drivers/iio/afe/iio-rescale.c @@ -276,11 +276,9 @@ static int rescale_probe(struct platform_device *pdev) int ret; source = devm_iio_channel_get(dev, NULL); - if (IS_ERR(source)) { - if (PTR_ERR(source) != -EPROBE_DEFER) - dev_err(dev, "failed to get source channel\n"); - return PTR_ERR(source); - } + if (IS_ERR(source)) + return dev_err_probe(dev, PTR_ERR(source), + "failed to get source channel\n"); sizeof_ext_info = iio_get_channel_ext_info_count(source); if (sizeof_ext_info) { diff --git a/drivers/iio/amplifiers/Kconfig b/drivers/iio/amplifiers/Kconfig index 9b02c9a2bc8a..5eb1357a9c78 100644 --- a/drivers/iio/amplifiers/Kconfig +++ b/drivers/iio/amplifiers/Kconfig @@ -18,6 +18,7 @@ config AD8366 AD8366 Dual-Digital Variable Gain Amplifier (VGA) ADA4961 BiCMOS RF Digital Gain Amplifier (DGA) ADL5240 Digitally controlled variable gain amplifier (VGA) + HMC1119 0.25 dB LSB, 7-Bit, Silicon Digital Attenuator To compile this driver as a module, choose M here: the module will be called ad8366. diff --git a/drivers/iio/amplifiers/hmc425a.c b/drivers/iio/amplifiers/hmc425a.c index 582708924e4f..9efa692151f0 100644 --- a/drivers/iio/amplifiers/hmc425a.c +++ b/drivers/iio/amplifiers/hmc425a.c @@ -201,12 +201,9 @@ static int hmc425a_probe(struct platform_device *pdev) st->gain = st->chip_info->default_gain; st->gpios = devm_gpiod_get_array(&pdev->dev, "ctrl", GPIOD_OUT_LOW); - if (IS_ERR(st->gpios)) { - ret = PTR_ERR(st->gpios); - if (ret != -EPROBE_DEFER) - dev_err(&pdev->dev, "failed to get gpios\n"); - return ret; - } + if (IS_ERR(st->gpios)) + return dev_err_probe(&pdev->dev, PTR_ERR(st->gpios), + "failed to get gpios\n"); if (st->gpios->ndescs != st->chip_info->num_gpios) { dev_err(&pdev->dev, "%d GPIOs needed to operate\n", diff --git a/drivers/iio/buffer/Kconfig b/drivers/iio/buffer/Kconfig index 63f265c8b466..047b931591a9 100644 --- a/drivers/iio/buffer/Kconfig +++ b/drivers/iio/buffer/Kconfig @@ -11,7 +11,7 @@ config IIO_BUFFER_CB usage. That is, those where the data is pushed to the consumer. config IIO_BUFFER_DMA - tristate + tristate "Industrial I/O DMA buffer infrastructure" help Provides the generic IIO DMA buffer infrastructure that can be used by drivers for devices with DMA support to implement the IIO buffer. @@ -20,13 +20,13 @@ config IIO_BUFFER_DMA infrastructure. config IIO_BUFFER_DMAENGINE - tristate + tristate "Industrial I/O DMA buffer integration with DMAEngine" select IIO_BUFFER_DMA help Provides a bonding of the generic IIO DMA buffer infrastructure with the - DMAengine framework. This can be used by converter drivers with a DMA port + DMAEngine framework. This can be used by converter drivers with a DMA port connected to an external DMA controller which is supported by the - DMAengine framework. + DMAEngine framework. Should be selected by drivers that want to use this functionality. @@ -48,7 +48,7 @@ config IIO_KFIFO_BUF often to read from the buffer. config IIO_TRIGGERED_BUFFER - tristate + tristate "Industrial I/O triggered buffer support" select IIO_TRIGGER select IIO_KFIFO_BUF help diff --git a/drivers/iio/buffer/industrialio-buffer-dmaengine.c b/drivers/iio/buffer/industrialio-buffer-dmaengine.c index 6dedf12b69a4..93b4e9e6bb55 100644 --- a/drivers/iio/buffer/industrialio-buffer-dmaengine.c +++ b/drivers/iio/buffer/industrialio-buffer-dmaengine.c @@ -45,7 +45,8 @@ static struct dmaengine_buffer *iio_buffer_to_dmaengine_buffer( return container_of(buffer, struct dmaengine_buffer, queue.buffer); } -static void iio_dmaengine_buffer_block_done(void *data) +static void iio_dmaengine_buffer_block_done(void *data, + const struct dmaengine_result *result) { struct iio_dma_buffer_block *block = data; unsigned long flags; @@ -53,6 +54,7 @@ static void iio_dmaengine_buffer_block_done(void *data) spin_lock_irqsave(&block->queue->list_lock, flags); list_del(&block->head); spin_unlock_irqrestore(&block->queue->list_lock, flags); + block->bytes_used -= result->residue; iio_dma_buffer_block_done(block); } @@ -74,7 +76,7 @@ static int iio_dmaengine_buffer_submit_block(struct iio_dma_buffer_queue *queue, if (!desc) return -ENOMEM; - desc->callback = iio_dmaengine_buffer_block_done; + desc->callback_result = iio_dmaengine_buffer_block_done; desc->callback_param = block; cookie = dmaengine_submit(desc); @@ -157,7 +159,7 @@ static const struct attribute *iio_dmaengine_buffer_attrs[] = { * Once done using the buffer iio_dmaengine_buffer_free() should be used to * release it. */ -struct iio_buffer *iio_dmaengine_buffer_alloc(struct device *dev, +static struct iio_buffer *iio_dmaengine_buffer_alloc(struct device *dev, const char *channel) { struct dmaengine_buffer *dmaengine_buffer; @@ -209,7 +211,6 @@ err_free: kfree(dmaengine_buffer); return ERR_PTR(ret); } -EXPORT_SYMBOL(iio_dmaengine_buffer_alloc); /** * iio_dmaengine_buffer_free() - Free dmaengine buffer @@ -217,7 +218,7 @@ EXPORT_SYMBOL(iio_dmaengine_buffer_alloc); * * Frees a buffer previously allocated with iio_dmaengine_buffer_alloc(). */ -void iio_dmaengine_buffer_free(struct iio_buffer *buffer) +static void iio_dmaengine_buffer_free(struct iio_buffer *buffer) { struct dmaengine_buffer *dmaengine_buffer = iio_buffer_to_dmaengine_buffer(buffer); @@ -227,7 +228,6 @@ void iio_dmaengine_buffer_free(struct iio_buffer *buffer) iio_buffer_put(buffer); } -EXPORT_SYMBOL_GPL(iio_dmaengine_buffer_free); static void __devm_iio_dmaengine_buffer_free(struct device *dev, void *res) { diff --git a/drivers/iio/chemical/ams-iaq-core.c b/drivers/iio/chemical/ams-iaq-core.c index 8c1b64fd424a..97be3669c554 100644 --- a/drivers/iio/chemical/ams-iaq-core.c +++ b/drivers/iio/chemical/ams-iaq-core.c @@ -7,6 +7,7 @@ */ #include <linux/module.h> +#include <linux/mod_devicetable.h> #include <linux/mutex.h> #include <linux/init.h> #include <linux/i2c.h> @@ -177,7 +178,7 @@ MODULE_DEVICE_TABLE(of, ams_iaqcore_dt_ids); static struct i2c_driver ams_iaqcore_driver = { .driver = { .name = "ams-iaq-core", - .of_match_table = of_match_ptr(ams_iaqcore_dt_ids), + .of_match_table = ams_iaqcore_dt_ids, }, .probe = ams_iaqcore_probe, .id_table = ams_iaqcore_id, diff --git a/drivers/iio/chemical/atlas-ezo-sensor.c b/drivers/iio/chemical/atlas-ezo-sensor.c index 8b72bb012363..b1bacfe3c3ce 100644 --- a/drivers/iio/chemical/atlas-ezo-sensor.c +++ b/drivers/iio/chemical/atlas-ezo-sensor.c @@ -16,10 +16,13 @@ #include <linux/iio/iio.h> #define ATLAS_EZO_DRV_NAME "atlas-ezo-sensor" -#define ATLAS_CO2_INT_TIME_IN_MS 950 +#define ATLAS_INT_TIME_IN_MS 950 +#define ATLAS_INT_HUM_TIME_IN_MS 350 enum { ATLAS_CO2_EZO, + ATLAS_O2_EZO, + ATLAS_HUM_EZO, }; struct atlas_ezo_device { @@ -38,15 +41,37 @@ struct atlas_ezo_data { u8 buffer[8]; }; +#define ATLAS_CONCENTRATION_CHANNEL(_modifier) \ + { \ + .type = IIO_CONCENTRATION, \ + .modified = 1,\ + .channel2 = _modifier, \ + .info_mask_separate = \ + BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), \ + .scan_index = 0, \ + .scan_type = { \ + .sign = 'u', \ + .realbits = 32, \ + .storagebits = 32, \ + .endianness = IIO_CPU, \ + }, \ + } + static const struct iio_chan_spec atlas_co2_ezo_channels[] = { + ATLAS_CONCENTRATION_CHANNEL(IIO_MOD_CO2), +}; + +static const struct iio_chan_spec atlas_o2_ezo_channels[] = { + ATLAS_CONCENTRATION_CHANNEL(IIO_MOD_O2), +}; + +static const struct iio_chan_spec atlas_hum_ezo_channels[] = { { - .type = IIO_CONCENTRATION, - .modified = 1, - .channel2 = IIO_MOD_CO2, + .type = IIO_HUMIDITYRELATIVE, .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), .scan_index = 0, - .scan_type = { + .scan_type = { .sign = 'u', .realbits = 32, .storagebits = 32, @@ -59,10 +84,30 @@ static struct atlas_ezo_device atlas_ezo_devices[] = { [ATLAS_CO2_EZO] = { .channels = atlas_co2_ezo_channels, .num_channels = 1, - .delay = ATLAS_CO2_INT_TIME_IN_MS, + .delay = ATLAS_INT_TIME_IN_MS, + }, + [ATLAS_O2_EZO] = { + .channels = atlas_o2_ezo_channels, + .num_channels = 1, + .delay = ATLAS_INT_TIME_IN_MS, + }, + [ATLAS_HUM_EZO] = { + .channels = atlas_hum_ezo_channels, + .num_channels = 1, + .delay = ATLAS_INT_HUM_TIME_IN_MS, }, }; +static void atlas_ezo_sanitize(char *buf) +{ + char *ptr = strchr(buf, '.'); + + if (!ptr) + return; + + memmove(ptr, ptr + 1, strlen(ptr)); +} + static int atlas_ezo_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2, long mask) @@ -96,6 +141,9 @@ static int atlas_ezo_read_raw(struct iio_dev *indio_dev, return -EBUSY; } + /* removing floating point for fixed number representation */ + atlas_ezo_sanitize(data->buffer + 2); + ret = kstrtol(data->buffer + 1, 10, &tmp); *val = tmp; @@ -105,9 +153,27 @@ static int atlas_ezo_read_raw(struct iio_dev *indio_dev, return ret ? ret : IIO_VAL_INT; } case IIO_CHAN_INFO_SCALE: - *val = 0; - *val2 = 100; /* 0.0001 */ - return IIO_VAL_INT_PLUS_MICRO; + switch (chan->type) { + case IIO_HUMIDITYRELATIVE: + *val = 10; + return IIO_VAL_INT; + case IIO_CONCENTRATION: + break; + default: + return -EINVAL; + } + + /* IIO_CONCENTRATION modifiers */ + switch (chan->channel2) { + case IIO_MOD_CO2: + *val = 0; + *val2 = 100; /* 0.0001 */ + return IIO_VAL_INT_PLUS_MICRO; + case IIO_MOD_O2: + *val = 100; + return IIO_VAL_INT; + } + return -EINVAL; } return 0; @@ -119,12 +185,16 @@ static const struct iio_info atlas_info = { static const struct i2c_device_id atlas_ezo_id[] = { { "atlas-co2-ezo", ATLAS_CO2_EZO }, + { "atlas-o2-ezo", ATLAS_O2_EZO }, + { "atlas-hum-ezo", ATLAS_HUM_EZO }, {} }; MODULE_DEVICE_TABLE(i2c, atlas_ezo_id); static const struct of_device_id atlas_ezo_dt_ids[] = { { .compatible = "atlas,co2-ezo", .data = (void *)ATLAS_CO2_EZO, }, + { .compatible = "atlas,o2-ezo", .data = (void *)ATLAS_O2_EZO, }, + { .compatible = "atlas,hum-ezo", .data = (void *)ATLAS_HUM_EZO, }, {} }; MODULE_DEVICE_TABLE(of, atlas_ezo_dt_ids); diff --git a/drivers/iio/chemical/atlas-sensor.c b/drivers/iio/chemical/atlas-sensor.c index 43069636fcd5..cdab9d04dedd 100644 --- a/drivers/iio/chemical/atlas-sensor.c +++ b/drivers/iio/chemical/atlas-sensor.c @@ -15,7 +15,7 @@ #include <linux/irq.h> #include <linux/irq_work.h> #include <linux/i2c.h> -#include <linux/of_device.h> +#include <linux/mod_devicetable.h> #include <linux/regmap.h> #include <linux/iio/iio.h> #include <linux/iio/buffer.h> @@ -620,7 +620,6 @@ static int atlas_probe(struct i2c_client *client, { struct atlas_data *data; struct atlas_device *chip; - const struct of_device_id *of_id; struct iio_trigger *trig; struct iio_dev *indio_dev; int ret; @@ -629,11 +628,10 @@ static int atlas_probe(struct i2c_client *client, if (!indio_dev) return -ENOMEM; - of_id = of_match_device(atlas_dt_ids, &client->dev); - if (!of_id) + if (!dev_fwnode(&client->dev)) chip = &atlas_devices[id->driver_data]; else - chip = &atlas_devices[(unsigned long)of_id->data]; + chip = &atlas_devices[(unsigned long)device_get_match_data(&client->dev)]; indio_dev->info = &atlas_info; indio_dev->name = ATLAS_DRV_NAME; @@ -775,7 +773,7 @@ static const struct dev_pm_ops atlas_pm_ops = { static struct i2c_driver atlas_driver = { .driver = { .name = ATLAS_DRV_NAME, - .of_match_table = of_match_ptr(atlas_dt_ids), + .of_match_table = atlas_dt_ids, .pm = &atlas_pm_ops, }, .probe = atlas_probe, diff --git a/drivers/iio/chemical/scd30_core.c b/drivers/iio/chemical/scd30_core.c index eac76972f83e..4d0d798c7cd3 100644 --- a/drivers/iio/chemical/scd30_core.c +++ b/drivers/iio/chemical/scd30_core.c @@ -705,13 +705,8 @@ int scd30_probe(struct device *dev, int irq, const char *name, void *priv, indio_dev->available_scan_masks = scd30_scan_masks; state->vdd = devm_regulator_get(dev, "vdd"); - if (IS_ERR(state->vdd)) { - if (PTR_ERR(state->vdd) == -EPROBE_DEFER) - return -EPROBE_DEFER; - - dev_err(dev, "failed to get regulator\n"); - return PTR_ERR(state->vdd); - } + if (IS_ERR(state->vdd)) + return dev_err_probe(dev, PTR_ERR(state->vdd), "failed to get regulator\n"); ret = regulator_enable(state->vdd); if (ret) diff --git a/drivers/iio/chemical/sgp30.c b/drivers/iio/chemical/sgp30.c index 2c4086c48136..1029c457be15 100644 --- a/drivers/iio/chemical/sgp30.c +++ b/drivers/iio/chemical/sgp30.c @@ -20,9 +20,9 @@ #include <linux/delay.h> #include <linux/kthread.h> #include <linux/module.h> +#include <linux/mod_devicetable.h> #include <linux/mutex.h> #include <linux/i2c.h> -#include <linux/of_device.h> #include <linux/iio/iio.h> #include <linux/iio/sysfs.h> @@ -227,6 +227,7 @@ static int sgp_verify_buffer(const struct sgp_data *data, * @cmd: SGP Command to issue * @buf: Raw data buffer to use * @word_count: Num words to read, excluding CRC bytes + * @duration_us: Time taken to sensor to take a reading and data to be ready. * * Return: 0 on success, negative error otherwise. */ @@ -409,6 +410,7 @@ static int sgp_read_raw(struct iio_dev *indio_dev, static int sgp_check_compat(struct sgp_data *data, unsigned int product_id) { + struct device *dev = &data->client->dev; const struct sgp_version *supported_versions; u16 ix, num_fs; u16 product, generation, major, minor; @@ -416,21 +418,20 @@ static int sgp_check_compat(struct sgp_data *data, /* driver does not match product */ generation = SGP_VERS_GEN(data); if (generation != 0) { - dev_err(&data->client->dev, + dev_err(dev, "incompatible product generation %d != 0", generation); return -ENODEV; } product = SGP_VERS_PRODUCT(data); if (product != product_id) { - dev_err(&data->client->dev, - "sensor reports a different product: 0x%04hx\n", + dev_err(dev, "sensor reports a different product: 0x%04hx\n", product); return -ENODEV; } if (SGP_VERS_RESERVED(data)) - dev_warn(&data->client->dev, "reserved bit is set\n"); + dev_warn(dev, "reserved bit is set\n"); /* engineering samples are not supported: no interface guarantees */ if (SGP_VERS_ENG_BIT(data)) @@ -456,8 +457,7 @@ static int sgp_check_compat(struct sgp_data *data, minor >= supported_versions[ix].minor) return 0; } - dev_err(&data->client->dev, "unsupported sgp version: %d.%d\n", - major, minor); + dev_err(dev, "unsupported sgp version: %d.%d\n", major, minor); return -ENODEV; } @@ -499,19 +499,18 @@ static const struct of_device_id sgp_dt_ids[] = { static int sgp_probe(struct i2c_client *client, const struct i2c_device_id *id) { + struct device *dev = &client->dev; struct iio_dev *indio_dev; struct sgp_data *data; - const struct of_device_id *of_id; unsigned long product_id; int ret; - indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); + indio_dev = devm_iio_device_alloc(dev, sizeof(*data)); if (!indio_dev) return -ENOMEM; - of_id = of_match_device(sgp_dt_ids, &client->dev); - if (of_id) - product_id = (unsigned long)of_id->data; + if (dev_fwnode(dev)) + product_id = (unsigned long)device_get_match_data(dev); else product_id = id->driver_data; @@ -541,9 +540,9 @@ static int sgp_probe(struct i2c_client *client, sgp_init(data); - ret = devm_iio_device_register(&client->dev, indio_dev); + ret = devm_iio_device_register(dev, indio_dev); if (ret) { - dev_err(&client->dev, "failed to register iio device\n"); + dev_err(dev, "failed to register iio device\n"); return ret; } @@ -576,7 +575,7 @@ MODULE_DEVICE_TABLE(of, sgp_dt_ids); static struct i2c_driver sgp_driver = { .driver = { .name = "sgp30", - .of_match_table = of_match_ptr(sgp_dt_ids), + .of_match_table = sgp_dt_ids, }, .probe = sgp_probe, .remove = sgp_remove, diff --git a/drivers/iio/chemical/vz89x.c b/drivers/iio/chemical/vz89x.c index 5586eb8e12cd..23b22a5f5c1c 100644 --- a/drivers/iio/chemical/vz89x.c +++ b/drivers/iio/chemical/vz89x.c @@ -10,8 +10,7 @@ #include <linux/mutex.h> #include <linux/init.h> #include <linux/i2c.h> -#include <linux/of.h> -#include <linux/of_device.h> +#include <linux/mod_devicetable.h> #include <linux/iio/iio.h> #include <linux/iio/sysfs.h> @@ -352,12 +351,12 @@ MODULE_DEVICE_TABLE(of, vz89x_dt_ids); static int vz89x_probe(struct i2c_client *client, const struct i2c_device_id *id) { + struct device *dev = &client->dev; struct iio_dev *indio_dev; struct vz89x_data *data; - const struct of_device_id *of_id; int chip_id; - indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); + indio_dev = devm_iio_device_alloc(dev, sizeof(*data)); if (!indio_dev) return -ENOMEM; data = iio_priv(indio_dev); @@ -370,11 +369,10 @@ static int vz89x_probe(struct i2c_client *client, else return -EOPNOTSUPP; - of_id = of_match_device(vz89x_dt_ids, &client->dev); - if (!of_id) + if (!dev_fwnode(dev)) chip_id = id->driver_data; else - chip_id = (unsigned long)of_id->data; + chip_id = (unsigned long)device_get_match_data(dev); i2c_set_clientdata(client, indio_dev); data->client = client; @@ -383,13 +381,13 @@ static int vz89x_probe(struct i2c_client *client, mutex_init(&data->lock); indio_dev->info = &vz89x_info; - indio_dev->name = dev_name(&client->dev); + indio_dev->name = dev_name(dev); indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->channels = data->chip->channels; indio_dev->num_channels = data->chip->num_channels; - return devm_iio_device_register(&client->dev, indio_dev); + return devm_iio_device_register(dev, indio_dev); } static const struct i2c_device_id vz89x_id[] = { @@ -402,7 +400,7 @@ MODULE_DEVICE_TABLE(i2c, vz89x_id); static struct i2c_driver vz89x_driver = { .driver = { .name = "vz89x", - .of_match_table = of_match_ptr(vz89x_dt_ids), + .of_match_table = vz89x_dt_ids, }, .probe = vz89x_probe, .id_table = vz89x_id, diff --git a/drivers/iio/common/cros_ec_sensors/cros_ec_lid_angle.c b/drivers/iio/common/cros_ec_sensors/cros_ec_lid_angle.c index af801e203623..752f59037715 100644 --- a/drivers/iio/common/cros_ec_sensors/cros_ec_lid_angle.c +++ b/drivers/iio/common/cros_ec_sensors/cros_ec_lid_angle.c @@ -97,7 +97,8 @@ static int cros_ec_lid_angle_probe(struct platform_device *pdev) if (!indio_dev) return -ENOMEM; - ret = cros_ec_sensors_core_init(pdev, indio_dev, false, NULL, NULL); + ret = cros_ec_sensors_core_init(pdev, indio_dev, false, NULL, + NULL, false); if (ret) return ret; diff --git a/drivers/iio/common/cros_ec_sensors/cros_ec_sensors.c b/drivers/iio/common/cros_ec_sensors/cros_ec_sensors.c index 130ab8ce0269..57038ca48d93 100644 --- a/drivers/iio/common/cros_ec_sensors/cros_ec_sensors.c +++ b/drivers/iio/common/cros_ec_sensors/cros_ec_sensors.c @@ -236,12 +236,11 @@ static int cros_ec_sensors_probe(struct platform_device *pdev) ret = cros_ec_sensors_core_init(pdev, indio_dev, true, cros_ec_sensors_capture, - cros_ec_sensors_push_data); + cros_ec_sensors_push_data, + true); if (ret) return ret; - iio_buffer_set_attrs(indio_dev->buffer, cros_ec_sensor_fifo_attributes); - indio_dev->info = &ec_sensors_info; state = iio_priv(indio_dev); for (channel = state->channels, i = CROS_EC_SENSOR_X; diff --git a/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c b/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c index 1bc6efa47316..c62cacc04672 100644 --- a/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c +++ b/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c @@ -177,12 +177,11 @@ static ssize_t hwfifo_watermark_max_show(struct device *dev, static IIO_DEVICE_ATTR_RO(hwfifo_watermark_max, 0); -const struct attribute *cros_ec_sensor_fifo_attributes[] = { +static const struct attribute *cros_ec_sensor_fifo_attributes[] = { &iio_dev_attr_hwfifo_timeout.dev_attr.attr, &iio_dev_attr_hwfifo_watermark_max.dev_attr.attr, NULL, }; -EXPORT_SYMBOL_GPL(cros_ec_sensor_fifo_attributes); int cros_ec_sensors_push_data(struct iio_dev *indio_dev, s16 *data, @@ -241,6 +240,7 @@ static void cros_ec_sensors_core_clean(void *arg) * for backward compatibility. * @push_data: function to call when cros_ec_sensorhub receives * a sample for that sensor. + * @has_hw_fifo: Set true if this device has/uses a HW FIFO * * Return: 0 on success, -errno on failure. */ @@ -248,7 +248,8 @@ int cros_ec_sensors_core_init(struct platform_device *pdev, struct iio_dev *indio_dev, bool physical_device, cros_ec_sensors_capture_t trigger_capture, - cros_ec_sensorhub_push_data_cb_t push_data) + cros_ec_sensorhub_push_data_cb_t push_data, + bool has_hw_fifo) { struct device *dev = &pdev->dev; struct cros_ec_sensors_core_state *state = iio_priv(indio_dev); @@ -361,6 +362,10 @@ int cros_ec_sensors_core_init(struct platform_device *pdev, NULL); if (ret) return ret; + + if (has_hw_fifo) + iio_buffer_set_attrs(indio_dev->buffer, + cros_ec_sensor_fifo_attributes); } } diff --git a/drivers/iio/common/ssp_sensors/ssp_dev.c b/drivers/iio/common/ssp_sensors/ssp_dev.c index a94dbcf491ce..1aee87100038 100644 --- a/drivers/iio/common/ssp_sensors/ssp_dev.c +++ b/drivers/iio/common/ssp_sensors/ssp_dev.c @@ -503,7 +503,8 @@ static int ssp_probe(struct spi_device *spi) return -ENODEV; } - ret = mfd_add_devices(&spi->dev, -1, sensorhub_sensor_devs, + ret = mfd_add_devices(&spi->dev, PLATFORM_DEVID_NONE, + sensorhub_sensor_devs, ARRAY_SIZE(sensorhub_sensor_devs), NULL, 0, NULL); if (ret < 0) { dev_err(&spi->dev, "mfd add devices fail\n"); diff --git a/drivers/iio/dac/ad5064.c b/drivers/iio/dac/ad5064.c index fef503f8012d..82abd4d6886c 100644 --- a/drivers/iio/dac/ad5064.c +++ b/drivers/iio/dac/ad5064.c @@ -68,8 +68,8 @@ enum ad5064_regmap_type { * struct ad5064_chip_info - chip specific information * @shared_vref: whether the vref supply is shared between channels * @internal_vref: internal reference voltage. 0 if the chip has no - internal vref. - * @channel: channel specification + * internal vref. + * @channels: channel specification * @num_channels: number of channels * @regmap_type: register map layout variant */ @@ -98,6 +98,7 @@ typedef int (*ad5064_write_func)(struct ad5064_state *st, unsigned int cmd, * @use_internal_vref: set to true if the internal reference voltage should be * used. * @write: register write callback + * @lock: maintain consistency between cached and dev state * @data: i2c/spi transfer buffers */ @@ -111,7 +112,6 @@ struct ad5064_state { bool use_internal_vref; ad5064_write_func write; - /* Lock used to maintain consistency between cached and dev state */ struct mutex lock; /* diff --git a/drivers/iio/dac/ad5446.c b/drivers/iio/dac/ad5446.c index 935a6177569f..d87e21016863 100644 --- a/drivers/iio/dac/ad5446.c +++ b/drivers/iio/dac/ad5446.c @@ -17,6 +17,7 @@ #include <linux/regulator/consumer.h> #include <linux/err.h> #include <linux/module.h> +#include <linux/mod_devicetable.h> #include <linux/iio/iio.h> #include <linux/iio/sysfs.h> @@ -478,13 +479,11 @@ static const struct spi_device_id ad5446_spi_ids[] = { }; MODULE_DEVICE_TABLE(spi, ad5446_spi_ids); -#ifdef CONFIG_OF static const struct of_device_id ad5446_of_ids[] = { { .compatible = "ti,dac7512" }, { } }; MODULE_DEVICE_TABLE(of, ad5446_of_ids); -#endif static int ad5446_spi_probe(struct spi_device *spi) { @@ -502,7 +501,7 @@ static int ad5446_spi_remove(struct spi_device *spi) static struct spi_driver ad5446_spi_driver = { .driver = { .name = "ad5446", - .of_match_table = of_match_ptr(ad5446_of_ids), + .of_match_table = ad5446_of_ids, }, .probe = ad5446_spi_probe, .remove = ad5446_spi_remove, diff --git a/drivers/iio/dac/ad5592r-base.c b/drivers/iio/dac/ad5592r-base.c index 1fd75c02a7cd..0405e92b9e8c 100644 --- a/drivers/iio/dac/ad5592r-base.c +++ b/drivers/iio/dac/ad5592r-base.c @@ -374,36 +374,36 @@ static int ad5592r_read_raw(struct iio_dev *iio_dev, { struct ad5592r_state *st = iio_priv(iio_dev); u16 read_val; - int ret; + int ret, mult; switch (m) { case IIO_CHAN_INFO_RAW: - mutex_lock(&st->lock); - if (!chan->output) { + mutex_lock(&st->lock); ret = st->ops->read_adc(st, chan->channel, &read_val); + mutex_unlock(&st->lock); if (ret) - goto unlock; + return ret; if ((read_val >> 12 & 0x7) != (chan->channel & 0x7)) { dev_err(st->dev, "Error while reading channel %u\n", chan->channel); - ret = -EIO; - goto unlock; + return -EIO; } read_val &= GENMASK(11, 0); } else { + mutex_lock(&st->lock); read_val = st->cached_dac[chan->channel]; + mutex_unlock(&st->lock); } dev_dbg(st->dev, "Channel %u read: 0x%04hX\n", chan->channel, read_val); *val = (int) read_val; - ret = IIO_VAL_INT; - break; + return IIO_VAL_INT; case IIO_CHAN_INFO_SCALE: *val = ad5592r_get_vref(st); @@ -412,24 +412,24 @@ static int ad5592r_read_raw(struct iio_dev *iio_dev, *val = div_s64_rem(tmp, 1000000000LL, val2); return IIO_VAL_INT_PLUS_MICRO; - } else { - int mult; + } - mutex_lock(&st->lock); + mutex_lock(&st->lock); - if (chan->output) - mult = !!(st->cached_gp_ctrl & - AD5592R_REG_CTRL_DAC_RANGE); - else - mult = !!(st->cached_gp_ctrl & - AD5592R_REG_CTRL_ADC_RANGE); + if (chan->output) + mult = !!(st->cached_gp_ctrl & + AD5592R_REG_CTRL_DAC_RANGE); + else + mult = !!(st->cached_gp_ctrl & + AD5592R_REG_CTRL_ADC_RANGE); - *val *= ++mult; + mutex_unlock(&st->lock); - *val2 = chan->scan_type.realbits; - ret = IIO_VAL_FRACTIONAL_LOG2; - } - break; + *val *= ++mult; + + *val2 = chan->scan_type.realbits; + + return IIO_VAL_FRACTIONAL_LOG2; case IIO_CHAN_INFO_OFFSET: ret = ad5592r_get_vref(st); @@ -439,15 +439,13 @@ static int ad5592r_read_raw(struct iio_dev *iio_dev, *val = (-34365 * 25) / ret; else *val = (-75365 * 25) / ret; - ret = IIO_VAL_INT; - break; + + mutex_unlock(&st->lock); + + return IIO_VAL_INT; default: return -EINVAL; } - -unlock: - mutex_unlock(&st->lock); - return ret; } static int ad5592r_write_raw_get_fmt(struct iio_dev *indio_dev, @@ -486,7 +484,7 @@ static const struct iio_chan_spec_ext_info ad5592r_ext_info[] = { { .name = "scale_available", .read = ad5592r_show_scale_available, - .shared = true, + .shared = IIO_SHARED_BY_TYPE, }, {}, }; diff --git a/drivers/iio/dac/ad5592r.c b/drivers/iio/dac/ad5592r.c index 49308ad13c4b..41f651500668 100644 --- a/drivers/iio/dac/ad5592r.c +++ b/drivers/iio/dac/ad5592r.c @@ -10,9 +10,8 @@ #include <linux/bitops.h> #include <linux/module.h> -#include <linux/of.h> +#include <linux/mod_devicetable.h> #include <linux/spi/spi.h> -#include <linux/acpi.h> #define AD5592R_GPIO_READBACK_EN BIT(10) #define AD5592R_LDAC_READBACK_EN BIT(6) @@ -157,8 +156,8 @@ MODULE_DEVICE_TABLE(acpi, ad5592r_acpi_match); static struct spi_driver ad5592r_spi_driver = { .driver = { .name = "ad5592r", - .of_match_table = of_match_ptr(ad5592r_of_match), - .acpi_match_table = ACPI_PTR(ad5592r_acpi_match), + .of_match_table = ad5592r_of_match, + .acpi_match_table = ad5592r_acpi_match, }, .probe = ad5592r_spi_probe, .remove = ad5592r_spi_remove, diff --git a/drivers/iio/dac/ad5593r.c b/drivers/iio/dac/ad5593r.c index 1fbe9c019c7f..5b4df36fdc2a 100644 --- a/drivers/iio/dac/ad5593r.c +++ b/drivers/iio/dac/ad5593r.c @@ -11,8 +11,7 @@ #include <linux/bitops.h> #include <linux/i2c.h> #include <linux/module.h> -#include <linux/of.h> -#include <linux/acpi.h> +#include <linux/mod_devicetable.h> #define AD5593R_MODE_CONF (0 << 4) #define AD5593R_MODE_DAC_WRITE (1 << 4) @@ -124,8 +123,8 @@ MODULE_DEVICE_TABLE(acpi, ad5593r_acpi_match); static struct i2c_driver ad5593r_driver = { .driver = { .name = "ad5593r", - .of_match_table = of_match_ptr(ad5593r_of_match), - .acpi_match_table = ACPI_PTR(ad5593r_acpi_match), + .of_match_table = ad5593r_of_match, + .acpi_match_table = ad5593r_acpi_match, }, .probe = ad5593r_i2c_probe, .remove = ad5593r_i2c_remove, diff --git a/drivers/iio/dac/ad5686.c b/drivers/iio/dac/ad5686.c index 56cf9344d187..148d9541f517 100644 --- a/drivers/iio/dac/ad5686.c +++ b/drivers/iio/dac/ad5686.c @@ -206,12 +206,12 @@ static const struct iio_chan_spec_ext_info ad5686_ext_info[] = { } #define DECLARE_AD5693_CHANNELS(name, bits, _shift) \ -static struct iio_chan_spec name[] = { \ +static const struct iio_chan_spec name[] = { \ AD5868_CHANNEL(0, 0, bits, _shift), \ } #define DECLARE_AD5686_CHANNELS(name, bits, _shift) \ -static struct iio_chan_spec name[] = { \ +static const struct iio_chan_spec name[] = { \ AD5868_CHANNEL(0, 1, bits, _shift), \ AD5868_CHANNEL(1, 2, bits, _shift), \ AD5868_CHANNEL(2, 4, bits, _shift), \ @@ -219,7 +219,7 @@ static struct iio_chan_spec name[] = { \ } #define DECLARE_AD5676_CHANNELS(name, bits, _shift) \ -static struct iio_chan_spec name[] = { \ +static const struct iio_chan_spec name[] = { \ AD5868_CHANNEL(0, 0, bits, _shift), \ AD5868_CHANNEL(1, 1, bits, _shift), \ AD5868_CHANNEL(2, 2, bits, _shift), \ @@ -231,7 +231,7 @@ static struct iio_chan_spec name[] = { \ } #define DECLARE_AD5679_CHANNELS(name, bits, _shift) \ -static struct iio_chan_spec name[] = { \ +static const struct iio_chan_spec name[] = { \ AD5868_CHANNEL(0, 0, bits, _shift), \ AD5868_CHANNEL(1, 1, bits, _shift), \ AD5868_CHANNEL(2, 2, bits, _shift), \ diff --git a/drivers/iio/dac/ad5686.h b/drivers/iio/dac/ad5686.h index 52009b5eef88..a15f2970577e 100644 --- a/drivers/iio/dac/ad5686.h +++ b/drivers/iio/dac/ad5686.h @@ -104,7 +104,7 @@ typedef int (*ad5686_read_func)(struct ad5686_state *st, u8 addr); struct ad5686_chip_info { u16 int_vref_mv; unsigned int num_channels; - struct iio_chan_spec *channels; + const struct iio_chan_spec *channels; enum ad5686_regmap_type regmap_type; }; diff --git a/drivers/iio/dac/ad7303.c b/drivers/iio/dac/ad7303.c index 4460aa57a33f..2e46def9d8ee 100644 --- a/drivers/iio/dac/ad7303.c +++ b/drivers/iio/dac/ad7303.c @@ -7,6 +7,7 @@ #include <linux/err.h> #include <linux/module.h> +#include <linux/mod_devicetable.h> #include <linux/kernel.h> #include <linux/spi/spi.h> #include <linux/slab.h> @@ -29,6 +30,9 @@ * @spi: the device for this driver instance * @config: cached config register value * @dac_cache: current DAC raw value (chip does not support readback) + * @vdd_reg: reference to VDD regulator + * @vref_reg: reference to VREF regulator + * @lock: protect writes and cache updates * @data: spi transfer buffer */ @@ -287,7 +291,7 @@ MODULE_DEVICE_TABLE(spi, ad7303_spi_ids); static struct spi_driver ad7303_driver = { .driver = { .name = "ad7303", - .of_match_table = of_match_ptr(ad7303_spi_of_match), + .of_match_table = ad7303_spi_of_match, }, .probe = ad7303_probe, .remove = ad7303_remove, diff --git a/drivers/iio/dac/dpot-dac.c b/drivers/iio/dac/dpot-dac.c index 1a9609eda5c5..5d1819448102 100644 --- a/drivers/iio/dac/dpot-dac.c +++ b/drivers/iio/dac/dpot-dac.c @@ -184,18 +184,14 @@ static int dpot_dac_probe(struct platform_device *pdev) indio_dev->num_channels = 1; dac->vref = devm_regulator_get(dev, "vref"); - if (IS_ERR(dac->vref)) { - if (PTR_ERR(dac->vref) != -EPROBE_DEFER) - dev_err(&pdev->dev, "failed to get vref regulator\n"); - return PTR_ERR(dac->vref); - } + if (IS_ERR(dac->vref)) + return dev_err_probe(&pdev->dev, PTR_ERR(dac->vref), + "failed to get vref regulator\n"); dac->dpot = devm_iio_channel_get(dev, "dpot"); - if (IS_ERR(dac->dpot)) { - if (PTR_ERR(dac->dpot) != -EPROBE_DEFER) - dev_err(dev, "failed to get dpot input channel\n"); - return PTR_ERR(dac->dpot); - } + if (IS_ERR(dac->dpot)) + return dev_err_probe(&pdev->dev, PTR_ERR(dac->dpot), + "failed to get dpot input channel\n"); ret = iio_get_channel_type(dac->dpot, &type); if (ret < 0) diff --git a/drivers/iio/dac/mcp4725.c b/drivers/iio/dac/mcp4725.c index ee174d224110..beb9a15b7c74 100644 --- a/drivers/iio/dac/mcp4725.c +++ b/drivers/iio/dac/mcp4725.c @@ -16,8 +16,8 @@ #include <linux/err.h> #include <linux/delay.h> #include <linux/regulator/consumer.h> -#include <linux/of_device.h> -#include <linux/of.h> +#include <linux/mod_devicetable.h> +#include <linux/property.h> #include <linux/iio/iio.h> #include <linux/iio/sysfs.h> @@ -357,29 +357,16 @@ static const struct iio_info mcp4725_info = { .attrs = &mcp4725_attribute_group, }; -#ifdef CONFIG_OF static int mcp4725_probe_dt(struct device *dev, struct mcp4725_platform_data *pdata) { - struct device_node *np = dev->of_node; - - if (!np) - return -ENODEV; - /* check if is the vref-supply defined */ - pdata->use_vref = of_property_read_bool(np, "vref-supply"); + pdata->use_vref = device_property_read_bool(dev, "vref-supply"); pdata->vref_buffered = - of_property_read_bool(np, "microchip,vref-buffered"); + device_property_read_bool(dev, "microchip,vref-buffered"); return 0; } -#else -static int mcp4725_probe_dt(struct device *dev, - struct mcp4725_platform_data *platform_data) -{ - return -ENODEV; -} -#endif static int mcp4725_probe(struct i2c_client *client, const struct i2c_device_id *id) @@ -398,8 +385,8 @@ static int mcp4725_probe(struct i2c_client *client, data = iio_priv(indio_dev); i2c_set_clientdata(client, indio_dev); data->client = client; - if (client->dev.of_node) - data->id = (enum chip_id)of_device_get_match_data(&client->dev); + if (dev_fwnode(&client->dev)) + data->id = (enum chip_id)device_get_match_data(&client->dev); else data->id = id->driver_data; pdata = dev_get_platdata(&client->dev); @@ -519,7 +506,6 @@ static const struct i2c_device_id mcp4725_id[] = { }; MODULE_DEVICE_TABLE(i2c, mcp4725_id); -#ifdef CONFIG_OF static const struct of_device_id mcp4725_of_match[] = { { .compatible = "microchip,mcp4725", @@ -532,12 +518,11 @@ static const struct of_device_id mcp4725_of_match[] = { { } }; MODULE_DEVICE_TABLE(of, mcp4725_of_match); -#endif static struct i2c_driver mcp4725_driver = { .driver = { .name = MCP4725_DRV_NAME, - .of_match_table = of_match_ptr(mcp4725_of_match), + .of_match_table = mcp4725_of_match, .pm = &mcp4725_pm_ops, }, .probe = mcp4725_probe, diff --git a/drivers/iio/dac/stm32-dac-core.c b/drivers/iio/dac/stm32-dac-core.c index 7e5809ba0dee..906436780347 100644 --- a/drivers/iio/dac/stm32-dac-core.c +++ b/drivers/iio/dac/stm32-dac-core.c @@ -150,10 +150,7 @@ static int stm32_dac_probe(struct platform_device *pdev) rst = devm_reset_control_get_optional_exclusive(dev, NULL); if (rst) { if (IS_ERR(rst)) { - ret = PTR_ERR(rst); - if (ret != -EPROBE_DEFER) - dev_err(dev, "reset get failed, %d\n", ret); - + ret = dev_err_probe(dev, PTR_ERR(rst), "reset get failed\n"); goto err_hw_stop; } diff --git a/drivers/iio/dac/stm32-dac.c b/drivers/iio/dac/stm32-dac.c index 092c796fa3d9..12dec68c16f7 100644 --- a/drivers/iio/dac/stm32-dac.c +++ b/drivers/iio/dac/stm32-dac.c @@ -26,9 +26,12 @@ /** * struct stm32_dac - private data of DAC driver * @common: reference to DAC common data + * @lock: lock to protect against potential races when reading + * and update CR, to keep it in sync with pm_runtime */ struct stm32_dac { struct stm32_dac_common *common; + struct mutex lock; }; static int stm32_dac_is_enabled(struct iio_dev *indio_dev, int channel) @@ -58,10 +61,10 @@ static int stm32_dac_set_enable_state(struct iio_dev *indio_dev, int ch, int ret; /* already enabled / disabled ? */ - mutex_lock(&indio_dev->mlock); + mutex_lock(&dac->lock); ret = stm32_dac_is_enabled(indio_dev, ch); if (ret < 0 || enable == !!ret) { - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&dac->lock); return ret < 0 ? ret : 0; } @@ -69,13 +72,13 @@ static int stm32_dac_set_enable_state(struct iio_dev *indio_dev, int ch, ret = pm_runtime_get_sync(dev); if (ret < 0) { pm_runtime_put_noidle(dev); - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&dac->lock); return ret; } } ret = regmap_update_bits(dac->common->regmap, STM32_DAC_CR, msk, en); - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&dac->lock); if (ret < 0) { dev_err(&indio_dev->dev, "%s failed\n", en ? "Enable" : "Disable"); @@ -327,6 +330,8 @@ static int stm32_dac_probe(struct platform_device *pdev) indio_dev->info = &stm32_dac_iio_info; indio_dev->modes = INDIO_DIRECT_MODE; + mutex_init(&dac->lock); + ret = stm32_dac_chan_of_init(indio_dev); if (ret < 0) return ret; diff --git a/drivers/iio/dac/ti-dac082s085.c b/drivers/iio/dac/ti-dac082s085.c index 86bfb1c3f9b9..de33c1fc6e0b 100644 --- a/drivers/iio/dac/ti-dac082s085.c +++ b/drivers/iio/dac/ti-dac082s085.c @@ -14,6 +14,7 @@ #include <linux/iio/iio.h> #include <linux/module.h> +#include <linux/mod_devicetable.h> #include <linux/regulator/consumer.h> #include <linux/spi/spi.h> @@ -324,7 +325,6 @@ static int ti_dac_remove(struct spi_device *spi) return 0; } -#ifdef CONFIG_OF static const struct of_device_id ti_dac_of_id[] = { { .compatible = "ti,dac082s085" }, { .compatible = "ti,dac102s085" }, @@ -335,7 +335,6 @@ static const struct of_device_id ti_dac_of_id[] = { { } }; MODULE_DEVICE_TABLE(of, ti_dac_of_id); -#endif static const struct spi_device_id ti_dac_spi_id[] = { { "dac082s085", dual_8bit }, @@ -351,7 +350,7 @@ MODULE_DEVICE_TABLE(spi, ti_dac_spi_id); static struct spi_driver ti_dac_driver = { .driver = { .name = "ti-dac082s085", - .of_match_table = of_match_ptr(ti_dac_of_id), + .of_match_table = ti_dac_of_id, }, .probe = ti_dac_probe, .remove = ti_dac_remove, diff --git a/drivers/iio/dac/ti-dac5571.c b/drivers/iio/dac/ti-dac5571.c index 00fc7db8eb65..d3295767a079 100644 --- a/drivers/iio/dac/ti-dac5571.c +++ b/drivers/iio/dac/ti-dac5571.c @@ -18,8 +18,7 @@ #include <linux/iio/iio.h> #include <linux/i2c.h> #include <linux/module.h> -#include <linux/of_device.h> -#include <linux/of.h> +#include <linux/mod_devicetable.h> #include <linux/regulator/consumer.h> enum chip_id { @@ -47,8 +46,8 @@ struct dac5571_data { struct mutex lock; struct regulator *vref; u16 val[4]; - bool powerdown; - u8 powerdown_mode; + bool powerdown[4]; + u8 powerdown_mode[4]; struct dac5571_spec const *spec; int (*dac5571_cmd)(struct dac5571_data *data, int channel, u16 val); int (*dac5571_pwrdwn)(struct dac5571_data *data, int channel, u8 pwrdwn); @@ -125,7 +124,7 @@ static int dac5571_get_powerdown_mode(struct iio_dev *indio_dev, { struct dac5571_data *data = iio_priv(indio_dev); - return data->powerdown_mode; + return data->powerdown_mode[chan->channel]; } static int dac5571_set_powerdown_mode(struct iio_dev *indio_dev, @@ -135,17 +134,17 @@ static int dac5571_set_powerdown_mode(struct iio_dev *indio_dev, struct dac5571_data *data = iio_priv(indio_dev); int ret = 0; - if (data->powerdown_mode == mode) + if (data->powerdown_mode[chan->channel] == mode) return 0; mutex_lock(&data->lock); - if (data->powerdown) { + if (data->powerdown[chan->channel]) { ret = data->dac5571_pwrdwn(data, chan->channel, DAC5571_POWERDOWN(mode)); if (ret) goto out; } - data->powerdown_mode = mode; + data->powerdown_mode[chan->channel] = mode; out: mutex_unlock(&data->lock); @@ -167,7 +166,7 @@ static ssize_t dac5571_read_powerdown(struct iio_dev *indio_dev, { struct dac5571_data *data = iio_priv(indio_dev); - return sprintf(buf, "%d\n", data->powerdown); + return sprintf(buf, "%d\n", data->powerdown[chan->channel]); } static ssize_t dac5571_write_powerdown(struct iio_dev *indio_dev, @@ -183,19 +182,20 @@ static ssize_t dac5571_write_powerdown(struct iio_dev *indio_dev, if (ret) return ret; - if (data->powerdown == powerdown) + if (data->powerdown[chan->channel] == powerdown) return len; mutex_lock(&data->lock); if (powerdown) ret = data->dac5571_pwrdwn(data, chan->channel, - DAC5571_POWERDOWN(data->powerdown_mode)); + DAC5571_POWERDOWN(data->powerdown_mode[chan->channel])); else - ret = data->dac5571_cmd(data, chan->channel, data->val[0]); + ret = data->dac5571_cmd(data, chan->channel, + data->val[chan->channel]); if (ret) goto out; - data->powerdown = powerdown; + data->powerdown[chan->channel] = powerdown; out: mutex_unlock(&data->lock); @@ -209,9 +209,9 @@ static const struct iio_chan_spec_ext_info dac5571_ext_info[] = { .name = "powerdown", .read = dac5571_read_powerdown, .write = dac5571_write_powerdown, - .shared = IIO_SHARED_BY_TYPE, + .shared = IIO_SEPARATE, }, - IIO_ENUM("powerdown_mode", IIO_SHARED_BY_TYPE, &dac5571_powerdown_mode), + IIO_ENUM("powerdown_mode", IIO_SEPARATE, &dac5571_powerdown_mode), IIO_ENUM_AVAILABLE("powerdown_mode", &dac5571_powerdown_mode), {}, }; @@ -276,7 +276,7 @@ static int dac5571_write_raw(struct iio_dev *indio_dev, if (val >= (1 << data->spec->resolution) || val < 0) return -EINVAL; - if (data->powerdown) + if (data->powerdown[chan->channel]) return -EBUSY; mutex_lock(&data->lock); @@ -383,7 +383,6 @@ static int dac5571_remove(struct i2c_client *i2c) return 0; } -#ifdef CONFIG_OF static const struct of_device_id dac5571_of_id[] = { {.compatible = "ti,dac5571"}, {.compatible = "ti,dac6571"}, @@ -397,7 +396,6 @@ static const struct of_device_id dac5571_of_id[] = { {} }; MODULE_DEVICE_TABLE(of, dac5571_of_id); -#endif static const struct i2c_device_id dac5571_id[] = { {"dac5571", single_8bit}, @@ -416,7 +414,7 @@ MODULE_DEVICE_TABLE(i2c, dac5571_id); static struct i2c_driver dac5571_driver = { .driver = { .name = "ti-dac5571", - .of_match_table = of_match_ptr(dac5571_of_id), + .of_match_table = dac5571_of_id, }, .probe = dac5571_probe, .remove = dac5571_remove, diff --git a/drivers/iio/dac/ti-dac7612.c b/drivers/iio/dac/ti-dac7612.c index 07c9f39d54f1..4c0f4b5e9ff4 100644 --- a/drivers/iio/dac/ti-dac7612.c +++ b/drivers/iio/dac/ti-dac7612.c @@ -23,6 +23,14 @@ struct dac7612 { uint16_t cache[2]; /* + * Lock to protect the state of the device from potential concurrent + * write accesses from userspace. The write operation requires an + * SPI write, then toggling of a GPIO, so the lock aims to protect + * the sanity of the entire sequence of operation. + */ + struct mutex lock; + + /* * DMA (thus cache coherency maintenance) requires the * transfer buffers to live in their own cache lines. */ @@ -101,9 +109,9 @@ static int dac7612_write_raw(struct iio_dev *iio_dev, if (val == priv->cache[chan->channel]) return 0; - mutex_lock(&iio_dev->mlock); + mutex_lock(&priv->lock); ret = dac7612_cmd_single(priv, chan->channel, val); - mutex_unlock(&iio_dev->mlock); + mutex_unlock(&priv->lock); return ret; } @@ -145,6 +153,8 @@ static int dac7612_probe(struct spi_device *spi) iio_dev->num_channels = ARRAY_SIZE(priv->cache); iio_dev->name = spi_get_device_id(spi)->name; + mutex_init(&priv->lock); + for (i = 0; i < ARRAY_SIZE(priv->cache); i++) { ret = dac7612_cmd_single(priv, i, 0); if (ret) diff --git a/drivers/iio/dummy/iio_dummy_evgen.c b/drivers/iio/dummy/iio_dummy_evgen.c index ee85d596e528..5a0072727ba4 100644 --- a/drivers/iio/dummy/iio_dummy_evgen.c +++ b/drivers/iio/dummy/iio_dummy_evgen.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/** +/* * Copyright (c) 2011 Jonathan Cameron * * Companion module to the iio simple dummy example driver. @@ -27,11 +27,13 @@ #define IIO_EVENTGEN_NO 10 /** + * struct iio_dummy_eventgen - event generator specific state * @regs: irq regs we are faking * @lock: protect the evgen state * @inuse: mask of which irqs are connected * @irq_sim: interrupt simulator * @base: base of irq range + * @irq_sim_domain: irq simulator domain */ struct iio_dummy_eventgen { struct iio_dummy_regs regs[IIO_EVENTGEN_NO]; diff --git a/drivers/iio/frequency/ad9523.c b/drivers/iio/frequency/ad9523.c index 334e1d779d6d..bdb0bc3b12dd 100644 --- a/drivers/iio/frequency/ad9523.c +++ b/drivers/iio/frequency/ad9523.c @@ -969,6 +969,13 @@ static int ad9523_setup(struct iio_dev *indio_dev) return 0; } +static void ad9523_reg_disable(void *data) +{ + struct regulator *reg = data; + + regulator_disable(reg); +} + static int ad9523_probe(struct spi_device *spi) { struct ad9523_platform_data *pdata = spi->dev.platform_data; @@ -994,21 +1001,22 @@ static int ad9523_probe(struct spi_device *spi) ret = regulator_enable(st->reg); if (ret) return ret; + + ret = devm_add_action_or_reset(&spi->dev, ad9523_reg_disable, + st->reg); + if (ret) + return ret; } st->pwrdown_gpio = devm_gpiod_get_optional(&spi->dev, "powerdown", GPIOD_OUT_HIGH); - if (IS_ERR(st->pwrdown_gpio)) { - ret = PTR_ERR(st->pwrdown_gpio); - goto error_disable_reg; - } + if (IS_ERR(st->pwrdown_gpio)) + return PTR_ERR(st->pwrdown_gpio); st->reset_gpio = devm_gpiod_get_optional(&spi->dev, "reset", GPIOD_OUT_LOW); - if (IS_ERR(st->reset_gpio)) { - ret = PTR_ERR(st->reset_gpio); - goto error_disable_reg; - } + if (IS_ERR(st->reset_gpio)) + return PTR_ERR(st->reset_gpio); if (st->reset_gpio) { udelay(1); @@ -1017,10 +1025,8 @@ static int ad9523_probe(struct spi_device *spi) st->sync_gpio = devm_gpiod_get_optional(&spi->dev, "sync", GPIOD_OUT_HIGH); - if (IS_ERR(st->sync_gpio)) { - ret = PTR_ERR(st->sync_gpio); - goto error_disable_reg; - } + if (IS_ERR(st->sync_gpio)) + return PTR_ERR(st->sync_gpio); spi_set_drvdata(spi, indio_dev); st->spi = spi; @@ -1035,34 +1041,9 @@ static int ad9523_probe(struct spi_device *spi) ret = ad9523_setup(indio_dev); if (ret < 0) - goto error_disable_reg; - - ret = iio_device_register(indio_dev); - if (ret) - goto error_disable_reg; - - dev_info(&spi->dev, "probed %s\n", indio_dev->name); - - return 0; - -error_disable_reg: - if (!IS_ERR(st->reg)) - regulator_disable(st->reg); - - return ret; -} - -static int ad9523_remove(struct spi_device *spi) -{ - struct iio_dev *indio_dev = spi_get_drvdata(spi); - struct ad9523_state *st = iio_priv(indio_dev); - - iio_device_unregister(indio_dev); - - if (!IS_ERR(st->reg)) - regulator_disable(st->reg); + return ret; - return 0; + return devm_iio_device_register(&spi->dev, indio_dev); } static const struct spi_device_id ad9523_id[] = { @@ -1076,7 +1057,6 @@ static struct spi_driver ad9523_driver = { .name = "ad9523", }, .probe = ad9523_probe, - .remove = ad9523_remove, .id_table = ad9523_id, }; module_spi_driver(ad9523_driver); diff --git a/drivers/iio/frequency/adf4350.c b/drivers/iio/frequency/adf4350.c index 409c9c47161e..82c050a3899d 100644 --- a/drivers/iio/frequency/adf4350.c +++ b/drivers/iio/frequency/adf4350.c @@ -48,6 +48,13 @@ struct adf4350_state { unsigned long regs_hw[6]; unsigned long long freq_req; /* + * Lock to protect the state of the device from potential concurrent + * writes. The device is configured via a sequence of SPI writes, + * and this lock is meant to prevent the start of another sequence + * before another one has finished. + */ + struct mutex lock; + /* * DMA (thus cache coherency maintenance) requires the * transfer buffers to live in their own cache lines. */ @@ -99,7 +106,7 @@ static int adf4350_reg_access(struct iio_dev *indio_dev, if (reg > ADF4350_REG5) return -EINVAL; - mutex_lock(&indio_dev->mlock); + mutex_lock(&st->lock); if (readval == NULL) { st->regs[reg] = writeval & ~(BIT(0) | BIT(1) | BIT(2)); ret = adf4350_sync_config(st); @@ -107,7 +114,7 @@ static int adf4350_reg_access(struct iio_dev *indio_dev, *readval = st->regs_hw[reg]; ret = 0; } - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&st->lock); return ret; } @@ -254,7 +261,7 @@ static ssize_t adf4350_write(struct iio_dev *indio_dev, if (ret) return ret; - mutex_lock(&indio_dev->mlock); + mutex_lock(&st->lock); switch ((u32)private) { case ADF4350_FREQ: ret = adf4350_set_freq(st, readin); @@ -295,7 +302,7 @@ static ssize_t adf4350_write(struct iio_dev *indio_dev, default: ret = -EINVAL; } - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&st->lock); return ret ? ret : len; } @@ -309,7 +316,7 @@ static ssize_t adf4350_read(struct iio_dev *indio_dev, unsigned long long val; int ret = 0; - mutex_lock(&indio_dev->mlock); + mutex_lock(&st->lock); switch ((u32)private) { case ADF4350_FREQ: val = (u64)((st->r0_int * st->r1_mod) + st->r0_fract) * @@ -338,7 +345,7 @@ static ssize_t adf4350_read(struct iio_dev *indio_dev, ret = -EINVAL; val = 0; } - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&st->lock); return ret < 0 ? ret : sprintf(buf, "%llu\n", val); } @@ -539,6 +546,8 @@ static int adf4350_probe(struct spi_device *spi) indio_dev->channels = &adf4350_chan; indio_dev->num_channels = 1; + mutex_init(&st->lock); + st->chspc = pdata->channel_spacing; if (clk) { st->clk = clk; diff --git a/drivers/iio/gyro/Kconfig b/drivers/iio/gyro/Kconfig index 6daeddf37f60..5824f2edf975 100644 --- a/drivers/iio/gyro/Kconfig +++ b/drivers/iio/gyro/Kconfig @@ -41,6 +41,18 @@ config ADIS16260 This driver can also be built as a module. If so, the module will be called adis16260. +config ADXRS290 + tristate "Analog Devices ADXRS290 Dual-Axis MEMS Gyroscope SPI driver" + depends on SPI + select IIO_BUFFER + select IIO_TRIGGERED_BUFFER + help + Say yes here to build support for Analog Devices ADXRS290 programmable + digital output gyroscope. + + This driver can also be built as a module. If so, the module will be + called adxrs290. + config ADXRS450 tristate "Analog Devices ADXRS450/3 Digital Output Gyroscope SPI driver" depends on SPI diff --git a/drivers/iio/gyro/Makefile b/drivers/iio/gyro/Makefile index 45cbd5dc644e..0319b397dc3f 100644 --- a/drivers/iio/gyro/Makefile +++ b/drivers/iio/gyro/Makefile @@ -8,6 +8,7 @@ obj-$(CONFIG_ADIS16080) += adis16080.o obj-$(CONFIG_ADIS16130) += adis16130.o obj-$(CONFIG_ADIS16136) += adis16136.o obj-$(CONFIG_ADIS16260) += adis16260.o +obj-$(CONFIG_ADXRS290) += adxrs290.o obj-$(CONFIG_ADXRS450) += adxrs450.o obj-$(CONFIG_BMG160) += bmg160_core.o obj-$(CONFIG_BMG160_I2C) += bmg160_i2c.o diff --git a/drivers/iio/gyro/adis16080.c b/drivers/iio/gyro/adis16080.c index 6e5e2d98943c..e2f4d943e220 100644 --- a/drivers/iio/gyro/adis16080.c +++ b/drivers/iio/gyro/adis16080.c @@ -38,7 +38,7 @@ struct adis16080_chip_info { * @us: actual spi_device to write data * @info: chip specific parameters * @buf: transmit or receive buffer - * @lock lock to protect buffer during reads + * @lock: lock to protect buffer during reads **/ struct adis16080_state { struct spi_device *us; diff --git a/drivers/iio/gyro/adis16136.c b/drivers/iio/gyro/adis16136.c index d8a96f6bbae2..a11ae9db0d11 100644 --- a/drivers/iio/gyro/adis16136.c +++ b/drivers/iio/gyro/adis16136.c @@ -523,6 +523,11 @@ static const struct adis16136_chip_info adis16136_chip_info[] = { }, }; +static void adis16136_stop(void *data) +{ + adis16136_stop_device(data); +} + static int adis16136_probe(struct spi_device *spi) { const struct spi_device_id *id = spi_get_device_id(spi); @@ -552,38 +557,23 @@ static int adis16136_probe(struct spi_device *spi) if (ret) return ret; - ret = adis_setup_buffer_and_trigger(&adis16136->adis, indio_dev, NULL); + ret = devm_adis_setup_buffer_and_trigger(&adis16136->adis, indio_dev, NULL); if (ret) return ret; ret = adis16136_initial_setup(indio_dev); if (ret) - goto error_cleanup_buffer; + return ret; - ret = iio_device_register(indio_dev); + ret = devm_add_action_or_reset(&spi->dev, adis16136_stop, indio_dev); if (ret) - goto error_stop_device; - - adis16136_debugfs_init(indio_dev); - - return 0; - -error_stop_device: - adis16136_stop_device(indio_dev); -error_cleanup_buffer: - adis_cleanup_buffer_and_trigger(&adis16136->adis, indio_dev); - return ret; -} - -static int adis16136_remove(struct spi_device *spi) -{ - struct iio_dev *indio_dev = spi_get_drvdata(spi); - struct adis16136 *adis16136 = iio_priv(indio_dev); + return ret; - iio_device_unregister(indio_dev); - adis16136_stop_device(indio_dev); + ret = devm_iio_device_register(&spi->dev, indio_dev); + if (ret) + return ret; - adis_cleanup_buffer_and_trigger(&adis16136->adis, indio_dev); + adis16136_debugfs_init(indio_dev); return 0; } @@ -603,7 +593,6 @@ static struct spi_driver adis16136_driver = { }, .id_table = adis16136_ids, .probe = adis16136_probe, - .remove = adis16136_remove, }; module_spi_driver(adis16136_driver); diff --git a/drivers/iio/gyro/adis16260.c b/drivers/iio/gyro/adis16260.c index e638d56e1574..e7c9a3e31c45 100644 --- a/drivers/iio/gyro/adis16260.c +++ b/drivers/iio/gyro/adis16260.c @@ -359,6 +359,11 @@ static const struct adis_data adis16260_data = { BIT(ADIS16260_DIAG_STAT_POWER_LOW_BIT), }; +static void adis16260_stop(void *data) +{ + adis16260_stop_device(data); +} + static int adis16260_probe(struct spi_device *spi) { const struct spi_device_id *id; @@ -390,35 +395,20 @@ static int adis16260_probe(struct spi_device *spi) if (ret) return ret; - ret = adis_setup_buffer_and_trigger(&adis16260->adis, indio_dev, NULL); + ret = devm_adis_setup_buffer_and_trigger(&adis16260->adis, indio_dev, NULL); if (ret) return ret; /* Get the device into a sane initial state */ ret = adis_initial_startup(&adis16260->adis); if (ret) - goto error_cleanup_buffer_trigger; - ret = iio_device_register(indio_dev); - if (ret) - goto error_cleanup_buffer_trigger; - - return 0; - -error_cleanup_buffer_trigger: - adis_cleanup_buffer_and_trigger(&adis16260->adis, indio_dev); - return ret; -} - -static int adis16260_remove(struct spi_device *spi) -{ - struct iio_dev *indio_dev = spi_get_drvdata(spi); - struct adis16260 *adis16260 = iio_priv(indio_dev); + return ret; - iio_device_unregister(indio_dev); - adis16260_stop_device(indio_dev); - adis_cleanup_buffer_and_trigger(&adis16260->adis, indio_dev); + ret = devm_add_action_or_reset(&spi->dev, adis16260_stop, indio_dev); + if (ret) + return ret; - return 0; + return devm_iio_device_register(&spi->dev, indio_dev); } /* @@ -441,7 +431,6 @@ static struct spi_driver adis16260_driver = { .name = "adis16260", }, .probe = adis16260_probe, - .remove = adis16260_remove, .id_table = adis16260_id, }; module_spi_driver(adis16260_driver); diff --git a/drivers/iio/gyro/adxrs290.c b/drivers/iio/gyro/adxrs290.c new file mode 100644 index 000000000000..ca6fc234076e --- /dev/null +++ b/drivers/iio/gyro/adxrs290.c @@ -0,0 +1,710 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * ADXRS290 SPI Gyroscope Driver + * + * Copyright (C) 2020 Nishant Malpani <nish.malpani25@gmail.com> + * Copyright (C) 2020 Analog Devices, Inc. + */ + +#include <linux/bitfield.h> +#include <linux/delay.h> +#include <linux/device.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/spi/spi.h> + +#include <linux/iio/buffer.h> +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> +#include <linux/iio/trigger.h> +#include <linux/iio/triggered_buffer.h> +#include <linux/iio/trigger_consumer.h> + +#define ADXRS290_ADI_ID 0xAD +#define ADXRS290_MEMS_ID 0x1D +#define ADXRS290_DEV_ID 0x92 + +#define ADXRS290_REG_ADI_ID 0x00 +#define ADXRS290_REG_MEMS_ID 0x01 +#define ADXRS290_REG_DEV_ID 0x02 +#define ADXRS290_REG_REV_ID 0x03 +#define ADXRS290_REG_SN0 0x04 /* Serial Number Registers, 4 bytes */ +#define ADXRS290_REG_DATAX0 0x08 /* Roll Rate o/p Data Regs, 2 bytes */ +#define ADXRS290_REG_DATAY0 0x0A /* Pitch Rate o/p Data Regs, 2 bytes */ +#define ADXRS290_REG_TEMP0 0x0C +#define ADXRS290_REG_POWER_CTL 0x10 +#define ADXRS290_REG_FILTER 0x11 +#define ADXRS290_REG_DATA_RDY 0x12 + +#define ADXRS290_READ BIT(7) +#define ADXRS290_TSM BIT(0) +#define ADXRS290_MEASUREMENT BIT(1) +#define ADXRS290_DATA_RDY_OUT BIT(0) +#define ADXRS290_SYNC_MASK GENMASK(1, 0) +#define ADXRS290_SYNC(x) FIELD_PREP(ADXRS290_SYNC_MASK, x) +#define ADXRS290_LPF_MASK GENMASK(2, 0) +#define ADXRS290_LPF(x) FIELD_PREP(ADXRS290_LPF_MASK, x) +#define ADXRS290_HPF_MASK GENMASK(7, 4) +#define ADXRS290_HPF(x) FIELD_PREP(ADXRS290_HPF_MASK, x) + +#define ADXRS290_READ_REG(reg) (ADXRS290_READ | (reg)) + +#define ADXRS290_MAX_TRANSITION_TIME_MS 100 + +enum adxrs290_mode { + ADXRS290_MODE_STANDBY, + ADXRS290_MODE_MEASUREMENT, +}; + +enum adxrs290_scan_index { + ADXRS290_IDX_X, + ADXRS290_IDX_Y, + ADXRS290_IDX_TEMP, + ADXRS290_IDX_TS, +}; + +struct adxrs290_state { + struct spi_device *spi; + /* Serialize reads and their subsequent processing */ + struct mutex lock; + enum adxrs290_mode mode; + unsigned int lpf_3db_freq_idx; + unsigned int hpf_3db_freq_idx; + struct iio_trigger *dready_trig; + /* Ensure correct alignment of timestamp when present */ + struct { + s16 channels[3]; + s64 ts __aligned(8); + } buffer; +}; + +/* + * Available cut-off frequencies of the low pass filter in Hz. + * The integer part and fractional part are represented separately. + */ +static const int adxrs290_lpf_3db_freq_hz_table[][2] = { + [0] = {480, 0}, + [1] = {320, 0}, + [2] = {160, 0}, + [3] = {80, 0}, + [4] = {56, 600000}, + [5] = {40, 0}, + [6] = {28, 300000}, + [7] = {20, 0}, +}; + +/* + * Available cut-off frequencies of the high pass filter in Hz. + * The integer part and fractional part are represented separately. + */ +static const int adxrs290_hpf_3db_freq_hz_table[][2] = { + [0] = {0, 0}, + [1] = {0, 11000}, + [2] = {0, 22000}, + [3] = {0, 44000}, + [4] = {0, 87000}, + [5] = {0, 175000}, + [6] = {0, 350000}, + [7] = {0, 700000}, + [8] = {1, 400000}, + [9] = {2, 800000}, + [10] = {11, 300000}, +}; + +static int adxrs290_get_rate_data(struct iio_dev *indio_dev, const u8 cmd, int *val) +{ + struct adxrs290_state *st = iio_priv(indio_dev); + int ret = 0; + int temp; + + mutex_lock(&st->lock); + temp = spi_w8r16(st->spi, cmd); + if (temp < 0) { + ret = temp; + goto err_unlock; + } + + *val = temp; + +err_unlock: + mutex_unlock(&st->lock); + return ret; +} + +static int adxrs290_get_temp_data(struct iio_dev *indio_dev, int *val) +{ + const u8 cmd = ADXRS290_READ_REG(ADXRS290_REG_TEMP0); + struct adxrs290_state *st = iio_priv(indio_dev); + int ret = 0; + int temp; + + mutex_lock(&st->lock); + temp = spi_w8r16(st->spi, cmd); + if (temp < 0) { + ret = temp; + goto err_unlock; + } + + /* extract lower 12 bits temperature reading */ + *val = temp & 0x0FFF; + +err_unlock: + mutex_unlock(&st->lock); + return ret; +} + +static int adxrs290_get_3db_freq(struct iio_dev *indio_dev, u8 *val, u8 *val2) +{ + const u8 cmd = ADXRS290_READ_REG(ADXRS290_REG_FILTER); + struct adxrs290_state *st = iio_priv(indio_dev); + int ret = 0; + short temp; + + mutex_lock(&st->lock); + temp = spi_w8r8(st->spi, cmd); + if (temp < 0) { + ret = temp; + goto err_unlock; + } + + *val = FIELD_GET(ADXRS290_LPF_MASK, temp); + *val2 = FIELD_GET(ADXRS290_HPF_MASK, temp); + +err_unlock: + mutex_unlock(&st->lock); + return ret; +} + +static int adxrs290_spi_write_reg(struct spi_device *spi, const u8 reg, + const u8 val) +{ + u8 buf[2]; + + buf[0] = reg; + buf[1] = val; + + return spi_write_then_read(spi, buf, ARRAY_SIZE(buf), NULL, 0); +} + +static int adxrs290_find_match(const int (*freq_tbl)[2], const int n, + const int val, const int val2) +{ + int i; + + for (i = 0; i < n; i++) { + if (freq_tbl[i][0] == val && freq_tbl[i][1] == val2) + return i; + } + + return -EINVAL; +} + +static int adxrs290_set_filter_freq(struct iio_dev *indio_dev, + const unsigned int lpf_idx, + const unsigned int hpf_idx) +{ + struct adxrs290_state *st = iio_priv(indio_dev); + u8 val; + + val = ADXRS290_HPF(hpf_idx) | ADXRS290_LPF(lpf_idx); + + return adxrs290_spi_write_reg(st->spi, ADXRS290_REG_FILTER, val); +} + +static int adxrs290_set_mode(struct iio_dev *indio_dev, enum adxrs290_mode mode) +{ + struct adxrs290_state *st = iio_priv(indio_dev); + int val, ret; + + if (st->mode == mode) + return 0; + + mutex_lock(&st->lock); + + ret = spi_w8r8(st->spi, ADXRS290_READ_REG(ADXRS290_REG_POWER_CTL)); + if (ret < 0) + goto out_unlock; + + val = ret; + + switch (mode) { + case ADXRS290_MODE_STANDBY: + val &= ~ADXRS290_MEASUREMENT; + break; + case ADXRS290_MODE_MEASUREMENT: + val |= ADXRS290_MEASUREMENT; + break; + default: + ret = -EINVAL; + goto out_unlock; + } + + ret = adxrs290_spi_write_reg(st->spi, ADXRS290_REG_POWER_CTL, val); + if (ret < 0) { + dev_err(&st->spi->dev, "unable to set mode: %d\n", ret); + goto out_unlock; + } + + /* update cached mode */ + st->mode = mode; + +out_unlock: + mutex_unlock(&st->lock); + return ret; +} + +static void adxrs290_chip_off_action(void *data) +{ + struct iio_dev *indio_dev = data; + + adxrs290_set_mode(indio_dev, ADXRS290_MODE_STANDBY); +} + +static int adxrs290_initial_setup(struct iio_dev *indio_dev) +{ + struct adxrs290_state *st = iio_priv(indio_dev); + struct spi_device *spi = st->spi; + int ret; + + ret = adxrs290_spi_write_reg(spi, ADXRS290_REG_POWER_CTL, + ADXRS290_MEASUREMENT | ADXRS290_TSM); + if (ret < 0) + return ret; + + st->mode = ADXRS290_MODE_MEASUREMENT; + + return devm_add_action_or_reset(&spi->dev, adxrs290_chip_off_action, + indio_dev); +} + +static int adxrs290_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, + int *val2, + long mask) +{ + struct adxrs290_state *st = iio_priv(indio_dev); + unsigned int t; + int ret; + + switch (mask) { + case IIO_CHAN_INFO_RAW: + ret = iio_device_claim_direct_mode(indio_dev); + if (ret) + return ret; + + switch (chan->type) { + case IIO_ANGL_VEL: + ret = adxrs290_get_rate_data(indio_dev, + ADXRS290_READ_REG(chan->address), + val); + if (ret < 0) + break; + + ret = IIO_VAL_INT; + break; + case IIO_TEMP: + ret = adxrs290_get_temp_data(indio_dev, val); + if (ret < 0) + break; + + ret = IIO_VAL_INT; + break; + default: + ret = -EINVAL; + break; + } + + iio_device_release_direct_mode(indio_dev); + return ret; + case IIO_CHAN_INFO_SCALE: + switch (chan->type) { + case IIO_ANGL_VEL: + /* 1 LSB = 0.005 degrees/sec */ + *val = 0; + *val2 = 87266; + return IIO_VAL_INT_PLUS_NANO; + case IIO_TEMP: + /* 1 LSB = 0.1 degrees Celsius */ + *val = 100; + return IIO_VAL_INT; + default: + return -EINVAL; + } + case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: + switch (chan->type) { + case IIO_ANGL_VEL: + t = st->lpf_3db_freq_idx; + *val = adxrs290_lpf_3db_freq_hz_table[t][0]; + *val2 = adxrs290_lpf_3db_freq_hz_table[t][1]; + return IIO_VAL_INT_PLUS_MICRO; + default: + return -EINVAL; + } + case IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY: + switch (chan->type) { + case IIO_ANGL_VEL: + t = st->hpf_3db_freq_idx; + *val = adxrs290_hpf_3db_freq_hz_table[t][0]; + *val2 = adxrs290_hpf_3db_freq_hz_table[t][1]; + return IIO_VAL_INT_PLUS_MICRO; + default: + return -EINVAL; + } + } + + return -EINVAL; +} + +static int adxrs290_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int val, + int val2, + long mask) +{ + struct adxrs290_state *st = iio_priv(indio_dev); + int ret, lpf_idx, hpf_idx; + + ret = iio_device_claim_direct_mode(indio_dev); + if (ret) + return ret; + + switch (mask) { + case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: + lpf_idx = adxrs290_find_match(adxrs290_lpf_3db_freq_hz_table, + ARRAY_SIZE(adxrs290_lpf_3db_freq_hz_table), + val, val2); + if (lpf_idx < 0) { + ret = -EINVAL; + break; + } + + /* caching the updated state of the low-pass filter */ + st->lpf_3db_freq_idx = lpf_idx; + /* retrieving the current state of the high-pass filter */ + hpf_idx = st->hpf_3db_freq_idx; + ret = adxrs290_set_filter_freq(indio_dev, lpf_idx, hpf_idx); + break; + + case IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY: + hpf_idx = adxrs290_find_match(adxrs290_hpf_3db_freq_hz_table, + ARRAY_SIZE(adxrs290_hpf_3db_freq_hz_table), + val, val2); + if (hpf_idx < 0) { + ret = -EINVAL; + break; + } + + /* caching the updated state of the high-pass filter */ + st->hpf_3db_freq_idx = hpf_idx; + /* retrieving the current state of the low-pass filter */ + lpf_idx = st->lpf_3db_freq_idx; + ret = adxrs290_set_filter_freq(indio_dev, lpf_idx, hpf_idx); + break; + + default: + ret = -EINVAL; + break; + } + + iio_device_release_direct_mode(indio_dev); + return ret; +} + +static int adxrs290_read_avail(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + const int **vals, int *type, int *length, + long mask) +{ + switch (mask) { + case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: + *vals = (const int *)adxrs290_lpf_3db_freq_hz_table; + *type = IIO_VAL_INT_PLUS_MICRO; + /* Values are stored in a 2D matrix */ + *length = ARRAY_SIZE(adxrs290_lpf_3db_freq_hz_table) * 2; + + return IIO_AVAIL_LIST; + case IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY: + *vals = (const int *)adxrs290_hpf_3db_freq_hz_table; + *type = IIO_VAL_INT_PLUS_MICRO; + /* Values are stored in a 2D matrix */ + *length = ARRAY_SIZE(adxrs290_hpf_3db_freq_hz_table) * 2; + + return IIO_AVAIL_LIST; + default: + return -EINVAL; + } +} + +static int adxrs290_reg_access_rw(struct spi_device *spi, unsigned int reg, + unsigned int *readval) +{ + int ret; + + ret = spi_w8r8(spi, ADXRS290_READ_REG(reg)); + if (ret < 0) + return ret; + + *readval = ret; + + return 0; +} + +static int adxrs290_reg_access(struct iio_dev *indio_dev, unsigned int reg, + unsigned int writeval, unsigned int *readval) +{ + struct adxrs290_state *st = iio_priv(indio_dev); + + if (readval) + return adxrs290_reg_access_rw(st->spi, reg, readval); + else + return adxrs290_spi_write_reg(st->spi, reg, writeval); +} + +static int adxrs290_data_rdy_trigger_set_state(struct iio_trigger *trig, + bool state) +{ + struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig); + struct adxrs290_state *st = iio_priv(indio_dev); + int ret; + u8 val; + + val = state ? ADXRS290_SYNC(ADXRS290_DATA_RDY_OUT) : 0; + + ret = adxrs290_spi_write_reg(st->spi, ADXRS290_REG_DATA_RDY, val); + if (ret < 0) + dev_err(&st->spi->dev, "failed to start data rdy interrupt\n"); + + return ret; +} + +static int adxrs290_reset_trig(struct iio_trigger *trig) +{ + struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig); + int val; + + /* + * Data ready interrupt is reset after a read of the data registers. + * Here, we only read the 16b DATAY registers as that marks the end of + * a read of the data registers and initiates a reset for the interrupt + * line. + */ + adxrs290_get_rate_data(indio_dev, + ADXRS290_READ_REG(ADXRS290_REG_DATAY0), &val); + + return 0; +} + +static const struct iio_trigger_ops adxrs290_trigger_ops = { + .set_trigger_state = &adxrs290_data_rdy_trigger_set_state, + .validate_device = &iio_trigger_validate_own_device, + .try_reenable = &adxrs290_reset_trig, +}; + +static irqreturn_t adxrs290_trigger_handler(int irq, void *p) +{ + struct iio_poll_func *pf = p; + struct iio_dev *indio_dev = pf->indio_dev; + struct adxrs290_state *st = iio_priv(indio_dev); + u8 tx = ADXRS290_READ_REG(ADXRS290_REG_DATAX0); + int ret; + + mutex_lock(&st->lock); + + /* exercise a bulk data capture starting from reg DATAX0... */ + ret = spi_write_then_read(st->spi, &tx, sizeof(tx), st->buffer.channels, + sizeof(st->buffer.channels)); + if (ret < 0) + goto out_unlock_notify; + + iio_push_to_buffers_with_timestamp(indio_dev, &st->buffer, + pf->timestamp); + +out_unlock_notify: + mutex_unlock(&st->lock); + iio_trigger_notify_done(indio_dev->trig); + + return IRQ_HANDLED; +} + +#define ADXRS290_ANGL_VEL_CHANNEL(reg, axis) { \ + .type = IIO_ANGL_VEL, \ + .address = reg, \ + .modified = 1, \ + .channel2 = IIO_MOD_##axis, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \ + BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY) | \ + BIT(IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY), \ + .info_mask_shared_by_type_available = \ + BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY) | \ + BIT(IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY), \ + .scan_index = ADXRS290_IDX_##axis, \ + .scan_type = { \ + .sign = 's', \ + .realbits = 16, \ + .storagebits = 16, \ + .endianness = IIO_LE, \ + }, \ +} + +static const struct iio_chan_spec adxrs290_channels[] = { + ADXRS290_ANGL_VEL_CHANNEL(ADXRS290_REG_DATAX0, X), + ADXRS290_ANGL_VEL_CHANNEL(ADXRS290_REG_DATAY0, Y), + { + .type = IIO_TEMP, + .address = ADXRS290_REG_TEMP0, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_SCALE), + .scan_index = ADXRS290_IDX_TEMP, + .scan_type = { + .sign = 's', + .realbits = 12, + .storagebits = 16, + .endianness = IIO_LE, + }, + }, + IIO_CHAN_SOFT_TIMESTAMP(ADXRS290_IDX_TS), +}; + +static const unsigned long adxrs290_avail_scan_masks[] = { + BIT(ADXRS290_IDX_X) | BIT(ADXRS290_IDX_Y) | BIT(ADXRS290_IDX_TEMP), + 0 +}; + +static const struct iio_info adxrs290_info = { + .read_raw = &adxrs290_read_raw, + .write_raw = &adxrs290_write_raw, + .read_avail = &adxrs290_read_avail, + .debugfs_reg_access = &adxrs290_reg_access, +}; + +static int adxrs290_probe_trigger(struct iio_dev *indio_dev) +{ + struct adxrs290_state *st = iio_priv(indio_dev); + int ret; + + if (!st->spi->irq) { + dev_info(&st->spi->dev, "no irq, using polling\n"); + return 0; + } + + st->dready_trig = devm_iio_trigger_alloc(&st->spi->dev, "%s-dev%d", + indio_dev->name, + indio_dev->id); + if (!st->dready_trig) + return -ENOMEM; + + st->dready_trig->dev.parent = &st->spi->dev; + st->dready_trig->ops = &adxrs290_trigger_ops; + iio_trigger_set_drvdata(st->dready_trig, indio_dev); + + ret = devm_request_irq(&st->spi->dev, st->spi->irq, + &iio_trigger_generic_data_rdy_poll, + IRQF_ONESHOT, "adxrs290_irq", st->dready_trig); + if (ret < 0) + return dev_err_probe(&st->spi->dev, ret, + "request irq %d failed\n", st->spi->irq); + + ret = devm_iio_trigger_register(&st->spi->dev, st->dready_trig); + if (ret) { + dev_err(&st->spi->dev, "iio trigger register failed\n"); + return ret; + } + + indio_dev->trig = iio_trigger_get(st->dready_trig); + + return 0; +} + +static int adxrs290_probe(struct spi_device *spi) +{ + struct iio_dev *indio_dev; + struct adxrs290_state *st; + u8 val, val2; + int ret; + + indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); + if (!indio_dev) + return -ENOMEM; + + st = iio_priv(indio_dev); + st->spi = spi; + + indio_dev->name = "adxrs290"; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->channels = adxrs290_channels; + indio_dev->num_channels = ARRAY_SIZE(adxrs290_channels); + indio_dev->info = &adxrs290_info; + indio_dev->available_scan_masks = adxrs290_avail_scan_masks; + + mutex_init(&st->lock); + + val = spi_w8r8(spi, ADXRS290_READ_REG(ADXRS290_REG_ADI_ID)); + if (val != ADXRS290_ADI_ID) { + dev_err(&spi->dev, "Wrong ADI ID 0x%02x\n", val); + return -ENODEV; + } + + val = spi_w8r8(spi, ADXRS290_READ_REG(ADXRS290_REG_MEMS_ID)); + if (val != ADXRS290_MEMS_ID) { + dev_err(&spi->dev, "Wrong MEMS ID 0x%02x\n", val); + return -ENODEV; + } + + val = spi_w8r8(spi, ADXRS290_READ_REG(ADXRS290_REG_DEV_ID)); + if (val != ADXRS290_DEV_ID) { + dev_err(&spi->dev, "Wrong DEV ID 0x%02x\n", val); + return -ENODEV; + } + + /* default mode the gyroscope starts in */ + st->mode = ADXRS290_MODE_STANDBY; + + /* switch to measurement mode and switch on the temperature sensor */ + ret = adxrs290_initial_setup(indio_dev); + if (ret < 0) + return ret; + + /* max transition time to measurement mode */ + msleep(ADXRS290_MAX_TRANSITION_TIME_MS); + + ret = adxrs290_get_3db_freq(indio_dev, &val, &val2); + if (ret < 0) + return ret; + + st->lpf_3db_freq_idx = val; + st->hpf_3db_freq_idx = val2; + + ret = devm_iio_triggered_buffer_setup(&spi->dev, indio_dev, + &iio_pollfunc_store_time, + &adxrs290_trigger_handler, NULL); + if (ret < 0) + return dev_err_probe(&spi->dev, ret, + "iio triggered buffer setup failed\n"); + + ret = adxrs290_probe_trigger(indio_dev); + if (ret < 0) + return ret; + + return devm_iio_device_register(&spi->dev, indio_dev); +} + +static const struct of_device_id adxrs290_of_match[] = { + { .compatible = "adi,adxrs290" }, + { } +}; +MODULE_DEVICE_TABLE(of, adxrs290_of_match); + +static struct spi_driver adxrs290_driver = { + .driver = { + .name = "adxrs290", + .of_match_table = adxrs290_of_match, + }, + .probe = adxrs290_probe, +}; +module_spi_driver(adxrs290_driver); + +MODULE_AUTHOR("Nishant Malpani <nish.malpani25@gmail.com>"); +MODULE_DESCRIPTION("Analog Devices ADXRS290 Gyroscope SPI driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/iio/gyro/itg3200_buffer.c b/drivers/iio/gyro/itg3200_buffer.c index d3fbe9d86467..1c3c1bd53374 100644 --- a/drivers/iio/gyro/itg3200_buffer.c +++ b/drivers/iio/gyro/itg3200_buffer.c @@ -46,13 +46,20 @@ static irqreturn_t itg3200_trigger_handler(int irq, void *p) struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf->indio_dev; struct itg3200 *st = iio_priv(indio_dev); - __be16 buf[ITG3200_SCAN_ELEMENTS + sizeof(s64)/sizeof(u16)]; - - int ret = itg3200_read_all_channels(st->i2c, buf); + /* + * Ensure correct alignment and padding including for the + * timestamp that may be inserted. + */ + struct { + __be16 buf[ITG3200_SCAN_ELEMENTS]; + s64 ts __aligned(8); + } scan; + + int ret = itg3200_read_all_channels(st->i2c, scan.buf); if (ret < 0) goto error_ret; - iio_push_to_buffers_with_timestamp(indio_dev, buf, pf->timestamp); + iio_push_to_buffers_with_timestamp(indio_dev, &scan, pf->timestamp); iio_trigger_notify_done(indio_dev->trig); diff --git a/drivers/iio/health/max30102.c b/drivers/iio/health/max30102.c index d9b2ed80882a..b35557a54ee2 100644 --- a/drivers/iio/health/max30102.c +++ b/drivers/iio/health/max30102.c @@ -2,7 +2,7 @@ /* * max30102.c - Support for MAX30102 heart rate and pulse oximeter sensor * - * Copyright (C) 2017 Matt Ranostay <matt@ranostay.consulting> + * Copyright (C) 2017 Matt Ranostay <matt.ranostay@konsulko.com> * * Support for MAX30105 optical particle sensor * Copyright (C) 2017 Peter Meerwald-Stadler <pmeerw@pmeerw.net> @@ -19,7 +19,7 @@ #include <linux/irq.h> #include <linux/i2c.h> #include <linux/mutex.h> -#include <linux/of.h> +#include <linux/mod_devicetable.h> #include <linux/regmap.h> #include <linux/iio/iio.h> #include <linux/iio/buffer.h> @@ -323,11 +323,10 @@ static int max30102_get_current_idx(unsigned int val, int *reg) static int max30102_led_init(struct max30102_data *data) { struct device *dev = &data->client->dev; - struct device_node *np = dev->of_node; unsigned int val; int reg, ret; - ret = of_property_read_u32(np, "maxim,red-led-current-microamp", &val); + ret = device_property_read_u32(dev, "maxim,red-led-current-microamp", &val); if (ret) { dev_info(dev, "no red-led-current-microamp set\n"); @@ -346,7 +345,7 @@ static int max30102_led_init(struct max30102_data *data) return ret; if (data->chip_id == max30105) { - ret = of_property_read_u32(np, + ret = device_property_read_u32(dev, "maxim,green-led-current-microamp", &val); if (ret) { dev_info(dev, "no green-led-current-microamp set\n"); @@ -368,7 +367,7 @@ static int max30102_led_init(struct max30102_data *data) return ret; } - ret = of_property_read_u32(np, "maxim,ir-led-current-microamp", &val); + ret = device_property_read_u32(dev, "maxim,ir-led-current-microamp", &val); if (ret) { dev_info(dev, "no ir-led-current-microamp set\n"); @@ -624,7 +623,7 @@ MODULE_DEVICE_TABLE(of, max30102_dt_ids); static struct i2c_driver max30102_driver = { .driver = { .name = MAX30102_DRV_NAME, - .of_match_table = of_match_ptr(max30102_dt_ids), + .of_match_table = max30102_dt_ids, }, .probe = max30102_probe, .remove = max30102_remove, @@ -632,6 +631,6 @@ static struct i2c_driver max30102_driver = { }; module_i2c_driver(max30102_driver); -MODULE_AUTHOR("Matt Ranostay <matt@ranostay.consulting>"); +MODULE_AUTHOR("Matt Ranostay <matt.ranostay@konsulko.com>"); MODULE_DESCRIPTION("MAX30102 heart rate/pulse oximeter and MAX30105 particle sensor driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/iio/humidity/Kconfig b/drivers/iio/humidity/Kconfig index 6c5507a6cd74..6549fcf6db69 100644 --- a/drivers/iio/humidity/Kconfig +++ b/drivers/iio/humidity/Kconfig @@ -38,6 +38,16 @@ config HDC100X To compile this driver as a module, choose M here: the module will be called hdc100x. +config HDC2010 + tristate "TI HDC2010 relative humidity and temperature sensor" + depends on I2C + help + Say yes here to build support for the Texas Instruments + HDC2010 and HDC2080 relative humidity and temperature sensors. + + To compile this driver as a module, choose M here: the module + will be called hdc2010. + config HID_SENSOR_HUMIDITY tristate "HID Environmental humidity sensor" depends on HID_SENSOR_HUB diff --git a/drivers/iio/humidity/Makefile b/drivers/iio/humidity/Makefile index ae4204995017..f19ff3de97c5 100644 --- a/drivers/iio/humidity/Makefile +++ b/drivers/iio/humidity/Makefile @@ -6,6 +6,7 @@ obj-$(CONFIG_AM2315) += am2315.o obj-$(CONFIG_DHT11) += dht11.o obj-$(CONFIG_HDC100X) += hdc100x.o +obj-$(CONFIG_HDC2010) += hdc2010.o obj-$(CONFIG_HID_SENSOR_HUMIDITY) += hid-sensor-humidity.o hts221-y := hts221_core.o \ diff --git a/drivers/iio/humidity/hdc100x.c b/drivers/iio/humidity/hdc100x.c index 071cb2b12bb6..2a957f19048e 100644 --- a/drivers/iio/humidity/hdc100x.c +++ b/drivers/iio/humidity/hdc100x.c @@ -15,6 +15,7 @@ #include <linux/delay.h> #include <linux/module.h> +#include <linux/mod_devicetable.h> #include <linux/init.h> #include <linux/i2c.h> @@ -417,7 +418,7 @@ MODULE_DEVICE_TABLE(of, hdc100x_dt_ids); static struct i2c_driver hdc100x_driver = { .driver = { .name = "hdc100x", - .of_match_table = of_match_ptr(hdc100x_dt_ids), + .of_match_table = hdc100x_dt_ids, }, .probe = hdc100x_probe, .id_table = hdc100x_id, diff --git a/drivers/iio/humidity/hdc2010.c b/drivers/iio/humidity/hdc2010.c new file mode 100644 index 000000000000..83f5b9f60780 --- /dev/null +++ b/drivers/iio/humidity/hdc2010.c @@ -0,0 +1,353 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * hdc2010.c - Support for the TI HDC2010 and HDC2080 + * temperature + relative humidity sensors + * + * Copyright (C) 2020 Norphonic AS + * Author: Eugene Zaikonnikov <ez@norphonic.com> + * + * Datasheet: https://www.ti.com/product/HDC2010/datasheet + * Datasheet: https://www.ti.com/product/HDC2080/datasheet + */ + +#include <linux/module.h> +#include <linux/init.h> +#include <linux/i2c.h> +#include <linux/bitops.h> + +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> + +#define HDC2010_REG_TEMP_LOW 0x00 +#define HDC2010_REG_TEMP_HIGH 0x01 +#define HDC2010_REG_HUMIDITY_LOW 0x02 +#define HDC2010_REG_HUMIDITY_HIGH 0x03 +#define HDC2010_REG_INTERRUPT_DRDY 0x04 +#define HDC2010_REG_TEMP_MAX 0x05 +#define HDC2010_REG_HUMIDITY_MAX 0x06 +#define HDC2010_REG_INTERRUPT_EN 0x07 +#define HDC2010_REG_TEMP_OFFSET_ADJ 0x08 +#define HDC2010_REG_HUMIDITY_OFFSET_ADJ 0x09 +#define HDC2010_REG_TEMP_THR_L 0x0a +#define HDC2010_REG_TEMP_THR_H 0x0b +#define HDC2010_REG_RH_THR_L 0x0c +#define HDC2010_REG_RH_THR_H 0x0d +#define HDC2010_REG_RESET_DRDY_INT_CONF 0x0e +#define HDC2010_REG_MEASUREMENT_CONF 0x0f + +#define HDC2010_MEAS_CONF GENMASK(2, 1) +#define HDC2010_MEAS_TRIG BIT(0) +#define HDC2010_HEATER_EN BIT(3) +#define HDC2010_AMM GENMASK(6, 4) + +struct hdc2010_data { + struct i2c_client *client; + struct mutex lock; + u8 measurement_config; + u8 interrupt_config; + u8 drdy_config; +}; + +enum hdc2010_addr_groups { + HDC2010_GROUP_TEMP = 0, + HDC2010_GROUP_HUMIDITY, +}; + +struct hdc2010_reg_record { + unsigned long primary; + unsigned long peak; +}; + +static const struct hdc2010_reg_record hdc2010_reg_translation[] = { + [HDC2010_GROUP_TEMP] = { + .primary = HDC2010_REG_TEMP_LOW, + .peak = HDC2010_REG_TEMP_MAX, + }, + [HDC2010_GROUP_HUMIDITY] = { + .primary = HDC2010_REG_HUMIDITY_LOW, + .peak = HDC2010_REG_HUMIDITY_MAX, + }, +}; + +static IIO_CONST_ATTR(out_current_heater_raw_available, "0 1"); + +static struct attribute *hdc2010_attributes[] = { + &iio_const_attr_out_current_heater_raw_available.dev_attr.attr, + NULL +}; + +static const struct attribute_group hdc2010_attribute_group = { + .attrs = hdc2010_attributes, +}; + +static const struct iio_chan_spec hdc2010_channels[] = { + { + .type = IIO_TEMP, + .address = HDC2010_GROUP_TEMP, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_PEAK) | + BIT(IIO_CHAN_INFO_OFFSET) | + BIT(IIO_CHAN_INFO_SCALE), + }, + { + .type = IIO_HUMIDITYRELATIVE, + .address = HDC2010_GROUP_HUMIDITY, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_PEAK) | + BIT(IIO_CHAN_INFO_SCALE), + }, + { + .type = IIO_CURRENT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), + .extend_name = "heater", + .output = 1, + }, +}; + +static int hdc2010_update_drdy_config(struct hdc2010_data *data, + char mask, char val) +{ + u8 tmp = (~mask & data->drdy_config) | val; + int ret; + + ret = i2c_smbus_write_byte_data(data->client, + HDC2010_REG_RESET_DRDY_INT_CONF, tmp); + if (ret) + return ret; + + data->drdy_config = tmp; + + return 0; +} + +static int hdc2010_get_prim_measurement_word(struct hdc2010_data *data, + struct iio_chan_spec const *chan) +{ + struct i2c_client *client = data->client; + s32 ret; + + ret = i2c_smbus_read_word_data(client, + hdc2010_reg_translation[chan->address].primary); + + if (ret < 0) + dev_err(&client->dev, "Could not read sensor measurement word\n"); + + return ret; +} + +static int hdc2010_get_peak_measurement_byte(struct hdc2010_data *data, + struct iio_chan_spec const *chan) +{ + struct i2c_client *client = data->client; + s32 ret; + + ret = i2c_smbus_read_byte_data(client, + hdc2010_reg_translation[chan->address].peak); + + if (ret < 0) + dev_err(&client->dev, "Could not read sensor measurement byte\n"); + + return ret; +} + +static int hdc2010_get_heater_status(struct hdc2010_data *data) +{ + return !!(data->drdy_config & HDC2010_HEATER_EN); +} + +static int hdc2010_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, int *val, + int *val2, long mask) +{ + struct hdc2010_data *data = iio_priv(indio_dev); + + switch (mask) { + case IIO_CHAN_INFO_RAW: { + int ret; + + if (chan->type == IIO_CURRENT) { + *val = hdc2010_get_heater_status(data); + return IIO_VAL_INT; + } + ret = iio_device_claim_direct_mode(indio_dev); + if (ret) + return ret; + mutex_lock(&data->lock); + ret = hdc2010_get_prim_measurement_word(data, chan); + mutex_unlock(&data->lock); + iio_device_release_direct_mode(indio_dev); + if (ret < 0) + return ret; + *val = ret; + return IIO_VAL_INT; + } + case IIO_CHAN_INFO_PEAK: { + int ret; + + ret = iio_device_claim_direct_mode(indio_dev); + if (ret) + return ret; + mutex_lock(&data->lock); + ret = hdc2010_get_peak_measurement_byte(data, chan); + mutex_unlock(&data->lock); + iio_device_release_direct_mode(indio_dev); + if (ret < 0) + return ret; + /* Scaling up the value so we can use same offset as RAW */ + *val = ret * 256; + return IIO_VAL_INT; + } + case IIO_CHAN_INFO_SCALE: + *val2 = 65536; + if (chan->type == IIO_TEMP) + *val = 165000; + else + *val = 100000; + return IIO_VAL_FRACTIONAL; + case IIO_CHAN_INFO_OFFSET: + *val = -15887; + *val2 = 515151; + return IIO_VAL_INT_PLUS_MICRO; + default: + return -EINVAL; + } +} + +static int hdc2010_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int val, int val2, long mask) +{ + struct hdc2010_data *data = iio_priv(indio_dev); + int new, ret; + + switch (mask) { + case IIO_CHAN_INFO_RAW: + if (chan->type != IIO_CURRENT || val2 != 0) + return -EINVAL; + + switch (val) { + case 1: + new = HDC2010_HEATER_EN; + break; + case 0: + new = 0; + break; + default: + return -EINVAL; + } + + mutex_lock(&data->lock); + ret = hdc2010_update_drdy_config(data, HDC2010_HEATER_EN, new); + mutex_unlock(&data->lock); + return ret; + default: + return -EINVAL; + } +} + +static const struct iio_info hdc2010_info = { + .read_raw = hdc2010_read_raw, + .write_raw = hdc2010_write_raw, + .attrs = &hdc2010_attribute_group, +}; + +static int hdc2010_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct iio_dev *indio_dev; + struct hdc2010_data *data; + u8 tmp; + int ret; + + if (!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_BYTE | I2C_FUNC_I2C)) + return -EOPNOTSUPP; + + indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); + if (!indio_dev) + return -ENOMEM; + + data = iio_priv(indio_dev); + i2c_set_clientdata(client, indio_dev); + data->client = client; + mutex_init(&data->lock); + + indio_dev->dev.parent = &client->dev; + /* + * As DEVICE ID register does not differentiate between + * HDC2010 and HDC2080, we have the name hardcoded + */ + indio_dev->name = "hdc2010"; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->info = &hdc2010_info; + + indio_dev->channels = hdc2010_channels; + indio_dev->num_channels = ARRAY_SIZE(hdc2010_channels); + + /* Enable Automatic Measurement Mode at 5Hz */ + ret = hdc2010_update_drdy_config(data, HDC2010_AMM, HDC2010_AMM); + if (ret) + return ret; + + /* + * We enable both temp and humidity measurement. + * However the measurement won't start even in AMM until triggered. + */ + tmp = (data->measurement_config & ~HDC2010_MEAS_CONF) | + HDC2010_MEAS_TRIG; + + ret = i2c_smbus_write_byte_data(client, HDC2010_REG_MEASUREMENT_CONF, tmp); + if (ret) { + dev_warn(&client->dev, "Unable to set up measurement\n"); + if (hdc2010_update_drdy_config(data, HDC2010_AMM, 0)) + dev_warn(&client->dev, "Unable to restore default AMM\n"); + return ret; + } + + data->measurement_config = tmp; + + return iio_device_register(indio_dev); +} + +static int hdc2010_remove(struct i2c_client *client) +{ + struct iio_dev *indio_dev = i2c_get_clientdata(client); + struct hdc2010_data *data = iio_priv(indio_dev); + + iio_device_unregister(indio_dev); + + /* Disable Automatic Measurement Mode */ + if (hdc2010_update_drdy_config(data, HDC2010_AMM, 0)) + dev_warn(&client->dev, "Unable to restore default AMM\n"); + + return 0; +} + +static const struct i2c_device_id hdc2010_id[] = { + { "hdc2010" }, + { "hdc2080" }, + { } +}; +MODULE_DEVICE_TABLE(i2c, hdc2010_id); + +static const struct of_device_id hdc2010_dt_ids[] = { + { .compatible = "ti,hdc2010" }, + { .compatible = "ti,hdc2080" }, + { } +}; +MODULE_DEVICE_TABLE(of, hdc2010_dt_ids); + +static struct i2c_driver hdc2010_driver = { + .driver = { + .name = "hdc2010", + .of_match_table = hdc2010_dt_ids, + }, + .probe = hdc2010_probe, + .remove = hdc2010_remove, + .id_table = hdc2010_id, +}; +module_i2c_driver(hdc2010_driver); + +MODULE_AUTHOR("Eugene Zaikonnikov <ez@norphonic.com>"); +MODULE_DESCRIPTION("TI HDC2010 humidity and temperature sensor driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/iio/humidity/htu21.c b/drivers/iio/humidity/htu21.c index 4f5d9d1c05ab..36df2a102ca4 100644 --- a/drivers/iio/humidity/htu21.c +++ b/drivers/iio/humidity/htu21.c @@ -19,6 +19,7 @@ #include <linux/kernel.h> #include <linux/stat.h> #include <linux/module.h> +#include <linux/mod_devicetable.h> #include <linux/iio/iio.h> #include <linux/iio/sysfs.h> @@ -247,7 +248,7 @@ static struct i2c_driver htu21_driver = { .id_table = htu21_id, .driver = { .name = "htu21", - .of_match_table = of_match_ptr(htu21_of_match), + .of_match_table = htu21_of_match, }, }; diff --git a/drivers/iio/humidity/si7020.c b/drivers/iio/humidity/si7020.c index a09b5773d377..ab6537f136ba 100644 --- a/drivers/iio/humidity/si7020.c +++ b/drivers/iio/humidity/si7020.c @@ -20,6 +20,7 @@ #include <linux/delay.h> #include <linux/i2c.h> #include <linux/module.h> +#include <linux/mod_devicetable.h> #include <linux/slab.h> #include <linux/sysfs.h> @@ -153,7 +154,7 @@ MODULE_DEVICE_TABLE(of, si7020_dt_ids); static struct i2c_driver si7020_driver = { .driver = { .name = "si7020", - .of_match_table = of_match_ptr(si7020_dt_ids), + .of_match_table = si7020_dt_ids, }, .probe = si7020_probe, .id_table = si7020_id, diff --git a/drivers/iio/iio_core_trigger.h b/drivers/iio/iio_core_trigger.h index 9d1a92cc6480..374816bc3e73 100644 --- a/drivers/iio/iio_core_trigger.h +++ b/drivers/iio/iio_core_trigger.h @@ -30,7 +30,7 @@ int iio_trigger_detach_poll_func(struct iio_trigger *trig, * iio_device_register_trigger_consumer() - set up an iio_dev to use triggers * @indio_dev: iio_dev associated with the device that will consume the trigger **/ -static int iio_device_register_trigger_consumer(struct iio_dev *indio_dev) +static inline int iio_device_register_trigger_consumer(struct iio_dev *indio_dev) { return 0; } @@ -39,7 +39,7 @@ static int iio_device_register_trigger_consumer(struct iio_dev *indio_dev) * iio_device_unregister_trigger_consumer() - reverse the registration process * @indio_dev: iio_dev associated with the device that consumed the trigger **/ -static void iio_device_unregister_trigger_consumer(struct iio_dev *indio_dev) +static inline void iio_device_unregister_trigger_consumer(struct iio_dev *indio_dev) { } diff --git a/drivers/iio/imu/adis16400.c b/drivers/iio/imu/adis16400.c index 1ebe3e50d3e6..54af2ed664f6 100644 --- a/drivers/iio/imu/adis16400.c +++ b/drivers/iio/imu/adis16400.c @@ -173,6 +173,8 @@ struct adis16400_chip_info { * @variant: chip variant info * @filt_int: integer part of requested filter frequency * @adis: adis device + * @avail_scan_mask: NULL terminated array of bitmaps of channels + * that must be enabled together **/ struct adis16400_state { struct adis16400_chip_info *variant; @@ -317,11 +319,6 @@ enum adis16400_chip_variant { ADIS16448, }; -static struct adis_burst adis16400_burst = { - .en = true, - .reg_cmd = ADIS16400_GLOB_CMD, -}; - static int adis16334_get_freq(struct adis16400_state *st) { int ret; @@ -947,7 +944,7 @@ static const char * const adis16400_status_error_msgs[] = { [ADIS16400_DIAG_STAT_POWER_LOW] = "Power supply below 4.75V", }; -#define ADIS16400_DATA(_timeouts) \ +#define ADIS16400_DATA(_timeouts, _burst_len) \ { \ .msc_ctrl_reg = ADIS16400_MSC_CTRL, \ .glob_cmd_reg = ADIS16400_GLOB_CMD, \ @@ -973,6 +970,8 @@ static const char * const adis16400_status_error_msgs[] = { BIT(ADIS16400_DIAG_STAT_POWER_HIGH) | \ BIT(ADIS16400_DIAG_STAT_POWER_LOW), \ .timeouts = (_timeouts), \ + .burst_reg_cmd = ADIS16400_GLOB_CMD, \ + .burst_len = (_burst_len) \ } static const struct adis_timeout adis16300_timeouts = { @@ -1023,7 +1022,7 @@ static struct adis16400_chip_info adis16400_chips[] = { .temp_offset = 25000000 / 140000, /* 25 C = 0x00 */ .set_freq = adis16400_set_freq, .get_freq = adis16400_get_freq, - .adis_data = ADIS16400_DATA(&adis16300_timeouts), + .adis_data = ADIS16400_DATA(&adis16300_timeouts, 18), }, [ADIS16334] = { .channels = adis16334_channels, @@ -1036,7 +1035,7 @@ static struct adis16400_chip_info adis16400_chips[] = { .temp_offset = 25000000 / 67850, /* 25 C = 0x00 */ .set_freq = adis16334_set_freq, .get_freq = adis16334_get_freq, - .adis_data = ADIS16400_DATA(&adis16334_timeouts), + .adis_data = ADIS16400_DATA(&adis16334_timeouts, 0), }, [ADIS16350] = { .channels = adis16350_channels, @@ -1048,7 +1047,7 @@ static struct adis16400_chip_info adis16400_chips[] = { .flags = ADIS16400_NO_BURST | ADIS16400_HAS_SLOW_MODE, .set_freq = adis16400_set_freq, .get_freq = adis16400_get_freq, - .adis_data = ADIS16400_DATA(&adis16300_timeouts), + .adis_data = ADIS16400_DATA(&adis16300_timeouts, 0), }, [ADIS16360] = { .channels = adis16350_channels, @@ -1061,7 +1060,7 @@ static struct adis16400_chip_info adis16400_chips[] = { .temp_offset = 25000000 / 136000, /* 25 C = 0x00 */ .set_freq = adis16400_set_freq, .get_freq = adis16400_get_freq, - .adis_data = ADIS16400_DATA(&adis16300_timeouts), + .adis_data = ADIS16400_DATA(&adis16300_timeouts, 28), }, [ADIS16362] = { .channels = adis16350_channels, @@ -1074,7 +1073,7 @@ static struct adis16400_chip_info adis16400_chips[] = { .temp_offset = 25000000 / 136000, /* 25 C = 0x00 */ .set_freq = adis16400_set_freq, .get_freq = adis16400_get_freq, - .adis_data = ADIS16400_DATA(&adis16362_timeouts), + .adis_data = ADIS16400_DATA(&adis16362_timeouts, 28), }, [ADIS16364] = { .channels = adis16350_channels, @@ -1087,7 +1086,7 @@ static struct adis16400_chip_info adis16400_chips[] = { .temp_offset = 25000000 / 136000, /* 25 C = 0x00 */ .set_freq = adis16400_set_freq, .get_freq = adis16400_get_freq, - .adis_data = ADIS16400_DATA(&adis16362_timeouts), + .adis_data = ADIS16400_DATA(&adis16362_timeouts, 28), }, [ADIS16367] = { .channels = adis16350_channels, @@ -1100,7 +1099,7 @@ static struct adis16400_chip_info adis16400_chips[] = { .temp_offset = 25000000 / 136000, /* 25 C = 0x00 */ .set_freq = adis16400_set_freq, .get_freq = adis16400_get_freq, - .adis_data = ADIS16400_DATA(&adis16300_timeouts), + .adis_data = ADIS16400_DATA(&adis16300_timeouts, 28), }, [ADIS16400] = { .channels = adis16400_channels, @@ -1112,7 +1111,7 @@ static struct adis16400_chip_info adis16400_chips[] = { .temp_offset = 25000000 / 140000, /* 25 C = 0x00 */ .set_freq = adis16400_set_freq, .get_freq = adis16400_get_freq, - .adis_data = ADIS16400_DATA(&adis16400_timeouts), + .adis_data = ADIS16400_DATA(&adis16400_timeouts, 24), }, [ADIS16445] = { .channels = adis16445_channels, @@ -1126,7 +1125,7 @@ static struct adis16400_chip_info adis16400_chips[] = { .temp_offset = 31000000 / 73860, /* 31 C = 0x00 */ .set_freq = adis16334_set_freq, .get_freq = adis16334_get_freq, - .adis_data = ADIS16400_DATA(&adis16445_timeouts), + .adis_data = ADIS16400_DATA(&adis16445_timeouts, 16), }, [ADIS16448] = { .channels = adis16448_channels, @@ -1140,7 +1139,7 @@ static struct adis16400_chip_info adis16400_chips[] = { .temp_offset = 31000000 / 73860, /* 31 C = 0x00 */ .set_freq = adis16334_set_freq, .get_freq = adis16334_get_freq, - .adis_data = ADIS16400_DATA(&adis16448_timeouts), + .adis_data = ADIS16400_DATA(&adis16448_timeouts, 24), } }; @@ -1164,6 +1163,12 @@ static void adis16400_setup_chan_mask(struct adis16400_state *st) st->avail_scan_mask[0] |= BIT(ch->scan_index); } } + +static void adis16400_stop(void *data) +{ + adis16400_stop_device(data); +} + static int adis16400_probe(struct spi_device *spi) { struct adis16400_state *st; @@ -1190,9 +1195,6 @@ static int adis16400_probe(struct spi_device *spi) if (!(st->variant->flags & ADIS16400_NO_BURST)) { adis16400_setup_chan_mask(st); indio_dev->available_scan_masks = st->avail_scan_mask; - st->adis.burst = &adis16400_burst; - if (st->variant->flags & ADIS16400_BURST_DIAG_STAT) - st->adis.burst_extra_len = sizeof(u16); } adis16400_data = &st->variant->adis_data; @@ -1201,37 +1203,24 @@ static int adis16400_probe(struct spi_device *spi) if (ret) return ret; - ret = adis_setup_buffer_and_trigger(&st->adis, indio_dev, - adis16400_trigger_handler); + ret = devm_adis_setup_buffer_and_trigger(&st->adis, indio_dev, adis16400_trigger_handler); if (ret) return ret; /* Get the device into a sane initial state */ ret = adis16400_initial_setup(indio_dev); if (ret) - goto error_cleanup_buffer; - ret = iio_device_register(indio_dev); - if (ret) - goto error_cleanup_buffer; - - adis16400_debugfs_init(indio_dev); - return 0; - -error_cleanup_buffer: - adis_cleanup_buffer_and_trigger(&st->adis, indio_dev); - return ret; -} - -static int adis16400_remove(struct spi_device *spi) -{ - struct iio_dev *indio_dev = spi_get_drvdata(spi); - struct adis16400_state *st = iio_priv(indio_dev); + return ret; - iio_device_unregister(indio_dev); - adis16400_stop_device(indio_dev); + ret = devm_add_action_or_reset(&spi->dev, adis16400_stop, indio_dev); + if (ret) + return ret; - adis_cleanup_buffer_and_trigger(&st->adis, indio_dev); + ret = devm_iio_device_register(&spi->dev, indio_dev); + if (ret) + return ret; + adis16400_debugfs_init(indio_dev); return 0; } @@ -1261,7 +1250,6 @@ static struct spi_driver adis16400_driver = { }, .id_table = adis16400_id, .probe = adis16400_probe, - .remove = adis16400_remove, }; module_spi_driver(adis16400_driver); diff --git a/drivers/iio/imu/adis16460.c b/drivers/iio/imu/adis16460.c index b26a5f1bc51a..74a161e39733 100644 --- a/drivers/iio/imu/adis16460.c +++ b/drivers/iio/imu/adis16460.c @@ -403,7 +403,7 @@ static int adis16460_probe(struct spi_device *spi) if (ret) return ret; - ret = adis_setup_buffer_and_trigger(&st->adis, indio_dev, NULL); + ret = devm_adis_setup_buffer_and_trigger(&st->adis, indio_dev, NULL); if (ret) return ret; @@ -411,31 +411,15 @@ static int adis16460_probe(struct spi_device *spi) ret = __adis_initial_startup(&st->adis); if (ret) - goto error_cleanup_buffer; + return ret; - ret = iio_device_register(indio_dev); + ret = devm_iio_device_register(&spi->dev, indio_dev); if (ret) - goto error_cleanup_buffer; + return ret; adis16460_debugfs_init(indio_dev); return 0; - -error_cleanup_buffer: - adis_cleanup_buffer_and_trigger(&st->adis, indio_dev); - return ret; -} - -static int adis16460_remove(struct spi_device *spi) -{ - struct iio_dev *indio_dev = spi_get_drvdata(spi); - struct adis16460 *st = iio_priv(indio_dev); - - iio_device_unregister(indio_dev); - - adis_cleanup_buffer_and_trigger(&st->adis, indio_dev); - - return 0; } static const struct spi_device_id adis16460_ids[] = { @@ -457,7 +441,6 @@ static struct spi_driver adis16460_driver = { }, .id_table = adis16460_ids, .probe = adis16460_probe, - .remove = adis16460_remove, }; module_spi_driver(adis16460_driver); diff --git a/drivers/iio/imu/adis16475.c b/drivers/iio/imu/adis16475.c index 35d10ccb66c2..197d48240991 100644 --- a/drivers/iio/imu/adis16475.c +++ b/drivers/iio/imu/adis16475.c @@ -565,6 +565,9 @@ static int adis16475_enable_irq(struct adis *adis, bool enable) BIT(ADIS16475_DIAG_STAT_CLK), \ .enable_irq = adis16475_enable_irq, \ .timeouts = (_timeouts), \ + .burst_reg_cmd = ADIS16475_REG_GLOB_CMD, \ + .burst_len = ADIS16475_BURST_MAX_DATA, \ + .burst_max_len = ADIS16475_BURST32_MAX_DATA \ } static const struct adis16475_sync adis16475_sync_mode[] = { @@ -910,20 +913,6 @@ static const struct iio_info adis16475_info = { .debugfs_reg_access = adis_debugfs_reg_access, }; -static struct adis_burst adis16475_burst = { - .en = true, - .reg_cmd = ADIS16475_REG_GLOB_CMD, - /* - * adis_update_scan_mode_burst() sets the burst length in respect with - * the number of channels and allocates 16 bits for each. However, - * adis1647x devices also need space for DIAG_STAT, DATA_CNTR or - * TIME_STAMP (depending on the clock mode but for us these bytes are - * don't care...) and CRC. - */ - .extra_len = 3 * sizeof(u16), - .burst_max_len = ADIS16475_BURST32_MAX_DATA, -}; - static bool adis16475_validate_crc(const u8 *buffer, u16 crc, const bool burst32) { @@ -1279,7 +1268,6 @@ static int adis16475_probe(struct spi_device *spi) st = iio_priv(indio_dev); spi_set_drvdata(spi, indio_dev); - st->adis.burst = &adis16475_burst; st->info = device_get_match_data(&spi->dev); if (!st->info) diff --git a/drivers/iio/imu/adis16480.c b/drivers/iio/imu/adis16480.c index 1eb4f98076f1..dfe86c589325 100644 --- a/drivers/iio/imu/adis16480.c +++ b/drivers/iio/imu/adis16480.c @@ -1212,6 +1212,16 @@ static int adis16480_get_ext_clocks(struct adis16480 *st) return 0; } +static void adis16480_stop(void *data) +{ + adis16480_stop_device(data); +} + +static void adis16480_clk_disable(void *data) +{ + clk_disable_unprepare(data); +} + static int adis16480_probe(struct spi_device *spi) { const struct spi_device_id *id = spi_get_device_id(spi); @@ -1245,18 +1255,26 @@ static int adis16480_probe(struct spi_device *spi) if (ret) return ret; + ret = devm_add_action_or_reset(&spi->dev, adis16480_stop, indio_dev); + if (ret) + return ret; + ret = adis16480_config_irq_pin(spi->dev.of_node, st); if (ret) - goto error_stop_device; + return ret; ret = adis16480_get_ext_clocks(st); if (ret) - goto error_stop_device; + return ret; if (!IS_ERR_OR_NULL(st->ext_clk)) { ret = adis16480_ext_clk_config(st, spi->dev.of_node, true); if (ret) - goto error_stop_device; + return ret; + + ret = devm_add_action_or_reset(&spi->dev, adis16480_clk_disable, st->ext_clk); + if (ret) + return ret; st->clk_freq = clk_get_rate(st->ext_clk); st->clk_freq *= 1000; /* micro */ @@ -1264,39 +1282,17 @@ static int adis16480_probe(struct spi_device *spi) st->clk_freq = st->chip_info->int_clk; } - ret = adis_setup_buffer_and_trigger(&st->adis, indio_dev, NULL); + ret = devm_adis_setup_buffer_and_trigger(&st->adis, indio_dev, NULL); if (ret) - goto error_clk_disable_unprepare; + return ret; - ret = iio_device_register(indio_dev); + ret = devm_iio_device_register(&spi->dev, indio_dev); if (ret) - goto error_cleanup_buffer; + return ret; adis16480_debugfs_init(indio_dev); return 0; - -error_cleanup_buffer: - adis_cleanup_buffer_and_trigger(&st->adis, indio_dev); -error_clk_disable_unprepare: - clk_disable_unprepare(st->ext_clk); -error_stop_device: - adis16480_stop_device(indio_dev); - return ret; -} - -static int adis16480_remove(struct spi_device *spi) -{ - struct iio_dev *indio_dev = spi_get_drvdata(spi); - struct adis16480 *st = iio_priv(indio_dev); - - iio_device_unregister(indio_dev); - adis16480_stop_device(indio_dev); - - adis_cleanup_buffer_and_trigger(&st->adis, indio_dev); - clk_disable_unprepare(st->ext_clk); - - return 0; } static const struct spi_device_id adis16480_ids[] = { @@ -1338,7 +1334,6 @@ static struct spi_driver adis16480_driver = { }, .id_table = adis16480_ids, .probe = adis16480_probe, - .remove = adis16480_remove, }; module_spi_driver(adis16480_driver); diff --git a/drivers/iio/imu/adis_buffer.c b/drivers/iio/imu/adis_buffer.c index 5b4225ee09b9..ac354321f63a 100644 --- a/drivers/iio/imu/adis_buffer.c +++ b/drivers/iio/imu/adis_buffer.c @@ -26,12 +26,10 @@ static int adis_update_scan_mode_burst(struct iio_dev *indio_dev, unsigned int burst_length, burst_max_length; u8 *tx; - /* All but the timestamp channel */ - burst_length = (indio_dev->num_channels - 1) * sizeof(u16); - burst_length += adis->burst->extra_len + adis->burst_extra_len; + burst_length = adis->data->burst_len + adis->burst_extra_len; - if (adis->burst->burst_max_len) - burst_max_length = adis->burst->burst_max_len; + if (adis->data->burst_max_len) + burst_max_length = adis->data->burst_max_len; else burst_max_length = burst_length; @@ -47,7 +45,7 @@ static int adis_update_scan_mode_burst(struct iio_dev *indio_dev, } tx = adis->buffer + burst_max_length; - tx[0] = ADIS_READ_REG(adis->burst->reg_cmd); + tx[0] = ADIS_READ_REG(adis->data->burst_reg_cmd); tx[1] = 0; adis->xfer[0].tx_buf = tx; @@ -76,7 +74,7 @@ int adis_update_scan_mode(struct iio_dev *indio_dev, kfree(adis->xfer); kfree(adis->buffer); - if (adis->burst && adis->burst->en) + if (adis->data->burst_len) return adis_update_scan_mode_burst(indio_dev, scan_mask); scan_count = indio_dev->scan_bytes / 2; @@ -170,48 +168,6 @@ static void adis_buffer_cleanup(void *arg) } /** - * adis_setup_buffer_and_trigger() - Sets up buffer and trigger for the adis device - * @adis: The adis device. - * @indio_dev: The IIO device. - * @trigger_handler: Optional trigger handler, may be NULL. - * - * Returns 0 on success, a negative error code otherwise. - * - * This function sets up the buffer and trigger for a adis devices. If - * 'trigger_handler' is NULL the default trigger handler will be used. The - * default trigger handler will simply read the registers assigned to the - * currently active channels. - * - * adis_cleanup_buffer_and_trigger() should be called to free the resources - * allocated by this function. - */ -int adis_setup_buffer_and_trigger(struct adis *adis, struct iio_dev *indio_dev, - irqreturn_t (*trigger_handler)(int, void *)) -{ - int ret; - - if (!trigger_handler) - trigger_handler = adis_trigger_handler; - - ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time, - trigger_handler, NULL); - if (ret) - return ret; - - if (adis->spi->irq) { - ret = adis_probe_trigger(adis, indio_dev); - if (ret) - goto error_buffer_cleanup; - } - return 0; - -error_buffer_cleanup: - iio_triggered_buffer_cleanup(indio_dev); - return ret; -} -EXPORT_SYMBOL_GPL(adis_setup_buffer_and_trigger); - -/** * devm_adis_setup_buffer_and_trigger() - Sets up buffer and trigger for * the managed adis device * @adis: The adis device @@ -220,7 +176,10 @@ EXPORT_SYMBOL_GPL(adis_setup_buffer_and_trigger); * * Returns 0 on success, a negative error code otherwise. * - * This function perfoms exactly the same as adis_setup_buffer_and_trigger() + * This function sets up the buffer and trigger for a adis devices. If + * 'trigger_handler' is NULL the default trigger handler will be used. The + * default trigger handler will simply read the registers assigned to the + * currently active channels. */ int devm_adis_setup_buffer_and_trigger(struct adis *adis, struct iio_dev *indio_dev, @@ -248,20 +207,3 @@ devm_adis_setup_buffer_and_trigger(struct adis *adis, struct iio_dev *indio_dev, } EXPORT_SYMBOL_GPL(devm_adis_setup_buffer_and_trigger); -/** - * adis_cleanup_buffer_and_trigger() - Free buffer and trigger resources - * @adis: The adis device. - * @indio_dev: The IIO device. - * - * Frees resources allocated by adis_setup_buffer_and_trigger() - */ -void adis_cleanup_buffer_and_trigger(struct adis *adis, - struct iio_dev *indio_dev) -{ - if (adis->spi->irq) - adis_remove_trigger(adis); - kfree(adis->buffer); - kfree(adis->xfer); - iio_triggered_buffer_cleanup(indio_dev); -} -EXPORT_SYMBOL_GPL(adis_cleanup_buffer_and_trigger); diff --git a/drivers/iio/imu/adis_trigger.c b/drivers/iio/imu/adis_trigger.c index 8afe71947c00..64e0ba51cb18 100644 --- a/drivers/iio/imu/adis_trigger.c +++ b/drivers/iio/imu/adis_trigger.c @@ -55,53 +55,6 @@ static int adis_validate_irq_flag(struct adis *adis) return 0; } -/** - * adis_probe_trigger() - Sets up trigger for a adis device - * @adis: The adis device - * @indio_dev: The IIO device - * - * Returns 0 on success or a negative error code - * - * adis_remove_trigger() should be used to free the trigger. - */ -int adis_probe_trigger(struct adis *adis, struct iio_dev *indio_dev) -{ - int ret; - - adis->trig = iio_trigger_alloc("%s-dev%d", indio_dev->name, - indio_dev->id); - if (adis->trig == NULL) - return -ENOMEM; - - adis_trigger_setup(adis); - - ret = adis_validate_irq_flag(adis); - if (ret) - return ret; - - ret = request_irq(adis->spi->irq, - &iio_trigger_generic_data_rdy_poll, - adis->irq_flag, - indio_dev->name, - adis->trig); - if (ret) - goto error_free_trig; - - ret = iio_trigger_register(adis->trig); - - indio_dev->trig = iio_trigger_get(adis->trig); - if (ret) - goto error_free_irq; - - return 0; - -error_free_irq: - free_irq(adis->spi->irq, adis->trig); -error_free_trig: - iio_trigger_free(adis->trig); - return ret; -} -EXPORT_SYMBOL_GPL(adis_probe_trigger); /** * devm_adis_probe_trigger() - Sets up trigger for a managed adis device @@ -137,16 +90,3 @@ int devm_adis_probe_trigger(struct adis *adis, struct iio_dev *indio_dev) } EXPORT_SYMBOL_GPL(devm_adis_probe_trigger); -/** - * adis_remove_trigger() - Remove trigger for a adis devices - * @adis: The adis device - * - * Removes the trigger previously registered with adis_probe_trigger(). - */ -void adis_remove_trigger(struct adis *adis) -{ - iio_trigger_unregister(adis->trig); - free_irq(adis->spi->irq, adis->trig); - iio_trigger_free(adis->trig); -} -EXPORT_SYMBOL_GPL(adis_remove_trigger); diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c index 3fee3947f772..18a1898e3e34 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c @@ -1475,22 +1475,14 @@ int inv_mpu_core_probe(struct regmap *regmap, int irq, const char *name, } st->vdd_supply = devm_regulator_get(dev, "vdd"); - if (IS_ERR(st->vdd_supply)) { - if (PTR_ERR(st->vdd_supply) != -EPROBE_DEFER) - dev_err(dev, "Failed to get vdd regulator %d\n", - (int)PTR_ERR(st->vdd_supply)); - - return PTR_ERR(st->vdd_supply); - } + if (IS_ERR(st->vdd_supply)) + return dev_err_probe(dev, PTR_ERR(st->vdd_supply), + "Failed to get vdd regulator\n"); st->vddio_supply = devm_regulator_get(dev, "vddio"); - if (IS_ERR(st->vddio_supply)) { - if (PTR_ERR(st->vddio_supply) != -EPROBE_DEFER) - dev_err(dev, "Failed to get vddio regulator %d\n", - (int)PTR_ERR(st->vddio_supply)); - - return PTR_ERR(st->vddio_supply); - } + if (IS_ERR(st->vddio_supply)) + return dev_err_probe(dev, PTR_ERR(st->vddio_supply), + "Failed to get vddio regulator\n"); result = regulator_enable(st->vdd_supply); if (result) { diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h index cd38b3fccc7b..eb522b38acf3 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h @@ -122,6 +122,13 @@ struct inv_mpu6050_chip_config { u8 user_ctrl; }; +/* + * Maximum of 6 + 6 + 2 + 7 (for MPU9x50) = 21 round up to 24 and plus 8. + * May be less if fewer channels are enabled, as long as the timestamp + * remains 8 byte aligned + */ +#define INV_MPU6050_OUTPUT_DATA_SIZE 32 + /** * struct inv_mpu6050_hw - Other important hardware information. * @whoami: Self identification byte from WHO_AM_I register @@ -165,6 +172,7 @@ struct inv_mpu6050_hw { * @magn_raw_to_gauss: coefficient to convert mag raw value to Gauss. * @magn_orient: magnetometer sensor chip orientation if available. * @suspended_sensors: sensors mask of sensors turned off for suspend + * @data: dma safe buffer used for bulk reads. */ struct inv_mpu6050_state { struct mutex lock; @@ -190,6 +198,7 @@ struct inv_mpu6050_state { s32 magn_raw_to_gauss[3]; struct iio_mount_matrix magn_orient; unsigned int suspended_sensors; + u8 data[INV_MPU6050_OUTPUT_DATA_SIZE] ____cacheline_aligned; }; /*register and associated bit definition*/ @@ -334,9 +343,6 @@ struct inv_mpu6050_state { #define INV_ICM20608_TEMP_OFFSET 8170 #define INV_ICM20608_TEMP_SCALE 3059976 -/* 6 + 6 + 2 + 7 (for MPU9x50) = 21 round up to 24 and plus 8 */ -#define INV_MPU6050_OUTPUT_DATA_SIZE 32 - #define INV_MPU6050_REG_INT_PIN_CFG 0x37 #define INV_MPU6050_ACTIVE_HIGH 0x00 #define INV_MPU6050_ACTIVE_LOW 0x80 diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c index b533fa2dad0a..45c37525c2f1 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c @@ -13,7 +13,6 @@ #include <linux/interrupt.h> #include <linux/poll.h> #include <linux/math64.h> -#include <asm/unaligned.h> #include "inv_mpu_iio.h" /** @@ -121,7 +120,6 @@ irqreturn_t inv_mpu6050_read_fifo(int irq, void *p) struct inv_mpu6050_state *st = iio_priv(indio_dev); size_t bytes_per_datum; int result; - u8 data[INV_MPU6050_OUTPUT_DATA_SIZE]; u16 fifo_count; s64 timestamp; int int_status; @@ -160,11 +158,11 @@ irqreturn_t inv_mpu6050_read_fifo(int irq, void *p) * read fifo_count register to know how many bytes are inside the FIFO * right now */ - result = regmap_bulk_read(st->map, st->reg->fifo_count_h, data, - INV_MPU6050_FIFO_COUNT_BYTE); + result = regmap_bulk_read(st->map, st->reg->fifo_count_h, + st->data, INV_MPU6050_FIFO_COUNT_BYTE); if (result) goto end_session; - fifo_count = get_unaligned_be16(&data[0]); + fifo_count = be16_to_cpup((__be16 *)&st->data[0]); /* * Handle fifo overflow by resetting fifo. @@ -181,8 +179,8 @@ irqreturn_t inv_mpu6050_read_fifo(int irq, void *p) nb = fifo_count / bytes_per_datum; inv_mpu6050_update_period(st, pf->timestamp, nb); for (i = 0; i < nb; ++i) { - result = regmap_bulk_read(st->map, st->reg->fifo_r_w, - data, bytes_per_datum); + result = regmap_noinc_read(st->map, st->reg->fifo_r_w, + st->data, bytes_per_datum); if (result) goto flush_fifo; /* skip first samples if needed */ @@ -191,7 +189,7 @@ irqreturn_t inv_mpu6050_read_fifo(int irq, void *p) continue; } timestamp = inv_mpu6050_get_timestamp(st); - iio_push_to_buffers_with_timestamp(indio_dev, data, timestamp); + iio_push_to_buffers_with_timestamp(indio_dev, st->data, timestamp); } end_session: diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h index d80ba2e688ed..9275346a9cc1 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h @@ -383,6 +383,7 @@ struct st_lsm6dsx_sensor { * @iio_devs: Pointers to acc/gyro iio_dev instances. * @settings: Pointer to the specific sensor settings in use. * @orientation: sensor chip orientation relative to main hardware. + * @scan: Temporary buffers used to align data before iio_push_to_buffers() */ struct st_lsm6dsx_hw { struct device *dev; @@ -411,6 +412,11 @@ struct st_lsm6dsx_hw { const struct st_lsm6dsx_settings *settings; struct iio_mount_matrix orientation; + /* Ensure natural alignment of buffer elements */ + struct { + __le16 channels[3]; + s64 ts __aligned(8); + } scan[3]; }; static __maybe_unused const struct iio_event_spec st_lsm6dsx_event = { diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c index 7de10bd636ea..12ed0a2e55e4 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c @@ -353,9 +353,6 @@ int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw) int err, sip, acc_sip, gyro_sip, ts_sip, ext_sip, read_len, offset; u16 fifo_len, pattern_len = hw->sip * ST_LSM6DSX_SAMPLE_SIZE; u16 fifo_diff_mask = hw->settings->fifo_ops.fifo_diff.mask; - u8 gyro_buff[ST_LSM6DSX_IIO_BUFF_SIZE]; - u8 acc_buff[ST_LSM6DSX_IIO_BUFF_SIZE]; - u8 ext_buff[ST_LSM6DSX_IIO_BUFF_SIZE]; bool reset_ts = false; __le16 fifo_status; s64 ts = 0; @@ -416,19 +413,22 @@ int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw) while (acc_sip > 0 || gyro_sip > 0 || ext_sip > 0) { if (gyro_sip > 0 && !(sip % gyro_sensor->decimator)) { - memcpy(gyro_buff, &hw->buff[offset], - ST_LSM6DSX_SAMPLE_SIZE); - offset += ST_LSM6DSX_SAMPLE_SIZE; + memcpy(hw->scan[ST_LSM6DSX_ID_GYRO].channels, + &hw->buff[offset], + sizeof(hw->scan[ST_LSM6DSX_ID_GYRO].channels)); + offset += sizeof(hw->scan[ST_LSM6DSX_ID_GYRO].channels); } if (acc_sip > 0 && !(sip % acc_sensor->decimator)) { - memcpy(acc_buff, &hw->buff[offset], - ST_LSM6DSX_SAMPLE_SIZE); - offset += ST_LSM6DSX_SAMPLE_SIZE; + memcpy(hw->scan[ST_LSM6DSX_ID_ACC].channels, + &hw->buff[offset], + sizeof(hw->scan[ST_LSM6DSX_ID_ACC].channels)); + offset += sizeof(hw->scan[ST_LSM6DSX_ID_ACC].channels); } if (ext_sip > 0 && !(sip % ext_sensor->decimator)) { - memcpy(ext_buff, &hw->buff[offset], - ST_LSM6DSX_SAMPLE_SIZE); - offset += ST_LSM6DSX_SAMPLE_SIZE; + memcpy(hw->scan[ST_LSM6DSX_ID_EXT0].channels, + &hw->buff[offset], + sizeof(hw->scan[ST_LSM6DSX_ID_EXT0].channels)); + offset += sizeof(hw->scan[ST_LSM6DSX_ID_EXT0].channels); } if (ts_sip-- > 0) { @@ -458,19 +458,22 @@ int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw) if (gyro_sip > 0 && !(sip % gyro_sensor->decimator)) { iio_push_to_buffers_with_timestamp( hw->iio_devs[ST_LSM6DSX_ID_GYRO], - gyro_buff, gyro_sensor->ts_ref + ts); + &hw->scan[ST_LSM6DSX_ID_GYRO], + gyro_sensor->ts_ref + ts); gyro_sip--; } if (acc_sip > 0 && !(sip % acc_sensor->decimator)) { iio_push_to_buffers_with_timestamp( hw->iio_devs[ST_LSM6DSX_ID_ACC], - acc_buff, acc_sensor->ts_ref + ts); + &hw->scan[ST_LSM6DSX_ID_ACC], + acc_sensor->ts_ref + ts); acc_sip--; } if (ext_sip > 0 && !(sip % ext_sensor->decimator)) { iio_push_to_buffers_with_timestamp( hw->iio_devs[ST_LSM6DSX_ID_EXT0], - ext_buff, ext_sensor->ts_ref + ts); + &hw->scan[ST_LSM6DSX_ID_EXT0], + ext_sensor->ts_ref + ts); ext_sip--; } sip++; @@ -555,7 +558,14 @@ int st_lsm6dsx_read_tagged_fifo(struct st_lsm6dsx_hw *hw) { u16 pattern_len = hw->sip * ST_LSM6DSX_TAGGED_SAMPLE_SIZE; u16 fifo_len, fifo_diff_mask; - u8 iio_buff[ST_LSM6DSX_IIO_BUFF_SIZE], tag; + /* + * Alignment needed as this can ultimately be passed to a + * call to iio_push_to_buffers_with_timestamp() which + * must be passed a buffer that is aligned to 8 bytes so + * as to allow insertion of a naturally aligned timestamp. + */ + u8 iio_buff[ST_LSM6DSX_IIO_BUFF_SIZE] __aligned(8); + u8 tag; bool reset_ts = false; int i, err, read_len; __le16 fifo_status; diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c index 346c24281d26..42f485634d04 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c @@ -157,10 +157,10 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .addr = 0x20, .mask = GENMASK(4, 3), }, - .fs_avl[0] = { IIO_G_TO_M_S_2(61), 0x0 }, - .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 }, - .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 }, - .fs_avl[3] = { IIO_G_TO_M_S_2(732), 0x1 }, + .fs_avl[0] = { IIO_G_TO_M_S_2(61000), 0x0 }, + .fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x2 }, + .fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x3 }, + .fs_avl[3] = { IIO_G_TO_M_S_2(732000), 0x1 }, .fs_len = 4, }, [ST_LSM6DSX_ID_GYRO] = { @@ -169,9 +169,9 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .mask = GENMASK(4, 3), }, - .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750), 0x0 }, - .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 }, - .fs_avl[2] = { IIO_DEGREE_TO_RAD(70000), 0x3 }, + .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750000), 0x0 }, + .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x1 }, + .fs_avl[2] = { IIO_DEGREE_TO_RAD(70000000), 0x3 }, .fs_len = 3, }, }, @@ -259,10 +259,10 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .addr = 0x10, .mask = GENMASK(3, 2), }, - .fs_avl[0] = { IIO_G_TO_M_S_2(61), 0x0 }, - .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 }, - .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 }, - .fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 }, + .fs_avl[0] = { IIO_G_TO_M_S_2(61000), 0x0 }, + .fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x2 }, + .fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x3 }, + .fs_avl[3] = { IIO_G_TO_M_S_2(488000), 0x1 }, .fs_len = 4, }, [ST_LSM6DSX_ID_GYRO] = { @@ -270,10 +270,10 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .addr = 0x11, .mask = GENMASK(3, 2), }, - .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750), 0x0 }, - .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 }, - .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 }, - .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 }, + .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750000), 0x0 }, + .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x1 }, + .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000000), 0x2 }, + .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000000), 0x3 }, .fs_len = 4, }, }, @@ -425,10 +425,10 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .addr = 0x10, .mask = GENMASK(3, 2), }, - .fs_avl[0] = { IIO_G_TO_M_S_2(61), 0x0 }, - .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 }, - .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 }, - .fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 }, + .fs_avl[0] = { IIO_G_TO_M_S_2(61000), 0x0 }, + .fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x2 }, + .fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x3 }, + .fs_avl[3] = { IIO_G_TO_M_S_2(488000), 0x1 }, .fs_len = 4, }, [ST_LSM6DSX_ID_GYRO] = { @@ -436,10 +436,10 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .addr = 0x11, .mask = GENMASK(3, 2), }, - .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750), 0x0 }, - .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 }, - .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 }, - .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 }, + .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750000), 0x0 }, + .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x1 }, + .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000000), 0x2 }, + .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000000), 0x3 }, .fs_len = 4, }, }, @@ -600,10 +600,10 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .addr = 0x10, .mask = GENMASK(3, 2), }, - .fs_avl[0] = { IIO_G_TO_M_S_2(61), 0x0 }, - .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 }, - .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 }, - .fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 }, + .fs_avl[0] = { IIO_G_TO_M_S_2(61000), 0x0 }, + .fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x2 }, + .fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x3 }, + .fs_avl[3] = { IIO_G_TO_M_S_2(488000), 0x1 }, .fs_len = 4, }, [ST_LSM6DSX_ID_GYRO] = { @@ -611,10 +611,10 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .addr = 0x11, .mask = GENMASK(3, 2), }, - .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750), 0x0 }, - .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 }, - .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 }, - .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 }, + .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750000), 0x0 }, + .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x1 }, + .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000000), 0x2 }, + .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000000), 0x3 }, .fs_len = 4, }, }, @@ -816,10 +816,10 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .addr = 0x10, .mask = GENMASK(3, 2), }, - .fs_avl[0] = { IIO_G_TO_M_S_2(61), 0x0 }, - .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 }, - .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 }, - .fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 }, + .fs_avl[0] = { IIO_G_TO_M_S_2(61000), 0x0 }, + .fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x2 }, + .fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x3 }, + .fs_avl[3] = { IIO_G_TO_M_S_2(488000), 0x1 }, .fs_len = 4, }, [ST_LSM6DSX_ID_GYRO] = { @@ -827,10 +827,10 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .addr = 0x11, .mask = GENMASK(3, 2), }, - .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750), 0x0 }, - .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 }, - .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 }, - .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 }, + .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750000), 0x0 }, + .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x1 }, + .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000000), 0x2 }, + .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000000), 0x3 }, .fs_len = 4, }, }, @@ -1021,10 +1021,10 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .addr = 0x10, .mask = GENMASK(3, 2), }, - .fs_avl[0] = { IIO_G_TO_M_S_2(61), 0x0 }, - .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 }, - .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 }, - .fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 }, + .fs_avl[0] = { IIO_G_TO_M_S_2(61000), 0x0 }, + .fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x2 }, + .fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x3 }, + .fs_avl[3] = { IIO_G_TO_M_S_2(488000), 0x1 }, .fs_len = 4, }, [ST_LSM6DSX_ID_GYRO] = { @@ -1032,10 +1032,10 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .addr = 0x11, .mask = GENMASK(3, 2), }, - .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750), 0x0 }, - .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 }, - .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 }, - .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 }, + .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750000), 0x0 }, + .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x1 }, + .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000000), 0x2 }, + .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000000), 0x3 }, .fs_len = 4, }, }, @@ -1200,10 +1200,10 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .addr = 0x10, .mask = GENMASK(3, 2), }, - .fs_avl[0] = { IIO_G_TO_M_S_2(61), 0x0 }, - .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 }, - .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 }, - .fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 }, + .fs_avl[0] = { IIO_G_TO_M_S_2(61000), 0x0 }, + .fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x2 }, + .fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x3 }, + .fs_avl[3] = { IIO_G_TO_M_S_2(488000), 0x1 }, .fs_len = 4, }, [ST_LSM6DSX_ID_GYRO] = { @@ -1211,10 +1211,10 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .addr = 0x11, .mask = GENMASK(3, 2), }, - .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750), 0x0 }, - .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 }, - .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 }, - .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 }, + .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750000), 0x0 }, + .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x1 }, + .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000000), 0x2 }, + .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000000), 0x3 }, .fs_len = 4, }, }, @@ -1598,7 +1598,7 @@ static int st_lsm6dsx_read_raw(struct iio_dev *iio_dev, case IIO_CHAN_INFO_SCALE: *val = 0; *val2 = sensor->gain; - ret = IIO_VAL_INT_PLUS_MICRO; + ret = IIO_VAL_INT_PLUS_NANO; break; default: ret = -EINVAL; @@ -1836,13 +1836,31 @@ static ssize_t st_lsm6dsx_sysfs_scale_avail(struct device *dev, fs_table = &hw->settings->fs_table[sensor->id]; for (i = 0; i < fs_table->fs_len; i++) - len += scnprintf(buf + len, PAGE_SIZE - len, "0.%06u ", + len += scnprintf(buf + len, PAGE_SIZE - len, "0.%09u ", fs_table->fs_avl[i].gain); buf[len - 1] = '\n'; return len; } +static int st_lsm6dsx_write_raw_get_fmt(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + long mask) +{ + switch (mask) { + case IIO_CHAN_INFO_SCALE: + switch (chan->type) { + case IIO_ANGL_VEL: + case IIO_ACCEL: + return IIO_VAL_INT_PLUS_NANO; + default: + return IIO_VAL_INT_PLUS_MICRO; + } + default: + return IIO_VAL_INT_PLUS_MICRO; + } +} + static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(st_lsm6dsx_sysfs_sampling_frequency_avail); static IIO_DEVICE_ATTR(in_accel_scale_available, 0444, st_lsm6dsx_sysfs_scale_avail, NULL, 0); @@ -1868,6 +1886,7 @@ static const struct iio_info st_lsm6dsx_acc_info = { .read_event_config = st_lsm6dsx_read_event_config, .write_event_config = st_lsm6dsx_write_event_config, .hwfifo_set_watermark = st_lsm6dsx_set_watermark, + .write_raw_get_fmt = st_lsm6dsx_write_raw_get_fmt, }; static struct attribute *st_lsm6dsx_gyro_attributes[] = { @@ -1885,6 +1904,7 @@ static const struct iio_info st_lsm6dsx_gyro_info = { .read_raw = st_lsm6dsx_read_raw, .write_raw = st_lsm6dsx_write_raw, .hwfifo_set_watermark = st_lsm6dsx_set_watermark, + .write_raw_get_fmt = st_lsm6dsx_write_raw_get_fmt, }; static int st_lsm6dsx_get_drdy_pin(struct st_lsm6dsx_hw *hw, int *drdy_pin) diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_shub.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_shub.c index ed83471dc7dd..8c8d8870ca07 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_shub.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_shub.c @@ -313,6 +313,8 @@ st_lsm6dsx_shub_read(struct st_lsm6dsx_sensor *sensor, u8 addr, err = st_lsm6dsx_shub_read_output(hw, data, len & ST_LS6DSX_READ_OP_MASK); + if (err < 0) + return err; st_lsm6dsx_shub_master_enable(sensor, false); diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c index a7d7e5143ed2..a4f6bb96d4f4 100644 --- a/drivers/iio/industrialio-buffer.c +++ b/drivers/iio/industrialio-buffer.c @@ -1264,26 +1264,14 @@ static struct attribute *iio_buffer_attrs[] = { &dev_attr_data_available.attr, }; -int iio_buffer_alloc_sysfs_and_mask(struct iio_dev *indio_dev) +static int __iio_buffer_alloc_sysfs_and_mask(struct iio_buffer *buffer, + struct iio_dev *indio_dev) { struct iio_dev_attr *p; struct attribute **attr; - struct iio_buffer *buffer = indio_dev->buffer; int ret, i, attrn, attrcount; const struct iio_chan_spec *channels; - channels = indio_dev->channels; - if (channels) { - int ml = indio_dev->masklength; - - for (i = 0; i < indio_dev->num_channels; i++) - ml = max(ml, channels[i].scan_index + 1); - indio_dev->masklength = ml; - } - - if (!buffer) - return 0; - attrcount = 0; if (buffer->attrs) { while (buffer->attrs[attrcount] != NULL) @@ -1367,19 +1355,45 @@ error_cleanup_dynamic: return ret; } -void iio_buffer_free_sysfs_and_mask(struct iio_dev *indio_dev) +int iio_buffer_alloc_sysfs_and_mask(struct iio_dev *indio_dev) { struct iio_buffer *buffer = indio_dev->buffer; + const struct iio_chan_spec *channels; + int i; + + channels = indio_dev->channels; + if (channels) { + int ml = indio_dev->masklength; + + for (i = 0; i < indio_dev->num_channels; i++) + ml = max(ml, channels[i].scan_index + 1); + indio_dev->masklength = ml; + } if (!buffer) - return; + return 0; + + return __iio_buffer_alloc_sysfs_and_mask(buffer, indio_dev); +} +static void __iio_buffer_free_sysfs_and_mask(struct iio_buffer *buffer) +{ bitmap_free(buffer->scan_mask); kfree(buffer->buffer_group.attrs); kfree(buffer->scan_el_group.attrs); iio_free_chan_devattr_list(&buffer->scan_el_dev_attr_list); } +void iio_buffer_free_sysfs_and_mask(struct iio_dev *indio_dev) +{ + struct iio_buffer *buffer = indio_dev->buffer; + + if (!buffer) + return; + + __iio_buffer_free_sysfs_and_mask(buffer); +} + /** * iio_validate_scan_mask_onehot() - Validates that exactly one channel is selected * @indio_dev: the iio device diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index cdcd16f19500..261d3b17edc9 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -133,6 +133,7 @@ static const char * const iio_modifier_names[] = { [IIO_MOD_PM10] = "pm10", [IIO_MOD_ETHANOL] = "ethanol", [IIO_MOD_H2] = "h2", + [IIO_MOD_O2] = "o2", }; /* relies on pairs of these shared then separate */ @@ -165,10 +166,11 @@ static const char * const iio_chan_info_postfix[] = { [IIO_CHAN_INFO_CALIBEMISSIVITY] = "calibemissivity", [IIO_CHAN_INFO_OVERSAMPLING_RATIO] = "oversampling_ratio", [IIO_CHAN_INFO_THERMOCOUPLE_TYPE] = "thermocouple_type", + [IIO_CHAN_INFO_CALIBAMBIENT] = "calibambient", }; #if defined(CONFIG_DEBUG_FS) -/** +/* * There's also a CONFIG_DEBUG_FS guard in include/linux/iio/iio.h for * iio_get_debugfs_dentry() to make it inline if CONFIG_DEBUG_FS is undefined */ @@ -1523,6 +1525,7 @@ struct device_type iio_device_type = { /** * iio_device_alloc() - allocate an iio_dev from a driver + * @parent: Parent device. * @sizeof_priv: Space to allocate for private structure. **/ struct iio_dev *iio_device_alloc(struct device *parent, int sizeof_priv) diff --git a/drivers/iio/industrialio-event.c b/drivers/iio/industrialio-event.c index 2ab4d4c44427..99ba657b8568 100644 --- a/drivers/iio/industrialio-event.c +++ b/drivers/iio/industrialio-event.c @@ -477,6 +477,7 @@ static const char *iio_event_group_name = "events"; int iio_device_register_eventset(struct iio_dev *indio_dev) { struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev); + struct iio_event_interface *ev_int; struct iio_dev_attr *p; int ret = 0, attrcount_orig = 0, attrcount, attrn; struct attribute **attr; @@ -485,14 +486,15 @@ int iio_device_register_eventset(struct iio_dev *indio_dev) iio_check_for_dynamic_events(indio_dev))) return 0; - iio_dev_opaque->event_interface = - kzalloc(sizeof(struct iio_event_interface), GFP_KERNEL); - if (iio_dev_opaque->event_interface == NULL) + ev_int = kzalloc(sizeof(struct iio_event_interface), GFP_KERNEL); + if (ev_int == NULL) return -ENOMEM; - INIT_LIST_HEAD(&iio_dev_opaque->event_interface->dev_attr_list); + iio_dev_opaque->event_interface = ev_int; - iio_setup_ev_int(iio_dev_opaque->event_interface); + INIT_LIST_HEAD(&ev_int->dev_attr_list); + + iio_setup_ev_int(ev_int); if (indio_dev->info->event_attrs != NULL) { attr = indio_dev->info->event_attrs->attrs; while (*attr++ != NULL) @@ -506,34 +508,29 @@ int iio_device_register_eventset(struct iio_dev *indio_dev) attrcount += ret; } - iio_dev_opaque->event_interface->group.name = iio_event_group_name; - iio_dev_opaque->event_interface->group.attrs = kcalloc(attrcount + 1, - sizeof(iio_dev_opaque->event_interface->group.attrs[0]), - GFP_KERNEL); - if (iio_dev_opaque->event_interface->group.attrs == NULL) { + ev_int->group.name = iio_event_group_name; + ev_int->group.attrs = kcalloc(attrcount + 1, + sizeof(ev_int->group.attrs[0]), + GFP_KERNEL); + if (ev_int->group.attrs == NULL) { ret = -ENOMEM; goto error_free_setup_event_lines; } if (indio_dev->info->event_attrs) - memcpy(iio_dev_opaque->event_interface->group.attrs, + memcpy(ev_int->group.attrs, indio_dev->info->event_attrs->attrs, - sizeof(iio_dev_opaque->event_interface->group.attrs[0]) - *attrcount_orig); + sizeof(ev_int->group.attrs[0]) * attrcount_orig); attrn = attrcount_orig; /* Add all elements from the list. */ - list_for_each_entry(p, - &iio_dev_opaque->event_interface->dev_attr_list, - l) - iio_dev_opaque->event_interface->group.attrs[attrn++] = - &p->dev_attr.attr; - indio_dev->groups[indio_dev->groupcounter++] = - &iio_dev_opaque->event_interface->group; + list_for_each_entry(p, &ev_int->dev_attr_list, l) + ev_int->group.attrs[attrn++] = &p->dev_attr.attr; + indio_dev->groups[indio_dev->groupcounter++] = &ev_int->group; return 0; error_free_setup_event_lines: - iio_free_chan_devattr_list(&iio_dev_opaque->event_interface->dev_attr_list); - kfree(iio_dev_opaque->event_interface); + iio_free_chan_devattr_list(&ev_int->dev_attr_list); + kfree(ev_int); iio_dev_opaque->event_interface = NULL; return ret; } @@ -557,10 +554,12 @@ void iio_device_wakeup_eventset(struct iio_dev *indio_dev) void iio_device_unregister_eventset(struct iio_dev *indio_dev) { struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev); + struct iio_event_interface *ev_int = iio_dev_opaque->event_interface; - if (iio_dev_opaque->event_interface == NULL) + if (ev_int == NULL) return; - iio_free_chan_devattr_list(&iio_dev_opaque->event_interface->dev_attr_list); - kfree(iio_dev_opaque->event_interface->group.attrs); - kfree(iio_dev_opaque->event_interface); + iio_free_chan_devattr_list(&ev_int->dev_attr_list); + kfree(ev_int->group.attrs); + kfree(ev_int); + iio_dev_opaque->event_interface = NULL; } diff --git a/drivers/iio/industrialio-trigger.c b/drivers/iio/industrialio-trigger.c index 6f16357fd732..583bb51f65a7 100644 --- a/drivers/iio/industrialio-trigger.c +++ b/drivers/iio/industrialio-trigger.c @@ -516,7 +516,8 @@ static void iio_trig_subirqunmask(struct irq_data *d) trig->subirqs[d->irq - trig->subirq_base].enabled = true; } -static struct iio_trigger *viio_trigger_alloc(const char *fmt, va_list vargs) +static __printf(1, 0) +struct iio_trigger *viio_trigger_alloc(const char *fmt, va_list vargs) { struct iio_trigger *trig; int i; diff --git a/drivers/iio/light/Kconfig b/drivers/iio/light/Kconfig index 182bd18c4bb2..cade6dc0305b 100644 --- a/drivers/iio/light/Kconfig +++ b/drivers/iio/light/Kconfig @@ -86,6 +86,21 @@ config APDS9960 To compile this driver as a module, choose M here: the module will be called apds9960 +config AS73211 + tristate "AMS AS73211 XYZ color sensor" + depends on I2C + select IIO_BUFFER + select IIO_TRIGGERED_BUFFER + help + If you say yes here you get support for the AMS AS73211 + JENCOLOR(R) Digital XYZ Sensor. + + For triggered measurements, you will need an additional trigger driver + like IIO_HRTIMER_TRIGGER or IIO_SYSFS_TRIGGER. + + This driver can also be built as a module. If so, the module + will be called as73211. + config BH1750 tristate "ROHM BH1750 ambient light sensor" depends on I2C diff --git a/drivers/iio/light/Makefile b/drivers/iio/light/Makefile index d1c8aa30b9a8..ea376deaca54 100644 --- a/drivers/iio/light/Makefile +++ b/drivers/iio/light/Makefile @@ -11,6 +11,7 @@ obj-$(CONFIG_AL3010) += al3010.o obj-$(CONFIG_AL3320A) += al3320a.o obj-$(CONFIG_APDS9300) += apds9300.o obj-$(CONFIG_APDS9960) += apds9960.o +obj-$(CONFIG_AS73211) += as73211.o obj-$(CONFIG_BH1750) += bh1750.o obj-$(CONFIG_BH1780) += bh1780.o obj-$(CONFIG_CM32181) += cm32181.o diff --git a/drivers/iio/light/as73211.c b/drivers/iio/light/as73211.c new file mode 100644 index 000000000000..7b32dfaee9b3 --- /dev/null +++ b/drivers/iio/light/as73211.c @@ -0,0 +1,800 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Support for AMS AS73211 JENCOLOR(R) Digital XYZ Sensor + * + * Author: Christian Eggers <ceggers@arri.de> + * + * Copyright (c) 2020 ARRI Lighting + * + * Color light sensor with 16-bit channels for x, y, z and temperature); + * 7-bit I2C slave address 0x74 .. 0x77. + * + * Datasheet: https://ams.com/documents/20143/36005/AS73211_DS000556_3-01.pdf + */ + +#include <linux/bitfield.h> +#include <linux/completion.h> +#include <linux/delay.h> +#include <linux/i2c.h> +#include <linux/iio/buffer.h> +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> +#include <linux/iio/trigger_consumer.h> +#include <linux/iio/triggered_buffer.h> +#include <linux/module.h> +#include <linux/mutex.h> +#include <linux/pm.h> + +#define HZ_PER_KHZ 1000 + +#define AS73211_DRV_NAME "as73211" + +/* AS73211 configuration registers */ +#define AS73211_REG_OSR 0x0 +#define AS73211_REG_AGEN 0x2 +#define AS73211_REG_CREG1 0x6 +#define AS73211_REG_CREG2 0x7 +#define AS73211_REG_CREG3 0x8 + +/* AS73211 output register bank */ +#define AS73211_OUT_OSR_STATUS 0 +#define AS73211_OUT_TEMP 1 +#define AS73211_OUT_MRES1 2 +#define AS73211_OUT_MRES2 3 +#define AS73211_OUT_MRES3 4 + +#define AS73211_OSR_SS BIT(7) +#define AS73211_OSR_PD BIT(6) +#define AS73211_OSR_SW_RES BIT(3) +#define AS73211_OSR_DOS_MASK GENMASK(2, 0) +#define AS73211_OSR_DOS_CONFIG FIELD_PREP(AS73211_OSR_DOS_MASK, 0x2) +#define AS73211_OSR_DOS_MEASURE FIELD_PREP(AS73211_OSR_DOS_MASK, 0x3) + +#define AS73211_AGEN_DEVID_MASK GENMASK(7, 4) +#define AS73211_AGEN_DEVID(x) FIELD_PREP(AS73211_AGEN_DEVID_MASK, (x)) +#define AS73211_AGEN_MUT_MASK GENMASK(3, 0) +#define AS73211_AGEN_MUT(x) FIELD_PREP(AS73211_AGEN_MUT_MASK, (x)) + +#define AS73211_CREG1_GAIN_MASK GENMASK(7, 4) +#define AS73211_CREG1_GAIN_1 11 +#define AS73211_CREG1_TIME_MASK GENMASK(3, 0) + +#define AS73211_CREG3_CCLK_MASK GENMASK(1, 0) + +#define AS73211_OSR_STATUS_OUTCONVOF BIT(15) +#define AS73211_OSR_STATUS_MRESOF BIT(14) +#define AS73211_OSR_STATUS_ADCOF BIT(13) +#define AS73211_OSR_STATUS_LDATA BIT(12) +#define AS73211_OSR_STATUS_NDATA BIT(11) +#define AS73211_OSR_STATUS_NOTREADY BIT(10) + +#define AS73211_SAMPLE_FREQ_BASE 1024000 + +#define AS73211_SAMPLE_TIME_NUM 15 +#define AS73211_SAMPLE_TIME_MAX_MS BIT(AS73211_SAMPLE_TIME_NUM - 1) + +/* Available sample frequencies are 1.024MHz multiplied by powers of two. */ +static const int as73211_samp_freq_avail[] = { + AS73211_SAMPLE_FREQ_BASE * 1, + AS73211_SAMPLE_FREQ_BASE * 2, + AS73211_SAMPLE_FREQ_BASE * 4, + AS73211_SAMPLE_FREQ_BASE * 8, +}; + +static const int as73211_hardwaregain_avail[] = { + 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, +}; + +/** + * struct as73211_data - Instance data for one AS73211 + * @client: I2C client. + * @osr: Cached Operational State Register. + * @creg1: Cached Configuration Register 1. + * @creg2: Cached Configuration Register 2. + * @creg3: Cached Configuration Register 3. + * @mutex: Keeps cached registers in sync with the device. + * @completion: Completion to wait for interrupt. + * @int_time_avail: Available integration times (depend on sampling frequency). + */ +struct as73211_data { + struct i2c_client *client; + u8 osr; + u8 creg1; + u8 creg2; + u8 creg3; + struct mutex mutex; + struct completion completion; + int int_time_avail[AS73211_SAMPLE_TIME_NUM * 2]; +}; + +#define AS73211_COLOR_CHANNEL(_color, _si, _addr) { \ + .type = IIO_INTENSITY, \ + .modified = 1, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), \ + .info_mask_shared_by_type = \ + BIT(IIO_CHAN_INFO_SAMP_FREQ) | \ + BIT(IIO_CHAN_INFO_HARDWAREGAIN) | \ + BIT(IIO_CHAN_INFO_INT_TIME), \ + .info_mask_shared_by_type_available = \ + BIT(IIO_CHAN_INFO_SAMP_FREQ) | \ + BIT(IIO_CHAN_INFO_HARDWAREGAIN) | \ + BIT(IIO_CHAN_INFO_INT_TIME), \ + .channel2 = IIO_MOD_##_color, \ + .address = _addr, \ + .scan_index = _si, \ + .scan_type = { \ + .sign = 'u', \ + .realbits = 16, \ + .storagebits = 16, \ + .endianness = IIO_LE, \ + }, \ +} + +#define AS73211_OFFSET_TEMP_INT (-66) +#define AS73211_OFFSET_TEMP_MICRO 900000 +#define AS73211_SCALE_TEMP_INT 0 +#define AS73211_SCALE_TEMP_MICRO 50000 + +#define AS73211_SCALE_X 277071108 /* nW/m^2 */ +#define AS73211_SCALE_Y 298384270 /* nW/m^2 */ +#define AS73211_SCALE_Z 160241927 /* nW/m^2 */ + +/* Channel order MUST match devices result register order */ +#define AS73211_SCAN_INDEX_TEMP 0 +#define AS73211_SCAN_INDEX_X 1 +#define AS73211_SCAN_INDEX_Y 2 +#define AS73211_SCAN_INDEX_Z 3 +#define AS73211_SCAN_INDEX_TS 4 + +#define AS73211_SCAN_MASK_COLOR ( \ + BIT(AS73211_SCAN_INDEX_X) | \ + BIT(AS73211_SCAN_INDEX_Y) | \ + BIT(AS73211_SCAN_INDEX_Z)) + +#define AS73211_SCAN_MASK_ALL ( \ + BIT(AS73211_SCAN_INDEX_TEMP) | \ + AS73211_SCAN_MASK_COLOR) + +static const struct iio_chan_spec as73211_channels[] = { + { + .type = IIO_TEMP, + .info_mask_separate = + BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_OFFSET) | + BIT(IIO_CHAN_INFO_SCALE), + .address = AS73211_OUT_TEMP, + .scan_index = AS73211_SCAN_INDEX_TEMP, + .scan_type = { + .sign = 'u', + .realbits = 16, + .storagebits = 16, + .endianness = IIO_LE, + } + }, + AS73211_COLOR_CHANNEL(X, AS73211_SCAN_INDEX_X, AS73211_OUT_MRES1), + AS73211_COLOR_CHANNEL(Y, AS73211_SCAN_INDEX_Y, AS73211_OUT_MRES2), + AS73211_COLOR_CHANNEL(Z, AS73211_SCAN_INDEX_Z, AS73211_OUT_MRES3), + IIO_CHAN_SOFT_TIMESTAMP(AS73211_SCAN_INDEX_TS), +}; + +static unsigned int as73211_integration_time_1024cyc(struct as73211_data *data) +{ + /* + * Return integration time in units of 1024 clock cycles. Integration time + * in CREG1 is in powers of 2 (x 1024 cycles). + */ + return BIT(FIELD_GET(AS73211_CREG1_TIME_MASK, data->creg1)); +} + +static unsigned int as73211_integration_time_us(struct as73211_data *data, + unsigned int integration_time_1024cyc) +{ + /* + * f_samp is configured in CREG3 in powers of 2 (x 1.024 MHz) + * t_cycl is configured in CREG1 in powers of 2 (x 1024 cycles) + * t_int_us = 1 / (f_samp) * t_cycl * US_PER_SEC + * = 1 / (2^CREG3_CCLK * 1,024,000) * 2^CREG1_CYCLES * 1,024 * US_PER_SEC + * = 2^(-CREG3_CCLK) * 2^CREG1_CYCLES * 1,000 + * In order to get rid of negative exponents, we extend the "fraction" + * by 2^3 (CREG3_CCLK,max = 3) + * t_int_us = 2^(3-CREG3_CCLK) * 2^CREG1_CYCLES * 125 + */ + return BIT(3 - FIELD_GET(AS73211_CREG3_CCLK_MASK, data->creg3)) * + integration_time_1024cyc * 125; +} + +static void as73211_integration_time_calc_avail(struct as73211_data *data) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(data->int_time_avail) / 2; i++) { + unsigned int time_us = as73211_integration_time_us(data, BIT(i)); + + data->int_time_avail[i * 2 + 0] = time_us / USEC_PER_SEC; + data->int_time_avail[i * 2 + 1] = time_us % USEC_PER_SEC; + } +} + +static unsigned int as73211_gain(struct as73211_data *data) +{ + /* gain can be calculated from CREG1 as 2^(11 - CREG1_GAIN) */ + return BIT(AS73211_CREG1_GAIN_1 - FIELD_GET(AS73211_CREG1_GAIN_MASK, data->creg1)); +} + +/* must be called with as73211_data::mutex held. */ +static int as73211_req_data(struct as73211_data *data) +{ + unsigned int time_us = as73211_integration_time_us(data, + as73211_integration_time_1024cyc(data)); + struct device *dev = &data->client->dev; + union i2c_smbus_data smbus_data; + u16 osr_status; + int ret; + + if (data->client->irq) + reinit_completion(&data->completion); + + /* + * During measurement, there should be no traffic on the i2c bus as the + * electrical noise would disturb the measurement process. + */ + i2c_lock_bus(data->client->adapter, I2C_LOCK_SEGMENT); + + data->osr &= ~AS73211_OSR_DOS_MASK; + data->osr |= AS73211_OSR_DOS_MEASURE | AS73211_OSR_SS; + + smbus_data.byte = data->osr; + ret = __i2c_smbus_xfer(data->client->adapter, data->client->addr, + data->client->flags, I2C_SMBUS_WRITE, + AS73211_REG_OSR, I2C_SMBUS_BYTE_DATA, &smbus_data); + if (ret < 0) { + i2c_unlock_bus(data->client->adapter, I2C_LOCK_SEGMENT); + return ret; + } + + /* + * Reset AS73211_OSR_SS (is self clearing) in order to avoid unintentional + * triggering of further measurements later. + */ + data->osr &= ~AS73211_OSR_SS; + + /* + * Add 33% extra margin for the timeout. fclk,min = fclk,typ - 27%. + */ + time_us += time_us / 3; + if (data->client->irq) { + ret = wait_for_completion_timeout(&data->completion, usecs_to_jiffies(time_us)); + if (!ret) { + dev_err(dev, "timeout waiting for READY IRQ\n"); + i2c_unlock_bus(data->client->adapter, I2C_LOCK_SEGMENT); + return -ETIMEDOUT; + } + } else { + /* Wait integration time */ + usleep_range(time_us, 2 * time_us); + } + + i2c_unlock_bus(data->client->adapter, I2C_LOCK_SEGMENT); + + ret = i2c_smbus_read_word_data(data->client, AS73211_OUT_OSR_STATUS); + if (ret < 0) + return ret; + + osr_status = ret; + if (osr_status != (AS73211_OSR_DOS_MEASURE | AS73211_OSR_STATUS_NDATA)) { + if (osr_status & AS73211_OSR_SS) { + dev_err(dev, "%s() Measurement has not stopped\n", __func__); + return -ETIME; + } + if (osr_status & AS73211_OSR_STATUS_NOTREADY) { + dev_err(dev, "%s() Data is not ready\n", __func__); + return -ENODATA; + } + if (!(osr_status & AS73211_OSR_STATUS_NDATA)) { + dev_err(dev, "%s() No new data available\n", __func__); + return -ENODATA; + } + if (osr_status & AS73211_OSR_STATUS_LDATA) { + dev_err(dev, "%s() Result buffer overrun\n", __func__); + return -ENOBUFS; + } + if (osr_status & AS73211_OSR_STATUS_ADCOF) { + dev_err(dev, "%s() ADC overflow\n", __func__); + return -EOVERFLOW; + } + if (osr_status & AS73211_OSR_STATUS_MRESOF) { + dev_err(dev, "%s() Measurement result overflow\n", __func__); + return -EOVERFLOW; + } + if (osr_status & AS73211_OSR_STATUS_OUTCONVOF) { + dev_err(dev, "%s() Timer overflow\n", __func__); + return -EOVERFLOW; + } + dev_err(dev, "%s() Unexpected status value\n", __func__); + return -EIO; + } + + return 0; +} + +static int as73211_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, + int *val, int *val2, long mask) +{ + struct as73211_data *data = iio_priv(indio_dev); + + switch (mask) { + case IIO_CHAN_INFO_RAW: { + int ret; + + ret = iio_device_claim_direct_mode(indio_dev); + if (ret < 0) + return ret; + + ret = as73211_req_data(data); + if (ret < 0) { + iio_device_release_direct_mode(indio_dev); + return ret; + } + + ret = i2c_smbus_read_word_data(data->client, chan->address); + iio_device_release_direct_mode(indio_dev); + if (ret < 0) + return ret; + + *val = ret; + return IIO_VAL_INT; + } + case IIO_CHAN_INFO_OFFSET: + *val = AS73211_OFFSET_TEMP_INT; + *val2 = AS73211_OFFSET_TEMP_MICRO; + return IIO_VAL_INT_PLUS_MICRO; + + case IIO_CHAN_INFO_SCALE: + switch (chan->type) { + case IIO_TEMP: + *val = AS73211_SCALE_TEMP_INT; + *val2 = AS73211_SCALE_TEMP_MICRO; + return IIO_VAL_INT_PLUS_MICRO; + + case IIO_INTENSITY: { + unsigned int scale; + + switch (chan->channel2) { + case IIO_MOD_X: + scale = AS73211_SCALE_X; + break; + case IIO_MOD_Y: + scale = AS73211_SCALE_Y; + break; + case IIO_MOD_Z: + scale = AS73211_SCALE_Z; + break; + default: + return -EINVAL; + } + scale /= as73211_gain(data); + scale /= as73211_integration_time_1024cyc(data); + *val = scale; + return IIO_VAL_INT; + + default: + return -EINVAL; + }} + + case IIO_CHAN_INFO_SAMP_FREQ: + /* f_samp is configured in CREG3 in powers of 2 (x 1.024 MHz) */ + *val = BIT(FIELD_GET(AS73211_CREG3_CCLK_MASK, data->creg3)) * + AS73211_SAMPLE_FREQ_BASE; + return IIO_VAL_INT; + + case IIO_CHAN_INFO_HARDWAREGAIN: + *val = as73211_gain(data); + return IIO_VAL_INT; + + case IIO_CHAN_INFO_INT_TIME: { + unsigned int time_us; + + mutex_lock(&data->mutex); + time_us = as73211_integration_time_us(data, as73211_integration_time_1024cyc(data)); + mutex_unlock(&data->mutex); + *val = time_us / USEC_PER_SEC; + *val2 = time_us % USEC_PER_SEC; + return IIO_VAL_INT_PLUS_MICRO; + + default: + return -EINVAL; + }} +} + +static int as73211_read_avail(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, + const int **vals, int *type, int *length, long mask) +{ + struct as73211_data *data = iio_priv(indio_dev); + + switch (mask) { + case IIO_CHAN_INFO_SAMP_FREQ: + *length = ARRAY_SIZE(as73211_samp_freq_avail); + *vals = as73211_samp_freq_avail; + *type = IIO_VAL_INT; + return IIO_AVAIL_LIST; + + case IIO_CHAN_INFO_HARDWAREGAIN: + *length = ARRAY_SIZE(as73211_hardwaregain_avail); + *vals = as73211_hardwaregain_avail; + *type = IIO_VAL_INT; + return IIO_AVAIL_LIST; + + case IIO_CHAN_INFO_INT_TIME: + *length = ARRAY_SIZE(data->int_time_avail); + *vals = data->int_time_avail; + *type = IIO_VAL_INT_PLUS_MICRO; + return IIO_AVAIL_LIST; + + default: + return -EINVAL; + } +} + +static int _as73211_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan __always_unused, + int val, int val2, long mask) +{ + struct as73211_data *data = iio_priv(indio_dev); + int ret; + + switch (mask) { + case IIO_CHAN_INFO_SAMP_FREQ: { + int reg_bits, freq_kHz = val / HZ_PER_KHZ; /* 1024, 2048, ... */ + + /* val must be 1024 * 2^x */ + if (val < 0 || (freq_kHz * HZ_PER_KHZ) != val || + !is_power_of_2(freq_kHz) || val2) + return -EINVAL; + + /* f_samp is configured in CREG3 in powers of 2 (x 1.024 MHz (=2^10)) */ + reg_bits = ilog2(freq_kHz) - 10; + if (!FIELD_FIT(AS73211_CREG3_CCLK_MASK, reg_bits)) + return -EINVAL; + + data->creg3 &= ~AS73211_CREG3_CCLK_MASK; + data->creg3 |= FIELD_PREP(AS73211_CREG3_CCLK_MASK, reg_bits); + as73211_integration_time_calc_avail(data); + + ret = i2c_smbus_write_byte_data(data->client, AS73211_REG_CREG3, data->creg3); + if (ret < 0) + return ret; + + return 0; + } + case IIO_CHAN_INFO_HARDWAREGAIN: { + unsigned int reg_bits; + + if (val < 0 || !is_power_of_2(val) || val2) + return -EINVAL; + + /* gain can be calculated from CREG1 as 2^(11 - CREG1_GAIN) */ + reg_bits = AS73211_CREG1_GAIN_1 - ilog2(val); + if (!FIELD_FIT(AS73211_CREG1_GAIN_MASK, reg_bits)) + return -EINVAL; + + data->creg1 &= ~AS73211_CREG1_GAIN_MASK; + data->creg1 |= FIELD_PREP(AS73211_CREG1_GAIN_MASK, reg_bits); + + ret = i2c_smbus_write_byte_data(data->client, AS73211_REG_CREG1, data->creg1); + if (ret < 0) + return ret; + + return 0; + } + case IIO_CHAN_INFO_INT_TIME: { + int val_us = val * USEC_PER_SEC + val2; + int time_ms; + int reg_bits; + + /* f_samp is configured in CREG3 in powers of 2 (x 1.024 MHz) */ + int f_samp_1_024mhz = BIT(FIELD_GET(AS73211_CREG3_CCLK_MASK, data->creg3)); + + /* + * time_ms = time_us * US_PER_MS * f_samp_1_024mhz / MHZ_PER_HZ + * = time_us * f_samp_1_024mhz / 1000 + */ + time_ms = (val_us * f_samp_1_024mhz) / 1000; /* 1 ms, 2 ms, ... (power of two) */ + if (time_ms < 0 || !is_power_of_2(time_ms) || time_ms > AS73211_SAMPLE_TIME_MAX_MS) + return -EINVAL; + + reg_bits = ilog2(time_ms); + if (!FIELD_FIT(AS73211_CREG1_TIME_MASK, reg_bits)) + return -EINVAL; /* not possible due to previous tests */ + + data->creg1 &= ~AS73211_CREG1_TIME_MASK; + data->creg1 |= FIELD_PREP(AS73211_CREG1_TIME_MASK, reg_bits); + + ret = i2c_smbus_write_byte_data(data->client, AS73211_REG_CREG1, data->creg1); + if (ret < 0) + return ret; + + return 0; + + default: + return -EINVAL; + }} +} + +static int as73211_write_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, + int val, int val2, long mask) +{ + struct as73211_data *data = iio_priv(indio_dev); + int ret; + + mutex_lock(&data->mutex); + + ret = iio_device_claim_direct_mode(indio_dev); + if (ret < 0) + goto error_unlock; + + /* Need to switch to config mode ... */ + if ((data->osr & AS73211_OSR_DOS_MASK) != AS73211_OSR_DOS_CONFIG) { + data->osr &= ~AS73211_OSR_DOS_MASK; + data->osr |= AS73211_OSR_DOS_CONFIG; + + ret = i2c_smbus_write_byte_data(data->client, AS73211_REG_OSR, data->osr); + if (ret < 0) + goto error_release; + } + + ret = _as73211_write_raw(indio_dev, chan, val, val2, mask); + +error_release: + iio_device_release_direct_mode(indio_dev); +error_unlock: + mutex_unlock(&data->mutex); + return ret; +} + +static irqreturn_t as73211_ready_handler(int irq __always_unused, void *priv) +{ + struct as73211_data *data = iio_priv(priv); + + complete(&data->completion); + + return IRQ_HANDLED; +} + +static irqreturn_t as73211_trigger_handler(int irq __always_unused, void *p) +{ + struct iio_poll_func *pf = p; + struct iio_dev *indio_dev = pf->indio_dev; + struct as73211_data *data = iio_priv(indio_dev); + struct { + __le16 chan[4]; + s64 ts __aligned(8); + } scan; + int data_result, ret; + + mutex_lock(&data->mutex); + + data_result = as73211_req_data(data); + if (data_result < 0 && data_result != -EOVERFLOW) + goto done; /* don't push any data for errors other than EOVERFLOW */ + + if (*indio_dev->active_scan_mask == AS73211_SCAN_MASK_ALL) { + /* Optimization for reading all (color + temperature) channels */ + u8 addr = as73211_channels[0].address; + struct i2c_msg msgs[] = { + { + .addr = data->client->addr, + .flags = 0, + .len = 1, + .buf = &addr, + }, + { + .addr = data->client->addr, + .flags = I2C_M_RD, + .len = sizeof(scan.chan), + .buf = (u8 *)&scan.chan, + }, + }; + + ret = i2c_transfer(data->client->adapter, msgs, ARRAY_SIZE(msgs)); + if (ret < 0) + goto done; + } else { + /* Optimization for reading only color channels */ + + /* AS73211 starts reading at address 2 */ + ret = i2c_master_recv(data->client, + (char *)&scan.chan[1], 3 * sizeof(scan.chan[1])); + if (ret < 0) + goto done; + } + + if (data_result) { + /* + * Saturate all channels (in case of overflows). Temperature channel + * is not affected by overflows. + */ + scan.chan[1] = cpu_to_le16(U16_MAX); + scan.chan[2] = cpu_to_le16(U16_MAX); + scan.chan[3] = cpu_to_le16(U16_MAX); + } + + iio_push_to_buffers_with_timestamp(indio_dev, &scan, iio_get_time_ns(indio_dev)); + +done: + mutex_unlock(&data->mutex); + iio_trigger_notify_done(indio_dev->trig); + + return IRQ_HANDLED; +} + +static const struct iio_info as73211_info = { + .read_raw = as73211_read_raw, + .read_avail = as73211_read_avail, + .write_raw = as73211_write_raw, +}; + +static int as73211_power(struct iio_dev *indio_dev, bool state) +{ + struct as73211_data *data = iio_priv(indio_dev); + int ret; + + mutex_lock(&data->mutex); + + if (state) + data->osr &= ~AS73211_OSR_PD; + else + data->osr |= AS73211_OSR_PD; + + ret = i2c_smbus_write_byte_data(data->client, AS73211_REG_OSR, data->osr); + + mutex_unlock(&data->mutex); + + if (ret < 0) + return ret; + + return 0; +} + +static void as73211_power_disable(void *data) +{ + struct iio_dev *indio_dev = data; + + as73211_power(indio_dev, false); +} + +static int as73211_probe(struct i2c_client *client) +{ + struct device *dev = &client->dev; + struct as73211_data *data; + struct iio_dev *indio_dev; + int ret; + + indio_dev = devm_iio_device_alloc(dev, sizeof(*data)); + if (!indio_dev) + return -ENOMEM; + + data = iio_priv(indio_dev); + i2c_set_clientdata(client, indio_dev); + data->client = client; + + mutex_init(&data->mutex); + init_completion(&data->completion); + + indio_dev->info = &as73211_info; + indio_dev->name = AS73211_DRV_NAME; + indio_dev->channels = as73211_channels; + indio_dev->num_channels = ARRAY_SIZE(as73211_channels); + indio_dev->modes = INDIO_DIRECT_MODE; + + ret = i2c_smbus_read_byte_data(data->client, AS73211_REG_OSR); + if (ret < 0) + return ret; + data->osr = ret; + + /* reset device */ + data->osr |= AS73211_OSR_SW_RES; + ret = i2c_smbus_write_byte_data(data->client, AS73211_REG_OSR, data->osr); + if (ret < 0) + return ret; + + ret = i2c_smbus_read_byte_data(data->client, AS73211_REG_OSR); + if (ret < 0) + return ret; + data->osr = ret; + + /* + * Reading AGEN is only possible after reset (AGEN is not available if + * device is in measurement mode). + */ + ret = i2c_smbus_read_byte_data(data->client, AS73211_REG_AGEN); + if (ret < 0) + return ret; + + /* At the time of writing this driver, only DEVID 2 and MUT 1 are known. */ + if ((ret & AS73211_AGEN_DEVID_MASK) != AS73211_AGEN_DEVID(2) || + (ret & AS73211_AGEN_MUT_MASK) != AS73211_AGEN_MUT(1)) + return -ENODEV; + + ret = i2c_smbus_read_byte_data(data->client, AS73211_REG_CREG1); + if (ret < 0) + return ret; + data->creg1 = ret; + + ret = i2c_smbus_read_byte_data(data->client, AS73211_REG_CREG2); + if (ret < 0) + return ret; + data->creg2 = ret; + + ret = i2c_smbus_read_byte_data(data->client, AS73211_REG_CREG3); + if (ret < 0) + return ret; + data->creg3 = ret; + as73211_integration_time_calc_avail(data); + + ret = as73211_power(indio_dev, true); + if (ret < 0) + return ret; + + ret = devm_add_action_or_reset(dev, as73211_power_disable, indio_dev); + if (ret) + return ret; + + ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL, as73211_trigger_handler, NULL); + if (ret) + return ret; + + if (client->irq) { + ret = devm_request_threaded_irq(&client->dev, client->irq, + NULL, + as73211_ready_handler, + IRQF_ONESHOT, + client->name, indio_dev); + if (ret) + return ret; + } + + return devm_iio_device_register(dev, indio_dev); +} + +static int __maybe_unused as73211_suspend(struct device *dev) +{ + struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); + + return as73211_power(indio_dev, false); +} + +static int __maybe_unused as73211_resume(struct device *dev) +{ + struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); + + return as73211_power(indio_dev, true); +} + +static SIMPLE_DEV_PM_OPS(as73211_pm_ops, as73211_suspend, as73211_resume); + +static const struct of_device_id as73211_of_match[] = { + { .compatible = "ams,as73211" }, + { } +}; +MODULE_DEVICE_TABLE(of, as73211_of_match); + +static const struct i2c_device_id as73211_id[] = { + { "as73211", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, as73211_id); + +static struct i2c_driver as73211_driver = { + .driver = { + .name = AS73211_DRV_NAME, + .of_match_table = as73211_of_match, + .pm = &as73211_pm_ops, + }, + .probe_new = as73211_probe, + .id_table = as73211_id, +}; +module_i2c_driver(as73211_driver); + +MODULE_AUTHOR("Christian Eggers <ceggers@arri.de>"); +MODULE_DESCRIPTION("AS73211 XYZ True Color Sensor driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/iio/light/cros_ec_light_prox.c b/drivers/iio/light/cros_ec_light_prox.c index fed79ba27fda..75d6b5fcf2cc 100644 --- a/drivers/iio/light/cros_ec_light_prox.c +++ b/drivers/iio/light/cros_ec_light_prox.c @@ -182,12 +182,11 @@ static int cros_ec_light_prox_probe(struct platform_device *pdev) ret = cros_ec_sensors_core_init(pdev, indio_dev, true, cros_ec_sensors_capture, - cros_ec_sensors_push_data); + cros_ec_sensors_push_data, + true); if (ret) return ret; - iio_buffer_set_attrs(indio_dev->buffer, cros_ec_sensor_fifo_attributes); - indio_dev->info = &cros_ec_light_prox_info; state = iio_priv(indio_dev); state->core.type = state->core.resp->info.type; diff --git a/drivers/iio/light/gp2ap002.c b/drivers/iio/light/gp2ap002.c index d5e1cd27eb46..7ba7aa59437c 100644 --- a/drivers/iio/light/gp2ap002.c +++ b/drivers/iio/light/gp2ap002.c @@ -566,7 +566,7 @@ static int gp2ap002_probe(struct i2c_client *client, /* * Initialize the device and signal to runtime PM that now we are - * definately up and using power. + * definitely up and using power. */ ret = gp2ap002_init(gp2ap002); if (ret) { diff --git a/drivers/iio/light/isl29018.c b/drivers/iio/light/isl29018.c index ac8ad0f32689..2689867467a8 100644 --- a/drivers/iio/light/isl29018.c +++ b/drivers/iio/light/isl29018.c @@ -746,12 +746,9 @@ static int isl29018_probe(struct i2c_client *client, chip->suspended = false; chip->vcc_reg = devm_regulator_get(&client->dev, "vcc"); - if (IS_ERR(chip->vcc_reg)) { - err = PTR_ERR(chip->vcc_reg); - if (err != -EPROBE_DEFER) - dev_err(&client->dev, "failed to get VCC regulator!\n"); - return err; - } + if (IS_ERR(chip->vcc_reg)) + return dev_err_probe(&client->dev, PTR_ERR(chip->vcc_reg), + "failed to get VCC regulator!\n"); err = regulator_enable(chip->vcc_reg); if (err) { diff --git a/drivers/iio/light/si1145.c b/drivers/iio/light/si1145.c index 8f5f857c2e7d..b304801c7916 100644 --- a/drivers/iio/light/si1145.c +++ b/drivers/iio/light/si1145.c @@ -168,6 +168,7 @@ struct si1145_part_info { * @part_info: Part information * @trig: Pointer to iio trigger * @meas_rate: Value of MEAS_RATE register. Only set in HW in auto mode + * @buffer: Used to pack data read from sensor. */ struct si1145_data { struct i2c_client *client; @@ -179,6 +180,14 @@ struct si1145_data { bool autonomous; struct iio_trigger *trig; int meas_rate; + /* + * Ensure timestamp will be naturally aligned if present. + * Maximum buffer size (may be only partly used if not all + * channels are enabled): + * 6*2 bytes channels data + 4 bytes alignment + + * 8 bytes timestamp + */ + u8 buffer[24] __aligned(8); }; /* @@ -440,12 +449,6 @@ static irqreturn_t si1145_trigger_handler(int irq, void *private) struct iio_poll_func *pf = private; struct iio_dev *indio_dev = pf->indio_dev; struct si1145_data *data = iio_priv(indio_dev); - /* - * Maximum buffer size: - * 6*2 bytes channels data + 4 bytes alignment + - * 8 bytes timestamp - */ - u8 buffer[24]; int i, j = 0; int ret; u8 irq_status = 0; @@ -478,7 +481,7 @@ static irqreturn_t si1145_trigger_handler(int irq, void *private) ret = i2c_smbus_read_i2c_block_data_or_emulated( data->client, indio_dev->channels[i].address, - sizeof(u16) * run, &buffer[j]); + sizeof(u16) * run, &data->buffer[j]); if (ret < 0) goto done; j += run * sizeof(u16); @@ -493,7 +496,7 @@ static irqreturn_t si1145_trigger_handler(int irq, void *private) goto done; } - iio_push_to_buffers_with_timestamp(indio_dev, buffer, + iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, iio_get_time_ns(indio_dev)); done: diff --git a/drivers/iio/light/tsl2772.c b/drivers/iio/light/tsl2772.c index 735399405417..d79205361dfa 100644 --- a/drivers/iio/light/tsl2772.c +++ b/drivers/iio/light/tsl2772.c @@ -1776,14 +1776,8 @@ static int tsl2772_probe(struct i2c_client *clientp, ret = devm_regulator_bulk_get(&clientp->dev, ARRAY_SIZE(chip->supplies), chip->supplies); - if (ret < 0) { - if (ret != -EPROBE_DEFER) - dev_err(&clientp->dev, - "Failed to get regulators: %d\n", - ret); - - return ret; - } + if (ret < 0) + return dev_err_probe(&clientp->dev, ret, "Failed to get regulators\n"); ret = regulator_bulk_enable(ARRAY_SIZE(chip->supplies), chip->supplies); if (ret < 0) { diff --git a/drivers/iio/magnetometer/ak8974.c b/drivers/iio/magnetometer/ak8974.c index cbb44e401c0a..24b2f7b1fe44 100644 --- a/drivers/iio/magnetometer/ak8974.c +++ b/drivers/iio/magnetometer/ak8974.c @@ -12,6 +12,7 @@ * Author: Linus Walleij <linus.walleij@linaro.org> */ #include <linux/module.h> +#include <linux/mod_devicetable.h> #include <linux/kernel.h> #include <linux/i2c.h> #include <linux/interrupt.h> @@ -843,15 +844,8 @@ static int ak8974_probe(struct i2c_client *i2c, ret = devm_regulator_bulk_get(&i2c->dev, ARRAY_SIZE(ak8974->regs), ak8974->regs); - if (ret < 0) { - if (ret != -EPROBE_DEFER) - dev_err(&i2c->dev, "cannot get regulators: %d\n", ret); - else - dev_dbg(&i2c->dev, - "regulators unavailable, deferring probe\n"); - - return ret; - } + if (ret < 0) + return dev_err_probe(&i2c->dev, ret, "cannot get regulators\n"); ret = regulator_bulk_enable(ARRAY_SIZE(ak8974->regs), ak8974->regs); if (ret < 0) { @@ -1058,7 +1052,7 @@ static struct i2c_driver ak8974_driver = { .driver = { .name = "ak8974", .pm = &ak8974_dev_pm_ops, - .of_match_table = of_match_ptr(ak8974_of_match), + .of_match_table = ak8974_of_match, }, .probe = ak8974_probe, .remove = ak8974_remove, diff --git a/drivers/iio/magnetometer/ak8975.c b/drivers/iio/magnetometer/ak8975.c index 623766ff800b..d988b6ac3659 100644 --- a/drivers/iio/magnetometer/ak8975.c +++ b/drivers/iio/magnetometer/ak8975.c @@ -8,6 +8,7 @@ */ #include <linux/module.h> +#include <linux/mod_devicetable.h> #include <linux/kernel.h> #include <linux/slab.h> #include <linux/i2c.h> @@ -17,7 +18,6 @@ #include <linux/delay.h> #include <linux/bitops.h> #include <linux/gpio/consumer.h> -#include <linux/acpi.h> #include <linux/regulator/consumer.h> #include <linux/pm_runtime.h> @@ -779,7 +779,6 @@ static const struct iio_info ak8975_info = { .read_raw = &ak8975_read_raw, }; -#ifdef CONFIG_ACPI static const struct acpi_device_id ak_acpi_match[] = { {"AK8975", AK8975}, {"AK8963", AK8963}, @@ -791,7 +790,6 @@ static const struct acpi_device_id ak_acpi_match[] = { { } }; MODULE_DEVICE_TABLE(acpi, ak_acpi_match); -#endif static void ak8975_fill_buffer(struct iio_dev *indio_dev) { @@ -1081,8 +1079,8 @@ static struct i2c_driver ak8975_driver = { .driver = { .name = "ak8975", .pm = &ak8975_dev_pm_ops, - .of_match_table = of_match_ptr(ak8975_of_match), - .acpi_match_table = ACPI_PTR(ak_acpi_match), + .of_match_table = ak8975_of_match, + .acpi_match_table = ak_acpi_match, }, .probe = ak8975_probe, .remove = ak8975_remove, diff --git a/drivers/iio/magnetometer/hmc5843_core.c b/drivers/iio/magnetometer/hmc5843_core.c index 1474ba63babe..780faea61d82 100644 --- a/drivers/iio/magnetometer/hmc5843_core.c +++ b/drivers/iio/magnetometer/hmc5843_core.c @@ -245,7 +245,7 @@ static const struct iio_enum hmc5843_meas_conf_enum = { }; static const struct iio_chan_spec_ext_info hmc5843_ext_info[] = { - IIO_ENUM("meas_conf", true, &hmc5843_meas_conf_enum), + IIO_ENUM("meas_conf", IIO_SHARED_BY_TYPE, &hmc5843_meas_conf_enum), IIO_ENUM_AVAILABLE("meas_conf", &hmc5843_meas_conf_enum), IIO_MOUNT_MATRIX(IIO_SHARED_BY_DIR, hmc5843_get_mount_matrix), { } @@ -259,7 +259,7 @@ static const struct iio_enum hmc5983_meas_conf_enum = { }; static const struct iio_chan_spec_ext_info hmc5983_ext_info[] = { - IIO_ENUM("meas_conf", true, &hmc5983_meas_conf_enum), + IIO_ENUM("meas_conf", IIO_SHARED_BY_TYPE, &hmc5983_meas_conf_enum), IIO_ENUM_AVAILABLE("meas_conf", &hmc5983_meas_conf_enum), IIO_MOUNT_MATRIX(IIO_SHARED_BY_DIR, hmc5843_get_mount_matrix), { } diff --git a/drivers/iio/magnetometer/mag3110.c b/drivers/iio/magnetometer/mag3110.c index 4d305a21c379..838b13c8bb3d 100644 --- a/drivers/iio/magnetometer/mag3110.c +++ b/drivers/iio/magnetometer/mag3110.c @@ -476,22 +476,14 @@ static int mag3110_probe(struct i2c_client *client, data = iio_priv(indio_dev); data->vdd_reg = devm_regulator_get(&client->dev, "vdd"); - if (IS_ERR(data->vdd_reg)) { - if (PTR_ERR(data->vdd_reg) == -EPROBE_DEFER) - return -EPROBE_DEFER; - - dev_err(&client->dev, "failed to get VDD regulator!\n"); - return PTR_ERR(data->vdd_reg); - } + if (IS_ERR(data->vdd_reg)) + return dev_err_probe(&client->dev, PTR_ERR(data->vdd_reg), + "failed to get VDD regulator!\n"); data->vddio_reg = devm_regulator_get(&client->dev, "vddio"); - if (IS_ERR(data->vddio_reg)) { - if (PTR_ERR(data->vddio_reg) == -EPROBE_DEFER) - return -EPROBE_DEFER; - - dev_err(&client->dev, "failed to get VDDIO regulator!\n"); - return PTR_ERR(data->vddio_reg); - } + if (IS_ERR(data->vddio_reg)) + return dev_err_probe(&client->dev, PTR_ERR(data->vddio_reg), + "failed to get VDDIO regulator!\n"); ret = regulator_enable(data->vdd_reg); if (ret) { diff --git a/drivers/iio/multiplexer/iio-mux.c b/drivers/iio/multiplexer/iio-mux.c index 6910218fdb00..d54ae5cbe51b 100644 --- a/drivers/iio/multiplexer/iio-mux.c +++ b/drivers/iio/multiplexer/iio-mux.c @@ -354,11 +354,9 @@ static int mux_probe(struct platform_device *pdev) return -ENODEV; parent = devm_iio_channel_get(dev, "parent"); - if (IS_ERR(parent)) { - if (PTR_ERR(parent) != -EPROBE_DEFER) - dev_err(dev, "failed to get parent channel\n"); - return PTR_ERR(parent); - } + if (IS_ERR(parent)) + return dev_err_probe(dev, PTR_ERR(parent), + "failed to get parent channel\n"); sizeof_ext_info = iio_get_channel_ext_info_count(parent); if (sizeof_ext_info) { diff --git a/drivers/iio/potentiometer/ad5272.c b/drivers/iio/potentiometer/ad5272.c index 933afcf7e925..70c45d346df0 100644 --- a/drivers/iio/potentiometer/ad5272.c +++ b/drivers/iio/potentiometer/ad5272.c @@ -15,6 +15,7 @@ #include <linux/i2c.h> #include <linux/iio/iio.h> #include <linux/module.h> +#include <linux/mod_devicetable.h> #define AD5272_RDAC_WR 1 #define AD5272_RDAC_RD 2 @@ -192,7 +193,6 @@ static int ad5272_probe(struct i2c_client *client, return devm_iio_device_register(dev, indio_dev); } -#if defined(CONFIG_OF) static const struct of_device_id ad5272_dt_ids[] = { { .compatible = "adi,ad5272-020", .data = (void *)AD5272_020 }, { .compatible = "adi,ad5272-050", .data = (void *)AD5272_050 }, @@ -202,7 +202,6 @@ static const struct of_device_id ad5272_dt_ids[] = { {} }; MODULE_DEVICE_TABLE(of, ad5272_dt_ids); -#endif /* CONFIG_OF */ static const struct i2c_device_id ad5272_id[] = { { "ad5272-020", AD5272_020 }, @@ -217,7 +216,7 @@ MODULE_DEVICE_TABLE(i2c, ad5272_id); static struct i2c_driver ad5272_driver = { .driver = { .name = "ad5272", - .of_match_table = of_match_ptr(ad5272_dt_ids), + .of_match_table = ad5272_dt_ids, }, .probe = ad5272_probe, .id_table = ad5272_id, diff --git a/drivers/iio/potentiometer/ds1803.c b/drivers/iio/potentiometer/ds1803.c index 5c061ab8f46c..20b45407eaac 100644 --- a/drivers/iio/potentiometer/ds1803.c +++ b/drivers/iio/potentiometer/ds1803.c @@ -14,7 +14,7 @@ #include <linux/i2c.h> #include <linux/iio/iio.h> #include <linux/module.h> -#include <linux/of.h> +#include <linux/mod_devicetable.h> #define DS1803_MAX_POS 255 #define DS1803_WRITE(chan) (0xa8 | ((chan) + 1)) @@ -134,7 +134,6 @@ static int ds1803_probe(struct i2c_client *client, return devm_iio_device_register(dev, indio_dev); } -#if defined(CONFIG_OF) static const struct of_device_id ds1803_dt_ids[] = { { .compatible = "maxim,ds1803-010", .data = &ds1803_cfg[DS1803_010] }, { .compatible = "maxim,ds1803-050", .data = &ds1803_cfg[DS1803_050] }, @@ -142,7 +141,6 @@ static const struct of_device_id ds1803_dt_ids[] = { {} }; MODULE_DEVICE_TABLE(of, ds1803_dt_ids); -#endif /* CONFIG_OF */ static const struct i2c_device_id ds1803_id[] = { { "ds1803-010", DS1803_010 }, @@ -155,7 +153,7 @@ MODULE_DEVICE_TABLE(i2c, ds1803_id); static struct i2c_driver ds1803_driver = { .driver = { .name = "ds1803", - .of_match_table = of_match_ptr(ds1803_dt_ids), + .of_match_table = ds1803_dt_ids, }, .probe = ds1803_probe, .id_table = ds1803_id, diff --git a/drivers/iio/potentiometer/max5432.c b/drivers/iio/potentiometer/max5432.c index 280de9c54471..aed3b6ab82a2 100644 --- a/drivers/iio/potentiometer/max5432.c +++ b/drivers/iio/potentiometer/max5432.c @@ -11,8 +11,8 @@ #include <linux/iio/iio.h> #include <linux/limits.h> #include <linux/module.h> -#include <linux/of.h> -#include <linux/of_device.h> +#include <linux/mod_devicetable.h> +#include <linux/property.h> /* All chip variants have 32 wiper positions. */ #define MAX5432_MAX_POS 31 @@ -100,7 +100,7 @@ static int max5432_probe(struct i2c_client *client, data = iio_priv(indio_dev); data->client = client; - data->ohm = (unsigned long)of_device_get_match_data(dev); + data->ohm = (unsigned long)device_get_match_data(dev); indio_dev->info = &max5432_info; indio_dev->channels = max5432_channels; @@ -122,7 +122,7 @@ MODULE_DEVICE_TABLE(of, max5432_dt_ids); static struct i2c_driver max5432_driver = { .driver = { .name = "max5432", - .of_match_table = of_match_ptr(max5432_dt_ids), + .of_match_table = max5432_dt_ids, }, .probe = max5432_probe, }; diff --git a/drivers/iio/potentiometer/max5481.c b/drivers/iio/potentiometer/max5481.c index 5f5988189796..a88ed0eb3adc 100644 --- a/drivers/iio/potentiometer/max5481.c +++ b/drivers/iio/potentiometer/max5481.c @@ -7,12 +7,11 @@ * https://datasheets.maximintegrated.com/en/ds/MAX5481-MAX5484.pdf */ -#include <linux/acpi.h> #include <linux/iio/iio.h> #include <linux/iio/sysfs.h> #include <linux/module.h> -#include <linux/of.h> -#include <linux/of_device.h> +#include <linux/mod_devicetable.h> +#include <linux/property.h> #include <linux/spi/spi.h> /* write wiper reg */ @@ -117,7 +116,6 @@ static const struct iio_info max5481_info = { .write_raw = max5481_write_raw, }; -#if defined(CONFIG_OF) static const struct of_device_id max5481_match[] = { { .compatible = "maxim,max5481", .data = &max5481_cfg[max5481] }, { .compatible = "maxim,max5482", .data = &max5481_cfg[max5482] }, @@ -126,7 +124,6 @@ static const struct of_device_id max5481_match[] = { { } }; MODULE_DEVICE_TABLE(of, max5481_match); -#endif static int max5481_probe(struct spi_device *spi) { @@ -144,7 +141,7 @@ static int max5481_probe(struct spi_device *spi) data->spi = spi; - data->cfg = of_device_get_match_data(&spi->dev); + data->cfg = device_get_match_data(&spi->dev); if (!data->cfg) data->cfg = &max5481_cfg[id->driver_data]; @@ -184,22 +181,10 @@ static const struct spi_device_id max5481_id_table[] = { }; MODULE_DEVICE_TABLE(spi, max5481_id_table); -#if defined(CONFIG_ACPI) -static const struct acpi_device_id max5481_acpi_match[] = { - { "max5481", max5481 }, - { "max5482", max5482 }, - { "max5483", max5483 }, - { "max5484", max5484 }, - { } -}; -MODULE_DEVICE_TABLE(acpi, max5481_acpi_match); -#endif - static struct spi_driver max5481_driver = { .driver = { .name = "max5481", - .of_match_table = of_match_ptr(max5481_match), - .acpi_match_table = ACPI_PTR(max5481_acpi_match), + .of_match_table = max5481_match, }, .probe = max5481_probe, .remove = max5481_remove, diff --git a/drivers/iio/potentiometer/mcp4018.c b/drivers/iio/potentiometer/mcp4018.c index fd0579ad3c83..c0e171fec062 100644 --- a/drivers/iio/potentiometer/mcp4018.c +++ b/drivers/iio/potentiometer/mcp4018.c @@ -16,8 +16,8 @@ #include <linux/i2c.h> #include <linux/iio/iio.h> #include <linux/module.h> -#include <linux/of.h> -#include <linux/of_device.h> +#include <linux/mod_devicetable.h> +#include <linux/property.h> #define MCP4018_WIPER_MAX 127 @@ -116,8 +116,6 @@ static const struct i2c_device_id mcp4018_id[] = { }; MODULE_DEVICE_TABLE(i2c, mcp4018_id); -#ifdef CONFIG_OF - #define MCP4018_COMPATIBLE(of_compatible, cfg) { \ .compatible = of_compatible, \ .data = &mcp4018_cfg[cfg], \ @@ -140,8 +138,6 @@ static const struct of_device_id mcp4018_of_match[] = { }; MODULE_DEVICE_TABLE(of, mcp4018_of_match); -#endif - static int mcp4018_probe(struct i2c_client *client) { struct device *dev = &client->dev; @@ -161,7 +157,7 @@ static int mcp4018_probe(struct i2c_client *client) i2c_set_clientdata(client, indio_dev); data->client = client; - data->cfg = of_device_get_match_data(dev); + data->cfg = device_get_match_data(dev); if (!data->cfg) data->cfg = &mcp4018_cfg[i2c_match_id(mcp4018_id, client)->driver_data]; @@ -176,7 +172,7 @@ static int mcp4018_probe(struct i2c_client *client) static struct i2c_driver mcp4018_driver = { .driver = { .name = "mcp4018", - .of_match_table = of_match_ptr(mcp4018_of_match), + .of_match_table = mcp4018_of_match, }, .probe_new = mcp4018_probe, .id_table = mcp4018_id, diff --git a/drivers/iio/potentiometer/mcp4131.c b/drivers/iio/potentiometer/mcp4131.c index 2923ce250fc3..7c8c18ab8764 100644 --- a/drivers/iio/potentiometer/mcp4131.c +++ b/drivers/iio/potentiometer/mcp4131.c @@ -37,9 +37,9 @@ #include <linux/iio/iio.h> #include <linux/iio/types.h> #include <linux/module.h> +#include <linux/mod_devicetable.h> #include <linux/mutex.h> -#include <linux/of.h> -#include <linux/of_device.h> +#include <linux/property.h> #include <linux/spi/spi.h> #define MCP4131_WRITE (0x00 << 2) @@ -252,7 +252,7 @@ static int mcp4131_probe(struct spi_device *spi) data = iio_priv(indio_dev); spi_set_drvdata(spi, indio_dev); data->spi = spi; - data->cfg = of_device_get_match_data(&spi->dev); + data->cfg = device_get_match_data(&spi->dev); if (!data->cfg) { devid = spi_get_device_id(spi)->driver_data; data->cfg = &mcp4131_cfg[devid]; @@ -479,7 +479,7 @@ MODULE_DEVICE_TABLE(spi, mcp4131_id); static struct spi_driver mcp4131_driver = { .driver = { .name = "mcp4131", - .of_match_table = of_match_ptr(mcp4131_dt_ids), + .of_match_table = mcp4131_dt_ids, }, .probe = mcp4131_probe, .id_table = mcp4131_id, diff --git a/drivers/iio/potentiometer/mcp4531.c b/drivers/iio/potentiometer/mcp4531.c index 95efc4b40514..c25f84b4a270 100644 --- a/drivers/iio/potentiometer/mcp4531.c +++ b/drivers/iio/potentiometer/mcp4531.c @@ -28,8 +28,8 @@ #include <linux/module.h> #include <linux/i2c.h> #include <linux/err.h> -#include <linux/of.h> -#include <linux/of_device.h> +#include <linux/mod_devicetable.h> +#include <linux/property.h> #include <linux/iio/iio.h> @@ -275,8 +275,6 @@ static const struct i2c_device_id mcp4531_id[] = { }; MODULE_DEVICE_TABLE(i2c, mcp4531_id); -#ifdef CONFIG_OF - #define MCP4531_COMPATIBLE(of_compatible, cfg) { \ .compatible = of_compatible, \ .data = &mcp4531_cfg[cfg], \ @@ -350,7 +348,6 @@ static const struct of_device_id mcp4531_of_match[] = { { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, mcp4531_of_match); -#endif static int mcp4531_probe(struct i2c_client *client) { @@ -371,7 +368,7 @@ static int mcp4531_probe(struct i2c_client *client) i2c_set_clientdata(client, indio_dev); data->client = client; - data->cfg = of_device_get_match_data(dev); + data->cfg = device_get_match_data(dev); if (!data->cfg) data->cfg = &mcp4531_cfg[i2c_match_id(mcp4531_id, client)->driver_data]; @@ -386,7 +383,7 @@ static int mcp4531_probe(struct i2c_client *client) static struct i2c_driver mcp4531_driver = { .driver = { .name = "mcp4531", - .of_match_table = of_match_ptr(mcp4531_of_match), + .of_match_table = mcp4531_of_match, }, .probe_new = mcp4531_probe, .id_table = mcp4531_id, diff --git a/drivers/iio/potentiostat/lmp91000.c b/drivers/iio/potentiostat/lmp91000.c index 67ae635a05f3..f34ca769dc20 100644 --- a/drivers/iio/potentiostat/lmp91000.c +++ b/drivers/iio/potentiostat/lmp91000.c @@ -11,7 +11,7 @@ #include <linux/module.h> #include <linux/i2c.h> #include <linux/delay.h> -#include <linux/of.h> +#include <linux/mod_devicetable.h> #include <linux/regmap.h> #include <linux/iio/iio.h> #include <linux/iio/buffer.h> @@ -205,13 +205,12 @@ static const struct iio_info lmp91000_info = { static int lmp91000_read_config(struct lmp91000_data *data) { struct device *dev = data->dev; - struct device_node *np = dev->of_node; unsigned int reg, val; int i, ret; - ret = of_property_read_u32(np, "ti,tia-gain-ohm", &val); + ret = device_property_read_u32(dev, "ti,tia-gain-ohm", &val); if (ret) { - if (!of_property_read_bool(np, "ti,external-tia-resistor")) { + if (!device_property_read_bool(dev, "ti,external-tia-resistor")) { dev_err(dev, "no ti,tia-gain-ohm defined and external resistor not specified\n"); return ret; } @@ -232,7 +231,7 @@ static int lmp91000_read_config(struct lmp91000_data *data) return ret; } - ret = of_property_read_u32(np, "ti,rload-ohm", &val); + ret = device_property_read_u32(dev, "ti,rload-ohm", &val); if (ret) { val = 100; dev_info(dev, "no ti,rload-ohm defined, default to %d\n", val); @@ -422,7 +421,7 @@ MODULE_DEVICE_TABLE(i2c, lmp91000_id); static struct i2c_driver lmp91000_driver = { .driver = { .name = LMP91000_DRV_NAME, - .of_match_table = of_match_ptr(lmp91000_of_match), + .of_match_table = lmp91000_of_match, }, .probe = lmp91000_probe, .remove = lmp91000_remove, diff --git a/drivers/iio/pressure/cros_ec_baro.c b/drivers/iio/pressure/cros_ec_baro.c index f0938b6fbba0..aa043cb9ac42 100644 --- a/drivers/iio/pressure/cros_ec_baro.c +++ b/drivers/iio/pressure/cros_ec_baro.c @@ -139,12 +139,11 @@ static int cros_ec_baro_probe(struct platform_device *pdev) ret = cros_ec_sensors_core_init(pdev, indio_dev, true, cros_ec_sensors_capture, - cros_ec_sensors_push_data); + cros_ec_sensors_push_data, + true); if (ret) return ret; - iio_buffer_set_attrs(indio_dev->buffer, cros_ec_sensor_fifo_attributes); - indio_dev->info = &cros_ec_baro_info; state = iio_priv(indio_dev); state->core.type = state->core.resp->info.type; diff --git a/drivers/iio/pressure/icp10100.c b/drivers/iio/pressure/icp10100.c index 90c0df068bbb..48759fc4bf18 100644 --- a/drivers/iio/pressure/icp10100.c +++ b/drivers/iio/pressure/icp10100.c @@ -10,6 +10,7 @@ #include <linux/device.h> #include <linux/module.h> +#include <linux/mod_devicetable.h> #include <linux/i2c.h> #include <linux/pm_runtime.h> #include <linux/crc8.h> @@ -645,7 +646,7 @@ static struct i2c_driver icp10100_driver = { .driver = { .name = "icp10100", .pm = &icp10100_pm, - .of_match_table = of_match_ptr(icp10100_of_match), + .of_match_table = icp10100_of_match, }, .probe = icp10100_probe, .id_table = icp10100_id, diff --git a/drivers/iio/pressure/ms5611_i2c.c b/drivers/iio/pressure/ms5611_i2c.c index 072c106dd66d..7c04f730430c 100644 --- a/drivers/iio/pressure/ms5611_i2c.c +++ b/drivers/iio/pressure/ms5611_i2c.c @@ -14,7 +14,7 @@ #include <linux/delay.h> #include <linux/i2c.h> #include <linux/module.h> -#include <linux/of_device.h> +#include <linux/mod_devicetable.h> #include <asm/unaligned.h> @@ -113,14 +113,12 @@ static int ms5611_i2c_remove(struct i2c_client *client) return ms5611_remove(i2c_get_clientdata(client)); } -#if defined(CONFIG_OF) static const struct of_device_id ms5611_i2c_matches[] = { { .compatible = "meas,ms5611" }, { .compatible = "meas,ms5607" }, { } }; MODULE_DEVICE_TABLE(of, ms5611_i2c_matches); -#endif static const struct i2c_device_id ms5611_id[] = { { "ms5611", MS5611 }, @@ -132,7 +130,7 @@ MODULE_DEVICE_TABLE(i2c, ms5611_id); static struct i2c_driver ms5611_driver = { .driver = { .name = "ms5611", - .of_match_table = of_match_ptr(ms5611_i2c_matches) + .of_match_table = ms5611_i2c_matches, }, .id_table = ms5611_id, .probe = ms5611_i2c_probe, diff --git a/drivers/iio/pressure/ms5611_spi.c b/drivers/iio/pressure/ms5611_spi.c index 4799aa57135e..45d3a7d5be8e 100644 --- a/drivers/iio/pressure/ms5611_spi.c +++ b/drivers/iio/pressure/ms5611_spi.c @@ -9,7 +9,7 @@ #include <linux/delay.h> #include <linux/module.h> #include <linux/spi/spi.h> -#include <linux/of_device.h> +#include <linux/mod_devicetable.h> #include <asm/unaligned.h> @@ -115,14 +115,12 @@ static int ms5611_spi_remove(struct spi_device *spi) return ms5611_remove(spi_get_drvdata(spi)); } -#if defined(CONFIG_OF) static const struct of_device_id ms5611_spi_matches[] = { { .compatible = "meas,ms5611" }, { .compatible = "meas,ms5607" }, { } }; MODULE_DEVICE_TABLE(of, ms5611_spi_matches); -#endif static const struct spi_device_id ms5611_id[] = { { "ms5611", MS5611 }, @@ -134,7 +132,7 @@ MODULE_DEVICE_TABLE(spi, ms5611_id); static struct spi_driver ms5611_driver = { .driver = { .name = "ms5611", - .of_match_table = of_match_ptr(ms5611_spi_matches) + .of_match_table = ms5611_spi_matches }, .id_table = ms5611_id, .probe = ms5611_spi_probe, diff --git a/drivers/iio/pressure/ms5637.c b/drivers/iio/pressure/ms5637.c index 05e0ef7260d5..5b59a4137d32 100644 --- a/drivers/iio/pressure/ms5637.c +++ b/drivers/iio/pressure/ms5637.c @@ -22,6 +22,7 @@ #include <linux/kernel.h> #include <linux/stat.h> #include <linux/module.h> +#include <linux/mod_devicetable.h> #include <linux/i2c.h> #include <linux/iio/iio.h> #include <linux/iio/sysfs.h> @@ -192,7 +193,7 @@ static struct i2c_driver ms5637_driver = { .id_table = ms5637_id, .driver = { .name = "ms5637", - .of_match_table = of_match_ptr(ms5637_of_match), + .of_match_table = ms5637_of_match, }, }; diff --git a/drivers/iio/pressure/zpa2326_i2c.c b/drivers/iio/pressure/zpa2326_i2c.c index 1a65791ba279..95d9739444c4 100644 --- a/drivers/iio/pressure/zpa2326_i2c.c +++ b/drivers/iio/pressure/zpa2326_i2c.c @@ -10,7 +10,7 @@ #include <linux/module.h> #include <linux/regmap.h> #include <linux/i2c.h> -#include <linux/of_device.h> +#include <linux/mod_devicetable.h> #include "zpa2326.h" /* @@ -66,18 +66,16 @@ static const struct i2c_device_id zpa2326_i2c_ids[] = { }; MODULE_DEVICE_TABLE(i2c, zpa2326_i2c_ids); -#if defined(CONFIG_OF) static const struct of_device_id zpa2326_i2c_matches[] = { { .compatible = "murata,zpa2326" }, { } }; MODULE_DEVICE_TABLE(of, zpa2326_i2c_matches); -#endif static struct i2c_driver zpa2326_i2c_driver = { .driver = { .name = "zpa2326-i2c", - .of_match_table = of_match_ptr(zpa2326_i2c_matches), + .of_match_table = zpa2326_i2c_matches, .pm = ZPA2326_PM_OPS, }, .probe = zpa2326_probe_i2c, diff --git a/drivers/iio/pressure/zpa2326_spi.c b/drivers/iio/pressure/zpa2326_spi.c index f37a4c738c75..85201a4bae44 100644 --- a/drivers/iio/pressure/zpa2326_spi.c +++ b/drivers/iio/pressure/zpa2326_spi.c @@ -10,7 +10,7 @@ #include <linux/module.h> #include <linux/regmap.h> #include <linux/spi/spi.h> -#include <linux/of_device.h> +#include <linux/mod_devicetable.h> #include "zpa2326.h" /* @@ -70,18 +70,16 @@ static const struct spi_device_id zpa2326_spi_ids[] = { }; MODULE_DEVICE_TABLE(spi, zpa2326_spi_ids); -#if defined(CONFIG_OF) static const struct of_device_id zpa2326_spi_matches[] = { { .compatible = "murata,zpa2326" }, { } }; MODULE_DEVICE_TABLE(of, zpa2326_spi_matches); -#endif static struct spi_driver zpa2326_spi_driver = { .driver = { .name = "zpa2326-spi", - .of_match_table = of_match_ptr(zpa2326_spi_matches), + .of_match_table = zpa2326_spi_matches, .pm = ZPA2326_PM_OPS, }, .probe = zpa2326_probe_spi, diff --git a/drivers/iio/proximity/as3935.c b/drivers/iio/proximity/as3935.c index c339e7339ec8..b79ada839e01 100644 --- a/drivers/iio/proximity/as3935.c +++ b/drivers/iio/proximity/as3935.c @@ -7,6 +7,7 @@ */ #include <linux/module.h> +#include <linux/mod_devicetable.h> #include <linux/init.h> #include <linux/interrupt.h> #include <linux/delay.h> @@ -352,19 +353,19 @@ static void as3935_stop_work(void *data) static int as3935_probe(struct spi_device *spi) { + struct device *dev = &spi->dev; struct iio_dev *indio_dev; struct iio_trigger *trig; struct as3935_state *st; - struct device_node *np = spi->dev.of_node; int ret; /* Be sure lightning event interrupt is specified */ if (!spi->irq) { - dev_err(&spi->dev, "unable to get event interrupt\n"); + dev_err(dev, "unable to get event interrupt\n"); return -EINVAL; } - indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); + indio_dev = devm_iio_device_alloc(dev, sizeof(*st)); if (!indio_dev) return -ENOMEM; @@ -374,27 +375,24 @@ static int as3935_probe(struct spi_device *spi) spi_set_drvdata(spi, indio_dev); mutex_init(&st->lock); - ret = of_property_read_u32(np, + ret = device_property_read_u32(dev, "ams,tuning-capacitor-pf", &st->tune_cap); if (ret) { st->tune_cap = 0; - dev_warn(&spi->dev, - "no tuning-capacitor-pf set, defaulting to %d", + dev_warn(dev, "no tuning-capacitor-pf set, defaulting to %d", st->tune_cap); } if (st->tune_cap > MAX_PF_CAP) { - dev_err(&spi->dev, - "wrong tuning-capacitor-pf setting of %d\n", + dev_err(dev, "wrong tuning-capacitor-pf setting of %d\n", st->tune_cap); return -EINVAL; } - ret = of_property_read_u32(np, + ret = device_property_read_u32(dev, "ams,nflwdth", &st->nflwdth_reg); if (!ret && st->nflwdth_reg > AS3935_NFLWDTH_MASK) { - dev_err(&spi->dev, - "invalid nflwdth setting of %d\n", + dev_err(dev, "invalid nflwdth setting of %d\n", st->nflwdth_reg); return -EINVAL; } @@ -405,7 +403,7 @@ static int as3935_probe(struct spi_device *spi) indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->info = &as3935_info; - trig = devm_iio_trigger_alloc(&spi->dev, "%s-dev%d", + trig = devm_iio_trigger_alloc(dev, "%s-dev%d", indio_dev->name, indio_dev->id); if (!trig) @@ -417,42 +415,42 @@ static int as3935_probe(struct spi_device *spi) iio_trigger_set_drvdata(trig, indio_dev); trig->ops = &iio_interrupt_trigger_ops; - ret = devm_iio_trigger_register(&spi->dev, trig); + ret = devm_iio_trigger_register(dev, trig); if (ret) { - dev_err(&spi->dev, "failed to register trigger\n"); + dev_err(dev, "failed to register trigger\n"); return ret; } - ret = devm_iio_triggered_buffer_setup(&spi->dev, indio_dev, + ret = devm_iio_triggered_buffer_setup(dev, indio_dev, iio_pollfunc_store_time, as3935_trigger_handler, NULL); if (ret) { - dev_err(&spi->dev, "cannot setup iio trigger\n"); + dev_err(dev, "cannot setup iio trigger\n"); return ret; } calibrate_as3935(st); INIT_DELAYED_WORK(&st->work, as3935_event_work); - ret = devm_add_action(&spi->dev, as3935_stop_work, indio_dev); + ret = devm_add_action(dev, as3935_stop_work, indio_dev); if (ret) return ret; - ret = devm_request_irq(&spi->dev, spi->irq, + ret = devm_request_irq(dev, spi->irq, &as3935_interrupt_handler, IRQF_TRIGGER_RISING, - dev_name(&spi->dev), + dev_name(dev), indio_dev); if (ret) { - dev_err(&spi->dev, "unable to request irq\n"); + dev_err(dev, "unable to request irq\n"); return ret; } - ret = devm_iio_device_register(&spi->dev, indio_dev); + ret = devm_iio_device_register(dev, indio_dev); if (ret < 0) { - dev_err(&spi->dev, "unable to register device\n"); + dev_err(dev, "unable to register device\n"); return ret; } return 0; @@ -473,7 +471,7 @@ MODULE_DEVICE_TABLE(spi, as3935_id); static struct spi_driver as3935_driver = { .driver = { .name = "as3935", - .of_match_table = of_match_ptr(as3935_of_match), + .of_match_table = as3935_of_match, .pm = AS3935_PM_OPS, }, .probe = as3935_probe, diff --git a/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c b/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c index a8e716dbd24e..c685f10b5ae4 100644 --- a/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c +++ b/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c @@ -13,6 +13,7 @@ #include <linux/i2c.h> #include <linux/delay.h> #include <linux/module.h> +#include <linux/mod_devicetable.h> #include <linux/pm_runtime.h> #include <linux/iio/iio.h> #include <linux/iio/sysfs.h> @@ -360,7 +361,7 @@ static const struct dev_pm_ops lidar_pm_ops = { static struct i2c_driver lidar_driver = { .driver = { .name = LIDAR_DRV_NAME, - .of_match_table = of_match_ptr(lidar_dt_ids), + .of_match_table = lidar_dt_ids, .pm = &lidar_pm_ops, }, .probe = lidar_probe, diff --git a/drivers/iio/proximity/sx9310.c b/drivers/iio/proximity/sx9310.c index dc2e11b43431..6d3f4ab8c6b2 100644 --- a/drivers/iio/proximity/sx9310.c +++ b/drivers/iio/proximity/sx9310.c @@ -6,19 +6,21 @@ * Based on SX9500 driver and Semtech driver using the input framework * <https://my.syncplicity.com/share/teouwsim8niiaud/ * linux-driver-SX9310_NoSmartHSensing>. - * Reworked April 2019 by Evan Green <evgreen@chromium.org> - * and January 2020 by Daniel Campello <campello@chromium.org> + * Reworked in April 2019 by Evan Green <evgreen@chromium.org> + * and in January 2020 by Daniel Campello <campello@chromium.org>. */ #include <linux/acpi.h> +#include <linux/bitfield.h> #include <linux/delay.h> #include <linux/i2c.h> #include <linux/irq.h> #include <linux/kernel.h> +#include <linux/mod_devicetable.h> #include <linux/module.h> -#include <linux/of.h> #include <linux/pm.h> #include <linux/regmap.h> +#include <linux/regulator/consumer.h> #include <linux/slab.h> #include <linux/iio/buffer.h> @@ -33,45 +35,44 @@ #define SX9310_REG_IRQ_SRC 0x00 #define SX9310_REG_STAT0 0x01 #define SX9310_REG_STAT1 0x02 +#define SX9310_REG_STAT1_COMPSTAT_MASK GENMASK(3, 0) #define SX9310_REG_IRQ_MSK 0x03 #define SX9310_CONVDONE_IRQ BIT(3) #define SX9310_FAR_IRQ BIT(5) #define SX9310_CLOSE_IRQ BIT(6) -#define SX9310_EVENT_IRQ (SX9310_FAR_IRQ | \ - SX9310_CLOSE_IRQ) #define SX9310_REG_IRQ_FUNC 0x04 #define SX9310_REG_PROX_CTRL0 0x10 -#define SX9310_REG_PROX_CTRL0_PROXSTAT2 0x10 -#define SX9310_REG_PROX_CTRL0_EN_MASK 0x0F +#define SX9310_REG_PROX_CTRL0_SENSOREN_MASK GENMASK(3, 0) +#define SX9310_REG_PROX_CTRL0_SCANPERIOD_MASK GENMASK(7, 4) +#define SX9310_REG_PROX_CTRL0_SCANPERIOD_15MS 0x01 #define SX9310_REG_PROX_CTRL1 0x11 #define SX9310_REG_PROX_CTRL2 0x12 -#define SX9310_REG_PROX_CTRL2_COMBMODE_ALL 0x80 -#define SX9310_REG_PROX_CTRL2_SHIELDEN_DYNAMIC 0x04 +#define SX9310_REG_PROX_CTRL2_COMBMODE_CS1_CS2 (0x02 << 6) +#define SX9310_REG_PROX_CTRL2_SHIELDEN_DYNAMIC (0x01 << 2) #define SX9310_REG_PROX_CTRL3 0x13 -#define SX9310_REG_PROX_CTRL3_GAIN0_X8 0x0c +#define SX9310_REG_PROX_CTRL3_GAIN0_X8 (0x03 << 2) #define SX9310_REG_PROX_CTRL3_GAIN12_X4 0x02 #define SX9310_REG_PROX_CTRL4 0x14 #define SX9310_REG_PROX_CTRL4_RESOLUTION_FINEST 0x07 #define SX9310_REG_PROX_CTRL5 0x15 -#define SX9310_REG_PROX_CTRL5_RANGE_SMALL 0xc0 -#define SX9310_REG_PROX_CTRL5_STARTUPSENS_CS1 0x04 +#define SX9310_REG_PROX_CTRL5_RANGE_SMALL (0x03 << 6) +#define SX9310_REG_PROX_CTRL5_STARTUPSENS_CS1 (0x01 << 2) #define SX9310_REG_PROX_CTRL5_RAWFILT_1P25 0x02 #define SX9310_REG_PROX_CTRL6 0x16 -#define SX9310_REG_PROX_CTRL6_COMP_COMMON 0x20 +#define SX9310_REG_PROX_CTRL6_AVGTHRESH_DEFAULT 0x20 #define SX9310_REG_PROX_CTRL7 0x17 -#define SX9310_REG_PROX_CTRL7_AVGNEGFILT_2 0x08 +#define SX9310_REG_PROX_CTRL7_AVGNEGFILT_2 (0x01 << 3) #define SX9310_REG_PROX_CTRL7_AVGPOSFILT_512 0x05 #define SX9310_REG_PROX_CTRL8 0x18 #define SX9310_REG_PROX_CTRL9 0x19 -#define SX9310_REG_PROX_CTRL8_9_PTHRESH12_28 0x40 -#define SX9310_REG_PROX_CTRL8_9_PTHRESH_96 0x88 +#define SX9310_REG_PROX_CTRL8_9_PTHRESH_28 (0x08 << 3) +#define SX9310_REG_PROX_CTRL8_9_PTHRESH_96 (0x11 << 3) #define SX9310_REG_PROX_CTRL8_9_BODYTHRESH_900 0x03 #define SX9310_REG_PROX_CTRL8_9_BODYTHRESH_1500 0x05 #define SX9310_REG_PROX_CTRL10 0x1a -#define SX9310_REG_PROX_CTRL10_HYST_6PCT 0x10 -#define SX9310_REG_PROX_CTRL10_CLOSE_DEBOUNCE_8 0x12 -#define SX9310_REG_PROX_CTRL10_FAR_DEBOUNCE_8 0x03 +#define SX9310_REG_PROX_CTRL10_HYST_6PCT (0x01 << 4) +#define SX9310_REG_PROX_CTRL10_FAR_DEBOUNCE_2 0x01 #define SX9310_REG_PROX_CTRL11 0x1b #define SX9310_REG_PROX_CTRL12 0x1c #define SX9310_REG_PROX_CTRL13 0x1d @@ -82,8 +83,8 @@ #define SX9310_REG_PROX_CTRL18 0x22 #define SX9310_REG_PROX_CTRL19 0x23 #define SX9310_REG_SAR_CTRL0 0x2a -#define SX9310_REG_SAR_CTRL0_SARDEB_4_SAMPLES 0x40 -#define SX9310_REG_SAR_CTRL0_SARHYST_8 0x10 +#define SX9310_REG_SAR_CTRL0_SARDEB_4_SAMPLES (0x02 << 5) +#define SX9310_REG_SAR_CTRL0_SARHYST_8 (0x02 << 3) #define SX9310_REG_SAR_CTRL1 0x2b /* Each increment of the slope register is 0.0078125. */ #define SX9310_REG_SAR_CTRL1_SLOPE(_hnslope) (_hnslope / 78125) @@ -91,39 +92,28 @@ #define SX9310_REG_SAR_CTRL2_SAROFFSET_DEFAULT 0x3c #define SX9310_REG_SENSOR_SEL 0x30 - #define SX9310_REG_USE_MSB 0x31 #define SX9310_REG_USE_LSB 0x32 - #define SX9310_REG_AVG_MSB 0x33 #define SX9310_REG_AVG_LSB 0x34 - #define SX9310_REG_DIFF_MSB 0x35 #define SX9310_REG_DIFF_LSB 0x36 - #define SX9310_REG_OFFSET_MSB 0x37 #define SX9310_REG_OFFSET_LSB 0x38 - #define SX9310_REG_SAR_MSB 0x39 #define SX9310_REG_SAR_LSB 0x3a - -#define SX9310_REG_I2CADDR 0x40 +#define SX9310_REG_I2C_ADDR 0x40 #define SX9310_REG_PAUSE 0x41 #define SX9310_REG_WHOAMI 0x42 #define SX9310_WHOAMI_VALUE 0x01 #define SX9311_WHOAMI_VALUE 0x02 - #define SX9310_REG_RESET 0x7f #define SX9310_SOFT_RESET 0xde -#define SX9310_SCAN_PERIOD_MASK GENMASK(7, 4) -#define SX9310_SCAN_PERIOD_SHIFT 4 - -#define SX9310_COMPSTAT_MASK GENMASK(3, 0) /* 4 hardware channels, as defined in STAT0: COMB, CS2, CS1 and CS0. */ #define SX9310_NUM_CHANNELS 4 -#define SX9310_CHAN_ENABLED_MASK GENMASK(3, 0) +static_assert(SX9310_NUM_CHANNELS < BITS_PER_LONG); struct sx9310_data { /* Serialize access to registers and channel configuration */ @@ -131,20 +121,24 @@ struct sx9310_data { struct i2c_client *client; struct iio_trigger *trig; struct regmap *regmap; + struct regulator_bulk_data supplies[2]; /* * Last reading of the proximity status for each channel. * We only send an event to user space when this changes. */ - bool prox_stat[SX9310_NUM_CHANNELS]; + unsigned long chan_prox_stat; bool trigger_enabled; - __be16 buffer[SX9310_NUM_CHANNELS + - 4]; /* 64-bit data + 64-bit timestamp */ + /* Ensure correct alignment of timestamp when present. */ + struct { + __be16 channels[SX9310_NUM_CHANNELS]; + s64 ts __aligned(8); + } buffer; /* Remember enabled channels and sample rate during suspend. */ unsigned int suspend_ctrl0; struct completion completion; - unsigned int chan_read, chan_event; - int channel_users[SX9310_NUM_CHANNELS]; - int whoami; + unsigned long chan_read; + unsigned long chan_event; + unsigned int whoami; }; static const struct iio_event_spec sx9310_events[] = { @@ -251,7 +245,7 @@ static const struct regmap_range sx9310_readable_reg_ranges[] = { regmap_reg_range(SX9310_REG_PROX_CTRL0, SX9310_REG_PROX_CTRL19), regmap_reg_range(SX9310_REG_SAR_CTRL0, SX9310_REG_SAR_CTRL2), regmap_reg_range(SX9310_REG_SENSOR_SEL, SX9310_REG_SAR_LSB), - regmap_reg_range(SX9310_REG_I2CADDR, SX9310_REG_WHOAMI), + regmap_reg_range(SX9310_REG_I2C_ADDR, SX9310_REG_WHOAMI), regmap_reg_range(SX9310_REG_RESET, SX9310_REG_RESET), }; @@ -285,15 +279,16 @@ static const struct regmap_config sx9310_regmap_config = { }; static int sx9310_update_chan_en(struct sx9310_data *data, - unsigned int chan_read, - unsigned int chan_event) + unsigned long chan_read, + unsigned long chan_event) { int ret; + unsigned long channels = chan_read | chan_event; - if ((data->chan_read | data->chan_event) != (chan_read | chan_event)) { + if ((data->chan_read | data->chan_event) != channels) { ret = regmap_update_bits(data->regmap, SX9310_REG_PROX_CTRL0, - SX9310_CHAN_ENABLED_MASK, - chan_read | chan_event); + SX9310_REG_PROX_CTRL0_SENSOREN_MASK, + channels); if (ret) return ret; } @@ -328,11 +323,15 @@ static int sx9310_put_event_channel(struct sx9310_data *data, int channel) static int sx9310_enable_irq(struct sx9310_data *data, unsigned int irq) { + if (!data->client->irq) + return 0; return regmap_update_bits(data->regmap, SX9310_REG_IRQ_MSK, irq, irq); } static int sx9310_disable_irq(struct sx9310_data *data, unsigned int irq) { + if (!data->client->irq) + return 0; return regmap_update_bits(data->regmap, SX9310_REG_IRQ_MSK, irq, 0); } @@ -342,10 +341,10 @@ static int sx9310_read_prox_data(struct sx9310_data *data, int ret; ret = regmap_write(data->regmap, SX9310_REG_SENSOR_SEL, chan->channel); - if (ret < 0) + if (ret) return ret; - return regmap_bulk_read(data->regmap, chan->address, val, 2); + return regmap_bulk_read(data->regmap, chan->address, val, sizeof(*val)); } /* @@ -358,10 +357,10 @@ static int sx9310_wait_for_sample(struct sx9310_data *data) unsigned int val; ret = regmap_read(data->regmap, SX9310_REG_PROX_CTRL0, &val); - if (ret < 0) + if (ret) return ret; - val = (val & SX9310_SCAN_PERIOD_MASK) >> SX9310_SCAN_PERIOD_SHIFT; + val = FIELD_GET(SX9310_REG_PROX_CTRL0_SCANPERIOD_MASK, val); msleep(sx9310_scan_period_table[val]); @@ -371,22 +370,22 @@ static int sx9310_wait_for_sample(struct sx9310_data *data) static int sx9310_read_proximity(struct sx9310_data *data, const struct iio_chan_spec *chan, int *val) { - int ret = 0; + int ret; __be16 rawval; mutex_lock(&data->mutex); ret = sx9310_get_read_channel(data, chan->channel); - if (ret < 0) + if (ret) goto out; ret = sx9310_enable_irq(data, SX9310_CONVDONE_IRQ); - if (ret < 0) + if (ret) goto out_put_channel; mutex_unlock(&data->mutex); - if (data->client->irq > 0) { + if (data->client->irq) { ret = wait_for_completion_interruptible(&data->completion); reinit_completion(&data->completion); } else { @@ -395,22 +394,22 @@ static int sx9310_read_proximity(struct sx9310_data *data, mutex_lock(&data->mutex); - if (ret < 0) + if (ret) goto out_disable_irq; ret = sx9310_read_prox_data(data, chan, &rawval); - if (ret < 0) + if (ret) goto out_disable_irq; *val = sign_extend32(be16_to_cpu(rawval), - (chan->address == SX9310_REG_DIFF_MSB ? 11 : 15)); + chan->address == SX9310_REG_DIFF_MSB ? 11 : 15); ret = sx9310_disable_irq(data, SX9310_CONVDONE_IRQ); - if (ret < 0) + if (ret) goto out_put_channel; ret = sx9310_put_read_channel(data, chan->channel); - if (ret < 0) + if (ret) goto out; mutex_unlock(&data->mutex); @@ -430,12 +429,13 @@ out: static int sx9310_read_samp_freq(struct sx9310_data *data, int *val, int *val2) { unsigned int regval; - int ret = regmap_read(data->regmap, SX9310_REG_PROX_CTRL0, ®val); + int ret; - if (ret < 0) + ret = regmap_read(data->regmap, SX9310_REG_PROX_CTRL0, ®val); + if (ret) return ret; - regval = (regval & SX9310_SCAN_PERIOD_MASK) >> SX9310_SCAN_PERIOD_SHIFT; + regval = FIELD_GET(SX9310_REG_PROX_CTRL0_SCANPERIOD_MASK, regval); *val = sx9310_samp_freq_table[regval].val; *val2 = sx9310_samp_freq_table[regval].val2; @@ -482,9 +482,10 @@ static int sx9310_set_samp_freq(struct sx9310_data *data, int val, int val2) mutex_lock(&data->mutex); - ret = regmap_update_bits(data->regmap, SX9310_REG_PROX_CTRL0, - SX9310_SCAN_PERIOD_MASK, - i << SX9310_SCAN_PERIOD_SHIFT); + ret = regmap_update_bits( + data->regmap, SX9310_REG_PROX_CTRL0, + SX9310_REG_PROX_CTRL0_SCANPERIOD_MASK, + FIELD_PREP(SX9310_REG_PROX_CTRL0_SCANPERIOD_MASK, i)); mutex_unlock(&data->mutex); @@ -515,10 +516,9 @@ static irqreturn_t sx9310_irq_handler(int irq, void *private) iio_trigger_poll(data->trig); /* - * Even if no event is enabled, we need to wake the thread to - * clear the interrupt state by reading SX9310_REG_IRQ_SRC. It - * is not possible to do that here because regmap_read takes a - * mutex. + * Even if no event is enabled, we need to wake the thread to clear the + * interrupt state by reading SX9310_REG_IRQ_SRC. + * It is not possible to do that here because regmap_read takes a mutex. */ return IRQ_WAKE_THREAD; } @@ -529,32 +529,32 @@ static void sx9310_push_events(struct iio_dev *indio_dev) unsigned int val, chan; struct sx9310_data *data = iio_priv(indio_dev); s64 timestamp = iio_get_time_ns(indio_dev); + unsigned long prox_changed; /* Read proximity state on all channels */ ret = regmap_read(data->regmap, SX9310_REG_STAT0, &val); - if (ret < 0) { + if (ret) { dev_err(&data->client->dev, "i2c transfer error in irq\n"); return; } - for (chan = 0; chan < SX9310_NUM_CHANNELS; chan++) { + /* + * Only iterate over channels with changes on proximity status that have + * events enabled. + */ + prox_changed = (data->chan_prox_stat ^ val) & data->chan_event; + + for_each_set_bit(chan, &prox_changed, SX9310_NUM_CHANNELS) { int dir; u64 ev; - bool new_prox = val & BIT(chan); - if (!(data->chan_event & BIT(chan))) - continue; - if (new_prox == data->prox_stat[chan]) - /* No change on this channel. */ - continue; - - dir = new_prox ? IIO_EV_DIR_FALLING : IIO_EV_DIR_RISING; + dir = (val & BIT(chan)) ? IIO_EV_DIR_FALLING : IIO_EV_DIR_RISING; ev = IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY, chan, IIO_EV_TYPE_THRESH, dir); iio_push_event(indio_dev, ev, timestamp); - data->prox_stat[chan] = new_prox; } + data->chan_prox_stat = val; } static irqreturn_t sx9310_irq_thread_handler(int irq, void *private) @@ -567,12 +567,12 @@ static irqreturn_t sx9310_irq_thread_handler(int irq, void *private) mutex_lock(&data->mutex); ret = regmap_read(data->regmap, SX9310_REG_IRQ_SRC, &val); - if (ret < 0) { + if (ret) { dev_err(&data->client->dev, "i2c transfer error in irq\n"); goto out; } - if (val & SX9310_EVENT_IRQ) + if (val & (SX9310_FAR_IRQ | SX9310_CLOSE_IRQ)) sx9310_push_events(indio_dev); if (val & SX9310_CONVDONE_IRQ) @@ -600,6 +600,7 @@ static int sx9310_write_event_config(struct iio_dev *indio_dev, enum iio_event_direction dir, int state) { struct sx9310_data *data = iio_priv(indio_dev); + unsigned int eventirq = SX9310_FAR_IRQ | SX9310_CLOSE_IRQ; int ret; /* If the state hasn't changed, there's nothing to do. */ @@ -609,20 +610,20 @@ static int sx9310_write_event_config(struct iio_dev *indio_dev, mutex_lock(&data->mutex); if (state) { ret = sx9310_get_event_channel(data, chan->channel); - if (ret < 0) + if (ret) goto out_unlock; if (!(data->chan_event & ~BIT(chan->channel))) { - ret = sx9310_enable_irq(data, SX9310_EVENT_IRQ); - if (ret < 0) + ret = sx9310_enable_irq(data, eventirq); + if (ret) sx9310_put_event_channel(data, chan->channel); } } else { ret = sx9310_put_event_channel(data, chan->channel); - if (ret < 0) + if (ret) goto out_unlock; if (!data->chan_event) { - ret = sx9310_disable_irq(data, SX9310_EVENT_IRQ); - if (ret < 0) + ret = sx9310_disable_irq(data, eventirq); + if (ret) sx9310_get_event_channel(data, chan->channel); } } @@ -634,7 +635,7 @@ out_unlock: static struct attribute *sx9310_attributes[] = { &iio_dev_attr_sampling_frequency_available.dev_attr.attr, - NULL, + NULL }; static const struct attribute_group sx9310_attribute_group = { @@ -661,7 +662,7 @@ static int sx9310_set_trigger_state(struct iio_trigger *trig, bool state) ret = sx9310_enable_irq(data, SX9310_CONVDONE_IRQ); else if (!data->chan_read) ret = sx9310_disable_irq(data, SX9310_CONVDONE_IRQ); - if (ret < 0) + if (ret) goto out; data->trigger_enabled = state; @@ -690,13 +691,13 @@ static irqreturn_t sx9310_trigger_handler(int irq, void *private) indio_dev->masklength) { ret = sx9310_read_prox_data(data, &indio_dev->channels[bit], &val); - if (ret < 0) + if (ret) goto out; - data->buffer[i++] = val; + data->buffer.channels[i++] = val; } - iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, + iio_push_to_buffers_with_timestamp(indio_dev, &data->buffer, pf->timestamp); out: @@ -710,13 +711,13 @@ out: static int sx9310_buffer_preenable(struct iio_dev *indio_dev) { struct sx9310_data *data = iio_priv(indio_dev); - unsigned int channels = 0; + unsigned long channels = 0; int bit, ret; mutex_lock(&data->mutex); for_each_set_bit(bit, indio_dev->active_scan_mask, indio_dev->masklength) - channels |= BIT(indio_dev->channels[bit].channel); + __set_bit(indio_dev->channels[bit].channel, &channels); ret = sx9310_update_chan_en(data, channels, data->chan_event); mutex_unlock(&data->mutex); @@ -744,89 +745,77 @@ struct sx9310_reg_default { u8 def; }; -#define SX_INIT(_reg, _def) \ - { \ - .reg = SX9310_REG_##_reg, \ - .def = _def, \ - } - static const struct sx9310_reg_default sx9310_default_regs[] = { - SX_INIT(IRQ_MSK, 0x00), - SX_INIT(IRQ_FUNC, 0x00), + { SX9310_REG_IRQ_MSK, 0x00 }, + { SX9310_REG_IRQ_FUNC, 0x00 }, /* * The lower 4 bits should not be set as it enable sensors measurements. * Turning the detection on before the configuration values are set to * good values can cause the device to return erroneous readings. */ - SX_INIT(PROX_CTRL0, SX9310_REG_PROX_CTRL0_PROXSTAT2), - SX_INIT(PROX_CTRL1, 0x00), - SX_INIT(PROX_CTRL2, SX9310_REG_PROX_CTRL2_COMBMODE_ALL | - SX9310_REG_PROX_CTRL2_SHIELDEN_DYNAMIC), - SX_INIT(PROX_CTRL3, SX9310_REG_PROX_CTRL3_GAIN0_X8 | - SX9310_REG_PROX_CTRL3_GAIN12_X4), - SX_INIT(PROX_CTRL4, SX9310_REG_PROX_CTRL4_RESOLUTION_FINEST), - SX_INIT(PROX_CTRL5, SX9310_REG_PROX_CTRL5_RANGE_SMALL | - SX9310_REG_PROX_CTRL5_STARTUPSENS_CS1 | - SX9310_REG_PROX_CTRL5_RAWFILT_1P25), - SX_INIT(PROX_CTRL6, SX9310_REG_PROX_CTRL6_COMP_COMMON), - SX_INIT(PROX_CTRL7, SX9310_REG_PROX_CTRL7_AVGNEGFILT_2 | - SX9310_REG_PROX_CTRL7_AVGPOSFILT_512), - SX_INIT(PROX_CTRL8, SX9310_REG_PROX_CTRL8_9_PTHRESH_96 | - SX9310_REG_PROX_CTRL8_9_BODYTHRESH_1500), - SX_INIT(PROX_CTRL9, SX9310_REG_PROX_CTRL8_9_PTHRESH12_28 | - SX9310_REG_PROX_CTRL8_9_BODYTHRESH_900), - SX_INIT(PROX_CTRL10, SX9310_REG_PROX_CTRL10_HYST_6PCT | - SX9310_REG_PROX_CTRL10_CLOSE_DEBOUNCE_8 | - SX9310_REG_PROX_CTRL10_FAR_DEBOUNCE_8), - SX_INIT(PROX_CTRL11, 0x00), - SX_INIT(PROX_CTRL12, 0x00), - SX_INIT(PROX_CTRL13, 0x00), - SX_INIT(PROX_CTRL14, 0x00), - SX_INIT(PROX_CTRL15, 0x00), - SX_INIT(PROX_CTRL16, 0x00), - SX_INIT(PROX_CTRL17, 0x00), - SX_INIT(PROX_CTRL18, 0x00), - SX_INIT(PROX_CTRL19, 0x00), - SX_INIT(SAR_CTRL0, SX9310_REG_SAR_CTRL0_SARDEB_4_SAMPLES | - SX9310_REG_SAR_CTRL0_SARHYST_8), - SX_INIT(SAR_CTRL1, SX9310_REG_SAR_CTRL1_SLOPE(10781250)), - SX_INIT(SAR_CTRL2, SX9310_REG_SAR_CTRL2_SAROFFSET_DEFAULT), + { SX9310_REG_PROX_CTRL0, SX9310_REG_PROX_CTRL0_SCANPERIOD_15MS }, + { SX9310_REG_PROX_CTRL1, 0x00 }, + { SX9310_REG_PROX_CTRL2, SX9310_REG_PROX_CTRL2_COMBMODE_CS1_CS2 | + SX9310_REG_PROX_CTRL2_SHIELDEN_DYNAMIC }, + { SX9310_REG_PROX_CTRL3, SX9310_REG_PROX_CTRL3_GAIN0_X8 | + SX9310_REG_PROX_CTRL3_GAIN12_X4 }, + { SX9310_REG_PROX_CTRL4, SX9310_REG_PROX_CTRL4_RESOLUTION_FINEST }, + { SX9310_REG_PROX_CTRL5, SX9310_REG_PROX_CTRL5_RANGE_SMALL | + SX9310_REG_PROX_CTRL5_STARTUPSENS_CS1 | + SX9310_REG_PROX_CTRL5_RAWFILT_1P25 }, + { SX9310_REG_PROX_CTRL6, SX9310_REG_PROX_CTRL6_AVGTHRESH_DEFAULT }, + { SX9310_REG_PROX_CTRL7, SX9310_REG_PROX_CTRL7_AVGNEGFILT_2 | + SX9310_REG_PROX_CTRL7_AVGPOSFILT_512 }, + { SX9310_REG_PROX_CTRL8, SX9310_REG_PROX_CTRL8_9_PTHRESH_96 | + SX9310_REG_PROX_CTRL8_9_BODYTHRESH_1500 }, + { SX9310_REG_PROX_CTRL9, SX9310_REG_PROX_CTRL8_9_PTHRESH_28 | + SX9310_REG_PROX_CTRL8_9_BODYTHRESH_900 }, + { SX9310_REG_PROX_CTRL10, SX9310_REG_PROX_CTRL10_HYST_6PCT | + SX9310_REG_PROX_CTRL10_FAR_DEBOUNCE_2 }, + { SX9310_REG_PROX_CTRL11, 0x00 }, + { SX9310_REG_PROX_CTRL12, 0x00 }, + { SX9310_REG_PROX_CTRL13, 0x00 }, + { SX9310_REG_PROX_CTRL14, 0x00 }, + { SX9310_REG_PROX_CTRL15, 0x00 }, + { SX9310_REG_PROX_CTRL16, 0x00 }, + { SX9310_REG_PROX_CTRL17, 0x00 }, + { SX9310_REG_PROX_CTRL18, 0x00 }, + { SX9310_REG_PROX_CTRL19, 0x00 }, + { SX9310_REG_SAR_CTRL0, SX9310_REG_SAR_CTRL0_SARDEB_4_SAMPLES | + SX9310_REG_SAR_CTRL0_SARHYST_8 }, + { SX9310_REG_SAR_CTRL1, SX9310_REG_SAR_CTRL1_SLOPE(10781250) }, + { SX9310_REG_SAR_CTRL2, SX9310_REG_SAR_CTRL2_SAROFFSET_DEFAULT }, }; /* Activate all channels and perform an initial compensation. */ static int sx9310_init_compensation(struct iio_dev *indio_dev) { struct sx9310_data *data = iio_priv(indio_dev); - int i, ret; + int ret; unsigned int val; unsigned int ctrl0; ret = regmap_read(data->regmap, SX9310_REG_PROX_CTRL0, &ctrl0); - if (ret < 0) + if (ret) return ret; /* run the compensation phase on all channels */ ret = regmap_write(data->regmap, SX9310_REG_PROX_CTRL0, - ctrl0 | SX9310_REG_PROX_CTRL0_EN_MASK); - if (ret < 0) + ctrl0 | SX9310_REG_PROX_CTRL0_SENSOREN_MASK); + if (ret) return ret; - for (i = 100; i >= 0; i--) { - msleep(20); - ret = regmap_read(data->regmap, SX9310_REG_STAT1, &val); - if (ret < 0) - goto out; - if (!(val & SX9310_COMPSTAT_MASK)) - break; - } - - if (i < 0) { - dev_err(&data->client->dev, - "initial compensation timed out: 0x%02x", val); - ret = -ETIMEDOUT; + ret = regmap_read_poll_timeout(data->regmap, SX9310_REG_STAT1, val, + !(val & SX9310_REG_STAT1_COMPSTAT_MASK), + 20000, 2000000); + if (ret) { + if (ret == -ETIMEDOUT) + dev_err(&data->client->dev, + "initial compensation timed out: 0x%02x\n", + val); + return ret; } -out: regmap_write(data->regmap, SX9310_REG_PROX_CTRL0, ctrl0); return ret; } @@ -839,21 +828,21 @@ static int sx9310_init_device(struct iio_dev *indio_dev) unsigned int i, val; ret = regmap_write(data->regmap, SX9310_REG_RESET, SX9310_SOFT_RESET); - if (ret < 0) + if (ret) return ret; usleep_range(1000, 2000); /* power-up time is ~1ms. */ /* Clear reset interrupt state by reading SX9310_REG_IRQ_SRC. */ ret = regmap_read(data->regmap, SX9310_REG_IRQ_SRC, &val); - if (ret < 0) + if (ret) return ret; /* Program some sane defaults. */ for (i = 0; i < ARRAY_SIZE(sx9310_default_regs); i++) { initval = &sx9310_default_regs[i]; ret = regmap_write(data->regmap, initval->reg, initval->def); - if (ret < 0) + if (ret) return ret; } @@ -862,24 +851,15 @@ static int sx9310_init_device(struct iio_dev *indio_dev) static int sx9310_set_indio_dev_name(struct device *dev, struct iio_dev *indio_dev, - const struct i2c_device_id *id, int whoami) + unsigned int whoami) { - const struct acpi_device_id *acpi_id; - - /* id will be NULL when enumerated via ACPI */ - if (id) { - if (id->driver_data != whoami) - dev_err(dev, "WHOAMI does not match i2c_device_id: %s", - id->name); - } else if (ACPI_HANDLE(dev)) { - acpi_id = acpi_match_device(dev->driver->acpi_match_table, dev); - if (!acpi_id) - return -ENODEV; - if (acpi_id->driver_data != whoami) - dev_err(dev, "WHOAMI does not match acpi_device_id: %s", - acpi_id->id); - } else + unsigned int long ddata; + + ddata = (uintptr_t)device_get_match_data(dev); + if (ddata != whoami) { + dev_err(dev, "WHOAMI does not match device data: %u\n", whoami); return -ENODEV; + } switch (whoami) { case SX9310_WHOAMI_VALUE: @@ -889,26 +869,35 @@ static int sx9310_set_indio_dev_name(struct device *dev, indio_dev->name = "sx9311"; break; default: - dev_err(dev, "unexpected WHOAMI response: %u", whoami); + dev_err(dev, "unexpected WHOAMI response: %u\n", whoami); return -ENODEV; } return 0; } -static int sx9310_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static void sx9310_regulator_disable(void *_data) +{ + struct sx9310_data *data = _data; + + regulator_bulk_disable(ARRAY_SIZE(data->supplies), data->supplies); +} + +static int sx9310_probe(struct i2c_client *client) { int ret; + struct device *dev = &client->dev; struct iio_dev *indio_dev; struct sx9310_data *data; - indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); - if (indio_dev == NULL) + indio_dev = devm_iio_device_alloc(dev, sizeof(*data)); + if (!indio_dev) return -ENOMEM; data = iio_priv(indio_dev); data->client = client; + data->supplies[0].supply = "vdd"; + data->supplies[1].supply = "svdd"; mutex_init(&data->mutex); init_completion(&data->completion); @@ -916,19 +905,32 @@ static int sx9310_probe(struct i2c_client *client, if (IS_ERR(data->regmap)) return PTR_ERR(data->regmap); + ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(data->supplies), + data->supplies); + if (ret) + return ret; + + ret = regulator_bulk_enable(ARRAY_SIZE(data->supplies), data->supplies); + if (ret) + return ret; + /* Must wait for Tpor time after initial power up */ + usleep_range(1000, 1100); + + ret = devm_add_action_or_reset(dev, sx9310_regulator_disable, data); + if (ret) + return ret; + ret = regmap_read(data->regmap, SX9310_REG_WHOAMI, &data->whoami); - if (ret < 0) { - dev_err(&client->dev, "error in reading WHOAMI register: %d", - ret); + if (ret) { + dev_err(dev, "error in reading WHOAMI register: %d", ret); return ret; } - ret = sx9310_set_indio_dev_name(&client->dev, indio_dev, id, - data->whoami); - if (ret < 0) + ret = sx9310_set_indio_dev_name(dev, indio_dev, data->whoami); + if (ret) return ret; - ACPI_COMPANION_SET(&indio_dev->dev, ACPI_COMPANION(&client->dev)); + ACPI_COMPANION_SET(&indio_dev->dev, ACPI_COMPANION(dev)); indio_dev->channels = sx9310_channels; indio_dev->num_channels = ARRAY_SIZE(sx9310_channels); indio_dev->info = &sx9310_info; @@ -936,41 +938,41 @@ static int sx9310_probe(struct i2c_client *client, i2c_set_clientdata(client, indio_dev); ret = sx9310_init_device(indio_dev); - if (ret < 0) + if (ret) return ret; if (client->irq) { - ret = devm_request_threaded_irq(&client->dev, client->irq, + ret = devm_request_threaded_irq(dev, client->irq, sx9310_irq_handler, sx9310_irq_thread_handler, - IRQF_TRIGGER_LOW | IRQF_ONESHOT, + IRQF_ONESHOT, "sx9310_event", indio_dev); - if (ret < 0) + if (ret) return ret; - data->trig = - devm_iio_trigger_alloc(&client->dev, "%s-dev%d", - indio_dev->name, indio_dev->id); + data->trig = devm_iio_trigger_alloc(dev, "%s-dev%d", + indio_dev->name, + indio_dev->id); if (!data->trig) return -ENOMEM; - data->trig->dev.parent = &client->dev; + data->trig->dev.parent = dev; data->trig->ops = &sx9310_trigger_ops; iio_trigger_set_drvdata(data->trig, indio_dev); - ret = devm_iio_trigger_register(&client->dev, data->trig); + ret = devm_iio_trigger_register(dev, data->trig); if (ret) return ret; } - ret = devm_iio_triggered_buffer_setup(&client->dev, indio_dev, + ret = devm_iio_triggered_buffer_setup(dev, indio_dev, iio_pollfunc_store_time, sx9310_trigger_handler, &sx9310_buffer_setup_ops); - if (ret < 0) + if (ret) return ret; - return devm_iio_device_register(&client->dev, indio_dev); + return devm_iio_device_register(dev, indio_dev); } static int __maybe_unused sx9310_suspend(struct device *dev) @@ -985,11 +987,10 @@ static int __maybe_unused sx9310_suspend(struct device *dev) mutex_lock(&data->mutex); ret = regmap_read(data->regmap, SX9310_REG_PROX_CTRL0, &data->suspend_ctrl0); - if (ret) goto out; - ctrl0 = data->suspend_ctrl0 & ~SX9310_REG_PROX_CTRL0_EN_MASK; + ctrl0 = data->suspend_ctrl0 & ~SX9310_REG_PROX_CTRL0_SENSOREN_MASK; ret = regmap_write(data->regmap, SX9310_REG_PROX_CTRL0, ctrl0); if (ret) goto out; @@ -1017,10 +1018,11 @@ static int __maybe_unused sx9310_resume(struct device *dev) out: mutex_unlock(&data->mutex); + if (ret) + return ret; enable_irq(data->client->irq); - - return ret; + return 0; } static const struct dev_pm_ops sx9310_pm_ops = { @@ -1030,32 +1032,39 @@ static const struct dev_pm_ops sx9310_pm_ops = { static const struct acpi_device_id sx9310_acpi_match[] = { { "STH9310", SX9310_WHOAMI_VALUE }, { "STH9311", SX9311_WHOAMI_VALUE }, - {}, + {} }; MODULE_DEVICE_TABLE(acpi, sx9310_acpi_match); static const struct of_device_id sx9310_of_match[] = { - { .compatible = "semtech,sx9310" }, - { .compatible = "semtech,sx9311" }, - {}, + { .compatible = "semtech,sx9310", (void *)SX9310_WHOAMI_VALUE }, + { .compatible = "semtech,sx9311", (void *)SX9311_WHOAMI_VALUE }, + {} }; MODULE_DEVICE_TABLE(of, sx9310_of_match); static const struct i2c_device_id sx9310_id[] = { { "sx9310", SX9310_WHOAMI_VALUE }, { "sx9311", SX9311_WHOAMI_VALUE }, - {}, + {} }; MODULE_DEVICE_TABLE(i2c, sx9310_id); static struct i2c_driver sx9310_driver = { .driver = { .name = "sx9310", - .acpi_match_table = ACPI_PTR(sx9310_acpi_match), - .of_match_table = of_match_ptr(sx9310_of_match), + .acpi_match_table = sx9310_acpi_match, + .of_match_table = sx9310_of_match, .pm = &sx9310_pm_ops, + + /* + * Lots of i2c transfers in probe + over 200 ms waiting in + * sx9310_init_compensation() mean a slow probe; prefer async + * so we don't delay boot if we're builtin to the kernel. + */ + .probe_type = PROBE_PREFER_ASYNCHRONOUS, }, - .probe = sx9310_probe, + .probe_new = sx9310_probe, .id_table = sx9310_id, }; module_i2c_driver(sx9310_driver); diff --git a/drivers/iio/proximity/vl53l0x-i2c.c b/drivers/iio/proximity/vl53l0x-i2c.c index 5fbda9475ba9..235e125aeb3a 100644 --- a/drivers/iio/proximity/vl53l0x-i2c.c +++ b/drivers/iio/proximity/vl53l0x-i2c.c @@ -4,18 +4,19 @@ * * Copyright (C) 2016 STMicroelectronics Imaging Division. * Copyright (C) 2018 Song Qiang <songqiang1304521@gmail.com> + * Copyright (C) 2020 Ivan Drobyshevskyi <drobyshevskyi@gmail.com> * * Datasheet available at * <https://www.st.com/resource/en/datasheet/vl53l0x.pdf> * * Default 7-bit i2c slave address 0x29. * - * TODO: FIFO buffer, continuous mode, interrupts, range selection, - * sensor ID check. + * TODO: FIFO buffer, continuous mode, range selection, sensor ID check. */ #include <linux/delay.h> #include <linux/i2c.h> +#include <linux/interrupt.h> #include <linux/module.h> #include <linux/iio/iio.h> @@ -29,14 +30,72 @@ #define VL_REG_SYSRANGE_MODE_TIMED BIT(2) #define VL_REG_SYSRANGE_MODE_HISTOGRAM BIT(3) +#define VL_REG_SYSTEM_INTERRUPT_CONFIG_GPIO 0x0A +#define VL_REG_SYSTEM_INTERRUPT_GPIO_NEW_SAMPLE_READY BIT(2) + +#define VL_REG_SYSTEM_INTERRUPT_CLEAR 0x0B + #define VL_REG_RESULT_INT_STATUS 0x13 #define VL_REG_RESULT_RANGE_STATUS 0x14 #define VL_REG_RESULT_RANGE_STATUS_COMPLETE BIT(0) struct vl53l0x_data { struct i2c_client *client; + struct completion completion; }; +static irqreturn_t vl53l0x_handle_irq(int irq, void *priv) +{ + struct iio_dev *indio_dev = priv; + struct vl53l0x_data *data = iio_priv(indio_dev); + + complete(&data->completion); + + return IRQ_HANDLED; +} + +static int vl53l0x_configure_irq(struct i2c_client *client, + struct iio_dev *indio_dev) +{ + struct vl53l0x_data *data = iio_priv(indio_dev); + int ret; + + ret = devm_request_irq(&client->dev, client->irq, vl53l0x_handle_irq, + IRQF_TRIGGER_FALLING, indio_dev->name, indio_dev); + if (ret) { + dev_err(&client->dev, "devm_request_irq error: %d\n", ret); + return ret; + } + + ret = i2c_smbus_write_byte_data(data->client, + VL_REG_SYSTEM_INTERRUPT_CONFIG_GPIO, + VL_REG_SYSTEM_INTERRUPT_GPIO_NEW_SAMPLE_READY); + if (ret < 0) + dev_err(&client->dev, "failed to configure IRQ: %d\n", ret); + + return ret; +} + +static void vl53l0x_clear_irq(struct vl53l0x_data *data) +{ + struct device *dev = &data->client->dev; + int ret; + + ret = i2c_smbus_write_byte_data(data->client, + VL_REG_SYSTEM_INTERRUPT_CLEAR, 1); + if (ret < 0) + dev_err(dev, "failed to clear error irq: %d\n", ret); + + ret = i2c_smbus_write_byte_data(data->client, + VL_REG_SYSTEM_INTERRUPT_CLEAR, 0); + if (ret < 0) + dev_err(dev, "failed to clear range irq: %d\n", ret); + + ret = i2c_smbus_read_byte_data(data->client, VL_REG_RESULT_INT_STATUS); + if (ret < 0 || ret & 0x07) + dev_err(dev, "failed to clear irq: %d\n", ret); +} + static int vl53l0x_read_proximity(struct vl53l0x_data *data, const struct iio_chan_spec *chan, int *val) @@ -50,19 +109,31 @@ static int vl53l0x_read_proximity(struct vl53l0x_data *data, if (ret < 0) return ret; - do { - ret = i2c_smbus_read_byte_data(client, - VL_REG_RESULT_RANGE_STATUS); + if (data->client->irq) { + reinit_completion(&data->completion); + + ret = wait_for_completion_timeout(&data->completion, HZ/10); if (ret < 0) return ret; + else if (ret == 0) + return -ETIMEDOUT; - if (ret & VL_REG_RESULT_RANGE_STATUS_COMPLETE) - break; + vl53l0x_clear_irq(data); + } else { + do { + ret = i2c_smbus_read_byte_data(client, + VL_REG_RESULT_RANGE_STATUS); + if (ret < 0) + return ret; - usleep_range(1000, 5000); - } while (--tries); - if (!tries) - return -ETIMEDOUT; + if (ret & VL_REG_RESULT_RANGE_STATUS_COMPLETE) + break; + + usleep_range(1000, 5000); + } while (--tries); + if (!tries) + return -ETIMEDOUT; + } ret = i2c_smbus_read_i2c_block_data(client, VL_REG_RESULT_RANGE_STATUS, 12, buffer); @@ -140,6 +211,17 @@ static int vl53l0x_probe(struct i2c_client *client) indio_dev->num_channels = ARRAY_SIZE(vl53l0x_channels); indio_dev->modes = INDIO_DIRECT_MODE; + /* usage of interrupt is optional */ + if (client->irq) { + int ret; + + init_completion(&data->completion); + + ret = vl53l0x_configure_irq(client, indio_dev); + if (ret) + return ret; + } + return devm_iio_device_register(&client->dev, indio_dev); } diff --git a/drivers/iio/resolver/ad2s1200.c b/drivers/iio/resolver/ad2s1200.c index 6007abad116b..9746bd935628 100644 --- a/drivers/iio/resolver/ad2s1200.c +++ b/drivers/iio/resolver/ad2s1200.c @@ -12,6 +12,7 @@ #include <linux/device.h> #include <linux/gpio/consumer.h> #include <linux/module.h> +#include <linux/mod_devicetable.h> #include <linux/mutex.h> #include <linux/spi/spi.h> #include <linux/sysfs.h> @@ -192,7 +193,7 @@ MODULE_DEVICE_TABLE(spi, ad2s1200_id); static struct spi_driver ad2s1200_driver = { .driver = { .name = DRV_NAME, - .of_match_table = of_match_ptr(ad2s1200_of_match), + .of_match_table = ad2s1200_of_match, }, .probe = ad2s1200_probe, .id_table = ad2s1200_id, diff --git a/drivers/iio/temperature/ltc2983.c b/drivers/iio/temperature/ltc2983.c index 55ff28a0f1c7..3b5ba26d7d86 100644 --- a/drivers/iio/temperature/ltc2983.c +++ b/drivers/iio/temperature/ltc2983.c @@ -1285,18 +1285,20 @@ static int ltc2983_parse_dt(struct ltc2983_data *st) ret = of_property_read_u32(child, "reg", &sensor.chan); if (ret) { dev_err(dev, "reg property must given for child nodes\n"); - return ret; + goto put_child; } /* check if we have a valid channel */ if (sensor.chan < LTC2983_MIN_CHANNELS_NR || sensor.chan > LTC2983_MAX_CHANNELS_NR) { + ret = -EINVAL; dev_err(dev, "chan:%d must be from 1 to 20\n", sensor.chan); - return -EINVAL; + goto put_child; } else if (channel_avail_mask & BIT(sensor.chan)) { + ret = -EINVAL; dev_err(dev, "chan:%d already in use\n", sensor.chan); - return -EINVAL; + goto put_child; } ret = of_property_read_u32(child, "adi,sensor-type", @@ -1304,7 +1306,7 @@ static int ltc2983_parse_dt(struct ltc2983_data *st) if (ret) { dev_err(dev, "adi,sensor-type property must given for child nodes\n"); - return ret; + goto put_child; } dev_dbg(dev, "Create new sensor, type %u, chann %u", @@ -1334,13 +1336,15 @@ static int ltc2983_parse_dt(struct ltc2983_data *st) st->sensors[chan] = ltc2983_adc_new(child, st, &sensor); } else { dev_err(dev, "Unknown sensor type %d\n", sensor.type); - return -EINVAL; + ret = -EINVAL; + goto put_child; } if (IS_ERR(st->sensors[chan])) { dev_err(dev, "Failed to create sensor %ld", PTR_ERR(st->sensors[chan])); - return PTR_ERR(st->sensors[chan]); + ret = PTR_ERR(st->sensors[chan]); + goto put_child; } /* set generic sensor parameters */ st->sensors[chan]->chan = sensor.chan; @@ -1351,6 +1355,9 @@ static int ltc2983_parse_dt(struct ltc2983_data *st) } return 0; +put_child: + of_node_put(child); + return ret; } static int ltc2983_setup(struct ltc2983_data *st, bool assign_iio) diff --git a/drivers/iio/temperature/mlx90632.c b/drivers/iio/temperature/mlx90632.c index 51b812bcff2e..503fe54a0bb9 100644 --- a/drivers/iio/temperature/mlx90632.c +++ b/drivers/iio/temperature/mlx90632.c @@ -10,7 +10,9 @@ #include <linux/err.h> #include <linux/gpio/consumer.h> #include <linux/i2c.h> +#include <linux/iopoll.h> #include <linux/kernel.h> +#include <linux/limits.h> #include <linux/module.h> #include <linux/math64.h> #include <linux/of.h> @@ -58,6 +60,8 @@ /* Control register address - volatile */ #define MLX90632_REG_CONTROL 0x3001 /* Control Register address */ #define MLX90632_CFG_PWR_MASK GENMASK(2, 1) /* PowerMode Mask */ +#define MLX90632_CFG_MTYP_MASK GENMASK(8, 4) /* Meas select Mask */ + /* PowerModes statuses */ #define MLX90632_PWR_STATUS(ctrl_val) (ctrl_val << 1) #define MLX90632_PWR_STATUS_HALT MLX90632_PWR_STATUS(0) /* hold */ @@ -65,6 +69,18 @@ #define MLX90632_PWR_STATUS_STEP MLX90632_PWR_STATUS(2) /* step */ #define MLX90632_PWR_STATUS_CONTINUOUS MLX90632_PWR_STATUS(3) /* continuous*/ +/* Measurement types */ +#define MLX90632_MTYP_MEDICAL 0 +#define MLX90632_MTYP_EXTENDED 17 + +/* Measurement type select*/ +#define MLX90632_MTYP_STATUS(ctrl_val) (ctrl_val << 4) +#define MLX90632_MTYP_STATUS_MEDICAL MLX90632_MTYP_STATUS(MLX90632_MTYP_MEDICAL) +#define MLX90632_MTYP_STATUS_EXTENDED MLX90632_MTYP_STATUS(MLX90632_MTYP_EXTENDED) + +/* I2C command register - volatile */ +#define MLX90632_REG_I2C_CMD 0x3005 /* I2C command Register address */ + /* Device status register - volatile */ #define MLX90632_REG_STATUS 0x3fff /* Device status register */ #define MLX90632_STAT_BUSY BIT(10) /* Device busy indicator */ @@ -78,26 +94,53 @@ #define MLX90632_RAM_2(meas_num) (MLX90632_ADDR_RAM + 3 * meas_num + 1) #define MLX90632_RAM_3(meas_num) (MLX90632_ADDR_RAM + 3 * meas_num + 2) +/* Name important RAM_MEAS channels */ +#define MLX90632_RAM_DSP5_EXTENDED_AMBIENT_1 MLX90632_RAM_3(17) +#define MLX90632_RAM_DSP5_EXTENDED_AMBIENT_2 MLX90632_RAM_3(18) +#define MLX90632_RAM_DSP5_EXTENDED_OBJECT_1 MLX90632_RAM_1(17) +#define MLX90632_RAM_DSP5_EXTENDED_OBJECT_2 MLX90632_RAM_2(17) +#define MLX90632_RAM_DSP5_EXTENDED_OBJECT_3 MLX90632_RAM_1(18) +#define MLX90632_RAM_DSP5_EXTENDED_OBJECT_4 MLX90632_RAM_2(18) +#define MLX90632_RAM_DSP5_EXTENDED_OBJECT_5 MLX90632_RAM_1(19) +#define MLX90632_RAM_DSP5_EXTENDED_OBJECT_6 MLX90632_RAM_2(19) + /* Magic constants */ #define MLX90632_ID_MEDICAL 0x0105 /* EEPROM DSPv5 Medical device id */ #define MLX90632_ID_CONSUMER 0x0205 /* EEPROM DSPv5 Consumer device id */ +#define MLX90632_ID_EXTENDED 0x0505 /* EEPROM DSPv5 Extended range device id */ +#define MLX90632_ID_MASK GENMASK(14, 0) /* DSP version and device ID in EE_VERSION */ #define MLX90632_DSP_VERSION 5 /* DSP version */ #define MLX90632_DSP_MASK GENMASK(7, 0) /* DSP version in EE_VERSION */ #define MLX90632_RESET_CMD 0x0006 /* Reset sensor (address or global) */ -#define MLX90632_REF_12 12LL /**< ResCtrlRef value of Ch 1 or Ch 2 */ -#define MLX90632_REF_3 12LL /**< ResCtrlRef value of Channel 3 */ -#define MLX90632_MAX_MEAS_NUM 31 /**< Maximum measurements in list */ -#define MLX90632_SLEEP_DELAY_MS 3000 /**< Autosleep delay */ +#define MLX90632_REF_12 12LL /* ResCtrlRef value of Ch 1 or Ch 2 */ +#define MLX90632_REF_3 12LL /* ResCtrlRef value of Channel 3 */ +#define MLX90632_MAX_MEAS_NUM 31 /* Maximum measurements in list */ +#define MLX90632_SLEEP_DELAY_MS 3000 /* Autosleep delay */ +#define MLX90632_EXTENDED_LIMIT 27000 /* Extended mode raw value limit */ +/** + * struct mlx90632_data - private data for the MLX90632 device + * @client: I2C client of the device + * @lock: Internal mutex for multiple reads for single measurement + * @regmap: Regmap of the device + * @emissivity: Object emissivity from 0 to 1000 where 1000 = 1. + * @mtyp: Measurement type physical sensor configuration for extended range + * calculations + * @object_ambient_temperature: Ambient temperature at object (might differ of + * the ambient temperature of sensor. + */ struct mlx90632_data { struct i2c_client *client; - struct mutex lock; /* Multiple reads for single measurement */ + struct mutex lock; struct regmap *regmap; u16 emissivity; + u8 mtyp; + u32 object_ambient_temperature; }; static const struct regmap_range mlx90632_volatile_reg_range[] = { regmap_reg_range(MLX90632_REG_I2C_ADDR, MLX90632_REG_CONTROL), + regmap_reg_range(MLX90632_REG_I2C_CMD, MLX90632_REG_I2C_CMD), regmap_reg_range(MLX90632_REG_STATUS, MLX90632_REG_STATUS), regmap_reg_range(MLX90632_RAM_1(0), MLX90632_RAM_3(MLX90632_MAX_MEAS_NUM)), @@ -113,6 +156,7 @@ static const struct regmap_range mlx90632_read_reg_range[] = { regmap_reg_range(MLX90632_EE_CTRL, MLX90632_EE_I2C_ADDR), regmap_reg_range(MLX90632_EE_Ha, MLX90632_EE_Hb), regmap_reg_range(MLX90632_REG_I2C_ADDR, MLX90632_REG_CONTROL), + regmap_reg_range(MLX90632_REG_I2C_CMD, MLX90632_REG_I2C_CMD), regmap_reg_range(MLX90632_REG_STATUS, MLX90632_REG_STATUS), regmap_reg_range(MLX90632_RAM_1(0), MLX90632_RAM_3(MLX90632_MAX_MEAS_NUM)), @@ -173,25 +217,19 @@ static s32 mlx90632_pwr_continuous(struct regmap *regmap) */ static int mlx90632_perform_measurement(struct mlx90632_data *data) { - int ret, tries = 100; unsigned int reg_status; + int ret; ret = regmap_update_bits(data->regmap, MLX90632_REG_STATUS, MLX90632_STAT_DATA_RDY, 0); if (ret < 0) return ret; - while (tries-- > 0) { - ret = regmap_read(data->regmap, MLX90632_REG_STATUS, - ®_status); - if (ret < 0) - return ret; - if (reg_status & MLX90632_STAT_DATA_RDY) - break; - usleep_range(10000, 11000); - } + ret = regmap_read_poll_timeout(data->regmap, MLX90632_REG_STATUS, reg_status, + !(reg_status & MLX90632_STAT_DATA_RDY), 10000, + 100 * 10000); - if (tries < 0) { + if (ret < 0) { dev_err(&data->client->dev, "data not ready"); return -ETIMEDOUT; } @@ -199,6 +237,26 @@ static int mlx90632_perform_measurement(struct mlx90632_data *data) return (reg_status & MLX90632_STAT_CYCLE_POS) >> 2; } +static int mlx90632_set_meas_type(struct regmap *regmap, u8 type) +{ + int ret; + + if ((type != MLX90632_MTYP_MEDICAL) && (type != MLX90632_MTYP_EXTENDED)) + return -EINVAL; + + ret = regmap_write(regmap, MLX90632_REG_I2C_CMD, MLX90632_RESET_CMD); + if (ret < 0) + return ret; + + ret = regmap_write_bits(regmap, MLX90632_REG_CONTROL, + (MLX90632_CFG_MTYP_MASK | MLX90632_CFG_PWR_MASK), + (MLX90632_MTYP_STATUS(type) | MLX90632_PWR_STATUS_HALT)); + if (ret < 0) + return ret; + + return mlx90632_pwr_continuous(regmap); +} + static int mlx90632_channel_new_select(int perform_ret, uint8_t *channel_new, uint8_t *channel_old) { @@ -300,6 +358,97 @@ read_unlock: return ret; } +static int mlx90632_read_ambient_raw_extended(struct regmap *regmap, + s16 *ambient_new_raw, s16 *ambient_old_raw) +{ + unsigned int read_tmp; + int ret; + + ret = regmap_read(regmap, MLX90632_RAM_DSP5_EXTENDED_AMBIENT_1, &read_tmp); + if (ret < 0) + return ret; + *ambient_new_raw = (s16)read_tmp; + + ret = regmap_read(regmap, MLX90632_RAM_DSP5_EXTENDED_AMBIENT_2, &read_tmp); + if (ret < 0) + return ret; + *ambient_old_raw = (s16)read_tmp; + + return 0; +} + +static int mlx90632_read_object_raw_extended(struct regmap *regmap, s16 *object_new_raw) +{ + unsigned int read_tmp; + s32 read; + int ret; + + ret = regmap_read(regmap, MLX90632_RAM_DSP5_EXTENDED_OBJECT_1, &read_tmp); + if (ret < 0) + return ret; + read = (s16)read_tmp; + + ret = regmap_read(regmap, MLX90632_RAM_DSP5_EXTENDED_OBJECT_2, &read_tmp); + if (ret < 0) + return ret; + read = read - (s16)read_tmp; + + ret = regmap_read(regmap, MLX90632_RAM_DSP5_EXTENDED_OBJECT_3, &read_tmp); + if (ret < 0) + return ret; + read = read - (s16)read_tmp; + + ret = regmap_read(regmap, MLX90632_RAM_DSP5_EXTENDED_OBJECT_4, &read_tmp); + if (ret < 0) + return ret; + read = (read + (s16)read_tmp) / 2; + + ret = regmap_read(regmap, MLX90632_RAM_DSP5_EXTENDED_OBJECT_5, &read_tmp); + if (ret < 0) + return ret; + read = read + (s16)read_tmp; + + ret = regmap_read(regmap, MLX90632_RAM_DSP5_EXTENDED_OBJECT_6, &read_tmp); + if (ret < 0) + return ret; + read = read + (s16)read_tmp; + + if (read > S16_MAX || read < S16_MIN) + return -ERANGE; + + *object_new_raw = read; + + return 0; +} + +static int mlx90632_read_all_channel_extended(struct mlx90632_data *data, s16 *object_new_raw, + s16 *ambient_new_raw, s16 *ambient_old_raw) +{ + s32 ret, meas; + + mutex_lock(&data->lock); + ret = mlx90632_set_meas_type(data->regmap, MLX90632_MTYP_EXTENDED); + if (ret < 0) + goto read_unlock; + + ret = read_poll_timeout(mlx90632_perform_measurement, meas, meas == 19, + 50000, 800000, false, data); + if (ret != 0) + goto read_unlock; + + ret = mlx90632_read_object_raw_extended(data->regmap, object_new_raw); + if (ret < 0) + goto read_unlock; + + ret = mlx90632_read_ambient_raw_extended(data->regmap, ambient_new_raw, ambient_old_raw); + +read_unlock: + (void) mlx90632_set_meas_type(data->regmap, MLX90632_MTYP_MEDICAL); + + mutex_unlock(&data->lock); + return ret; +} + static int mlx90632_read_ee_register(struct regmap *regmap, u16 reg_lsb, s32 *reg_value) { @@ -354,9 +503,23 @@ static s64 mlx90632_preprocess_temp_obj(s16 object_new_raw, s16 object_old_raw, return div64_s64((tmp << 19ULL), 1000LL); } +static s64 mlx90632_preprocess_temp_obj_extended(s16 object_new_raw, s16 ambient_new_raw, + s16 ambient_old_raw, s16 Ka) +{ + s64 VR_IR, kKa, tmp; + + kKa = ((s64)Ka * 1000LL) >> 10ULL; + VR_IR = (s64)ambient_old_raw * 1000000LL + + kKa * div64_s64((s64)ambient_new_raw * 1000LL, + MLX90632_REF_3); + tmp = div64_s64( + div64_s64((s64) object_new_raw * 1000000000000LL, MLX90632_REF_12), + VR_IR); + return div64_s64(tmp << 19ULL, 1000LL); +} + static s32 mlx90632_calc_temp_ambient(s16 ambient_new_raw, s16 ambient_old_raw, - s32 P_T, s32 P_R, s32 P_G, s32 P_O, - s16 Gb) + s32 P_T, s32 P_R, s32 P_G, s32 P_O, s16 Gb) { s64 Asub, Bsub, Ablock, Bblock, Cblock, AMB, sum; @@ -374,11 +537,11 @@ static s32 mlx90632_calc_temp_ambient(s16 ambient_new_raw, s16 ambient_old_raw, } static s32 mlx90632_calc_temp_object_iteration(s32 prev_object_temp, s64 object, - s64 TAdut, s32 Fa, s32 Fb, + s64 TAdut, s64 TAdut4, s32 Fa, s32 Fb, s32 Ga, s16 Ha, s16 Hb, u16 emissivity) { - s64 calcedKsTO, calcedKsTA, ir_Alpha, TAdut4, Alpha_corr; + s64 calcedKsTO, calcedKsTA, ir_Alpha, Alpha_corr; s64 Ha_customer, Hb_customer; Ha_customer = ((s64)Ha * 1000000LL) >> 14ULL; @@ -393,36 +556,66 @@ static s32 mlx90632_calc_temp_object_iteration(s32 prev_object_temp, s64 object, Alpha_corr = emissivity * div64_s64(Alpha_corr, 100000LL); Alpha_corr = div64_s64(Alpha_corr, 1000LL); ir_Alpha = div64_s64((s64)object * 10000000LL, Alpha_corr); - TAdut4 = (div64_s64(TAdut, 10000LL) + 27315) * - (div64_s64(TAdut, 10000LL) + 27315) * - (div64_s64(TAdut, 10000LL) + 27315) * - (div64_s64(TAdut, 10000LL) + 27315); return (int_sqrt64(int_sqrt64(ir_Alpha * 1000000000000LL + TAdut4)) - 27315 - Hb_customer) * 10; } +static s64 mlx90632_calc_ta4(s64 TAdut, s64 scale) +{ + return (div64_s64(TAdut, scale) + 27315) * + (div64_s64(TAdut, scale) + 27315) * + (div64_s64(TAdut, scale) + 27315) * + (div64_s64(TAdut, scale) + 27315); +} + static s32 mlx90632_calc_temp_object(s64 object, s64 ambient, s32 Ea, s32 Eb, s32 Fa, s32 Fb, s32 Ga, s16 Ha, s16 Hb, u16 tmp_emi) { - s64 kTA, kTA0, TAdut; + s64 kTA, kTA0, TAdut, TAdut4; s64 temp = 25000; s8 i; kTA = (Ea * 1000LL) >> 16LL; kTA0 = (Eb * 1000LL) >> 8LL; TAdut = div64_s64(((ambient - kTA0) * 1000000LL), kTA) + 25 * 1000000LL; + TAdut4 = mlx90632_calc_ta4(TAdut, 10000LL); /* Iterations of calculation as described in datasheet */ for (i = 0; i < 5; ++i) { - temp = mlx90632_calc_temp_object_iteration(temp, object, TAdut, + temp = mlx90632_calc_temp_object_iteration(temp, object, TAdut, TAdut4, Fa, Fb, Ga, Ha, Hb, tmp_emi); } return temp; } +static s32 mlx90632_calc_temp_object_extended(s64 object, s64 ambient, s64 reflected, + s32 Ea, s32 Eb, s32 Fa, s32 Fb, s32 Ga, + s16 Ha, s16 Hb, u16 tmp_emi) +{ + s64 kTA, kTA0, TAdut, TAdut4, Tr4, TaTr4; + s64 temp = 25000; + s8 i; + + kTA = (Ea * 1000LL) >> 16LL; + kTA0 = (Eb * 1000LL) >> 8LL; + TAdut = div64_s64((ambient - kTA0) * 1000000LL, kTA) + 25 * 1000000LL; + Tr4 = mlx90632_calc_ta4(reflected, 10); + TAdut4 = mlx90632_calc_ta4(TAdut, 10000LL); + TaTr4 = Tr4 - div64_s64(Tr4 - TAdut4, tmp_emi) * 1000; + + /* Iterations of calculation as described in datasheet */ + for (i = 0; i < 5; ++i) { + temp = mlx90632_calc_temp_object_iteration(temp, object, TAdut, TaTr4, + Fa / 2, Fb, Ga, Ha, Hb, + tmp_emi); + } + + return temp; +} + static int mlx90632_calc_object_dsp105(struct mlx90632_data *data, int *val) { s32 ret; @@ -470,6 +663,26 @@ static int mlx90632_calc_object_dsp105(struct mlx90632_data *data, int *val) if (ret < 0) return ret; + if (object_new_raw > MLX90632_EXTENDED_LIMIT && + data->mtyp == MLX90632_MTYP_EXTENDED) { + ret = mlx90632_read_all_channel_extended(data, &object_new_raw, + &ambient_new_raw, &ambient_old_raw); + if (ret < 0) + return ret; + + /* Use extended mode calculations */ + ambient = mlx90632_preprocess_temp_amb(ambient_new_raw, + ambient_old_raw, Gb); + object = mlx90632_preprocess_temp_obj_extended(object_new_raw, + ambient_new_raw, + ambient_old_raw, Ka); + *val = mlx90632_calc_temp_object_extended(object, ambient, + data->object_ambient_temperature, + Ea, Eb, Fa, Fb, Ga, + Ha, Hb, data->emissivity); + return 0; + } + ambient = mlx90632_preprocess_temp_amb(ambient_new_raw, ambient_old_raw, Gb); object = mlx90632_preprocess_temp_obj(object_new_raw, @@ -548,7 +761,9 @@ static int mlx90632_read_raw(struct iio_dev *indio_dev, *val2 = data->emissivity * 1000; } return IIO_VAL_INT_PLUS_MICRO; - + case IIO_CHAN_INFO_CALIBAMBIENT: + *val = data->object_ambient_temperature; + return IIO_VAL_INT; default: return -EINVAL; } @@ -568,6 +783,9 @@ static int mlx90632_write_raw(struct iio_dev *indio_dev, return -EINVAL; data->emissivity = val * 1000 + val2 / 1000; return 0; + case IIO_CHAN_INFO_CALIBAMBIENT: + data->object_ambient_temperature = val; + return 0; default: return -EINVAL; } @@ -585,7 +803,7 @@ static const struct iio_chan_spec mlx90632_channels[] = { .modified = 1, .channel2 = IIO_MOD_TEMP_OBJECT, .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) | - BIT(IIO_CHAN_INFO_CALIBEMISSIVITY), + BIT(IIO_CHAN_INFO_CALIBEMISSIVITY) | BIT(IIO_CHAN_INFO_CALIBAMBIENT), }, }; @@ -643,6 +861,7 @@ static int mlx90632_probe(struct i2c_client *client, i2c_set_clientdata(client, indio_dev); mlx90632->client = client; mlx90632->regmap = regmap; + mlx90632->mtyp = MLX90632_MTYP_MEDICAL; mutex_init(&mlx90632->lock); indio_dev->name = id->name; @@ -662,15 +881,20 @@ static int mlx90632_probe(struct i2c_client *client, dev_err(&client->dev, "read of version failed: %d\n", ret); return ret; } + read = read & MLX90632_ID_MASK; if (read == MLX90632_ID_MEDICAL) { dev_dbg(&client->dev, "Detected Medical EEPROM calibration %x\n", read); } else if (read == MLX90632_ID_CONSUMER) { dev_dbg(&client->dev, "Detected Consumer EEPROM calibration %x\n", read); + } else if (read == MLX90632_ID_EXTENDED) { + dev_dbg(&client->dev, + "Detected Extended range EEPROM calibration %x\n", read); + mlx90632->mtyp = MLX90632_MTYP_EXTENDED; } else if ((read & MLX90632_DSP_MASK) == MLX90632_DSP_VERSION) { dev_dbg(&client->dev, - "Detected Unknown EEPROM calibration %x\n", read); + "Detected Unknown EEPROM calibration %x\n", read); } else { dev_err(&client->dev, "Wrong DSP version %x (expected %x)\n", @@ -679,6 +903,7 @@ static int mlx90632_probe(struct i2c_client *client, } mlx90632->emissivity = 1000; + mlx90632->object_ambient_temperature = 25000; /* 25 degrees milliCelsius */ pm_runtime_disable(&client->dev); ret = pm_runtime_set_active(&client->dev); diff --git a/drivers/iio/temperature/tmp007.c b/drivers/iio/temperature/tmp007.c index f90fe9e5617b..ad2b35c65548 100644 --- a/drivers/iio/temperature/tmp007.c +++ b/drivers/iio/temperature/tmp007.c @@ -20,7 +20,7 @@ #include <linux/module.h> #include <linux/pm.h> #include <linux/bitops.h> -#include <linux/of.h> +#include <linux/mod_devicetable.h> #include <linux/irq.h> #include <linux/interrupt.h> @@ -578,7 +578,7 @@ MODULE_DEVICE_TABLE(i2c, tmp007_id); static struct i2c_driver tmp007_driver = { .driver = { .name = "tmp007", - .of_match_table = of_match_ptr(tmp007_of_match), + .of_match_table = tmp007_of_match, .pm = &tmp007_pm_ops, }, .probe = tmp007_probe, diff --git a/drivers/iio/temperature/tsys01.c b/drivers/iio/temperature/tsys01.c index 2c631a1ca33b..bbfbad9a8767 100644 --- a/drivers/iio/temperature/tsys01.c +++ b/drivers/iio/temperature/tsys01.c @@ -13,6 +13,7 @@ #include <linux/device.h> #include <linux/mutex.h> #include <linux/module.h> +#include <linux/mod_devicetable.h> #include <linux/init.h> #include <linux/kernel.h> #include <linux/stat.h> @@ -222,7 +223,7 @@ static struct i2c_driver tsys01_driver = { .id_table = tsys01_id, .driver = { .name = "tsys01", - .of_match_table = of_match_ptr(tsys01_of_match), + .of_match_table = tsys01_of_match, }, }; diff --git a/drivers/most/Kconfig b/drivers/most/Kconfig index 60fc0820dad3..ebfe84e69715 100644 --- a/drivers/most/Kconfig +++ b/drivers/most/Kconfig @@ -23,4 +23,13 @@ config MOST_USB_HDM To compile this driver as a module, choose M here: the module will be called most_usb. + +config MOST_CDEV + tristate "Cdev" + + help + Say Y here if you want to commumicate via character devices. + + To compile this driver as a module, choose M here: the + module will be called most_cdev. endif diff --git a/drivers/most/Makefile b/drivers/most/Makefile index 6a3cb9056288..8b53ca46633f 100644 --- a/drivers/most/Makefile +++ b/drivers/most/Makefile @@ -4,3 +4,4 @@ most_core-y := core.o \ configfs.o obj-$(CONFIG_MOST_USB_HDM) += most_usb.o +obj-$(CONFIG_MOST_CDEV) += most_cdev.o diff --git a/drivers/staging/most/cdev/cdev.c b/drivers/most/most_cdev.c index 044880760b58..044880760b58 100644 --- a/drivers/staging/most/cdev/cdev.c +++ b/drivers/most/most_cdev.c diff --git a/drivers/net/wireless/microchip/wilc1000/spi.c b/drivers/net/wireless/microchip/wilc1000/spi.c index 3f19e3f38a39..a18dac0aa6b6 100644 --- a/drivers/net/wireless/microchip/wilc1000/spi.c +++ b/drivers/net/wireless/microchip/wilc1000/spi.c @@ -112,9 +112,10 @@ static int wilc_bus_probe(struct spi_device *spi) wilc->dev_irq_num = spi->irq; wilc->rtc_clk = devm_clk_get(&spi->dev, "rtc_clk"); - if (PTR_ERR_OR_ZERO(wilc->rtc_clk) == -EPROBE_DEFER) + if (PTR_ERR_OR_ZERO(wilc->rtc_clk) == -EPROBE_DEFER) { + kfree(spi_priv); return -EPROBE_DEFER; - else if (!IS_ERR(wilc->rtc_clk)) + } else if (!IS_ERR(wilc->rtc_clk)) clk_prepare_enable(wilc->rtc_clk); return 0; diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index e6c831c6cccc..2d0310448eba 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -116,4 +116,6 @@ source "drivers/staging/qlge/Kconfig" source "drivers/staging/wfx/Kconfig" +source "drivers/staging/hikey9xx/Kconfig" + endif # STAGING diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index a3b1fd0622f9..757a892ab5b9 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -48,3 +48,4 @@ obj-$(CONFIG_FIELDBUS_DEV) += fieldbus/ obj-$(CONFIG_KPC2000) += kpc2000/ obj-$(CONFIG_QLGE) += qlge/ obj-$(CONFIG_WFX) += wfx/ +obj-y += hikey9xx/ diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c index 3c9f09506ffa..e1fe03ceb7f1 100644 --- a/drivers/staging/android/ion/ion.c +++ b/drivers/staging/android/ion/ion.c @@ -205,8 +205,8 @@ static int ion_dma_buf_attach(struct dma_buf *dmabuf, return 0; } -static void ion_dma_buf_detatch(struct dma_buf *dmabuf, - struct dma_buf_attachment *attachment) +static void ion_dma_buf_detach(struct dma_buf *dmabuf, + struct dma_buf_attachment *attachment) { struct ion_dma_buf_attachment *a = attachment->priv; struct ion_buffer *buffer = dmabuf->priv; @@ -331,7 +331,7 @@ static const struct dma_buf_ops dma_buf_ops = { .mmap = ion_mmap, .release = ion_dma_buf_release, .attach = ion_dma_buf_attach, - .detach = ion_dma_buf_detatch, + .detach = ion_dma_buf_detach, .begin_cpu_access = ion_dma_buf_begin_cpu_access, .end_cpu_access = ion_dma_buf_end_cpu_access, }; diff --git a/drivers/staging/comedi/comedi.h b/drivers/staging/comedi/comedi.h index 09a940066c0e..b5d00a006dbb 100644 --- a/drivers/staging/comedi/comedi.h +++ b/drivers/staging/comedi/comedi.h @@ -680,7 +680,7 @@ struct comedi_rangeinfo { * value of 1 volt. * * The only defined flag value is %RF_EXTERNAL (%0x100), indicating that the - * the range needs to be multiplied by an external reference. + * range needs to be multiplied by an external reference. */ struct comedi_krange { int min; @@ -970,7 +970,7 @@ enum i8254_mode { * major reasons exist why this caused major confusion for users: * 1) The register values are _NOT_ in user documentation, but rather in * arcane locations, such as a few register programming manuals that are - * increasingly hard to find and the NI MHDDK (comments in in example code). + * increasingly hard to find and the NI MHDDK (comments in example code). * There is no one place to find the various valid values of the registers. * 2) The register values are _NOT_ completely consistent. There is no way to * gain any sense of intuition of which values, or even enums one should use diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index 0dff1ac057cd..0e1b95ef9a4d 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -627,7 +627,7 @@ extern const struct comedi_lrange range_unknown; * @range: Array of &struct comedi_krange, one for each range. * * Each element of @range[] describes the minimum and maximum physical range - * range and the type of units. Typically, the type of unit is %UNIT_volt + * and the type of units. Typically, the type of unit is %UNIT_volt * (i.e. volts) and the minimum and maximum are in millionths of a volt. * There may also be a flag that indicates the minimum and maximum are merely * scale factors for an unknown, external reference. diff --git a/drivers/staging/comedi/drivers/addi_apci_1564.c b/drivers/staging/comedi/drivers/addi_apci_1564.c index fadefcb5c237..06fc7ed96200 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1564.c +++ b/drivers/staging/comedi/drivers/addi_apci_1564.c @@ -544,7 +544,7 @@ static int apci1564_timer_insn_write(struct comedi_device *dev, { struct apci1564_private *devpriv = dev->private; - /* just write the last last to the reload register */ + /* just write the last to the reload register */ if (insn->n) { unsigned int val = data[insn->n - 1]; @@ -628,7 +628,7 @@ static int apci1564_counter_insn_write(struct comedi_device *dev, unsigned int chan = CR_CHAN(insn->chanspec); unsigned long iobase = devpriv->counters + APCI1564_COUNTER(chan); - /* just write the last last to the reload register */ + /* just write the last to the reload register */ if (insn->n) { unsigned int val = data[insn->n - 1]; diff --git a/drivers/staging/comedi/drivers/comedi_8255.c b/drivers/staging/comedi/drivers/comedi_8255.c index 3298725b9ba5..b7ca465933ee 100644 --- a/drivers/staging/comedi/drivers/comedi_8255.c +++ b/drivers/staging/comedi/drivers/comedi_8255.c @@ -248,7 +248,7 @@ EXPORT_SYMBOL_GPL(subdev_8255_mm_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 to + * 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. */ diff --git a/drivers/staging/comedi/drivers/ni_tiocmd.c b/drivers/staging/comedi/drivers/ni_tiocmd.c index 2a9f7e9821a7..ab6d9e8269f3 100644 --- a/drivers/staging/comedi/drivers/ni_tiocmd.c +++ b/drivers/staging/comedi/drivers/ni_tiocmd.c @@ -286,7 +286,7 @@ int ni_tio_cmdtest(struct comedi_device *dev, * This should be done, but we don't yet know the actual * register values. These should be tested and then documented * in the ni_route_values/ni_*.csv files, with indication of - * who/when/which/how these these were tested. + * who/when/which/how these were tested. * When at least a e/m/660x series have been tested, this code * should be uncommented: * diff --git a/drivers/staging/comedi/drivers/pcl726.c b/drivers/staging/comedi/drivers/pcl726.c index 58b3d07ae907..64eb649c9813 100644 --- a/drivers/staging/comedi/drivers/pcl726.c +++ b/drivers/staging/comedi/drivers/pcl726.c @@ -389,7 +389,7 @@ static int pcl726_attach(struct comedi_device *dev, } if (dev->irq) { - /* Digial Input subdevice - Interrupt support */ + /* Digital Input subdevice - Interrupt support */ s = &dev->subdevices[subdev++]; dev->read_subdev = s; s->type = COMEDI_SUBD_DI; diff --git a/drivers/staging/comedi/drivers/pcmuio.c b/drivers/staging/comedi/drivers/pcmuio.c index 7e1fc6ffb48c..b299d648a0eb 100644 --- a/drivers/staging/comedi/drivers/pcmuio.c +++ b/drivers/staging/comedi/drivers/pcmuio.c @@ -48,7 +48,7 @@ * * In the 48-channel version: * - * On subdev 0, the first 24 channels channels are edge-detect channels. + * On subdev 0, the first 24 channels are edge-detect channels. * * In the 96-channel board you have the following channels that can do edge * detection: diff --git a/drivers/staging/comedi/drivers/quatech_daqp_cs.c b/drivers/staging/comedi/drivers/quatech_daqp_cs.c index 1b1efa4d31f6..fe4408ebf6b3 100644 --- a/drivers/staging/comedi/drivers/quatech_daqp_cs.c +++ b/drivers/staging/comedi/drivers/quatech_daqp_cs.c @@ -164,7 +164,7 @@ static int daqp_clear_events(struct comedi_device *dev, int loops) /* * Reset any pending interrupts (my card has a tendency to require - * require multiple reads on the status register to achieve this). + * multiple reads on the status register to achieve this). */ while (--loops) { status = inb(dev->iobase + DAQP_STATUS_REG); diff --git a/drivers/staging/comedi/drivers/vmk80xx.c b/drivers/staging/comedi/drivers/vmk80xx.c index 65dc6c51037e..7956abcbae22 100644 --- a/drivers/staging/comedi/drivers/vmk80xx.c +++ b/drivers/staging/comedi/drivers/vmk80xx.c @@ -667,6 +667,9 @@ static int vmk80xx_find_usb_endpoints(struct comedi_device *dev) if (!devpriv->ep_rx || !devpriv->ep_tx) return -ENODEV; + if (!usb_endpoint_maxp(devpriv->ep_rx) || !usb_endpoint_maxp(devpriv->ep_tx)) + return -EINVAL; + return 0; } diff --git a/drivers/staging/emxx_udc/Kconfig b/drivers/staging/emxx_udc/Kconfig index ad1478c53e9e..e7a95b3b6a2f 100644 --- a/drivers/staging/emxx_udc/Kconfig +++ b/drivers/staging/emxx_udc/Kconfig @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 config USB_EMXX tristate "EMXX USB Function Device Controller" - depends on USB_GADGET && (ARCH_RENESAS || (ARM && COMPILE_TEST)) + depends on USB_GADGET && (ARCH_RENESAS || COMPILE_TEST) help The Emma Mobile series of SoCs from Renesas Electronics and former NEC Electronics include USB Function hardware. diff --git a/drivers/staging/emxx_udc/emxx_udc.c b/drivers/staging/emxx_udc/emxx_udc.c index 03929b9d3a8b..a30b4f5b199b 100644 --- a/drivers/staging/emxx_udc/emxx_udc.c +++ b/drivers/staging/emxx_udc/emxx_udc.c @@ -793,7 +793,7 @@ static int _nbu2ss_out_dma(struct nbu2ss_udc *udc, struct nbu2ss_req *req, u32 dmacnt; u32 burst = 1; u32 data; - int result = -EINVAL; + int result; struct fc_regs __iomem *preg = udc->p_regs; if (req->dma_flag) @@ -1288,8 +1288,6 @@ static void _nbu2ss_set_endpoint_stall(struct nbu2ss_udc *udc, _nbu2ss_bitset(&preg->EP_REGS[num].EP_CONTROL, data); } else { - /* Clear STALL */ - ep->stalled = false; if (ep_adrs & USB_DIR_IN) { _nbu2ss_bitclr(&preg->EP_REGS[num].EP_CONTROL , EPN_ISTL); @@ -1304,6 +1302,7 @@ static void _nbu2ss_set_endpoint_stall(struct nbu2ss_udc *udc, , data); } + /* Clear STALL */ ep->stalled = false; if (ep->halted) { ep->halted = false; @@ -2164,8 +2163,8 @@ static int _nbu2ss_enable_controller(struct nbu2ss_udc *udc) _nbu2ss_writel(&udc->p_regs->AHBSCTR, WAIT_MODE); - _nbu2ss_writel(&udc->p_regs->AHBMCTR, - HBUSREQ_MODE | HTRANS_MODE | WBURST_TYPE); + _nbu2ss_writel(&udc->p_regs->AHBMCTR, + HBUSREQ_MODE | HTRANS_MODE | WBURST_TYPE); while (!(_nbu2ss_readl(&udc->p_regs->EPCTR) & PLL_LOCK)) { waitcnt++; @@ -2176,7 +2175,7 @@ static int _nbu2ss_enable_controller(struct nbu2ss_udc *udc) } } - _nbu2ss_bitset(&udc->p_regs->UTMI_CHARACTER_1, USB_SQUSET); + _nbu2ss_bitset(&udc->p_regs->UTMI_CHARACTER_1, USB_SQUSET); _nbu2ss_bitset(&udc->p_regs->USB_CONTROL, (INT_SEL | SOF_RCV)); @@ -2593,7 +2592,7 @@ static int nbu2ss_ep_queue(struct usb_ep *_ep, if (req->unaligned) { if (!ep->virt_buf) - ep->virt_buf = dma_alloc_coherent(NULL, PAGE_SIZE, + ep->virt_buf = dma_alloc_coherent(udc->dev, PAGE_SIZE, &ep->phys_buf, GFP_ATOMIC | GFP_DMA); if (ep->epnum > 0) { @@ -3073,8 +3072,8 @@ static int nbu2ss_drv_contest_init(struct platform_device *pdev, */ static int nbu2ss_drv_probe(struct platform_device *pdev) { - int status = -ENODEV; - struct nbu2ss_udc *udc; + int status; + struct nbu2ss_udc *udc; int irq; void __iomem *mmio_base; @@ -3148,7 +3147,7 @@ static int nbu2ss_drv_remove(struct platform_device *pdev) for (i = 0; i < NUM_ENDPOINTS; i++) { ep = &udc->ep[i]; if (ep->virt_buf) - dma_free_coherent(NULL, PAGE_SIZE, (void *)ep->virt_buf, + dma_free_coherent(udc->dev, PAGE_SIZE, (void *)ep->virt_buf, ep->phys_buf); } diff --git a/drivers/staging/emxx_udc/emxx_udc.h b/drivers/staging/emxx_udc/emxx_udc.h index 9c2671cb32f7..bca614d69aca 100644 --- a/drivers/staging/emxx_udc/emxx_udc.h +++ b/drivers/staging/emxx_udc/emxx_udc.h @@ -9,11 +9,6 @@ #define _LINUX_EMXX_H /*---------------------------------------------------------------------------*/ -/*----------------- Default undef */ -#if 0 -#define DEBUG -#define UDC_DEBUG_DUMP -#endif /*----------------- Default define */ #define USE_DMA 1 @@ -52,197 +47,163 @@ int vbus_irq; #define U2F_ENABLE 1 #define U2F_DISABLE 0 -/*------- BIT */ -#define BIT00 0x00000001 -#define BIT01 0x00000002 -#define BIT02 0x00000004 -#define BIT03 0x00000008 -#define BIT04 0x00000010 -#define BIT05 0x00000020 -#define BIT06 0x00000040 -#define BIT07 0x00000080 -#define BIT08 0x00000100 -#define BIT09 0x00000200 -#define BIT10 0x00000400 -#define BIT11 0x00000800 -#define BIT12 0x00001000 -#define BIT13 0x00002000 -#define BIT14 0x00004000 -#define BIT15 0x00008000 -#define BIT16 0x00010000 -#define BIT17 0x00020000 -#define BIT18 0x00040000 -#define BIT19 0x00080000 -#define BIT20 0x00100000 -#define BIT21 0x00200000 -#define BIT22 0x00400000 -#define BIT23 0x00800000 -#define BIT24 0x01000000 -#define BIT25 0x02000000 -#define BIT26 0x04000000 -#define BIT27 0x08000000 -#define BIT28 0x10000000 -#define BIT29 0x20000000 -#define BIT30 0x40000000 -#define BIT31 0x80000000 - -#define TEST_FORCE_ENABLE (BIT18 + BIT16) - -#define INT_SEL BIT10 -#define CONSTFS BIT09 -#define SOF_RCV BIT08 -#define RSUM_IN BIT07 -#define SUSPEND BIT06 -#define CONF BIT05 -#define DEFAULT BIT04 -#define CONNECTB BIT03 -#define PUE2 BIT02 +#define TEST_FORCE_ENABLE (BIT(18) | BIT(16)) + +#define INT_SEL BIT(10) +#define CONSTFS BIT(9) +#define SOF_RCV BIT(8) +#define RSUM_IN BIT(7) +#define SUSPEND BIT(6) +#define CONF BIT(5) +#define DEFAULT BIT(4) +#define CONNECTB BIT(3) +#define PUE2 BIT(2) #define MAX_TEST_MODE_NUM 0x05 #define TEST_MODE_SHIFT 16 /*------- (0x0004) USB Status Register */ -#define SPEED_MODE BIT06 -#define HIGH_SPEED BIT06 +#define SPEED_MODE BIT(6) +#define HIGH_SPEED BIT(6) -#define CONF BIT05 -#define DEFAULT BIT04 -#define USB_RST BIT03 -#define SPND_OUT BIT02 -#define RSUM_OUT BIT01 +#define CONF BIT(5) +#define DEFAULT BIT(4) +#define USB_RST BIT(3) +#define SPND_OUT BIT(2) +#define RSUM_OUT BIT(1) /*------- (0x0008) USB Address Register */ #define USB_ADDR 0x007F0000 -#define SOF_STATUS BIT15 -#define UFRAME (BIT14 + BIT13 + BIT12) +#define SOF_STATUS BIT(15) +#define UFRAME (BIT(14) | BIT(13) | BIT(12)) #define FRAME 0x000007FF #define USB_ADRS_SHIFT 16 /*------- (0x000C) UTMI Characteristic 1 Register */ -#define SQUSET (BIT07 + BIT06 + BIT05 + BIT04) +#define SQUSET (BIT(7) | BIT(6) | BIT(5) | BIT(4)) -#define USB_SQUSET (BIT06 + BIT05 + BIT04) +#define USB_SQUSET (BIT(6) | BIT(5) | BIT(4)) /*------- (0x0010) TEST Control Register */ -#define FORCEHS BIT02 -#define CS_TESTMODEEN BIT01 -#define LOOPBACK BIT00 +#define FORCEHS BIT(2) +#define CS_TESTMODEEN BIT(1) +#define LOOPBACK BIT(0) /*------- (0x0018) Setup Data 0 Register */ /*------- (0x001C) Setup Data 1 Register */ /*------- (0x0020) USB Interrupt Status Register */ #define EPN_INT 0x00FFFF00 -#define EP15_INT BIT23 -#define EP14_INT BIT22 -#define EP13_INT BIT21 -#define EP12_INT BIT20 -#define EP11_INT BIT19 -#define EP10_INT BIT18 -#define EP9_INT BIT17 -#define EP8_INT BIT16 -#define EP7_INT BIT15 -#define EP6_INT BIT14 -#define EP5_INT BIT13 -#define EP4_INT BIT12 -#define EP3_INT BIT11 -#define EP2_INT BIT10 -#define EP1_INT BIT09 -#define EP0_INT BIT08 -#define SPEED_MODE_INT BIT06 -#define SOF_ERROR_INT BIT05 -#define SOF_INT BIT04 -#define USB_RST_INT BIT03 -#define SPND_INT BIT02 -#define RSUM_INT BIT01 +#define EP15_INT BIT(23) +#define EP14_INT BIT(22) +#define EP13_INT BIT(21) +#define EP12_INT BIT(20) +#define EP11_INT BIT(19) +#define EP10_INT BIT(18) +#define EP9_INT BIT(17) +#define EP8_INT BIT(16) +#define EP7_INT BIT(15) +#define EP6_INT BIT(14) +#define EP5_INT BIT(13) +#define EP4_INT BIT(12) +#define EP3_INT BIT(11) +#define EP2_INT BIT(10) +#define EP1_INT BIT(9) +#define EP0_INT BIT(8) +#define SPEED_MODE_INT BIT(6) +#define SOF_ERROR_INT BIT(5) +#define SOF_INT BIT(4) +#define USB_RST_INT BIT(3) +#define SPND_INT BIT(2) +#define RSUM_INT BIT(1) #define USB_INT_STA_RW 0x7E /*------- (0x0024) USB Interrupt Enable Register */ #define EP15_0_EN 0x00FFFF00 -#define EP15_EN BIT23 -#define EP14_EN BIT22 -#define EP13_EN BIT21 -#define EP12_EN BIT20 -#define EP11_EN BIT19 -#define EP10_EN BIT18 -#define EP9_EN BIT17 -#define EP8_EN BIT16 -#define EP7_EN BIT15 -#define EP6_EN BIT14 -#define EP5_EN BIT13 -#define EP4_EN BIT12 -#define EP3_EN BIT11 -#define EP2_EN BIT10 -#define EP1_EN BIT09 -#define EP0_EN BIT08 -#define SPEED_MODE_EN BIT06 -#define SOF_ERROR_EN BIT05 -#define SOF_EN BIT04 -#define USB_RST_EN BIT03 -#define SPND_EN BIT02 -#define RSUM_EN BIT01 +#define EP15_EN BIT(23) +#define EP14_EN BIT(22) +#define EP13_EN BIT(21) +#define EP12_EN BIT(20) +#define EP11_EN BIT(19) +#define EP10_EN BIT(18) +#define EP9_EN BIT(17) +#define EP8_EN BIT(16) +#define EP7_EN BIT(15) +#define EP6_EN BIT(14) +#define EP5_EN BIT(13) +#define EP4_EN BIT(12) +#define EP3_EN BIT(11) +#define EP2_EN BIT(10) +#define EP1_EN BIT(9) +#define EP0_EN BIT(8) +#define SPEED_MODE_EN BIT(6) +#define SOF_ERROR_EN BIT(5) +#define SOF_EN BIT(4) +#define USB_RST_EN BIT(3) +#define SPND_EN BIT(2) +#define RSUM_EN BIT(1) #define USB_INT_EN_BIT \ (EP0_EN | SPEED_MODE_EN | USB_RST_EN | SPND_EN | RSUM_EN) /*------- (0x0028) EP0 Control Register */ -#define EP0_STGSEL BIT18 -#define EP0_OVERSEL BIT17 -#define EP0_AUTO BIT16 -#define EP0_PIDCLR BIT09 -#define EP0_BCLR BIT08 -#define EP0_DEND BIT07 -#define EP0_DW (BIT06 + BIT05) +#define EP0_STGSEL BIT(18) +#define EP0_OVERSEL BIT(17) +#define EP0_AUTO BIT(16) +#define EP0_PIDCLR BIT(9) +#define EP0_BCLR BIT(8) +#define EP0_DEND BIT(7) +#define EP0_DW (BIT(6) | BIT(5)) #define EP0_DW4 0 -#define EP0_DW3 (BIT06 + BIT05) -#define EP0_DW2 BIT06 -#define EP0_DW1 BIT05 +#define EP0_DW3 (BIT(6) | BIT(5)) +#define EP0_DW2 BIT(6) +#define EP0_DW1 BIT(5) -#define EP0_INAK_EN BIT04 -#define EP0_PERR_NAK_CLR BIT03 -#define EP0_STL BIT02 -#define EP0_INAK BIT01 -#define EP0_ONAK BIT00 +#define EP0_INAK_EN BIT(4) +#define EP0_PERR_NAK_CLR BIT(3) +#define EP0_STL BIT(2) +#define EP0_INAK BIT(1) +#define EP0_ONAK BIT(0) /*------- (0x002C) EP0 Status Register */ -#define EP0_PID BIT18 -#define EP0_PERR_NAK BIT17 -#define EP0_PERR_NAK_INT BIT16 -#define EP0_OUT_NAK_INT BIT15 -#define EP0_OUT_NULL BIT14 -#define EP0_OUT_FULL BIT13 -#define EP0_OUT_EMPTY BIT12 -#define EP0_IN_NAK_INT BIT11 -#define EP0_IN_DATA BIT10 -#define EP0_IN_FULL BIT09 -#define EP0_IN_EMPTY BIT08 -#define EP0_OUT_NULL_INT BIT07 -#define EP0_OUT_OR_INT BIT06 -#define EP0_OUT_INT BIT05 -#define EP0_IN_INT BIT04 -#define EP0_STALL_INT BIT03 -#define STG_END_INT BIT02 -#define STG_START_INT BIT01 -#define SETUP_INT BIT00 - -#define EP0_STATUS_RW_BIT (BIT16 | BIT15 | BIT11 | 0xFF) +#define EP0_PID BIT(18) +#define EP0_PERR_NAK BIT(17) +#define EP0_PERR_NAK_INT BIT(16) +#define EP0_OUT_NAK_INT BIT(15) +#define EP0_OUT_NULL BIT(14) +#define EP0_OUT_FULL BIT(13) +#define EP0_OUT_EMPTY BIT(12) +#define EP0_IN_NAK_INT BIT(11) +#define EP0_IN_DATA BIT(10) +#define EP0_IN_FULL BIT(9) +#define EP0_IN_EMPTY BIT(8) +#define EP0_OUT_NULL_INT BIT(7) +#define EP0_OUT_OR_INT BIT(6) +#define EP0_OUT_INT BIT(5) +#define EP0_IN_INT BIT(4) +#define EP0_STALL_INT BIT(3) +#define STG_END_INT BIT(2) +#define STG_START_INT BIT(1) +#define SETUP_INT BIT(0) + +#define EP0_STATUS_RW_BIT (BIT(16) | BIT(15) | BIT(11) | 0xFF) /*------- (0x0030) EP0 Interrupt Enable Register */ -#define EP0_PERR_NAK_EN BIT16 -#define EP0_OUT_NAK_EN BIT15 +#define EP0_PERR_NAK_EN BIT(16) +#define EP0_OUT_NAK_EN BIT(15) -#define EP0_IN_NAK_EN BIT11 +#define EP0_IN_NAK_EN BIT(11) -#define EP0_OUT_NULL_EN BIT07 -#define EP0_OUT_OR_EN BIT06 -#define EP0_OUT_EN BIT05 -#define EP0_IN_EN BIT04 -#define EP0_STALL_EN BIT03 -#define STG_END_EN BIT02 -#define STG_START_EN BIT01 -#define SETUP_EN BIT00 +#define EP0_OUT_NULL_EN BIT(7) +#define EP0_OUT_OR_EN BIT(6) +#define EP0_OUT_EN BIT(5) +#define EP0_IN_EN BIT(4) +#define EP0_STALL_EN BIT(3) +#define STG_END_EN BIT(2) +#define STG_START_EN BIT(1) +#define SETUP_EN BIT(0) #define EP0_INT_EN_BIT \ (EP0_OUT_OR_EN | EP0_OUT_EN | EP0_IN_EN | STG_END_EN | SETUP_EN) @@ -254,90 +215,90 @@ int vbus_irq; /*------- (0x003C) EP0 Write Register */ /*------- (0x0040:) EPN Control Register */ -#define EPN_EN BIT31 -#define EPN_BUF_TYPE BIT30 -#define EPN_BUF_SINGLE BIT30 +#define EPN_EN BIT(31) +#define EPN_BUF_TYPE BIT(30) +#define EPN_BUF_SINGLE BIT(30) -#define EPN_DIR0 BIT26 -#define EPN_MODE (BIT25 + BIT24) +#define EPN_DIR0 BIT(26) +#define EPN_MODE (BIT(25) | BIT(24)) #define EPN_BULK 0 -#define EPN_INTERRUPT BIT24 -#define EPN_ISO BIT25 - -#define EPN_OVERSEL BIT17 -#define EPN_AUTO BIT16 - -#define EPN_IPIDCLR BIT11 -#define EPN_OPIDCLR BIT10 -#define EPN_BCLR BIT09 -#define EPN_CBCLR BIT08 -#define EPN_DEND BIT07 -#define EPN_DW (BIT06 + BIT05) +#define EPN_INTERRUPT BIT(24) +#define EPN_ISO BIT(25) + +#define EPN_OVERSEL BIT(17) +#define EPN_AUTO BIT(16) + +#define EPN_IPIDCLR BIT(11) +#define EPN_OPIDCLR BIT(10) +#define EPN_BCLR BIT(9) +#define EPN_CBCLR BIT(8) +#define EPN_DEND BIT(7) +#define EPN_DW (BIT(6) | BIT(5)) #define EPN_DW4 0 -#define EPN_DW3 (BIT06 + BIT05) -#define EPN_DW2 BIT06 -#define EPN_DW1 BIT05 +#define EPN_DW3 (BIT(6) | BIT(5)) +#define EPN_DW2 BIT(6) +#define EPN_DW1 BIT(5) -#define EPN_OSTL_EN BIT04 -#define EPN_ISTL BIT03 -#define EPN_OSTL BIT02 +#define EPN_OSTL_EN BIT(4) +#define EPN_ISTL BIT(3) +#define EPN_OSTL BIT(2) -#define EPN_ONAK BIT00 +#define EPN_ONAK BIT(0) /*------- (0x0044:) EPN Status Register */ -#define EPN_ISO_PIDERR BIT29 /* R */ -#define EPN_OPID BIT28 /* R */ -#define EPN_OUT_NOTKN BIT27 /* R */ -#define EPN_ISO_OR BIT26 /* R */ - -#define EPN_ISO_CRC BIT24 /* R */ -#define EPN_OUT_END_INT BIT23 /* RW */ -#define EPN_OUT_OR_INT BIT22 /* RW */ -#define EPN_OUT_NAK_ERR_INT BIT21 /* RW */ -#define EPN_OUT_STALL_INT BIT20 /* RW */ -#define EPN_OUT_INT BIT19 /* RW */ -#define EPN_OUT_NULL_INT BIT18 /* RW */ -#define EPN_OUT_FULL BIT17 /* R */ -#define EPN_OUT_EMPTY BIT16 /* R */ - -#define EPN_IPID BIT10 /* R */ -#define EPN_IN_NOTKN BIT09 /* R */ -#define EPN_ISO_UR BIT08 /* R */ -#define EPN_IN_END_INT BIT07 /* RW */ - -#define EPN_IN_NAK_ERR_INT BIT05 /* RW */ -#define EPN_IN_STALL_INT BIT04 /* RW */ -#define EPN_IN_INT BIT03 /* RW */ -#define EPN_IN_DATA BIT02 /* R */ -#define EPN_IN_FULL BIT01 /* R */ -#define EPN_IN_EMPTY BIT00 /* R */ +#define EPN_ISO_PIDERR BIT(29) /* R */ +#define EPN_OPID BIT(28) /* R */ +#define EPN_OUT_NOTKN BIT(27) /* R */ +#define EPN_ISO_OR BIT(26) /* R */ + +#define EPN_ISO_CRC BIT(24) /* R */ +#define EPN_OUT_END_INT BIT(23) /* RW */ +#define EPN_OUT_OR_INT BIT(22) /* RW */ +#define EPN_OUT_NAK_ERR_INT BIT(21) /* RW */ +#define EPN_OUT_STALL_INT BIT(20) /* RW */ +#define EPN_OUT_INT BIT(19) /* RW */ +#define EPN_OUT_NULL_INT BIT(18) /* RW */ +#define EPN_OUT_FULL BIT(17) /* R */ +#define EPN_OUT_EMPTY BIT(16) /* R */ + +#define EPN_IPID BIT(10) /* R */ +#define EPN_IN_NOTKN BIT(9) /* R */ +#define EPN_ISO_UR BIT(8) /* R */ +#define EPN_IN_END_INT BIT(7) /* RW */ + +#define EPN_IN_NAK_ERR_INT BIT(5) /* RW */ +#define EPN_IN_STALL_INT BIT(4) /* RW */ +#define EPN_IN_INT BIT(3) /* RW */ +#define EPN_IN_DATA BIT(2) /* R */ +#define EPN_IN_FULL BIT(1) /* R */ +#define EPN_IN_EMPTY BIT(0) /* R */ #define EPN_INT_EN \ (EPN_OUT_END_INT | EPN_OUT_INT | EPN_IN_END_INT | EPN_IN_INT) /*------- (0x0048:) EPN Interrupt Enable Register */ -#define EPN_OUT_END_EN BIT23 /* RW */ -#define EPN_OUT_OR_EN BIT22 /* RW */ -#define EPN_OUT_NAK_ERR_EN BIT21 /* RW */ -#define EPN_OUT_STALL_EN BIT20 /* RW */ -#define EPN_OUT_EN BIT19 /* RW */ -#define EPN_OUT_NULL_EN BIT18 /* RW */ +#define EPN_OUT_END_EN BIT(23) /* RW */ +#define EPN_OUT_OR_EN BIT(22) /* RW */ +#define EPN_OUT_NAK_ERR_EN BIT(21) /* RW */ +#define EPN_OUT_STALL_EN BIT(20) /* RW */ +#define EPN_OUT_EN BIT(19) /* RW */ +#define EPN_OUT_NULL_EN BIT(18) /* RW */ -#define EPN_IN_END_EN BIT07 /* RW */ +#define EPN_IN_END_EN BIT(7) /* RW */ -#define EPN_IN_NAK_ERR_EN BIT05 /* RW */ -#define EPN_IN_STALL_EN BIT04 /* RW */ -#define EPN_IN_EN BIT03 /* RW */ +#define EPN_IN_NAK_ERR_EN BIT(5) /* RW */ +#define EPN_IN_STALL_EN BIT(4) /* RW */ +#define EPN_IN_EN BIT(3) /* RW */ /*------- (0x004C:) EPN Interrupt Enable Register */ -#define EPN_STOP_MODE BIT11 -#define EPN_DEND_SET BIT10 -#define EPN_BURST_SET BIT09 -#define EPN_STOP_SET BIT08 +#define EPN_STOP_MODE BIT(11) +#define EPN_DEND_SET BIT(10) +#define EPN_BURST_SET BIT(9) +#define EPN_STOP_SET BIT(8) -#define EPN_DMA_EN BIT04 +#define EPN_DMA_EN BIT(4) -#define EPN_DMAMODE0 BIT00 +#define EPN_DMAMODE0 BIT(0) /*------- (0x0050:) EPN MaxPacket & BaseAddress Register */ #define EPN_BASEAD 0x1FFF0000 @@ -351,62 +312,62 @@ int vbus_irq; /*------- (0x005C:) EPN Write Register */ /*------- (0x1000) AHBSCTR Register */ -#define WAIT_MODE BIT00 +#define WAIT_MODE BIT(0) /*------- (0x1004) AHBMCTR Register */ -#define ARBITER_CTR BIT31 /* RW */ -#define MCYCLE_RST BIT12 /* RW */ +#define ARBITER_CTR BIT(31) /* RW */ +#define MCYCLE_RST BIT(12) /* RW */ -#define ENDIAN_CTR (BIT09 + BIT08) /* RW */ -#define ENDIAN_BYTE_SWAP BIT09 +#define ENDIAN_CTR (BIT(9) | BIT(8)) /* RW */ +#define ENDIAN_BYTE_SWAP BIT(9) #define ENDIAN_HALF_WORD_SWAP ENDIAN_CTR -#define HBUSREQ_MODE BIT05 /* RW */ -#define HTRANS_MODE BIT04 /* RW */ +#define HBUSREQ_MODE BIT(5) /* RW */ +#define HTRANS_MODE BIT(4) /* RW */ -#define WBURST_TYPE BIT02 /* RW */ -#define BURST_TYPE (BIT01 + BIT00) /* RW */ +#define WBURST_TYPE BIT(2) /* RW */ +#define BURST_TYPE (BIT(1) | BIT(0)) /* RW */ #define BURST_MAX_16 0 -#define BURST_MAX_8 BIT00 -#define BURST_MAX_4 BIT01 +#define BURST_MAX_8 BIT(0) +#define BURST_MAX_4 BIT(1) #define BURST_SINGLE BURST_TYPE /*------- (0x1008) AHBBINT Register */ #define DMA_ENDINT 0xFFFE0000 /* RW */ -#define AHB_VBUS_INT BIT13 /* RW */ +#define AHB_VBUS_INT BIT(13) /* RW */ -#define MBUS_ERRINT BIT06 /* RW */ +#define MBUS_ERRINT BIT(6) /* RW */ -#define SBUS_ERRINT0 BIT04 /* RW */ +#define SBUS_ERRINT0 BIT(4) /* RW */ #define ERR_MASTER 0x0000000F /* R */ /*------- (0x100C) AHBBINTEN Register */ #define DMA_ENDINTEN 0xFFFE0000 /* RW */ -#define VBUS_INTEN BIT13 /* RW */ +#define VBUS_INTEN BIT(13) /* RW */ -#define MBUS_ERRINTEN BIT06 /* RW */ +#define MBUS_ERRINTEN BIT(6) /* RW */ -#define SBUS_ERRINT0EN BIT04 /* RW */ +#define SBUS_ERRINT0EN BIT(4) /* RW */ /*------- (0x1010) EPCTR Register */ -#define DIRPD BIT12 /* RW */ +#define DIRPD BIT(12) /* RW */ -#define VBUS_LEVEL BIT08 /* R */ +#define VBUS_LEVEL BIT(8) /* R */ -#define PLL_RESUME BIT05 /* RW */ -#define PLL_LOCK BIT04 /* R */ +#define PLL_RESUME BIT(5) /* RW */ +#define PLL_LOCK BIT(4) /* R */ -#define EPC_RST BIT00 /* RW */ +#define EPC_RST BIT(0) /* RW */ /*------- (0x1014) USBF_EPTEST Register */ -#define LINESTATE (BIT09 + BIT08) /* R */ -#define DM_LEVEL BIT09 /* R */ -#define DP_LEVEL BIT08 /* R */ +#define LINESTATE (BIT(9) | BIT(8)) /* R */ +#define DM_LEVEL BIT(9) /* R */ +#define DP_LEVEL BIT(8) /* R */ -#define PHY_TST BIT01 /* RW */ -#define PHY_TSTCLK BIT00 /* RW */ +#define PHY_TST BIT(1) /* RW */ +#define PHY_TSTCLK BIT(0) /* RW */ /*------- (0x1020) USBSSVER Register */ #define AHBB_VER 0x00FF0000 /* R */ @@ -420,8 +381,8 @@ int vbus_irq; /*------- (0x1110:) EPNDCR1 Register */ #define DCR1_EPN_DMACNT 0x00FF0000 /* RW */ -#define DCR1_EPN_DIR0 BIT01 /* RW */ -#define DCR1_EPN_REQEN BIT00 /* RW */ +#define DCR1_EPN_DIR0 BIT(1) /* RW */ +#define DCR1_EPN_REQEN BIT(0) /* RW */ /*------- (0x1114:) EPNDCR2 Register */ #define DCR2_EPN_LMPKT 0x07FF0000 /* RW */ diff --git a/drivers/staging/fsl-dpaa2/ethsw/ethsw-ethtool.c b/drivers/staging/fsl-dpaa2/ethsw/ethsw-ethtool.c index 4f0bff86e43e..ace4a6d28562 100644 --- a/drivers/staging/fsl-dpaa2/ethsw/ethsw-ethtool.c +++ b/drivers/staging/fsl-dpaa2/ethsw/ethsw-ethtool.c @@ -12,7 +12,7 @@ static struct { enum dpsw_counter id; char name[ETH_GSTRING_LEN]; -} ethsw_ethtool_counters[] = { +} dpaa2_switch_ethtool_counters[] = { {DPSW_CNT_ING_FRAME, "rx frames"}, {DPSW_CNT_ING_BYTE, "rx bytes"}, {DPSW_CNT_ING_FLTR_FRAME, "rx filtered frames"}, @@ -27,10 +27,10 @@ static struct { }; -#define ETHSW_NUM_COUNTERS ARRAY_SIZE(ethsw_ethtool_counters) +#define DPAA2_SWITCH_NUM_COUNTERS ARRAY_SIZE(dpaa2_switch_ethtool_counters) -static void ethsw_get_drvinfo(struct net_device *netdev, - struct ethtool_drvinfo *drvinfo) +static void dpaa2_switch_get_drvinfo(struct net_device *netdev, + struct ethtool_drvinfo *drvinfo) { struct ethsw_port_priv *port_priv = netdev_priv(netdev); u16 version_major, version_minor; @@ -53,8 +53,8 @@ static void ethsw_get_drvinfo(struct net_device *netdev, } static int -ethsw_get_link_ksettings(struct net_device *netdev, - struct ethtool_link_ksettings *link_ksettings) +dpaa2_switch_get_link_ksettings(struct net_device *netdev, + struct ethtool_link_ksettings *link_ksettings) { struct ethsw_port_priv *port_priv = netdev_priv(netdev); struct dpsw_link_state state = {0}; @@ -84,8 +84,8 @@ out: } static int -ethsw_set_link_ksettings(struct net_device *netdev, - const struct ethtool_link_ksettings *link_ksettings) +dpaa2_switch_set_link_ksettings(struct net_device *netdev, + const struct ethtool_link_ksettings *link_ksettings) { struct ethsw_port_priv *port_priv = netdev_priv(netdev); struct ethsw_core *ethsw = port_priv->ethsw_data; @@ -132,55 +132,56 @@ ethsw_set_link_ksettings(struct net_device *netdev, return err; } -static int ethsw_ethtool_get_sset_count(struct net_device *dev, int sset) +static int dpaa2_switch_ethtool_get_sset_count(struct net_device *dev, int sset) { switch (sset) { case ETH_SS_STATS: - return ETHSW_NUM_COUNTERS; + return DPAA2_SWITCH_NUM_COUNTERS; default: return -EOPNOTSUPP; } } -static void ethsw_ethtool_get_strings(struct net_device *netdev, - u32 stringset, u8 *data) +static void dpaa2_switch_ethtool_get_strings(struct net_device *netdev, + u32 stringset, u8 *data) { int i; switch (stringset) { case ETH_SS_STATS: - for (i = 0; i < ETHSW_NUM_COUNTERS; i++) + for (i = 0; i < DPAA2_SWITCH_NUM_COUNTERS; i++) memcpy(data + i * ETH_GSTRING_LEN, - ethsw_ethtool_counters[i].name, ETH_GSTRING_LEN); + dpaa2_switch_ethtool_counters[i].name, + ETH_GSTRING_LEN); break; } } -static void ethsw_ethtool_get_stats(struct net_device *netdev, - struct ethtool_stats *stats, - u64 *data) +static void dpaa2_switch_ethtool_get_stats(struct net_device *netdev, + struct ethtool_stats *stats, + u64 *data) { struct ethsw_port_priv *port_priv = netdev_priv(netdev); int i, err; - for (i = 0; i < ETHSW_NUM_COUNTERS; i++) { + for (i = 0; i < DPAA2_SWITCH_NUM_COUNTERS; i++) { err = dpsw_if_get_counter(port_priv->ethsw_data->mc_io, 0, port_priv->ethsw_data->dpsw_handle, port_priv->idx, - ethsw_ethtool_counters[i].id, + dpaa2_switch_ethtool_counters[i].id, &data[i]); if (err) netdev_err(netdev, "dpsw_if_get_counter[%s] err %d\n", - ethsw_ethtool_counters[i].name, err); + dpaa2_switch_ethtool_counters[i].name, err); } } -const struct ethtool_ops ethsw_port_ethtool_ops = { - .get_drvinfo = ethsw_get_drvinfo, +const struct ethtool_ops dpaa2_switch_port_ethtool_ops = { + .get_drvinfo = dpaa2_switch_get_drvinfo, .get_link = ethtool_op_get_link, - .get_link_ksettings = ethsw_get_link_ksettings, - .set_link_ksettings = ethsw_set_link_ksettings, - .get_strings = ethsw_ethtool_get_strings, - .get_ethtool_stats = ethsw_ethtool_get_stats, - .get_sset_count = ethsw_ethtool_get_sset_count, + .get_link_ksettings = dpaa2_switch_get_link_ksettings, + .set_link_ksettings = dpaa2_switch_set_link_ksettings, + .get_strings = dpaa2_switch_ethtool_get_strings, + .get_ethtool_stats = dpaa2_switch_ethtool_get_stats, + .get_sset_count = dpaa2_switch_ethtool_get_sset_count, }; diff --git a/drivers/staging/fsl-dpaa2/ethsw/ethsw.c b/drivers/staging/fsl-dpaa2/ethsw/ethsw.c index 316fd9afd461..20c6326e5dee 100644 --- a/drivers/staging/fsl-dpaa2/ethsw/ethsw.c +++ b/drivers/staging/fsl-dpaa2/ethsw/ethsw.c @@ -24,7 +24,7 @@ #define DEFAULT_VLAN_ID 1 -static int ethsw_add_vlan(struct ethsw_core *ethsw, u16 vid) +static int dpaa2_switch_add_vlan(struct ethsw_core *ethsw, u16 vid) { int err; @@ -43,7 +43,7 @@ static int ethsw_add_vlan(struct ethsw_core *ethsw, u16 vid) return 0; } -static bool ethsw_port_is_up(struct ethsw_port_priv *port_priv) +static bool dpaa2_switch_port_is_up(struct ethsw_port_priv *port_priv) { struct net_device *netdev = port_priv->netdev; struct dpsw_link_state state; @@ -62,7 +62,7 @@ static bool ethsw_port_is_up(struct ethsw_port_priv *port_priv) return state.up ? true : false; } -static int ethsw_port_set_pvid(struct ethsw_port_priv *port_priv, u16 pvid) +static int dpaa2_switch_port_set_pvid(struct ethsw_port_priv *port_priv, u16 pvid) { struct ethsw_core *ethsw = port_priv->ethsw_data; struct net_device *netdev = port_priv->netdev; @@ -80,7 +80,7 @@ static int ethsw_port_set_pvid(struct ethsw_port_priv *port_priv, u16 pvid) tci_cfg.vlan_id = pvid; /* Interface needs to be down to change PVID */ - up = ethsw_port_is_up(port_priv); + up = dpaa2_switch_port_is_up(port_priv); if (up) { err = dpsw_if_disable(ethsw->mc_io, 0, ethsw->dpsw_handle, @@ -117,8 +117,8 @@ set_tci_error: return err; } -static int ethsw_port_add_vlan(struct ethsw_port_priv *port_priv, - u16 vid, u16 flags) +static int dpaa2_switch_port_add_vlan(struct ethsw_port_priv *port_priv, + u16 vid, u16 flags) { struct ethsw_core *ethsw = port_priv->ethsw_data; struct net_device *netdev = port_priv->netdev; @@ -153,7 +153,7 @@ static int ethsw_port_add_vlan(struct ethsw_port_priv *port_priv, } if (flags & BRIDGE_VLAN_INFO_PVID) { - err = ethsw_port_set_pvid(port_priv, vid); + err = dpaa2_switch_port_set_pvid(port_priv, vid); if (err) return err; } @@ -161,7 +161,7 @@ static int ethsw_port_add_vlan(struct ethsw_port_priv *port_priv, return 0; } -static int ethsw_set_learning(struct ethsw_core *ethsw, bool enable) +static int dpaa2_switch_set_learning(struct ethsw_core *ethsw, bool enable) { enum dpsw_fdb_learning_mode learn_mode; int err; @@ -182,7 +182,7 @@ static int ethsw_set_learning(struct ethsw_core *ethsw, bool enable) return 0; } -static int ethsw_port_set_flood(struct ethsw_port_priv *port_priv, bool enable) +static int dpaa2_switch_port_set_flood(struct ethsw_port_priv *port_priv, bool enable) { int err; @@ -199,7 +199,7 @@ static int ethsw_port_set_flood(struct ethsw_port_priv *port_priv, bool enable) return 0; } -static int ethsw_port_set_stp_state(struct ethsw_port_priv *port_priv, u8 state) +static int dpaa2_switch_port_set_stp_state(struct ethsw_port_priv *port_priv, u8 state) { struct dpsw_stp_cfg stp_cfg = { .state = state, @@ -229,7 +229,7 @@ static int ethsw_port_set_stp_state(struct ethsw_port_priv *port_priv, u8 state) return 0; } -static int ethsw_dellink_switch(struct ethsw_core *ethsw, u16 vid) +static int dpaa2_switch_dellink(struct ethsw_core *ethsw, u16 vid) { struct ethsw_port_priv *ppriv_local = NULL; int i, err; @@ -252,8 +252,8 @@ static int ethsw_dellink_switch(struct ethsw_core *ethsw, u16 vid) return 0; } -static int ethsw_port_fdb_add_uc(struct ethsw_port_priv *port_priv, - const unsigned char *addr) +static int dpaa2_switch_port_fdb_add_uc(struct ethsw_port_priv *port_priv, + const unsigned char *addr) { struct dpsw_fdb_unicast_cfg entry = {0}; int err; @@ -271,8 +271,8 @@ static int ethsw_port_fdb_add_uc(struct ethsw_port_priv *port_priv, return err; } -static int ethsw_port_fdb_del_uc(struct ethsw_port_priv *port_priv, - const unsigned char *addr) +static int dpaa2_switch_port_fdb_del_uc(struct ethsw_port_priv *port_priv, + const unsigned char *addr) { struct dpsw_fdb_unicast_cfg entry = {0}; int err; @@ -291,8 +291,8 @@ static int ethsw_port_fdb_del_uc(struct ethsw_port_priv *port_priv, return err; } -static int ethsw_port_fdb_add_mc(struct ethsw_port_priv *port_priv, - const unsigned char *addr) +static int dpaa2_switch_port_fdb_add_mc(struct ethsw_port_priv *port_priv, + const unsigned char *addr) { struct dpsw_fdb_multicast_cfg entry = {0}; int err; @@ -312,8 +312,8 @@ static int ethsw_port_fdb_add_mc(struct ethsw_port_priv *port_priv, return err; } -static int ethsw_port_fdb_del_mc(struct ethsw_port_priv *port_priv, - const unsigned char *addr) +static int dpaa2_switch_port_fdb_del_mc(struct ethsw_port_priv *port_priv, + const unsigned char *addr) { struct dpsw_fdb_multicast_cfg entry = {0}; int err; @@ -333,33 +333,33 @@ static int ethsw_port_fdb_del_mc(struct ethsw_port_priv *port_priv, return err; } -static int port_fdb_add(struct ndmsg *ndm, struct nlattr *tb[], - struct net_device *dev, const unsigned char *addr, - u16 vid, u16 flags, - struct netlink_ext_ack *extack) +static int dpaa2_switch_port_fdb_add(struct ndmsg *ndm, struct nlattr *tb[], + struct net_device *dev, const unsigned char *addr, + u16 vid, u16 flags, + struct netlink_ext_ack *extack) { if (is_unicast_ether_addr(addr)) - return ethsw_port_fdb_add_uc(netdev_priv(dev), - addr); + return dpaa2_switch_port_fdb_add_uc(netdev_priv(dev), + addr); else - return ethsw_port_fdb_add_mc(netdev_priv(dev), - addr); + return dpaa2_switch_port_fdb_add_mc(netdev_priv(dev), + addr); } -static int port_fdb_del(struct ndmsg *ndm, struct nlattr *tb[], - struct net_device *dev, - const unsigned char *addr, u16 vid) +static int dpaa2_switch_port_fdb_del(struct ndmsg *ndm, struct nlattr *tb[], + struct net_device *dev, + const unsigned char *addr, u16 vid) { if (is_unicast_ether_addr(addr)) - return ethsw_port_fdb_del_uc(netdev_priv(dev), - addr); + return dpaa2_switch_port_fdb_del_uc(netdev_priv(dev), + addr); else - return ethsw_port_fdb_del_mc(netdev_priv(dev), - addr); + return dpaa2_switch_port_fdb_del_mc(netdev_priv(dev), + addr); } -static void port_get_stats(struct net_device *netdev, - struct rtnl_link_stats64 *stats) +static void dpaa2_switch_port_get_stats(struct net_device *netdev, + struct rtnl_link_stats64 *stats) { struct ethsw_port_priv *port_priv = netdev_priv(netdev); u64 tmp; @@ -424,26 +424,26 @@ error: netdev_err(netdev, "dpsw_if_get_counter err %d\n", err); } -static bool port_has_offload_stats(const struct net_device *netdev, - int attr_id) +static bool dpaa2_switch_port_has_offload_stats(const struct net_device *netdev, + int attr_id) { return (attr_id == IFLA_OFFLOAD_XSTATS_CPU_HIT); } -static int port_get_offload_stats(int attr_id, - const struct net_device *netdev, - void *sp) +static int dpaa2_switch_port_get_offload_stats(int attr_id, + const struct net_device *netdev, + void *sp) { switch (attr_id) { case IFLA_OFFLOAD_XSTATS_CPU_HIT: - port_get_stats((struct net_device *)netdev, sp); + dpaa2_switch_port_get_stats((struct net_device *)netdev, sp); return 0; } return -EINVAL; } -static int port_change_mtu(struct net_device *netdev, int mtu) +static int dpaa2_switch_port_change_mtu(struct net_device *netdev, int mtu) { struct ethsw_port_priv *port_priv = netdev_priv(netdev); int err; @@ -463,7 +463,7 @@ static int port_change_mtu(struct net_device *netdev, int mtu) return 0; } -static int port_carrier_state_sync(struct net_device *netdev) +static int dpaa2_switch_port_carrier_state_sync(struct net_device *netdev) { struct ethsw_port_priv *port_priv = netdev_priv(netdev); struct dpsw_link_state state; @@ -496,7 +496,7 @@ static int port_carrier_state_sync(struct net_device *netdev) return 0; } -static int port_open(struct net_device *netdev) +static int dpaa2_switch_port_open(struct net_device *netdev) { struct ethsw_port_priv *port_priv = netdev_priv(netdev); int err; @@ -520,10 +520,10 @@ static int port_open(struct net_device *netdev) } /* sync carrier state */ - err = port_carrier_state_sync(netdev); + err = dpaa2_switch_port_carrier_state_sync(netdev); if (err) { netdev_err(netdev, - "port_carrier_state_sync err %d\n", err); + "dpaa2_switch_port_carrier_state_sync err %d\n", err); goto err_carrier_sync; } @@ -536,7 +536,7 @@ err_carrier_sync: return err; } -static int port_stop(struct net_device *netdev) +static int dpaa2_switch_port_stop(struct net_device *netdev) { struct ethsw_port_priv *port_priv = netdev_priv(netdev); int err; @@ -552,8 +552,8 @@ static int port_stop(struct net_device *netdev) return 0; } -static netdev_tx_t port_dropframe(struct sk_buff *skb, - struct net_device *netdev) +static netdev_tx_t dpaa2_switch_port_dropframe(struct sk_buff *skb, + struct net_device *netdev) { /* we don't support I/O for now, drop the frame */ dev_kfree_skb_any(skb); @@ -561,8 +561,8 @@ static netdev_tx_t port_dropframe(struct sk_buff *skb, return NETDEV_TX_OK; } -static int swdev_get_port_parent_id(struct net_device *dev, - struct netdev_phys_item_id *ppid) +static int dpaa2_switch_port_parent_id(struct net_device *dev, + struct netdev_phys_item_id *ppid) { struct ethsw_port_priv *port_priv = netdev_priv(dev); @@ -572,8 +572,8 @@ static int swdev_get_port_parent_id(struct net_device *dev, return 0; } -static int port_get_phys_name(struct net_device *netdev, char *name, - size_t len) +static int dpaa2_switch_port_get_phys_name(struct net_device *netdev, char *name, + size_t len) { struct ethsw_port_priv *port_priv = netdev_priv(netdev); int err; @@ -592,8 +592,8 @@ struct ethsw_dump_ctx { int idx; }; -static int ethsw_fdb_do_dump(struct fdb_dump_entry *entry, - struct ethsw_dump_ctx *dump) +static int dpaa2_switch_fdb_dump_nl(struct fdb_dump_entry *entry, + struct ethsw_dump_ctx *dump) { int is_dynamic = entry->type & DPSW_FDB_ENTRY_DINAMIC; u32 portid = NETLINK_CB(dump->cb->skb).portid; @@ -632,8 +632,8 @@ nla_put_failure: return -EMSGSIZE; } -static int port_fdb_valid_entry(struct fdb_dump_entry *entry, - struct ethsw_port_priv *port_priv) +static int dpaa2_switch_port_fdb_valid_entry(struct fdb_dump_entry *entry, + struct ethsw_port_priv *port_priv) { int idx = port_priv->idx; int valid; @@ -646,9 +646,9 @@ static int port_fdb_valid_entry(struct fdb_dump_entry *entry, return valid; } -static int port_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb, - struct net_device *net_dev, - struct net_device *filter_dev, int *idx) +static int dpaa2_switch_port_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb, + struct net_device *net_dev, + struct net_device *filter_dev, int *idx) { struct ethsw_port_priv *port_priv = netdev_priv(net_dev); struct ethsw_core *ethsw = port_priv->ethsw_data; @@ -693,10 +693,10 @@ static int port_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb, for (i = 0; i < num_fdb_entries; i++) { fdb_entry = fdb_entries[i]; - if (!port_fdb_valid_entry(&fdb_entry, port_priv)) + if (!dpaa2_switch_port_fdb_valid_entry(&fdb_entry, port_priv)) continue; - err = ethsw_fdb_do_dump(&fdb_entry, &dump); + err = dpaa2_switch_fdb_dump_nl(&fdb_entry, &dump); if (err) goto end; } @@ -715,7 +715,7 @@ err_map: return err; } -static int ethsw_port_set_mac_addr(struct ethsw_port_priv *port_priv) +static int dpaa2_switch_port_set_mac_addr(struct ethsw_port_priv *port_priv) { struct ethsw_core *ethsw = port_priv->ethsw_data; struct net_device *net_dev = port_priv->netdev; @@ -755,30 +755,30 @@ static int ethsw_port_set_mac_addr(struct ethsw_port_priv *port_priv) return 0; } -static const struct net_device_ops ethsw_port_ops = { - .ndo_open = port_open, - .ndo_stop = port_stop, +static const struct net_device_ops dpaa2_switch_port_ops = { + .ndo_open = dpaa2_switch_port_open, + .ndo_stop = dpaa2_switch_port_stop, .ndo_set_mac_address = eth_mac_addr, - .ndo_get_stats64 = port_get_stats, - .ndo_change_mtu = port_change_mtu, - .ndo_has_offload_stats = port_has_offload_stats, - .ndo_get_offload_stats = port_get_offload_stats, - .ndo_fdb_add = port_fdb_add, - .ndo_fdb_del = port_fdb_del, - .ndo_fdb_dump = port_fdb_dump, - - .ndo_start_xmit = port_dropframe, - .ndo_get_port_parent_id = swdev_get_port_parent_id, - .ndo_get_phys_port_name = port_get_phys_name, + .ndo_get_stats64 = dpaa2_switch_port_get_stats, + .ndo_change_mtu = dpaa2_switch_port_change_mtu, + .ndo_has_offload_stats = dpaa2_switch_port_has_offload_stats, + .ndo_get_offload_stats = dpaa2_switch_port_get_offload_stats, + .ndo_fdb_add = dpaa2_switch_port_fdb_add, + .ndo_fdb_del = dpaa2_switch_port_fdb_del, + .ndo_fdb_dump = dpaa2_switch_port_fdb_dump, + + .ndo_start_xmit = dpaa2_switch_port_dropframe, + .ndo_get_port_parent_id = dpaa2_switch_port_parent_id, + .ndo_get_phys_port_name = dpaa2_switch_port_get_phys_name, }; -static bool ethsw_port_dev_check(const struct net_device *netdev, - struct notifier_block *nb) +static bool dpaa2_switch_port_dev_check(const struct net_device *netdev, + struct notifier_block *nb) { struct ethsw_port_priv *port_priv = netdev_priv(netdev); - if (netdev->netdev_ops == ðsw_port_ops && + if (netdev->netdev_ops == &dpaa2_switch_port_ops && (!nb || &port_priv->ethsw_data->port_nb == nb || &port_priv->ethsw_data->port_switchdev_nb == nb || &port_priv->ethsw_data->port_switchdevb_nb == nb)) @@ -787,17 +787,17 @@ static bool ethsw_port_dev_check(const struct net_device *netdev, return false; } -static void ethsw_links_state_update(struct ethsw_core *ethsw) +static void dpaa2_switch_links_state_update(struct ethsw_core *ethsw) { int i; for (i = 0; i < ethsw->sw_attr.num_ifs; i++) { - port_carrier_state_sync(ethsw->ports[i]->netdev); - ethsw_port_set_mac_addr(ethsw->ports[i]); + dpaa2_switch_port_carrier_state_sync(ethsw->ports[i]->netdev); + dpaa2_switch_port_set_mac_addr(ethsw->ports[i]); } } -static irqreturn_t ethsw_irq0_handler_thread(int irq_num, void *arg) +static irqreturn_t dpaa2_switch_irq0_handler_thread(int irq_num, void *arg) { struct device *dev = (struct device *)arg; struct ethsw_core *ethsw = dev_get_drvdata(dev); @@ -819,13 +819,13 @@ static irqreturn_t ethsw_irq0_handler_thread(int irq_num, void *arg) } if (status & DPSW_IRQ_EVENT_LINK_CHANGED) - ethsw_links_state_update(ethsw); + dpaa2_switch_links_state_update(ethsw); out: return IRQ_HANDLED; } -static int ethsw_setup_irqs(struct fsl_mc_device *sw_dev) +static int dpaa2_switch_setup_irqs(struct fsl_mc_device *sw_dev) { struct device *dev = &sw_dev->dev; struct ethsw_core *ethsw = dev_get_drvdata(dev); @@ -855,7 +855,7 @@ static int ethsw_setup_irqs(struct fsl_mc_device *sw_dev) err = devm_request_threaded_irq(dev, irq->msi_desc->irq, NULL, - ethsw_irq0_handler_thread, + dpaa2_switch_irq0_handler_thread, IRQF_NO_SUSPEND | IRQF_ONESHOT, dev_name(dev), dev); if (err) { @@ -886,7 +886,7 @@ free_irq: return err; } -static void ethsw_teardown_irqs(struct fsl_mc_device *sw_dev) +static void dpaa2_switch_teardown_irqs(struct fsl_mc_device *sw_dev) { struct device *dev = &sw_dev->dev; struct ethsw_core *ethsw = dev_get_drvdata(dev); @@ -900,21 +900,21 @@ static void ethsw_teardown_irqs(struct fsl_mc_device *sw_dev) fsl_mc_free_irqs(sw_dev); } -static int port_attr_stp_state_set(struct net_device *netdev, - struct switchdev_trans *trans, - u8 state) +static int dpaa2_switch_port_attr_stp_state_set(struct net_device *netdev, + struct switchdev_trans *trans, + u8 state) { struct ethsw_port_priv *port_priv = netdev_priv(netdev); if (switchdev_trans_ph_prepare(trans)) return 0; - return ethsw_port_set_stp_state(port_priv, state); + return dpaa2_switch_port_set_stp_state(port_priv, state); } -static int port_attr_br_flags_pre_set(struct net_device *netdev, - struct switchdev_trans *trans, - unsigned long flags) +static int dpaa2_switch_port_attr_br_flags_pre_set(struct net_device *netdev, + struct switchdev_trans *trans, + unsigned long flags) { if (flags & ~(BR_LEARNING | BR_FLOOD)) return -EINVAL; @@ -922,9 +922,9 @@ static int port_attr_br_flags_pre_set(struct net_device *netdev, return 0; } -static int port_attr_br_flags_set(struct net_device *netdev, - struct switchdev_trans *trans, - unsigned long flags) +static int dpaa2_switch_port_attr_br_flags_set(struct net_device *netdev, + struct switchdev_trans *trans, + unsigned long flags) { struct ethsw_port_priv *port_priv = netdev_priv(netdev); int err = 0; @@ -933,35 +933,35 @@ static int port_attr_br_flags_set(struct net_device *netdev, return 0; /* Learning is enabled per switch */ - err = ethsw_set_learning(port_priv->ethsw_data, - !!(flags & BR_LEARNING)); + err = dpaa2_switch_set_learning(port_priv->ethsw_data, + !!(flags & BR_LEARNING)); if (err) goto exit; - err = ethsw_port_set_flood(port_priv, !!(flags & BR_FLOOD)); + err = dpaa2_switch_port_set_flood(port_priv, !!(flags & BR_FLOOD)); exit: return err; } -static int swdev_port_attr_set(struct net_device *netdev, - const struct switchdev_attr *attr, - struct switchdev_trans *trans) +static int dpaa2_switch_port_attr_set(struct net_device *netdev, + const struct switchdev_attr *attr, + struct switchdev_trans *trans) { int err = 0; switch (attr->id) { case SWITCHDEV_ATTR_ID_PORT_STP_STATE: - err = port_attr_stp_state_set(netdev, trans, - attr->u.stp_state); + err = dpaa2_switch_port_attr_stp_state_set(netdev, trans, + attr->u.stp_state); break; case SWITCHDEV_ATTR_ID_PORT_PRE_BRIDGE_FLAGS: - err = port_attr_br_flags_pre_set(netdev, trans, - attr->u.brport_flags); + err = dpaa2_switch_port_attr_br_flags_pre_set(netdev, trans, + attr->u.brport_flags); break; case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS: - err = port_attr_br_flags_set(netdev, trans, - attr->u.brport_flags); + err = dpaa2_switch_port_attr_br_flags_set(netdev, trans, + attr->u.brport_flags); break; case SWITCHDEV_ATTR_ID_BRIDGE_VLAN_FILTERING: /* VLANs are supported by default */ @@ -974,9 +974,9 @@ static int swdev_port_attr_set(struct net_device *netdev, return err; } -static int port_vlans_add(struct net_device *netdev, - const struct switchdev_obj_port_vlan *vlan, - struct switchdev_trans *trans) +static int dpaa2_switch_port_vlans_add(struct net_device *netdev, + const struct switchdev_obj_port_vlan *vlan, + struct switchdev_trans *trans) { struct ethsw_port_priv *port_priv = netdev_priv(netdev); struct ethsw_core *ethsw = port_priv->ethsw_data; @@ -1004,13 +1004,13 @@ static int port_vlans_add(struct net_device *netdev, for (vid = vlan->vid_begin; vid <= vlan->vid_end; vid++) { if (!port_priv->ethsw_data->vlans[vid]) { /* this is a new VLAN */ - err = ethsw_add_vlan(port_priv->ethsw_data, vid); + err = dpaa2_switch_add_vlan(port_priv->ethsw_data, vid); if (err) return err; port_priv->ethsw_data->vlans[vid] |= ETHSW_VLAN_GLOBAL; } - err = ethsw_port_add_vlan(port_priv, vid, vlan->flags); + err = dpaa2_switch_port_add_vlan(port_priv, vid, vlan->flags); if (err) break; } @@ -1018,8 +1018,8 @@ static int port_vlans_add(struct net_device *netdev, return err; } -static int port_lookup_address(struct net_device *netdev, int is_uc, - const unsigned char *addr) +static int dpaa2_switch_port_lookup_address(struct net_device *netdev, int is_uc, + const unsigned char *addr) { struct netdev_hw_addr_list *list = (is_uc) ? &netdev->uc : &netdev->mc; struct netdev_hw_addr *ha; @@ -1035,9 +1035,9 @@ static int port_lookup_address(struct net_device *netdev, int is_uc, return 0; } -static int port_mdb_add(struct net_device *netdev, - const struct switchdev_obj_port_mdb *mdb, - struct switchdev_trans *trans) +static int dpaa2_switch_port_mdb_add(struct net_device *netdev, + const struct switchdev_obj_port_mdb *mdb, + struct switchdev_trans *trans) { struct ethsw_port_priv *port_priv = netdev_priv(netdev); int err; @@ -1046,38 +1046,38 @@ static int port_mdb_add(struct net_device *netdev, return 0; /* Check if address is already set on this port */ - if (port_lookup_address(netdev, 0, mdb->addr)) + if (dpaa2_switch_port_lookup_address(netdev, 0, mdb->addr)) return -EEXIST; - err = ethsw_port_fdb_add_mc(port_priv, mdb->addr); + err = dpaa2_switch_port_fdb_add_mc(port_priv, mdb->addr); if (err) return err; err = dev_mc_add(netdev, mdb->addr); if (err) { netdev_err(netdev, "dev_mc_add err %d\n", err); - ethsw_port_fdb_del_mc(port_priv, mdb->addr); + dpaa2_switch_port_fdb_del_mc(port_priv, mdb->addr); } return err; } -static int swdev_port_obj_add(struct net_device *netdev, - const struct switchdev_obj *obj, - struct switchdev_trans *trans) +static int dpaa2_switch_port_obj_add(struct net_device *netdev, + const struct switchdev_obj *obj, + struct switchdev_trans *trans) { int err; switch (obj->id) { case SWITCHDEV_OBJ_ID_PORT_VLAN: - err = port_vlans_add(netdev, - SWITCHDEV_OBJ_PORT_VLAN(obj), - trans); + err = dpaa2_switch_port_vlans_add(netdev, + SWITCHDEV_OBJ_PORT_VLAN(obj), + trans); break; case SWITCHDEV_OBJ_ID_PORT_MDB: - err = port_mdb_add(netdev, - SWITCHDEV_OBJ_PORT_MDB(obj), - trans); + err = dpaa2_switch_port_mdb_add(netdev, + SWITCHDEV_OBJ_PORT_MDB(obj), + trans); break; default: err = -EOPNOTSUPP; @@ -1087,7 +1087,7 @@ static int swdev_port_obj_add(struct net_device *netdev, return err; } -static int ethsw_port_del_vlan(struct ethsw_port_priv *port_priv, u16 vid) +static int dpaa2_switch_port_del_vlan(struct ethsw_port_priv *port_priv, u16 vid) { struct ethsw_core *ethsw = port_priv->ethsw_data; struct net_device *netdev = port_priv->netdev; @@ -1098,7 +1098,7 @@ static int ethsw_port_del_vlan(struct ethsw_port_priv *port_priv, u16 vid) return -ENOENT; if (port_priv->vlans[vid] & ETHSW_VLAN_PVID) { - err = ethsw_port_set_pvid(port_priv, 0); + err = dpaa2_switch_port_set_pvid(port_priv, 0); if (err) return err; } @@ -1136,7 +1136,7 @@ static int ethsw_port_del_vlan(struct ethsw_port_priv *port_priv, u16 vid) ethsw->vlans[vid] &= ~ETHSW_VLAN_GLOBAL; - err = ethsw_dellink_switch(ethsw, vid); + err = dpaa2_switch_dellink(ethsw, vid); if (err) return err; } @@ -1144,8 +1144,8 @@ static int ethsw_port_del_vlan(struct ethsw_port_priv *port_priv, u16 vid) return 0; } -static int port_vlans_del(struct net_device *netdev, - const struct switchdev_obj_port_vlan *vlan) +static int dpaa2_switch_port_vlans_del(struct net_device *netdev, + const struct switchdev_obj_port_vlan *vlan) { struct ethsw_port_priv *port_priv = netdev_priv(netdev); int vid, err = 0; @@ -1154,7 +1154,7 @@ static int port_vlans_del(struct net_device *netdev, return -EOPNOTSUPP; for (vid = vlan->vid_begin; vid <= vlan->vid_end; vid++) { - err = ethsw_port_del_vlan(port_priv, vid); + err = dpaa2_switch_port_del_vlan(port_priv, vid); if (err) break; } @@ -1162,16 +1162,16 @@ static int port_vlans_del(struct net_device *netdev, return err; } -static int port_mdb_del(struct net_device *netdev, - const struct switchdev_obj_port_mdb *mdb) +static int dpaa2_switch_port_mdb_del(struct net_device *netdev, + const struct switchdev_obj_port_mdb *mdb) { struct ethsw_port_priv *port_priv = netdev_priv(netdev); int err; - if (!port_lookup_address(netdev, 0, mdb->addr)) + if (!dpaa2_switch_port_lookup_address(netdev, 0, mdb->addr)) return -ENOENT; - err = ethsw_port_fdb_del_mc(port_priv, mdb->addr); + err = dpaa2_switch_port_fdb_del_mc(port_priv, mdb->addr); if (err) return err; @@ -1184,17 +1184,17 @@ static int port_mdb_del(struct net_device *netdev, return err; } -static int swdev_port_obj_del(struct net_device *netdev, - const struct switchdev_obj *obj) +static int dpaa2_switch_port_obj_del(struct net_device *netdev, + const struct switchdev_obj *obj) { int err; switch (obj->id) { case SWITCHDEV_OBJ_ID_PORT_VLAN: - err = port_vlans_del(netdev, SWITCHDEV_OBJ_PORT_VLAN(obj)); + err = dpaa2_switch_port_vlans_del(netdev, SWITCHDEV_OBJ_PORT_VLAN(obj)); break; case SWITCHDEV_OBJ_ID_PORT_MDB: - err = port_mdb_del(netdev, SWITCHDEV_OBJ_PORT_MDB(obj)); + err = dpaa2_switch_port_mdb_del(netdev, SWITCHDEV_OBJ_PORT_MDB(obj)); break; default: err = -EOPNOTSUPP; @@ -1203,23 +1203,22 @@ static int swdev_port_obj_del(struct net_device *netdev, return err; } -static int -ethsw_switchdev_port_attr_set_event(struct net_device *netdev, - struct switchdev_notifier_port_attr_info - *port_attr_info) +static int dpaa2_switch_port_attr_set_event(struct net_device *netdev, + struct switchdev_notifier_port_attr_info + *port_attr_info) { int err; - err = swdev_port_attr_set(netdev, port_attr_info->attr, - port_attr_info->trans); + err = dpaa2_switch_port_attr_set(netdev, port_attr_info->attr, + port_attr_info->trans); port_attr_info->handled = true; return notifier_from_errno(err); } /* For the moment, only flood setting needs to be updated */ -static int port_bridge_join(struct net_device *netdev, - struct net_device *upper_dev) +static int dpaa2_switch_port_bridge_join(struct net_device *netdev, + struct net_device *upper_dev) { struct ethsw_port_priv *port_priv = netdev_priv(netdev); struct ethsw_core *ethsw = port_priv->ethsw_data; @@ -1237,7 +1236,7 @@ static int port_bridge_join(struct net_device *netdev, } netdev_for_each_lower_dev(upper_dev, other_dev, iter) { - if (!ethsw_port_dev_check(other_dev, NULL)) + if (!dpaa2_switch_port_dev_check(other_dev, NULL)) continue; other_port_priv = netdev_priv(other_dev); @@ -1249,35 +1248,35 @@ static int port_bridge_join(struct net_device *netdev, } /* Enable flooding */ - err = ethsw_port_set_flood(port_priv, 1); + err = dpaa2_switch_port_set_flood(port_priv, 1); if (!err) port_priv->bridge_dev = upper_dev; return err; } -static int port_bridge_leave(struct net_device *netdev) +static int dpaa2_switch_port_bridge_leave(struct net_device *netdev) { struct ethsw_port_priv *port_priv = netdev_priv(netdev); int err; /* Disable flooding */ - err = ethsw_port_set_flood(port_priv, 0); + err = dpaa2_switch_port_set_flood(port_priv, 0); if (!err) port_priv->bridge_dev = NULL; return err; } -static int port_netdevice_event(struct notifier_block *nb, - unsigned long event, void *ptr) +static int dpaa2_switch_port_netdevice_event(struct notifier_block *nb, + unsigned long event, void *ptr) { struct net_device *netdev = netdev_notifier_info_to_dev(ptr); struct netdev_notifier_changeupper_info *info = ptr; struct net_device *upper_dev; int err = 0; - if (!ethsw_port_dev_check(netdev, nb)) + if (!dpaa2_switch_port_dev_check(netdev, nb)) return NOTIFY_DONE; /* Handle just upper dev link/unlink for the moment */ @@ -1285,9 +1284,9 @@ static int port_netdevice_event(struct notifier_block *nb, upper_dev = info->upper_dev; if (netif_is_bridge_master(upper_dev)) { if (info->linking) - err = port_bridge_join(netdev, upper_dev); + err = dpaa2_switch_port_bridge_join(netdev, upper_dev); else - err = port_bridge_leave(netdev); + err = dpaa2_switch_port_bridge_leave(netdev); } } @@ -1301,7 +1300,7 @@ struct ethsw_switchdev_event_work { unsigned long event; }; -static void ethsw_switchdev_event_work(struct work_struct *work) +static void dpaa2_switch_event_work(struct work_struct *work) { struct ethsw_switchdev_event_work *switchdev_work = container_of(work, struct ethsw_switchdev_event_work, work); @@ -1317,11 +1316,11 @@ static void ethsw_switchdev_event_work(struct work_struct *work) if (!fdb_info->added_by_user) break; if (is_unicast_ether_addr(fdb_info->addr)) - err = ethsw_port_fdb_add_uc(netdev_priv(dev), - fdb_info->addr); + err = dpaa2_switch_port_fdb_add_uc(netdev_priv(dev), + fdb_info->addr); else - err = ethsw_port_fdb_add_mc(netdev_priv(dev), - fdb_info->addr); + err = dpaa2_switch_port_fdb_add_mc(netdev_priv(dev), + fdb_info->addr); if (err) break; fdb_info->offloaded = true; @@ -1332,9 +1331,9 @@ static void ethsw_switchdev_event_work(struct work_struct *work) if (!fdb_info->added_by_user) break; if (is_unicast_ether_addr(fdb_info->addr)) - ethsw_port_fdb_del_uc(netdev_priv(dev), fdb_info->addr); + dpaa2_switch_port_fdb_del_uc(netdev_priv(dev), fdb_info->addr); else - ethsw_port_fdb_del_mc(netdev_priv(dev), fdb_info->addr); + dpaa2_switch_port_fdb_del_mc(netdev_priv(dev), fdb_info->addr); break; } @@ -1345,8 +1344,8 @@ static void ethsw_switchdev_event_work(struct work_struct *work) } /* Called under rcu_read_lock() */ -static int port_switchdev_event(struct notifier_block *nb, - unsigned long event, void *ptr) +static int dpaa2_switch_port_event(struct notifier_block *nb, + unsigned long event, void *ptr) { struct net_device *dev = switchdev_notifier_info_to_dev(ptr); struct ethsw_port_priv *port_priv = netdev_priv(dev); @@ -1354,17 +1353,17 @@ static int port_switchdev_event(struct notifier_block *nb, struct switchdev_notifier_fdb_info *fdb_info = ptr; struct ethsw_core *ethsw = port_priv->ethsw_data; - if (!ethsw_port_dev_check(dev, nb)) + if (!dpaa2_switch_port_dev_check(dev, nb)) return NOTIFY_DONE; if (event == SWITCHDEV_PORT_ATTR_SET) - return ethsw_switchdev_port_attr_set_event(dev, ptr); + return dpaa2_switch_port_attr_set_event(dev, ptr); switchdev_work = kzalloc(sizeof(*switchdev_work), GFP_ATOMIC); if (!switchdev_work) return NOTIFY_BAD; - INIT_WORK(&switchdev_work->work, ethsw_switchdev_event_work); + INIT_WORK(&switchdev_work->work, dpaa2_switch_event_work); switchdev_work->dev = dev; switchdev_work->event = event; @@ -1397,20 +1396,19 @@ err_addr_alloc: return NOTIFY_BAD; } -static int -ethsw_switchdev_port_obj_event(unsigned long event, struct net_device *netdev, - struct switchdev_notifier_port_obj_info - *port_obj_info) +static int dpaa2_switch_port_obj_event(unsigned long event, + struct net_device *netdev, + struct switchdev_notifier_port_obj_info *port_obj_info) { int err = -EOPNOTSUPP; switch (event) { case SWITCHDEV_PORT_OBJ_ADD: - err = swdev_port_obj_add(netdev, port_obj_info->obj, - port_obj_info->trans); + err = dpaa2_switch_port_obj_add(netdev, port_obj_info->obj, + port_obj_info->trans); break; case SWITCHDEV_PORT_OBJ_DEL: - err = swdev_port_obj_del(netdev, port_obj_info->obj); + err = dpaa2_switch_port_obj_del(netdev, port_obj_info->obj); break; } @@ -1418,45 +1416,45 @@ ethsw_switchdev_port_obj_event(unsigned long event, struct net_device *netdev, return notifier_from_errno(err); } -static int port_switchdev_blocking_event(struct notifier_block *nb, - unsigned long event, void *ptr) +static int dpaa2_switch_port_blocking_event(struct notifier_block *nb, + unsigned long event, void *ptr) { struct net_device *dev = switchdev_notifier_info_to_dev(ptr); - if (!ethsw_port_dev_check(dev, nb)) + if (!dpaa2_switch_port_dev_check(dev, nb)) return NOTIFY_DONE; switch (event) { case SWITCHDEV_PORT_OBJ_ADD: case SWITCHDEV_PORT_OBJ_DEL: - return ethsw_switchdev_port_obj_event(event, dev, ptr); + return dpaa2_switch_port_obj_event(event, dev, ptr); case SWITCHDEV_PORT_ATTR_SET: - return ethsw_switchdev_port_attr_set_event(dev, ptr); + return dpaa2_switch_port_attr_set_event(dev, ptr); } return NOTIFY_DONE; } -static int ethsw_register_notifier(struct device *dev) +static int dpaa2_switch_register_notifier(struct device *dev) { struct ethsw_core *ethsw = dev_get_drvdata(dev); int err; - ethsw->port_nb.notifier_call = port_netdevice_event; + ethsw->port_nb.notifier_call = dpaa2_switch_port_netdevice_event; err = register_netdevice_notifier(ðsw->port_nb); if (err) { dev_err(dev, "Failed to register netdev notifier\n"); return err; } - ethsw->port_switchdev_nb.notifier_call = port_switchdev_event; + ethsw->port_switchdev_nb.notifier_call = dpaa2_switch_port_event; err = register_switchdev_notifier(ðsw->port_switchdev_nb); if (err) { dev_err(dev, "Failed to register switchdev notifier\n"); goto err_switchdev_nb; } - ethsw->port_switchdevb_nb.notifier_call = port_switchdev_blocking_event; + ethsw->port_switchdevb_nb.notifier_call = dpaa2_switch_port_blocking_event; err = register_switchdev_blocking_notifier(ðsw->port_switchdevb_nb); if (err) { dev_err(dev, "Failed to register switchdev blocking notifier\n"); @@ -1472,7 +1470,7 @@ err_switchdev_nb: return err; } -static void ethsw_detect_features(struct ethsw_core *ethsw) +static void dpaa2_switch_detect_features(struct ethsw_core *ethsw) { ethsw->features = 0; @@ -1480,7 +1478,7 @@ static void ethsw_detect_features(struct ethsw_core *ethsw) ethsw->features |= ETHSW_FEATURE_MAC_ADDR; } -static int ethsw_init(struct fsl_mc_device *sw_dev) +static int dpaa2_switch_init(struct fsl_mc_device *sw_dev) { struct device *dev = &sw_dev->dev; struct ethsw_core *ethsw = dev_get_drvdata(dev); @@ -1523,7 +1521,7 @@ static int ethsw_init(struct fsl_mc_device *sw_dev) goto err_close; } - ethsw_detect_features(ethsw); + dpaa2_switch_detect_features(ethsw); err = dpsw_reset(ethsw->mc_io, 0, ethsw->dpsw_handle); if (err) { @@ -1568,7 +1566,7 @@ static int ethsw_init(struct fsl_mc_device *sw_dev) goto err_close; } - err = ethsw_register_notifier(dev); + err = dpaa2_switch_register_notifier(dev); if (err) goto err_destroy_ordered_workqueue; @@ -1582,7 +1580,7 @@ err_close: return err; } -static int ethsw_port_init(struct ethsw_port_priv *port_priv, u16 port) +static int dpaa2_switch_port_init(struct ethsw_port_priv *port_priv, u16 port) { struct net_device *netdev = port_priv->netdev; struct ethsw_core *ethsw = port_priv->ethsw_data; @@ -1603,7 +1601,7 @@ static int ethsw_port_init(struct ethsw_port_priv *port_priv, u16 port) return err; } - err = ethsw_port_set_pvid(port_priv, 0); + err = dpaa2_switch_port_set_pvid(port_priv, 0); if (err) return err; @@ -1615,7 +1613,7 @@ static int ethsw_port_init(struct ethsw_port_priv *port_priv, u16 port) return err; } -static void ethsw_unregister_notifier(struct device *dev) +static void dpaa2_switch_unregister_notifier(struct device *dev) { struct ethsw_core *ethsw = dev_get_drvdata(dev); struct notifier_block *nb; @@ -1639,20 +1637,20 @@ static void ethsw_unregister_notifier(struct device *dev) "Failed to unregister netdev notifier (%d)\n", err); } -static void ethsw_takedown(struct fsl_mc_device *sw_dev) +static void dpaa2_switch_takedown(struct fsl_mc_device *sw_dev) { struct device *dev = &sw_dev->dev; struct ethsw_core *ethsw = dev_get_drvdata(dev); int err; - ethsw_unregister_notifier(dev); + dpaa2_switch_unregister_notifier(dev); err = dpsw_close(ethsw->mc_io, 0, ethsw->dpsw_handle); if (err) dev_warn(dev, "dpsw_close err %d\n", err); } -static int ethsw_remove(struct fsl_mc_device *sw_dev) +static int dpaa2_switch_remove(struct fsl_mc_device *sw_dev) { struct ethsw_port_priv *port_priv; struct ethsw_core *ethsw; @@ -1662,7 +1660,7 @@ static int ethsw_remove(struct fsl_mc_device *sw_dev) dev = &sw_dev->dev; ethsw = dev_get_drvdata(dev); - ethsw_teardown_irqs(sw_dev); + dpaa2_switch_teardown_irqs(sw_dev); dpsw_disable(ethsw->mc_io, 0, ethsw->dpsw_handle); @@ -1673,7 +1671,7 @@ static int ethsw_remove(struct fsl_mc_device *sw_dev) } kfree(ethsw->ports); - ethsw_takedown(sw_dev); + dpaa2_switch_takedown(sw_dev); destroy_workqueue(ethsw->workqueue); @@ -1686,7 +1684,8 @@ static int ethsw_remove(struct fsl_mc_device *sw_dev) return 0; } -static int ethsw_probe_port(struct ethsw_core *ethsw, u16 port_idx) +static int dpaa2_switch_probe_port(struct ethsw_core *ethsw, + u16 port_idx) { struct ethsw_port_priv *port_priv; struct device *dev = ethsw->dev; @@ -1710,18 +1709,18 @@ static int ethsw_probe_port(struct ethsw_core *ethsw, u16 port_idx) port_priv->flood = true; SET_NETDEV_DEV(port_netdev, dev); - port_netdev->netdev_ops = ðsw_port_ops; - port_netdev->ethtool_ops = ðsw_port_ethtool_ops; + port_netdev->netdev_ops = &dpaa2_switch_port_ops; + port_netdev->ethtool_ops = &dpaa2_switch_port_ethtool_ops; /* Set MTU limits */ port_netdev->min_mtu = ETH_MIN_MTU; port_netdev->max_mtu = ETHSW_MAX_FRAME_LENGTH; - err = ethsw_port_init(port_priv, port_idx); + err = dpaa2_switch_port_init(port_priv, port_idx); if (err) goto err_port_probe; - err = ethsw_port_set_mac_addr(port_priv); + err = dpaa2_switch_port_set_mac_addr(port_priv); if (err) goto err_port_probe; @@ -1741,7 +1740,7 @@ err_port_probe: return err; } -static int ethsw_probe(struct fsl_mc_device *sw_dev) +static int dpaa2_switch_probe(struct fsl_mc_device *sw_dev) { struct device *dev = &sw_dev->dev; struct ethsw_core *ethsw; @@ -1766,7 +1765,7 @@ static int ethsw_probe(struct fsl_mc_device *sw_dev) goto err_free_drvdata; } - err = ethsw_init(sw_dev); + err = dpaa2_switch_init(sw_dev); if (err) goto err_free_cmdport; @@ -1784,7 +1783,7 @@ static int ethsw_probe(struct fsl_mc_device *sw_dev) } for (i = 0; i < ethsw->sw_attr.num_ifs; i++) { - err = ethsw_probe_port(ethsw, i); + err = dpaa2_switch_probe_port(ethsw, i); if (err) goto err_free_ports; } @@ -1800,7 +1799,7 @@ static int ethsw_probe(struct fsl_mc_device *sw_dev) dpsw_if_disable(ethsw->mc_io, 0, ethsw->dpsw_handle, i); /* Setup IRQs */ - err = ethsw_setup_irqs(sw_dev); + err = dpaa2_switch_setup_irqs(sw_dev); if (err) goto err_stop; @@ -1819,7 +1818,7 @@ err_free_ports: kfree(ethsw->ports); err_takedown: - ethsw_takedown(sw_dev); + dpaa2_switch_takedown(sw_dev); err_free_cmdport: fsl_mc_portal_free(ethsw->mc_io); @@ -1831,26 +1830,26 @@ err_free_drvdata: return err; } -static const struct fsl_mc_device_id ethsw_match_id_table[] = { +static const struct fsl_mc_device_id dpaa2_switch_match_id_table[] = { { .vendor = FSL_MC_VENDOR_FREESCALE, .obj_type = "dpsw", }, { .vendor = 0x0 } }; -MODULE_DEVICE_TABLE(fslmc, ethsw_match_id_table); +MODULE_DEVICE_TABLE(fslmc, dpaa2_switch_match_id_table); -static struct fsl_mc_driver eth_sw_drv = { +static struct fsl_mc_driver dpaa2_switch_drv = { .driver = { .name = KBUILD_MODNAME, .owner = THIS_MODULE, }, - .probe = ethsw_probe, - .remove = ethsw_remove, - .match_id_table = ethsw_match_id_table + .probe = dpaa2_switch_probe, + .remove = dpaa2_switch_remove, + .match_id_table = dpaa2_switch_match_id_table }; -module_fsl_mc_driver(eth_sw_drv); +module_fsl_mc_driver(dpaa2_switch_drv); MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("DPAA2 Ethernet Switch Driver"); diff --git a/drivers/staging/fsl-dpaa2/ethsw/ethsw.h b/drivers/staging/fsl-dpaa2/ethsw/ethsw.h index d136dbdcaffa..5f9211ccb1ef 100644 --- a/drivers/staging/fsl-dpaa2/ethsw/ethsw.h +++ b/drivers/staging/fsl-dpaa2/ethsw/ethsw.h @@ -39,7 +39,7 @@ #define ETHSW_FEATURE_MAC_ADDR BIT(0) -extern const struct ethtool_ops ethsw_port_ethtool_ops; +extern const struct ethtool_ops dpaa2_switch_port_ethtool_ops; struct ethsw_core; diff --git a/drivers/staging/fwserial/fwserial.c b/drivers/staging/fwserial/fwserial.c index aec0f19597a9..db83d34cd677 100644 --- a/drivers/staging/fwserial/fwserial.c +++ b/drivers/staging/fwserial/fwserial.c @@ -466,7 +466,7 @@ static void fwtty_throttle_port(struct fwtty_port *port) * fwtty_do_hangup - wait for ldisc to deliver all pending rx; only then hangup * * When the remote has finished tx, and all in-flight rx has been received and - * and pushed to the flip buffer, the remote may close its device. This will + * pushed to the flip buffer, the remote may close its device. This will * drop DTR on the remote which will drop carrier here. Typically, the tty is * hung up when carrier is dropped or lost. * diff --git a/drivers/staging/greybus/audio_codec.c b/drivers/staging/greybus/audio_codec.c index 74538f8c5fa4..494aa823e998 100644 --- a/drivers/staging/greybus/audio_codec.c +++ b/drivers/staging/greybus/audio_codec.c @@ -688,7 +688,7 @@ static struct snd_soc_dai_driver gbaudio_dai[] = { .playback = { .stream_name = "I2S 0 Playback", .rates = SNDRV_PCM_RATE_48000, - .formats = SNDRV_PCM_FORMAT_S16_LE, + .formats = SNDRV_PCM_FMTBIT_S16_LE, .rate_max = 48000, .rate_min = 48000, .channels_min = 1, @@ -698,7 +698,7 @@ static struct snd_soc_dai_driver gbaudio_dai[] = { .capture = { .stream_name = "I2S 0 Capture", .rates = SNDRV_PCM_RATE_48000, - .formats = SNDRV_PCM_FORMAT_S16_LE, + .formats = SNDRV_PCM_FMTBIT_S16_LE, .rate_max = 48000, .rate_min = 48000, .channels_min = 1, diff --git a/drivers/staging/greybus/audio_module.c b/drivers/staging/greybus/audio_module.c index 16f60256adb2..c52c4f361b90 100644 --- a/drivers/staging/greybus/audio_module.c +++ b/drivers/staging/greybus/audio_module.c @@ -219,7 +219,7 @@ static int gb_audio_add_data_connection(struct gbaudio_module_info *gbmodule, greybus_set_drvdata(bundle, gbmodule); dai->id = 0; - dai->data_cport = connection->intf_cport_id; + dai->data_cport = cpu_to_le16(connection->intf_cport_id); dai->connection = connection; list_add(&dai->list, &gbmodule->data_list); @@ -329,7 +329,7 @@ static int gb_audio_probe(struct gb_bundle *bundle, if (ret) { dev_err(dev, "%d:Error while enabling %d:data connection\n", - ret, dai->data_cport); + ret, le16_to_cpu(dai->data_cport)); goto disable_data_connection; } } @@ -451,7 +451,7 @@ static int gb_audio_resume(struct device *dev) if (ret) { dev_err(dev, "%d:Error while enabling %d:data connection\n", - ret, dai->data_cport); + ret, le16_to_cpu(dai->data_cport)); return ret; } } diff --git a/drivers/staging/greybus/audio_topology.c b/drivers/staging/greybus/audio_topology.c index 83b38ae8908c..662e3e8b4b63 100644 --- a/drivers/staging/greybus/audio_topology.c +++ b/drivers/staging/greybus/audio_topology.c @@ -182,7 +182,7 @@ static int gbcodec_mixer_ctl_info(struct snd_kcontrol *kcontrol, /* update uinfo */ uinfo->access = data->access; uinfo->count = data->vcount; - uinfo->type = (snd_ctl_elem_type_t)info->type; + uinfo->type = (__force snd_ctl_elem_type_t)info->type; switch (info->type) { case GB_AUDIO_CTL_ELEM_TYPE_BOOLEAN: @@ -466,7 +466,7 @@ static int gbcodec_mixer_dapm_ctl_put(struct snd_kcontrol *kcontrol, goto exit; /* update ucontrol */ - if (gbvalue.value.integer_value[0] != val) { + if (le32_to_cpu(gbvalue.value.integer_value[0]) != val) { for (wi = 0; wi < wlist->num_widgets; wi++) { widget = wlist->widgets[wi]; snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, @@ -689,7 +689,7 @@ static int gbaudio_tplg_create_kcontrol(struct gbaudio_module_info *gb, return -ENOMEM; ctldata->ctl_id = ctl->id; ctldata->data_cport = le16_to_cpu(ctl->data_cport); - ctldata->access = ctl->access; + ctldata->access = le32_to_cpu(ctl->access); ctldata->vcount = ctl->count_values; ctldata->info = &ctl->info; *kctl = (struct snd_kcontrol_new) @@ -744,10 +744,10 @@ static int gbcodec_enum_dapm_ctl_get(struct snd_kcontrol *kcontrol, return ret; } - ucontrol->value.enumerated.item[0] = gbvalue.value.enumerated_item[0]; + ucontrol->value.enumerated.item[0] = le32_to_cpu(gbvalue.value.enumerated_item[0]); if (e->shift_l != e->shift_r) ucontrol->value.enumerated.item[1] = - gbvalue.value.enumerated_item[1]; + le32_to_cpu(gbvalue.value.enumerated_item[1]); return 0; } @@ -800,11 +800,11 @@ static int gbcodec_enum_dapm_ctl_put(struct snd_kcontrol *kcontrol, val = mux << e->shift_l; mask = e->mask << e->shift_l; - if (gbvalue.value.enumerated_item[0] != + if (le32_to_cpu(gbvalue.value.enumerated_item[0]) != ucontrol->value.enumerated.item[0]) { change = 1; gbvalue.value.enumerated_item[0] = - ucontrol->value.enumerated.item[0]; + cpu_to_le32(ucontrol->value.enumerated.item[0]); } if (e->shift_l != e->shift_r) { @@ -812,11 +812,11 @@ static int gbcodec_enum_dapm_ctl_put(struct snd_kcontrol *kcontrol, return -EINVAL; val |= ucontrol->value.enumerated.item[1] << e->shift_r; mask |= e->mask << e->shift_r; - if (gbvalue.value.enumerated_item[1] != + if (le32_to_cpu(gbvalue.value.enumerated_item[1]) != ucontrol->value.enumerated.item[1]) { change = 1; gbvalue.value.enumerated_item[1] = - ucontrol->value.enumerated.item[1]; + cpu_to_le32(ucontrol->value.enumerated.item[1]); } } @@ -887,7 +887,7 @@ static int gbaudio_tplg_create_mixer_ctl(struct gbaudio_module_info *gb, return -ENOMEM; ctldata->ctl_id = ctl->id; ctldata->data_cport = le16_to_cpu(ctl->data_cport); - ctldata->access = ctl->access; + ctldata->access = le32_to_cpu(ctl->access); ctldata->vcount = ctl->count_values; ctldata->info = &ctl->info; *kctl = (struct snd_kcontrol_new) diff --git a/drivers/staging/greybus/gbphy.h b/drivers/staging/greybus/gbphy.h index 087928a586fb..d4a225b76338 100644 --- a/drivers/staging/greybus/gbphy.h +++ b/drivers/staging/greybus/gbphy.h @@ -36,9 +36,9 @@ struct gbphy_device_id { struct gbphy_driver { const char *name; - int (*probe)(struct gbphy_device *, + int (*probe)(struct gbphy_device *device, const struct gbphy_device_id *id); - void (*remove)(struct gbphy_device *); + void (*remove)(struct gbphy_device *device); const struct gbphy_device_id *id_table; struct device_driver driver; diff --git a/drivers/staging/hikey9xx/Kconfig b/drivers/staging/hikey9xx/Kconfig new file mode 100644 index 000000000000..b29f5d5df134 --- /dev/null +++ b/drivers/staging/hikey9xx/Kconfig @@ -0,0 +1,49 @@ +# SPDX-License-Identifier: GPL-2.0 + +# to be placed at drivers/phy +config PHY_HI3670_USB + tristate "hi3670 USB PHY support" + depends on (ARCH_HISI && ARM64) || COMPILE_TEST + select GENERIC_PHY + select MFD_SYSCON + help + Enable this to support the HISILICON HI3670 USB PHY. + + To compile this driver as a module, choose M here. + +# to be placed at drivers/spmi +config SPMI_HISI3670 + tristate "Hisilicon 3670 SPMI Controller" + select IRQ_DOMAIN_HIERARCHY + depends on HAS_IOMEM + depends on SPMI + help + If you say yes to this option, support will be included for the + built-in SPMI PMIC Arbiter interface on Hisilicon 3670 + processors. + +# to be placed at drivers/mfd +config MFD_HI6421_SPMI + tristate "HiSilicon Hi6421v600 SPMI PMU/Codec IC" + depends on OF + depends on SPMI + select MFD_CORE + help + Add support for HiSilicon Hi6421v600 SPMI PMIC. Hi6421 includes + multi-functions, such as regulators, RTC, codec, Coulomb counter, + etc. + + This driver includes core APIs _only_. You have to select + individual components like voltage regulators under corresponding + menus in order to enable them. + We communicate with the Hi6421v600 via a SPMI bus. + +# to be placed at drivers/regulator +config REGULATOR_HI6421V600 + tristate "HiSilicon Hi6421v600 PMIC voltage regulator support" + depends on MFD_HI6421_SPMI && OF + depends on REGULATOR + help + This driver provides support for the voltage regulators on + HiSilicon Hi6421v600 PMU / Codec IC. + This is used on Kirin 3670 boards, like HiKey 970. diff --git a/drivers/staging/hikey9xx/Makefile b/drivers/staging/hikey9xx/Makefile new file mode 100644 index 000000000000..1924fadac952 --- /dev/null +++ b/drivers/staging/hikey9xx/Makefile @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: GPL-2.0 + +obj-$(CONFIG_PHY_HI3670_USB) += phy-hi3670-usb3.o + +obj-$(CONFIG_SPMI_HISI3670) += hisi-spmi-controller.o +obj-$(CONFIG_MFD_HI6421_SPMI) += hi6421-spmi-pmic.o +obj-$(CONFIG_REGULATOR_HI6421V600) += hi6421v600-regulator.o diff --git a/drivers/staging/hikey9xx/TODO b/drivers/staging/hikey9xx/TODO new file mode 100644 index 000000000000..65e7996a3066 --- /dev/null +++ b/drivers/staging/hikey9xx/TODO @@ -0,0 +1,5 @@ +ToDo list: + +- Port other drivers needed by Hikey 960/970; +- Test drivers on Hikey 960; +- Validate device tree bindings. diff --git a/drivers/staging/hikey9xx/hi6421-spmi-pmic.c b/drivers/staging/hikey9xx/hi6421-spmi-pmic.c new file mode 100644 index 000000000000..64b30d263c8d --- /dev/null +++ b/drivers/staging/hikey9xx/hi6421-spmi-pmic.c @@ -0,0 +1,342 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Device driver for regulators in HISI PMIC IC + * + * Copyright (c) 2013 Linaro Ltd. + * Copyright (c) 2011 Hisilicon. + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include <linux/delay.h> +#include <linux/device.h> +#include <linux/err.h> +#include <linux/interrupt.h> +#include <linux/io.h> +#include <linux/irq.h> +#include <linux/mfd/core.h> +#include <linux/mfd/hi6421-spmi-pmic.h> +#include <linux/module.h> +#include <linux/of_address.h> +#include <linux/of_device.h> +#include <linux/of_gpio.h> +#include <linux/of.h> +#include <linux/of_irq.h> +#include <linux/platform_device.h> +#include <linux/slab.h> +#include <linux/spmi.h> + +/* 8-bit register offset in PMIC */ +#define HISI_MASK_STATE 0xff + +#define HISI_IRQ_ARRAY 2 +#define HISI_IRQ_NUM (HISI_IRQ_ARRAY * 8) + +#define SOC_PMIC_IRQ_MASK_0_ADDR 0x0202 +#define SOC_PMIC_IRQ0_ADDR 0x0212 + +#define HISI_IRQ_KEY_NUM 0 +#define HISI_IRQ_KEY_VALUE 0xc0 +#define HISI_IRQ_KEY_DOWN 7 +#define HISI_IRQ_KEY_UP 6 + +#define HISI_MASK_FIELD 0xFF +#define HISI_BITS 8 + +/*define the first group interrupt register number*/ +#define HISI_PMIC_FIRST_GROUP_INT_NUM 2 + +static const struct mfd_cell hi6421v600_devs[] = { + { .name = "hi6421v600-regulator", }, +}; + +/* + * The PMIC register is only 8-bit. + * Hisilicon SoC use hardware to map PMIC register into SoC mapping. + * At here, we are accessing SoC register with 32-bit. + */ +int hi6421_spmi_pmic_read(struct hi6421_spmi_pmic *pmic, int reg) +{ + struct spmi_device *pdev; + u8 read_value = 0; + u32 ret; + + pdev = to_spmi_device(pmic->dev); + if (!pdev) { + pr_err("%s: pdev get failed!\n", __func__); + return -ENODEV; + } + + ret = spmi_ext_register_readl(pdev, reg, &read_value, 1); + if (ret) { + pr_err("%s: spmi_ext_register_readl failed!\n", __func__); + return ret; + } + return read_value; +} +EXPORT_SYMBOL(hi6421_spmi_pmic_read); + +int hi6421_spmi_pmic_write(struct hi6421_spmi_pmic *pmic, int reg, u32 val) +{ + struct spmi_device *pdev; + u32 ret; + + pdev = to_spmi_device(pmic->dev); + if (!pdev) { + pr_err("%s: pdev get failed!\n", __func__); + return -ENODEV; + } + + ret = spmi_ext_register_writel(pdev, reg, (unsigned char *)&val, 1); + if (ret) + pr_err("%s: spmi_ext_register_writel failed!\n", __func__); + + return ret; +} +EXPORT_SYMBOL(hi6421_spmi_pmic_write); + +int hi6421_spmi_pmic_rmw(struct hi6421_spmi_pmic *pmic, int reg, + u32 mask, u32 bits) +{ + unsigned long flags; + u32 data; + int ret; + + spin_lock_irqsave(&pmic->lock, flags); + data = hi6421_spmi_pmic_read(pmic, reg) & ~mask; + data |= mask & bits; + ret = hi6421_spmi_pmic_write(pmic, reg, data); + spin_unlock_irqrestore(&pmic->lock, flags); + + return ret; +} +EXPORT_SYMBOL(hi6421_spmi_pmic_rmw); + +static irqreturn_t hi6421_spmi_irq_handler(int irq, void *data) +{ + struct hi6421_spmi_pmic *pmic = (struct hi6421_spmi_pmic *)data; + unsigned long pending; + int i, offset; + + for (i = 0; i < HISI_IRQ_ARRAY; i++) { + pending = hi6421_spmi_pmic_read(pmic, (i + SOC_PMIC_IRQ0_ADDR)); + pending &= HISI_MASK_FIELD; + if (pending != 0) + pr_debug("pending[%d]=0x%lx\n\r", i, pending); + + hi6421_spmi_pmic_write(pmic, (i + SOC_PMIC_IRQ0_ADDR), pending); + + /* solve powerkey order */ + if ((i == HISI_IRQ_KEY_NUM) && + ((pending & HISI_IRQ_KEY_VALUE) == HISI_IRQ_KEY_VALUE)) { + generic_handle_irq(pmic->irqs[HISI_IRQ_KEY_DOWN]); + generic_handle_irq(pmic->irqs[HISI_IRQ_KEY_UP]); + pending &= (~HISI_IRQ_KEY_VALUE); + } + + if (pending) { + for_each_set_bit(offset, &pending, HISI_BITS) + generic_handle_irq(pmic->irqs[offset + i * HISI_BITS]); + } + } + + return IRQ_HANDLED; +} + +static void hi6421_spmi_irq_mask(struct irq_data *d) +{ + struct hi6421_spmi_pmic *pmic = irq_data_get_irq_chip_data(d); + u32 data, offset; + unsigned long flags; + + offset = (irqd_to_hwirq(d) >> 3); + offset += SOC_PMIC_IRQ_MASK_0_ADDR; + + spin_lock_irqsave(&pmic->lock, flags); + data = hi6421_spmi_pmic_read(pmic, offset); + data |= (1 << (irqd_to_hwirq(d) & 0x07)); + hi6421_spmi_pmic_write(pmic, offset, data); + spin_unlock_irqrestore(&pmic->lock, flags); +} + +static void hi6421_spmi_irq_unmask(struct irq_data *d) +{ + struct hi6421_spmi_pmic *pmic = irq_data_get_irq_chip_data(d); + u32 data, offset; + unsigned long flags; + + offset = (irqd_to_hwirq(d) >> 3); + offset += SOC_PMIC_IRQ_MASK_0_ADDR; + + spin_lock_irqsave(&pmic->lock, flags); + data = hi6421_spmi_pmic_read(pmic, offset); + data &= ~(1 << (irqd_to_hwirq(d) & 0x07)); + hi6421_spmi_pmic_write(pmic, offset, data); + spin_unlock_irqrestore(&pmic->lock, flags); +} + +static struct irq_chip hi6421_spmi_pmu_irqchip = { + .name = "hisi-irq", + .irq_mask = hi6421_spmi_irq_mask, + .irq_unmask = hi6421_spmi_irq_unmask, + .irq_disable = hi6421_spmi_irq_mask, + .irq_enable = hi6421_spmi_irq_unmask, +}; + +static int hi6421_spmi_irq_map(struct irq_domain *d, unsigned int virq, + irq_hw_number_t hw) +{ + struct hi6421_spmi_pmic *pmic = d->host_data; + + irq_set_chip_and_handler_name(virq, &hi6421_spmi_pmu_irqchip, + handle_simple_irq, "hisi"); + irq_set_chip_data(virq, pmic); + irq_set_irq_type(virq, IRQ_TYPE_NONE); + + return 0; +} + +static const struct irq_domain_ops hi6421_spmi_domain_ops = { + .map = hi6421_spmi_irq_map, + .xlate = irq_domain_xlate_twocell, +}; + +static void hi6421_spmi_pmic_irq_prc(struct hi6421_spmi_pmic *pmic) +{ + int i, pending; + + for (i = 0 ; i < HISI_IRQ_ARRAY; i++) + hi6421_spmi_pmic_write(pmic, SOC_PMIC_IRQ_MASK_0_ADDR + i, + HISI_MASK_STATE); + + for (i = 0 ; i < HISI_IRQ_ARRAY; i++) { + pending = hi6421_spmi_pmic_read(pmic, SOC_PMIC_IRQ0_ADDR + i); + + pr_debug("PMU IRQ address value:irq[0x%x] = 0x%x\n", + SOC_PMIC_IRQ0_ADDR + i, pending); + hi6421_spmi_pmic_write(pmic, SOC_PMIC_IRQ0_ADDR + i, + HISI_MASK_STATE); + } +} + +static int hi6421_spmi_pmic_probe(struct spmi_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + struct hi6421_spmi_pmic *pmic; + unsigned int virq; + int ret, i; + + pmic = devm_kzalloc(dev, sizeof(*pmic), GFP_KERNEL); + if (!pmic) + return -ENOMEM; + + spin_lock_init(&pmic->lock); + + pmic->dev = dev; + + pmic->gpio = of_get_gpio(np, 0); + if (pmic->gpio < 0) + return pmic->gpio; + + if (!gpio_is_valid(pmic->gpio)) + return -EINVAL; + + ret = devm_gpio_request_one(dev, pmic->gpio, GPIOF_IN, "pmic"); + if (ret < 0) { + dev_err(dev, "failed to request gpio%d\n", pmic->gpio); + return ret; + } + + pmic->irq = gpio_to_irq(pmic->gpio); + + hi6421_spmi_pmic_irq_prc(pmic); + + pmic->irqs = devm_kzalloc(dev, HISI_IRQ_NUM * sizeof(int), GFP_KERNEL); + if (!pmic->irqs) + goto irq_malloc; + + pmic->domain = irq_domain_add_simple(np, HISI_IRQ_NUM, 0, + &hi6421_spmi_domain_ops, pmic); + if (!pmic->domain) { + dev_err(dev, "failed irq domain add simple!\n"); + ret = -ENODEV; + goto irq_malloc; + } + + for (i = 0; i < HISI_IRQ_NUM; i++) { + virq = irq_create_mapping(pmic->domain, i); + if (!virq) { + dev_err(dev, "Failed mapping hwirq\n"); + ret = -ENOSPC; + goto irq_malloc; + } + pmic->irqs[i] = virq; + dev_dbg(dev, "%s: pmic->irqs[%d] = %d\n", + __func__, i, pmic->irqs[i]); + } + + ret = request_threaded_irq(pmic->irq, hi6421_spmi_irq_handler, NULL, + IRQF_TRIGGER_LOW | IRQF_SHARED | IRQF_NO_SUSPEND, + "pmic", pmic); + if (ret < 0) { + dev_err(dev, "could not claim pmic IRQ: error %d\n", ret); + goto irq_malloc; + } + + dev_set_drvdata(&pdev->dev, pmic); + + /* + * The logic below will rely that the pmic is already stored at + * drvdata. + */ + dev_dbg(&pdev->dev, "SPMI-PMIC: adding children for %pOF\n", + pdev->dev.of_node); + ret = devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_NONE, + hi6421v600_devs, ARRAY_SIZE(hi6421v600_devs), + NULL, 0, NULL); + if (!ret) + return 0; + + dev_err(dev, "Failed to add child devices: %d\n", ret); + +irq_malloc: + free_irq(pmic->irq, pmic); + + return ret; +} + +static void hi6421_spmi_pmic_remove(struct spmi_device *pdev) +{ + struct hi6421_spmi_pmic *pmic = dev_get_drvdata(&pdev->dev); + + free_irq(pmic->irq, pmic); +} + +static const struct of_device_id pmic_spmi_id_table[] = { + { .compatible = "hisilicon,hi6421-spmi" }, + { } +}; +MODULE_DEVICE_TABLE(of, pmic_spmi_id_table); + +static struct spmi_driver hi6421_spmi_pmic_driver = { + .driver = { + .name = "hi6421-spmi-pmic", + .of_match_table = pmic_spmi_id_table, + }, + .probe = hi6421_spmi_pmic_probe, + .remove = hi6421_spmi_pmic_remove, +}; +module_spmi_driver(hi6421_spmi_pmic_driver); + +MODULE_DESCRIPTION("HiSilicon Hi6421v600 SPMI PMIC driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/hikey9xx/hi6421v600-regulator.c b/drivers/staging/hikey9xx/hi6421v600-regulator.c new file mode 100644 index 000000000000..614b03c9ddfb --- /dev/null +++ b/drivers/staging/hikey9xx/hi6421v600-regulator.c @@ -0,0 +1,478 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Device driver for regulators in Hisi IC + * + * Copyright (c) 2013 Linaro Ltd. + * Copyright (c) 2011 Hisilicon. + * + * Guodong Xu <guodong.xu@linaro.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <linux/delay.h> +#include <linux/device.h> +#include <linux/err.h> +#include <linux/io.h> +#include <linux/mfd/hi6421-spmi-pmic.h> +#include <linux/module.h> +#include <linux/of_address.h> +#include <linux/of_device.h> +#include <linux/of.h> +#include <linux/platform_device.h> +#include <linux/regmap.h> +#include <linux/regulator/driver.h> +#include <linux/regulator/machine.h> +#include <linux/regulator/of_regulator.h> +#include <linux/seq_file.h> +#include <linux/slab.h> +#include <linux/spmi.h> +#include <linux/time.h> +#include <linux/uaccess.h> + +#define rdev_dbg(rdev, fmt, arg...) \ + pr_debug("%s: %s: " fmt, (rdev)->desc->name, __func__, ##arg) + +struct hi6421v600_regulator { + struct regulator_desc rdesc; + struct hi6421_spmi_pmic *pmic; + u32 eco_mode_mask, eco_uA; +}; + +static DEFINE_MUTEX(enable_mutex); + +/* + * helper function to ensure when it returns it is at least 'delay_us' + * microseconds after 'since'. + */ + +static int hi6421_spmi_regulator_is_enabled(struct regulator_dev *rdev) +{ + struct hi6421v600_regulator *sreg = rdev_get_drvdata(rdev); + struct hi6421_spmi_pmic *pmic = sreg->pmic; + u32 reg_val; + + reg_val = hi6421_spmi_pmic_read(pmic, rdev->desc->enable_reg); + + rdev_dbg(rdev, + "enable_reg=0x%x, val= 0x%x, enable_state=%d\n", + rdev->desc->enable_reg, + reg_val, (reg_val & rdev->desc->enable_mask)); + + return ((reg_val & rdev->desc->enable_mask) != 0); +} + +static int hi6421_spmi_regulator_enable(struct regulator_dev *rdev) +{ + struct hi6421v600_regulator *sreg = rdev_get_drvdata(rdev); + struct hi6421_spmi_pmic *pmic = sreg->pmic; + + /* cannot enable more than one regulator at one time */ + mutex_lock(&enable_mutex); + usleep_range(HISI_REGS_ENA_PROTECT_TIME, + HISI_REGS_ENA_PROTECT_TIME + 1000); + + /* set enable register */ + rdev_dbg(rdev, + "off_on_delay=%d us, enable_reg=0x%x, enable_mask=0x%x\n", + rdev->desc->off_on_delay, rdev->desc->enable_reg, + rdev->desc->enable_mask); + + hi6421_spmi_pmic_rmw(pmic, rdev->desc->enable_reg, + rdev->desc->enable_mask, + rdev->desc->enable_mask); + + mutex_unlock(&enable_mutex); + + return 0; +} + +static int hi6421_spmi_regulator_disable(struct regulator_dev *rdev) +{ + struct hi6421v600_regulator *sreg = rdev_get_drvdata(rdev); + struct hi6421_spmi_pmic *pmic = sreg->pmic; + + /* set enable register to 0 */ + rdev_dbg(rdev, "enable_reg=0x%x, enable_mask=0x%x\n", + rdev->desc->enable_reg, rdev->desc->enable_mask); + + hi6421_spmi_pmic_rmw(pmic, rdev->desc->enable_reg, + rdev->desc->enable_mask, 0); + + return 0; +} + +static int hi6421_spmi_regulator_get_voltage_sel(struct regulator_dev *rdev) +{ + struct hi6421v600_regulator *sreg = rdev_get_drvdata(rdev); + struct hi6421_spmi_pmic *pmic = sreg->pmic; + u32 reg_val, selector; + + /* get voltage selector */ + reg_val = hi6421_spmi_pmic_read(pmic, rdev->desc->vsel_reg); + + selector = (reg_val & rdev->desc->vsel_mask) >> (ffs(rdev->desc->vsel_mask) - 1); + + rdev_dbg(rdev, + "vsel_reg=0x%x, value=0x%x, entry=0x%x, voltage=%d mV\n", + rdev->desc->vsel_reg, reg_val, selector, + rdev->desc->ops->list_voltage(rdev, selector) / 1000); + + return selector; +} + +static int hi6421_spmi_regulator_set_voltage_sel(struct regulator_dev *rdev, + unsigned int selector) +{ + struct hi6421v600_regulator *sreg = rdev_get_drvdata(rdev); + struct hi6421_spmi_pmic *pmic = sreg->pmic; + u32 reg_val; + + if (unlikely(selector >= rdev->desc->n_voltages)) + return -EINVAL; + + reg_val = selector << (ffs(rdev->desc->vsel_mask) - 1); + + /* set voltage selector */ + rdev_dbg(rdev, + "vsel_reg=0x%x, mask=0x%x, value=0x%x, voltage=%d mV\n", + rdev->desc->vsel_reg, rdev->desc->vsel_mask, reg_val, + rdev->desc->ops->list_voltage(rdev, selector) / 1000); + + hi6421_spmi_pmic_rmw(pmic, rdev->desc->vsel_reg, + rdev->desc->vsel_mask, reg_val); + + return 0; +} + +static unsigned int hi6421_spmi_regulator_get_mode(struct regulator_dev *rdev) +{ + struct hi6421v600_regulator *sreg = rdev_get_drvdata(rdev); + struct hi6421_spmi_pmic *pmic = sreg->pmic; + unsigned int mode; + u32 reg_val; + + reg_val = hi6421_spmi_pmic_read(pmic, rdev->desc->enable_reg); + + if (reg_val & sreg->eco_mode_mask) + mode = REGULATOR_MODE_IDLE; + else + mode = REGULATOR_MODE_NORMAL; + + rdev_dbg(rdev, + "enable_reg=0x%x, eco_mode_mask=0x%x, reg_val=0x%x, %s mode\n", + rdev->desc->enable_reg, sreg->eco_mode_mask, reg_val, + mode == REGULATOR_MODE_IDLE ? "idle" : "normal"); + + return mode; +} + +static int hi6421_spmi_regulator_set_mode(struct regulator_dev *rdev, + unsigned int mode) +{ + struct hi6421v600_regulator *sreg = rdev_get_drvdata(rdev); + struct hi6421_spmi_pmic *pmic = sreg->pmic; + u32 val; + + switch (mode) { + case REGULATOR_MODE_NORMAL: + val = 0; + break; + case REGULATOR_MODE_IDLE: + val = sreg->eco_mode_mask << (ffs(sreg->eco_mode_mask) - 1); + break; + default: + return -EINVAL; + } + + /* set mode */ + rdev_dbg(rdev, "enable_reg=0x%x, eco_mode_mask=0x%x, value=0x%x\n", + rdev->desc->enable_reg, sreg->eco_mode_mask, val); + + hi6421_spmi_pmic_rmw(pmic, rdev->desc->enable_reg, + sreg->eco_mode_mask, val); + + return 0; +} + +static unsigned int +hi6421_spmi_regulator_get_optimum_mode(struct regulator_dev *rdev, + int input_uV, int output_uV, + int load_uA) +{ + struct hi6421v600_regulator *sreg = rdev_get_drvdata(rdev); + + if (load_uA || ((unsigned int)load_uA > sreg->eco_uA)) + return REGULATOR_MODE_NORMAL; + + return REGULATOR_MODE_IDLE; +} + +static int hi6421_spmi_dt_parse(struct platform_device *pdev, + struct hi6421v600_regulator *sreg, + struct regulator_desc *rdesc) +{ + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + unsigned int *v_table; + int ret; + + ret = of_property_read_u32(np, "reg", &rdesc->enable_reg); + if (ret) { + dev_err(dev, "missing reg property\n"); + return ret; + } + + ret = of_property_read_u32(np, "vsel-reg", &rdesc->vsel_reg); + if (ret) { + dev_err(dev, "missing vsel-reg property\n"); + return ret; + } + + ret = of_property_read_u32(np, "enable-mask", &rdesc->enable_mask); + if (ret) { + dev_err(dev, "missing enable-mask property\n"); + return ret; + } + + /* + * Not all regulators work on idle mode + */ + ret = of_property_read_u32(np, "idle-mode-mask", &sreg->eco_mode_mask); + if (ret) { + dev_dbg(dev, "LDO doesn't support economy mode.\n"); + sreg->eco_mode_mask = 0; + sreg->eco_uA = 0; + } else { + ret = of_property_read_u32(np, "eco-microamp", &sreg->eco_uA); + if (ret) { + dev_err(dev, "missing eco-microamp property\n"); + return ret; + } + } + + /* parse .off-on-delay */ + ret = of_property_read_u32(np, "off-on-delay-us", + &rdesc->off_on_delay); + if (ret) { + dev_err(dev, "missing off-on-delay-us property\n"); + return ret; + } + + /* parse .enable_time */ + ret = of_property_read_u32(np, "startup-delay-us", + &rdesc->enable_time); + if (ret) { + dev_err(dev, "missing startup-delay-us property\n"); + return ret; + } + + /* FIXME: are there a better value for this? */ + rdesc->ramp_delay = rdesc->enable_time; + + /* parse volt_table */ + + rdesc->n_voltages = of_property_count_u32_elems(np, "voltage-table"); + + v_table = devm_kzalloc(dev, sizeof(unsigned int) * rdesc->n_voltages, + GFP_KERNEL); + if (unlikely(!v_table)) + return -ENOMEM; + rdesc->volt_table = v_table; + + ret = of_property_read_u32_array(np, "voltage-table", + v_table, rdesc->n_voltages); + if (ret) { + dev_err(dev, "missing voltage-table property\n"); + return ret; + } + + /* + * Instead of explicitly requiring a mask for the voltage selector, + * as they all start from bit zero (at least on the known LDOs), + * just use the number of voltages at the voltage table, getting the + * minimal mask that would pick everything. + */ + rdesc->vsel_mask = (1 << (fls(rdesc->n_voltages) - 1)) - 1; + + dev_dbg(dev, "voltage selector settings: reg: 0x%x, mask: 0x%x\n", + rdesc->vsel_reg, rdesc->vsel_mask); + + return 0; +} + +static const struct regulator_ops hi6421_spmi_ldo_rops = { + .is_enabled = hi6421_spmi_regulator_is_enabled, + .enable = hi6421_spmi_regulator_enable, + .disable = hi6421_spmi_regulator_disable, + .list_voltage = regulator_list_voltage_table, + .map_voltage = regulator_map_voltage_iterate, + .get_voltage_sel = hi6421_spmi_regulator_get_voltage_sel, + .set_voltage_sel = hi6421_spmi_regulator_set_voltage_sel, + .get_mode = hi6421_spmi_regulator_get_mode, + .set_mode = hi6421_spmi_regulator_set_mode, + .get_optimum_mode = hi6421_spmi_regulator_get_optimum_mode, +}; + +static int hi6421_spmi_regulator_probe_ldo(struct platform_device *pdev, + struct device_node *np, + struct hi6421_spmi_pmic *pmic) +{ + struct regulation_constraints *constraint; + struct regulator_init_data *initdata; + struct regulator_config config = { }; + struct hi6421v600_regulator *sreg; + struct device *dev = &pdev->dev; + struct regulator_desc *rdesc; + struct regulator_dev *rdev; + const char *supplyname; + int ret; + + initdata = of_get_regulator_init_data(dev, np, NULL); + if (!initdata) { + dev_err(dev, "failed to get regulator data\n"); + return -EINVAL; + } + + sreg = devm_kzalloc(dev, sizeof(*sreg), GFP_KERNEL); + if (!sreg) + return -ENOMEM; + + sreg->pmic = pmic; + rdesc = &sreg->rdesc; + + rdesc->name = initdata->constraints.name; + rdesc->ops = &hi6421_spmi_ldo_rops; + rdesc->type = REGULATOR_VOLTAGE; + rdesc->min_uV = initdata->constraints.min_uV; + + supplyname = of_get_property(np, "supply_name", NULL); + if (supplyname) + initdata->supply_regulator = supplyname; + + /* parse device tree data for regulator specific */ + ret = hi6421_spmi_dt_parse(pdev, sreg, rdesc); + if (ret) + return ret; + + /* hisi regulator supports two modes */ + constraint = &initdata->constraints; + + constraint->valid_modes_mask = REGULATOR_MODE_NORMAL; + if (sreg->eco_mode_mask) { + constraint->valid_modes_mask |= REGULATOR_MODE_IDLE; + constraint->valid_ops_mask |= REGULATOR_CHANGE_MODE; + } + + config.dev = &pdev->dev; + config.init_data = initdata; + config.driver_data = sreg; + config.of_node = pdev->dev.of_node; + + /* register regulator */ + rdev = regulator_register(rdesc, &config); + if (IS_ERR(rdev)) { + dev_err(dev, "failed to register %s\n", + rdesc->name); + return PTR_ERR(rdev); + } + + rdev_dbg(rdev, "valid_modes_mask: 0x%x, valid_ops_mask: 0x%x\n", + constraint->valid_modes_mask, constraint->valid_ops_mask); + + dev_set_drvdata(dev, rdev); + + return 0; +} + +static int hi6421_spmi_regulator_probe(struct platform_device *pdev) +{ + struct device *pmic_dev = pdev->dev.parent; + struct device_node *np = pmic_dev->of_node; + struct device_node *regulators, *child; + struct platform_device *new_pdev; + struct hi6421_spmi_pmic *pmic; + int ret; + + /* + * This driver is meant to be called by hi6421-spmi-core, + * which should first set drvdata. If this doesn't happen, hit + * a warn on and return. + */ + pmic = dev_get_drvdata(pmic_dev); + if (WARN_ON(!pmic)) + return -ENODEV; + + regulators = of_get_child_by_name(np, "regulators"); + if (!regulators) { + dev_err(&pdev->dev, "regulator node not found\n"); + return -ENODEV; + } + + /* + * Parse all LDO regulator nodes + */ + for_each_child_of_node(regulators, child) { + dev_dbg(&pdev->dev, "adding child %pOF\n", child); + + new_pdev = platform_device_alloc(child->name, -1); + new_pdev->dev.parent = pmic_dev; + new_pdev->dev.of_node = of_node_get(child); + + ret = platform_device_add(new_pdev); + if (ret < 0) { + platform_device_put(new_pdev); + continue; + } + + ret = hi6421_spmi_regulator_probe_ldo(new_pdev, child, pmic); + if (ret < 0) + platform_device_put(new_pdev); + } + + of_node_put(regulators); + + return 0; +} + +static int hi6421_spmi_regulator_remove(struct platform_device *pdev) +{ + struct regulator_dev *rdev = dev_get_drvdata(&pdev->dev); + struct hi6421v600_regulator *sreg = rdev_get_drvdata(rdev); + + regulator_unregister(rdev); + + if (rdev->desc->volt_table) + devm_kfree(&pdev->dev, (unsigned int *)rdev->desc->volt_table); + + kfree(sreg); + + return 0; +} + +static const struct platform_device_id hi6421v600_regulator_table[] = { + { .name = "hi6421v600-regulator" }, + {}, +}; +MODULE_DEVICE_TABLE(platform, hi6421v600_regulator_table); + +static struct platform_driver hi6421v600_regulator_driver = { + .id_table = hi6421v600_regulator_table, + .driver = { + .name = "hi6421v600-regulator", + }, + .probe = hi6421_spmi_regulator_probe, + .remove = hi6421_spmi_regulator_remove, +}; +module_platform_driver(hi6421v600_regulator_driver); + +MODULE_DESCRIPTION("Hi6421v600 regulator driver"); +MODULE_LICENSE("GPL v2"); + diff --git a/drivers/staging/hikey9xx/hisi-spmi-controller.c b/drivers/staging/hikey9xx/hisi-spmi-controller.c new file mode 100644 index 000000000000..f831c43f4783 --- /dev/null +++ b/drivers/staging/hikey9xx/hisi-spmi-controller.c @@ -0,0 +1,358 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include <linux/delay.h> +#include <linux/err.h> +#include <linux/interrupt.h> +#include <linux/io.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/platform_device.h> +#include <linux/seq_file.h> +#include <linux/slab.h> +#include <linux/spmi.h> + +/* + * SPMI register addr + */ +#define SPMI_CHANNEL_OFFSET 0x0300 +#define SPMI_SLAVE_OFFSET 0x20 + +#define SPMI_APB_SPMI_CMD_BASE_ADDR 0x0100 + +#define SPMI_APB_SPMI_WDATA0_BASE_ADDR 0x0104 +#define SPMI_APB_SPMI_WDATA1_BASE_ADDR 0x0108 +#define SPMI_APB_SPMI_WDATA2_BASE_ADDR 0x010c +#define SPMI_APB_SPMI_WDATA3_BASE_ADDR 0x0110 + +#define SPMI_APB_SPMI_STATUS_BASE_ADDR 0x0200 + +#define SPMI_APB_SPMI_RDATA0_BASE_ADDR 0x0204 +#define SPMI_APB_SPMI_RDATA1_BASE_ADDR 0x0208 +#define SPMI_APB_SPMI_RDATA2_BASE_ADDR 0x020c +#define SPMI_APB_SPMI_RDATA3_BASE_ADDR 0x0210 + +#define SPMI_PER_DATAREG_BYTE 4 +/* + * SPMI cmd register + */ +#define SPMI_APB_SPMI_CMD_EN BIT(31) +#define SPMI_APB_SPMI_CMD_TYPE_OFFSET 24 +#define SPMI_APB_SPMI_CMD_LENGTH_OFFSET 20 +#define SPMI_APB_SPMI_CMD_SLAVEID_OFFSET 16 +#define SPMI_APB_SPMI_CMD_ADDR_OFFSET 0 + +/* Command Opcodes */ + +enum spmi_controller_cmd_op_code { + SPMI_CMD_REG_ZERO_WRITE = 0, + SPMI_CMD_REG_WRITE = 1, + SPMI_CMD_REG_READ = 2, + SPMI_CMD_EXT_REG_WRITE = 3, + SPMI_CMD_EXT_REG_READ = 4, + SPMI_CMD_EXT_REG_WRITE_L = 5, + SPMI_CMD_EXT_REG_READ_L = 6, + SPMI_CMD_REG_RESET = 7, + SPMI_CMD_REG_SLEEP = 8, + SPMI_CMD_REG_SHUTDOWN = 9, + SPMI_CMD_REG_WAKEUP = 10, +}; + +/* + * SPMI status register + */ +#define SPMI_APB_TRANS_DONE BIT(0) +#define SPMI_APB_TRANS_FAIL BIT(2) + +/* Command register fields */ +#define SPMI_CONTROLLER_CMD_MAX_BYTE_COUNT 16 + +/* Maximum number of support PMIC peripherals */ +#define SPMI_CONTROLLER_TIMEOUT_US 1000 +#define SPMI_CONTROLLER_MAX_TRANS_BYTES 16 + +struct spmi_controller_dev { + struct spmi_controller *controller; + struct device *dev; + void __iomem *base; + spinlock_t lock; + u32 channel; +}; + +static int spmi_controller_wait_for_done(struct device *dev, + struct spmi_controller_dev *ctrl_dev, + void __iomem *base, u8 sid, u16 addr) +{ + u32 timeout = SPMI_CONTROLLER_TIMEOUT_US; + u32 status, offset; + + offset = SPMI_APB_SPMI_STATUS_BASE_ADDR; + offset += SPMI_CHANNEL_OFFSET * ctrl_dev->channel + SPMI_SLAVE_OFFSET * sid; + + do { + status = readl(base + offset); + + if (status & SPMI_APB_TRANS_DONE) { + if (status & SPMI_APB_TRANS_FAIL) { + dev_err(dev, "%s: transaction failed (0x%x)\n", + __func__, status); + return -EIO; + } + dev_dbg(dev, "%s: status 0x%x\n", __func__, status); + return 0; + } + udelay(1); + } while (timeout--); + + dev_err(dev, "%s: timeout, status 0x%x\n", __func__, status); + return -ETIMEDOUT; +} + +static int spmi_read_cmd(struct spmi_controller *ctrl, + u8 opc, u8 slave_id, u16 slave_addr, u8 *__buf, size_t bc) +{ + struct spmi_controller_dev *spmi_controller = dev_get_drvdata(&ctrl->dev); + u32 chnl_ofst = SPMI_CHANNEL_OFFSET * spmi_controller->channel; + unsigned long flags; + u8 *buf = __buf; + u32 cmd, data; + int rc; + u8 op_code, i; + + if (bc > SPMI_CONTROLLER_MAX_TRANS_BYTES) { + dev_err(&ctrl->dev, + "spmi_controller supports 1..%d bytes per trans, but:%zu requested\n", + SPMI_CONTROLLER_MAX_TRANS_BYTES, bc); + return -EINVAL; + } + + switch (opc) { + case SPMI_CMD_READ: + op_code = SPMI_CMD_REG_READ; + break; + case SPMI_CMD_EXT_READ: + op_code = SPMI_CMD_EXT_REG_READ; + break; + case SPMI_CMD_EXT_READL: + op_code = SPMI_CMD_EXT_REG_READ_L; + break; + default: + dev_err(&ctrl->dev, "invalid read cmd 0x%x\n", opc); + return -EINVAL; + } + + cmd = SPMI_APB_SPMI_CMD_EN | + (op_code << SPMI_APB_SPMI_CMD_TYPE_OFFSET) | + ((bc - 1) << SPMI_APB_SPMI_CMD_LENGTH_OFFSET) | + ((slave_id & 0xf) << SPMI_APB_SPMI_CMD_SLAVEID_OFFSET) | /* slvid */ + ((slave_addr & 0xffff) << SPMI_APB_SPMI_CMD_ADDR_OFFSET); /* slave_addr */ + + spin_lock_irqsave(&spmi_controller->lock, flags); + + writel(cmd, spmi_controller->base + chnl_ofst + SPMI_APB_SPMI_CMD_BASE_ADDR); + + rc = spmi_controller_wait_for_done(&ctrl->dev, spmi_controller, + spmi_controller->base, slave_id, slave_addr); + if (rc) + goto done; + + for (i = 0; bc > i * SPMI_PER_DATAREG_BYTE; i++) { + data = readl(spmi_controller->base + chnl_ofst + + SPMI_SLAVE_OFFSET * slave_id + + SPMI_APB_SPMI_RDATA0_BASE_ADDR + + i * SPMI_PER_DATAREG_BYTE); + data = be32_to_cpu((__be32)data); + if ((bc - i * SPMI_PER_DATAREG_BYTE) >> 2) { + memcpy(buf, &data, sizeof(data)); + buf += sizeof(data); + } else { + memcpy(buf, &data, bc % SPMI_PER_DATAREG_BYTE); + buf += (bc % SPMI_PER_DATAREG_BYTE); + } + } + +done: + spin_unlock_irqrestore(&spmi_controller->lock, flags); + if (rc) + dev_err(&ctrl->dev, + "spmi read wait timeout op:0x%x slave_id:%d slave_addr:0x%x bc:%zu\n", + opc, slave_id, slave_addr, bc + 1); + else + dev_dbg(&ctrl->dev, "%s: id:%d slave_addr:0x%x, read value: %*ph\n", + __func__, slave_id, slave_addr, (int)bc, __buf); + + return rc; +} + +static int spmi_write_cmd(struct spmi_controller *ctrl, + u8 opc, u8 slave_id, u16 slave_addr, const u8 *__buf, size_t bc) +{ + struct spmi_controller_dev *spmi_controller = dev_get_drvdata(&ctrl->dev); + u32 chnl_ofst = SPMI_CHANNEL_OFFSET * spmi_controller->channel; + const u8 *buf = __buf; + unsigned long flags; + u32 cmd, data; + int rc; + u8 op_code, i; + + if (bc > SPMI_CONTROLLER_MAX_TRANS_BYTES) { + dev_err(&ctrl->dev, + "spmi_controller supports 1..%d bytes per trans, but:%zu requested\n", + SPMI_CONTROLLER_MAX_TRANS_BYTES, bc); + return -EINVAL; + } + + switch (opc) { + case SPMI_CMD_WRITE: + op_code = SPMI_CMD_REG_WRITE; + break; + case SPMI_CMD_EXT_WRITE: + op_code = SPMI_CMD_EXT_REG_WRITE; + break; + case SPMI_CMD_EXT_WRITEL: + op_code = SPMI_CMD_EXT_REG_WRITE_L; + break; + default: + dev_err(&ctrl->dev, "invalid write cmd 0x%x\n", opc); + return -EINVAL; + } + + cmd = SPMI_APB_SPMI_CMD_EN | + (op_code << SPMI_APB_SPMI_CMD_TYPE_OFFSET) | + ((bc - 1) << SPMI_APB_SPMI_CMD_LENGTH_OFFSET) | + ((slave_id & 0xf) << SPMI_APB_SPMI_CMD_SLAVEID_OFFSET) | + ((slave_addr & 0xffff) << SPMI_APB_SPMI_CMD_ADDR_OFFSET); + + /* Write data to FIFOs */ + spin_lock_irqsave(&spmi_controller->lock, flags); + + for (i = 0; bc > i * SPMI_PER_DATAREG_BYTE; i++) { + data = 0; + if ((bc - i * SPMI_PER_DATAREG_BYTE) >> 2) { + memcpy(&data, buf, sizeof(data)); + buf += sizeof(data); + } else { + memcpy(&data, buf, bc % SPMI_PER_DATAREG_BYTE); + buf += (bc % SPMI_PER_DATAREG_BYTE); + } + + writel((u32)cpu_to_be32(data), + spmi_controller->base + chnl_ofst + + SPMI_APB_SPMI_WDATA0_BASE_ADDR + + SPMI_PER_DATAREG_BYTE * i); + } + + /* Start the transaction */ + writel(cmd, spmi_controller->base + chnl_ofst + SPMI_APB_SPMI_CMD_BASE_ADDR); + + rc = spmi_controller_wait_for_done(&ctrl->dev, spmi_controller, + spmi_controller->base, slave_id, + slave_addr); + spin_unlock_irqrestore(&spmi_controller->lock, flags); + + if (rc) + dev_err(&ctrl->dev, "spmi write wait timeout op:0x%x slave_id:%d slave_addr:0x%x bc:%zu\n", + opc, slave_id, slave_addr, bc); + else + dev_dbg(&ctrl->dev, "%s: id:%d slave_addr:0x%x, wrote value: %*ph\n", + __func__, slave_id, slave_addr, (int)bc, __buf); + + return rc; +} + +static int spmi_controller_probe(struct platform_device *pdev) +{ + struct spmi_controller_dev *spmi_controller; + struct spmi_controller *ctrl; + struct resource *iores; + int ret; + + ctrl = spmi_controller_alloc(&pdev->dev, sizeof(*spmi_controller)); + if (!ctrl) { + dev_err(&pdev->dev, "can not allocate spmi_controller data\n"); + return -ENOMEM; + } + spmi_controller = spmi_controller_get_drvdata(ctrl); + spmi_controller->controller = ctrl; + + iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!iores) { + dev_err(&pdev->dev, "can not get resource!\n"); + return -EINVAL; + } + + spmi_controller->base = devm_ioremap(&pdev->dev, iores->start, + resource_size(iores)); + if (!spmi_controller->base) { + dev_err(&pdev->dev, "can not remap base addr!\n"); + return -EADDRNOTAVAIL; + } + + ret = of_property_read_u32(pdev->dev.of_node, "spmi-channel", + &spmi_controller->channel); + if (ret) { + dev_err(&pdev->dev, "can not get channel\n"); + return -ENODEV; + } + + platform_set_drvdata(pdev, spmi_controller); + dev_set_drvdata(&ctrl->dev, spmi_controller); + + spin_lock_init(&spmi_controller->lock); + + ctrl->nr = spmi_controller->channel; + ctrl->dev.parent = pdev->dev.parent; + ctrl->dev.of_node = of_node_get(pdev->dev.of_node); + + /* Callbacks */ + ctrl->read_cmd = spmi_read_cmd; + ctrl->write_cmd = spmi_write_cmd; + + ret = spmi_controller_add(ctrl); + if (ret) + dev_err(&pdev->dev, "spmi_add_controller failed with error %d!\n", ret); + + return ret; +} + +static int spmi_del_controller(struct platform_device *pdev) +{ + struct spmi_controller *ctrl = platform_get_drvdata(pdev); + + spmi_controller_remove(ctrl); + kfree(ctrl); + return 0; +} + +static const struct of_device_id spmi_controller_match_table[] = { + { + .compatible = "hisilicon,kirin970-spmi-controller", + }, + {} +}; +MODULE_DEVICE_TABLE(of, spmi_controller_match_table); + +static struct platform_driver spmi_controller_driver = { + .probe = spmi_controller_probe, + .remove = spmi_del_controller, + .driver = { + .name = "hisi_spmi_controller", + .of_match_table = spmi_controller_match_table, + }, +}; + +static int __init spmi_controller_init(void) +{ + return platform_driver_register(&spmi_controller_driver); +} +postcore_initcall(spmi_controller_init); + +static void __exit spmi_controller_exit(void) +{ + platform_driver_unregister(&spmi_controller_driver); +} +module_exit(spmi_controller_exit); + +MODULE_LICENSE("GPL v2"); +MODULE_VERSION("1.0"); +MODULE_ALIAS("platform:spmi_controller"); diff --git a/drivers/staging/hikey9xx/hisilicon,hi6421-spmi-pmic.yaml b/drivers/staging/hikey9xx/hisilicon,hi6421-spmi-pmic.yaml new file mode 100644 index 000000000000..80e74c261e05 --- /dev/null +++ b/drivers/staging/hikey9xx/hisilicon,hi6421-spmi-pmic.yaml @@ -0,0 +1,159 @@ +# SPDX-License-Identifier: GPL-2.0 +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mfd/hisilicon,hi6421-spmi-pmic.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: HiSilicon 6421v600 SPMI PMIC + +maintainers: + - Mauro Carvalho Chehab <mchehab+huawei@kernel.org> + +description: | + HiSilicon 6421v600 should be connected inside a MIPI System Power Management + (SPMI) bus. It provides interrupts and power supply. + + The GPIO and interrupt settings are represented as part of the top-level PMIC + node. + + The SPMI controller part is provided by + drivers/staging/hikey9xx/hisilicon,hisi-spmi-controller.yaml. + +properties: + $nodename: + pattern: "pmic@[0-9a-f]" + + compatible: + const: hisilicon,hi6421v600-spmi + + reg: + maxItems: 1 + + '#interrupt-cells': + const: 2 + + interrupt-controller: + description: + Identify that the PMIC is capable of behaving as an interrupt controller. + + gpios: + maxItems: 1 + + regulators: + type: object + + properties: + '#address-cells': + const: 1 + + '#size-cells': + const: 0 + + patternProperties: + '^ldo[0-9]+@[0-9a-f]$': + type: object + + $ref: "/schemas/regulator/regulator.yaml#" + + properties: + reg: + description: Enable register. + + '#address-cells': + const: 1 + + '#size-cells': + const: 0 + + vsel-reg: + description: Voltage selector register. + + enable-mask: + description: Bitmask used to enable the regulator. + + voltage-table: + description: Table with the selector items for the voltage regulator. + minItems: 2 + maxItems: 16 + + off-on-delay-us: + description: Time required for changing state to enabled in microseconds. + + startup-delay-us: + description: Startup time in microseconds. + + idle-mode-mask: + description: Bitmask used to put the regulator on idle mode. + + eco-microamp: + description: Maximum current while on idle mode. + + required: + - reg + - vsel-reg + - enable-mask + - voltage-table + - off-on-delay-us + - startup-delay-us + +required: + - compatible + - reg + - regulators + +examples: + - | + /* pmic properties */ + + pmic: pmic@0 { + compatible = "hisilicon,hi6421-spmi"; + reg = <0 0>; + + #interrupt-cells = <2>; + interrupt-controller; + gpios = <&gpio28 0 0>; + + regulators { + #address-cells = <1>; + #size-cells = <0>; + + ldo3: ldo3@16 { + reg = <0x16>; + vsel-reg = <0x51>; + + regulator-name = "ldo3"; + regulator-min-microvolt = <1500000>; + regulator-max-microvolt = <2000000>; + regulator-boot-on; + + enable-mask = <0x01>; + + voltage-table = <1500000>, <1550000>, <1600000>, <1650000>, + <1700000>, <1725000>, <1750000>, <1775000>, + <1800000>, <1825000>, <1850000>, <1875000>, + <1900000>, <1925000>, <1950000>, <2000000>; + off-on-delay-us = <20000>; + startup-delay-us = <120>; + }; + + ldo4: ldo4@17 { /* 40 PIN */ + reg = <0x17>; + vsel-reg = <0x52>; + + regulator-name = "ldo4"; + regulator-min-microvolt = <1725000>; + regulator-max-microvolt = <1900000>; + regulator-boot-on; + + enable-mask = <0x01>; + idle-mode-mask = <0x10>; + eco-microamp = <10000>; + + hi6421-vsel = <0x52 0x07>; + voltage-table = <1725000>, <1750000>, <1775000>, <1800000>, + <1825000>, <1850000>, <1875000>, <1900000>; + off-on-delay-us = <20000>; + startup-delay-us = <120>; + }; + }; + }; diff --git a/drivers/staging/hikey9xx/hisilicon,hisi-spmi-controller.yaml b/drivers/staging/hikey9xx/hisilicon,hisi-spmi-controller.yaml new file mode 100644 index 000000000000..f2a56fa4e78e --- /dev/null +++ b/drivers/staging/hikey9xx/hisilicon,hisi-spmi-controller.yaml @@ -0,0 +1,62 @@ +# SPDX-License-Identifier: GPL-2.0 +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/spmi/hisilicon,hisi-spmi-controller.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: HiSilicon SPMI controller + +maintainers: + - Mauro Carvalho Chehab <mchehab+huawei@kernel.org> + +description: | + The HiSilicon SPMI BUS controller is found on some Kirin-based designs. + It is a MIPI System Power Management (SPMI) controller. + + The PMIC part is provided by + drivers/staging/hikey9xx/hisilicon,hi6421-spmi-pmic.yaml. + +properties: + $nodename: + pattern: "spmi@[0-9a-f]" + + compatible: + const: hisilicon,kirin970-spmi-controller + + reg: + maxItems: 1 + + spmi-channel: + description: | + number of the Kirin 970 SPMI channel where the SPMI devices are connected. + +required: + - compatible + - reg + - spmi-channel + +patternProperties: + "^pmic@[0-9a-f]$": + description: | + PMIC properties, which are specific to the used SPMI PMIC device(s). + When used in combination with HiSilicon 6421v600, the properties + are documented at + drivers/staging/hikey9xx/hisilicon,hi6421-spmi-pmic.yaml. + +examples: + - | + bus { + #address-cells = <2>; + #size-cells = <2>; + + spmi: spmi@fff24000 { + compatible = "hisilicon,kirin970-spmi-controller"; + status = "ok"; + reg = <0x0 0xfff24000 0x0 0x1000>; + spmi-channel = <2>; + + pmic@0 { + /* pmic properties */ + }; + }; + }; diff --git a/drivers/staging/hikey9xx/phy-hi3670-usb3.c b/drivers/staging/hikey9xx/phy-hi3670-usb3.c new file mode 100644 index 000000000000..4fc013911a78 --- /dev/null +++ b/drivers/staging/hikey9xx/phy-hi3670-usb3.c @@ -0,0 +1,671 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Phy provider for USB 3.1 controller on HiSilicon Kirin970 platform + * + * Copyright (C) 2017-2020 Hilisicon Electronics Co., Ltd. + * http://www.huawei.com + * + * Authors: Yu Chen <chenyu56@huawei.com> + */ + +#include <linux/clk.h> +#include <linux/kernel.h> +#include <linux/mfd/syscon.h> +#include <linux/module.h> +#include <linux/phy/phy.h> +#include <linux/platform_device.h> +#include <linux/regmap.h> + +#define SCTRL_SCDEEPSLEEPED (0x0) +#define USB_CLK_SELECTED BIT(20) + +#define PERI_CRG_PEREN0 (0x00) +#define PERI_CRG_PERDIS0 (0x04) +#define PERI_CRG_PEREN4 (0x40) +#define PERI_CRG_PERDIS4 (0x44) +#define PERI_CRG_PERRSTEN4 (0x90) +#define PERI_CRG_PERRSTDIS4 (0x94) +#define PERI_CRG_ISODIS (0x148) +#define PERI_CRG_PEREN6 (0x410) +#define PERI_CRG_PERDIS6 (0x414) + +#define USB_REFCLK_ISO_EN BIT(25) + +#define GT_CLK_USB2PHY_REF BIT(19) + +#define PCTRL_PERI_CTRL3 (0x10) +#define PCTRL_PERI_CTRL3_MSK_START (16) +#define USB_TCXO_EN BIT(1) + +#define PCTRL_PERI_CTRL24 (0x64) +#define SC_CLK_USB3PHY_3MUX1_SEL BIT(25) + +#define USB3OTG_CTRL0 (0x00) +#define USB3OTG_CTRL3 (0x0C) +#define USB3OTG_CTRL4 (0x10) +#define USB3OTG_CTRL5 (0x14) +#define USB3OTG_CTRL7 (0x1C) +#define USB_MISC_CFG50 (0x50) +#define USB_MISC_CFG54 (0x54) +#define USB_MISC_CFG58 (0x58) +#define USB_MISC_CFG5C (0x5C) +#define USB_MISC_CFGA0 (0xA0) +#define TCA_CLK_RST (0x200) +#define TCA_INTR_EN (0x204) +#define TCA_INTR_STS (0x208) +#define TCA_GCFG (0x210) +#define TCA_TCPC (0x214) +#define TCA_SYSMODE_CFG (0x218) +#define TCA_VBUS_CTRL (0x240) + +#define CTRL0_USB3_VBUSVLD BIT(7) +#define CTRL0_USB3_VBUSVLD_SEL BIT(6) + +#define CTRL3_USB2_VBUSVLDEXT0 BIT(6) +#define CTRL3_USB2_VBUSVLDEXTSEL0 BIT(5) + +#define CTRL5_USB2_SIDDQ BIT(0) + +#define CTRL7_USB2_REFCLKSEL_MASK (3 << 3) +#define CTRL7_USB2_REFCLKSEL_ABB (3 << 3) +#define CTRL7_USB2_REFCLKSEL_PAD (2 << 3) + +#define CFG50_USB3_PHY_TEST_POWERDOWN BIT(23) + +#define CFG54_USB31PHY_CR_ADDR_MASK (0xFFFF) +#define CFG54_USB31PHY_CR_ADDR_SHIFT (16) +#define CFG54_USB3PHY_REF_USE_PAD BIT(12) +#define CFG54_PHY0_PMA_PWR_STABLE BIT(11) +#define CFG54_PHY0_PCS_PWR_STABLE BIT(9) +#define CFG54_USB31PHY_CR_ACK BIT(7) +#define CFG54_USB31PHY_CR_WR_EN BIT(5) +#define CFG54_USB31PHY_CR_SEL BIT(4) +#define CFG54_USB31PHY_CR_RD_EN BIT(3) +#define CFG54_USB31PHY_CR_CLK BIT(2) +#define CFG54_USB3_PHY0_ANA_PWR_EN BIT(1) + +#define CFG58_USB31PHY_CR_DATA_MASK (0xFFFF) +#define CFG58_USB31PHY_CR_DATA_RD_START (16) + +#define CFG5C_USB3_PHY0_SS_MPLLA_SSC_EN BIT(1) + +#define CFGA0_VAUX_RESET BIT(9) +#define CFGA0_USB31C_RESET BIT(8) +#define CFGA0_USB2PHY_REFCLK_SELECT BIT(4) +#define CFGA0_USB3PHY_RESET BIT(1) +#define CFGA0_USB2PHY_POR BIT(0) + +#define INTR_EN_XA_TIMEOUT_EVT_EN BIT(1) +#define INTR_EN_XA_ACK_EVT_EN BIT(0) + +#define CLK_RST_TCA_REF_CLK_EN BIT(1) +#define CLK_RST_SUSPEND_CLK_EN BIT(0) + +#define GCFG_ROLE_HSTDEV BIT(4) +#define GCFG_OP_MODE (3 << 0) +#define GCFG_OP_MODE_CTRL_SYNC_MODE BIT(0) + +#define TCPC_VALID BIT(4) +#define TCPC_LOW_POWER_EN BIT(3) +#define TCPC_MUX_CONTROL_MASK (3 << 0) +#define TCPC_MUX_CONTROL_USB31 BIT(0) + +#define SYSMODE_CFG_TYPEC_DISABLE BIT(3) + +#define VBUS_CTRL_POWERPRESENT_OVERRD (3 << 2) +#define VBUS_CTRL_VBUSVALID_OVERRD (3 << 0) + +#define KIRIN970_USB_DEFAULT_PHY_PARAM (0xFDFEE4) +#define KIRIN970_USB_DEFAULT_PHY_VBOOST (0x5) + +#define TX_VBOOST_LVL_REG (0xf) +#define TX_VBOOST_LVL_START (6) +#define TX_VBOOST_LVL_ENABLE BIT(9) + +struct hi3670_priv { + struct device *dev; + struct regmap *peri_crg; + struct regmap *pctrl; + struct regmap *sctrl; + struct regmap *usb31misc; + + u32 eye_diagram_param; + u32 tx_vboost_lvl; + + u32 peri_crg_offset; + u32 pctrl_offset; + u32 usb31misc_offset; +}; + +static int hi3670_phy_cr_clk(struct regmap *usb31misc) +{ + int ret; + + /* Clock up */ + ret = regmap_update_bits(usb31misc, USB_MISC_CFG54, + CFG54_USB31PHY_CR_CLK, CFG54_USB31PHY_CR_CLK); + if (ret) + return ret; + + /* Clock down */ + ret = regmap_update_bits(usb31misc, USB_MISC_CFG54, + CFG54_USB31PHY_CR_CLK, 0); + + return ret; +} + +static int hi3670_phy_cr_set_sel(struct regmap *usb31misc) +{ + return regmap_update_bits(usb31misc, USB_MISC_CFG54, + CFG54_USB31PHY_CR_SEL, CFG54_USB31PHY_CR_SEL); +} + +static int hi3670_phy_cr_start(struct regmap *usb31misc, int direction) +{ + int ret; + + if (direction) + ret = regmap_update_bits(usb31misc, USB_MISC_CFG54, + CFG54_USB31PHY_CR_WR_EN, + CFG54_USB31PHY_CR_WR_EN); + else + ret = regmap_update_bits(usb31misc, USB_MISC_CFG54, + CFG54_USB31PHY_CR_RD_EN, + CFG54_USB31PHY_CR_RD_EN); + + if (ret) + return ret; + + ret = hi3670_phy_cr_clk(usb31misc); + if (ret) + return ret; + + ret = regmap_update_bits(usb31misc, USB_MISC_CFG54, + CFG54_USB31PHY_CR_RD_EN | CFG54_USB31PHY_CR_WR_EN, 0); + + return ret; +} + +static int hi3670_phy_cr_wait_ack(struct regmap *usb31misc) +{ + u32 reg; + int retry = 100000; + int ret; + + while (retry-- > 0) { + ret = regmap_read(usb31misc, USB_MISC_CFG54, ®); + if (ret) + return ret; + if ((reg & CFG54_USB31PHY_CR_ACK) == CFG54_USB31PHY_CR_ACK) + return 0; + + ret = hi3670_phy_cr_clk(usb31misc); + if (ret) + return ret; + } + + return -ETIMEDOUT; +} + +static int hi3670_phy_cr_set_addr(struct regmap *usb31misc, u32 addr) +{ + u32 reg; + int ret; + + ret = regmap_read(usb31misc, USB_MISC_CFG54, ®); + if (ret) + return ret; + + reg &= ~(CFG54_USB31PHY_CR_ADDR_MASK << CFG54_USB31PHY_CR_ADDR_SHIFT); + reg |= ((addr & CFG54_USB31PHY_CR_ADDR_MASK) << CFG54_USB31PHY_CR_ADDR_SHIFT); + ret = regmap_write(usb31misc, USB_MISC_CFG54, reg); + + return ret; +} + +static int hi3670_phy_cr_read(struct regmap *usb31misc, u32 addr, u32 *val) +{ + int reg; + int i; + int ret; + + for (i = 0; i < 100; i++) { + ret = hi3670_phy_cr_clk(usb31misc); + if (ret) + return ret; + } + + ret = hi3670_phy_cr_set_sel(usb31misc); + if (ret) + return ret; + + ret = hi3670_phy_cr_set_addr(usb31misc, addr); + if (ret) + return ret; + + ret = hi3670_phy_cr_start(usb31misc, 0); + if (ret) + return ret; + + ret = hi3670_phy_cr_wait_ack(usb31misc); + if (ret) + return ret; + + ret = regmap_read(usb31misc, USB_MISC_CFG58, ®); + if (ret) + return ret; + + *val = (reg >> CFG58_USB31PHY_CR_DATA_RD_START) & + CFG58_USB31PHY_CR_DATA_MASK; + + return 0; +} + +static int hi3670_phy_cr_write(struct regmap *usb31misc, u32 addr, u32 val) +{ + int i; + int ret; + + for (i = 0; i < 100; i++) { + ret = hi3670_phy_cr_clk(usb31misc); + if (ret) + return ret; + } + + ret = hi3670_phy_cr_set_sel(usb31misc); + if (ret) + return ret; + + ret = hi3670_phy_cr_set_addr(usb31misc, addr); + if (ret) + return ret; + + ret = regmap_write(usb31misc, USB_MISC_CFG58, + val & CFG58_USB31PHY_CR_DATA_MASK); + if (ret) + return ret; + + ret = hi3670_phy_cr_start(usb31misc, 1); + if (ret) + return ret; + + ret = hi3670_phy_cr_wait_ack(usb31misc); + + return ret; +} + +static int hi3670_phy_set_params(struct hi3670_priv *priv) +{ + u32 reg; + int ret; + int retry = 3; + + ret = regmap_write(priv->usb31misc, USB3OTG_CTRL4, + priv->eye_diagram_param); + if (ret) { + dev_err(priv->dev, "set USB3OTG_CTRL4 failed\n"); + return ret; + } + + while (retry-- > 0) { + ret = hi3670_phy_cr_read(priv->usb31misc, + TX_VBOOST_LVL_REG, ®); + if (!ret) + break; + + if (ret != -ETIMEDOUT) { + dev_err(priv->dev, "read TX_VBOOST_LVL_REG failed\n"); + return ret; + } + } + if (ret) + return ret; + + reg |= (TX_VBOOST_LVL_ENABLE | (priv->tx_vboost_lvl << TX_VBOOST_LVL_START)); + ret = hi3670_phy_cr_write(priv->usb31misc, TX_VBOOST_LVL_REG, reg); + if (ret) + dev_err(priv->dev, "write TX_VBOOST_LVL_REG failed\n"); + + return ret; +} + +static int hi3670_is_abbclk_seleted(struct hi3670_priv *priv) +{ + u32 reg; + + if (!priv->sctrl) { + dev_err(priv->dev, "priv->sctrl is null!\n"); + return 1; + } + + if (regmap_read(priv->sctrl, SCTRL_SCDEEPSLEEPED, ®)) { + dev_err(priv->dev, "SCTRL_SCDEEPSLEEPED read failed!\n"); + return 1; + } + + if ((reg & USB_CLK_SELECTED) == 0) + return 1; + + return 0; +} + +static int hi3670_config_phy_clock(struct hi3670_priv *priv) +{ + u32 val, mask; + int ret; + + if (hi3670_is_abbclk_seleted(priv)) { + /* usb refclk iso disable */ + ret = regmap_write(priv->peri_crg, PERI_CRG_ISODIS, + USB_REFCLK_ISO_EN); + if (ret) + goto out; + + /* enable usb_tcxo_en */ + ret = regmap_write(priv->pctrl, PCTRL_PERI_CTRL3, + USB_TCXO_EN | + (USB_TCXO_EN << PCTRL_PERI_CTRL3_MSK_START)); + + /* select usbphy clk from abb */ + mask = SC_CLK_USB3PHY_3MUX1_SEL; + ret = regmap_update_bits(priv->pctrl, + PCTRL_PERI_CTRL24, mask, 0); + if (ret) + goto out; + + ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFGA0, + CFGA0_USB2PHY_REFCLK_SELECT, 0); + if (ret) + goto out; + + ret = regmap_read(priv->usb31misc, USB3OTG_CTRL7, &val); + if (ret) + goto out; + val &= ~CTRL7_USB2_REFCLKSEL_MASK; + val |= CTRL7_USB2_REFCLKSEL_ABB; + ret = regmap_write(priv->usb31misc, USB3OTG_CTRL7, val); + if (ret) + goto out; + + return 0; + } + + ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFG54, + CFG54_USB3PHY_REF_USE_PAD, + CFG54_USB3PHY_REF_USE_PAD); + if (ret) + goto out; + + ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFGA0, + CFGA0_USB2PHY_REFCLK_SELECT, + CFGA0_USB2PHY_REFCLK_SELECT); + if (ret) + goto out; + + ret = regmap_read(priv->usb31misc, USB3OTG_CTRL7, &val); + if (ret) + goto out; + val &= ~CTRL7_USB2_REFCLKSEL_MASK; + val |= CTRL7_USB2_REFCLKSEL_PAD; + ret = regmap_write(priv->usb31misc, USB3OTG_CTRL7, val); + if (ret) + goto out; + + ret = regmap_write(priv->peri_crg, + PERI_CRG_PEREN6, GT_CLK_USB2PHY_REF); + if (ret) + goto out; + + return 0; +out: + dev_err(priv->dev, "failed to config phy clock ret: %d\n", ret); + return ret; +} + +static int hi3670_config_tca(struct hi3670_priv *priv) +{ + u32 val, mask; + int ret; + + ret = regmap_write(priv->usb31misc, TCA_INTR_STS, 0xffff); + if (ret) + goto out; + + ret = regmap_write(priv->usb31misc, TCA_INTR_EN, + INTR_EN_XA_TIMEOUT_EVT_EN | INTR_EN_XA_ACK_EVT_EN); + if (ret) + goto out; + + mask = CLK_RST_TCA_REF_CLK_EN | CLK_RST_SUSPEND_CLK_EN; + ret = regmap_update_bits(priv->usb31misc, TCA_CLK_RST, mask, 0); + if (ret) + goto out; + + ret = regmap_update_bits(priv->usb31misc, TCA_GCFG, + GCFG_ROLE_HSTDEV | GCFG_OP_MODE, + GCFG_ROLE_HSTDEV | GCFG_OP_MODE_CTRL_SYNC_MODE); + if (ret) + goto out; + + ret = regmap_update_bits(priv->usb31misc, TCA_SYSMODE_CFG, + SYSMODE_CFG_TYPEC_DISABLE, 0); + if (ret) + goto out; + + ret = regmap_read(priv->usb31misc, TCA_TCPC, &val); + if (ret) + goto out; + val &= ~(TCPC_VALID | TCPC_LOW_POWER_EN | TCPC_MUX_CONTROL_MASK); + val |= (TCPC_VALID | TCPC_MUX_CONTROL_USB31); + ret = regmap_write(priv->usb31misc, TCA_TCPC, val); + if (ret) + goto out; + + ret = regmap_write(priv->usb31misc, TCA_VBUS_CTRL, + VBUS_CTRL_POWERPRESENT_OVERRD | VBUS_CTRL_VBUSVALID_OVERRD); + if (ret) + goto out; + + return 0; +out: + dev_err(priv->dev, "failed to config phy clock ret: %d\n", ret); + return ret; +} + +static int hi3670_phy_init(struct phy *phy) +{ + struct hi3670_priv *priv = phy_get_drvdata(phy); + u32 val; + int ret; + + /* assert controller */ + val = CFGA0_VAUX_RESET | CFGA0_USB31C_RESET | + CFGA0_USB3PHY_RESET | CFGA0_USB2PHY_POR; + ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFGA0, val, 0); + if (ret) + goto out; + + ret = hi3670_config_phy_clock(priv); + if (ret) + goto out; + + /* Exit from IDDQ mode */ + ret = regmap_update_bits(priv->usb31misc, USB3OTG_CTRL5, + CTRL5_USB2_SIDDQ, 0); + if (ret) + goto out; + + /* Release USB31 PHY out of TestPowerDown mode */ + ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFG50, + CFG50_USB3_PHY_TEST_POWERDOWN, 0); + if (ret) + goto out; + + /* Deassert phy */ + val = CFGA0_USB3PHY_RESET | CFGA0_USB2PHY_POR; + ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFGA0, val, val); + if (ret) + goto out; + + usleep_range(100, 120); + + /* Tell the PHY power is stable */ + val = CFG54_USB3_PHY0_ANA_PWR_EN | CFG54_PHY0_PCS_PWR_STABLE | + CFG54_PHY0_PMA_PWR_STABLE; + ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFG54, + val, val); + if (ret) + goto out; + + ret = hi3670_config_tca(priv); + if (ret) + goto out; + + /* Enable SSC */ + ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFG5C, + CFG5C_USB3_PHY0_SS_MPLLA_SSC_EN, + CFG5C_USB3_PHY0_SS_MPLLA_SSC_EN); + if (ret) + goto out; + + /* Deassert controller */ + val = CFGA0_VAUX_RESET | CFGA0_USB31C_RESET; + ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFGA0, val, val); + if (ret) + goto out; + + usleep_range(100, 120); + + /* Set fake vbus valid signal */ + val = CTRL0_USB3_VBUSVLD | CTRL0_USB3_VBUSVLD_SEL; + ret = regmap_update_bits(priv->usb31misc, USB3OTG_CTRL0, val, val); + if (ret) + goto out; + + val = CTRL3_USB2_VBUSVLDEXT0 | CTRL3_USB2_VBUSVLDEXTSEL0; + ret = regmap_update_bits(priv->usb31misc, USB3OTG_CTRL3, val, val); + if (ret) + goto out; + + usleep_range(100, 120); + + ret = hi3670_phy_set_params(priv); + if (ret) + goto out; + + return 0; +out: + dev_err(priv->dev, "failed to init phy ret: %d\n", ret); + return ret; +} + +static int hi3670_phy_exit(struct phy *phy) +{ + struct hi3670_priv *priv = phy_get_drvdata(phy); + u32 mask; + int ret; + + /* Assert phy */ + mask = CFGA0_USB3PHY_RESET | CFGA0_USB2PHY_POR; + ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFGA0, mask, 0); + if (ret) + goto out; + + if (hi3670_is_abbclk_seleted(priv)) { + /* disable usb_tcxo_en */ + ret = regmap_write(priv->pctrl, PCTRL_PERI_CTRL3, + USB_TCXO_EN << PCTRL_PERI_CTRL3_MSK_START); + } else { + ret = regmap_write(priv->peri_crg, PERI_CRG_PERDIS6, + GT_CLK_USB2PHY_REF); + if (ret) + goto out; + } + + return 0; +out: + dev_err(priv->dev, "failed to exit phy ret: %d\n", ret); + return ret; +} + +static struct phy_ops hi3670_phy_ops = { + .init = hi3670_phy_init, + .exit = hi3670_phy_exit, + .owner = THIS_MODULE, +}; + +static int hi3670_phy_probe(struct platform_device *pdev) +{ + struct phy_provider *phy_provider; + struct device *dev = &pdev->dev; + struct phy *phy; + struct hi3670_priv *priv; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->dev = dev; + priv->peri_crg = syscon_regmap_lookup_by_phandle(dev->of_node, + "hisilicon,pericrg-syscon"); + if (IS_ERR(priv->peri_crg)) { + dev_err(dev, "no hisilicon,pericrg-syscon\n"); + return PTR_ERR(priv->peri_crg); + } + + priv->pctrl = syscon_regmap_lookup_by_phandle(dev->of_node, + "hisilicon,pctrl-syscon"); + if (IS_ERR(priv->pctrl)) { + dev_err(dev, "no hisilicon,pctrl-syscon\n"); + return PTR_ERR(priv->pctrl); + } + + priv->sctrl = syscon_regmap_lookup_by_phandle(dev->of_node, + "hisilicon,sctrl-syscon"); + if (IS_ERR(priv->sctrl)) { + dev_err(dev, "no hisilicon,sctrl-syscon\n"); + return PTR_ERR(priv->sctrl); + } + + /* node of hi3670 phy is a sub-node of usb3_otg_bc */ + priv->usb31misc = syscon_node_to_regmap(dev->parent->of_node); + if (IS_ERR(priv->usb31misc)) { + dev_err(dev, "no hisilicon,usb3-otg-bc-syscon\n"); + return PTR_ERR(priv->usb31misc); + } + + if (of_property_read_u32(dev->of_node, "hisilicon,eye-diagram-param", + &priv->eye_diagram_param)) + priv->eye_diagram_param = KIRIN970_USB_DEFAULT_PHY_PARAM; + + if (of_property_read_u32(dev->of_node, "hisilicon,tx-vboost-lvl", + &priv->tx_vboost_lvl)) + priv->tx_vboost_lvl = KIRIN970_USB_DEFAULT_PHY_VBOOST; + + phy = devm_phy_create(dev, NULL, &hi3670_phy_ops); + if (IS_ERR(phy)) + return PTR_ERR(phy); + + phy_set_drvdata(phy, priv); + phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); + return PTR_ERR_OR_ZERO(phy_provider); +} + +static const struct of_device_id hi3670_phy_of_match[] = { + { .compatible = "hisilicon,hi3670-usb-phy" }, + { }, +}; +MODULE_DEVICE_TABLE(of, hi3670_phy_of_match); + +static struct platform_driver hi3670_phy_driver = { + .probe = hi3670_phy_probe, + .driver = { + .name = "hi3670-usb-phy", + .of_match_table = hi3670_phy_of_match, + } +}; +module_platform_driver(hi3670_phy_driver); + +MODULE_AUTHOR("Yu Chen <chenyu56@huawei.com>"); +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("Hilisicon Kirin970 USB31 PHY Driver"); diff --git a/drivers/staging/hikey9xx/phy-hi3670-usb3.yaml b/drivers/staging/hikey9xx/phy-hi3670-usb3.yaml new file mode 100644 index 000000000000..125a5d6546ae --- /dev/null +++ b/drivers/staging/hikey9xx/phy-hi3670-usb3.yaml @@ -0,0 +1,72 @@ +# SPDX-License-Identifier: GPL-2.0 +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/phy/hisilicon,hi3670-usb3.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Hisilicon Kirin970 USB PHY + +maintainers: + - Mauro Carvalho Chehab <mchehab+huawei@kernel.org> +description: |+ + Bindings for USB3 PHY on HiSilicon Kirin 970. + +properties: + compatible: + const: hisilicon,hi3670-usb-phy + + "#phy-cells": + const: 0 + + hisilicon,pericrg-syscon: + $ref: '/schemas/types.yaml#/definitions/phandle' + description: phandle of syscon used to control iso refclk. + + hisilicon,pctrl-syscon: + $ref: '/schemas/types.yaml#/definitions/phandle' + description: phandle of syscon used to control usb tcxo. + + hisilicon,sctrl-syscon: + $ref: '/schemas/types.yaml#/definitions/phandle' + description: phandle of syscon used to control phy deep sleep. + + hisilicon,eye-diagram-param: + $ref: /schemas/types.yaml#/definitions/uint32 + description: Eye diagram for phy. + + hisilicon,tx-vboost-lvl: + $ref: /schemas/types.yaml#/definitions/uint32 + description: TX level vboost for phy. + +required: + - compatible + - hisilicon,pericrg-syscon + - hisilicon,pctrl-syscon + - hisilicon,sctrl-syscon + - hisilicon,eye-diagram-param + - hisilicon,tx-vboost-lvl + - "#phy-cells" + +additionalProperties: false + +examples: + - | + bus { + #address-cells = <2>; + #size-cells = <2>; + + usb3_otg_bc: usb3_otg_bc@ff200000 { + compatible = "syscon", "simple-mfd"; + reg = <0x0 0xff200000 0x0 0x1000>; + + usb_phy { + compatible = "hisilicon,hi3670-usb-phy"; + #phy-cells = <0>; + hisilicon,pericrg-syscon = <&crg_ctrl>; + hisilicon,pctrl-syscon = <&pctrl>; + hisilicon,sctrl-syscon = <&sctrl>; + hisilicon,eye-diagram-param = <0xfdfee4>; + hisilicon,tx-vboost-lvl = <0x5>; + }; + }; + }; diff --git a/drivers/staging/iio/Documentation/dac/max517 b/drivers/staging/iio/Documentation/dac/max517 deleted file mode 100644 index e60ec2f91a7a..000000000000 --- a/drivers/staging/iio/Documentation/dac/max517 +++ /dev/null @@ -1,41 +0,0 @@ -Kernel driver max517 -==================== - -Supported chips: - * Maxim MAX517, MAX518, MAX519 - Prefix: 'max517' - Datasheet: Publicly available at the Maxim website - http://www.maxim-ic.com/ - -Author: - Roland Stigge <stigge@antcom.de> - -Description ------------ - -The Maxim MAX517/518/519 is an 8-bit DAC on the I2C bus. The following table -shows the different feature sets of the variants MAX517, MAX518 and MAX519: - -Feature MAX517 MAX518 MAX519 --------------------------------------------------------------------------- -One output channel X -Two output channels X X -Simultaneous output updates X X -Supply voltage as reference X -Separate reference input X -Reference input for each DAC X - -Via the iio sysfs interface, there are three attributes available: out1_raw, -out2_raw and out12_raw. With out1_raw and out2_raw, the current output values -(0..255) of the DACs can be written to the device. out12_raw can be used to set -both output channel values simultaneously. - -With MAX517, only out1_raw is available. - -Via out1_scale (and where appropriate, out2_scale), the current scaling factor -in mV can be read. - -When the operating system goes to a power down state, the Power Down function -of the chip is activated, reducing the supply current to 4uA. - -On power-up, the device is in 0V-output state. diff --git a/drivers/staging/iio/Documentation/device.txt b/drivers/staging/iio/Documentation/device.txt deleted file mode 100644 index 0d1275b1eb3f..000000000000 --- a/drivers/staging/iio/Documentation/device.txt +++ /dev/null @@ -1,74 +0,0 @@ -IIO Device drivers - -This is not intended to provide a comprehensive guide to writing an -IIO device driver. For further information see the drivers within the -subsystem. - -The crucial structure for device drivers in iio is iio_dev. - -First allocate one using: - -struct iio_dev *indio_dev = iio_device_alloc(parent, sizeof(struct chip_state)); -where chip_state is a structure of local state data for this instance of -the chip. - -That data can be accessed using iio_priv(struct iio_dev *). - -Then fill in the following: - -- indio_dev->name - Name of the device being driven - made available as the name - attribute in sysfs. - -- indio_dev->info - pointer to a structure with elements that tend to be fixed for - large sets of different parts supported by a given driver. - This contains: - * info->event_attrs: - Attributes used to enable / disable hardware events. - * info->attrs: - General device attributes. Typically used for the weird - and the wonderful bits not covered by the channel specification. - * info->read_raw: - Raw data reading function. Used for both raw channel access - and for associate parameters such as offsets and scales. - * info->write_raw: - Raw value writing function. Used for writable device values such - as DAC values and calibbias. - * info->read_event_config: - Typically only set if there are some interrupt lines. This - is used to read if an on sensor event detector is enabled. - * info->write_event_config: - Enable / disable an on sensor event detector. - * info->read_event_value: - Read value associated with on sensor event detectors. Note that - the meaning of the returned value is dependent on the event - type. - * info->write_event_value: - Write the value associated with on sensor event detectors. E.g. - a threshold above which an interrupt occurs. Note that the - meaning of the value to be set is event type dependent. - -- indio_dev->modes: - Specify whether direct access and / or ring buffer access is supported. -- indio_dev->buffer: - An optional associated buffer. -- indio_dev->pollfunc: - Poll function related elements. This controls what occurs when a trigger - to which this device is attached sends an event. -- indio_dev->channels: - Specification of device channels. Most attributes etc. are built - from this spec. -- indio_dev->num_channels: - How many channels are there? - -Once these are set up, a call to iio_device_register(indio_dev) -will register the device with the iio core. - -Worth noting here is that, if a ring buffer is to be used, it can be -allocated prior to registering the device with the iio-core, but must -be registered afterwards (otherwise the whole parentage of devices -gets confused) - -On remove, iio_device_unregister(indio_dev) will remove the device from -the core, and iio_device_free(indio_dev) will clean up. diff --git a/drivers/staging/iio/Documentation/overview.txt b/drivers/staging/iio/Documentation/overview.txt deleted file mode 100644 index ebdc64f451d7..000000000000 --- a/drivers/staging/iio/Documentation/overview.txt +++ /dev/null @@ -1,57 +0,0 @@ -Overview of IIO - -The Industrial I/O subsystem is intended to provide support for devices -that in some sense are analog to digital converters (ADCs). As many -actual devices combine some ADCs with digital to analog converters -(DACs) that functionality is also supported. - -The aim is to fill the gap between the somewhat similar hwmon and -input subsystems. Hwmon is very much directed at low sample rate -sensors used in applications such as fan speed control and temperature -measurement. Input is, as its name suggests focused on input -devices. In some cases there is considerable overlap between these and -IIO. - -A typical device falling into this category would be connected via SPI -or I2C. - -Functionality of IIO - -* Basic device registration and handling. This is very similar to -hwmon with simple polled access to device channels via sysfs. - -* Event chrdevs. These are similar to input in that they provide a -route to user space for hardware triggered events. Such events include -threshold detectors, free-fall detectors and more complex action -detection. The events themselves are currently very simple with -merely an event code and a timestamp. Any data associated with the -event must be accessed via polling. - -Note: A given device may have one or more event channel. These events are -turned on or off (if possible) via sysfs interfaces. - -* Hardware buffer support. Some recent sensors have included -fifo / ring buffers on the sensor chip. These greatly reduce the load -on the host CPU by buffering relatively large numbers of data samples -based on an internal sampling clock. Examples include VTI SCA3000 -series and Analog Devices ADXL345 accelerometers. Each buffer supports -polling to establish when data is available. - -* Trigger and software buffer support. In many data analysis -applications it it useful to be able to capture data based on some -external signal (trigger). These triggers might be a data ready -signal, a gpio line connected to some external system or an on -processor periodic interrupt. A single trigger may initialize data -capture or reading from a number of sensors. These triggers are -used in IIO to fill software buffers acting in a very similar -fashion to the hardware buffers described above. - -Other documentation: - -device.txt - elements of a typical device driver. - -trigger.txt - elements of a typical trigger driver. - -ring.txt - additional elements required for buffer support. - -sysfs-bus-iio - abi documentation file. diff --git a/drivers/staging/iio/Documentation/ring.txt b/drivers/staging/iio/Documentation/ring.txt deleted file mode 100644 index 18718fcaf259..000000000000 --- a/drivers/staging/iio/Documentation/ring.txt +++ /dev/null @@ -1,47 +0,0 @@ -Buffer support within IIO - -This document is intended as a general overview of the functionality -a buffer may supply and how it is specified within IIO. For more -specific information on a given buffer implementation, see the -comments in the source code. Note that some drivers allow buffer -implementation to be selected at compile time via Kconfig options. - -A given buffer implementation typically embeds a struct -iio_ring_buffer and it is a pointer to this that is provided to the -IIO core. Access to the embedding structure is typically done via -container_of functions. - -struct iio_ring_buffer contains a struct iio_ring_setup_ops *setup_ops -which in turn contains the 4 function pointers -(preenable, postenable, predisable and postdisable). -These are used to perform device specific steps on either side -of the core changing its current mode to indicate that the buffer -is enabled or disabled (along with enabling triggering etc. as appropriate). - -Also in struct iio_ring_buffer is a struct iio_ring_access_funcs. -The function pointers within here are used to allow the core to handle -as much buffer functionality as possible. Note almost all of these -are optional. - -store_to - If possible, push data to the buffer. - -read_last - If possible, get the most recent scan from the buffer (without removal). - This provides polling like functionality whilst the ring buffering is in - use without a separate read from the device. - -rip_first_n - The primary buffer reading function. Note that it may well not return - as much data as requested. - -request_update - If parameters have changed that require reinitialization or configuration of - the buffer this will trigger it. - -set_bytes_per_datum - Set the number of bytes for a complete scan. (All samples + timestamp) - -set_length - Set the number of complete scans that may be held by the buffer. - diff --git a/drivers/staging/iio/Documentation/sysfs-bus-iio-light b/drivers/staging/iio/Documentation/sysfs-bus-iio-light deleted file mode 100644 index 7c7cd8456060..000000000000 --- a/drivers/staging/iio/Documentation/sysfs-bus-iio-light +++ /dev/null @@ -1,79 +0,0 @@ -What: /sys/bus/iio/devices/device[n]/in_illuminance0[_input|_raw] -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - This should return the calculated lux from the light sensor. If - it comes back in SI units, it should also include _input else it - should include _raw to signify it is not in SI units. - -What: /sys/.../device[n]/proximity_on_chip_ambient_infrared_suppression -KernelVersion: 2.6.37 -Contact: linux-iio@vger.kernel.org -Description: - Hardware dependent mode for an ALS device to calculate the value - in proximity mode. When this is enabled, then the device should - use a infrared sensor reading to remove infrared noise from the - proximity reading. If this is not enabled, the driver can still - do this calculation manually by reading the infrared sensor - value and doing the negation in sw. - -What: /sys/bus/iio/devices/device[n]/in_proximity[_input|_raw] -KernelVersion: 2.6.37 -Contact: linux-iio@vger.kernel.org -Description: - This property is supported by proximity sensors and should be - used to return the value of a reading by the sensor. If this - value is returned in SI units, it should also include _input - but if it is not, then it should include _raw. - -What: /sys/bus/iio/devices/device[n]/intensity_infrared[_input|_raw] -KernelVersion: 2.6.37 -Contact: linux-iio@vger.kernel.org -Description: - This property is supported by sensors that have an infrared - sensing mode. This value should be the output from a reading - and if expressed in SI units, should include _input. If this - value is not in SI units, then it should include _raw. - -What: /sys/bus/iio/devices/device[n]/in_illuminance0_target -KernelVersion: 2.6.37 -Contact: linux-iio@vger.kernel.org -Description: - This property gets/sets the last known external - lux measurement used in/for calibration. - -What: /sys/bus/iio/devices/device[n]/in_illuminance0_integration_time -KernelVersion: 2.6.37 -Contact: linux-iio@vger.kernel.org -Description: - This property gets/sets the sensors ADC analog integration time. - -What: /sys/bus/iio/devices/device[n]/in_illuminance0_lux_table -KernelVersion: 2.6.37 -Contact: linux-iio@vger.kernel.org -Description: - This property gets/sets the table of coefficients - used in calculating illuminance in lux. - -What: /sys/bus/iio/devices/device[n]/in_intensity_clear[_input|_raw] -What: /sys/bus/iio/devices/device[n]/in_intensity_red[_input|_raw] -What: /sys/bus/iio/devices/device[n]/in_intensity_green[_input|_raw] -What: /sys/bus/iio/devices/device[n]/in_intensity_blue[_input|_raw] -KernelVersion: 3.6.0 -Contact: linux-iio@vger.kernel.org -Description: - This property is supported by sensors that have a RGBC - sensing mode. This value should be the output from a reading - and if expressed in SI units, should include _input. If this - value is not in SI units (irradiance, uW/mm^2), then it should - include _raw. - -What: /sys/bus/iio/devices/device[n]/in_cct0[_input|_raw] -KernelVersion: 3.6.0 -Contact: linux-iio@vger.kernel.org -Description: - This should return the correlated color temperature from the - light sensor. If it comes back in SI units, it should also - include _input else it should include _raw to signify it is not - in SI units. - diff --git a/drivers/staging/iio/Documentation/trigger.txt b/drivers/staging/iio/Documentation/trigger.txt deleted file mode 100644 index 299a1add98bf..000000000000 --- a/drivers/staging/iio/Documentation/trigger.txt +++ /dev/null @@ -1,31 +0,0 @@ -IIO trigger drivers. - -Many triggers are provided by hardware that will also be registered as -an IIO device. Whilst this can create device specific complexities -such triggers are registered with the core in the same way as -stand-alone triggers. - -struct iio_trig *trig = iio_trigger_alloc("<trigger format string>", ...); - -allocates a trigger structure. The key elements to then fill in within -a driver are: - -trig->set_trigger_state: - Function that enables / disables the underlying source of the trigger. - -There is also a -trig->alloc_list which is useful for drivers that allocate multiple -triggers to keep track of what they have created. - -When these have been set call: - -iio_trigger_register(trig); - -to register the trigger with the core, making it available to trigger -consumers. - -Trigger Consumers - -Currently triggers are only used for the filling of software -buffers and as such any device supporting INDIO_BUFFER_TRIGGERED has the -consumer interface automatically created. diff --git a/drivers/staging/iio/accel/adis16203.c b/drivers/staging/iio/accel/adis16203.c index c7798908ef0e..b68304da288b 100644 --- a/drivers/staging/iio/accel/adis16203.c +++ b/drivers/staging/iio/accel/adis16203.c @@ -286,35 +286,16 @@ static int adis16203_probe(struct spi_device *spi) if (ret) return ret; - ret = adis_setup_buffer_and_trigger(st, indio_dev, NULL); + ret = devm_adis_setup_buffer_and_trigger(st, indio_dev, NULL); if (ret) return ret; /* Get the device into a sane initial state */ ret = adis_initial_startup(st); if (ret) - goto error_cleanup_buffer_trigger; - - ret = iio_device_register(indio_dev); - if (ret) - goto error_cleanup_buffer_trigger; - - return 0; - -error_cleanup_buffer_trigger: - adis_cleanup_buffer_and_trigger(st, indio_dev); - return ret; -} - -static int adis16203_remove(struct spi_device *spi) -{ - struct iio_dev *indio_dev = spi_get_drvdata(spi); - struct adis *st = iio_priv(indio_dev); - - iio_device_unregister(indio_dev); - adis_cleanup_buffer_and_trigger(st, indio_dev); + return ret; - return 0; + return devm_iio_device_register(&spi->dev, indio_dev); } static const struct of_device_id adis16203_of_match[] = { @@ -330,7 +311,6 @@ static struct spi_driver adis16203_driver = { .of_match_table = adis16203_of_match, }, .probe = adis16203_probe, - .remove = adis16203_remove, }; module_spi_driver(adis16203_driver); diff --git a/drivers/staging/iio/accel/adis16240.c b/drivers/staging/iio/accel/adis16240.c index 38ec40b458c9..5064adce5f58 100644 --- a/drivers/staging/iio/accel/adis16240.c +++ b/drivers/staging/iio/accel/adis16240.c @@ -415,35 +415,17 @@ static int adis16240_probe(struct spi_device *spi) ret = adis_init(st, indio_dev, spi, &adis16240_data); if (ret) return ret; - ret = adis_setup_buffer_and_trigger(st, indio_dev, NULL); + ret = devm_adis_setup_buffer_and_trigger(st, indio_dev, NULL); if (ret) return ret; /* Get the device into a sane initial state */ ret = adis_initial_startup(st); if (ret) - goto error_cleanup_buffer_trigger; - ret = iio_device_register(indio_dev); - if (ret) - goto error_cleanup_buffer_trigger; - return 0; - -error_cleanup_buffer_trigger: - adis_cleanup_buffer_and_trigger(st, indio_dev); - return ret; -} - -static int adis16240_remove(struct spi_device *spi) -{ - struct iio_dev *indio_dev = spi_get_drvdata(spi); - struct adis *st = iio_priv(indio_dev); - - iio_device_unregister(indio_dev); - adis_cleanup_buffer_and_trigger(st, indio_dev); + return ret; - return 0; + return devm_iio_device_register(&spi->dev, indio_dev); } - static const struct of_device_id adis16240_of_match[] = { { .compatible = "adi,adis16240" }, { }, @@ -456,7 +438,6 @@ static struct spi_driver adis16240_driver = { .of_match_table = adis16240_of_match, }, .probe = adis16240_probe, - .remove = adis16240_remove, }; module_spi_driver(adis16240_driver); diff --git a/drivers/staging/iio/frequency/ad9834.c b/drivers/staging/iio/frequency/ad9834.c index 77f77a2b2e05..262c3590e64e 100644 --- a/drivers/staging/iio/frequency/ad9834.c +++ b/drivers/staging/iio/frequency/ad9834.c @@ -397,7 +397,6 @@ static int ad9834_probe(struct spi_device *spi) struct regulator *reg; int ret; - reg = devm_regulator_get(&spi->dev, "avdd"); if (IS_ERR(reg)) return PTR_ERR(reg); diff --git a/drivers/staging/kpc2000/kpc_dma/fileops.c b/drivers/staging/kpc2000/kpc_dma/fileops.c index dd716edd9b1b..e1c7c04f16fe 100644 --- a/drivers/staging/kpc2000/kpc_dma/fileops.c +++ b/drivers/staging/kpc2000/kpc_dma/fileops.c @@ -53,7 +53,7 @@ static int kpc_dma_transfer(struct dev_private_data *priv, acd = kzalloc(sizeof(*acd), GFP_KERNEL); if (!acd) { - dev_err(&priv->ldev->pldev->dev, "Couldn't kmalloc space for for the aio data\n"); + dev_err(&priv->ldev->pldev->dev, "Couldn't kmalloc space for the aio data\n"); return -ENOMEM; } memset(acd, 0x66, sizeof(struct aio_cb_data)); @@ -69,7 +69,7 @@ static int kpc_dma_transfer(struct dev_private_data *priv, acd->user_pages = kcalloc(acd->page_count, sizeof(struct page *), GFP_KERNEL); if (!acd->user_pages) { - dev_err(&priv->ldev->pldev->dev, "Couldn't kmalloc space for for the page pointers\n"); + dev_err(&priv->ldev->pldev->dev, "Couldn't kmalloc space for the page pointers\n"); rv = -ENOMEM; goto err_alloc_userpages; } diff --git a/drivers/staging/ks7010/ks7010_sdio.c b/drivers/staging/ks7010/ks7010_sdio.c index 6b2660c94f4e..78dc8beeae98 100644 --- a/drivers/staging/ks7010/ks7010_sdio.c +++ b/drivers/staging/ks7010/ks7010_sdio.c @@ -405,9 +405,9 @@ int ks_wlan_hw_tx(struct ks_wlan_private *priv, void *p, unsigned long size, return result; } -static void rx_event_task(unsigned long dev) +static void rx_event_task(struct tasklet_struct *t) { - struct ks_wlan_private *priv = (struct ks_wlan_private *)dev; + struct ks_wlan_private *priv = from_tasklet(priv, t, rx_bh_task); struct rx_device_buffer *rp; if (rxq_has_space(priv) && priv->dev_state >= DEVICE_STATE_BOOT) { @@ -618,7 +618,7 @@ static int trx_device_init(struct ks_wlan_private *priv) spin_lock_init(&priv->tx_dev.tx_dev_lock); spin_lock_init(&priv->rx_dev.rx_dev_lock); - tasklet_init(&priv->rx_bh_task, rx_event_task, (unsigned long)priv); + tasklet_setup(&priv->rx_bh_task, rx_event_task); return 0; } diff --git a/drivers/staging/ks7010/ks_hostif.c b/drivers/staging/ks7010/ks_hostif.c index eaaf6a5440a9..8bc3b7d8d3d5 100644 --- a/drivers/staging/ks7010/ks_hostif.c +++ b/drivers/staging/ks7010/ks_hostif.c @@ -2205,9 +2205,9 @@ static void hostif_sme_execute(struct ks_wlan_private *priv, int event) } static -void hostif_sme_task(unsigned long dev) +void hostif_sme_task(struct tasklet_struct *t) { - struct ks_wlan_private *priv = (struct ks_wlan_private *)dev; + struct ks_wlan_private *priv = from_tasklet(priv, t, sme_task); if (priv->dev_state < DEVICE_STATE_BOOT) return; @@ -2258,7 +2258,7 @@ static inline void hostif_sme_init(struct ks_wlan_private *priv) priv->sme_i.qtail = 0; spin_lock_init(&priv->sme_i.sme_spin); priv->sme_i.sme_flag = 0; - tasklet_init(&priv->sme_task, hostif_sme_task, (unsigned long)priv); + tasklet_setup(&priv->sme_task, hostif_sme_task); } static inline void hostif_wpa_init(struct ks_wlan_private *priv) diff --git a/drivers/staging/media/atomisp/i2c/atomisp-lm3554.c b/drivers/staging/media/atomisp/i2c/atomisp-lm3554.c index 809010af7855..7ca7378b1859 100644 --- a/drivers/staging/media/atomisp/i2c/atomisp-lm3554.c +++ b/drivers/staging/media/atomisp/i2c/atomisp-lm3554.c @@ -19,14 +19,13 @@ #include <linux/i2c.h> #include <linux/mutex.h> #include <linux/delay.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/slab.h> #include "../include/media/lm3554.h" #include <media/v4l2-ctrls.h> #include <media/v4l2-device.h> #include <linux/acpi.h> -#include <linux/gpio/consumer.h> #include "../include/linux/atomisp_gmin_platform.h" #include "../include/linux/atomisp.h" @@ -173,7 +172,7 @@ static void lm3554_flash_off_delay(struct timer_list *t) struct lm3554 *flash = from_timer(flash, t, flash_off_delay); struct lm3554_platform_data *pdata = flash->pdata; - gpio_set_value(pdata->gpio_strobe, 0); + gpiod_set_value(pdata->gpio_strobe, 0); } static int lm3554_hw_strobe(struct i2c_client *client, bool strobe) @@ -209,7 +208,7 @@ static int lm3554_hw_strobe(struct i2c_client *client, bool strobe) * so must strobe off here */ if (timer_pending) - gpio_set_value(pdata->gpio_strobe, 0); + gpiod_set_value(pdata->gpio_strobe, 0); /* Restore flash current settings */ ret = lm3554_set_flash(flash); @@ -217,7 +216,7 @@ static int lm3554_hw_strobe(struct i2c_client *client, bool strobe) goto err; /* Strobe on Flash */ - gpio_set_value(pdata->gpio_strobe, 1); + gpiod_set_value(pdata->gpio_strobe, 1); return 0; err: @@ -627,7 +626,7 @@ static int __lm3554_s_power(struct lm3554 *flash, int power) int ret; /*initialize flash driver*/ - gpio_set_value(pdata->gpio_reset, power); + gpiod_set_value(pdata->gpio_reset, power); usleep_range(100, 100 + 1); if (power) { @@ -766,33 +765,22 @@ static int lm3554_gpio_init(struct i2c_client *client) struct lm3554_platform_data *pdata = flash->pdata; int ret; - if (!gpio_is_valid(pdata->gpio_reset)) + if (!pdata->gpio_reset) return -EINVAL; - ret = gpio_direction_output(pdata->gpio_reset, 0); + ret = gpiod_direction_output(pdata->gpio_reset, 0); if (ret < 0) - goto err_gpio_reset; + return ret; dev_info(&client->dev, "flash led reset successfully\n"); - if (!gpio_is_valid(pdata->gpio_strobe)) { - ret = -EINVAL; - goto err_gpio_dir_reset; - } + if (!pdata->gpio_strobe) + return -EINVAL; - ret = gpio_direction_output(pdata->gpio_strobe, 0); + ret = gpiod_direction_output(pdata->gpio_strobe, 0); if (ret < 0) - goto err_gpio_strobe; + return ret; return 0; - -err_gpio_strobe: - gpio_free(pdata->gpio_strobe); -err_gpio_dir_reset: - gpio_direction_output(pdata->gpio_reset, 0); -err_gpio_reset: - gpio_free(pdata->gpio_reset); - - return ret; } static int lm3554_gpio_uninit(struct i2c_client *client) @@ -802,16 +790,14 @@ static int lm3554_gpio_uninit(struct i2c_client *client) struct lm3554_platform_data *pdata = flash->pdata; int ret; - ret = gpio_direction_output(pdata->gpio_strobe, 0); + ret = gpiod_direction_output(pdata->gpio_strobe, 0); if (ret < 0) return ret; - ret = gpio_direction_output(pdata->gpio_reset, 0); + ret = gpiod_direction_output(pdata->gpio_reset, 0); if (ret < 0) return ret; - gpio_free(pdata->gpio_strobe); - gpio_free(pdata->gpio_reset); return 0; } @@ -819,18 +805,18 @@ static void *lm3554_platform_data_func(struct i2c_client *client) { static struct lm3554_platform_data platform_data; - platform_data.gpio_reset = - desc_to_gpio(gpiod_get_index(&client->dev, - NULL, 2, GPIOD_OUT_LOW)); - platform_data.gpio_strobe = - desc_to_gpio(gpiod_get_index(&client->dev, - NULL, 0, GPIOD_OUT_LOW)); - platform_data.gpio_torch = - desc_to_gpio(gpiod_get_index(&client->dev, - NULL, 1, GPIOD_OUT_LOW)); - dev_info(&client->dev, "camera pdata: lm3554: reset: %d strobe %d torch %d\n", - platform_data.gpio_reset, platform_data.gpio_strobe, - platform_data.gpio_torch); + platform_data.gpio_reset = gpiod_get_index(&client->dev, + NULL, 2, GPIOD_OUT_LOW); + if (IS_ERR(platform_data.gpio_reset)) + return ERR_CAST(platform_data.gpio_reset); + platform_data.gpio_strobe = gpiod_get_index(&client->dev, + NULL, 0, GPIOD_OUT_LOW); + if (IS_ERR(platform_data.gpio_strobe)) + return ERR_CAST(platform_data.gpio_strobe); + platform_data.gpio_torch = gpiod_get_index(&client->dev, + NULL, 1, GPIOD_OUT_LOW); + if (IS_ERR(platform_data.gpio_torch)) + return ERR_CAST(platform_data.gpio_torch); /* Set to TX2 mode, then ENVM/TX2 pin is a power amplifier sync input: * ENVM/TX pin asserted, flash forced into torch; @@ -857,6 +843,8 @@ static int lm3554_probe(struct i2c_client *client) return -ENOMEM; flash->pdata = lm3554_platform_data_func(client); + if (IS_ERR(flash->pdata)) + return PTR_ERR(flash->pdata); v4l2_i2c_subdev_init(&flash->sd, client, &lm3554_ops); flash->sd.internal_ops = &lm3554_internal_ops; diff --git a/drivers/staging/media/atomisp/include/media/lm3554.h b/drivers/staging/media/atomisp/include/media/lm3554.h index 812ce74f0635..711b7d7c9950 100644 --- a/drivers/staging/media/atomisp/include/media/lm3554.h +++ b/drivers/staging/media/atomisp/include/media/lm3554.h @@ -18,6 +18,7 @@ #ifndef _LM3554_H_ #define _LM3554_H_ +#include <linux/gpio/consumer.h> #include <linux/videodev2.h> #include <media/v4l2-subdev.h> @@ -119,9 +120,9 @@ * lm3554_platform_data - Flash controller platform data */ struct lm3554_platform_data { - int gpio_torch; - int gpio_strobe; - int gpio_reset; + struct gpio_desc *gpio_torch; + struct gpio_desc *gpio_strobe; + struct gpio_desc *gpio_reset; unsigned int current_limit; unsigned int envm_tx2; diff --git a/drivers/staging/media/tegra-vde/iommu.c b/drivers/staging/media/tegra-vde/iommu.c index 6af863d92123..adf8dc7ee25c 100644 --- a/drivers/staging/media/tegra-vde/iommu.c +++ b/drivers/staging/media/tegra-vde/iommu.c @@ -36,8 +36,8 @@ int tegra_vde_iommu_map(struct tegra_vde *vde, addr = iova_dma_addr(&vde->iova, iova); - size = iommu_map_sg(vde->domain, addr, sgt->sgl, sgt->nents, - IOMMU_READ | IOMMU_WRITE); + size = iommu_map_sgtable(vde->domain, addr, sgt, + IOMMU_READ | IOMMU_WRITE); if (!size) { __free_iova(&vde->iova, iova); return -ENXIO; diff --git a/drivers/staging/most/Kconfig b/drivers/staging/most/Kconfig index c35fb34fae79..535e6dec3504 100644 --- a/drivers/staging/most/Kconfig +++ b/drivers/staging/most/Kconfig @@ -18,8 +18,6 @@ menuconfig MOST_COMPONENTS if MOST_COMPONENTS -source "drivers/staging/most/cdev/Kconfig" - source "drivers/staging/most/net/Kconfig" source "drivers/staging/most/sound/Kconfig" diff --git a/drivers/staging/most/Makefile b/drivers/staging/most/Makefile index 7c10b84ebac0..be94673209f5 100644 --- a/drivers/staging/most/Makefile +++ b/drivers/staging/most/Makefile @@ -1,6 +1,5 @@ # SPDX-License-Identifier: GPL-2.0 -obj-$(CONFIG_MOST_CDEV) += cdev/ obj-$(CONFIG_MOST_NET) += net/ obj-$(CONFIG_MOST_SOUND) += sound/ obj-$(CONFIG_MOST_VIDEO) += video/ diff --git a/drivers/staging/most/cdev/Kconfig b/drivers/staging/most/cdev/Kconfig deleted file mode 100644 index dab99477858e..000000000000 --- a/drivers/staging/most/cdev/Kconfig +++ /dev/null @@ -1,13 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -# -# MOST Cdev configuration -# - -config MOST_CDEV - tristate "Cdev" - - help - Say Y here if you want to commumicate via character devices. - - To compile this driver as a module, choose M here: the - module will be called most_cdev. diff --git a/drivers/staging/most/cdev/Makefile b/drivers/staging/most/cdev/Makefile deleted file mode 100644 index ef90cd71994a..000000000000 --- a/drivers/staging/most/cdev/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -obj-$(CONFIG_MOST_CDEV) += most_cdev.o - -most_cdev-objs := cdev.o diff --git a/drivers/staging/most/dim2/dim2.c b/drivers/staging/most/dim2/dim2.c index 509c8012d20b..b34e3c130f53 100644 --- a/drivers/staging/most/dim2/dim2.c +++ b/drivers/staging/most/dim2/dim2.c @@ -100,12 +100,12 @@ struct dim2_hdm { struct medialb_bus bus; void (*on_netinfo)(struct most_interface *most_iface, unsigned char link_state, unsigned char *addrs); - void (*disable_platform)(struct platform_device *); + void (*disable_platform)(struct platform_device *pdev); }; struct dim2_platform_data { - int (*enable)(struct platform_device *); - void (*disable)(struct platform_device *); + int (*enable)(struct platform_device *pdev); + void (*disable)(struct platform_device *pdev); }; #define iface_to_hdm(iface) container_of(iface, struct dim2_hdm, most_iface) diff --git a/drivers/staging/mt7621-dma/mtk-hsdma.c b/drivers/staging/mt7621-dma/mtk-hsdma.c index 14592ed9ce98..354536783e1c 100644 --- a/drivers/staging/mt7621-dma/mtk-hsdma.c +++ b/drivers/staging/mt7621-dma/mtk-hsdma.c @@ -533,9 +533,9 @@ static void mtk_hsdma_rx(struct mtk_hsdam_engine *hsdma) mtk_hsdma_chan_done(hsdma, chan); } -static void mtk_hsdma_tasklet(unsigned long arg) +static void mtk_hsdma_tasklet(struct tasklet_struct *t) { - struct mtk_hsdam_engine *hsdma = (struct mtk_hsdam_engine *)arg; + struct mtk_hsdam_engine *hsdma = from_tasklet(hsdma, t, task); mtk_hsdma_rx(hsdma); mtk_hsdma_tx(hsdma); @@ -670,7 +670,7 @@ static int mtk_hsdma_probe(struct platform_device *pdev) if (IS_ERR(base)) return PTR_ERR(base); hsdma->base = base + HSDMA_BASE_OFFSET; - tasklet_init(&hsdma->task, mtk_hsdma_tasklet, (unsigned long)hsdma); + tasklet_setup(&hsdma->task, mtk_hsdma_tasklet); irq = platform_get_irq(pdev, 0); if (irq < 0) diff --git a/drivers/staging/mt7621-pci/TODO b/drivers/staging/mt7621-pci/TODO index ccfd266db4ca..d674a9ac85c1 100644 --- a/drivers/staging/mt7621-pci/TODO +++ b/drivers/staging/mt7621-pci/TODO @@ -1,4 +1,4 @@ - general code review and cleanup -Cc: NeilBrown <neil@brown.name> +Cc: NeilBrown <neil@brown.name> diff --git a/drivers/staging/nvec/nvec.c b/drivers/staging/nvec/nvec.c index 360ec0407740..a80996b2f5ce 100644 --- a/drivers/staging/nvec/nvec.c +++ b/drivers/staging/nvec/nvec.c @@ -289,7 +289,7 @@ EXPORT_SYMBOL(nvec_write_async); * interrupt handlers. * * Returns: 0 on success, a negative error code on failure. - * The response message is returned in @msg. Shall be freed with + * The response message is returned in @msg. Shall be freed * with nvec_msg_free() once no longer used. * */ diff --git a/drivers/staging/octeon-usb/octeon-hcd.c b/drivers/staging/octeon-usb/octeon-hcd.c index 61471a19d4e6..e2f8b6b67f75 100644 --- a/drivers/staging/octeon-usb/octeon-hcd.c +++ b/drivers/staging/octeon-usb/octeon-hcd.c @@ -1233,8 +1233,7 @@ static int cvmx_usb_fill_tx_hw(struct octeon_hcd *usb, cvmx_write64_uint32(csr_address, *ptr++); cvmx_write64_uint32(csr_address, *ptr++); cvmx_write64_uint32(csr_address, *ptr++); - cvmx_read64_uint64( - CVMX_USBNX_DMA0_INB_CHN0(usb->index)); + cvmx_read64_uint64(CVMX_USBNX_DMA0_INB_CHN0(usb->index)); words -= 3; } cvmx_write64_uint32(csr_address, *ptr++); diff --git a/drivers/staging/pi433/pi433_if.h b/drivers/staging/pi433/pi433_if.h index 16c5b7fba249..d5c1521192c1 100644 --- a/drivers/staging/pi433/pi433_if.h +++ b/drivers/staging/pi433/pi433_if.h @@ -117,9 +117,15 @@ struct pi433_rx_cfg { /* packet format */ enum option_on_off enable_sync; - enum option_on_off enable_length_byte; /* should be used in combination with sync, only */ - enum address_filtering enable_address_filtering; /* operational with sync, only */ - enum option_on_off enable_crc; /* only operational, if sync on and fixed length or length byte is used */ + + /* should be used in combination with sync, only */ + enum option_on_off enable_length_byte; + + /* operational with sync, only */ + enum address_filtering enable_address_filtering; + + /* only operational, if sync on and fixed length or length byte is used */ + enum option_on_off enable_crc; __u8 sync_length; __u8 fixed_message_length; @@ -130,12 +136,16 @@ struct pi433_rx_cfg { __u8 broadcast_address; }; -#define PI433_IOC_MAGIC 'r' +#define PI433_IOC_MAGIC 'r' -#define PI433_IOC_RD_TX_CFG _IOR(PI433_IOC_MAGIC, PI433_TX_CFG_IOCTL_NR, char[sizeof(struct pi433_tx_cfg)]) -#define PI433_IOC_WR_TX_CFG _IOW(PI433_IOC_MAGIC, PI433_TX_CFG_IOCTL_NR, char[sizeof(struct pi433_tx_cfg)]) +#define PI433_IOC_RD_TX_CFG \ + _IOR(PI433_IOC_MAGIC, PI433_TX_CFG_IOCTL_NR, char[sizeof(struct pi433_tx_cfg)]) +#define PI433_IOC_WR_TX_CFG \ + _IOW(PI433_IOC_MAGIC, PI433_TX_CFG_IOCTL_NR, char[sizeof(struct pi433_tx_cfg)]) -#define PI433_IOC_RD_RX_CFG _IOR(PI433_IOC_MAGIC, PI433_RX_CFG_IOCTL_NR, char[sizeof(struct pi433_rx_cfg)]) -#define PI433_IOC_WR_RX_CFG _IOW(PI433_IOC_MAGIC, PI433_RX_CFG_IOCTL_NR, char[sizeof(struct pi433_rx_cfg)]) +#define PI433_IOC_RD_RX_CFG \ + _IOR(PI433_IOC_MAGIC, PI433_RX_CFG_IOCTL_NR, char[sizeof(struct pi433_rx_cfg)]) +#define PI433_IOC_WR_RX_CFG \ + _IOW(PI433_IOC_MAGIC, PI433_RX_CFG_IOCTL_NR, char[sizeof(struct pi433_rx_cfg)]) #endif /* PI433_H */ diff --git a/drivers/staging/qlge/qlge.h b/drivers/staging/qlge/qlge.h index 48f346503979..b295990e361b 100644 --- a/drivers/staging/qlge/qlge.h +++ b/drivers/staging/qlge/qlge.h @@ -2337,21 +2337,21 @@ void ql_dump_hw_cb(struct ql_adapter *qdev, int size, u32 bit, u16 q_id); #endif #ifdef QL_OB_DUMP -void ql_dump_tx_desc(struct tx_buf_desc *tbd); -void ql_dump_ob_mac_iocb(struct ob_mac_iocb_req *ob_mac_iocb); -void ql_dump_ob_mac_rsp(struct ob_mac_iocb_rsp *ob_mac_rsp); -#define QL_DUMP_OB_MAC_IOCB(ob_mac_iocb) ql_dump_ob_mac_iocb(ob_mac_iocb) -#define QL_DUMP_OB_MAC_RSP(ob_mac_rsp) ql_dump_ob_mac_rsp(ob_mac_rsp) +void ql_dump_tx_desc(struct ql_adapter *qdev, struct tx_buf_desc *tbd); +void ql_dump_ob_mac_iocb(struct ql_adapter *qdev, struct ob_mac_iocb_req *ob_mac_iocb); +void ql_dump_ob_mac_rsp(struct ql_adapter *qdev, struct ob_mac_iocb_rsp *ob_mac_rsp); +#define QL_DUMP_OB_MAC_IOCB(qdev, ob_mac_iocb) ql_dump_ob_mac_iocb(qdev, ob_mac_iocb) +#define QL_DUMP_OB_MAC_RSP(qdev, ob_mac_rsp) ql_dump_ob_mac_rsp(qdev, ob_mac_rsp) #else -#define QL_DUMP_OB_MAC_IOCB(ob_mac_iocb) -#define QL_DUMP_OB_MAC_RSP(ob_mac_rsp) +#define QL_DUMP_OB_MAC_IOCB(qdev, ob_mac_iocb) +#define QL_DUMP_OB_MAC_RSP(qdev, ob_mac_rsp) #endif #ifdef QL_IB_DUMP -void ql_dump_ib_mac_rsp(struct ib_mac_iocb_rsp *ib_mac_rsp); -#define QL_DUMP_IB_MAC_RSP(ib_mac_rsp) ql_dump_ib_mac_rsp(ib_mac_rsp) +void ql_dump_ib_mac_rsp(struct ql_adapter *qdev, struct ib_mac_iocb_rsp *ib_mac_rsp); +#define QL_DUMP_IB_MAC_RSP(qdev, ib_mac_rsp) ql_dump_ib_mac_rsp(qdev, ib_mac_rsp) #else -#define QL_DUMP_IB_MAC_RSP(ib_mac_rsp) +#define QL_DUMP_IB_MAC_RSP(qdev, ib_mac_rsp) #endif #ifdef QL_ALL_DUMP diff --git a/drivers/staging/qlge/qlge_dbg.c b/drivers/staging/qlge/qlge_dbg.c index a55bf0b3e9dc..42fd13990f3a 100644 --- a/drivers/staging/qlge/qlge_dbg.c +++ b/drivers/staging/qlge/qlge_dbg.c @@ -1431,7 +1431,7 @@ void ql_dump_routing_entries(struct ql_adapter *qdev) } if (value) netdev_err(qdev->ndev, - "%s: Routing Mask %d = 0x%.08x\n", + "Routing Mask %d = 0x%.08x\n", i, value); } ql_sem_unlock(qdev, SEM_RT_IDX_MASK); @@ -1617,6 +1617,9 @@ void ql_dump_qdev(struct ql_adapter *qdev) #ifdef QL_CB_DUMP void ql_dump_wqicb(struct wqicb *wqicb) { + struct tx_ring *tx_ring = container_of(wqicb, struct tx_ring, wqicb); + struct ql_adapter *qdev = tx_ring->qdev; + netdev_err(qdev->ndev, "Dumping wqicb stuff...\n"); netdev_err(qdev->ndev, "wqicb->len = 0x%x\n", le16_to_cpu(wqicb->len)); netdev_err(qdev->ndev, "wqicb->flags = %x\n", @@ -1632,8 +1635,8 @@ void ql_dump_wqicb(struct wqicb *wqicb) void ql_dump_tx_ring(struct tx_ring *tx_ring) { - if (!tx_ring) - return; + struct ql_adapter *qdev = tx_ring->qdev; + netdev_err(qdev->ndev, "===================== Dumping tx_ring %d ===============\n", tx_ring->wq_id); netdev_err(qdev->ndev, "tx_ring->base = %p\n", tx_ring->wq_base); @@ -1657,6 +1660,8 @@ void ql_dump_tx_ring(struct tx_ring *tx_ring) void ql_dump_ricb(struct ricb *ricb) { int i; + struct ql_adapter *qdev = + container_of(ricb, struct ql_adapter, ricb); netdev_err(qdev->ndev, "===================== Dumping ricb ===============\n"); netdev_err(qdev->ndev, "Dumping ricb stuff...\n"); @@ -1686,6 +1691,9 @@ void ql_dump_ricb(struct ricb *ricb) void ql_dump_cqicb(struct cqicb *cqicb) { + struct rx_ring *rx_ring = container_of(cqicb, struct rx_ring, cqicb); + struct ql_adapter *qdev = rx_ring->qdev; + netdev_err(qdev->ndev, "Dumping cqicb stuff...\n"); netdev_err(qdev->ndev, "cqicb->msix_vect = %d\n", cqicb->msix_vect); @@ -1725,8 +1733,8 @@ static const char *qlge_rx_ring_type_name(struct rx_ring *rx_ring) void ql_dump_rx_ring(struct rx_ring *rx_ring) { - if (!rx_ring) - return; + struct ql_adapter *qdev = rx_ring->qdev; + netdev_err(qdev->ndev, "===================== Dumping rx_ring %d ===============\n", rx_ring->cq_id); @@ -1816,7 +1824,7 @@ fail_it: #endif #ifdef QL_OB_DUMP -void ql_dump_tx_desc(struct tx_buf_desc *tbd) +void ql_dump_tx_desc(struct ql_adapter *qdev, struct tx_buf_desc *tbd) { netdev_err(qdev->ndev, "tbd->addr = 0x%llx\n", le64_to_cpu((u64)tbd->addr)); @@ -1843,7 +1851,7 @@ void ql_dump_tx_desc(struct tx_buf_desc *tbd) tbd->len & TX_DESC_E ? "E" : "."); } -void ql_dump_ob_mac_iocb(struct ob_mac_iocb_req *ob_mac_iocb) +void ql_dump_ob_mac_iocb(struct ql_adapter *qdev, struct ob_mac_iocb_req *ob_mac_iocb) { struct ob_mac_tso_iocb_req *ob_mac_tso_iocb = (struct ob_mac_tso_iocb_req *)ob_mac_iocb; @@ -1886,10 +1894,10 @@ void ql_dump_ob_mac_iocb(struct ob_mac_iocb_req *ob_mac_iocb) frame_len = le16_to_cpu(ob_mac_iocb->frame_len); } tbd = &ob_mac_iocb->tbd[0]; - ql_dump_tx_desc(tbd); + ql_dump_tx_desc(qdev, tbd); } -void ql_dump_ob_mac_rsp(struct ob_mac_iocb_rsp *ob_mac_rsp) +void ql_dump_ob_mac_rsp(struct ql_adapter *qdev, struct ob_mac_iocb_rsp *ob_mac_rsp) { netdev_err(qdev->ndev, "%s\n", __func__); netdev_err(qdev->ndev, "opcode = %d\n", ob_mac_rsp->opcode); @@ -1906,7 +1914,7 @@ void ql_dump_ob_mac_rsp(struct ob_mac_iocb_rsp *ob_mac_rsp) #endif #ifdef QL_IB_DUMP -void ql_dump_ib_mac_rsp(struct ib_mac_iocb_rsp *ib_mac_rsp) +void ql_dump_ib_mac_rsp(struct ql_adapter *qdev, struct ib_mac_iocb_rsp *ib_mac_rsp) { netdev_err(qdev->ndev, "%s\n", __func__); netdev_err(qdev->ndev, "opcode = 0x%x\n", ib_mac_rsp->opcode); diff --git a/drivers/staging/qlge/qlge_main.c b/drivers/staging/qlge/qlge_main.c index 96f8356c4c1a..27da386f9d87 100644 --- a/drivers/staging/qlge/qlge_main.c +++ b/drivers/staging/qlge/qlge_main.c @@ -1856,7 +1856,7 @@ static void ql_process_mac_split_rx_intr(struct ql_adapter *qdev, struct net_device *ndev = qdev->ndev; struct sk_buff *skb = NULL; - QL_DUMP_IB_MAC_RSP(ib_mac_rsp); + QL_DUMP_IB_MAC_RSP(qdev, ib_mac_rsp); skb = ql_build_rx_skb(qdev, rx_ring, ib_mac_rsp); if (unlikely(!skb)) { @@ -1954,7 +1954,7 @@ static unsigned long ql_process_mac_rx_intr(struct ql_adapter *qdev, ((le16_to_cpu(ib_mac_rsp->vlan_id) & IB_MAC_IOCB_RSP_VLAN_MASK)) : 0xffff; - QL_DUMP_IB_MAC_RSP(ib_mac_rsp); + QL_DUMP_IB_MAC_RSP(qdev, ib_mac_rsp); if (ib_mac_rsp->flags4 & IB_MAC_IOCB_RSP_HV) { /* The data and headers are split into @@ -2001,7 +2001,7 @@ static void ql_process_mac_tx_intr(struct ql_adapter *qdev, struct tx_ring *tx_ring; struct tx_ring_desc *tx_ring_desc; - QL_DUMP_OB_MAC_RSP(mac_rsp); + QL_DUMP_OB_MAC_RSP(qdev, mac_rsp); tx_ring = &qdev->tx_ring[mac_rsp->txq_idx]; tx_ring_desc = &tx_ring->q[mac_rsp->tid]; ql_unmap_send(qdev, tx_ring_desc, tx_ring_desc->map_cnt); @@ -2079,9 +2079,9 @@ static void ql_process_chip_ae_intr(struct ql_adapter *qdev, break; case PCI_ERR_ANON_BUF_RD: - netdev_err(qdev->ndev, "PCI error occurred when reading " - "anonymous buffers from rx_ring %d.\n", - ib_ae_rsp->q_id); + netdev_err(qdev->ndev, + "PCI error occurred when reading anonymous buffers from rx_ring %d.\n", + ib_ae_rsp->q_id); ql_queue_asic_error(qdev); break; @@ -2415,8 +2415,7 @@ static irqreturn_t qlge_isr(int irq, void *dev_id) ql_queue_asic_error(qdev); netdev_err(qdev->ndev, "Got fatal error, STS = %x.\n", var); var = ql_read32(qdev, ERR_STS); - netdev_err(qdev->ndev, "Resetting chip. " - "Error Status Register = 0x%x\n", var); + netdev_err(qdev->ndev, "Resetting chip. Error Status Register = 0x%x\n", var); return IRQ_HANDLED; } @@ -2593,7 +2592,7 @@ static netdev_tx_t qlge_send(struct sk_buff *skb, struct net_device *ndev) tx_ring->tx_errors++; return NETDEV_TX_BUSY; } - QL_DUMP_OB_MAC_IOCB(mac_iocb_ptr); + QL_DUMP_OB_MAC_IOCB(qdev, mac_iocb_ptr); tx_ring->prod_idx++; if (tx_ring->prod_idx == tx_ring->wq_len) tx_ring->prod_idx = 0; @@ -3739,8 +3738,7 @@ static void ql_display_dev_info(struct net_device *ndev) struct ql_adapter *qdev = netdev_priv(ndev); netif_info(qdev, probe, qdev->ndev, - "Function #%d, Port %d, NIC Roll %d, NIC Rev = %d, " - "XG Roll = %d, XG Rev = %d.\n", + "Function #%d, Port %d, NIC Roll %d, NIC Rev = %d, XG Roll = %d, XG Rev = %d.\n", qdev->func, qdev->port, qdev->chip_rev_id & 0x0000000f, diff --git a/drivers/staging/qlge/qlge_mpi.c b/drivers/staging/qlge/qlge_mpi.c index e85c6ab538df..143a886080c5 100644 --- a/drivers/staging/qlge/qlge_mpi.c +++ b/drivers/staging/qlge/qlge_mpi.c @@ -117,7 +117,6 @@ int ql_own_firmware(struct ql_adapter *qdev) return 1; return 0; - } static int ql_get_mb_sts(struct ql_adapter *qdev, struct mbox_params *mbcp) @@ -240,12 +239,12 @@ static int ql_idc_cmplt_aen(struct ql_adapter *qdev) netif_err(qdev, drv, qdev->ndev, "Could not read MPI, resetting RISC!\n"); ql_queue_fw_error(qdev); - } else + } else { /* Wake up the sleeping mpi_idc_work thread that is * waiting for this event. */ complete(&qdev->ide_completion); - + } return status; } @@ -347,16 +346,15 @@ static int ql_aen_lost(struct ql_adapter *qdev, struct mbox_params *mbcp) mbcp->out_count = 6; status = ql_get_mb_sts(qdev, mbcp); - if (status) + if (status) { netif_err(qdev, drv, qdev->ndev, "Lost AEN broken!\n"); - else { + } else { int i; netif_err(qdev, drv, qdev->ndev, "Lost AEN detected.\n"); for (i = 0; i < mbcp->out_count; i++) netif_err(qdev, drv, qdev->ndev, "mbox_out[%d] = 0x%.08x.\n", i, mbcp->mbox_out[i]); - } return status; @@ -405,7 +403,6 @@ static int ql_mpi_handler(struct ql_adapter *qdev, struct mbox_params *mbcp) } switch (mbcp->mbox_out[0]) { - /* This case is only active when we arrive here * as a result of issuing a mailbox command to * the firmware. @@ -998,9 +995,9 @@ int ql_mb_get_led_cfg(struct ql_adapter *qdev) netif_err(qdev, drv, qdev->ndev, "Failed to get LED Configuration.\n"); status = -EIO; - } else + } else { qdev->led_config = mbcp->mbox_out[1]; - + } return status; } diff --git a/drivers/staging/ralink-gdma/ralink-gdma.c b/drivers/staging/ralink-gdma/ralink-gdma.c index eabf1093328e..655df317d0ee 100644 --- a/drivers/staging/ralink-gdma/ralink-gdma.c +++ b/drivers/staging/ralink-gdma/ralink-gdma.c @@ -701,9 +701,9 @@ static void gdma_dma_desc_free(struct virt_dma_desc *vdesc) kfree(container_of(vdesc, struct gdma_dma_desc, vdesc)); } -static void gdma_dma_tasklet(unsigned long arg) +static void gdma_dma_tasklet(struct tasklet_struct *t) { - struct gdma_dma_dev *dma_dev = (struct gdma_dma_dev *)arg; + struct gdma_dma_dev *dma_dev = from_tasklet(dma_dev, t, task); struct gdma_dmaengine_chan *chan; static unsigned int last_chan; unsigned int i, chan_mask; @@ -821,7 +821,7 @@ static int gdma_dma_probe(struct platform_device *pdev) if (IS_ERR(base)) return PTR_ERR(base); dma_dev->base = base; - tasklet_init(&dma_dev->task, gdma_dma_tasklet, (unsigned long)dma_dev); + tasklet_setup(&dma_dev->task, gdma_dma_tasklet); irq = platform_get_irq(pdev, 0); if (irq < 0) diff --git a/drivers/staging/rtl8188eu/core/rtw_ap.c b/drivers/staging/rtl8188eu/core/rtw_ap.c index 41535441f82c..2078d87055bf 100644 --- a/drivers/staging/rtl8188eu/core/rtw_ap.c +++ b/drivers/staging/rtl8188eu/core/rtw_ap.c @@ -422,7 +422,7 @@ static void update_bmc_sta(struct adapter *padapter) int i, supportRateNum = 0; unsigned int tx_ra_bitmap = 0; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct wlan_bssid_ex *pcur_network = (struct wlan_bssid_ex *)&pmlmepriv->cur_network.network; + struct wlan_bssid_ex *pcur_network = &pmlmepriv->cur_network.network; struct sta_info *psta = rtw_get_bcmc_stainfo(padapter); if (psta) { @@ -599,7 +599,7 @@ static void start_bss_network(struct adapter *padapter, u8 *pbuf) struct registry_priv *pregpriv = &padapter->registrypriv; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct security_priv *psecuritypriv = &padapter->securitypriv; - struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)&pmlmepriv->cur_network.network; + struct wlan_bssid_ex *pnetwork = &pmlmepriv->cur_network.network; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; struct wlan_bssid_ex *pnetwork_mlmeext = &pmlmeinfo->network; @@ -711,7 +711,7 @@ static void start_bss_network(struct adapter *padapter, u8 *pbuf) update_wireless_mode(padapter); /* update capability after cur_wireless_mode updated */ - update_capinfo(padapter, rtw_get_capability((struct wlan_bssid_ex *)pnetwork)); + update_capinfo(padapter, rtw_get_capability(pnetwork)); /* let pnetwork_mlmeext == pnetwork_mlme. */ memcpy(pnetwork_mlmeext, pnetwork, pnetwork->Length); @@ -745,7 +745,7 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf, int len) struct registry_priv *pregistrypriv = &padapter->registrypriv; struct security_priv *psecuritypriv = &padapter->securitypriv; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct wlan_bssid_ex *pbss_network = (struct wlan_bssid_ex *)&pmlmepriv->cur_network.network; + struct wlan_bssid_ex *pbss_network = &pmlmepriv->cur_network.network; u8 *ie = pbss_network->ies; /* SSID */ @@ -982,7 +982,7 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf, int len) HT_info_handler(padapter, (struct ndis_802_11_var_ie *)pHT_info_ie); } - pbss_network->Length = get_wlan_bssid_ex_sz((struct wlan_bssid_ex *)pbss_network); + pbss_network->Length = get_wlan_bssid_ex_sz(pbss_network); /* issue beacon to start bss network */ start_bss_network(padapter, (u8 *)pbss_network); diff --git a/drivers/staging/rtl8188eu/core/rtw_cmd.c b/drivers/staging/rtl8188eu/core/rtw_cmd.c index a97d50081071..a2b88ba242d5 100644 --- a/drivers/staging/rtl8188eu/core/rtw_cmd.c +++ b/drivers/staging/rtl8188eu/core/rtw_cmd.c @@ -159,14 +159,16 @@ int rtw_cmd_thread(void *context) if (padapter->bDriverStopped || padapter->bSurpriseRemoved) { DBG_88E("%s: DriverStopped(%d) SurpriseRemoved(%d) break at line %d\n", - __func__, padapter->bDriverStopped, padapter->bSurpriseRemoved, __LINE__); + __func__, padapter->bDriverStopped, + padapter->bSurpriseRemoved, __LINE__); break; } _next: if (padapter->bDriverStopped || padapter->bSurpriseRemoved) { DBG_88E("%s: DriverStopped(%d) SurpriseRemoved(%d) break at line %d\n", - __func__, padapter->bDriverStopped, padapter->bSurpriseRemoved, __LINE__); + __func__, padapter->bDriverStopped, + padapter->bSurpriseRemoved, __LINE__); break; } @@ -195,14 +197,18 @@ _next: if (pcmd->cmdcode < ARRAY_SIZE(rtw_cmd_callback)) { pcmd_callback = rtw_cmd_callback[pcmd->cmdcode].callback; if (!pcmd_callback) { - RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, ("mlme_cmd_hdl(): pcmd_callback = 0x%p, cmdcode = 0x%x\n", pcmd_callback, pcmd->cmdcode)); + RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, + ("mlme_cmd_hdl(): pcmd_callback = 0x%p, cmdcode = 0x%x\n", + pcmd_callback, pcmd->cmdcode)); rtw_free_cmd_obj(pcmd); } else { /* todo: !!! fill rsp_buf to pcmd->rsp if (pcmd->rsp!= NULL) */ pcmd_callback(pcmd->padapter, pcmd);/* need consider that free cmd_obj in rtw_cmd_callback */ } } else { - RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("%s: cmdcode = 0x%x callback not defined!\n", __func__, pcmd->cmdcode)); + RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, + ("%s: cmdcode = 0x%x callback not defined!\n", + __func__, pcmd->cmdcode)); rtw_free_cmd_obj(pcmd); } @@ -264,7 +270,8 @@ u8 rtw_sitesurvey_cmd(struct adapter *padapter, struct ndis_802_11_ssid *ssid, for (i = 0; i < ssid_num && i < RTW_SSID_SCAN_AMOUNT; i++) { if (ssid[i].ssid_length) { - memcpy(&psurveyPara->ssid[i], &ssid[i], sizeof(struct ndis_802_11_ssid)); + memcpy(&psurveyPara->ssid[i], &ssid[i], + sizeof(struct ndis_802_11_ssid)); psurveyPara->ssid_num++; } } @@ -276,7 +283,8 @@ u8 rtw_sitesurvey_cmd(struct adapter *padapter, struct ndis_802_11_ssid *ssid, for (i = 0; i < ch_num && i < RTW_CHANNEL_SCAN_AMOUNT; i++) { if (ch[i].hw_value && !(ch[i].flags & RTW_IEEE80211_CHAN_DISABLED)) { - memcpy(&psurveyPara->ch[i], &ch[i], sizeof(struct rtw_ieee80211_channel)); + memcpy(&psurveyPara->ch[i], &ch[i], + sizeof(struct rtw_ieee80211_channel)); psurveyPara->ch_num++; } } @@ -317,9 +325,11 @@ u8 rtw_createbss_cmd(struct adapter *padapter) led_control_8188eu(padapter, LED_CTL_START_TO_LINK); if (pmlmepriv->assoc_ssid.ssid_length == 0) - RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, (" createbss for Any SSid:%s\n", pmlmepriv->assoc_ssid.ssid)); + RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, + (" createbss for Any SSid:%s\n", pmlmepriv->assoc_ssid.ssid)); else - RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, (" createbss for SSid:%s\n", pmlmepriv->assoc_ssid.ssid)); + RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, + (" createbss for SSid:%s\n", pmlmepriv->assoc_ssid.ssid)); pcmd = kzalloc(sizeof(*pcmd), GFP_ATOMIC); if (!pcmd) { @@ -330,7 +340,7 @@ u8 rtw_createbss_cmd(struct adapter *padapter) INIT_LIST_HEAD(&pcmd->list); pcmd->cmdcode = _CreateBss_CMD_; pcmd->parmbuf = (unsigned char *)pdev_network; - pcmd->cmdsz = get_wlan_bssid_ex_sz((struct wlan_bssid_ex *)pdev_network); + pcmd->cmdsz = get_wlan_bssid_ex_sz(pdev_network); pcmd->rsp = NULL; pcmd->rspsz = 0; pdev_network->Length = pcmd->cmdsz; @@ -361,7 +371,8 @@ u8 rtw_joinbss_cmd(struct adapter *padapter, struct wlan_network *pnetwork) if (pmlmepriv->assoc_ssid.ssid_length == 0) RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, ("+Join cmd: Any SSid\n")); else - RT_TRACE(_module_rtl871x_cmd_c_, _drv_notice_, ("+Join cmd: SSid =[%s]\n", pmlmepriv->assoc_ssid.ssid)); + RT_TRACE(_module_rtl871x_cmd_c_, _drv_notice_, + ("+Join cmd: SSid =[%s]\n", pmlmepriv->assoc_ssid.ssid)); pcmd = kzalloc(sizeof(*pcmd), GFP_ATOMIC); if (!pcmd) { @@ -387,7 +398,7 @@ u8 rtw_joinbss_cmd(struct adapter *padapter, struct wlan_network *pnetwork) } } - psecnetwork = (struct wlan_bssid_ex *)&psecuritypriv->sec_bss; + psecnetwork = &psecuritypriv->sec_bss; if (!psecnetwork) { kfree(pcmd); @@ -406,7 +417,8 @@ u8 rtw_joinbss_cmd(struct adapter *padapter, struct wlan_network *pnetwork) psecuritypriv->authenticator_ie[0] = (unsigned char)psecnetwork->ie_length; if (psecnetwork->ie_length - 12 < 255) - memcpy(&psecuritypriv->authenticator_ie[1], &psecnetwork->ies[12], psecnetwork->ie_length - 12); + memcpy(&psecuritypriv->authenticator_ie[1], &psecnetwork->ies[12], + psecnetwork->ie_length - 12); else memcpy(&psecuritypriv->authenticator_ie[1], &psecnetwork->ies[12], 255); @@ -419,14 +431,19 @@ u8 rtw_joinbss_cmd(struct adapter *padapter, struct wlan_network *pnetwork) if (!pmlmepriv->assoc_by_bssid) memcpy(&pmlmepriv->assoc_bssid[0], &pnetwork->network.MacAddress[0], ETH_ALEN); - psecnetwork->ie_length = rtw_restruct_sec_ie(padapter, &pnetwork->network.ies[0], &psecnetwork->ies[0], pnetwork->network.ie_length); + psecnetwork->ie_length = rtw_restruct_sec_ie(padapter, &pnetwork->network.ies[0], + &psecnetwork->ies[0], + pnetwork->network.ie_length); pqospriv->qos_option = 0; if (pregistrypriv->wmm_enable) { u32 tmp_len; - tmp_len = rtw_restruct_wmm_ie(padapter, &pnetwork->network.ies[0], &psecnetwork->ies[0], pnetwork->network.ie_length, psecnetwork->ie_length); + tmp_len = rtw_restruct_wmm_ie(padapter, &pnetwork->network.ies[0], + &psecnetwork->ies[0], + pnetwork->network.ie_length, + psecnetwork->ie_length); if (psecnetwork->ie_length != tmp_len) { psecnetwork->ie_length = tmp_len; @@ -448,7 +465,8 @@ u8 rtw_joinbss_cmd(struct adapter *padapter, struct wlan_network *pnetwork) (padapter->securitypriv.dot11PrivacyAlgrthm != _WEP104_) && (padapter->securitypriv.dot11PrivacyAlgrthm != _TKIP_)) { /* rtw_restructure_ht_ie */ - rtw_restructure_ht_ie(padapter, &pnetwork->network.ies[0], &psecnetwork->ies[0], + rtw_restructure_ht_ie(padapter, &pnetwork->network.ies[0], + &psecnetwork->ies[0], pnetwork->network.ie_length, &psecnetwork->ie_length); } } @@ -573,7 +591,8 @@ u8 rtw_setstakey_cmd(struct adapter *padapter, u8 *psta, u8 unicast_key) if (unicast_key) memcpy(&psetstakey_para->key, &sta->dot118021x_UncstKey, 16); else - memcpy(&psetstakey_para->key, &psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].skey, 16); + memcpy(&psetstakey_para->key, + &psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].skey, 16); /* jeff: set this because at least sw key is ready */ padapter->securitypriv.busetkipkey = true; @@ -760,7 +779,8 @@ static void traffic_status_watchdog(struct adapter *padapter) pmlmepriv->LinkDetectInfo.NumTxOkInPeriod > 100) { bBusyTraffic = true; - if (pmlmepriv->LinkDetectInfo.NumRxOkInPeriod > pmlmepriv->LinkDetectInfo.NumTxOkInPeriod) + if (pmlmepriv->LinkDetectInfo.NumRxOkInPeriod > + pmlmepriv->LinkDetectInfo.NumTxOkInPeriod) bRxBusyTraffic = true; else bTxBusyTraffic = true; @@ -771,7 +791,8 @@ static void traffic_status_watchdog(struct adapter *padapter) pmlmepriv->LinkDetectInfo.NumTxOkInPeriod > 4000) { bHigherBusyTraffic = true; - if (pmlmepriv->LinkDetectInfo.NumRxOkInPeriod > pmlmepriv->LinkDetectInfo.NumTxOkInPeriod) + if (pmlmepriv->LinkDetectInfo.NumRxOkInPeriod > + pmlmepriv->LinkDetectInfo.NumTxOkInPeriod) bHigherBusyRxTraffic = true; else bHigherBusyTxTraffic = true; @@ -1127,7 +1148,8 @@ void rtw_survey_cmd_callback(struct adapter *padapter, struct cmd_obj *pcmd) } else if (pcmd->res != H2C_SUCCESS) { mod_timer(&pmlmepriv->scan_to_timer, jiffies + msecs_to_jiffies(1)); - RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("\n ********Error: MgntActrtw_set_802_11_bssid_LIST_SCAN Fail ************\n\n.")); + RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, + ("\n ********Error: MgntActrtw_set_802_11_bssid_LIST_SCAN Fail ************\n\n.")); } /* free cmd */ @@ -1143,7 +1165,8 @@ void rtw_disassoc_cmd_callback(struct adapter *padapter, struct cmd_obj *pcmd) set_fwstate(pmlmepriv, _FW_LINKED); spin_unlock_bh(&pmlmepriv->lock); - RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("\n ***Error: disconnect_cmd_callback Fail ***\n.")); + RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, + ("\n ***Error: disconnect_cmd_callback Fail ***\n.")); return; } @@ -1161,7 +1184,8 @@ void rtw_joinbss_cmd_callback(struct adapter *padapter, struct cmd_obj *pcmd) mod_timer(&pmlmepriv->assoc_timer, jiffies + msecs_to_jiffies(1)); } else if (pcmd->res != H2C_SUCCESS) { - RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("********Error:rtw_select_and_join_from_scanned_queue Wait Sema Fail ************\n")); + RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, + ("********Error:rtw_select_and_join_from_scanned_queue Wait Sema Fail ************\n")); mod_timer(&pmlmepriv->assoc_timer, jiffies + msecs_to_jiffies(1)); } @@ -1193,7 +1217,8 @@ void rtw_createbss_cmd_callback(struct adapter *padapter, struct cmd_obj *pcmd) if (!psta) { psta = rtw_alloc_stainfo(&padapter->stapriv, pnetwork->MacAddress); if (!psta) { - RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("\nCan't alloc sta_info when createbss_cmd_callback\n")); + RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, + ("\nCan't alloc sta_info when createbss_cmd_callback\n")); goto createbss_cmd_fail; } } @@ -1205,7 +1230,8 @@ void rtw_createbss_cmd_callback(struct adapter *padapter, struct cmd_obj *pcmd) if (!pwlan) { pwlan = rtw_get_oldest_wlan_network(&pmlmepriv->scanned_queue); if (!pwlan) { - RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("\n Error: can't get pwlan in rtw_joinbss_event_callback\n")); + RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, + ("\n Error: can't get pwlan in rtw_joinbss_event_callback\n")); spin_unlock_bh(&pmlmepriv->scanned_queue.lock); goto createbss_cmd_fail; } @@ -1242,7 +1268,8 @@ void rtw_setstaKey_cmdrsp_callback(struct adapter *padapter, struct cmd_obj *pc struct sta_info *psta = rtw_get_stainfo(pstapriv, psetstakey_rsp->addr); if (!psta) { - RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("\nERROR: %s => can't get sta_info\n\n", __func__)); + RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, + ("\nERROR: %s => can't get sta_info\n\n", __func__)); goto exit; } exit: @@ -1258,7 +1285,8 @@ void rtw_setassocsta_cmdrsp_callback(struct adapter *padapter, struct cmd_obj * struct sta_info *psta = rtw_get_stainfo(pstapriv, passocsta_parm->addr); if (!psta) { - RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("\nERROR: %s => can't get sta_info\n\n", __func__)); + RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, + ("\nERROR: %s => can't get sta_info\n\n", __func__)); goto exit; } diff --git a/drivers/staging/rtl8188eu/core/rtw_debug.c b/drivers/staging/rtl8188eu/core/rtw_debug.c index fcc8bd1011e1..3c0d20cb9c6a 100644 --- a/drivers/staging/rtl8188eu/core/rtw_debug.c +++ b/drivers/staging/rtl8188eu/core/rtw_debug.c @@ -33,7 +33,7 @@ int proc_set_write_reg(struct file *file, const char __user *buffer, unsigned long count, void *data) { struct net_device *dev = data; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); char tmp[32]; u32 addr, val, len; @@ -75,7 +75,7 @@ int proc_get_read_reg(char *page, char **start, int *eof, void *data) { struct net_device *dev = data; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); int len = 0; @@ -135,7 +135,7 @@ int proc_get_adapter_state(char *page, char **start, int *eof, void *data) { struct net_device *dev = data; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); int len = 0; len += scnprintf(page + len, count - len, "bSurpriseRemoved=%d, bDriverStopped=%d\n", @@ -150,7 +150,7 @@ int proc_get_best_channel(char *page, char **start, int *eof, void *data) { struct net_device *dev = data; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; int len = 0; u32 i, best_channel_24G = 1, index_24G = 0; diff --git a/drivers/staging/rtl8188eu/core/rtw_mlme.c b/drivers/staging/rtl8188eu/core/rtw_mlme.c index d334dc335914..9d12f92994b3 100644 --- a/drivers/staging/rtl8188eu/core/rtw_mlme.c +++ b/drivers/staging/rtl8188eu/core/rtw_mlme.c @@ -1672,8 +1672,8 @@ static int SecIsInPMKIDList(struct adapter *Adapter, u8 *bssid) int i = 0; do { - if ((psecuritypriv->PMKIDList[i].bUsed) && - (!memcmp(psecuritypriv->PMKIDList[i].Bssid, bssid, ETH_ALEN))) + if ((psecuritypriv->PMKIDList[i].used) && + (!memcmp(psecuritypriv->PMKIDList[i].bssid, bssid, ETH_ALEN))) break; } while (++i < NUM_PMKID_CACHE); @@ -1730,7 +1730,7 @@ int rtw_restruct_sec_ie(struct adapter *adapter, u8 *in_ie, u8 *out_ie, uint in_ (ndisauthmode == Ndis802_11AuthModeWPAPSK)) authmode = _WPA_IE_ID_; else if ((ndisauthmode == Ndis802_11AuthModeWPA2) || - (ndisauthmode == Ndis802_11AuthModeWPA2PSK)) + (ndisauthmode == Ndis802_11AuthModeWPA2PSK)) authmode = _WPA2_IE_ID_; else authmode = 0x0; @@ -1815,7 +1815,7 @@ void rtw_update_registrypriv_dev_network(struct adapter *adapter) sz = rtw_generate_ie(pregistrypriv); pdev_network->ie_length = sz; - pdev_network->Length = get_wlan_bssid_ex_sz((struct wlan_bssid_ex *)pdev_network); + pdev_network->Length = get_wlan_bssid_ex_sz(pdev_network); /* notes: translate ie_length & Length after assign the Length to cmdsz in createbss_cmd(); */ /* pdev_network->ie_length = cpu_to_le32(sz); */ @@ -1894,9 +1894,9 @@ unsigned int rtw_restructure_ht_ie(struct adapter *padapter, u8 *in_ie, u8 *out_ rtw_hal_get_def_var(padapter, HAL_DEF_MAX_RECVBUF_SZ, &max_recvbuf_sz); /* - ampdu_params_info [1:0]:Max AMPDU Len => 0:8k , 1:16k, 2:32k, 3:64k - ampdu_params_info [4:2]:Min MPDU Start Spacing - */ + * ampdu_params_info [1:0]:Max AMPDU Len => 0:8k , 1:16k, 2:32k, 3:64k + * ampdu_params_info [4:2]:Min MPDU Start Spacing + */ rtw_hal_get_def_var(padapter, HW_VAR_MAX_RX_AMPDU_FACTOR, &max_rx_ampdu_factor); ht_cap.ampdu_params_info = max_rx_ampdu_factor & 0x03; diff --git a/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c b/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c index 98b1ba2e489f..b3eddcb83cd0 100644 --- a/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c @@ -19,9 +19,7 @@ static u8 null_addr[ETH_ALEN] = {}; -/************************************************** -OUI definitions for the vendor specific IE -***************************************************/ +/* OUI definitions for the vendor specific IE */ const u8 RTW_WPA_OUI[] = {0x00, 0x50, 0xf2, 0x01}; const u8 WPS_OUI[] = {0x00, 0x50, 0xf2, 0x04}; static const u8 WMM_OUI[] = {0x00, 0x50, 0xf2, 0x02}; @@ -32,17 +30,13 @@ static const u8 WMM_PARA_OUI[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01}; const u8 WPA_TKIP_CIPHER[4] = {0x00, 0x50, 0xf2, 0x02}; const u8 RSN_TKIP_CIPHER[4] = {0x00, 0x0f, 0xac, 0x02}; -/******************************************************** -MCS rate definitions -*********************************************************/ +/* MCS rate definitions */ const u8 MCS_rate_1R[16] = { 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -/******************************************************** -ChannelPlan definitions -*********************************************************/ +/* ChannelPlan definitions */ static struct rt_channel_plan_2g RTW_ChannelPlan2G[RT_CHANNEL_DOMAIN_2G_MAX] = { {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13}, /* 0x00, RT_CHANNEL_DOMAIN_2G_WORLD , Passive scan CH 12, 13 */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13}, /* 0x01, RT_CHANNEL_DOMAIN_2G_ETSI1 */ @@ -1777,7 +1771,7 @@ static void issue_action_BSSCoexistPacket(struct adapter *padapter) plist = plist->next; - pbss_network = (struct wlan_bssid_ex *)&pnetwork->network; + pbss_network = &pnetwork->network; p = rtw_get_ie(pbss_network->ies + _FIXED_IE_LENGTH_, _HT_CAPABILITY_IE_, &len, pbss_network->ie_length - _FIXED_IE_LENGTH_); if (!p || len == 0) { /* non-HT */ @@ -2137,7 +2131,7 @@ static u8 collect_bss_info(struct adapter *padapter, bssid->Configuration.BeaconPeriod = get_unaligned_le16(rtw_get_beacon_interval_from_ie(bssid->ies)); - val16 = rtw_get_capability((struct wlan_bssid_ex *)bssid); + val16 = rtw_get_capability(bssid); if (val16 & BIT(0)) { bssid->InfrastructureMode = Ndis802_11Infrastructure; @@ -2183,7 +2177,7 @@ static void start_create_ibss(struct adapter *padapter) u8 join_type; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; - struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)(&pmlmeinfo->network); + struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network; pmlmeext->cur_channel = (u8)pnetwork->Configuration.DSConfig; pmlmeinfo->bcn_interval = get_beacon_interval(pnetwork); @@ -2192,7 +2186,7 @@ static void start_create_ibss(struct adapter *padapter) update_wireless_mode(padapter); /* update capability */ - caps = rtw_get_capability((struct wlan_bssid_ex *)pnetwork); + caps = rtw_get_capability(pnetwork); update_capinfo(padapter, caps); if (caps & cap_IBSS) {/* adhoc master */ val8 = 0xcf; @@ -2234,7 +2228,7 @@ static void start_clnt_join(struct adapter *padapter) u8 val8; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; - struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)(&pmlmeinfo->network); + struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network; int beacon_timeout; pmlmeext->cur_channel = (u8)pnetwork->Configuration.DSConfig; @@ -2244,7 +2238,7 @@ static void start_clnt_join(struct adapter *padapter) update_wireless_mode(padapter); /* update capability */ - caps = rtw_get_capability((struct wlan_bssid_ex *)pnetwork); + caps = rtw_get_capability(pnetwork); update_capinfo(padapter, caps); if (caps & cap_ESS) { Set_MSR(padapter, WIFI_FW_STATION_STATE); @@ -2599,9 +2593,9 @@ static unsigned int OnBeacon(struct adapter *padapter, if (psta) { ret = rtw_check_bcn_info(padapter, pframe, len); if (!ret) { - DBG_88E_LEVEL(_drv_info_, "ap has changed, disconnect now\n "); - receive_disconnect(padapter, pmlmeinfo->network.MacAddress, 65535); - return _SUCCESS; + DBG_88E_LEVEL(_drv_info_, "ap has changed, disconnect now\n "); + receive_disconnect(padapter, pmlmeinfo->network.MacAddress, 65535); + return _SUCCESS; } /* update WMM, ERP in the beacon */ /* todo: the timer is used instead of the number of the beacon received */ @@ -2929,7 +2923,7 @@ static unsigned int OnAssocReq(struct adapter *padapter, pstat = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe)); if (!pstat) { - status = _RSON_CLS2_; + status = WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA; goto asoc_class2_error; } @@ -2943,7 +2937,7 @@ static unsigned int OnAssocReq(struct adapter *padapter, /* check if this stat has been successfully authenticated/assocated */ if (!((pstat->state) & WIFI_FW_AUTH_SUCCESS)) { if (!((pstat->state) & WIFI_FW_ASSOC_SUCCESS)) { - status = _RSON_CLS2_; + status = WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA; goto asoc_class2_error; } else { pstat->state &= (~WIFI_FW_ASSOC_SUCCESS); @@ -2981,7 +2975,7 @@ static unsigned int OnAssocReq(struct adapter *padapter, status = _STATS_FAILURE_; } - if (_STATS_SUCCESSFUL_ != status) + if (status != _STATS_SUCCESSFUL_) goto OnAssocReqFail; /* check if the supported rate is ok */ @@ -3072,7 +3066,7 @@ static unsigned int OnAssocReq(struct adapter *padapter, wpa_ie_len = 0; } - if (_STATS_SUCCESSFUL_ != status) + if (status != _STATS_SUCCESSFUL_) goto OnAssocReqFail; pstat->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS); @@ -3282,7 +3276,7 @@ static unsigned int OnAssocReq(struct adapter *padapter, spin_unlock_bh(&pstapriv->asoc_list_lock); /* now the station is qualified to join our BSS... */ - if ((pstat->state & WIFI_FW_ASSOC_SUCCESS) && (_STATS_SUCCESSFUL_ == status)) { + if ((pstat->state & WIFI_FW_ASSOC_SUCCESS) && (status == _STATS_SUCCESSFUL_)) { /* 1 bss_cap_update & sta_info_update */ bss_cap_update_on_sta_join(padapter, pstat); sta_info_update(padapter, pstat); @@ -3546,12 +3540,12 @@ static unsigned int on_action_spct(struct adapter *padapter, action = frame_body[1]; switch (action) { - case RTW_WLAN_ACTION_SPCT_MSR_REQ: - case RTW_WLAN_ACTION_SPCT_MSR_RPRT: - case RTW_WLAN_ACTION_SPCT_TPC_REQ: - case RTW_WLAN_ACTION_SPCT_TPC_RPRT: + case WLAN_ACTION_SPCT_MSR_REQ: + case WLAN_ACTION_SPCT_MSR_RPRT: + case WLAN_ACTION_SPCT_TPC_REQ: + case WLAN_ACTION_SPCT_TPC_RPRT: break; - case RTW_WLAN_ACTION_SPCT_CHL_SWITCH: + case WLAN_ACTION_SPCT_CHL_SWITCH: break; default: break; @@ -4199,7 +4193,7 @@ void report_survey_event(struct adapter *padapter, psurvey_evt = (struct survey_event *)(pevtcmd + sizeof(struct C2HEvent_Header)); - if (collect_bss_info(padapter, precv_frame, (struct wlan_bssid_ex *)&psurvey_evt->bss) == _FAIL) { + if (collect_bss_info(padapter, precv_frame, &psurvey_evt->bss) == _FAIL) { kfree(pcmd_obj); kfree(pevtcmd); return; @@ -4857,7 +4851,7 @@ u8 createbss_hdl(struct adapter *padapter, u8 *pbuf) { struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; - struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)(&pmlmeinfo->network); + struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network; struct wlan_bssid_ex *pparm = (struct wlan_bssid_ex *)pbuf; if (pparm->InfrastructureMode == Ndis802_11APMode) { @@ -4919,7 +4913,7 @@ u8 join_cmd_hdl(struct adapter *padapter, u8 *pbuf) struct registry_priv *pregpriv = &padapter->registrypriv; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; - struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)(&pmlmeinfo->network); + struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network; struct wlan_bssid_ex *pparm = (struct wlan_bssid_ex *)pbuf; u32 i; @@ -5030,7 +5024,7 @@ u8 disconnect_hdl(struct adapter *padapter, unsigned char *pbuf) struct disconnect_parm *param = (struct disconnect_parm *)pbuf; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; - struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)(&pmlmeinfo->network); + struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network; u8 val8; if (is_client_associated_to_ap(padapter)) diff --git a/drivers/staging/rtl8188eu/core/rtw_pwrctrl.c b/drivers/staging/rtl8188eu/core/rtw_pwrctrl.c index 39ca97411fd5..3848e695ac84 100644 --- a/drivers/staging/rtl8188eu/core/rtw_pwrctrl.c +++ b/drivers/staging/rtl8188eu/core/rtw_pwrctrl.c @@ -84,7 +84,7 @@ static int rtw_hw_resume(struct adapter *padapter) pwrpriv->bips_processing = true; rtw_reset_drv_sw(padapter); - if (ips_netdrv_open((struct adapter *)rtw_netdev_priv(pnetdev)) != _SUCCESS) { + if (ips_netdrv_open(rtw_netdev_priv(pnetdev)) != _SUCCESS) { mutex_unlock(&pwrpriv->mutex_lock); goto error_exit; } @@ -530,11 +530,11 @@ void rtw_init_pwrctrl_priv(struct adapter *padapter) } /* -* rtw_pwr_wakeup - Wake the NIC up from: 1)IPS. 2)USB autosuspend -* @adapter: pointer to struct adapter structure -* @ips_deffer_ms: the ms will prevent from falling into IPS after wakeup -* Return _SUCCESS or _FAIL -*/ + * rtw_pwr_wakeup - Wake the NIC up from: 1)IPS. 2)USB autosuspend + * @adapter: pointer to struct adapter structure + * @ips_deffer_ms: the ms will prevent from falling into IPS after wakeup + * Return _SUCCESS or _FAIL + */ int _rtw_pwr_wakeup(struct adapter *padapter, u32 ips_deffer_ms, const char *caller) { diff --git a/drivers/staging/rtl8188eu/core/rtw_security.c b/drivers/staging/rtl8188eu/core/rtw_security.c index 78a8ac60bf3d..46ba55a8952a 100644 --- a/drivers/staging/rtl8188eu/core/rtw_security.c +++ b/drivers/staging/rtl8188eu/core/rtw_security.c @@ -142,7 +142,7 @@ void rtw_wep_encrypt(struct adapter *padapter, struct xmit_frame *pxmitframe) struct sk_buff *skb; struct lib80211_crypto_ops *crypto_ops; - if (pxmitframe->buf_addr == NULL) + if (!pxmitframe->buf_addr) return; if ((pattrib->encrypt != _WEP40_) && (pattrib->encrypt != _WEP104_)) @@ -371,8 +371,6 @@ void rtw_seccalctkipmic(u8 *key, u8 *header, u8 *data, u32 data_len, u8 *mic_cod rtw_secgetmic(&micdata, mic_code); } - - /* macros for extraction/creation of unsigned char/unsigned short values */ #define RotR1(v16) ((((v16) >> 1) & 0x7FFF) ^ (((v16) & 1) << 15)) #define Lo8(v16) ((u8)((v16) & 0x00FF)) @@ -591,7 +589,7 @@ u32 rtw_tkip_encrypt(struct adapter *padapter, struct xmit_frame *pxmitframe) struct xmit_priv *pxmitpriv = &padapter->xmitpriv; u32 res = _SUCCESS; - if (pxmitframe->buf_addr == NULL) + if (!pxmitframe->buf_addr) return _FAIL; hw_hdr_offset = TXDESC_SIZE + @@ -604,7 +602,7 @@ u32 rtw_tkip_encrypt(struct adapter *padapter, struct xmit_frame *pxmitframe) else stainfo = rtw_get_stainfo(&padapter->stapriv, &pattrib->ra[0]); - if (stainfo != NULL) { + if (stainfo) { RT_TRACE(_module_rtl871x_security_c_, _drv_err_, ("%s: stainfo!= NULL!!!\n", __func__)); if (is_multicast_ether_addr(pattrib->ra)) @@ -662,7 +660,6 @@ u32 rtw_tkip_decrypt(struct adapter *padapter, struct recv_frame *precvframe) u8 crc[4]; struct arc4context mycontext; int length; - u8 *pframe, *payload, *iv, *prwskey; union pn48 dot11txpn; struct sta_info *stainfo; @@ -670,7 +667,6 @@ u32 rtw_tkip_decrypt(struct adapter *padapter, struct recv_frame *precvframe) struct security_priv *psecuritypriv = &padapter->securitypriv; u32 res = _SUCCESS; - pframe = (unsigned char *)precvframe->pkt->data; /* 4 start to decrypt recvframe */ @@ -726,553 +722,106 @@ exit: return res; } -/* 3 ===== AES related ===== */ - - -#define MAX_MSG_SIZE 2048 -/*****************************/ -/******** SBOX Table *********/ -/*****************************/ - -static const u8 sbox_table[256] = { - 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, - 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, - 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, - 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, - 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, - 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, - 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, - 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, - 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, - 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, - 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, - 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, - 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, - 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, - 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, - 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, - 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, - 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, - 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, - 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, - 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, - 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, - 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, - 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, - 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, - 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, - 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, - 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, - 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, - 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, - 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, - 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 -}; - -/*****************************/ -/**** Function Prototypes ****/ -/*****************************/ - -static void bitwise_xor(u8 *ina, u8 *inb, u8 *out); -static void construct_mic_iv(u8 *mic_header1, int qc_exists, int a4_exists, u8 *mpdu, uint payload_length, u8 *pn_vector); -static void construct_mic_header1(u8 *mic_header1, int header_length, u8 *mpdu); -static void construct_mic_header2(u8 *mic_header2, u8 *mpdu, int a4_exists, int qc_exists); -static void construct_ctr_preload(u8 *ctr_preload, int a4_exists, int qc_exists, u8 *mpdu, u8 *pn_vector, int c); -static void xor_128(u8 *a, u8 *b, u8 *out); -static void xor_32(u8 *a, u8 *b, u8 *out); -static u8 sbox(u8 a); -static void next_key(u8 *key, int round); -static void byte_sub(u8 *in, u8 *out); -static void shift_row(u8 *in, u8 *out); -static void mix_column(u8 *in, u8 *out); -static void aes128k128d(u8 *key, u8 *data, u8 *ciphertext); - -/****************************************/ -/* aes128k128d() */ -/* Performs a 128 bit AES encrypt with */ -/* 128 bit data. */ -/****************************************/ -static void xor_128(u8 *a, u8 *b, u8 *out) -{ - int i; - - for (i = 0; i < 16; i++) - out[i] = a[i] ^ b[i]; -} - -static void xor_32(u8 *a, u8 *b, u8 *out) -{ - int i; - - for (i = 0; i < 4; i++) - out[i] = a[i] ^ b[i]; -} - -static u8 sbox(u8 a) +u32 rtw_aes_encrypt(struct adapter *padapter, struct xmit_frame *pxmitframe) { - return sbox_table[(int)a]; -} - -static void next_key(u8 *key, int round) -{ - u8 rcon; - u8 sbox_key[4]; - static const u8 rcon_table[12] = { - 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, - 0x1b, 0x36, 0x36, 0x36 - }; - - sbox_key[0] = sbox(key[13]); - sbox_key[1] = sbox(key[14]); - sbox_key[2] = sbox(key[15]); - sbox_key[3] = sbox(key[12]); - - rcon = rcon_table[round]; - - xor_32(&key[0], sbox_key, &key[0]); - key[0] = key[0] ^ rcon; - - xor_32(&key[4], &key[0], &key[4]); - xor_32(&key[8], &key[4], &key[8]); - xor_32(&key[12], &key[8], &key[12]); -} - -static void byte_sub(u8 *in, u8 *out) -{ - int i; - - for (i = 0; i < 16; i++) - out[i] = sbox(in[i]); -} - -static void shift_row(u8 *in, u8 *out) -{ - out[0] = in[0]; - out[1] = in[5]; - out[2] = in[10]; - out[3] = in[15]; - out[4] = in[4]; - out[5] = in[9]; - out[6] = in[14]; - out[7] = in[3]; - out[8] = in[8]; - out[9] = in[13]; - out[10] = in[2]; - out[11] = in[7]; - out[12] = in[12]; - out[13] = in[1]; - out[14] = in[6]; - out[15] = in[11]; -} - -static void mix_column(u8 *in, u8 *out) -{ - int i; - u8 add1b[4]; - u8 add1bf7[4]; - u8 rotl[4]; - u8 swap_halves[4]; - u8 andf7[4]; - u8 rotr[4]; - u8 temp[4]; - u8 tempb[4]; - - for (i = 0 ; i < 4; i++) { - if ((in[i] & 0x80) == 0x80) - add1b[i] = 0x1b; - else - add1b[i] = 0x00; - } - - swap_halves[0] = in[2]; /* Swap halves */ - swap_halves[1] = in[3]; - swap_halves[2] = in[0]; - swap_halves[3] = in[1]; - - rotl[0] = in[3]; /* Rotate left 8 bits */ - rotl[1] = in[0]; - rotl[2] = in[1]; - rotl[3] = in[2]; - - andf7[0] = in[0] & 0x7f; - andf7[1] = in[1] & 0x7f; - andf7[2] = in[2] & 0x7f; - andf7[3] = in[3] & 0x7f; - - for (i = 3; i > 0; i--) { /* logical shift left 1 bit */ - andf7[i] = andf7[i] << 1; - if ((andf7[i - 1] & 0x80) == 0x80) - andf7[i] = (andf7[i] | 0x01); - } - andf7[0] = andf7[0] << 1; - andf7[0] = andf7[0] & 0xfe; - - xor_32(add1b, andf7, add1bf7); - - xor_32(in, add1bf7, rotr); - - temp[0] = rotr[0]; /* Rotate right 8 bits */ - rotr[0] = rotr[1]; - rotr[1] = rotr[2]; - rotr[2] = rotr[3]; - rotr[3] = temp[0]; - - xor_32(add1bf7, rotr, temp); - xor_32(swap_halves, rotl, tempb); - xor_32(temp, tempb, out); -} - -static void aes128k128d(u8 *key, u8 *data, u8 *ciphertext) -{ - int round; - int i; - u8 intermediatea[16]; - u8 intermediateb[16]; - u8 round_key[16]; - - for (i = 0; i < 16; i++) - round_key[i] = key[i]; - for (round = 0; round < 11; round++) { - if (round == 0) { - xor_128(round_key, data, ciphertext); - next_key(round_key, round); - } else if (round == 10) { - byte_sub(ciphertext, intermediatea); - shift_row(intermediatea, intermediateb); - xor_128(intermediateb, round_key, ciphertext); - } else { /* 1 - 9 */ - byte_sub(ciphertext, intermediatea); - shift_row(intermediatea, intermediateb); - mix_column(&intermediateb[0], &intermediatea[0]); - mix_column(&intermediateb[4], &intermediatea[4]); - mix_column(&intermediateb[8], &intermediatea[8]); - mix_column(&intermediateb[12], &intermediatea[12]); - xor_128(intermediatea, round_key, ciphertext); - next_key(round_key, round); - } - } -} - -/************************************************/ -/* construct_mic_iv() */ -/* Builds the MIC IV from header fields and PN */ -/************************************************/ -static void construct_mic_iv(u8 *mic_iv, int qc_exists, int a4_exists, u8 *mpdu, - uint payload_length, u8 *pn_vector) -{ - int i; - - mic_iv[0] = 0x59; - if (qc_exists && a4_exists) - mic_iv[1] = mpdu[30] & 0x0f; /* QoS_TC */ - if (qc_exists && !a4_exists) - mic_iv[1] = mpdu[24] & 0x0f; /* mute bits 7-4 */ - if (!qc_exists) - mic_iv[1] = 0x00; - for (i = 2; i < 8; i++) - mic_iv[i] = mpdu[i + 8]; /* mic_iv[2:7] = A2[0:5] = mpdu[10:15] */ - for (i = 8; i < 14; i++) - mic_iv[i] = pn_vector[13 - i]; /* mic_iv[8:13] = PN[5:0] */ - mic_iv[14] = (unsigned char)(payload_length / 256); - mic_iv[15] = (unsigned char)(payload_length % 256); -} - -/************************************************/ -/* construct_mic_header1() */ -/* Builds the first MIC header block from */ -/* header fields. */ -/************************************************/ -static void construct_mic_header1(u8 *mic_header1, int header_length, u8 *mpdu) -{ - mic_header1[0] = (u8)((header_length - 2) / 256); - mic_header1[1] = (u8)((header_length - 2) % 256); - mic_header1[2] = mpdu[0] & 0xcf; /* Mute CF poll & CF ack bits */ - mic_header1[3] = mpdu[1] & 0xc7; /* Mute retry, more data and pwr mgt bits */ - mic_header1[4] = mpdu[4]; /* A1 */ - mic_header1[5] = mpdu[5]; - mic_header1[6] = mpdu[6]; - mic_header1[7] = mpdu[7]; - mic_header1[8] = mpdu[8]; - mic_header1[9] = mpdu[9]; - mic_header1[10] = mpdu[10]; /* A2 */ - mic_header1[11] = mpdu[11]; - mic_header1[12] = mpdu[12]; - mic_header1[13] = mpdu[13]; - mic_header1[14] = mpdu[14]; - mic_header1[15] = mpdu[15]; -} - -/************************************************/ -/* construct_mic_header2() */ -/* Builds the last MIC header block from */ -/* header fields. */ -/************************************************/ -static void construct_mic_header2(u8 *mic_header2, u8 *mpdu, int a4_exists, int qc_exists) -{ - int i; - - for (i = 0; i < 16; i++) - mic_header2[i] = 0x00; + int curfragnum, length; + u8 *pframe; /* *payload,*iv */ + u8 hw_hdr_offset = 0; + struct sta_info *stainfo; + struct pkt_attrib *pattrib = &pxmitframe->attrib; + struct security_priv *psecuritypriv = &padapter->securitypriv; + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + u32 res = _SUCCESS; + void *crypto_private; + struct sk_buff *skb; + struct lib80211_crypto_ops *crypto_ops; + const int key_idx = is_multicast_ether_addr(pattrib->ra) ? psecuritypriv->dot118021XGrpKeyid : 0; + const int key_length = 16; + u8 *key; - mic_header2[0] = mpdu[16]; /* A3 */ - mic_header2[1] = mpdu[17]; - mic_header2[2] = mpdu[18]; - mic_header2[3] = mpdu[19]; - mic_header2[4] = mpdu[20]; - mic_header2[5] = mpdu[21]; + if (!pxmitframe->buf_addr) + return _FAIL; - mic_header2[6] = 0x00; - mic_header2[7] = 0x00; /* mpdu[23]; */ + hw_hdr_offset = TXDESC_SIZE + + (pxmitframe->pkt_offset * PACKET_OFFSET_SZ); - if (!qc_exists && a4_exists) { - for (i = 0; i < 6; i++) - mic_header2[8 + i] = mpdu[24 + i]; /* A4 */ - } + pframe = pxmitframe->buf_addr + hw_hdr_offset; - if (qc_exists && !a4_exists) { - mic_header2[8] = mpdu[24] & 0x0f; /* mute bits 15 - 4 */ - mic_header2[9] = mpdu[25] & 0x00; - } + /* 4 start to encrypt each fragment */ + if (pattrib->encrypt != _AES_) + return res; - if (qc_exists && a4_exists) { - for (i = 0; i < 6; i++) - mic_header2[8 + i] = mpdu[24 + i]; /* A4 */ + if (pattrib->psta) + stainfo = pattrib->psta; + else + stainfo = rtw_get_stainfo(&padapter->stapriv, &pattrib->ra[0]); - mic_header2[14] = mpdu[30] & 0x0f; - mic_header2[15] = mpdu[31] & 0x00; + if (!stainfo) { + RT_TRACE(_module_rtl871x_security_c_, _drv_err_, ("%s: stainfo==NULL!!!\n", __func__)); + return _FAIL; } -} -/************************************************/ -/* construct_mic_header2() */ -/* Builds the last MIC header block from */ -/* header fields. */ -/************************************************/ -static void construct_ctr_preload(u8 *ctr_preload, int a4_exists, int qc_exists, u8 *mpdu, u8 *pn_vector, int c) -{ - int i; - - for (i = 0; i < 16; i++) - ctr_preload[i] = 0x00; - i = 0; - - ctr_preload[0] = 0x01; /* flag */ - if (qc_exists && a4_exists) - ctr_preload[1] = mpdu[30] & 0x0f; /* QoC_Control */ - if (qc_exists && !a4_exists) - ctr_preload[1] = mpdu[24] & 0x0f; - - for (i = 2; i < 8; i++) - ctr_preload[i] = mpdu[i + 8]; /* ctr_preload[2:7] = A2[0:5] = mpdu[10:15] */ - for (i = 8; i < 14; i++) - ctr_preload[i] = pn_vector[13 - i]; /* ctr_preload[8:13] = PN[5:0] */ - ctr_preload[14] = (unsigned char)(c / 256); /* Ctr */ - ctr_preload[15] = (unsigned char)(c % 256); -} - -/************************************/ -/* bitwise_xor() */ -/* A 128 bit, bitwise exclusive or */ -/************************************/ -static void bitwise_xor(u8 *ina, u8 *inb, u8 *out) -{ - int i; - - for (i = 0; i < 16; i++) - out[i] = ina[i] ^ inb[i]; -} + crypto_ops = lib80211_get_crypto_ops("CCMP"); -static int aes_cipher(u8 *key, uint hdrlen, u8 *pframe, uint plen) -{ - uint qc_exists, a4_exists, i, j, payload_remainder, - num_blocks, payload_index; - - u8 pn_vector[6]; - u8 mic_iv[16]; - u8 mic_header1[16]; - u8 mic_header2[16]; - u8 ctr_preload[16]; - - /* Intermediate Buffers */ - u8 chain_buffer[16]; - u8 aes_out[16]; - u8 padded_buffer[16]; - u8 mic[8]; - uint frtype = GetFrameType(pframe); - uint frsubtype = GetFrameSubType(pframe); - - frsubtype >>= 4; - - memset(mic_iv, 0, 16); - memset(mic_header1, 0, 16); - memset(mic_header2, 0, 16); - memset(ctr_preload, 0, 16); - memset(chain_buffer, 0, 16); - memset(aes_out, 0, 16); - memset(padded_buffer, 0, 16); - - if ((hdrlen == WLAN_HDR_A3_LEN) || (hdrlen == WLAN_HDR_A3_QOS_LEN)) - a4_exists = 0; + if (is_multicast_ether_addr(pattrib->ra)) + key = psecuritypriv->dot118021XGrpKey[key_idx].skey; else - a4_exists = 1; - - if ((frtype == WIFI_DATA_CFACK) || (frtype == WIFI_DATA_CFPOLL) || (frtype == WIFI_DATA_CFACKPOLL)) { - qc_exists = 1; - if (hdrlen != WLAN_HDR_A3_QOS_LEN) - hdrlen += 2; - } else if ((frsubtype == 0x08) || (frsubtype == 0x09) || (frsubtype == 0x0a) || (frsubtype == 0x0b)) { - if (hdrlen != WLAN_HDR_A3_QOS_LEN) - hdrlen += 2; - qc_exists = 1; - } else { - qc_exists = 0; - } - - pn_vector[0] = pframe[hdrlen]; - pn_vector[1] = pframe[hdrlen + 1]; - pn_vector[2] = pframe[hdrlen + 4]; - pn_vector[3] = pframe[hdrlen + 5]; - pn_vector[4] = pframe[hdrlen + 6]; - pn_vector[5] = pframe[hdrlen + 7]; - - construct_mic_iv(mic_iv, qc_exists, a4_exists, pframe, plen, pn_vector); + key = stainfo->dot118021x_UncstKey.skey; - construct_mic_header1(mic_header1, hdrlen, pframe); - construct_mic_header2(mic_header2, pframe, a4_exists, qc_exists); - - payload_remainder = plen % 16; - num_blocks = plen / 16; - - /* Find start of payload */ - payload_index = hdrlen + 8; - - /* Calculate MIC */ - aes128k128d(key, mic_iv, aes_out); - bitwise_xor(aes_out, mic_header1, chain_buffer); - aes128k128d(key, chain_buffer, aes_out); - bitwise_xor(aes_out, mic_header2, chain_buffer); - aes128k128d(key, chain_buffer, aes_out); - - for (i = 0; i < num_blocks; i++) { - bitwise_xor(aes_out, &pframe[payload_index], chain_buffer);/* bitwise_xor(aes_out, &message[payload_index], chain_buffer); */ - - payload_index += 16; - aes128k128d(key, chain_buffer, aes_out); + if (!crypto_ops) { + res = _FAIL; + goto exit; } - /* Add on the final payload block if it needs padding */ - if (payload_remainder > 0) { - for (j = 0; j < 16; j++) - padded_buffer[j] = 0x00; - for (j = 0; j < payload_remainder; j++) - padded_buffer[j] = pframe[payload_index++];/* padded_buffer[j] = message[payload_index++]; */ - bitwise_xor(aes_out, padded_buffer, chain_buffer); - aes128k128d(key, chain_buffer, aes_out); + crypto_private = crypto_ops->init(key_idx); + if (!crypto_private) { + res = _FAIL; + goto exit; } - for (j = 0; j < 8; j++) - mic[j] = aes_out[j]; - - /* Insert MIC into payload */ - for (j = 0; j < 8; j++) - pframe[payload_index + j] = mic[j]; - - payload_index = hdrlen + 8; - for (i = 0; i < num_blocks; i++) { - construct_ctr_preload(ctr_preload, a4_exists, qc_exists, pframe, pn_vector, i + 1); - aes128k128d(key, ctr_preload, aes_out); - bitwise_xor(aes_out, &pframe[payload_index], chain_buffer); - for (j = 0; j < 16; j++) - pframe[payload_index++] = chain_buffer[j]; + if (crypto_ops->set_key(key, key_length, NULL, crypto_private) < 0) { + res = _FAIL; + goto exit_crypto_ops_deinit; } - if (payload_remainder > 0) { /* If there is a short final block, then pad it,*/ - /* encrypt it and copy the unpadded part back */ - construct_ctr_preload(ctr_preload, a4_exists, qc_exists, pframe, pn_vector, num_blocks + 1); - - for (j = 0; j < 16; j++) - padded_buffer[j] = 0x00; - for (j = 0; j < payload_remainder; j++) - padded_buffer[j] = pframe[payload_index + j]; - aes128k128d(key, ctr_preload, aes_out); - bitwise_xor(aes_out, padded_buffer, chain_buffer); - for (j = 0; j < payload_remainder; j++) - pframe[payload_index++] = chain_buffer[j]; - } - /* Encrypt the MIC */ - construct_ctr_preload(ctr_preload, a4_exists, qc_exists, pframe, pn_vector, 0); - - for (j = 0; j < 16; j++) - padded_buffer[j] = 0x00; - for (j = 0; j < 8; j++) - padded_buffer[j] = pframe[j + hdrlen + 8 + plen]; - - aes128k128d(key, ctr_preload, aes_out); - bitwise_xor(aes_out, padded_buffer, chain_buffer); - for (j = 0; j < 8; j++) - pframe[payload_index++] = chain_buffer[j]; - return _SUCCESS; -} - -u32 rtw_aes_encrypt(struct adapter *padapter, struct xmit_frame *pxmitframe) -{ /* exclude ICV */ - - /*static*/ -/* unsigned char message[MAX_MSG_SIZE]; */ - - /* Intermediate Buffers */ - int curfragnum, length; - u8 *pframe, *prwskey; /* *payload,*iv */ - u8 hw_hdr_offset = 0; - struct sta_info *stainfo; - struct pkt_attrib *pattrib = &pxmitframe->attrib; - struct security_priv *psecuritypriv = &padapter->securitypriv; - struct xmit_priv *pxmitpriv = &padapter->xmitpriv; - -/* uint offset = 0; */ - u32 res = _SUCCESS; - - if (pxmitframe->buf_addr == NULL) - return _FAIL; - - hw_hdr_offset = TXDESC_SIZE + - (pxmitframe->pkt_offset * PACKET_OFFSET_SZ); - - pframe = pxmitframe->buf_addr + hw_hdr_offset; + RT_TRACE(_module_rtl871x_security_c_, _drv_err_, ("%s: stainfo!= NULL!!!\n", __func__)); - /* 4 start to encrypt each fragment */ - if (pattrib->encrypt == _AES_) { - if (pattrib->psta) - stainfo = pattrib->psta; + for (curfragnum = 0; curfragnum < pattrib->nr_frags; curfragnum++) { + if (curfragnum + 1 == pattrib->nr_frags) + length = pattrib->last_txcmdsz; else - stainfo = rtw_get_stainfo(&padapter->stapriv, &pattrib->ra[0]); + length = pxmitpriv->frag_len; - if (stainfo) { - RT_TRACE(_module_rtl871x_security_c_, _drv_err_, ("%s: stainfo!= NULL!!!\n", __func__)); + skb = dev_alloc_skb(length); + if (!skb) { + res = _FAIL; + goto exit_crypto_ops_deinit; + } - if (is_multicast_ether_addr(pattrib->ra)) - prwskey = psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].skey; - else - prwskey = &stainfo->dot118021x_UncstKey.skey[0]; - for (curfragnum = 0; curfragnum < pattrib->nr_frags; curfragnum++) { - if ((curfragnum + 1) == pattrib->nr_frags) { /* 4 the last fragment */ - length = pattrib->last_txcmdsz - pattrib->hdrlen - pattrib->iv_len - pattrib->icv_len; + skb_put_data(skb, pframe, length); - aes_cipher(prwskey, pattrib->hdrlen, pframe, length); - } else { - length = pxmitpriv->frag_len - pattrib->hdrlen - pattrib->iv_len - pattrib->icv_len; + memmove(skb->data + pattrib->iv_len, skb->data, pattrib->hdrlen); + skb_pull(skb, pattrib->iv_len); + skb_trim(skb, skb->len - pattrib->icv_len); - aes_cipher(prwskey, pattrib->hdrlen, pframe, length); - pframe += pxmitpriv->frag_len; - pframe = (u8 *)round_up((size_t)(pframe), 8); - } - } - } else { - RT_TRACE(_module_rtl871x_security_c_, _drv_err_, ("%s: stainfo==NULL!!!\n", __func__)); + if (crypto_ops->encrypt_mpdu(skb, pattrib->hdrlen, crypto_private)) { + kfree_skb(skb); res = _FAIL; + goto exit_crypto_ops_deinit; } + + memcpy(pframe, skb->data, skb->len); + + pframe += skb->len; + pframe = (u8 *)round_up((size_t)(pframe), 8); + + kfree_skb(skb); } +exit_crypto_ops_deinit: + crypto_ops->deinit(crypto_private); + +exit: return res; } @@ -1285,7 +834,7 @@ u32 rtw_aes_decrypt(struct adapter *padapter, struct recv_frame *precvframe) if (prxattrib->encrypt == _AES_) { struct sta_info *stainfo = rtw_get_stainfo(&padapter->stapriv, &prxattrib->ta[0]); - if (stainfo != NULL) { + if (stainfo) { int key_idx; const int key_length = 16, iv_len = 8, icv_len = 8; struct sk_buff *skb = precvframe->pkt; @@ -1349,190 +898,3 @@ exit_lib80211_ccmp: exit: return res; } - -/* AES tables*/ -const u32 Te0[256] = { - 0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU, - 0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U, - 0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU, - 0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU, - 0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U, - 0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU, - 0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU, - 0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU, - 0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU, - 0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU, - 0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U, - 0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU, - 0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU, - 0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U, - 0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU, - 0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU, - 0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU, - 0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU, - 0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU, - 0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U, - 0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU, - 0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU, - 0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU, - 0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU, - 0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U, - 0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U, - 0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U, - 0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U, - 0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU, - 0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U, - 0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U, - 0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU, - 0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU, - 0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U, - 0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U, - 0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U, - 0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU, - 0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U, - 0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU, - 0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U, - 0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU, - 0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U, - 0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U, - 0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU, - 0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U, - 0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U, - 0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U, - 0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U, - 0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U, - 0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U, - 0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U, - 0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U, - 0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU, - 0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U, - 0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U, - 0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U, - 0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U, - 0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U, - 0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U, - 0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU, - 0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U, - 0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U, - 0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U, - 0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU, -}; - -const u32 Td0[256] = { - 0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U, - 0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U, - 0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U, - 0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU, - 0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U, - 0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U, - 0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU, - 0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U, - 0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU, - 0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U, - 0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U, - 0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U, - 0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U, - 0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU, - 0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U, - 0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU, - 0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U, - 0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU, - 0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U, - 0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U, - 0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U, - 0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU, - 0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U, - 0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU, - 0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U, - 0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU, - 0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U, - 0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU, - 0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU, - 0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U, - 0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU, - 0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U, - 0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU, - 0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U, - 0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U, - 0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U, - 0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU, - 0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U, - 0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U, - 0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU, - 0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U, - 0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U, - 0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U, - 0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U, - 0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U, - 0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU, - 0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U, - 0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U, - 0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U, - 0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U, - 0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U, - 0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU, - 0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU, - 0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU, - 0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU, - 0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U, - 0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U, - 0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU, - 0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU, - 0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U, - 0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU, - 0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U, - 0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U, - 0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U, -}; - -const u8 Td4s[256] = { - 0x52U, 0x09U, 0x6aU, 0xd5U, 0x30U, 0x36U, 0xa5U, 0x38U, - 0xbfU, 0x40U, 0xa3U, 0x9eU, 0x81U, 0xf3U, 0xd7U, 0xfbU, - 0x7cU, 0xe3U, 0x39U, 0x82U, 0x9bU, 0x2fU, 0xffU, 0x87U, - 0x34U, 0x8eU, 0x43U, 0x44U, 0xc4U, 0xdeU, 0xe9U, 0xcbU, - 0x54U, 0x7bU, 0x94U, 0x32U, 0xa6U, 0xc2U, 0x23U, 0x3dU, - 0xeeU, 0x4cU, 0x95U, 0x0bU, 0x42U, 0xfaU, 0xc3U, 0x4eU, - 0x08U, 0x2eU, 0xa1U, 0x66U, 0x28U, 0xd9U, 0x24U, 0xb2U, - 0x76U, 0x5bU, 0xa2U, 0x49U, 0x6dU, 0x8bU, 0xd1U, 0x25U, - 0x72U, 0xf8U, 0xf6U, 0x64U, 0x86U, 0x68U, 0x98U, 0x16U, - 0xd4U, 0xa4U, 0x5cU, 0xccU, 0x5dU, 0x65U, 0xb6U, 0x92U, - 0x6cU, 0x70U, 0x48U, 0x50U, 0xfdU, 0xedU, 0xb9U, 0xdaU, - 0x5eU, 0x15U, 0x46U, 0x57U, 0xa7U, 0x8dU, 0x9dU, 0x84U, - 0x90U, 0xd8U, 0xabU, 0x00U, 0x8cU, 0xbcU, 0xd3U, 0x0aU, - 0xf7U, 0xe4U, 0x58U, 0x05U, 0xb8U, 0xb3U, 0x45U, 0x06U, - 0xd0U, 0x2cU, 0x1eU, 0x8fU, 0xcaU, 0x3fU, 0x0fU, 0x02U, - 0xc1U, 0xafU, 0xbdU, 0x03U, 0x01U, 0x13U, 0x8aU, 0x6bU, - 0x3aU, 0x91U, 0x11U, 0x41U, 0x4fU, 0x67U, 0xdcU, 0xeaU, - 0x97U, 0xf2U, 0xcfU, 0xceU, 0xf0U, 0xb4U, 0xe6U, 0x73U, - 0x96U, 0xacU, 0x74U, 0x22U, 0xe7U, 0xadU, 0x35U, 0x85U, - 0xe2U, 0xf9U, 0x37U, 0xe8U, 0x1cU, 0x75U, 0xdfU, 0x6eU, - 0x47U, 0xf1U, 0x1aU, 0x71U, 0x1dU, 0x29U, 0xc5U, 0x89U, - 0x6fU, 0xb7U, 0x62U, 0x0eU, 0xaaU, 0x18U, 0xbeU, 0x1bU, - 0xfcU, 0x56U, 0x3eU, 0x4bU, 0xc6U, 0xd2U, 0x79U, 0x20U, - 0x9aU, 0xdbU, 0xc0U, 0xfeU, 0x78U, 0xcdU, 0x5aU, 0xf4U, - 0x1fU, 0xddU, 0xa8U, 0x33U, 0x88U, 0x07U, 0xc7U, 0x31U, - 0xb1U, 0x12U, 0x10U, 0x59U, 0x27U, 0x80U, 0xecU, 0x5fU, - 0x60U, 0x51U, 0x7fU, 0xa9U, 0x19U, 0xb5U, 0x4aU, 0x0dU, - 0x2dU, 0xe5U, 0x7aU, 0x9fU, 0x93U, 0xc9U, 0x9cU, 0xefU, - 0xa0U, 0xe0U, 0x3bU, 0x4dU, 0xaeU, 0x2aU, 0xf5U, 0xb0U, - 0xc8U, 0xebU, 0xbbU, 0x3cU, 0x83U, 0x53U, 0x99U, 0x61U, - 0x17U, 0x2bU, 0x04U, 0x7eU, 0xbaU, 0x77U, 0xd6U, 0x26U, - 0xe1U, 0x69U, 0x14U, 0x63U, 0x55U, 0x21U, 0x0cU, 0x7dU, -}; -const u8 rcons[] = { - 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1B, 0x36 - /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */ -}; - -/** - * Expand the cipher key into the encryption key schedule. - * - * @return the number of rounds for the given cipher key size. - */ -#define ROUND(i, d, s) \ -do { \ - d##0 = TE0(s##0) ^ TE1(s##1) ^ TE2(s##2) ^ TE3(s##3) ^ rk[4 * i]; \ - d##1 = TE0(s##1) ^ TE1(s##2) ^ TE2(s##3) ^ TE3(s##0) ^ rk[4 * i + 1]; \ - d##2 = TE0(s##2) ^ TE1(s##3) ^ TE2(s##0) ^ TE3(s##1) ^ rk[4 * i + 2]; \ - d##3 = TE0(s##3) ^ TE1(s##0) ^ TE2(s##1) ^ TE3(s##2) ^ rk[4 * i + 3]; \ -} while (0) diff --git a/drivers/staging/rtl8188eu/core/rtw_wlan_util.c b/drivers/staging/rtl8188eu/core/rtw_wlan_util.c index be843fd2461a..26f128836a5e 100644 --- a/drivers/staging/rtl8188eu/core/rtw_wlan_util.c +++ b/drivers/staging/rtl8188eu/core/rtw_wlan_util.c @@ -53,32 +53,6 @@ static const u8 rtw_basic_rate_mix[7] = { IEEE80211_OFDM_RATE_24MB | IEEE80211_BASIC_RATE_MASK }; -bool cckrates_included(unsigned char *rate, int ratelen) -{ - int i; - - for (i = 0; i < ratelen; i++) { - u8 r = rate[i] & 0x7f; - - if (r == 2 || r == 4 || r == 11 || r == 22) - return true; - } - return false; -} - -bool cckratesonly_included(unsigned char *rate, int ratelen) -{ - int i; - - for (i = 0; i < ratelen; i++) { - u8 r = rate[i] & 0x7f; - - if (r != 2 && r != 4 && r != 11 && r != 22) - return false; - } - return true; -} - unsigned char networktype_to_raid(unsigned char network_type) { switch (network_type) { @@ -102,7 +76,7 @@ unsigned char networktype_to_raid(unsigned char network_type) } } -u8 judge_network_type(struct adapter *padapter, unsigned char *rate, int ratelen) +u8 judge_network_type(struct adapter *padapter, unsigned char *rate) { u8 network_type = 0; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; @@ -111,9 +85,9 @@ u8 judge_network_type(struct adapter *padapter, unsigned char *rate, int ratelen if (pmlmeinfo->HT_enable) network_type = WIRELESS_11_24N; - if (cckratesonly_included(rate, ratelen)) + if (rtw_is_cckratesonly_included(rate)) network_type |= WIRELESS_11B; - else if (cckrates_included(rate, ratelen)) + else if (rtw_is_cckrates_included(rate)) network_type |= WIRELESS_11BG; else network_type |= WIRELESS_11G; @@ -869,42 +843,42 @@ int rtw_check_bcn_info(struct adapter *Adapter, u8 *pframe, u32 packet_len) /* parsing HT_INFO_IE */ p = rtw_get_ie(bssid->ies + _FIXED_IE_LENGTH_, _HT_ADD_INFO_IE_, &len, bssid->ie_length - _FIXED_IE_LENGTH_); if (p && len > 0) { - pht_info = (struct HT_info_element *)(p + 2); - ht_info_infos_0 = pht_info->infos[0]; + pht_info = (struct HT_info_element *)(p + 2); + ht_info_infos_0 = pht_info->infos[0]; } else { - ht_info_infos_0 = 0; + ht_info_infos_0 = 0; } if (ht_cap_info != cur_network->BcnInfo.ht_cap_info || ((ht_info_infos_0 & 0x03) != (cur_network->BcnInfo.ht_info_infos_0 & 0x03))) { - DBG_88E("%s bcn now: ht_cap_info:%x ht_info_infos_0:%x\n", __func__, - ht_cap_info, ht_info_infos_0); - DBG_88E("%s bcn link: ht_cap_info:%x ht_info_infos_0:%x\n", __func__, - cur_network->BcnInfo.ht_cap_info, cur_network->BcnInfo.ht_info_infos_0); - DBG_88E("%s bw mode change, disconnect\n", __func__); - /* bcn_info_update */ - cur_network->BcnInfo.ht_cap_info = ht_cap_info; - cur_network->BcnInfo.ht_info_infos_0 = ht_info_infos_0; - /* to do : need to check that whether modify related register of BB or not */ - /* goto _mismatch; */ + DBG_88E("%s bcn now: ht_cap_info:%x ht_info_infos_0:%x\n", __func__, + ht_cap_info, ht_info_infos_0); + DBG_88E("%s bcn link: ht_cap_info:%x ht_info_infos_0:%x\n", __func__, + cur_network->BcnInfo.ht_cap_info, cur_network->BcnInfo.ht_info_infos_0); + DBG_88E("%s bw mode change, disconnect\n", __func__); + /* bcn_info_update */ + cur_network->BcnInfo.ht_cap_info = ht_cap_info; + cur_network->BcnInfo.ht_info_infos_0 = ht_info_infos_0; + /* to do : need to check that whether modify related register of BB or not */ + /* goto _mismatch; */ } /* Checking for channel */ p = rtw_get_ie(bssid->ies + _FIXED_IE_LENGTH_, _DSSET_IE_, &len, bssid->ie_length - _FIXED_IE_LENGTH_); if (p) { - bcn_channel = *(p + 2); + bcn_channel = *(p + 2); } else {/* In 5G, some ap do not have DSSET IE checking HT info for channel */ - p = rtw_get_ie(bssid->ies + _FIXED_IE_LENGTH_, _HT_ADD_INFO_IE_, &len, bssid->ie_length - _FIXED_IE_LENGTH_); - if (pht_info) { - bcn_channel = pht_info->primary_channel; - } else { /* we don't find channel IE, so don't check it */ - DBG_88E("Oops: %s we don't find channel IE, so don't check it\n", __func__); - bcn_channel = Adapter->mlmeextpriv.cur_channel; - } + p = rtw_get_ie(bssid->ies + _FIXED_IE_LENGTH_, _HT_ADD_INFO_IE_, &len, bssid->ie_length - _FIXED_IE_LENGTH_); + if (pht_info) { + bcn_channel = pht_info->primary_channel; + } else { /* we don't find channel IE, so don't check it */ + DBG_88E("Oops: %s we don't find channel IE, so don't check it\n", __func__); + bcn_channel = Adapter->mlmeextpriv.cur_channel; + } } if (bcn_channel != Adapter->mlmeextpriv.cur_channel) { - DBG_88E("%s beacon channel:%d cur channel:%d disconnect\n", __func__, - bcn_channel, Adapter->mlmeextpriv.cur_channel); - goto _mismatch; + DBG_88E("%s beacon channel:%d cur channel:%d disconnect\n", __func__, + bcn_channel, Adapter->mlmeextpriv.cur_channel); + goto _mismatch; } /* checking SSID */ @@ -932,7 +906,7 @@ int rtw_check_bcn_info(struct adapter *Adapter, u8 *pframe, u32 packet_len) } /* check encryption info */ - val16 = rtw_get_capability((struct wlan_bssid_ex *)bssid); + val16 = rtw_get_capability(bssid); if (val16 & BIT(4)) bssid->Privacy = 1; @@ -1043,7 +1017,7 @@ unsigned int is_ap_in_tkip(struct adapter *padapter) struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; struct wlan_bssid_ex *cur_network = &pmlmeinfo->network; - if (rtw_get_capability((struct wlan_bssid_ex *)cur_network) & WLAN_CAPABILITY_PRIVACY) { + if (rtw_get_capability(cur_network) & WLAN_CAPABILITY_PRIVACY) { for (i = sizeof(struct ndis_802_11_fixed_ie); i < pmlmeinfo->network.ie_length;) { pIE = (struct ndis_802_11_var_ie *)(pmlmeinfo->network.ies + i); @@ -1347,24 +1321,22 @@ void update_capinfo(struct adapter *Adapter, u16 updateCap) void update_wireless_mode(struct adapter *padapter) { - int ratelen, network_type = 0; + int network_type = 0; u32 SIFS_Timer; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; struct wlan_bssid_ex *cur_network = &pmlmeinfo->network; unsigned char *rate = cur_network->SupportedRates; - ratelen = rtw_get_rateset_len(cur_network->SupportedRates); - if (pmlmeinfo->HT_info_enable && pmlmeinfo->HT_caps_enable) pmlmeinfo->HT_enable = 1; if (pmlmeinfo->HT_enable) network_type = WIRELESS_11_24N; - if (cckratesonly_included(rate, ratelen)) + if (rtw_is_cckratesonly_included(rate)) network_type |= WIRELESS_11B; - else if (cckrates_included(rate, ratelen)) + else if (rtw_is_cckrates_included(rate)) network_type |= WIRELESS_11BG; else network_type |= WIRELESS_11G; diff --git a/drivers/staging/rtl8188eu/hal/hal_intf.c b/drivers/staging/rtl8188eu/hal/hal_intf.c index b8fecc952cfc..9585dffc63a3 100644 --- a/drivers/staging/rtl8188eu/hal/hal_intf.c +++ b/drivers/staging/rtl8188eu/hal/hal_intf.c @@ -23,7 +23,7 @@ uint rtw_hal_init(struct adapter *adapt) rtw_hal_notch_filter(adapt, 1); } else { adapt->hw_init_completed = false; - DBG_88E("rtw_hal_init: hal__init fail\n"); + DBG_88E("%s: hal__init fail\n", __func__); } RT_TRACE(_module_hal_init_c_, _drv_err_, @@ -41,7 +41,7 @@ uint rtw_hal_deinit(struct adapter *adapt) if (status == _SUCCESS) adapt->hw_init_completed = false; else - DBG_88E("\n rtw_hal_deinit: hal_init fail\n"); + DBG_88E("\n %s: hal_init fail\n", __func__); return status; } diff --git a/drivers/staging/rtl8188eu/hal/odm.c b/drivers/staging/rtl8188eu/hal/odm.c index 28974808839d..4d659a812aed 100644 --- a/drivers/staging/rtl8188eu/hal/odm.c +++ b/drivers/staging/rtl8188eu/hal/odm.c @@ -249,7 +249,7 @@ void odm_CommonInfoSelfUpdate(struct odm_dm_struct *pDM_Odm) void odm_CmnInfoInit_Debug(struct odm_dm_struct *pDM_Odm) { - ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("odm_CmnInfoInit_Debug==>\n")); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("%s==>\n", __func__)); ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("SupportPlatform=%d\n", pDM_Odm->SupportPlatform)); ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("SupportAbility=0x%x\n", pDM_Odm->SupportAbility)); ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("SupportInterface=%d\n", pDM_Odm->SupportInterface)); @@ -267,7 +267,7 @@ void odm_CmnInfoInit_Debug(struct odm_dm_struct *pDM_Odm) void odm_CmnInfoHook_Debug(struct odm_dm_struct *pDM_Odm) { - ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("odm_CmnInfoHook_Debug==>\n")); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("%s==>\n", __func__)); ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("pNumTxBytesUnicast=%llu\n", *pDM_Odm->pNumTxBytesUnicast)); ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("pNumRxBytesUnicast=%llu\n", *pDM_Odm->pNumRxBytesUnicast)); ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("pWirelessMode=0x%x\n", *pDM_Odm->pWirelessMode)); @@ -282,7 +282,7 @@ void odm_CmnInfoHook_Debug(struct odm_dm_struct *pDM_Odm) void odm_CmnInfoUpdate_Debug(struct odm_dm_struct *pDM_Odm) { - ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("odm_CmnInfoUpdate_Debug==>\n")); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("%s==>\n", __func__)); ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("bWIFI_Direct=%d\n", pDM_Odm->bWIFI_Direct)); ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("bWIFI_Display=%d\n", pDM_Odm->bWIFI_Display)); ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("bLinked=%d\n", pDM_Odm->bLinked)); @@ -339,21 +339,21 @@ void odm_DIG(struct odm_dm_struct *pDM_Odm) u8 dm_dig_max, dm_dig_min; u8 CurrentIGI = pDM_DigTable->CurIGValue; - ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG()==>\n")); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("%s()==>\n", __func__)); if ((!(pDM_Odm->SupportAbility & ODM_BB_DIG)) || (!(pDM_Odm->SupportAbility & ODM_BB_FA_CNT))) { ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, - ("odm_DIG() Return: SupportAbility ODM_BB_DIG or ODM_BB_FA_CNT is disabled\n")); + ("%s() Return: SupportAbility ODM_BB_DIG or ODM_BB_FA_CNT is disabled\n", __func__)); return; } if (*pDM_Odm->pbScanInProcess) { - ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG() Return: In Scan Progress\n")); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("%s() Return: In Scan Progress\n", __func__)); return; } /* add by Neil Chen to avoid PSD is processing */ if (!pDM_Odm->bDMInitialGainEnable) { - ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG() Return: PSD is Processing\n")); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("%s() Return: PSD is Processing\n", __func__)); return; } @@ -383,18 +383,18 @@ void odm_DIG(struct odm_dm_struct *pDM_Odm) else DIG_Dynamic_MIN = pDM_Odm->RSSI_Min; ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, - ("odm_DIG() : bOneEntryOnly=true, DIG_Dynamic_MIN=0x%x\n", - DIG_Dynamic_MIN)); + ("%s() : bOneEntryOnly=true, DIG_Dynamic_MIN=0x%x\n", + __func__, DIG_Dynamic_MIN)); ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, - ("odm_DIG() : pDM_Odm->RSSI_Min=%d\n", - pDM_Odm->RSSI_Min)); + ("%s() : pDM_Odm->RSSI_Min=%d\n", + __func__, pDM_Odm->RSSI_Min)); } else if (pDM_Odm->SupportAbility & ODM_BB_ANT_DIV) { /* 1 Lower Bound for 88E AntDiv */ if (pDM_Odm->AntDivType == CG_TRX_HW_ANTDIV) { DIG_Dynamic_MIN = (u8)pDM_DigTable->AntDiv_RSSI_max; ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, - ("odm_DIG(): pDM_DigTable->AntDiv_RSSI_max=%d\n", - pDM_DigTable->AntDiv_RSSI_max)); + ("%s(): pDM_DigTable->AntDiv_RSSI_max=%d\n", + __func__, pDM_DigTable->AntDiv_RSSI_max)); } } else { DIG_Dynamic_MIN = dm_dig_min; @@ -402,7 +402,7 @@ void odm_DIG(struct odm_dm_struct *pDM_Odm) } else { pDM_DigTable->rx_gain_range_max = dm_dig_max; DIG_Dynamic_MIN = dm_dig_min; - ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG() : No Link\n")); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("%s() : No Link\n", __func__)); } /* 1 Modify DIG lower bound, deal with abnormally large false alarm */ @@ -433,11 +433,11 @@ void odm_DIG(struct odm_dm_struct *pDM_Odm) if ((pDM_DigTable->ForbiddenIGI - 1) < DIG_Dynamic_MIN) { /* DM_DIG_MIN) */ pDM_DigTable->ForbiddenIGI = DIG_Dynamic_MIN; /* DM_DIG_MIN; */ pDM_DigTable->rx_gain_range_min = DIG_Dynamic_MIN; /* DM_DIG_MIN; */ - ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Normal Case: At Lower Bound\n")); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("%s(): Normal Case: At Lower Bound\n", __func__)); } else { pDM_DigTable->ForbiddenIGI--; pDM_DigTable->rx_gain_range_min = (pDM_DigTable->ForbiddenIGI + 1); - ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Normal Case: Approach Lower Bound\n")); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("%s(): Normal Case: Approach Lower Bound\n", __func__)); } } else { pDM_DigTable->LargeFAHit = 0; @@ -445,12 +445,12 @@ void odm_DIG(struct odm_dm_struct *pDM_Odm) } } ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, - ("odm_DIG(): pDM_DigTable->LargeFAHit=%d\n", - pDM_DigTable->LargeFAHit)); + ("%s(): pDM_DigTable->LargeFAHit=%d\n", + __func__, pDM_DigTable->LargeFAHit)); /* 1 Adjust initial gain by false alarm */ if (pDM_Odm->bLinked) { - ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): DIG AfterLink\n")); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("%s(): DIG AfterLink\n", __func__)); if (FirstConnect) { CurrentIGI = pDM_Odm->RSSI_Min; ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("DIG: First Connect\n")); @@ -463,10 +463,10 @@ void odm_DIG(struct odm_dm_struct *pDM_Odm) CurrentIGI = CurrentIGI - 2;/* pDM_DigTable->CurIGValue =pDM_DigTable->PreIGValue-1; */ } } else { - ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): DIG BeforeLink\n")); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("%s(): DIG BeforeLink\n", __func__)); if (FirstDisConnect) { CurrentIGI = pDM_DigTable->rx_gain_range_min; - ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): First DisConnect\n")); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("%s(): First DisConnect\n", __func__)); } else { /* 2012.03.30 LukeLee: enable DIG before link but with very high thresholds */ if (pFalseAlmCnt->Cnt_all > 10000) @@ -475,10 +475,10 @@ void odm_DIG(struct odm_dm_struct *pDM_Odm) CurrentIGI = CurrentIGI + 1;/* pDM_DigTable->CurIGValue = pDM_DigTable->PreIGValue+1; */ else if (pFalseAlmCnt->Cnt_all < 500) CurrentIGI = CurrentIGI - 1;/* pDM_DigTable->CurIGValue =pDM_DigTable->PreIGValue-1; */ - ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): England DIG\n")); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("%s(): England DIG\n", __func__)); } } - ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): DIG End Adjust IGI\n")); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("%s(): DIG End Adjust IGI\n", __func__)); /* 1 Check initial gain by upper/lower bound */ if (CurrentIGI > pDM_DigTable->rx_gain_range_max) CurrentIGI = pDM_DigTable->rx_gain_range_max; @@ -486,10 +486,10 @@ void odm_DIG(struct odm_dm_struct *pDM_Odm) CurrentIGI = pDM_DigTable->rx_gain_range_min; ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, - ("odm_DIG(): rx_gain_range_max=0x%x, rx_gain_range_min=0x%x\n", - pDM_DigTable->rx_gain_range_max, pDM_DigTable->rx_gain_range_min)); - ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): TotalFA=%d\n", pFalseAlmCnt->Cnt_all)); - ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): CurIGValue=0x%x\n", CurrentIGI)); + ("%s(): rx_gain_range_max=0x%x, rx_gain_range_min=0x%x\n", + __func__, pDM_DigTable->rx_gain_range_max, pDM_DigTable->rx_gain_range_min)); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("%s(): TotalFA=%d\n", __func__, pFalseAlmCnt->Cnt_all)); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("%s(): CurIGValue=0x%x\n", __func__, CurrentIGI)); /* 2 High power RSSI threshold */ @@ -557,7 +557,7 @@ void odm_FalseAlarmCounterStatistics(struct odm_dm_struct *pDM_Odm) FalseAlmCnt->Cnt_CCA_all = FalseAlmCnt->Cnt_OFDM_CCA + FalseAlmCnt->Cnt_CCK_CCA; - ODM_RT_TRACE(pDM_Odm, ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("Enter odm_FalseAlarmCounterStatistics\n")); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("Enter %s\n", __func__)); ODM_RT_TRACE(pDM_Odm, ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("Cnt_Fast_Fsync=%d, Cnt_SB_Search_fail=%d\n", FalseAlmCnt->Cnt_Fast_Fsync, FalseAlmCnt->Cnt_SB_Search_fail)); @@ -829,9 +829,9 @@ bool ODM_RAStateCheck(struct odm_dm_struct *pDM_Odm, s32 RSSI, bool bForceUpdate } /* Decide RATRState by RSSI. */ - if (RSSI > HighRSSIThreshForRA) + if (HighRSSIThreshForRA < RSSI) RATRState = DM_RATR_STA_HIGH; - else if (RSSI > LowRSSIThreshForRA) + else if (LowRSSIThreshForRA < RSSI) RATRState = DM_RATR_STA_MIDDLE; else RATRState = DM_RATR_STA_LOW; @@ -969,7 +969,6 @@ void ODM_TXPowerTrackingCheck(struct odm_dm_struct *pDM_Odm) rtl88eu_dm_txpower_tracking_callback_thermalmeter(Adapter); pDM_Odm->RFCalibrateInfo.TM_Trigger = 0; - } /* 3============================================================ */ @@ -1016,13 +1015,13 @@ void odm_EdcaTurboCheck(struct odm_dm_struct *pDM_Odm) /* 2011/09/29 MH In HW integration first stage, we provide 4 different handle to operate */ /* at the same time. In the stage2/3, we need to prive universal interface and merge all */ /* HW dynamic mechanism. */ - ODM_RT_TRACE(pDM_Odm, ODM_COMP_EDCA_TURBO, ODM_DBG_LOUD, ("odm_EdcaTurboCheck========================>\n")); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_EDCA_TURBO, ODM_DBG_LOUD, ("%s========================>\n", __func__)); if (!(pDM_Odm->SupportAbility & ODM_MAC_EDCA_TURBO)) return; odm_EdcaTurboCheckCE(pDM_Odm); - ODM_RT_TRACE(pDM_Odm, ODM_COMP_EDCA_TURBO, ODM_DBG_LOUD, ("<========================odm_EdcaTurboCheck\n")); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_EDCA_TURBO, ODM_DBG_LOUD, ("<========================%s\n", __func__)); } /* odm_CheckEdcaTurbo */ void odm_EdcaTurboCheckCE(struct odm_dm_struct *pDM_Odm) diff --git a/drivers/staging/rtl8188eu/hal/phy.c b/drivers/staging/rtl8188eu/hal/phy.c index 920688fc9e9f..a970189ba8c6 100644 --- a/drivers/staging/rtl8188eu/hal/phy.c +++ b/drivers/staging/rtl8188eu/hal/phy.c @@ -51,8 +51,7 @@ void phy_set_bb_reg(struct adapter *adapt, u32 regaddr, u32 bitmask, u32 data) usb_write32(adapt, regaddr, data); } -static u32 rf_serial_read(struct adapter *adapt, - enum rf_radio_path rfpath, u32 offset) +static u32 rf_serial_read(struct adapter *adapt, enum rf_radio_path rfpath, u32 offset) { u32 ret = 0; struct bb_reg_def *phyreg = &adapt->HalData->PHYRegDef[rfpath]; @@ -107,7 +106,7 @@ static void rf_serial_write(struct adapter *adapt, } u32 rtw_hal_read_rfreg(struct adapter *adapt, enum rf_radio_path rf_path, - u32 reg_addr, u32 bit_mask) + u32 reg_addr, u32 bit_mask) { u32 original_value, bit_shift; @@ -117,7 +116,7 @@ u32 rtw_hal_read_rfreg(struct adapter *adapt, enum rf_radio_path rf_path, } void phy_set_rf_reg(struct adapter *adapt, enum rf_radio_path rf_path, - u32 reg_addr, u32 bit_mask, u32 data) + u32 reg_addr, u32 bit_mask, u32 data) { u32 original_value, bit_shift; @@ -190,7 +189,7 @@ void phy_set_tx_power_level(struct adapter *adapt, u8 channel) rtl88eu_phy_rf6052_set_cck_txpower(adapt, &cck_pwr[0]); rtl88eu_phy_rf6052_set_ofdm_txpower(adapt, &ofdm_pwr[0], &bw20_pwr[0], - &bw40_pwr[0], channel); + &bw40_pwr[0], channel); } static void phy_set_bw_mode_callback(struct adapter *adapt) @@ -236,11 +235,11 @@ static void phy_set_bw_mode_callback(struct adapter *adapt) * These settings are required only for 40MHz */ phy_set_bb_reg(adapt, rCCK0_System, bCCKSideBand, - (hal_data->nCur40MhzPrimeSC >> 1)); + (hal_data->nCur40MhzPrimeSC >> 1)); phy_set_bb_reg(adapt, rOFDM1_LSTF, 0xC00, hal_data->nCur40MhzPrimeSC); phy_set_bb_reg(adapt, 0x818, (BIT(26) | BIT(27)), - (hal_data->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1); + (hal_data->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1); break; default: break; @@ -251,7 +250,7 @@ static void phy_set_bw_mode_callback(struct adapter *adapt) } void rtw_hal_set_bwmode(struct adapter *adapt, enum ht_channel_width bandwidth, - unsigned char offset) + unsigned char offset) { struct hal_data_8188e *hal_data = adapt->HalData; enum ht_channel_width tmp_bw = hal_data->CurrentChannelBW; @@ -345,7 +344,7 @@ static void dm_txpwr_track_setpwr(struct odm_dm_struct *dm_odm) { if (dm_odm->BbSwingFlagOfdm || dm_odm->BbSwingFlagCck) { ODM_RT_TRACE(dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, - ("dm_txpwr_track_setpwr CH=%d\n", *dm_odm->pChannel)); + ("%s CH=%d\n", __func__, *dm_odm->pChannel)); phy_set_tx_power_level(dm_odm->Adapter, *dm_odm->pChannel); dm_odm->BbSwingFlagOfdm = false; dm_odm->BbSwingFlagCck = false; @@ -403,11 +402,11 @@ void rtl88eu_dm_txpower_tracking_callback_thermalmeter(struct adapter *adapt) for (i = 0; i < CCK_TABLE_SIZE; i++) { if ((dm_odm->RFCalibrateInfo.bCCKinCH14 && - memcmp(&temp_cck, &CCKSwingTable_Ch14[i][2], 4)) || - memcmp(&temp_cck, &CCKSwingTable_Ch1_Ch13[i][2], 4)) { - cck_index_old = (u8)i; - dm_odm->BbSwingIdxCckBase = (u8)i; - break; + memcmp(&temp_cck, &CCKSwingTable_Ch14[i][2], 4)) || + memcmp(&temp_cck, &CCKSwingTable_Ch1_Ch13[i][2], 4)) { + cck_index_old = (u8)i; + dm_odm->BbSwingIdxCckBase = (u8)i; + break; } } @@ -437,7 +436,7 @@ void rtl88eu_dm_txpower_tracking_callback_thermalmeter(struct adapter *adapt) thermal_val = (u8)(thermal_avg / thermal_avg_count); if (dm_odm->RFCalibrateInfo.bDoneTxpower && - !dm_odm->RFCalibrateInfo.bReloadtxpowerindex) { + !dm_odm->RFCalibrateInfo.bReloadtxpowerindex) { delta = abs(thermal_val - dm_odm->RFCalibrateInfo.ThermalValue); } else { delta = abs(thermal_val - hal_data->EEPROMThermalMeter); @@ -1039,10 +1038,10 @@ static void phy_iq_calibrate(struct adapter *adapt, s32 result[][8], for (i = 0; i < retry_count; i++) { path_a_ok = phy_path_a_iqk(adapt, is2t); if (path_a_ok == 0x01) { - result[t][0] = (phy_query_bb_reg(adapt, rTx_Power_Before_IQK_A, - bMaskDWord) & 0x3FF0000) >> 16; - result[t][1] = (phy_query_bb_reg(adapt, rTx_Power_After_IQK_A, - bMaskDWord) & 0x3FF0000) >> 16; + result[t][0] = (phy_query_bb_reg(adapt, rTx_Power_Before_IQK_A, + bMaskDWord) & 0x3FF0000) >> 16; + result[t][1] = (phy_query_bb_reg(adapt, rTx_Power_After_IQK_A, + bMaskDWord) & 0x3FF0000) >> 16; break; } } @@ -1050,10 +1049,10 @@ static void phy_iq_calibrate(struct adapter *adapt, s32 result[][8], for (i = 0; i < retry_count; i++) { path_a_ok = phy_path_a_rx_iqk(adapt, is2t); if (path_a_ok == 0x03) { - result[t][2] = (phy_query_bb_reg(adapt, rRx_Power_Before_IQK_A_2, - bMaskDWord) & 0x3FF0000) >> 16; - result[t][3] = (phy_query_bb_reg(adapt, rRx_Power_After_IQK_A_2, - bMaskDWord) & 0x3FF0000) >> 16; + result[t][2] = (phy_query_bb_reg(adapt, rRx_Power_Before_IQK_A_2, + bMaskDWord) & 0x3FF0000) >> 16; + result[t][3] = (phy_query_bb_reg(adapt, rRx_Power_After_IQK_A_2, + bMaskDWord) & 0x3FF0000) >> 16; break; } ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, @@ -1149,12 +1148,12 @@ static void phy_lc_calibrate(struct adapter *adapt, bool is2t) /* 1. Read original RF mode */ /* Path-A */ rf_a_mode = rtw_hal_read_rfreg(adapt, RF_PATH_A, RF_AC, - bMask12Bits); + bMask12Bits); /* Path-B */ if (is2t) rf_b_mode = rtw_hal_read_rfreg(adapt, RF_PATH_B, RF_AC, - bMask12Bits); + bMask12Bits); /* 2. Set RF mode = standby mode */ /* Path-A */ diff --git a/drivers/staging/rtl8188eu/hal/pwrseqcmd.c b/drivers/staging/rtl8188eu/hal/pwrseqcmd.c index 77edd7ad19a1..34784943a7d1 100644 --- a/drivers/staging/rtl8188eu/hal/pwrseqcmd.c +++ b/drivers/staging/rtl8188eu/hal/pwrseqcmd.c @@ -26,25 +26,26 @@ u8 rtl88eu_pwrseqcmdparsing(struct adapter *padapter, u8 cut_vers, pwrcfgcmd = pwrseqcmd[aryidx]; RT_TRACE(_module_hal_init_c_, _drv_info_, - ("rtl88eu_pwrseqcmdparsing: offset(%#x) cut_msk(%#x)" + ("%s: offset(%#x) cut_msk(%#x)" " cmd(%#x)" "msk(%#x) value(%#x)\n", - GET_PWR_CFG_OFFSET(pwrcfgcmd), - GET_PWR_CFG_CUT_MASK(pwrcfgcmd), - GET_PWR_CFG_CMD(pwrcfgcmd), - GET_PWR_CFG_MASK(pwrcfgcmd), - GET_PWR_CFG_VALUE(pwrcfgcmd))); + __func__, + GET_PWR_CFG_OFFSET(pwrcfgcmd), + GET_PWR_CFG_CUT_MASK(pwrcfgcmd), + GET_PWR_CFG_CMD(pwrcfgcmd), + GET_PWR_CFG_MASK(pwrcfgcmd), + GET_PWR_CFG_VALUE(pwrcfgcmd))); /* Only Handle the command whose CUT is matched */ if (GET_PWR_CFG_CUT_MASK(pwrcfgcmd) & cut_vers) { switch (GET_PWR_CFG_CMD(pwrcfgcmd)) { case PWR_CMD_READ: RT_TRACE(_module_hal_init_c_, _drv_info_, - ("rtl88eu_pwrseqcmdparsing: PWR_CMD_READ\n")); + ("%s: PWR_CMD_READ\n", __func__)); break; case PWR_CMD_WRITE: RT_TRACE(_module_hal_init_c_, _drv_info_, - ("rtl88eu_pwrseqcmdparsing: PWR_CMD_WRITE\n")); + ("%s: PWR_CMD_WRITE\n", __func__)); offset = GET_PWR_CFG_OFFSET(pwrcfgcmd); /* Read the value from system register */ @@ -59,7 +60,7 @@ u8 rtl88eu_pwrseqcmdparsing(struct adapter *padapter, u8 cut_vers, break; case PWR_CMD_POLLING: RT_TRACE(_module_hal_init_c_, _drv_info_, - ("rtl88eu_pwrseqcmdparsing: PWR_CMD_POLLING\n")); + ("%s: PWR_CMD_POLLING\n", __func__)); poll_bit = false; offset = GET_PWR_CFG_OFFSET(pwrcfgcmd); @@ -81,7 +82,7 @@ u8 rtl88eu_pwrseqcmdparsing(struct adapter *padapter, u8 cut_vers, break; case PWR_CMD_DELAY: RT_TRACE(_module_hal_init_c_, _drv_info_, - ("rtl88eu_pwrseqcmdparsing: PWR_CMD_DELAY\n")); + ("%s: PWR_CMD_DELAY\n", __func__)); if (GET_PWR_CFG_VALUE(pwrcfgcmd) == PWRSEQ_DELAY_US) udelay(GET_PWR_CFG_OFFSET(pwrcfgcmd)); else @@ -90,11 +91,11 @@ u8 rtl88eu_pwrseqcmdparsing(struct adapter *padapter, u8 cut_vers, case PWR_CMD_END: /* When this command is parsed, end the process */ RT_TRACE(_module_hal_init_c_, _drv_info_, - ("rtl88eu_pwrseqcmdparsing: PWR_CMD_END\n")); + ("%s: PWR_CMD_END\n", __func__)); return true; default: RT_TRACE(_module_hal_init_c_, _drv_err_, - ("rtl88eu_pwrseqcmdparsing: Unknown CMD!!\n")); + ("%s: Unknown CMD!!\n", __func__)); break; } } diff --git a/drivers/staging/rtl8188eu/hal/rf.c b/drivers/staging/rtl8188eu/hal/rf.c index 6702f263c770..aab0f54a75fc 100644 --- a/drivers/staging/rtl8188eu/hal/rf.c +++ b/drivers/staging/rtl8188eu/hal/rf.c @@ -138,6 +138,7 @@ static void getpowerbase88e(struct adapter *adapt, u8 *pwr_level_ofdm, (powerbase1 << 8) | powerbase1; *mcs_base = powerbase1; } + static void get_rx_power_val_by_reg(struct adapter *adapt, u8 channel, u8 index, u32 *powerbase0, u32 *powerbase1, u32 *out_val) diff --git a/drivers/staging/rtl8188eu/hal/rf_cfg.c b/drivers/staging/rtl8188eu/hal/rf_cfg.c index 0b20e62f9a68..d39e1bd97f85 100644 --- a/drivers/staging/rtl8188eu/hal/rf_cfg.c +++ b/drivers/staging/rtl8188eu/hal/rf_cfg.c @@ -171,8 +171,7 @@ static void rtl_rfreg_delay(struct adapter *adapt, enum rf_radio_path rfpath, u3 } } -static void rtl8188e_config_rf_reg(struct adapter *adapt, - u32 addr, u32 data) +static void rtl8188e_config_rf_reg(struct adapter *adapt, u32 addr, u32 data) { u32 content = 0x1000; /*RF Content: radio_a_txt*/ u32 maskforphyset = content & 0xE000; @@ -206,8 +205,8 @@ static bool rtl88e_phy_config_rf_with_headerfile(struct adapter *adapt) READ_NEXT_PAIR(v1, v2, i); while (v2 != 0xDEAD && v2 != 0xCDEF && v2 != 0xCDCD && i < array_len - 2) { - rtl8188e_config_rf_reg(adapt, v1, v2); - READ_NEXT_PAIR(v1, v2, i); + rtl8188e_config_rf_reg(adapt, v1, v2); + READ_NEXT_PAIR(v1, v2, i); } while (v2 != 0xDEAD && i < array_len - 2) diff --git a/drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c b/drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c index 2baef9a285c0..95b27b4df705 100644 --- a/drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c +++ b/drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c @@ -95,7 +95,7 @@ void _8051Reset88E(struct adapter *padapter) u1bTmp = usb_read8(padapter, REG_SYS_FUNC_EN + 1); usb_write8(padapter, REG_SYS_FUNC_EN + 1, u1bTmp & (~BIT(2))); usb_write8(padapter, REG_SYS_FUNC_EN + 1, u1bTmp | (BIT(2))); - DBG_88E("=====> _8051Reset88E(): 8051 reset success .\n"); + DBG_88E("=====> %s(): 8051 reset success .\n", __func__); } void rtl8188e_InitializeFirmwareVars(struct adapter *padapter) @@ -187,7 +187,7 @@ static s32 _LLTWrite(struct adapter *padapter, u32 address, u32 data) /* polling */ do { value = usb_read32(padapter, LLTReg); - if (_LLT_NO_ACTIVE == _LLT_OP_VALUE(value)) + if (_LLT_OP_VALUE(value) == _LLT_NO_ACTIVE) break; if (count > POLLING_LLT_THRESHOLD) { @@ -406,7 +406,7 @@ void Hal_ReadPowerSavingMode88E(struct adapter *padapter, u8 *hwinfo, bool AutoL padapter->pwrctrlpriv.bSupportRemoteWakeup = (hwinfo[EEPROM_USB_OPTIONAL_FUNCTION0] & BIT(1)) ? true : false; DBG_88E("%s...bHWPwrPindetect(%x)-bHWPowerdown(%x) , bSupportRemoteWakeup(%x)\n", __func__, - padapter->pwrctrlpriv.bHWPwrPindetect, padapter->pwrctrlpriv.bHWPowerdown, padapter->pwrctrlpriv.bSupportRemoteWakeup); + padapter->pwrctrlpriv.bHWPwrPindetect, padapter->pwrctrlpriv.bHWPowerdown, padapter->pwrctrlpriv.bSupportRemoteWakeup); DBG_88E("### PS params => power_mgnt(%x), usbss_enable(%x) ###\n", padapter->registrypriv.power_mgnt, padapter->registrypriv.usbss_enable); } diff --git a/drivers/staging/rtl8188eu/hal/rtl8188eu_recv.c b/drivers/staging/rtl8188eu/hal/rtl8188eu_recv.c index 7badfc2e45df..25f46b2f4920 100644 --- a/drivers/staging/rtl8188eu/hal/rtl8188eu_recv.c +++ b/drivers/staging/rtl8188eu/hal/rtl8188eu_recv.c @@ -22,8 +22,7 @@ int rtw_hal_init_recv_priv(struct adapter *padapter) int i, res = _SUCCESS; struct recv_buf *precvbuf; - tasklet_init(&precvpriv->recv_tasklet, rtl8188eu_recv_tasklet, - (unsigned long)padapter); + tasklet_setup(&precvpriv->recv_tasklet, rtl8188eu_recv_tasklet); /* init recv_buf */ _rtw_init_queue(&precvpriv->free_recv_buf_queue); diff --git a/drivers/staging/rtl8188eu/hal/rtl8188eu_xmit.c b/drivers/staging/rtl8188eu/hal/rtl8188eu_xmit.c index 7d315bd438d4..2866283c211d 100644 --- a/drivers/staging/rtl8188eu/hal/rtl8188eu_xmit.c +++ b/drivers/staging/rtl8188eu/hal/rtl8188eu_xmit.c @@ -17,8 +17,7 @@ s32 rtw_hal_init_xmit_priv(struct adapter *adapt) { struct xmit_priv *pxmitpriv = &adapt->xmitpriv; - tasklet_init(&pxmitpriv->xmit_tasklet, rtl8188eu_xmit_tasklet, - (unsigned long)adapt); + tasklet_setup(&pxmitpriv->xmit_tasklet, rtl8188eu_xmit_tasklet); return _SUCCESS; } @@ -347,7 +346,7 @@ static s32 rtw_dump_xframe(struct adapter *adapt, struct xmit_frame *pxmitframe) rtw_issue_addbareq_cmd(adapt, pxmitframe); mem_addr = pxmitframe->buf_addr; - RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("rtw_dump_xframe()\n")); + RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("%s()\n", __func__)); for (t = 0; t < pattrib->nr_frags; t++) { if (inner_ret != _SUCCESS && ret == _SUCCESS) diff --git a/drivers/staging/rtl8188eu/hal/usb_halinit.c b/drivers/staging/rtl8188eu/hal/usb_halinit.c index 114638f6f719..abe58cf2de16 100644 --- a/drivers/staging/rtl8188eu/hal/usb_halinit.c +++ b/drivers/staging/rtl8188eu/hal/usb_halinit.c @@ -78,8 +78,8 @@ void rtw_hal_chip_configure(struct adapter *adapt) haldata->UsbRxAggPageCount = 48; /* uint :128 b 0x0A; 10 = MAX_RX_DMA_BUFFER_SIZE/2/haldata->UsbBulkOutSize */ haldata->UsbRxAggPageTimeout = 0x4; /* 6, absolute time = 34ms/(2^6) */ - HalUsbSetQueuePipeMapping8188EUsb(adapt, - pdvobjpriv->RtNumInPipes, pdvobjpriv->RtNumOutPipes); + HalUsbSetQueuePipeMapping8188EUsb(adapt, pdvobjpriv->RtNumInPipes, + pdvobjpriv->RtNumOutPipes); } u32 rtw_hal_power_on(struct adapter *adapt) @@ -876,7 +876,7 @@ static void CardDisableRTL8188EU(struct adapter *Adapter) { u8 val8; - RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("CardDisableRTL8188EU\n")); + RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("%s\n", __func__)); /* Stop Tx Report Timer. 0x4EC[Bit1]=b'0 */ val8 = usb_read8(Adapter, REG_TX_RPT_CTRL); @@ -1038,8 +1038,7 @@ static void Hal_EfuseParseMACAddr_8188EU(struct adapter *adapt, u8 *hwinfo, bool memcpy(eeprom->mac_addr, &hwinfo[EEPROM_MAC_ADDR_88EU], ETH_ALEN); } RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, - ("Hal_EfuseParseMACAddr_8188EU: Permanent Address = %pM\n", - eeprom->mac_addr)); + ("%s: Permanent Address = %pM\n", __func__, eeprom->mac_addr)); } static void readAdapterInfo_8188EU(struct adapter *adapt) @@ -1894,7 +1893,7 @@ void UpdateHalRAMask8188EUsb(struct adapter *adapt, u32 mac_id, u8 rssi_level) switch (mac_id) { case 0:/* for infra mode */ supportRateNum = rtw_get_rateset_len(cur_network->SupportedRates); - networkType = judge_network_type(adapt, cur_network->SupportedRates, supportRateNum) & 0xf; + networkType = judge_network_type(adapt, cur_network->SupportedRates) & 0xf; raid = networktype_to_raid(networkType); mask = update_supported_rate(cur_network->SupportedRates, supportRateNum); mask |= (pmlmeinfo->HT_enable) ? update_MSC_rate(&pmlmeinfo->HT_caps) : 0; @@ -1912,7 +1911,7 @@ void UpdateHalRAMask8188EUsb(struct adapter *adapt, u32 mac_id, u8 rssi_level) break; default: /* for each sta in IBSS */ supportRateNum = rtw_get_rateset_len(pmlmeinfo->FW_sta_info[mac_id].SupportedRates); - networkType = judge_network_type(adapt, pmlmeinfo->FW_sta_info[mac_id].SupportedRates, supportRateNum) & 0xf; + networkType = judge_network_type(adapt, pmlmeinfo->FW_sta_info[mac_id].SupportedRates) & 0xf; raid = networktype_to_raid(networkType); mask = update_supported_rate(cur_network->SupportedRates, supportRateNum); diff --git a/drivers/staging/rtl8188eu/include/ieee80211.h b/drivers/staging/rtl8188eu/include/ieee80211.h index 83218e7ec0a9..cb6940d2aeab 100644 --- a/drivers/staging/rtl8188eu/include/ieee80211.h +++ b/drivers/staging/rtl8188eu/include/ieee80211.h @@ -526,16 +526,6 @@ enum rtw_ieee80211_category { RTW_WLAN_CATEGORY_P2P = 0x7f,/* P2P action frames */ }; -/* SPECTRUM_MGMT action code */ -enum rtw_ieee80211_spectrum_mgmt_actioncode { - RTW_WLAN_ACTION_SPCT_MSR_REQ = 0, - RTW_WLAN_ACTION_SPCT_MSR_RPRT = 1, - RTW_WLAN_ACTION_SPCT_TPC_REQ = 2, - RTW_WLAN_ACTION_SPCT_TPC_RPRT = 3, - RTW_WLAN_ACTION_SPCT_CHL_SWITCH = 4, - RTW_WLAN_ACTION_SPCT_EXT_CHL_SWITCH = 5, -}; - enum _PUBLIC_ACTION { ACT_PUBLIC_BSSCOEXIST = 0, /* 20/40 BSS Coexistence */ ACT_PUBLIC_DSE_ENABLE = 1, diff --git a/drivers/staging/rtl8188eu/include/osdep_service.h b/drivers/staging/rtl8188eu/include/osdep_service.h index b44d602e954a..56e937b26407 100644 --- a/drivers/staging/rtl8188eu/include/osdep_service.h +++ b/drivers/staging/rtl8188eu/include/osdep_service.h @@ -69,6 +69,7 @@ void _rtw_init_queue(struct __queue *pqueue); struct rtw_netdev_priv_indicator { void *priv; }; + struct net_device *rtw_alloc_etherdev_with_old_priv(void *old_priv); static inline struct adapter *rtw_netdev_priv(struct net_device *netdev) diff --git a/drivers/staging/rtl8188eu/include/rtl8188e_recv.h b/drivers/staging/rtl8188eu/include/rtl8188e_recv.h index 23251ffa8404..fea1119c426e 100644 --- a/drivers/staging/rtl8188eu/include/rtl8188e_recv.h +++ b/drivers/staging/rtl8188eu/include/rtl8188e_recv.h @@ -43,7 +43,7 @@ enum rx_packet_type { }; #define INTERRUPT_MSG_FORMAT_LEN 60 -void rtl8188eu_recv_tasklet(unsigned long priv); +void rtl8188eu_recv_tasklet(struct tasklet_struct *t); void rtl8188e_process_phy_info(struct adapter *padapter, struct recv_frame *prframe); void update_recvframe_phyinfo_88e(struct recv_frame *fra, struct phy_stat *phy); diff --git a/drivers/staging/rtl8188eu/include/rtl8188e_xmit.h b/drivers/staging/rtl8188eu/include/rtl8188e_xmit.h index 85efa41c8350..617c2273b41b 100644 --- a/drivers/staging/rtl8188eu/include/rtl8188e_xmit.h +++ b/drivers/staging/rtl8188eu/include/rtl8188e_xmit.h @@ -94,6 +94,7 @@ enum TXDESC_SC { SC_LOWER = 0x02, SC_DUPLICATE = 0x03 }; + /* OFFSET 20 */ #define SGI BIT(6) #define USB_TXAGG_NUM_SHT 24 @@ -147,7 +148,7 @@ void rtl8188e_fill_fake_txdesc(struct adapter *padapter, u8 *pDesc, s32 rtl8188eu_init_xmit_priv(struct adapter *padapter); s32 rtl8188eu_xmit_buf_handler(struct adapter *padapter); #define hal_xmit_handler rtl8188eu_xmit_buf_handler -void rtl8188eu_xmit_tasklet(unsigned long priv); +void rtl8188eu_xmit_tasklet(struct tasklet_struct *t); bool rtl8188eu_xmitframe_complete(struct adapter *padapter, struct xmit_priv *pxmitpriv); diff --git a/drivers/staging/rtl8188eu/include/rtw_mlme.h b/drivers/staging/rtl8188eu/include/rtw_mlme.h index 010f0c42368a..1b74b32b8a81 100644 --- a/drivers/staging/rtl8188eu/include/rtw_mlme.h +++ b/drivers/staging/rtl8188eu/include/rtw_mlme.h @@ -266,7 +266,7 @@ static inline void set_fwstate(struct mlme_priv *pmlmepriv, int state) { pmlmepriv->fw_state |= state; /* FOR HW integration */ - if (_FW_UNDER_SURVEY == state) + if (state == _FW_UNDER_SURVEY) pmlmepriv->bScanInProcess = true; } @@ -274,7 +274,7 @@ static inline void _clr_fwstate_(struct mlme_priv *pmlmepriv, int state) { pmlmepriv->fw_state &= ~state; /* FOR HW integration */ - if (_FW_UNDER_SURVEY == state) + if (state == _FW_UNDER_SURVEY) pmlmepriv->bScanInProcess = false; } diff --git a/drivers/staging/rtl8188eu/include/rtw_mlme_ext.h b/drivers/staging/rtl8188eu/include/rtw_mlme_ext.h index 565bfe46256c..b11a6886a083 100644 --- a/drivers/staging/rtl8188eu/include/rtw_mlme_ext.h +++ b/drivers/staging/rtl8188eu/include/rtw_mlme_ext.h @@ -448,7 +448,7 @@ void init_addba_retry_timer(struct adapter *adapt, struct sta_info *sta); struct xmit_frame *alloc_mgtxmitframe(struct xmit_priv *pxmitpriv); unsigned char networktype_to_raid(unsigned char network_type); -u8 judge_network_type(struct adapter *padapter, unsigned char *rate, int len); +u8 judge_network_type(struct adapter *padapter, unsigned char *rate); void get_rate_set(struct adapter *padapter, unsigned char *pbssrate, int *len); void UpdateBrateTbl(struct adapter *padapter, u8 *mBratesOS); void UpdateBrateTblForSoftAP(u8 *bssrateset, u32 bssratelen); @@ -568,9 +568,6 @@ void addba_timer_hdl(struct timer_list *t); mod_timer(&mlmeext->link_timer, jiffies + \ msecs_to_jiffies(ms)) -bool cckrates_included(unsigned char *rate, int ratelen); -bool cckratesonly_included(unsigned char *rate, int ratelen); - void process_addba_req(struct adapter *padapter, u8 *paddba_req, u8 *addr); void update_TSF(struct mlme_ext_priv *pmlmeext, u8 *pframe, uint len); diff --git a/drivers/staging/rtl8188eu/include/rtw_recv.h b/drivers/staging/rtl8188eu/include/rtw_recv.h index b281b9e7fcea..e20bab41708a 100644 --- a/drivers/staging/rtl8188eu/include/rtw_recv.h +++ b/drivers/staging/rtl8188eu/include/rtw_recv.h @@ -62,7 +62,9 @@ struct signal_stat { u32 total_num; /* num of valid elements */ u32 total_val; /* sum of valid elements */ }; + #define MAX_PATH_NUM_92CS 3 + struct phy_info { u8 RxPWDBAll; u8 SignalQuality; /* in 0-100 index. */ diff --git a/drivers/staging/rtl8188eu/include/rtw_security.h b/drivers/staging/rtl8188eu/include/rtw_security.h index 8ba02a7cea60..d08a8d8adccf 100644 --- a/drivers/staging/rtl8188eu/include/rtw_security.h +++ b/drivers/staging/rtl8188eu/include/rtw_security.h @@ -81,8 +81,8 @@ union Keytype { }; struct rt_pmkid_list { - u8 bUsed; - u8 Bssid[6]; + u8 used; + u8 bssid[ETH_ALEN]; u8 PMKID[16]; u8 SsidBuf[33]; u8 *ssid_octet; @@ -228,64 +228,6 @@ struct mic_data { u32 nBytesInM; /* # bytes in M */ }; -extern const u32 Te0[256]; -extern const u32 Td0[256]; -extern const u32 Td1[256]; -extern const u32 Td2[256]; -extern const u32 Td3[256]; -extern const u32 Td4[256]; -extern const u32 rcon[10]; -extern const u8 Td4s[256]; -extern const u8 rcons[10]; - -#define RCON(i) (rcons[(i)] << 24) - -static inline u32 rotr(u32 val, int bits) -{ - return (val >> bits) | (val << (32 - bits)); -} - -#define TE0(i) Te0[((i) >> 24) & 0xff] -#define TE1(i) rotr(Te0[((i) >> 16) & 0xff], 8) -#define TE2(i) rotr(Te0[((i) >> 8) & 0xff], 16) -#define TE3(i) rotr(Te0[(i) & 0xff], 24) - -/* ===== start - public domain SHA256 implementation ===== */ - -/* This is based on SHA256 implementation in LibTomCrypt that was released into - * public domain by Tom St Denis. - */ - -/* the K array */ -static const unsigned long K[64] = { - 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL, - 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL, - 0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, - 0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, - 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL, - 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL, - 0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, - 0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, - 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL, - 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL, - 0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, - 0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, - 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL -}; - -/* Various logical functions */ -#define RORc(x, y) \ - (((((unsigned long)(x) & 0xFFFFFFFFUL) >> (unsigned long)((y) & 31)) | \ - ((unsigned long)(x) << (unsigned long)(32 - ((y) & 31)))) & 0xFFFFFFFFUL) -#define Ch(x, y, z) (z ^ (x & (y ^ z))) -#define Maj(x, y, z) (((x | y) & z) | (x & y)) -#define S(x, n) RORc((x), (n)) -#define R(x, n) (((x) & 0xFFFFFFFFUL) >> (n)) -#define Sigma0(x) (S(x, 2) ^ S(x, 13) ^ S(x, 22)) -#define Sigma1(x) (S(x, 6) ^ S(x, 11) ^ S(x, 25)) -#define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3)) -#define Gamma1(x) (S(x, 17) ^ S(x, 19) ^ R(x, 10)) - void rtw_secmicsetkey(struct mic_data *pmicdata, u8 *key); void rtw_secmicappendbyte(struct mic_data *pmicdata, u8 b); void rtw_secmicappend(struct mic_data *pmicdata, u8 *src, u32 nBytes); diff --git a/drivers/staging/rtl8188eu/include/wifi.h b/drivers/staging/rtl8188eu/include/wifi.h index 217be809b937..757c582ba4d9 100644 --- a/drivers/staging/rtl8188eu/include/wifi.h +++ b/drivers/staging/rtl8188eu/include/wifi.h @@ -74,37 +74,6 @@ enum WIFI_FRAME_SUBTYPE { WIFI_QOS_DATA_NULL = (BIT(6) | WIFI_QOS_DATA_TYPE), }; -enum WIFI_REASON_CODE { - _RSON_RESERVED_ = 0, - _RSON_UNSPECIFIED_ = 1, - _RSON_AUTH_NO_LONGER_VALID_ = 2, - _RSON_DEAUTH_STA_LEAVING_ = 3, - _RSON_INACTIVITY_ = 4, - _RSON_UNABLE_HANDLE_ = 5, - _RSON_CLS2_ = 6, - _RSON_CLS3_ = 7, - _RSON_DISAOC_STA_LEAVING_ = 8, - _RSON_ASOC_NOT_AUTH_ = 9, - - /* WPA reason */ - _RSON_INVALID_IE_ = 13, - _RSON_MIC_FAILURE_ = 14, - _RSON_4WAY_HNDSHK_TIMEOUT_ = 15, - _RSON_GROUP_KEY_UPDATE_TIMEOUT_ = 16, - _RSON_DIFF_IE_ = 17, - _RSON_MLTCST_CIPHER_NOT_VALID_ = 18, - _RSON_UNICST_CIPHER_NOT_VALID_ = 19, - _RSON_AKMP_NOT_VALID_ = 20, - _RSON_UNSUPPORT_RSNE_VER_ = 21, - _RSON_INVALID_RSNE_CAP_ = 22, - _RSON_IEEE_802DOT1X_AUTH_FAIL_ = 23, - - /* belowing are Realtek definition */ - _RSON_PMK_NOT_AVAILABLE_ = 24, - _RSON_TDLS_TEAR_TOOFAR_ = 25, - _RSON_TDLS_TEAR_UN_RSN_ = 26, -}; - enum WIFI_STATUS_CODE { _STATS_SUCCESSFUL_ = 0, _STATS_FAILURE_ = 1, @@ -326,11 +295,12 @@ static inline unsigned char *get_hdr_bssid(unsigned char *pframe) static inline int IsFrameTypeCtrl(unsigned char *pframe) { - if (WIFI_CTRL_TYPE == GetFrameType(pframe)) + if (GetFrameType(pframe) == WIFI_CTRL_TYPE) return true; else return false; } + /*----------------------------------------------------------------------------- Below is for the security related definition ------------------------------------------------------------------------------*/ diff --git a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c index 2e83d24fcb09..8e10462f1fbe 100644 --- a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c +++ b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c @@ -124,6 +124,7 @@ static char *translate_scan(struct adapter *padapter, if (p && ht_ielen > 0) { struct ieee80211_ht_cap *pht_capie; + ht_cap = true; pht_capie = (struct ieee80211_ht_cap *)(p + 2); @@ -310,30 +311,30 @@ static char *translate_scan(struct adapter *padapter, static int wpa_set_auth_algs(struct net_device *dev, u32 value) { - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); int ret = 0; if ((value & AUTH_ALG_SHARED_KEY) && (value & AUTH_ALG_OPEN_SYSTEM)) { - DBG_88E("wpa_set_auth_algs, AUTH_ALG_SHARED_KEY and AUTH_ALG_OPEN_SYSTEM [value:0x%x]\n", value); + DBG_88E("%s, AUTH_ALG_SHARED_KEY and AUTH_ALG_OPEN_SYSTEM [value:0x%x]\n", __func__, value); padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled; padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeAutoSwitch; padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Auto; } else if (value & AUTH_ALG_SHARED_KEY) { - DBG_88E("wpa_set_auth_algs, AUTH_ALG_SHARED_KEY [value:0x%x]\n", value); + DBG_88E("%s, AUTH_ALG_SHARED_KEY [value:0x%x]\n", __func__, value); padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled; padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeShared; padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Shared; } else if (value & AUTH_ALG_OPEN_SYSTEM) { - DBG_88E("wpa_set_auth_algs, AUTH_ALG_OPEN_SYSTEM\n"); + DBG_88E("%s, AUTH_ALG_OPEN_SYSTEM\n", __func__); if (padapter->securitypriv.ndisauthtype < Ndis802_11AuthModeWPAPSK) { padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen; padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open; } } else if (value & AUTH_ALG_LEAP) { - DBG_88E("wpa_set_auth_algs, AUTH_ALG_LEAP\n"); + DBG_88E("%s, AUTH_ALG_LEAP\n", __func__); } else { - DBG_88E("wpa_set_auth_algs, error!\n"); + DBG_88E("%s, error!\n", __func__); ret = -EINVAL; } return ret; @@ -343,9 +344,9 @@ static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param, { int ret = 0; u32 wep_key_idx, wep_key_len, wep_total_len; - struct ndis_802_11_wep *pwep = NULL; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct ndis_802_11_wep *pwep = NULL; + struct adapter *padapter = rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct security_priv *psecuritypriv = &padapter->securitypriv; param->u.crypt.err = 0; @@ -367,8 +368,8 @@ static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param, } if (strcmp(param->u.crypt.alg, "WEP") == 0) { - RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_, ("wpa_set_encryption, crypt.alg = WEP\n")); - DBG_88E("wpa_set_encryption, crypt.alg = WEP\n"); + RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_, ("%s, crypt.alg = WEP\n", __func__)); + DBG_88E("%s, crypt.alg = WEP\n", __func__); padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled; padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_; @@ -390,7 +391,7 @@ static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param, wep_total_len = wep_key_len + offsetof(struct ndis_802_11_wep, KeyMaterial); pwep = (struct ndis_802_11_wep *)rtw_malloc(wep_total_len); if (!pwep) { - RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_, (" wpa_set_encryption: pwep allocate fail !!!\n")); + RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_, ("%s: pwep allocate fail !!!\n", __func__)); goto exit; } memset(pwep, 0, wep_total_len); @@ -437,11 +438,11 @@ static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param, psta->ieee8021x_blocked = false; if ((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled) || - (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled)) + (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled)) psta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm; if (param->u.crypt.set_tx == 1) { /* pairwise key */ - memcpy(psta->dot118021x_UncstKey.skey, param->u.crypt.key, min_t(u16, param->u.crypt.key_len, 16)); + memcpy(psta->dot118021x_UncstKey.skey, param->u.crypt.key, min_t(u16, param->u.crypt.key_len, 16)); if (strcmp(param->u.crypt.alg, "TKIP") == 0) { /* set mic key */ memcpy(psta->dot11tkiptxmickey.skey, ¶m->u.crypt.key[16], 8); @@ -453,7 +454,7 @@ static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param, rtw_setstakey_cmd(padapter, (unsigned char *)psta, true); } else { /* group key */ - memcpy(padapter->securitypriv.dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, min_t(u16, param->u.crypt.key_len, 16 )); + memcpy(padapter->securitypriv.dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, min_t(u16, param->u.crypt.key_len, 16)); memcpy(padapter->securitypriv.dot118021XGrptxmickey[param->u.crypt.idx].skey, ¶m->u.crypt.key[16], 8); memcpy(padapter->securitypriv.dot118021XGrprxmickey[param->u.crypt.idx].skey, ¶m->u.crypt.key[24], 8); padapter->securitypriv.binstallGrpkey = true; @@ -473,7 +474,7 @@ static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param, pbcmc_sta->ieee8021x_blocked = false; if ((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled) || - (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled)) + (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled)) pbcmc_sta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm; } } @@ -603,8 +604,8 @@ static int rtw_set_wpa_ie(struct adapter *padapter, char *pie, unsigned short ie } RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, - ("rtw_set_wpa_ie: pairwise_cipher = 0x%08x padapter->securitypriv.ndisencryptstatus =%d padapter->securitypriv.ndisauthtype =%d\n", - pairwise_cipher, padapter->securitypriv.ndisencryptstatus, padapter->securitypriv.ndisauthtype)); + ("%s: pairwise_cipher = 0x%08x padapter->securitypriv.ndisencryptstatus =%d padapter->securitypriv.ndisauthtype =%d\n", + __func__, pairwise_cipher, padapter->securitypriv.ndisencryptstatus, padapter->securitypriv.ndisauthtype)); exit: kfree(buf); return ret; @@ -613,10 +614,10 @@ exit: typedef unsigned char NDIS_802_11_RATES_EX[NDIS_802_11_LENGTH_RATES_EX]; static int rtw_wx_get_name(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) { - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); u32 ht_ielen = 0; char *p; u8 ht_cap = false; @@ -657,18 +658,18 @@ static int rtw_wx_get_name(struct net_device *dev, } static int rtw_wx_set_freq(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) { - RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_, ("+rtw_wx_set_freq\n")); + RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_, ("+%s\n", __func__)); return 0; } static int rtw_wx_get_freq(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) { - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network; @@ -687,13 +688,13 @@ static int rtw_wx_get_freq(struct net_device *dev, } static int rtw_wx_set_mode(struct net_device *dev, struct iw_request_info *a, - union iwreq_data *wrqu, char *b) + union iwreq_data *wrqu, char *b) { - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); enum ndis_802_11_network_infra networkType; int ret = 0; - if (_FAIL == rtw_pwr_wakeup(padapter)) { + if (!rtw_pwr_wakeup(padapter)) { ret = -EPERM; goto exit; } @@ -735,12 +736,12 @@ exit: } static int rtw_wx_get_mode(struct net_device *dev, struct iw_request_info *a, - union iwreq_data *wrqu, char *b) + union iwreq_data *wrqu, char *b) { - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, (" rtw_wx_get_mode\n")); + RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("%s\n", __func__)); if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) wrqu->mode = IW_MODE_INFRA; @@ -759,7 +760,7 @@ static int rtw_wx_set_pmkid(struct net_device *dev, struct iw_request_info *a, union iwreq_data *wrqu, char *extra) { - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); u8 j, blInserted = false; int ret = false; struct security_priv *psecuritypriv = &padapter->securitypriv; @@ -769,7 +770,7 @@ static int rtw_wx_set_pmkid(struct net_device *dev, memcpy(strIssueBssid, pPMK->bssid.sa_data, ETH_ALEN); if (pPMK->cmd == IW_PMKSA_ADD) { - DBG_88E("[rtw_wx_set_pmkid] IW_PMKSA_ADD!\n"); + DBG_88E("[%s] IW_PMKSA_ADD!\n", __func__); if (!memcmp(strIssueBssid, strZeroMacAddress, ETH_ALEN)) return ret; ret = true; @@ -777,11 +778,11 @@ static int rtw_wx_set_pmkid(struct net_device *dev, /* overwrite PMKID */ for (j = 0; j < NUM_PMKID_CACHE; j++) { - if (!memcmp(psecuritypriv->PMKIDList[j].Bssid, strIssueBssid, ETH_ALEN)) { + if (!memcmp(psecuritypriv->PMKIDList[j].bssid, strIssueBssid, ETH_ALEN)) { /* BSSID is matched, the same AP => rewrite with new PMKID. */ - DBG_88E("[rtw_wx_set_pmkid] BSSID exists in the PMKList.\n"); + DBG_88E("[%s] BSSID exists in the PMKList.\n", __func__); memcpy(psecuritypriv->PMKIDList[j].PMKID, pPMK->pmkid, IW_PMKID_LEN); - psecuritypriv->PMKIDList[j].bUsed = true; + psecuritypriv->PMKIDList[j].used = true; psecuritypriv->PMKIDIndex = j + 1; blInserted = true; break; @@ -790,30 +791,30 @@ static int rtw_wx_set_pmkid(struct net_device *dev, if (!blInserted) { /* Find a new entry */ - DBG_88E("[rtw_wx_set_pmkid] Use the new entry index = %d for this PMKID.\n", - psecuritypriv->PMKIDIndex); + DBG_88E("[%s] Use the new entry index = %d for this PMKID.\n", + __func__, psecuritypriv->PMKIDIndex); - memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].Bssid, strIssueBssid, ETH_ALEN); + memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].bssid, strIssueBssid, ETH_ALEN); memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].PMKID, pPMK->pmkid, IW_PMKID_LEN); - psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].bUsed = true; + psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].used = true; psecuritypriv->PMKIDIndex++; if (psecuritypriv->PMKIDIndex == 16) psecuritypriv->PMKIDIndex = 0; } } else if (pPMK->cmd == IW_PMKSA_REMOVE) { - DBG_88E("[rtw_wx_set_pmkid] IW_PMKSA_REMOVE!\n"); + DBG_88E("[%s] IW_PMKSA_REMOVE!\n", __func__); ret = true; for (j = 0; j < NUM_PMKID_CACHE; j++) { - if (!memcmp(psecuritypriv->PMKIDList[j].Bssid, strIssueBssid, ETH_ALEN)) { + if (!memcmp(psecuritypriv->PMKIDList[j].bssid, strIssueBssid, ETH_ALEN)) { /* BSSID is matched, the same AP => Remove this PMKID information and reset it. */ - eth_zero_addr(psecuritypriv->PMKIDList[j].Bssid); - psecuritypriv->PMKIDList[j].bUsed = false; + eth_zero_addr(psecuritypriv->PMKIDList[j].bssid); + psecuritypriv->PMKIDList[j].used = false; break; } } } else if (pPMK->cmd == IW_PMKSA_FLUSH) { - DBG_88E("[rtw_wx_set_pmkid] IW_PMKSA_FLUSH!\n"); + DBG_88E("[%s] IW_PMKSA_FLUSH!\n", __func__); memset(&psecuritypriv->PMKIDList[0], 0x00, sizeof(struct rt_pmkid_list) * NUM_PMKID_CACHE); psecuritypriv->PMKIDIndex = 0; ret = true; @@ -822,8 +823,8 @@ static int rtw_wx_set_pmkid(struct net_device *dev, } static int rtw_wx_get_sens(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) { wrqu->sens.value = 0; wrqu->sens.fixed = 0; /* no auto select */ @@ -832,17 +833,17 @@ static int rtw_wx_get_sens(struct net_device *dev, } static int rtw_wx_get_range(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) { struct iw_range *range = (struct iw_range *)extra; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; u16 val; int i; - RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_get_range. cmd_code =%x\n", info->cmd)); + RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("%s. cmd_code =%x\n", __func__, info->cmd)); wrqu->data.length = sizeof(*range); memset(range, 0, sizeof(*range)); @@ -931,12 +932,11 @@ static int rtw_wx_get_range(struct net_device *dev, /* s3. set_802_11_encryption_mode() */ /* s4. rtw_set_802_11_bssid() */ static int rtw_wx_set_wap(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *awrq, - char *extra) + struct iw_request_info *info, + union iwreq_data *awrq, char *extra) { uint ret = 0; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); struct sockaddr *temp = (struct sockaddr *)awrq; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct list_head *phead; @@ -945,7 +945,7 @@ static int rtw_wx_set_wap(struct net_device *dev, struct wlan_network *pnetwork = NULL; enum ndis_802_11_auth_mode authmode; - if (_FAIL == rtw_pwr_wakeup(padapter)) { + if (!rtw_pwr_wakeup(padapter)) { ret = -1; goto exit; } @@ -998,10 +998,10 @@ exit: } static int rtw_wx_get_wap(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) { - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network; @@ -1009,7 +1009,7 @@ static int rtw_wx_get_wap(struct net_device *dev, eth_zero_addr(wrqu->ap_addr.sa_data); - RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_get_wap\n")); + RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("%s\n", __func__)); if (check_fwstate(pmlmepriv, _FW_LINKED) || check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) || @@ -1021,12 +1021,12 @@ static int rtw_wx_get_wap(struct net_device *dev, } static int rtw_wx_set_mlme(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) { int ret = 0; u16 reason; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); struct iw_mlme *mlme = (struct iw_mlme *)extra; if (!mlme) @@ -1054,17 +1054,17 @@ static int rtw_wx_set_mlme(struct net_device *dev, } static int rtw_wx_set_scan(struct net_device *dev, struct iw_request_info *a, - union iwreq_data *wrqu, char *extra) + union iwreq_data *wrqu, char *extra) { u8 _status = false; int ret = 0; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct ndis_802_11_ssid ssid[RTW_SSID_SCAN_AMOUNT]; - RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_set_scan\n")); + RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("%s\n", __func__)); - if (_FAIL == rtw_pwr_wakeup(padapter)) { + if (!rtw_pwr_wakeup(padapter)) { ret = -1; goto exit; } @@ -1122,7 +1122,7 @@ static int rtw_wx_set_scan(struct net_device *dev, struct iw_request_info *a, spin_unlock_bh(&pmlmepriv->lock); } else if (req->scan_type == IW_SCAN_TYPE_PASSIVE) { - DBG_88E("rtw_wx_set_scan, req->scan_type == IW_SCAN_TYPE_PASSIVE\n"); + DBG_88E("%s, req->scan_type == IW_SCAN_TYPE_PASSIVE\n", __func__); } } else { if (wrqu->data.length >= WEXT_CSCAN_HEADER_SIZE && @@ -1184,10 +1184,10 @@ exit: } static int rtw_wx_get_scan(struct net_device *dev, struct iw_request_info *a, - union iwreq_data *wrqu, char *extra) + union iwreq_data *wrqu, char *extra) { struct list_head *plist, *phead; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct __queue *queue = &pmlmepriv->scanned_queue; struct wlan_network *pnetwork = NULL; @@ -1198,7 +1198,7 @@ static int rtw_wx_get_scan(struct net_device *dev, struct iw_request_info *a, u32 wait_for_surveydone; int wait_status; - RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_get_scan\n")); + RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("%s\n", __func__)); RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, (" Start of Query SIOCGIWSCAN .\n")); if (padapter->pwrctrlpriv.brfoffbyhw && padapter->bDriverStopped) { @@ -1252,10 +1252,10 @@ exit: /* s3. set_802_11_encryption_mode() */ /* s4. rtw_set_802_11_ssid() */ static int rtw_wx_set_essid(struct net_device *dev, - struct iw_request_info *a, - union iwreq_data *wrqu, char *extra) + struct iw_request_info *a, + union iwreq_data *wrqu, char *extra) { - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct __queue *queue = &pmlmepriv->scanned_queue; struct list_head *phead; @@ -1267,8 +1267,8 @@ static int rtw_wx_set_essid(struct net_device *dev, uint ret = 0, len; RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, - ("+rtw_wx_set_essid: fw_state = 0x%08x\n", get_fwstate(pmlmepriv))); - if (_FAIL == rtw_pwr_wakeup(padapter)) { + ("+%s: fw_state = 0x%08x\n", __func__, get_fwstate(pmlmepriv))); + if (!rtw_pwr_wakeup(padapter)) { ret = -1; goto exit; } @@ -1301,7 +1301,7 @@ static int rtw_wx_set_essid(struct net_device *dev, memcpy(ndis_ssid.ssid, extra, len); src_ssid = ndis_ssid.ssid; - RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, ("rtw_wx_set_essid: ssid =[%s]\n", src_ssid)); + RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, ("%s: ssid =[%s]\n", __func__, src_ssid)); spin_lock_bh(&queue->lock); phead = get_list_head(queue); pmlmepriv->pscanned = phead->next; @@ -1314,13 +1314,13 @@ static int rtw_wx_set_essid(struct net_device *dev, dst_ssid = pnetwork->network.ssid.ssid; RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, - ("rtw_wx_set_essid: dst_ssid =%s\n", + ("%s: dst_ssid =%s\n", __func__, pnetwork->network.ssid.ssid)); if ((!memcmp(dst_ssid, src_ssid, ndis_ssid.ssid_length)) && (pnetwork->network.ssid.ssid_length == ndis_ssid.ssid_length)) { RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, - ("rtw_wx_set_essid: find match, set infra mode\n")); + ("%s: find match, set infra mode\n", __func__)); if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) { if (pnetwork->network.InfrastructureMode != pmlmepriv->cur_network.network.InfrastructureMode) @@ -1353,15 +1353,15 @@ exit: } static int rtw_wx_get_essid(struct net_device *dev, - struct iw_request_info *a, - union iwreq_data *wrqu, char *extra) + struct iw_request_info *a, + union iwreq_data *wrqu, char *extra) { u32 len; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network; - RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_get_essid\n")); + RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("%s\n", __func__)); if ((check_fwstate(pmlmepriv, _FW_LINKED)) || (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE))) { @@ -1378,8 +1378,8 @@ static int rtw_wx_get_essid(struct net_device *dev, } static int rtw_wx_set_rate(struct net_device *dev, - struct iw_request_info *a, - union iwreq_data *wrqu, char *extra) + struct iw_request_info *a, + union iwreq_data *wrqu, char *extra) { int i; u8 datarates[NumRates]; @@ -1388,7 +1388,7 @@ static int rtw_wx_set_rate(struct net_device *dev, u32 ratevalue = 0; u8 mpdatarate[NumRates] = {11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0xff}; - RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, (" rtw_wx_set_rate\n")); + RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("%s\n", __func__)); RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, ("target_rate = %d, fixed = %d\n", target_rate, fixed)); if (target_rate == -1) { @@ -1457,12 +1457,12 @@ set_rate: } static int rtw_wx_get_rate(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) { u16 max_rate = 0; - max_rate = rtw_get_cur_max_rate((struct adapter *)rtw_netdev_priv(dev)); + max_rate = rtw_get_cur_max_rate(rtw_netdev_priv(dev)); if (max_rate == 0) return -EPERM; @@ -1474,10 +1474,10 @@ static int rtw_wx_get_rate(struct net_device *dev, } static int rtw_wx_set_rts(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) { - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); if (wrqu->rts.disabled) { padapter->registrypriv.rts_thresh = 2347; @@ -1495,10 +1495,10 @@ static int rtw_wx_set_rts(struct net_device *dev, } static int rtw_wx_get_rts(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) { - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); DBG_88E("%s, rts_thresh =%d\n", __func__, padapter->registrypriv.rts_thresh); @@ -1510,10 +1510,10 @@ static int rtw_wx_get_rts(struct net_device *dev, } static int rtw_wx_set_frag(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) { - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); if (wrqu->frag.disabled) { padapter->xmitpriv.frag_len = MAX_FRAG_THRESHOLD; @@ -1531,10 +1531,10 @@ static int rtw_wx_set_frag(struct net_device *dev, } static int rtw_wx_get_frag(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) { - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); DBG_88E("%s, frag_len =%d\n", __func__, padapter->xmitpriv.frag_len); @@ -1545,8 +1545,8 @@ static int rtw_wx_get_frag(struct net_device *dev, } static int rtw_wx_get_retry(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) { wrqu->retry.value = 7; wrqu->retry.fixed = 0; /* no auto select */ @@ -1556,8 +1556,8 @@ static int rtw_wx_get_retry(struct net_device *dev, } static int rtw_wx_set_enc(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *keybuf) + struct iw_request_info *info, + union iwreq_data *wrqu, char *keybuf) { u32 key, ret = 0; u32 keyindex_provided; @@ -1565,10 +1565,10 @@ static int rtw_wx_set_enc(struct net_device *dev, enum ndis_802_11_auth_mode authmode; struct iw_point *erq = &wrqu->encoding; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; - DBG_88E("+rtw_wx_set_enc, flags = 0x%x\n", erq->flags); + DBG_88E("+%s, flags = 0x%x\n", __func__, erq->flags); memset(&wep, 0, sizeof(struct ndis_802_11_wep)); @@ -1594,12 +1594,12 @@ static int rtw_wx_set_enc(struct net_device *dev, } else { keyindex_provided = 0; key = padapter->securitypriv.dot11PrivacyKeyIndex; - DBG_88E("rtw_wx_set_enc, key =%d\n", key); + DBG_88E("%s, key =%d\n", __func__, key); } /* set authentication mode */ if (erq->flags & IW_ENCODE_OPEN) { - DBG_88E("rtw_wx_set_enc():IW_ENCODE_OPEN\n"); + DBG_88E("%s():IW_ENCODE_OPEN\n", __func__); padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;/* Ndis802_11EncryptionDisabled; */ padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open; padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_; @@ -1607,7 +1607,7 @@ static int rtw_wx_set_enc(struct net_device *dev, authmode = Ndis802_11AuthModeOpen; padapter->securitypriv.ndisauthtype = authmode; } else if (erq->flags & IW_ENCODE_RESTRICTED) { - DBG_88E("rtw_wx_set_enc():IW_ENCODE_RESTRICTED\n"); + DBG_88E("%s():IW_ENCODE_RESTRICTED\n", __func__); padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled; padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Shared; padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_; @@ -1615,7 +1615,7 @@ static int rtw_wx_set_enc(struct net_device *dev, authmode = Ndis802_11AuthModeShared; padapter->securitypriv.ndisauthtype = authmode; } else { - DBG_88E("rtw_wx_set_enc():erq->flags = 0x%x\n", erq->flags); + DBG_88E("%s():erq->flags = 0x%x\n", __func__, erq->flags); padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;/* Ndis802_11EncryptionDisabled; */ padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open; @@ -1670,11 +1670,11 @@ exit: } static int rtw_wx_get_enc(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *keybuf) + struct iw_request_info *info, + union iwreq_data *wrqu, char *keybuf) { uint key; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); struct iw_point *erq = &wrqu->encoding; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; @@ -1735,8 +1735,8 @@ static int rtw_wx_get_enc(struct net_device *dev, } static int rtw_wx_get_power(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) { wrqu->power.value = 0; wrqu->power.fixed = 0; /* no auto select */ @@ -1749,16 +1749,16 @@ static int rtw_wx_set_gen_ie(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); return rtw_set_wpa_ie(padapter, extra, wrqu->data.length); } static int rtw_wx_set_auth(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) { - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); struct iw_param *param = (struct iw_param *)&wrqu->param; int ret = 0; @@ -1812,9 +1812,7 @@ static int rtw_wx_set_auth(struct net_device *dev, break; case IW_AUTH_80211_AUTH_ALG: - /* - * It's the starting point of a link layer connection using wpa_supplicant - */ + /* It's the starting point of a link layer connection using wpa_supplicant */ if (check_fwstate(&padapter->mlmepriv, _FW_LINKED)) { LeaveAllPowerSaveMode(padapter); rtw_disassoc_cmd(padapter, 500, false); @@ -1838,8 +1836,8 @@ static int rtw_wx_set_auth(struct net_device *dev, } static int rtw_wx_set_enc_ext(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) { char *alg_name; u32 param_len; @@ -1930,7 +1928,7 @@ static int dummy(struct net_device *dev, struct iw_request_info *a, static int wpa_set_param(struct net_device *dev, u8 name, u32 value) { uint ret = 0; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); switch (name) { case IEEE_PARAM_WPA_ENABLED: @@ -1946,7 +1944,7 @@ static int wpa_set_param(struct net_device *dev, u8 name, u32 value) break; } RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, - ("wpa_set_param:padapter->securitypriv.ndisauthtype =%d\n", padapter->securitypriv.ndisauthtype)); + ("%s:padapter->securitypriv.ndisauthtype =%d\n", __func__, padapter->securitypriv.ndisauthtype)); break; case IEEE_PARAM_TKIP_COUNTERMEASURES: break; @@ -1985,7 +1983,7 @@ static int wpa_set_param(struct net_device *dev, u8 name, u32 value) static int wpa_mlme(struct net_device *dev, u32 command, u32 reason) { int ret = 0; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); switch (command) { case IEEE_MLME_STA_DEAUTH: @@ -2022,7 +2020,7 @@ static int wpa_supplicant_ioctl(struct net_device *dev, struct iw_point *p) break; case IEEE_CMD_SET_WPA_IE: - ret = rtw_set_wpa_ie((struct adapter *)rtw_netdev_priv(dev), + ret = rtw_set_wpa_ie(rtw_netdev_priv(dev), (char *)param->u.wpa_ie.data, (u16)param->u.wpa_ie.len); break; @@ -2166,7 +2164,7 @@ static int rtw_set_encryption(struct net_device *dev, struct ieee_param *param, u32 wep_key_idx, wep_key_len, wep_total_len; struct ndis_802_11_wep *pwep = NULL; struct sta_info *psta = NULL, *pbcmc_sta = NULL; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct security_priv *psecuritypriv = &padapter->securitypriv; struct sta_priv *pstapriv = &padapter->stapriv; @@ -2186,7 +2184,7 @@ static int rtw_set_encryption(struct net_device *dev, struct ieee_param *param, } else { psta = rtw_get_stainfo(pstapriv, param->sta_addr); if (!psta) { - DBG_88E("rtw_set_encryption(), sta has already been removed or never been added\n"); + DBG_88E("%s(), sta has already been removed or never been added\n", __func__); goto exit; } } @@ -2267,7 +2265,7 @@ static int rtw_set_encryption(struct net_device *dev, struct ieee_param *param, DBG_88E("%s, set group_key, WEP\n", __func__); memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, - param->u.crypt.key, min_t(u16, param->u.crypt.key_len, 16)); + param->u.crypt.key, min_t(u16, param->u.crypt.key_len, 16)); psecuritypriv->dot118021XGrpPrivacy = _WEP40_; if (param->u.crypt.key_len == 13) @@ -2276,7 +2274,7 @@ static int rtw_set_encryption(struct net_device *dev, struct ieee_param *param, DBG_88E("%s, set group_key, TKIP\n", __func__); psecuritypriv->dot118021XGrpPrivacy = _TKIP_; memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, - param->u.crypt.key, min_t(u16, param->u.crypt.key_len, 16)); + param->u.crypt.key, min_t(u16, param->u.crypt.key_len, 16)); /* set mic key */ memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey, ¶m->u.crypt.key[16], 8); memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey, ¶m->u.crypt.key[24], 8); @@ -2286,7 +2284,7 @@ static int rtw_set_encryption(struct net_device *dev, struct ieee_param *param, DBG_88E("%s, set group_key, CCMP\n", __func__); psecuritypriv->dot118021XGrpPrivacy = _AES_; memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, - param->u.crypt.key, min_t(u16, param->u.crypt.key_len, 16)); + param->u.crypt.key, min_t(u16, param->u.crypt.key_len, 16)); } else { DBG_88E("%s, set group_key, none\n", __func__); psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_; @@ -2341,7 +2339,7 @@ static int rtw_set_encryption(struct net_device *dev, struct ieee_param *param, } else { /* group key??? */ if (strcmp(param->u.crypt.alg, "WEP") == 0) { memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, - param->u.crypt.key, min_t(u16, param->u.crypt.key_len, 16)); + param->u.crypt.key, min_t(u16, param->u.crypt.key_len, 16)); psecuritypriv->dot118021XGrpPrivacy = _WEP40_; if (param->u.crypt.key_len == 13) psecuritypriv->dot118021XGrpPrivacy = _WEP104_; @@ -2349,7 +2347,7 @@ static int rtw_set_encryption(struct net_device *dev, struct ieee_param *param, psecuritypriv->dot118021XGrpPrivacy = _TKIP_; memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, - param->u.crypt.key, min_t(u16, param->u.crypt.key_len, 16)); + param->u.crypt.key, min_t(u16, param->u.crypt.key_len, 16)); /* set mic key */ memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey, ¶m->u.crypt.key[16], 8); @@ -2360,7 +2358,7 @@ static int rtw_set_encryption(struct net_device *dev, struct ieee_param *param, psecuritypriv->dot118021XGrpPrivacy = _AES_; memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, - param->u.crypt.key, min_t(u16, param->u.crypt.key_len, 16)); + param->u.crypt.key, min_t(u16, param->u.crypt.key_len, 16)); } else { psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_; } @@ -2392,7 +2390,7 @@ exit: static int rtw_set_beacon(struct net_device *dev, struct ieee_param *param, int len) { int ret = 0; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct sta_priv *pstapriv = &padapter->stapriv; unsigned char *pbuf = param->u.bcn_ie.buf; @@ -2417,7 +2415,7 @@ static int rtw_set_beacon(struct net_device *dev, struct ieee_param *param, int static int rtw_hostapd_sta_flush(struct net_device *dev) { - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); DBG_88E("%s\n", __func__); @@ -2430,11 +2428,11 @@ static int rtw_add_sta(struct net_device *dev, struct ieee_param *param) { int ret = 0; struct sta_info *psta = NULL; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct sta_priv *pstapriv = &padapter->stapriv; - DBG_88E("rtw_add_sta(aid =%d) =%pM\n", param->u.add_sta.aid, (param->sta_addr)); + DBG_88E("%s(aid =%d) =%pM\n", __func__, param->u.add_sta.aid, (param->sta_addr)); if (!check_fwstate(pmlmepriv, (_FW_LINKED | WIFI_AP_STATE))) return -EINVAL; @@ -2483,12 +2481,12 @@ static int rtw_add_sta(struct net_device *dev, struct ieee_param *param) static int rtw_del_sta(struct net_device *dev, struct ieee_param *param) { struct sta_info *psta = NULL; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct sta_priv *pstapriv = &padapter->stapriv; int updated = 0; - DBG_88E("rtw_del_sta =%pM\n", (param->sta_addr)); + DBG_88E("%s =%pM\n", __func__, (param->sta_addr)); if (!check_fwstate(pmlmepriv, _FW_LINKED | WIFI_AP_STATE)) return -EINVAL; @@ -2508,7 +2506,7 @@ static int rtw_del_sta(struct net_device *dev, struct ieee_param *param) associated_clients_update(padapter, updated); psta = NULL; } else { - DBG_88E("rtw_del_sta(), sta has already been removed or never been added\n"); + DBG_88E("%s(), sta has already been removed or never been added\n", __func__); } return 0; @@ -2518,7 +2516,7 @@ static int rtw_ioctl_get_sta_data(struct net_device *dev, struct ieee_param *par { int ret = 0; struct sta_info *psta = NULL; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct sta_priv *pstapriv = &padapter->stapriv; struct ieee_param_ex *param_ex = (struct ieee_param_ex *)param; @@ -2574,11 +2572,11 @@ static int rtw_get_sta_wpaie(struct net_device *dev, struct ieee_param *param) { int ret = 0; struct sta_info *psta = NULL; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct sta_priv *pstapriv = &padapter->stapriv; - DBG_88E("rtw_get_sta_wpaie, sta_addr: %pM\n", (param->sta_addr)); + DBG_88E("%s, sta_addr: %pM\n", __func__, (param->sta_addr)); if (!check_fwstate(pmlmepriv, _FW_LINKED | WIFI_AP_STATE)) return -EINVAL; @@ -2610,7 +2608,7 @@ static int rtw_get_sta_wpaie(struct net_device *dev, struct ieee_param *param) static int rtw_set_wps_beacon(struct net_device *dev, struct ieee_param *param, int len) { unsigned char wps_oui[4] = {0x0, 0x50, 0xf2, 0x04}; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; int ie_len; @@ -2645,7 +2643,7 @@ static int rtw_set_wps_beacon(struct net_device *dev, struct ieee_param *param, static int rtw_set_wps_probe_resp(struct net_device *dev, struct ieee_param *param, int len) { - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); struct mlme_priv *pmlmepriv = &padapter->mlmepriv; int ie_len; @@ -2674,7 +2672,7 @@ static int rtw_set_wps_probe_resp(struct net_device *dev, struct ieee_param *par static int rtw_set_wps_assoc_resp(struct net_device *dev, struct ieee_param *param, int len) { - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); struct mlme_priv *pmlmepriv = &padapter->mlmepriv; int ie_len; @@ -2704,7 +2702,7 @@ static int rtw_set_wps_assoc_resp(struct net_device *dev, struct ieee_param *par static int rtw_set_hidden_ssid(struct net_device *dev, struct ieee_param *param, int len) { - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; @@ -2728,7 +2726,7 @@ static int rtw_set_hidden_ssid(struct net_device *dev, struct ieee_param *param, static int rtw_ioctl_acl_remove_sta(struct net_device *dev, struct ieee_param *param, int len) { - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); struct mlme_priv *pmlmepriv = &padapter->mlmepriv; if (!check_fwstate(pmlmepriv, WIFI_AP_STATE)) @@ -2742,7 +2740,7 @@ static int rtw_ioctl_acl_remove_sta(struct net_device *dev, struct ieee_param *p static int rtw_ioctl_acl_add_sta(struct net_device *dev, struct ieee_param *param, int len) { - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); struct mlme_priv *pmlmepriv = &padapter->mlmepriv; if (!check_fwstate(pmlmepriv, WIFI_AP_STATE)) @@ -2756,7 +2754,7 @@ static int rtw_ioctl_acl_add_sta(struct net_device *dev, struct ieee_param *para static int rtw_ioctl_set_macaddr_acl(struct net_device *dev, struct ieee_param *param, int len) { - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); struct mlme_priv *pmlmepriv = &padapter->mlmepriv; if (!check_fwstate(pmlmepriv, WIFI_AP_STATE)) @@ -2771,12 +2769,12 @@ static int rtw_hostapd_ioctl(struct net_device *dev, struct iw_point *p) { struct ieee_param *param; int ret = 0; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); /* - * this function is expect to call in master mode, which allows no power saving - * so, we just check hw_init_completed - */ + * this function is expect to call in master mode, which allows no power saving + * so, we just check hw_init_completed + */ if (!padapter->hw_init_completed) return -EPERM; @@ -2846,14 +2844,13 @@ static int rtw_hostapd_ioctl(struct net_device *dev, struct iw_point *p) #include <rtw_android.h> static int rtw_wx_set_priv(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *awrq, - char *extra) + struct iw_request_info *info, + union iwreq_data *awrq, char *extra) { int ret = 0; int len = 0; char *ext; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); struct iw_point *dwrq = (struct iw_point *)awrq; if (dwrq->length == 0) @@ -2877,7 +2874,7 @@ static int rtw_wx_set_priv(struct net_device *dev, int probereq_wpsie_len = len; u8 wps_oui[4] = {0x0, 0x50, 0xf2, 0x04}; - if ((_VENDOR_SPECIFIC_IE_ == probereq_wpsie[0]) && + if ((probereq_wpsie[0] == _VENDOR_SPECIFIC_IE_) && (!memcmp(&probereq_wpsie[2], wps_oui, 4))) { cp_sz = min(probereq_wpsie_len, MAX_WPS_IE_LEN); @@ -2971,7 +2968,7 @@ static iw_handler rtw_handlers[] = { static struct iw_statistics *rtw_get_wireless_stats(struct net_device *dev) { - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct adapter *padapter = rtw_netdev_priv(dev); struct iw_statistics *piwstats = &padapter->iwstats; int tmp_level = 0; int tmp_qual = 0; diff --git a/drivers/staging/rtl8188eu/os_dep/os_intfs.c b/drivers/staging/rtl8188eu/os_dep/os_intfs.c index 8907bf6bb7ff..e291df87f620 100644 --- a/drivers/staging/rtl8188eu/os_dep/os_intfs.c +++ b/drivers/staging/rtl8188eu/os_dep/os_intfs.c @@ -187,7 +187,7 @@ static void loadparam(struct adapter *padapter, struct net_device *pnetdev) static int rtw_net_set_mac_address(struct net_device *pnetdev, void *p) { - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(pnetdev); + struct adapter *padapter = rtw_netdev_priv(pnetdev); struct sockaddr *addr = p; if (!padapter->bup) @@ -198,7 +198,7 @@ static int rtw_net_set_mac_address(struct net_device *pnetdev, void *p) static struct net_device_stats *rtw_net_get_stats(struct net_device *pnetdev) { - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(pnetdev); + struct adapter *padapter = rtw_netdev_priv(pnetdev); struct xmit_priv *pxmitpriv = &padapter->xmitpriv; struct recv_priv *precvpriv = &padapter->recvpriv; @@ -335,7 +335,7 @@ static int rtw_start_drv_threads(struct adapter *padapter) { int err = 0; - RT_TRACE(_module_os_intfs_c_, _drv_info_, ("+rtw_start_drv_threads\n")); + RT_TRACE(_module_os_intfs_c_, _drv_info_, ("+%s\n", __func__)); padapter->cmdThread = kthread_run(rtw_cmd_thread, padapter, "RTW_CMD_THREAD"); @@ -350,7 +350,7 @@ static int rtw_start_drv_threads(struct adapter *padapter) void rtw_stop_drv_threads(struct adapter *padapter) { - RT_TRACE(_module_os_intfs_c_, _drv_info_, ("+rtw_stop_drv_threads\n")); + RT_TRACE(_module_os_intfs_c_, _drv_info_, ("+%s\n", __func__)); /* Below is to terminate rtw_cmd_thread & event_thread... */ complete(&padapter->cmdpriv.cmd_queue_comp); @@ -433,7 +433,7 @@ u8 rtw_init_drv_sw(struct adapter *padapter) { u8 ret8 = _SUCCESS; - RT_TRACE(_module_os_intfs_c_, _drv_info_, ("+rtw_init_drv_sw\n")); + RT_TRACE(_module_os_intfs_c_, _drv_info_, ("+%s\n", __func__)); if ((rtw_init_cmd_priv(&padapter->cmdpriv)) == _FAIL) { RT_TRACE(_module_os_intfs_c_, _drv_err_, ("\n Can't init cmd_priv\n")); @@ -487,27 +487,27 @@ u8 rtw_init_drv_sw(struct adapter *padapter) rtw_hal_sreset_init(padapter); exit: - RT_TRACE(_module_os_intfs_c_, _drv_info_, ("-rtw_init_drv_sw\n")); + RT_TRACE(_module_os_intfs_c_, _drv_info_, ("-%s\n", __func__)); return ret8; } void rtw_cancel_all_timer(struct adapter *padapter) { - RT_TRACE(_module_os_intfs_c_, _drv_info_, ("+rtw_cancel_all_timer\n")); + RT_TRACE(_module_os_intfs_c_, _drv_info_, ("+%s\n", __func__)); del_timer_sync(&padapter->mlmepriv.assoc_timer); - RT_TRACE(_module_os_intfs_c_, _drv_info_, ("rtw_cancel_all_timer:cancel association timer complete!\n")); + RT_TRACE(_module_os_intfs_c_, _drv_info_, ("%s:cancel association timer complete!\n", __func__)); del_timer_sync(&padapter->mlmepriv.scan_to_timer); - RT_TRACE(_module_os_intfs_c_, _drv_info_, ("rtw_cancel_all_timer:cancel scan_to_timer!\n")); + RT_TRACE(_module_os_intfs_c_, _drv_info_, ("%s:cancel scan_to_timer!\n", __func__)); del_timer_sync(&padapter->mlmepriv.dynamic_chk_timer); - RT_TRACE(_module_os_intfs_c_, _drv_info_, ("rtw_cancel_all_timer:cancel dynamic_chk_timer!\n")); + RT_TRACE(_module_os_intfs_c_, _drv_info_, ("%s:cancel dynamic_chk_timer!\n", __func__)); /* cancel sw led timer */ rtw_hal_sw_led_deinit(padapter); - RT_TRACE(_module_os_intfs_c_, _drv_info_, ("rtw_cancel_all_timer:cancel DeInitSwLeds!\n")); + RT_TRACE(_module_os_intfs_c_, _drv_info_, ("%s:cancel DeInitSwLeds!\n", __func__)); del_timer_sync(&padapter->pwrctrlpriv.pwr_state_check_timer); @@ -516,7 +516,7 @@ void rtw_cancel_all_timer(struct adapter *padapter) u8 rtw_free_drv_sw(struct adapter *padapter) { - RT_TRACE(_module_os_intfs_c_, _drv_info_, ("==>rtw_free_drv_sw")); + RT_TRACE(_module_os_intfs_c_, _drv_info_, ("==>%s", __func__)); free_mlme_ext_priv(&padapter->mlmeextpriv); @@ -530,11 +530,11 @@ u8 rtw_free_drv_sw(struct adapter *padapter) rtw_hal_free_data(padapter); - RT_TRACE(_module_os_intfs_c_, _drv_info_, ("<== rtw_free_drv_sw\n")); + RT_TRACE(_module_os_intfs_c_, _drv_info_, ("<== %s\n", __func__)); mutex_destroy(&padapter->hw_init_mutex); - RT_TRACE(_module_os_intfs_c_, _drv_info_, ("-rtw_free_drv_sw\n")); + RT_TRACE(_module_os_intfs_c_, _drv_info_, ("-%s\n", __func__)); return _SUCCESS; } @@ -543,7 +543,7 @@ static int _netdev_open(struct net_device *pnetdev) { uint status; int err; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(pnetdev); + struct adapter *padapter = rtw_netdev_priv(pnetdev); struct pwrctrl_priv *pwrctrlpriv = &padapter->pwrctrlpriv; RT_TRACE(_module_os_intfs_c_, _drv_info_, ("+88eu_drv - dev_open\n")); @@ -612,7 +612,7 @@ netdev_open_error: int netdev_open(struct net_device *pnetdev) { int ret; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(pnetdev); + struct adapter *padapter = rtw_netdev_priv(pnetdev); if (mutex_lock_interruptible(&padapter->hw_init_mutex)) return -ERESTARTSYS; @@ -633,7 +633,7 @@ int ips_netdrv_open(struct adapter *padapter) status = rtw_hal_init(padapter); if (status == _FAIL) { - RT_TRACE(_module_os_intfs_c_, _drv_err_, ("ips_netdrv_open(): Can't init h/w!\n")); + RT_TRACE(_module_os_intfs_c_, _drv_err_, ("%s(): Can't init h/w!\n", __func__)); goto netdev_open_error; } @@ -646,7 +646,7 @@ int ips_netdrv_open(struct adapter *padapter) return _SUCCESS; netdev_open_error: - DBG_88E("-ips_netdrv_open - drv_open failure, bup =%d\n", padapter->bup); + DBG_88E("-%s - drv_open failure, bup =%d\n", __func__, padapter->bup); return _FAIL; } @@ -656,14 +656,14 @@ int rtw_ips_pwr_up(struct adapter *padapter) int result; unsigned long start_time = jiffies; - DBG_88E("===> rtw_ips_pwr_up..............\n"); + DBG_88E("===> %s..............\n", __func__); rtw_reset_drv_sw(padapter); result = ips_netdrv_open(padapter); led_control_8188eu(padapter, LED_CTL_NO_LINK); - DBG_88E("<=== rtw_ips_pwr_up.............. in %dms\n", + DBG_88E("<=== %s.............. in %dms\n", __func__, jiffies_to_msecs(jiffies - start_time)); return result; } @@ -672,14 +672,14 @@ void rtw_ips_pwr_down(struct adapter *padapter) { unsigned long start_time = jiffies; - DBG_88E("===> rtw_ips_pwr_down...................\n"); + DBG_88E("===> %s...................\n", __func__); padapter->net_closed = true; led_control_8188eu(padapter, LED_CTL_POWER_OFF); rtw_ips_dev_unload(padapter); - DBG_88E("<=== rtw_ips_pwr_down..................... in %dms\n", + DBG_88E("<=== %s..................... in %dms\n", __func__, jiffies_to_msecs(jiffies - start_time)); } @@ -698,7 +698,7 @@ void rtw_ips_dev_unload(struct adapter *padapter) static int netdev_close(struct net_device *pnetdev) { - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(pnetdev); + struct adapter *padapter = rtw_netdev_priv(pnetdev); RT_TRACE(_module_os_intfs_c_, _drv_info_, ("+88eu_drv - drv_close\n")); diff --git a/drivers/staging/rtl8188eu/os_dep/rtw_android.c b/drivers/staging/rtl8188eu/os_dep/rtw_android.c index bf86d03820ca..b5209627fd1a 100644 --- a/drivers/staging/rtl8188eu/os_dep/rtw_android.c +++ b/drivers/staging/rtl8188eu/os_dep/rtw_android.c @@ -68,7 +68,7 @@ int rtw_android_cmdstr_to_num(char *cmdstr) for (cmd_num = 0; cmd_num < ANDROID_WIFI_CMD_MAX; cmd_num++) if (!strncasecmp(cmdstr, android_wifi_cmd_str[cmd_num], - strlen(android_wifi_cmd_str[cmd_num]))) + strlen(android_wifi_cmd_str[cmd_num]))) break; return cmd_num; } @@ -76,7 +76,7 @@ int rtw_android_cmdstr_to_num(char *cmdstr) static int rtw_android_get_rssi(struct net_device *net, char *command, int total_len) { - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(net); + struct adapter *padapter = rtw_netdev_priv(net); struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct wlan_network *pcur_network = &pmlmepriv->cur_network; int bytes_written = 0; @@ -93,7 +93,7 @@ static int rtw_android_get_rssi(struct net_device *net, char *command, static int rtw_android_get_link_speed(struct net_device *net, char *command, int total_len) { - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(net); + struct adapter *padapter = rtw_netdev_priv(net); u16 link_speed; link_speed = rtw_get_cur_max_rate(padapter) / 10; @@ -111,7 +111,7 @@ static int rtw_android_get_macaddr(struct net_device *net, char *command, static int android_set_cntry(struct net_device *net, char *command, int total_len) { - struct adapter *adapter = (struct adapter *)rtw_netdev_priv(net); + struct adapter *adapter = rtw_netdev_priv(net); char *country_code = command + strlen(android_wifi_cmd_str[ANDROID_WIFI_CMD_COUNTRY]) + 1; int ret; @@ -120,7 +120,7 @@ static int android_set_cntry(struct net_device *net, char *command, } static int android_get_p2p_addr(struct net_device *net, char *command, - int total_len) + int total_len) { /* We use the same address as our HW MAC address */ memcpy(command, net->dev_addr, ETH_ALEN); diff --git a/drivers/staging/rtl8188eu/os_dep/usb_intf.c b/drivers/staging/rtl8188eu/os_dep/usb_intf.c index f7f09c0d273f..99bfc828672c 100644 --- a/drivers/staging/rtl8188eu/os_dep/usb_intf.c +++ b/drivers/staging/rtl8188eu/os_dep/usb_intf.c @@ -118,7 +118,7 @@ static void usb_dvobj_deinit(struct usb_interface *usb_intf) if (dvobj) { /* Modify condition for 92DU DMDP 2010.11.18, by Thomas */ if ((dvobj->NumInterfaces != 2 && - dvobj->NumInterfaces != 3) || + dvobj->NumInterfaces != 3) || (dvobj->InterfaceNumber == 1)) { if (interface_to_usbdev(usb_intf)->state != USB_STATE_NOTATTACHED) { @@ -126,7 +126,8 @@ static void usb_dvobj_deinit(struct usb_interface *usb_intf) * remove/insert module, driver fails * on sitesurvey for the first time when * device is up . Reset usb port for sitesurvey - * fail issue. */ + * fail issue. + */ pr_debug("usb attached..., try to reset usb device\n"); usb_reset_device(interface_to_usbdev(usb_intf)); } @@ -141,7 +142,7 @@ static void usb_dvobj_deinit(struct usb_interface *usb_intf) void usb_intf_stop(struct adapter *padapter) { - RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("+usb_intf_stop\n")); + RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("+%s\n", __func__)); /* disable_hw_interrupt */ if (!padapter->bSurpriseRemoved) { @@ -159,15 +160,15 @@ void usb_intf_stop(struct adapter *padapter) /* todo:cancel other irps */ - RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("-usb_intf_stop\n")); + RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("-%s\n", __func__)); } static void rtw_dev_unload(struct adapter *padapter) { - RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("+rtw_dev_unload\n")); + RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("+%s\n", __func__)); if (padapter->bup) { - pr_debug("===> rtw_dev_unload\n"); + pr_debug("===> %s\n", __func__); padapter->bDriverStopped = true; if (padapter->xmitpriv.ack_tx) rtw_ack_tx_done(&padapter->xmitpriv, RTW_SCTX_DONE_DRV_STOP); @@ -189,9 +190,9 @@ static void rtw_dev_unload(struct adapter *padapter) ("r871x_dev_unload():padapter->bup == false\n")); } - pr_debug("<=== rtw_dev_unload\n"); + pr_debug("<=== %s\n", __func__); - RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("-rtw_dev_unload\n")); + RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("-%s\n", __func__)); } static int rtw_suspend(struct usb_interface *pusb_intf, pm_message_t message) @@ -208,8 +209,8 @@ static int rtw_suspend(struct usb_interface *pusb_intf, pm_message_t message) if ((!padapter->bup) || (padapter->bDriverStopped) || (padapter->bSurpriseRemoved)) { pr_debug("padapter->bup=%d bDriverStopped=%d bSurpriseRemoved = %d\n", - padapter->bup, padapter->bDriverStopped, - padapter->bSurpriseRemoved); + padapter->bup, padapter->bDriverStopped, + padapter->bSurpriseRemoved); goto exit; } @@ -230,11 +231,11 @@ static int rtw_suspend(struct usb_interface *pusb_intf, pm_message_t message) if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) && check_fwstate(pmlmepriv, _FW_LINKED)) { pr_debug("%s:%d %s(%pM), length:%d assoc_ssid.length:%d\n", - __func__, __LINE__, - pmlmepriv->cur_network.network.ssid.ssid, - pmlmepriv->cur_network.network.MacAddress, - pmlmepriv->cur_network.network.ssid.ssid_length, - pmlmepriv->assoc_ssid.ssid_length); + __func__, __LINE__, + pmlmepriv->cur_network.network.ssid.ssid, + pmlmepriv->cur_network.network.MacAddress, + pmlmepriv->cur_network.network.ssid.ssid_length, + pmlmepriv->assoc_ssid.ssid_length); pmlmepriv->to_roaming = 1; } @@ -299,7 +300,7 @@ exit: if (pwrpriv) pwrpriv->bInSuspend = false; pr_debug("<=== %s return %d.............. in %dms\n", __func__, - ret, jiffies_to_msecs(jiffies - start_time)); + ret, jiffies_to_msecs(jiffies - start_time)); return ret; } @@ -321,7 +322,8 @@ static int rtw_resume(struct usb_interface *pusb_intf) */ static struct adapter *rtw_usb_if1_init(struct dvobj_priv *dvobj, - struct usb_interface *pusb_intf, const struct usb_device_id *pdid) + struct usb_interface *pusb_intf, + const struct usb_device_id *pdid) { struct adapter *padapter = NULL; struct net_device *pnetdev = NULL; @@ -379,12 +381,11 @@ static struct adapter *rtw_usb_if1_init(struct dvobj_priv *dvobj, device_init_wakeup(&pusb_intf->dev, 1); pr_debug("\n padapter->pwrctrlpriv.bSupportRemoteWakeup~~~~~~\n"); pr_debug("\n padapter->pwrctrlpriv.bSupportRemoteWakeup~~~[%d]~~~\n", - device_may_wakeup(&pusb_intf->dev)); + device_may_wakeup(&pusb_intf->dev)); } #endif - /* 2012-07-11 Move here to prevent the 8723AS-VAU BT auto - * suspend influence */ + /* 2012-07-11 Move here to prevent the 8723AS-VAU BT auto suspend influence */ if (usb_autopm_get_interface(pusb_intf) < 0) pr_debug("can't get autopm:\n"); @@ -393,7 +394,7 @@ static struct adapter *rtw_usb_if1_init(struct dvobj_priv *dvobj, rtw_macaddr_cfg(padapter->eeprompriv.mac_addr); memcpy(pnetdev->dev_addr, padapter->eeprompriv.mac_addr, ETH_ALEN); pr_debug("MAC Address from pnetdev->dev_addr = %pM\n", - pnetdev->dev_addr); + pnetdev->dev_addr); /* step 6. Tell the network stack we exist */ if (register_netdev(pnetdev) != 0) { @@ -445,7 +446,7 @@ static void rtw_usb_if1_deinit(struct adapter *if1) rtw_dev_unload(if1); pr_debug("+r871xu_dev_remove, hw_init_completed=%d\n", - if1->hw_init_completed); + if1->hw_init_completed); rtw_free_drv_sw(if1); rtw_free_netdev(pnetdev); } @@ -479,14 +480,15 @@ exit: /* * dev_remove() - our device is being removed -*/ -/* rmmod module & unplug(SurpriseRemoved) will call r871xu_dev_remove() => how to recognize both */ + * + * rmmod module & unplug(SurpriseRemoved) will call r871xu_dev_remove() => how to recognize both + */ static void rtw_dev_remove(struct usb_interface *pusb_intf) { struct dvobj_priv *dvobj = usb_get_intfdata(pusb_intf); struct adapter *padapter = dvobj->if1; - pr_debug("+rtw_dev_remove\n"); + pr_debug("+%s\n", __func__); RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("+dev_remove()\n")); if (!pusb_intf->unregistering) diff --git a/drivers/staging/rtl8188eu/os_dep/usb_ops_linux.c b/drivers/staging/rtl8188eu/os_dep/usb_ops_linux.c index a80c7f3b86d1..6926443bba4e 100644 --- a/drivers/staging/rtl8188eu/os_dep/usb_ops_linux.c +++ b/drivers/staging/rtl8188eu/os_dep/usb_ops_linux.c @@ -773,10 +773,10 @@ void usb_write_port_cancel(struct adapter *padapter) } } -void rtl8188eu_recv_tasklet(unsigned long priv) +void rtl8188eu_recv_tasklet(struct tasklet_struct *t) { struct sk_buff *pskb; - struct adapter *adapt = (struct adapter *)priv; + struct adapter *adapt = from_tasklet(adapt, t, recvpriv.recv_tasklet); struct recv_priv *precvpriv = &adapt->recvpriv; while (NULL != (pskb = skb_dequeue(&precvpriv->rx_skb_queue))) { @@ -792,9 +792,9 @@ void rtl8188eu_recv_tasklet(unsigned long priv) } } -void rtl8188eu_xmit_tasklet(unsigned long priv) +void rtl8188eu_xmit_tasklet(struct tasklet_struct *t) { - struct adapter *adapt = (struct adapter *)priv; + struct adapter *adapt = from_tasklet(adapt, t, xmitpriv.xmit_tasklet); struct xmit_priv *pxmitpriv = &adapt->xmitpriv; if (check_fwstate(&adapt->mlmepriv, _FW_UNDER_SURVEY)) diff --git a/drivers/staging/rtl8188eu/os_dep/xmit_linux.c b/drivers/staging/rtl8188eu/os_dep/xmit_linux.c index a73313cf6a75..c22ddeb9a56b 100644 --- a/drivers/staging/rtl8188eu/os_dep/xmit_linux.c +++ b/drivers/staging/rtl8188eu/os_dep/xmit_linux.c @@ -164,7 +164,7 @@ static int rtw_mlcst2unicst(struct adapter *padapter, struct sk_buff *skb) int rtw_xmit_entry(struct sk_buff *pkt, struct net_device *pnetdev) { - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(pnetdev); + struct adapter *padapter = rtw_netdev_priv(pnetdev); struct xmit_priv *pxmitpriv = &padapter->xmitpriv; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; s32 res = 0; diff --git a/drivers/staging/rtl8192e/Kconfig b/drivers/staging/rtl8192e/Kconfig index 4c440bdaaf6e..03fcc23516fd 100644 --- a/drivers/staging/rtl8192e/Kconfig +++ b/drivers/staging/rtl8192e/Kconfig @@ -14,6 +14,7 @@ if RTLLIB config RTLLIB_CRYPTO_CCMP tristate "Support for rtllib CCMP crypto" depends on RTLLIB + select CRYPTO select CRYPTO_AES select CRYPTO_CCM default y diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c index fac58eebf263..663675efcfe4 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c @@ -82,8 +82,8 @@ static int _rtl92e_hard_start_xmit(struct sk_buff *skb, struct net_device *dev); static void _rtl92e_tx_cmd(struct net_device *dev, struct sk_buff *skb); static short _rtl92e_tx(struct net_device *dev, struct sk_buff *skb); static short _rtl92e_pci_initdescring(struct net_device *dev); -static void _rtl92e_irq_tx_tasklet(unsigned long data); -static void _rtl92e_irq_rx_tasklet(unsigned long data); +static void _rtl92e_irq_tx_tasklet(struct tasklet_struct *t); +static void _rtl92e_irq_rx_tasklet(struct tasklet_struct *t); static void _rtl92e_cancel_deferred_work(struct r8192_priv *priv); static int _rtl92e_up(struct net_device *dev, bool is_silent_reset); static int _rtl92e_try_up(struct net_device *dev); @@ -517,9 +517,10 @@ static int _rtl92e_handle_assoc_response(struct net_device *dev, return 0; } -static void _rtl92e_prepare_beacon(unsigned long data) +static void _rtl92e_prepare_beacon(struct tasklet_struct *t) { - struct r8192_priv *priv = (struct r8192_priv *)data; + struct r8192_priv *priv = from_tasklet(priv, t, + irq_prepare_beacon_tasklet); struct net_device *dev = priv->rtllib->dev; struct sk_buff *pskb = NULL, *pnewskb = NULL; struct cb_desc *tcb_desc = NULL; @@ -1009,12 +1010,10 @@ static void _rtl92e_init_priv_task(struct net_device *dev) (void *)rtl92e_hw_wakeup_wq, dev); INIT_DELAYED_WORK_RSL(&priv->rtllib->hw_sleep_wq, (void *)rtl92e_hw_sleep_wq, dev); - tasklet_init(&priv->irq_rx_tasklet, _rtl92e_irq_rx_tasklet, - (unsigned long)priv); - tasklet_init(&priv->irq_tx_tasklet, _rtl92e_irq_tx_tasklet, - (unsigned long)priv); - tasklet_init(&priv->irq_prepare_beacon_tasklet, _rtl92e_prepare_beacon, - (unsigned long)priv); + tasklet_setup(&priv->irq_rx_tasklet, _rtl92e_irq_rx_tasklet); + tasklet_setup(&priv->irq_tx_tasklet, _rtl92e_irq_tx_tasklet); + tasklet_setup(&priv->irq_prepare_beacon_tasklet, + _rtl92e_prepare_beacon); } static short _rtl92e_get_channel_map(struct net_device *dev) @@ -2109,16 +2108,16 @@ static void _rtl92e_tx_resume(struct net_device *dev) } } -static void _rtl92e_irq_tx_tasklet(unsigned long data) +static void _rtl92e_irq_tx_tasklet(struct tasklet_struct *t) { - struct r8192_priv *priv = (struct r8192_priv *)data; + struct r8192_priv *priv = from_tasklet(priv, t, irq_tx_tasklet); _rtl92e_tx_resume(priv->rtllib->dev); } -static void _rtl92e_irq_rx_tasklet(unsigned long data) +static void _rtl92e_irq_rx_tasklet(struct tasklet_struct *t) { - struct r8192_priv *priv = (struct r8192_priv *)data; + struct r8192_priv *priv = from_tasklet(priv, t, irq_rx_tasklet); _rtl92e_rx_normal(priv->rtllib->dev); diff --git a/drivers/staging/rtl8192e/rtllib_softmac.c b/drivers/staging/rtl8192e/rtllib_softmac.c index 6e2f620afd14..2c752ba5a802 100644 --- a/drivers/staging/rtl8192e/rtllib_softmac.c +++ b/drivers/staging/rtl8192e/rtllib_softmac.c @@ -2044,9 +2044,9 @@ static short rtllib_sta_ps_sleep(struct rtllib_device *ieee, u64 *time) } -static inline void rtllib_sta_ps(unsigned long data) +static inline void rtllib_sta_ps(struct tasklet_struct *t) { - struct rtllib_device *ieee = (struct rtllib_device *)data; + struct rtllib_device *ieee = from_tasklet(ieee, t, ps_task); u64 time; short sleep; unsigned long flags, flags2; @@ -3028,7 +3028,7 @@ void rtllib_softmac_init(struct rtllib_device *ieee) spin_lock_init(&ieee->mgmt_tx_lock); spin_lock_init(&ieee->beacon_lock); - tasklet_init(&ieee->ps_task, rtllib_sta_ps, (unsigned long)ieee); + tasklet_setup(&ieee->ps_task, rtllib_sta_ps); } diff --git a/drivers/staging/rtl8192e/rtllib_tx.c b/drivers/staging/rtl8192e/rtllib_tx.c index 79d7ad7c0a4a..e0d79daca24a 100644 --- a/drivers/staging/rtl8192e/rtllib_tx.c +++ b/drivers/staging/rtl8192e/rtllib_tx.c @@ -859,7 +859,7 @@ static int rtllib_xmit_inter(struct sk_buff *skb, struct net_device *dev) if (ieee->seq_ctrl[0] == 0xFFF) ieee->seq_ctrl[0] = 0; else - ieee->seq_ctrl[0]++; + ieee->seq_ctrl[0]++; } } else { if (unlikely(skb->len < sizeof(struct rtllib_hdr_3addr))) { diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c index 195d963c4fbb..b6fee7230ce0 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c @@ -597,7 +597,7 @@ static void RxReorderIndicatePacket(struct ieee80211_device *ieee, prxbIndicateArray = kmalloc_array(REORDER_WIN_SIZE, sizeof(struct ieee80211_rxb *), - GFP_KERNEL); + GFP_ATOMIC); if (!prxbIndicateArray) return; diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c index d8eb907ff301..690b664df8fa 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c @@ -1687,9 +1687,9 @@ static short ieee80211_sta_ps_sleep(struct ieee80211_device *ieee, u32 *time_h, return 1; } -static inline void ieee80211_sta_ps(unsigned long data) +static inline void ieee80211_sta_ps(struct tasklet_struct *t) { - struct ieee80211_device *ieee = (struct ieee80211_device *)data; + struct ieee80211_device *ieee = from_tasklet(ieee, t, ps_task); u32 th, tl; short sleep; @@ -2598,7 +2598,7 @@ void ieee80211_softmac_init(struct ieee80211_device *ieee) spin_lock_init(&ieee->mgmt_tx_lock); spin_lock_init(&ieee->beacon_lock); - tasklet_init(&ieee->ps_task, ieee80211_sta_ps, (unsigned long)ieee); + tasklet_setup(&ieee->ps_task, ieee80211_sta_ps); } void ieee80211_softmac_free(struct ieee80211_device *ieee) diff --git a/drivers/staging/rtl8192u/r8192U_core.c b/drivers/staging/rtl8192u/r8192U_core.c index 6ec65187bef9..27dc181c4c9b 100644 --- a/drivers/staging/rtl8192u/r8192U_core.c +++ b/drivers/staging/rtl8192u/r8192U_core.c @@ -2193,7 +2193,7 @@ static void rtl8192_init_priv_lock(struct r8192_priv *priv) static void rtl819x_watchdog_wqcallback(struct work_struct *work); -static void rtl8192_irq_rx_tasklet(unsigned long data); +static void rtl8192_irq_rx_tasklet(struct tasklet_struct *t); /* init tasklet and wait_queue here. only 2.6 above kernel is considered */ #define DRV_NAME "wlan0" static void rtl8192_init_priv_task(struct net_device *dev) @@ -2214,8 +2214,7 @@ static void rtl8192_init_priv_task(struct net_device *dev) InitialGainOperateWorkItemCallBack); INIT_WORK(&priv->qos_activate, rtl8192_qos_activate); - tasklet_init(&priv->irq_rx_tasklet, rtl8192_irq_rx_tasklet, - (unsigned long)priv); + tasklet_setup(&priv->irq_rx_tasklet, rtl8192_irq_rx_tasklet); } static void rtl8192_get_eeprom_size(struct net_device *dev) @@ -4647,9 +4646,9 @@ static void rtl8192_rx_cmd(struct sk_buff *skb) } } -static void rtl8192_irq_rx_tasklet(unsigned long data) +static void rtl8192_irq_rx_tasklet(struct tasklet_struct *t) { - struct r8192_priv *priv = (struct r8192_priv *)data; + struct r8192_priv *priv = from_tasklet(priv, t, irq_rx_tasklet); struct sk_buff *skb; struct rtl8192_rx_info *info; diff --git a/drivers/staging/rtl8192u/r8192U_dm.c b/drivers/staging/rtl8192u/r8192U_dm.c index 6b301acb584e..bac402b40121 100644 --- a/drivers/staging/rtl8192u/r8192U_dm.c +++ b/drivers/staging/rtl8192u/r8192U_dm.c @@ -26,6 +26,7 @@ Major Change History: static u32 edca_setting_DL[HT_IOT_PEER_MAX] = { 0x5e4322, 0x5e4322, 0x5e4322, 0x604322, 0x00a44f, 0x5ea44f }; + static u32 edca_setting_UL[HT_IOT_PEER_MAX] = { 0x5e4322, 0x00a44f, 0x5e4322, 0x604322, 0x5ea44f, 0x5ea44f }; @@ -599,7 +600,6 @@ static void dm_TXPowerTrackingCallback_TSSI(struct net_device *dev) priv->rfa_txpowertrackingindex++; priv->rfa_txpowertrackingindex_real++; rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfa_txpowertrackingindex_real].txbbgain_value); - } } priv->cck_present_attenuation_difference @@ -1268,7 +1268,6 @@ static void dm_InitializeTXPowerTracking_TSSI(struct net_device *dev) priv->btxpower_tracking = true; priv->txpower_count = 0; priv->btxpower_trackingInit = false; - } static void dm_InitializeTXPowerTracking_ThermalMeter(struct net_device *dev) @@ -1773,7 +1772,6 @@ static void dm_ctrl_initgain_byrssi_by_fwfalse_alarm( /* 1.5 Higher EDCCA. */ /*PlatformEFIOWrite4Byte(pAdapter, rOFDM0_ECCAThreshold, 0x325);*/ return; - } /* 2. When RSSI increase, We have to judge if it is larger than a threshold @@ -1836,7 +1834,6 @@ static void dm_ctrl_initgain_byrssi_by_fwfalse_alarm( /* 2.5 DIG On. */ rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1); /* Only clear byte 1 and rewrite. */ - } dm_ctrl_initgain_byrssi_highpwr(dev); @@ -2157,7 +2154,6 @@ static void dm_check_edca_turbo( write_nic_dword(dev, EDCAPARA_BE, edca_setting_UL[pHTInfo->IOTPeer]); priv->bis_cur_rdlstate = false; } - } priv->bcurrent_turbo_EDCA = true; @@ -2191,7 +2187,6 @@ static void dm_check_edca_turbo( write_nic_dword(dev, EDCAPARA_BE, u4bAcParam); - /* Check ACM bit. * If it is set, immediately set ACM control bit to downgrading AC for passing WMM testplan. Annie, 2005-12-13. */ @@ -2296,7 +2291,6 @@ static void dm_check_pbc_gpio(struct net_device *dev) RT_TRACE(COMP_IO, "CheckPbcGPIO - PBC is pressed\n"); priv->bpbc_pressed = true; } - } /*----------------------------------------------------------------------------- @@ -2495,7 +2489,6 @@ static void dm_rxpath_sel_byrssi(struct net_device *dev) cck_rx_ver2_min_index = i; } } - } } } @@ -2715,7 +2708,6 @@ static void dm_EndSWFsync(struct net_device *dev) priv->ContinueDiffCount = 0; write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c52cd); - } static void dm_StartSWFsync(struct net_device *dev) @@ -2751,7 +2743,6 @@ static void dm_StartSWFsync(struct net_device *dev) add_timer(&priv->fsync_timer); write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c12cd); - } static void dm_EndHWFsync(struct net_device *dev) @@ -2759,7 +2750,6 @@ static void dm_EndHWFsync(struct net_device *dev) RT_TRACE(COMP_HALDM, "%s\n", __func__); write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c52cd); write_nic_byte(dev, 0xc3b, 0x49); - } void dm_check_fsync(struct net_device *dev) diff --git a/drivers/staging/rtl8192u/r8192U_hw.h b/drivers/staging/rtl8192u/r8192U_hw.h index 95a2d2ee3c65..8d3a592f1c35 100644 --- a/drivers/staging/rtl8192u/r8192U_hw.h +++ b/drivers/staging/rtl8192u/r8192U_hw.h @@ -239,6 +239,7 @@ enum _RTL8192Usb_HW { #define EPROM_W_BIT BIT(1) #define EPROM_R_BIT BIT(0) }; + //---------------------------------------------------------------------------- // 818xB AnaParm & AnaParm2 Register //---------------------------------------------------------------------------- diff --git a/drivers/staging/rtl8192u/r8192U_wx.c b/drivers/staging/rtl8192u/r8192U_wx.c index 100532598781..d853586705fc 100644 --- a/drivers/staging/rtl8192u/r8192U_wx.c +++ b/drivers/staging/rtl8192u/r8192U_wx.c @@ -138,7 +138,6 @@ static int r8192_wx_force_reset(struct net_device *dev, priv->force_reset = *extra; mutex_unlock(&priv->wx_mutex); return 0; - } static int r8192_wx_set_rawtx(struct net_device *dev, @@ -155,7 +154,6 @@ static int r8192_wx_set_rawtx(struct net_device *dev, mutex_unlock(&priv->wx_mutex); return ret; - } static int r8192_wx_set_crcmon(struct net_device *dev, @@ -218,6 +216,7 @@ struct iw_range_with_scan_capa { /* Scan capabilities */ __u8 scan_capa; }; + static int rtl8180_wx_get_range(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) @@ -251,7 +250,7 @@ static int rtl8180_wx_get_range(struct net_device *dev, /* range->old_num_channels; */ /* range->old_num_frequency; */ /* range->old_freq[6]; */ /* Filler to keep "version" at the same offset */ - if (priv->rf_set_sens != NULL) + if (priv->rf_set_sens) range->sensitivity = priv->max_sens; /* signal level threshold range */ range->max_qual.qual = 100; @@ -294,7 +293,6 @@ static int rtl8180_wx_get_range(struct net_device *dev, /* range->max_r_time; */ /* Maximal retry lifetime */ for (i = 0, val = 0; i < 14; i++) { - /* Include only legal frequencies for some countries */ if ((GET_DOT11D_INFO(priv->ieee80211)->channel_map)[i+1]) { range->freq[val].i = i + 1; @@ -350,11 +348,9 @@ static int r8192_wx_set_scan(struct net_device *dev, struct iw_request_info *a, return ret; } - static int r8192_wx_get_scan(struct net_device *dev, struct iw_request_info *a, union iwreq_data *wrqu, char *b) { - int ret; struct r8192_priv *priv = ieee80211_priv(dev); @@ -444,7 +440,6 @@ static int r8192_wx_set_frag(struct net_device *dev, return 0; } - static int r8192_wx_get_frag(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) @@ -458,13 +453,11 @@ static int r8192_wx_get_frag(struct net_device *dev, return 0; } - static int r8192_wx_set_wap(struct net_device *dev, struct iw_request_info *info, union iwreq_data *awrq, char *extra) { - int ret; struct r8192_priv *priv = ieee80211_priv(dev); /* struct sockaddr *temp = (struct sockaddr *)awrq; */ @@ -475,7 +468,6 @@ static int r8192_wx_set_wap(struct net_device *dev, mutex_unlock(&priv->wx_mutex); return ret; - } static int r8192_wx_get_wap(struct net_device *dev, @@ -522,11 +514,8 @@ static int r8192_wx_set_enc(struct net_device *dev, mutex_unlock(&priv->wx_mutex); - - /* sometimes, the length is zero while we do not type key value */ if (wrqu->encoding.length != 0) { - for (i = 0; i < 4; i++) { hwkey[i] |= key[4*i+0]&mask; if (i == 1 && (4*i+1) == wrqu->encoding.length) @@ -572,10 +561,7 @@ static int r8192_wx_set_enc(struct net_device *dev, zero_addr[key_idx], 0, /* DefaultKey */ hwkey); /* KeyContent */ - - } - - else if (wrqu->encoding.length == 0xd) { + } else if (wrqu->encoding.length == 0xd) { ieee->pairwise_key_type = KEY_TYPE_WEP104; EnableHWSecurityConfig8192(dev); @@ -586,21 +572,17 @@ static int r8192_wx_set_enc(struct net_device *dev, zero_addr[key_idx], 0, /* DefaultKey */ hwkey); /* KeyContent */ - } else { netdev_warn(dev, "wrong type in WEP, not WEP40 and WEP104\n"); } - } return ret; } - static int r8192_wx_set_scan_type(struct net_device *dev, struct iw_request_info *aa, union iwreq_data *wrqu, char *p) { - struct r8192_priv *priv = ieee80211_priv(dev); int *parms = (int *)p; int mode = parms[0]; @@ -610,8 +592,6 @@ static int r8192_wx_set_scan_type(struct net_device *dev, struct iw_request_info return 1; } - - static int r8192_wx_set_retry(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) @@ -663,7 +643,6 @@ static int r8192_wx_get_retry(struct net_device *dev, { struct r8192_priv *priv = ieee80211_priv(dev); - wrqu->retry.disabled = 0; /* can't be disabled */ if ((wrqu->retry.flags & IW_RETRY_TYPE) == @@ -687,7 +666,7 @@ static int r8192_wx_get_sens(struct net_device *dev, { struct r8192_priv *priv = ieee80211_priv(dev); - if (priv->rf_set_sens == NULL) + if (!priv->rf_set_sens) return -1; /* we have not this support for this radio */ wrqu->sens.value = priv->sens; return 0; @@ -697,12 +676,11 @@ static int r8192_wx_set_sens(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { - struct r8192_priv *priv = ieee80211_priv(dev); short err = 0; mutex_lock(&priv->wx_mutex); - if (priv->rf_set_sens == NULL) { + if (!priv->rf_set_sens) { err = -1; /* we have not this support for this radio */ goto exit; } @@ -726,7 +704,6 @@ static int r8192_wx_set_enc_ext(struct net_device *dev, struct r8192_priv *priv = ieee80211_priv(dev); struct ieee80211_device *ieee = priv->ieee80211; - mutex_lock(&priv->wx_mutex); ret = ieee80211_wx_set_encode_ext(priv->ieee80211, info, wrqu, extra); @@ -758,7 +735,6 @@ static int r8192_wx_set_enc_ext(struct net_device *dev, memcpy((u8 *)key, ext->key, 16); /* we only get 16 bytes key.why? WB 2008.7.1 */ if ((alg & KEY_TYPE_WEP40) && (ieee->auth_mode != 2)) { - setKey(dev, idx, /* EntryNao */ idx, /* KeyIndex */ @@ -784,16 +760,14 @@ static int r8192_wx_set_enc_ext(struct net_device *dev, 0, /* DefaultKey */ key); /* KeyContent */ } - - } end_hw_sec: mutex_unlock(&priv->wx_mutex); return ret; - } + static int r8192_wx_set_auth(struct net_device *dev, struct iw_request_info *info, union iwreq_data *data, char *extra) @@ -811,7 +785,6 @@ static int r8192_wx_set_mlme(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { - int ret = 0; struct r8192_priv *priv = ieee80211_priv(dev); @@ -833,8 +806,6 @@ static int r8192_wx_set_gen_ie(struct net_device *dev, ret = ieee80211_wx_set_gen_ie(priv->ieee80211, extra, data->data.length); mutex_unlock(&priv->wx_mutex); return ret; - - } static int dummy(struct net_device *dev, struct iw_request_info *a, diff --git a/drivers/staging/rtl8192u/r819xU_cmdpkt.c b/drivers/staging/rtl8192u/r819xU_cmdpkt.c index bc98cdaf61ec..4cece40a92f6 100644 --- a/drivers/staging/rtl8192u/r819xU_cmdpkt.c +++ b/drivers/staging/rtl8192u/r819xU_cmdpkt.c @@ -336,7 +336,6 @@ static void cmpk_count_tx_status(struct net_device *dev, priv->stats.txretrycount += pstx_status->txretry; priv->stats.txfeedbackretry += pstx_status->txretry; - priv->stats.txmulticast += pstx_status->txmcok; priv->stats.txbroadcast += pstx_status->txbcok; priv->stats.txunicast += pstx_status->txucok; @@ -431,7 +430,7 @@ static void cmpk_handle_tx_rate_history(struct net_device *dev, u8 *pmsg) ptxrate = (cmpk_tx_rahis_t *)pmsg; - if (ptxrate == NULL) + if (!ptxrate) return; for (i = 0; i < 16; i++) { @@ -480,7 +479,7 @@ u32 cmpk_message_handle_rx(struct net_device *dev, /* 0. Check inpt arguments. It is a command queue message or * pointer is null. */ - if (pstats == NULL) + if (!pstats) return 0; /* This is not a command packet. */ /* 1. Read received command packet message length from RFD. */ diff --git a/drivers/staging/rtl8192u/r819xU_firmware.c b/drivers/staging/rtl8192u/r819xU_firmware.c index dd81d210bd49..4f8629e47e82 100644 --- a/drivers/staging/rtl8192u/r819xU_firmware.c +++ b/drivers/staging/rtl8192u/r819xU_firmware.c @@ -54,11 +54,9 @@ static bool fw_download_code(struct net_device *dev, u8 *code_virtual_address, if ((buffer_len - frag_offset) > frag_threshold) { frag_length = frag_threshold; bLastIniPkt = 0; - } else { frag_length = buffer_len - frag_offset; bLastIniPkt = 1; - } /* Allocate skb buffer to contain firmware info and tx descriptor info @@ -104,7 +102,6 @@ static bool fw_download_code(struct net_device *dev, u8 *code_virtual_address, } while (frag_offset < buffer_len); return rt_status; - } /* @@ -172,7 +169,6 @@ CPUCheckMainCodeOKAndTurnOnCPU_Fail: static bool CPUcheck_firmware_ready(struct net_device *dev) { - bool rt_status = true; int check_time = 200000; u32 CPU_status = 0; @@ -197,7 +193,6 @@ CPUCheckFirmwareReady_Fail: RT_TRACE(COMP_ERR, "ERR in %s()\n", __func__); rt_status = false; return rt_status; - } bool init_firmware(struct net_device *dev) @@ -338,7 +333,6 @@ download_firmware_fail: RT_TRACE(COMP_ERR, "ERR in %s()\n", __func__); rt_status = false; return rt_status; - } MODULE_FIRMWARE("RTL8192U/boot.img"); diff --git a/drivers/staging/rtl8192u/r819xU_firmware_img.h b/drivers/staging/rtl8192u/r819xU_firmware_img.h index 355da9157be1..61585a72465e 100644 --- a/drivers/staging/rtl8192u/r819xU_firmware_img.h +++ b/drivers/staging/rtl8192u/r819xU_firmware_img.h @@ -13,7 +13,6 @@ #define RadioD_ArrayLength 1 #define PHY_REGArrayLength 1 - extern u32 Rtl8192UsbPHY_REGArray[]; extern u32 Rtl8192UsbPHY_REG_1T2RArray[]; extern u32 Rtl8192UsbRadioA_Array[]; @@ -24,6 +23,4 @@ extern u32 Rtl8192UsbMACPHY_Array[]; extern u32 Rtl8192UsbMACPHY_Array_PG[]; extern u32 Rtl8192UsbAGCTAB_Array[]; - - #endif diff --git a/drivers/staging/rtl8192u/r819xU_phy.c b/drivers/staging/rtl8192u/r819xU_phy.c index 37b99cf4b35f..eef751d2b12e 100644 --- a/drivers/staging/rtl8192u/r819xU_phy.c +++ b/drivers/staging/rtl8192u/r819xU_phy.c @@ -67,7 +67,6 @@ u8 rtl8192_phy_CheckIsLegalRFPath(struct net_device *dev, u32 e_rfpath) void rtl8192_setBBreg(struct net_device *dev, u32 reg_addr, u32 bitmask, u32 data) { - u32 reg, bitshift; if (bitmask != bMaskDWord) { @@ -169,14 +168,12 @@ static u32 rtl8192_phy_RFSerialRead(struct net_device *dev, rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2, bLSSIReadEdge, 0x0); rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2, bLSSIReadEdge, 0x1); - /* TODO: we should not delay such a long time. Ask for help from SD3 */ usleep_range(1000, 1000); ret = rtl8192_QueryBBReg(dev, pPhyReg->rfLSSIReadBack, bLSSIReadBackData); - /* Switch back to Reg_Mode0 */ if (priv->rf_chip == RF_8256) { priv->RfReg0Value[e_rfpath] &= 0xebf; @@ -219,7 +216,6 @@ static void rtl8192_phy_RFSerialWrite(struct net_device *dev, offset &= 0x3f; if (priv->rf_chip == RF_8256) { - if (offset >= 31) { priv->RfReg0Value[e_rfpath] |= 0x140; rtl8192_setBBreg(dev, pPhyReg->rf3wireOffset, @@ -248,7 +244,6 @@ static void rtl8192_phy_RFSerialWrite(struct net_device *dev, /* Write operation */ rtl8192_setBBreg(dev, pPhyReg->rf3wireOffset, bMaskDWord, DataAndAddr); - if (offset == 0x0) priv->RfReg0Value[e_rfpath] = data; @@ -330,7 +325,6 @@ u32 rtl8192_phy_QueryRFReg(struct net_device *dev, u32 reg, bitshift; struct r8192_priv *priv = ieee80211_priv(dev); - if (!rtl8192_phy_CheckIsLegalRFPath(dev, e_rfpath)) return 0; if (priv->Rf_Mode == RF_OP_By_FW) { @@ -342,7 +336,6 @@ u32 rtl8192_phy_QueryRFReg(struct net_device *dev, bitshift = ffs(bitmask) - 1; reg = (reg & bitmask) >> bitshift; return reg; - } /****************************************************************************** @@ -700,7 +693,6 @@ u8 rtl8192_phy_checkBBAndRF(struct net_device *dev, enum hw90_block_e CheckBlock WriteAddr[HW90_BLOCK_RF] = 0x3; RT_TRACE(COMP_PHY, "%s(), CheckBlock: %d\n", __func__, CheckBlock); for (i = 0; i < CheckTimes; i++) { - /* Write data to register and readback */ switch (CheckBlock) { case HW90_BLOCK_MAC: @@ -735,7 +727,6 @@ u8 rtl8192_phy_checkBBAndRF(struct net_device *dev, enum hw90_block_e CheckBlock break; } - /* Check whether readback data is correct */ if (reg != WriteData[i]) { RT_TRACE((COMP_PHY|COMP_ERR), @@ -844,7 +835,6 @@ void rtl8192_BBConfig(struct net_device *dev) rtl8192_BB_Config_ParaFile(dev); } - /****************************************************************************** * function: This function obtains the initialization value of Tx power Level * offset @@ -961,13 +951,11 @@ void rtl8192_phy_updateInitGain(struct net_device *dev) u8 rtl8192_phy_ConfigRFWithHeaderFile(struct net_device *dev, enum rf90_radio_path_e e_rfpath) { - int i; switch (e_rfpath) { case RF90_PATH_A: for (i = 0; i < RadioA_ArrayLength; i = i+2) { - if (Rtl8192UsbRadioA_Array[i] == 0xfe) { mdelay(100); continue; @@ -977,12 +965,10 @@ u8 rtl8192_phy_ConfigRFWithHeaderFile(struct net_device *dev, bMask12Bits, Rtl8192UsbRadioA_Array[i+1]); mdelay(1); - } break; case RF90_PATH_B: for (i = 0; i < RadioB_ArrayLength; i = i+2) { - if (Rtl8192UsbRadioB_Array[i] == 0xfe) { mdelay(100); continue; @@ -992,12 +978,10 @@ u8 rtl8192_phy_ConfigRFWithHeaderFile(struct net_device *dev, bMask12Bits, Rtl8192UsbRadioB_Array[i+1]); mdelay(1); - } break; case RF90_PATH_C: for (i = 0; i < RadioC_ArrayLength; i = i+2) { - if (Rtl8192UsbRadioC_Array[i] == 0xfe) { mdelay(100); continue; @@ -1007,12 +991,10 @@ u8 rtl8192_phy_ConfigRFWithHeaderFile(struct net_device *dev, bMask12Bits, Rtl8192UsbRadioC_Array[i+1]); mdelay(1); - } break; case RF90_PATH_D: for (i = 0; i < RadioD_ArrayLength; i = i+2) { - if (Rtl8192UsbRadioD_Array[i] == 0xfe) { mdelay(100); continue; @@ -1022,7 +1004,6 @@ u8 rtl8192_phy_ConfigRFWithHeaderFile(struct net_device *dev, bMask12Bits, Rtl8192UsbRadioD_Array[i+1]); mdelay(1); - } break; default: @@ -1030,7 +1011,6 @@ u8 rtl8192_phy_ConfigRFWithHeaderFile(struct net_device *dev, } return 0; - } /****************************************************************************** @@ -1170,7 +1150,7 @@ static u8 rtl8192_phy_SetSwChnlCmdArray(struct sw_chnl_cmd *CmdTable, u32 CmdTab { struct sw_chnl_cmd *pCmd; - if (CmdTable == NULL) { + if (!CmdTable) { RT_TRACE(COMP_ERR, "%s(): CmdTable cannot be NULL\n", __func__); return false; } @@ -1225,7 +1205,6 @@ static u8 rtl8192_phy_SwChnlStepByStep(struct net_device *dev, u8 channel, } /* FIXME: need to check whether channel is legal or not here */ - /* <1> Fill up pre common command. */ PreCommonCmdCnt = 0; rtl8192_phy_SetSwChnlCmdArray(PreCommonCmd, PreCommonCmdCnt++, @@ -1286,7 +1265,6 @@ static u8 rtl8192_phy_SwChnlStepByStep(struct net_device *dev, u8 channel, return true; } - do { switch (*stage) { case 0: @@ -1378,13 +1356,11 @@ static void rtl8192_phy_FinishSwChnlNow(struct net_device *dev, u8 channel) *****************************************************************************/ void rtl8192_SwChnl_WorkItem(struct net_device *dev) { - struct r8192_priv *priv = ieee80211_priv(dev); RT_TRACE(COMP_CH, "==> SwChnlCallback819xUsbWorkItem(), chan:%d\n", priv->chan); - rtl8192_phy_FinishSwChnlNow(dev, priv->chan); RT_TRACE(COMP_CH, "<== SwChnlCallback819xUsbWorkItem()\n"); @@ -1459,14 +1435,12 @@ u8 rtl8192_phy_SwChnl(struct net_device *dev, u8 channel) *****************************************************************************/ void rtl8192_SetBWModeWorkItem(struct net_device *dev) { - struct r8192_priv *priv = ieee80211_priv(dev); u8 regBwOpMode; RT_TRACE(COMP_SWBW, "%s() Switch to %s bandwidth\n", __func__, priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20?"20MHz":"40MHz"); - if (priv->rf_chip == RF_PSEUDO_11N) { priv->SetBWModeInProgress = false; return; @@ -1563,7 +1537,6 @@ void rtl8192_SetBWModeWorkItem(struct net_device *dev) "SetChannelBandwidth819xUsb(): unknown Bandwidth: %#X\n", priv->CurrentChannelBW); break; - } /* Skip over setting of J-mode in BB register here. * Default value is "None J mode". @@ -1624,7 +1597,6 @@ void rtl8192_SetBWMode(struct net_device *dev, priv->nCur40MhzPrimeSC = HAL_PRIME_CHNL_OFFSET_DONT_CARE; rtl8192_SetBWModeWorkItem(dev); - } void InitialGain819xUsb(struct net_device *dev, u8 Operation) diff --git a/drivers/staging/rtl8192u/r819xU_phyreg.h b/drivers/staging/rtl8192u/r819xU_phyreg.h index dc9ddf100eab..c9669821b278 100644 --- a/drivers/staging/rtl8192u/r819xU_phyreg.h +++ b/drivers/staging/rtl8192u/r819xU_phyreg.h @@ -2,7 +2,6 @@ #ifndef _R819XU_PHYREG_H #define _R819XU_PHYREG_H - #define RF_DATA 0x1d4 /* FW will write RF data in the register.*/ /* page8 */ @@ -81,7 +80,6 @@ #define rOFDM0_XDTxIQImbalance 0xc98 #define rOFDM0_XDTxAFE 0xc9c - /* page d */ #define rOFDM1_LSTF 0xd00 #define rOFDM1_TRxPathEnable 0xd04 @@ -95,7 +93,6 @@ #define rTxAGC_Mcs11_Mcs08 0xe18 #define rTxAGC_Mcs15_Mcs12 0xe1c - /* RF * Zebra1 */ diff --git a/drivers/staging/rtl8712/rtl8712_recv.c b/drivers/staging/rtl8712/rtl8712_recv.c index d83f421acfc1..db5c7a487ab3 100644 --- a/drivers/staging/rtl8712/rtl8712_recv.c +++ b/drivers/staging/rtl8712/rtl8712_recv.c @@ -28,7 +28,7 @@ #include "usb_ops.h" #include "wifi.h" -static void recv_tasklet(unsigned long priv); +static void recv_tasklet(struct tasklet_struct *t); void r8712_init_recv_priv(struct recv_priv *precvpriv, struct _adapter *padapter) @@ -60,8 +60,7 @@ void r8712_init_recv_priv(struct recv_priv *precvpriv, precvbuf++; } precvpriv->free_recv_buf_queue_cnt = NR_RECVBUFF; - tasklet_init(&precvpriv->recv_tasklet, recv_tasklet, - (unsigned long)padapter); + tasklet_setup(&precvpriv->recv_tasklet, recv_tasklet); skb_queue_head_init(&precvpriv->rx_skb_queue); skb_queue_head_init(&precvpriv->free_recv_skb_queue); @@ -477,11 +476,14 @@ static int enqueue_reorder_recvframe(struct recv_reorder_ctrl *preorder_ctrl, while (!end_of_queue_search(phead, plist)) { pnextrframe = container_of(plist, union recv_frame, u.list); pnextattrib = &pnextrframe->u.hdr.attrib; + + if (SN_EQUAL(pnextattrib->seq_num, pattrib->seq_num)) + return false; + if (SN_LESS(pnextattrib->seq_num, pattrib->seq_num)) plist = plist->next; - else if (SN_EQUAL(pnextattrib->seq_num, pattrib->seq_num)) - return false; - break; + else + break; } list_del_init(&(prframe->u.hdr.list)); list_add_tail(&(prframe->u.hdr.list), plist); @@ -1057,10 +1059,11 @@ static void recvbuf2recvframe(struct _adapter *padapter, struct sk_buff *pskb) } while ((transfer_len > 0) && pkt_cnt > 0); } -static void recv_tasklet(unsigned long priv) +static void recv_tasklet(struct tasklet_struct *t) { struct sk_buff *pskb; - struct _adapter *padapter = (struct _adapter *)priv; + struct _adapter *padapter = from_tasklet(padapter, t, + recvpriv.recv_tasklet); struct recv_priv *precvpriv = &padapter->recvpriv; while (NULL != (pskb = skb_dequeue(&precvpriv->rx_skb_queue))) { diff --git a/drivers/staging/rtl8712/rtl871x_cmd.c b/drivers/staging/rtl8712/rtl871x_cmd.c index c7523072a660..18116469bd31 100644 --- a/drivers/staging/rtl8712/rtl871x_cmd.c +++ b/drivers/staging/rtl8712/rtl871x_cmd.c @@ -161,7 +161,7 @@ void r8712_free_cmd_obj(struct cmd_obj *pcmd) if ((pcmd->cmdcode != _JoinBss_CMD_) && (pcmd->cmdcode != _CreateBss_CMD_)) kfree(pcmd->parmbuf); - if (pcmd->rsp != NULL) { + if (pcmd->rsp) { if (pcmd->rspsz != 0) kfree(pcmd->rsp); } @@ -191,7 +191,7 @@ u8 r8712_sitesurvey_cmd(struct _adapter *padapter, psurveyPara->passive_mode = cpu_to_le32(pmlmepriv->passive_mode); psurveyPara->ss_ssidlen = 0; memset(psurveyPara->ss_ssid, 0, IW_ESSID_MAX_SIZE + 1); - if ((pssid != NULL) && (pssid->SsidLength)) { + if (pssid && pssid->SsidLength) { memcpy(psurveyPara->ss_ssid, pssid->Ssid, pssid->SsidLength); psurveyPara->ss_ssidlen = cpu_to_le32(pssid->SsidLength); } diff --git a/drivers/staging/rtl8712/rtl871x_io.c b/drivers/staging/rtl8712/rtl871x_io.c index 87024d6a465e..6789a4c98564 100644 --- a/drivers/staging/rtl8712/rtl871x_io.c +++ b/drivers/staging/rtl8712/rtl871x_io.c @@ -50,7 +50,7 @@ static uint _init_intf_hdl(struct _adapter *padapter, init_intf_priv = &r8712_usb_init_intf_priv; pintf_priv = pintf_hdl->pintfpriv = kmalloc(sizeof(struct intf_priv), GFP_ATOMIC); - if (pintf_priv == NULL) + if (!pintf_priv) goto _init_intf_hdl_fail; pintf_hdl->adapter = (u8 *)padapter; set_intf_option(&pintf_hdl->intf_option); diff --git a/drivers/staging/rtl8712/rtl871x_ioctl_linux.c b/drivers/staging/rtl8712/rtl871x_ioctl_linux.c index df6ae855f3c1..cbaa7a489748 100644 --- a/drivers/staging/rtl8712/rtl871x_ioctl_linux.c +++ b/drivers/staging/rtl8712/rtl871x_ioctl_linux.c @@ -481,11 +481,11 @@ static int r871x_set_wpa_ie(struct _adapter *padapter, char *pie, int group_cipher = 0, pairwise_cipher = 0; int ret = 0; - if ((ielen > MAX_WPA_IE_LEN) || (pie == NULL)) + if (ielen > MAX_WPA_IE_LEN || !pie) return -EINVAL; if (ielen) { buf = kmemdup(pie, ielen, GFP_ATOMIC); - if (buf == NULL) + if (!buf) return -ENOMEM; if (ielen < RSN_HEADER_LEN) { ret = -EINVAL; @@ -777,7 +777,7 @@ static int r871x_wx_set_pmkid(struct net_device *dev, * If cmd is IW_PMKSA_REMOVE, it means the wpa_supplicant wants to * remove a PMKID/BSSID from driver. */ - if (pPMK == NULL) + if (!pPMK) return -EINVAL; memcpy(strIssueBssid, pPMK->bssid.sa_data, ETH_ALEN); switch (pPMK->cmd) { @@ -1099,7 +1099,7 @@ static int r871x_wx_set_mlme(struct net_device *dev, struct _adapter *padapter = netdev_priv(dev); struct iw_mlme *mlme = (struct iw_mlme *) extra; - if (mlme == NULL) + if (!mlme) return -1; switch (mlme->cmd) { case IW_MLME_DEAUTH: @@ -1950,7 +1950,7 @@ static int r871x_get_ap_info(struct net_device *dev, u8 bssid[ETH_ALEN]; char data[33]; - if (padapter->driver_stopped || (pdata == NULL)) + if (padapter->driver_stopped || !pdata) return -EINVAL; while (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY | _FW_UNDER_LINKING)) { @@ -2014,7 +2014,7 @@ static int r871x_set_pid(struct net_device *dev, struct _adapter *padapter = netdev_priv(dev); struct iw_point *pdata = &wrqu->data; - if ((padapter->driver_stopped) || (pdata == NULL)) + if (padapter->driver_stopped || !pdata) return -EINVAL; if (copy_from_user(&padapter->pid, pdata->pointer, sizeof(int))) return -EINVAL; @@ -2030,7 +2030,7 @@ static int r871x_set_chplan(struct net_device *dev, struct iw_point *pdata = &wrqu->data; int ch_plan = -1; - if ((padapter->driver_stopped) || (pdata == NULL)) { + if (padapter->driver_stopped || !pdata) { ret = -EINVAL; goto exit; } @@ -2050,7 +2050,7 @@ static int r871x_wps_start(struct net_device *dev, struct iw_point *pdata = &wrqu->data; u32 u32wps_start = 0; - if ((padapter->driver_stopped) || (pdata == NULL)) + if (padapter->driver_stopped || !pdata) return -EINVAL; if (copy_from_user((void *)&u32wps_start, pdata->pointer, 4)) return -EFAULT; diff --git a/drivers/staging/rtl8712/rtl871x_mlme.c b/drivers/staging/rtl8712/rtl871x_mlme.c index 2ccd49032206..6074383ec0b5 100644 --- a/drivers/staging/rtl8712/rtl871x_mlme.c +++ b/drivers/staging/rtl8712/rtl871x_mlme.c @@ -754,7 +754,7 @@ void r8712_joinbss_event_callback(struct _adapter *adapter, u8 *pbuf) ptarget_wlan->fixed = true; } - if (ptarget_wlan == NULL) { + if (!ptarget_wlan) { if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) pmlmepriv->fw_state ^= @@ -768,7 +768,7 @@ void r8712_joinbss_event_callback(struct _adapter *adapter, u8 *pbuf) ptarget_sta = r8712_get_stainfo(pstapriv, pnetwork->network.MacAddress); - if (ptarget_sta == NULL) + if (!ptarget_sta) ptarget_sta = r8712_alloc_stainfo(pstapriv, pnetwork->network.MacAddress); @@ -879,7 +879,7 @@ void r8712_stassoc_event_callback(struct _adapter *adapter, u8 *pbuf) if (!r8712_access_ctrl(&adapter->acl_list, pstassoc->macaddr)) return; psta = r8712_get_stainfo(&adapter->stapriv, pstassoc->macaddr); - if (psta != NULL) { + if (psta) { /*the sta have been in sta_info_queue => do nothing *(between drv has received this event before and * fw have not yet to set key to CAM_ENTRY) @@ -888,7 +888,7 @@ void r8712_stassoc_event_callback(struct _adapter *adapter, u8 *pbuf) } psta = r8712_alloc_stainfo(&adapter->stapriv, pstassoc->macaddr); - if (psta == NULL) + if (!psta) return; /* to do : init sta_info variable */ psta->qos_option = 0; @@ -1080,8 +1080,7 @@ int r8712_select_and_join_from_scan(struct mlme_priv *pmlmepriv) pmlmepriv->pscanned = phead->next; while (1) { if (end_of_queue_search(phead, pmlmepriv->pscanned)) { - if ((pmlmepriv->assoc_by_rssi) && - (pnetwork_max_rssi != NULL)) { + if (pmlmepriv->assoc_by_rssi && pnetwork_max_rssi) { pnetwork = pnetwork_max_rssi; goto ask_for_joinbss; } diff --git a/drivers/staging/rtl8712/rtl871x_mp_ioctl.c b/drivers/staging/rtl8712/rtl871x_mp_ioctl.c index 29b85330815f..f906d3fbe179 100644 --- a/drivers/staging/rtl8712/rtl871x_mp_ioctl.c +++ b/drivers/staging/rtl8712/rtl871x_mp_ioctl.c @@ -186,7 +186,7 @@ static int mp_start_test(struct _adapter *padapter) if (psta) r8712_free_stainfo(padapter, psta); psta = r8712_alloc_stainfo(&padapter->stapriv, bssid.MacAddress); - if (psta == NULL) { + if (!psta) { res = -ENOMEM; goto end_of_mp_start_test; } diff --git a/drivers/staging/rtl8712/rtl871x_recv.c b/drivers/staging/rtl8712/rtl871x_recv.c index c1bfd61824ef..eb4e46a7f743 100644 --- a/drivers/staging/rtl8712/rtl871x_recv.c +++ b/drivers/staging/rtl8712/rtl871x_recv.c @@ -58,7 +58,7 @@ void _r8712_init_recv_priv(struct recv_priv *precvpriv, precvpriv->pallocated_frame_buf = kzalloc(NR_RECVFRAME * sizeof(union recv_frame) + RXFRAME_ALIGN_SZ, GFP_ATOMIC); - if (precvpriv->pallocated_frame_buf == NULL) + if (!precvpriv->pallocated_frame_buf) return; kmemleak_not_leak(precvpriv->pallocated_frame_buf); precvpriv->precv_frame_buf = precvpriv->pallocated_frame_buf + @@ -97,7 +97,7 @@ union recv_frame *r8712_alloc_recvframe(struct __queue *pfree_recv_queue) if (precvframe) { list_del_init(&precvframe->u.hdr.list); padapter = precvframe->u.hdr.adapter; - if (padapter != NULL) { + if (padapter) { precvpriv = &padapter->recvpriv; if (pfree_recv_queue == &precvpriv->free_recv_queue) precvpriv->free_recvframe_cnt--; @@ -145,7 +145,7 @@ sint r8712_recvframe_chkmic(struct _adapter *adapter, stainfo = r8712_get_stainfo(&adapter->stapriv, &prxattrib->ta[0]); if (prxattrib->encrypt == _TKIP_) { /* calculate mic code */ - if (stainfo != NULL) { + if (stainfo) { if (is_multicast_ether_addr(prxattrib->ra)) { iv = precvframe->u.hdr.rx_data + prxattrib->hdrlen; @@ -242,7 +242,7 @@ union recv_frame *r8712_portctrl(struct _adapter *adapter, ptr = ptr + pfhdr->attrib.hdrlen + LLC_HEADER_SIZE; ether_type = get_unaligned_be16(ptr); - if ((psta != NULL) && (psta->ieee8021x_blocked)) { + if (psta && psta->ieee8021x_blocked) { /* blocked * only accept EAPOL frame */ @@ -349,7 +349,7 @@ static sint sta2sta_data_frame(struct _adapter *adapter, *psta = r8712_get_bcmc_stainfo(adapter); else *psta = r8712_get_stainfo(pstapriv, sta_addr); /* get ap_info */ - if (*psta == NULL) { + if (!*psta) { if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) adapter->mppriv.rx_pktloss++; return _FAIL; @@ -399,7 +399,7 @@ static sint ap2sta_data_frame(struct _adapter *adapter, *psta = r8712_get_bcmc_stainfo(adapter); else *psta = r8712_get_stainfo(pstapriv, pattrib->bssid); - if (*psta == NULL) + if (!*psta) return _FAIL; } else if (check_fwstate(pmlmepriv, WIFI_MP_STATE) && check_fwstate(pmlmepriv, _FW_LINKED)) { @@ -410,7 +410,7 @@ static sint ap2sta_data_frame(struct _adapter *adapter, memcpy(pattrib->ta, pattrib->src, ETH_ALEN); memcpy(pattrib->bssid, mybssid, ETH_ALEN); *psta = r8712_get_stainfo(pstapriv, pattrib->bssid); - if (*psta == NULL) + if (!*psta) return _FAIL; } else { return _FAIL; @@ -435,7 +435,7 @@ static sint sta2ap_data_frame(struct _adapter *adapter, if (memcmp(pattrib->bssid, mybssid, ETH_ALEN)) return _FAIL; *psta = r8712_get_stainfo(pstapriv, pattrib->src); - if (*psta == NULL) + if (!*psta) return _FAIL; } return _SUCCESS; @@ -469,7 +469,7 @@ static sint validate_recv_data_frame(struct _adapter *adapter, pda = get_da(ptr); psa = get_sa(ptr); pbssid = get_hdr_bssid(ptr); - if (pbssid == NULL) + if (!pbssid) return _FAIL; memcpy(pattrib->dst, pda, ETH_ALEN); memcpy(pattrib->src, psa, ETH_ALEN); @@ -499,7 +499,7 @@ static sint validate_recv_data_frame(struct _adapter *adapter, } if (res == _FAIL) return _FAIL; - if (psta == NULL) + if (!psta) return _FAIL; precv_frame->u.hdr.psta = psta; pattrib->amsdu = 0; diff --git a/drivers/staging/rtl8712/rtl871x_security.c b/drivers/staging/rtl8712/rtl871x_security.c index c05010d85212..5000c87752d3 100644 --- a/drivers/staging/rtl8712/rtl871x_security.c +++ b/drivers/staging/rtl8712/rtl871x_security.c @@ -584,7 +584,7 @@ u32 r8712_tkip_encrypt(struct _adapter *padapter, u8 *pxmitframe) else stainfo = r8712_get_stainfo(&padapter->stapriv, &pattrib->ra[0]); - if (stainfo != NULL) { + if (stainfo) { prwskey = &stainfo->x_UncstKey.skey[0]; for (curfragnum = 0; curfragnum < pattrib->nr_frags; curfragnum++) { @@ -658,7 +658,7 @@ void r8712_tkip_decrypt(struct _adapter *padapter, u8 *precvframe) if (prxattrib->encrypt == _TKIP_) { stainfo = r8712_get_stainfo(&padapter->stapriv, &prxattrib->ta[0]); - if (stainfo != NULL) { + if (stainfo) { iv = pframe + prxattrib->hdrlen; payload = pframe + prxattrib->iv_len + prxattrib->hdrlen; @@ -1155,7 +1155,7 @@ u32 r8712_aes_encrypt(struct _adapter *padapter, u8 *pxmitframe) else stainfo = r8712_get_stainfo(&padapter->stapriv, &pattrib->ra[0]); - if (stainfo != NULL) { + if (stainfo) { prwskey = &stainfo->x_UncstKey.skey[0]; for (curfragnum = 0; curfragnum < pattrib->nr_frags; curfragnum++) { @@ -1357,7 +1357,7 @@ void r8712_aes_decrypt(struct _adapter *padapter, u8 *precvframe) if (prxattrib->encrypt == _AES_) { stainfo = r8712_get_stainfo(&padapter->stapriv, &prxattrib->ta[0]); - if (stainfo != NULL) { + if (stainfo) { if (is_multicast_ether_addr(prxattrib->ra)) { iv = pframe + prxattrib->hdrlen; idx = iv[3]; diff --git a/drivers/staging/rtl8712/rtl871x_sta_mgt.c b/drivers/staging/rtl8712/rtl871x_sta_mgt.c index 653812c5d5a8..706e9db0fc5b 100644 --- a/drivers/staging/rtl8712/rtl871x_sta_mgt.c +++ b/drivers/staging/rtl8712/rtl871x_sta_mgt.c @@ -149,7 +149,7 @@ void r8712_free_stainfo(struct _adapter *padapter, struct sta_info *psta) struct xmit_priv *pxmitpriv = &padapter->xmitpriv; struct sta_priv *pstapriv = &padapter->stapriv; - if (psta == NULL) + if (!psta) return; pfree_sta_queue = &pstapriv->free_sta_queue; pstaxmitpriv = &psta->sta_xmitpriv; @@ -222,7 +222,7 @@ struct sta_info *r8712_get_stainfo(struct sta_priv *pstapriv, u8 *hwaddr) struct sta_info *psta = NULL; u32 index; - if (hwaddr == NULL) + if (!hwaddr) return NULL; index = wifi_mac_hash(hwaddr); spin_lock_irqsave(&pstapriv->sta_hash_lock, irqL); diff --git a/drivers/staging/rtl8712/rtl871x_xmit.c b/drivers/staging/rtl8712/rtl871x_xmit.c index 8b88fd5dc9a1..fd99782a400a 100644 --- a/drivers/staging/rtl8712/rtl871x_xmit.c +++ b/drivers/staging/rtl8712/rtl871x_xmit.c @@ -144,8 +144,7 @@ int _r8712_init_xmit_priv(struct xmit_priv *pxmitpriv, INIT_WORK(&padapter->wk_filter_rx_ff0, r8712_SetFilter); alloc_hwxmits(padapter); init_hwxmits(pxmitpriv->hwxmits, pxmitpriv->hwxmit_entry); - tasklet_init(&pxmitpriv->xmit_tasklet, r8712_xmit_bh, - (unsigned long)padapter); + tasklet_setup(&pxmitpriv->xmit_tasklet, r8712_xmit_bh); return 0; } @@ -157,7 +156,7 @@ void _free_xmit_priv(struct xmit_priv *pxmitpriv) pxmitpriv->pxmit_frame_buf; struct xmit_buf *pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmitbuf; - if (pxmitpriv->pxmit_frame_buf == NULL) + if (!pxmitpriv->pxmit_frame_buf) return; for (i = 0; i < NR_XMITFRAME; i++) { r8712_xmit_complete(padapter, pxmitframe); @@ -270,7 +269,7 @@ int r8712_update_attrib(struct _adapter *padapter, _pkt *pkt, pattrib->mac_id = 5; } else { psta = r8712_get_stainfo(pstapriv, pattrib->ra); - if (psta == NULL) /* drop the pkt */ + if (!psta) /* drop the pkt */ return -ENOMEM; if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) pattrib->mac_id = 5; @@ -353,7 +352,7 @@ static int xmitframe_addmic(struct _adapter *padapter, struct pkt_attrib *pattrib = &pxmitframe->attrib; struct security_priv *psecpriv = &padapter->securitypriv; struct xmit_priv *pxmitpriv = &padapter->xmitpriv; - u8 priority[4] = {0x0, 0x0, 0x0, 0x0}; + u8 priority[4] = {}; bool bmcst = is_multicast_ether_addr(pattrib->ra); if (pattrib->psta) @@ -363,10 +362,9 @@ static int xmitframe_addmic(struct _adapter *padapter, &pattrib->ra[0]); if (pattrib->encrypt == _TKIP_) { /*encode mic code*/ - if (stainfo != NULL) { - u8 null_key[16] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0}; + if (stainfo) { + u8 null_key[16] = {}; + pframe = pxmitframe->buf_addr + TXDESC_OFFSET; if (bmcst) { if (!memcmp(psecpriv->XGrptxmickey @@ -593,10 +591,10 @@ sint r8712_xmitframe_coalesce(struct _adapter *padapter, _pkt *pkt, u8 *pbuf_start; bool bmcst = is_multicast_ether_addr(pattrib->ra); - if (pattrib->psta == NULL) + if (!pattrib->psta) return _FAIL; psta = pattrib->psta; - if (pxmitframe->buf_addr == NULL) + if (!pxmitframe->buf_addr) return _FAIL; pbuf_start = pxmitframe->buf_addr; ptxdesc = pbuf_start; @@ -624,7 +622,7 @@ sint r8712_xmitframe_coalesce(struct _adapter *padapter, _pkt *pkt, mpdu_len -= pattrib->hdrlen; /* adding icv, if necessary...*/ if (pattrib->iv_len) { - if (psta != NULL) { + if (psta) { switch (pattrib->encrypt) { case _WEP40_: case _WEP104_: @@ -712,7 +710,7 @@ void r8712_update_protection(struct _adapter *padapter, u8 *ie, uint ie_len) case AUTO_VCS: default: perp = r8712_get_ie(ie, _ERPINFO_IE_, &erp_len, ie_len); - if (perp == NULL) { + if (!perp) { pxmitpriv->vcs = NONE_VCS; } else { protection = (*(perp + 2)) & BIT(1); @@ -751,7 +749,7 @@ void r8712_free_xmitbuf(struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf) unsigned long irqL; struct __queue *pfree_xmitbuf_queue = &pxmitpriv->free_xmitbuf_queue; - if (pxmitbuf == NULL) + if (!pxmitbuf) return; spin_lock_irqsave(&pfree_xmitbuf_queue->lock, irqL); list_del_init(&pxmitbuf->list); @@ -804,7 +802,7 @@ void r8712_free_xmitframe(struct xmit_priv *pxmitpriv, struct __queue *pfree_xmit_queue = &pxmitpriv->free_xmit_queue; struct _adapter *padapter = pxmitpriv->adapter; - if (pxmitframe == NULL) + if (!pxmitframe) return; spin_lock_irqsave(&pfree_xmit_queue->lock, irqL); list_del_init(&pxmitframe->list); @@ -820,7 +818,7 @@ void r8712_free_xmitframe(struct xmit_priv *pxmitpriv, void r8712_free_xmitframe_ex(struct xmit_priv *pxmitpriv, struct xmit_frame *pxmitframe) { - if (pxmitframe == NULL) + if (!pxmitframe) return; if (pxmitframe->frame_tag == DATA_FRAMETAG) r8712_free_xmitframe(pxmitpriv, pxmitframe); @@ -911,7 +909,7 @@ int r8712_xmit_classifier(struct _adapter *padapter, psta = r8712_get_stainfo(pstapriv, pattrib->ra); } } - if (psta == NULL) + if (!psta) return -EINVAL; ptxservq = get_sta_pending(padapter, &pstapending, psta, pattrib->priority); @@ -1023,7 +1021,7 @@ int r8712_pre_xmit(struct _adapter *padapter, struct xmit_frame *pxmitframe) return ret; } pxmitbuf = r8712_alloc_xmitbuf(pxmitpriv); - if (pxmitbuf == NULL) { /*enqueue packet*/ + if (!pxmitbuf) { /*enqueue packet*/ ret = false; r8712_xmit_enqueue(padapter, pxmitframe); spin_unlock_irqrestore(&pxmitpriv->lock, irqL); diff --git a/drivers/staging/rtl8712/rtl871x_xmit.h b/drivers/staging/rtl8712/rtl871x_xmit.h index c0c0c781fe17..cc58c7216935 100644 --- a/drivers/staging/rtl8712/rtl871x_xmit.h +++ b/drivers/staging/rtl8712/rtl871x_xmit.h @@ -277,7 +277,7 @@ int r8712_pre_xmit(struct _adapter *padapter, struct xmit_frame *pxmitframe); int r8712_xmit_enqueue(struct _adapter *padapter, struct xmit_frame *pxmitframe); void r8712_xmit_direct(struct _adapter *padapter, struct xmit_frame *pxmitframe); -void r8712_xmit_bh(unsigned long priv); +void r8712_xmit_bh(struct tasklet_struct *t); void xmitframe_xmitbuf_attach(struct xmit_frame *pxmitframe, struct xmit_buf *pxmitbuf); diff --git a/drivers/staging/rtl8712/usb_intf.c b/drivers/staging/rtl8712/usb_intf.c index 2fcd65260f4c..dc21e7743349 100644 --- a/drivers/staging/rtl8712/usb_intf.c +++ b/drivers/staging/rtl8712/usb_intf.c @@ -577,7 +577,7 @@ static int r871xu_drv_init(struct usb_interface *pusb_intf, error: usb_put_dev(udev); usb_set_intfdata(pusb_intf, NULL); - if (padapter && padapter->dvobj_deinit != NULL) + if (padapter && padapter->dvobj_deinit) padapter->dvobj_deinit(padapter); if (pnetdev) free_netdev(pnetdev); diff --git a/drivers/staging/rtl8712/usb_ops_linux.c b/drivers/staging/rtl8712/usb_ops_linux.c index 9a04a752af13..655497cead12 100644 --- a/drivers/staging/rtl8712/usb_ops_linux.c +++ b/drivers/staging/rtl8712/usb_ops_linux.c @@ -308,10 +308,11 @@ void r8712_usb_read_port_cancel(struct _adapter *padapter) } } -void r8712_xmit_bh(unsigned long priv) +void r8712_xmit_bh(struct tasklet_struct *t) { int ret = false; - struct _adapter *padapter = (struct _adapter *)priv; + struct _adapter *padapter = from_tasklet(padapter, t, + xmitpriv.xmit_tasklet); struct xmit_priv *pxmitpriv = &padapter->xmitpriv; if (padapter->driver_stopped || diff --git a/drivers/staging/rtl8723bs/core/rtw_ap.c b/drivers/staging/rtl8723bs/core/rtw_ap.c index a76e81330756..4f270d509ad3 100644 --- a/drivers/staging/rtl8723bs/core/rtw_ap.c +++ b/drivers/staging/rtl8723bs/core/rtw_ap.c @@ -8,6 +8,7 @@ #include <drv_types.h> #include <rtw_debug.h> +#include <asm/unaligned.h> extern unsigned char RTW_WPA_OUI[]; extern unsigned char WMM_OUI[]; @@ -995,12 +996,12 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf, int len) /* beacon interval */ p = rtw_get_beacon_interval_from_ie(ie);/* ie + 8; 8: TimeStamp, 2: Beacon Interval 2:Capability */ /* pbss_network->Configuration.BeaconPeriod = le16_to_cpu(*(unsigned short*)p); */ - pbss_network->Configuration.BeaconPeriod = RTW_GET_LE16(p); + pbss_network->Configuration.BeaconPeriod = get_unaligned_le16(p); /* capability */ /* cap = *(unsigned short *)rtw_get_capability_from_ie(ie); */ /* cap = le16_to_cpu(cap); */ - cap = RTW_GET_LE16(ie); + cap = get_unaligned_le16(ie); /* SSID */ p = rtw_get_ie( diff --git a/drivers/staging/rtl8723bs/core/rtw_cmd.c b/drivers/staging/rtl8723bs/core/rtw_cmd.c index bd18d1803e27..2abe205e3453 100644 --- a/drivers/staging/rtl8723bs/core/rtw_cmd.c +++ b/drivers/staging/rtl8723bs/core/rtw_cmd.c @@ -469,7 +469,7 @@ _next: pcmdpriv->cmd_issued_cnt++; - pcmd->cmdsz = _RND4((pcmd->cmdsz));/* _RND4 */ + pcmd->cmdsz = round_up((pcmd->cmdsz), 4); memcpy(pcmdbuf, pcmd->parmbuf, pcmd->cmdsz); @@ -2034,7 +2034,6 @@ void rtw_joinbss_cmd_callback(struct adapter *padapter, struct cmd_obj *pcmd) void rtw_createbss_cmd_callback(struct adapter *padapter, struct cmd_obj *pcmd) { - u8 timer_cancelled; struct sta_info *psta = NULL; struct wlan_network *pwlan = NULL; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; @@ -2049,7 +2048,7 @@ void rtw_createbss_cmd_callback(struct adapter *padapter, struct cmd_obj *pcmd) _set_timer(&pmlmepriv->assoc_timer, 1); } - _cancel_timer(&pmlmepriv->assoc_timer, &timer_cancelled); + del_timer_sync(&pmlmepriv->assoc_timer); spin_lock_bh(&pmlmepriv->lock); diff --git a/drivers/staging/rtl8723bs/core/rtw_ieee80211.c b/drivers/staging/rtl8723bs/core/rtw_ieee80211.c index ca98274ae390..c43cca4a3828 100644 --- a/drivers/staging/rtl8723bs/core/rtw_ieee80211.c +++ b/drivers/staging/rtl8723bs/core/rtw_ieee80211.c @@ -9,6 +9,7 @@ #include <drv_types.h> #include <rtw_debug.h> #include <linux/of.h> +#include <asm/unaligned.h> u8 RTW_WPA_OUI_TYPE[] = { 0x00, 0x50, 0xf2, 1 }; u16 RTW_WPA_VERSION = 1; @@ -499,7 +500,7 @@ int rtw_parse_wpa_ie(u8 *wpa_ie, int wpa_ie_len, int *group_cipher, int *pairwis /* pairwise_cipher */ if (left >= 2) { /* count = le16_to_cpu(*(u16*)pos); */ - count = RTW_GET_LE16(pos); + count = get_unaligned_le16(pos); pos += 2; left -= 2; @@ -569,7 +570,7 @@ int rtw_parse_wpa2_ie(u8 *rsn_ie, int rsn_ie_len, int *group_cipher, int *pairwi /* pairwise_cipher */ if (left >= 2) { /* count = le16_to_cpu(*(u16*)pos); */ - count = RTW_GET_LE16(pos); + count = get_unaligned_le16(pos); pos += 2; left -= 2; @@ -800,8 +801,8 @@ u8 *rtw_get_wps_attr(u8 *wps_ie, uint wps_ielen, u16 target_attr_id, u8 *buf_att while (attr_ptr - wps_ie < wps_ielen) { /* 4 = 2(Attribute ID) + 2(Length) */ - u16 attr_id = RTW_GET_BE16(attr_ptr); - u16 attr_data_len = RTW_GET_BE16(attr_ptr + 2); + u16 attr_id = get_unaligned_be16(attr_ptr); + u16 attr_data_len = get_unaligned_be16(attr_ptr + 2); u16 attr_len = attr_data_len + 4; /* DBG_871X("%s attr_ptr:%p, id:%u, length:%u\n", __func__, attr_ptr, attr_id, attr_data_len); */ @@ -874,7 +875,7 @@ static int rtw_ieee802_11_parse_vendor_specific(u8 *pos, uint elen, return -1; } - oui = RTW_GET_BE24(pos); + oui = get_unaligned_be24(pos); switch (oui) { case OUI_MICROSOFT: /* Microsoft/Wi-Fi information elements are further typed and diff --git a/drivers/staging/rtl8723bs/core/rtw_mlme.c b/drivers/staging/rtl8723bs/core/rtw_mlme.c index e65c5a870b46..9531ba54e95b 100644 --- a/drivers/staging/rtl8723bs/core/rtw_mlme.c +++ b/drivers/staging/rtl8723bs/core/rtw_mlme.c @@ -814,7 +814,6 @@ exit: void rtw_surveydone_event_callback(struct adapter *adapter, u8 *pbuf) { - u8 timer_cancelled = false; struct mlme_priv *pmlmepriv = &(adapter->mlmepriv); spin_lock_bh(&pmlmepriv->lock); @@ -827,22 +826,12 @@ void rtw_surveydone_event_callback(struct adapter *adapter, u8 *pbuf) RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_surveydone_event_callback: fw_state:%x\n\n", get_fwstate(pmlmepriv))); if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) { - /* u8 timer_cancelled; */ - - timer_cancelled = true; - /* _cancel_timer(&pmlmepriv->scan_to_timer, &timer_cancelled); */ - + del_timer_sync(&pmlmepriv->scan_to_timer); _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY); } else { RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("nic status =%x, survey done event comes too late!\n", get_fwstate(pmlmepriv))); } - spin_unlock_bh(&pmlmepriv->lock); - - if (timer_cancelled) - _cancel_timer(&pmlmepriv->scan_to_timer, &timer_cancelled); - - spin_lock_bh(&pmlmepriv->lock); rtw_set_signal_stat_timer(&adapter->recvpriv); @@ -1298,7 +1287,6 @@ static void rtw_joinbss_update_network(struct adapter *padapter, struct wlan_net void rtw_joinbss_event_prehandle(struct adapter *adapter, u8 *pbuf) { static u8 retry; - u8 timer_cancelled; struct sta_info *ptarget_sta = NULL, *pcur_sta = NULL; struct sta_priv *pstapriv = &adapter->stapriv; struct mlme_priv *pmlmepriv = &(adapter->mlmepriv); @@ -1392,7 +1380,7 @@ void rtw_joinbss_event_prehandle(struct adapter *adapter, u8 *pbuf) } /* s5. Cancel assoc_timer */ - _cancel_timer(&pmlmepriv->assoc_timer, &timer_cancelled); + del_timer_sync(&pmlmepriv->assoc_timer); RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("Cancel assoc_timer\n")); diff --git a/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c b/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c index 6db637701063..b912ad2f4b72 100644 --- a/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c +++ b/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c @@ -11,6 +11,7 @@ #include <rtw_wifi_regd.h> #include <hal_btcoex.h> #include <linux/kernel.h> +#include <asm/unaligned.h> static struct mlme_handler mlme_sta_tbl[] = { {WIFI_ASSOCREQ, "OnAssocReq", &OnAssocReq}, @@ -1213,7 +1214,7 @@ unsigned int OnAssocReq(struct adapter *padapter, union recv_frame *precv_frame) goto asoc_class2_error; } - capab_info = RTW_GET_LE16(pframe + WLAN_HDR_A3_LEN); + capab_info = get_unaligned_le16(pframe + WLAN_HDR_A3_LEN); /* capab_info = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN)); */ left = pkt_len - (sizeof(struct ieee80211_hdr_3addr) + ie_offset); @@ -1959,7 +1960,7 @@ unsigned int OnAction_back(struct adapter *padapter, union recv_frame *precv_fra break; case RTW_WLAN_ACTION_ADDBA_RESP: /* ADDBA response */ - status = RTW_GET_LE16(&frame_body[3]); + status = get_unaligned_le16(&frame_body[3]); tid = ((frame_body[5] >> 2) & 0x7); if (status == 0) { @@ -1989,7 +1990,7 @@ unsigned int OnAction_back(struct adapter *padapter, union recv_frame *precv_fra ~BIT((frame_body[3] >> 4) & 0xf); /* reason_code = frame_body[4] | (frame_body[5] << 8); */ - reason_code = RTW_GET_LE16(&frame_body[4]); + reason_code = get_unaligned_le16(&frame_body[4]); } else if ((frame_body[3] & BIT(3)) == BIT(3)) { tid = (frame_body[3] >> 4) & 0x0F; diff --git a/drivers/staging/rtl8723bs/core/rtw_recv.c b/drivers/staging/rtl8723bs/core/rtw_recv.c index 7e1da0e35812..6979f8dbccb8 100644 --- a/drivers/staging/rtl8723bs/core/rtw_recv.c +++ b/drivers/staging/rtl8723bs/core/rtw_recv.c @@ -11,6 +11,7 @@ #include <linux/jiffies.h> #include <rtw_recv.h> #include <net/cfg80211.h> +#include <asm/unaligned.h> static u8 SNAP_ETH_TYPE_IPX[2] = {0x81, 0x37}; static u8 SNAP_ETH_TYPE_APPLETALK_AARP[2] = {0x80, 0xf3}; @@ -1906,7 +1907,7 @@ static int amsdu_to_msdu(struct adapter *padapter, union recv_frame *prframe) while (a_len > ETH_HLEN) { /* Offset 12 denote 2 mac address */ - nSubframe_Length = RTW_GET_BE16(pdata + 12); + nSubframe_Length = get_unaligned_be16(pdata + 12); if (a_len < (ETHERNET_HEADER_SIZE + nSubframe_Length)) { DBG_871X("nRemain_Length is %d and nSubframe_Length is : %d\n", a_len, nSubframe_Length); diff --git a/drivers/staging/rtl8723bs/core/rtw_security.c b/drivers/staging/rtl8723bs/core/rtw_security.c index 7f74e1d05b3a..159d32ace2bc 100644 --- a/drivers/staging/rtl8723bs/core/rtw_security.c +++ b/drivers/staging/rtl8723bs/core/rtw_security.c @@ -260,7 +260,7 @@ void rtw_wep_encrypt(struct adapter *padapter, u8 *pxmitframe) arcfour_encrypt(&mycontext, payload+length, crc, 4); pframe += pxmitpriv->frag_len; - pframe = (u8 *)RND4((SIZE_PTR)(pframe)); + pframe = (u8 *)round_up((SIZE_PTR)(pframe), 4); } } @@ -716,7 +716,7 @@ u32 rtw_tkip_encrypt(struct adapter *padapter, u8 *pxmitframe) arcfour_encrypt(&mycontext, payload+length, crc, 4); pframe += pxmitpriv->frag_len; - pframe = (u8 *)RND4((SIZE_PTR)(pframe)); + pframe = (u8 *)round_up((SIZE_PTR)(pframe), 4); } } @@ -1523,7 +1523,7 @@ u32 rtw_aes_encrypt(struct adapter *padapter, u8 *pxmitframe) aes_cipher(prwskey, pattrib->hdrlen, pframe, length); pframe += pxmitpriv->frag_len; - pframe = (u8 *)RND4((SIZE_PTR)(pframe)); + pframe = (u8 *)round_up((SIZE_PTR)(pframe), 4); } } diff --git a/drivers/staging/rtl8723bs/core/rtw_wlan_util.c b/drivers/staging/rtl8723bs/core/rtw_wlan_util.c index a3ea7ce3e12e..372ce17c3569 100644 --- a/drivers/staging/rtl8723bs/core/rtw_wlan_util.c +++ b/drivers/staging/rtl8723bs/core/rtw_wlan_util.c @@ -54,32 +54,6 @@ static u8 rtw_basic_rate_ofdm[3] = { IEEE80211_OFDM_RATE_24MB | IEEE80211_BASIC_RATE_MASK }; -int cckrates_included(unsigned char *rate, int ratelen) -{ - int i; - - for (i = 0; i < ratelen; i++) { - if ((((rate[i]) & 0x7f) == 2) || (((rate[i]) & 0x7f) == 4) || - (((rate[i]) & 0x7f) == 11) || (((rate[i]) & 0x7f) == 22)) - return true; - } - - return false; -} - -int cckratesonly_included(unsigned char *rate, int ratelen) -{ - int i; - - for (i = 0; i < ratelen; i++) { - if ((((rate[i]) & 0x7f) != 2) && (((rate[i]) & 0x7f) != 4) && - (((rate[i]) & 0x7f) != 11) && (((rate[i]) & 0x7f) != 22)) - return false; - } - - return true; -} - u8 networktype_to_raid_ex(struct adapter *adapter, struct sta_info *psta) { u8 raid, cur_rf_type, rf_type = RF_1T1R; @@ -374,20 +348,7 @@ u8 rtw_get_center_ch(u8 channel, u8 chnl_bw, u8 chnl_offset) u8 center_ch = channel; if (chnl_bw == CHANNEL_WIDTH_80) { - if ((channel == 36) || (channel == 40) || (channel == 44) || (channel == 48)) - center_ch = 42; - if ((channel == 52) || (channel == 56) || (channel == 60) || (channel == 64)) - center_ch = 58; - if ((channel == 100) || (channel == 104) || (channel == 108) || (channel == 112)) - center_ch = 106; - if ((channel == 116) || (channel == 120) || (channel == 124) || (channel == 128)) - center_ch = 122; - if ((channel == 132) || (channel == 136) || (channel == 140) || (channel == 144)) - center_ch = 138; - if ((channel == 149) || (channel == 153) || (channel == 157) || (channel == 161)) - center_ch = 155; - else if (channel <= 14) - center_ch = 7; + center_ch = 7; } else if (chnl_bw == CHANNEL_WIDTH_40) { if (chnl_offset == HAL_PRIME_CHNL_OFFSET_LOWER) center_ch = channel + 2; @@ -1753,38 +1714,27 @@ void update_capinfo(struct adapter *Adapter, u16 updateCap) void update_wireless_mode(struct adapter *padapter) { - int ratelen, network_type = 0; + int network_type = 0; u32 SIFS_Timer; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); struct wlan_bssid_ex *cur_network = &(pmlmeinfo->network); unsigned char *rate = cur_network->SupportedRates; - ratelen = rtw_get_rateset_len(cur_network->SupportedRates); - if ((pmlmeinfo->HT_info_enable) && (pmlmeinfo->HT_caps_enable)) pmlmeinfo->HT_enable = 1; - if (pmlmeext->cur_channel > 14) { - if (pmlmeinfo->VHT_enable) - network_type = WIRELESS_11AC; - else if (pmlmeinfo->HT_enable) - network_type = WIRELESS_11_5N; + if (pmlmeinfo->VHT_enable) + network_type = WIRELESS_11AC; + else if (pmlmeinfo->HT_enable) + network_type = WIRELESS_11_24N; - network_type |= WIRELESS_11A; - } else { - if (pmlmeinfo->VHT_enable) - network_type = WIRELESS_11AC; - else if (pmlmeinfo->HT_enable) - network_type = WIRELESS_11_24N; - - if ((cckratesonly_included(rate, ratelen)) == true) - network_type |= WIRELESS_11B; - else if ((cckrates_included(rate, ratelen)) == true) - network_type |= WIRELESS_11BG; - else - network_type |= WIRELESS_11G; - } + if (rtw_is_cckratesonly_included(rate)) + network_type |= WIRELESS_11B; + else if (rtw_is_cckrates_included(rate)) + network_type |= WIRELESS_11BG; + else + network_type |= WIRELESS_11G; pmlmeext->cur_wireless_mode = network_type & padapter->registrypriv.wireless_mode; diff --git a/drivers/staging/rtl8723bs/core/rtw_xmit.c b/drivers/staging/rtl8723bs/core/rtw_xmit.c index 571353404a95..6ecaff9728fd 100644 --- a/drivers/staging/rtl8723bs/core/rtw_xmit.c +++ b/drivers/staging/rtl8723bs/core/rtw_xmit.c @@ -865,7 +865,7 @@ static s32 xmitframe_addmic(struct adapter *padapter, struct xmit_frame *pxmitfr payload = pframe; for (curfragnum = 0; curfragnum < pattrib->nr_frags; curfragnum++) { - payload = (u8 *)RND4((SIZE_PTR)(payload)); + payload = (u8 *)round_up((SIZE_PTR)(payload), 4); RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("===curfragnum =%d, pframe = 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x,!!!\n", curfragnum, *payload, *(payload+1), *(payload+2), *(payload+3), *(payload+4), *(payload+5), *(payload+6), *(payload+7))); @@ -1209,7 +1209,7 @@ s32 rtw_xmitframe_coalesce(struct adapter *padapter, _pkt *pkt, struct xmit_fram addr = (SIZE_PTR)(pframe); - mem_start = (unsigned char *)RND4(addr) + hw_hdr_offset; + mem_start = (unsigned char *)round_up(addr, 4) + hw_hdr_offset; memcpy(mem_start, pbuf_start + hw_hdr_offset, pattrib->hdrlen); } diff --git a/drivers/staging/rtl8723bs/hal/rtl8723bs_recv.c b/drivers/staging/rtl8723bs/hal/rtl8723bs_recv.c index 29c29e2e125b..1fbf89cb72d0 100644 --- a/drivers/staging/rtl8723bs/hal/rtl8723bs_recv.c +++ b/drivers/staging/rtl8723bs/hal/rtl8723bs_recv.c @@ -230,9 +230,10 @@ static inline bool pkt_exceeds_tail(struct recv_priv *precvpriv, return false; } -static void rtl8723bs_recv_tasklet(unsigned long priv) +static void rtl8723bs_recv_tasklet(struct tasklet_struct *t) { - struct adapter *padapter; + struct adapter *padapter = from_tasklet(padapter, t, + recvpriv.recv_tasklet); struct hal_com_data *p_hal_data; struct recv_priv *precvpriv; struct recv_buf *precvbuf; @@ -244,7 +245,6 @@ static void rtl8723bs_recv_tasklet(unsigned long priv) _pkt *pkt_copy = NULL; u8 shift_sz = 0, rx_report_sz = 0; - padapter = (struct adapter *)priv; p_hal_data = GET_HAL_DATA(padapter); precvpriv = &padapter->recvpriv; recv_buf_queue = &precvpriv->recv_buf_pending_queue; @@ -369,7 +369,7 @@ static void rtl8723bs_recv_tasklet(unsigned long priv) } } - pkt_offset = _RND8(pkt_offset); + pkt_offset = round_up(pkt_offset, 8); precvbuf->pdata += pkt_offset; ptr = precvbuf->pdata; precvframe = NULL; @@ -444,8 +444,7 @@ s32 rtl8723bs_init_recv_priv(struct adapter *padapter) goto initbuferror; /* 3 2. init tasklet */ - tasklet_init(&precvpriv->recv_tasklet, rtl8723bs_recv_tasklet, - (unsigned long)padapter); + tasklet_setup(&precvpriv->recv_tasklet, rtl8723bs_recv_tasklet); goto exit; diff --git a/drivers/staging/rtl8723bs/hal/sdio_ops.c b/drivers/staging/rtl8723bs/hal/sdio_ops.c index b6b4adb5a28a..369f55d11519 100644 --- a/drivers/staging/rtl8723bs/hal/sdio_ops.c +++ b/drivers/staging/rtl8723bs/hal/sdio_ops.c @@ -474,7 +474,7 @@ static u32 sdio_write_port( return _FAIL; } - cnt = _RND4(cnt); + cnt = round_up(cnt, 4); HalSdioGetCmdAddr8723BSdio(adapter, addr, cnt >> 2, &addr); if (cnt > psdio->block_transfer_len) @@ -534,7 +534,7 @@ static s32 _sdio_local_read( if (!mac_pwr_ctrl_on) return _sd_cmd52_read(intfhdl, addr, cnt, buf); - n = RND4(cnt); + n = round_up(cnt, 4); tmpbuf = rtw_malloc(n); if (!tmpbuf) return -1; @@ -575,7 +575,7 @@ s32 sdio_local_read( ) return sd_cmd52_read(intfhdl, addr, cnt, buf); - n = RND4(cnt); + n = round_up(cnt, 4); tmpbuf = rtw_malloc(n); if (!tmpbuf) return -1; @@ -859,7 +859,7 @@ static struct recv_buf *sd_recv_rxfifo(struct adapter *adapter, u32 size) /* Patch for some SDIO Host 4 bytes issue */ /* ex. RK3188 */ - readsize = RND4(size); + readsize = round_up(size, 4); /* 3 1. alloc recvbuf */ recv_priv = &adapter->recvpriv; @@ -945,8 +945,7 @@ void sd_int_dpc(struct adapter *adapter) if (hal->sdio_hisr & SDIO_HISR_CPWM1) { struct reportpwrstate_parm report; - u8 bcancelled; - _cancel_timer(&(pwrctl->pwr_rpwm_timer), &bcancelled); + del_timer_sync(&(pwrctl->pwr_rpwm_timer)); report.state = SdioLocalCmd52Read1Byte(adapter, SDIO_REG_HCPWM1_8723B); diff --git a/drivers/staging/rtl8723bs/include/osdep_service.h b/drivers/staging/rtl8723bs/include/osdep_service.h index be34e279670b..a94b72397ce7 100644 --- a/drivers/staging/rtl8723bs/include/osdep_service.h +++ b/drivers/staging/rtl8723bs/include/osdep_service.h @@ -131,29 +131,6 @@ static inline int rtw_bug_check(void *parg1, void *parg2, void *parg3, void *par } #define _RND(sz, r) ((((sz)+((r)-1))/(r))*(r)) -#define RND4(x) (((x >> 2) + (((x & 3) == 0) ? 0 : 1)) << 2) - -static inline u32 _RND4(u32 sz) -{ - - u32 val; - - val = ((sz >> 2) + ((sz & 3) ? 1 : 0)) << 2; - - return val; - -} - -static inline u32 _RND8(u32 sz) -{ - - u32 val; - - val = ((sz >> 3) + ((sz & 7) ? 1 : 0)) << 3; - - return val; - -} #ifndef MAC_FMT #define MAC_FMT "%pM" @@ -173,70 +150,6 @@ extern void rtw_free_netdev(struct net_device * netdev); /* Macros for handling unaligned memory accesses */ -#define RTW_GET_BE16(a) ((u16) (((a)[0] << 8) | (a)[1])) -#define RTW_PUT_BE16(a, val) \ - do { \ - (a)[0] = ((u16) (val)) >> 8; \ - (a)[1] = ((u16) (val)) & 0xff; \ - } while (0) - -#define RTW_GET_LE16(a) ((u16) (((a)[1] << 8) | (a)[0])) -#define RTW_PUT_LE16(a, val) \ - do { \ - (a)[1] = ((u16) (val)) >> 8; \ - (a)[0] = ((u16) (val)) & 0xff; \ - } while (0) - -#define RTW_GET_BE24(a) ((((u32) (a)[0]) << 16) | (((u32) (a)[1]) << 8) | \ - ((u32) (a)[2])) -#define RTW_PUT_BE24(a, val) \ - do { \ - (a)[0] = (u8) ((((u32) (val)) >> 16) & 0xff); \ - (a)[1] = (u8) ((((u32) (val)) >> 8) & 0xff); \ - (a)[2] = (u8) (((u32) (val)) & 0xff); \ - } while (0) - -#define RTW_GET_BE32(a) ((((u32) (a)[0]) << 24) | (((u32) (a)[1]) << 16) | \ - (((u32) (a)[2]) << 8) | ((u32) (a)[3])) -#define RTW_PUT_BE32(a, val) \ - do { \ - (a)[0] = (u8) ((((u32) (val)) >> 24) & 0xff); \ - (a)[1] = (u8) ((((u32) (val)) >> 16) & 0xff); \ - (a)[2] = (u8) ((((u32) (val)) >> 8) & 0xff); \ - (a)[3] = (u8) (((u32) (val)) & 0xff); \ - } while (0) - -#define RTW_GET_LE32(a) ((((u32) (a)[3]) << 24) | (((u32) (a)[2]) << 16) | \ - (((u32) (a)[1]) << 8) | ((u32) (a)[0])) -#define RTW_PUT_LE32(a, val) \ - do { \ - (a)[3] = (u8) ((((u32) (val)) >> 24) & 0xff); \ - (a)[2] = (u8) ((((u32) (val)) >> 16) & 0xff); \ - (a)[1] = (u8) ((((u32) (val)) >> 8) & 0xff); \ - (a)[0] = (u8) (((u32) (val)) & 0xff); \ - } while (0) - -#define RTW_GET_BE64(a) ((((u64) (a)[0]) << 56) | (((u64) (a)[1]) << 48) | \ - (((u64) (a)[2]) << 40) | (((u64) (a)[3]) << 32) | \ - (((u64) (a)[4]) << 24) | (((u64) (a)[5]) << 16) | \ - (((u64) (a)[6]) << 8) | ((u64) (a)[7])) -#define RTW_PUT_BE64(a, val) \ - do { \ - (a)[0] = (u8) (((u64) (val)) >> 56); \ - (a)[1] = (u8) (((u64) (val)) >> 48); \ - (a)[2] = (u8) (((u64) (val)) >> 40); \ - (a)[3] = (u8) (((u64) (val)) >> 32); \ - (a)[4] = (u8) (((u64) (val)) >> 24); \ - (a)[5] = (u8) (((u64) (val)) >> 16); \ - (a)[6] = (u8) (((u64) (val)) >> 8); \ - (a)[7] = (u8) (((u64) (val)) & 0xff); \ - } while (0) - -#define RTW_GET_LE64(a) ((((u64) (a)[7]) << 56) | (((u64) (a)[6]) << 48) | \ - (((u64) (a)[5]) << 40) | (((u64) (a)[4]) << 32) | \ - (((u64) (a)[3]) << 24) | (((u64) (a)[2]) << 16) | \ - (((u64) (a)[1]) << 8) | ((u64) (a)[0])) - void rtw_buf_free(u8 **buf, u32 *buf_len); void rtw_buf_update(u8 **buf, u32 *buf_len, u8 *src, u32 src_len); diff --git a/drivers/staging/rtl8723bs/include/osdep_service_linux.h b/drivers/staging/rtl8723bs/include/osdep_service_linux.h index 1710fa3eeb71..498d5474010c 100644 --- a/drivers/staging/rtl8723bs/include/osdep_service_linux.h +++ b/drivers/staging/rtl8723bs/include/osdep_service_linux.h @@ -83,12 +83,6 @@ static inline void _set_timer(_timer *ptimer, u32 delay_time) mod_timer(ptimer, (jiffies + (delay_time * HZ / 1000))); } -static inline void _cancel_timer(_timer *ptimer, u8 *bcancelled) -{ - del_timer_sync(ptimer); - *bcancelled = true;/* true == 1; false == 0 */ -} - static inline void _init_workitem(_workitem *pwork, void *pfunc, void *cntx) { INIT_WORK(pwork, pfunc); @@ -129,8 +123,6 @@ static inline void rtw_netif_stop_queue(struct net_device *pnetdev) #define rtw_signal_process(pid, sig) kill_pid(find_vpid((pid)), (sig), 1) -#define rtw_netdev_priv(netdev) (((struct rtw_netdev_priv_indicator *)netdev_priv(netdev))->priv) - #define NDEV_FMT "%s" #define NDEV_ARG(ndev) ndev->name #define ADPT_FMT "%s" @@ -144,6 +136,12 @@ struct rtw_netdev_priv_indicator { void *priv; u32 sizeof_priv; }; + +static inline struct adapter *rtw_netdev_priv(struct net_device *netdev) +{ + return ((struct rtw_netdev_priv_indicator *)netdev_priv(netdev))->priv; +} + struct net_device *rtw_alloc_etherdev_with_old_priv(int sizeof_priv, void *old_priv); extern struct net_device * rtw_alloc_etherdev(int sizeof_priv); diff --git a/drivers/staging/rtl8723bs/include/rtw_mlme_ext.h b/drivers/staging/rtl8723bs/include/rtw_mlme_ext.h index 14583799039f..1567831caf91 100644 --- a/drivers/staging/rtl8723bs/include/rtw_mlme_ext.h +++ b/drivers/staging/rtl8723bs/include/rtw_mlme_ext.h @@ -716,8 +716,6 @@ void sa_query_timer_hdl(struct timer_list *t); DBG_871X("%s set_sa_query_timer(%p, %d)\n", __func__, (mlmeext), (ms)); \ _set_timer(&(mlmeext)->sa_query_timer, (ms)); \ } while (0) -extern int cckrates_included(unsigned char *rate, int ratelen); -extern int cckratesonly_included(unsigned char *rate, int ratelen); extern void process_addba_req(struct adapter *padapter, u8 *paddba_req, u8 *addr); diff --git a/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c b/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c index 2fb80b6eb51d..ea3ae3d38337 100644 --- a/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c +++ b/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c @@ -2021,7 +2021,7 @@ static int cfg80211_rtw_leave_ibss(struct wiphy *wiphy, struct net_device *ndev) } leave_ibss: - return 0; + return ret; } static int cfg80211_rtw_connect(struct wiphy *wiphy, struct net_device *ndev, diff --git a/drivers/staging/rtl8723bs/os_dep/recv_linux.c b/drivers/staging/rtl8723bs/os_dep/recv_linux.c index b2a1bbb30df6..900ff3a3b014 100644 --- a/drivers/staging/rtl8723bs/os_dep/recv_linux.c +++ b/drivers/staging/rtl8723bs/os_dep/recv_linux.c @@ -10,6 +10,7 @@ #include <rtw_debug.h> #include <linux/jiffies.h> #include <net/cfg80211.h> +#include <asm/unaligned.h> void rtw_os_free_recvframe(union recv_frame *precvframe) { @@ -69,7 +70,7 @@ _pkt *rtw_os_alloc_msdu_pkt(union recv_frame *prframe, u16 nSubframe_Length, u8 skb_reserve(sub_skb, 12); skb_put_data(sub_skb, (pdata + ETH_HLEN), nSubframe_Length); - eth_type = RTW_GET_BE16(&sub_skb->data[6]); + eth_type = get_unaligned_be16(&sub_skb->data[6]); if (sub_skb->len >= 8 && ((!memcmp(sub_skb->data, rfc1042_header, SNAP_SIZE) && diff --git a/drivers/staging/rtl8723bs/os_dep/sdio_intf.c b/drivers/staging/rtl8723bs/os_dep/sdio_intf.c index 5b1392deb0a7..79b55ec827a4 100644 --- a/drivers/staging/rtl8723bs/os_dep/sdio_intf.c +++ b/drivers/staging/rtl8723bs/os_dep/sdio_intf.c @@ -15,8 +15,7 @@ #define dev_to_sdio_func(d) container_of(d, struct sdio_func, dev) #endif -static const struct sdio_device_id sdio_ids[] = -{ +static const struct sdio_device_id sdio_ids[] = { { SDIO_DEVICE(0x024c, 0x0523), }, { SDIO_DEVICE(0x024c, 0x0525), }, { SDIO_DEVICE(0x024c, 0x0623), }, @@ -132,6 +131,7 @@ static irqreturn_t gpio_hostwakeup_irq_thread(int irq, void *data) static u8 gpio_hostwakeup_alloc_irq(struct adapter *padapter) { int err; + if (oob_irq == 0) { DBG_871X("oob_irq ZERO!\n"); return _FAIL; diff --git a/drivers/staging/rtl8723bs/os_dep/sdio_ops_linux.c b/drivers/staging/rtl8723bs/os_dep/sdio_ops_linux.c index 50b89340465b..079da433d811 100644 --- a/drivers/staging/rtl8723bs/os_dep/sdio_ops_linux.c +++ b/drivers/staging/rtl8723bs/os_dep/sdio_ops_linux.c @@ -84,9 +84,9 @@ s32 _sd_cmd52_read(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pdata) func = psdio->func; for (i = 0; i < cnt; i++) { - pdata[i] = sdio_readb(func, addr+i, &err); + pdata[i] = sdio_readb(func, addr + i, &err); if (err) { - DBG_871X(KERN_ERR "%s: FAIL!(%d) addr = 0x%05x\n", __func__, err, addr+i); + DBG_871X(KERN_ERR "%s: FAIL!(%d) addr = 0x%05x\n", __func__, err, addr + i); break; } } @@ -154,9 +154,10 @@ s32 _sd_cmd52_write(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pdata) func = psdio->func; for (i = 0; i < cnt; i++) { - sdio_writeb(func, pdata[i], addr+i, &err); + sdio_writeb(func, pdata[i], addr + i, &err); if (err) { - DBG_871X(KERN_ERR "%s: FAIL!(%d) addr = 0x%05x val = 0x%02x\n", __func__, err, addr+i, pdata[i]); + DBG_871X(KERN_ERR "%s: FAIL!(%d) addr = 0x%05x val = 0x%02x\n", __func__, + err, addr + i, pdata[i]); break; } } @@ -264,18 +265,19 @@ u32 sd_read32(struct intf_hdl *pintfhdl, u32 addr, s32 *err) *err = 0; for (i = 0; i < SD_IO_TRY_CNT; i++) { - if (claim_needed) sdio_claim_host(func); + if (claim_needed) + sdio_claim_host(func); v = sdio_readl(func, addr, err); - if (claim_needed) sdio_release_host(func); + if (claim_needed) + sdio_release_host(func); if (*err == 0) { rtw_reset_continual_io_error(psdiodev); break; } else { DBG_871X(KERN_ERR "%s: (%d) addr = 0x%05x, val = 0x%x, try_cnt =%d\n", __func__, *err, addr, v, i); - if ((-ESHUTDOWN == *err) || (-ENODEV == *err)) { + if ((-ESHUTDOWN == *err) || (-ENODEV == *err)) padapter->bSurpriseRemoved = true; - } if (rtw_inc_and_chk_continual_io_error(psdiodev) == true) { padapter->bSurpriseRemoved = true; @@ -355,17 +357,18 @@ void sd_write32(struct intf_hdl *pintfhdl, u32 addr, u32 v, s32 *err) *err = 0; for (i = 0; i < SD_IO_TRY_CNT; i++) { - if (claim_needed) sdio_claim_host(func); + if (claim_needed) + sdio_claim_host(func); sdio_writel(func, v, addr, err); - if (claim_needed) sdio_release_host(func); + if (claim_needed) + sdio_release_host(func); if (*err == 0) { rtw_reset_continual_io_error(psdiodev); break; } else { DBG_871X(KERN_ERR "%s: (%d) addr = 0x%05x, val = 0x%x, try_cnt =%d\n", __func__, *err, addr, v, i); - if ((-ESHUTDOWN == *err) || (-ENODEV == *err)) { + if ((-ESHUTDOWN == *err) || (-ENODEV == *err)) padapter->bSurpriseRemoved = true; - } if (rtw_inc_and_chk_continual_io_error(psdiodev) == true) { padapter->bSurpriseRemoved = true; @@ -421,7 +424,7 @@ s32 _sd_read(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, void *pdata) u8 *pbuf = pdata; for (i = 0; i < cnt; i++) { - *(pbuf+i) = sdio_readb(func, addr+i, &err); + *(pbuf + i) = sdio_readb(func, addr + i, &err); if (err) { DBG_871X(KERN_ERR "%s: FAIL!(%d) addr = 0x%05x\n", __func__, err, addr); @@ -432,9 +435,9 @@ s32 _sd_read(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, void *pdata) } err = sdio_memcpy_fromio(func, pdata, addr, cnt); - if (err) { + if (err) DBG_871X(KERN_ERR "%s: FAIL(%d)! ADDR =%#x Size =%d\n", __func__, err, addr, cnt); - } + return err; } @@ -522,9 +525,10 @@ s32 _sd_write(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, void *pdata) u8 *pbuf = pdata; for (i = 0; i < cnt; i++) { - sdio_writeb(func, *(pbuf+i), addr+i, &err); + sdio_writeb(func, *(pbuf + i), addr + i, &err); if (err) { - DBG_871X(KERN_ERR "%s: FAIL!(%d) addr = 0x%05x val = 0x%02x\n", __func__, err, addr, *(pbuf+i)); + DBG_871X(KERN_ERR "%s: FAIL!(%d) addr = 0x%05x val = 0x%02x\n", + __func__, err, addr, *(pbuf + i)); break; } } @@ -534,9 +538,9 @@ s32 _sd_write(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, void *pdata) size = cnt; err = sdio_memcpy_toio(func, addr, pdata, size); - if (err) { + if (err) DBG_871X(KERN_ERR "%s: FAIL(%d)! ADDR =%#x Size =%d(%d)\n", __func__, err, addr, cnt, size); - } + return err; } diff --git a/drivers/staging/rts5208/rtsx_transport.c b/drivers/staging/rts5208/rtsx_transport.c index 0027bcf638ad..909a3e663ef6 100644 --- a/drivers/staging/rts5208/rtsx_transport.c +++ b/drivers/staging/rts5208/rtsx_transport.c @@ -257,8 +257,8 @@ int rtsx_send_cmd(struct rtsx_chip *chip, u8 card, int timeout) spin_unlock_irq(&rtsx->reg_lock); /* Wait for TRANS_OK_INT */ - timeleft = wait_for_completion_interruptible_timeout( - &trans_done, msecs_to_jiffies(timeout)); + timeleft = wait_for_completion_interruptible_timeout(&trans_done, + msecs_to_jiffies(timeout)); if (timeleft <= 0) { dev_dbg(rtsx_dev(chip), "chip->int_reg = 0x%x\n", chip->int_reg); @@ -284,8 +284,8 @@ finish_send_cmd: return err; } -static inline void rtsx_add_sg_tbl( - struct rtsx_chip *chip, u32 addr, u32 len, u8 option) +static inline void rtsx_add_sg_tbl(struct rtsx_chip *chip, + u32 addr, u32 len, u8 option) { __le64 *sgb = (__le64 *)(chip->host_sg_tbl_ptr); u64 val = 0; @@ -419,8 +419,8 @@ static int rtsx_transfer_sglist_adma_partial(struct rtsx_chip *chip, u8 card, spin_unlock_irq(&rtsx->reg_lock); - timeleft = wait_for_completion_interruptible_timeout( - &trans_done, msecs_to_jiffies(timeout)); + timeleft = wait_for_completion_interruptible_timeout(&trans_done, + msecs_to_jiffies(timeout)); if (timeleft <= 0) { dev_dbg(rtsx_dev(chip), "Timeout (%s %d)\n", __func__, __LINE__); @@ -443,8 +443,8 @@ static int rtsx_transfer_sglist_adma_partial(struct rtsx_chip *chip, u8 card, if (rtsx->trans_result == TRANS_NOT_READY) { init_completion(&trans_done); spin_unlock_irq(&rtsx->reg_lock); - timeleft = wait_for_completion_interruptible_timeout( - &trans_done, msecs_to_jiffies(timeout)); + timeleft = wait_for_completion_interruptible_timeout(&trans_done, + msecs_to_jiffies(timeout)); if (timeleft <= 0) { dev_dbg(rtsx_dev(chip), "Timeout (%s %d)\n", __func__, __LINE__); @@ -563,8 +563,8 @@ static int rtsx_transfer_sglist_adma(struct rtsx_chip *chip, u8 card, spin_unlock_irq(&rtsx->reg_lock); - timeleft = wait_for_completion_interruptible_timeout( - &trans_done, msecs_to_jiffies(timeout)); + timeleft = wait_for_completion_interruptible_timeout(&trans_done, + msecs_to_jiffies(timeout)); if (timeleft <= 0) { dev_dbg(rtsx_dev(chip), "Timeout (%s %d)\n", __func__, __LINE__); @@ -590,8 +590,8 @@ static int rtsx_transfer_sglist_adma(struct rtsx_chip *chip, u8 card, if (rtsx->trans_result == TRANS_NOT_READY) { init_completion(&trans_done); spin_unlock_irq(&rtsx->reg_lock); - timeleft = wait_for_completion_interruptible_timeout( - &trans_done, msecs_to_jiffies(timeout)); + timeleft = wait_for_completion_interruptible_timeout(&trans_done, + msecs_to_jiffies(timeout)); if (timeleft <= 0) { dev_dbg(rtsx_dev(chip), "Timeout (%s %d)\n", __func__, __LINE__); diff --git a/drivers/staging/sm750fb/sm750.c b/drivers/staging/sm750fb/sm750.c index 84fb585a5739..029f0d09e966 100644 --- a/drivers/staging/sm750fb/sm750.c +++ b/drivers/staging/sm750fb/sm750.c @@ -411,6 +411,7 @@ static int __maybe_unused lynxfb_suspend(struct device *dev) { struct fb_info *info; struct sm750_dev *sm750_dev; + sm750_dev = dev_get_drvdata(dev); console_lock(); @@ -500,7 +501,7 @@ static int lynxfb_ops_check_var(struct fb_var_screeninfo *var, var->height = var->width = -1; var->accel_flags = 0;/* FB_ACCELF_TEXT; */ - /* check if current fb's video memory big enought to hold the onscreen*/ + /* check if current fb's video memory big enough to hold the onscreen*/ request = var->xres_virtual * (var->bits_per_pixel >> 3); /* defaulty crtc->channel go with par->index */ diff --git a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c index 292fcee9d6f2..d567a2e3f70c 100644 --- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c +++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c @@ -122,7 +122,7 @@ static int vc_vchi_audio_init(struct vchiq_instance *vchiq_instance, struct bcm2835_audio_instance *instance) { - struct vchiq_service_params params = { + struct vchiq_service_params_kernel params = { .version = VC_AUDIOSERV_VER, .version_min = VC_AUDIOSERV_MIN_VER, .fourcc = VCHIQ_MAKE_FOURCC('A', 'U', 'D', 'S'), diff --git a/drivers/staging/vc04_services/include/linux/raspberrypi/vchiq.h b/drivers/staging/vc04_services/include/linux/raspberrypi/vchiq.h index 18d63df368c4..fefc664eefcf 100644 --- a/drivers/staging/vc04_services/include/linux/raspberrypi/vchiq.h +++ b/drivers/staging/vc04_services/include/linux/raspberrypi/vchiq.h @@ -62,7 +62,14 @@ struct vchiq_service_base { void *userdata; }; -struct vchiq_service_params { +struct vchiq_completion_data_kernel { + enum vchiq_reason reason; + struct vchiq_header *header; + void *service_userdata; + void *bulk_userdata; +}; + +struct vchiq_service_params_kernel { int fourcc; enum vchiq_status (*callback)(enum vchiq_reason reason, struct vchiq_header *header, @@ -79,7 +86,7 @@ extern enum vchiq_status vchiq_initialise(struct vchiq_instance **pinstance); extern enum vchiq_status vchiq_shutdown(struct vchiq_instance *instance); extern enum vchiq_status vchiq_connect(struct vchiq_instance *instance); extern enum vchiq_status vchiq_open_service(struct vchiq_instance *instance, - const struct vchiq_service_params *params, + const struct vchiq_service_params_kernel *params, unsigned int *pservice); extern enum vchiq_status vchiq_close_service(unsigned int service); extern enum vchiq_status vchiq_use_service(unsigned int service); diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c index 5ed36d557014..8782ebe0b39a 100644 --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c @@ -70,7 +70,7 @@ static irqreturn_t vchiq_doorbell_irq(int irq, void *dev_id); static struct vchiq_pagelist_info * -create_pagelist(char __user *buf, size_t count, unsigned short type); +create_pagelist(char *buf, char __user *ubuf, size_t count, unsigned short type); static void free_pagelist(struct vchiq_pagelist_info *pagelistinfo, @@ -216,12 +216,12 @@ remote_event_signal(struct remote_event *event) } enum vchiq_status -vchiq_prepare_bulk_data(struct vchiq_bulk *bulk, void *offset, int size, - int dir) +vchiq_prepare_bulk_data(struct vchiq_bulk *bulk, void *offset, + void __user *uoffset, int size, int dir) { struct vchiq_pagelist_info *pagelistinfo; - pagelistinfo = create_pagelist((char __user *)offset, size, + pagelistinfo = create_pagelist(offset, uoffset, size, (dir == VCHIQ_BULK_RECEIVE) ? PAGELIST_READ : PAGELIST_WRITE); @@ -229,7 +229,7 @@ vchiq_prepare_bulk_data(struct vchiq_bulk *bulk, void *offset, int size, if (!pagelistinfo) return VCHIQ_ERROR; - bulk->data = (void *)(unsigned long)pagelistinfo->dma_addr; + bulk->data = pagelistinfo->dma_addr; /* * Store the pagelistinfo address in remote_data, @@ -304,7 +304,8 @@ cleanup_pagelistinfo(struct vchiq_pagelist_info *pagelistinfo) */ static struct vchiq_pagelist_info * -create_pagelist(char __user *buf, size_t count, unsigned short type) +create_pagelist(char *buf, char __user *ubuf, + size_t count, unsigned short type) { struct pagelist *pagelist; struct vchiq_pagelist_info *pagelistinfo; @@ -320,7 +321,10 @@ create_pagelist(char __user *buf, size_t count, unsigned short type) if (count >= INT_MAX - PAGE_SIZE) return NULL; - offset = ((unsigned int)(unsigned long)buf & (PAGE_SIZE - 1)); + if (buf) + offset = (uintptr_t)buf & (PAGE_SIZE - 1); + else + offset = (uintptr_t)ubuf & (PAGE_SIZE - 1); num_pages = DIV_ROUND_UP(count + offset, PAGE_SIZE); if (num_pages > (SIZE_MAX - sizeof(struct pagelist) - @@ -368,14 +372,14 @@ create_pagelist(char __user *buf, size_t count, unsigned short type) pagelistinfo->scatterlist = scatterlist; pagelistinfo->scatterlist_mapped = 0; - if (is_vmalloc_addr((void __force *)buf)) { + if (buf) { unsigned long length = count; unsigned int off = offset; for (actual_pages = 0; actual_pages < num_pages; actual_pages++) { struct page *pg = - vmalloc_to_page((void __force *)(buf + + vmalloc_to_page((buf + (actual_pages * PAGE_SIZE))); size_t bytes = PAGE_SIZE - off; @@ -393,7 +397,7 @@ create_pagelist(char __user *buf, size_t count, unsigned short type) /* do not try and release vmalloc pages */ } else { actual_pages = pin_user_pages_fast( - (unsigned long)buf & PAGE_MASK, + (unsigned long)ubuf & PAGE_MASK, num_pages, type == PAGELIST_READ, pages); diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c index d4d811884861..01125d9f991b 100644 --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c @@ -53,7 +53,7 @@ int vchiq_susp_log_level = VCHIQ_LOG_ERROR; struct user_service { struct vchiq_service *service; - void *userdata; + void __user *userdata; struct vchiq_instance *instance; char is_vchi; char dequeue_pending; @@ -75,7 +75,7 @@ struct bulk_waiter_node { struct vchiq_instance { struct vchiq_state *state; - struct vchiq_completion_data completions[MAX_COMPLETIONS]; + struct vchiq_completion_data_kernel completions[MAX_COMPLETIONS]; int completion_insert; int completion_remove; struct completion insert_event; @@ -273,7 +273,7 @@ EXPORT_SYMBOL(vchiq_connect); static enum vchiq_status vchiq_add_service( struct vchiq_instance *instance, - const struct vchiq_service_params *params, + const struct vchiq_service_params_kernel *params, unsigned int *phandle) { enum vchiq_status status; @@ -311,7 +311,7 @@ static enum vchiq_status vchiq_add_service( enum vchiq_status vchiq_open_service( struct vchiq_instance *instance, - const struct vchiq_service_params *params, + const struct vchiq_service_params_kernel *params, unsigned int *phandle) { enum vchiq_status status = VCHIQ_ERROR; @@ -359,8 +359,9 @@ vchiq_bulk_transmit(unsigned int handle, const void *data, switch (mode) { case VCHIQ_BULK_MODE_NOCALLBACK: case VCHIQ_BULK_MODE_CALLBACK: - status = vchiq_bulk_transfer(handle, (void *)data, size, - userdata, mode, + status = vchiq_bulk_transfer(handle, + (void *)data, NULL, + size, userdata, mode, VCHIQ_BULK_TRANSMIT); break; case VCHIQ_BULK_MODE_BLOCKING: @@ -396,7 +397,8 @@ enum vchiq_status vchiq_bulk_receive(unsigned int handle, void *data, switch (mode) { case VCHIQ_BULK_MODE_NOCALLBACK: case VCHIQ_BULK_MODE_CALLBACK: - status = vchiq_bulk_transfer(handle, data, size, userdata, + status = vchiq_bulk_transfer(handle, data, NULL, + size, userdata, mode, VCHIQ_BULK_RECEIVE); break; case VCHIQ_BULK_MODE_BLOCKING: @@ -430,6 +432,7 @@ vchiq_blocking_bulk_transfer(unsigned int handle, void *data, struct vchiq_service *service; enum vchiq_status status; struct bulk_waiter_node *waiter = NULL; + bool found = false; service = find_service_by_handle(handle); if (!service) @@ -443,17 +446,19 @@ vchiq_blocking_bulk_transfer(unsigned int handle, void *data, list_for_each_entry(waiter, &instance->bulk_waiter_list, list) { if (waiter->pid == current->pid) { list_del(&waiter->list); + found = true; break; } } mutex_unlock(&instance->bulk_waiter_list_mutex); - if (waiter) { + if (found) { struct vchiq_bulk *bulk = waiter->bulk_waiter.bulk; if (bulk) { /* This thread has an outstanding bulk transfer. */ - if ((bulk->data != data) || + /* FIXME: why compare a dma address to a pointer? */ + if ((bulk->data != (dma_addr_t)(uintptr_t)data) || (bulk->size != size)) { /* This is not a retry of the previous one. * Cancel the signal when the transfer @@ -464,9 +469,7 @@ vchiq_blocking_bulk_transfer(unsigned int handle, void *data, spin_unlock(&bulk_waiter_spinlock); } } - } - - if (!waiter) { + } else { waiter = kzalloc(sizeof(struct bulk_waiter_node), GFP_KERNEL); if (!waiter) { vchiq_log_error(vchiq_core_log_level, @@ -475,7 +478,8 @@ vchiq_blocking_bulk_transfer(unsigned int handle, void *data, } } - status = vchiq_bulk_transfer(handle, data, size, &waiter->bulk_waiter, + status = vchiq_bulk_transfer(handle, data, NULL, size, + &waiter->bulk_waiter, VCHIQ_BULK_MODE_BLOCKING, dir); if ((status != VCHIQ_RETRY) || fatal_signal_pending(current) || !waiter->bulk_waiter.bulk) { @@ -513,7 +517,7 @@ add_completion(struct vchiq_instance *instance, enum vchiq_reason reason, struct vchiq_header *header, struct user_service *user_service, void *bulk_userdata) { - struct vchiq_completion_data *completion; + struct vchiq_completion_data_kernel *completion; int insert; DEBUG_INITIALISE(g_state.local) @@ -765,12 +769,13 @@ static ssize_t vchiq_ioc_copy_element_data(void *context, void *dest, * vchiq_ioc_queue_message * **************************************************************************/ -static enum vchiq_status +static int vchiq_ioc_queue_message(unsigned int handle, struct vchiq_element *elements, unsigned long count) { struct vchiq_io_copy_callback_context context; + enum vchiq_status status = VCHIQ_SUCCESS; unsigned long i; size_t total_size = 0; @@ -785,8 +790,459 @@ vchiq_ioc_queue_message(unsigned int handle, total_size += elements[i].size; } - return vchiq_queue_message(handle, vchiq_ioc_copy_element_data, - &context, total_size); + status = vchiq_queue_message(handle, vchiq_ioc_copy_element_data, + &context, total_size); + + if (status == VCHIQ_ERROR) + return -EIO; + else if (status == VCHIQ_RETRY) + return -EINTR; + return 0; +} + +static int vchiq_ioc_create_service(struct vchiq_instance *instance, + struct vchiq_create_service *args) +{ + struct user_service *user_service = NULL; + struct vchiq_service *service; + enum vchiq_status status = VCHIQ_SUCCESS; + struct vchiq_service_params_kernel params; + int srvstate; + + user_service = kmalloc(sizeof(*user_service), GFP_KERNEL); + if (!user_service) + return -ENOMEM; + + if (args->is_open) { + if (!instance->connected) { + kfree(user_service); + return -ENOTCONN; + } + srvstate = VCHIQ_SRVSTATE_OPENING; + } else { + srvstate = instance->connected ? + VCHIQ_SRVSTATE_LISTENING : VCHIQ_SRVSTATE_HIDDEN; + } + + params = (struct vchiq_service_params_kernel) { + .fourcc = args->params.fourcc, + .callback = service_callback, + .userdata = user_service, + .version = args->params.version, + .version_min = args->params.version_min, + }; + service = vchiq_add_service_internal(instance->state, ¶ms, + srvstate, instance, + user_service_free); + if (!service) { + kfree(user_service); + return -EEXIST; + } + + user_service->service = service; + user_service->userdata = args->params.userdata; + user_service->instance = instance; + user_service->is_vchi = (args->is_vchi != 0); + user_service->dequeue_pending = 0; + user_service->close_pending = 0; + user_service->message_available_pos = instance->completion_remove - 1; + user_service->msg_insert = 0; + user_service->msg_remove = 0; + init_completion(&user_service->insert_event); + init_completion(&user_service->remove_event); + init_completion(&user_service->close_event); + + if (args->is_open) { + status = vchiq_open_service_internal(service, instance->pid); + if (status != VCHIQ_SUCCESS) { + vchiq_remove_service(service->handle); + return (status == VCHIQ_RETRY) ? + -EINTR : -EIO; + } + } + args->handle = service->handle; + + return 0; +} + +static int vchiq_ioc_dequeue_message(struct vchiq_instance *instance, + struct vchiq_dequeue_message *args) +{ + struct user_service *user_service; + struct vchiq_service *service; + struct vchiq_header *header; + int ret; + + DEBUG_INITIALISE(g_state.local) + DEBUG_TRACE(DEQUEUE_MESSAGE_LINE); + service = find_service_for_instance(instance, args->handle); + if (!service) + return -EINVAL; + + user_service = (struct user_service *)service->base.userdata; + if (user_service->is_vchi == 0) { + ret = -EINVAL; + goto out; + } + + spin_lock(&msg_queue_spinlock); + if (user_service->msg_remove == user_service->msg_insert) { + if (!args->blocking) { + spin_unlock(&msg_queue_spinlock); + DEBUG_TRACE(DEQUEUE_MESSAGE_LINE); + ret = -EWOULDBLOCK; + goto out; + } + user_service->dequeue_pending = 1; + ret = 0; + do { + spin_unlock(&msg_queue_spinlock); + DEBUG_TRACE(DEQUEUE_MESSAGE_LINE); + if (wait_for_completion_interruptible( + &user_service->insert_event)) { + vchiq_log_info(vchiq_arm_log_level, + "DEQUEUE_MESSAGE interrupted"); + ret = -EINTR; + break; + } + spin_lock(&msg_queue_spinlock); + } while (user_service->msg_remove == + user_service->msg_insert); + + if (ret) + goto out; + } + + BUG_ON((int)(user_service->msg_insert - + user_service->msg_remove) < 0); + + header = user_service->msg_queue[user_service->msg_remove & + (MSG_QUEUE_SIZE - 1)]; + user_service->msg_remove++; + spin_unlock(&msg_queue_spinlock); + + complete(&user_service->remove_event); + if (!header) { + ret = -ENOTCONN; + } else if (header->size <= args->bufsize) { + /* Copy to user space if msgbuf is not NULL */ + if (!args->buf || (copy_to_user(args->buf, + header->data, header->size) == 0)) { + ret = header->size; + vchiq_release_message(service->handle, header); + } else + ret = -EFAULT; + } else { + vchiq_log_error(vchiq_arm_log_level, + "header %pK: bufsize %x < size %x", + header, args->bufsize, header->size); + WARN(1, "invalid size\n"); + ret = -EMSGSIZE; + } + DEBUG_TRACE(DEQUEUE_MESSAGE_LINE); +out: + unlock_service(service); + return ret; +} + +static int vchiq_irq_queue_bulk_tx_rx(struct vchiq_instance *instance, + struct vchiq_queue_bulk_transfer *args, + enum vchiq_bulk_dir dir, + enum vchiq_bulk_mode __user *mode) +{ + struct vchiq_service *service; + struct bulk_waiter_node *waiter = NULL; + bool found = false; + void *userdata = NULL; + int status = 0; + int ret; + + service = find_service_for_instance(instance, args->handle); + if (!service) + return -EINVAL; + + if (args->mode == VCHIQ_BULK_MODE_BLOCKING) { + waiter = kzalloc(sizeof(struct bulk_waiter_node), + GFP_KERNEL); + if (!waiter) { + ret = -ENOMEM; + goto out; + } + + userdata = &waiter->bulk_waiter; + } else if (args->mode == VCHIQ_BULK_MODE_WAITING) { + mutex_lock(&instance->bulk_waiter_list_mutex); + list_for_each_entry(waiter, &instance->bulk_waiter_list, + list) { + if (waiter->pid == current->pid) { + list_del(&waiter->list); + found = true; + break; + } + } + mutex_unlock(&instance->bulk_waiter_list_mutex); + if (!found) { + vchiq_log_error(vchiq_arm_log_level, + "no bulk_waiter found for pid %d", + current->pid); + ret = -ESRCH; + goto out; + } + vchiq_log_info(vchiq_arm_log_level, + "found bulk_waiter %pK for pid %d", waiter, + current->pid); + userdata = &waiter->bulk_waiter; + } + + /* + * FIXME address space mismatch: + * args->data may be interpreted as a kernel pointer + * in create_pagelist() called from vchiq_bulk_transfer(), + * accessing kernel data instead of user space, based on the + * address. + */ + status = vchiq_bulk_transfer(args->handle, NULL, args->data, args->size, + userdata, args->mode, dir); + + if (!waiter) { + ret = 0; + goto out; + } + + if ((status != VCHIQ_RETRY) || fatal_signal_pending(current) || + !waiter->bulk_waiter.bulk) { + if (waiter->bulk_waiter.bulk) { + /* Cancel the signal when the transfer + ** completes. */ + spin_lock(&bulk_waiter_spinlock); + waiter->bulk_waiter.bulk->userdata = NULL; + spin_unlock(&bulk_waiter_spinlock); + } + kfree(waiter); + ret = 0; + } else { + const enum vchiq_bulk_mode mode_waiting = + VCHIQ_BULK_MODE_WAITING; + waiter->pid = current->pid; + mutex_lock(&instance->bulk_waiter_list_mutex); + list_add(&waiter->list, &instance->bulk_waiter_list); + mutex_unlock(&instance->bulk_waiter_list_mutex); + vchiq_log_info(vchiq_arm_log_level, + "saved bulk_waiter %pK for pid %d", + waiter, current->pid); + + ret = put_user(mode_waiting, mode); + } +out: + unlock_service(service); + if (ret) + return ret; + else if (status == VCHIQ_ERROR) + return -EIO; + else if (status == VCHIQ_RETRY) + return -EINTR; + return 0; +} + +/* read a user pointer value from an array pointers in user space */ +static inline int vchiq_get_user_ptr(void __user **buf, void __user *ubuf, int index) +{ + int ret; + + if (in_compat_syscall()) { + compat_uptr_t ptr32; + compat_uptr_t __user *uptr = ubuf; + ret = get_user(ptr32, uptr + index); + *buf = compat_ptr(ptr32); + } else { + uintptr_t ptr, __user *uptr = ubuf; + ret = get_user(ptr, uptr + index); + *buf = (void __user *)ptr; + } + + return ret; +} + +struct vchiq_completion_data32 { + enum vchiq_reason reason; + compat_uptr_t header; + compat_uptr_t service_userdata; + compat_uptr_t bulk_userdata; +}; + +static int vchiq_put_completion(struct vchiq_completion_data __user *buf, + struct vchiq_completion_data *completion, + int index) +{ + struct vchiq_completion_data32 __user *buf32 = (void __user *)buf; + + if (in_compat_syscall()) { + struct vchiq_completion_data32 tmp = { + .reason = completion->reason, + .header = ptr_to_compat(completion->header), + .service_userdata = ptr_to_compat(completion->service_userdata), + .bulk_userdata = ptr_to_compat(completion->bulk_userdata), + }; + if (copy_to_user(&buf32[index], &tmp, sizeof(tmp))) + return -EFAULT; + } else { + if (copy_to_user(&buf[index], completion, sizeof(*completion))) + return -EFAULT; + } + + return 0; +} + +static int vchiq_ioc_await_completion(struct vchiq_instance *instance, + struct vchiq_await_completion *args, + int __user *msgbufcountp) +{ + int msgbufcount; + int remove; + int ret; + + DEBUG_INITIALISE(g_state.local) + + DEBUG_TRACE(AWAIT_COMPLETION_LINE); + if (!instance->connected) { + return -ENOTCONN; + } + + mutex_lock(&instance->completion_mutex); + + DEBUG_TRACE(AWAIT_COMPLETION_LINE); + while ((instance->completion_remove == + instance->completion_insert) + && !instance->closing) { + int rc; + + DEBUG_TRACE(AWAIT_COMPLETION_LINE); + mutex_unlock(&instance->completion_mutex); + rc = wait_for_completion_interruptible( + &instance->insert_event); + mutex_lock(&instance->completion_mutex); + if (rc) { + DEBUG_TRACE(AWAIT_COMPLETION_LINE); + vchiq_log_info(vchiq_arm_log_level, + "AWAIT_COMPLETION interrupted"); + ret = -EINTR; + goto out; + } + } + DEBUG_TRACE(AWAIT_COMPLETION_LINE); + + msgbufcount = args->msgbufcount; + remove = instance->completion_remove; + + for (ret = 0; ret < args->count; ret++) { + struct vchiq_completion_data_kernel *completion; + struct vchiq_completion_data user_completion; + struct vchiq_service *service; + struct user_service *user_service; + struct vchiq_header *header; + + if (remove == instance->completion_insert) + break; + + completion = &instance->completions[ + remove & (MAX_COMPLETIONS - 1)]; + + /* + * A read memory barrier is needed to stop + * prefetch of a stale completion record + */ + rmb(); + + service = completion->service_userdata; + user_service = service->base.userdata; + + memset(&user_completion, 0, sizeof(user_completion)); + user_completion = (struct vchiq_completion_data) { + .reason = completion->reason, + .service_userdata = user_service->userdata, + }; + + header = completion->header; + if (header) { + void __user *msgbuf; + int msglen; + + msglen = header->size + sizeof(struct vchiq_header); + /* This must be a VCHIQ-style service */ + if (args->msgbufsize < msglen) { + vchiq_log_error(vchiq_arm_log_level, + "header %pK: msgbufsize %x < msglen %x", + header, args->msgbufsize, msglen); + WARN(1, "invalid message size\n"); + if (ret == 0) + ret = -EMSGSIZE; + break; + } + if (msgbufcount <= 0) + /* Stall here for lack of a + ** buffer for the message. */ + break; + /* Get the pointer from user space */ + msgbufcount--; + if (vchiq_get_user_ptr(&msgbuf, args->msgbufs, + msgbufcount)) { + if (ret == 0) + ret = -EFAULT; + break; + } + + /* Copy the message to user space */ + if (copy_to_user(msgbuf, header, msglen)) { + if (ret == 0) + ret = -EFAULT; + break; + } + + /* Now it has been copied, the message + ** can be released. */ + vchiq_release_message(service->handle, header); + + /* The completion must point to the + ** msgbuf. */ + user_completion.header = msgbuf; + } + + if ((completion->reason == VCHIQ_SERVICE_CLOSED) && + !instance->use_close_delivered) + unlock_service(service); + + /* + * FIXME: address space mismatch, does bulk_userdata + * actually point to user or kernel memory? + */ + user_completion.bulk_userdata = completion->bulk_userdata; + + if (vchiq_put_completion(args->buf, &user_completion, ret)) { + if (ret == 0) + ret = -EFAULT; + break; + } + + /* + * Ensure that the above copy has completed + * before advancing the remove pointer. + */ + mb(); + remove++; + instance->completion_remove = remove; + } + + if (msgbufcount != args->msgbufcount) { + if (put_user(msgbufcount, msgbufcountp)) + ret = -EFAULT; + } +out: + if (ret) + complete(&instance->remove_event); + mutex_unlock(&instance->completion_mutex); + DEBUG_TRACE(AWAIT_COMPLETION_LINE); + + return ret; } /**************************************************************************** @@ -803,8 +1259,6 @@ vchiq_ioctl(struct file *file, unsigned int cmd, unsigned long arg) long ret = 0; int i, rc; - DEBUG_INITIALISE(g_state.local) - vchiq_log_trace(vchiq_arm_log_level, "%s - instance %pK, cmd %s, arg %lx", __func__, instance, @@ -861,85 +1315,22 @@ vchiq_ioctl(struct file *file, unsigned int cmd, unsigned long arg) break; case VCHIQ_IOC_CREATE_SERVICE: { + struct vchiq_create_service __user *argp; struct vchiq_create_service args; - struct user_service *user_service = NULL; - void *userdata; - int srvstate; - if (copy_from_user(&args, (const void __user *)arg, - sizeof(args))) { + argp = (void __user *)arg; + if (copy_from_user(&args, argp, sizeof(args))) { ret = -EFAULT; break; } - user_service = kmalloc(sizeof(*user_service), GFP_KERNEL); - if (!user_service) { - ret = -ENOMEM; + ret = vchiq_ioc_create_service(instance, &args); + if (ret < 0) break; - } - - if (args.is_open) { - if (!instance->connected) { - ret = -ENOTCONN; - kfree(user_service); - break; - } - srvstate = VCHIQ_SRVSTATE_OPENING; - } else { - srvstate = - instance->connected ? - VCHIQ_SRVSTATE_LISTENING : - VCHIQ_SRVSTATE_HIDDEN; - } - - userdata = args.params.userdata; - args.params.callback = service_callback; - args.params.userdata = user_service; - service = vchiq_add_service_internal( - instance->state, - &args.params, srvstate, - instance, user_service_free); - - if (service) { - user_service->service = service; - user_service->userdata = userdata; - user_service->instance = instance; - user_service->is_vchi = (args.is_vchi != 0); - user_service->dequeue_pending = 0; - user_service->close_pending = 0; - user_service->message_available_pos = - instance->completion_remove - 1; - user_service->msg_insert = 0; - user_service->msg_remove = 0; - init_completion(&user_service->insert_event); - init_completion(&user_service->remove_event); - init_completion(&user_service->close_event); - - if (args.is_open) { - status = vchiq_open_service_internal - (service, instance->pid); - if (status != VCHIQ_SUCCESS) { - vchiq_remove_service(service->handle); - service = NULL; - ret = (status == VCHIQ_RETRY) ? - -EINTR : -EIO; - break; - } - } - - if (copy_to_user((void __user *) - &(((struct vchiq_create_service __user *) - arg)->handle), - (const void *)&service->handle, - sizeof(service->handle))) { - ret = -EFAULT; - vchiq_remove_service(service->handle); - } - service = NULL; - } else { - ret = -EEXIST; - kfree(user_service); + if (put_user(args.handle, &argp->handle)) { + vchiq_remove_service(args.handle); + ret = -EFAULT; } } break; @@ -1020,9 +1411,8 @@ vchiq_ioctl(struct file *file, unsigned int cmd, unsigned long arg) if (copy_from_user(elements, args.elements, args.count * sizeof(struct vchiq_element)) == 0) - status = vchiq_ioc_queue_message - (args.handle, - elements, args.count); + ret = vchiq_ioc_queue_message(args.handle, elements, + args.count); else ret = -EFAULT; } else { @@ -1033,333 +1423,46 @@ vchiq_ioctl(struct file *file, unsigned int cmd, unsigned long arg) case VCHIQ_IOC_QUEUE_BULK_TRANSMIT: case VCHIQ_IOC_QUEUE_BULK_RECEIVE: { struct vchiq_queue_bulk_transfer args; - struct bulk_waiter_node *waiter = NULL; + struct vchiq_queue_bulk_transfer __user *argp; enum vchiq_bulk_dir dir = (cmd == VCHIQ_IOC_QUEUE_BULK_TRANSMIT) ? VCHIQ_BULK_TRANSMIT : VCHIQ_BULK_RECEIVE; - if (copy_from_user(&args, (const void __user *)arg, - sizeof(args))) { + argp = (void __user *)arg; + if (copy_from_user(&args, argp, sizeof(args))) { ret = -EFAULT; break; } - service = find_service_for_instance(instance, args.handle); - if (!service) { - ret = -EINVAL; - break; - } - - if (args.mode == VCHIQ_BULK_MODE_BLOCKING) { - waiter = kzalloc(sizeof(struct bulk_waiter_node), - GFP_KERNEL); - if (!waiter) { - ret = -ENOMEM; - break; - } - - args.userdata = &waiter->bulk_waiter; - } else if (args.mode == VCHIQ_BULK_MODE_WAITING) { - mutex_lock(&instance->bulk_waiter_list_mutex); - list_for_each_entry(waiter, &instance->bulk_waiter_list, - list) { - if (waiter->pid == current->pid) { - list_del(&waiter->list); - break; - } - } - mutex_unlock(&instance->bulk_waiter_list_mutex); - if (!waiter) { - vchiq_log_error(vchiq_arm_log_level, - "no bulk_waiter found for pid %d", - current->pid); - ret = -ESRCH; - break; - } - vchiq_log_info(vchiq_arm_log_level, - "found bulk_waiter %pK for pid %d", waiter, - current->pid); - args.userdata = &waiter->bulk_waiter; - } - - status = vchiq_bulk_transfer(args.handle, args.data, args.size, - args.userdata, args.mode, dir); - - if (!waiter) - break; - - if ((status != VCHIQ_RETRY) || fatal_signal_pending(current) || - !waiter->bulk_waiter.bulk) { - if (waiter->bulk_waiter.bulk) { - /* Cancel the signal when the transfer - ** completes. */ - spin_lock(&bulk_waiter_spinlock); - waiter->bulk_waiter.bulk->userdata = NULL; - spin_unlock(&bulk_waiter_spinlock); - } - kfree(waiter); - } else { - const enum vchiq_bulk_mode mode_waiting = - VCHIQ_BULK_MODE_WAITING; - waiter->pid = current->pid; - mutex_lock(&instance->bulk_waiter_list_mutex); - list_add(&waiter->list, &instance->bulk_waiter_list); - mutex_unlock(&instance->bulk_waiter_list_mutex); - vchiq_log_info(vchiq_arm_log_level, - "saved bulk_waiter %pK for pid %d", - waiter, current->pid); - - if (copy_to_user((void __user *) - &(((struct vchiq_queue_bulk_transfer __user *) - arg)->mode), - (const void *)&mode_waiting, - sizeof(mode_waiting))) - ret = -EFAULT; - } + ret = vchiq_irq_queue_bulk_tx_rx(instance, &args, + dir, &argp->mode); } break; case VCHIQ_IOC_AWAIT_COMPLETION: { struct vchiq_await_completion args; + struct vchiq_await_completion __user *argp; - DEBUG_TRACE(AWAIT_COMPLETION_LINE); - if (!instance->connected) { - ret = -ENOTCONN; - break; - } - - if (copy_from_user(&args, (const void __user *)arg, - sizeof(args))) { + argp = (void __user *)arg; + if (copy_from_user(&args, argp, sizeof(args))) { ret = -EFAULT; break; } - mutex_lock(&instance->completion_mutex); - - DEBUG_TRACE(AWAIT_COMPLETION_LINE); - while ((instance->completion_remove == - instance->completion_insert) - && !instance->closing) { - int rc; - - DEBUG_TRACE(AWAIT_COMPLETION_LINE); - mutex_unlock(&instance->completion_mutex); - rc = wait_for_completion_interruptible( - &instance->insert_event); - mutex_lock(&instance->completion_mutex); - if (rc) { - DEBUG_TRACE(AWAIT_COMPLETION_LINE); - vchiq_log_info(vchiq_arm_log_level, - "AWAIT_COMPLETION interrupted"); - ret = -EINTR; - break; - } - } - DEBUG_TRACE(AWAIT_COMPLETION_LINE); - - if (ret == 0) { - int msgbufcount = args.msgbufcount; - int remove = instance->completion_remove; - - for (ret = 0; ret < args.count; ret++) { - struct vchiq_completion_data *completion; - struct vchiq_service *service; - struct user_service *user_service; - struct vchiq_header *header; - - if (remove == instance->completion_insert) - break; - - completion = &instance->completions[ - remove & (MAX_COMPLETIONS - 1)]; - - /* - * A read memory barrier is needed to stop - * prefetch of a stale completion record - */ - rmb(); - - service = completion->service_userdata; - user_service = service->base.userdata; - completion->service_userdata = - user_service->userdata; - - header = completion->header; - if (header) { - void __user *msgbuf; - int msglen; - - msglen = header->size + - sizeof(struct vchiq_header); - /* This must be a VCHIQ-style service */ - if (args.msgbufsize < msglen) { - vchiq_log_error( - vchiq_arm_log_level, - "header %pK: msgbufsize %x < msglen %x", - header, args.msgbufsize, - msglen); - WARN(1, "invalid message " - "size\n"); - if (ret == 0) - ret = -EMSGSIZE; - break; - } - if (msgbufcount <= 0) - /* Stall here for lack of a - ** buffer for the message. */ - break; - /* Get the pointer from user space */ - msgbufcount--; - if (copy_from_user(&msgbuf, - (const void __user *) - &args.msgbufs[msgbufcount], - sizeof(msgbuf))) { - if (ret == 0) - ret = -EFAULT; - break; - } - - /* Copy the message to user space */ - if (copy_to_user(msgbuf, header, - msglen)) { - if (ret == 0) - ret = -EFAULT; - break; - } - - /* Now it has been copied, the message - ** can be released. */ - vchiq_release_message(service->handle, - header); - - /* The completion must point to the - ** msgbuf. */ - completion->header = - (struct vchiq_header __force *) - msgbuf; - } - - if ((completion->reason == - VCHIQ_SERVICE_CLOSED) && - !instance->use_close_delivered) - unlock_service(service); - - if (copy_to_user((void __user *)( - (size_t)args.buf + ret * - sizeof(struct vchiq_completion_data)), - completion, - sizeof(struct vchiq_completion_data))) { - if (ret == 0) - ret = -EFAULT; - break; - } - - /* - * Ensure that the above copy has completed - * before advancing the remove pointer. - */ - mb(); - remove++; - instance->completion_remove = remove; - } - - if (msgbufcount != args.msgbufcount) { - if (copy_to_user((void __user *) - &((struct vchiq_await_completion *)arg) - ->msgbufcount, - &msgbufcount, - sizeof(msgbufcount))) { - ret = -EFAULT; - } - } - } - - if (ret) - complete(&instance->remove_event); - mutex_unlock(&instance->completion_mutex); - DEBUG_TRACE(AWAIT_COMPLETION_LINE); + ret = vchiq_ioc_await_completion(instance, &args, + &argp->msgbufcount); } break; case VCHIQ_IOC_DEQUEUE_MESSAGE: { struct vchiq_dequeue_message args; - struct user_service *user_service; - struct vchiq_header *header; - DEBUG_TRACE(DEQUEUE_MESSAGE_LINE); if (copy_from_user(&args, (const void __user *)arg, sizeof(args))) { ret = -EFAULT; break; } - service = find_service_for_instance(instance, args.handle); - if (!service) { - ret = -EINVAL; - break; - } - user_service = (struct user_service *)service->base.userdata; - if (user_service->is_vchi == 0) { - ret = -EINVAL; - break; - } - spin_lock(&msg_queue_spinlock); - if (user_service->msg_remove == user_service->msg_insert) { - if (!args.blocking) { - spin_unlock(&msg_queue_spinlock); - DEBUG_TRACE(DEQUEUE_MESSAGE_LINE); - ret = -EWOULDBLOCK; - break; - } - user_service->dequeue_pending = 1; - do { - spin_unlock(&msg_queue_spinlock); - DEBUG_TRACE(DEQUEUE_MESSAGE_LINE); - if (wait_for_completion_interruptible( - &user_service->insert_event)) { - vchiq_log_info(vchiq_arm_log_level, - "DEQUEUE_MESSAGE interrupted"); - ret = -EINTR; - break; - } - spin_lock(&msg_queue_spinlock); - } while (user_service->msg_remove == - user_service->msg_insert); - - if (ret) - break; - } - - BUG_ON((int)(user_service->msg_insert - - user_service->msg_remove) < 0); - - header = user_service->msg_queue[user_service->msg_remove & - (MSG_QUEUE_SIZE - 1)]; - user_service->msg_remove++; - spin_unlock(&msg_queue_spinlock); - - complete(&user_service->remove_event); - if (!header) - ret = -ENOTCONN; - else if (header->size <= args.bufsize) { - /* Copy to user space if msgbuf is not NULL */ - if (!args.buf || - (copy_to_user((void __user *)args.buf, - header->data, - header->size) == 0)) { - ret = header->size; - vchiq_release_message( - service->handle, - header); - } else - ret = -EFAULT; - } else { - vchiq_log_error(vchiq_arm_log_level, - "header %pK: bufsize %x < size %x", - header, args.bufsize, header->size); - WARN(1, "invalid size\n"); - ret = -EMSGSIZE; - } - DEBUG_TRACE(DEQUEUE_MESSAGE_LINE); + ret = vchiq_ioc_dequeue_message(instance, &args); } break; case VCHIQ_IOC_GET_CLIENT_ID: { @@ -1489,46 +1592,36 @@ static long vchiq_compat_ioctl_create_service( struct file *file, unsigned int cmd, - unsigned long arg) + struct vchiq_create_service32 __user *ptrargs32) { - struct vchiq_create_service __user *args; - struct vchiq_create_service32 __user *ptrargs32 = - (struct vchiq_create_service32 __user *)arg; + struct vchiq_create_service args; struct vchiq_create_service32 args32; long ret; - args = compat_alloc_user_space(sizeof(*args)); - if (!args) - return -EFAULT; - if (copy_from_user(&args32, ptrargs32, sizeof(args32))) return -EFAULT; - if (put_user(args32.params.fourcc, &args->params.fourcc) || - put_user(compat_ptr(args32.params.callback), - &args->params.callback) || - put_user(compat_ptr(args32.params.userdata), - &args->params.userdata) || - put_user(args32.params.version, &args->params.version) || - put_user(args32.params.version_min, - &args->params.version_min) || - put_user(args32.is_open, &args->is_open) || - put_user(args32.is_vchi, &args->is_vchi) || - put_user(args32.handle, &args->handle)) - return -EFAULT; - - ret = vchiq_ioctl(file, VCHIQ_IOC_CREATE_SERVICE, (unsigned long)args); + args = (struct vchiq_create_service) { + .params = { + .fourcc = args32.params.fourcc, + .callback = compat_ptr(args32.params.callback), + .userdata = compat_ptr(args32.params.userdata), + .version = args32.params.version, + .version_min = args32.params.version_min, + }, + .is_open = args32.is_open, + .is_vchi = args32.is_vchi, + .handle = args32.handle, + }; + ret = vchiq_ioc_create_service(file->private_data, &args); if (ret < 0) return ret; - if (get_user(args32.handle, &args->handle)) - return -EFAULT; - - if (copy_to_user(&ptrargs32->handle, - &args32.handle, - sizeof(args32.handle))) + if (put_user(args.handle, &ptrargs32->handle)) { + vchiq_remove_service(args.handle); return -EFAULT; + } return 0; } @@ -1550,55 +1643,53 @@ struct vchiq_queue_message32 { static long vchiq_compat_ioctl_queue_message(struct file *file, unsigned int cmd, - unsigned long arg) + struct vchiq_queue_message32 __user *arg) { - struct vchiq_queue_message __user *args; - struct vchiq_element __user *elements; + struct vchiq_queue_message args; struct vchiq_queue_message32 args32; - unsigned int count; - - if (copy_from_user(&args32, - (struct vchiq_queue_message32 __user *)arg, - sizeof(args32))) - return -EFAULT; - - args = compat_alloc_user_space(sizeof(*args) + - (sizeof(*elements) * MAX_ELEMENTS)); + struct vchiq_service *service; + int ret; - if (!args) + if (copy_from_user(&args32, arg, sizeof(args32))) return -EFAULT; - if (put_user(args32.handle, &args->handle) || - put_user(args32.count, &args->count) || - put_user(compat_ptr(args32.elements), &args->elements)) - return -EFAULT; + args = (struct vchiq_queue_message) { + .handle = args32.handle, + .count = args32.count, + .elements = compat_ptr(args32.elements), + }; if (args32.count > MAX_ELEMENTS) return -EINVAL; - if (args32.elements && args32.count) { - struct vchiq_element32 tempelement32[MAX_ELEMENTS]; + service = find_service_for_instance(file->private_data, args.handle); + if (!service) + return -EINVAL; - elements = (struct vchiq_element __user *)(args + 1); + if (args32.elements && args32.count) { + struct vchiq_element32 element32[MAX_ELEMENTS]; + struct vchiq_element elements[MAX_ELEMENTS]; + unsigned int count; - if (copy_from_user(&tempelement32, - compat_ptr(args32.elements), - sizeof(tempelement32))) + if (copy_from_user(&element32, args.elements, + sizeof(element32))) { + unlock_service(service); return -EFAULT; + } for (count = 0; count < args32.count; count++) { - if (put_user(compat_ptr(tempelement32[count].data), - &elements[count].data) || - put_user(tempelement32[count].size, - &elements[count].size)) - return -EFAULT; + elements[count].data = + compat_ptr(element32[count].data); + elements[count].size = element32[count].size; } - - if (put_user(elements, &args->elements)) - return -EFAULT; + ret = vchiq_ioc_queue_message(args.handle, elements, + args.count); + } else { + ret = -EINVAL; } + unlock_service(service); - return vchiq_ioctl(file, VCHIQ_IOC_QUEUE_MESSAGE, (unsigned long)args); + return ret; } struct vchiq_queue_bulk_transfer32 { @@ -1617,56 +1708,28 @@ struct vchiq_queue_bulk_transfer32 { static long vchiq_compat_ioctl_queue_bulk(struct file *file, unsigned int cmd, - unsigned long arg) + struct vchiq_queue_bulk_transfer32 __user *argp) { - struct vchiq_queue_bulk_transfer __user *args; struct vchiq_queue_bulk_transfer32 args32; - struct vchiq_queue_bulk_transfer32 __user *ptrargs32 = - (struct vchiq_queue_bulk_transfer32 __user *)arg; - long ret; - - args = compat_alloc_user_space(sizeof(*args)); - if (!args) - return -EFAULT; - - if (copy_from_user(&args32, ptrargs32, sizeof(args32))) - return -EFAULT; - - if (put_user(args32.handle, &args->handle) || - put_user(compat_ptr(args32.data), &args->data) || - put_user(args32.size, &args->size) || - put_user(compat_ptr(args32.userdata), &args->userdata) || - put_user(args32.mode, &args->mode)) - return -EFAULT; - - if (cmd == VCHIQ_IOC_QUEUE_BULK_TRANSMIT32) - cmd = VCHIQ_IOC_QUEUE_BULK_TRANSMIT; - else - cmd = VCHIQ_IOC_QUEUE_BULK_RECEIVE; - - ret = vchiq_ioctl(file, cmd, (unsigned long)args); - - if (ret < 0) - return ret; + struct vchiq_queue_bulk_transfer args; + enum vchiq_bulk_dir dir = (cmd == VCHIQ_IOC_QUEUE_BULK_TRANSMIT) ? + VCHIQ_BULK_TRANSMIT : VCHIQ_BULK_RECEIVE; - if (get_user(args32.mode, &args->mode)) + if (copy_from_user(&args32, argp, sizeof(args32))) return -EFAULT; - if (copy_to_user(&ptrargs32->mode, - &args32.mode, - sizeof(args32.mode))) - return -EFAULT; + args = (struct vchiq_queue_bulk_transfer) { + .handle = args32.handle, + .data = compat_ptr(args32.data), + .size = args32.size, + .userdata = compat_ptr(args32.userdata), + .mode = args32.mode, + }; - return 0; + return vchiq_irq_queue_bulk_tx_rx(file->private_data, &args, + dir, &argp->mode); } -struct vchiq_completion_data32 { - enum vchiq_reason reason; - compat_uptr_t header; - compat_uptr_t service_userdata; - compat_uptr_t bulk_userdata; -}; - struct vchiq_await_completion32 { unsigned int count; compat_uptr_t buf; @@ -1681,141 +1744,24 @@ struct vchiq_await_completion32 { static long vchiq_compat_ioctl_await_completion(struct file *file, unsigned int cmd, - unsigned long arg) + struct vchiq_await_completion32 __user *argp) { - struct vchiq_await_completion __user *args; - struct vchiq_completion_data __user *completion; - struct vchiq_completion_data completiontemp; + struct vchiq_await_completion args; struct vchiq_await_completion32 args32; - struct vchiq_completion_data32 completion32; - unsigned int __user *msgbufcount32; - unsigned int msgbufcount_native; - compat_uptr_t msgbuf32; - void __user *msgbuf; - void * __user *msgbufptr; - long ret; - - args = compat_alloc_user_space(sizeof(*args) + - sizeof(*completion) + - sizeof(*msgbufptr)); - if (!args) - return -EFAULT; - - completion = (struct vchiq_completion_data __user *)(args + 1); - msgbufptr = (void * __user *)(completion + 1); - - if (copy_from_user(&args32, - (struct vchiq_completion_data32 __user *)arg, - sizeof(args32))) - return -EFAULT; - - if (put_user(args32.count, &args->count) || - put_user(compat_ptr(args32.buf), &args->buf) || - put_user(args32.msgbufsize, &args->msgbufsize) || - put_user(args32.msgbufcount, &args->msgbufcount) || - put_user(compat_ptr(args32.msgbufs), &args->msgbufs)) - return -EFAULT; - - /* These are simple cases, so just fall into the native handler */ - if (!args32.count || !args32.buf || !args32.msgbufcount) - return vchiq_ioctl(file, - VCHIQ_IOC_AWAIT_COMPLETION, - (unsigned long)args); - - /* - * These are the more complex cases. Typical applications of this - * ioctl will use a very large count, with a very large msgbufcount. - * Since the native ioctl can asynchronously fill in the returned - * buffers and the application can in theory begin processing messages - * even before the ioctl returns, a bit of a trick is used here. - * - * By forcing both count and msgbufcount to be 1, it forces the native - * ioctl to only claim at most 1 message is available. This tricks - * the calling application into thinking only 1 message was actually - * available in the queue so like all good applications it will retry - * waiting until all the required messages are received. - * - * This trick has been tested and proven to work with vchiq_test, - * Minecraft_PI, the "hello pi" examples, and various other - * applications that are included in Raspbian. - */ - - if (copy_from_user(&msgbuf32, - compat_ptr(args32.msgbufs) + - (sizeof(compat_uptr_t) * - (args32.msgbufcount - 1)), - sizeof(msgbuf32))) - return -EFAULT; - - msgbuf = compat_ptr(msgbuf32); - - if (copy_to_user(msgbufptr, - &msgbuf, - sizeof(msgbuf))) - return -EFAULT; - - if (copy_to_user(&args->msgbufs, - &msgbufptr, - sizeof(msgbufptr))) - return -EFAULT; - - if (put_user(1U, &args->count) || - put_user(completion, &args->buf) || - put_user(1U, &args->msgbufcount)) - return -EFAULT; - - ret = vchiq_ioctl(file, - VCHIQ_IOC_AWAIT_COMPLETION, - (unsigned long)args); - - /* - * An return value of 0 here means that no messages where available - * in the message queue. In this case the native ioctl does not - * return any data to the application at all. Not even to update - * msgbufcount. This functionality needs to be kept here for - * compatibility. - * - * Of course, < 0 means that an error occurred and no data is being - * returned. - * - * Since count and msgbufcount was forced to 1, that means - * the only other possible return value is 1. Meaning that 1 message - * was available, so that multiple message case does not need to be - * handled here. - */ - if (ret <= 0) - return ret; - if (copy_from_user(&completiontemp, completion, sizeof(*completion))) + if (copy_from_user(&args32, argp, sizeof(args32))) return -EFAULT; - completion32.reason = completiontemp.reason; - completion32.header = ptr_to_compat(completiontemp.header); - completion32.service_userdata = - ptr_to_compat(completiontemp.service_userdata); - completion32.bulk_userdata = - ptr_to_compat(completiontemp.bulk_userdata); - - if (copy_to_user(compat_ptr(args32.buf), - &completion32, - sizeof(completion32))) - return -EFAULT; - - if (get_user(msgbufcount_native, &args->msgbufcount)) - return -EFAULT; - - if (!msgbufcount_native) - args32.msgbufcount--; - - msgbufcount32 = - &((struct vchiq_await_completion32 __user *)arg)->msgbufcount; - - if (copy_to_user(msgbufcount32, - &args32.msgbufcount, - sizeof(args32.msgbufcount))) - return -EFAULT; + args = (struct vchiq_await_completion) { + .count = args32.count, + .buf = compat_ptr(args32.buf), + .msgbufsize = args32.msgbufsize, + .msgbufcount = args32.msgbufcount, + .msgbufs = compat_ptr(args32.msgbufs), + }; - return 1; + return vchiq_ioc_await_completion(file->private_data, &args, + &argp->msgbufcount); } struct vchiq_dequeue_message32 { @@ -1831,28 +1777,22 @@ struct vchiq_dequeue_message32 { static long vchiq_compat_ioctl_dequeue_message(struct file *file, unsigned int cmd, - unsigned long arg) + struct vchiq_dequeue_message32 __user *arg) { - struct vchiq_dequeue_message __user *args; struct vchiq_dequeue_message32 args32; + struct vchiq_dequeue_message args; - args = compat_alloc_user_space(sizeof(*args)); - if (!args) - return -EFAULT; - - if (copy_from_user(&args32, - (struct vchiq_dequeue_message32 __user *)arg, - sizeof(args32))) + if (copy_from_user(&args32, arg, sizeof(args32))) return -EFAULT; - if (put_user(args32.handle, &args->handle) || - put_user(args32.blocking, &args->blocking) || - put_user(args32.bufsize, &args->bufsize) || - put_user(compat_ptr(args32.buf), &args->buf)) - return -EFAULT; + args = (struct vchiq_dequeue_message) { + .handle = args32.handle, + .blocking = args32.blocking, + .bufsize = args32.bufsize, + .buf = compat_ptr(args32.buf), + }; - return vchiq_ioctl(file, VCHIQ_IOC_DEQUEUE_MESSAGE, - (unsigned long)args); + return vchiq_ioc_dequeue_message(file->private_data, &args); } struct vchiq_get_config32 { @@ -1866,46 +1806,45 @@ struct vchiq_get_config32 { static long vchiq_compat_ioctl_get_config(struct file *file, unsigned int cmd, - unsigned long arg) + struct vchiq_get_config32 __user *arg) { - struct vchiq_get_config __user *args; struct vchiq_get_config32 args32; + struct vchiq_config config; + void __user *ptr; - args = compat_alloc_user_space(sizeof(*args)); - if (!args) - return -EFAULT; - - if (copy_from_user(&args32, - (struct vchiq_get_config32 __user *)arg, - sizeof(args32))) + if (copy_from_user(&args32, arg, sizeof(args32))) return -EFAULT; + if (args32.config_size > sizeof(config)) + return -EINVAL; - if (put_user(args32.config_size, &args->config_size) || - put_user(compat_ptr(args32.pconfig), &args->pconfig)) + vchiq_get_config(&config); + ptr = compat_ptr(args32.pconfig); + if (copy_to_user(ptr, &config, args32.config_size)) return -EFAULT; - return vchiq_ioctl(file, VCHIQ_IOC_GET_CONFIG, (unsigned long)args); + return 0; } static long vchiq_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { + void __user *argp = compat_ptr(arg); switch (cmd) { case VCHIQ_IOC_CREATE_SERVICE32: - return vchiq_compat_ioctl_create_service(file, cmd, arg); + return vchiq_compat_ioctl_create_service(file, cmd, argp); case VCHIQ_IOC_QUEUE_MESSAGE32: - return vchiq_compat_ioctl_queue_message(file, cmd, arg); + return vchiq_compat_ioctl_queue_message(file, cmd, argp); case VCHIQ_IOC_QUEUE_BULK_TRANSMIT32: case VCHIQ_IOC_QUEUE_BULK_RECEIVE32: - return vchiq_compat_ioctl_queue_bulk(file, cmd, arg); + return vchiq_compat_ioctl_queue_bulk(file, cmd, argp); case VCHIQ_IOC_AWAIT_COMPLETION32: - return vchiq_compat_ioctl_await_completion(file, cmd, arg); + return vchiq_compat_ioctl_await_completion(file, cmd, argp); case VCHIQ_IOC_DEQUEUE_MESSAGE32: - return vchiq_compat_ioctl_dequeue_message(file, cmd, arg); + return vchiq_compat_ioctl_dequeue_message(file, cmd, argp); case VCHIQ_IOC_GET_CONFIG32: - return vchiq_compat_ioctl_get_config(file, cmd, arg); + return vchiq_compat_ioctl_get_config(file, cmd, argp); default: - return vchiq_ioctl(file, cmd, arg); + return vchiq_ioctl(file, cmd, (unsigned long)argp); } } @@ -2018,7 +1957,7 @@ static int vchiq_release(struct inode *inode, struct file *file) /* Release any closed services */ while (instance->completion_remove != instance->completion_insert) { - struct vchiq_completion_data *completion; + struct vchiq_completion_data_kernel *completion; struct vchiq_service *service; completion = &instance->completions[ @@ -2283,7 +2222,7 @@ vchiq_keepalive_thread_func(void *v) struct vchiq_instance *instance; unsigned int ka_handle; - struct vchiq_service_params params = { + struct vchiq_service_params_kernel params = { .fourcc = VCHIQ_MAKE_FOURCC('K', 'E', 'E', 'P'), .callback = vchiq_keepalive_vchiq_callback, .version = KEEPALIVE_VER, diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c index 5a361e8e7c6c..38b10fd5d992 100644 --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c @@ -1392,7 +1392,7 @@ abort_outstanding_bulks(struct vchiq_service *service, bulk->remote_size); } else { /* fabricate a matching dummy bulk */ - bulk->data = NULL; + bulk->data = 0; bulk->size = 0; bulk->actual = VCHIQ_BULK_ACTUAL_ABORTED; bulk->dir = is_tx ? VCHIQ_BULK_TRANSMIT : @@ -1764,10 +1764,10 @@ parse_rx_slots(struct vchiq_state *state) queue->remote_insert++; vchiq_log_info(vchiq_core_log_level, - "%d: prs %s@%pK (%d->%d) %x@%pK", + "%d: prs %s@%pK (%d->%d) %x@%pad", state->id, msg_type_str(type), header, remoteport, localport, - bulk->actual, bulk->data); + bulk->actual, &bulk->data); vchiq_log_trace(vchiq_core_log_level, "%d: prs:%d %cx li=%x ri=%x p=%x", @@ -2316,7 +2316,7 @@ struct vchiq_header *vchiq_msg_hold(unsigned int handle) } EXPORT_SYMBOL(vchiq_msg_hold); -static int vchiq_validate_params(const struct vchiq_service_params *params) +static int vchiq_validate_params(const struct vchiq_service_params_kernel *params) { if (!params->callback || !params->fourcc) { vchiq_loud_error("Can't add service, invalid params\n"); @@ -2329,7 +2329,7 @@ static int vchiq_validate_params(const struct vchiq_service_params *params) /* Called from application thread when a client or server service is created. */ struct vchiq_service * vchiq_add_service_internal(struct vchiq_state *state, - const struct vchiq_service_params *params, + const struct vchiq_service_params_kernel *params, int srvstate, struct vchiq_instance *instance, vchiq_userdata_term userdata_term) { @@ -3015,7 +3015,8 @@ vchiq_remove_service(unsigned int handle) * structure. */ enum vchiq_status vchiq_bulk_transfer(unsigned int handle, - void *offset, int size, void *userdata, + void *offset, void __user *uoffset, + int size, void *userdata, enum vchiq_bulk_mode mode, enum vchiq_bulk_dir dir) { @@ -3031,7 +3032,8 @@ enum vchiq_status vchiq_bulk_transfer(unsigned int handle, int payload[2]; if (!service || service->srvstate != VCHIQ_SRVSTATE_OPEN || - !offset || vchiq_check_service(service) != VCHIQ_SUCCESS) + (!offset && !uoffset) || + vchiq_check_service(service) != VCHIQ_SUCCESS) goto error_exit; switch (mode) { @@ -3087,15 +3089,16 @@ enum vchiq_status vchiq_bulk_transfer(unsigned int handle, bulk->size = size; bulk->actual = VCHIQ_BULK_ACTUAL_ABORTED; - if (vchiq_prepare_bulk_data(bulk, offset, size, dir) != VCHIQ_SUCCESS) + if (vchiq_prepare_bulk_data(bulk, offset, uoffset, size, dir) + != VCHIQ_SUCCESS) goto unlock_error_exit; wmb(); vchiq_log_info(vchiq_core_log_level, - "%d: bt (%d->%d) %cx %x@%pK %pK", + "%d: bt (%d->%d) %cx %x@%pad %pK", state->id, service->localport, service->remoteport, dir_char, - size, bulk->data, userdata); + size, &bulk->data, userdata); /* The slot mutex must be held when the service is being closed, so claim it here to ensure that isn't happening */ @@ -3107,7 +3110,7 @@ enum vchiq_status vchiq_bulk_transfer(unsigned int handle, if (service->srvstate != VCHIQ_SRVSTATE_OPEN) goto unlock_both_error_exit; - payload[0] = (int)(long)bulk->data; + payload[0] = lower_32_bits(bulk->data); payload[1] = bulk->size; status = queue_message(state, NULL, diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.h b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.h index e67692879249..06200a76b871 100644 --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.h +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.h @@ -231,7 +231,7 @@ struct vchiq_bulk { short mode; short dir; void *userdata; - void *data; + dma_addr_t data; int size; void *remote_data; int remote_size; @@ -534,9 +534,9 @@ vchiq_init_state(struct vchiq_state *state, struct vchiq_slot_zero *slot_zero); extern enum vchiq_status vchiq_connect_internal(struct vchiq_state *state, struct vchiq_instance *instance); -extern struct vchiq_service * +struct vchiq_service * vchiq_add_service_internal(struct vchiq_state *state, - const struct vchiq_service_params *params, + const struct vchiq_service_params_kernel *params, int srvstate, struct vchiq_instance *instance, vchiq_userdata_term userdata_term); @@ -559,8 +559,8 @@ extern void remote_event_pollall(struct vchiq_state *state); extern enum vchiq_status -vchiq_bulk_transfer(unsigned int handle, void *offset, int size, - void *userdata, enum vchiq_bulk_mode mode, +vchiq_bulk_transfer(unsigned int handle, void *offset, void __user *uoffset, + int size, void *userdata, enum vchiq_bulk_mode mode, enum vchiq_bulk_dir dir); extern int @@ -632,8 +632,8 @@ vchiq_queue_message(unsigned int handle, ** implementations must be provided. */ extern enum vchiq_status -vchiq_prepare_bulk_data(struct vchiq_bulk *bulk, void *offset, int size, - int dir); +vchiq_prepare_bulk_data(struct vchiq_bulk *bulk, void *offset, + void __user *uoffset, int size, int dir); extern void vchiq_complete_bulk(struct vchiq_bulk *bulk); diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_ioctl.h b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_ioctl.h index 3653fd99d8a1..86d77f2eeea5 100644 --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_ioctl.h +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_ioctl.h @@ -10,6 +10,17 @@ #define VCHIQ_IOC_MAGIC 0xc4 #define VCHIQ_INVALID_HANDLE (~0) +struct vchiq_service_params { + int fourcc; + enum vchiq_status __user (*callback)(enum vchiq_reason reason, + struct vchiq_header *header, + unsigned int handle, + void *bulk_userdata); + void __user *userdata; + short version; /* Increment for non-trivial changes */ + short version_min; /* Update for incompatible changes */ +}; + struct vchiq_create_service { struct vchiq_service_params params; int is_open; @@ -25,32 +36,32 @@ struct vchiq_queue_message { struct vchiq_queue_bulk_transfer { unsigned int handle; - void *data; + void __user *data; unsigned int size; - void *userdata; + void __user *userdata; enum vchiq_bulk_mode mode; }; struct vchiq_completion_data { enum vchiq_reason reason; - struct vchiq_header *header; - void *service_userdata; - void *bulk_userdata; + struct vchiq_header __user *header; + void __user *service_userdata; + void __user *bulk_userdata; }; struct vchiq_await_completion { unsigned int count; - struct vchiq_completion_data *buf; + struct vchiq_completion_data __user *buf; unsigned int msgbufsize; unsigned int msgbufcount; /* IN/OUT */ - void **msgbufs; + void * __user *msgbufs; }; struct vchiq_dequeue_message { unsigned int handle; int blocking; unsigned int bufsize; - void *buf; + void __user *buf; }; struct vchiq_get_config { @@ -65,7 +76,7 @@ struct vchiq_set_service_option { }; struct vchiq_dump_mem { - void *virt_addr; + void __user *virt_addr; size_t num_bytes; }; diff --git a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c index e798d494f00f..3a4202551cfc 100644 --- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c +++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c @@ -1858,7 +1858,7 @@ int vchiq_mmal_init(struct vchiq_mmal_instance **out_instance) int status; struct vchiq_mmal_instance *instance; static struct vchiq_instance *vchiq_instance; - struct vchiq_service_params params = { + struct vchiq_service_params_kernel params = { .version = VC_MMAL_VER, .version_min = VC_MMAL_MIN_VER, .fourcc = VCHIQ_MAKE_FOURCC('m', 'm', 'a', 'l'), diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index 76de1fd568eb..09ab6d6f2429 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -555,7 +555,7 @@ static int device_init_rd0_ring(struct vnt_private *priv) } if (i > 0) - priv->aRD0Ring[i-1].next_desc = cpu_to_le32(priv->rd0_pool_dma); + priv->aRD0Ring[i - 1].next_desc = cpu_to_le32(priv->rd0_pool_dma); priv->pCurrRD[0] = &priv->aRD0Ring[0]; return 0; @@ -596,12 +596,12 @@ static int device_init_rd1_ring(struct vnt_private *priv) goto err_free_rd; } - desc->next = &priv->aRD1Ring[(i+1) % priv->opts.rx_descs1]; + desc->next = &priv->aRD1Ring[(i + 1) % priv->opts.rx_descs1]; desc->next_desc = cpu_to_le32(curr + sizeof(struct vnt_rx_desc)); } if (i > 0) - priv->aRD1Ring[i-1].next_desc = cpu_to_le32(priv->rd1_pool_dma); + priv->aRD1Ring[i - 1].next_desc = cpu_to_le32(priv->rd1_pool_dma); priv->pCurrRD[1] = &priv->aRD1Ring[0]; return 0; diff --git a/drivers/staging/vt6655/mac.h b/drivers/staging/vt6655/mac.h index c7888c4e96f2..6e2bd16ef384 100644 --- a/drivers/staging/vt6655/mac.h +++ b/drivers/staging/vt6655/mac.h @@ -621,7 +621,7 @@ do { \ /* set the chip with current BCN length */ #define MACvSetCurrBCNLength(iobase, wCurrBCNLength) \ - VNSvOutPortW(iobase + MAC_REG_BCNDMACTL+2, \ + VNSvOutPortW(iobase + MAC_REG_BCNDMACTL + 2, \ wCurrBCNLength) #define MACvReadBSSIDAddress(iobase, pbyEtherAddr) \ diff --git a/drivers/staging/vt6655/rxtx.c b/drivers/staging/vt6655/rxtx.c index 4778439e8757..477d19314634 100644 --- a/drivers/staging/vt6655/rxtx.c +++ b/drivers/staging/vt6655/rxtx.c @@ -367,52 +367,52 @@ s_uGetRTSCTSDuration( case RTSDUR_BA_F0: /* RTSDuration_ba_f0 */ uCTSTime = bb_get_frame_time(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate); if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M)) - uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck); + uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate - RATE_18M], bNeedAck); else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M)) - uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck); + uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate - RATE_18M], bNeedAck); break; case RTSDUR_AA_F0: /* RTSDuration_aa_f0 */ uCTSTime = bb_get_frame_time(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate); if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M)) - uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck); + uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate - RATE_18M], bNeedAck); else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M)) - uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck); + uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate - RATE_18M], bNeedAck); break; case RTSDUR_BA_F1: /* RTSDuration_ba_f1 */ uCTSTime = bb_get_frame_time(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate); if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M)) - uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck); + uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate - RATE_18M], bNeedAck); else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M)) - uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck); + uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate - RATE_18M], bNeedAck); break; case RTSDUR_AA_F1: /* RTSDuration_aa_f1 */ uCTSTime = bb_get_frame_time(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate); if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M)) - uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck); + uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate - RATE_18M], bNeedAck); else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M)) - uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck); + uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate - RATE_18M], bNeedAck); break; case CTSDUR_BA_F0: /* CTSDuration_ba_f0 */ if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M)) - uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck); + uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate - RATE_18M], bNeedAck); else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M)) - uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck); + uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate - RATE_18M], bNeedAck); break; case CTSDUR_BA_F1: /* CTSDuration_ba_f1 */ if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M)) - uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck); + uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate - RATE_18M], bNeedAck); else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M)) - uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck); + uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate - RATE_18M], bNeedAck); break; diff --git a/drivers/staging/wfx/Documentation/devicetree/bindings/net/wireless/silabs,wfx.yaml b/drivers/staging/wfx/Documentation/devicetree/bindings/net/wireless/silabs,wfx.yaml new file mode 100644 index 000000000000..43b5630c0407 --- /dev/null +++ b/drivers/staging/wfx/Documentation/devicetree/bindings/net/wireless/silabs,wfx.yaml @@ -0,0 +1,125 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +# Copyright (c) 2020, Silicon Laboratories, Inc. +%YAML 1.2 +--- + +$id: http://devicetree.org/schemas/net/wireless/silabs,wfx.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Silicon Labs WFxxx devicetree bindings + +maintainers: + - Jérôme Pouiller <jerome.pouiller@silabs.com> + +description: + The WFxxx chip series can be connected via SPI or via SDIO. + + For SDIO':' + + The driver is able to detect a WFxxx chip on SDIO bus by matching its Vendor + ID and Product ID. However, driver will only provide limited features in + this case. Thus declaring WFxxx chip in device tree is recommended (and may + become mandatory in the future). + + In addition, it is recommended to declare a mmc-pwrseq on SDIO host above + WFx. Without it, you may encounter issues with warm boot. The mmc-pwrseq + should be compatible with mmc-pwrseq-simple. Please consult + Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt for more + information. + + For SPI':' + + In add of the properties below, please consult + Documentation/devicetree/bindings/spi/spi-controller.yaml for optional SPI + related properties. + + Note that in add of the properties below, the WFx driver also supports + `mac-address` and `local-mac-address` as described in + Documentation/devicetree/bindings/net/ethernet.txt + +properties: + compatible: + const: silabs,wf200 + reg: + description: + When used on SDIO bus, <reg> must be set to 1. When used on SPI bus, it is + the chip select address of the device as defined in the SPI devices + bindings. + maxItems: 1 + spi-max-frequency: + description: (SPI only) Maximum SPI clocking speed of device in Hz. + maxItems: 1 + interrupts: + description: The interrupt line. Triggers IRQ_TYPE_LEVEL_HIGH and + IRQ_TYPE_EDGE_RISING are both supported by the chip and the driver. When + SPI is used, this property is required. When SDIO is used, the "in-band" + interrupt provided by the SDIO bus is used unless an interrupt is defined + in the Device Tree. + maxItems: 1 + reset-gpios: + description: (SPI only) Phandle of gpio that will be used to reset chip + during probe. Without this property, you may encounter issues with warm + boot. (For legacy purpose, the gpio in inverted when compatible == + "silabs,wfx-spi") + + For SDIO, the reset gpio should declared using a mmc-pwrseq. + maxItems: 1 + wakeup-gpios: + description: Phandle of gpio that will be used to wake-up chip. Without this + property, driver will disable most of power saving features. + maxItems: 1 + config-file: + description: Use an alternative file as PDS. Default is `wf200.pds`. Only + necessary for development/debug purpose. + maxItems: 1 + +required: + - compatible + - reg + +examples: + - | + #include <dt-bindings/gpio/gpio.h> + #include <dt-bindings/interrupt-controller/irq.h> + + spi0 { + #address-cells = <1>; + #size-cells = <0>; + + wfx@0 { + compatible = "silabs,wf200"; + pinctrl-names = "default"; + pinctrl-0 = <&wfx_irq &wfx_gpios>; + reg = <0>; + interrupts-extended = <&gpio 16 IRQ_TYPE_EDGE_RISING>; + wakeup-gpios = <&gpio 12 GPIO_ACTIVE_HIGH>; + reset-gpios = <&gpio 13 GPIO_ACTIVE_LOW>; + spi-max-frequency = <42000000>; + }; + }; + + - | + #include <dt-bindings/gpio/gpio.h> + #include <dt-bindings/interrupt-controller/irq.h> + + wfx_pwrseq: wfx_pwrseq { + compatible = "mmc-pwrseq-simple"; + pinctrl-names = "default"; + pinctrl-0 = <&wfx_reset>; + reset-gpios = <&gpio 13 GPIO_ACTIVE_LOW>; + }; + + mmc0 { + mmc-pwrseq = <&wfx_pwrseq>; + #address-cells = <1>; + #size-cells = <0>; + + mmc@1 { + compatible = "silabs,wf200"; + pinctrl-names = "default"; + pinctrl-0 = <&wfx_wakeup>; + reg = <1>; + wakeup-gpios = <&gpio 12 GPIO_ACTIVE_HIGH>; + }; + }; +... diff --git a/drivers/staging/wfx/Documentation/devicetree/bindings/net/wireless/siliabs,wfx.txt b/drivers/staging/wfx/Documentation/devicetree/bindings/net/wireless/siliabs,wfx.txt deleted file mode 100644 index 17db67559f5e..000000000000 --- a/drivers/staging/wfx/Documentation/devicetree/bindings/net/wireless/siliabs,wfx.txt +++ /dev/null @@ -1,98 +0,0 @@ -The WFxxx chip series can be connected via SPI or via SDIO. - -SPI ---- - -You have to declare the WFxxx chip in your device tree. - -Required properties: - - compatible: Should be "silabs,wf200" - - reg: Chip select address of device - - spi-max-frequency: Maximum SPI clocking speed of device in Hz - - interrupts-extended: Should contain interrupt line (interrupt-parent + - interrupt can also been used). Trigger should be `IRQ_TYPE_EDGE_RISING`. - -Optional properties: - - reset-gpios: phandle of gpio that will be used to reset chip during probe. - Without this property, you may encounter issues with warm boot. - (Legacy: when compatible == "silabs,wfx-spi", the gpio is inverted.) - -Please consult Documentation/devicetree/bindings/spi/spi-bus.txt for optional -SPI connection related properties, - -Example: - -&spi1 { - wfx { - compatible = "silabs,wf200"; - pinctrl-names = "default"; - pinctrl-0 = <&wfx_irq &wfx_gpios>; - interrupts-extended = <&gpio 16 IRQ_TYPE_EDGE_RISING>; - wakeup-gpios = <&gpio 12 GPIO_ACTIVE_HIGH>; - reset-gpios = <&gpio 13 GPIO_ACTIVE_LOW>; - reg = <0>; - spi-max-frequency = <42000000>; - }; -}; - - -SDIO ----- - -The driver is able to detect a WFxxx chip on SDIO bus by matching its Vendor ID -and Product ID. However, driver will only provide limited features in this -case. Thus declaring WFxxx chip in device tree is strongly recommended (and may -become mandatory in the future). - -Required properties: - - compatible: Should be "silabs,wf200" - - reg: Should be 1 - -In addition, it is recommended to declare a mmc-pwrseq on SDIO host above WFx. -Without it, you may encounter issues with warm boot. mmc-pwrseq should be -compatible with mmc-pwrseq-simple. Please consult -Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt for more -information. - -Example: - -/ { - wfx_pwrseq: wfx_pwrseq { - compatible = "mmc-pwrseq-simple"; - pinctrl-names = "default"; - pinctrl-0 = <&wfx_reset>; - reset-gpios = <&gpio 13 GPIO_ACTIVE_LOW>; - }; -}; - -&mmc1 { - mmc-pwrseq = <&wfx_pwrseq>; - #address-size = <1>; - #size = <0>; - - mmc@1 { - compatible = "silabs,wf200"; - reg = <1>; - pinctrl-names = "default"; - pinctrl-0 = <&wfx_wakeup>; - wakeup-gpios = <&gpio 12 GPIO_ACTIVE_HIGH>; - }; -}; - -Note that #address-size and #size shoud already be defined in node mmc1, but it -is rarely the case. - -Common properties ------------------ - -Some properties are recognized either by SPI and SDIO versions: - - wakeup-gpios: phandle of gpio that will be used to wake-up chip. Without - this property, driver will disable most of power saving features. - - config-file: Use an alternative file as PDS. Default is `wf200.pds`. Only - necessary for development/debug purpose. - - slk_key: String representing hexadecimal value of secure link key to use. - Must contains 64 hexadecimal digits. Not supported in current version. - -WFx driver also supports `mac-address` and `local-mac-address` as described in -Documentation/devicetree/bindings/net/ethernet.txt - diff --git a/drivers/staging/wfx/TODO b/drivers/staging/wfx/TODO index 42bf36d43970..1b4bc2af94b6 100644 --- a/drivers/staging/wfx/TODO +++ b/drivers/staging/wfx/TODO @@ -1,25 +1,6 @@ This is a list of things that need to be done to get this driver out of the staging directory. - - The HIF API is not yet clean enough. - - - The code that check the corectness of received message (in rx_helper()) can - be improved. See: - https://lore.kernel.org/driverdev-devel/2302785.6C7ODC2LYm@pc-42/ - - As suggested by Felix, rate control could be improved following this idea: https://lore.kernel.org/lkml/3099559.gv3Q75KnN1@pc-42/ - - Feature called "secure link" should be either developed (using kernel - crypto API) or dropped. - - - The device allows to filter multicast traffic. The code to support these - filters exists in the driver but it is disabled because it has never been - tested. - - - In wfx_cmd_send(), "async" allow to send command without waiting the reply. - It may help in some situation, but it is not yet used. In add, it may cause - some trouble: - https://lore.kernel.org/driverdev-devel/alpine.DEB.2.21.1910041317381.2992@hadrien/ - So, fix it (by replacing the mutex with a semaphore) or drop it. - diff --git a/drivers/staging/wfx/bh.c b/drivers/staging/wfx/bh.c index 53ae0b5abcdd..2ffa587aefaa 100644 --- a/drivers/staging/wfx/bh.c +++ b/drivers/staging/wfx/bh.c @@ -2,7 +2,7 @@ /* * Interrupt bottom half (BH). * - * Copyright (c) 2017-2019, Silicon Laboratories, Inc. + * Copyright (c) 2017-2020, Silicon Laboratories, Inc. * Copyright (c) 2010, ST-Ericsson */ #include <linux/gpio/consumer.h> @@ -12,31 +12,45 @@ #include "wfx.h" #include "hwio.h" #include "traces.h" -#include "secure_link.h" #include "hif_rx.h" #include "hif_api_cmd.h" static void device_wakeup(struct wfx_dev *wdev) { + int max_retry = 3; + if (!wdev->pdata.gpio_wakeup) return; - if (gpiod_get_value_cansleep(wdev->pdata.gpio_wakeup)) + if (gpiod_get_value_cansleep(wdev->pdata.gpio_wakeup) >= 0) return; - gpiod_set_value_cansleep(wdev->pdata.gpio_wakeup, 1); if (wfx_api_older_than(wdev, 1, 4)) { + gpiod_set_value_cansleep(wdev->pdata.gpio_wakeup, 1); if (!completion_done(&wdev->hif.ctrl_ready)) usleep_range(2000, 2500); - } else { + return; + } + for (;;) { + gpiod_set_value_cansleep(wdev->pdata.gpio_wakeup, 1); // completion.h does not provide any function to wait // completion without consume it (a kind of // wait_for_completion_done_timeout()). So we have to emulate // it. if (wait_for_completion_timeout(&wdev->hif.ctrl_ready, - msecs_to_jiffies(2) + 1)) + msecs_to_jiffies(2))) { complete(&wdev->hif.ctrl_ready); - else + return; + } else if (max_retry-- > 0) { + // Older firmwares have a race in sleep/wake-up process. + // Redo the process is sufficient to unfreeze the + // chip. dev_err(wdev->dev, "timeout while wake up chip\n"); + gpiod_set_value_cansleep(wdev->pdata.gpio_wakeup, 0); + usleep_range(2000, 2500); + } else { + dev_err(wdev->dev, "max wake-up retries reached\n"); + return; + } } } @@ -73,20 +87,11 @@ static int rx_helper(struct wfx_dev *wdev, size_t read_len, int *is_cnf) _trace_piggyback(piggyback, false); hif = (struct hif_msg *)skb->data; - WARN(hif->encrypted & 0x1, "unsupported encryption type"); - if (hif->encrypted == 0x2) { - if (WARN(read_len < sizeof(struct hif_sl_msg), "corrupted read")) - goto err; - computed_len = le16_to_cpu(((struct hif_sl_msg *)hif)->len); - computed_len = round_up(computed_len - sizeof(u16), 16); - computed_len += sizeof(struct hif_sl_msg); - computed_len += sizeof(struct hif_sl_tag); - } else { - if (WARN(read_len < sizeof(struct hif_msg), "corrupted read")) - goto err; - computed_len = le16_to_cpu(hif->len); - computed_len = round_up(computed_len, 2); - } + WARN(hif->encrypted & 0x3, "encryption is unsupported"); + if (WARN(read_len < sizeof(struct hif_msg), "corrupted read")) + goto err; + computed_len = le16_to_cpu(hif->len); + computed_len = round_up(computed_len, 2); if (computed_len != read_len) { dev_err(wdev->dev, "inconsistent message length: %zu != %zu\n", computed_len, read_len); @@ -94,16 +99,6 @@ static int rx_helper(struct wfx_dev *wdev, size_t read_len, int *is_cnf) hif, read_len, true); goto err; } - if (hif->encrypted == 0x2) { - if (wfx_sl_decode(wdev, (struct hif_sl_msg *)hif)) { - dev_kfree_skb(skb); - // If frame was a confirmation, expect trouble in next - // exchange. However, it is harmless to fail to decode - // an indication frame, so try to continue. Anyway, - // piggyback is probably correct. - return piggyback; - } - } if (!(hif->id & HIF_ID_IS_INDICATION)) { (*is_cnf)++; @@ -184,23 +179,7 @@ static void tx_helper(struct wfx_dev *wdev, struct hif_msg *hif) hif->seqnum = wdev->hif.tx_seqnum; wdev->hif.tx_seqnum = (wdev->hif.tx_seqnum + 1) % (HIF_COUNTER_MAX + 1); - if (wfx_is_secure_command(wdev, hif->id)) { - len = round_up(len - sizeof(hif->len), 16) + sizeof(hif->len) + - sizeof(struct hif_sl_msg_hdr) + - sizeof(struct hif_sl_tag); - // AES support encryption in-place. However, mac80211 access to - // 802.11 header after frame was sent (to get MAC addresses). - // So, keep origin buffer clear. - data = kmalloc(len, GFP_KERNEL); - if (!data) - goto end; - is_encrypted = true; - ret = wfx_sl_encode(wdev, hif, data); - if (ret) - goto end; - } else { - data = hif; - } + data = hif; WARN(len > wdev->hw_caps.size_inp_ch_buf, "%s: request exceed WFx capability: %zu > %d\n", __func__, len, wdev->hw_caps.size_inp_ch_buf); diff --git a/drivers/staging/wfx/bh.h b/drivers/staging/wfx/bh.h index 4b73437869e1..78c49329e22a 100644 --- a/drivers/staging/wfx/bh.h +++ b/drivers/staging/wfx/bh.h @@ -2,7 +2,7 @@ /* * Interrupt bottom half. * - * Copyright (c) 2017-2019, Silicon Laboratories, Inc. + * Copyright (c) 2017-2020, Silicon Laboratories, Inc. * Copyright (c) 2010, ST-Ericsson */ #ifndef WFX_BH_H diff --git a/drivers/staging/wfx/bus.h b/drivers/staging/wfx/bus.h index 0370b6c59863..ca04b3da6204 100644 --- a/drivers/staging/wfx/bus.h +++ b/drivers/staging/wfx/bus.h @@ -2,7 +2,7 @@ /* * Common bus abstraction layer. * - * Copyright (c) 2017-2018, Silicon Laboratories, Inc. + * Copyright (c) 2017-2020, Silicon Laboratories, Inc. * Copyright (c) 2010, ST-Ericsson */ #ifndef WFX_BUS_H diff --git a/drivers/staging/wfx/bus_sdio.c b/drivers/staging/wfx/bus_sdio.c index 496bfc8bbacc..e06d7e1ebe9c 100644 --- a/drivers/staging/wfx/bus_sdio.c +++ b/drivers/staging/wfx/bus_sdio.c @@ -2,7 +2,7 @@ /* * SDIO interface. * - * Copyright (c) 2017-2019, Silicon Laboratories, Inc. + * Copyright (c) 2017-2020, Silicon Laboratories, Inc. * Copyright (c) 2010, ST-Ericsson */ #include <linux/module.h> diff --git a/drivers/staging/wfx/bus_spi.c b/drivers/staging/wfx/bus_spi.c index d19c0478e8be..a99125d1a30d 100644 --- a/drivers/staging/wfx/bus_spi.c +++ b/drivers/staging/wfx/bus_spi.c @@ -2,7 +2,7 @@ /* * SPI interface. * - * Copyright (c) 2017-2019, Silicon Laboratories, Inc. + * Copyright (c) 2017-2020, Silicon Laboratories, Inc. * Copyright (c) 2011, Sagrad Inc. * Copyright (c) 2010, ST-Ericsson */ diff --git a/drivers/staging/wfx/data_rx.c b/drivers/staging/wfx/data_rx.c index 6fb078880742..385f2d42a0e2 100644 --- a/drivers/staging/wfx/data_rx.c +++ b/drivers/staging/wfx/data_rx.c @@ -2,7 +2,7 @@ /* * Datapath implementation. * - * Copyright (c) 2017-2019, Silicon Laboratories, Inc. + * Copyright (c) 2017-2020, Silicon Laboratories, Inc. * Copyright (c) 2010, ST-Ericsson */ #include <linux/etherdevice.h> @@ -17,6 +17,9 @@ static void wfx_rx_handle_ba(struct wfx_vif *wvif, struct ieee80211_mgmt *mgmt) { int params, tid; + if (wfx_api_older_than(wvif->wdev, 3, 6)) + return; + switch (mgmt->u.action.u.addba_req.action_code) { case WLAN_ACTION_ADDBA_REQ: params = le16_to_cpu(mgmt->u.action.u.addba_req.capab); @@ -41,7 +44,7 @@ void wfx_rx_cb(struct wfx_vif *wvif, memset(hdr, 0, sizeof(*hdr)); if (arg->status == HIF_STATUS_RX_FAIL_MIC) - hdr->flag |= RX_FLAG_MMIC_ERROR; + hdr->flag |= RX_FLAG_MMIC_ERROR | RX_FLAG_IV_STRIPPED; else if (arg->status) goto drop; @@ -70,10 +73,10 @@ void wfx_rx_cb(struct wfx_vif *wvif, hdr->signal = arg->rcpi_rssi / 2 - 110; hdr->antenna = 0; - if (arg->rx_flags.encryp) + if (arg->encryp) hdr->flag |= RX_FLAG_DECRYPTED; - // Block ack negociation is offloaded by the firmware. However, + // Block ack negotiation is offloaded by the firmware. However, // re-ordering must be done by the mac80211. if (ieee80211_is_action(frame->frame_control) && mgmt->u.action.category == WLAN_CATEGORY_BACK && diff --git a/drivers/staging/wfx/data_rx.h b/drivers/staging/wfx/data_rx.h index 125dbfc1f875..4c0da37f2084 100644 --- a/drivers/staging/wfx/data_rx.h +++ b/drivers/staging/wfx/data_rx.h @@ -2,7 +2,7 @@ /* * Datapath implementation. * - * Copyright (c) 2017-2019, Silicon Laboratories, Inc. + * Copyright (c) 2017-2020, Silicon Laboratories, Inc. * Copyright (c) 2010, ST-Ericsson */ #ifndef WFX_DATA_RX_H diff --git a/drivers/staging/wfx/data_tx.c b/drivers/staging/wfx/data_tx.c index 3acf4eb0214d..41f6a604a697 100644 --- a/drivers/staging/wfx/data_tx.c +++ b/drivers/staging/wfx/data_tx.c @@ -2,7 +2,7 @@ /* * Datapath implementation. * - * Copyright (c) 2017-2019, Silicon Laboratories, Inc. + * Copyright (c) 2017-2020, Silicon Laboratories, Inc. * Copyright (c) 2010, ST-Ericsson */ #include <net/mac80211.h> @@ -31,6 +31,10 @@ static int wfx_get_hw_rate(struct wfx_dev *wdev, } return rate->idx + 14; } + if (rate->idx >= band->n_bitrates) { + WARN(1, "wrong rate->idx value: %d", rate->idx); + return -1; + } // WFx only support 2GHz, else band information should be retrieved // from ieee80211_tx_info band = wdev->hw->wiphy->bands[NL80211_BAND_2GHZ]; @@ -234,7 +238,7 @@ static void wfx_tx_fixup_rates(struct ieee80211_tx_rate *rates) int i; bool finished; - // Firmware is not able to mix rates with differents flags + // Firmware is not able to mix rates with different flags for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { if (rates[0].flags & IEEE80211_TX_RC_SHORT_GI) rates[i].flags |= IEEE80211_TX_RC_SHORT_GI; @@ -300,23 +304,14 @@ static u8 wfx_tx_get_rate_id(struct wfx_vif *wvif, return rate_id; } -static struct hif_ht_tx_parameters wfx_tx_get_tx_parms(struct wfx_dev *wdev, - struct ieee80211_tx_info *tx_info) +static int wfx_tx_get_frame_format(struct ieee80211_tx_info *tx_info) { - struct ieee80211_tx_rate *rate = &tx_info->driver_rates[0]; - struct hif_ht_tx_parameters ret = { }; - - if (!(rate->flags & IEEE80211_TX_RC_MCS)) - ret.frame_format = HIF_FRAME_FORMAT_NON_HT; - else if (!(rate->flags & IEEE80211_TX_RC_GREEN_FIELD)) - ret.frame_format = HIF_FRAME_FORMAT_MIXED_FORMAT_HT; + if (!(tx_info->driver_rates[0].flags & IEEE80211_TX_RC_MCS)) + return HIF_FRAME_FORMAT_NON_HT; + else if (!(tx_info->driver_rates[0].flags & IEEE80211_TX_RC_GREEN_FIELD)) + return HIF_FRAME_FORMAT_MIXED_FORMAT_HT; else - ret.frame_format = HIF_FRAME_FORMAT_GF_HT_11N; - if (rate->flags & IEEE80211_TX_RC_SHORT_GI) - ret.short_gi = 1; - if (tx_info->flags & IEEE80211_TX_CTL_STBC) - ret.stbc = 0; // FIXME: Not yet supported by firmware? - return ret; + return HIF_FRAME_FORMAT_GF_HT_11N; } static int wfx_tx_get_icv_len(struct ieee80211_key_conf *hw_key) @@ -325,6 +320,8 @@ static int wfx_tx_get_icv_len(struct ieee80211_key_conf *hw_key) if (!hw_key) return 0; + if (hw_key->cipher == WLAN_CIPHER_SUITE_AES_CMAC) + return 0; mic_space = (hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) ? 8 : 0; return hw_key->icv_len + mic_space; } @@ -334,7 +331,6 @@ static int wfx_tx_inner(struct wfx_vif *wvif, struct ieee80211_sta *sta, { struct hif_msg *hif_msg; struct hif_req_tx *req; - struct wfx_tx_priv *tx_priv; struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); struct ieee80211_key_conf *hw_key = tx_info->control.hw_key; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; @@ -348,15 +344,11 @@ static int wfx_tx_inner(struct wfx_vif *wvif, struct ieee80211_sta *sta, // From now tx_info->control is unusable memset(tx_info->rate_driver_data, 0, sizeof(struct wfx_tx_priv)); - // Fill tx_priv - tx_priv = (struct wfx_tx_priv *)tx_info->rate_driver_data; - if (ieee80211_has_protected(hdr->frame_control)) - tx_priv->hw_key = hw_key; // Fill hif_msg WARN(skb_headroom(skb) < wmsg_len, "not enough space in skb"); WARN(offset & 1, "attempt to transmit an unaligned frame"); - skb_put(skb, wfx_tx_get_icv_len(tx_priv->hw_key)); + skb_put(skb, wfx_tx_get_icv_len(hw_key)); skb_push(skb, wmsg_len); memset(skb->data, 0, wmsg_len); hif_msg = (struct hif_msg *)skb->data; @@ -380,14 +372,16 @@ static int wfx_tx_inner(struct wfx_vif *wvif, struct ieee80211_sta *sta, req->packet_id |= IEEE80211_SEQ_TO_SN(le16_to_cpu(hdr->seq_ctrl)) << 16; req->packet_id |= queue_id << 28; - req->data_flags.fc_offset = offset; + req->fc_offset = offset; if (tx_info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) - req->data_flags.after_dtim = 1; - req->queue_id.peer_sta_id = wfx_tx_get_link_id(wvif, sta, hdr); + req->after_dtim = 1; + req->peer_sta_id = wfx_tx_get_link_id(wvif, sta, hdr); // Queue index are inverted between firmware and Linux - req->queue_id.queue_id = 3 - queue_id; - req->ht_tx_parameters = wfx_tx_get_tx_parms(wvif->wdev, tx_info); - req->tx_flags.retry_policy_index = wfx_tx_get_rate_id(wvif, tx_info); + req->queue_id = 3 - queue_id; + req->retry_policy_index = wfx_tx_get_rate_id(wvif, tx_info); + req->frame_format = wfx_tx_get_frame_format(tx_info); + if (tx_info->driver_rates[0].flags & IEEE80211_TX_RC_SHORT_GI) + req->short_gi = 1; // Auxiliary operations wfx_tx_queues_put(wvif, skb); @@ -439,10 +433,13 @@ static void wfx_skb_dtor(struct wfx_vif *wvif, struct sk_buff *skb) struct hif_req_tx *req = (struct hif_req_tx *)hif->body; unsigned int offset = sizeof(struct hif_msg) + sizeof(struct hif_req_tx) + - req->data_flags.fc_offset; + req->fc_offset; - WARN_ON(!wvif); - wfx_tx_policy_put(wvif, req->tx_flags.retry_policy_index); + if (!wvif) { + pr_warn("%s: vif associated with the skb does not exist anymore\n", __func__); + return; + } + wfx_tx_policy_put(wvif, req->retry_policy_index); skb_pull(skb, offset); ieee80211_tx_status_irqsafe(wvif->wdev->hw, skb); } @@ -488,7 +485,6 @@ static void wfx_tx_fill_rates(struct wfx_dev *wdev, void wfx_tx_confirm_cb(struct wfx_dev *wdev, const struct hif_cnf_tx *arg) { struct ieee80211_tx_info *tx_info; - const struct wfx_tx_priv *tx_priv; struct wfx_vif *wvif; struct sk_buff *skb; @@ -498,18 +494,15 @@ void wfx_tx_confirm_cb(struct wfx_dev *wdev, const struct hif_cnf_tx *arg) arg->packet_id); return; } + tx_info = IEEE80211_SKB_CB(skb); wvif = wdev_to_wvif(wdev, ((struct hif_msg *)skb->data)->interface); WARN_ON(!wvif); if (!wvif) return; - tx_info = IEEE80211_SKB_CB(skb); - tx_priv = wfx_skb_tx_priv(skb); - _trace_tx_stats(arg, skb, wfx_pending_get_pkt_us_delay(wdev, skb)); - // You can touch to tx_priv, but don't touch to tx_info->status. + // Note that wfx_pending_get_pkt_us_delay() get data from tx_info + _trace_tx_stats(arg, skb, wfx_pending_get_pkt_us_delay(wdev, skb)); wfx_tx_fill_rates(wdev, tx_info, arg); - skb_trim(skb, skb->len - wfx_tx_get_icv_len(tx_priv->hw_key)); - // From now, you can touch to tx_info->status, but do not touch to // tx_priv anymore // FIXME: use ieee80211_tx_info_clear_status() @@ -525,8 +518,7 @@ void wfx_tx_confirm_cb(struct wfx_dev *wdev, const struct hif_cnf_tx *arg) else tx_info->flags |= IEEE80211_TX_STAT_ACK; } else if (arg->status == HIF_STATUS_TX_FAIL_REQUEUE) { - WARN(!arg->tx_result_flags.requeue, - "incoherent status and result_flags"); + WARN(!arg->requeue, "incoherent status and result_flags"); if (tx_info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) { wvif->after_dtim_tx_allowed = false; // DTIM period elapsed schedule_work(&wvif->update_tim_work); diff --git a/drivers/staging/wfx/data_tx.h b/drivers/staging/wfx/data_tx.h index cff7b9ff99a9..46c9fff7a870 100644 --- a/drivers/staging/wfx/data_tx.h +++ b/drivers/staging/wfx/data_tx.h @@ -2,7 +2,7 @@ /* * Datapath implementation. * - * Copyright (c) 2017-2019, Silicon Laboratories, Inc. + * Copyright (c) 2017-2020, Silicon Laboratories, Inc. * Copyright (c) 2010, ST-Ericsson */ #ifndef WFX_DATA_TX_H @@ -35,8 +35,7 @@ struct tx_policy_cache { struct wfx_tx_priv { ktime_t xmit_timestamp; - struct ieee80211_key_conf *hw_key; -} __packed; +}; void wfx_tx_policy_init(struct wfx_vif *wvif); void wfx_tx_policy_upload_work(struct work_struct *work); diff --git a/drivers/staging/wfx/debug.c b/drivers/staging/wfx/debug.c index 3f1712b7c919..eedada78c25f 100644 --- a/drivers/staging/wfx/debug.c +++ b/drivers/staging/wfx/debug.c @@ -2,7 +2,7 @@ /* * Debugfs interface. * - * Copyright (c) 2017-2019, Silicon Laboratories, Inc. + * Copyright (c) 2017-2020, Silicon Laboratories, Inc. * Copyright (c) 2010, ST-Ericsson */ #include <linux/debugfs.h> @@ -32,7 +32,7 @@ static const struct trace_print_flags wfx_reg_print_map[] = { }; static const char *get_symbol(unsigned long val, - const struct trace_print_flags *symbol_array) + const struct trace_print_flags *symbol_array) { int i; @@ -230,21 +230,6 @@ static const struct file_operations wfx_send_pds_fops = { .write = wfx_send_pds_write, }; -static ssize_t wfx_burn_slk_key_write(struct file *file, - const char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct wfx_dev *wdev = file->private_data; - - dev_info(wdev->dev, "this driver does not support secure link\n"); - return -EINVAL; -} - -static const struct file_operations wfx_burn_slk_key_fops = { - .open = simple_open, - .write = wfx_burn_slk_key_write, -}; - struct dbgfs_hif_msg { struct wfx_dev *wdev; struct completion complete; @@ -267,7 +252,7 @@ static ssize_t wfx_send_hif_msg_write(struct file *file, if (count < sizeof(struct hif_msg)) return -EINVAL; - // wfx_cmd_send() chekc that reply buffer is wide enough, but do not + // wfx_cmd_send() checks that reply buffer is wide enough, but does not // return precise length read. User have to know how many bytes should // be read. Filling reply buffer with a memory pattern may help user. memset(context->reply, 0xFF, sizeof(context->reply)); @@ -299,8 +284,8 @@ static ssize_t wfx_send_hif_msg_read(struct file *file, char __user *user_buf, return ret; if (context->ret < 0) return context->ret; - // Be carefull, write() is waiting for a full message while read() - // only return a payload + // Be careful, write() is waiting for a full message while read() + // only returns a payload if (copy_to_user(user_buf, context->reply, count)) return -EFAULT; @@ -366,8 +351,6 @@ int wfx_debug_init(struct wfx_dev *wdev) debugfs_create_file("tx_power_loop", 0444, d, wdev, &wfx_tx_power_loop_fops); debugfs_create_file("send_pds", 0200, d, wdev, &wfx_send_pds_fops); - debugfs_create_file("burn_slk_key", 0200, d, wdev, - &wfx_burn_slk_key_fops); debugfs_create_file("send_hif_msg", 0600, d, wdev, &wfx_send_hif_msg_fops); debugfs_create_file("ps_timeout", 0600, d, wdev, &wfx_ps_timeout_fops); diff --git a/drivers/staging/wfx/fwio.c b/drivers/staging/wfx/fwio.c index 22d3b684f04f..1b8aec02d169 100644 --- a/drivers/staging/wfx/fwio.c +++ b/drivers/staging/wfx/fwio.c @@ -2,7 +2,7 @@ /* * Firmware loading. * - * Copyright (c) 2017-2019, Silicon Laboratories, Inc. + * Copyright (c) 2017-2020, Silicon Laboratories, Inc. * Copyright (c) 2010, ST-Ericsson */ #include <linux/firmware.h> @@ -94,7 +94,7 @@ static int sram_write_dma_safe(struct wfx_dev *wdev, u32 addr, const u8 *buf, tmp = buf; } ret = sram_buf_write(wdev, addr, tmp, len); - if (!virt_addr_valid(buf)) + if (tmp != buf) kfree(tmp); return ret; } diff --git a/drivers/staging/wfx/hif_api_cmd.h b/drivers/staging/wfx/hif_api_cmd.h index 21cde19cff75..11bc1a58edae 100644 --- a/drivers/staging/wfx/hif_api_cmd.h +++ b/drivers/staging/wfx/hif_api_cmd.h @@ -2,15 +2,15 @@ /* * WFx hardware interface definitions * - * Copyright (c) 2018-2019, Silicon Laboratories Inc. + * Copyright (c) 2018-2020, Silicon Laboratories Inc. */ #ifndef WFX_HIF_API_CMD_H #define WFX_HIF_API_CMD_H -#include "hif_api_general.h" +#include <linux/ieee80211.h> -#define HIF_API_SSID_SIZE API_SSID_SIZE +#include "hif_api_general.h" enum hif_requests_ids { HIF_REQ_ID_RESET = 0x0a, @@ -60,21 +60,15 @@ enum hif_indications_ids { HIF_IND_ID_EVENT = 0x85 }; -union hif_commands_ids { - enum hif_requests_ids request; - enum hif_confirmations_ids confirmation; - enum hif_indications_ids indication; -}; - -struct hif_reset_flags { +struct hif_req_reset { u8 reset_stat:1; u8 reset_all_int:1; u8 reserved1:6; u8 reserved2[3]; } __packed; -struct hif_req_reset { - struct hif_reset_flags reset_flags; +struct hif_cnf_reset { + __le32 status; } __packed; struct hif_req_read_mib { @@ -99,52 +93,23 @@ struct hif_cnf_write_mib { __le32 status; } __packed; -struct hif_ie_flags { +struct hif_req_update_ie { u8 beacon:1; u8 probe_resp:1; u8 probe_req:1; u8 reserved1:5; u8 reserved2; -} __packed; - -struct hif_ie_tlv { - u8 type; - u8 length; - u8 data[]; -} __packed; - -struct hif_req_update_ie { - struct hif_ie_flags ie_flags; __le16 num_ies; - struct hif_ie_tlv ie[]; + struct element ie[]; } __packed; struct hif_cnf_update_ie { __le32 status; } __packed; -struct hif_scan_type { - u8 type:1; - u8 mode:1; - u8 reserved:6; -} __packed; - -struct hif_scan_flags { - u8 fbg:1; - u8 reserved1:1; - u8 pre:1; - u8 reserved2:5; -} __packed; - -struct hif_auto_scan_param { - __le16 interval; - u8 reserved; - s8 rssi_thr; -} __packed; - struct hif_ssid_def { __le32 ssid_length; - u8 ssid[HIF_API_SSID_SIZE]; + u8 ssid[IEEE80211_MAX_SSID_LEN]; } __packed; #define HIF_API_MAX_NB_SSIDS 2 @@ -152,10 +117,17 @@ struct hif_ssid_def { struct hif_req_start_scan_alt { u8 band; - struct hif_scan_type scan_type; - struct hif_scan_flags scan_flags; + u8 maintain_current_bss:1; + u8 periodic:1; + u8 reserved1:6; + u8 disallow_ps:1; + u8 reserved2:1; + u8 short_preamble:1; + u8 reserved3:5; u8 max_transmit_rate; - struct hif_auto_scan_param auto_scan_param; + __le16 periodic_interval; + u8 reserved4; + s8 periodic_rssi_thr; u8 num_of_probe_requests; u8 probe_delay; u8 num_of_ssids; @@ -201,53 +173,32 @@ enum hif_frame_format { HIF_FRAME_FORMAT_GF_HT_11N = 0x2 }; -enum hif_stbc { - HIF_STBC_NOT_ALLOWED = 0x0, - HIF_STBC_ALLOWED = 0x1 -}; - -struct hif_queue { +struct hif_req_tx { + // packet_id is not interpreted by the device, so it is not necessary to + // declare it little endian + u32 packet_id; + u8 max_tx_rate; u8 queue_id:2; u8 peer_sta_id:4; - u8 reserved:2; -} __packed; - -struct hif_data_flags { + u8 reserved1:2; u8 more:1; u8 fc_offset:3; u8 after_dtim:1; - u8 reserved:3; -} __packed; - -struct hif_tx_flags { + u8 reserved2:3; u8 start_exp:1; - u8 reserved:3; + u8 reserved3:3; u8 retry_policy_index:4; -} __packed; - -struct hif_ht_tx_parameters { + __le32 reserved4; + __le32 expire_time; u8 frame_format:4; u8 fec_coding:1; u8 short_gi:1; - u8 reserved1:1; + u8 reserved5:1; u8 stbc:1; - u8 reserved2; + u8 reserved6; u8 aggregation:1; - u8 reserved3:7; - u8 reserved4; -} __packed; - -struct hif_req_tx { - // packet_id is not interpreted by the device, so it is not necessary to - // declare it little endian - u32 packet_id; - u8 max_tx_rate; - struct hif_queue queue_id; - struct hif_data_flags data_flags; - struct hif_tx_flags tx_flags; - __le32 reserved; - __le32 expire_time; - struct hif_ht_tx_parameters ht_tx_parameters; + u8 reserved7:7; + u8 reserved8; u8 frame[]; } __packed; @@ -258,15 +209,6 @@ enum hif_qos_ackplcy { HIF_QOS_ACKPLCY_BLCKACK = 0x3 }; -struct hif_tx_result_flags { - u8 aggr:1; - u8 requeue:1; - u8 ack_policy:2; - u8 txop_limit:1; - u8 reserved1:3; - u8 reserved2; -} __packed; - struct hif_cnf_tx { __le32 status; // packet_id is copied from struct hif_req_tx without been interpreted @@ -274,7 +216,12 @@ struct hif_cnf_tx { u32 packet_id; u8 txed_rate; u8 ack_failures; - struct hif_tx_result_flags tx_result_flags; + u8 aggr:1; + u8 requeue:1; + u8 ack_policy:2; + u8 txop_limit:1; + u8 reserved1:3; + u8 reserved2; __le32 media_delay; __le32 tx_queue_delay; } __packed; @@ -282,7 +229,7 @@ struct hif_cnf_tx { struct hif_cnf_multi_transmit { u8 num_tx_confs; u8 reserved[3]; - struct hif_cnf_tx tx_conf_payload[]; + struct hif_cnf_tx tx_conf_payload[]; } __packed; enum hif_ri_flags_encrypt { @@ -293,7 +240,12 @@ enum hif_ri_flags_encrypt { HIF_RI_FLAGS_WAPI_ENCRYPTED = 0x4 }; -struct hif_rx_flags { +struct hif_ind_rx { + __le32 status; + u8 channel_number; + u8 reserved1; + u8 rxed_rate; + u8 rcpi_rssi; u8 encryp:3; u8 in_aggr:1; u8 first_aggr:1; @@ -305,7 +257,7 @@ struct hif_rx_flags { u8 match_ssid:1; u8 match_bssid:1; u8 more:1; - u8 reserved1:1; + u8 reserved2:1; u8 ht:1; u8 stbc:1; u8 match_uc_addr:1; @@ -313,23 +265,13 @@ struct hif_rx_flags { u8 match_bc_addr:1; u8 key_type:1; u8 key_index:4; - u8 reserved2:1; + u8 reserved3:1; u8 peer_sta_id:4; - u8 reserved3:2; - u8 reserved4:1; -} __packed; - -struct hif_ind_rx { - __le32 status; - u8 channel_number; - u8 reserved; - u8 rxed_rate; - u8 rcpi_rssi; - struct hif_rx_flags rx_flags; + u8 reserved4:2; + u8 reserved5:1; u8 frame[]; } __packed; - struct hif_req_edca_queue_params { u8 queue_id; u8 reserved1; @@ -346,28 +288,24 @@ struct hif_cnf_edca_queue_params { __le32 status; } __packed; -struct hif_join_flags { - u8 reserved1:2; - u8 force_no_beacon:1; - u8 force_with_ind:1; - u8 reserved2:4; -} __packed; - struct hif_req_join { u8 infrastructure_bss_mode:1; u8 reserved1:7; u8 band; u8 channel_number; - u8 reserved; + u8 reserved2; u8 bssid[ETH_ALEN]; __le16 atim_window; u8 short_preamble:1; - u8 reserved2:7; + u8 reserved3:7; u8 probe_for_join; - u8 reserved3; - struct hif_join_flags join_flags; + u8 reserved4; + u8 reserved5:2; + u8 force_no_beacon:1; + u8 force_with_ind:1; + u8 reserved6:4; __le32 ssid_length; - u8 ssid[HIF_API_SSID_SIZE]; + u8 ssid[IEEE80211_MAX_SSID_LEN]; __le32 beacon_interval; __le32 basic_rate_set; } __packed; @@ -380,13 +318,9 @@ struct hif_ind_join_complete { __le32 status; } __packed; -struct hif_bss_flags { +struct hif_req_set_bss_params { u8 lost_count_only:1; u8 reserved:7; -} __packed; - -struct hif_req_set_bss_params { - struct hif_bss_flags bss_flags; u8 beacon_lost_count; __le16 aid; __le32 operational_rate_set; @@ -396,14 +330,10 @@ struct hif_cnf_set_bss_params { __le32 status; } __packed; -struct hif_pm_mode { +struct hif_req_set_pm_mode { u8 enter_psm:1; u8 reserved:6; u8 fast_psm:1; -} __packed; - -struct hif_req_set_pm_mode { - struct hif_pm_mode pm_mode; u8 fast_psm_idle_period; u8 ap_psm_change_period; u8 min_auto_ps_poll_period; @@ -419,7 +349,6 @@ struct hif_ind_set_pm_mode_cmpl { u8 reserved[3]; } __packed; - struct hif_req_start { u8 mode; u8 band; @@ -432,7 +361,7 @@ struct hif_req_start { u8 reserved3:7; u8 reserved4; u8 ssid_length; - u8 ssid[HIF_API_SSID_SIZE]; + u8 ssid[IEEE80211_MAX_SSID_LEN]; __le32 basic_rate_set; } __packed; @@ -440,11 +369,6 @@ struct hif_cnf_start { __le32 status; } __packed; -enum hif_beacon { - HIF_BEACON_STOP = 0x0, - HIF_BEACON_START = 0x1 -}; - struct hif_req_beacon_transmit { u8 enable_beaconing; u8 reserved[3]; @@ -457,20 +381,11 @@ struct hif_cnf_beacon_transmit { #define HIF_LINK_ID_MAX 14 #define HIF_LINK_ID_NOT_ASSOCIATED (HIF_LINK_ID_MAX + 1) -enum hif_sta_map_direction { - HIF_STA_MAP = 0x0, - HIF_STA_UNMAP = 0x1 -}; - -struct hif_map_link_flags { - u8 map_direction:1; - u8 mfpc:1; - u8 reserved:6; -} __packed; - struct hif_req_map_link { u8 mac_addr[ETH_ALEN]; - struct hif_map_link_flags map_link_flags; + u8 unmap:1; + u8 mfpc:1; + u8 reserved:6; u8 peer_sta_id; } __packed; @@ -478,16 +393,12 @@ struct hif_cnf_map_link { __le32 status; } __packed; -struct hif_suspend_resume_flags { +struct hif_ind_suspend_resume_tx { u8 resume:1; u8 reserved1:2; u8 bc_mc_only:1; u8 reserved2:4; u8 reserved3; -} __packed; - -struct hif_ind_suspend_resume_tx { - struct hif_suspend_resume_flags suspend_resume_flags; __le16 peer_sta_set; } __packed; @@ -582,25 +493,23 @@ struct hif_igtk_group_key { u8 ipn[HIF_API_IPN_SIZE]; } __packed; -union hif_privacy_key_data { - struct hif_wep_pairwise_key wep_pairwise_key; - struct hif_wep_group_key wep_group_key; - struct hif_tkip_pairwise_key tkip_pairwise_key; - struct hif_tkip_group_key tkip_group_key; - struct hif_aes_pairwise_key aes_pairwise_key; - struct hif_aes_group_key aes_group_key; - struct hif_wapi_pairwise_key wapi_pairwise_key; - struct hif_wapi_group_key wapi_group_key; - struct hif_igtk_group_key igtk_group_key; -}; - struct hif_req_add_key { u8 type; u8 entry_index; u8 int_id:2; u8 reserved1:6; u8 reserved2; - union hif_privacy_key_data key; + union { + struct hif_wep_pairwise_key wep_pairwise_key; + struct hif_wep_group_key wep_group_key; + struct hif_tkip_pairwise_key tkip_pairwise_key; + struct hif_tkip_group_key tkip_group_key; + struct hif_aes_pairwise_key aes_pairwise_key; + struct hif_aes_group_key aes_group_key; + struct hif_wapi_pairwise_key wapi_pairwise_key; + struct hif_wapi_group_key wapi_group_key; + struct hif_igtk_group_key igtk_group_key; + } key; } __packed; struct hif_cnf_add_key { @@ -632,16 +541,13 @@ enum hif_ps_mode_error { HIF_PS_ERROR_AP_NO_DATA_AFTER_TIM = 4 }; -union hif_event_data { - u8 rcpi_rssi; - __le32 ps_mode_error; - __le32 peer_sta_set; -}; - struct hif_ind_event { __le32 event_id; - union hif_event_data event_data; + union { + u8 rcpi_rssi; + __le32 ps_mode_error; + __le32 peer_sta_set; + } event_data; } __packed; - #endif diff --git a/drivers/staging/wfx/hif_api_general.h b/drivers/staging/wfx/hif_api_general.h index dba18a7ae919..24188945718d 100644 --- a/drivers/staging/wfx/hif_api_general.h +++ b/drivers/staging/wfx/hif_api_general.h @@ -2,7 +2,7 @@ /* * WFx hardware interface definitions * - * Copyright (c) 2018-2019, Silicon Laboratories Inc. + * Copyright (c) 2018-2020, Silicon Laboratories Inc. */ #ifndef WFX_HIF_API_GENERAL_H @@ -17,8 +17,6 @@ #define __packed __attribute__((__packed__)) #endif -#define API_SSID_SIZE 32 - #define HIF_ID_IS_INDICATION 0x80 #define HIF_COUNTER_MAX 7 @@ -115,32 +113,12 @@ enum hif_api_rate_index { API_RATE_NUM_ENTRIES = 22 }; - enum hif_fw_type { HIF_FW_TYPE_ETF = 0x0, HIF_FW_TYPE_WFM = 0x1, HIF_FW_TYPE_WSM = 0x2 }; -struct hif_capabilities { - u8 link_mode:2; - u8 reserved1:6; - u8 reserved2; - u8 reserved3; - u8 reserved4; -} __packed; - -struct hif_otp_regul_sel_mode_info { - u8 region_sel_mode:4; - u8 reserved:4; -} __packed; - -struct hif_otp_phy_info { - u8 phy1_region:3; - u8 phy0_region:3; - u8 otp_phy_ver:2; -} __packed; - struct hif_ind_startup { // As the others, this struct is interpreted as little endian by the // device. However, this struct is also used by the driver. We prefer to @@ -156,14 +134,21 @@ struct hif_ind_startup { u8 mac_addr[2][ETH_ALEN]; u8 api_version_minor; u8 api_version_major; - struct hif_capabilities capabilities; + u8 link_mode:2; + u8 reserved1:6; + u8 reserved2; + u8 reserved3; + u8 reserved4; u8 firmware_build; u8 firmware_minor; u8 firmware_major; u8 firmware_type; u8 disabled_channel_list[2]; - struct hif_otp_regul_sel_mode_info regul_sel_mode_info; - struct hif_otp_phy_info otp_phy_info; + u8 region_sel_mode:4; + u8 reserved5:4; + u8 phy1_region:3; + u8 phy0_region:3; + u8 otp_phy_ver:2; u32 supported_rate_mask; u8 firmware_label[128]; } __packed; @@ -233,15 +218,12 @@ struct hif_tx_power_loop_info { u8 reserved; } __packed; -union hif_indication_data { - struct hif_rx_stats rx_stats; - struct hif_tx_power_loop_info tx_power_loop_info; - u8 raw_data[1]; -}; - struct hif_ind_generic { - __le32 indication_type; - union hif_indication_data indication_data; + __le32 type; + union { + struct hif_rx_stats rx_stats; + struct hif_tx_power_loop_info tx_power_loop_info; + } data; } __packed; enum hif_error { @@ -262,6 +244,7 @@ enum hif_error { HIF_ERROR_HIF_TX_QUEUE_FULL = 0x0d, HIF_ERROR_HIF_BUS = 0x0f, HIF_ERROR_PDS_TESTFEATURE = 0x10, + HIF_ERROR_SLK_UNCONFIGURED = 0x11, }; struct hif_ind_error { @@ -281,84 +264,4 @@ enum hif_secure_link_state { SEC_LINK_ENFORCED = 0x3 }; -enum hif_sl_encryption_type { - NO_ENCRYPTION = 0, - TX_ENCRYPTION = 1, - RX_ENCRYPTION = 2, - HP_ENCRYPTION = 3 -}; - -struct hif_sl_msg_hdr { - u32 seqnum:30; - u32 encrypted:2; -} __packed; - -struct hif_sl_msg { - struct hif_sl_msg_hdr hdr; - __le16 len; - u8 payload[]; -} __packed; - -#define AES_CCM_TAG_SIZE 16 - -struct hif_sl_tag { - u8 tag[16]; -} __packed; - -enum hif_sl_mac_key_dest { - SL_MAC_KEY_DEST_OTP = 0x78, - SL_MAC_KEY_DEST_RAM = 0x87 -}; - -#define API_KEY_VALUE_SIZE 32 - -struct hif_req_set_sl_mac_key { - u8 otp_or_ram; - u8 key_value[API_KEY_VALUE_SIZE]; -} __packed; - -struct hif_cnf_set_sl_mac_key { - __le32 status; -} __packed; - -enum hif_sl_session_key_alg { - HIF_SL_CURVE25519 = 0x01, - HIF_SL_KDF = 0x02 -}; - -#define API_HOST_PUB_KEY_SIZE 32 -#define API_HOST_PUB_KEY_MAC_SIZE 64 - -struct hif_req_sl_exchange_pub_keys { - u8 algorithm:2; - u8 reserved1:6; - u8 reserved2[3]; - u8 host_pub_key[API_HOST_PUB_KEY_SIZE]; - u8 host_pub_key_mac[API_HOST_PUB_KEY_MAC_SIZE]; -} __packed; - -struct hif_cnf_sl_exchange_pub_keys { - __le32 status; -} __packed; - -#define API_NCP_PUB_KEY_SIZE 32 -#define API_NCP_PUB_KEY_MAC_SIZE 64 - -struct hif_ind_sl_exchange_pub_keys { - __le32 status; - u8 ncp_pub_key[API_NCP_PUB_KEY_SIZE]; - u8 ncp_pub_key_mac[API_NCP_PUB_KEY_MAC_SIZE]; -} __packed; - -struct hif_req_sl_configure { - u8 encr_bmp[32]; - u8 disable_session_key_protection:1; - u8 reserved1:7; - u8 reserved2[3]; -} __packed; - -struct hif_cnf_sl_configure { - __le32 status; -} __packed; - #endif diff --git a/drivers/staging/wfx/hif_api_mib.h b/drivers/staging/wfx/hif_api_mib.h index 6f1434795fa8..ace924720ce6 100644 --- a/drivers/staging/wfx/hif_api_mib.h +++ b/drivers/staging/wfx/hif_api_mib.h @@ -2,7 +2,7 @@ /* * WFx hardware interface definitions * - * Copyright (c) 2018-2019, Silicon Laboratories Inc. + * Copyright (c) 2018-2020, Silicon Laboratories Inc. */ #ifndef WFX_HIF_API_MIB_H @@ -82,50 +82,6 @@ struct hif_mib_gl_set_multi_msg { u8 reserved2[3]; } __packed; -enum hif_mac_addr_type { - HIF_MAC_ADDR_A1 = 0x0, - HIF_MAC_ADDR_A2 = 0x1, - HIF_MAC_ADDR_A3 = 0x2 -}; - -struct hif_mib_mac_addr_data_frame_condition { - u8 condition_idx; - u8 address_type; - u8 mac_address[ETH_ALEN]; -} __packed; - -#define HIF_FILTER_UNICAST 0x1 -#define HIF_FILTER_MULTICAST 0x2 -#define HIF_FILTER_BROADCAST 0x4 - -struct hif_mib_uc_mc_bc_data_frame_condition { - u8 condition_idx; - u8 allowed_frames; - u8 reserved[2]; -} __packed; - -struct hif_mib_config_data_filter { - u8 filter_idx; - u8 enable; - u8 reserved1[2]; - u8 eth_type_cond; - u8 port_cond; - u8 magic_cond; - u8 mac_cond; - u8 ipv4_cond; - u8 ipv6_cond; - u8 uc_mc_bc_cond; - u8 reserved2; -} __packed; - -struct hif_mib_set_data_filtering { - u8 invert_matching:1; - u8 reserved1:7; - u8 enable:1; - u8 reserved2:7; - u8 reserved3[2]; -} __packed; - enum hif_arp_ns_frame_treatment { HIF_ARP_NS_FILTERING_DISABLE = 0x0, HIF_ARP_NS_FILTERING_ENABLE = 0x1, @@ -349,7 +305,7 @@ struct hif_mib_set_uapsd_information { __le16 auto_trigger_step; } __packed; -struct hif_mib_tx_rate_retry_policy { +struct hif_tx_rate_retry_policy { u8 policy_index; u8 short_retry_count; u8 long_retry_count; @@ -368,7 +324,7 @@ struct hif_mib_tx_rate_retry_policy { struct hif_mib_set_tx_rate_retry_policy { u8 num_tx_rate_policies; u8 reserved[3]; - struct hif_mib_tx_rate_retry_policy tx_rate_retry_policy[]; + struct hif_tx_rate_retry_policy tx_rate_retry_policy[]; } __packed; struct hif_mib_protected_mgmt_policy { diff --git a/drivers/staging/wfx/hif_rx.c b/drivers/staging/wfx/hif_rx.c index cc7c0cf226ba..56a5f891447b 100644 --- a/drivers/staging/wfx/hif_rx.c +++ b/drivers/staging/wfx/hif_rx.c @@ -3,7 +3,7 @@ * Implementation of chip-to-host event (aka indications) of WFxxx Split Mac * (WSM) API. * - * Copyright (c) 2017-2019, Silicon Laboratories, Inc. + * Copyright (c) 2017-2020, Silicon Laboratories, Inc. * Copyright (c) 2010, ST-Ericsson */ #include <linux/skbuff.h> @@ -15,7 +15,6 @@ #include "bh.h" #include "sta.h" #include "data_rx.h" -#include "secure_link.h" #include "hif_api_cmd.h" static int hif_generic_confirm(struct wfx_dev *wdev, @@ -41,21 +40,14 @@ static int hif_generic_confirm(struct wfx_dev *wdev, } if (wdev->hif_cmd.buf_recv) { - if (wdev->hif_cmd.len_recv >= len) + if (wdev->hif_cmd.len_recv >= len && len > 0) memcpy(wdev->hif_cmd.buf_recv, buf, len); else - status = -ENOMEM; + status = -EIO; } wdev->hif_cmd.ret = status; - if (!wdev->hif_cmd.async) { - complete(&wdev->hif_cmd.done); - } else { - wdev->hif_cmd.buf_send = NULL; - mutex_unlock(&wdev->hif_cmd.lock); - if (cmd != HIF_REQ_ID_SL_EXCHANGE_PUB_KEYS) - mutex_unlock(&wdev->hif_cmd.key_renew_lock); - } + complete(&wdev->hif_cmd.done); return status; } @@ -102,29 +94,14 @@ static int hif_startup_indication(struct wfx_dev *wdev, static int hif_wakeup_indication(struct wfx_dev *wdev, const struct hif_msg *hif, const void *buf) { - if (!wdev->pdata.gpio_wakeup - || !gpiod_get_value(wdev->pdata.gpio_wakeup)) { + if (!wdev->pdata.gpio_wakeup || + gpiod_get_value(wdev->pdata.gpio_wakeup) == 0) { dev_warn(wdev->dev, "unexpected wake-up indication\n"); return -EIO; } return 0; } -static int hif_keys_indication(struct wfx_dev *wdev, - const struct hif_msg *hif, const void *buf) -{ - const struct hif_ind_sl_exchange_pub_keys *body = buf; - u8 pubkey[API_NCP_PUB_KEY_SIZE]; - - // SL_PUB_KEY_EXCHANGE_STATUS_SUCCESS is used by legacy secure link - if (body->status && body->status != HIF_STATUS_SLK_NEGO_SUCCESS) - dev_warn(wdev->dev, "secure link negociation error\n"); - memcpy(pubkey, body->ncp_pub_key, sizeof(pubkey)); - memreverse(pubkey, sizeof(pubkey)); - wfx_sl_check_pubkey(wdev, pubkey, body->ncp_pub_key_mac); - return 0; -} - static int hif_receive_indication(struct wfx_dev *wdev, const struct hif_msg *hif, const void *buf, struct sk_buff *skb) @@ -133,9 +110,9 @@ static int hif_receive_indication(struct wfx_dev *wdev, const struct hif_ind_rx *body = buf; if (!wvif) { - dev_warn(wdev->dev, "ignore rx data for non-existent vif %d\n", - hif->interface); - return 0; + dev_warn(wdev->dev, "%s: ignore rx data for non-existent vif %d\n", + __func__, hif->interface); + return -EIO; } skb_pull(skb, sizeof(struct hif_msg) + sizeof(struct hif_ind_rx)); wfx_rx_cb(wvif, body, skb); @@ -151,8 +128,8 @@ static int hif_event_indication(struct wfx_dev *wdev, int type = le32_to_cpu(body->event_id); if (!wvif) { - dev_warn(wdev->dev, "received event for non-existent vif\n"); - return 0; + dev_warn(wdev->dev, "%s: received event for non-existent vif\n", __func__); + return -EIO; } switch (type) { @@ -184,7 +161,10 @@ static int hif_pm_mode_complete_indication(struct wfx_dev *wdev, { struct wfx_vif *wvif = wdev_to_wvif(wdev, hif->interface); - WARN_ON(!wvif); + if (!wvif) { + dev_warn(wdev->dev, "%s: received event for non-existent vif\n", __func__); + return -EIO; + } complete(&wvif->set_pm_mode_complete); return 0; @@ -196,7 +176,11 @@ static int hif_scan_complete_indication(struct wfx_dev *wdev, { struct wfx_vif *wvif = wdev_to_wvif(wdev, hif->interface); - WARN_ON(!wvif); + if (!wvif) { + dev_warn(wdev->dev, "%s: received event for non-existent vif\n", __func__); + return -EIO; + } + wfx_scan_complete(wvif); return 0; @@ -208,7 +192,10 @@ static int hif_join_complete_indication(struct wfx_dev *wdev, { struct wfx_vif *wvif = wdev_to_wvif(wdev, hif->interface); - WARN_ON(!wvif); + if (!wvif) { + dev_warn(wdev->dev, "%s: received event for non-existent vif\n", __func__); + return -EIO; + } dev_warn(wdev->dev, "unattended JoinCompleteInd\n"); return 0; @@ -218,19 +205,23 @@ static int hif_suspend_resume_indication(struct wfx_dev *wdev, const struct hif_msg *hif, const void *buf) { - struct wfx_vif *wvif = wdev_to_wvif(wdev, hif->interface); const struct hif_ind_suspend_resume_tx *body = buf; + struct wfx_vif *wvif; - if (body->suspend_resume_flags.bc_mc_only) { - WARN_ON(!wvif); - if (body->suspend_resume_flags.resume) + if (body->bc_mc_only) { + wvif = wdev_to_wvif(wdev, hif->interface); + if (!wvif) { + dev_warn(wdev->dev, "%s: received event for non-existent vif\n", __func__); + return -EIO; + } + if (body->resume) wfx_suspend_resume_mc(wvif, STA_NOTIFY_AWAKE); else wfx_suspend_resume_mc(wvif, STA_NOTIFY_SLEEP); } else { WARN(body->peer_sta_set, "misunderstood indication"); WARN(hif->interface != 2, "misunderstood indication"); - if (body->suspend_resume_flags.resume) + if (body->resume) wfx_suspend_hot_dev(wdev, STA_NOTIFY_AWAKE); else wfx_suspend_hot_dev(wdev, STA_NOTIFY_SLEEP); @@ -243,29 +234,28 @@ static int hif_generic_indication(struct wfx_dev *wdev, const struct hif_msg *hif, const void *buf) { const struct hif_ind_generic *body = buf; - int type = le32_to_cpu(body->indication_type); + int type = le32_to_cpu(body->type); switch (type) { case HIF_GENERIC_INDICATION_TYPE_RAW: return 0; case HIF_GENERIC_INDICATION_TYPE_STRING: - dev_info(wdev->dev, "firmware says: %s\n", - (char *)body->indication_data.raw_data); + dev_info(wdev->dev, "firmware says: %s\n", (char *)&body->data); return 0; case HIF_GENERIC_INDICATION_TYPE_RX_STATS: mutex_lock(&wdev->rx_stats_lock); // Older firmware send a generic indication beside RxStats if (!wfx_api_older_than(wdev, 1, 4)) - dev_info(wdev->dev, "Rx test ongoing. Temperature: %d°C\n", - body->indication_data.rx_stats.current_temp); - memcpy(&wdev->rx_stats, &body->indication_data.rx_stats, + dev_info(wdev->dev, "Rx test ongoing. Temperature: %d degrees C\n", + body->data.rx_stats.current_temp); + memcpy(&wdev->rx_stats, &body->data.rx_stats, sizeof(wdev->rx_stats)); mutex_unlock(&wdev->rx_stats_lock); return 0; case HIF_GENERIC_INDICATION_TYPE_TX_POWER_LOOP_INFO: mutex_lock(&wdev->tx_power_loop_info_lock); memcpy(&wdev->tx_power_loop_info, - &body->indication_data.tx_power_loop_info, + &body->data.tx_power_loop_info, sizeof(wdev->tx_power_loop_info)); mutex_unlock(&wdev->tx_power_loop_info_lock); return 0; @@ -301,6 +291,8 @@ static const struct { "secure link overflow" }, { HIF_ERROR_SLK_WRONG_ENCRYPTION_STATE, "secure link messages list does not match message encryption" }, + { HIF_ERROR_SLK_UNCONFIGURED, + "secure link not yet configured" }, { HIF_ERROR_HIF_BUS_FREQUENCY_TOO_LOW, "bus clock is too slow (<1kHz)" }, { HIF_ERROR_HIF_RX_DATA_TOO_LARGE, @@ -378,7 +370,6 @@ static const struct { { HIF_IND_ID_SET_PM_MODE_CMPL, hif_pm_mode_complete_indication }, { HIF_IND_ID_SCAN_CMPL, hif_scan_complete_indication }, { HIF_IND_ID_SUSPEND_RESUME_TX, hif_suspend_resume_indication }, - { HIF_IND_ID_SL_EXCHANGE_PUB_KEYS, hif_keys_indication }, { HIF_IND_ID_EVENT, hif_event_indication }, { HIF_IND_ID_GENERIC, hif_generic_indication }, { HIF_IND_ID_ERROR, hif_error_indication }, diff --git a/drivers/staging/wfx/hif_tx.c b/drivers/staging/wfx/hif_tx.c index 5110f9b93762..63b437261eb7 100644 --- a/drivers/staging/wfx/hif_tx.c +++ b/drivers/staging/wfx/hif_tx.c @@ -3,7 +3,7 @@ * Implementation of host-to-chip commands (aka request/confirmation) of WFxxx * Split Mac (WSM) API. * - * Copyright (c) 2017-2019, Silicon Laboratories, Inc. + * Copyright (c) 2017-2020, Silicon Laboratories, Inc. * Copyright (c) 2010, ST-Ericsson */ #include <linux/etherdevice.h> @@ -20,7 +20,6 @@ void wfx_init_hif_cmd(struct wfx_hif_cmd *hif_cmd) init_completion(&hif_cmd->ready); init_completion(&hif_cmd->done); mutex_init(&hif_cmd->lock); - mutex_init(&hif_cmd->key_renew_lock); } static void wfx_fill_header(struct hif_msg *hif, int if_id, @@ -48,7 +47,7 @@ static void *wfx_alloc_hif(size_t body_len, struct hif_msg **hif) } int wfx_cmd_send(struct wfx_dev *wdev, struct hif_msg *request, - void *reply, size_t reply_len, bool async) + void *reply, size_t reply_len, bool no_reply) { const char *mib_name = ""; const char *mib_sep = ""; @@ -56,15 +55,10 @@ int wfx_cmd_send(struct wfx_dev *wdev, struct hif_msg *request, int vif = request->interface; int ret; - WARN(wdev->hif_cmd.buf_recv && wdev->hif_cmd.async, "API usage error"); - // Do not wait for any reply if chip is frozen if (wdev->chip_frozen) return -ETIMEDOUT; - if (cmd != HIF_REQ_ID_SL_EXCHANGE_PUB_KEYS) - mutex_lock(&wdev->hif_cmd.key_renew_lock); - mutex_lock(&wdev->hif_cmd.lock); WARN(wdev->hif_cmd.buf_send, "data locking error"); @@ -73,14 +67,18 @@ int wfx_cmd_send(struct wfx_dev *wdev, struct hif_msg *request, wdev->hif_cmd.buf_send = request; wdev->hif_cmd.buf_recv = reply; wdev->hif_cmd.len_recv = reply_len; - wdev->hif_cmd.async = async; complete(&wdev->hif_cmd.ready); wfx_bh_request_tx(wdev); - // NOTE: no timeout is catched async is enabled - if (async) + if (no_reply) { + // Chip won't reply. Give enough time to the wq to send the + // buffer. + msleep(100); + wdev->hif_cmd.buf_send = NULL; + mutex_unlock(&wdev->hif_cmd.lock); return 0; + } if (wdev->poll_irq) wfx_bh_poll_irq(wdev); @@ -118,36 +116,25 @@ int wfx_cmd_send(struct wfx_dev *wdev, struct hif_msg *request, "WSM request %s%s%s (%#.2x) on vif %d returned status %d\n", get_hif_name(cmd), mib_sep, mib_name, cmd, vif, ret); - if (cmd != HIF_REQ_ID_SL_EXCHANGE_PUB_KEYS) - mutex_unlock(&wdev->hif_cmd.key_renew_lock); return ret; } // This function is special. After HIF_REQ_ID_SHUT_DOWN, chip won't reply to any -// request anymore. We need to slightly hack struct wfx_hif_cmd for that job. Be -// carefull to only call this funcion during device unregister. +// request anymore. Obviously, only call this function during device unregister. int hif_shutdown(struct wfx_dev *wdev) { int ret; struct hif_msg *hif; - if (wdev->chip_frozen) - return 0; wfx_alloc_hif(0, &hif); if (!hif) return -ENOMEM; wfx_fill_header(hif, -1, HIF_REQ_ID_SHUT_DOWN, 0); ret = wfx_cmd_send(wdev, hif, NULL, 0, true); - // After this command, chip won't reply. Be sure to give enough time to - // bh to send buffer: - msleep(100); - wdev->hif_cmd.buf_send = NULL; if (wdev->pdata.gpio_wakeup) gpiod_set_value(wdev->pdata.gpio_wakeup, 0); else control_reg_write(wdev, 0); - mutex_unlock(&wdev->hif_cmd.lock); - mutex_unlock(&wdev->hif_cmd.key_renew_lock); kfree(hif); return ret; } @@ -177,7 +164,7 @@ int hif_reset(struct wfx_vif *wvif, bool reset_stat) if (!hif) return -ENOMEM; - body->reset_flags.reset_stat = reset_stat; + body->reset_stat = reset_stat; wfx_fill_header(hif, wvif->id, HIF_REQ_ID_RESET, sizeof(*body)); ret = wfx_cmd_send(wvif->wdev, hif, NULL, 0, false); kfree(hif); @@ -252,8 +239,6 @@ int hif_scan(struct wfx_vif *wvif, struct cfg80211_scan_request *req, WARN(chan_num > HIF_API_MAX_NB_CHANNELS, "invalid params"); WARN(req->n_ssids > HIF_API_MAX_NB_SSIDS, "invalid params"); - compiletime_assert(IEEE80211_MAX_SSID_LEN == HIF_API_SSID_SIZE, - "API inconsistency"); if (!hif) return -ENOMEM; for (i = 0; i < req->n_ssids; i++) { @@ -263,9 +248,8 @@ int hif_scan(struct wfx_vif *wvif, struct cfg80211_scan_request *req, cpu_to_le32(req->ssids[i].ssid_len); } body->num_of_ssids = HIF_API_MAX_NB_SSIDS; - // Background scan is always a good idea - body->scan_type.type = 1; - body->scan_flags.fbg = 1; + body->maintain_current_bss = 1; + body->disallow_ps = 1; body->tx_power_level = cpu_to_le32(req->channels[chan_start_idx]->max_power); body->num_of_channels = chan_num; @@ -324,11 +308,13 @@ int hif_join(struct wfx_vif *wvif, const struct ieee80211_bss_conf *conf, WARN_ON(!conf->basic_rates); WARN_ON(sizeof(body->ssid) < ssidlen); WARN(!conf->ibss_joined && !ssidlen, "joining an unknown BSS"); + if (WARN_ON(!channel)) + return -EINVAL; if (!hif) return -ENOMEM; body->infrastructure_bss_mode = !conf->ibss_joined; body->short_preamble = conf->use_short_preamble; - if (channel && channel->flags & IEEE80211_CHAN_NO_IR) + if (channel->flags & IEEE80211_CHAN_NO_IR) body->probe_for_join = 0; else body->probe_for_join = 1; @@ -446,11 +432,11 @@ int hif_set_pm(struct wfx_vif *wvif, bool ps, int dynamic_ps_timeout) if (!hif) return -ENOMEM; if (ps) { - body->pm_mode.enter_psm = 1; + body->enter_psm = 1; // Firmware does not support more than 128ms body->fast_psm_idle_period = min(dynamic_ps_timeout * 2, 255); if (body->fast_psm_idle_period) - body->pm_mode.fast_psm = 1; + body->fast_psm = 1; } wfx_fill_header(hif, wvif->id, HIF_REQ_ID_SET_PM_MODE, sizeof(*body)); ret = wfx_cmd_send(wvif->wdev, hif, NULL, 0, false); @@ -499,7 +485,7 @@ int hif_beacon_transmit(struct wfx_vif *wvif, bool enable) return ret; } -int hif_map_link(struct wfx_vif *wvif, u8 *mac_addr, int flags, int sta_id) +int hif_map_link(struct wfx_vif *wvif, bool unmap, u8 *mac_addr, int sta_id, bool mfp) { int ret; struct hif_msg *hif; @@ -509,7 +495,8 @@ int hif_map_link(struct wfx_vif *wvif, u8 *mac_addr, int flags, int sta_id) return -ENOMEM; if (mac_addr) ether_addr_copy(body->mac_addr, mac_addr); - body->map_link_flags = *(struct hif_map_link_flags *)&flags; + body->mfpc = mfp ? 1 : 0; + body->unmap = unmap ? 1 : 0; body->peer_sta_id = sta_id; wfx_fill_header(hif, wvif->id, HIF_REQ_ID_MAP_LINK, sizeof(*body)); ret = wfx_cmd_send(wvif->wdev, hif, NULL, 0, false); @@ -526,7 +513,7 @@ int hif_update_ie_beacon(struct wfx_vif *wvif, const u8 *ies, size_t ies_len) if (!hif) return -ENOMEM; - body->ie_flags.beacon = 1; + body->beacon = 1; body->num_ies = cpu_to_le16(1); memcpy(body->ie, ies, ies_len); wfx_fill_header(hif, wvif->id, HIF_REQ_ID_UPDATE_IE, buf_len); @@ -534,62 +521,3 @@ int hif_update_ie_beacon(struct wfx_vif *wvif, const u8 *ies, size_t ies_len) kfree(hif); return ret; } - -int hif_sl_send_pub_keys(struct wfx_dev *wdev, - const u8 *pubkey, const u8 *pubkey_hmac) -{ - int ret; - struct hif_msg *hif; - struct hif_req_sl_exchange_pub_keys *body = wfx_alloc_hif(sizeof(*body), - &hif); - - if (!hif) - return -ENOMEM; - body->algorithm = HIF_SL_CURVE25519; - memcpy(body->host_pub_key, pubkey, sizeof(body->host_pub_key)); - memcpy(body->host_pub_key_mac, pubkey_hmac, - sizeof(body->host_pub_key_mac)); - wfx_fill_header(hif, -1, HIF_REQ_ID_SL_EXCHANGE_PUB_KEYS, - sizeof(*body)); - ret = wfx_cmd_send(wdev, hif, NULL, 0, false); - kfree(hif); - // Compatibility with legacy secure link - if (ret == le32_to_cpu(HIF_STATUS_SLK_NEGO_SUCCESS)) - ret = 0; - return ret; -} - -int hif_sl_config(struct wfx_dev *wdev, const unsigned long *bitmap) -{ - int ret; - struct hif_msg *hif; - struct hif_req_sl_configure *body = wfx_alloc_hif(sizeof(*body), &hif); - - if (!hif) - return -ENOMEM; - memcpy(body->encr_bmp, bitmap, sizeof(body->encr_bmp)); - wfx_fill_header(hif, -1, HIF_REQ_ID_SL_CONFIGURE, sizeof(*body)); - ret = wfx_cmd_send(wdev, hif, NULL, 0, false); - kfree(hif); - return ret; -} - -int hif_sl_set_mac_key(struct wfx_dev *wdev, const u8 *slk_key, int destination) -{ - int ret; - struct hif_msg *hif; - struct hif_req_set_sl_mac_key *body = wfx_alloc_hif(sizeof(*body), - &hif); - - if (!hif) - return -ENOMEM; - memcpy(body->key_value, slk_key, sizeof(body->key_value)); - body->otp_or_ram = destination; - wfx_fill_header(hif, -1, HIF_REQ_ID_SET_SL_MAC_KEY, sizeof(*body)); - ret = wfx_cmd_send(wdev, hif, NULL, 0, false); - kfree(hif); - // Compatibility with legacy secure link - if (ret == le32_to_cpu(HIF_STATUS_SLK_SET_KEY_SUCCESS)) - ret = 0; - return ret; -} diff --git a/drivers/staging/wfx/hif_tx.h b/drivers/staging/wfx/hif_tx.h index e1da28aef706..3521c545ae6b 100644 --- a/drivers/staging/wfx/hif_tx.h +++ b/drivers/staging/wfx/hif_tx.h @@ -3,7 +3,7 @@ * Implementation of host-to-chip commands (aka request/confirmation) of WFxxx * Split Mac (WSM) API. * - * Copyright (c) 2017-2019, Silicon Laboratories, Inc. + * Copyright (c) 2017-2020, Silicon Laboratories, Inc. * Copyright (c) 2010, ST-Ericsson * Copyright (C) 2010, ST-Ericsson SA */ @@ -20,10 +20,8 @@ struct wfx_vif; struct wfx_hif_cmd { struct mutex lock; - struct mutex key_renew_lock; struct completion ready; struct completion done; - bool async; struct hif_msg *buf_send; void *buf_recv; size_t len_recv; @@ -55,12 +53,8 @@ int hif_set_edca_queue_params(struct wfx_vif *wvif, u16 queue, int hif_start(struct wfx_vif *wvif, const struct ieee80211_bss_conf *conf, const struct ieee80211_channel *channel); int hif_beacon_transmit(struct wfx_vif *wvif, bool enable); -int hif_map_link(struct wfx_vif *wvif, u8 *mac_addr, int flags, int sta_id); +int hif_map_link(struct wfx_vif *wvif, + bool unmap, u8 *mac_addr, int sta_id, bool mfp); int hif_update_ie_beacon(struct wfx_vif *wvif, const u8 *ies, size_t ies_len); -int hif_sl_set_mac_key(struct wfx_dev *wdev, - const u8 *slk_key, int destination); -int hif_sl_config(struct wfx_dev *wdev, const unsigned long *bitmap); -int hif_sl_send_pub_keys(struct wfx_dev *wdev, - const u8 *pubkey, const u8 *pubkey_hmac); #endif diff --git a/drivers/staging/wfx/hif_tx_mib.c b/drivers/staging/wfx/hif_tx_mib.c index 05f1e1e98af9..1926cf1b62be 100644 --- a/drivers/staging/wfx/hif_tx_mib.c +++ b/drivers/staging/wfx/hif_tx_mib.c @@ -2,7 +2,7 @@ /* * Implementation of host-to-chip MIBs of WFxxx Split Mac (WSM) API. * - * Copyright (c) 2017-2019, Silicon Laboratories, Inc. + * Copyright (c) 2017-2020, Silicon Laboratories, Inc. * Copyright (c) 2010, ST-Ericsson * Copyright (C) 2010, ST-Ericsson SA */ @@ -29,7 +29,7 @@ int hif_set_beacon_wakeup_period(struct wfx_vif *wvif, unsigned int dtim_interval, unsigned int listen_interval) { - struct hif_mib_beacon_wake_up_period val = { + struct hif_mib_beacon_wake_up_period arg = { .wakeup_period_min = dtim_interval, .receive_dtim = 0, .wakeup_period_max = listen_interval, @@ -39,7 +39,7 @@ int hif_set_beacon_wakeup_period(struct wfx_vif *wvif, return -EINVAL; return hif_write_mib(wvif->wdev, wvif->id, HIF_MIB_ID_BEACON_WAKEUP_PERIOD, - &val, sizeof(val)); + &arg, sizeof(arg)); } int hif_set_rcpi_rssi_threshold(struct wfx_vif *wvif, @@ -92,31 +92,31 @@ int hif_set_macaddr(struct wfx_vif *wvif, u8 *mac) int hif_set_rx_filter(struct wfx_vif *wvif, bool filter_bssid, bool filter_prbreq) { - struct hif_mib_rx_filter val = { }; + struct hif_mib_rx_filter arg = { }; if (filter_bssid) - val.bssid_filter = 1; + arg.bssid_filter = 1; if (!filter_prbreq) - val.fwd_probe_req = 1; + arg.fwd_probe_req = 1; return hif_write_mib(wvif->wdev, wvif->id, HIF_MIB_ID_RX_FILTER, - &val, sizeof(val)); + &arg, sizeof(arg)); } int hif_set_beacon_filter_table(struct wfx_vif *wvif, int tbl_len, const struct hif_ie_table_entry *tbl) { int ret; - struct hif_mib_bcn_filter_table *val; - int buf_len = struct_size(val, ie_table, tbl_len); + struct hif_mib_bcn_filter_table *arg; + int buf_len = struct_size(arg, ie_table, tbl_len); - val = kzalloc(buf_len, GFP_KERNEL); - if (!val) + arg = kzalloc(buf_len, GFP_KERNEL); + if (!arg) return -ENOMEM; - val->num_of_info_elmts = cpu_to_le32(tbl_len); - memcpy(val->ie_table, tbl, flex_array_size(val, ie_table, tbl_len)); + arg->num_of_info_elmts = cpu_to_le32(tbl_len); + memcpy(arg->ie_table, tbl, flex_array_size(arg, ie_table, tbl_len)); ret = hif_write_mib(wvif->wdev, wvif->id, - HIF_MIB_ID_BEACON_FILTER_TABLE, val, buf_len); - kfree(val); + HIF_MIB_ID_BEACON_FILTER_TABLE, arg, buf_len); + kfree(arg); return ret; } @@ -134,13 +134,13 @@ int hif_beacon_filter_control(struct wfx_vif *wvif, int hif_set_operational_mode(struct wfx_dev *wdev, enum hif_op_power_mode mode) { - struct hif_mib_gl_operational_power_mode val = { + struct hif_mib_gl_operational_power_mode arg = { .power_mode = mode, .wup_ind_activation = 1, }; return hif_write_mib(wdev, -1, HIF_MIB_ID_GL_OPERATIONAL_POWER_MODE, - &val, sizeof(val)); + &arg, sizeof(arg)); } int hif_set_template_frame(struct wfx_vif *wvif, struct sk_buff *skb, @@ -161,57 +161,46 @@ int hif_set_template_frame(struct wfx_vif *wvif, struct sk_buff *skb, int hif_set_mfp(struct wfx_vif *wvif, bool capable, bool required) { - struct hif_mib_protected_mgmt_policy val = { }; + struct hif_mib_protected_mgmt_policy arg = { }; WARN(required && !capable, "incoherent arguments"); if (capable) { - val.pmf_enable = 1; - val.host_enc_auth_frames = 1; + arg.pmf_enable = 1; + arg.host_enc_auth_frames = 1; } if (!required) - val.unpmf_allowed = 1; + arg.unpmf_allowed = 1; return hif_write_mib(wvif->wdev, wvif->id, HIF_MIB_ID_PROTECTED_MGMT_POLICY, - &val, sizeof(val)); + &arg, sizeof(arg)); } int hif_set_block_ack_policy(struct wfx_vif *wvif, u8 tx_tid_policy, u8 rx_tid_policy) { - struct hif_mib_block_ack_policy val = { + struct hif_mib_block_ack_policy arg = { .block_ack_tx_tid_policy = tx_tid_policy, .block_ack_rx_tid_policy = rx_tid_policy, }; return hif_write_mib(wvif->wdev, wvif->id, HIF_MIB_ID_BLOCK_ACK_POLICY, - &val, sizeof(val)); + &arg, sizeof(arg)); } -int hif_set_association_mode(struct wfx_vif *wvif, - struct ieee80211_bss_conf *info) +int hif_set_association_mode(struct wfx_vif *wvif, int ampdu_density, + bool greenfield, bool short_preamble) { - struct ieee80211_sta *sta = NULL; - struct hif_mib_set_association_mode val = { + struct hif_mib_set_association_mode arg = { .preambtype_use = 1, .mode = 1, .spacing = 1, - .short_preamble = info->use_short_preamble, + .short_preamble = short_preamble, + .greenfield = greenfield, + .mpdu_start_spacing = ampdu_density, }; - rcu_read_lock(); // protect sta - if (info->bssid && !info->ibss_joined) - sta = ieee80211_find_sta(wvif->vif, info->bssid); - - // FIXME: it is strange to not retrieve all information from bss_info - if (sta && sta->ht_cap.ht_supported) { - val.mpdu_start_spacing = sta->ht_cap.ampdu_density; - if (!(info->ht_operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT)) - val.greenfield = !!(sta->ht_cap.cap & IEEE80211_HT_CAP_GRN_FLD); - } - rcu_read_unlock(); - return hif_write_mib(wvif->wdev, wvif->id, - HIF_MIB_ID_SET_ASSOCIATION_MODE, &val, sizeof(val)); + HIF_MIB_ID_SET_ASSOCIATION_MODE, &arg, sizeof(arg)); } int hif_set_tx_rate_retry_policy(struct wfx_vif *wvif, @@ -239,57 +228,6 @@ int hif_set_tx_rate_retry_policy(struct wfx_vif *wvif, return ret; } -int hif_set_mac_addr_condition(struct wfx_vif *wvif, - int idx, const u8 *mac_addr) -{ - struct hif_mib_mac_addr_data_frame_condition val = { - .condition_idx = idx, - .address_type = HIF_MAC_ADDR_A1, - }; - - ether_addr_copy(val.mac_address, mac_addr); - return hif_write_mib(wvif->wdev, wvif->id, - HIF_MIB_ID_MAC_ADDR_DATAFRAME_CONDITION, - &val, sizeof(val)); -} - -int hif_set_uc_mc_bc_condition(struct wfx_vif *wvif, int idx, u8 allowed_frames) -{ - struct hif_mib_uc_mc_bc_data_frame_condition val = { - .condition_idx = idx, - .allowed_frames = allowed_frames, - }; - - return hif_write_mib(wvif->wdev, wvif->id, - HIF_MIB_ID_UC_MC_BC_DATAFRAME_CONDITION, - &val, sizeof(val)); -} - -int hif_set_config_data_filter(struct wfx_vif *wvif, bool enable, int idx, - int mac_filters, int frames_types_filters) -{ - struct hif_mib_config_data_filter val = { - .enable = enable, - .filter_idx = idx, - .mac_cond = mac_filters, - .uc_mc_bc_cond = frames_types_filters, - }; - - return hif_write_mib(wvif->wdev, wvif->id, - HIF_MIB_ID_CONFIG_DATA_FILTER, &val, sizeof(val)); -} - -int hif_set_data_filtering(struct wfx_vif *wvif, bool enable, bool invert) -{ - struct hif_mib_set_data_filtering val = { - .enable = enable, - .invert_matching = invert, - }; - - return hif_write_mib(wvif->wdev, wvif->id, - HIF_MIB_ID_SET_DATA_FILTERING, &val, sizeof(val)); -} - int hif_keep_alive_period(struct wfx_vif *wvif, int period) { struct hif_mib_keep_alive_period arg = { diff --git a/drivers/staging/wfx/hif_tx_mib.h b/drivers/staging/wfx/hif_tx_mib.h index 86683de7de7c..812b3ba0f00e 100644 --- a/drivers/staging/wfx/hif_tx_mib.h +++ b/drivers/staging/wfx/hif_tx_mib.h @@ -2,7 +2,7 @@ /* * Implementation of host-to-chip MIBs of WFxxx Split Mac (WSM) API. * - * Copyright (c) 2017-2019, Silicon Laboratories, Inc. + * Copyright (c) 2017-2020, Silicon Laboratories, Inc. * Copyright (c) 2010, ST-Ericsson * Copyright (C) 2010, ST-Ericsson SA */ @@ -33,17 +33,10 @@ int hif_set_template_frame(struct wfx_vif *wvif, struct sk_buff *skb, int hif_set_mfp(struct wfx_vif *wvif, bool capable, bool required); int hif_set_block_ack_policy(struct wfx_vif *wvif, u8 tx_tid_policy, u8 rx_tid_policy); -int hif_set_association_mode(struct wfx_vif *wvif, - struct ieee80211_bss_conf *info); +int hif_set_association_mode(struct wfx_vif *wvif, int ampdu_density, + bool greenfield, bool short_preamble); int hif_set_tx_rate_retry_policy(struct wfx_vif *wvif, int policy_index, u8 *rates); -int hif_set_mac_addr_condition(struct wfx_vif *wvif, - int idx, const u8 *mac_addr); -int hif_set_uc_mc_bc_condition(struct wfx_vif *wvif, - int idx, u8 allowed_frames); -int hif_set_config_data_filter(struct wfx_vif *wvif, bool enable, int idx, - int mac_filters, int frames_types_filters); -int hif_set_data_filtering(struct wfx_vif *wvif, bool enable, bool invert); int hif_keep_alive_period(struct wfx_vif *wvif, int period); int hif_set_arp_ipv4_filter(struct wfx_vif *wvif, int idx, __be32 *addr); int hif_use_multi_tx_conf(struct wfx_dev *wdev, bool enable); diff --git a/drivers/staging/wfx/hwio.c b/drivers/staging/wfx/hwio.c index 777217cdf9a7..36fbc5b5d64c 100644 --- a/drivers/staging/wfx/hwio.c +++ b/drivers/staging/wfx/hwio.c @@ -2,7 +2,7 @@ /* * Low-level I/O functions. * - * Copyright (c) 2017-2019, Silicon Laboratories, Inc. + * Copyright (c) 2017-2020, Silicon Laboratories, Inc. * Copyright (c) 2010, ST-Ericsson */ #include <linux/kernel.h> diff --git a/drivers/staging/wfx/hwio.h b/drivers/staging/wfx/hwio.h index 4b6ef061b40b..0b8e4f7157df 100644 --- a/drivers/staging/wfx/hwio.h +++ b/drivers/staging/wfx/hwio.h @@ -2,7 +2,7 @@ /* * Low-level API. * - * Copyright (c) 2017-2018, Silicon Laboratories, Inc. + * Copyright (c) 2017-2020, Silicon Laboratories, Inc. * Copyright (c) 2010, ST-Ericsson */ #ifndef WFX_HWIO_H diff --git a/drivers/staging/wfx/key.c b/drivers/staging/wfx/key.c index 5ee2ffc5f935..2ab82bed4c1b 100644 --- a/drivers/staging/wfx/key.c +++ b/drivers/staging/wfx/key.c @@ -2,7 +2,7 @@ /* * Key management related functions. * - * Copyright (c) 2017-2019, Silicon Laboratories, Inc. + * Copyright (c) 2017-2020, Silicon Laboratories, Inc. * Copyright (c) 2010, ST-Ericsson */ #include <linux/etherdevice.h> @@ -171,7 +171,7 @@ static int wfx_add_key(struct wfx_vif *wvif, struct ieee80211_sta *sta, k.int_id = wvif->id; k.entry_index = idx; if (key->cipher == WLAN_CIPHER_SUITE_WEP40 || - key->cipher == WLAN_CIPHER_SUITE_WEP104) { + key->cipher == WLAN_CIPHER_SUITE_WEP104) { if (pairwise) k.type = fill_wep_pair(&k.key.wep_pairwise_key, key, sta->addr); @@ -191,15 +191,15 @@ static int wfx_add_key(struct wfx_vif *wvif, struct ieee80211_sta *sta, else k.type = fill_ccmp_group(&k.key.aes_group_key, key, &seq); - } else if (key->cipher == WLAN_CIPHER_SUITE_SMS4) { + } else if (key->cipher == WLAN_CIPHER_SUITE_SMS4) { if (pairwise) k.type = fill_sms4_pair(&k.key.wapi_pairwise_key, key, sta->addr); else k.type = fill_sms4_group(&k.key.wapi_group_key, key); - } else if (key->cipher == WLAN_CIPHER_SUITE_AES_CMAC) { - k.type = fill_aes_cmac_group(&k.key.igtk_group_key, key, - &seq); + } else if (key->cipher == WLAN_CIPHER_SUITE_AES_CMAC) { + k.type = fill_aes_cmac_group(&k.key.igtk_group_key, key, &seq); + key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIE; } else { dev_warn(wdev->dev, "unsupported key type %d\n", key->cipher); wfx_free_key(wdev, idx); diff --git a/drivers/staging/wfx/key.h b/drivers/staging/wfx/key.h index ff31fc9c565a..70a44d0ca35e 100644 --- a/drivers/staging/wfx/key.h +++ b/drivers/staging/wfx/key.h @@ -2,7 +2,7 @@ /* * Implementation of mac80211 API. * - * Copyright (c) 2017-2019, Silicon Laboratories, Inc. + * Copyright (c) 2017-2020, Silicon Laboratories, Inc. * Copyright (c) 2010, ST-Ericsson */ #ifndef WFX_KEY_H diff --git a/drivers/staging/wfx/main.c b/drivers/staging/wfx/main.c index 11dfa088fc86..e7bc1988124a 100644 --- a/drivers/staging/wfx/main.c +++ b/drivers/staging/wfx/main.c @@ -2,7 +2,7 @@ /* * Device probe and register. * - * Copyright (c) 2017-2019, Silicon Laboratories, Inc. + * Copyright (c) 2017-2020, Silicon Laboratories, Inc. * Copyright (c) 2010, ST-Ericsson * Copyright (c) 2008, Johannes Berg <johannes@sipsolutions.net> * Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). @@ -30,7 +30,6 @@ #include "scan.h" #include "debug.h" #include "data_tx.h" -#include "secure_link.h" #include "hif_tx_mib.h" #include "hif_api_cmd.h" @@ -143,7 +142,6 @@ static const struct ieee80211_ops wfx_ops = { .set_rts_threshold = wfx_set_rts_threshold, .set_default_unicast_key = wfx_set_default_unicast_key, .bss_info_changed = wfx_bss_info_changed, - .prepare_multicast = wfx_prepare_multicast, .configure_filter = wfx_configure_filter, .ampdu_action = wfx_ampdu_action, .flush = wfx_flush, @@ -224,12 +222,18 @@ static int wfx_send_pdata_pds(struct wfx_dev *wdev) if (ret) { dev_err(wdev->dev, "can't load PDS file %s\n", wdev->pdata.file_pds); - return ret; + goto err1; } tmp_buf = kmemdup(pds->data, pds->size, GFP_KERNEL); + if (!tmp_buf) { + ret = -ENOMEM; + goto err2; + } ret = wfx_send_pds(wdev, tmp_buf, pds->size); kfree(tmp_buf); +err2: release_firmware(pds); +err1: return ret; } @@ -271,8 +275,7 @@ struct wfx_dev *wfx_init_common(struct device *dev, hw->queues = 4; hw->max_rates = 8; hw->max_rate_tries = 8; - hw->extra_tx_headroom = sizeof(struct hif_sl_msg_hdr) + - sizeof(struct hif_msg) + hw->extra_tx_headroom = sizeof(struct hif_msg) + sizeof(struct hif_req_tx) + 4 /* alignment */ + 8 /* TKIP IV */; hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | @@ -282,9 +285,9 @@ struct wfx_dev *wfx_init_common(struct device *dev, NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 | NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P | NL80211_PROBE_RESP_OFFLOAD_SUPPORT_80211U; + hw->wiphy->features |= NL80211_FEATURE_AP_SCAN; hw->wiphy->flags |= WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD; hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD; - hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; hw->wiphy->max_ap_assoc_sta = HIF_LINK_ID_MAX; hw->wiphy->max_scan_ssids = 2; hw->wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN; @@ -306,10 +309,9 @@ struct wfx_dev *wfx_init_common(struct device *dev, wdev->pdata.gpio_wakeup = devm_gpiod_get_optional(dev, "wakeup", GPIOD_OUT_LOW); if (IS_ERR(wdev->pdata.gpio_wakeup)) - return ERR_CAST(wdev->pdata.gpio_wakeup); + return NULL; if (wdev->pdata.gpio_wakeup) gpiod_set_consumer_name(wdev->pdata.gpio_wakeup, "wfx wakeup"); - wfx_sl_fill_pdata(dev, &wdev->pdata); mutex_init(&wdev->conf_mutex); mutex_init(&wdev->rx_stats_lock); @@ -363,9 +365,8 @@ int wfx_probe(struct wfx_dev *wdev) dev_info(wdev->dev, "started firmware %d.%d.%d \"%s\" (API: %d.%d, keyset: %02X, caps: 0x%.8X)\n", wdev->hw_caps.firmware_major, wdev->hw_caps.firmware_minor, wdev->hw_caps.firmware_build, wdev->hw_caps.firmware_label, - wdev->hw_caps.api_version_major, - wdev->hw_caps.api_version_minor, - wdev->keyset, *((u32 *)&wdev->hw_caps.capabilities)); + wdev->hw_caps.api_version_major, wdev->hw_caps.api_version_minor, + wdev->keyset, wdev->hw_caps.link_mode); snprintf(wdev->hw->wiphy->fw_version, sizeof(wdev->hw->wiphy->fw_version), "%d.%d.%d", @@ -381,14 +382,13 @@ int wfx_probe(struct wfx_dev *wdev) goto err0; } - err = wfx_sl_init(wdev); - if (err && wdev->hw_caps.capabilities.link_mode == SEC_LINK_ENFORCED) { + if (wdev->hw_caps.link_mode == SEC_LINK_ENFORCED) { dev_err(wdev->dev, - "chip require secure_link, but can't negociate it\n"); + "chip require secure_link, but can't negotiate it\n"); goto err0; } - if (wdev->hw_caps.regul_sel_mode_info.region_sel_mode) { + if (wdev->hw_caps.region_sel_mode) { wdev->hw->wiphy->bands[NL80211_BAND_2GHZ]->channels[11].flags |= IEEE80211_CHAN_NO_IR; wdev->hw->wiphy->bands[NL80211_BAND_2GHZ]->channels[12].flags |= IEEE80211_CHAN_NO_IR; wdev->hw->wiphy->bands[NL80211_BAND_2GHZ]->channels[13].flags |= IEEE80211_CHAN_DISABLED; @@ -466,7 +466,6 @@ void wfx_release(struct wfx_dev *wdev) hif_shutdown(wdev); wdev->hwbus_ops->irq_unsubscribe(wdev->hwbus_priv); wfx_bh_unregister(wdev); - wfx_sl_deinit(wdev); } static int __init wfx_core_init(void) diff --git a/drivers/staging/wfx/main.h b/drivers/staging/wfx/main.h index c59d375dd3ad..a0db322383a3 100644 --- a/drivers/staging/wfx/main.h +++ b/drivers/staging/wfx/main.h @@ -2,7 +2,7 @@ /* * Device probe and register. * - * Copyright (c) 2017-2019, Silicon Laboratories, Inc. + * Copyright (c) 2017-2020, Silicon Laboratories, Inc. * Copyright (c) 2010, ST-Ericsson * Copyright (c) 2006, Michael Wu <flamingice@sourmilk.net> * Copyright 2004-2006 Jean-Baptiste Note <jbnote@gmail.com>, et al. @@ -19,7 +19,7 @@ struct wfx_dev; struct hwbus_ops; struct wfx_platform_data { - /* Keyset and ".sec" extention will appended to this string */ + /* Keyset and ".sec" extension will be appended to this string */ const char *file_fw; const char *file_pds; struct gpio_desc *gpio_wakeup; diff --git a/drivers/staging/wfx/queue.c b/drivers/staging/wfx/queue.c index 6e3159165143..31c37f69c295 100644 --- a/drivers/staging/wfx/queue.c +++ b/drivers/staging/wfx/queue.c @@ -2,7 +2,7 @@ /* * O(1) TX queue with built-in allocator. * - * Copyright (c) 2017-2019, Silicon Laboratories, Inc. + * Copyright (c) 2017-2020, Silicon Laboratories, Inc. * Copyright (c) 2010, ST-Ericsson */ #include <linux/sched.h> @@ -60,11 +60,16 @@ void wfx_tx_lock_flush(struct wfx_dev *wdev) void wfx_tx_queues_init(struct wfx_vif *wvif) { + // The device is in charge to respect the details of the QoS parameters. + // The driver just ensure that it roughtly respect the priorities to + // avoid any shortage. + const int priorities[IEEE80211_NUM_ACS] = { 1, 2, 64, 128 }; int i; for (i = 0; i < IEEE80211_NUM_ACS; ++i) { skb_queue_head_init(&wvif->tx_queue[i].normal); skb_queue_head_init(&wvif->tx_queue[i].cab); + wvif->tx_queue[i].priority = priorities[i]; } } @@ -219,6 +224,11 @@ bool wfx_tx_queues_has_cab(struct wfx_vif *wvif) return false; } +static int wfx_tx_queue_get_weight(struct wfx_queue *queue) +{ + return atomic_read(&queue->pending_frames) * queue->priority; +} + static struct sk_buff *wfx_tx_queues_get_skb(struct wfx_dev *wdev) { struct wfx_queue *queues[IEEE80211_NUM_ACS * ARRAY_SIZE(wdev->vif)]; @@ -234,8 +244,8 @@ static struct sk_buff *wfx_tx_queues_get_skb(struct wfx_dev *wdev) WARN_ON(num_queues >= ARRAY_SIZE(queues)); queues[num_queues] = &wvif->tx_queue[i]; for (j = num_queues; j > 0; j--) - if (atomic_read(&queues[j]->pending_frames) < - atomic_read(&queues[j - 1]->pending_frames)) + if (wfx_tx_queue_get_weight(queues[j]) < + wfx_tx_queue_get_weight(queues[j - 1])) swap(queues[j - 1], queues[j]); num_queues++; } diff --git a/drivers/staging/wfx/queue.h b/drivers/staging/wfx/queue.h index 22d7c936907f..80ba19455ef3 100644 --- a/drivers/staging/wfx/queue.h +++ b/drivers/staging/wfx/queue.h @@ -2,7 +2,7 @@ /* * O(1) TX queue with built-in allocator. * - * Copyright (c) 2017-2018, Silicon Laboratories, Inc. + * Copyright (c) 2017-2020, Silicon Laboratories, Inc. * Copyright (c) 2010, ST-Ericsson */ #ifndef WFX_QUEUE_H @@ -18,6 +18,7 @@ struct wfx_queue { struct sk_buff_head normal; struct sk_buff_head cab; // Content After (DTIM) Beacon atomic_t pending_frames; + int priority; }; void wfx_tx_lock(struct wfx_dev *wdev); diff --git a/drivers/staging/wfx/scan.c b/drivers/staging/wfx/scan.c index e9de19784865..fb47c7cddf2f 100644 --- a/drivers/staging/wfx/scan.c +++ b/drivers/staging/wfx/scan.c @@ -2,7 +2,7 @@ /* * Scan related functions. * - * Copyright (c) 2017-2019, Silicon Laboratories, Inc. + * Copyright (c) 2017-2020, Silicon Laboratories, Inc. * Copyright (c) 2010, ST-Ericsson */ #include <net/mac80211.h> @@ -113,10 +113,6 @@ int wfx_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct wfx_vif *wvif = (struct wfx_vif *)vif->drv_priv; WARN_ON(hw_req->req.n_channels > HIF_API_MAX_NB_CHANNELS); - - if (vif->type == NL80211_IFTYPE_AP) - return -EOPNOTSUPP; - wvif->scan_req = hw_req; schedule_work(&wvif->scan_work); return 0; diff --git a/drivers/staging/wfx/scan.h b/drivers/staging/wfx/scan.h index 2eb786c9572c..c7496a766478 100644 --- a/drivers/staging/wfx/scan.h +++ b/drivers/staging/wfx/scan.h @@ -2,7 +2,7 @@ /* * Scan related functions. * - * Copyright (c) 2017-2019, Silicon Laboratories, Inc. + * Copyright (c) 2017-2020, Silicon Laboratories, Inc. * Copyright (c) 2010, ST-Ericsson */ #ifndef WFX_SCAN_H diff --git a/drivers/staging/wfx/secure_link.h b/drivers/staging/wfx/secure_link.h deleted file mode 100644 index c3d055b2f8b1..000000000000 --- a/drivers/staging/wfx/secure_link.h +++ /dev/null @@ -1,59 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (c) 2019, Silicon Laboratories, Inc. - */ -#ifndef WFX_SECURE_LINK_H -#define WFX_SECURE_LINK_H - -#include <linux/of.h> - -#include "hif_api_general.h" - -struct wfx_dev; - - -struct sl_context { -}; - -static inline bool wfx_is_secure_command(struct wfx_dev *wdev, int cmd_id) -{ - return false; -} - -static inline int wfx_sl_decode(struct wfx_dev *wdev, struct hif_sl_msg *m) -{ - return -EIO; -} - -static inline int wfx_sl_encode(struct wfx_dev *wdev, - const struct hif_msg *input, - struct hif_sl_msg *output) -{ - return -EIO; -} - -static inline int wfx_sl_check_pubkey(struct wfx_dev *wdev, - const u8 *ncp_pubkey, - const u8 *ncp_pubmac) -{ - return -EIO; -} - -static inline void wfx_sl_fill_pdata(struct device *dev, - struct wfx_platform_data *pdata) -{ - if (of_find_property(dev->of_node, "slk_key", NULL)) - dev_err(dev, "secure link is not supported by this driver, ignoring provided key\n"); -} - -static inline int wfx_sl_init(struct wfx_dev *wdev) -{ - return -EIO; -} - -static inline void wfx_sl_deinit(struct wfx_dev *wdev) -{ -} - - -#endif diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c index 4e30ab17a93d..2320a81eae0b 100644 --- a/drivers/staging/wfx/sta.c +++ b/drivers/staging/wfx/sta.c @@ -2,7 +2,7 @@ /* * Implementation of mac80211 API. * - * Copyright (c) 2017-2019, Silicon Laboratories, Inc. + * Copyright (c) 2017-2020, Silicon Laboratories, Inc. * Copyright (c) 2010, ST-Ericsson */ #include <linux/etherdevice.h> @@ -91,59 +91,12 @@ static void wfx_filter_beacon(struct wfx_vif *wvif, bool filter_beacon) } } -static void wfx_filter_mcast(struct wfx_vif *wvif, bool filter_mcast) -{ - int i; - - // Temporary workaround for filters - hif_set_data_filtering(wvif, false, true); - return; - - if (!filter_mcast) { - hif_set_data_filtering(wvif, false, true); - return; - } - for (i = 0; i < wvif->filter_mcast_count; i++) - hif_set_mac_addr_condition(wvif, i, wvif->filter_mcast_addr[i]); - hif_set_uc_mc_bc_condition(wvif, 0, - HIF_FILTER_UNICAST | HIF_FILTER_BROADCAST); - hif_set_config_data_filter(wvif, true, 0, BIT(1), - BIT(wvif->filter_mcast_count) - 1); - hif_set_data_filtering(wvif, true, true); -} - -u64 wfx_prepare_multicast(struct ieee80211_hw *hw, - struct netdev_hw_addr_list *mc_list) -{ - int i; - struct netdev_hw_addr *ha; - struct wfx_vif *wvif = NULL; - struct wfx_dev *wdev = hw->priv; - int count = netdev_hw_addr_list_count(mc_list); - - while ((wvif = wvif_iterate(wdev, wvif)) != NULL) { - if (count > ARRAY_SIZE(wvif->filter_mcast_addr)) { - wvif->filter_mcast_count = 0; - continue; - } - wvif->filter_mcast_count = count; - - i = 0; - netdev_hw_addr_list_for_each(ha, mc_list) { - ether_addr_copy(wvif->filter_mcast_addr[i], ha->addr); - i++; - } - } - - return 0; -} - void wfx_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags, unsigned int *total_flags, u64 unused) { struct wfx_vif *wvif = NULL; struct wfx_dev *wdev = hw->priv; - bool filter_bssid, filter_prbreq, filter_beacon, filter_mcast; + bool filter_bssid, filter_prbreq, filter_beacon; // Notes: // - Probe responses (FIF_BCN_PRBRESP_PROMISC) are never filtered @@ -167,16 +120,6 @@ void wfx_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags, filter_beacon = true; wfx_filter_beacon(wvif, filter_beacon); - if (*total_flags & FIF_ALLMULTI) { - filter_mcast = false; - } else if (!wvif->filter_mcast_count) { - dev_dbg(wdev->dev, "disabling unconfigured multicast filter"); - filter_mcast = false; - } else { - filter_mcast = true; - } - wfx_filter_mcast(wvif, filter_mcast); - if (*total_flags & FIF_OTHER_BSS) filter_bssid = false; else @@ -214,7 +157,7 @@ static int wfx_get_ps_timeout(struct wfx_vif *wvif, bool *enable_ps) if (chan0 && chan1 && chan0->hw_value != chan1->hw_value && wvif->vif->type != NL80211_IFTYPE_AP) { // It is necessary to enable powersave if channels - // are differents. + // are different. if (enable_ps) *enable_ps = true; if (wvif->wdev->force_ps_timeout > -1) @@ -323,36 +266,6 @@ void wfx_set_default_unicast_key(struct ieee80211_hw *hw, hif_wep_default_key_id(wvif, idx); } -static void wfx_set_mfp(struct wfx_vif *wvif, - struct cfg80211_bss *bss) -{ - const int pairwise_cipher_suite_count_offset = 8 / sizeof(u16); - const int pairwise_cipher_suite_size = 4 / sizeof(u16); - const int akm_suite_size = 4 / sizeof(u16); - const u16 *ptr = NULL; - bool mfpc = false; - bool mfpr = false; - - /* 802.11w protected mgmt frames */ - - /* retrieve MFPC and MFPR flags from beacon or PBRSP */ - - rcu_read_lock(); - if (bss) - ptr = (const u16 *)ieee80211_bss_get_ie(bss, WLAN_EID_RSN); - - if (ptr) { - ptr += pairwise_cipher_suite_count_offset; - ptr += 1 + pairwise_cipher_suite_size * *ptr; - ptr += 1 + akm_suite_size * *ptr; - mfpr = *ptr & BIT(6); - mfpc = *ptr & BIT(7); - } - rcu_read_unlock(); - - hif_set_mfp(wvif, mfpc, mfpr); -} - void wfx_reset(struct wfx_vif *wvif) { struct wfx_dev *wdev = wvif->wdev; @@ -370,55 +283,6 @@ void wfx_reset(struct wfx_vif *wvif) wfx_update_pm(wvif); } -static void wfx_do_join(struct wfx_vif *wvif) -{ - int ret; - struct ieee80211_bss_conf *conf = &wvif->vif->bss_conf; - struct cfg80211_bss *bss = NULL; - u8 ssid[IEEE80211_MAX_SSID_LEN]; - const u8 *ssidie = NULL; - int ssidlen = 0; - - wfx_tx_lock_flush(wvif->wdev); - - bss = cfg80211_get_bss(wvif->wdev->hw->wiphy, wvif->channel, - conf->bssid, NULL, 0, - IEEE80211_BSS_TYPE_ANY, IEEE80211_PRIVACY_ANY); - if (!bss && !conf->ibss_joined) { - wfx_tx_unlock(wvif->wdev); - return; - } - - rcu_read_lock(); // protect ssidie - if (bss) - ssidie = ieee80211_bss_get_ie(bss, WLAN_EID_SSID); - if (ssidie) { - ssidlen = ssidie[1]; - if (ssidlen > IEEE80211_MAX_SSID_LEN) - ssidlen = IEEE80211_MAX_SSID_LEN; - memcpy(ssid, &ssidie[2], ssidlen); - } - rcu_read_unlock(); - - wfx_set_mfp(wvif, bss); - cfg80211_put_bss(wvif->wdev->hw->wiphy, bss); - - wvif->join_in_progress = true; - ret = hif_join(wvif, conf, wvif->channel, ssid, ssidlen); - if (ret) { - ieee80211_connection_loss(wvif->vif); - wfx_reset(wvif); - } else { - /* Due to beacon filtering it is possible that the - * AP's beacon is not known for the mac80211 stack. - * Disable filtering temporary to make sure the stack - * receives at least one - */ - wfx_filter_beacon(wvif, false); - } - wfx_tx_unlock(wvif->wdev); -} - int wfx_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta) { @@ -427,6 +291,9 @@ int wfx_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, sta_priv->vif_id = wvif->id; + if (vif->type == NL80211_IFTYPE_STATION) + hif_set_mfp(wvif, sta->mfp, sta->mfp); + // In station mode, the firmware interprets new link-id as a TDLS peer. if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) return 0; @@ -434,7 +301,7 @@ int wfx_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, wvif->link_id_map |= BIT(sta_priv->link_id); WARN_ON(!sta_priv->link_id); WARN_ON(sta_priv->link_id >= HIF_LINK_ID_MAX); - hif_map_link(wvif, sta->addr, 0, sta_priv->link_id); + hif_map_link(wvif, false, sta->addr, sta_priv->link_id, sta->mfp); return 0; } @@ -449,7 +316,7 @@ int wfx_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, if (!sta_priv->link_id) return 0; // FIXME add a mutex? - hif_map_link(wvif, sta->addr, 1, sta_priv->link_id); + hif_map_link(wvif, true, sta->addr, sta_priv->link_id, false); wvif->link_id_map &= ~BIT(sta_priv->link_id); return 0; } @@ -474,6 +341,31 @@ static int wfx_upload_ap_templates(struct wfx_vif *wvif) return 0; } +static void wfx_set_mfp_ap(struct wfx_vif *wvif) +{ + struct sk_buff *skb = ieee80211_beacon_get(wvif->wdev->hw, wvif->vif); + const int ieoffset = offsetof(struct ieee80211_mgmt, u.beacon.variable); + const u16 *ptr = (u16 *)cfg80211_find_ie(WLAN_EID_RSN, + skb->data + ieoffset, + skb->len - ieoffset); + const int pairwise_cipher_suite_count_offset = 8 / sizeof(u16); + const int pairwise_cipher_suite_size = 4 / sizeof(u16); + const int akm_suite_size = 4 / sizeof(u16); + + if (ptr) { + ptr += pairwise_cipher_suite_count_offset; + if (WARN_ON(ptr > (u16 *)skb_tail_pointer(skb))) + return; + ptr += 1 + pairwise_cipher_suite_size * *ptr; + if (WARN_ON(ptr > (u16 *)skb_tail_pointer(skb))) + return; + ptr += 1 + akm_suite_size * *ptr; + if (WARN_ON(ptr > (u16 *)skb_tail_pointer(skb))) + return; + hif_set_mfp(wvif, *ptr & BIT(7), *ptr & BIT(6)); + } +} + int wfx_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { struct wfx_vif *wvif = (struct wfx_vif *)vif->drv_priv; @@ -488,6 +380,7 @@ int wfx_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif) ret = hif_start(wvif, &vif->bss_conf, wvif->channel); if (ret > 0) return -EIO; + wfx_set_mfp_ap(wvif); return ret; } @@ -498,11 +391,74 @@ void wfx_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif) wfx_reset(wvif); } +static void wfx_join(struct wfx_vif *wvif) +{ + int ret; + struct ieee80211_bss_conf *conf = &wvif->vif->bss_conf; + struct cfg80211_bss *bss = NULL; + u8 ssid[IEEE80211_MAX_SSID_LEN]; + const u8 *ssidie = NULL; + int ssidlen = 0; + + wfx_tx_lock_flush(wvif->wdev); + + bss = cfg80211_get_bss(wvif->wdev->hw->wiphy, wvif->channel, + conf->bssid, NULL, 0, + IEEE80211_BSS_TYPE_ANY, IEEE80211_PRIVACY_ANY); + if (!bss && !conf->ibss_joined) { + wfx_tx_unlock(wvif->wdev); + return; + } + + rcu_read_lock(); // protect ssidie + if (bss) + ssidie = ieee80211_bss_get_ie(bss, WLAN_EID_SSID); + if (ssidie) { + ssidlen = ssidie[1]; + if (ssidlen > IEEE80211_MAX_SSID_LEN) + ssidlen = IEEE80211_MAX_SSID_LEN; + memcpy(ssid, &ssidie[2], ssidlen); + } + rcu_read_unlock(); + + cfg80211_put_bss(wvif->wdev->hw->wiphy, bss); + + wvif->join_in_progress = true; + ret = hif_join(wvif, conf, wvif->channel, ssid, ssidlen); + if (ret) { + ieee80211_connection_loss(wvif->vif); + wfx_reset(wvif); + } else { + /* Due to beacon filtering it is possible that the + * AP's beacon is not known for the mac80211 stack. + * Disable filtering temporary to make sure the stack + * receives at least one + */ + wfx_filter_beacon(wvif, false); + } + wfx_tx_unlock(wvif->wdev); +} + static void wfx_join_finalize(struct wfx_vif *wvif, struct ieee80211_bss_conf *info) { + struct ieee80211_sta *sta = NULL; + int ampdu_density = 0; + bool greenfield = false; + + rcu_read_lock(); // protect sta + if (info->bssid && !info->ibss_joined) + sta = ieee80211_find_sta(wvif->vif, info->bssid); + if (sta && sta->ht_cap.ht_supported) + ampdu_density = sta->ht_cap.ampdu_density; + if (sta && sta->ht_cap.ht_supported && + !(info->ht_operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT)) + greenfield = !!(sta->ht_cap.cap & IEEE80211_HT_CAP_GRN_FLD); + rcu_read_unlock(); + wvif->join_in_progress = false; - hif_set_association_mode(wvif, info); + hif_set_association_mode(wvif, ampdu_density, greenfield, + info->use_short_preamble); hif_keep_alive_period(wvif, 0); // beacon_loss_count is defined to 7 in net/mac80211/mlme.c. Let's use // the same value. @@ -516,7 +472,7 @@ int wfx_join_ibss(struct ieee80211_hw *hw, struct ieee80211_vif *vif) struct wfx_vif *wvif = (struct wfx_vif *)vif->drv_priv; wfx_upload_ap_templates(wvif); - wfx_do_join(wvif); + wfx_join(wvif); return 0; } @@ -549,32 +505,22 @@ void wfx_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, mutex_lock(&wdev->conf_mutex); - /* TODO: BSS_CHANGED_QOS */ - if (changed & BSS_CHANGED_ARP_FILTER) { - for (i = 0; i < HIF_MAX_ARP_IP_ADDRTABLE_ENTRIES; i++) { - __be32 *arp_addr = &info->arp_addr_list[i]; - - if (info->arp_addr_cnt > HIF_MAX_ARP_IP_ADDRTABLE_ENTRIES) - arp_addr = NULL; - if (i >= info->arp_addr_cnt) - arp_addr = NULL; - hif_set_arp_ipv4_filter(wvif, i, arp_addr); - } - } - if (changed & BSS_CHANGED_BASIC_RATES || changed & BSS_CHANGED_BEACON_INT || changed & BSS_CHANGED_BSSID) { if (vif->type == NL80211_IFTYPE_STATION) - wfx_do_join(wvif); + wfx_join(wvif); } - if (changed & BSS_CHANGED_AP_PROBE_RESP || - changed & BSS_CHANGED_BEACON) - wfx_upload_ap_templates(wvif); - - if (changed & BSS_CHANGED_BEACON_ENABLED) - wfx_enable_beacon(wvif, info->enable_beacon); + if (changed & BSS_CHANGED_ASSOC) { + if (info->assoc || info->ibss_joined) + wfx_join_finalize(wvif, info); + else if (!info->assoc && vif->type == NL80211_IFTYPE_STATION) + wfx_reset(wvif); + else + dev_warn(wdev->dev, "%s: misunderstood change: ASSOC\n", + __func__); + } if (changed & BSS_CHANGED_BEACON_INFO) { if (vif->type != NL80211_IFTYPE_STATION) @@ -587,16 +533,25 @@ void wfx_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, wfx_filter_beacon(wvif, true); } - if (changed & BSS_CHANGED_ASSOC) { - if (info->assoc || info->ibss_joined) - wfx_join_finalize(wvif, info); - else if (!info->assoc && vif->type == NL80211_IFTYPE_STATION) - wfx_reset(wvif); - else - dev_warn(wdev->dev, "%s: misunderstood change: ASSOC\n", - __func__); + if (changed & BSS_CHANGED_ARP_FILTER) { + for (i = 0; i < HIF_MAX_ARP_IP_ADDRTABLE_ENTRIES; i++) { + __be32 *arp_addr = &info->arp_addr_list[i]; + + if (info->arp_addr_cnt > HIF_MAX_ARP_IP_ADDRTABLE_ENTRIES) + arp_addr = NULL; + if (i >= info->arp_addr_cnt) + arp_addr = NULL; + hif_set_arp_ipv4_filter(wvif, i, arp_addr); + } } + if (changed & BSS_CHANGED_AP_PROBE_RESP || + changed & BSS_CHANGED_BEACON) + wfx_upload_ap_templates(wvif); + + if (changed & BSS_CHANGED_BEACON_ENABLED) + wfx_enable_beacon(wvif, info->enable_beacon); + if (changed & BSS_CHANGED_KEEP_ALIVE) hif_keep_alive_period(wvif, info->max_idle_period * USEC_PER_TU / USEC_PER_MSEC); @@ -664,6 +619,10 @@ int wfx_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, bool set) struct wfx_sta_priv *sta_dev = (struct wfx_sta_priv *)&sta->drv_priv; struct wfx_vif *wvif = wdev_to_wvif(wdev, sta_dev->vif_id); + if (!wvif) { + dev_warn(wdev->dev, "%s: received event for non-existent vif\n", __func__); + return -EIO; + } schedule_work(&wvif->update_tim_work); return 0; } @@ -682,15 +641,16 @@ int wfx_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_ampdu_params *params) { - /* Aggregation is implemented fully in firmware, - * including block ack negotiation. Do not allow - * mac80211 stack to do anything: it interferes with - * the firmware. - */ - - /* Note that we still need this function stubbed. */ - - return -ENOTSUPP; + // Aggregation is implemented fully in firmware + switch (params->action) { + case IEEE80211_AMPDU_RX_START: + case IEEE80211_AMPDU_RX_STOP: + // Just acknowledge it to enable frame re-ordering + return 0; + default: + // Leave the firmware doing its business for tx aggregation + return -ENOTSUPP; + } } int wfx_add_chanctx(struct ieee80211_hw *hw, @@ -760,17 +720,6 @@ int wfx_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) return -EOPNOTSUPP; } - for (i = 0; i < ARRAY_SIZE(wdev->vif); i++) { - if (!wdev->vif[i]) { - wdev->vif[i] = vif; - wvif->id = i; - break; - } - } - if (i == ARRAY_SIZE(wdev->vif)) { - mutex_unlock(&wdev->conf_mutex); - return -EOPNOTSUPP; - } // FIXME: prefer use of container_of() to get vif wvif->vif = vif; wvif->wdev = wdev; @@ -787,12 +736,22 @@ int wfx_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) init_completion(&wvif->scan_complete); INIT_WORK(&wvif->scan_work, wfx_hw_scan_work); - mutex_unlock(&wdev->conf_mutex); + wfx_tx_queues_init(wvif); + wfx_tx_policy_init(wvif); + + for (i = 0; i < ARRAY_SIZE(wdev->vif); i++) { + if (!wdev->vif[i]) { + wdev->vif[i] = vif; + wvif->id = i; + break; + } + } + WARN(i == ARRAY_SIZE(wdev->vif), "try to instantiate more vif than supported"); hif_set_macaddr(wvif, vif->addr); - wfx_tx_queues_init(wvif); - wfx_tx_policy_init(wvif); + mutex_unlock(&wdev->conf_mutex); + wvif = NULL; while ((wvif = wvif_iterate(wdev, wvif)) != NULL) { // Combo mode does not support Block Acks. We can re-enable them @@ -824,6 +783,7 @@ void wfx_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) wvif->vif = NULL; mutex_unlock(&wdev->conf_mutex); + wvif = NULL; while ((wvif = wvif_iterate(wdev, wvif)) != NULL) { // Combo mode does not support Block Acks. We can re-enable them diff --git a/drivers/staging/wfx/sta.h b/drivers/staging/wfx/sta.h index 6b15a64ac9e2..d7b5df5ea4e6 100644 --- a/drivers/staging/wfx/sta.h +++ b/drivers/staging/wfx/sta.h @@ -2,7 +2,7 @@ /* * Implementation of mac80211 API. * - * Copyright (c) 2017-2019, Silicon Laboratories, Inc. + * Copyright (c) 2017-2020, Silicon Laboratories, Inc. * Copyright (c) 2010, ST-Ericsson */ #ifndef WFX_STA_H @@ -25,8 +25,6 @@ int wfx_config(struct ieee80211_hw *hw, u32 changed); int wfx_set_rts_threshold(struct ieee80211_hw *hw, u32 value); void wfx_set_default_unicast_key(struct ieee80211_hw *hw, struct ieee80211_vif *vif, int idx); -u64 wfx_prepare_multicast(struct ieee80211_hw *hw, - struct netdev_hw_addr_list *mc_list); void wfx_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags, unsigned int *total_flags, u64 unused); diff --git a/drivers/staging/wfx/traces.h b/drivers/staging/wfx/traces.h index d376db2f1891..e34c7a538c65 100644 --- a/drivers/staging/wfx/traces.h +++ b/drivers/staging/wfx/traces.h @@ -2,7 +2,7 @@ /* * Tracepoints definitions. * - * Copyright (c) 2018-2019, Silicon Laboratories, Inc. + * Copyright (c) 2018-2020, Silicon Laboratories, Inc. */ #undef TRACE_SYSTEM diff --git a/drivers/staging/wfx/wfx.h b/drivers/staging/wfx/wfx.h index 38e24d7f72f2..94898680ccde 100644 --- a/drivers/staging/wfx/wfx.h +++ b/drivers/staging/wfx/wfx.h @@ -2,7 +2,7 @@ /* * Common private data for Silicon Labs WFx chips. * - * Copyright (c) 2017-2019, Silicon Laboratories, Inc. + * Copyright (c) 2017-2020, Silicon Laboratories, Inc. * Copyright (c) 2010, ST-Ericsson * Copyright (c) 2006, Michael Wu <flamingice@sourmilk.net> * Copyright 2004-2006 Jean-Baptiste Note <jbnote@gmail.com>, et al. @@ -20,7 +20,6 @@ #include "data_tx.h" #include "main.h" #include "queue.h" -#include "secure_link.h" #include "hif_tx.h" #define USEC_PER_TXOP 32 // see struct ieee80211_tx_queue_params @@ -41,7 +40,6 @@ struct wfx_dev { struct completion firmware_ready; struct hif_ind_startup hw_caps; struct wfx_hif hif; - struct sl_context sl; struct delayed_work cooling_timeout_work; bool poll_irq; bool chip_frozen; @@ -81,9 +79,6 @@ struct wfx_vif { struct work_struct update_tim_work; - int filter_mcast_count; - u8 filter_mcast_addr[8][ETH_ALEN]; - unsigned long uapsd_mask; /* avoid some operations in parallel with scan */ diff --git a/drivers/staging/wlan-ng/hfa384x_usb.c b/drivers/staging/wlan-ng/hfa384x_usb.c index 2720f7319a3d..f2a0e16b0318 100644 --- a/drivers/staging/wlan-ng/hfa384x_usb.c +++ b/drivers/staging/wlan-ng/hfa384x_usb.c @@ -191,9 +191,9 @@ static void hfa384x_usbctlx_resptimerfn(struct timer_list *t); static void hfa384x_usb_throttlefn(struct timer_list *t); -static void hfa384x_usbctlx_completion_task(unsigned long data); +static void hfa384x_usbctlx_completion_task(struct tasklet_struct *t); -static void hfa384x_usbctlx_reaper_task(unsigned long data); +static void hfa384x_usbctlx_reaper_task(struct tasklet_struct *t); static int hfa384x_usbctlx_submit(struct hfa384x *hw, struct hfa384x_usbctlx *ctlx); @@ -539,10 +539,8 @@ void hfa384x_create(struct hfa384x *hw, struct usb_device *usb) /* Initialize the authentication queue */ skb_queue_head_init(&hw->authq); - tasklet_init(&hw->reaper_bh, - hfa384x_usbctlx_reaper_task, (unsigned long)hw); - tasklet_init(&hw->completion_bh, - hfa384x_usbctlx_completion_task, (unsigned long)hw); + tasklet_setup(&hw->reaper_bh, hfa384x_usbctlx_reaper_task); + tasklet_setup(&hw->completion_bh, hfa384x_usbctlx_completion_task); INIT_WORK(&hw->link_bh, prism2sta_processing_defer); INIT_WORK(&hw->usb_work, hfa384x_usb_defer); @@ -2599,9 +2597,9 @@ void hfa384x_tx_timeout(struct wlandevice *wlandev) * Interrupt *---------------------------------------------------------------- */ -static void hfa384x_usbctlx_reaper_task(unsigned long data) +static void hfa384x_usbctlx_reaper_task(struct tasklet_struct *t) { - struct hfa384x *hw = (struct hfa384x *)data; + struct hfa384x *hw = from_tasklet(hw, t, reaper_bh); struct hfa384x_usbctlx *ctlx, *temp; unsigned long flags; @@ -2633,9 +2631,9 @@ static void hfa384x_usbctlx_reaper_task(unsigned long data) * Interrupt *---------------------------------------------------------------- */ -static void hfa384x_usbctlx_completion_task(unsigned long data) +static void hfa384x_usbctlx_completion_task(struct tasklet_struct *t) { - struct hfa384x *hw = (struct hfa384x *)data; + struct hfa384x *hw = from_tasklet(hw, t, completion_bh); struct hfa384x_usbctlx *ctlx, *temp; unsigned long flags; diff --git a/drivers/staging/wlan-ng/p80211netdev.c b/drivers/staging/wlan-ng/p80211netdev.c index 7b091c5a2984..a15abb2c8f54 100644 --- a/drivers/staging/wlan-ng/p80211netdev.c +++ b/drivers/staging/wlan-ng/p80211netdev.c @@ -266,15 +266,15 @@ static int p80211_convert_to_ether(struct wlandevice *wlandev, /** * p80211netdev_rx_bh - deferred processing of all received frames * - * @arg: pointer to WLAN network device structure (cast to unsigned long) + * @t: pointer to the tasklet associated with this handler */ -static void p80211netdev_rx_bh(unsigned long arg) +static void p80211netdev_rx_bh(struct tasklet_struct *t) { - struct wlandevice *wlandev = (struct wlandevice *)arg; + struct wlandevice *wlandev = from_tasklet(wlandev, t, rx_bh); struct sk_buff *skb = NULL; struct net_device *dev = wlandev->netdev; - /* Let's empty our our queue */ + /* Let's empty our queue */ while ((skb = skb_dequeue(&wlandev->nsd_rxq))) { if (wlandev->state == WLAN_DEVICE_OPEN) { if (dev->type != ARPHRD_ETHER) { @@ -728,8 +728,7 @@ int wlan_setup(struct wlandevice *wlandev, struct device *physdev) /* Set up the rx queue */ skb_queue_head_init(&wlandev->nsd_rxq); - tasklet_init(&wlandev->rx_bh, - p80211netdev_rx_bh, (unsigned long)wlandev); + tasklet_setup(&wlandev->rx_bh, p80211netdev_rx_bh); /* Allocate and initialize the wiphy struct */ wiphy = wlan_create_wiphy(physdev, wlandev); diff --git a/drivers/staging/wlan-ng/prism2mgmt.c b/drivers/staging/wlan-ng/prism2mgmt.c index a8860d2aee68..a908ff301707 100644 --- a/drivers/staging/wlan-ng/prism2mgmt.c +++ b/drivers/staging/wlan-ng/prism2mgmt.c @@ -228,8 +228,8 @@ int prism2mgmt_scan(struct wlandevice *wlandev, void *msgp) __le16 wordbuf[17]; result = hfa384x_drvr_setconfig16(hw, - HFA384x_RID_CNFROAMINGMODE, - HFA384x_ROAMMODE_HOSTSCAN_HOSTROAM); + HFA384x_RID_CNFROAMINGMODE, + HFA384x_ROAMMODE_HOSTSCAN_HOSTROAM); if (result) { netdev_err(wlandev->netdev, "setconfig(ROAMINGMODE) failed. result=%d\n", @@ -275,8 +275,8 @@ int prism2mgmt_scan(struct wlandevice *wlandev, void *msgp) } /* ibss options */ result = hfa384x_drvr_setconfig16(hw, - HFA384x_RID_CREATEIBSS, - HFA384x_CREATEIBSS_JOINCREATEIBSS); + HFA384x_RID_CREATEIBSS, + HFA384x_CREATEIBSS_JOINCREATEIBSS); if (result) { netdev_err(wlandev->netdev, "Failed to set CREATEIBSS.\n"); @@ -1167,8 +1167,8 @@ int prism2mgmt_wlansniff(struct wlandevice *wlandev, void *msgp) if (hw->presniff_port_type != 0) { word = hw->presniff_port_type; result = hfa384x_drvr_setconfig16(hw, - HFA384x_RID_CNFPORTTYPE, - word); + HFA384x_RID_CNFPORTTYPE, + word); if (result) { netdev_dbg (wlandev->netdev, @@ -1209,8 +1209,8 @@ int prism2mgmt_wlansniff(struct wlandevice *wlandev, void *msgp) } /* Save the wepflags state */ result = hfa384x_drvr_getconfig16(hw, - HFA384x_RID_CNFWEPFLAGS, - &hw->presniff_wepflags); + HFA384x_RID_CNFWEPFLAGS, + &hw->presniff_wepflags); if (result) { netdev_dbg (wlandev->netdev, @@ -1259,8 +1259,8 @@ int prism2mgmt_wlansniff(struct wlandevice *wlandev, void *msgp) /* Set the port type to pIbss */ word = HFA384x_PORTTYPE_PSUEDOIBSS; result = hfa384x_drvr_setconfig16(hw, - HFA384x_RID_CNFPORTTYPE, - word); + HFA384x_RID_CNFPORTTYPE, + word); if (result) { netdev_dbg (wlandev->netdev, @@ -1276,8 +1276,8 @@ int prism2mgmt_wlansniff(struct wlandevice *wlandev, void *msgp) HFA384x_WEPFLAGS_DISABLE_RXCRYPT; result = hfa384x_drvr_setconfig16(hw, - HFA384x_RID_CNFWEPFLAGS, - word); + HFA384x_RID_CNFWEPFLAGS, + word); } if (result) { diff --git a/drivers/staging/wlan-ng/prism2mib.c b/drivers/staging/wlan-ng/prism2mib.c index 7d7d77b04255..875812a391c9 100644 --- a/drivers/staging/wlan-ng/prism2mib.c +++ b/drivers/staging/wlan-ng/prism2mib.c @@ -292,7 +292,7 @@ int prism2mgmt_mibset_mibget(struct wlandevice *wlandev, void *msgp) /* ** Determine if this is a "mibget" or a "mibset". If this is a ** "mibget", then make sure that the MIB may be read. Otherwise, - ** this is a "mibset" so make make sure that the MIB may be written. + ** this is a "mibset" so make sure that the MIB may be written. */ isget = (msg->msgcode == DIDMSG_DOT11REQ_MIBGET); diff --git a/drivers/staging/wlan-ng/prism2sta.c b/drivers/staging/wlan-ng/prism2sta.c index 8f25496188aa..e6dcb687e7a1 100644 --- a/drivers/staging/wlan-ng/prism2sta.c +++ b/drivers/staging/wlan-ng/prism2sta.c @@ -461,7 +461,7 @@ u32 prism2sta_ifstate(struct wlandevice *wlandev, u32 ifstate) case WLAN_MSD_FWLOAD: wlandev->msdstate = WLAN_MSD_RUNNING_PENDING; /* Initialize the device+driver for full - * operation. Note that this might me an FWLOAD to + * operation. Note that this might me an FWLOAD * to RUNNING transition so we must not do a chip * or board level reset. Note that on failure, * the MSD state is set to HWPRESENT because we @@ -1352,7 +1352,7 @@ void prism2sta_processing_defer(struct work_struct *data) * we get back in range. We should block transmits and * receives in this state. Do we need an indication here? * Probably not since a polling user-mode element would - * get this status from from p2PortStatus(FD40). What about + * get this status from p2PortStatus(FD40). What about * p80211? * Response: * Block Transmits, Ignore receives of data frames diff --git a/include/linux/iio/buffer-dmaengine.h b/include/linux/iio/buffer-dmaengine.h index 0e503db71289..5b502291d6a4 100644 --- a/include/linux/iio/buffer-dmaengine.h +++ b/include/linux/iio/buffer-dmaengine.h @@ -10,10 +10,6 @@ struct iio_buffer; struct device; -struct iio_buffer *iio_dmaengine_buffer_alloc(struct device *dev, - const char *channel); -void iio_dmaengine_buffer_free(struct iio_buffer *buffer); - struct iio_buffer *devm_iio_dmaengine_buffer_alloc(struct device *dev, const char *channel); diff --git a/include/linux/iio/common/cros_ec_sensors_core.h b/include/linux/iio/common/cros_ec_sensors_core.h index caa8bb279a34..c9b80be82440 100644 --- a/include/linux/iio/common/cros_ec_sensors_core.h +++ b/include/linux/iio/common/cros_ec_sensors_core.h @@ -96,7 +96,8 @@ struct platform_device; int cros_ec_sensors_core_init(struct platform_device *pdev, struct iio_dev *indio_dev, bool physical_device, cros_ec_sensors_capture_t trigger_capture, - cros_ec_sensorhub_push_data_cb_t push_data); + cros_ec_sensorhub_push_data_cb_t push_data, + bool has_hw_fifo); irqreturn_t cros_ec_sensors_capture(int irq, void *p); int cros_ec_sensors_push_data(struct iio_dev *indio_dev, @@ -125,6 +126,5 @@ extern const struct dev_pm_ops cros_ec_sensors_pm_ops; /* List of extended channel specification for all sensors. */ extern const struct iio_chan_spec_ext_info cros_ec_sensors_ext_info[]; -extern const struct attribute *cros_ec_sensor_fifo_attributes[]; #endif /* __CROS_EC_SENSORS_CORE_H */ diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h index f1daaba9e706..f015fa185253 100644 --- a/include/linux/iio/iio.h +++ b/include/linux/iio/iio.h @@ -691,8 +691,9 @@ static inline void *iio_priv(const struct iio_dev *indio_dev) void iio_device_free(struct iio_dev *indio_dev); struct iio_dev *devm_iio_device_alloc(struct device *parent, int sizeof_priv); +__printf(2, 3) struct iio_trigger *devm_iio_trigger_alloc(struct device *dev, - const char *fmt, ...); + const char *fmt, ...); /** * iio_buffer_enabled() - helper function to test if the buffer is enabled * @indio_dev: IIO device structure for device diff --git a/include/linux/iio/imu/adis.h b/include/linux/iio/imu/adis.h index 2df67448f0d1..04e96d688ba9 100644 --- a/include/linux/iio/imu/adis.h +++ b/include/linux/iio/imu/adis.h @@ -20,7 +20,6 @@ #define ADIS_REG_PAGE_ID 0x00 struct adis; -struct adis_burst; /** * struct adis_timeouts - ADIS chip variant timeouts @@ -51,6 +50,11 @@ struct adis_timeout { * @timeouts: Chip specific delays * @enable_irq: Hook for ADIS devices that have a special IRQ enable/disable * @has_paging: True if ADIS device has paged registers + * @burst_reg_cmd: Register command that triggers burst + * @burst_len: Burst size in the SPI RX buffer. If @burst_max_len is defined, + * this should be the minimum size supported by the device. + * @burst_max_len: Holds the maximum burst size when the device supports + * more than one burst mode with different sizes */ struct adis_data { unsigned int read_delay; @@ -75,6 +79,10 @@ struct adis_data { int (*enable_irq)(struct adis *adis, bool enable); bool has_paging; + + unsigned int burst_reg_cmd; + unsigned int burst_len; + unsigned int burst_max_len; }; /** @@ -99,7 +107,6 @@ struct adis { struct iio_trigger *trig; const struct adis_data *data; - struct adis_burst *burst; unsigned int burst_extra_len; /** * The state_lock is meant to be used during operations that require @@ -499,32 +506,11 @@ int adis_single_conversion(struct iio_dev *indio_dev, #ifdef CONFIG_IIO_ADIS_LIB_BUFFER -/** - * struct adis_burst - ADIS data for burst transfers - * @en burst mode enabled - * @reg_cmd register command that triggers burst - * @extra_len extra length to account in the SPI RX buffer - * @burst_max_len holds the maximum burst size when the device supports - * more than one burst mode with different sizes - */ -struct adis_burst { - bool en; - unsigned int reg_cmd; - const u32 extra_len; - const u32 burst_max_len; -}; - int devm_adis_setup_buffer_and_trigger(struct adis *adis, struct iio_dev *indio_dev, irq_handler_t trigger_handler); -int adis_setup_buffer_and_trigger(struct adis *adis, - struct iio_dev *indio_dev, irqreturn_t (*trigger_handler)(int, void *)); -void adis_cleanup_buffer_and_trigger(struct adis *adis, - struct iio_dev *indio_dev); int devm_adis_probe_trigger(struct adis *adis, struct iio_dev *indio_dev); -int adis_probe_trigger(struct adis *adis, struct iio_dev *indio_dev); -void adis_remove_trigger(struct adis *adis); int adis_update_scan_mode(struct iio_dev *indio_dev, const unsigned long *scan_mask); @@ -538,33 +524,12 @@ devm_adis_setup_buffer_and_trigger(struct adis *adis, struct iio_dev *indio_dev, return 0; } -static inline int adis_setup_buffer_and_trigger(struct adis *adis, - struct iio_dev *indio_dev, irqreturn_t (*trigger_handler)(int, void *)) -{ - return 0; -} - -static inline void adis_cleanup_buffer_and_trigger(struct adis *adis, - struct iio_dev *indio_dev) -{ -} - static inline int devm_adis_probe_trigger(struct adis *adis, struct iio_dev *indio_dev) { return 0; } -static inline int adis_probe_trigger(struct adis *adis, - struct iio_dev *indio_dev) -{ - return 0; -} - -static inline void adis_remove_trigger(struct adis *adis) -{ -} - #define adis_update_scan_mode NULL #endif /* CONFIG_IIO_BUFFER */ diff --git a/include/linux/iio/trigger_consumer.h b/include/linux/iio/trigger_consumer.h index 3aa2f132dd67..2c05dfad88d7 100644 --- a/include/linux/iio/trigger_consumer.h +++ b/include/linux/iio/trigger_consumer.h @@ -38,7 +38,7 @@ struct iio_poll_func { }; -struct iio_poll_func +__printf(5, 6) struct iio_poll_func *iio_alloc_pollfunc(irqreturn_t (*h)(int irq, void *p), irqreturn_t (*thread)(int irq, void *p), int type, diff --git a/include/linux/iio/types.h b/include/linux/iio/types.h index e6fd3645963c..1e3ed6f55bca 100644 --- a/include/linux/iio/types.h +++ b/include/linux/iio/types.h @@ -59,6 +59,7 @@ enum iio_chan_info_enum { IIO_CHAN_INFO_CALIBEMISSIVITY, IIO_CHAN_INFO_OVERSAMPLING_RATIO, IIO_CHAN_INFO_THERMOCOUPLE_TYPE, + IIO_CHAN_INFO_CALIBAMBIENT, }; #endif /* _IIO_TYPES_H_ */ diff --git a/include/linux/mfd/hi6421-spmi-pmic.h b/include/linux/mfd/hi6421-spmi-pmic.h new file mode 100644 index 000000000000..2c8896fd852e --- /dev/null +++ b/include/linux/mfd/hi6421-spmi-pmic.h @@ -0,0 +1,53 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Header file for device driver Hi6421 PMIC + * + * Copyright (c) 2013 Linaro Ltd. + * Copyright (C) 2011 Hisilicon. + * + * Guodong Xu <guodong.xu@linaro.org> + */ + +#ifndef __HISI_PMIC_H +#define __HISI_PMIC_H + +#include <linux/irqdomain.h> + +#define HISI_REGS_ENA_PROTECT_TIME (0) /* in microseconds */ +#define HISI_ECO_MODE_ENABLE (1) +#define HISI_ECO_MODE_DISABLE (0) + +struct hi6421_spmi_pmic { + struct resource *res; + struct device *dev; + void __iomem *regs; + spinlock_t lock; + struct irq_domain *domain; + int irq; + int gpio; + unsigned int *irqs; +}; + +int hi6421_spmi_pmic_read(struct hi6421_spmi_pmic *pmic, int reg); +int hi6421_spmi_pmic_write(struct hi6421_spmi_pmic *pmic, int reg, u32 val); +int hi6421_spmi_pmic_rmw(struct hi6421_spmi_pmic *pmic, int reg, + u32 mask, u32 bits); + +enum hi6421_spmi_pmic_irq_list { + OTMP = 0, + VBUS_CONNECT, + VBUS_DISCONNECT, + ALARMON_R, + HOLD_6S, + HOLD_1S, + POWERKEY_UP, + POWERKEY_DOWN, + OCP_SCP_R, + COUL_R, + SIM0_HPD_R, + SIM0_HPD_F, + SIM1_HPD_R, + SIM1_HPD_F, + PMIC_IRQ_LIST_MAX, +}; +#endif /* __HISI_PMIC_H */ diff --git a/include/linux/platform_data/ad7291.h b/include/linux/platform_data/ad7291.h deleted file mode 100644 index b1fd1530c9a5..000000000000 --- a/include/linux/platform_data/ad7291.h +++ /dev/null @@ -1,13 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef __IIO_AD7291_H__ -#define __IIO_AD7291_H__ - -/** - * struct ad7291_platform_data - AD7291 platform data - * @use_external_ref: Whether to use an external or internal reference voltage - */ -struct ad7291_platform_data { - bool use_external_ref; -}; - -#endif diff --git a/include/linux/platform_data/ad7793.h b/include/linux/platform_data/ad7793.h index 576c7f962c4e..7c697e58f02a 100644 --- a/include/linux/platform_data/ad7793.h +++ b/include/linux/platform_data/ad7793.h @@ -40,7 +40,7 @@ enum ad7793_bias_voltage { * enum ad7793_refsel - AD7793 reference voltage selection * @AD7793_REFSEL_REFIN1: External reference applied between REFIN1(+) * and REFIN1(-). - * @AD7793_REFSEL_REFIN2: External reference applied between REFIN2(+) and + * @AD7793_REFSEL_REFIN2: External reference applied between REFIN2(+) * and REFIN1(-). Only valid for AD7795/AD7796. * @AD7793_REFSEL_INTERNAL: Internal 1.17 V reference. */ diff --git a/include/uapi/linux/iio/types.h b/include/uapi/linux/iio/types.h index fdd81affca4b..48c13147c0a8 100644 --- a/include/uapi/linux/iio/types.h +++ b/include/uapi/linux/iio/types.h @@ -94,6 +94,7 @@ enum iio_modifier { IIO_MOD_PM10, IIO_MOD_ETHANOL, IIO_MOD_H2, + IIO_MOD_O2, }; enum iio_event_type { diff --git a/tools/iio/iio_event_monitor.c b/tools/iio/iio_event_monitor.c index f115d166c985..bb03859db89d 100644 --- a/tools/iio/iio_event_monitor.c +++ b/tools/iio/iio_event_monitor.c @@ -119,6 +119,7 @@ static const char * const iio_modifier_names[] = { [IIO_MOD_PM2P5] = "pm2p5", [IIO_MOD_PM4] = "pm4", [IIO_MOD_PM10] = "pm10", + [IIO_MOD_O2] = "o2", }; static bool event_is_known(struct iio_event_data *event) @@ -211,6 +212,7 @@ static bool event_is_known(struct iio_event_data *event) case IIO_MOD_PM2P5: case IIO_MOD_PM4: case IIO_MOD_PM10: + case IIO_MOD_O2: break; default: return false; |