Merge ed6c23b175 ("Merge tag 'pinctrl-v6.8-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl") into android-mainline

Steps on the way to v6.8-rc1

Signed-off-by: Lee Jones <joneslee@google.com>
Change-Id: Ide9aeec28438a0b0ae9f0783b0657f3b249a607e
This commit is contained in:
Lee Jones
2024-03-27 11:17:18 +00:00
248 changed files with 10505 additions and 2406 deletions
@@ -114,6 +114,45 @@ Description:
speed of 1000Mbps of the named network device.
Setting this value also immediately changes the LED state.
What: /sys/class/leds/<led>/link_2500
Date: Nov 2023
KernelVersion: 6.8
Contact: linux-leds@vger.kernel.org
Description:
Signal the link speed state of 2500Mbps of the named network device.
If set to 0 (default), the LED's normal state is off.
If set to 1, the LED's normal state reflects the link state
speed of 2500Mbps of the named network device.
Setting this value also immediately changes the LED state.
What: /sys/class/leds/<led>/link_5000
Date: Nov 2023
KernelVersion: 6.8
Contact: linux-leds@vger.kernel.org
Description:
Signal the link speed state of 5000Mbps of the named network device.
If set to 0 (default), the LED's normal state is off.
If set to 1, the LED's normal state reflects the link state
speed of 5000Mbps of the named network device.
Setting this value also immediately changes the LED state.
What: /sys/class/leds/<led>/link_10000
Date: Nov 2023
KernelVersion: 6.8
Contact: linux-leds@vger.kernel.org
Description:
Signal the link speed state of 10000Mbps of the named network device.
If set to 0 (default), the LED's normal state is off.
If set to 1, the LED's normal state reflects the link state
speed of 10000Mbps of the named network device.
Setting this value also immediately changes the LED state.
What: /sys/class/leds/<led>/half_duplex
Date: Jun 2023
KernelVersion: 6.5
@@ -4,3 +4,59 @@ KernelVersion: 5.10
Contact: linux-leds@vger.kernel.org
Description:
Specifies the tty device name of the triggering tty
What: /sys/class/leds/<led>/rx
Date: February 2024
KernelVersion: 6.8
Description:
Signal reception (rx) of data on the named tty device.
If set to 0, the LED will not blink on reception.
If set to 1 (default), the LED will blink on reception.
What: /sys/class/leds/<led>/tx
Date: February 2024
KernelVersion: 6.8
Description:
Signal transmission (tx) of data on the named tty device.
If set to 0, the LED will not blink on transmission.
If set to 1 (default), the LED will blink on transmission.
What: /sys/class/leds/<led>/cts
Date: February 2024
KernelVersion: 6.8
Description:
CTS = Clear To Send
DCE is ready to accept data from the DTE.
If the line state is detected, the LED is switched on.
If set to 0 (default), the LED will not evaluate CTS.
If set to 1, the LED will evaluate CTS.
What: /sys/class/leds/<led>/dsr
Date: February 2024
KernelVersion: 6.8
Description:
DSR = Data Set Ready
DCE is ready to receive and send data.
If the line state is detected, the LED is switched on.
If set to 0 (default), the LED will not evaluate DSR.
If set to 1, the LED will evaluate DSR.
What: /sys/class/leds/<led>/dcd
Date: February 2024
KernelVersion: 6.8
Description:
DCD = Data Carrier Detect
DTE is receiving a carrier from the DCE.
If the line state is detected, the LED is switched on.
If set to 0 (default), the LED will not evaluate CAR (DCD).
If set to 1, the LED will evaluate CAR (DCD).
What: /sys/class/leds/<led>/rng
Date: February 2024
KernelVersion: 6.8
Description:
RNG = Ring Indicator
DCE has detected an incoming ring signal on the telephone
line. If the line state is detected, the LED is switched on.
If set to 0 (default), the LED will not evaluate RNG.
If set to 1, the LED will evaluate RNG.
@@ -0,0 +1,137 @@
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/leds/allwinner,sun50i-a100-ledc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Allwinner A100 LED Controller
maintainers:
- Samuel Holland <samuel@sholland.org>
description:
The LED controller found in Allwinner sunxi SoCs uses a one-wire serial
interface to drive up to 1024 RGB LEDs.
properties:
compatible:
oneOf:
- const: allwinner,sun50i-a100-ledc
- items:
- enum:
- allwinner,sun20i-d1-ledc
- allwinner,sun50i-r329-ledc
- const: allwinner,sun50i-a100-ledc
reg:
maxItems: 1
"#address-cells":
const: 1
"#size-cells":
const: 0
interrupts:
maxItems: 1
clocks:
items:
- description: Bus clock
- description: Module clock
clock-names:
items:
- const: bus
- const: mod
resets:
maxItems: 1
dmas:
maxItems: 1
description: TX DMA channel
dma-names:
const: tx
allwinner,pixel-format:
description: Pixel format (subpixel transmission order), default is "grb"
enum:
- bgr
- brg
- gbr
- grb
- rbg
- rgb
allwinner,t0h-ns:
default: 336
description: Length of high pulse when transmitting a "0" bit
allwinner,t0l-ns:
default: 840
description: Length of low pulse when transmitting a "0" bit
allwinner,t1h-ns:
default: 882
description: Length of high pulse when transmitting a "1" bit
allwinner,t1l-ns:
default: 294
description: Length of low pulse when transmitting a "1" bit
allwinner,treset-ns:
default: 300000
description: Minimum delay between transmission frames
patternProperties:
"^multi-led@[0-9a-f]+$":
type: object
$ref: leds-class-multicolor.yaml#
unevaluatedProperties: false
properties:
reg:
minimum: 0
maximum: 1023
description: Index of the LED in the series (must be contiguous)
required:
- reg
required:
- compatible
- reg
- interrupts
- clocks
- clock-names
- resets
additionalProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/leds/common.h>
ledc: led-controller@2008000 {
compatible = "allwinner,sun20i-d1-ledc",
"allwinner,sun50i-a100-ledc";
reg = <0x2008000 0x400>;
interrupts = <36 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&ccu 12>, <&ccu 34>;
clock-names = "bus", "mod";
resets = <&ccu 12>;
dmas = <&dma 42>;
dma-names = "tx";
#address-cells = <1>;
#size-cells = <0>;
multi-led@0 {
reg = <0x0>;
color = <LED_COLOR_ID_RGB>;
function = LED_FUNCTION_INDICATOR;
};
};
...
@@ -10,15 +10,19 @@ maintainers:
- Martin Kurbanov <mmkurbanov@sberdevices.ru>
description: |
This controller is present on AW20036/AW20054/AW20072.
It is a 3x12/6x9/6x12 matrix LED programmed via
an I2C interface, up to 36/54/72 LEDs or 12/18/24 RGBs,
3 pattern controllers for auto breathing or group dimming control.
It is a matrix LED driver programmed via an I2C interface. Devices have
a set of individually controlled leds and support 3 pattern controllers
for auto breathing or group dimming control. Supported devices:
- AW20036 (3x12) 36 LEDs
- AW20054 (6x9) 54 LEDs
- AW20072 (6x12) 72 LEDs
- AW20108 (9x12) 108 LEDs
For more product information please see the link below:
aw20036 - https://www.awinic.com/en/productDetail/AW20036QNR#tech-docs
aw20054 - https://www.awinic.com/en/productDetail/AW20054QNR#tech-docs
aw20072 - https://www.awinic.com/en/productDetail/AW20072QNR#tech-docs
aw20108 - https://www.awinic.com/en/productDetail/AW20108QNR#tech-docs
properties:
compatible:
@@ -26,6 +30,7 @@ properties:
- awinic,aw20036
- awinic,aw20054
- awinic,aw20072
- awinic,aw20108
reg:
maxItems: 1
@@ -36,13 +41,11 @@ properties:
"#size-cells":
const: 0
awinic,display-rows:
$ref: /schemas/types.yaml#/definitions/uint32
description:
Leds matrix size
enable-gpios:
maxItems: 1
patternProperties:
"^led@[0-9a-f]$":
"^led@[0-9a-f]+$":
type: object
$ref: common.yaml#
unevaluatedProperties: false
@@ -60,16 +63,11 @@ patternProperties:
since the chip has a single global setting.
The maximum output current of each LED is calculated by the
following formula:
IMAXled = 160000 * (592 / 600.5) * (1 / display-rows)
IMAXled = 160000 * (592 / 600.5) * (1 / max-current-switch-number)
And the minimum output current formula:
IMINled = 3300 * (592 / 600.5) * (1 / display-rows)
required:
- compatible
- reg
- "#address-cells"
- "#size-cells"
- awinic,display-rows
IMINled = 3300 * (592 / 600.5) * (1 / max-current-switch-number)
where max-current-switch-number is determinated by led configuration
and depends on how leds are physically connected to the led driver.
allOf:
- if:
@@ -78,18 +76,67 @@ allOf:
contains:
const: awinic,aw20036
then:
patternProperties:
"^led@[0-9a-f]+$":
properties:
reg:
items:
minimum: 0
maximum: 36
- if:
properties:
awinic,display-rows:
enum: [1, 2, 3]
else:
compatible:
contains:
const: awinic,aw20054
then:
patternProperties:
"^led@[0-9a-f]+$":
properties:
reg:
items:
minimum: 0
maximum: 54
- if:
properties:
awinic,display-rows:
enum: [1, 2, 3, 4, 5, 6, 7]
compatible:
contains:
const: awinic,aw20072
then:
patternProperties:
"^led@[0-9a-f]+$":
properties:
reg:
items:
minimum: 0
maximum: 72
- if:
properties:
compatible:
contains:
const: awinic,aw20108
then:
patternProperties:
"^led@[0-9a-f]+$":
properties:
reg:
items:
minimum: 0
maximum: 108
required:
- compatible
- reg
- "#address-cells"
- "#size-cells"
additionalProperties: false
examples:
- |
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/leds/common.h>
i2c {
@@ -101,7 +148,7 @@ examples:
reg = <0x3a>;
#address-cells = <1>;
#size-cells = <0>;
awinic,display-rows = <3>;
enable-gpios = <&gpio 3 GPIO_ACTIVE_HIGH>;
led@0 {
reg = <0x0>;
@@ -167,7 +167,7 @@ properties:
Note that this flag is mainly used for PWM-LEDs, where it is not possible
to map brightness to current. Drivers for other controllers should use
led-max-microamp.
$ref: /schemas/types.yaml#definitions/uint32
$ref: /schemas/types.yaml#/definitions/uint32
panic-indicator:
description:
@@ -89,9 +89,11 @@ additionalProperties: false
examples:
- |
#include <dt-bindings/leds/common.h>
spmi {
pmic {
#address-cells = <1>;
#size-cells = <0>;
led-controller@ee00 {
compatible = "qcom,pm8350c-flash-led", "qcom,spmi-flash-led";
reg = <0xee00>;
@@ -23,6 +23,24 @@ properties:
- qcom,ipq8074-apcs-apps-global
- qcom,ipq9574-apcs-apps-global
- const: qcom,ipq6018-apcs-apps-global
- items:
- enum:
- qcom,qcs404-apcs-apps-global
- const: qcom,msm8916-apcs-kpss-global
- const: syscon
- items:
- enum:
- qcom,msm8976-apcs-kpss-global
- const: qcom,msm8994-apcs-kpss-global
- const: syscon
- items:
- enum:
- qcom,msm8998-apcs-hmss-global
- qcom,sdm660-apcs-hmss-global
- qcom,sm4250-apcs-hmss-global
- qcom,sm6115-apcs-hmss-global
- qcom,sm6125-apcs-hmss-global
- const: qcom,msm8994-apcs-kpss-global
- items:
- enum:
- qcom,sc7180-apss-shared
@@ -34,22 +52,14 @@ properties:
- qcom,msm8916-apcs-kpss-global
- qcom,msm8939-apcs-kpss-global
- qcom,msm8953-apcs-kpss-global
- qcom,msm8976-apcs-kpss-global
- qcom,msm8994-apcs-kpss-global
- qcom,qcs404-apcs-apps-global
- qcom,sdx55-apcs-gcc
- const: syscon
- enum:
- qcom,ipq6018-apcs-apps-global
- qcom,ipq8074-apcs-apps-global
- qcom,msm8996-apcs-hmss-global
- qcom,msm8998-apcs-hmss-global
- qcom,qcm2290-apcs-hmss-global
- qcom,sdm660-apcs-hmss-global
- qcom,sdm845-apss-shared
- qcom,sm4250-apcs-hmss-global
- qcom,sm6115-apcs-hmss-global
- qcom,sm6125-apcs-hmss-global
reg:
maxItems: 1
@@ -80,10 +90,9 @@ allOf:
- if:
properties:
compatible:
enum:
- qcom,msm8916-apcs-kpss-global
- qcom,msm8939-apcs-kpss-global
- qcom,qcs404-apcs-apps-global
contains:
enum:
- qcom,msm8916-apcs-kpss-global
then:
properties:
clocks:
@@ -95,6 +104,25 @@ allOf:
- const: pll
- const: aux
- if:
properties:
compatible:
contains:
enum:
- qcom,msm8939-apcs-kpss-global
then:
properties:
clocks:
items:
- description: primary pll parent of the clock driver
- description: auxiliary parent
- description: reference clock
clock-names:
items:
- const: pll
- const: aux
- const: ref
- if:
properties:
compatible:
@@ -113,6 +141,7 @@ allOf:
- const: ref
- const: pll
- const: aux
- if:
properties:
compatible:
@@ -137,16 +166,10 @@ allOf:
compatible:
enum:
- qcom,msm8953-apcs-kpss-global
- qcom,msm8976-apcs-kpss-global
- qcom,msm8994-apcs-kpss-global
- qcom,msm8996-apcs-hmss-global
- qcom,msm8998-apcs-hmss-global
- qcom,qcm2290-apcs-hmss-global
- qcom,sdm660-apcs-hmss-global
- qcom,sdm845-apss-shared
- qcom,sm4250-apcs-hmss-global
- qcom,sm6115-apcs-hmss-global
- qcom,sm6125-apcs-hmss-global
then:
properties:
clocks: false
@@ -192,7 +215,8 @@ examples:
#define GCC_APSS_AHB_CLK_SRC 1
#define GCC_GPLL0_AO_OUT_MAIN 123
apcs: mailbox@b011000 {
compatible = "qcom,qcs404-apcs-apps-global", "syscon";
compatible = "qcom,qcs404-apcs-apps-global",
"qcom,msm8916-apcs-kpss-global", "syscon";
reg = <0x0b011000 0x1000>;
#mbox-cells = <1>;
clocks = <&apcs_hfpll>, <&gcc GCC_GPLL0_AO_OUT_MAIN>;
@@ -35,6 +35,7 @@ properties:
- qcom,sm8450-ipcc
- qcom,sm8550-ipcc
- qcom,sm8650-ipcc
- qcom,x1e80100-ipcc
- const: qcom,ipcc
reg:
@@ -37,7 +37,9 @@ maintainers:
properties:
compatible:
const: xlnx,zynqmp-ipi-mailbox
enum:
- xlnx,zynqmp-ipi-mailbox
- xlnx,versal-ipi-mailbox
method:
description: |
@@ -58,6 +60,12 @@ properties:
'#size-cells':
const: 2
reg:
maxItems: 2
reg-names:
maxItems: 2
xlnx,ipi-id:
description: |
Remote Xilinx IPI agent ID of which the mailbox is connected to.
@@ -76,7 +84,17 @@ patternProperties:
properties:
compatible:
const: xlnx,zynqmp-ipi-dest-mailbox
enum:
- xlnx,zynqmp-ipi-dest-mailbox
- xlnx,versal-ipi-dest-mailbox
reg:
minItems: 1
maxItems: 4
reg-names:
minItems: 1
maxItems: 4
xlnx,ipi-id:
description:
@@ -88,23 +106,44 @@ patternProperties:
description:
It contains tx(0) or rx(1) channel IPI id number.
reg:
maxItems: 4
allOf:
- if:
properties:
compatible:
contains:
enum:
- xlnx,zynqmp-ipi-dest-mailbox
then:
properties:
reg:
maxItems: 4
reg-names:
items:
- const: local_request_region
- const: local_response_region
- const: remote_request_region
- const: remote_response_region
reg-names:
items:
- const: local_request_region
- const: local_response_region
- const: remote_request_region
- const: remote_response_region
else:
properties:
reg:
minItems: 1
items:
- description: Remote IPI agent control register region
- description: Remote IPI agent optional message buffers
reg-names:
minItems: 1
items:
- const: ctrl
- const: msg
required:
- compatible
- reg
- reg-names
- "#mbox-cells"
additionalProperties: false
- xlnx,ipi-id
required:
- compatible
@@ -113,6 +152,36 @@ required:
- '#size-cells'
- xlnx,ipi-id
allOf:
- if:
properties:
compatible:
contains:
enum:
- xlnx,zynqmp-ipi-mailbox
then:
properties:
reg: false
reg-names: false
else:
properties:
reg:
items:
- description: Host IPI agent control register region
- description: Host IPI agent optional message buffers
reg-names:
items:
- const: ctrl
- const: msg
required:
- reg
- reg-names
additionalProperties: false
examples:
- |
#include<dt-bindings/interrupt-controller/arm-gic.h>
@@ -144,4 +213,41 @@ examples:
};
};
- |
#include<dt-bindings/interrupt-controller/arm-gic.h>
bus {
#address-cells = <2>;
#size-cells = <2>;
mailbox@ff300000 {
compatible = "xlnx,versal-ipi-mailbox";
interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <2>;
#size-cells = <2>;
reg = <0x0 0xff300000 0x0 0x1000>,
<0x0 0xff990000 0x0 0x1ff>;
reg-names = "ctrl", "msg";
xlnx,ipi-id = <0>;
ranges;
/* buffered IPI */
mailbox@ff340000 {
compatible = "xlnx,versal-ipi-dest-mailbox";
reg = <0x0 0xff340000 0x0 0x1000>,
<0x0 0xff990400 0x0 0x1ff>;
reg-names = "ctrl", "msg";
#mbox-cells = <1>;
xlnx,ipi-id = <4>;
};
/* bufferless IPI */
mailbox@ff370000 {
compatible = "xlnx,versal-ipi-dest-mailbox";
reg = <0x0 0xff370000 0x0 0x1000>;
reg-names = "ctrl";
#mbox-cells = <1>;
xlnx,ipi-id = <7>;
};
};
};
...
@@ -0,0 +1,223 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/mfd/ams,as3711.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Austria MicroSystems AS3711 Quad Buck High Current PMIC with Charger
maintainers:
- Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
description:
AS3711 is an I2C PMIC from Austria MicroSystems with multiple DC/DC and LDO
power supplies, a battery charger and an RTC. So far only bindings for the
two step-up DC/DC converters are defined.
properties:
compatible:
const: ams,as3711
reg:
maxItems: 1
backlight:
description:
Step-up converter configuration, to be used as a backlight source
type: object
additionalProperties: false
properties:
compatible:
const: ams,as3711-bl
su1-dev:
description: Framebuffer phandle for the first step-up converter
$ref: /schemas/types.yaml#/definitions/phandle
su1-max-uA:
description: Maximum current for the first step-up converter
$ref: /schemas/types.yaml#/definitions/uint32
su2-dev:
description: Framebuffer phandle for the second step-up converter
$ref: /schemas/types.yaml#/definitions/phandle
su2-max-uA:
description: Maximum current for the second step-up converter
$ref: /schemas/types.yaml#/definitions/uint32
su2-feedback-voltage:
description: Second step-up converter uses voltage feedback
type: boolean
su2-feedback-curr1:
description:
Second step-up converter uses CURR1 input for current feedback
type: boolean
su2-feedback-curr2:
description:
Second step-up converter uses CURR2 input for current feedback
type: boolean
su2-feedback-curr3:
description:
Second step-up converter uses CURR3 input for current feedback
type: boolean
su2-feedback-curr-auto:
description:
Second step-up converter uses automatic current feedback selection
type: boolean
su2-fbprot-lx-sd4:
description:
Second step-up converter uses LX_SD4 for over-voltage protection
type: boolean
su2-fbprot-gpio2:
description:
Second step-up converter uses GPIO2 for over-voltage protection
type: boolean
su2-fbprot-gpio3:
description:
Second step-up converter uses GPIO3 for over-voltage protection
type: boolean
su2-fbprot-gpio4:
description:
Second step-up converter uses GPIO4 for over-voltage protection
type: boolean
su2-auto-curr1:
description:
Second step-up converter uses CURR1 input for automatic current
feedback
type: boolean
su2-auto-curr2:
description:
Second step-up converter uses CURR2 input for automatic current
feedback
type: boolean
su2-auto-curr3:
description:
Second step-up converter uses CURR3 input for automatic current
feedback
type: boolean
required:
- compatible
dependentRequired:
# To use the SU1 converter as a backlight source the following two
# properties must be provided:
su1-dev: [ su1-max-uA ]
su1-max-uA: [ su1-dev ]
# To use the SU2 converter as a backlight source the following two
# properties must be provided:
su2-dev: [ su2-max-uA ]
su2-max-uA: [ su2-dev ]
su2-feedback-voltage: [ su2-dev ]
su2-feedback-curr1: [ su2-dev ]
su2-feedback-curr2: [ su2-dev ]
su2-feedback-curr3: [ su2-dev ]
su2-feedback-curr-auto: [ su2-dev ]
su2-fbprot-lx-sd4: [ su2-dev ]
su2-fbprot-gpio2: [ su2-dev ]
su2-fbprot-gpio3: [ su2-dev ]
su2-fbprot-gpio4: [ su2-dev ]
su2-auto-curr1: [ su2-feedback-curr-auto ]
su2-auto-curr2: [ su2-feedback-curr-auto ]
su2-auto-curr3: [ su2-feedback-curr-auto ]
dependentSchemas:
su2-dev:
allOf:
- oneOf:
- required:
- su2-feedback-voltage
- required:
- su2-feedback-curr1
- required:
- su2-feedback-curr2
- required:
- su2-feedback-curr3
- required:
- su2-feedback-curr-auto
- oneOf:
- required:
- su2-fbprot-lx-sd4
- required:
- su2-fbprot-gpio2
- required:
- su2-fbprot-gpio3
- required:
- su2-fbprot-gpio4
su2-feedback-curr-auto:
anyOf:
- required:
- su2-auto-curr1
- required:
- su2-auto-curr2
- required:
- su2-auto-curr3
regulators:
description: Other DC/DC and LDO supplies
type: object
unevaluatedProperties: false
patternProperties:
"^(sd[1-4]|ldo[1-8])$":
type: object
$ref: /schemas/regulator/regulator.yaml#
unevaluatedProperties: false
required:
- compatible
- reg
additionalProperties: false
examples:
- |
i2c {
#address-cells = <1>;
#size-cells = <0>;
pmic@40 {
compatible = "ams,as3711";
reg = <0x40>;
regulators {
sd4 {
regulator-name = "1.215V";
regulator-min-microvolt = <1215000>;
regulator-max-microvolt = <1235000>;
};
ldo2 {
regulator-name = "2.8V CPU";
regulator-min-microvolt = <2800000>;
regulator-max-microvolt = <2800000>;
regulator-always-on;
regulator-boot-on;
};
};
backlight {
compatible = "ams,as3711-bl";
su2-dev = <&lcdc>;
su2-max-uA = <36000>;
su2-feedback-curr-auto;
su2-fbprot-gpio4;
su2-auto-curr1;
su2-auto-curr2;
su2-auto-curr3;
};
};
};
@@ -1,73 +0,0 @@
AS3711 is an I2C PMIC from Austria MicroSystems with multiple DCDC and LDO power
supplies, a battery charger and an RTC. So far only bindings for the two stepup
DCDC converters are defined. Other DCDC and LDO supplies are configured, using
standard regulator properties, they must belong to a sub-node, called
"regulators" and be called "sd1" to "sd4" and "ldo1" to "ldo8." Stepup converter
configuration should be placed in a subnode, called "backlight."
Compulsory properties:
- compatible : must be "ams,as3711"
- reg : specifies the I2C address
To use the SU1 converter as a backlight source the following two properties must
be provided:
- su1-dev : framebuffer phandle
- su1-max-uA : maximum current
To use the SU2 converter as a backlight source the following two properties must
be provided:
- su2-dev : framebuffer phandle
- su1-max-uA : maximum current
Additionally one of these properties must be provided to select the type of
feedback used:
- su2-feedback-voltage : voltage feedback is used
- su2-feedback-curr1 : CURR1 input used for current feedback
- su2-feedback-curr2 : CURR2 input used for current feedback
- su2-feedback-curr3 : CURR3 input used for current feedback
- su2-feedback-curr-auto: automatic current feedback selection
and one of these to select the over-voltage protection pin
- su2-fbprot-lx-sd4 : LX_SD4 is used for over-voltage protection
- su2-fbprot-gpio2 : GPIO2 is used for over-voltage protection
- su2-fbprot-gpio3 : GPIO3 is used for over-voltage protection
- su2-fbprot-gpio4 : GPIO4 is used for over-voltage protection
If "su2-feedback-curr-auto" is selected, one or more of the following properties
have to be specified:
- su2-auto-curr1 : use CURR1 input for current feedback
- su2-auto-curr2 : use CURR2 input for current feedback
- su2-auto-curr3 : use CURR3 input for current feedback
Example:
as3711@40 {
compatible = "ams,as3711";
reg = <0x40>;
regulators {
sd4 {
regulator-name = "1.215V";
regulator-min-microvolt = <1215000>;
regulator-max-microvolt = <1235000>;
};
ldo2 {
regulator-name = "2.8V CPU";
regulator-min-microvolt = <2800000>;
regulator-max-microvolt = <2800000>;
regulator-always-on;
regulator-boot-on;
};
};
backlight {
compatible = "ams,as3711-bl";
su2-dev = <&lcdc>;
su2-max-uA = <36000>;
su2-feedback-curr-auto;
su2-fbprot-gpio4;
su2-auto-curr1;
su2-auto-curr2;
su2-auto-curr3;
};
};
@@ -17,7 +17,7 @@ description: |
node.
The SPMI controller part is provided by
Documentation/devicetree/bindings/mfd/hisilicon,hi6421-spmi-pmic.yaml
Documentation/devicetree/bindings/spmi/hisilicon,hisi-spmi-controller.yaml
properties:
$nodename:
@@ -42,13 +42,6 @@ properties:
additionalProperties: false
properties:
'#address-cells':
const: 1
'#size-cells':
const: 0
patternProperties:
'^ldo[0-9]+$':
type: object
@@ -66,72 +59,75 @@ additionalProperties: false
examples:
- |
#include <dt-bindings/spmi/spmi.h>
pmic: pmic@0 {
compatible = "hisilicon,hi6421v600-spmi";
reg = <0 0>;
#interrupt-cells = <2>;
interrupt-controller;
interrupt-parent = <&gpio28>;
interrupts = <0 0>;
regulators {
#address-cells = <1>;
spmi {
#address-cells = <2>;
#size-cells = <0>;
ldo3: ldo3 {
regulator-name = "ldo3";
regulator-min-microvolt = <1500000>;
regulator-max-microvolt = <2000000>;
regulator-boot-on;
};
pmic@0 {
compatible = "hisilicon,hi6421v600-spmi";
reg = <0 SPMI_USID>;
ldo4: ldo4 {
regulator-name = "ldo4";
regulator-min-microvolt = <1725000>;
regulator-max-microvolt = <1900000>;
regulator-boot-on;
};
#interrupt-cells = <2>;
interrupt-controller;
interrupt-parent = <&gpio28>;
interrupts = <0 0>;
ldo9: ldo9 {
regulator-name = "ldo9";
regulator-min-microvolt = <1750000>;
regulator-max-microvolt = <3300000>;
regulator-boot-on;
};
regulators {
ldo3 {
regulator-name = "ldo3";
regulator-min-microvolt = <1500000>;
regulator-max-microvolt = <2000000>;
regulator-boot-on;
};
ldo15: ldo15 {
regulator-name = "ldo15";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <3000000>;
regulator-always-on;
};
ldo4 {
regulator-name = "ldo4";
regulator-min-microvolt = <1725000>;
regulator-max-microvolt = <1900000>;
regulator-boot-on;
};
ldo16: ldo16 {
regulator-name = "ldo16";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <3000000>;
regulator-boot-on;
};
ldo9 {
regulator-name = "ldo9";
regulator-min-microvolt = <1750000>;
regulator-max-microvolt = <3300000>;
regulator-boot-on;
};
ldo17: ldo17 {
regulator-name = "ldo17";
regulator-min-microvolt = <2500000>;
regulator-max-microvolt = <3300000>;
};
ldo15 {
regulator-name = "ldo15";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <3000000>;
regulator-always-on;
};
ldo33: ldo33 {
regulator-name = "ldo33";
regulator-min-microvolt = <2500000>;
regulator-max-microvolt = <3300000>;
regulator-boot-on;
};
ldo16 {
regulator-name = "ldo16";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <3000000>;
regulator-boot-on;
};
ldo34: ldo34 {
regulator-name = "ldo34";
regulator-min-microvolt = <2600000>;
regulator-max-microvolt = <3300000>;
ldo17 {
regulator-name = "ldo17";
regulator-min-microvolt = <2500000>;
regulator-max-microvolt = <3300000>;
};
ldo33 {
regulator-name = "ldo33";
regulator-min-microvolt = <2500000>;
regulator-max-microvolt = <3300000>;
regulator-boot-on;
};
ldo34 {
regulator-name = "ldo34";
regulator-min-microvolt = <2600000>;
regulator-max-microvolt = <3300000>;
};
};
};
};
};
@@ -99,10 +99,12 @@ examples:
- |
#include <dt-bindings/mfd/qcom-pm8008.h>
#include <dt-bindings/interrupt-controller/irq.h>
qupv3_se13_i2c {
i2c {
#address-cells = <1>;
#size-cells = <0>;
pm8008i@8 {
pmic@8 {
compatible = "qcom,pm8008";
reg = <0x8>;
#address-cells = <1>;
@@ -66,6 +66,7 @@ properties:
- qcom,pm8841
- qcom,pm8909
- qcom,pm8916
- qcom,pm8937
- qcom,pm8941
- qcom,pm8950
- qcom,pm8953
@@ -134,9 +135,15 @@ patternProperties:
type: object
$ref: /schemas/sound/qcom,pm8916-wcd-analog-codec.yaml#
"^battery@[0-9a-f]+$":
type: object
oneOf:
- $ref: /schemas/power/supply/qcom,pm8916-bms-vm.yaml#
"^charger@[0-9a-f]+$":
type: object
oneOf:
- $ref: /schemas/power/supply/qcom,pm8916-lbc.yaml#
- $ref: /schemas/power/supply/qcom,pm8941-charger.yaml#
- $ref: /schemas/power/supply/qcom,pm8941-coincell.yaml#
- $ref: /schemas/power/supply/qcom,pmi8998-charger.yaml#
@@ -29,6 +29,8 @@ properties:
- qcom,sdx65-tcsr
- qcom,sm4450-tcsr
- qcom,sm8150-tcsr
- qcom,sm8250-tcsr
- qcom,sm8350-tcsr
- qcom,sm8450-tcsr
- qcom,tcsr-apq8064
- qcom,tcsr-apq8084
@@ -19,7 +19,9 @@ description:
properties:
compatible:
items:
- const: sprd,ums512-glbregs
- enum:
- sprd,ums512-glbregs
- sprd,ums9620-glbregs
- const: syscon
- const: simple-mfd
@@ -61,8 +61,6 @@ required:
- interrupts
- clocks
- clock-names
- dmas
- dma-names
additionalProperties: false
@@ -31,6 +31,7 @@ properties:
- ti,omap3-padconf
- ti,omap4-padconf
- ti,omap5-padconf
- ti,j7200-padconf
- const: pinctrl-single
reg:
@@ -23,13 +23,6 @@ properties:
interrupts:
maxItems: 1
interrupt-controller: true
"#interrupt-cells": true
gpio-controller: true
"#gpio-cells": true
gpio-ranges: true
wakeup-parent: true
gpio-reserved-ranges:
minItems: 1
maxItems: 24
@@ -95,7 +88,10 @@ required:
- compatible
- reg
additionalProperties: false
allOf:
- $ref: /schemas/pinctrl/qcom,tlmm-common.yaml#
unevaluatedProperties: false
examples:
- |
@@ -26,13 +26,6 @@ properties:
interrupts:
maxItems: 1
interrupt-controller: true
"#interrupt-cells": true
gpio-controller: true
"#gpio-cells": true
gpio-ranges: true
wakeup-parent: true
gpio-reserved-ranges:
minItems: 1
maxItems: 27
@@ -100,7 +93,7 @@ required:
- compatible
- reg
additionalProperties: false
unevaluatedProperties: false
examples:
- |
@@ -22,12 +22,6 @@ properties:
interrupts:
maxItems: 1
interrupt-controller: true
"#interrupt-cells": true
gpio-controller: true
"#gpio-cells": true
gpio-ranges: true
patternProperties:
"-state$":
oneOf:
@@ -100,7 +94,7 @@ required:
- compatible
- reg
additionalProperties: false
unevaluatedProperties: false
examples:
- |
@@ -23,13 +23,6 @@ properties:
interrupts:
maxItems: 1
interrupt-controller: true
"#interrupt-cells": true
gpio-controller: true
"#gpio-cells": true
gpio-ranges: true
wakeup-parent: true
gpio-reserved-ranges:
minItems: 1
maxItems: 35
@@ -103,7 +96,7 @@ required:
- compatible
- reg
additionalProperties: false
unevaluatedProperties: false
examples:
- |
@@ -23,13 +23,6 @@ properties:
interrupts:
maxItems: 1
interrupt-controller: true
"#interrupt-cells": true
gpio-controller: true
"#gpio-cells": true
gpio-ranges: true
wakeup-parent: true
gpio-reserved-ranges:
minItems: 1
maxItems: 33
@@ -97,7 +90,7 @@ required:
- compatible
- reg
additionalProperties: false
unevaluatedProperties: false
examples:
- |
@@ -0,0 +1,75 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/pinctrl/qcom,lpass-lpi-common.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm SoC LPASS LPI TLMM Common Properties
maintainers:
- Bjorn Andersson <andersson@kernel.org>
- Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
- Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
description:
Common properties for the Top Level Mode Multiplexer pin controllers in the
Low Power Audio SubSystem (LPASS) Low Power Island (LPI) of Qualcomm SoCs.
properties:
gpio-controller: true
"#gpio-cells":
description:
Specifying the pin number and flags, as defined in
include/dt-bindings/gpio/gpio.h
const: 2
gpio-ranges:
maxItems: 1
required:
- gpio-controller
- "#gpio-cells"
- gpio-ranges
allOf:
- $ref: pinctrl.yaml#
additionalProperties: true
$defs:
qcom-tlmm-state:
properties:
drive-strength:
enum: [2, 4, 6, 8, 10, 12, 14, 16]
default: 2
description:
Selects the drive strength for the specified pins, in mA.
slew-rate:
enum: [0, 1, 2, 3]
default: 0
description: |
0: No adjustments
1: Higher Slew rate (faster edges)
2: Lower Slew rate (slower edges)
3: Reserved (No adjustments)
bias-bus-hold: true
bias-pull-down: true
bias-pull-up: true
bias-disable: true
input-enable: true
output-high: true
output-low: true
required:
- pins
- function
allOf:
- $ref: pincfg-node.yaml#
- $ref: pinmux-node.yaml#
additionalProperties: true
@@ -25,19 +25,7 @@ properties:
interrupts:
maxItems: 1
interrupt-controller: true
"#interrupt-cells": true
gpio-controller: true
gpio-reserved-ranges: true
"#gpio-cells": true
gpio-ranges: true
wakeup-parent: true
required:
- compatible
- reg
additionalProperties: false
patternProperties:
"-state$":
@@ -110,6 +98,12 @@ $defs:
required:
- pins
required:
- compatible
- reg
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/arm-gic.h>
@@ -23,18 +23,6 @@ properties:
interrupts:
maxItems: 1
interrupt-controller: true
'#interrupt-cells': true
gpio-controller: true
'#gpio-cells': true
gpio-ranges: true
required:
- compatible
- reg
additionalProperties: false
patternProperties:
"-state$":
oneOf:
@@ -74,6 +62,12 @@ $defs:
required:
- pins
required:
- compatible
- reg
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/arm-gic.h>
@@ -23,12 +23,6 @@ properties:
interrupts:
maxItems: 1
interrupt-controller: true
"#interrupt-cells": true
gpio-controller: true
"#gpio-cells": true
gpio-ranges: true
gpio-reserved-ranges:
maxItems: 1
@@ -82,7 +76,7 @@ required:
- compatible
- reg
additionalProperties: false
unevaluatedProperties: false
examples:
- |
@@ -23,13 +23,6 @@ properties:
interrupts:
maxItems: 1
interrupt-controller: true
"#interrupt-cells": true
gpio-controller: true
"#gpio-cells": true
gpio-ranges: true
wakeup-parent: true
gpio-reserved-ranges:
minItems: 1
maxItems: 86
@@ -92,7 +85,7 @@ required:
- compatible
- reg
additionalProperties: false
unevaluatedProperties: false
examples:
- |
@@ -25,19 +25,7 @@ properties:
interrupts:
maxItems: 1
interrupt-controller: true
"#interrupt-cells": true
gpio-controller: true
gpio-reserved-ranges: true
"#gpio-cells": true
gpio-ranges: true
wakeup-parent: true
required:
- compatible
- reg
additionalProperties: false
patternProperties:
"-state$":
@@ -108,6 +96,12 @@ $defs:
required:
- pins
required:
- compatible
- reg
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/arm-gic.h>
@@ -23,13 +23,6 @@ properties:
interrupts:
maxItems: 1
interrupt-controller: true
"#interrupt-cells": true
gpio-controller: true
"#gpio-cells": true
gpio-ranges: true
wakeup-parent: true
gpio-reserved-ranges:
minItems: 1
maxItems: 61
@@ -114,7 +107,7 @@ required:
- compatible
- reg
additionalProperties: false
unevaluatedProperties: false
examples:
- |
@@ -22,12 +22,7 @@ properties:
interrupts:
maxItems: 1
interrupt-controller: true
"#interrupt-cells": true
gpio-controller: true
gpio-reserved-ranges: true
"#gpio-cells": true
gpio-ranges: true
patternProperties:
"-state$":
@@ -117,7 +112,7 @@ required:
- compatible
- reg
additionalProperties: false
unevaluatedProperties: false
examples:
- |
@@ -23,13 +23,6 @@ properties:
interrupts:
maxItems: 1
interrupt-controller: true
"#interrupt-cells": true
gpio-controller: true
"#gpio-cells": true
gpio-ranges: true
wakeup-parent: true
gpio-reserved-ranges:
minItems: 1
maxItems: 76
@@ -108,7 +101,7 @@ required:
- compatible
- reg
additionalProperties: false
unevaluatedProperties: false
examples:
- |
@@ -23,13 +23,6 @@ properties:
interrupts:
maxItems: 1
interrupt-controller: true
"#interrupt-cells": true
gpio-controller: true
"#gpio-cells": true
gpio-ranges: true
wakeup-parent: true
gpio-reserved-ranges:
minItems: 1
maxItems: 73
@@ -124,7 +117,7 @@ required:
- compatible
- reg
additionalProperties: false
unevaluatedProperties: false
examples:
- |
@@ -23,13 +23,6 @@ properties:
interrupts:
maxItems: 1
interrupt-controller: true
"#interrupt-cells": true
gpio-controller: true
"#gpio-cells": true
gpio-ranges: true
wakeup-parent: true
gpio-reserved-ranges:
minItems: 1
maxItems: 73
@@ -104,7 +97,7 @@ required:
- compatible
- reg
additionalProperties: false
unevaluatedProperties: false
examples:
- |
@@ -25,13 +25,6 @@ properties:
interrupts:
maxItems: 1
interrupt-controller: true
"#interrupt-cells": true
gpio-controller: true
"#gpio-cells": true
gpio-ranges: true
wakeup-parent: true
gpio-reserved-ranges:
minItems: 1
maxItems: 73
@@ -114,7 +107,7 @@ required:
- compatible
- reg
additionalProperties: false
unevaluatedProperties: false
examples:
- |
@@ -23,13 +23,6 @@ properties:
interrupts:
maxItems: 1
interrupt-controller: true
"#interrupt-cells": true
gpio-controller: true
"#gpio-cells": true
gpio-ranges: true
wakeup-parent: true
gpio-reserved-ranges:
minItems: 1
maxItems: 75
@@ -133,7 +126,7 @@ required:
- compatible
- reg
additionalProperties: false
unevaluatedProperties: false
examples:
- |
@@ -23,13 +23,6 @@ properties:
interrupts:
maxItems: 1
interrupt-controller: true
"#interrupt-cells": true
gpio-controller: true
"#gpio-cells": true
gpio-ranges: true
wakeup-parent: true
gpio-reserved-ranges:
minItems: 1
maxItems: 75
@@ -118,7 +111,7 @@ required:
- compatible
- reg
additionalProperties: false
unevaluatedProperties: false
examples:
- |
@@ -158,34 +158,40 @@ examples:
- |
#include <dt-bindings/pinctrl/qcom,pmic-mpp.h>
pm8841_mpp: mpps@a000 {
compatible = "qcom,pm8841-mpp", "qcom,spmi-mpp";
reg = <0xa000 0>;
gpio-controller;
#gpio-cells = <2>;
gpio-ranges = <&pm8841_mpp 0 0 4>;
gpio-line-names = "VDD_PX_BIAS", "WLAN_LED_CTRL",
"BT_LED_CTRL", "GPIO-F";
interrupt-controller;
#interrupt-cells = <2>;
pmic {
#address-cells = <1>;
#size-cells = <0>;
pinctrl-names = "default";
pinctrl-0 = <&pm8841_default>;
pm8841_mpp: mpps@a000 {
compatible = "qcom,pm8841-mpp", "qcom,spmi-mpp";
reg = <0xa000>;
mpp1-state {
pins = "mpp1";
function = "digital";
input-enable;
power-source = <PM8841_MPP_S3>;
};
gpio-controller;
#gpio-cells = <2>;
gpio-ranges = <&pm8841_mpp 0 0 4>;
gpio-line-names = "VDD_PX_BIAS", "WLAN_LED_CTRL",
"BT_LED_CTRL", "GPIO-F";
interrupt-controller;
#interrupt-cells = <2>;
default-state {
gpio-pins {
pins = "mpp1", "mpp2", "mpp3", "mpp4";
function = "digital";
input-enable;
power-source = <PM8841_MPP_S3>;
pinctrl-names = "default";
pinctrl-0 = <&pm8841_default>;
mpp1-state {
pins = "mpp1";
function = "digital";
input-enable;
power-source = <PM8841_MPP_S3>;
};
default-state {
gpio-pins {
pins = "mpp1", "mpp2", "mpp3", "mpp4";
function = "digital";
input-enable;
power-source = <PM8841_MPP_S3>;
};
};
};
};
};
...
@@ -22,13 +22,6 @@ properties:
interrupts:
maxItems: 1
interrupt-controller: true
"#interrupt-cells": true
gpio-controller: true
"#gpio-cells": true
gpio-ranges: true
wakeup-parent: true
patternProperties:
"-state$":
oneOf:
@@ -92,7 +85,7 @@ required:
- compatible
- reg
additionalProperties: false
unevaluatedProperties: false
examples:
- |
@@ -29,13 +29,6 @@ properties:
interrupts:
maxItems: 1
interrupt-controller: true
"#interrupt-cells": true
gpio-controller: true
"#gpio-cells": true
gpio-ranges: true
wakeup-parent: true
gpio-reserved-ranges:
minItems: 1
maxItems: 60
@@ -130,7 +123,7 @@ required:
- compatible
- reg
additionalProperties: false
unevaluatedProperties: false
examples:
- |
@@ -23,10 +23,8 @@ properties:
reg:
maxItems: 1
interrupts: true
interrupt-controller: true
"#interrupt-cells": true
gpio-controller: true
interrupts:
maxItems: 1
gpio-reserved-ranges:
minItems: 1
@@ -35,10 +33,6 @@ properties:
gpio-line-names:
maxItems: 151
"#gpio-cells": true
gpio-ranges: true
wakeup-parent: true
patternProperties:
"-state$":
oneOf:
@@ -101,7 +95,7 @@ required:
- compatible
- reg
additionalProperties: false
unevaluatedProperties: false
examples:
- |
@@ -22,13 +22,8 @@ properties:
reg:
maxItems: 1
interrupts: true
interrupt-controller: true
"#interrupt-cells": true
gpio-controller: true
"#gpio-cells": true
gpio-ranges: true
wakeup-parent: true
interrupts:
maxItems: 1
gpio-reserved-ranges:
minItems: 1
@@ -37,12 +32,6 @@ properties:
gpio-line-names:
maxItems: 148
required:
- compatible
- reg
additionalProperties: false
patternProperties:
"-state$":
oneOf:
@@ -108,6 +97,12 @@ $defs:
required:
- pins
required:
- compatible
- reg
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/arm-gic.h>
@@ -29,13 +29,6 @@ properties:
interrupts:
maxItems: 1
interrupt-controller: true
"#interrupt-cells": true
gpio-controller: true
"#gpio-cells": true
gpio-ranges: true
wakeup-parent: true
gpio-reserved-ranges:
minItems: 1
maxItems: 60
@@ -112,7 +105,7 @@ required:
- reg
- reg-names
additionalProperties: false
unevaluatedProperties: false
examples:
- |
@@ -20,16 +20,6 @@ properties:
reg:
maxItems: 2
gpio-controller: true
"#gpio-cells":
description: Specifying the pin number and flags, as defined in
include/dt-bindings/gpio/gpio.h
const: 2
gpio-ranges:
maxItems: 1
patternProperties:
"-state$":
oneOf:
@@ -45,7 +35,8 @@ $defs:
description:
Pinctrl node's client devices use subnodes for desired pin configuration.
Client device subnodes use below standard properties.
$ref: /schemas/pinctrl/pincfg-node.yaml
$ref: qcom,lpass-lpi-common.yaml#/$defs/qcom-tlmm-state
unevaluatedProperties: false
properties:
pins:
@@ -68,42 +59,14 @@ $defs:
Specify the alternative function to be configured for the specified
pins.
drive-strength:
enum: [2, 4, 6, 8, 10, 12, 14, 16]
default: 2
description:
Selects the drive strength for the specified pins, in mA.
slew-rate:
enum: [0, 1, 2, 3]
default: 0
description: |
0: No adjustments
1: Higher Slew rate (faster edges)
2: Lower Slew rate (slower edges)
3: Reserved (No adjustments)
bias-pull-down: true
bias-pull-up: true
bias-bus-hold: true
bias-disable: true
output-high: true
output-low: true
required:
- pins
- function
additionalProperties: false
required:
- compatible
- reg
- gpio-controller
- "#gpio-cells"
- gpio-ranges
additionalProperties: false
allOf:
- $ref: qcom,lpass-lpi-common.yaml#
unevaluatedProperties: false
examples:
- |
@@ -23,24 +23,6 @@ properties:
description: Specifies the TLMM summary IRQ
maxItems: 1
interrupt-controller: true
'#interrupt-cells':
description:
Specifies the PIN numbers and Flags, as defined in defined in
include/dt-bindings/interrupt-controller/irq.h
const: 2
gpio-controller: true
'#gpio-cells':
description: Specifying the pin number and flags, as defined in
include/dt-bindings/gpio/gpio.h
const: 2
gpio-ranges:
maxItems: 1
gpio-reserved-ranges:
minItems: 1
maxItems: 88
@@ -48,8 +30,6 @@ properties:
gpio-line-names:
maxItems: 175
wakeup-parent: true
patternProperties:
"-state$":
oneOf:
@@ -124,14 +104,8 @@ allOf:
required:
- compatible
- reg
- interrupts
- interrupt-controller
- '#interrupt-cells'
- gpio-controller
- '#gpio-cells'
- gpio-ranges
additionalProperties: false
unevaluatedProperties: false
examples:
- |
@@ -31,20 +31,7 @@ properties:
interrupts:
maxItems: 1
interrupt-controller: true
'#interrupt-cells': true
gpio-controller: true
gpio-reserved-ranges: true
'#gpio-cells': true
gpio-ranges: true
wakeup-parent: true
required:
- compatible
- reg
- reg-names
additionalProperties: false
patternProperties:
"-state$":
@@ -106,6 +93,13 @@ $defs:
required:
- pins
required:
- compatible
- reg
- reg-names
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/arm-gic.h>
@@ -32,16 +32,6 @@ properties:
- const: core
- const: audio
gpio-controller: true
"#gpio-cells":
description: Specifying the pin number and flags, as defined in
include/dt-bindings/gpio/gpio.h
const: 2
gpio-ranges:
maxItems: 1
patternProperties:
"-state$":
oneOf:
@@ -57,7 +47,8 @@ $defs:
description:
Pinctrl node's client devices use subnodes for desired pin configuration.
Client device subnodes use below standard properties.
$ref: /schemas/pinctrl/pincfg-node.yaml
$ref: qcom,lpass-lpi-common.yaml#/$defs/qcom-tlmm-state
unevaluatedProperties: false
properties:
pins:
@@ -79,48 +70,16 @@ $defs:
Specify the alternative function to be configured for the specified
pins.
drive-strength:
enum: [2, 4, 6, 8, 10, 12, 14, 16]
default: 2
description:
Selects the drive strength for the specified pins, in mA.
slew-rate:
enum: [0, 1, 2, 3]
default: 0
description: |
0: No adjustments
1: Higher Slew rate (faster edges)
2: Lower Slew rate (slower edges)
3: Reserved (No adjustments)
bias-bus-hold: true
bias-pull-down: true
bias-pull-up: true
bias-disable: true
input-enable: true
output-high: true
output-low: true
required:
- pins
- function
additionalProperties: false
allOf:
- $ref: pinctrl.yaml#
- $ref: qcom,lpass-lpi-common.yaml#
required:
- compatible
- reg
- clocks
- clock-names
- gpio-controller
- "#gpio-cells"
- gpio-ranges
additionalProperties: false
unevaluatedProperties: false
examples:
- |
@@ -25,19 +25,7 @@ properties:
interrupts:
maxItems: 1
interrupt-controller: true
"#interrupt-cells": true
gpio-controller: true
gpio-reserved-ranges: true
"#gpio-cells": true
gpio-ranges: true
wakeup-parent: true
required:
- compatible
- reg
additionalProperties: false
patternProperties:
"-state$":
@@ -108,6 +96,12 @@ $defs:
required:
- pins
required:
- compatible
- reg
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/arm-gic.h>
@@ -34,10 +34,6 @@ properties:
interrupts:
maxItems: 1
interrupt-controller: true
"#interrupt-cells": true
gpio-controller: true
gpio-reserved-ranges:
minItems: 1
maxItems: 57
@@ -45,10 +41,6 @@ properties:
gpio-line-names:
maxItems: 114
"#gpio-cells": true
gpio-ranges: true
wakeup-parent: true
patternProperties:
"-state$":
oneOf:
@@ -130,7 +122,7 @@ required:
- compatible
- reg
additionalProperties: false
unevaluatedProperties: false
examples:
- |
@@ -25,23 +25,10 @@ properties:
interrupts:
maxItems: 1
interrupt-controller: true
"#interrupt-cells": true
gpio-controller: true
gpio-reserved-ranges:
minItems: 1
maxItems: 75
"#gpio-cells": true
gpio-ranges: true
wakeup-parent: true
required:
- compatible
- reg
additionalProperties: false
patternProperties:
"-state$":
oneOf:
@@ -98,6 +85,12 @@ $defs:
required:
- pins
required:
- compatible
- reg
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/arm-gic.h>
@@ -26,10 +26,6 @@ properties:
interrupts:
maxItems: 1
interrupt-controller: true
"#interrupt-cells": true
gpio-controller: true
gpio-reserved-ranges:
minItems: 1
maxItems: 75
@@ -37,10 +33,6 @@ properties:
gpio-line-names:
maxItems: 150
"#gpio-cells": true
gpio-ranges: true
wakeup-parent: true
patternProperties:
"-state$":
oneOf:
@@ -110,7 +102,7 @@ required:
- compatible
- reg
additionalProperties: false
unevaluatedProperties: false
examples:
- |
@@ -23,12 +23,6 @@ properties:
interrupts:
maxItems: 1
interrupt-controller: true
"#interrupt-cells": true
gpio-controller: true
"#gpio-cells": true
gpio-ranges: true
gpio-reserved-ranges:
maxItems: 1
@@ -102,7 +96,7 @@ required:
- compatible
- reg
additionalProperties: false
unevaluatedProperties: false
examples:
- |
@@ -22,12 +22,6 @@ properties:
interrupts:
maxItems: 1
interrupt-controller: true
"#interrupt-cells": true
gpio-controller: true
"#gpio-cells": true
gpio-ranges: true
gpio-reserved-ranges:
maxItems: 1
@@ -122,7 +116,7 @@ required:
- compatible
- reg
additionalProperties: false
unevaluatedProperties: false
examples:
- |
@@ -22,10 +22,8 @@ properties:
reg:
maxItems: 1
interrupts: true
interrupt-controller: true
"#interrupt-cells": true
gpio-controller: true
interrupts:
maxItems: 1
gpio-reserved-ranges:
minItems: 1
@@ -34,10 +32,6 @@ properties:
gpio-line-names:
maxItems: 133
"#gpio-cells": true
gpio-ranges: true
wakeup-parent: true
patternProperties:
"-state$":
oneOf:
@@ -100,7 +94,7 @@ required:
- compatible
- reg
additionalProperties: false
unevaluatedProperties: false
examples:
- |
@@ -0,0 +1,151 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/pinctrl/qcom,sm4450-tlmm.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm Technologies, Inc. SM4450 TLMM block
maintainers:
- Tengfei Fan <quic_tengfan@quicinc.com>
description:
Top Level Mode Multiplexer pin controller in Qualcomm SM4450 SoC.
allOf:
- $ref: /schemas/pinctrl/qcom,tlmm-common.yaml#
properties:
compatible:
const: qcom,sm4450-pinctrl
reg:
maxItems: 1
interrupts: true
interrupt-controller: true
"#interrupt-cells": true
gpio-controller: true
gpio-reserved-ranges:
minItems: 1
maxItems: 68
gpio-line-names:
maxItems: 136
"#gpio-cells": true
gpio-ranges: true
wakeup-parent: true
patternProperties:
"-state$":
oneOf:
- $ref: "#/$defs/qcom-sm4450-tlmm-state"
- patternProperties:
"-pins$":
$ref: "#/$defs/qcom-sm4450-tlmm-state"
additionalProperties: false
$defs:
qcom-sm4450-tlmm-state:
type: object
description:
Pinctrl node's client devices use subnodes for desired pin configuration.
Client device subnodes use below standard properties.
$ref: qcom,tlmm-common.yaml#/$defs/qcom-tlmm-state
unevaluatedProperties: false
properties:
pins:
description:
List of gpio pins affected by the properties specified in this
subnode.
items:
oneOf:
- pattern: "^gpio([0-9]|[1-9][0-9]|1[0-2][0-9]|13[0-5])$"
- enum: [ sdc2_clk, sdc2_cmd, sdc2_data, ufs_reset ]
minItems: 1
maxItems: 36
function:
description:
Specify the alternative function to be configured for the specified
pins.
enum: [ gpio, atest_char, atest_char0, atest_char1, atest_char2,
atest_char3, atest_usb0, atest_usb00, atest_usb01, atest_usb02,
atest_usb03, audio_ref, cam_mclk, cci_async, cci_i2c,
cci_timer0, cci_timer1, cci_timer2, cci_timer3, cci_timer4,
cmu_rng0, cmu_rng1, cmu_rng2, cmu_rng3, coex_uart1, cri_trng,
cri_trng0, cri_trng1, dbg_out, ddr_bist, ddr_pxi0, ddr_pxi1,
dp0_hot, gcc_gp1, gcc_gp2, gcc_gp3, host2wlan_sol, ibi_i3c,
jitter_bist, mdp_vsync, mdp_vsync0, mdp_vsync1, mdp_vsync2,
mdp_vsync3, mi2s0_data0, mi2s0_data1, mi2s0_sck, mi2s0_ws,
mi2s2_data0, mi2s2_data1, mi2s2_sck, mi2s2_ws, mi2s_mclk0,
mi2s_mclk1, nav_gpio0, nav_gpio1, nav_gpio2, pcie0_clk,
phase_flag0, phase_flag1, phase_flag10, phase_flag11,
phase_flag12, phase_flag13, phase_flag14, phase_flag15,
phase_flag16, phase_flag17, phase_flag18, phase_flag19,
phase_flag2, phase_flag20, phase_flag21, phase_flag22,
phase_flag23, phase_flag24, phase_flag25, phase_flag26,
phase_flag27, phase_flag28, phase_flag29, phase_flag3,
phase_flag30, phase_flag31, phase_flag4, phase_flag5,
phase_flag6, phase_flag7, phase_flag8, phase_flag9,
pll_bist, pll_clk, prng_rosc0, prng_rosc1, prng_rosc2,
prng_rosc3, qdss_cti, qdss_gpio, qdss_gpio0, qdss_gpio1,
qdss_gpio10, qdss_gpio11, qdss_gpio12, qdss_gpio13, qdss_gpio14,
qdss_gpio15, qdss_gpio2, qdss_gpio3, qdss_gpio4, qdss_gpio5,
qdss_gpio6, qdss_gpio7, qdss_gpio8, qdss_gpio9, qlink0_enable,
qlink0_request, qlink0_wmss, qlink1_enable, qlink1_request,
qlink1_wmss, qlink2_enable, qlink2_request, qlink2_wmss,
qup0_se0, qup0_se1, qup0_se2, qup0_se3, qup0_se4, qup0_se5,
qup0_se6, qup0_se7, qup1_se0, qup1_se1, qup1_se2, qup1_se3,
qup1_se4, qup1_se5, qup1_se6, sd_write, tb_trig, tgu_ch0,
tgu_ch1, tgu_ch2, tgu_ch3, tmess_prng0, tmess_prng1,
tmess_prng2, tmess_prng3, tsense_pwm1, tsense_pwm2, uim0_clk,
uim0_data, uim0_present, uim0_reset, uim1_clk, uim1_data,
uim1_present, uim1_reset, usb0_hs, usb0_phy, vfr_0, vfr_1,
vsense_trigger ]
required:
- pins
required:
- compatible
- reg
additionalProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/arm-gic.h>
tlmm: pinctrl@f100000 {
compatible = "qcom,sm4450-tlmm";
reg = <0x0f100000 0x300000>;
gpio-controller;
#gpio-cells = <2>;
gpio-ranges = <&tlmm 0 0 137>;
interrupt-controller;
#interrupt-cells = <2>;
interrupts = <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>;
gpio-wo-state {
pins = "gpio1";
function = "gpio";
};
uart-w-state {
rx-pins {
pins = "gpio23";
function = "qup1_se2";
bias-pull-up;
};
tx-pins {
pins = "gpio22";
function = "qup1_se2";
bias-disable;
};
};
};
...
@@ -31,16 +31,6 @@ properties:
items:
- const: audio
gpio-controller: true
"#gpio-cells":
description: Specifying the pin number and flags, as defined in
include/dt-bindings/gpio/gpio.h
const: 2
gpio-ranges:
maxItems: 1
patternProperties:
"-state$":
oneOf:
@@ -56,7 +46,8 @@ $defs:
description:
Pinctrl node's client devices use subnodes for desired pin configuration.
Client device subnodes use below standard properties.
$ref: /schemas/pinctrl/pincfg-node.yaml
$ref: qcom,lpass-lpi-common.yaml#/$defs/qcom-tlmm-state
unevaluatedProperties: false
properties:
pins:
@@ -75,48 +66,17 @@ $defs:
Specify the alternative function to be configured for the specified
pins.
drive-strength:
enum: [2, 4, 6, 8, 10, 12, 14, 16]
default: 2
description:
Selects the drive strength for the specified pins, in mA.
slew-rate:
enum: [0, 1, 2, 3]
default: 0
description: |
0: No adjustments
1: Higher Slew rate (faster edges)
2: Lower Slew rate (slower edges)
3: Reserved (No adjustments)
bias-bus-hold: true
bias-pull-down: true
bias-pull-up: true
bias-disable: true
input-enable: true
output-high: true
output-low: true
required:
- pins
- function
additionalProperties: false
allOf:
- $ref: pinctrl.yaml#
- $ref: qcom,lpass-lpi-common.yaml#
required:
- compatible
- reg
- clocks
- clock-names
- gpio-controller
- "#gpio-cells"
- gpio-ranges
additionalProperties: false
unevaluatedProperties: false
examples:
- |
@@ -29,13 +29,7 @@ properties:
interrupts:
maxItems: 1
interrupt-controller: true
"#interrupt-cells": true
gpio-controller: true
"#gpio-cells": true
gpio-ranges: true
gpio-reserved-ranges: true
wakeup-parent: true
patternProperties:
"-state$":
@@ -97,7 +91,7 @@ required:
- reg
- reg-names
additionalProperties: false
unevaluatedProperties: false
examples:
- |
@@ -30,20 +30,7 @@ properties:
interrupts:
maxItems: 1
interrupt-controller: true
"#interrupt-cells": true
gpio-controller: true
gpio-reserved-ranges: true
"#gpio-cells": true
gpio-ranges: true
wakeup-parent: true
required:
- compatible
- reg
- reg-names
additionalProperties: false
patternProperties:
"-state$":
@@ -105,6 +92,13 @@ $defs:
required:
- pins
required:
- compatible
- reg
- reg-names
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/arm-gic.h>
@@ -26,10 +26,6 @@ properties:
minItems: 9
maxItems: 9
interrupt-controller: true
"#interrupt-cells": true
gpio-controller: true
gpio-reserved-ranges:
minItems: 1
maxItems: 78
@@ -37,16 +33,6 @@ properties:
gpio-line-names:
maxItems: 156
"#gpio-cells": true
gpio-ranges: true
wakeup-parent: true
required:
- compatible
- reg
additionalProperties: false
patternProperties:
"-state$":
oneOf:
@@ -112,6 +98,12 @@ $defs:
required:
- pins
required:
- compatible
- reg
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/arm-gic.h>
@@ -25,19 +25,7 @@ properties:
interrupts:
maxItems: 1
interrupt-controller: true
"#interrupt-cells": true
gpio-controller: true
gpio-reserved-ranges: true
"#gpio-cells": true
gpio-ranges: true
wakeup-parent: true
required:
- compatible
- reg
additionalProperties: false
patternProperties:
"-state$":
@@ -113,6 +101,12 @@ $defs:
required:
- pins
required:
- compatible
- reg
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/arm-gic.h>
@@ -32,13 +32,6 @@ properties:
interrupts:
maxItems: 1
interrupt-controller: true
"#interrupt-cells": true
gpio-controller: true
"#gpio-cells": true
gpio-ranges: true
wakeup-parent: true
gpio-reserved-ranges:
minItems: 1
maxItems: 60
@@ -111,7 +104,7 @@ required:
- reg
- reg-names
additionalProperties: false
unevaluatedProperties: false
examples:
- |
@@ -30,13 +30,6 @@ properties:
interrupts:
maxItems: 1
interrupt-controller: true
"#interrupt-cells": true
gpio-controller: true
"#gpio-cells": true
gpio-ranges: true
wakeup-parent: true
gpio-reserved-ranges:
minItems: 1
maxItems: 88
@@ -113,7 +106,7 @@ required:
- reg
- reg-names
additionalProperties: false
unevaluatedProperties: false
examples:
- |
@@ -30,16 +30,6 @@ properties:
- const: core
- const: audio
gpio-controller: true
"#gpio-cells":
description: Specifying the pin number and flags, as defined in
include/dt-bindings/gpio/gpio.h
const: 2
gpio-ranges:
maxItems: 1
patternProperties:
"-state$":
oneOf:
@@ -55,7 +45,8 @@ $defs:
description:
Pinctrl node's client devices use subnodes for desired pin configuration.
Client device subnodes use below standard properties.
$ref: /schemas/pinctrl/pincfg-node.yaml
$ref: qcom,lpass-lpi-common.yaml#/$defs/qcom-tlmm-state
unevaluatedProperties: false
properties:
pins:
@@ -78,48 +69,16 @@ $defs:
Specify the alternative function to be configured for the specified
pins.
drive-strength:
enum: [2, 4, 6, 8, 10, 12, 14, 16]
default: 2
description:
Selects the drive strength for the specified pins, in mA.
slew-rate:
enum: [0, 1, 2, 3]
default: 0
description: |
0: No adjustments
1: Higher Slew rate (faster edges)
2: Lower Slew rate (slower edges)
3: Reserved (No adjustments)
bias-pull-down: true
bias-pull-up: true
bias-bus-hold: true
bias-disable: true
input-enable: true
output-high: true
output-low: true
required:
- pins
- function
additionalProperties: false
allOf:
- $ref: pinctrl.yaml#
- $ref: qcom,lpass-lpi-common.yaml#
required:
- compatible
- reg
- clocks
- clock-names
- gpio-controller
- "#gpio-cells"
- gpio-ranges
additionalProperties: false
unevaluatedProperties: false
examples:
- |
@@ -28,13 +28,6 @@ properties:
interrupts:
maxItems: 1
interrupt-controller: true
"#interrupt-cells": true
gpio-controller: true
"#gpio-cells": true
gpio-ranges: true
wakeup-parent: true
gpio-reserved-ranges:
minItems: 1
maxItems: 90
@@ -106,7 +99,7 @@ required:
- reg
- reg-names
additionalProperties: false
unevaluatedProperties: false
examples:
- |
@@ -33,16 +33,6 @@ properties:
- const: core
- const: audio
gpio-controller: true
"#gpio-cells":
description: Specifying the pin number and flags, as defined in
include/dt-bindings/gpio/gpio.h
const: 2
gpio-ranges:
maxItems: 1
patternProperties:
"-state$":
oneOf:
@@ -58,7 +48,8 @@ $defs:
description:
Pinctrl node's client devices use subnodes for desired pin configuration.
Client device subnodes use below standard properties.
$ref: /schemas/pinctrl/pincfg-node.yaml
$ref: qcom,lpass-lpi-common.yaml#/$defs/qcom-tlmm-state
unevaluatedProperties: false
properties:
pins:
@@ -81,48 +72,16 @@ $defs:
Specify the alternative function to be configured for the specified
pins.
drive-strength:
enum: [2, 4, 6, 8, 10, 12, 14, 16]
default: 2
description:
Selects the drive strength for the specified pins, in mA.
slew-rate:
enum: [0, 1, 2, 3]
default: 0
description: |
0: No adjustments
1: Higher Slew rate (faster edges)
2: Lower Slew rate (slower edges)
3: Reserved (No adjustments)
bias-bus-hold: true
bias-pull-down: true
bias-pull-up: true
bias-disable: true
input-enable: true
output-high: true
output-low: true
required:
- pins
- function
additionalProperties: false
allOf:
- $ref: pinctrl.yaml#
- $ref: qcom,lpass-lpi-common.yaml#
required:
- compatible
- reg
- clocks
- clock-names
- gpio-controller
- "#gpio-cells"
- gpio-ranges
additionalProperties: false
unevaluatedProperties: false
examples:
- |
@@ -25,10 +25,6 @@ properties:
interrupts:
maxItems: 1
interrupt-controller: true
"#interrupt-cells": true
gpio-controller: true
gpio-reserved-ranges:
minItems: 1
maxItems: 102
@@ -36,16 +32,6 @@ properties:
gpio-line-names:
maxItems: 203
"#gpio-cells": true
gpio-ranges: true
wakeup-parent: true
required:
- compatible
- reg
additionalProperties: false
patternProperties:
"-state$":
oneOf:
@@ -108,6 +94,12 @@ $defs:
required:
- pins
required:
- compatible
- reg
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/arm-gic.h>
@@ -32,16 +32,6 @@ properties:
- const: core
- const: audio
gpio-controller: true
"#gpio-cells":
description: Specifying the pin number and flags, as defined in
include/dt-bindings/gpio/gpio.h
const: 2
gpio-ranges:
maxItems: 1
patternProperties:
"-state$":
oneOf:
@@ -57,7 +47,8 @@ $defs:
description:
Pinctrl node's client devices use subnodes for desired pin configuration.
Client device subnodes use below standard properties.
$ref: /schemas/pinctrl/pincfg-node.yaml
$ref: qcom,lpass-lpi-common.yaml#/$defs/qcom-tlmm-state
unevaluatedProperties: false
properties:
pins:
@@ -81,48 +72,16 @@ $defs:
Specify the alternative function to be configured for the specified
pins.
drive-strength:
enum: [2, 4, 6, 8, 10, 12, 14, 16]
default: 2
description:
Selects the drive strength for the specified pins, in mA.
slew-rate:
enum: [0, 1, 2, 3]
default: 0
description: |
0: No adjustments
1: Higher Slew rate (faster edges)
2: Lower Slew rate (slower edges)
3: Reserved (No adjustments)
bias-bus-hold: true
bias-pull-down: true
bias-pull-up: true
bias-disable: true
input-enable: true
output-high: true
output-low: true
required:
- pins
- function
additionalProperties: false
allOf:
- $ref: pinctrl.yaml#
- $ref: qcom,lpass-lpi-common.yaml#
required:
- compatible
- reg
- clocks
- clock-names
- gpio-controller
- "#gpio-cells"
- gpio-ranges
additionalProperties: false
unevaluatedProperties: false
examples:
- |
@@ -25,10 +25,6 @@ properties:
interrupts:
maxItems: 1
interrupt-controller: true
"#interrupt-cells": true
gpio-controller: true
gpio-reserved-ranges:
minItems: 1
maxItems: 105
@@ -36,16 +32,6 @@ properties:
gpio-line-names:
maxItems: 210
"#gpio-cells": true
gpio-ranges: true
wakeup-parent: true
required:
- compatible
- reg
additionalProperties: false
patternProperties:
"-state$":
oneOf:
@@ -107,6 +93,12 @@ $defs:
required:
- pins
required:
- compatible
- reg
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/arm-gic.h>
@@ -16,7 +16,11 @@ description:
properties:
compatible:
const: qcom,sm8550-lpass-lpi-pinctrl
oneOf:
- const: qcom,sm8550-lpass-lpi-pinctrl
- items:
- const: qcom,x1e80100-lpass-lpi-pinctrl
- const: qcom,sm8550-lpass-lpi-pinctrl
reg:
items:
@@ -33,16 +37,6 @@ properties:
- const: core
- const: audio
gpio-controller: true
"#gpio-cells":
description: Specifying the pin number and flags, as defined in
include/dt-bindings/gpio/gpio.h
const: 2
gpio-ranges:
maxItems: 1
patternProperties:
"-state$":
oneOf:
@@ -58,7 +52,8 @@ $defs:
description:
Pinctrl node's client devices use subnodes for desired pin configuration.
Client device subnodes use below standard properties.
$ref: /schemas/pinctrl/pincfg-node.yaml
$ref: qcom,lpass-lpi-common.yaml#/$defs/qcom-tlmm-state
unevaluatedProperties: false
properties:
pins:
@@ -81,48 +76,16 @@ $defs:
Specify the alternative function to be configured for the specified
pins.
drive-strength:
enum: [2, 4, 6, 8, 10, 12, 14, 16]
default: 2
description:
Selects the drive strength for the specified pins, in mA.
slew-rate:
enum: [0, 1, 2, 3]
default: 0
description: |
0: No adjustments
1: Higher Slew rate (faster edges)
2: Lower Slew rate (slower edges)
3: Reserved (No adjustments)
bias-bus-hold: true
bias-pull-down: true
bias-pull-up: true
bias-disable: true
input-enable: true
output-high: true
output-low: true
required:
- pins
- function
additionalProperties: false
allOf:
- $ref: pinctrl.yaml#
- $ref: qcom,lpass-lpi-common.yaml#
required:
- compatible
- reg
- clocks
- clock-names
- gpio-controller
- "#gpio-cells"
- gpio-ranges
additionalProperties: false
unevaluatedProperties: false
examples:
- |
@@ -22,10 +22,8 @@ properties:
reg:
maxItems: 1
interrupts: true
interrupt-controller: true
"#interrupt-cells": true
gpio-controller: true
interrupts:
maxItems: 1
gpio-reserved-ranges:
minItems: 1
@@ -34,10 +32,6 @@ properties:
gpio-line-names:
maxItems: 210
"#gpio-cells": true
gpio-ranges: true
wakeup-parent: true
patternProperties:
"-state$":
oneOf:
@@ -117,7 +111,7 @@ required:
- compatible
- reg
additionalProperties: false
unevaluatedProperties: false
examples:
- |
@@ -0,0 +1,107 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/pinctrl/qcom,sm8650-lpass-lpi-pinctrl.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm SM8650 SoC LPASS LPI TLMM
maintainers:
- Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
- Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
description:
Top Level Mode Multiplexer pin controller in the Low Power Audio SubSystem
(LPASS) Low Power Island (LPI) of Qualcomm SM8650 SoC.
properties:
compatible:
const: qcom,sm8650-lpass-lpi-pinctrl
reg:
items:
- description: LPASS LPI TLMM Control and Status registers
clocks:
items:
- description: LPASS Core voting clock
- description: LPASS Audio voting clock
clock-names:
items:
- const: core
- const: audio
patternProperties:
"-state$":
oneOf:
- $ref: "#/$defs/qcom-sm8650-lpass-state"
- patternProperties:
"-pins$":
$ref: "#/$defs/qcom-sm8650-lpass-state"
additionalProperties: false
$defs:
qcom-sm8650-lpass-state:
type: object
description:
Pinctrl node's client devices use subnodes for desired pin configuration.
Client device subnodes use below standard properties.
$ref: qcom,lpass-lpi-common.yaml#/$defs/qcom-tlmm-state
unevaluatedProperties: false
properties:
pins:
description:
List of gpio pins affected by the properties specified in this
subnode.
items:
pattern: "^gpio([0-9]|1[0-9]|2[0-2])$"
function:
enum: [ dmic1_clk, dmic1_data, dmic2_clk, dmic2_data, dmic3_clk,
dmic3_data, dmic4_clk, dmic4_data, ext_mclk1_a, ext_mclk1_b,
ext_mclk1_c, ext_mclk1_d, ext_mclk1_e, gpio, i2s0_clk,
i2s0_data, i2s0_ws, i2s1_clk, i2s1_data, i2s1_ws, i2s2_clk,
i2s2_data, i2s2_ws, i2s3_clk, i2s3_data, i2s3_ws, i2s4_clk,
i2s4_data, i2s4_ws, qca_swr_clk, qca_swr_data, slimbus_clk,
slimbus_data, swr_rx_clk, swr_rx_data, swr_tx_clk, swr_tx_data,
wsa_swr_clk, wsa_swr_data, wsa2_swr_clk, wsa2_swr_data ]
description:
Specify the alternative function to be configured for the specified
pins.
allOf:
- $ref: qcom,lpass-lpi-common.yaml#
required:
- compatible
- reg
- clocks
- clock-names
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/sound/qcom,q6dsp-lpass-ports.h>
lpass_tlmm: pinctrl@6e80000 {
compatible = "qcom,sm8650-lpass-lpi-pinctrl";
reg = <0x06e80000 0x20000>;
clocks = <&q6prmcc LPASS_HW_MACRO_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>,
<&q6prmcc LPASS_HW_DCODEC_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>;
clock-names = "core", "audio";
gpio-controller;
#gpio-cells = <2>;
gpio-ranges = <&lpass_tlmm 0 0 23>;
tx-swr-sleep-clk-state {
pins = "gpio0";
function = "swr_tx_clk";
drive-strength = <2>;
bias-pull-down;
};
};
@@ -0,0 +1,141 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/pinctrl/qcom,sm8650-tlmm.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm Technologies, Inc. SM8650 TLMM block
maintainers:
- Bjorn Andersson <andersson@kernel.org>
description:
Top Level Mode Multiplexer pin controller in Qualcomm SM8650 SoC.
allOf:
- $ref: /schemas/pinctrl/qcom,tlmm-common.yaml#
properties:
compatible:
const: qcom,sm8650-tlmm
reg:
maxItems: 1
interrupts:
maxItems: 1
gpio-reserved-ranges:
minItems: 1
maxItems: 105
gpio-line-names:
maxItems: 210
patternProperties:
"-state$":
oneOf:
- $ref: "#/$defs/qcom-sm8650-tlmm-state"
- patternProperties:
"-pins$":
$ref: "#/$defs/qcom-sm8650-tlmm-state"
additionalProperties: false
$defs:
qcom-sm8650-tlmm-state:
type: object
description:
Pinctrl node's client devices use subnodes for desired pin configuration.
Client device subnodes use below standard properties.
$ref: qcom,tlmm-common.yaml#/$defs/qcom-tlmm-state
unevaluatedProperties: false
properties:
pins:
description:
List of gpio pins affected by the properties specified in this
subnode.
items:
oneOf:
- pattern: "^gpio([0-9]|[1-9][0-9]|1[0-9][0-9]|20[0-9])$"
- enum: [ ufs_reset, sdc2_clk, sdc2_cmd, sdc2_data ]
minItems: 1
maxItems: 36
function:
description:
Specify the alternative function to be configured for the specified
pins.
enum: [ gpio, aoss_cti, atest_char, atest_usb, audio_ext_mclk0,
audio_ext_mclk1, audio_ref_clk, cam_aon_mclk2, cam_aon_mclk4,
cam_mclk, cci_async_in, cci_i2c_scl, cci_i2c_sda, cci_timer,
cmu_rng, coex_uart1_rx, coex_uart1_tx, coex_uart2_rx,
coex_uart2_tx, cri_trng, dbg_out_clk, ddr_bist_complete,
ddr_bist_fail, ddr_bist_start, ddr_bist_stop, ddr_pxi0,
ddr_pxi1, ddr_pxi2, ddr_pxi3, do_not, dp_hot, gcc_gp1,
gcc_gp2, gcc_gp3, gnss_adc0, gnss_adc1, i2chub0_se0,
i2chub0_se1, i2chub0_se2, i2chub0_se3, i2chub0_se4,
i2chub0_se5, i2chub0_se6, i2chub0_se7, i2chub0_se8,
i2chub0_se9, i2s0_data0, i2s0_data1, i2s0_sck, i2s0_ws,
i2s1_data0, i2s1_data1, i2s1_sck, i2s1_ws, ibi_i3c,
jitter_bist, mdp_vsync, mdp_vsync0_out, mdp_vsync1_out,
mdp_vsync2_out, mdp_vsync3_out, mdp_vsync_e, nav_gpio0,
nav_gpio1, nav_gpio2, nav_gpio3, pcie0_clk_req_n,
pcie1_clk_req_n, phase_flag, pll_bist_sync, pll_clk_aux,
prng_rosc0, prng_rosc1, prng_rosc2, prng_rosc3, qdss_cti,
qdss_gpio, qlink_big_enable, qlink_big_request,
qlink_little_enable, qlink_little_request, qlink_wmss,
qspi0, qspi1, qspi2, qspi3, qspi_clk, qspi_cs, qup1_se0,
qup1_se1, qup1_se2, qup1_se3, qup1_se4, qup1_se5, qup1_se6,
qup1_se7, qup2_se0, qup2_se1, qup2_se2, qup2_se3, qup2_se4,
qup2_se5, qup2_se6, qup2_se7, sd_write_protect, sdc40, sdc41,
sdc42, sdc43, sdc4_clk, sdc4_cmd, tb_trig_sdc2, tb_trig_sdc4,
tgu_ch0_trigout, tgu_ch1_trigout, tgu_ch2_trigout,
tgu_ch3_trigout, tmess_prng0, tmess_prng1, tmess_prng2,
tmess_prng3, tsense_pwm1, tsense_pwm2, tsense_pwm3, uim0_clk,
uim0_data, uim0_present, uim0_reset, uim1_clk, uim1_data,
uim1_present, uim1_reset, usb1_hs, usb_phy, vfr_0, vfr_1,
vsense_trigger_mirnat ]
required:
- pins
required:
- compatible
- reg
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/arm-gic.h>
tlmm: pinctrl@f100000 {
compatible = "qcom,sm8650-tlmm";
reg = <0x0f100000 0x300000>;
gpio-controller;
#gpio-cells = <2>;
gpio-ranges = <&tlmm 0 0 211>;
interrupt-controller;
#interrupt-cells = <2>;
interrupts = <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>;
gpio-wo-state {
pins = "gpio1";
function = "gpio";
};
uart-w-state {
rx-pins {
pins = "gpio60";
function = "qup1_se7";
bias-pull-up;
};
tx-pins {
pins = "gpio61";
function = "qup1_se7";
bias-disable;
};
};
};
...
@@ -0,0 +1,137 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/pinctrl/qcom,x1e80100-tlmm.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm Technologies, Inc. X1E80100 TLMM block
maintainers:
- Rajendra Nayak <quic_rjendra@quicinc.com>
description:
Top Level Mode Multiplexer pin controller in Qualcomm X1E80100 SoC.
allOf:
- $ref: /schemas/pinctrl/qcom,tlmm-common.yaml#
properties:
compatible:
const: qcom,x1e80100-tlmm
reg:
maxItems: 1
interrupts:
maxItems: 1
gpio-reserved-ranges:
minItems: 1
maxItems: 119
gpio-line-names:
maxItems: 238
patternProperties:
"-state$":
oneOf:
- $ref: "#/$defs/qcom-x1e80100-tlmm-state"
- patternProperties:
"-pins$":
$ref: "#/$defs/qcom-x1e80100-tlmm-state"
additionalProperties: false
$defs:
qcom-x1e80100-tlmm-state:
type: object
description:
Pinctrl node's client devices use subnodes for desired pin configuration.
Client device subnodes use below standard properties.
$ref: qcom,tlmm-common.yaml#/$defs/qcom-tlmm-state
unevaluatedProperties: false
properties:
pins:
description:
List of gpio pins affected by the properties specified in this
subnode.
items:
oneOf:
- pattern: "^gpio([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-2][0-9]|23[0-7])$"
- enum: [ ufs_reset, sdc2_clk, sdc2_cmd, sdc2_data ]
minItems: 1
maxItems: 36
function:
description:
Specify the alternative function to be configured for the specified
pins.
enum: [ aon_cci, aoss_cti, atest_char, atest_char0,
atest_char1, atest_char2, atest_char3, atest_usb,
audio_ext, audio_ref, cam_aon, cam_mclk, cci_async,
cci_i2c, cci_timer0, cci_timer1, cci_timer2, cci_timer3,
cci_timer4, cmu_rng0, cmu_rng1, cmu_rng2, cmu_rng3,
cri_trng, dbg_out, ddr_bist, ddr_pxi0, ddr_pxi1,
ddr_pxi2, ddr_pxi3, ddr_pxi4, ddr_pxi5, ddr_pxi6, ddr_pxi7,
edp0_hot, edp0_lcd, edp1_hot, edp1_lcd, eusb0_ac, eusb1_ac,
eusb2_ac, eusb3_ac, eusb5_ac, eusb6_ac, gcc_gp1, gcc_gp2,
gcc_gp3, gpio, i2s0_data0, i2s0_data1, i2s0_sck, i2s0_ws, i2s1_data0,
i2s1_data1, i2s1_sck, i2s1_ws, ibi_i3c, jitter_bist, mdp_vsync0,
mdp_vsync1, mdp_vsync2, mdp_vsync3, mdp_vsync4, mdp_vsync5,
mdp_vsync6, mdp_vsync7, mdp_vsync8, pcie3_clk, pcie4_clk,
pcie5_clk, pcie6a_clk, pcie6b_clk, phase_flag, pll_bist, pll_clk,
prng_rosc0, prng_rosc1, prng_rosc2, prng_rosc3, qdss_cti,
qdss_gpio, qspi00, qspi01, qspi02, qspi03, qspi0_clk, qspi0_cs0,
qspi0_cs1, qup0_se0, qup0_se1, qup0_se2, qup0_se3, qup0_se4,
qup0_se5, qup0_se6, qup0_se7, qup1_se0, qup1_se1, qup1_se2, qup1_se3,
qup1_se4, qup1_se5, qup1_se6, qup1_se7, qup2_se0, qup2_se1, qup2_se2,
qup2_se3, qup2_se4, qup2_se5, qup2_se6, qup2_se7, sd_write, sdc4_clk,
sdc4_cmd, sdc4_data0, sdc4_data1, sdc4_data2, sdc4_data3, sys_throttle,
tb_trig, tgu_ch0, tgu_ch1, tgu_ch2, tgu_ch3, tgu_ch4, tgu_ch5,
tgu_ch6, tgu_ch7, tmess_prng0, tmess_prng1, tmess_prng2, tmess_prng3,
tsense_pwm1, tsense_pwm2, sense_pwm3, tsense_pwm4, usb0_dp, usb0_phy,
usb0_sbrx, usb0_sbtx, usb1_dp, usb1_phy, usb1_sbrx, usb1_sbtx,
usb2_dp, usb2_phy, usb2_sbrx, usb2_sbtx, vsense_trigger ]
required:
- pins
required:
- compatible
- reg
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/arm-gic.h>
tlmm: pinctrl@f100000 {
compatible = "qcom,x1e80100-tlmm";
reg = <0x0f100000 0xf00000>;
gpio-controller;
#gpio-cells = <2>;
gpio-ranges = <&tlmm 0 0 239>;
interrupt-controller;
#interrupt-cells = <2>;
interrupts = <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>;
gpio-wo-state {
pins = "gpio1";
function = "gpio";
};
uart-w-state {
rx-pins {
pins = "gpio26";
function = "qup2_se7";
bias-pull-up;
};
tx-pins {
pins = "gpio27";
function = "qup2_se7";
bias-disable;
};
};
};
...
@@ -20,7 +20,7 @@ description:
properties:
compatible:
const: "renesas,r7s9210-pinctrl" # RZ/A2M
const: renesas,r7s9210-pinctrl # RZ/A2M
reg:
maxItems: 1
@@ -28,15 +28,27 @@ description: |
properties:
compatible:
enum:
- samsung,s3c2410-wakeup-eint
- samsung,s3c2412-wakeup-eint
- samsung,s3c64xx-wakeup-eint
- samsung,s5pv210-wakeup-eint
- samsung,exynos4210-wakeup-eint
- samsung,exynos7-wakeup-eint
- samsung,exynos850-wakeup-eint
- samsung,exynosautov9-wakeup-eint
oneOf:
- enum:
- samsung,s3c2410-wakeup-eint
- samsung,s3c2412-wakeup-eint
- samsung,s3c64xx-wakeup-eint
- samsung,s5pv210-wakeup-eint
- samsung,exynos4210-wakeup-eint
- samsung,exynos7-wakeup-eint
- samsung,exynosautov920-wakeup-eint
- items:
- enum:
- samsung,exynos5433-wakeup-eint
- samsung,exynos7885-wakeup-eint
- samsung,exynos850-wakeup-eint
- const: samsung,exynos7-wakeup-eint
- items:
- enum:
- google,gs101-wakeup-eint
- samsung,exynosautov9-wakeup-eint
- const: samsung,exynos850-wakeup-eint
- const: samsung,exynos7-wakeup-eint
interrupts:
description:
@@ -79,11 +91,14 @@ allOf:
- if:
properties:
compatible:
contains:
enum:
- samsung,s5pv210-wakeup-eint
- samsung,exynos4210-wakeup-eint
- samsung,exynos7-wakeup-eint
# Match without "contains", to skip newer variants which are still
# compatible with samsung,exynos7-wakeup-eint
enum:
- samsung,s5pv210-wakeup-eint
- samsung,exynos4210-wakeup-eint
- samsung,exynos5433-wakeup-eint
- samsung,exynos7-wakeup-eint
- samsung,exynos7885-wakeup-eint
then:
properties:
interrupts:
@@ -98,7 +113,7 @@ allOf:
contains:
enum:
- samsung,exynos850-wakeup-eint
- samsung,exynosautov9-wakeup-eint
- samsung,exynosautov920-wakeup-eint
then:
properties:
interrupts: false
@@ -35,6 +35,7 @@ properties:
compatible:
enum:
- google,gs101-pinctrl
- samsung,s3c2412-pinctrl
- samsung,s3c2416-pinctrl
- samsung,s3c2440-pinctrl
@@ -53,6 +54,7 @@ properties:
- samsung,exynos7885-pinctrl
- samsung,exynos850-pinctrl
- samsung,exynosautov9-pinctrl
- samsung,exynosautov920-pinctrl
- tesla,fsd-pinctrl
interrupts:
@@ -313,7 +315,8 @@ examples:
pinctrl-0 = <&initial_alive>;
wakeup-interrupt-controller {
compatible = "samsung,exynos7-wakeup-eint";
compatible = "samsung,exynos5433-wakeup-eint",
"samsung,exynos7-wakeup-eint";
interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
};
@@ -39,7 +39,7 @@ properties:
phandle to the SLCR.
patternProperties:
'^(.*-)?(default|gpio)$':
'^(.*-)?(default|gpio-grp)$':
type: object
patternProperties:
'^mux':
@@ -31,7 +31,7 @@ properties:
const: xlnx,zynqmp-pinctrl
patternProperties:
'^(.*-)?(default|gpio)$':
'^(.*-)?(default|gpio-grp)$':
type: object
patternProperties:
'^mux':
-1
View File
@@ -19295,7 +19295,6 @@ R: Alim Akhtar <alim.akhtar@samsung.com>
L: linux-samsung-soc@vger.kernel.org
S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux.git
T: git git://git.kernel.org/pub/scm/linux/kernel/git/snawrocki/clk.git
F: Documentation/devicetree/bindings/clock/samsung,*.yaml
F: Documentation/devicetree/bindings/clock/samsung,s3c*
F: drivers/clk/samsung/
+3 -3
View File
@@ -355,7 +355,7 @@ static int ssi_add_controller(struct hsi_controller *ssi,
if (!omap_ssi)
return -ENOMEM;
err = ida_simple_get(&platform_omap_ssi_ida, 0, 0, GFP_KERNEL);
err = ida_alloc(&platform_omap_ssi_ida, GFP_KERNEL);
if (err < 0)
return err;
ssi->id = err;
@@ -417,7 +417,7 @@ static int ssi_add_controller(struct hsi_controller *ssi,
return 0;
out_err:
ida_simple_remove(&platform_omap_ssi_ida, ssi->id);
ida_free(&platform_omap_ssi_ida, ssi->id);
return err;
}
@@ -451,7 +451,7 @@ static void ssi_remove_controller(struct hsi_controller *ssi)
tasklet_kill(&omap_ssi->gdd_tasklet);
hsi_unregister_controller(ssi);
clk_notifier_unregister(omap_ssi->fck, &omap_ssi->fck_nb);
ida_simple_remove(&platform_omap_ssi_ida, id);
ida_free(&platform_omap_ssi_ida, id);
}
static inline int ssi_of_get_available_ports_count(const struct device_node *np)
+29 -24
View File
@@ -84,8 +84,9 @@ static DEFINE_MUTEX(hwspinlock_tree_lock);
* should decide between spin_trylock, spin_trylock_irq and
* spin_trylock_irqsave.
*
* Returns 0 if we successfully locked the hwspinlock or -EBUSY if
* Returns: %0 if we successfully locked the hwspinlock or -EBUSY if
* the hwspinlock was already taken.
*
* This function will never sleep.
*/
int __hwspin_trylock(struct hwspinlock *hwlock, int mode, unsigned long *flags)
@@ -171,7 +172,7 @@ EXPORT_SYMBOL_GPL(__hwspin_trylock);
/**
* __hwspin_lock_timeout() - lock an hwspinlock with timeout limit
* @hwlock: the hwspinlock to be locked
* @timeout: timeout value in msecs
* @to: timeout value in msecs
* @mode: mode which controls whether local interrupts are disabled or not
* @flags: a pointer to where the caller's interrupt state will be saved at (if
* requested)
@@ -199,9 +200,11 @@ EXPORT_SYMBOL_GPL(__hwspin_trylock);
* to choose the appropriate @mode of operation, exactly the same way users
* should decide between spin_lock, spin_lock_irq and spin_lock_irqsave.
*
* Returns 0 when the @hwlock was successfully taken, and an appropriate
* Returns: %0 when the @hwlock was successfully taken, and an appropriate
* error code otherwise (most notably -ETIMEDOUT if the @hwlock is still
* busy after @timeout msecs). The function will never sleep.
* busy after @timeout msecs).
*
* The function will never sleep.
*/
int __hwspin_lock_timeout(struct hwspinlock *hwlock, unsigned int to,
int mode, unsigned long *flags)
@@ -304,13 +307,12 @@ EXPORT_SYMBOL_GPL(__hwspin_unlock);
/**
* of_hwspin_lock_simple_xlate - translate hwlock_spec to return a lock id
* @bank: the hwspinlock device bank
* @hwlock_spec: hwlock specifier as found in the device tree
*
* This is a simple translation function, suitable for hwspinlock platform
* drivers that only has a lock specifier length of 1.
*
* Returns a relative index of the lock within a specified bank on success,
* Returns: a relative index of the lock within a specified bank on success,
* or -EINVAL on invalid specifier cell count.
*/
static inline int
@@ -332,9 +334,10 @@ of_hwspin_lock_simple_xlate(const struct of_phandle_args *hwlock_spec)
* hwspinlock device, so that it can be requested using the normal
* hwspin_lock_request_specific() API.
*
* Returns the global lock id number on success, -EPROBE_DEFER if the hwspinlock
* device is not yet registered, -EINVAL on invalid args specifier value or an
* appropriate error as returned from the OF parsing of the DT client node.
* Returns: the global lock id number on success, -EPROBE_DEFER if the
* hwspinlock device is not yet registered, -EINVAL on invalid args
* specifier value or an appropriate error as returned from the OF parsing
* of the DT client node.
*/
int of_hwspin_lock_get_id(struct device_node *np, int index)
{
@@ -399,9 +402,10 @@ EXPORT_SYMBOL_GPL(of_hwspin_lock_get_id);
* the hwspinlock device, so that it can be requested using the normal
* hwspin_lock_request_specific() API.
*
* Returns the global lock id number on success, -EPROBE_DEFER if the hwspinlock
* device is not yet registered, -EINVAL on invalid args specifier value or an
* appropriate error as returned from the OF parsing of the DT client node.
* Returns: the global lock id number on success, -EPROBE_DEFER if the
* hwspinlock device is not yet registered, -EINVAL on invalid args
* specifier value or an appropriate error as returned from the OF parsing
* of the DT client node.
*/
int of_hwspin_lock_get_id_byname(struct device_node *np, const char *name)
{
@@ -481,7 +485,7 @@ out:
*
* Should be called from a process context (might sleep)
*
* Returns 0 on success, or an appropriate error code on failure
* Returns: %0 on success, or an appropriate error code on failure
*/
int hwspin_lock_register(struct hwspinlock_device *bank, struct device *dev,
const struct hwspinlock_ops *ops, int base_id, int num_locks)
@@ -529,7 +533,7 @@ EXPORT_SYMBOL_GPL(hwspin_lock_register);
*
* Should be called from a process context (might sleep)
*
* Returns 0 on success, or an appropriate error code on failure
* Returns: %0 on success, or an appropriate error code on failure
*/
int hwspin_lock_unregister(struct hwspinlock_device *bank)
{
@@ -578,7 +582,7 @@ static int devm_hwspin_lock_device_match(struct device *dev, void *res,
*
* Should be called from a process context (might sleep)
*
* Returns 0 on success, or an appropriate error code on failure
* Returns: %0 on success, or an appropriate error code on failure
*/
int devm_hwspin_lock_unregister(struct device *dev,
struct hwspinlock_device *bank)
@@ -607,7 +611,7 @@ EXPORT_SYMBOL_GPL(devm_hwspin_lock_unregister);
*
* Should be called from a process context (might sleep)
*
* Returns 0 on success, or an appropriate error code on failure
* Returns: %0 on success, or an appropriate error code on failure
*/
int devm_hwspin_lock_register(struct device *dev,
struct hwspinlock_device *bank,
@@ -635,12 +639,13 @@ EXPORT_SYMBOL_GPL(devm_hwspin_lock_register);
/**
* __hwspin_lock_request() - tag an hwspinlock as used and power it up
* @hwlock: the target hwspinlock
*
* This is an internal function that prepares an hwspinlock instance
* before it is given to the user. The function assumes that
* hwspinlock_tree_lock is taken.
*
* Returns 0 or positive to indicate success, and a negative value to
* Returns: %0 or positive to indicate success, and a negative value to
* indicate an error (with the appropriate error code)
*/
static int __hwspin_lock_request(struct hwspinlock *hwlock)
@@ -680,7 +685,7 @@ static int __hwspin_lock_request(struct hwspinlock *hwlock)
* hwspin_lock_get_id() - retrieve id number of a given hwspinlock
* @hwlock: a valid hwspinlock instance
*
* Returns the id number of a given @hwlock, or -EINVAL if @hwlock is invalid.
* Returns: the id number of a given @hwlock, or -EINVAL if @hwlock is invalid.
*/
int hwspin_lock_get_id(struct hwspinlock *hwlock)
{
@@ -704,7 +709,7 @@ EXPORT_SYMBOL_GPL(hwspin_lock_get_id);
*
* Should be called from a process context (might sleep)
*
* Returns the address of the assigned hwspinlock, or NULL on error
* Returns: the address of the assigned hwspinlock, or %NULL on error
*/
struct hwspinlock *hwspin_lock_request(void)
{
@@ -747,7 +752,7 @@ EXPORT_SYMBOL_GPL(hwspin_lock_request);
*
* Should be called from a process context (might sleep)
*
* Returns the address of the assigned hwspinlock, or NULL on error
* Returns: the address of the assigned hwspinlock, or %NULL on error
*/
struct hwspinlock *hwspin_lock_request_specific(unsigned int id)
{
@@ -795,7 +800,7 @@ EXPORT_SYMBOL_GPL(hwspin_lock_request_specific);
*
* Should be called from a process context (might sleep)
*
* Returns 0 on success, or an appropriate error code on failure
* Returns: %0 on success, or an appropriate error code on failure
*/
int hwspin_lock_free(struct hwspinlock *hwlock)
{
@@ -865,7 +870,7 @@ static void devm_hwspin_lock_release(struct device *dev, void *res)
*
* Should be called from a process context (might sleep)
*
* Returns 0 on success, or an appropriate error code on failure
* Returns: %0 on success, or an appropriate error code on failure
*/
int devm_hwspin_lock_free(struct device *dev, struct hwspinlock *hwlock)
{
@@ -891,7 +896,7 @@ EXPORT_SYMBOL_GPL(devm_hwspin_lock_free);
*
* Should be called from a process context (might sleep)
*
* Returns the address of the assigned hwspinlock, or NULL on error
* Returns: the address of the assigned hwspinlock, or %NULL on error
*/
struct hwspinlock *devm_hwspin_lock_request(struct device *dev)
{
@@ -926,7 +931,7 @@ EXPORT_SYMBOL_GPL(devm_hwspin_lock_request);
*
* Should be called from a process context (might sleep)
*
* Returns the address of the assigned hwspinlock, or NULL on error
* Returns: the address of the assigned hwspinlock, or %NULL on error
*/
struct hwspinlock *devm_hwspin_lock_request_specific(struct device *dev,
unsigned int id)
-1
View File
@@ -115,7 +115,6 @@ static const struct of_device_id qcom_hwspinlock_of_match[] = {
{ .compatible = "qcom,sfpb-mutex", .data = &of_sfpb_mutex },
{ .compatible = "qcom,tcsr-mutex", .data = &of_tcsr_mutex },
{ .compatible = "qcom,apq8084-tcsr-mutex", .data = &of_msm8226_tcsr_mutex },
{ .compatible = "qcom,ipq6018-tcsr-mutex", .data = &of_msm8226_tcsr_mutex },
{ .compatible = "qcom,msm8226-tcsr-mutex", .data = &of_msm8226_tcsr_mutex },
{ .compatible = "qcom,msm8974-tcsr-mutex", .data = &of_msm8226_tcsr_mutex },
{ .compatible = "qcom,msm8994-tcsr-mutex", .data = &of_msm8226_tcsr_mutex },
+30 -5
View File
@@ -95,14 +95,18 @@ config LEDS_ARIEL
Say Y to if your machine is a Dell Wyse 3020 thin client.
config LEDS_AW200XX
tristate "LED support for Awinic AW20036/AW20054/AW20072"
tristate "LED support for Awinic AW20036/AW20054/AW20072/AW20108"
depends on LEDS_CLASS
depends on I2C
help
This option enables support for the AW20036/AW20054/AW20072 LED driver.
It is a 3x12/6x9/6x12 matrix LED driver programmed via
an I2C interface, up to 36/54/72 LEDs or 12/18/24 RGBs,
3 pattern controllers for auto breathing or group dimming control.
This option enables support for the Awinic AW200XX LED controllers.
It is a matrix LED driver programmed via an I2C interface. Devices have
a set of individually controlled LEDs and support 3 pattern controllers
for auto breathing or group dimming control. Supported devices:
- AW20036 (3x12) 36 LEDs
- AW20054 (6x9) 54 LEDs
- AW20072 (6x12) 72 LEDs
- AW20108 (9x12) 108 LEDs
To compile this driver as a module, choose M here: the module
will be called leds-aw200xx.
@@ -110,6 +114,7 @@ config LEDS_AW200XX
config LEDS_AW2013
tristate "LED support for Awinic AW2013"
depends on LEDS_CLASS && I2C && OF
select REGMAP_I2C
help
This option enables support for the AW2013 3-channel
LED driver.
@@ -298,6 +303,15 @@ config LEDS_COBALT_RAQ
help
This option enables support for the Cobalt Raq series LEDs.
config LEDS_SUN50I_A100
tristate "LED support for Allwinner A100 RGB LED controller"
depends on LEDS_CLASS_MULTICOLOR
depends on ARCH_SUNXI || COMPILE_TEST
help
This option enables support for the RGB LED controller found
in some Allwinner sunxi SoCs, including A100, R329, and D1.
It uses a one-wire interface to control up to 1024 LEDs.
config LEDS_SUNFIRE
tristate "LED support for SunFire servers."
depends on LEDS_CLASS
@@ -638,6 +652,17 @@ config LEDS_ADP5520
To compile this driver as a module, choose M here: the module will
be called leds-adp5520.
config LEDS_MAX5970
tristate "LED Support for Maxim 5970"
depends on LEDS_CLASS
depends on MFD_MAX5970
help
This option enables support for the Maxim MAX5970 & MAX5978 smart
switch indication LEDs via the I2C bus.
To compile this driver as a module, choose M here: the module will
be called leds-max5970.
config LEDS_MC13783
tristate "LED Support for MC13XXX PMIC"
depends on LEDS_CLASS
+2
View File
@@ -56,6 +56,7 @@ obj-$(CONFIG_LEDS_LP8501) += leds-lp8501.o
obj-$(CONFIG_LEDS_LP8788) += leds-lp8788.o
obj-$(CONFIG_LEDS_LP8860) += leds-lp8860.o
obj-$(CONFIG_LEDS_LT3593) += leds-lt3593.o
obj-$(CONFIG_LEDS_MAX5970) += leds-max5970.o
obj-$(CONFIG_LEDS_MAX77650) += leds-max77650.o
obj-$(CONFIG_LEDS_MAX8997) += leds-max8997.o
obj-$(CONFIG_LEDS_MC13783) += leds-mc13783.o
@@ -78,6 +79,7 @@ obj-$(CONFIG_LEDS_POWERNV) += leds-powernv.o
obj-$(CONFIG_LEDS_PWM) += leds-pwm.o
obj-$(CONFIG_LEDS_REGULATOR) += leds-regulator.o
obj-$(CONFIG_LEDS_SC27XX_BLTC) += leds-sc27xx-bltc.o
obj-$(CONFIG_LEDS_SUN50I_A100) += leds-sun50i-a100.o
obj-$(CONFIG_LEDS_SUNFIRE) += leds-sunfire.o
obj-$(CONFIG_LEDS_SYSCON) += leds-syscon.o
obj-$(CONFIG_LEDS_TCA6507) += leds-tca6507.o
-13
View File
@@ -269,19 +269,6 @@ void led_trigger_set_default(struct led_classdev *led_cdev)
}
EXPORT_SYMBOL_GPL(led_trigger_set_default);
void led_trigger_rename_static(const char *name, struct led_trigger *trig)
{
/* new name must be on a temporary string to prevent races */
BUG_ON(name == trig->name);
down_write(&triggers_list_lock);
/* this assumes that trig->name was originaly allocated to
* non constant storage */
strcpy((char *)trig->name, name);
up_write(&triggers_list_lock);
}
EXPORT_SYMBOL_GPL(led_trigger_rename_static);
/* LED Trigger Interface */
int led_trigger_register(struct led_trigger *trig)
+83 -15
View File
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Awinic AW20036/AW20054/AW20072 LED driver
* Awinic AW20036/AW20054/AW20072/AW20108 LED driver
*
* Copyright (c) 2023, SberDevices. All Rights Reserved.
*
@@ -10,6 +10,7 @@
#include <linux/bitfield.h>
#include <linux/bits.h>
#include <linux/container_of.h>
#include <linux/gpio/consumer.h>
#include <linux/i2c.h>
#include <linux/leds.h>
#include <linux/mod_devicetable.h>
@@ -74,6 +75,10 @@
#define AW200XX_LED2REG(x, columns) \
((x) + (((x) / (columns)) * (AW200XX_DSIZE_COLUMNS_MAX - (columns))))
/* DIM current configuration register on page 1 */
#define AW200XX_REG_DIM_PAGE1(x, columns) \
AW200XX_REG(AW200XX_PAGE1, AW200XX_LED2REG(x, columns))
/*
* DIM current configuration register (page 4).
* The even address for current DIM configuration.
@@ -82,6 +87,8 @@
#define AW200XX_REG_DIM(x, columns) \
AW200XX_REG(AW200XX_PAGE4, AW200XX_LED2REG(x, columns) * 2)
#define AW200XX_REG_DIM2FADE(x) ((x) + 1)
#define AW200XX_REG_FADE2DIM(fade) \
DIV_ROUND_UP((fade) * AW200XX_DIM_MAX, AW200XX_FADE_MAX)
/*
* Duty ratio of display scan (see p.15 of datasheet for formula):
@@ -112,6 +119,7 @@ struct aw200xx {
struct mutex mutex;
u32 num_leds;
u32 display_rows;
struct gpio_desc *hwen;
struct aw200xx_led leds[] __counted_by(num_leds);
};
@@ -153,7 +161,8 @@ static ssize_t dim_store(struct device *dev, struct device_attribute *devattr,
if (dim >= 0) {
ret = regmap_write(chip->regmap,
AW200XX_REG_DIM(led->num, columns), dim);
AW200XX_REG_DIM_PAGE1(led->num, columns),
dim);
if (ret)
goto out_unlock;
}
@@ -188,9 +197,7 @@ static int aw200xx_brightness_set(struct led_classdev *cdev,
dim = led->dim;
if (dim < 0)
dim = max_t(int,
brightness / (AW200XX_FADE_MAX / AW200XX_DIM_MAX),
1);
dim = AW200XX_REG_FADE2DIM(brightness);
ret = regmap_write(chip->regmap, reg, dim);
if (ret)
@@ -314,6 +321,9 @@ static int aw200xx_chip_reset(const struct aw200xx *const chip)
if (ret)
return ret;
/* According to the datasheet software reset takes at least 1ms */
fsleep(1000);
regcache_mark_dirty(chip->regmap);
return regmap_write(chip->regmap, AW200XX_REG_FCD, AW200XX_FCD_CLEAR);
}
@@ -353,6 +363,50 @@ static int aw200xx_chip_check(const struct aw200xx *const chip)
return 0;
}
static void aw200xx_enable(const struct aw200xx *const chip)
{
gpiod_set_value_cansleep(chip->hwen, 1);
/*
* After HWEN pin set high the chip begins to load the OTP information,
* which takes 200us to complete. About 200us wait time is needed for
* internal oscillator startup and display SRAM initialization. After
* display SRAM initialization, the registers in page1 to page5 can be
* configured via i2c interface.
*/
fsleep(400);
}
static void aw200xx_disable(const struct aw200xx *const chip)
{
return gpiod_set_value_cansleep(chip->hwen, 0);
}
static int aw200xx_probe_get_display_rows(struct device *dev,
struct aw200xx *chip)
{
struct fwnode_handle *child;
u32 max_source = 0;
device_for_each_child_node(dev, child) {
u32 source;
int ret;
ret = fwnode_property_read_u32(child, "reg", &source);
if (ret || source >= chip->cdef->channels)
continue;
max_source = max(max_source, source);
}
if (max_source == 0)
return -EINVAL;
chip->display_rows = max_source / chip->cdef->display_size_columns + 1;
return 0;
}
static int aw200xx_probe_fw(struct device *dev, struct aw200xx *chip)
{
struct fwnode_handle *child;
@@ -360,18 +414,10 @@ static int aw200xx_probe_fw(struct device *dev, struct aw200xx *chip)
int ret;
int i;
ret = device_property_read_u32(dev, "awinic,display-rows",
&chip->display_rows);
ret = aw200xx_probe_get_display_rows(dev, chip);
if (ret)
return dev_err_probe(dev, ret,
"Failed to read 'display-rows' property\n");
if (!chip->display_rows ||
chip->display_rows > chip->cdef->display_size_rows_max) {
return dev_err_probe(dev, -EINVAL,
"Invalid leds display size %u\n",
chip->display_rows);
}
"No valid led definitions found\n");
current_max = aw200xx_imax_from_global(chip, AW200XX_IMAX_MAX_uA);
current_min = aw200xx_imax_from_global(chip, AW200XX_IMAX_MIN_uA);
@@ -416,6 +462,7 @@ static int aw200xx_probe_fw(struct device *dev, struct aw200xx *chip)
led->num = source;
led->chip = chip;
led->cdev.brightness_set_blocking = aw200xx_brightness_set;
led->cdev.max_brightness = AW200XX_FADE_MAX;
led->cdev.groups = dim_groups;
init_data.fwnode = child;
@@ -480,6 +527,7 @@ static const struct regmap_config aw200xx_regmap_config = {
.rd_table = &aw200xx_readable_table,
.wr_table = &aw200xx_writeable_table,
.cache_type = REGCACHE_MAPLE,
.disable_locking = true,
};
static int aw200xx_probe(struct i2c_client *client)
@@ -512,6 +560,14 @@ static int aw200xx_probe(struct i2c_client *client)
if (IS_ERR(chip->regmap))
return PTR_ERR(chip->regmap);
chip->hwen = devm_gpiod_get_optional(&client->dev, "enable",
GPIOD_OUT_HIGH);
if (IS_ERR(chip->hwen))
return dev_err_probe(&client->dev, PTR_ERR(chip->hwen),
"Cannot get enable GPIO");
aw200xx_enable(chip);
ret = aw200xx_chip_check(chip);
if (ret)
return ret;
@@ -532,6 +588,9 @@ static int aw200xx_probe(struct i2c_client *client)
ret = aw200xx_chip_init(chip);
out_unlock:
if (ret)
aw200xx_disable(chip);
mutex_unlock(&chip->mutex);
return ret;
}
@@ -541,6 +600,7 @@ static void aw200xx_remove(struct i2c_client *client)
struct aw200xx *chip = i2c_get_clientdata(client);
aw200xx_chip_reset(chip);
aw200xx_disable(chip);
mutex_destroy(&chip->mutex);
}
@@ -562,10 +622,17 @@ static const struct aw200xx_chipdef aw20072_cdef = {
.display_size_columns = 12,
};
static const struct aw200xx_chipdef aw20108_cdef = {
.channels = 108,
.display_size_rows_max = 9,
.display_size_columns = 12,
};
static const struct i2c_device_id aw200xx_id[] = {
{ "aw20036" },
{ "aw20054" },
{ "aw20072" },
{ "aw20108" },
{}
};
MODULE_DEVICE_TABLE(i2c, aw200xx_id);
@@ -574,6 +641,7 @@ static const struct of_device_id aw200xx_match_table[] = {
{ .compatible = "awinic,aw20036", .data = &aw20036_cdef, },
{ .compatible = "awinic,aw20054", .data = &aw20054_cdef, },
{ .compatible = "awinic,aw20072", .data = &aw20072_cdef, },
{ .compatible = "awinic,aw20108", .data = &aw20108_cdef, },
{}
};
MODULE_DEVICE_TABLE(of, aw200xx_match_table);
+2
View File
@@ -172,6 +172,8 @@ static struct gpio_leds_priv *gpio_leds_create(struct device *dev)
led.gpiod = devm_fwnode_gpiod_get(dev, child, NULL, GPIOD_ASIS,
NULL);
if (IS_ERR(led.gpiod)) {
dev_err_probe(dev, PTR_ERR(led.gpiod), "Failed to get GPIO '%pfw'\n",
child);
fwnode_handle_put(child);
return ERR_CAST(led.gpiod);
}
+111
View File
@@ -0,0 +1,111 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Device driver for leds in MAX5970 and MAX5978 IC
*
* Copyright (c) 2022 9elements GmbH
*
* Author: Patrick Rudolph <patrick.rudolph@9elements.com>
*/
#include <linux/bits.h>
#include <linux/container_of.h>
#include <linux/device.h>
#include <linux/leds.h>
#include <linux/mfd/max5970.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/regmap.h>
#define ldev_to_maxled(c) container_of(c, struct max5970_led, cdev)
struct max5970_led {
struct device *dev;
struct regmap *regmap;
struct led_classdev cdev;
unsigned int index;
};
static int max5970_led_set_brightness(struct led_classdev *cdev,
enum led_brightness brightness)
{
struct max5970_led *ddata = ldev_to_maxled(cdev);
int ret, val;
/* Set/clear corresponding bit for given led index */
val = !brightness ? BIT(ddata->index) : 0;
ret = regmap_update_bits(ddata->regmap, MAX5970_REG_LED_FLASH, BIT(ddata->index), val);
if (ret < 0)
dev_err(cdev->dev, "failed to set brightness %d", ret);
return ret;
}
static int max5970_led_probe(struct platform_device *pdev)
{
struct fwnode_handle *led_node, *child;
struct device *dev = &pdev->dev;
struct regmap *regmap;
struct max5970_led *ddata;
int ret = -ENODEV;
regmap = dev_get_regmap(dev->parent, NULL);
if (!regmap)
return -ENODEV;
led_node = device_get_named_child_node(dev->parent, "leds");
if (!led_node)
return -ENODEV;
fwnode_for_each_available_child_node(led_node, child) {
u32 reg;
if (fwnode_property_read_u32(child, "reg", &reg))
continue;
if (reg >= MAX5970_NUM_LEDS) {
dev_err_probe(dev, -EINVAL, "invalid LED (%u >= %d)\n", reg, MAX5970_NUM_LEDS);
continue;
}
ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL);
if (!ddata) {
fwnode_handle_put(child);
return -ENOMEM;
}
ddata->index = reg;
ddata->regmap = regmap;
ddata->dev = dev;
if (fwnode_property_read_string(child, "label", &ddata->cdev.name))
ddata->cdev.name = fwnode_get_name(child);
ddata->cdev.max_brightness = 1;
ddata->cdev.brightness_set_blocking = max5970_led_set_brightness;
ddata->cdev.default_trigger = "none";
ret = devm_led_classdev_register(dev, &ddata->cdev);
if (ret < 0) {
fwnode_handle_put(child);
return dev_err_probe(dev, ret, "Failed to initialize LED %u\n", reg);
}
}
return ret;
}
static struct platform_driver max5970_led_driver = {
.driver = {
.name = "max5970-led",
},
.probe = max5970_led_probe,
};
module_platform_driver(max5970_led_driver);
MODULE_AUTHOR("Patrick Rudolph <patrick.rudolph@9elements.com>");
MODULE_AUTHOR("Naresh Solanki <Naresh.Solanki@9elements.com>");
MODULE_DESCRIPTION("MAX5970_hot-swap controller LED driver");
MODULE_LICENSE("GPL");
+584
View File
@@ -0,0 +1,584 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2021-2023 Samuel Holland <samuel@sholland.org>
*
* Partly based on drivers/leds/leds-turris-omnia.c, which is:
* Copyright (c) 2020 by Marek Behún <kabel@kernel.org>
*/
#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/dmaengine.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/led-class-multicolor.h>
#include <linux/leds.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/property.h>
#include <linux/reset.h>
#include <linux/spinlock.h>
#define LEDC_CTRL_REG 0x0000
#define LEDC_CTRL_REG_DATA_LENGTH GENMASK(28, 16)
#define LEDC_CTRL_REG_RGB_MODE GENMASK(8, 6)
#define LEDC_CTRL_REG_LEDC_EN BIT(0)
#define LEDC_T01_TIMING_CTRL_REG 0x0004
#define LEDC_T01_TIMING_CTRL_REG_T1H GENMASK(26, 21)
#define LEDC_T01_TIMING_CTRL_REG_T1L GENMASK(20, 16)
#define LEDC_T01_TIMING_CTRL_REG_T0H GENMASK(10, 6)
#define LEDC_T01_TIMING_CTRL_REG_T0L GENMASK(5, 0)
#define LEDC_RESET_TIMING_CTRL_REG 0x000c
#define LEDC_RESET_TIMING_CTRL_REG_TR GENMASK(28, 16)
#define LEDC_RESET_TIMING_CTRL_REG_LED_NUM GENMASK(9, 0)
#define LEDC_DATA_REG 0x0014
#define LEDC_DMA_CTRL_REG 0x0018
#define LEDC_DMA_CTRL_REG_DMA_EN BIT(5)
#define LEDC_DMA_CTRL_REG_FIFO_TRIG_LEVEL GENMASK(4, 0)
#define LEDC_INT_CTRL_REG 0x001c
#define LEDC_INT_CTRL_REG_GLOBAL_INT_EN BIT(5)
#define LEDC_INT_CTRL_REG_FIFO_CPUREQ_INT_EN BIT(1)
#define LEDC_INT_CTRL_REG_TRANS_FINISH_INT_EN BIT(0)
#define LEDC_INT_STS_REG 0x0020
#define LEDC_INT_STS_REG_FIFO_WLW GENMASK(15, 10)
#define LEDC_INT_STS_REG_FIFO_CPUREQ_INT BIT(1)
#define LEDC_INT_STS_REG_TRANS_FINISH_INT BIT(0)
#define LEDC_FIFO_DEPTH 32U
#define LEDC_MAX_LEDS 1024
#define LEDC_CHANNELS_PER_LED 3 /* RGB */
#define LEDS_TO_BYTES(n) ((n) * sizeof(u32))
struct sun50i_a100_ledc_led {
struct led_classdev_mc mc_cdev;
struct mc_subled subled_info[LEDC_CHANNELS_PER_LED];
u32 addr;
};
#define to_ledc_led(mc) container_of(mc, struct sun50i_a100_ledc_led, mc_cdev)
struct sun50i_a100_ledc_timing {
u32 t0h_ns;
u32 t0l_ns;
u32 t1h_ns;
u32 t1l_ns;
u32 treset_ns;
};
struct sun50i_a100_ledc {
struct device *dev;
void __iomem *base;
struct clk *bus_clk;
struct clk *mod_clk;
struct reset_control *reset;
u32 *buffer;
struct dma_chan *dma_chan;
dma_addr_t dma_handle;
unsigned int pio_length;
unsigned int pio_offset;
spinlock_t lock;
unsigned int next_length;
bool xfer_active;
u32 format;
struct sun50i_a100_ledc_timing timing;
u32 max_addr;
u32 num_leds;
struct sun50i_a100_ledc_led leds[] __counted_by(num_leds);
};
static int sun50i_a100_ledc_dma_xfer(struct sun50i_a100_ledc *priv, unsigned int length)
{
struct dma_async_tx_descriptor *desc;
dma_cookie_t cookie;
desc = dmaengine_prep_slave_single(priv->dma_chan, priv->dma_handle,
LEDS_TO_BYTES(length), DMA_MEM_TO_DEV, 0);
if (!desc)
return -ENOMEM;
cookie = dmaengine_submit(desc);
if (dma_submit_error(cookie))
return -EIO;
dma_async_issue_pending(priv->dma_chan);
return 0;
}
static void sun50i_a100_ledc_pio_xfer(struct sun50i_a100_ledc *priv, unsigned int fifo_used)
{
unsigned int burst, length, offset;
u32 control;
length = priv->pio_length;
offset = priv->pio_offset;
burst = min(length, LEDC_FIFO_DEPTH - fifo_used);
iowrite32_rep(priv->base + LEDC_DATA_REG, priv->buffer + offset, burst);
if (burst < length) {
priv->pio_length = length - burst;
priv->pio_offset = offset + burst;
if (!offset) {
control = readl(priv->base + LEDC_INT_CTRL_REG);
control |= LEDC_INT_CTRL_REG_FIFO_CPUREQ_INT_EN;
writel(control, priv->base + LEDC_INT_CTRL_REG);
}
} else {
/* Disable the request IRQ once all data is written. */
control = readl(priv->base + LEDC_INT_CTRL_REG);
control &= ~LEDC_INT_CTRL_REG_FIFO_CPUREQ_INT_EN;
writel(control, priv->base + LEDC_INT_CTRL_REG);
}
}
static void sun50i_a100_ledc_start_xfer(struct sun50i_a100_ledc *priv, unsigned int length)
{
bool use_dma = false;
u32 control;
if (priv->dma_chan && length > LEDC_FIFO_DEPTH) {
int ret;
ret = sun50i_a100_ledc_dma_xfer(priv, length);
if (ret)
dev_warn(priv->dev, "Failed to set up DMA (%d), using PIO\n", ret);
else
use_dma = true;
}
/* The DMA trigger level must be at least the burst length. */
control = FIELD_PREP(LEDC_DMA_CTRL_REG_DMA_EN, use_dma) |
FIELD_PREP_CONST(LEDC_DMA_CTRL_REG_FIFO_TRIG_LEVEL, LEDC_FIFO_DEPTH / 2);
writel(control, priv->base + LEDC_DMA_CTRL_REG);
control = readl(priv->base + LEDC_CTRL_REG);
control &= ~LEDC_CTRL_REG_DATA_LENGTH;
control |= FIELD_PREP(LEDC_CTRL_REG_DATA_LENGTH, length) | LEDC_CTRL_REG_LEDC_EN;
writel(control, priv->base + LEDC_CTRL_REG);
if (!use_dma) {
/* The FIFO is empty when starting a new transfer. */
unsigned int fifo_used = 0;
priv->pio_length = length;
priv->pio_offset = 0;
sun50i_a100_ledc_pio_xfer(priv, fifo_used);
}
}
static irqreturn_t sun50i_a100_ledc_irq(int irq, void *data)
{
struct sun50i_a100_ledc *priv = data;
u32 status;
status = readl(priv->base + LEDC_INT_STS_REG);
if (status & LEDC_INT_STS_REG_TRANS_FINISH_INT) {
unsigned int next_length;
spin_lock(&priv->lock);
/* If another transfer is queued, dequeue and start it. */
next_length = priv->next_length;
if (next_length)
priv->next_length = 0;
else
priv->xfer_active = false;
spin_unlock(&priv->lock);
if (next_length)
sun50i_a100_ledc_start_xfer(priv, next_length);
} else if (status & LEDC_INT_STS_REG_FIFO_CPUREQ_INT) {
/* Continue the current transfer. */
sun50i_a100_ledc_pio_xfer(priv, FIELD_GET(LEDC_INT_STS_REG_FIFO_WLW, status));
}
/* Clear the W1C status bits. */
writel(status, priv->base + LEDC_INT_STS_REG);
return IRQ_HANDLED;
}
static void sun50i_a100_ledc_brightness_set(struct led_classdev *cdev,
enum led_brightness brightness)
{
struct sun50i_a100_ledc *priv = dev_get_drvdata(cdev->dev->parent);
struct led_classdev_mc *mc_cdev = lcdev_to_mccdev(cdev);
struct sun50i_a100_ledc_led *led = to_ledc_led(mc_cdev);
unsigned int next_length;
unsigned long flags;
bool xfer_active;
led_mc_calc_color_components(mc_cdev, brightness);
priv->buffer[led->addr] = led->subled_info[0].brightness << 16 |
led->subled_info[1].brightness << 8 |
led->subled_info[2].brightness;
spin_lock_irqsave(&priv->lock, flags);
/* Start, enqueue, or extend an enqueued transfer, as appropriate. */
next_length = max(priv->next_length, led->addr + 1);
xfer_active = priv->xfer_active;
if (xfer_active)
priv->next_length = next_length;
else
priv->xfer_active = true;
spin_unlock_irqrestore(&priv->lock, flags);
if (!xfer_active)
sun50i_a100_ledc_start_xfer(priv, next_length);
}
static const char *const sun50i_a100_ledc_formats[] = {
"rgb", "rbg", "grb", "gbr", "brg", "bgr",
};
static int sun50i_a100_ledc_parse_format(struct device *dev,
struct sun50i_a100_ledc *priv)
{
const char *format = "grb";
u32 i;
device_property_read_string(dev, "allwinner,pixel-format", &format);
for (i = 0; i < ARRAY_SIZE(sun50i_a100_ledc_formats); i++) {
if (!strcmp(format, sun50i_a100_ledc_formats[i])) {
priv->format = i;
return 0;
}
}
return dev_err_probe(dev, -EINVAL, "Bad pixel format '%s'\n", format);
}
static void sun50i_a100_ledc_set_format(struct sun50i_a100_ledc *priv)
{
u32 control;
control = readl(priv->base + LEDC_CTRL_REG);
control &= ~LEDC_CTRL_REG_RGB_MODE;
control |= FIELD_PREP(LEDC_CTRL_REG_RGB_MODE, priv->format);
writel(control, priv->base + LEDC_CTRL_REG);
}
static const struct sun50i_a100_ledc_timing sun50i_a100_ledc_default_timing = {
.t0h_ns = 336,
.t0l_ns = 840,
.t1h_ns = 882,
.t1l_ns = 294,
.treset_ns = 300000,
};
static int sun50i_a100_ledc_parse_timing(struct device *dev,
struct sun50i_a100_ledc *priv)
{
struct sun50i_a100_ledc_timing *timing = &priv->timing;
*timing = sun50i_a100_ledc_default_timing;
device_property_read_u32(dev, "allwinner,t0h-ns", &timing->t0h_ns);
device_property_read_u32(dev, "allwinner,t0l-ns", &timing->t0l_ns);
device_property_read_u32(dev, "allwinner,t1h-ns", &timing->t1h_ns);
device_property_read_u32(dev, "allwinner,t1l-ns", &timing->t1l_ns);
device_property_read_u32(dev, "allwinner,treset-ns", &timing->treset_ns);
return 0;
}
static void sun50i_a100_ledc_set_timing(struct sun50i_a100_ledc *priv)
{
const struct sun50i_a100_ledc_timing *timing = &priv->timing;
unsigned long mod_freq = clk_get_rate(priv->mod_clk);
u32 cycle_ns;
u32 control;
if (!mod_freq)
return;
cycle_ns = NSEC_PER_SEC / mod_freq;
control = FIELD_PREP(LEDC_T01_TIMING_CTRL_REG_T1H, timing->t1h_ns / cycle_ns) |
FIELD_PREP(LEDC_T01_TIMING_CTRL_REG_T1L, timing->t1l_ns / cycle_ns) |
FIELD_PREP(LEDC_T01_TIMING_CTRL_REG_T0H, timing->t0h_ns / cycle_ns) |
FIELD_PREP(LEDC_T01_TIMING_CTRL_REG_T0L, timing->t0l_ns / cycle_ns);
writel(control, priv->base + LEDC_T01_TIMING_CTRL_REG);
control = FIELD_PREP(LEDC_RESET_TIMING_CTRL_REG_TR, timing->treset_ns / cycle_ns) |
FIELD_PREP(LEDC_RESET_TIMING_CTRL_REG_LED_NUM, priv->max_addr);
writel(control, priv->base + LEDC_RESET_TIMING_CTRL_REG);
}
static int sun50i_a100_ledc_resume(struct device *dev)
{
struct sun50i_a100_ledc *priv = dev_get_drvdata(dev);
int ret;
ret = reset_control_deassert(priv->reset);
if (ret)
return ret;
ret = clk_prepare_enable(priv->bus_clk);
if (ret)
goto err_assert_reset;
ret = clk_prepare_enable(priv->mod_clk);
if (ret)
goto err_disable_bus_clk;
sun50i_a100_ledc_set_format(priv);
sun50i_a100_ledc_set_timing(priv);
writel(LEDC_INT_CTRL_REG_GLOBAL_INT_EN | LEDC_INT_CTRL_REG_TRANS_FINISH_INT_EN,
priv->base + LEDC_INT_CTRL_REG);
return 0;
err_disable_bus_clk:
clk_disable_unprepare(priv->bus_clk);
err_assert_reset:
reset_control_assert(priv->reset);
return ret;
}
static int sun50i_a100_ledc_suspend(struct device *dev)
{
struct sun50i_a100_ledc *priv = dev_get_drvdata(dev);
/* Wait for all transfers to complete. */
for (;;) {
unsigned long flags;
bool xfer_active;
spin_lock_irqsave(&priv->lock, flags);
xfer_active = priv->xfer_active;
spin_unlock_irqrestore(&priv->lock, flags);
if (!xfer_active)
break;
msleep(1);
}
clk_disable_unprepare(priv->mod_clk);
clk_disable_unprepare(priv->bus_clk);
reset_control_assert(priv->reset);
return 0;
}
static void sun50i_a100_ledc_dma_cleanup(void *data)
{
struct sun50i_a100_ledc *priv = data;
dma_release_channel(priv->dma_chan);
}
static int sun50i_a100_ledc_probe(struct platform_device *pdev)
{
struct dma_slave_config dma_cfg = {};
struct led_init_data init_data = {};
struct sun50i_a100_ledc_led *led;
struct device *dev = &pdev->dev;
struct sun50i_a100_ledc *priv;
struct fwnode_handle *child;
struct resource *mem;
u32 max_addr = 0;
u32 num_leds = 0;
int irq, ret;
/*
* The maximum LED address must be known in sun50i_a100_ledc_resume() before
* class device registration, so parse and validate the subnodes up front.
*/
device_for_each_child_node(dev, child) {
u32 addr, color;
ret = fwnode_property_read_u32(child, "reg", &addr);
if (ret || addr >= LEDC_MAX_LEDS) {
fwnode_handle_put(child);
return dev_err_probe(dev, -EINVAL, "'reg' must be between 0 and %d\n",
LEDC_MAX_LEDS - 1);
}
ret = fwnode_property_read_u32(child, "color", &color);
if (ret || color != LED_COLOR_ID_RGB) {
fwnode_handle_put(child);
return dev_err_probe(dev, -EINVAL, "'color' must be LED_COLOR_ID_RGB\n");
}
max_addr = max(max_addr, addr);
num_leds++;
}
if (!num_leds)
return -ENODEV;
priv = devm_kzalloc(dev, struct_size(priv, leds, num_leds), GFP_KERNEL);
if (!priv)
return -ENOMEM;
priv->dev = dev;
priv->max_addr = max_addr;
priv->num_leds = num_leds;
spin_lock_init(&priv->lock);
dev_set_drvdata(dev, priv);
ret = sun50i_a100_ledc_parse_format(dev, priv);
if (ret)
return ret;
ret = sun50i_a100_ledc_parse_timing(dev, priv);
if (ret)
return ret;
priv->base = devm_platform_get_and_ioremap_resource(pdev, 0, &mem);
if (IS_ERR(priv->base))
return PTR_ERR(priv->base);
priv->bus_clk = devm_clk_get(dev, "bus");
if (IS_ERR(priv->bus_clk))
return PTR_ERR(priv->bus_clk);
priv->mod_clk = devm_clk_get(dev, "mod");
if (IS_ERR(priv->mod_clk))
return PTR_ERR(priv->mod_clk);
priv->reset = devm_reset_control_get_exclusive(dev, NULL);
if (IS_ERR(priv->reset))
return PTR_ERR(priv->reset);
priv->dma_chan = dma_request_chan(dev, "tx");
if (IS_ERR(priv->dma_chan)) {
if (PTR_ERR(priv->dma_chan) != -ENODEV)
return PTR_ERR(priv->dma_chan);
priv->dma_chan = NULL;
priv->buffer = devm_kzalloc(dev, LEDS_TO_BYTES(LEDC_MAX_LEDS), GFP_KERNEL);
if (!priv->buffer)
return -ENOMEM;
} else {
ret = devm_add_action_or_reset(dev, sun50i_a100_ledc_dma_cleanup, priv);
if (ret)
return ret;
dma_cfg.dst_addr = mem->start + LEDC_DATA_REG;
dma_cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
dma_cfg.dst_maxburst = LEDC_FIFO_DEPTH / 2;
ret = dmaengine_slave_config(priv->dma_chan, &dma_cfg);
if (ret)
return ret;
priv->buffer = dmam_alloc_attrs(dmaengine_get_dma_device(priv->dma_chan),
LEDS_TO_BYTES(LEDC_MAX_LEDS), &priv->dma_handle,
GFP_KERNEL, DMA_ATTR_WRITE_COMBINE);
if (!priv->buffer)
return -ENOMEM;
}
irq = platform_get_irq(pdev, 0);
if (irq < 0)
return irq;
ret = devm_request_irq(dev, irq, sun50i_a100_ledc_irq, 0, dev_name(dev), priv);
if (ret)
return ret;
ret = sun50i_a100_ledc_resume(dev);
if (ret)
return ret;
led = priv->leds;
device_for_each_child_node(dev, child) {
struct led_classdev *cdev;
/* The node was already validated above. */
fwnode_property_read_u32(child, "reg", &led->addr);
led->subled_info[0].color_index = LED_COLOR_ID_RED;
led->subled_info[0].channel = 0;
led->subled_info[1].color_index = LED_COLOR_ID_GREEN;
led->subled_info[1].channel = 1;
led->subled_info[2].color_index = LED_COLOR_ID_BLUE;
led->subled_info[2].channel = 2;
led->mc_cdev.num_colors = ARRAY_SIZE(led->subled_info);
led->mc_cdev.subled_info = led->subled_info;
cdev = &led->mc_cdev.led_cdev;
cdev->max_brightness = U8_MAX;
cdev->brightness_set = sun50i_a100_ledc_brightness_set;
init_data.fwnode = child;
ret = led_classdev_multicolor_register_ext(dev, &led->mc_cdev, &init_data);
if (ret) {
dev_err_probe(dev, ret, "Failed to register multicolor LED %u", led->addr);
goto err_put_child;
}
led++;
}
dev_info(dev, "Registered %u LEDs\n", num_leds);
return 0;
err_put_child:
fwnode_handle_put(child);
while (led-- > priv->leds)
led_classdev_multicolor_unregister(&led->mc_cdev);
sun50i_a100_ledc_suspend(&pdev->dev);
return ret;
}
static void sun50i_a100_ledc_remove(struct platform_device *pdev)
{
struct sun50i_a100_ledc *priv = platform_get_drvdata(pdev);
for (u32 i = 0; i < priv->num_leds; i++)
led_classdev_multicolor_unregister(&priv->leds[i].mc_cdev);
sun50i_a100_ledc_suspend(&pdev->dev);
}
static const struct of_device_id sun50i_a100_ledc_of_match[] = {
{ .compatible = "allwinner,sun50i-a100-ledc" },
{}
};
MODULE_DEVICE_TABLE(of, sun50i_a100_ledc_of_match);
static DEFINE_SIMPLE_DEV_PM_OPS(sun50i_a100_ledc_pm,
sun50i_a100_ledc_suspend,
sun50i_a100_ledc_resume);
static struct platform_driver sun50i_a100_ledc_driver = {
.probe = sun50i_a100_ledc_probe,
.remove_new = sun50i_a100_ledc_remove,
.shutdown = sun50i_a100_ledc_remove,
.driver = {
.name = "sun50i-a100-ledc",
.of_match_table = sun50i_a100_ledc_of_match,
.pm = pm_ptr(&sun50i_a100_ledc_pm),
},
};
module_platform_driver(sun50i_a100_ledc_driver);
MODULE_AUTHOR("Samuel Holland <samuel@sholland.org>");
MODULE_DESCRIPTION("Allwinner A100 LED controller driver");
MODULE_LICENSE("GPL");
+2 -1
View File
@@ -81,7 +81,8 @@ static int syscon_led_probe(struct platform_device *pdev)
sled->map = map;
if (of_property_read_u32(np, "offset", &sled->offset))
if (of_property_read_u32(np, "reg", &sled->offset) &&
of_property_read_u32(np, "offset", &sled->offset))
return -EINVAL;
if (of_property_read_u32(np, "mask", &sled->mask))
return -EINVAL;
+4 -26
View File
@@ -638,19 +638,13 @@ static int tca6507_probe_gpios(struct device *dev,
tca->gpio.direction_output = tca6507_gpio_direction_output;
tca->gpio.set = tca6507_gpio_set_value;
tca->gpio.parent = dev;
err = gpiochip_add_data(&tca->gpio, tca);
err = devm_gpiochip_add_data(dev, &tca->gpio, tca);
if (err) {
tca->gpio.ngpio = 0;
return err;
}
return 0;
}
static void tca6507_remove_gpio(struct tca6507_chip *tca)
{
if (tca->gpio.ngpio)
gpiochip_remove(&tca->gpio);
}
#else /* CONFIG_GPIOLIB */
static int tca6507_probe_gpios(struct device *dev,
struct tca6507_chip *tca,
@@ -658,9 +652,6 @@ static int tca6507_probe_gpios(struct device *dev,
{
return 0;
}
static void tca6507_remove_gpio(struct tca6507_chip *tca)
{
}
#endif /* CONFIG_GPIOLIB */
static struct tca6507_platform_data *
@@ -762,38 +753,25 @@ static int tca6507_probe(struct i2c_client *client)
l->led_cdev.brightness_set = tca6507_brightness_set;
l->led_cdev.blink_set = tca6507_blink_set;
l->bank = -1;
err = led_classdev_register(dev, &l->led_cdev);
err = devm_led_classdev_register(dev, &l->led_cdev);
if (err < 0)
goto exit;
return err;
}
}
err = tca6507_probe_gpios(dev, tca, pdata);
if (err)
goto exit;
return err;
/* set all registers to known state - zero */
tca->reg_set = 0x7f;
schedule_work(&tca->work);
return 0;
exit:
while (i--) {
if (tca->leds[i].led_cdev.name)
led_classdev_unregister(&tca->leds[i].led_cdev);
}
return err;
}
static void tca6507_remove(struct i2c_client *client)
{
int i;
struct tca6507_chip *tca = i2c_get_clientdata(client);
struct tca6507_led *tca_leds = tca->leds;
for (i = 0; i < NUM_LEDS; i++) {
if (tca_leds[i].led_cdev.name)
led_classdev_unregister(&tca_leds[i].led_cdev);
}
tca6507_remove_gpio(tca);
cancel_work_sync(&tca->work);
}
+1 -1
View File
@@ -4,7 +4,7 @@ if LEDS_CLASS_MULTICOLOR
config LEDS_GROUP_MULTICOLOR
tristate "LEDs group multi-color support"
depends on OF || COMPILE_TEST
depends on OF
help
This option enables support for monochrome LEDs that are grouped
into multicolor LEDs which is useful in the case where LEDs of
+26 -37
View File
@@ -552,9 +552,9 @@ static int lpg_parse_dtest(struct lpg *lpg)
ret = count;
goto err_malformed;
} else if (count != lpg->data->num_channels * 2) {
dev_err(lpg->dev, "qcom,dtest needs to be %d items\n",
lpg->data->num_channels * 2);
return -EINVAL;
return dev_err_probe(lpg->dev, -EINVAL,
"qcom,dtest needs to be %d items\n",
lpg->data->num_channels * 2);
}
for (i = 0; i < lpg->data->num_channels; i++) {
@@ -574,8 +574,7 @@ static int lpg_parse_dtest(struct lpg *lpg)
return 0;
err_malformed:
dev_err(lpg->dev, "malformed qcom,dtest\n");
return ret;
return dev_err_probe(lpg->dev, ret, "malformed qcom,dtest\n");
}
static void lpg_apply_dtest(struct lpg_channel *chan)
@@ -977,9 +976,14 @@ static int lpg_pattern_mc_clear(struct led_classdev *cdev)
return lpg_pattern_clear(led);
}
static inline struct lpg *lpg_pwm_from_chip(struct pwm_chip *chip)
{
return container_of(chip, struct lpg, pwm);
}
static int lpg_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
{
struct lpg *lpg = container_of(chip, struct lpg, pwm);
struct lpg *lpg = lpg_pwm_from_chip(chip);
struct lpg_channel *chan = &lpg->channels[pwm->hwpwm];
return chan->in_use ? -EBUSY : 0;
@@ -995,7 +999,7 @@ static int lpg_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
static int lpg_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
const struct pwm_state *state)
{
struct lpg *lpg = container_of(chip, struct lpg, pwm);
struct lpg *lpg = lpg_pwm_from_chip(chip);
struct lpg_channel *chan = &lpg->channels[pwm->hwpwm];
int ret = 0;
@@ -1026,7 +1030,7 @@ out_unlock:
static int lpg_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
struct pwm_state *state)
{
struct lpg *lpg = container_of(chip, struct lpg, pwm);
struct lpg *lpg = lpg_pwm_from_chip(chip);
struct lpg_channel *chan = &lpg->channels[pwm->hwpwm];
unsigned int resolution;
unsigned int pre_div;
@@ -1095,9 +1099,9 @@ static int lpg_add_pwm(struct lpg *lpg)
lpg->pwm.npwm = lpg->num_channels;
lpg->pwm.ops = &lpg_pwm_ops;
ret = pwmchip_add(&lpg->pwm);
ret = devm_pwmchip_add(lpg->dev, &lpg->pwm);
if (ret)
dev_err(lpg->dev, "failed to add PWM chip: ret %d\n", ret);
dev_err_probe(lpg->dev, ret, "failed to add PWM chip\n");
return ret;
}
@@ -1111,19 +1115,16 @@ static int lpg_parse_channel(struct lpg *lpg, struct device_node *np,
int ret;
ret = of_property_read_u32(np, "reg", &reg);
if (ret || !reg || reg > lpg->num_channels) {
dev_err(lpg->dev, "invalid \"reg\" of %pOFn\n", np);
return -EINVAL;
}
if (ret || !reg || reg > lpg->num_channels)
return dev_err_probe(lpg->dev, -EINVAL, "invalid \"reg\" of %pOFn\n", np);
chan = &lpg->channels[reg - 1];
chan->in_use = true;
ret = of_property_read_u32(np, "color", &color);
if (ret < 0 && ret != -EINVAL) {
dev_err(lpg->dev, "failed to parse \"color\" of %pOF\n", np);
return ret;
}
if (ret < 0 && ret != -EINVAL)
return dev_err_probe(lpg->dev, ret,
"failed to parse \"color\" of %pOF\n", np);
chan->color = color;
@@ -1146,10 +1147,9 @@ static int lpg_add_led(struct lpg *lpg, struct device_node *np)
int i;
ret = of_property_read_u32(np, "color", &color);
if (ret < 0 && ret != -EINVAL) {
dev_err(lpg->dev, "failed to parse \"color\" of %pOF\n", np);
return ret;
}
if (ret < 0 && ret != -EINVAL)
return dev_err_probe(lpg->dev, ret,
"failed to parse \"color\" of %pOF\n", np);
if (color == LED_COLOR_ID_RGB)
num_channels = of_get_available_child_count(np);
@@ -1226,7 +1226,7 @@ static int lpg_add_led(struct lpg *lpg, struct device_node *np)
else
ret = devm_led_classdev_register_ext(lpg->dev, &led->cdev, &init_data);
if (ret)
dev_err(lpg->dev, "unable to register %s\n", cdev->name);
dev_err_probe(lpg->dev, ret, "unable to register %s\n", cdev->name);
return ret;
}
@@ -1272,10 +1272,9 @@ static int lpg_init_triled(struct lpg *lpg)
if (lpg->triled_has_src_sel) {
ret = of_property_read_u32(np, "qcom,power-source", &lpg->triled_src);
if (ret || lpg->triled_src == 2 || lpg->triled_src > 3) {
dev_err(lpg->dev, "invalid power source\n");
return -EINVAL;
}
if (ret || lpg->triled_src == 2 || lpg->triled_src > 3)
return dev_err_probe(lpg->dev, -EINVAL,
"invalid power source\n");
}
/* Disable automatic trickle charge LED */
@@ -1324,8 +1323,6 @@ static int lpg_probe(struct platform_device *pdev)
if (!lpg->data)
return -EINVAL;
platform_set_drvdata(pdev, lpg);
lpg->dev = &pdev->dev;
mutex_init(&lpg->lock);
@@ -1363,13 +1360,6 @@ static int lpg_probe(struct platform_device *pdev)
return lpg_add_pwm(lpg);
}
static void lpg_remove(struct platform_device *pdev)
{
struct lpg *lpg = platform_get_drvdata(pdev);
pwmchip_remove(&lpg->pwm);
}
static const struct lpg_data pm8916_pwm_data = {
.num_channels = 1,
.channels = (const struct lpg_channel_data[]) {
@@ -1529,7 +1519,6 @@ MODULE_DEVICE_TABLE(of, lpg_of_table);
static struct platform_driver lpg_driver = {
.probe = lpg_probe,
.remove_new = lpg_remove,
.driver = {
.name = "qcom-spmi-lpg",
.of_match_table = lpg_of_table,
+11 -15
View File
@@ -41,33 +41,30 @@ static irqreturn_t gpio_trig_irq(int irq, void *_led)
return IRQ_HANDLED;
}
static ssize_t gpio_trig_brightness_show(struct device *dev,
static ssize_t desired_brightness_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct gpio_trig_data *gpio_data = led_trigger_get_drvdata(dev);
return sprintf(buf, "%u\n", gpio_data->desired_brightness);
return sysfs_emit(buf, "%u\n", gpio_data->desired_brightness);
}
static ssize_t gpio_trig_brightness_store(struct device *dev,
static ssize_t desired_brightness_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t n)
{
struct gpio_trig_data *gpio_data = led_trigger_get_drvdata(dev);
unsigned desired_brightness;
u8 desired_brightness;
int ret;
ret = sscanf(buf, "%u", &desired_brightness);
if (ret < 1 || desired_brightness > 255) {
dev_err(dev, "invalid value\n");
return -EINVAL;
}
ret = kstrtou8(buf, 10, &desired_brightness);
if (ret)
return ret;
gpio_data->desired_brightness = desired_brightness;
return n;
}
static DEVICE_ATTR(desired_brightness, 0644, gpio_trig_brightness_show,
gpio_trig_brightness_store);
static DEVICE_ATTR_RW(desired_brightness);
static struct attribute *gpio_trig_attrs[] = {
&dev_attr_desired_brightness.attr,
@@ -89,10 +86,7 @@ static int gpio_trig_activate(struct led_classdev *led)
* The generic property "trigger-sources" is followed,
* and we hope that this is a GPIO.
*/
gpio_data->gpiod = fwnode_gpiod_get_index(dev->fwnode,
"trigger-sources",
0, GPIOD_IN,
"led-trigger");
gpio_data->gpiod = gpiod_get_optional(dev, "trigger-sources", GPIOD_IN);
if (IS_ERR(gpio_data->gpiod)) {
ret = PTR_ERR(gpio_data->gpiod);
kfree(gpio_data);
@@ -104,6 +98,8 @@ static int gpio_trig_activate(struct led_classdev *led)
return -EINVAL;
}
gpiod_set_consumer_name(gpio_data->gpiod, "led-trigger");
gpio_data->led = led;
led_set_trigger_data(led, gpio_data);
+46 -1
View File
@@ -38,6 +38,16 @@
* tx - LED blinks on transmitted data
* rx - LED blinks on receive data
*
* Note: If the user selects a mode that is not supported by hw, default
* behavior is to fall back to software control of the LED. However not every
* hw supports software control. LED callbacks brightness_set() and
* brightness_set_blocking() are NULL in this case. hw_control_is_supported()
* should use available means supported by hw to inform the user that selected
* mode isn't supported by hw. This could be switching off the LED or any
* hw blink mode. If software control fallback isn't possible, we return
* -EOPNOTSUPP to the user, but still store the selected mode. This is needed
* in case an intermediate unsupported mode is necessary to switch from one
* supported mode to another.
*/
struct led_netdev_data {
@@ -99,6 +109,18 @@ static void set_baseline_state(struct led_netdev_data *trigger_data)
trigger_data->link_speed == SPEED_1000)
blink_on = true;
if (test_bit(TRIGGER_NETDEV_LINK_2500, &trigger_data->mode) &&
trigger_data->link_speed == SPEED_2500)
blink_on = true;
if (test_bit(TRIGGER_NETDEV_LINK_5000, &trigger_data->mode) &&
trigger_data->link_speed == SPEED_5000)
blink_on = true;
if (test_bit(TRIGGER_NETDEV_LINK_10000, &trigger_data->mode) &&
trigger_data->link_speed == SPEED_10000)
blink_on = true;
if (test_bit(TRIGGER_NETDEV_HALF_DUPLEX, &trigger_data->mode) &&
trigger_data->duplex == DUPLEX_HALF)
blink_on = true;
@@ -289,6 +311,9 @@ static ssize_t netdev_led_attr_show(struct device *dev, char *buf,
case TRIGGER_NETDEV_LINK_10:
case TRIGGER_NETDEV_LINK_100:
case TRIGGER_NETDEV_LINK_1000:
case TRIGGER_NETDEV_LINK_2500:
case TRIGGER_NETDEV_LINK_5000:
case TRIGGER_NETDEV_LINK_10000:
case TRIGGER_NETDEV_HALF_DUPLEX:
case TRIGGER_NETDEV_FULL_DUPLEX:
case TRIGGER_NETDEV_TX:
@@ -306,6 +331,7 @@ static ssize_t netdev_led_attr_store(struct device *dev, const char *buf,
size_t size, enum led_trigger_netdev_modes attr)
{
struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev);
struct led_classdev *led_cdev = trigger_data->led_cdev;
unsigned long state, mode = trigger_data->mode;
int ret;
int bit;
@@ -319,6 +345,9 @@ static ssize_t netdev_led_attr_store(struct device *dev, const char *buf,
case TRIGGER_NETDEV_LINK_10:
case TRIGGER_NETDEV_LINK_100:
case TRIGGER_NETDEV_LINK_1000:
case TRIGGER_NETDEV_LINK_2500:
case TRIGGER_NETDEV_LINK_5000:
case TRIGGER_NETDEV_LINK_10000:
case TRIGGER_NETDEV_HALF_DUPLEX:
case TRIGGER_NETDEV_FULL_DUPLEX:
case TRIGGER_NETDEV_TX:
@@ -337,7 +366,10 @@ static ssize_t netdev_led_attr_store(struct device *dev, const char *buf,
if (test_bit(TRIGGER_NETDEV_LINK, &mode) &&
(test_bit(TRIGGER_NETDEV_LINK_10, &mode) ||
test_bit(TRIGGER_NETDEV_LINK_100, &mode) ||
test_bit(TRIGGER_NETDEV_LINK_1000, &mode)))
test_bit(TRIGGER_NETDEV_LINK_1000, &mode) ||
test_bit(TRIGGER_NETDEV_LINK_2500, &mode) ||
test_bit(TRIGGER_NETDEV_LINK_5000, &mode) ||
test_bit(TRIGGER_NETDEV_LINK_10000, &mode)))
return -EINVAL;
cancel_delayed_work_sync(&trigger_data->work);
@@ -345,6 +377,10 @@ static ssize_t netdev_led_attr_store(struct device *dev, const char *buf,
trigger_data->mode = mode;
trigger_data->hw_control = can_hw_control(trigger_data);
if (!led_cdev->brightness_set && !led_cdev->brightness_set_blocking &&
!trigger_data->hw_control)
return -EOPNOTSUPP;
set_baseline_state(trigger_data);
return size;
@@ -367,6 +403,9 @@ DEFINE_NETDEV_TRIGGER(link, TRIGGER_NETDEV_LINK);
DEFINE_NETDEV_TRIGGER(link_10, TRIGGER_NETDEV_LINK_10);
DEFINE_NETDEV_TRIGGER(link_100, TRIGGER_NETDEV_LINK_100);
DEFINE_NETDEV_TRIGGER(link_1000, TRIGGER_NETDEV_LINK_1000);
DEFINE_NETDEV_TRIGGER(link_2500, TRIGGER_NETDEV_LINK_2500);
DEFINE_NETDEV_TRIGGER(link_5000, TRIGGER_NETDEV_LINK_5000);
DEFINE_NETDEV_TRIGGER(link_10000, TRIGGER_NETDEV_LINK_10000);
DEFINE_NETDEV_TRIGGER(half_duplex, TRIGGER_NETDEV_HALF_DUPLEX);
DEFINE_NETDEV_TRIGGER(full_duplex, TRIGGER_NETDEV_FULL_DUPLEX);
DEFINE_NETDEV_TRIGGER(tx, TRIGGER_NETDEV_TX);
@@ -425,6 +464,9 @@ static struct attribute *netdev_trig_attrs[] = {
&dev_attr_link_10.attr,
&dev_attr_link_100.attr,
&dev_attr_link_1000.attr,
&dev_attr_link_2500.attr,
&dev_attr_link_5000.attr,
&dev_attr_link_10000.attr,
&dev_attr_full_duplex.attr,
&dev_attr_half_duplex.attr,
&dev_attr_rx.attr,
@@ -522,6 +564,9 @@ static void netdev_trig_work(struct work_struct *work)
test_bit(TRIGGER_NETDEV_LINK_10, &trigger_data->mode) ||
test_bit(TRIGGER_NETDEV_LINK_100, &trigger_data->mode) ||
test_bit(TRIGGER_NETDEV_LINK_1000, &trigger_data->mode) ||
test_bit(TRIGGER_NETDEV_LINK_2500, &trigger_data->mode) ||
test_bit(TRIGGER_NETDEV_LINK_5000, &trigger_data->mode) ||
test_bit(TRIGGER_NETDEV_LINK_10000, &trigger_data->mode) ||
test_bit(TRIGGER_NETDEV_HALF_DUPLEX, &trigger_data->mode) ||
test_bit(TRIGGER_NETDEV_FULL_DUPLEX, &trigger_data->mode);
interval = jiffies_to_msecs(
+4 -1
View File
@@ -64,10 +64,13 @@ static long led_panic_blink(int state)
static int __init ledtrig_panic_init(void)
{
led_trigger_register_simple("panic", &trigger);
if (!trigger)
return -ENOMEM;
atomic_notifier_chain_register(&panic_notifier_list,
&led_trigger_panic_nb);
led_trigger_register_simple("panic", &trigger);
panic_blink = led_panic_blink;
return 0;
}
+210 -37
View File
@@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
#include <linux/completion.h>
#include <linux/delay.h>
#include <linux/leds.h>
#include <linux/module.h>
@@ -12,15 +13,45 @@
struct ledtrig_tty_data {
struct led_classdev *led_cdev;
struct delayed_work dwork;
struct mutex mutex;
struct completion sysfs;
const char *ttyname;
struct tty_struct *tty;
int rx, tx;
bool mode_rx;
bool mode_tx;
bool mode_cts;
bool mode_dsr;
bool mode_dcd;
bool mode_rng;
};
static void ledtrig_tty_restart(struct ledtrig_tty_data *trigger_data)
/* Indicates which state the LED should now display */
enum led_trigger_tty_state {
TTY_LED_BLINK,
TTY_LED_ENABLE,
TTY_LED_DISABLE,
};
enum led_trigger_tty_modes {
TRIGGER_TTY_RX = 0,
TRIGGER_TTY_TX,
TRIGGER_TTY_CTS,
TRIGGER_TTY_DSR,
TRIGGER_TTY_DCD,
TRIGGER_TTY_RNG,
};
static int ledtrig_tty_wait_for_completion(struct device *dev)
{
schedule_delayed_work(&trigger_data->dwork, 0);
struct ledtrig_tty_data *trigger_data = led_trigger_get_drvdata(dev);
int ret;
ret = wait_for_completion_timeout(&trigger_data->sysfs,
msecs_to_jiffies(LEDTRIG_TTY_INTERVAL * 20));
if (ret == 0)
return -ETIMEDOUT;
return ret;
}
static ssize_t ttyname_show(struct device *dev,
@@ -28,14 +59,16 @@ static ssize_t ttyname_show(struct device *dev,
{
struct ledtrig_tty_data *trigger_data = led_trigger_get_drvdata(dev);
ssize_t len = 0;
int completion;
mutex_lock(&trigger_data->mutex);
reinit_completion(&trigger_data->sysfs);
completion = ledtrig_tty_wait_for_completion(dev);
if (completion < 0)
return completion;
if (trigger_data->ttyname)
len = sprintf(buf, "%s\n", trigger_data->ttyname);
mutex_unlock(&trigger_data->mutex);
return len;
}
@@ -46,7 +79,7 @@ static ssize_t ttyname_store(struct device *dev,
struct ledtrig_tty_data *trigger_data = led_trigger_get_drvdata(dev);
char *ttyname;
ssize_t ret = size;
bool running;
int completion;
if (size > 0 && buf[size - 1] == '\n')
size -= 1;
@@ -59,9 +92,10 @@ static ssize_t ttyname_store(struct device *dev,
ttyname = NULL;
}
mutex_lock(&trigger_data->mutex);
running = trigger_data->ttyname != NULL;
reinit_completion(&trigger_data->sysfs);
completion = ledtrig_tty_wait_for_completion(dev);
if (completion < 0)
return completion;
kfree(trigger_data->ttyname);
tty_kref_put(trigger_data->tty);
@@ -69,29 +103,107 @@ static ssize_t ttyname_store(struct device *dev,
trigger_data->ttyname = ttyname;
mutex_unlock(&trigger_data->mutex);
if (ttyname && !running)
ledtrig_tty_restart(trigger_data);
return ret;
}
static DEVICE_ATTR_RW(ttyname);
static ssize_t ledtrig_tty_attr_show(struct device *dev, char *buf,
enum led_trigger_tty_modes attr)
{
struct ledtrig_tty_data *trigger_data = led_trigger_get_drvdata(dev);
bool state;
switch (attr) {
case TRIGGER_TTY_RX:
state = trigger_data->mode_rx;
break;
case TRIGGER_TTY_TX:
state = trigger_data->mode_tx;
break;
case TRIGGER_TTY_CTS:
state = trigger_data->mode_cts;
break;
case TRIGGER_TTY_DSR:
state = trigger_data->mode_dsr;
break;
case TRIGGER_TTY_DCD:
state = trigger_data->mode_dcd;
break;
case TRIGGER_TTY_RNG:
state = trigger_data->mode_rng;
break;
}
return sysfs_emit(buf, "%u\n", state);
}
static ssize_t ledtrig_tty_attr_store(struct device *dev, const char *buf,
size_t size, enum led_trigger_tty_modes attr)
{
struct ledtrig_tty_data *trigger_data = led_trigger_get_drvdata(dev);
bool state;
int ret;
ret = kstrtobool(buf, &state);
if (ret)
return ret;
switch (attr) {
case TRIGGER_TTY_RX:
trigger_data->mode_rx = state;
break;
case TRIGGER_TTY_TX:
trigger_data->mode_tx = state;
break;
case TRIGGER_TTY_CTS:
trigger_data->mode_cts = state;
break;
case TRIGGER_TTY_DSR:
trigger_data->mode_dsr = state;
break;
case TRIGGER_TTY_DCD:
trigger_data->mode_dcd = state;
break;
case TRIGGER_TTY_RNG:
trigger_data->mode_rng = state;
break;
}
return size;
}
#define DEFINE_TTY_TRIGGER(trigger_name, trigger) \
static ssize_t trigger_name##_show(struct device *dev, \
struct device_attribute *attr, char *buf) \
{ \
return ledtrig_tty_attr_show(dev, buf, trigger); \
} \
static ssize_t trigger_name##_store(struct device *dev, \
struct device_attribute *attr, const char *buf, size_t size) \
{ \
return ledtrig_tty_attr_store(dev, buf, size, trigger); \
} \
static DEVICE_ATTR_RW(trigger_name)
DEFINE_TTY_TRIGGER(rx, TRIGGER_TTY_RX);
DEFINE_TTY_TRIGGER(tx, TRIGGER_TTY_TX);
DEFINE_TTY_TRIGGER(cts, TRIGGER_TTY_CTS);
DEFINE_TTY_TRIGGER(dsr, TRIGGER_TTY_DSR);
DEFINE_TTY_TRIGGER(dcd, TRIGGER_TTY_DCD);
DEFINE_TTY_TRIGGER(rng, TRIGGER_TTY_RNG);
static void ledtrig_tty_work(struct work_struct *work)
{
struct ledtrig_tty_data *trigger_data =
container_of(work, struct ledtrig_tty_data, dwork.work);
struct serial_icounter_struct icount;
enum led_trigger_tty_state state = TTY_LED_DISABLE;
unsigned long interval = LEDTRIG_TTY_INTERVAL;
bool invert = false;
int status;
int ret;
mutex_lock(&trigger_data->mutex);
if (!trigger_data->ttyname) {
/* exit without rescheduling */
mutex_unlock(&trigger_data->mutex);
return;
}
if (!trigger_data->ttyname)
goto out;
/* try to get the tty corresponding to $ttyname */
if (!trigger_data->tty) {
@@ -115,32 +227,83 @@ static void ledtrig_tty_work(struct work_struct *work)
trigger_data->tty = tty;
}
ret = tty_get_icount(trigger_data->tty, &icount);
if (ret) {
dev_info(trigger_data->tty->dev, "Failed to get icount, stopped polling\n");
mutex_unlock(&trigger_data->mutex);
return;
status = tty_get_tiocm(trigger_data->tty);
if (status > 0) {
if (trigger_data->mode_cts) {
if (status & TIOCM_CTS)
state = TTY_LED_ENABLE;
}
if (trigger_data->mode_dsr) {
if (status & TIOCM_DSR)
state = TTY_LED_ENABLE;
}
if (trigger_data->mode_dcd) {
if (status & TIOCM_CAR)
state = TTY_LED_ENABLE;
}
if (trigger_data->mode_rng) {
if (status & TIOCM_RNG)
state = TTY_LED_ENABLE;
}
}
if (icount.rx != trigger_data->rx ||
icount.tx != trigger_data->tx) {
unsigned long interval = LEDTRIG_TTY_INTERVAL;
/*
* The evaluation of rx/tx must be done after the evaluation
* of TIOCM_*, because rx/tx has priority.
*/
if (trigger_data->mode_rx || trigger_data->mode_tx) {
struct serial_icounter_struct icount;
led_blink_set_oneshot(trigger_data->led_cdev, &interval,
&interval, 0);
ret = tty_get_icount(trigger_data->tty, &icount);
if (ret)
goto out;
trigger_data->rx = icount.rx;
trigger_data->tx = icount.tx;
if (trigger_data->mode_tx && (icount.tx != trigger_data->tx)) {
trigger_data->tx = icount.tx;
invert = state == TTY_LED_ENABLE;
state = TTY_LED_BLINK;
}
if (trigger_data->mode_rx && (icount.rx != trigger_data->rx)) {
trigger_data->rx = icount.rx;
invert = state == TTY_LED_ENABLE;
state = TTY_LED_BLINK;
}
}
out:
mutex_unlock(&trigger_data->mutex);
switch (state) {
case TTY_LED_BLINK:
led_blink_set_oneshot(trigger_data->led_cdev, &interval,
&interval, invert);
break;
case TTY_LED_ENABLE:
led_set_brightness(trigger_data->led_cdev,
trigger_data->led_cdev->blink_brightness);
break;
case TTY_LED_DISABLE:
fallthrough;
default:
led_set_brightness(trigger_data->led_cdev, LED_OFF);
break;
}
complete_all(&trigger_data->sysfs);
schedule_delayed_work(&trigger_data->dwork,
msecs_to_jiffies(LEDTRIG_TTY_INTERVAL * 2));
}
static struct attribute *ledtrig_tty_attrs[] = {
&dev_attr_ttyname.attr,
&dev_attr_rx.attr,
&dev_attr_tx.attr,
&dev_attr_cts.attr,
&dev_attr_dsr.attr,
&dev_attr_dcd.attr,
&dev_attr_rng.attr,
NULL
};
ATTRIBUTE_GROUPS(ledtrig_tty);
@@ -153,11 +316,17 @@ static int ledtrig_tty_activate(struct led_classdev *led_cdev)
if (!trigger_data)
return -ENOMEM;
/* Enable default rx/tx mode */
trigger_data->mode_rx = true;
trigger_data->mode_tx = true;
led_set_trigger_data(led_cdev, trigger_data);
INIT_DELAYED_WORK(&trigger_data->dwork, ledtrig_tty_work);
trigger_data->led_cdev = led_cdev;
mutex_init(&trigger_data->mutex);
init_completion(&trigger_data->sysfs);
schedule_delayed_work(&trigger_data->dwork, 0);
return 0;
}
@@ -168,6 +337,10 @@ static void ledtrig_tty_deactivate(struct led_classdev *led_cdev)
cancel_delayed_work_sync(&trigger_data->dwork);
kfree(trigger_data->ttyname);
tty_kref_put(trigger_data->tty);
trigger_data->tty = NULL;
kfree(trigger_data);
}
+2 -1
View File
@@ -553,7 +553,8 @@ static irqreturn_t mhuv2_sender_interrupt(int irq, void *data)
priv = chan->con_priv;
if (!IS_PROTOCOL_DOORBELL(priv)) {
writel_relaxed(1, &mhu->send->ch_wn[priv->ch_wn_idx + priv->windows - 1].int_clr);
for (i = 0; i < priv->windows; i++)
writel_relaxed(1, &mhu->send->ch_wn[priv->ch_wn_idx + i].int_clr);
if (chan->cl) {
mbox_chan_txdone(chan, 0);
+2 -4
View File
@@ -1650,7 +1650,7 @@ fail:
return ret;
}
static int flexrm_mbox_remove(struct platform_device *pdev)
static void flexrm_mbox_remove(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct flexrm_mbox *mbox = platform_get_drvdata(pdev);
@@ -1661,8 +1661,6 @@ static int flexrm_mbox_remove(struct platform_device *pdev)
dma_pool_destroy(mbox->cmpl_pool);
dma_pool_destroy(mbox->bd_pool);
return 0;
}
static const struct of_device_id flexrm_mbox_of_match[] = {
@@ -1677,7 +1675,7 @@ static struct platform_driver flexrm_mbox_driver = {
.of_match_table = flexrm_mbox_of_match,
},
.probe = flexrm_mbox_probe,
.remove = flexrm_mbox_remove,
.remove_new = flexrm_mbox_remove,
};
module_platform_driver(flexrm_mbox_driver);
+2 -3
View File
@@ -1605,7 +1605,7 @@ cleanup:
return err;
}
static int pdc_remove(struct platform_device *pdev)
static void pdc_remove(struct platform_device *pdev)
{
struct pdc_state *pdcs = platform_get_drvdata(pdev);
@@ -1617,12 +1617,11 @@ static int pdc_remove(struct platform_device *pdev)
dma_pool_destroy(pdcs->rx_buf_pool);
dma_pool_destroy(pdcs->ring_pool);
return 0;
}
static struct platform_driver pdc_mbox_driver = {
.probe = pdc_probe,
.remove = pdc_remove,
.remove_new = pdc_remove,
.driver = {
.name = "brcm-iproc-pdc-mbox",
.of_match_table = pdc_mbox_of_match,

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