diff --git a/.mailmap b/.mailmap index 4a9d87472ba8..ea246eac7ba1 100644 --- a/.mailmap +++ b/.mailmap @@ -275,6 +275,10 @@ Krzysztof Kozlowski Krzysztof Kozlowski Kuninori Morimoto Kuogee Hsieh +Lee Jones +Lee Jones +Lee Jones +Lee Jones Leonard Crestez Leonard Crestez Leonardo Bras Leonard Göhrs diff --git a/Documentation/ABI/testing/sysfs-class-led-driver-aw200xx b/Documentation/ABI/testing/sysfs-class-led-driver-aw200xx new file mode 100644 index 000000000000..6d4449cf9d71 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-class-led-driver-aw200xx @@ -0,0 +1,5 @@ +What: /sys/class/leds//dim +Date: May 2023 +Description: 64-level DIM current. If you write a negative value or + "auto", the dim will be calculated according to the + brightness. diff --git a/Documentation/devicetree/bindings/leds/awinic,aw200xx.yaml b/Documentation/devicetree/bindings/leds/awinic,aw200xx.yaml new file mode 100644 index 000000000000..feb5febaf361 --- /dev/null +++ b/Documentation/devicetree/bindings/leds/awinic,aw200xx.yaml @@ -0,0 +1,126 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/leds/awinic,aw200xx.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: AWINIC AW200XX LED + +maintainers: + - Martin Kurbanov + +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. + + 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 + +properties: + compatible: + enum: + - awinic,aw20036 + - awinic,aw20054 + - awinic,aw20072 + + reg: + maxItems: 1 + + "#address-cells": + const: 1 + + "#size-cells": + const: 0 + + awinic,display-rows: + $ref: /schemas/types.yaml#/definitions/uint32 + description: + Leds matrix size + +patternProperties: + "^led@[0-9a-f]$": + type: object + $ref: common.yaml# + unevaluatedProperties: false + + properties: + reg: + description: + LED number + maxItems: 1 + + led-max-microamp: + default: 9780 + description: | + Note that a driver will take the minimum of all LED limits + 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) + And the minimum output current formula: + IMINled = 3300 * (592 / 600.5) * (1 / display-rows) + +required: + - compatible + - reg + - "#address-cells" + - "#size-cells" + - awinic,display-rows + +allOf: + - if: + properties: + compatible: + contains: + const: awinic,aw20036 + then: + properties: + awinic,display-rows: + enum: [1, 2, 3] + else: + properties: + awinic,display-rows: + enum: [1, 2, 3, 4, 5, 6, 7] + +additionalProperties: false + +examples: + - | + #include + + i2c { + #address-cells = <1>; + #size-cells = <0>; + + led-controller@3a { + compatible = "awinic,aw20036"; + reg = <0x3a>; + #address-cells = <1>; + #size-cells = <0>; + awinic,display-rows = <3>; + + led@0 { + reg = <0x0>; + color = ; + led-max-microamp = <9780>; + }; + + led@1 { + reg = <0x1>; + color = ; + led-max-microamp = <9780>; + }; + + led@2 { + reg = <0x2>; + color = ; + led-max-microamp = <9780>; + }; + }; + }; + +... diff --git a/Documentation/devicetree/bindings/leds/backlight/kinetic,ktz8866.yaml b/Documentation/devicetree/bindings/leds/backlight/kinetic,ktz8866.yaml index e1191453c2f0..c914e1276982 100644 --- a/Documentation/devicetree/bindings/leds/backlight/kinetic,ktz8866.yaml +++ b/Documentation/devicetree/bindings/leds/backlight/kinetic,ktz8866.yaml @@ -21,6 +21,9 @@ properties: compatible: const: kinetic,ktz8866 + reg: + maxItems: 1 + vddpos-supply: description: positive boost supply regulator. @@ -33,6 +36,7 @@ properties: current-num-sinks: description: number of the LED current sinks' channels. + $ref: /schemas/types.yaml#/definitions/uint32 enum: [1, 2, 3, 4, 5, 6] kinetic,current-ramp-delay-ms: @@ -53,6 +57,7 @@ properties: required: - compatible + - reg - vddpos-supply - vddneg-supply - enable-gpios @@ -63,14 +68,19 @@ examples: - | #include - backlight { - compatible = "kinetic,ktz8866"; + i2c { + #address-cells = <1>; + #size-cells = <0>; - vddpos-supply = <&bl_vddpos_5p5>; - vddneg-supply = <&bl_vddneg_5p5>; - enable-gpios = <&tlmm 139 GPIO_ACTIVE_HIGH>; - current-num-sinks = <5>; - kinetic,current-ramp-delay-ms = <128>; - kinetic,led-enable-ramp-delay-ms = <1>; - kinetic,enable-lcd-bias; + backlight@11 { + compatible = "kinetic,ktz8866"; + reg = <0x11>; + vddpos-supply = <&bl_vddpos_5p5>; + vddneg-supply = <&bl_vddneg_5p5>; + enable-gpios = <&tlmm 139 GPIO_ACTIVE_HIGH>; + current-num-sinks = <5>; + kinetic,current-ramp-delay-ms = <128>; + kinetic,led-enable-ramp-delay-ms = <1>; + kinetic,enable-lcd-bias; + }; }; diff --git a/Documentation/devicetree/bindings/leds/backlight/lp855x-backlight.yaml b/Documentation/devicetree/bindings/leds/backlight/lp855x-backlight.yaml new file mode 100644 index 000000000000..9416e1bfab92 --- /dev/null +++ b/Documentation/devicetree/bindings/leds/backlight/lp855x-backlight.yaml @@ -0,0 +1,149 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/leds/backlight/lp855x-backlight.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Texas Instruments LP855X backlight controllers + +maintainers: + - Artur Weber + +properties: + compatible: + enum: + - ti,lp8550 + - ti,lp8551 + - ti,lp8552 + - ti,lp8553 + - ti,lp8555 + - ti,lp8556 + - ti,lp8557 + + reg: + maxItems: 1 + + dev-ctrl: + $ref: /schemas/types.yaml#/definitions/uint8 + description: + Value of device control register. This is a device-specific value. + + bl-name: + $ref: /schemas/types.yaml#/definitions/string + description: Backlight device name. + + init-brt: + $ref: /schemas/types.yaml#/definitions/uint8 + description: Initial value of backlight brightness. + + power-supply: + description: Regulator which controls the 3V rail. + + enable-supply: + description: Regulator which controls the EN/VDDIO input. + + pwms: + maxItems: 1 + description: | + PWM channel to use for controlling the backlight; setting this + enables the PWM-based backlight control mode. + + pwm-names: true + + pwm-period: + $ref: /schemas/types.yaml#/definitions/uint32 + description: + PWM period value. Deprecated; set the period value in the pwms + property instead. + deprecated: true + +patternProperties: + "^rom-[0-9a-f]{2}h$": + type: object + description: Nodes containing the values of configuration registers. + additionalProperties: false + properties: + rom-addr: + $ref: /schemas/types.yaml#/definitions/uint8 + description: Register address of ROM area to be updated. + + rom-val: + $ref: /schemas/types.yaml#/definitions/uint8 + description: Value to write to the ROM register. + +required: + - compatible + - reg + - dev-ctrl + +unevaluatedProperties: false + +examples: + - | + i2c { + #address-cells = <1>; + #size-cells = <0>; + + backlight@2c { + compatible = "ti,lp8555"; + reg = <0x2c>; + + dev-ctrl = /bits/ 8 <0x00>; + + pwms = <&pwm 0 10000>; + pwm-names = "lp8555"; + + /* 4V OV, 4 output LED0 string enabled */ + rom-14h { + rom-addr = /bits/ 8 <0x14>; + rom-val = /bits/ 8 <0xcf>; + }; + + /* Heavy smoothing, 24ms ramp time step */ + rom-15h { + rom-addr = /bits/ 8 <0x15>; + rom-val = /bits/ 8 <0xc7>; + }; + + /* 4 output LED1 string enabled */ + rom-19h { + rom-addr = /bits/ 8 <0x19>; + rom-val = /bits/ 8 <0x0f>; + }; + }; + }; + - | + i2c { + #address-cells = <1>; + #size-cells = <0>; + + backlight@2c { + compatible = "ti,lp8556"; + reg = <0x2c>; + + bl-name = "lcd-bl"; + dev-ctrl = /bits/ 8 <0x85>; + init-brt = /bits/ 8 <0x10>; + }; + }; + - | + i2c { + #address-cells = <1>; + #size-cells = <0>; + + backlight@2c { + compatible = "ti,lp8557"; + reg = <0x2c>; + enable-supply = <&backlight_vddio>; + power-supply = <&backlight_vdd>; + + dev-ctrl = /bits/ 8 <0x41>; + init-brt = /bits/ 8 <0x0a>; + + /* 4V OV, 4 output LED string enabled */ + rom-14h { + rom-addr = /bits/ 8 <0x14>; + rom-val = /bits/ 8 <0xcf>; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/leds/backlight/lp855x.txt b/Documentation/devicetree/bindings/leds/backlight/lp855x.txt deleted file mode 100644 index 88f56641fc28..000000000000 --- a/Documentation/devicetree/bindings/leds/backlight/lp855x.txt +++ /dev/null @@ -1,72 +0,0 @@ -lp855x bindings - -Required properties: - - compatible: "ti,lp8550", "ti,lp8551", "ti,lp8552", "ti,lp8553", - "ti,lp8555", "ti,lp8556", "ti,lp8557" - - reg: I2C slave address (u8) - - dev-ctrl: Value of DEVICE CONTROL register (u8). It depends on the device. - -Optional properties: - - bl-name: Backlight device name (string) - - init-brt: Initial value of backlight brightness (u8) - - pwm-period: PWM period value. Set only PWM input mode used (u32) - - rom-addr: Register address of ROM area to be updated (u8) - - rom-val: Register value to be updated (u8) - - power-supply: Regulator which controls the 3V rail - - enable-supply: Regulator which controls the EN/VDDIO input - -Example: - - /* LP8555 */ - backlight@2c { - compatible = "ti,lp8555"; - reg = <0x2c>; - - dev-ctrl = /bits/ 8 <0x00>; - pwm-period = <10000>; - - /* 4V OV, 4 output LED0 string enabled */ - rom_14h { - rom-addr = /bits/ 8 <0x14>; - rom-val = /bits/ 8 <0xcf>; - }; - - /* Heavy smoothing, 24ms ramp time step */ - rom_15h { - rom-addr = /bits/ 8 <0x15>; - rom-val = /bits/ 8 <0xc7>; - }; - - /* 4 output LED1 string enabled */ - rom_19h { - rom-addr = /bits/ 8 <0x19>; - rom-val = /bits/ 8 <0x0f>; - }; - }; - - /* LP8556 */ - backlight@2c { - compatible = "ti,lp8556"; - reg = <0x2c>; - - bl-name = "lcd-bl"; - dev-ctrl = /bits/ 8 <0x85>; - init-brt = /bits/ 8 <0x10>; - }; - - /* LP8557 */ - backlight@2c { - compatible = "ti,lp8557"; - reg = <0x2c>; - enable-supply = <&backlight_vddio>; - power-supply = <&backlight_vdd>; - - dev-ctrl = /bits/ 8 <0x41>; - init-brt = /bits/ 8 <0x0a>; - - /* 4V OV, 4 output LED string enabled */ - rom_14h { - rom-addr = /bits/ 8 <0x14>; - rom-val = /bits/ 8 <0xcf>; - }; - }; diff --git a/Documentation/devicetree/bindings/leds/backlight/pwm-backlight.yaml b/Documentation/devicetree/bindings/leds/backlight/pwm-backlight.yaml index 5ec47a8c6568..535690288990 100644 --- a/Documentation/devicetree/bindings/leds/backlight/pwm-backlight.yaml +++ b/Documentation/devicetree/bindings/leds/backlight/pwm-backlight.yaml @@ -68,7 +68,6 @@ dependencies: required: - compatible - pwms - - power-supply additionalProperties: false diff --git a/Documentation/devicetree/bindings/leds/common.yaml b/Documentation/devicetree/bindings/leds/common.yaml index 11aedf1650a1..58b492d00246 100644 --- a/Documentation/devicetree/bindings/leds/common.yaml +++ b/Documentation/devicetree/bindings/leds/common.yaml @@ -105,8 +105,6 @@ properties: - audio-mute # LED indicates bluetooth power state - bluetooth-power - # LED indicates activity of all CPUs - - cpu # LED indicates camera flash state - flash # LED indicated keyboard capslock diff --git a/Documentation/devicetree/bindings/leds/leds-class-multicolor.yaml b/Documentation/devicetree/bindings/leds/leds-class-multicolor.yaml index 31840e33dcf5..e850a8894758 100644 --- a/Documentation/devicetree/bindings/leds/leds-class-multicolor.yaml +++ b/Documentation/devicetree/bindings/leds/leds-class-multicolor.yaml @@ -34,7 +34,7 @@ required: - color allOf: - - $ref: "common.yaml#" + - $ref: common.yaml# additionalProperties: true diff --git a/Documentation/devicetree/bindings/leds/leds-lp55xx.yaml b/Documentation/devicetree/bindings/leds/leds-lp55xx.yaml index ae607911f1db..058be1fedbc8 100644 --- a/Documentation/devicetree/bindings/leds/leds-lp55xx.yaml +++ b/Documentation/devicetree/bindings/leds/leds-lp55xx.yaml @@ -66,6 +66,14 @@ properties: '#size-cells': const: 0 + ti,charge-pump-mode: + description: + Set the operating mode of the internal charge pump as defined in + . + $ref: /schemas/types.yaml#/definitions/uint32 + default: 3 # auto + maximum: 3 + patternProperties: '^multi-led@[0-8]$': type: object @@ -152,6 +160,7 @@ additionalProperties: false examples: - | #include + #include i2c { #address-cells = <1>; @@ -164,6 +173,7 @@ examples: reg = <0x32>; clock-mode = /bits/ 8 <2>; pwr-sel = /bits/ 8 <3>; /* D1~9 connected to VOUT */ + ti,charge-pump-mode = ; led@0 { reg = <0>; diff --git a/Documentation/devicetree/bindings/leds/leds-mt6323.txt b/Documentation/devicetree/bindings/leds/leds-mt6323.txt index 73353692efa1..052dccb8f2ce 100644 --- a/Documentation/devicetree/bindings/leds/leds-mt6323.txt +++ b/Documentation/devicetree/bindings/leds/leds-mt6323.txt @@ -12,7 +12,10 @@ For MediaTek PMIC wrapper bindings see: Documentation/devicetree/bindings/soc/mediatek/mediatek,pwrap.yaml Required properties: -- compatible : Must be "mediatek,mt6323-led" +- compatible : Must be one of + - "mediatek,mt6323-led" + - "mediatek,mt6331-led" + - "mediatek,mt6332-led" - address-cells : Must be 1 - size-cells : Must be 0 diff --git a/Documentation/devicetree/bindings/leds/leds-qcom-lpg.yaml b/Documentation/devicetree/bindings/leds/leds-qcom-lpg.yaml index 6295c91f43e8..e6f1999cb22f 100644 --- a/Documentation/devicetree/bindings/leds/leds-qcom-lpg.yaml +++ b/Documentation/devicetree/bindings/leds/leds-qcom-lpg.yaml @@ -16,18 +16,24 @@ description: > properties: compatible: - enum: - - qcom,pm660l-lpg - - qcom,pm8150b-lpg - - qcom,pm8150l-lpg - - qcom,pm8350c-pwm - - qcom,pm8916-pwm - - qcom,pm8941-lpg - - qcom,pm8994-lpg - - qcom,pmc8180c-lpg - - qcom,pmi8994-lpg - - qcom,pmi8998-lpg - - qcom,pmk8550-pwm + oneOf: + - enum: + - qcom,pm660l-lpg + - qcom,pm8150b-lpg + - qcom,pm8150l-lpg + - qcom,pm8350c-pwm + - qcom,pm8916-pwm + - qcom,pm8941-lpg + - qcom,pm8994-lpg + - qcom,pmc8180c-lpg + - qcom,pmi632-lpg + - qcom,pmi8994-lpg + - qcom,pmi8998-lpg + - qcom,pmk8550-pwm + - items: + - enum: + - qcom,pm8550-pwm + - const: qcom,pm8350c-pwm "#pwm-cells": const: 2 diff --git a/Documentation/devicetree/bindings/leds/leds-sgm3140.yaml b/Documentation/devicetree/bindings/leds/leds-sgm3140.yaml index 4d2ffe5fcfc7..37d2a93780ab 100644 --- a/Documentation/devicetree/bindings/leds/leds-sgm3140.yaml +++ b/Documentation/devicetree/bindings/leds/leds-sgm3140.yaml @@ -20,6 +20,7 @@ properties: compatible: enum: - ocs,ocp8110 + - richtek,rt5033-led - sgmicro,sgm3140 enable-gpios: diff --git a/Documentation/devicetree/bindings/leds/qcom,spmi-flash-led.yaml b/Documentation/devicetree/bindings/leds/qcom,spmi-flash-led.yaml index ffacf703d9f9..a8736fd5a539 100644 --- a/Documentation/devicetree/bindings/leds/qcom,spmi-flash-led.yaml +++ b/Documentation/devicetree/bindings/leds/qcom,spmi-flash-led.yaml @@ -26,6 +26,8 @@ properties: - qcom,pm8150c-flash-led - qcom,pm8150l-flash-led - qcom,pm8350c-flash-led + - qcom,pm8550-flash-led + - qcom,pmi8998-flash-led - const: qcom,spmi-flash-led reg: diff --git a/Documentation/devicetree/bindings/leds/rohm,bd71828-leds.yaml b/Documentation/devicetree/bindings/leds/rohm,bd71828-leds.yaml index 64b0be9cf70b..58f0d94c6d71 100644 --- a/Documentation/devicetree/bindings/leds/rohm,bd71828-leds.yaml +++ b/Documentation/devicetree/bindings/leds/rohm,bd71828-leds.yaml @@ -32,7 +32,7 @@ patternProperties: properties: rohm,led-compatible: description: LED identification string - $ref: "/schemas/types.yaml#/definitions/string" + $ref: /schemas/types.yaml#/definitions/string enum: - bd71828-ambled - bd71828-grnled diff --git a/Documentation/devicetree/bindings/mailbox/brcm,bcm2835-mbox.txt b/Documentation/devicetree/bindings/mailbox/brcm,bcm2835-mbox.txt deleted file mode 100644 index b48d7d30012c..000000000000 --- a/Documentation/devicetree/bindings/mailbox/brcm,bcm2835-mbox.txt +++ /dev/null @@ -1,26 +0,0 @@ -Broadcom BCM2835 VideoCore mailbox IPC - -Required properties: - -- compatible: Should be "brcm,bcm2835-mbox" -- reg: Specifies base physical address and size of the registers -- interrupts: The interrupt number - See bindings/interrupt-controller/brcm,bcm2835-armctrl-ic.txt -- #mbox-cells: Specifies the number of cells needed to encode a mailbox - channel. The value shall be 0, since there is only one - mailbox channel implemented by the device. - -Example: - -mailbox: mailbox@7e00b880 { - compatible = "brcm,bcm2835-mbox"; - reg = <0x7e00b880 0x40>; - interrupts = <0 1>; - #mbox-cells = <0>; -}; - -firmware: firmware { - compatible = "raspberrypi,firmware"; - mboxes = <&mailbox>; - #power-domain-cells = <1>; -}; diff --git a/Documentation/devicetree/bindings/mailbox/brcm,bcm2835-mbox.yaml b/Documentation/devicetree/bindings/mailbox/brcm,bcm2835-mbox.yaml new file mode 100644 index 000000000000..9588817f4511 --- /dev/null +++ b/Documentation/devicetree/bindings/mailbox/brcm,bcm2835-mbox.yaml @@ -0,0 +1,40 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mailbox/brcm,bcm2835-mbox.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Broadcom BCM2835 VideoCore mailbox IPC + +maintainers: + - Stefan Wahren + +properties: + compatible: + const: brcm,bcm2835-mbox + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + "#mbox-cells": + const: 0 + +required: + - compatible + - reg + - interrupts + - "#mbox-cells" + +additionalProperties: false + +examples: + - | + mailbox@7e00b880 { + compatible = "brcm,bcm2835-mbox"; + reg = <0x7e00b880 0x40>; + interrupts = <0 1>; + #mbox-cells = <0>; + }; diff --git a/Documentation/devicetree/bindings/mailbox/nvidia,tegra186-hsp.yaml b/Documentation/devicetree/bindings/mailbox/nvidia,tegra186-hsp.yaml index a3e87516d637..2d14fc948999 100644 --- a/Documentation/devicetree/bindings/mailbox/nvidia,tegra186-hsp.yaml +++ b/Documentation/devicetree/bindings/mailbox/nvidia,tegra186-hsp.yaml @@ -66,6 +66,7 @@ properties: oneOf: - const: nvidia,tegra186-hsp - const: nvidia,tegra194-hsp + - const: nvidia,tegra264-hsp - items: - const: nvidia,tegra234-hsp - const: nvidia,tegra194-hsp diff --git a/Documentation/devicetree/bindings/mailbox/qcom,apcs-kpss-global.yaml b/Documentation/devicetree/bindings/mailbox/qcom,apcs-kpss-global.yaml index 32d7bbc98cac..d2e25ff6db7f 100644 --- a/Documentation/devicetree/bindings/mailbox/qcom,apcs-kpss-global.yaml +++ b/Documentation/devicetree/bindings/mailbox/qcom,apcs-kpss-global.yaml @@ -18,6 +18,7 @@ properties: oneOf: - items: - enum: + - qcom,ipq5018-apcs-apps-global - qcom,ipq5332-apcs-apps-global - qcom,ipq8074-apcs-apps-global - qcom,ipq9574-apcs-apps-global diff --git a/Documentation/devicetree/bindings/mfd/adi,max77541.yaml b/Documentation/devicetree/bindings/mfd/adi,max77541.yaml new file mode 100644 index 000000000000..c7895b2c38c9 --- /dev/null +++ b/Documentation/devicetree/bindings/mfd/adi,max77541.yaml @@ -0,0 +1,68 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mfd/adi,max77541.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: MAX77540/MAX77541 PMIC from ADI + +maintainers: + - Okan Sahin + +description: | + MAX77540 is a Power Management IC with 2 buck regulators. + + MAX77541 is a Power Management IC with 2 buck regulators and 1 ADC. + +properties: + compatible: + enum: + - adi,max77540 + - adi,max77541 + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + regulators: + $ref: /schemas/regulator/adi,max77541-regulator.yaml# + +required: + - compatible + - reg + - interrupts + +additionalProperties: false + +examples: + - | + #include + + i2c { + #address-cells = <1>; + #size-cells = <0>; + + pmic@69 { + compatible = "adi,max77541"; + reg = <0x69>; + interrupt-parent = <&gpio>; + interrupts = <16 IRQ_TYPE_EDGE_FALLING>; + + regulators { + buck1 { + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <5200000>; + regulator-boot-on; + regulator-always-on; + }; + buck2 { + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <5200000>; + regulator-boot-on; + regulator-always-on; + }; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/mfd/gateworks-gsc.yaml b/Documentation/devicetree/bindings/mfd/gateworks-gsc.yaml index acb9c54942d9..dc379f3ebf24 100644 --- a/Documentation/devicetree/bindings/mfd/gateworks-gsc.yaml +++ b/Documentation/devicetree/bindings/mfd/gateworks-gsc.yaml @@ -122,12 +122,6 @@ patternProperties: compatible: const: gw,gsc-fan - "#address-cells": - const: 1 - - "#size-cells": - const: 0 - reg: description: The fan controller base address maxItems: 1 @@ -135,8 +129,6 @@ patternProperties: required: - compatible - reg - - "#address-cells" - - "#size-cells" required: - compatible @@ -194,8 +186,6 @@ examples: }; fan-controller@2c { - #address-cells = <1>; - #size-cells = <0>; compatible = "gw,gsc-fan"; reg = <0x2c>; }; diff --git a/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml b/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml index 36de335a33aa..e43e6d74e308 100644 --- a/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml +++ b/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml @@ -71,6 +71,7 @@ properties: - qcom,pm8998 - qcom,pma8084 - qcom,pmd9635 + - qcom,pmi632 - qcom,pmi8950 - qcom,pmi8962 - qcom,pmi8994 @@ -146,6 +147,10 @@ patternProperties: type: object $ref: /schemas/nvmem/qcom,spmi-sdam.yaml# + "phy@[0-9a-f]+$": + type: object + $ref: /schemas/phy/qcom,snps-eusb2-repeater.yaml# + "pon@[0-9a-f]+$": type: object $ref: /schemas/power/reset/qcom,pon.yaml# diff --git a/Documentation/devicetree/bindings/mfd/qcom,tcsr.yaml b/Documentation/devicetree/bindings/mfd/qcom,tcsr.yaml index fe790af7b4fb..5ad9d5deaaf8 100644 --- a/Documentation/devicetree/bindings/mfd/qcom,tcsr.yaml +++ b/Documentation/devicetree/bindings/mfd/qcom,tcsr.yaml @@ -34,6 +34,7 @@ properties: - qcom,tcsr-ipq5332 - qcom,tcsr-ipq6018 - qcom,tcsr-ipq8064 + - qcom,tcsr-ipq8074 - qcom,tcsr-ipq9574 - qcom,tcsr-mdm9615 - qcom,tcsr-msm8226 diff --git a/Documentation/devicetree/bindings/mfd/richtek,rt5033.yaml b/Documentation/devicetree/bindings/mfd/richtek,rt5033.yaml new file mode 100644 index 000000000000..386b1a50158a --- /dev/null +++ b/Documentation/devicetree/bindings/mfd/richtek,rt5033.yaml @@ -0,0 +1,138 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mfd/richtek,rt5033.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Richtek RT5033 Power Management Integrated Circuit + +maintainers: + - Jakob Hauser + +description: + RT5033 is a multifunction device which includes battery charger, fuel gauge, + flash LED current source, LDO and synchronous Buck converter for portable + applications. It is interfaced to host controller using I2C interface. The + battery fuel gauge uses a separate I2C bus. + +properties: + compatible: + const: richtek,rt5033 + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + regulators: + description: + The regulators of RT5033 have to be instantiated under a sub-node named + "regulators". For SAFE_LDO voltage there is only one value of 4.9 V. LDO + voltage ranges from 1.2 V to 3.0 V in 0.1 V steps. BUCK voltage ranges + from 1.0 V to 3.0 V in 0.1 V steps. + type: object + patternProperties: + "^(SAFE_LDO|LDO|BUCK)$": + type: object + $ref: /schemas/regulator/regulator.yaml# + unevaluatedProperties: false + additionalProperties: false + + charger: + type: object + $ref: /schemas/power/supply/richtek,rt5033-charger.yaml# + +required: + - compatible + - reg + - interrupts + +additionalProperties: false + +examples: + - | + #include + + battery: battery { + compatible = "simple-battery"; + precharge-current-microamp = <450000>; + constant-charge-current-max-microamp = <1000000>; + charge-term-current-microamp = <150000>; + precharge-upper-limit-microvolt = <3500000>; + constant-charge-voltage-max-microvolt = <4350000>; + }; + + extcon { + usb_con: connector { + compatible = "usb-b-connector"; + label = "micro-USB"; + type = "micro"; + }; + }; + + i2c { + #address-cells = <1>; + #size-cells = <0>; + + i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + + fuel-gauge@35 { + compatible = "richtek,rt5033-battery"; + reg = <0x35>; + + interrupt-parent = <&msmgpio>; + interrupts = <121 IRQ_TYPE_EDGE_FALLING>; + + pinctrl-names = "default"; + pinctrl-0 = <&fg_alert_default>; + + power-supplies = <&rt5033_charger>; + }; + }; + + i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + + pmic@34 { + compatible = "richtek,rt5033"; + reg = <0x34>; + + interrupt-parent = <&msmgpio>; + interrupts = <62 IRQ_TYPE_EDGE_FALLING>; + + pinctrl-names = "default"; + pinctrl-0 = <&pmic_int_default>; + + regulators { + safe_ldo_reg: SAFE_LDO { + regulator-name = "SAFE_LDO"; + regulator-min-microvolt = <4900000>; + regulator-max-microvolt = <4900000>; + regulator-always-on; + }; + ldo_reg: LDO { + regulator-name = "LDO"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + }; + buck_reg: BUCK { + regulator-name = "BUCK"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + }; + }; + + rt5033_charger: charger { + compatible = "richtek,rt5033-charger"; + monitored-battery = <&battery>; + richtek,usb-connector = <&usb_con>; + }; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/mfd/samsung,s5m8767.yaml b/Documentation/devicetree/bindings/mfd/samsung,s5m8767.yaml index 10c7b408f33a..aea0b7d57d04 100644 --- a/Documentation/devicetree/bindings/mfd/samsung,s5m8767.yaml +++ b/Documentation/devicetree/bindings/mfd/samsung,s5m8767.yaml @@ -153,29 +153,18 @@ dependencies: additionalProperties: false allOf: - - if: + - not: required: - s5m8767,pmic-buck2-uses-gpio-dvs - then: - properties: - s5m8767,pmic-buck3-uses-gpio-dvs: false - s5m8767,pmic-buck4-uses-gpio-dvs: false - - - if: + - s5m8767,pmic-buck3-uses-gpio-dvs + - not: + required: + - s5m8767,pmic-buck2-uses-gpio-dvs + - s5m8767,pmic-buck4-uses-gpio-dvs + - not: required: - s5m8767,pmic-buck3-uses-gpio-dvs - then: - properties: - s5m8767,pmic-buck2-uses-gpio-dvs: false - s5m8767,pmic-buck4-uses-gpio-dvs: false - - - if: - required: - s5m8767,pmic-buck4-uses-gpio-dvs - then: - properties: - s5m8767,pmic-buck2-uses-gpio-dvs: false - s5m8767,pmic-buck3-uses-gpio-dvs: false examples: - | diff --git a/Documentation/devicetree/bindings/mfd/st,stpmic1.yaml b/Documentation/devicetree/bindings/mfd/st,stpmic1.yaml index 9573e4af949e..97c61097f9e2 100644 --- a/Documentation/devicetree/bindings/mfd/st,stpmic1.yaml +++ b/Documentation/devicetree/bindings/mfd/st,stpmic1.yaml @@ -184,7 +184,7 @@ properties: additionalProperties: false patternProperties: - "^(buck[1-4]|ldo[1-6]|boost|pwr_sw[1-2])-supply$": + "^(buck[1-4]|ldo[1-6]|vref_ddr|boost|pwr_sw[1-2])-supply$": description: STPMIC1 voltage regulators supplies "^(buck[1-4]|ldo[1-6]|boost|vref_ddr|pwr_sw[1-2])$": diff --git a/Documentation/devicetree/bindings/mfd/ti,tps6594.yaml b/Documentation/devicetree/bindings/mfd/ti,tps6594.yaml new file mode 100644 index 000000000000..9d43376bebed --- /dev/null +++ b/Documentation/devicetree/bindings/mfd/ti,tps6594.yaml @@ -0,0 +1,193 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mfd/ti,tps6594.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: TI TPS6594 Power Management Integrated Circuit + +maintainers: + - Julien Panis + +description: + TPS6594 is a Power Management IC which provides regulators and others + features like GPIOs, RTC, watchdog, ESMs (Error Signal Monitor), and + PFSM (Pre-configurable Finite State Machine) managing the state of the device. + TPS6594 is the super-set device while TPS6593 and LP8764 are derivatives. + +properties: + compatible: + enum: + - ti,lp8764-q1 + - ti,tps6593-q1 + - ti,tps6594-q1 + + reg: + description: I2C slave address or SPI chip select number. + maxItems: 1 + + ti,primary-pmic: + type: boolean + description: | + Identify the primary PMIC on SPMI bus. + A multi-PMIC synchronization scheme is implemented in the PMIC device + to synchronize the power state changes with other PMIC devices. This is + accomplished through a SPMI bus: the primary PMIC is the controller + device on the SPMI bus, and the secondary PMICs are the target devices + on the SPMI bus. + + system-power-controller: true + + gpio-controller: true + + '#gpio-cells': + const: 2 + description: | + The first cell is the pin number, the second cell is used to specify flags. + See ../gpio/gpio.txt for more information. + + interrupts: + maxItems: 1 + + regulators: + type: object + description: List of regulators provided by this controller. + + patternProperties: + "^buck([1-5]|12|34|123|1234)$": + type: object + $ref: /schemas/regulator/regulator.yaml# + + unevaluatedProperties: false + + "^ldo[1-4]$": + type: object + $ref: /schemas/regulator/regulator.yaml# + + unevaluatedProperties: false + + allOf: + - if: + required: + - buck12 + then: + properties: + buck123: false + buck1234: false + - if: + required: + - buck123 + then: + properties: + buck34: false + - if: + required: + - buck1234 + then: + properties: + buck34: false + + additionalProperties: false + +patternProperties: + "^buck([1-5]|12|34|123|1234)-supply$": + description: Input supply phandle for each buck. + + "^ldo[1-4]-supply$": + description: Input supply phandle for each ldo. + +required: + - compatible + - reg + - interrupts + +additionalProperties: false + +examples: + - | + #include + i2c { + #address-cells = <1>; + #size-cells = <0>; + + tps6593: pmic@48 { + compatible = "ti,tps6593-q1"; + reg = <0x48>; + ti,primary-pmic; + system-power-controller; + + gpio-controller; + #gpio-cells = <2>; + + pinctrl-names = "default"; + pinctrl-0 = <&pmic_irq_pins_default>; + interrupt-parent = <&mcu_gpio0>; + interrupts = <0 IRQ_TYPE_EDGE_FALLING>; + + buck123-supply = <&vcc_3v3_sys>; + buck4-supply = <&vcc_3v3_sys>; + buck5-supply = <&vcc_3v3_sys>; + ldo1-supply = <&vcc_3v3_sys>; + ldo2-supply = <&vcc_3v3_sys>; + ldo3-supply = <&buck5>; + ldo4-supply = <&vcc_3v3_sys>; + + regulators { + buck123: buck123 { + regulator-name = "vcc_core"; + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <850000>; + regulator-boot-on; + regulator-always-on; + }; + + buck4: buck4 { + regulator-name = "vcc_1v1"; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + regulator-boot-on; + regulator-always-on; + }; + + buck5: buck5 { + regulator-name = "vcc_1v8_sys"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-boot-on; + regulator-always-on; + }; + + ldo1: ldo1 { + regulator-name = "vddshv5_sdio"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; + + ldo2: ldo2 { + regulator-name = "vpp_1v8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-boot-on; + regulator-always-on; + }; + + ldo3: ldo3 { + regulator-name = "vcc_0v85"; + regulator-min-microvolt = <850000>; + regulator-max-microvolt = <850000>; + regulator-boot-on; + regulator-always-on; + }; + + ldo4: ldo4 { + regulator-name = "vdda_1v8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-boot-on; + regulator-always-on; + }; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/mfd/x-powers,axp152.yaml b/Documentation/devicetree/bindings/mfd/x-powers,axp152.yaml index f7f0f2c0421a..9ad55746133b 100644 --- a/Documentation/devicetree/bindings/mfd/x-powers,axp152.yaml +++ b/Documentation/devicetree/bindings/mfd/x-powers,axp152.yaml @@ -90,6 +90,7 @@ properties: oneOf: - enum: - x-powers,axp152 + - x-powers,axp192 - x-powers,axp202 - x-powers,axp209 - x-powers,axp221 diff --git a/Documentation/devicetree/bindings/power/supply/richtek,rt5033-battery.yaml b/Documentation/devicetree/bindings/power/supply/richtek,rt5033-battery.yaml index 756c16d1727d..b5d8888d03d2 100644 --- a/Documentation/devicetree/bindings/power/supply/richtek,rt5033-battery.yaml +++ b/Documentation/devicetree/bindings/power/supply/richtek,rt5033-battery.yaml @@ -26,7 +26,7 @@ required: - compatible - reg -additionalProperties: false +unevaluatedProperties: false examples: - | diff --git a/Documentation/devicetree/bindings/power/supply/richtek,rt5033-charger.yaml b/Documentation/devicetree/bindings/power/supply/richtek,rt5033-charger.yaml new file mode 100644 index 000000000000..5b3edd79a523 --- /dev/null +++ b/Documentation/devicetree/bindings/power/supply/richtek,rt5033-charger.yaml @@ -0,0 +1,65 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/power/supply/richtek,rt5033-charger.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Richtek RT5033 PMIC Battery Charger + +maintainers: + - Jakob Hauser + +description: + The battery charger of the multifunction device RT5033 has to be instantiated + under sub-node named "charger" using the following format. + +properties: + compatible: + const: richtek,rt5033-charger + + monitored-battery: + $ref: /schemas/types.yaml#/definitions/phandle + description: | + Phandle to the monitored battery according to battery.yaml. The battery + node needs to contain five parameters. + + precharge-current-microamp: + Current of pre-charge mode. The pre-charge current levels are 350 mA + to 650 mA programmed by I2C per 100 mA. + + constant-charge-current-max-microamp: + Current of fast-charge mode. The fast-charge current levels are 700 mA + to 2000 mA programmed by I2C per 100 mA. + + charge-term-current-microamp: + This property is end of charge current. Its level ranges from 150 mA + to 600 mA. Between 150 mA and 300 mA in 50 mA steps, between 300 mA and + 600 mA in 100 mA steps. + + precharge-upper-limit-microvolt: + Voltage of pre-charge mode. If the battery voltage is below the pre-charge + threshold voltage, the charger is in pre-charge mode with pre-charge + current. Its levels are 2.3 V to 3.8 V programmed by I2C per 0.1 V. + + constant-charge-voltage-max-microvolt: + Battery regulation voltage of constant voltage mode. This voltage levels + from 3.65 V to 4.4 V by I2C per 0.025 V. + + richtek,usb-connector: + $ref: /schemas/types.yaml#/definitions/phandle + description: + Phandle to a USB connector according to usb-connector.yaml. The connector + should be a child of the extcon device. + +required: + - monitored-battery + +additionalProperties: false + +examples: + - | + charger { + compatible = "richtek,rt5033-charger"; + monitored-battery = <&battery>; + richtek,usb-connector = <&usb_con>; + }; diff --git a/Documentation/devicetree/bindings/regulator/adi,max77541-regulator.yaml b/Documentation/devicetree/bindings/regulator/adi,max77541-regulator.yaml new file mode 100644 index 000000000000..9e36d5467b56 --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/adi,max77541-regulator.yaml @@ -0,0 +1,38 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/regulator/adi,max77541-regulator.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Buck Converter for MAX77540/MAX77541 + +maintainers: + - Okan Sahin + +description: | + This is a part of device tree bindings for ADI MAX77540/MAX77541 + + The buck converter is represented as a sub-node of the PMIC node on the device tree. + + The device has two buck regulators. + See also Documentation/devicetree/bindings/mfd/adi,max77541.yaml for + additional information and example. + +patternProperties: + "^buck[12]$": + type: object + $ref: regulator.yaml# + additionalProperties: false + description: | + Buck regulator. + + properties: + regulator-name: true + regulator-always-on: true + regulator-boot-on: true + regulator-min-microvolt: + minimum: 300000 + regulator-max-microvolt: + maximum: 5200000 + +additionalProperties: false diff --git a/Documentation/devicetree/bindings/rtc/isil,isl1208.txt b/Documentation/devicetree/bindings/rtc/isil,isl1208.txt deleted file mode 100644 index 51f003006f04..000000000000 --- a/Documentation/devicetree/bindings/rtc/isil,isl1208.txt +++ /dev/null @@ -1,38 +0,0 @@ -Intersil ISL1209/19 I2C RTC/Alarm chip with event in - -ISL12X9 have additional pins EVIN and #EVDET for tamper detection, while the -ISL1208 and ISL1218 do not. They are all use the same driver with the bindings -described here, with chip specific properties as noted. - -Required properties supported by the device: - - "compatible": Should be one of the following: - - "isil,isl1208" - - "isil,isl1209" - - "isil,isl1218" - - "isil,isl1219" - - "reg": I2C bus address of the device - -Optional properties: - - "interrupt-names": list which may contains "irq" and "evdet" - evdet applies to isl1209 and isl1219 only - - "interrupts": list of interrupts for "irq" and "evdet" - evdet applies to isl1209 and isl1219 only - - "isil,ev-evienb": Enable or disable internal pull on EVIN pin - Applies to isl1209 and isl1219 only - Possible values are 0 and 1 - Value 0 enables internal pull-up on evin pin, 1 disables it. - Default will leave the non-volatile configuration of the pullup - as is. - -Example isl1219 node with #IRQ pin connected to SoC gpio1 pin12 and #EVDET pin -connected to SoC gpio2 pin 24 and internal pull-up enabled in EVIN pin. - - isl1219: rtc@68 { - compatible = "isil,isl1219"; - reg = <0x68>; - interrupt-names = "irq", "evdet"; - interrupts-extended = <&gpio1 12 IRQ_TYPE_EDGE_FALLING>, - <&gpio2 24 IRQ_TYPE_EDGE_FALLING>; - isil,ev-evienb = <1>; - }; - diff --git a/Documentation/devicetree/bindings/rtc/isil,isl1208.yaml b/Documentation/devicetree/bindings/rtc/isil,isl1208.yaml new file mode 100644 index 000000000000..11f7378d4997 --- /dev/null +++ b/Documentation/devicetree/bindings/rtc/isil,isl1208.yaml @@ -0,0 +1,100 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/rtc/isil,isl1208.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Intersil ISL1209/19 I2C RTC/Alarm chip with event in + +maintainers: + - Biju Das + - Trent Piepho + +description: + ISL12X9 have additional pins EVIN and EVDET for tamper detection, while the + ISL1208 and ISL1218 do not. + +properties: + compatible: + enum: + - isil,isl1208 + - isil,isl1209 + - isil,isl1218 + - isil,isl1219 + + reg: + maxItems: 1 + + clocks: + maxItems: 1 + + clock-names: + description: | + Use xin, if connected to an external crystal. + Use clkin, if connected to an external clock signal. + enum: + - xin + - clkin + + interrupts: + minItems: 1 + maxItems: 2 + + interrupt-names: + minItems: 1 + items: + - const: irq + - const: evdet + + isil,ev-evienb: + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [ 0, 1 ] + description: | + Enable or disable internal pull on EVIN pin + Default will leave the non-volatile configuration of the pullup + as is. + <0> : Enables internal pull-up on evin pin + <1> : Disables internal pull-up on evin pin + +required: + - compatible + - reg + +allOf: + - $ref: rtc.yaml# + - if: + properties: + compatible: + contains: + enum: + - isil,isl1209 + - isil,isl1219 + then: + properties: + interrupts: + maxItems: 2 + interrupt-names: + items: + - const: irq + - const: evdet + else: + properties: + interrupts: + maxItems: 1 + interrupt-names: + items: + - const: irq + +unevaluatedProperties: false + +examples: + - | + i2c { + #address-cells = <1>; + #size-cells = <0>; + + rtc_twi: rtc@6f { + compatible = "isil,isl1208"; + reg = <0x6f>; + }; + }; diff --git a/Documentation/devicetree/bindings/rtc/loongson,rtc.yaml b/Documentation/devicetree/bindings/rtc/loongson,rtc.yaml new file mode 100644 index 000000000000..f89c1f660aee --- /dev/null +++ b/Documentation/devicetree/bindings/rtc/loongson,rtc.yaml @@ -0,0 +1,57 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/rtc/loongson,rtc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Loongson Real-Time Clock + +description: + The Loongson family chips use an on-chip counter 0 (Time Of Year + counter) as the RTC. + +maintainers: + - Binbin Zhou + +allOf: + - $ref: rtc.yaml# + +properties: + compatible: + oneOf: + - enum: + - loongson,ls1b-rtc + - loongson,ls1c-rtc + - loongson,ls7a-rtc + - loongson,ls2k1000-rtc + - items: + - enum: + - loongson,ls2k2000-rtc + - loongson,ls2k0500-rtc + - const: loongson,ls7a-rtc + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + +required: + - compatible + - reg + +unevaluatedProperties: false + +examples: + - | + #include + + rtc@1fe27800 { + compatible = "loongson,ls2k1000-rtc"; + reg = <0x1fe27800 0x100>; + + interrupt-parent = <&liointc1>; + interrupts = <8 IRQ_TYPE_LEVEL_HIGH>; + }; + +... diff --git a/Documentation/devicetree/bindings/rtc/rtc.yaml b/Documentation/devicetree/bindings/rtc/rtc.yaml index c6fff5486fe6..efb66df82782 100644 --- a/Documentation/devicetree/bindings/rtc/rtc.yaml +++ b/Documentation/devicetree/bindings/rtc/rtc.yaml @@ -15,7 +15,7 @@ description: | properties: $nodename: - pattern: "^rtc(@.*|-[0-9a-f])*$" + pattern: "^rtc(@.*|-([0-9]|[1-9][0-9]+))?$" aux-voltage-chargeable: $ref: /schemas/types.yaml#/definitions/uint32 diff --git a/Documentation/devicetree/bindings/rtc/trivial-rtc.yaml b/Documentation/devicetree/bindings/rtc/trivial-rtc.yaml index a3603e638c37..9af77f21bb7f 100644 --- a/Documentation/devicetree/bindings/rtc/trivial-rtc.yaml +++ b/Documentation/devicetree/bindings/rtc/trivial-rtc.yaml @@ -47,8 +47,6 @@ properties: - isil,isl1218 # Intersil ISL12022 Real-time Clock - isil,isl12022 - # Loongson-2K Socs/LS7A bridge Real-time Clock - - loongson,ls2x-rtc # Real Time Clock Module with I2C-Bus - microcrystal,rv3029 # Real Time Clock diff --git a/Documentation/i2c/busses/i2c-i801.rst b/Documentation/i2c/busses/i2c-i801.rst index ab9e850e8fe0..e76e68ccf718 100644 --- a/Documentation/i2c/busses/i2c-i801.rst +++ b/Documentation/i2c/busses/i2c-i801.rst @@ -46,7 +46,7 @@ Supported adapters: * Intel Emmitsburg (PCH) * Intel Alder Lake (PCH) * Intel Raptor Lake (PCH) - * Intel Meteor Lake (SOC) + * Intel Meteor Lake (SOC and PCH) Datasheets: Publicly available at the Intel website diff --git a/Documentation/leds/index.rst b/Documentation/leds/index.rst index ce57254cb871..3ade16c18328 100644 --- a/Documentation/leds/index.rst +++ b/Documentation/leds/index.rst @@ -17,6 +17,7 @@ LEDs uleds leds-blinkm + leds-cht-wcove leds-el15203000 leds-lm3556 leds-lp3944 diff --git a/Documentation/leds/leds-cht-wcove.rst b/Documentation/leds/leds-cht-wcove.rst new file mode 100644 index 000000000000..5ec7cb60c4aa --- /dev/null +++ b/Documentation/leds/leds-cht-wcove.rst @@ -0,0 +1,38 @@ +.. SPDX-License-Identifier: GPL-2.0 + +=========================================================== +Kernel driver for Intel Cherry Trail Whiskey Cove PMIC LEDs +=========================================================== + +/sys/class/leds//hw_pattern +-------------------------------- + +Specify a hardware pattern for the Whiskey Cove PMIC LEDs. + +The only supported pattern is hardware breathing mode:: + + "0 2000 1 2000" + + ^ + | + Max-| --- + | / \ + | / \ + | / \ / + | / \ / + Min-|- --- + | + 0------2------4--> time (sec) + +The rise and fall times must be the same value. +Supported values are 2000, 1000, 500 and 250 for +breathing frequencies of 1/4, 1/2, 1 and 2 Hz. + +The set pattern only controls the timing. For max brightness the last +set brightness is used and the max brightness can be changed +while breathing by writing the brightness attribute. + +This is just like how blinking works in the LED subsystem, +for both sw and hw blinking the brightness can also be changed +while blinking. Breathing on this hw really is just a variant +mode of blinking. diff --git a/Documentation/leds/well-known-leds.txt b/Documentation/leds/well-known-leds.txt index e9c30dc75884..67b44704801f 100644 --- a/Documentation/leds/well-known-leds.txt +++ b/Documentation/leds/well-known-leds.txt @@ -58,6 +58,7 @@ LEDs on notebook body, indicating that sound input / output is muted. * System notification +Good: "rgb:status" Legacy: "status-led:{red,green,blue}" (Motorola Droid 4) Legacy: "lp5523:{r,g,b}" (Nokia N900) @@ -65,7 +66,7 @@ Phones usually have multi-color status LED. * Power management -Good: "platform:*:charging" (allwinner sun50i) +Good: "platform:*:charging" (allwinner sun50i, leds-cht-wcove) * Screen diff --git a/MAINTAINERS b/MAINTAINERS index 316cbc474c22..4f569c4d203c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -10890,7 +10890,6 @@ S: Maintained F: drivers/net/ethernet/sgi/ioc3-eth.c IOMAP FILESYSTEM LIBRARY -M: Christoph Hellwig M: Darrick J. Wong L: linux-xfs@vger.kernel.org L: linux-fsdevel@vger.kernel.org diff --git a/arch/csky/kernel/probes/uprobes.c b/arch/csky/kernel/probes/uprobes.c index 2d31a12e46cf..936bea6fd32d 100644 --- a/arch/csky/kernel/probes/uprobes.c +++ b/arch/csky/kernel/probes/uprobes.c @@ -64,6 +64,7 @@ int arch_uprobe_post_xol(struct arch_uprobe *auprobe, struct pt_regs *regs) struct uprobe_task *utask = current->utask; WARN_ON_ONCE(current->thread.trap_no != UPROBE_TRAP_NR); + current->thread.trap_no = utask->autask.saved_trap_no; instruction_pointer_set(regs, utask->vaddr + auprobe->insn_size); @@ -101,6 +102,8 @@ void arch_uprobe_abort_xol(struct arch_uprobe *auprobe, struct pt_regs *regs) { struct uprobe_task *utask = current->utask; + current->thread.trap_no = utask->autask.saved_trap_no; + /* * Task has received a fatal signal, so reset back to probed * address. diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig index c0b4b1c253d1..4cb46d5c64a2 100644 --- a/arch/parisc/Kconfig +++ b/arch/parisc/Kconfig @@ -304,16 +304,6 @@ config IRQSTACKS for handling hard and soft interrupts. This can help avoid overflowing the process kernel stacks. -config TLB_PTLOCK - bool "Use page table locks in TLB fault handler" - depends on SMP - default n - help - Select this option to enable page table locking in the TLB - fault handler. This ensures that page table entries are - updated consistently on SMP machines at the expense of some - loss in performance. - config HOTPLUG_CPU bool default y if SMP @@ -346,7 +336,7 @@ config NR_CPUS int "Maximum number of CPUs (2-32)" range 2 32 depends on SMP - default "4" if 64BIT + default "8" if 64BIT default "16" config KEXEC diff --git a/arch/parisc/Kconfig.debug b/arch/parisc/Kconfig.debug index 3a059cb5e112..1401e4c5fe5f 100644 --- a/arch/parisc/Kconfig.debug +++ b/arch/parisc/Kconfig.debug @@ -10,3 +10,14 @@ config LIGHTWEIGHT_SPINLOCK_CHECK spinlock debugging you should choose the DEBUG_SPINLOCK option which will detect unitialized spinlocks too. If unsure say Y here. + +config TLB_PTLOCK + bool "Use page table locks in TLB fault handler" + depends on SMP + default n + help + Select this option to enable page table locking in the TLB + fault handler. This ensures that page table entries are + updated consistently on SMP machines at the expense of some + loss in performance. + diff --git a/arch/parisc/configs/generic-32bit_defconfig b/arch/parisc/configs/generic-32bit_defconfig index 8c4d4844321f..9651f4390029 100644 --- a/arch/parisc/configs/generic-32bit_defconfig +++ b/arch/parisc/configs/generic-32bit_defconfig @@ -82,7 +82,6 @@ CONFIG_TUN=m # CONFIG_NET_VENDOR_AMD is not set # CONFIG_NET_VENDOR_ATHEROS is not set # CONFIG_NET_VENDOR_BROADCOM is not set -# CONFIG_NET_VENDOR_BROCADE is not set # CONFIG_NET_VENDOR_CHELSIO is not set # CONFIG_NET_VENDOR_CISCO is not set CONFIG_NET_TULIP=y @@ -97,6 +96,7 @@ CONFIG_LASI_82596=y # CONFIG_NET_VENDOR_NVIDIA is not set # CONFIG_NET_VENDOR_OKI is not set # CONFIG_NET_VENDOR_QLOGIC is not set +# CONFIG_NET_VENDOR_BROCADE is not set # CONFIG_NET_VENDOR_RDC is not set # CONFIG_NET_VENDOR_REALTEK is not set # CONFIG_NET_VENDOR_SEEQ is not set @@ -129,17 +129,53 @@ CONFIG_PRINTER=m CONFIG_PPDEV=m # CONFIG_HW_RANDOM is not set CONFIG_I2C=y -# CONFIG_HWMON is not set +CONFIG_HWMON=m +CONFIG_DRM=m +CONFIG_DRM_DP_CEC=y +# CONFIG_DRM_I2C_CH7006 is not set +# CONFIG_DRM_I2C_SIL164 is not set +CONFIG_DRM_RADEON=m +CONFIG_DRM_NOUVEAU=m +# CONFIG_DRM_NOUVEAU_BACKLIGHT is not set +CONFIG_DRM_VGEM=m +CONFIG_DRM_UDL=m +CONFIG_DRM_MGAG200=m CONFIG_FB=y CONFIG_FB_FOREIGN_ENDIAN=y -CONFIG_FB_MODE_HELPERS=y +CONFIG_FB_PM2=m +CONFIG_FB_PM2_FIFO_DISCONNECT=y +CONFIG_FB_NVIDIA=m +CONFIG_FB_NVIDIA_I2C=y +# CONFIG_FB_NVIDIA_BACKLIGHT is not set +CONFIG_FB_RIVA=m +CONFIG_FB_RIVA_I2C=y +# CONFIG_FB_RIVA_BACKLIGHT is not set CONFIG_FB_MATROX=m +CONFIG_FB_MATROX_MILLENIUM=y +CONFIG_FB_MATROX_MYSTIQUE=y CONFIG_FB_MATROX_G=y +CONFIG_FB_MATROX_I2C=m +CONFIG_FB_MATROX_MAVEN=m +CONFIG_FB_ATY128=m +# CONFIG_FB_ATY128_BACKLIGHT is not set +CONFIG_FB_ATY=m +CONFIG_FB_ATY_CT=y +CONFIG_FB_ATY_GX=y +# CONFIG_FB_ATY_BACKLIGHT is not set +CONFIG_FB_S3=m +CONFIG_FB_SAVAGE=m +CONFIG_FB_SAVAGE_I2C=y +CONFIG_FB_SAVAGE_ACCEL=y +CONFIG_FB_SIS=m +CONFIG_FB_SIS_300=y +CONFIG_FB_SIS_315=y CONFIG_FB_VOODOO1=m +CONFIG_FB_TRIDENT=m +CONFIG_FB_SMSCUFX=m +CONFIG_FB_UDL=m CONFIG_DUMMY_CONSOLE_COLUMNS=128 CONFIG_DUMMY_CONSOLE_ROWS=48 CONFIG_FRAMEBUFFER_CONSOLE=y -CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y CONFIG_LOGO=y # CONFIG_LOGO_LINUX_MONO is not set # CONFIG_LOGO_LINUX_VGA16 is not set @@ -216,17 +252,17 @@ CONFIG_CIFS_XATTR=y CONFIG_CIFS_POSIX=y # CONFIG_CIFS_DEBUG is not set CONFIG_CRYPTO_TEST=m -CONFIG_CRYPTO_HMAC=y -CONFIG_CRYPTO_MD5=y -CONFIG_CRYPTO_MICHAEL_MIC=m -CONFIG_CRYPTO_SHA1=y -CONFIG_CRYPTO_WP512=m CONFIG_CRYPTO_BLOWFISH=m CONFIG_CRYPTO_CAST5=m CONFIG_CRYPTO_CAST6=m CONFIG_CRYPTO_DES=y CONFIG_CRYPTO_SERPENT=m CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_MICHAEL_MIC=m +CONFIG_CRYPTO_SHA1=y +CONFIG_CRYPTO_WP512=m CONFIG_CRYPTO_DEFLATE=y CONFIG_CRC_CCITT=m CONFIG_CRC_T10DIF=y diff --git a/arch/parisc/configs/generic-64bit_defconfig b/arch/parisc/configs/generic-64bit_defconfig index 57501b0aed92..6758c030b09d 100644 --- a/arch/parisc/configs/generic-64bit_defconfig +++ b/arch/parisc/configs/generic-64bit_defconfig @@ -20,9 +20,6 @@ CONFIG_USER_NS=y CONFIG_RELAY=y CONFIG_BLK_DEV_INITRD=y CONFIG_CC_OPTIMIZE_FOR_SIZE=y -# CONFIG_COMPAT_BRK is not set -CONFIG_PA8X00=y -CONFIG_64BIT=y CONFIG_SMP=y CONFIG_HPPB=y CONFIG_IOMMU_CCIO=y @@ -37,6 +34,7 @@ CONFIG_MODULE_FORCE_UNLOAD=y CONFIG_MODVERSIONS=y CONFIG_BLK_DEV_INTEGRITY=y CONFIG_BINFMT_MISC=m +# CONFIG_COMPAT_BRK is not set # CONFIG_COMPACTION is not set CONFIG_MEMORY_FAILURE=y CONFIG_NET=y @@ -103,7 +101,6 @@ CONFIG_TUN=y # CONFIG_NET_VENDOR_AMD is not set # CONFIG_NET_VENDOR_ATHEROS is not set # CONFIG_NET_VENDOR_BROADCOM is not set -# CONFIG_NET_VENDOR_BROCADE is not set # CONFIG_NET_VENDOR_CHELSIO is not set # CONFIG_NET_VENDOR_CISCO is not set CONFIG_NET_TULIP=y @@ -121,6 +118,7 @@ CONFIG_E1000=y # CONFIG_NET_VENDOR_OKI is not set CONFIG_QLA3XXX=m CONFIG_QLCNIC=m +# CONFIG_NET_VENDOR_BROCADE is not set # CONFIG_NET_VENDOR_RDC is not set # CONFIG_NET_VENDOR_REALTEK is not set # CONFIG_NET_VENDOR_SEEQ is not set @@ -186,7 +184,6 @@ CONFIG_WATCHDOG=y CONFIG_SOFT_WATCHDOG=m CONFIG_SSB=m CONFIG_SSB_DRIVER_PCICORE=y -CONFIG_HTC_PASIC3=m CONFIG_LPC_SCH=m CONFIG_MFD_SM501=m CONFIG_REGULATOR=y @@ -196,14 +193,46 @@ CONFIG_MEDIA_SUPPORT=m CONFIG_AGP=y CONFIG_AGP_PARISC=y CONFIG_DRM=y +# CONFIG_DRM_I2C_CH7006 is not set +# CONFIG_DRM_I2C_SIL164 is not set CONFIG_DRM_RADEON=y +CONFIG_DRM_NOUVEAU=m +# CONFIG_DRM_NOUVEAU_BACKLIGHT is not set +CONFIG_DRM_MGAG200=m CONFIG_FB=y -CONFIG_FB_MATROX=y +CONFIG_FB_PM2=m +CONFIG_FB_PM2_FIFO_DISCONNECT=y +CONFIG_FB_NVIDIA=m +CONFIG_FB_NVIDIA_I2C=y +# CONFIG_FB_NVIDIA_BACKLIGHT is not set +CONFIG_FB_RIVA=m +CONFIG_FB_RIVA_I2C=y +# CONFIG_FB_RIVA_BACKLIGHT is not set +CONFIG_FB_MATROX=m +CONFIG_FB_MATROX_MILLENIUM=y CONFIG_FB_MATROX_MYSTIQUE=y CONFIG_FB_MATROX_G=y -CONFIG_FB_MATROX_I2C=y -CONFIG_FB_MATROX_MAVEN=y +CONFIG_FB_MATROX_I2C=m +CONFIG_FB_MATROX_MAVEN=m CONFIG_FB_RADEON=y +# CONFIG_FB_RADEON_BACKLIGHT is not set +CONFIG_FB_ATY128=m +# CONFIG_FB_ATY128_BACKLIGHT is not set +CONFIG_FB_ATY=m +CONFIG_FB_ATY_CT=y +CONFIG_FB_ATY_GX=y +# CONFIG_FB_ATY_BACKLIGHT is not set +CONFIG_FB_S3=m +CONFIG_FB_SAVAGE=m +CONFIG_FB_SAVAGE_I2C=y +CONFIG_FB_SAVAGE_ACCEL=y +CONFIG_FB_SIS=m +CONFIG_FB_SIS_300=y +CONFIG_FB_SIS_315=y +CONFIG_FB_VOODOO1=m +CONFIG_FB_TRIDENT=m +CONFIG_FB_SMSCUFX=m +CONFIG_FB_UDL=m CONFIG_LOGO=y # CONFIG_LOGO_LINUX_CLUT224 is not set CONFIG_HIDRAW=y @@ -257,12 +286,12 @@ CONFIG_NLS_ISO8859_1=m CONFIG_NLS_ISO8859_2=m CONFIG_NLS_UTF8=m CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_FCRYPT=m CONFIG_CRYPTO_ECB=m CONFIG_CRYPTO_PCBC=m CONFIG_CRYPTO_MD4=m CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_MICHAEL_MIC=m -CONFIG_CRYPTO_FCRYPT=m CONFIG_CRYPTO_DEFLATE=m # CONFIG_CRYPTO_HW is not set CONFIG_CRC_CCITT=m diff --git a/arch/parisc/include/asm/irqflags.h b/arch/parisc/include/asm/irqflags.h index 38a19c0bac3a..00fd87724588 100644 --- a/arch/parisc/include/asm/irqflags.h +++ b/arch/parisc/include/asm/irqflags.h @@ -31,6 +31,11 @@ static inline unsigned long arch_local_irq_save(void) static inline void arch_local_irq_restore(unsigned long flags) { + /* warn if IRQs are on although they should be off */ + if (IS_ENABLED(CONFIG_LIGHTWEIGHT_SPINLOCK_CHECK)) + if (arch_local_save_flags() & PSW_I) + asm volatile("break 6,6\n"); /* SPINLOCK_BREAK_INSN */ + asm volatile("mtsm %0" : : "r" (flags) : "memory"); } diff --git a/arch/parisc/include/asm/pdc.h b/arch/parisc/include/asm/pdc.h index 2b4fad8328e8..269b9a159f01 100644 --- a/arch/parisc/include/asm/pdc.h +++ b/arch/parisc/include/asm/pdc.h @@ -88,8 +88,8 @@ int pdc_iodc_print(const unsigned char *str, unsigned count); void pdc_emergency_unlock(void); int pdc_sti_call(unsigned long func, unsigned long flags, - unsigned long inptr, unsigned long outputr, - unsigned long glob_cfg); + unsigned long inptr, unsigned long outputr, + unsigned long glob_cfg, int do_call64); int __pdc_cpu_rendezvous(void); void pdc_cpu_rendezvous_lock(void); diff --git a/arch/parisc/include/asm/processor.h b/arch/parisc/include/asm/processor.h index a608970b249a..b1ea85e77ede 100644 --- a/arch/parisc/include/asm/processor.h +++ b/arch/parisc/include/asm/processor.h @@ -11,6 +11,7 @@ #ifndef __ASSEMBLY__ #include +#include #include #include @@ -291,6 +292,40 @@ extern void __noreturn toc_intr(struct pt_regs *regs); extern void toc_handler(void); extern unsigned int toc_handler_size; extern unsigned int toc_handler_csum; +extern void do_cpu_irq_mask(struct pt_regs *); +extern irqreturn_t timer_interrupt(int, void *); +extern irqreturn_t ipi_interrupt(int, void *); + +/* called from assembly code: */ +extern void start_parisc(void); +extern void smp_callin(unsigned long); +extern void sys_rt_sigreturn(struct pt_regs *, int); +extern void do_notify_resume(struct pt_regs *, long); +extern long do_syscall_trace_enter(struct pt_regs *); +extern void do_syscall_trace_exit(struct pt_regs *); + +/* CPU startup and info */ +struct seq_file; +extern void early_trap_init(void); +extern void collect_boot_cpu_data(void); +extern int show_cpuinfo (struct seq_file *m, void *v); + +/* driver code in driver/parisc */ +extern void gsc_init(void); +extern void processor_init(void); +extern void ccio_init(void); +extern void hppb_init(void); +extern void dino_init(void); +extern void iosapic_init(void); +extern void lba_init(void); +extern void sba_init(void); +extern void parisc_eisa_init(void); +struct parisc_device; +struct resource; +extern void sba_distributed_lmmio(struct parisc_device *, struct resource *); +extern void sba_directed_lmmio(struct parisc_device *, struct resource *); +extern void lba_set_iregs(struct parisc_device *lba, u32 ibase, u32 imask); +extern void ccio_cujo20_fixup(struct parisc_device *dev, u32 iovp); #endif /* __ASSEMBLY__ */ diff --git a/arch/parisc/include/uapi/asm/cachectl.h b/arch/parisc/include/uapi/asm/cachectl.h new file mode 100644 index 000000000000..68d6b455498b --- /dev/null +++ b/arch/parisc/include/uapi/asm/cachectl.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +#ifndef _ASM_CACHECTL +#define _ASM_CACHECTL + +/* + * Options for cacheflush system call + */ +#define ICACHE (1<<0) /* flush instruction cache */ +#define DCACHE (1<<1) /* writeback and flush data cache */ +#define BCACHE (ICACHE|DCACHE) /* flush both caches */ + +#endif /* _ASM_CACHECTL */ diff --git a/arch/parisc/kernel/audit.c b/arch/parisc/kernel/audit.c index f420b5552140..375cd73b5281 100644 --- a/arch/parisc/kernel/audit.c +++ b/arch/parisc/kernel/audit.c @@ -40,11 +40,6 @@ int audit_classify_arch(int arch) int audit_classify_syscall(int abi, unsigned syscall) { -#ifdef CONFIG_COMPAT - extern int parisc32_classify_syscall(unsigned); - if (abi == AUDIT_ARCH_PARISC) - return parisc32_classify_syscall(syscall); -#endif switch (syscall) { case __NR_open: return AUDITSC_OPEN; @@ -55,6 +50,10 @@ int audit_classify_syscall(int abi, unsigned syscall) case __NR_openat2: return AUDITSC_OPENAT2; default: +#ifdef CONFIG_COMPAT + if (abi == AUDIT_ARCH_PARISC) + return AUDITSC_COMPAT; +#endif return AUDITSC_NATIVE; } } diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c index 501160250bb7..b55b35c89d6a 100644 --- a/arch/parisc/kernel/cache.c +++ b/arch/parisc/kernel/cache.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -28,6 +29,7 @@ #include #include #include +#include int split_tlb __ro_after_init; int dcache_stride __ro_after_init; @@ -790,3 +792,50 @@ void invalidate_kernel_vmap_range(void *vaddr, int size) flush_tlb_kernel_range(start, end); } EXPORT_SYMBOL(invalidate_kernel_vmap_range); + + +SYSCALL_DEFINE3(cacheflush, unsigned long, addr, unsigned long, bytes, + unsigned int, cache) +{ + unsigned long start, end; + ASM_EXCEPTIONTABLE_VAR(error); + + if (bytes == 0) + return 0; + if (!access_ok((void __user *) addr, bytes)) + return -EFAULT; + + end = addr + bytes; + + if (cache & DCACHE) { + start = addr; + __asm__ __volatile__ ( +#ifdef CONFIG_64BIT + "1: cmpb,*<<,n %0,%2,1b\n" +#else + "1: cmpb,<<,n %0,%2,1b\n" +#endif + " fic,m %3(%4,%0)\n" + "2: sync\n" + ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 2b) + : "+r" (start), "+r" (error) + : "r" (end), "r" (dcache_stride), "i" (SR_USER)); + } + + if (cache & ICACHE && error == 0) { + start = addr; + __asm__ __volatile__ ( +#ifdef CONFIG_64BIT + "1: cmpb,*<<,n %0,%2,1b\n" +#else + "1: cmpb,<<,n %0,%2,1b\n" +#endif + " fdc,m %3(%4,%0)\n" + "2: sync\n" + ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 2b) + : "+r" (start), "+r" (error) + : "r" (end), "r" (icache_stride), "i" (SR_USER)); + } + + return error; +} diff --git a/arch/parisc/kernel/compat_audit.c b/arch/parisc/kernel/compat_audit.c index 539b16891bdf..3ac53f1ab860 100644 --- a/arch/parisc/kernel/compat_audit.c +++ b/arch/parisc/kernel/compat_audit.c @@ -26,19 +26,3 @@ unsigned int parisc32_signal_class[] = { #include ~0U }; - -int parisc32_classify_syscall(unsigned syscall) -{ - switch (syscall) { - case __NR_open: - return AUDITSC_OPEN; - case __NR_openat: - return AUDITSC_OPENAT; - case __NR_execve: - return AUDITSC_EXECVE; - case __NR_openat2: - return AUDITSC_OPENAT2; - default: - return AUDITSC_COMPAT; - } -} diff --git a/arch/parisc/kernel/drivers.c b/arch/parisc/kernel/drivers.c index 28f47285d448..8f4b77648491 100644 --- a/arch/parisc/kernel/drivers.c +++ b/arch/parisc/kernel/drivers.c @@ -4,7 +4,7 @@ * * Copyright (c) 1999 The Puffin Group * Copyright (c) 2001 Matthew Wilcox for Hewlett Packard - * Copyright (c) 2001 Helge Deller + * Copyright (c) 2001-2023 Helge Deller * Copyright (c) 2001,2002 Ryan Bradetich * Copyright (c) 2004-2005 Thibaut VARENE * @@ -74,13 +74,13 @@ static int descend_children(struct device * dev, void * data) } /** - * for_each_padev - Iterate over all devices in the tree - * @fn: Function to call for each device. - * @data: Data to pass to the called function. + * for_each_padev - Iterate over all devices in the tree + * @fn: Function to call for each device. + * @data: Data to pass to the called function. * - * This performs a depth-first traversal of the tree, calling the - * function passed for each node. It calls the function for parents - * before children. + * This performs a depth-first traversal of the tree, calling the + * function passed for each node. It calls the function for parents + * before children. */ static int for_each_padev(int (*fn)(struct device *, void *), void * data) @@ -280,7 +280,7 @@ int __init machine_has_merced_bus(void) /** * find_pa_parent_type - Find a parent of a specific type - * @dev: The device to start searching from + * @padev: The device to start searching from * @type: The device type to search for. * * Walks up the device tree looking for a device of the specified type. @@ -344,8 +344,8 @@ static char *print_hwpath(struct hardware_path *path, char *output) /** * print_pa_hwpath - Returns hardware path for PA devices - * dev: The device to return the path for - * output: Pointer to a previously-allocated array to place the path in. + * @dev: The device to return the path for + * @output: Pointer to a previously-allocated array to place the path in. * * This function fills in the output array with a human-readable path * to a PA device. This string is compatible with that used by PDC, and @@ -379,8 +379,8 @@ EXPORT_SYMBOL(get_pci_node_path); /** * print_pci_hwpath - Returns hardware path for PCI devices - * dev: The device to return the path for - * output: Pointer to a previously-allocated array to place the path in. + * @dev: The device to return the path for + * @output: Pointer to a previously-allocated array to place the path in. * * This function fills in the output array with a human-readable path * to a PCI device. This string is compatible with that used by PDC, and @@ -415,7 +415,8 @@ static void setup_bus_id(struct parisc_device *padev) dev_set_name(&padev->dev, name); } -struct parisc_device * __init create_tree_node(char id, struct device *parent) +static struct parisc_device * __init create_tree_node(char id, + struct device *parent) { struct parisc_device *dev = kzalloc(sizeof(*dev), GFP_KERNEL); if (!dev) @@ -741,7 +742,7 @@ parse_tree_node(struct device *parent, int index, struct hardware_path *modpath) }; if (device_for_each_child(parent, &recurse_data, descend_children)) - /* nothing */; + { /* nothing */ }; return d.dev; } @@ -771,8 +772,8 @@ EXPORT_SYMBOL(hwpath_to_device); /** * device_to_hwpath - Populates the hwpath corresponding to the given device. - * @param dev the target device - * @param path pointer to a previously allocated hwpath struct to be filled in + * @dev: the target device + * @path: pointer to a previously allocated hwpath struct to be filled in */ void device_to_hwpath(struct device *dev, struct hardware_path *path) { diff --git a/arch/parisc/kernel/firmware.c b/arch/parisc/kernel/firmware.c index cc124d9f1f7f..6d1c781eb1db 100644 --- a/arch/parisc/kernel/firmware.c +++ b/arch/parisc/kernel/firmware.c @@ -134,7 +134,7 @@ static unsigned long f_extend(unsigned long address) /** * convert_to_wide - Convert the return buffer addresses into kernel addresses. - * @address: The return buffer from PDC. + * @addr: The return buffer from PDC. * * This function is used to convert the return buffer addresses retrieved from PDC * into kernel addresses when the PDC address size and kernel address size are @@ -160,6 +160,8 @@ void set_firmware_width_unlocked(void) ret = mem_pdc_call(PDC_MODEL, PDC_MODEL_CAPABILITIES, __pa(pdc_result), 0); + if (ret < 0) + return; convert_to_wide(pdc_result); if (pdc_result[0] != NARROW_FIRMWARE) parisc_narrow_firmware = 0; @@ -255,8 +257,8 @@ int __init pdc_instr(unsigned int *instr) /** * pdc_chassis_info - Return chassis information. - * @result: The return buffer. * @chassis_info: The memory buffer address. + * @led_info: The size of the memory buffer address. * @len: The size of the memory buffer address. * * An HVERSION dependent call for returning the chassis information. @@ -280,7 +282,8 @@ int __init pdc_chassis_info(struct pdc_chassis_info *chassis_info, void *led_inf /** * pdc_pat_chassis_send_log - Sends a PDC PAT CHASSIS log message. - * @retval: -1 on error, 0 on success. Other value are PDC errors + * @state: state of the machine + * @data: value for that state * * Must be correctly formatted or expect system crash */ @@ -303,7 +306,7 @@ int pdc_pat_chassis_send_log(unsigned long state, unsigned long data) /** * pdc_chassis_disp - Updates chassis code - * @retval: -1 on error, 0 on success + * @disp: value to show on display */ int pdc_chassis_disp(unsigned long disp) { @@ -318,8 +321,7 @@ int pdc_chassis_disp(unsigned long disp) } /** - * pdc_cpu_rendenzvous - Stop currently executing CPU - * @retval: -1 on error, 0 on success + * __pdc_cpu_rendezvous - Stop currently executing CPU and do not return. */ int __pdc_cpu_rendezvous(void) { @@ -347,7 +349,7 @@ void pdc_cpu_rendezvous_unlock(void) /** * pdc_pat_get_PDC_entrypoint - Get PDC entry point for current CPU - * @retval: -1 on error, 0 on success + * @pdc_entry: pointer to where the PDC entry point should be stored */ int pdc_pat_get_PDC_entrypoint(unsigned long *pdc_entry) { @@ -369,7 +371,7 @@ int pdc_pat_get_PDC_entrypoint(unsigned long *pdc_entry) } /** * pdc_chassis_warn - Fetches chassis warnings - * @retval: -1 on error, 0 on success + * @warn: The warning value to be shown */ int pdc_chassis_warn(unsigned long *warn) { @@ -521,6 +523,7 @@ int pdc_model_info(struct pdc_model *model) /** * pdc_model_sysmodel - Get the system model name. + * @os_id: The operating system ID asked for (an OS_ID_* value) * @name: A char array of at least 81 characters. * * Get system model name from PDC ROM (e.g. 9000/715 or 9000/778/B160L). @@ -549,7 +552,7 @@ int pdc_model_sysmodel(unsigned int os_id, char *name) /** * pdc_model_versions - Identify the version number of each processor. - * @cpu_id: The return buffer. + * @versions: The return buffer. * @id: The id of the processor to check. * * Returns the version number for each processor component. @@ -996,8 +999,8 @@ int pdc_pci_irt(unsigned long num_entries, unsigned long hpa, void *tbl) /** * pdc_pci_config_read - read PCI config space. - * @hpa token from PDC to indicate which PCI device - * @pci_addr configuration space address to read from + * @hpa: Token from PDC to indicate which PCI device + * @cfg_addr: Configuration space address to read from * * Read PCI Configuration space *before* linux PCI subsystem is running. */ @@ -1019,9 +1022,9 @@ unsigned int pdc_pci_config_read(void *hpa, unsigned long cfg_addr) /** * pdc_pci_config_write - read PCI config space. - * @hpa token from PDC to indicate which PCI device - * @pci_addr configuration space address to write - * @val value we want in the 32-bit register + * @hpa: Token from PDC to indicate which PCI device + * @cfg_addr: Configuration space address to write + * @val: Value we want in the 32-bit register * * Write PCI Configuration space *before* linux PCI subsystem is running. */ @@ -1389,17 +1392,25 @@ int pdc_iodc_getc(void) } int pdc_sti_call(unsigned long func, unsigned long flags, - unsigned long inptr, unsigned long outputr, - unsigned long glob_cfg) + unsigned long inptr, unsigned long outputr, + unsigned long glob_cfg, int do_call64) { - int retval; + int retval = 0; unsigned long irqflags; - spin_lock_irqsave(&pdc_lock, irqflags); - retval = real32_call(func, flags, inptr, outputr, glob_cfg); - spin_unlock_irqrestore(&pdc_lock, irqflags); + spin_lock_irqsave(&pdc_lock, irqflags); + if (IS_ENABLED(CONFIG_64BIT) && do_call64) { +#ifdef CONFIG_64BIT + retval = real64_call(func, flags, inptr, outputr, glob_cfg); +#else + WARN_ON(1); +#endif + } else { + retval = real32_call(func, flags, inptr, outputr, glob_cfg); + } + spin_unlock_irqrestore(&pdc_lock, irqflags); - return retval; + return retval; } EXPORT_SYMBOL(pdc_sti_call); @@ -1549,7 +1560,7 @@ int pdc_pat_get_irt(void *r_addr, unsigned long cell_num) /** * pdc_pat_pd_get_addr_map - Retrieve information about memory address ranges. - * @actlen: The return buffer. + * @actual_len: The return buffer. * @mem_addr: Pointer to the memory buffer. * @count: The number of bytes to read from the buffer. * @offset: The offset with respect to the beginning of the buffer. @@ -1572,7 +1583,7 @@ int pdc_pat_pd_get_addr_map(unsigned long *actual_len, void *mem_addr, } /** - * pdc_pat_pd_get_PDC_interface_revisions - Retrieve PDC interface revisions. + * pdc_pat_pd_get_pdc_revisions - Retrieve PDC interface revisions. * @legacy_rev: The legacy revision. * @pat_rev: The PAT revision. * @pdc_cap: The PDC capabilities. @@ -1627,7 +1638,7 @@ int pdc_pat_io_pci_cfg_read(unsigned long pci_addr, int pci_size, u32 *mem_addr) * pdc_pat_io_pci_cfg_write - Retrieve information about memory address ranges. * @pci_addr: PCI configuration space address for which the write request is being made. * @pci_size: Size of write in bytes. Valid values are 1, 2, and 4. - * @value: Pointer to 1, 2, or 4 byte value in low order end of argument to be + * @val: Pointer to 1, 2, or 4 byte value in low order end of argument to be * written to PCI Config space. * */ @@ -1645,7 +1656,7 @@ int pdc_pat_io_pci_cfg_write(unsigned long pci_addr, int pci_size, u32 val) } /** - * pdc_pat_mem_pdc_info - Retrieve information about page deallocation table + * pdc_pat_mem_pdt_info - Retrieve information about page deallocation table * @rinfo: memory pdt information * */ diff --git a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c index b05055f3ba4b..12c4d4104ade 100644 --- a/arch/parisc/kernel/irq.c +++ b/arch/parisc/kernel/irq.c @@ -24,9 +24,6 @@ #undef PARISC_IRQ_CR16_COUNTS -extern irqreturn_t timer_interrupt(int, void *); -extern irqreturn_t ipi_interrupt(int, void *); - #define EIEM_MASK(irq) (1UL<<(CPU_IRQ_MAX - irq)) /* Bits in EIEM correlate with cpu_irq_action[]. @@ -489,7 +486,7 @@ void do_softirq_own_stack(void) #endif /* CONFIG_IRQSTACKS */ /* ONLY called from entry.S:intr_extint() */ -void do_cpu_irq_mask(struct pt_regs *regs) +asmlinkage void do_cpu_irq_mask(struct pt_regs *regs) { struct pt_regs *old_regs; unsigned long eirr_val; diff --git a/arch/parisc/kernel/module.c b/arch/parisc/kernel/module.c index f6e38c4d3904..d214bbe3c2af 100644 --- a/arch/parisc/kernel/module.c +++ b/arch/parisc/kernel/module.c @@ -845,7 +845,7 @@ int module_finalize(const Elf_Ehdr *hdr, const char *strtab = NULL; const Elf_Shdr *s; char *secstrings; - int symindex = -1; + int symindex __maybe_unused = -1; Elf_Sym *newptr, *oldptr; Elf_Shdr *symhdr = NULL; #ifdef DEBUG diff --git a/arch/parisc/kernel/pci-dma.c b/arch/parisc/kernel/pci-dma.c index 415f12d5bab3..d818ece23b4a 100644 --- a/arch/parisc/kernel/pci-dma.c +++ b/arch/parisc/kernel/pci-dma.c @@ -245,7 +245,7 @@ static void unmap_uncached_pages(unsigned long vaddr, unsigned long size) PCXL_SEARCH_LOOP(idx, mask, size); \ } -unsigned long +static unsigned long pcxl_alloc_range(size_t size) { int res_idx; diff --git a/arch/parisc/kernel/pdc_chassis.c b/arch/parisc/kernel/pdc_chassis.c index da154406d368..0a9d7008ef2a 100644 --- a/arch/parisc/kernel/pdc_chassis.c +++ b/arch/parisc/kernel/pdc_chassis.c @@ -40,7 +40,7 @@ static unsigned int pdc_chassis_enabled __read_mostly = 1; /** * pdc_chassis_setup() - Enable/disable pdc_chassis code at boot time. - * @str configuration param: 0 to disable chassis log + * @str: configuration param: 0 to disable chassis log * @return 1 */ @@ -55,7 +55,6 @@ __setup("pdcchassis=", pdc_chassis_setup); /** * pdc_chassis_checkold() - Checks for old PDC_CHASSIS compatibility - * @pdc_chassis_old: 1 if old pdc chassis style * * Currently, only E class and A180 are known to work with this. * Inspired by Christoph Plattner @@ -80,6 +79,9 @@ static void __init pdc_chassis_checkold(void) /** * pdc_chassis_panic_event() - Called by the panic handler. + * @this: unused + * @event: unused + * @ptr: unused * * As soon as a panic occurs, we should inform the PDC. */ @@ -88,7 +90,7 @@ static int pdc_chassis_panic_event(struct notifier_block *this, unsigned long event, void *ptr) { pdc_chassis_send_status(PDC_CHASSIS_DIRECT_PANIC); - return NOTIFY_DONE; + return NOTIFY_DONE; } @@ -99,7 +101,10 @@ static struct notifier_block pdc_chassis_panic_block = { /** - * parisc_reboot_event() - Called by the reboot handler. + * pdc_chassis_reboot_event() - Called by the reboot handler. + * @this: unused + * @event: unused + * @ptr: unused * * As soon as a reboot occurs, we should inform the PDC. */ @@ -108,7 +113,7 @@ static int pdc_chassis_reboot_event(struct notifier_block *this, unsigned long event, void *ptr) { pdc_chassis_send_status(PDC_CHASSIS_DIRECT_SHUTDOWN); - return NOTIFY_DONE; + return NOTIFY_DONE; } @@ -148,7 +153,7 @@ void __init parisc_pdc_chassis_init(void) /** * pdc_chassis_send_status() - Sends a predefined message to the chassis, * and changes the front panel LEDs according to the new system state - * @retval: PDC call return value. + * @message: Type of message, one of PDC_CHASSIS_DIRECT_* values. * * Only machines with 64 bits PDC PAT and those reported in * pdc_chassis_checkold() are supported atm. diff --git a/arch/parisc/kernel/pdt.c b/arch/parisc/kernel/pdt.c index 80943a00e245..b651d020e0e5 100644 --- a/arch/parisc/kernel/pdt.c +++ b/arch/parisc/kernel/pdt.c @@ -23,6 +23,7 @@ #include #include #include +#include enum pdt_access_type { PDT_NONE, diff --git a/arch/parisc/kernel/perf.c b/arch/parisc/kernel/perf.c index d46b6709ec56..90b04d8af212 100644 --- a/arch/parisc/kernel/perf.c +++ b/arch/parisc/kernel/perf.c @@ -288,7 +288,7 @@ static ssize_t perf_read(struct file *file, char __user *buf, size_t cnt, loff_t static ssize_t perf_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { - size_t image_size; + size_t image_size __maybe_unused; uint32_t image_type; uint32_t interface_type; uint32_t test; diff --git a/arch/parisc/kernel/processor.c b/arch/parisc/kernel/processor.c index ba07e760d3c7..00b0df97afb1 100644 --- a/arch/parisc/kernel/processor.c +++ b/arch/parisc/kernel/processor.c @@ -58,7 +58,7 @@ DEFINE_PER_CPU(struct cpuinfo_parisc, cpu_data); */ /** - * init_cpu_profiler - enable/setup per cpu profiling hooks. + * init_percpu_prof - enable/setup per cpu profiling hooks. * @cpunum: The processor instance. * * FIXME: doesn't do much yet... diff --git a/arch/parisc/kernel/setup.c b/arch/parisc/kernel/setup.c index 0797db617962..573f8303e2b0 100644 --- a/arch/parisc/kernel/setup.c +++ b/arch/parisc/kernel/setup.c @@ -45,7 +45,7 @@ struct proc_dir_entry * proc_runway_root __read_mostly = NULL; struct proc_dir_entry * proc_gsc_root __read_mostly = NULL; struct proc_dir_entry * proc_mckinley_root __read_mostly = NULL; -void __init setup_cmdline(char **cmdline_p) +static void __init setup_cmdline(char **cmdline_p) { extern unsigned int boot_args[]; char *p; @@ -86,7 +86,7 @@ void __init setup_cmdline(char **cmdline_p) } #ifdef CONFIG_PA11 -void __init dma_ops_init(void) +static void __init dma_ops_init(void) { switch (boot_cpu_data.cpu_type) { case pcx: @@ -106,8 +106,6 @@ void __init dma_ops_init(void) } #endif -extern void collect_boot_cpu_data(void); - void __init setup_arch(char **cmdline_p) { #ifdef CONFIG_64BIT @@ -167,10 +165,7 @@ void __init setup_arch(char **cmdline_p) /* * Display CPU info for all CPUs. - * for parisc this is in processor.c */ -extern int show_cpuinfo (struct seq_file *m, void *v); - static void * c_start (struct seq_file *m, loff_t *pos) { @@ -295,16 +290,6 @@ static int __init parisc_init_resources(void) return 0; } -extern void gsc_init(void); -extern void processor_init(void); -extern void ccio_init(void); -extern void hppb_init(void); -extern void dino_init(void); -extern void iosapic_init(void); -extern void lba_init(void); -extern void sba_init(void); -extern void eisa_init(void); - static int __init parisc_init(void) { u32 osid = (OS_ID_LINUX << 16); @@ -370,7 +355,7 @@ static int __init parisc_init(void) gsc_init(); #endif #ifdef CONFIG_EISA - eisa_init(); + parisc_eisa_init(); #endif #if defined(CONFIG_HPPB) @@ -391,8 +376,6 @@ arch_initcall(parisc_init); void __init start_parisc(void) { - extern void early_trap_init(void); - int ret, cpunum; struct pdc_coproc_cfg coproc_cfg; diff --git a/arch/parisc/kernel/signal.c b/arch/parisc/kernel/signal.c index 8bc0ddaa6219..f886ff0c75df 100644 --- a/arch/parisc/kernel/signal.c +++ b/arch/parisc/kernel/signal.c @@ -73,7 +73,7 @@ restore_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs) return err; } -void +asmlinkage void sys_rt_sigreturn(struct pt_regs *regs, int in_syscall) { struct rt_sigframe __user *frame; @@ -176,7 +176,7 @@ get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size) } static long -setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, int in_syscall) +setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, long in_syscall) { unsigned long flags = 0; @@ -211,7 +211,7 @@ setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, int in_sysc static long setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs, - int in_syscall) + long in_syscall) { struct rt_sigframe __user *frame; unsigned long rp, usp; @@ -380,7 +380,7 @@ setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs, */ static void -handle_signal(struct ksignal *ksig, struct pt_regs *regs, int in_syscall) +handle_signal(struct ksignal *ksig, struct pt_regs *regs, long in_syscall) { int ret; sigset_t *oldset = sigmask_to_save(); @@ -578,7 +578,7 @@ static void do_signal(struct pt_regs *regs, long in_syscall) restore_saved_sigmask(); } -void do_notify_resume(struct pt_regs *regs, long in_syscall) +asmlinkage void do_notify_resume(struct pt_regs *regs, long in_syscall) { if (test_thread_flag(TIF_SIGPENDING) || test_thread_flag(TIF_NOTIFY_SIGNAL)) diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c index 39acccabf2ed..9915062d5243 100644 --- a/arch/parisc/kernel/sys_parisc.c +++ b/arch/parisc/kernel/sys_parisc.c @@ -24,6 +24,7 @@ #include #include #include +#include /* * Construct an artificial page offset for the mapping based on the physical @@ -339,7 +340,7 @@ asmlinkage long parisc_fallocate(int fd, int mode, u32 offhi, u32 offlo, ((u64)lenhi << 32) | lenlo); } -long parisc_personality(unsigned long personality) +asmlinkage long parisc_personality(unsigned long personality) { long err; diff --git a/arch/parisc/kernel/syscalls/syscall.tbl b/arch/parisc/kernel/syscalls/syscall.tbl index 3c71fad78318..a0a9145b6dd4 100644 --- a/arch/parisc/kernel/syscalls/syscall.tbl +++ b/arch/parisc/kernel/syscalls/syscall.tbl @@ -400,6 +400,7 @@ 353 common pkey_free sys_pkey_free 354 common rseq sys_rseq 355 common kexec_file_load sys_kexec_file_load sys_kexec_file_load +356 common cacheflush sys_cacheflush # up to 402 is unassigned and reserved for arch specific syscalls 403 32 clock_gettime64 sys_clock_gettime sys_clock_gettime 404 32 clock_settime64 sys_clock_settime sys_clock_settime diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c index 304eebd1c83e..3b97944c7291 100644 --- a/arch/parisc/kernel/traps.c +++ b/arch/parisc/kernel/traps.c @@ -338,7 +338,7 @@ static void default_trap(int code, struct pt_regs *regs) void (*cpu_lpmc) (int code, struct pt_regs *regs) __read_mostly = default_trap; -void transfer_pim_to_trap_frame(struct pt_regs *regs) +static void transfer_pim_to_trap_frame(struct pt_regs *regs) { register int i; extern unsigned int hpmc_pim_data[]; @@ -800,14 +800,13 @@ void notrace handle_interruption(int code, struct pt_regs *regs) } -void __init initialize_ivt(const void *iva) +static void __init initialize_ivt(const void *iva) { extern const u32 os_hpmc[]; int i; u32 check = 0; u32 *ivap; - u32 *hpmcp; u32 instr; if (strcmp((const char *)iva, "cows can fly")) @@ -840,8 +839,6 @@ void __init initialize_ivt(const void *iva) /* Setup IVA and compute checksum for HPMC handler */ ivap[6] = (u32)__pa(os_hpmc); - hpmcp = (u32 *)os_hpmc; - for (i=0; i<8; i++) check += ivap[i]; diff --git a/arch/parisc/kernel/unaligned.c b/arch/parisc/kernel/unaligned.c index e8a4d77cff53..033b9e50b44a 100644 --- a/arch/parisc/kernel/unaligned.c +++ b/arch/parisc/kernel/unaligned.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include diff --git a/arch/parisc/kernel/unwind.c b/arch/parisc/kernel/unwind.c index 42acc3b52017..043184ce3843 100644 --- a/arch/parisc/kernel/unwind.c +++ b/arch/parisc/kernel/unwind.c @@ -24,12 +24,13 @@ #include #include #include +#include /* #define DEBUG 1 */ #ifdef DEBUG #define dbg(x...) pr_debug(x) #else -#define dbg(x...) +#define dbg(x...) do { } while (0) #endif #define KERNEL_START (KERNEL_BINARY_TEXT_START) @@ -179,7 +180,7 @@ void unwind_table_remove(struct unwind_table *table) /* Called from setup_arch to import the kernel unwind info */ int __init unwind_init(void) { - long start, stop; + long start __maybe_unused, stop __maybe_unused; register unsigned long gp __asm__ ("r27"); start = (long)&__start___unwind[0]; diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c index b0c43f3b0a5f..406c52fe23d5 100644 --- a/arch/parisc/mm/init.c +++ b/arch/parisc/mm/init.c @@ -626,12 +626,10 @@ static void __init pagetable_init(void) for (range = 0; range < npmem_ranges; range++) { unsigned long start_paddr; - unsigned long end_paddr; unsigned long size; start_paddr = pmem_ranges[range].start_pfn << PAGE_SHIFT; size = pmem_ranges[range].pages << PAGE_SHIFT; - end_paddr = start_paddr + size; map_pages((unsigned long)__va(start_paddr), start_paddr, size, PAGE_KERNEL, 0); diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c index 232acf418cfb..77f7ac3668cb 100644 --- a/arch/x86/platform/efi/efi_64.c +++ b/arch/x86/platform/efi/efi_64.c @@ -853,9 +853,9 @@ efi_set_virtual_address_map(unsigned long memory_map_size, /* Disable interrupts around EFI calls: */ local_irq_save(flags); - status = efi_call(efi.runtime->set_virtual_address_map, - memory_map_size, descriptor_size, - descriptor_version, virtual_map); + status = arch_efi_call_virt(efi.runtime, set_virtual_address_map, + memory_map_size, descriptor_size, + descriptor_version, virtual_map); local_irq_restore(flags); efi_fpu_end(); diff --git a/drivers/fpga/intel-m10-bmc-sec-update.c b/drivers/fpga/intel-m10-bmc-sec-update.c index d7e2f9f461bc..31af2e08c825 100644 --- a/drivers/fpga/intel-m10-bmc-sec-update.c +++ b/drivers/fpga/intel-m10-bmc-sec-update.c @@ -376,12 +376,11 @@ static enum fw_upload_err rsu_update_init(struct m10bmc_sec *sec) u32 doorbell_reg, progress, status; int ret, err; - ret = regmap_update_bits(sec->m10bmc->regmap, - csr_map->base + csr_map->doorbell, - DRBL_RSU_REQUEST | DRBL_HOST_STATUS, - DRBL_RSU_REQUEST | - FIELD_PREP(DRBL_HOST_STATUS, - HOST_STATUS_IDLE)); + ret = m10bmc_sys_update_bits(sec->m10bmc, csr_map->doorbell, + DRBL_RSU_REQUEST | DRBL_HOST_STATUS, + DRBL_RSU_REQUEST | + FIELD_PREP(DRBL_HOST_STATUS, + HOST_STATUS_IDLE)); if (ret) return FW_UPLOAD_ERR_RW_ERROR; @@ -450,11 +449,10 @@ static enum fw_upload_err rsu_send_data(struct m10bmc_sec *sec) u32 doorbell_reg, status; int ret; - ret = regmap_update_bits(sec->m10bmc->regmap, - csr_map->base + csr_map->doorbell, - DRBL_HOST_STATUS, - FIELD_PREP(DRBL_HOST_STATUS, - HOST_STATUS_WRITE_DONE)); + ret = m10bmc_sys_update_bits(sec->m10bmc, csr_map->doorbell, + DRBL_HOST_STATUS, + FIELD_PREP(DRBL_HOST_STATUS, + HOST_STATUS_WRITE_DONE)); if (ret) return FW_UPLOAD_ERR_RW_ERROR; @@ -517,11 +515,10 @@ static enum fw_upload_err rsu_cancel(struct m10bmc_sec *sec) if (rsu_prog(doorbell) != RSU_PROG_READY) return FW_UPLOAD_ERR_BUSY; - ret = regmap_update_bits(sec->m10bmc->regmap, - csr_map->base + csr_map->doorbell, - DRBL_HOST_STATUS, - FIELD_PREP(DRBL_HOST_STATUS, - HOST_STATUS_ABORT_RSU)); + ret = m10bmc_sys_update_bits(sec->m10bmc, csr_map->doorbell, + DRBL_HOST_STATUS, + FIELD_PREP(DRBL_HOST_STATUS, + HOST_STATUS_ABORT_RSU)); if (ret) return FW_UPLOAD_ERR_RW_ERROR; @@ -547,21 +544,28 @@ static enum fw_upload_err m10bmc_sec_prepare(struct fw_upload *fwl, if (ret != FW_UPLOAD_ERR_NONE) goto unlock_flash; + m10bmc_fw_state_set(sec->m10bmc, M10BMC_FW_STATE_SEC_UPDATE_PREPARE); + ret = rsu_update_init(sec); if (ret != FW_UPLOAD_ERR_NONE) - goto unlock_flash; + goto fw_state_exit; ret = rsu_prog_ready(sec); if (ret != FW_UPLOAD_ERR_NONE) - goto unlock_flash; + goto fw_state_exit; if (sec->cancel_request) { ret = rsu_cancel(sec); - goto unlock_flash; + goto fw_state_exit; } + m10bmc_fw_state_set(sec->m10bmc, M10BMC_FW_STATE_SEC_UPDATE_WRITE); + return FW_UPLOAD_ERR_NONE; +fw_state_exit: + m10bmc_fw_state_set(sec->m10bmc, M10BMC_FW_STATE_NORMAL); + unlock_flash: if (sec->m10bmc->flash_bulk_ops) sec->m10bmc->flash_bulk_ops->unlock_write(sec->m10bmc); @@ -610,6 +614,8 @@ static enum fw_upload_err m10bmc_sec_poll_complete(struct fw_upload *fwl) if (sec->cancel_request) return rsu_cancel(sec); + m10bmc_fw_state_set(sec->m10bmc, M10BMC_FW_STATE_SEC_UPDATE_PROGRAM); + result = rsu_send_data(sec); if (result != FW_UPLOAD_ERR_NONE) return result; @@ -653,6 +659,8 @@ static void m10bmc_sec_cleanup(struct fw_upload *fwl) (void)rsu_cancel(sec); + m10bmc_fw_state_set(sec->m10bmc, M10BMC_FW_STATE_NORMAL); + if (sec->m10bmc->flash_bulk_ops) sec->m10bmc->flash_bulk_ops->unlock_write(sec->m10bmc); } @@ -764,3 +772,4 @@ module_platform_driver(intel_m10bmc_sec_driver); MODULE_AUTHOR("Intel Corporation"); MODULE_DESCRIPTION("Intel MAX10 BMC Secure Update"); MODULE_LICENSE("GPL"); +MODULE_IMPORT_NS(INTEL_M10_BMC_CORE); diff --git a/drivers/hwmon/intel-m10-bmc-hwmon.c b/drivers/hwmon/intel-m10-bmc-hwmon.c index 6512f4bec79a..6500ca548f9c 100644 --- a/drivers/hwmon/intel-m10-bmc-hwmon.c +++ b/drivers/hwmon/intel-m10-bmc-hwmon.c @@ -794,3 +794,4 @@ MODULE_DEVICE_TABLE(platform, intel_m10bmc_hwmon_ids); MODULE_AUTHOR("Intel Corporation"); MODULE_DESCRIPTION("Intel MAX 10 BMC hardware monitor"); MODULE_LICENSE("GPL"); +MODULE_IMPORT_NS(INTEL_M10_BMC_CORE); diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 87600b4aacb3..9cfe8fc509d7 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -157,7 +157,7 @@ config I2C_I801 Emmitsburg (PCH) Alder Lake (PCH) Raptor Lake (PCH) - Meteor Lake (SOC) + Meteor Lake (SOC and PCH) This driver can also be built as a module. If so, the module will be called i2c-i801. @@ -1025,7 +1025,7 @@ config I2C_RZV2M depends on ARCH_RENESAS || COMPILE_TEST help If you say yes to this option, support will be included for the - Renesas RZ/V2M I2C interface. + Renesas RZ/V2M I2C interface. This driver can also be built as a module. If so, the module will be called i2c-rzv2m. diff --git a/drivers/i2c/busses/i2c-altera.c b/drivers/i2c/busses/i2c-altera.c index 50e7f3f670b6..252fbd175fb1 100644 --- a/drivers/i2c/busses/i2c-altera.c +++ b/drivers/i2c/busses/i2c-altera.c @@ -465,14 +465,12 @@ static int altr_i2c_probe(struct platform_device *pdev) return 0; } -static int altr_i2c_remove(struct platform_device *pdev) +static void altr_i2c_remove(struct platform_device *pdev) { struct altr_i2c_dev *idev = platform_get_drvdata(pdev); clk_disable_unprepare(idev->i2c_clk); i2c_del_adapter(&idev->adapter); - - return 0; } /* Match table for of_platform binding */ @@ -484,7 +482,7 @@ MODULE_DEVICE_TABLE(of, altr_i2c_of_match); static struct platform_driver altr_i2c_driver = { .probe = altr_i2c_probe, - .remove = altr_i2c_remove, + .remove_new = altr_i2c_remove, .driver = { .name = "altera-i2c", .of_match_table = altr_i2c_of_match, diff --git a/drivers/i2c/busses/i2c-amd-mp2-plat.c b/drivers/i2c/busses/i2c-amd-mp2-plat.c index 423fe0c8a471..112fe2bc5662 100644 --- a/drivers/i2c/busses/i2c-amd-mp2-plat.c +++ b/drivers/i2c/busses/i2c-amd-mp2-plat.c @@ -322,7 +322,7 @@ static int i2c_amd_probe(struct platform_device *pdev) return ret; } -static int i2c_amd_remove(struct platform_device *pdev) +static void i2c_amd_remove(struct platform_device *pdev) { struct amd_i2c_dev *i2c_dev = platform_get_drvdata(pdev); struct amd_i2c_common *i2c_common = &i2c_dev->common; @@ -336,7 +336,6 @@ static int i2c_amd_remove(struct platform_device *pdev) i2c_unlock_bus(&i2c_dev->adap, I2C_LOCK_ROOT_ADAPTER); i2c_del_adapter(&i2c_dev->adap); - return 0; } static const struct acpi_device_id i2c_amd_acpi_match[] = { @@ -347,7 +346,7 @@ MODULE_DEVICE_TABLE(acpi, i2c_amd_acpi_match); static struct platform_driver i2c_amd_plat_driver = { .probe = i2c_amd_probe, - .remove = i2c_amd_remove, + .remove_new = i2c_amd_remove, .driver = { .name = "i2c_amd_mp2", .acpi_match_table = ACPI_PTR(i2c_amd_acpi_match), diff --git a/drivers/i2c/busses/i2c-aspeed.c b/drivers/i2c/busses/i2c-aspeed.c index d3c99c5b3247..2e5acfeb76c8 100644 --- a/drivers/i2c/busses/i2c-aspeed.c +++ b/drivers/i2c/busses/i2c-aspeed.c @@ -1061,7 +1061,7 @@ static int aspeed_i2c_probe_bus(struct platform_device *pdev) return 0; } -static int aspeed_i2c_remove_bus(struct platform_device *pdev) +static void aspeed_i2c_remove_bus(struct platform_device *pdev) { struct aspeed_i2c_bus *bus = platform_get_drvdata(pdev); unsigned long flags; @@ -1077,13 +1077,11 @@ static int aspeed_i2c_remove_bus(struct platform_device *pdev) reset_control_assert(bus->rst); i2c_del_adapter(&bus->adap); - - return 0; } static struct platform_driver aspeed_i2c_bus_driver = { .probe = aspeed_i2c_probe_bus, - .remove = aspeed_i2c_remove_bus, + .remove_new = aspeed_i2c_remove_bus, .driver = { .name = "aspeed-i2c-bus", .of_match_table = aspeed_i2c_bus_of_table, diff --git a/drivers/i2c/busses/i2c-at91-core.c b/drivers/i2c/busses/i2c-at91-core.c index 2df9df585131..05ad3bc3578a 100644 --- a/drivers/i2c/busses/i2c-at91-core.c +++ b/drivers/i2c/busses/i2c-at91-core.c @@ -273,7 +273,7 @@ static int at91_twi_probe(struct platform_device *pdev) return 0; } -static int at91_twi_remove(struct platform_device *pdev) +static void at91_twi_remove(struct platform_device *pdev) { struct at91_twi_dev *dev = platform_get_drvdata(pdev); @@ -282,8 +282,6 @@ static int at91_twi_remove(struct platform_device *pdev) pm_runtime_disable(dev->dev); pm_runtime_set_suspended(dev->dev); - - return 0; } static int __maybe_unused at91_twi_runtime_suspend(struct device *dev) @@ -342,7 +340,7 @@ static const struct dev_pm_ops __maybe_unused at91_twi_pm = { static struct platform_driver at91_twi_driver = { .probe = at91_twi_probe, - .remove = at91_twi_remove, + .remove_new = at91_twi_remove, .id_table = at91_twi_devtypes, .driver = { .name = "at91_i2c", diff --git a/drivers/i2c/busses/i2c-au1550.c b/drivers/i2c/busses/i2c-au1550.c index 7b42d35b1294..e66c12ecf270 100644 --- a/drivers/i2c/busses/i2c-au1550.c +++ b/drivers/i2c/busses/i2c-au1550.c @@ -334,13 +334,12 @@ i2c_au1550_probe(struct platform_device *pdev) return 0; } -static int i2c_au1550_remove(struct platform_device *pdev) +static void i2c_au1550_remove(struct platform_device *pdev) { struct i2c_au1550_data *priv = platform_get_drvdata(pdev); i2c_del_adapter(&priv->adap); i2c_au1550_disable(priv); - return 0; } #ifdef CONFIG_PM @@ -379,7 +378,7 @@ static struct platform_driver au1xpsc_smbus_driver = { .pm = AU1XPSC_SMBUS_PMOPS, }, .probe = i2c_au1550_probe, - .remove = i2c_au1550_remove, + .remove_new = i2c_au1550_remove, }; module_platform_driver(au1xpsc_smbus_driver); diff --git a/drivers/i2c/busses/i2c-axxia.c b/drivers/i2c/busses/i2c-axxia.c index c1c74ce08407..d7f1e98777ac 100644 --- a/drivers/i2c/busses/i2c-axxia.c +++ b/drivers/i2c/busses/i2c-axxia.c @@ -804,14 +804,12 @@ error_disable_clk: return ret; } -static int axxia_i2c_remove(struct platform_device *pdev) +static void axxia_i2c_remove(struct platform_device *pdev) { struct axxia_i2c_dev *idev = platform_get_drvdata(pdev); clk_disable_unprepare(idev->i2c_clk); i2c_del_adapter(&idev->adapter); - - return 0; } /* Match table for of_platform binding */ @@ -824,7 +822,7 @@ MODULE_DEVICE_TABLE(of, axxia_i2c_of_match); static struct platform_driver axxia_i2c_driver = { .probe = axxia_i2c_probe, - .remove = axxia_i2c_remove, + .remove_new = axxia_i2c_remove, .driver = { .name = "axxia-i2c", .of_match_table = axxia_i2c_of_match, diff --git a/drivers/i2c/busses/i2c-bcm-iproc.c b/drivers/i2c/busses/i2c-bcm-iproc.c index 85d8a6b04885..2d8342fdc25d 100644 --- a/drivers/i2c/busses/i2c-bcm-iproc.c +++ b/drivers/i2c/busses/i2c-bcm-iproc.c @@ -1107,7 +1107,7 @@ static int bcm_iproc_i2c_probe(struct platform_device *pdev) return i2c_add_adapter(adap); } -static int bcm_iproc_i2c_remove(struct platform_device *pdev) +static void bcm_iproc_i2c_remove(struct platform_device *pdev) { struct bcm_iproc_i2c_dev *iproc_i2c = platform_get_drvdata(pdev); @@ -1123,8 +1123,6 @@ static int bcm_iproc_i2c_remove(struct platform_device *pdev) i2c_del_adapter(&iproc_i2c->adapter); bcm_iproc_i2c_enable_disable(iproc_i2c, false); - - return 0; } #ifdef CONFIG_PM_SLEEP @@ -1260,7 +1258,7 @@ static struct platform_driver bcm_iproc_i2c_driver = { .pm = BCM_IPROC_I2C_PM_OPS, }, .probe = bcm_iproc_i2c_probe, - .remove = bcm_iproc_i2c_remove, + .remove_new = bcm_iproc_i2c_remove, }; module_platform_driver(bcm_iproc_i2c_driver); diff --git a/drivers/i2c/busses/i2c-bcm-kona.c b/drivers/i2c/busses/i2c-bcm-kona.c index f3e369f0fd40..a57088ec2b06 100644 --- a/drivers/i2c/busses/i2c-bcm-kona.c +++ b/drivers/i2c/busses/i2c-bcm-kona.c @@ -859,13 +859,11 @@ probe_disable_clk: return rc; } -static int bcm_kona_i2c_remove(struct platform_device *pdev) +static void bcm_kona_i2c_remove(struct platform_device *pdev) { struct bcm_kona_i2c_dev *dev = platform_get_drvdata(pdev); i2c_del_adapter(&dev->adapter); - - return 0; } static const struct of_device_id bcm_kona_i2c_of_match[] = { @@ -880,7 +878,7 @@ static struct platform_driver bcm_kona_i2c_driver = { .of_match_table = bcm_kona_i2c_of_match, }, .probe = bcm_kona_i2c_probe, - .remove = bcm_kona_i2c_remove, + .remove_new = bcm_kona_i2c_remove, }; module_platform_driver(bcm_kona_i2c_driver); diff --git a/drivers/i2c/busses/i2c-bcm2835.c b/drivers/i2c/busses/i2c-bcm2835.c index 09a077b31bfe..8ce6d3f49551 100644 --- a/drivers/i2c/busses/i2c-bcm2835.c +++ b/drivers/i2c/busses/i2c-bcm2835.c @@ -503,7 +503,7 @@ err_put_exclusive_rate: return ret; } -static int bcm2835_i2c_remove(struct platform_device *pdev) +static void bcm2835_i2c_remove(struct platform_device *pdev) { struct bcm2835_i2c_dev *i2c_dev = platform_get_drvdata(pdev); @@ -512,8 +512,6 @@ static int bcm2835_i2c_remove(struct platform_device *pdev) free_irq(i2c_dev->irq, i2c_dev); i2c_del_adapter(&i2c_dev->adapter); - - return 0; } static const struct of_device_id bcm2835_i2c_of_match[] = { @@ -525,7 +523,7 @@ MODULE_DEVICE_TABLE(of, bcm2835_i2c_of_match); static struct platform_driver bcm2835_i2c_driver = { .probe = bcm2835_i2c_probe, - .remove = bcm2835_i2c_remove, + .remove_new = bcm2835_i2c_remove, .driver = { .name = "i2c-bcm2835", .of_match_table = bcm2835_i2c_of_match, diff --git a/drivers/i2c/busses/i2c-brcmstb.c b/drivers/i2c/busses/i2c-brcmstb.c index ef942714642a..cf92cbcb8c86 100644 --- a/drivers/i2c/busses/i2c-brcmstb.c +++ b/drivers/i2c/busses/i2c-brcmstb.c @@ -690,12 +690,11 @@ probe_errorout: return rc; } -static int brcmstb_i2c_remove(struct platform_device *pdev) +static void brcmstb_i2c_remove(struct platform_device *pdev) { struct brcmstb_i2c_dev *dev = platform_get_drvdata(pdev); i2c_del_adapter(&dev->adapter); - return 0; } #ifdef CONFIG_PM_SLEEP @@ -736,7 +735,7 @@ static struct platform_driver brcmstb_i2c_driver = { .pm = &brcmstb_i2c_pm, }, .probe = brcmstb_i2c_probe, - .remove = brcmstb_i2c_remove, + .remove_new = brcmstb_i2c_remove, }; module_platform_driver(brcmstb_i2c_driver); diff --git a/drivers/i2c/busses/i2c-cadence.c b/drivers/i2c/busses/i2c-cadence.c index 3a4edf7e75f9..9849f4502570 100644 --- a/drivers/i2c/busses/i2c-cadence.c +++ b/drivers/i2c/busses/i2c-cadence.c @@ -1415,7 +1415,7 @@ err_clk_dis: * * Return: 0 always */ -static int cdns_i2c_remove(struct platform_device *pdev) +static void cdns_i2c_remove(struct platform_device *pdev) { struct cdns_i2c *id = platform_get_drvdata(pdev); @@ -1427,8 +1427,6 @@ static int cdns_i2c_remove(struct platform_device *pdev) clk_notifier_unregister(id->clk, &id->clk_rate_change_nb); reset_control_assert(id->reset); clk_disable_unprepare(id->clk); - - return 0; } static struct platform_driver cdns_i2c_drv = { @@ -1438,7 +1436,7 @@ static struct platform_driver cdns_i2c_drv = { .pm = &cdns_i2c_dev_pm_ops, }, .probe = cdns_i2c_probe, - .remove = cdns_i2c_remove, + .remove_new = cdns_i2c_remove, }; module_platform_driver(cdns_i2c_drv); diff --git a/drivers/i2c/busses/i2c-cbus-gpio.c b/drivers/i2c/busses/i2c-cbus-gpio.c index d97c61eec95c..fdc1758a3275 100644 --- a/drivers/i2c/busses/i2c-cbus-gpio.c +++ b/drivers/i2c/busses/i2c-cbus-gpio.c @@ -200,13 +200,11 @@ static const struct i2c_algorithm cbus_i2c_algo = { .functionality = cbus_i2c_func, }; -static int cbus_i2c_remove(struct platform_device *pdev) +static void cbus_i2c_remove(struct platform_device *pdev) { struct i2c_adapter *adapter = platform_get_drvdata(pdev); i2c_del_adapter(adapter); - - return 0; } static int cbus_i2c_probe(struct platform_device *pdev) @@ -266,7 +264,7 @@ MODULE_DEVICE_TABLE(of, i2c_cbus_dt_ids); static struct platform_driver cbus_i2c_driver = { .probe = cbus_i2c_probe, - .remove = cbus_i2c_remove, + .remove_new = cbus_i2c_remove, .driver = { .name = "i2c-cbus-gpio", .of_match_table = of_match_ptr(i2c_cbus_dt_ids), diff --git a/drivers/i2c/busses/i2c-cht-wc.c b/drivers/i2c/busses/i2c-cht-wc.c index 2b2c3d090089..0209933b9a84 100644 --- a/drivers/i2c/busses/i2c-cht-wc.c +++ b/drivers/i2c/busses/i2c-cht-wc.c @@ -529,15 +529,13 @@ remove_irq_domain: return ret; } -static int cht_wc_i2c_adap_i2c_remove(struct platform_device *pdev) +static void cht_wc_i2c_adap_i2c_remove(struct platform_device *pdev) { struct cht_wc_i2c_adap *adap = platform_get_drvdata(pdev); i2c_unregister_device(adap->client); i2c_del_adapter(&adap->adapter); irq_domain_remove(adap->irq_domain); - - return 0; } static const struct platform_device_id cht_wc_i2c_adap_id_table[] = { @@ -548,7 +546,7 @@ MODULE_DEVICE_TABLE(platform, cht_wc_i2c_adap_id_table); static struct platform_driver cht_wc_i2c_adap_driver = { .probe = cht_wc_i2c_adap_i2c_probe, - .remove = cht_wc_i2c_adap_i2c_remove, + .remove_new = cht_wc_i2c_adap_i2c_remove, .driver = { .name = "cht_wcove_ext_chgr", }, diff --git a/drivers/i2c/busses/i2c-cpm.c b/drivers/i2c/busses/i2c-cpm.c index 24d584a1c9a7..732daf6a932b 100644 --- a/drivers/i2c/busses/i2c-cpm.c +++ b/drivers/i2c/busses/i2c-cpm.c @@ -676,7 +676,7 @@ out_free: return result; } -static int cpm_i2c_remove(struct platform_device *ofdev) +static void cpm_i2c_remove(struct platform_device *ofdev) { struct cpm_i2c *cpm = platform_get_drvdata(ofdev); @@ -685,8 +685,6 @@ static int cpm_i2c_remove(struct platform_device *ofdev) cpm_i2c_shutdown(cpm); kfree(cpm); - - return 0; } static const struct of_device_id cpm_i2c_match[] = { @@ -703,7 +701,7 @@ MODULE_DEVICE_TABLE(of, cpm_i2c_match); static struct platform_driver cpm_i2c_driver = { .probe = cpm_i2c_probe, - .remove = cpm_i2c_remove, + .remove_new = cpm_i2c_remove, .driver = { .name = "fsl-i2c-cpm", .of_match_table = cpm_i2c_match, diff --git a/drivers/i2c/busses/i2c-cros-ec-tunnel.c b/drivers/i2c/busses/i2c-cros-ec-tunnel.c index 8b3ff5bb14d8..2737fd8abd32 100644 --- a/drivers/i2c/busses/i2c-cros-ec-tunnel.c +++ b/drivers/i2c/busses/i2c-cros-ec-tunnel.c @@ -283,13 +283,11 @@ static int ec_i2c_probe(struct platform_device *pdev) return err; } -static int ec_i2c_remove(struct platform_device *dev) +static void ec_i2c_remove(struct platform_device *dev) { struct ec_i2c_device *bus = platform_get_drvdata(dev); i2c_del_adapter(&bus->adap); - - return 0; } static const struct of_device_id cros_ec_i2c_of_match[] __maybe_unused = { @@ -306,7 +304,7 @@ MODULE_DEVICE_TABLE(acpi, cros_ec_i2c_tunnel_acpi_id); static struct platform_driver ec_i2c_tunnel_driver = { .probe = ec_i2c_probe, - .remove = ec_i2c_remove, + .remove_new = ec_i2c_remove, .driver = { .name = "cros-ec-i2c-tunnel", .acpi_match_table = ACPI_PTR(cros_ec_i2c_tunnel_acpi_id), diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c index 9750310f2c96..71b60778c643 100644 --- a/drivers/i2c/busses/i2c-davinci.c +++ b/drivers/i2c/busses/i2c-davinci.c @@ -767,12 +767,9 @@ static int davinci_i2c_probe(struct platform_device *pdev) if (irq < 0) return dev_err_probe(&pdev->dev, irq, "can't get irq resource\n"); - dev = devm_kzalloc(&pdev->dev, sizeof(struct davinci_i2c_dev), - GFP_KERNEL); - if (!dev) { - dev_err(&pdev->dev, "Memory allocation failed\n"); + dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); + if (!dev) return -ENOMEM; - } init_completion(&dev->cmd_complete); @@ -885,7 +882,7 @@ err_pm: return r; } -static int davinci_i2c_remove(struct platform_device *pdev) +static void davinci_i2c_remove(struct platform_device *pdev) { struct davinci_i2c_dev *dev = platform_get_drvdata(pdev); int ret; @@ -894,17 +891,15 @@ static int davinci_i2c_remove(struct platform_device *pdev) i2c_del_adapter(&dev->adapter); - ret = pm_runtime_resume_and_get(&pdev->dev); + ret = pm_runtime_get_sync(&pdev->dev); if (ret < 0) - return ret; - - davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, 0); + dev_err(&pdev->dev, "Failed to resume device\n"); + else + davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, 0); pm_runtime_dont_use_autosuspend(dev->dev); pm_runtime_put_sync(dev->dev); pm_runtime_disable(dev->dev); - - return 0; } #ifdef CONFIG_PM @@ -940,12 +935,16 @@ static const struct dev_pm_ops davinci_i2c_pm = { #define davinci_i2c_pm_ops NULL #endif -/* work with hotplug and coldplug */ -MODULE_ALIAS("platform:i2c_davinci"); +static const struct platform_device_id davinci_i2c_driver_ids[] = { + { .name = "i2c_davinci", }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(platform, davinci_i2c_driver_ids); static struct platform_driver davinci_i2c_driver = { .probe = davinci_i2c_probe, - .remove = davinci_i2c_remove, + .remove_new = davinci_i2c_remove, + .id_table = davinci_i2c_driver_ids, .driver = { .name = "i2c_davinci", .pm = davinci_i2c_pm_ops, diff --git a/drivers/i2c/busses/i2c-designware-common.c b/drivers/i2c/busses/i2c-designware-common.c index 0dc6b1ce663f..cdd8c67d9129 100644 --- a/drivers/i2c/busses/i2c-designware-common.c +++ b/drivers/i2c/busses/i2c-designware-common.c @@ -575,6 +575,14 @@ int i2c_dw_set_fifo_size(struct dw_i2c_dev *dev) unsigned int param; int ret; + /* DW_IC_COMP_PARAM_1 not implement for IP issue */ + if ((dev->flags & MODEL_MASK) == MODEL_WANGXUN_SP) { + dev->tx_fifo_depth = TXGBE_TX_FIFO_DEPTH; + dev->rx_fifo_depth = TXGBE_RX_FIFO_DEPTH; + + return 0; + } + /* * Try to detect the FIFO depth if not set by interface driver, * the depth could be from 2 to 256 from HW spec. diff --git a/drivers/i2c/busses/i2c-designware-core.h b/drivers/i2c/busses/i2c-designware-core.h index bf23bfb51aea..cf4f684f5356 100644 --- a/drivers/i2c/busses/i2c-designware-core.h +++ b/drivers/i2c/busses/i2c-designware-core.h @@ -304,6 +304,7 @@ struct dw_i2c_dev { #define MODEL_MSCC_OCELOT BIT(8) #define MODEL_BAIKAL_BT1 BIT(9) #define MODEL_AMD_NAVI_GPU BIT(10) +#define MODEL_WANGXUN_SP BIT(11) #define MODEL_MASK GENMASK(11, 8) /* @@ -313,6 +314,9 @@ struct dw_i2c_dev { #define AMD_UCSI_INTR_REG 0x474 #define AMD_UCSI_INTR_EN 0xd +#define TXGBE_TX_FIFO_DEPTH 4 +#define TXGBE_RX_FIFO_DEPTH 0 + struct i2c_dw_semaphore_callbacks { int (*probe)(struct dw_i2c_dev *dev); void (*remove)(struct dw_i2c_dev *dev); diff --git a/drivers/i2c/busses/i2c-designware-master.c b/drivers/i2c/busses/i2c-designware-master.c index 55ea91a63382..3bfd7a2232db 100644 --- a/drivers/i2c/busses/i2c-designware-master.c +++ b/drivers/i2c/busses/i2c-designware-master.c @@ -354,6 +354,68 @@ static int amd_i2c_dw_xfer_quirk(struct i2c_adapter *adap, struct i2c_msg *msgs, return 0; } +static int i2c_dw_poll_tx_empty(struct dw_i2c_dev *dev) +{ + u32 val; + + return regmap_read_poll_timeout(dev->map, DW_IC_RAW_INTR_STAT, val, + val & DW_IC_INTR_TX_EMPTY, + 100, 1000); +} + +static int i2c_dw_poll_rx_full(struct dw_i2c_dev *dev) +{ + u32 val; + + return regmap_read_poll_timeout(dev->map, DW_IC_RAW_INTR_STAT, val, + val & DW_IC_INTR_RX_FULL, + 100, 1000); +} + +static int txgbe_i2c_dw_xfer_quirk(struct i2c_adapter *adap, struct i2c_msg *msgs, + int num_msgs) +{ + struct dw_i2c_dev *dev = i2c_get_adapdata(adap); + int msg_idx, buf_len, data_idx, ret; + unsigned int val, stop = 0; + u8 *buf; + + dev->msgs = msgs; + dev->msgs_num = num_msgs; + i2c_dw_xfer_init(dev); + regmap_write(dev->map, DW_IC_INTR_MASK, 0); + + for (msg_idx = 0; msg_idx < num_msgs; msg_idx++) { + buf = msgs[msg_idx].buf; + buf_len = msgs[msg_idx].len; + + for (data_idx = 0; data_idx < buf_len; data_idx++) { + if (msg_idx == num_msgs - 1 && data_idx == buf_len - 1) + stop |= BIT(9); + + if (msgs[msg_idx].flags & I2C_M_RD) { + regmap_write(dev->map, DW_IC_DATA_CMD, 0x100 | stop); + + ret = i2c_dw_poll_rx_full(dev); + if (ret) + return ret; + + regmap_read(dev->map, DW_IC_DATA_CMD, &val); + buf[data_idx] = val; + } else { + ret = i2c_dw_poll_tx_empty(dev); + if (ret) + return ret; + + regmap_write(dev->map, DW_IC_DATA_CMD, + buf[data_idx] | stop); + } + } + } + + return num_msgs; +} + /* * Initiate (and continue) low level master read/write transaction. * This function is only called from i2c_dw_isr, and pumping i2c_msg @@ -559,13 +621,19 @@ i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) pm_runtime_get_sync(dev->dev); /* - * Initiate I2C message transfer when AMD NAVI GPU card is enabled, + * Initiate I2C message transfer when polling mode is enabled, * As it is polling based transfer mechanism, which does not support * interrupt based functionalities of existing DesignWare driver. */ - if ((dev->flags & MODEL_MASK) == MODEL_AMD_NAVI_GPU) { + switch (dev->flags & MODEL_MASK) { + case MODEL_AMD_NAVI_GPU: ret = amd_i2c_dw_xfer_quirk(adap, msgs, num); goto done_nolock; + case MODEL_WANGXUN_SP: + ret = txgbe_i2c_dw_xfer_quirk(adap, msgs, num); + goto done_nolock; + default: + break; } reinit_completion(&dev->cmd_complete); @@ -848,7 +916,7 @@ static int i2c_dw_init_recovery_info(struct dw_i2c_dev *dev) return 0; } -static int amd_i2c_adap_quirk(struct dw_i2c_dev *dev) +static int i2c_dw_poll_adap_quirk(struct dw_i2c_dev *dev) { struct i2c_adapter *adap = &dev->adapter; int ret; @@ -862,6 +930,17 @@ static int amd_i2c_adap_quirk(struct dw_i2c_dev *dev) return ret; } +static bool i2c_dw_is_model_poll(struct dw_i2c_dev *dev) +{ + switch (dev->flags & MODEL_MASK) { + case MODEL_AMD_NAVI_GPU: + case MODEL_WANGXUN_SP: + return true; + default: + return false; + } +} + int i2c_dw_probe_master(struct dw_i2c_dev *dev) { struct i2c_adapter *adap = &dev->adapter; @@ -917,8 +996,8 @@ int i2c_dw_probe_master(struct dw_i2c_dev *dev) adap->dev.parent = dev->dev; i2c_set_adapdata(adap, dev); - if ((dev->flags & MODEL_MASK) == MODEL_AMD_NAVI_GPU) - return amd_i2c_adap_quirk(dev); + if (i2c_dw_is_model_poll(dev)) + return i2c_dw_poll_adap_quirk(dev); if (dev->flags & ACCESS_NO_IRQ_SUSPEND) { irq_flags = IRQF_NO_SUSPEND; diff --git a/drivers/i2c/busses/i2c-designware-pcidrv.c b/drivers/i2c/busses/i2c-designware-pcidrv.c index 782fe1ef3ca1..61d7a27aa070 100644 --- a/drivers/i2c/busses/i2c-designware-pcidrv.c +++ b/drivers/i2c/busses/i2c-designware-pcidrv.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -234,6 +235,16 @@ static const struct dev_pm_ops i2c_dw_pm_ops = { SET_RUNTIME_PM_OPS(i2c_dw_pci_runtime_suspend, i2c_dw_pci_runtime_resume, NULL) }; +static const struct property_entry dgpu_properties[] = { + /* USB-C doesn't power the system */ + PROPERTY_ENTRY_U8("scope", POWER_SUPPLY_SCOPE_DEVICE), + {} +}; + +static const struct software_node dgpu_node = { + .properties = dgpu_properties, +}; + static int i2c_dw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) { @@ -325,7 +336,7 @@ static int i2c_dw_pci_probe(struct pci_dev *pdev, } if ((dev->flags & MODEL_MASK) == MODEL_AMD_NAVI_GPU) { - dev->slave = i2c_new_ccgx_ucsi(&dev->adapter, dev->irq, NULL); + dev->slave = i2c_new_ccgx_ucsi(&dev->adapter, dev->irq, &dgpu_node); if (IS_ERR(dev->slave)) return dev_err_probe(dev->dev, PTR_ERR(dev->slave), "register UCSI failed\n"); diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c index 89ad88c54754..970c1c3b0402 100644 --- a/drivers/i2c/busses/i2c-designware-platdrv.c +++ b/drivers/i2c/busses/i2c-designware-platdrv.c @@ -168,6 +168,15 @@ static inline int dw_i2c_of_configure(struct platform_device *pdev) } #endif +static int txgbe_i2c_request_regs(struct dw_i2c_dev *dev) +{ + dev->map = dev_get_regmap(dev->dev->parent, NULL); + if (!dev->map) + return -ENODEV; + + return 0; +} + static void dw_i2c_plat_pm_cleanup(struct dw_i2c_dev *dev) { pm_runtime_disable(dev->dev); @@ -185,6 +194,9 @@ static int dw_i2c_plat_request_regs(struct dw_i2c_dev *dev) case MODEL_BAIKAL_BT1: ret = bt1_i2c_request_regs(dev); break; + case MODEL_WANGXUN_SP: + ret = txgbe_i2c_request_regs(dev); + break; default: dev->base = devm_platform_ioremap_resource(pdev, 0); ret = PTR_ERR_OR_ZERO(dev->base); @@ -277,6 +289,9 @@ static int dw_i2c_plat_probe(struct platform_device *pdev) return -ENOMEM; dev->flags = (uintptr_t)device_get_match_data(&pdev->dev); + if (device_property_present(&pdev->dev, "wx,i2c-snps-model")) + dev->flags = MODEL_WANGXUN_SP; + dev->dev = &pdev->dev; dev->irq = irq; platform_set_drvdata(pdev, dev); @@ -384,7 +399,7 @@ exit_reset: return ret; } -static int dw_i2c_plat_remove(struct platform_device *pdev) +static void dw_i2c_plat_remove(struct platform_device *pdev) { struct dw_i2c_dev *dev = platform_get_drvdata(pdev); @@ -401,8 +416,6 @@ static int dw_i2c_plat_remove(struct platform_device *pdev) i2c_dw_remove_lock_support(dev); reset_control_assert(dev->rst); - - return 0; } #ifdef CONFIG_PM_SLEEP @@ -481,7 +494,7 @@ MODULE_ALIAS("platform:i2c_designware"); static struct platform_driver dw_i2c_driver = { .probe = dw_i2c_plat_probe, - .remove = dw_i2c_plat_remove, + .remove_new = dw_i2c_plat_remove, .driver = { .name = "i2c_designware", .of_match_table = of_match_ptr(dw_i2c_of_match), diff --git a/drivers/i2c/busses/i2c-digicolor.c b/drivers/i2c/busses/i2c-digicolor.c index 50925d97fa42..3462f2bc0fa8 100644 --- a/drivers/i2c/busses/i2c-digicolor.c +++ b/drivers/i2c/busses/i2c-digicolor.c @@ -347,14 +347,12 @@ static int dc_i2c_probe(struct platform_device *pdev) return 0; } -static int dc_i2c_remove(struct platform_device *pdev) +static void dc_i2c_remove(struct platform_device *pdev) { struct dc_i2c *i2c = platform_get_drvdata(pdev); i2c_del_adapter(&i2c->adap); clk_disable_unprepare(i2c->clk); - - return 0; } static const struct of_device_id dc_i2c_match[] = { @@ -365,7 +363,7 @@ MODULE_DEVICE_TABLE(of, dc_i2c_match); static struct platform_driver dc_i2c_driver = { .probe = dc_i2c_probe, - .remove = dc_i2c_remove, + .remove_new = dc_i2c_remove, .driver = { .name = "digicolor-i2c", .of_match_table = dc_i2c_match, diff --git a/drivers/i2c/busses/i2c-dln2.c b/drivers/i2c/busses/i2c-dln2.c index 2a2089db71a5..4f02cc2fb567 100644 --- a/drivers/i2c/busses/i2c-dln2.c +++ b/drivers/i2c/busses/i2c-dln2.c @@ -236,20 +236,18 @@ out_disable: return ret; } -static int dln2_i2c_remove(struct platform_device *pdev) +static void dln2_i2c_remove(struct platform_device *pdev) { struct dln2_i2c *dln2 = platform_get_drvdata(pdev); i2c_del_adapter(&dln2->adapter); dln2_i2c_enable(dln2, false); - - return 0; } static struct platform_driver dln2_i2c_driver = { .driver.name = "dln2-i2c", .probe = dln2_i2c_probe, - .remove = dln2_i2c_remove, + .remove_new = dln2_i2c_remove, }; module_platform_driver(dln2_i2c_driver); diff --git a/drivers/i2c/busses/i2c-emev2.c b/drivers/i2c/busses/i2c-emev2.c index f2e537b137b2..4ba93cd91c0f 100644 --- a/drivers/i2c/busses/i2c-emev2.c +++ b/drivers/i2c/busses/i2c-emev2.c @@ -419,14 +419,12 @@ err_clk: return ret; } -static int em_i2c_remove(struct platform_device *dev) +static void em_i2c_remove(struct platform_device *dev) { struct em_i2c_device *priv = platform_get_drvdata(dev); i2c_del_adapter(&priv->adap); clk_disable_unprepare(priv->sclk); - - return 0; } static const struct of_device_id em_i2c_ids[] = { @@ -436,7 +434,7 @@ static const struct of_device_id em_i2c_ids[] = { static struct platform_driver em_i2c_driver = { .probe = em_i2c_probe, - .remove = em_i2c_remove, + .remove_new = em_i2c_remove, .driver = { .name = "em-i2c", .of_match_table = em_i2c_ids, diff --git a/drivers/i2c/busses/i2c-exynos5.c b/drivers/i2c/busses/i2c-exynos5.c index 4a6260d04db2..f378cd479e55 100644 --- a/drivers/i2c/busses/i2c-exynos5.c +++ b/drivers/i2c/busses/i2c-exynos5.c @@ -882,7 +882,7 @@ static int exynos5_i2c_probe(struct platform_device *pdev) return ret; } -static int exynos5_i2c_remove(struct platform_device *pdev) +static void exynos5_i2c_remove(struct platform_device *pdev) { struct exynos5_i2c *i2c = platform_get_drvdata(pdev); @@ -890,8 +890,6 @@ static int exynos5_i2c_remove(struct platform_device *pdev) clk_unprepare(i2c->clk); clk_unprepare(i2c->pclk); - - return 0; } #ifdef CONFIG_PM_SLEEP @@ -945,7 +943,7 @@ static const struct dev_pm_ops exynos5_i2c_dev_pm_ops = { static struct platform_driver exynos5_i2c_driver = { .probe = exynos5_i2c_probe, - .remove = exynos5_i2c_remove, + .remove_new = exynos5_i2c_remove, .driver = { .name = "exynos5-hsi2c", .pm = &exynos5_i2c_dev_pm_ops, diff --git a/drivers/i2c/busses/i2c-gpio.c b/drivers/i2c/busses/i2c-gpio.c index 1794c0399f22..e5a5b9e8bf2c 100644 --- a/drivers/i2c/busses/i2c-gpio.c +++ b/drivers/i2c/busses/i2c-gpio.c @@ -475,7 +475,7 @@ static int i2c_gpio_probe(struct platform_device *pdev) return 0; } -static int i2c_gpio_remove(struct platform_device *pdev) +static void i2c_gpio_remove(struct platform_device *pdev) { struct i2c_gpio_private_data *priv; struct i2c_adapter *adap; @@ -486,8 +486,6 @@ static int i2c_gpio_remove(struct platform_device *pdev) adap = &priv->adap; i2c_del_adapter(adap); - - return 0; } static const struct of_device_id i2c_gpio_dt_ids[] = { @@ -510,7 +508,7 @@ static struct platform_driver i2c_gpio_driver = { .acpi_match_table = i2c_gpio_acpi_match, }, .probe = i2c_gpio_probe, - .remove = i2c_gpio_remove, + .remove_new = i2c_gpio_remove, }; static int __init i2c_gpio_init(void) diff --git a/drivers/i2c/busses/i2c-gxp.c b/drivers/i2c/busses/i2c-gxp.c index 8ea3fb5e4c7f..70b0de07ed99 100644 --- a/drivers/i2c/busses/i2c-gxp.c +++ b/drivers/i2c/busses/i2c-gxp.c @@ -577,15 +577,13 @@ static int gxp_i2c_probe(struct platform_device *pdev) return 0; } -static int gxp_i2c_remove(struct platform_device *pdev) +static void gxp_i2c_remove(struct platform_device *pdev) { struct gxp_i2c_drvdata *drvdata = platform_get_drvdata(pdev); /* Disable interrupt */ regmap_update_bits(i2cg_map, GXP_I2CINTEN, BIT(drvdata->engine), 0); i2c_del_adapter(&drvdata->adapter); - - return 0; } static const struct of_device_id gxp_i2c_of_match[] = { @@ -596,7 +594,7 @@ MODULE_DEVICE_TABLE(of, gxp_i2c_of_match); static struct platform_driver gxp_i2c_driver = { .probe = gxp_i2c_probe, - .remove = gxp_i2c_remove, + .remove_new = gxp_i2c_remove, .driver = { .name = "gxp-i2c", .of_match_table = gxp_i2c_of_match, diff --git a/drivers/i2c/busses/i2c-highlander.c b/drivers/i2c/busses/i2c-highlander.c index 4374a8677271..7922bc917c33 100644 --- a/drivers/i2c/busses/i2c-highlander.c +++ b/drivers/i2c/busses/i2c-highlander.c @@ -435,7 +435,7 @@ err: return ret; } -static int highlander_i2c_remove(struct platform_device *pdev) +static void highlander_i2c_remove(struct platform_device *pdev) { struct highlander_i2c_dev *dev = platform_get_drvdata(pdev); @@ -446,8 +446,6 @@ static int highlander_i2c_remove(struct platform_device *pdev) iounmap(dev->base); kfree(dev); - - return 0; } static struct platform_driver highlander_i2c_driver = { @@ -456,7 +454,7 @@ static struct platform_driver highlander_i2c_driver = { }, .probe = highlander_i2c_probe, - .remove = highlander_i2c_remove, + .remove_new = highlander_i2c_remove, }; module_platform_driver(highlander_i2c_driver); diff --git a/drivers/i2c/busses/i2c-hix5hd2.c b/drivers/i2c/busses/i2c-hix5hd2.c index 0e34cbaca22d..784a5f56eb76 100644 --- a/drivers/i2c/busses/i2c-hix5hd2.c +++ b/drivers/i2c/busses/i2c-hix5hd2.c @@ -360,7 +360,11 @@ static int hix5hd2_i2c_xfer(struct i2c_adapter *adap, pm_runtime_get_sync(priv->dev); for (i = 0; i < num; i++, msgs++) { - stop = (i == num - 1); + if ((i == num - 1) || (msgs->flags & I2C_M_STOP)) + stop = 1; + else + stop = 0; + ret = hix5hd2_i2c_xfer_msg(priv, msgs, stop); if (ret < 0) goto out; @@ -416,12 +420,11 @@ static int hix5hd2_i2c_probe(struct platform_device *pdev) if (irq < 0) return irq; - priv->clk = devm_clk_get(&pdev->dev, NULL); + priv->clk = devm_clk_get_enabled(&pdev->dev, NULL); if (IS_ERR(priv->clk)) { - dev_err(&pdev->dev, "cannot get clock\n"); + dev_err(&pdev->dev, "cannot enable clock\n"); return PTR_ERR(priv->clk); } - clk_prepare_enable(priv->clk); strscpy(priv->adap.name, "hix5hd2-i2c", sizeof(priv->adap.name)); priv->dev = &pdev->dev; @@ -442,7 +445,7 @@ static int hix5hd2_i2c_probe(struct platform_device *pdev) IRQF_NO_SUSPEND, dev_name(&pdev->dev), priv); if (ret != 0) { dev_err(&pdev->dev, "cannot request HS-I2C IRQ %d\n", irq); - goto err_clk; + return ret; } pm_runtime_set_autosuspend_delay(priv->dev, MSEC_PER_SEC); @@ -459,21 +462,17 @@ static int hix5hd2_i2c_probe(struct platform_device *pdev) err_runtime: pm_runtime_disable(priv->dev); pm_runtime_set_suspended(priv->dev); -err_clk: - clk_disable_unprepare(priv->clk); + return ret; } -static int hix5hd2_i2c_remove(struct platform_device *pdev) +static void hix5hd2_i2c_remove(struct platform_device *pdev) { struct hix5hd2_i2c_priv *priv = platform_get_drvdata(pdev); i2c_del_adapter(&priv->adap); pm_runtime_disable(priv->dev); pm_runtime_set_suspended(priv->dev); - clk_disable_unprepare(priv->clk); - - return 0; } #ifdef CONFIG_PM @@ -511,7 +510,7 @@ MODULE_DEVICE_TABLE(of, hix5hd2_i2c_match); static struct platform_driver hix5hd2_i2c_driver = { .probe = hix5hd2_i2c_probe, - .remove = hix5hd2_i2c_remove, + .remove_new = hix5hd2_i2c_remove, .driver = { .name = "hix5hd2-i2c", .pm = &hix5hd2_i2c_pm_ops, diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index ac5326747c51..943b8e6d026d 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c @@ -77,6 +77,8 @@ * Alder Lake-M (PCH) 0x54a3 32 hard yes yes yes * Raptor Lake-S (PCH) 0x7a23 32 hard yes yes yes * Meteor Lake-P (SOC) 0x7e22 32 hard yes yes yes + * Meteor Lake SoC-S (SOC) 0xae22 32 hard yes yes yes + * Meteor Lake PCH-S (PCH) 0x7f23 32 hard yes yes yes * * Features supported by this driver: * Software PEC no @@ -233,6 +235,7 @@ #define PCI_DEVICE_ID_INTEL_RAPTOR_LAKE_S_SMBUS 0x7a23 #define PCI_DEVICE_ID_INTEL_ALDER_LAKE_S_SMBUS 0x7aa3 #define PCI_DEVICE_ID_INTEL_METEOR_LAKE_P_SMBUS 0x7e22 +#define PCI_DEVICE_ID_INTEL_METEOR_LAKE_PCH_S_SMBUS 0x7f23 #define PCI_DEVICE_ID_INTEL_LYNXPOINT_SMBUS 0x8c22 #define PCI_DEVICE_ID_INTEL_WILDCATPOINT_SMBUS 0x8ca2 #define PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS 0x8d22 @@ -250,6 +253,7 @@ #define PCI_DEVICE_ID_INTEL_KABYLAKE_PCH_H_SMBUS 0xa2a3 #define PCI_DEVICE_ID_INTEL_CANNONLAKE_H_SMBUS 0xa323 #define PCI_DEVICE_ID_INTEL_COMETLAKE_V_SMBUS 0xa3a3 +#define PCI_DEVICE_ID_INTEL_METEOR_LAKE_SOC_S_SMBUS 0xae22 struct i801_mux_config { char *gpio_chip; @@ -977,67 +981,69 @@ static const struct i2c_algorithm smbus_algorithm = { FEATURE_HOST_NOTIFY) static const struct pci_device_id i801_ids[] = { - { PCI_DEVICE_DATA(INTEL, 82801AA_3, 0) }, - { PCI_DEVICE_DATA(INTEL, 82801AB_3, 0) }, - { PCI_DEVICE_DATA(INTEL, 82801BA_2, 0) }, - { PCI_DEVICE_DATA(INTEL, 82801CA_3, FEATURE_HOST_NOTIFY) }, - { PCI_DEVICE_DATA(INTEL, 82801DB_3, FEATURES_ICH4) }, - { PCI_DEVICE_DATA(INTEL, 82801EB_3, FEATURES_ICH5) }, - { PCI_DEVICE_DATA(INTEL, ESB_4, FEATURES_ICH5) }, - { PCI_DEVICE_DATA(INTEL, ICH6_16, FEATURES_ICH5) }, - { PCI_DEVICE_DATA(INTEL, ICH7_17, FEATURES_ICH5) }, - { PCI_DEVICE_DATA(INTEL, ESB2_17, FEATURES_ICH5) }, - { PCI_DEVICE_DATA(INTEL, ICH8_5, FEATURES_ICH5) }, - { PCI_DEVICE_DATA(INTEL, ICH9_6, FEATURES_ICH5) }, - { PCI_DEVICE_DATA(INTEL, EP80579_1, FEATURES_ICH5) }, - { PCI_DEVICE_DATA(INTEL, ICH10_4, FEATURES_ICH5) }, - { PCI_DEVICE_DATA(INTEL, ICH10_5, FEATURES_ICH5) }, - { PCI_DEVICE_DATA(INTEL, 5_3400_SERIES_SMBUS, FEATURES_ICH5) }, - { PCI_DEVICE_DATA(INTEL, COUGARPOINT_SMBUS, FEATURES_ICH5) }, - { PCI_DEVICE_DATA(INTEL, PATSBURG_SMBUS, FEATURES_ICH5) }, - { PCI_DEVICE_DATA(INTEL, PATSBURG_SMBUS_IDF0, FEATURES_ICH5 | FEATURE_IDF) }, - { PCI_DEVICE_DATA(INTEL, PATSBURG_SMBUS_IDF1, FEATURES_ICH5 | FEATURE_IDF) }, - { PCI_DEVICE_DATA(INTEL, PATSBURG_SMBUS_IDF2, FEATURES_ICH5 | FEATURE_IDF) }, - { PCI_DEVICE_DATA(INTEL, DH89XXCC_SMBUS, FEATURES_ICH5) }, - { PCI_DEVICE_DATA(INTEL, PANTHERPOINT_SMBUS, FEATURES_ICH5) }, - { PCI_DEVICE_DATA(INTEL, LYNXPOINT_SMBUS, FEATURES_ICH5) }, - { PCI_DEVICE_DATA(INTEL, LYNXPOINT_LP_SMBUS, FEATURES_ICH5) }, - { PCI_DEVICE_DATA(INTEL, AVOTON_SMBUS, FEATURES_ICH5) }, - { PCI_DEVICE_DATA(INTEL, WELLSBURG_SMBUS, FEATURES_ICH5) }, - { PCI_DEVICE_DATA(INTEL, WELLSBURG_SMBUS_MS0, FEATURES_ICH5 | FEATURE_IDF) }, - { PCI_DEVICE_DATA(INTEL, WELLSBURG_SMBUS_MS1, FEATURES_ICH5 | FEATURE_IDF) }, - { PCI_DEVICE_DATA(INTEL, WELLSBURG_SMBUS_MS2, FEATURES_ICH5 | FEATURE_IDF) }, - { PCI_DEVICE_DATA(INTEL, COLETOCREEK_SMBUS, FEATURES_ICH5) }, - { PCI_DEVICE_DATA(INTEL, GEMINILAKE_SMBUS, FEATURES_ICH5) }, - { PCI_DEVICE_DATA(INTEL, WILDCATPOINT_SMBUS, FEATURES_ICH5) }, - { PCI_DEVICE_DATA(INTEL, WILDCATPOINT_LP_SMBUS, FEATURES_ICH5) }, - { PCI_DEVICE_DATA(INTEL, BAYTRAIL_SMBUS, FEATURES_ICH5) }, - { PCI_DEVICE_DATA(INTEL, BRASWELL_SMBUS, FEATURES_ICH5) }, - { PCI_DEVICE_DATA(INTEL, SUNRISEPOINT_H_SMBUS, FEATURES_ICH5 | FEATURE_TCO_SPT) }, - { PCI_DEVICE_DATA(INTEL, SUNRISEPOINT_LP_SMBUS, FEATURES_ICH5 | FEATURE_TCO_SPT) }, - { PCI_DEVICE_DATA(INTEL, CDF_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, - { PCI_DEVICE_DATA(INTEL, DNV_SMBUS, FEATURES_ICH5 | FEATURE_TCO_SPT) }, - { PCI_DEVICE_DATA(INTEL, EBG_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, - { PCI_DEVICE_DATA(INTEL, BROXTON_SMBUS, FEATURES_ICH5) }, - { PCI_DEVICE_DATA(INTEL, LEWISBURG_SMBUS, FEATURES_ICH5 | FEATURE_TCO_SPT) }, - { PCI_DEVICE_DATA(INTEL, LEWISBURG_SSKU_SMBUS, FEATURES_ICH5 | FEATURE_TCO_SPT) }, - { PCI_DEVICE_DATA(INTEL, KABYLAKE_PCH_H_SMBUS, FEATURES_ICH5 | FEATURE_TCO_SPT) }, - { PCI_DEVICE_DATA(INTEL, CANNONLAKE_H_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, - { PCI_DEVICE_DATA(INTEL, CANNONLAKE_LP_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, - { PCI_DEVICE_DATA(INTEL, ICELAKE_LP_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, - { PCI_DEVICE_DATA(INTEL, ICELAKE_N_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, - { PCI_DEVICE_DATA(INTEL, COMETLAKE_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, - { PCI_DEVICE_DATA(INTEL, COMETLAKE_H_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, - { PCI_DEVICE_DATA(INTEL, COMETLAKE_V_SMBUS, FEATURES_ICH5 | FEATURE_TCO_SPT) }, - { PCI_DEVICE_DATA(INTEL, ELKHART_LAKE_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, - { PCI_DEVICE_DATA(INTEL, TIGERLAKE_LP_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, - { PCI_DEVICE_DATA(INTEL, TIGERLAKE_H_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, - { PCI_DEVICE_DATA(INTEL, JASPER_LAKE_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, - { PCI_DEVICE_DATA(INTEL, ALDER_LAKE_S_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, - { PCI_DEVICE_DATA(INTEL, ALDER_LAKE_P_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, - { PCI_DEVICE_DATA(INTEL, ALDER_LAKE_M_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, - { PCI_DEVICE_DATA(INTEL, RAPTOR_LAKE_S_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, - { PCI_DEVICE_DATA(INTEL, METEOR_LAKE_P_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, + { PCI_DEVICE_DATA(INTEL, 82801AA_3, 0) }, + { PCI_DEVICE_DATA(INTEL, 82801AB_3, 0) }, + { PCI_DEVICE_DATA(INTEL, 82801BA_2, 0) }, + { PCI_DEVICE_DATA(INTEL, 82801CA_3, FEATURE_HOST_NOTIFY) }, + { PCI_DEVICE_DATA(INTEL, 82801DB_3, FEATURES_ICH4) }, + { PCI_DEVICE_DATA(INTEL, 82801EB_3, FEATURES_ICH5) }, + { PCI_DEVICE_DATA(INTEL, ESB_4, FEATURES_ICH5) }, + { PCI_DEVICE_DATA(INTEL, ICH6_16, FEATURES_ICH5) }, + { PCI_DEVICE_DATA(INTEL, ICH7_17, FEATURES_ICH5) }, + { PCI_DEVICE_DATA(INTEL, ESB2_17, FEATURES_ICH5) }, + { PCI_DEVICE_DATA(INTEL, ICH8_5, FEATURES_ICH5) }, + { PCI_DEVICE_DATA(INTEL, ICH9_6, FEATURES_ICH5) }, + { PCI_DEVICE_DATA(INTEL, EP80579_1, FEATURES_ICH5) }, + { PCI_DEVICE_DATA(INTEL, ICH10_4, FEATURES_ICH5) }, + { PCI_DEVICE_DATA(INTEL, ICH10_5, FEATURES_ICH5) }, + { PCI_DEVICE_DATA(INTEL, 5_3400_SERIES_SMBUS, FEATURES_ICH5) }, + { PCI_DEVICE_DATA(INTEL, COUGARPOINT_SMBUS, FEATURES_ICH5) }, + { PCI_DEVICE_DATA(INTEL, PATSBURG_SMBUS, FEATURES_ICH5) }, + { PCI_DEVICE_DATA(INTEL, PATSBURG_SMBUS_IDF0, FEATURES_ICH5 | FEATURE_IDF) }, + { PCI_DEVICE_DATA(INTEL, PATSBURG_SMBUS_IDF1, FEATURES_ICH5 | FEATURE_IDF) }, + { PCI_DEVICE_DATA(INTEL, PATSBURG_SMBUS_IDF2, FEATURES_ICH5 | FEATURE_IDF) }, + { PCI_DEVICE_DATA(INTEL, DH89XXCC_SMBUS, FEATURES_ICH5) }, + { PCI_DEVICE_DATA(INTEL, PANTHERPOINT_SMBUS, FEATURES_ICH5) }, + { PCI_DEVICE_DATA(INTEL, LYNXPOINT_SMBUS, FEATURES_ICH5) }, + { PCI_DEVICE_DATA(INTEL, LYNXPOINT_LP_SMBUS, FEATURES_ICH5) }, + { PCI_DEVICE_DATA(INTEL, AVOTON_SMBUS, FEATURES_ICH5) }, + { PCI_DEVICE_DATA(INTEL, WELLSBURG_SMBUS, FEATURES_ICH5) }, + { PCI_DEVICE_DATA(INTEL, WELLSBURG_SMBUS_MS0, FEATURES_ICH5 | FEATURE_IDF) }, + { PCI_DEVICE_DATA(INTEL, WELLSBURG_SMBUS_MS1, FEATURES_ICH5 | FEATURE_IDF) }, + { PCI_DEVICE_DATA(INTEL, WELLSBURG_SMBUS_MS2, FEATURES_ICH5 | FEATURE_IDF) }, + { PCI_DEVICE_DATA(INTEL, COLETOCREEK_SMBUS, FEATURES_ICH5) }, + { PCI_DEVICE_DATA(INTEL, GEMINILAKE_SMBUS, FEATURES_ICH5) }, + { PCI_DEVICE_DATA(INTEL, WILDCATPOINT_SMBUS, FEATURES_ICH5) }, + { PCI_DEVICE_DATA(INTEL, WILDCATPOINT_LP_SMBUS, FEATURES_ICH5) }, + { PCI_DEVICE_DATA(INTEL, BAYTRAIL_SMBUS, FEATURES_ICH5) }, + { PCI_DEVICE_DATA(INTEL, BRASWELL_SMBUS, FEATURES_ICH5) }, + { PCI_DEVICE_DATA(INTEL, SUNRISEPOINT_H_SMBUS, FEATURES_ICH5 | FEATURE_TCO_SPT) }, + { PCI_DEVICE_DATA(INTEL, SUNRISEPOINT_LP_SMBUS, FEATURES_ICH5 | FEATURE_TCO_SPT) }, + { PCI_DEVICE_DATA(INTEL, CDF_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, + { PCI_DEVICE_DATA(INTEL, DNV_SMBUS, FEATURES_ICH5 | FEATURE_TCO_SPT) }, + { PCI_DEVICE_DATA(INTEL, EBG_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, + { PCI_DEVICE_DATA(INTEL, BROXTON_SMBUS, FEATURES_ICH5) }, + { PCI_DEVICE_DATA(INTEL, LEWISBURG_SMBUS, FEATURES_ICH5 | FEATURE_TCO_SPT) }, + { PCI_DEVICE_DATA(INTEL, LEWISBURG_SSKU_SMBUS, FEATURES_ICH5 | FEATURE_TCO_SPT) }, + { PCI_DEVICE_DATA(INTEL, KABYLAKE_PCH_H_SMBUS, FEATURES_ICH5 | FEATURE_TCO_SPT) }, + { PCI_DEVICE_DATA(INTEL, CANNONLAKE_H_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, + { PCI_DEVICE_DATA(INTEL, CANNONLAKE_LP_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, + { PCI_DEVICE_DATA(INTEL, ICELAKE_LP_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, + { PCI_DEVICE_DATA(INTEL, ICELAKE_N_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, + { PCI_DEVICE_DATA(INTEL, COMETLAKE_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, + { PCI_DEVICE_DATA(INTEL, COMETLAKE_H_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, + { PCI_DEVICE_DATA(INTEL, COMETLAKE_V_SMBUS, FEATURES_ICH5 | FEATURE_TCO_SPT) }, + { PCI_DEVICE_DATA(INTEL, ELKHART_LAKE_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, + { PCI_DEVICE_DATA(INTEL, TIGERLAKE_LP_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, + { PCI_DEVICE_DATA(INTEL, TIGERLAKE_H_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, + { PCI_DEVICE_DATA(INTEL, JASPER_LAKE_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, + { PCI_DEVICE_DATA(INTEL, ALDER_LAKE_S_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, + { PCI_DEVICE_DATA(INTEL, ALDER_LAKE_P_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, + { PCI_DEVICE_DATA(INTEL, ALDER_LAKE_M_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, + { PCI_DEVICE_DATA(INTEL, RAPTOR_LAKE_S_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, + { PCI_DEVICE_DATA(INTEL, METEOR_LAKE_P_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, + { PCI_DEVICE_DATA(INTEL, METEOR_LAKE_SOC_S_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, + { PCI_DEVICE_DATA(INTEL, METEOR_LAKE_PCH_S_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, { 0, } }; diff --git a/drivers/i2c/busses/i2c-ibm_iic.c b/drivers/i2c/busses/i2c-ibm_iic.c index eeb80e34f9ad..1ad9d3b26dd3 100644 --- a/drivers/i2c/busses/i2c-ibm_iic.c +++ b/drivers/i2c/busses/i2c-ibm_iic.c @@ -694,10 +694,8 @@ static int iic_probe(struct platform_device *ofdev) int ret; dev = kzalloc(sizeof(*dev), GFP_KERNEL); - if (!dev) { - dev_err(&ofdev->dev, "failed to allocate device data\n"); + if (!dev) return -ENOMEM; - } platform_set_drvdata(ofdev, dev); @@ -769,7 +767,7 @@ error_cleanup: /* * Cleanup initialized IIC interface */ -static int iic_remove(struct platform_device *ofdev) +static void iic_remove(struct platform_device *ofdev) { struct ibm_iic_private *dev = platform_get_drvdata(ofdev); @@ -782,8 +780,6 @@ static int iic_remove(struct platform_device *ofdev) iounmap(dev->vaddr); kfree(dev); - - return 0; } static const struct of_device_id ibm_iic_match[] = { @@ -798,7 +794,7 @@ static struct platform_driver ibm_iic_driver = { .of_match_table = ibm_iic_match, }, .probe = iic_probe, - .remove = iic_remove, + .remove_new = iic_remove, }; module_platform_driver(ibm_iic_driver); diff --git a/drivers/i2c/busses/i2c-img-scb.c b/drivers/i2c/busses/i2c-img-scb.c index 39c479f96eb5..66ba36949ab5 100644 --- a/drivers/i2c/busses/i2c-img-scb.c +++ b/drivers/i2c/busses/i2c-img-scb.c @@ -913,7 +913,7 @@ static unsigned int img_i2c_auto(struct img_i2c *i2c, static irqreturn_t img_i2c_isr(int irq, void *dev_id) { - struct img_i2c *i2c = (struct img_i2c *)dev_id; + struct img_i2c *i2c = dev_id; u32 int_status, line_status; /* We handle transaction completion AFTER accessing registers */ unsigned int hret; @@ -1413,7 +1413,7 @@ rpm_disable: return ret; } -static int img_i2c_remove(struct platform_device *dev) +static void img_i2c_remove(struct platform_device *dev) { struct img_i2c *i2c = platform_get_drvdata(dev); @@ -1421,8 +1421,6 @@ static int img_i2c_remove(struct platform_device *dev) pm_runtime_disable(&dev->dev); if (!pm_runtime_status_suspended(&dev->dev)) img_i2c_runtime_suspend(&dev->dev); - - return 0; } static int img_i2c_runtime_suspend(struct device *dev) @@ -1506,7 +1504,7 @@ static struct platform_driver img_scb_i2c_driver = { .pm = &img_i2c_pm, }, .probe = img_i2c_probe, - .remove = img_i2c_remove, + .remove_new = img_i2c_remove, }; module_platform_driver(img_scb_i2c_driver); diff --git a/drivers/i2c/busses/i2c-imx-lpi2c.c b/drivers/i2c/busses/i2c-imx-lpi2c.c index 4d24ceb57ee7..c3287c887c6f 100644 --- a/drivers/i2c/busses/i2c-imx-lpi2c.c +++ b/drivers/i2c/busses/i2c-imx-lpi2c.c @@ -217,7 +217,7 @@ static int lpi2c_imx_config(struct lpi2c_imx_struct *lpi2c_imx) for (prescale = 0; prescale <= 7; prescale++) { clk_cycle = clk_rate / ((1 << prescale) * lpi2c_imx->bitrate) - 3 - (filt >> 1); - clkhi = (clk_cycle + I2C_CLK_RATIO) / (I2C_CLK_RATIO + 1); + clkhi = DIV_ROUND_UP(clk_cycle, I2C_CLK_RATIO + 1); clklo = clk_cycle - clkhi; if (clklo < 64) break; @@ -623,7 +623,7 @@ rpm_disable: return ret; } -static int lpi2c_imx_remove(struct platform_device *pdev) +static void lpi2c_imx_remove(struct platform_device *pdev) { struct lpi2c_imx_struct *lpi2c_imx = platform_get_drvdata(pdev); @@ -631,8 +631,6 @@ static int lpi2c_imx_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); pm_runtime_dont_use_autosuspend(&pdev->dev); - - return 0; } static int __maybe_unused lpi2c_runtime_suspend(struct device *dev) @@ -669,7 +667,7 @@ static const struct dev_pm_ops lpi2c_pm_ops = { static struct platform_driver lpi2c_imx_driver = { .probe = lpi2c_imx_probe, - .remove = lpi2c_imx_remove, + .remove_new = lpi2c_imx_remove, .driver = { .name = DRIVER_NAME, .of_match_table = lpi2c_imx_of_match, diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c index 42189a5f2905..65128a73e8a3 100644 --- a/drivers/i2c/busses/i2c-imx.c +++ b/drivers/i2c/busses/i2c-imx.c @@ -1561,7 +1561,7 @@ rpm_disable: return ret; } -static int i2c_imx_remove(struct platform_device *pdev) +static void i2c_imx_remove(struct platform_device *pdev) { struct imx_i2c_struct *i2c_imx = platform_get_drvdata(pdev); int irq, ret; @@ -1592,8 +1592,6 @@ static int i2c_imx_remove(struct platform_device *pdev) pm_runtime_put_noidle(&pdev->dev); pm_runtime_disable(&pdev->dev); - - return 0; } static int __maybe_unused i2c_imx_runtime_suspend(struct device *dev) @@ -1624,7 +1622,7 @@ static const struct dev_pm_ops i2c_imx_pm_ops = { static struct platform_driver i2c_imx_driver = { .probe = i2c_imx_probe, - .remove = i2c_imx_remove, + .remove_new = i2c_imx_remove, .driver = { .name = DRIVER_NAME, .pm = &i2c_imx_pm_ops, diff --git a/drivers/i2c/busses/i2c-iop3xx.c b/drivers/i2c/busses/i2c-iop3xx.c index 4a6ff54d87fe..f2f7ebeeaecb 100644 --- a/drivers/i2c/busses/i2c-iop3xx.c +++ b/drivers/i2c/busses/i2c-iop3xx.c @@ -388,7 +388,7 @@ static const struct i2c_algorithm iop3xx_i2c_algo = { .functionality = iop3xx_i2c_func, }; -static int +static void iop3xx_i2c_remove(struct platform_device *pdev) { struct i2c_adapter *padapter = platform_get_drvdata(pdev); @@ -408,8 +408,6 @@ iop3xx_i2c_remove(struct platform_device *pdev) release_mem_region(res->start, IOP3XX_I2C_IO_SIZE); kfree(adapter_data); kfree(padapter); - - return 0; } static int @@ -529,7 +527,7 @@ MODULE_DEVICE_TABLE(of, i2c_iop3xx_match); static struct platform_driver iop3xx_i2c_driver = { .probe = iop3xx_i2c_probe, - .remove = iop3xx_i2c_remove, + .remove_new = iop3xx_i2c_remove, .driver = { .name = "IOP3xx-I2C", .of_match_table = i2c_iop3xx_match, diff --git a/drivers/i2c/busses/i2c-isch.c b/drivers/i2c/busses/i2c-isch.c index 2dc7ada06ac5..1dc1ceaa4443 100644 --- a/drivers/i2c/busses/i2c-isch.c +++ b/drivers/i2c/busses/i2c-isch.c @@ -286,14 +286,12 @@ static int smbus_sch_probe(struct platform_device *dev) return retval; } -static int smbus_sch_remove(struct platform_device *pdev) +static void smbus_sch_remove(struct platform_device *pdev) { if (sch_smba) { i2c_del_adapter(&sch_adapter); sch_smba = 0; } - - return 0; } static struct platform_driver smbus_sch_driver = { @@ -301,7 +299,7 @@ static struct platform_driver smbus_sch_driver = { .name = "isch_smbus", }, .probe = smbus_sch_probe, - .remove = smbus_sch_remove, + .remove_new = smbus_sch_remove, }; module_platform_driver(smbus_sch_driver); diff --git a/drivers/i2c/busses/i2c-jz4780.c b/drivers/i2c/busses/i2c-jz4780.c index baa7319eee53..0dfe60399521 100644 --- a/drivers/i2c/busses/i2c-jz4780.c +++ b/drivers/i2c/busses/i2c-jz4780.c @@ -845,18 +845,17 @@ err: return ret; } -static int jz4780_i2c_remove(struct platform_device *pdev) +static void jz4780_i2c_remove(struct platform_device *pdev) { struct jz4780_i2c *i2c = platform_get_drvdata(pdev); clk_disable_unprepare(i2c->clk); i2c_del_adapter(&i2c->adap); - return 0; } static struct platform_driver jz4780_i2c_driver = { .probe = jz4780_i2c_probe, - .remove = jz4780_i2c_remove, + .remove_new = jz4780_i2c_remove, .driver = { .name = "jz4780-i2c", .of_match_table = jz4780_i2c_of_matches, diff --git a/drivers/i2c/busses/i2c-kempld.c b/drivers/i2c/busses/i2c-kempld.c index cf857cf22507..281058e3ea46 100644 --- a/drivers/i2c/busses/i2c-kempld.c +++ b/drivers/i2c/busses/i2c-kempld.c @@ -329,7 +329,7 @@ static int kempld_i2c_probe(struct platform_device *pdev) return 0; } -static int kempld_i2c_remove(struct platform_device *pdev) +static void kempld_i2c_remove(struct platform_device *pdev) { struct kempld_i2c_data *i2c = platform_get_drvdata(pdev); struct kempld_device_data *pld = i2c->pld; @@ -348,8 +348,6 @@ static int kempld_i2c_remove(struct platform_device *pdev) kempld_release_mutex(pld); i2c_del_adapter(&i2c->adap); - - return 0; } #ifdef CONFIG_PM @@ -389,7 +387,7 @@ static struct platform_driver kempld_i2c_driver = { .name = "kempld-i2c", }, .probe = kempld_i2c_probe, - .remove = kempld_i2c_remove, + .remove_new = kempld_i2c_remove, .suspend = kempld_i2c_suspend, .resume = kempld_i2c_resume, }; diff --git a/drivers/i2c/busses/i2c-lpc2k.c b/drivers/i2c/busses/i2c-lpc2k.c index 8fff6fbb7065..5c6d96554753 100644 --- a/drivers/i2c/busses/i2c-lpc2k.c +++ b/drivers/i2c/busses/i2c-lpc2k.c @@ -365,23 +365,17 @@ static int i2c_lpc2k_probe(struct platform_device *pdev) init_waitqueue_head(&i2c->wait); - i2c->clk = devm_clk_get(&pdev->dev, NULL); + i2c->clk = devm_clk_get_enabled(&pdev->dev, NULL); if (IS_ERR(i2c->clk)) { - dev_err(&pdev->dev, "error getting clock\n"); + dev_err(&pdev->dev, "failed to enable clock.\n"); return PTR_ERR(i2c->clk); } - ret = clk_prepare_enable(i2c->clk); - if (ret) { - dev_err(&pdev->dev, "unable to enable clock.\n"); - return ret; - } - ret = devm_request_irq(&pdev->dev, i2c->irq, i2c_lpc2k_handler, 0, dev_name(&pdev->dev), i2c); if (ret < 0) { dev_err(&pdev->dev, "can't request interrupt.\n"); - goto fail_clk; + return ret; } disable_irq_nosync(i2c->irq); @@ -397,8 +391,7 @@ static int i2c_lpc2k_probe(struct platform_device *pdev) clkrate = clk_get_rate(i2c->clk); if (clkrate == 0) { dev_err(&pdev->dev, "can't get I2C base clock\n"); - ret = -EINVAL; - goto fail_clk; + return -EINVAL; } /* Setup I2C dividers to generate clock with proper duty cycle */ @@ -424,25 +417,18 @@ static int i2c_lpc2k_probe(struct platform_device *pdev) ret = i2c_add_adapter(&i2c->adap); if (ret < 0) - goto fail_clk; + return ret; dev_info(&pdev->dev, "LPC2K I2C adapter\n"); return 0; - -fail_clk: - clk_disable_unprepare(i2c->clk); - return ret; } -static int i2c_lpc2k_remove(struct platform_device *dev) +static void i2c_lpc2k_remove(struct platform_device *dev) { struct lpc2k_i2c *i2c = platform_get_drvdata(dev); i2c_del_adapter(&i2c->adap); - clk_disable_unprepare(i2c->clk); - - return 0; } #ifdef CONFIG_PM @@ -483,7 +469,7 @@ MODULE_DEVICE_TABLE(of, lpc2k_i2c_match); static struct platform_driver i2c_lpc2k_driver = { .probe = i2c_lpc2k_probe, - .remove = i2c_lpc2k_remove, + .remove_new = i2c_lpc2k_remove, .driver = { .name = "lpc2k-i2c", .pm = I2C_LPC2K_DEV_PM_OPS, diff --git a/drivers/i2c/busses/i2c-meson.c b/drivers/i2c/busses/i2c-meson.c index 889eff06b78f..16026c895bb6 100644 --- a/drivers/i2c/busses/i2c-meson.c +++ b/drivers/i2c/busses/i2c-meson.c @@ -535,14 +535,12 @@ static int meson_i2c_probe(struct platform_device *pdev) return 0; } -static int meson_i2c_remove(struct platform_device *pdev) +static void meson_i2c_remove(struct platform_device *pdev) { struct meson_i2c *i2c = platform_get_drvdata(pdev); i2c_del_adapter(&i2c->adap); clk_disable_unprepare(i2c->clk); - - return 0; } static const struct meson_i2c_data i2c_meson6_data = { @@ -568,7 +566,7 @@ MODULE_DEVICE_TABLE(of, meson_i2c_match); static struct platform_driver meson_i2c_driver = { .probe = meson_i2c_probe, - .remove = meson_i2c_remove, + .remove_new = meson_i2c_remove, .driver = { .name = "meson-i2c", .of_match_table = meson_i2c_match, diff --git a/drivers/i2c/busses/i2c-microchip-corei2c.c b/drivers/i2c/busses/i2c-microchip-corei2c.c index 4d7e9b25f018..7f58f7eaabb6 100644 --- a/drivers/i2c/busses/i2c-microchip-corei2c.c +++ b/drivers/i2c/busses/i2c-microchip-corei2c.c @@ -446,14 +446,12 @@ static int mchp_corei2c_probe(struct platform_device *pdev) return 0; } -static int mchp_corei2c_remove(struct platform_device *pdev) +static void mchp_corei2c_remove(struct platform_device *pdev) { struct mchp_corei2c_dev *idev = platform_get_drvdata(pdev); clk_disable_unprepare(idev->i2c_clk); i2c_del_adapter(&idev->adapter); - - return 0; } static const struct of_device_id mchp_corei2c_of_match[] = { @@ -465,7 +463,7 @@ MODULE_DEVICE_TABLE(of, mchp_corei2c_of_match); static struct platform_driver mchp_corei2c_driver = { .probe = mchp_corei2c_probe, - .remove = mchp_corei2c_remove, + .remove_new = mchp_corei2c_remove, .driver = { .name = "microchip-corei2c", .of_match_table = mchp_corei2c_of_match, diff --git a/drivers/i2c/busses/i2c-mlxbf.c b/drivers/i2c/busses/i2c-mlxbf.c index 1810d5791b3d..ae66bdd1b737 100644 --- a/drivers/i2c/busses/i2c-mlxbf.c +++ b/drivers/i2c/busses/i2c-mlxbf.c @@ -2433,7 +2433,7 @@ static int mlxbf_i2c_probe(struct platform_device *pdev) return 0; } -static int mlxbf_i2c_remove(struct platform_device *pdev) +static void mlxbf_i2c_remove(struct platform_device *pdev) { struct mlxbf_i2c_priv *priv = platform_get_drvdata(pdev); struct device *dev = &pdev->dev; @@ -2474,13 +2474,11 @@ static int mlxbf_i2c_remove(struct platform_device *pdev) devm_free_irq(dev, priv->irq, priv); i2c_del_adapter(&priv->adap); - - return 0; } static struct platform_driver mlxbf_i2c_driver = { .probe = mlxbf_i2c_probe, - .remove = mlxbf_i2c_remove, + .remove_new = mlxbf_i2c_remove, .driver = { .name = "i2c-mlxbf", .acpi_match_table = ACPI_PTR(mlxbf_i2c_acpi_ids), diff --git a/drivers/i2c/busses/i2c-mlxcpld.c b/drivers/i2c/busses/i2c-mlxcpld.c index 081f51ef0551..c42fd4b329e4 100644 --- a/drivers/i2c/busses/i2c-mlxcpld.c +++ b/drivers/i2c/busses/i2c-mlxcpld.c @@ -571,19 +571,17 @@ mlxcpld_i2_probe_failed: return err; } -static int mlxcpld_i2c_remove(struct platform_device *pdev) +static void mlxcpld_i2c_remove(struct platform_device *pdev) { struct mlxcpld_i2c_priv *priv = platform_get_drvdata(pdev); i2c_del_adapter(&priv->adap); mutex_destroy(&priv->lock); - - return 0; } static struct platform_driver mlxcpld_i2c_driver = { .probe = mlxcpld_i2c_probe, - .remove = mlxcpld_i2c_remove, + .remove_new = mlxcpld_i2c_remove, .driver = { .name = MLXCPLD_I2C_DEVICE_NAME, }, diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c index cfd074ee6d54..fb1b640f33b7 100644 --- a/drivers/i2c/busses/i2c-mpc.c +++ b/drivers/i2c/busses/i2c-mpc.c @@ -316,9 +316,10 @@ static void mpc_i2c_setup_512x(struct device_node *node, if (node_ctrl) { ctrl = of_iomap(node_ctrl, 0); if (ctrl) { + u64 addr; /* Interrupt enable bits for i2c-0/1/2: bit 24/26/28 */ - pval = of_get_property(node, "reg", NULL); - idx = (*pval & 0xff) / 0x20; + of_property_read_reg(node, 0, &addr, NULL); + idx = (addr & 0xff) / 0x20; setbits32(ctrl, 1 << (24 + idx * 2)); iounmap(ctrl); } @@ -890,15 +891,13 @@ static int fsl_i2c_probe(struct platform_device *op) return result; }; -static int fsl_i2c_remove(struct platform_device *op) +static void fsl_i2c_remove(struct platform_device *op) { struct mpc_i2c *i2c = platform_get_drvdata(op); i2c_del_adapter(&i2c->adap); clk_disable_unprepare(i2c->clk_per); - - return 0; }; static int __maybe_unused mpc_i2c_suspend(struct device *dev) @@ -959,7 +958,7 @@ MODULE_DEVICE_TABLE(of, mpc_i2c_of_match); /* Structure for a device driver */ static struct platform_driver mpc_i2c_driver = { .probe = fsl_i2c_probe, - .remove = fsl_i2c_remove, + .remove_new = fsl_i2c_remove, .driver = { .name = DRV_NAME, .of_match_table = mpc_i2c_of_match, diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c index a43c4d77739a..7ca3f2221ba6 100644 --- a/drivers/i2c/busses/i2c-mt65xx.c +++ b/drivers/i2c/busses/i2c-mt65xx.c @@ -1505,15 +1505,13 @@ err_bulk_unprepare: return ret; } -static int mtk_i2c_remove(struct platform_device *pdev) +static void mtk_i2c_remove(struct platform_device *pdev) { struct mtk_i2c *i2c = platform_get_drvdata(pdev); i2c_del_adapter(&i2c->adap); clk_bulk_unprepare(I2C_MT65XX_CLK_MAX, i2c->clocks); - - return 0; } #ifdef CONFIG_PM_SLEEP @@ -1555,7 +1553,7 @@ static const struct dev_pm_ops mtk_i2c_pm = { static struct platform_driver mtk_i2c_driver = { .probe = mtk_i2c_probe, - .remove = mtk_i2c_remove, + .remove_new = mtk_i2c_remove, .driver = { .name = I2C_DRV_NAME, .pm = &mtk_i2c_pm, diff --git a/drivers/i2c/busses/i2c-mt7621.c b/drivers/i2c/busses/i2c-mt7621.c index 20eda5738ac4..104bb194e990 100644 --- a/drivers/i2c/busses/i2c-mt7621.c +++ b/drivers/i2c/busses/i2c-mt7621.c @@ -282,16 +282,11 @@ static int mtk_i2c_probe(struct platform_device *pdev) if (IS_ERR(i2c->base)) return PTR_ERR(i2c->base); - i2c->clk = devm_clk_get(&pdev->dev, NULL); + i2c->clk = devm_clk_get_enabled(&pdev->dev, NULL); if (IS_ERR(i2c->clk)) { - dev_err(&pdev->dev, "no clock defined\n"); + dev_err(&pdev->dev, "Failed to enable clock\n"); return PTR_ERR(i2c->clk); } - ret = clk_prepare_enable(i2c->clk); - if (ret) { - dev_err(&pdev->dev, "Unable to enable clock\n"); - return ret; - } i2c->dev = &pdev->dev; @@ -301,8 +296,7 @@ static int mtk_i2c_probe(struct platform_device *pdev) if (i2c->bus_freq == 0) { dev_warn(i2c->dev, "clock-frequency 0 not supported\n"); - ret = -EINVAL; - goto err_disable_clk; + return -EINVAL; } adap = &i2c->adap; @@ -320,31 +314,23 @@ static int mtk_i2c_probe(struct platform_device *pdev) ret = i2c_add_adapter(adap); if (ret < 0) - goto err_disable_clk; + return ret; dev_info(&pdev->dev, "clock %u kHz\n", i2c->bus_freq / 1000); return 0; - -err_disable_clk: - clk_disable_unprepare(i2c->clk); - - return ret; } -static int mtk_i2c_remove(struct platform_device *pdev) +static void mtk_i2c_remove(struct platform_device *pdev) { struct mtk_i2c *i2c = platform_get_drvdata(pdev); - clk_disable_unprepare(i2c->clk); i2c_del_adapter(&i2c->adap); - - return 0; } static struct platform_driver mtk_i2c_driver = { .probe = mtk_i2c_probe, - .remove = mtk_i2c_remove, + .remove_new = mtk_i2c_remove, .driver = { .name = "i2c-mt7621", .of_match_table = i2c_mtk_dt_ids, diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c index 878c076ebdc6..fd8403b07fa6 100644 --- a/drivers/i2c/busses/i2c-mv64xxx.c +++ b/drivers/i2c/busses/i2c-mv64xxx.c @@ -1084,7 +1084,7 @@ exit_disable_pm: return rc; } -static int +static void mv64xxx_i2c_remove(struct platform_device *pd) { struct mv64xxx_i2c_data *drv_data = platform_get_drvdata(pd); @@ -1094,8 +1094,6 @@ mv64xxx_i2c_remove(struct platform_device *pd) pm_runtime_disable(&pd->dev); if (!pm_runtime_status_suspended(&pd->dev)) mv64xxx_i2c_runtime_suspend(&pd->dev); - - return 0; } static const struct dev_pm_ops mv64xxx_i2c_pm_ops = { @@ -1107,7 +1105,7 @@ static const struct dev_pm_ops mv64xxx_i2c_pm_ops = { static struct platform_driver mv64xxx_i2c_driver = { .probe = mv64xxx_i2c_probe, - .remove = mv64xxx_i2c_remove, + .remove_new = mv64xxx_i2c_remove, .driver = { .name = MV64XXX_I2C_CTLR_NAME, .pm = &mv64xxx_i2c_pm_ops, diff --git a/drivers/i2c/busses/i2c-mxs.c b/drivers/i2c/busses/i2c-mxs.c index e0f3b3545cfe..1d76f1c4dc06 100644 --- a/drivers/i2c/busses/i2c-mxs.c +++ b/drivers/i2c/busses/i2c-mxs.c @@ -864,7 +864,7 @@ static int mxs_i2c_probe(struct platform_device *pdev) return 0; } -static int mxs_i2c_remove(struct platform_device *pdev) +static void mxs_i2c_remove(struct platform_device *pdev) { struct mxs_i2c_dev *i2c = platform_get_drvdata(pdev); @@ -874,8 +874,6 @@ static int mxs_i2c_remove(struct platform_device *pdev) dma_release_channel(i2c->dmach); writel(MXS_I2C_CTRL0_SFTRST, i2c->regs + MXS_I2C_CTRL0_SET); - - return 0; } static struct platform_driver mxs_i2c_driver = { @@ -884,7 +882,7 @@ static struct platform_driver mxs_i2c_driver = { .of_match_table = mxs_i2c_dt_ids, }, .probe = mxs_i2c_probe, - .remove = mxs_i2c_remove, + .remove_new = mxs_i2c_remove, }; static int __init mxs_i2c_init(void) diff --git a/drivers/i2c/busses/i2c-nomadik.c b/drivers/i2c/busses/i2c-nomadik.c index a2d12a5b1c34..1e5fd23ef45c 100644 --- a/drivers/i2c/busses/i2c-nomadik.c +++ b/drivers/i2c/busses/i2c-nomadik.c @@ -970,12 +970,10 @@ static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id) struct i2c_vendor_data *vendor = id->data; u32 max_fifo_threshold = (vendor->fifodepth / 2) - 1; - dev = devm_kzalloc(&adev->dev, sizeof(struct nmk_i2c_dev), GFP_KERNEL); - if (!dev) { - dev_err(&adev->dev, "cannot allocate memory\n"); - ret = -ENOMEM; - goto err_no_mem; - } + dev = devm_kzalloc(&adev->dev, sizeof(*dev), GFP_KERNEL); + if (!dev) + return -ENOMEM; + dev->vendor = vendor; dev->adev = adev; nmk_i2c_of_probe(np, dev); @@ -996,31 +994,20 @@ static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id) dev->virtbase = devm_ioremap(&adev->dev, adev->res.start, resource_size(&adev->res)); - if (!dev->virtbase) { - ret = -ENOMEM; - goto err_no_mem; - } + if (!dev->virtbase) + return -ENOMEM; dev->irq = adev->irq[0]; ret = devm_request_irq(&adev->dev, dev->irq, i2c_irq_handler, 0, DRIVER_NAME, dev); - if (ret) { - dev_err(&adev->dev, "cannot claim the irq %d\n", dev->irq); - goto err_no_mem; - } + if (ret) + return dev_err_probe(&adev->dev, ret, + "cannot claim the irq %d\n", dev->irq); - dev->clk = devm_clk_get(&adev->dev, NULL); - if (IS_ERR(dev->clk)) { - dev_err(&adev->dev, "could not get i2c clock\n"); - ret = PTR_ERR(dev->clk); - goto err_no_mem; - } - - ret = clk_prepare_enable(dev->clk); - if (ret) { - dev_err(&adev->dev, "can't prepare_enable clock\n"); - goto err_no_mem; - } + dev->clk = devm_clk_get_enabled(&adev->dev, NULL); + if (IS_ERR(dev->clk)) + return dev_err_probe(&adev->dev, PTR_ERR(dev->clk), + "could enable i2c clock\n"); init_hw(dev); @@ -1042,17 +1029,11 @@ static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id) ret = i2c_add_adapter(adap); if (ret) - goto err_no_adap; + return ret; pm_runtime_put(&adev->dev); return 0; - - err_no_adap: - clk_disable_unprepare(dev->clk); - err_no_mem: - - return ret; } static void nmk_i2c_remove(struct amba_device *adev) @@ -1066,7 +1047,6 @@ static void nmk_i2c_remove(struct amba_device *adev) clear_all_interrupts(dev); /* disable the controller */ i2c_clr_bit(dev->virtbase + I2C_CR, I2C_CR_PE); - clk_disable_unprepare(dev->clk); release_mem_region(res->start, resource_size(res)); } diff --git a/drivers/i2c/busses/i2c-npcm7xx.c b/drivers/i2c/busses/i2c-npcm7xx.c index 38d5864d0cb5..53b65ffb6a64 100644 --- a/drivers/i2c/busses/i2c-npcm7xx.c +++ b/drivers/i2c/busses/i2c-npcm7xx.c @@ -2361,7 +2361,7 @@ static int npcm_i2c_probe_bus(struct platform_device *pdev) return 0; } -static int npcm_i2c_remove_bus(struct platform_device *pdev) +static void npcm_i2c_remove_bus(struct platform_device *pdev) { unsigned long lock_flags; struct npcm_i2c *bus = platform_get_drvdata(pdev); @@ -2371,7 +2371,6 @@ static int npcm_i2c_remove_bus(struct platform_device *pdev) npcm_i2c_disable(bus); spin_unlock_irqrestore(&bus->lock, lock_flags); i2c_del_adapter(&bus->adap); - return 0; } static const struct of_device_id npcm_i2c_bus_of_table[] = { @@ -2383,7 +2382,7 @@ MODULE_DEVICE_TABLE(of, npcm_i2c_bus_of_table); static struct platform_driver npcm_i2c_bus_driver = { .probe = npcm_i2c_probe_bus, - .remove = npcm_i2c_remove_bus, + .remove_new = npcm_i2c_remove_bus, .driver = { .name = "nuvoton-i2c", .of_match_table = npcm_i2c_bus_of_table, diff --git a/drivers/i2c/busses/i2c-nvidia-gpu.c b/drivers/i2c/busses/i2c-nvidia-gpu.c index a8b99e7f6262..26622d24bb1b 100644 --- a/drivers/i2c/busses/i2c-nvidia-gpu.c +++ b/drivers/i2c/busses/i2c-nvidia-gpu.c @@ -14,6 +14,7 @@ #include #include #include +#include #include @@ -261,6 +262,8 @@ MODULE_DEVICE_TABLE(pci, gpu_i2c_ids); static const struct property_entry ccgx_props[] = { /* Use FW built for NVIDIA GPU only */ PROPERTY_ENTRY_STRING("firmware-name", "nvidia,gpu"), + /* USB-C doesn't power the system */ + PROPERTY_ENTRY_U8("scope", POWER_SUPPLY_SCOPE_DEVICE), { } }; diff --git a/drivers/i2c/busses/i2c-ocores.c b/drivers/i2c/busses/i2c-ocores.c index 2e575856c5cd..4ac77e57bbbf 100644 --- a/drivers/i2c/busses/i2c-ocores.c +++ b/drivers/i2c/busses/i2c-ocores.c @@ -552,28 +552,20 @@ static int ocores_i2c_of_probe(struct platform_device *pdev, &clock_frequency); i2c->bus_clock_khz = 100; - i2c->clk = devm_clk_get(&pdev->dev, NULL); - - if (!IS_ERR(i2c->clk)) { - int ret = clk_prepare_enable(i2c->clk); - - if (ret) { - dev_err(&pdev->dev, - "clk_prepare_enable failed: %d\n", ret); - return ret; - } - i2c->ip_clock_khz = clk_get_rate(i2c->clk) / 1000; - if (clock_frequency_present) - i2c->bus_clock_khz = clock_frequency / 1000; - } + i2c->clk = devm_clk_get_optional_enabled(&pdev->dev, NULL); + if (IS_ERR(i2c->clk)) + return dev_err_probe(&pdev->dev, PTR_ERR(i2c->clk), + "devm_clk_get_optional_enabled failed\n"); + i2c->ip_clock_khz = clk_get_rate(i2c->clk) / 1000; + if (clock_frequency_present) + i2c->bus_clock_khz = clock_frequency / 1000; if (i2c->ip_clock_khz == 0) { if (of_property_read_u32(np, "opencores,ip-clock-frequency", &val)) { if (!clock_frequency_present) { dev_err(&pdev->dev, "Missing required parameter 'opencores,ip-clock-frequency'\n"); - clk_disable_unprepare(i2c->clk); return -ENODEV; } i2c->ip_clock_khz = clock_frequency / 1000; @@ -678,8 +670,7 @@ static int ocores_i2c_probe(struct platform_device *pdev) default: dev_err(&pdev->dev, "Unsupported I/O width (%d)\n", i2c->reg_io_width); - ret = -EINVAL; - goto err_clk; + return -EINVAL; } } @@ -710,13 +701,13 @@ static int ocores_i2c_probe(struct platform_device *pdev) pdev->name, i2c); if (ret) { dev_err(&pdev->dev, "Cannot claim IRQ\n"); - goto err_clk; + return ret; } } ret = ocores_init(&pdev->dev, i2c); if (ret) - goto err_clk; + return ret; /* hook up driver to tree */ platform_set_drvdata(pdev, i2c); @@ -728,7 +719,7 @@ static int ocores_i2c_probe(struct platform_device *pdev) /* add i2c adapter to i2c tree */ ret = i2c_add_adapter(&i2c->adap); if (ret) - goto err_clk; + return ret; /* add in known devices to the bus */ if (pdata) { @@ -737,13 +728,9 @@ static int ocores_i2c_probe(struct platform_device *pdev) } return 0; - -err_clk: - clk_disable_unprepare(i2c->clk); - return ret; } -static int ocores_i2c_remove(struct platform_device *pdev) +static void ocores_i2c_remove(struct platform_device *pdev) { struct ocores_i2c *i2c = platform_get_drvdata(pdev); u8 ctrl = oc_getreg(i2c, OCI2C_CONTROL); @@ -754,11 +741,6 @@ static int ocores_i2c_remove(struct platform_device *pdev) /* remove adapter & data */ i2c_del_adapter(&i2c->adap); - - if (!IS_ERR(i2c->clk)) - clk_disable_unprepare(i2c->clk); - - return 0; } #ifdef CONFIG_PM_SLEEP @@ -771,28 +753,22 @@ static int ocores_i2c_suspend(struct device *dev) ctrl &= ~(OCI2C_CTRL_EN | OCI2C_CTRL_IEN); oc_setreg(i2c, OCI2C_CONTROL, ctrl); - if (!IS_ERR(i2c->clk)) - clk_disable_unprepare(i2c->clk); + clk_disable_unprepare(i2c->clk); return 0; } static int ocores_i2c_resume(struct device *dev) { struct ocores_i2c *i2c = dev_get_drvdata(dev); + unsigned long rate; + int ret; - if (!IS_ERR(i2c->clk)) { - unsigned long rate; - int ret = clk_prepare_enable(i2c->clk); - - if (ret) { - dev_err(dev, - "clk_prepare_enable failed: %d\n", ret); - return ret; - } - rate = clk_get_rate(i2c->clk) / 1000; - if (rate) - i2c->ip_clock_khz = rate; - } + ret = clk_prepare_enable(i2c->clk); + if (ret) + return dev_err_probe(dev, ret, "clk_prepare_enable failed\n"); + rate = clk_get_rate(i2c->clk) / 1000; + if (rate) + i2c->ip_clock_khz = rate; return ocores_init(dev, i2c); } @@ -804,7 +780,7 @@ static SIMPLE_DEV_PM_OPS(ocores_i2c_pm, ocores_i2c_suspend, ocores_i2c_resume); static struct platform_driver ocores_i2c_driver = { .probe = ocores_i2c_probe, - .remove = ocores_i2c_remove, + .remove_new = ocores_i2c_remove, .driver = { .name = "ocores-i2c", .of_match_table = ocores_i2c_match, diff --git a/drivers/i2c/busses/i2c-octeon-platdrv.c b/drivers/i2c/busses/i2c-octeon-platdrv.c index 0c227963c8d6..7d54b3203f71 100644 --- a/drivers/i2c/busses/i2c-octeon-platdrv.c +++ b/drivers/i2c/busses/i2c-octeon-platdrv.c @@ -253,12 +253,11 @@ out: return result; }; -static int octeon_i2c_remove(struct platform_device *pdev) +static void octeon_i2c_remove(struct platform_device *pdev) { struct octeon_i2c *i2c = platform_get_drvdata(pdev); i2c_del_adapter(&i2c->adap); - return 0; }; static const struct of_device_id octeon_i2c_match[] = { @@ -270,7 +269,7 @@ MODULE_DEVICE_TABLE(of, octeon_i2c_match); static struct platform_driver octeon_i2c_driver = { .probe = octeon_i2c_probe, - .remove = octeon_i2c_remove, + .remove_new = octeon_i2c_remove, .driver = { .name = DRV_NAME, .of_match_table = octeon_i2c_match, diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 4199f57a6bf2..58fd6fa3edf1 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -1519,7 +1519,7 @@ err_disable_pm: return r; } -static int omap_i2c_remove(struct platform_device *pdev) +static void omap_i2c_remove(struct platform_device *pdev) { struct omap_i2c_dev *omap = platform_get_drvdata(pdev); int ret; @@ -1535,8 +1535,6 @@ static int omap_i2c_remove(struct platform_device *pdev) pm_runtime_dont_use_autosuspend(&pdev->dev); pm_runtime_put_sync(&pdev->dev); pm_runtime_disable(&pdev->dev); - - return 0; } static int __maybe_unused omap_i2c_runtime_suspend(struct device *dev) @@ -1588,7 +1586,7 @@ static const struct dev_pm_ops omap_i2c_pm_ops = { static struct platform_driver omap_i2c_driver = { .probe = omap_i2c_probe, - .remove = omap_i2c_remove, + .remove_new = omap_i2c_remove, .driver = { .name = "omap_i2c", .pm = &omap_i2c_pm_ops, diff --git a/drivers/i2c/busses/i2c-opal.c b/drivers/i2c/busses/i2c-opal.c index 9f773b4f5ed8..17ef87d50f7c 100644 --- a/drivers/i2c/busses/i2c-opal.c +++ b/drivers/i2c/busses/i2c-opal.c @@ -232,13 +232,11 @@ static int i2c_opal_probe(struct platform_device *pdev) return rc; } -static int i2c_opal_remove(struct platform_device *pdev) +static void i2c_opal_remove(struct platform_device *pdev) { struct i2c_adapter *adapter = platform_get_drvdata(pdev); i2c_del_adapter(adapter); - - return 0; } static const struct of_device_id i2c_opal_of_match[] = { @@ -251,7 +249,7 @@ MODULE_DEVICE_TABLE(of, i2c_opal_of_match); static struct platform_driver i2c_opal_driver = { .probe = i2c_opal_probe, - .remove = i2c_opal_remove, + .remove_new = i2c_opal_remove, .driver = { .name = "i2c-opal", .of_match_table = i2c_opal_of_match, diff --git a/drivers/i2c/busses/i2c-owl.c b/drivers/i2c/busses/i2c-owl.c index 99ddd8894964..5f0ef8c35141 100644 --- a/drivers/i2c/busses/i2c-owl.c +++ b/drivers/i2c/busses/i2c-owl.c @@ -461,21 +461,16 @@ static int owl_i2c_probe(struct platform_device *pdev) return -EINVAL; } - i2c_dev->clk = devm_clk_get(dev, NULL); + i2c_dev->clk = devm_clk_get_enabled(dev, NULL); if (IS_ERR(i2c_dev->clk)) { - dev_err(dev, "failed to get clock\n"); + dev_err(dev, "failed to enable clock\n"); return PTR_ERR(i2c_dev->clk); } - ret = clk_prepare_enable(i2c_dev->clk); - if (ret) - return ret; - i2c_dev->clk_rate = clk_get_rate(i2c_dev->clk); if (!i2c_dev->clk_rate) { dev_err(dev, "input clock rate should not be zero\n"); - ret = -EINVAL; - goto disable_clk; + return -EINVAL; } init_completion(&i2c_dev->msg_complete); @@ -496,15 +491,10 @@ static int owl_i2c_probe(struct platform_device *pdev) i2c_dev); if (ret) { dev_err(dev, "failed to request irq %d\n", irq); - goto disable_clk; + return ret; } return i2c_add_adapter(&i2c_dev->adap); - -disable_clk: - clk_disable_unprepare(i2c_dev->clk); - - return ret; } static const struct of_device_id owl_i2c_of_match[] = { diff --git a/drivers/i2c/busses/i2c-pasemi-platform.c b/drivers/i2c/busses/i2c-pasemi-platform.c index e35945a91dbe..5fbfb9b41744 100644 --- a/drivers/i2c/busses/i2c-pasemi-platform.c +++ b/drivers/i2c/busses/i2c-pasemi-platform.c @@ -66,22 +66,18 @@ static int pasemi_platform_i2c_probe(struct platform_device *pdev) if (of_property_read_u32(dev->of_node, "clock-frequency", &frequency)) frequency = I2C_MAX_STANDARD_MODE_FREQ; - data->clk_ref = devm_clk_get(dev, NULL); + data->clk_ref = devm_clk_get_enabled(dev, NULL); if (IS_ERR(data->clk_ref)) return PTR_ERR(data->clk_ref); - error = clk_prepare_enable(data->clk_ref); - if (error) - return error; - error = pasemi_platform_i2c_calc_clk_div(data, frequency); if (error) - goto out_clk_disable; + return error; smbus->adapter.dev.of_node = pdev->dev.of_node; error = pasemi_i2c_common_probe(smbus); if (error) - goto out_clk_disable; + return error; irq_num = platform_get_irq(pdev, 0); error = devm_request_irq(smbus->dev, irq_num, pasemi_irq_handler, 0, "pasemi_apple_i2c", (void *)smbus); @@ -91,20 +87,9 @@ static int pasemi_platform_i2c_probe(struct platform_device *pdev) platform_set_drvdata(pdev, data); return 0; - -out_clk_disable: - clk_disable_unprepare(data->clk_ref); - - return error; } -static int pasemi_platform_i2c_remove(struct platform_device *pdev) -{ - struct pasemi_platform_i2c_data *data = platform_get_drvdata(pdev); - - clk_disable_unprepare(data->clk_ref); - return 0; -} +static void pasemi_platform_i2c_remove(struct platform_device *pdev) { } static const struct of_device_id pasemi_platform_i2c_of_match[] = { { .compatible = "apple,t8103-i2c" }, @@ -119,7 +104,7 @@ static struct platform_driver pasemi_platform_i2c_driver = { .of_match_table = pasemi_platform_i2c_of_match, }, .probe = pasemi_platform_i2c_probe, - .remove = pasemi_platform_i2c_remove, + .remove_new = pasemi_platform_i2c_remove, }; module_platform_driver(pasemi_platform_i2c_driver); diff --git a/drivers/i2c/busses/i2c-pca-platform.c b/drivers/i2c/busses/i2c-pca-platform.c index 86d4f75ef8d3..d2a9e7b61c1a 100644 --- a/drivers/i2c/busses/i2c-pca-platform.c +++ b/drivers/i2c/busses/i2c-pca-platform.c @@ -221,13 +221,11 @@ static int i2c_pca_pf_probe(struct platform_device *pdev) return 0; } -static int i2c_pca_pf_remove(struct platform_device *pdev) +static void i2c_pca_pf_remove(struct platform_device *pdev) { struct i2c_pca_pf_data *i2c = platform_get_drvdata(pdev); i2c_del_adapter(&i2c->adap); - - return 0; } #ifdef CONFIG_OF @@ -241,7 +239,7 @@ MODULE_DEVICE_TABLE(of, i2c_pca_of_match_table); static struct platform_driver i2c_pca_pf_driver = { .probe = i2c_pca_pf_probe, - .remove = i2c_pca_pf_remove, + .remove_new = i2c_pca_pf_remove, .driver = { .name = "i2c-pca-platform", .of_match_table = of_match_ptr(i2c_pca_of_match_table), diff --git a/drivers/i2c/busses/i2c-pnx.c b/drivers/i2c/busses/i2c-pnx.c index 50f21cdbe90d..82400057f810 100644 --- a/drivers/i2c/busses/i2c-pnx.c +++ b/drivers/i2c/busses/i2c-pnx.c @@ -743,14 +743,12 @@ out_clock: return ret; } -static int i2c_pnx_remove(struct platform_device *pdev) +static void i2c_pnx_remove(struct platform_device *pdev) { struct i2c_pnx_algo_data *alg_data = platform_get_drvdata(pdev); i2c_del_adapter(&alg_data->adapter); clk_disable_unprepare(alg_data->clk); - - return 0; } #ifdef CONFIG_OF @@ -768,7 +766,7 @@ static struct platform_driver i2c_pnx_driver = { .pm = PNX_I2C_PM, }, .probe = i2c_pnx_probe, - .remove = i2c_pnx_remove, + .remove_new = i2c_pnx_remove, }; static int __init i2c_adap_pnx_init(void) diff --git a/drivers/i2c/busses/i2c-powermac.c b/drivers/i2c/busses/i2c-powermac.c index ec706a3aba26..4996a628fdae 100644 --- a/drivers/i2c/busses/i2c-powermac.c +++ b/drivers/i2c/busses/i2c-powermac.c @@ -188,14 +188,12 @@ static const struct i2c_adapter_quirks i2c_powermac_quirks = { .max_num_msgs = 1, }; -static int i2c_powermac_remove(struct platform_device *dev) +static void i2c_powermac_remove(struct platform_device *dev) { struct i2c_adapter *adapter = platform_get_drvdata(dev); i2c_del_adapter(adapter); memset(adapter, 0, sizeof(*adapter)); - - return 0; } static u32 i2c_powermac_get_addr(struct i2c_adapter *adap, @@ -439,7 +437,7 @@ static int i2c_powermac_probe(struct platform_device *dev) static struct platform_driver i2c_powermac_driver = { .probe = i2c_powermac_probe, - .remove = i2c_powermac_remove, + .remove_new = i2c_powermac_remove, .driver = { .name = "i2c-powermac", .bus = &platform_bus_type, diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c index f9fa5308556b..937f7eebe906 100644 --- a/drivers/i2c/busses/i2c-pxa.c +++ b/drivers/i2c/busses/i2c-pxa.c @@ -1482,15 +1482,13 @@ ereqirq: return ret; } -static int i2c_pxa_remove(struct platform_device *dev) +static void i2c_pxa_remove(struct platform_device *dev) { struct pxa_i2c *i2c = platform_get_drvdata(dev); i2c_del_adapter(&i2c->adap); clk_disable_unprepare(i2c->clk); - - return 0; } #ifdef CONFIG_PM @@ -1525,7 +1523,7 @@ static const struct dev_pm_ops i2c_pxa_dev_pm_ops = { static struct platform_driver i2c_pxa_driver = { .probe = i2c_pxa_probe, - .remove = i2c_pxa_remove, + .remove_new = i2c_pxa_remove, .driver = { .name = "pxa2xx-i2c", .pm = I2C_PXA_DEV_PM_OPS, diff --git a/drivers/i2c/busses/i2c-qcom-cci.c b/drivers/i2c/busses/i2c-qcom-cci.c index 01358472680c..622dc14add9d 100644 --- a/drivers/i2c/busses/i2c-qcom-cci.c +++ b/drivers/i2c/busses/i2c-qcom-cci.c @@ -581,8 +581,7 @@ static int cci_probe(struct platform_device *pdev) /* Memory */ - r = platform_get_resource(pdev, IORESOURCE_MEM, 0); - cci->base = devm_ioremap_resource(dev, r); + cci->base = devm_platform_get_and_ioremap_resource(pdev, 0, &r); if (IS_ERR(cci->base)) return PTR_ERR(cci->base); @@ -675,7 +674,7 @@ disable_clocks: return ret; } -static int cci_remove(struct platform_device *pdev) +static void cci_remove(struct platform_device *pdev) { struct cci *cci = platform_get_drvdata(pdev); int i; @@ -691,8 +690,6 @@ static int cci_remove(struct platform_device *pdev) disable_irq(cci->irq); pm_runtime_disable(&pdev->dev); pm_runtime_set_suspended(&pdev->dev); - - return 0; } static const struct cci_data cci_v1_data = { @@ -829,7 +826,7 @@ MODULE_DEVICE_TABLE(of, cci_dt_match); static struct platform_driver qcom_cci_driver = { .probe = cci_probe, - .remove = cci_remove, + .remove_new = cci_remove, .driver = { .name = "i2c-qcom-cci", .of_match_table = cci_dt_match, diff --git a/drivers/i2c/busses/i2c-qcom-geni.c b/drivers/i2c/busses/i2c-qcom-geni.c index 83909b02a03e..b670a67c4fdd 100644 --- a/drivers/i2c/busses/i2c-qcom-geni.c +++ b/drivers/i2c/busses/i2c-qcom-geni.c @@ -936,14 +936,13 @@ err_dma: return ret; } -static int geni_i2c_remove(struct platform_device *pdev) +static void geni_i2c_remove(struct platform_device *pdev) { struct geni_i2c_dev *gi2c = platform_get_drvdata(pdev); i2c_del_adapter(&gi2c->adap); release_gpi_dma(gi2c); pm_runtime_disable(gi2c->se.dev); - return 0; } static void geni_i2c_shutdown(struct platform_device *pdev) @@ -1041,7 +1040,7 @@ MODULE_DEVICE_TABLE(of, geni_i2c_dt_match); static struct platform_driver geni_i2c_driver = { .probe = geni_i2c_probe, - .remove = geni_i2c_remove, + .remove_new = geni_i2c_remove, .shutdown = geni_i2c_shutdown, .driver = { .name = "geni_i2c", diff --git a/drivers/i2c/busses/i2c-qup.c b/drivers/i2c/busses/i2c-qup.c index 78682388e02e..ae90170023b0 100644 --- a/drivers/i2c/busses/i2c-qup.c +++ b/drivers/i2c/busses/i2c-qup.c @@ -1911,7 +1911,7 @@ fail_dma: return ret; } -static int qup_i2c_remove(struct platform_device *pdev) +static void qup_i2c_remove(struct platform_device *pdev) { struct qup_i2c_dev *qup = platform_get_drvdata(pdev); @@ -1925,7 +1925,6 @@ static int qup_i2c_remove(struct platform_device *pdev) i2c_del_adapter(&qup->adap); pm_runtime_disable(qup->dev); pm_runtime_set_suspended(qup->dev); - return 0; } #ifdef CONFIG_PM @@ -1985,7 +1984,7 @@ MODULE_DEVICE_TABLE(of, qup_i2c_dt_match); static struct platform_driver qup_i2c_driver = { .probe = qup_i2c_probe, - .remove = qup_i2c_remove, + .remove_new = qup_i2c_remove, .driver = { .name = "i2c_qup", .pm = &qup_i2c_qup_pm_ops, diff --git a/drivers/i2c/busses/i2c-rcar.c b/drivers/i2c/busses/i2c-rcar.c index cef82b205c26..2d9c37410ebd 100644 --- a/drivers/i2c/busses/i2c-rcar.c +++ b/drivers/i2c/busses/i2c-rcar.c @@ -1155,7 +1155,7 @@ static int rcar_i2c_probe(struct platform_device *pdev) return ret; } -static int rcar_i2c_remove(struct platform_device *pdev) +static void rcar_i2c_remove(struct platform_device *pdev) { struct rcar_i2c_priv *priv = platform_get_drvdata(pdev); struct device *dev = &pdev->dev; @@ -1167,8 +1167,6 @@ static int rcar_i2c_remove(struct platform_device *pdev) if (priv->flags & ID_P_PM_BLOCKED) pm_runtime_put(dev); pm_runtime_disable(dev); - - return 0; } #ifdef CONFIG_PM_SLEEP @@ -1204,7 +1202,7 @@ static struct platform_driver rcar_i2c_driver = { .pm = DEV_PM_OPS, }, .probe = rcar_i2c_probe, - .remove = rcar_i2c_remove, + .remove_new = rcar_i2c_remove, }; module_platform_driver(rcar_i2c_driver); diff --git a/drivers/i2c/busses/i2c-riic.c b/drivers/i2c/busses/i2c-riic.c index 849848ccb080..5f8c0bd508d2 100644 --- a/drivers/i2c/busses/i2c-riic.c +++ b/drivers/i2c/busses/i2c-riic.c @@ -477,7 +477,7 @@ out: return ret; } -static int riic_i2c_remove(struct platform_device *pdev) +static void riic_i2c_remove(struct platform_device *pdev) { struct riic_dev *riic = platform_get_drvdata(pdev); @@ -486,8 +486,6 @@ static int riic_i2c_remove(struct platform_device *pdev) pm_runtime_put(&pdev->dev); i2c_del_adapter(&riic->adapter); pm_runtime_disable(&pdev->dev); - - return 0; } static const struct of_device_id riic_i2c_dt_ids[] = { @@ -497,7 +495,7 @@ static const struct of_device_id riic_i2c_dt_ids[] = { static struct platform_driver riic_i2c_driver = { .probe = riic_i2c_probe, - .remove = riic_i2c_remove, + .remove_new = riic_i2c_remove, .driver = { .name = "i2c-riic", .of_match_table = riic_i2c_dt_ids, diff --git a/drivers/i2c/busses/i2c-rk3x.c b/drivers/i2c/busses/i2c-rk3x.c index b31cf4f18f85..a044ca0c35a1 100644 --- a/drivers/i2c/busses/i2c-rk3x.c +++ b/drivers/i2c/busses/i2c-rk3x.c @@ -1372,7 +1372,7 @@ err_clk: return ret; } -static int rk3x_i2c_remove(struct platform_device *pdev) +static void rk3x_i2c_remove(struct platform_device *pdev) { struct rk3x_i2c *i2c = platform_get_drvdata(pdev); @@ -1381,15 +1381,13 @@ static int rk3x_i2c_remove(struct platform_device *pdev) clk_notifier_unregister(i2c->clk, &i2c->clk_rate_nb); clk_unprepare(i2c->pclk); clk_unprepare(i2c->clk); - - return 0; } static SIMPLE_DEV_PM_OPS(rk3x_i2c_pm_ops, NULL, rk3x_i2c_resume); static struct platform_driver rk3x_i2c_driver = { .probe = rk3x_i2c_probe, - .remove = rk3x_i2c_remove, + .remove_new = rk3x_i2c_remove, .driver = { .name = "rk3x-i2c", .of_match_table = rk3x_i2c_match, diff --git a/drivers/i2c/busses/i2c-rzv2m.c b/drivers/i2c/busses/i2c-rzv2m.c index 56d0faee5c46..b0bfc96b9ede 100644 --- a/drivers/i2c/busses/i2c-rzv2m.c +++ b/drivers/i2c/busses/i2c-rzv2m.c @@ -50,9 +50,6 @@ #define IICB0MDSC BIT(7) /* Bus Mode */ #define IICB0SLSE BIT(1) /* Start condition output */ -#define bit_setl(addr, val) writel(readl(addr) | (val), (addr)) -#define bit_clrl(addr, val) writel(readl(addr) & ~(val), (addr)) - struct rzv2m_i2c_priv { void __iomem *base; struct i2c_adapter adap; @@ -78,6 +75,16 @@ static const struct bitrate_config bitrate_configs[] = { [RZV2M_I2C_400K] = { 52, 900 }, }; +static inline void bit_setl(void __iomem *addr, u32 val) +{ + writel(readl(addr) | val, addr); +} + +static inline void bit_clrl(void __iomem *addr, u32 val) +{ + writel(readl(addr) & ~val, addr); +} + static irqreturn_t rzv2m_i2c_tia_irq_handler(int this_irq, void *dev_id) { struct rzv2m_i2c_priv *priv = dev_id; @@ -382,6 +389,20 @@ static u32 rzv2m_i2c_func(struct i2c_adapter *adap) I2C_FUNC_10BIT_ADDR; } +static int rzv2m_i2c_disable(struct device *dev, struct rzv2m_i2c_priv *priv) +{ + int ret; + + ret = pm_runtime_resume_and_get(dev); + if (ret < 0) + return ret; + + bit_clrl(priv->base + IICB0CTL0, IICB0IICE); + pm_runtime_put(dev); + + return 0; +} + static const struct i2c_adapter_quirks rzv2m_i2c_quirks = { .flags = I2C_AQ_NO_ZERO_LEN, }; @@ -454,37 +475,29 @@ static int rzv2m_i2c_probe(struct platform_device *pdev) platform_set_drvdata(pdev, priv); ret = i2c_add_numbered_adapter(adap); - if (ret < 0) + if (ret < 0) { + rzv2m_i2c_disable(dev, priv); pm_runtime_disable(dev); + } return ret; } -static int rzv2m_i2c_remove(struct platform_device *pdev) +static void rzv2m_i2c_remove(struct platform_device *pdev) { struct rzv2m_i2c_priv *priv = platform_get_drvdata(pdev); struct device *dev = priv->adap.dev.parent; i2c_del_adapter(&priv->adap); - bit_clrl(priv->base + IICB0CTL0, IICB0IICE); + rzv2m_i2c_disable(dev, priv); pm_runtime_disable(dev); - - return 0; } static int rzv2m_i2c_suspend(struct device *dev) { struct rzv2m_i2c_priv *priv = dev_get_drvdata(dev); - int ret; - ret = pm_runtime_resume_and_get(dev); - if (ret < 0) - return ret; - - bit_clrl(priv->base + IICB0CTL0, IICB0IICE); - pm_runtime_put(dev); - - return 0; + return rzv2m_i2c_disable(dev, priv); } static int rzv2m_i2c_resume(struct device *dev) @@ -523,7 +536,7 @@ static struct platform_driver rzv2m_i2c_driver = { .pm = pm_sleep_ptr(&rzv2m_i2c_pm_ops), }, .probe = rzv2m_i2c_probe, - .remove = rzv2m_i2c_remove, + .remove_new = rzv2m_i2c_remove, }; module_platform_driver(rzv2m_i2c_driver); diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c index 45e9df81345a..28f0e5c64f32 100644 --- a/drivers/i2c/busses/i2c-s3c2410.c +++ b/drivers/i2c/busses/i2c-s3c2410.c @@ -1114,7 +1114,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev) return 0; } -static int s3c24xx_i2c_remove(struct platform_device *pdev) +static void s3c24xx_i2c_remove(struct platform_device *pdev) { struct s3c24xx_i2c *i2c = platform_get_drvdata(pdev); @@ -1123,8 +1123,6 @@ static int s3c24xx_i2c_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); i2c_del_adapter(&i2c->adap); - - return 0; } #ifdef CONFIG_PM_SLEEP @@ -1172,7 +1170,7 @@ static const struct dev_pm_ops s3c24xx_i2c_dev_pm_ops = { static struct platform_driver s3c24xx_i2c_driver = { .probe = s3c24xx_i2c_probe, - .remove = s3c24xx_i2c_remove, + .remove_new = s3c24xx_i2c_remove, .id_table = s3c24xx_driver_ids, .driver = { .name = "s3c-i2c", diff --git a/drivers/i2c/busses/i2c-scmi.c b/drivers/i2c/busses/i2c-scmi.c index 0239e134b90f..104570292241 100644 --- a/drivers/i2c/busses/i2c-scmi.c +++ b/drivers/i2c/busses/i2c-scmi.c @@ -404,19 +404,17 @@ err: return ret; } -static int smbus_cmi_remove(struct platform_device *device) +static void smbus_cmi_remove(struct platform_device *device) { struct acpi_smbus_cmi *smbus_cmi = platform_get_drvdata(device); i2c_del_adapter(&smbus_cmi->adapter); kfree(smbus_cmi); - - return 0; } static struct platform_driver smbus_cmi_driver = { .probe = smbus_cmi_probe, - .remove = smbus_cmi_remove, + .remove_new = smbus_cmi_remove, .driver = { .name = "smbus_cmi", .acpi_match_table = acpi_smbus_cmi_ids, diff --git a/drivers/i2c/busses/i2c-sh7760.c b/drivers/i2c/busses/i2c-sh7760.c index 319d1fa617c8..1ad2a26156d1 100644 --- a/drivers/i2c/busses/i2c-sh7760.c +++ b/drivers/i2c/busses/i2c-sh7760.c @@ -443,9 +443,8 @@ static int sh7760_i2c_probe(struct platform_device *pdev) goto out0; } - id = kzalloc(sizeof(struct cami2c), GFP_KERNEL); + id = kzalloc(sizeof(*id), GFP_KERNEL); if (!id) { - dev_err(&pdev->dev, "no mem for private data\n"); ret = -ENOMEM; goto out0; } @@ -536,7 +535,7 @@ out0: return ret; } -static int sh7760_i2c_remove(struct platform_device *pdev) +static void sh7760_i2c_remove(struct platform_device *pdev) { struct cami2c *id = platform_get_drvdata(pdev); @@ -546,8 +545,6 @@ static int sh7760_i2c_remove(struct platform_device *pdev) release_resource(id->ioarea); kfree(id->ioarea); kfree(id); - - return 0; } static struct platform_driver sh7760_i2c_drv = { @@ -555,7 +552,7 @@ static struct platform_driver sh7760_i2c_drv = { .name = SH7760_I2C_DEVNAME, }, .probe = sh7760_i2c_probe, - .remove = sh7760_i2c_remove, + .remove_new = sh7760_i2c_remove, }; module_platform_driver(sh7760_i2c_drv); diff --git a/drivers/i2c/busses/i2c-sh_mobile.c b/drivers/i2c/busses/i2c-sh_mobile.c index 29330ee64c9c..21717b943a9e 100644 --- a/drivers/i2c/busses/i2c-sh_mobile.c +++ b/drivers/i2c/busses/i2c-sh_mobile.c @@ -956,14 +956,13 @@ static int sh_mobile_i2c_probe(struct platform_device *dev) return 0; } -static int sh_mobile_i2c_remove(struct platform_device *dev) +static void sh_mobile_i2c_remove(struct platform_device *dev) { struct sh_mobile_i2c_data *pd = platform_get_drvdata(dev); i2c_del_adapter(&pd->adap); sh_mobile_i2c_release_dma(pd); pm_runtime_disable(&dev->dev); - return 0; } #ifdef CONFIG_PM_SLEEP @@ -1000,7 +999,7 @@ static struct platform_driver sh_mobile_i2c_driver = { .pm = DEV_PM_OPS, }, .probe = sh_mobile_i2c_probe, - .remove = sh_mobile_i2c_remove, + .remove_new = sh_mobile_i2c_remove, }; static int __init sh_mobile_i2c_adap_init(void) diff --git a/drivers/i2c/busses/i2c-simtec.c b/drivers/i2c/busses/i2c-simtec.c index 87701744752f..18516bc64e04 100644 --- a/drivers/i2c/busses/i2c-simtec.c +++ b/drivers/i2c/busses/i2c-simtec.c @@ -126,7 +126,7 @@ static int simtec_i2c_probe(struct platform_device *dev) return ret; } -static int simtec_i2c_remove(struct platform_device *dev) +static void simtec_i2c_remove(struct platform_device *dev) { struct simtec_i2c_data *pd = platform_get_drvdata(dev); @@ -135,8 +135,6 @@ static int simtec_i2c_remove(struct platform_device *dev) iounmap(pd->reg); release_mem_region(pd->ioarea->start, resource_size(pd->ioarea)); kfree(pd); - - return 0; } /* device driver */ @@ -146,7 +144,7 @@ static struct platform_driver simtec_i2c_driver = { .name = "simtec-i2c", }, .probe = simtec_i2c_probe, - .remove = simtec_i2c_remove, + .remove_new = simtec_i2c_remove, }; module_platform_driver(simtec_i2c_driver); diff --git a/drivers/i2c/busses/i2c-st.c b/drivers/i2c/busses/i2c-st.c index f823913b75a6..25c3521cae0e 100644 --- a/drivers/i2c/busses/i2c-st.c +++ b/drivers/i2c/busses/i2c-st.c @@ -876,13 +876,11 @@ static int st_i2c_probe(struct platform_device *pdev) return 0; } -static int st_i2c_remove(struct platform_device *pdev) +static void st_i2c_remove(struct platform_device *pdev) { struct st_i2c_dev *i2c_dev = platform_get_drvdata(pdev); i2c_del_adapter(&i2c_dev->adap); - - return 0; } static const struct of_device_id st_i2c_match[] = { @@ -899,7 +897,7 @@ static struct platform_driver st_i2c_driver = { .pm = pm_sleep_ptr(&st_i2c_pm), }, .probe = st_i2c_probe, - .remove = st_i2c_remove, + .remove_new = st_i2c_remove, }; module_platform_driver(st_i2c_driver); diff --git a/drivers/i2c/busses/i2c-stm32f4.c b/drivers/i2c/busses/i2c-stm32f4.c index eebce7ecef25..6ad06a5a22b4 100644 --- a/drivers/i2c/busses/i2c-stm32f4.c +++ b/drivers/i2c/busses/i2c-stm32f4.c @@ -861,15 +861,13 @@ clk_free: return ret; } -static int stm32f4_i2c_remove(struct platform_device *pdev) +static void stm32f4_i2c_remove(struct platform_device *pdev) { struct stm32f4_i2c_dev *i2c_dev = platform_get_drvdata(pdev); i2c_del_adapter(&i2c_dev->adap); clk_unprepare(i2c_dev->clk); - - return 0; } static const struct of_device_id stm32f4_i2c_match[] = { @@ -884,7 +882,7 @@ static struct platform_driver stm32f4_i2c_driver = { .of_match_table = stm32f4_i2c_match, }, .probe = stm32f4_i2c_probe, - .remove = stm32f4_i2c_remove, + .remove_new = stm32f4_i2c_remove, }; module_platform_driver(stm32f4_i2c_driver); diff --git a/drivers/i2c/busses/i2c-stm32f7.c b/drivers/i2c/busses/i2c-stm32f7.c index d1c59d83a65b..e897d9101434 100644 --- a/drivers/i2c/busses/i2c-stm32f7.c +++ b/drivers/i2c/busses/i2c-stm32f7.c @@ -2309,7 +2309,7 @@ clk_free: return ret; } -static int stm32f7_i2c_remove(struct platform_device *pdev) +static void stm32f7_i2c_remove(struct platform_device *pdev) { struct stm32f7_i2c_dev *i2c_dev = platform_get_drvdata(pdev); @@ -2341,8 +2341,6 @@ static int stm32f7_i2c_remove(struct platform_device *pdev) stm32f7_i2c_write_fm_plus_bits(i2c_dev, false); clk_disable_unprepare(i2c_dev->clk); - - return 0; } static int __maybe_unused stm32f7_i2c_runtime_suspend(struct device *dev) @@ -2486,7 +2484,7 @@ static struct platform_driver stm32f7_i2c_driver = { .pm = &stm32f7_i2c_pm_ops, }, .probe = stm32f7_i2c_probe, - .remove = stm32f7_i2c_remove, + .remove_new = stm32f7_i2c_remove, }; module_platform_driver(stm32f7_i2c_driver); diff --git a/drivers/i2c/busses/i2c-sun6i-p2wi.c b/drivers/i2c/busses/i2c-sun6i-p2wi.c index 9e3483f507ff..ad8270cdbd3e 100644 --- a/drivers/i2c/busses/i2c-sun6i-p2wi.c +++ b/drivers/i2c/busses/i2c-sun6i-p2wi.c @@ -239,15 +239,9 @@ static int p2wi_probe(struct platform_device *pdev) if (irq < 0) return irq; - p2wi->clk = devm_clk_get(dev, NULL); + p2wi->clk = devm_clk_get_enabled(dev, NULL); if (IS_ERR(p2wi->clk)) { ret = PTR_ERR(p2wi->clk); - dev_err(dev, "failed to retrieve clk: %d\n", ret); - return ret; - } - - ret = clk_prepare_enable(p2wi->clk); - if (ret) { dev_err(dev, "failed to enable clk: %d\n", ret); return ret; } @@ -256,15 +250,14 @@ static int p2wi_probe(struct platform_device *pdev) p2wi->rstc = devm_reset_control_get_exclusive(dev, NULL); if (IS_ERR(p2wi->rstc)) { - ret = PTR_ERR(p2wi->rstc); dev_err(dev, "failed to retrieve reset controller: %d\n", ret); - goto err_clk_disable; + return PTR_ERR(p2wi->rstc); } ret = reset_control_deassert(p2wi->rstc); if (ret) { dev_err(dev, "failed to deassert reset line: %d\n", ret); - goto err_clk_disable; + return ret; } init_completion(&p2wi->complete); @@ -307,26 +300,20 @@ static int p2wi_probe(struct platform_device *pdev) err_reset_assert: reset_control_assert(p2wi->rstc); -err_clk_disable: - clk_disable_unprepare(p2wi->clk); - return ret; } -static int p2wi_remove(struct platform_device *dev) +static void p2wi_remove(struct platform_device *dev) { struct p2wi *p2wi = platform_get_drvdata(dev); reset_control_assert(p2wi->rstc); - clk_disable_unprepare(p2wi->clk); i2c_del_adapter(&p2wi->adapter); - - return 0; } static struct platform_driver p2wi_driver = { .probe = p2wi_probe, - .remove = p2wi_remove, + .remove_new = p2wi_remove, .driver = { .name = "i2c-sunxi-p2wi", .of_match_table = p2wi_of_match_table, diff --git a/drivers/i2c/busses/i2c-synquacer.c b/drivers/i2c/busses/i2c-synquacer.c index 50d19cf99a03..4cc196ca8f6d 100644 --- a/drivers/i2c/busses/i2c-synquacer.c +++ b/drivers/i2c/busses/i2c-synquacer.c @@ -618,15 +618,13 @@ static int synquacer_i2c_probe(struct platform_device *pdev) return 0; } -static int synquacer_i2c_remove(struct platform_device *pdev) +static void synquacer_i2c_remove(struct platform_device *pdev) { struct synquacer_i2c *i2c = platform_get_drvdata(pdev); i2c_del_adapter(&i2c->adapter); if (!IS_ERR(i2c->pclk)) clk_disable_unprepare(i2c->pclk); - - return 0; }; static const struct of_device_id synquacer_i2c_dt_ids[] __maybe_unused = { @@ -645,7 +643,7 @@ MODULE_DEVICE_TABLE(acpi, synquacer_i2c_acpi_ids); static struct platform_driver synquacer_i2c_driver = { .probe = synquacer_i2c_probe, - .remove = synquacer_i2c_remove, + .remove_new = synquacer_i2c_remove, .driver = { .name = "synquacer_i2c", .of_match_table = of_match_ptr(synquacer_i2c_dt_ids), diff --git a/drivers/i2c/busses/i2c-tegra-bpmp.c b/drivers/i2c/busses/i2c-tegra-bpmp.c index 95139985b2d5..bc3f94561746 100644 --- a/drivers/i2c/busses/i2c-tegra-bpmp.c +++ b/drivers/i2c/busses/i2c-tegra-bpmp.c @@ -316,13 +316,11 @@ static int tegra_bpmp_i2c_probe(struct platform_device *pdev) return i2c_add_adapter(&i2c->adapter); } -static int tegra_bpmp_i2c_remove(struct platform_device *pdev) +static void tegra_bpmp_i2c_remove(struct platform_device *pdev) { struct tegra_bpmp_i2c *i2c = platform_get_drvdata(pdev); i2c_del_adapter(&i2c->adapter); - - return 0; } static const struct of_device_id tegra_bpmp_i2c_of_match[] = { @@ -337,7 +335,7 @@ static struct platform_driver tegra_bpmp_i2c_driver = { .of_match_table = tegra_bpmp_i2c_of_match, }, .probe = tegra_bpmp_i2c_probe, - .remove = tegra_bpmp_i2c_remove, + .remove_new = tegra_bpmp_i2c_remove, }; module_platform_driver(tegra_bpmp_i2c_driver); diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c index 157066f06a32..bcbbf23aa530 100644 --- a/drivers/i2c/busses/i2c-tegra.c +++ b/drivers/i2c/busses/i2c-tegra.c @@ -249,8 +249,7 @@ struct tegra_i2c_hw_feature { * @msg_read: indicates that the transfer is a read access * @timings: i2c timings information like bus frequency * @multimaster_mode: indicates that I2C controller is in multi-master mode - * @tx_dma_chan: DMA transmit channel - * @rx_dma_chan: DMA receive channel + * @dma_chan: DMA channel * @dma_phys: handle to DMA resources * @dma_buf: pointer to allocated DMA buffer * @dma_buf_size: DMA buffer size @@ -283,8 +282,7 @@ struct tegra_i2c_dev { u8 *msg_buf; struct completion dma_complete; - struct dma_chan *tx_dma_chan; - struct dma_chan *rx_dma_chan; + struct dma_chan *dma_chan; unsigned int dma_buf_size; struct device *dma_dev; dma_addr_t dma_phys; @@ -298,6 +296,9 @@ struct tegra_i2c_dev { bool is_vi; }; +#define IS_DVC(dev) (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) && (dev)->is_dvc) +#define IS_VI(dev) (IS_ENABLED(CONFIG_ARCH_TEGRA_210_SOC) && (dev)->is_vi) + static void dvc_writel(struct tegra_i2c_dev *i2c_dev, u32 val, unsigned int reg) { @@ -315,9 +316,9 @@ static u32 dvc_readl(struct tegra_i2c_dev *i2c_dev, unsigned int reg) */ static u32 tegra_i2c_reg_addr(struct tegra_i2c_dev *i2c_dev, unsigned int reg) { - if (i2c_dev->is_dvc) + if (IS_DVC(i2c_dev)) reg += (reg >= I2C_TX_FIFO) ? 0x10 : 0x40; - else if (i2c_dev->is_vi) + else if (IS_VI(i2c_dev)) reg = 0xc00 + (reg << 2); return reg; @@ -330,7 +331,7 @@ static void i2c_writel(struct tegra_i2c_dev *i2c_dev, u32 val, unsigned int reg) /* read back register to make sure that register writes completed */ if (reg != I2C_TX_FIFO) readl_relaxed(i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg)); - else if (i2c_dev->is_vi) + else if (IS_VI(i2c_dev)) readl_relaxed(i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, I2C_INT_STATUS)); } @@ -393,16 +394,14 @@ static int tegra_i2c_dma_submit(struct tegra_i2c_dev *i2c_dev, size_t len) { struct dma_async_tx_descriptor *dma_desc; enum dma_transfer_direction dir; - struct dma_chan *chan; dev_dbg(i2c_dev->dev, "starting DMA for length: %zu\n", len); reinit_completion(&i2c_dev->dma_complete); dir = i2c_dev->msg_read ? DMA_DEV_TO_MEM : DMA_MEM_TO_DEV; - chan = i2c_dev->msg_read ? i2c_dev->rx_dma_chan : i2c_dev->tx_dma_chan; - dma_desc = dmaengine_prep_slave_single(chan, i2c_dev->dma_phys, + dma_desc = dmaengine_prep_slave_single(i2c_dev->dma_chan, i2c_dev->dma_phys, len, dir, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); if (!dma_desc) { @@ -415,7 +414,7 @@ static int tegra_i2c_dma_submit(struct tegra_i2c_dev *i2c_dev, size_t len) dma_desc->callback_param = i2c_dev; dmaengine_submit(dma_desc); - dma_async_issue_pending(chan); + dma_async_issue_pending(i2c_dev->dma_chan); return 0; } @@ -428,25 +427,19 @@ static void tegra_i2c_release_dma(struct tegra_i2c_dev *i2c_dev) i2c_dev->dma_buf = NULL; } - if (i2c_dev->tx_dma_chan) { - dma_release_channel(i2c_dev->tx_dma_chan); - i2c_dev->tx_dma_chan = NULL; - } - - if (i2c_dev->rx_dma_chan) { - dma_release_channel(i2c_dev->rx_dma_chan); - i2c_dev->rx_dma_chan = NULL; + if (i2c_dev->dma_chan) { + dma_release_channel(i2c_dev->dma_chan); + i2c_dev->dma_chan = NULL; } } static int tegra_i2c_init_dma(struct tegra_i2c_dev *i2c_dev) { - struct dma_chan *chan; dma_addr_t dma_phys; u32 *dma_buf; int err; - if (i2c_dev->is_vi) + if (IS_VI(i2c_dev)) return 0; if (!i2c_dev->hw->has_apb_dma) { @@ -459,25 +452,18 @@ static int tegra_i2c_init_dma(struct tegra_i2c_dev *i2c_dev) return 0; } - chan = dma_request_chan(i2c_dev->dev, "rx"); - if (IS_ERR(chan)) { - err = PTR_ERR(chan); + /* + * The same channel will be used for both RX and TX. + * Keeping the name as "tx" for backward compatibility + * with existing devicetrees. + */ + i2c_dev->dma_chan = dma_request_chan(i2c_dev->dev, "tx"); + if (IS_ERR(i2c_dev->dma_chan)) { + err = PTR_ERR(i2c_dev->dma_chan); goto err_out; } - i2c_dev->rx_dma_chan = chan; - - chan = dma_request_chan(i2c_dev->dev, "tx"); - if (IS_ERR(chan)) { - err = PTR_ERR(chan); - goto err_out; - } - - i2c_dev->tx_dma_chan = chan; - - WARN_ON(i2c_dev->tx_dma_chan->device != i2c_dev->rx_dma_chan->device); - i2c_dev->dma_dev = chan->device->dev; - + i2c_dev->dma_dev = i2c_dev->dma_chan->device->dev; i2c_dev->dma_buf_size = i2c_dev->hw->quirks->max_write_len + I2C_PACKET_HEADER_SIZE; @@ -639,7 +625,7 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev) WARN_ON_ONCE(err); - if (i2c_dev->is_dvc) + if (IS_DVC(i2c_dev)) tegra_dvc_init(i2c_dev); val = I2C_CNFG_NEW_MASTER_FSM | I2C_CNFG_PACKET_MODE_EN | @@ -651,7 +637,7 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev) i2c_writel(i2c_dev, val, I2C_CNFG); i2c_writel(i2c_dev, 0, I2C_INT_MASK); - if (i2c_dev->is_vi) + if (IS_VI(i2c_dev)) tegra_i2c_vi_init(i2c_dev); switch (t->bus_freq_hz) { @@ -703,7 +689,7 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev) return err; } - if (!i2c_dev->is_dvc && !i2c_dev->is_vi) { + if (!IS_DVC(i2c_dev) && !IS_VI(i2c_dev)) { u32 sl_cfg = i2c_readl(i2c_dev, I2C_SL_CNFG); sl_cfg |= I2C_SL_CNFG_NACK | I2C_SL_CNFG_NEWSL; @@ -846,7 +832,7 @@ static int tegra_i2c_fill_tx_fifo(struct tegra_i2c_dev *i2c_dev) i2c_dev->msg_buf_remaining = buf_remaining; i2c_dev->msg_buf = buf + words_to_transfer * BYTES_PER_FIFO_WORD; - if (i2c_dev->is_vi) + if (IS_VI(i2c_dev)) i2c_writesl_vi(i2c_dev, buf, I2C_TX_FIFO, words_to_transfer); else i2c_writesl(i2c_dev, buf, I2C_TX_FIFO, words_to_transfer); @@ -933,7 +919,7 @@ static irqreturn_t tegra_i2c_isr(int irq, void *dev_id) } i2c_writel(i2c_dev, status, I2C_INT_STATUS); - if (i2c_dev->is_dvc) + if (IS_DVC(i2c_dev)) dvc_writel(i2c_dev, DVC_STATUS_I2C_DONE_INTR, DVC_STATUS); /* @@ -972,15 +958,11 @@ err: i2c_writel(i2c_dev, status, I2C_INT_STATUS); - if (i2c_dev->is_dvc) + if (IS_DVC(i2c_dev)) dvc_writel(i2c_dev, DVC_STATUS_I2C_DONE_INTR, DVC_STATUS); if (i2c_dev->dma_mode) { - if (i2c_dev->msg_read) - dmaengine_terminate_async(i2c_dev->rx_dma_chan); - else - dmaengine_terminate_async(i2c_dev->tx_dma_chan); - + dmaengine_terminate_async(i2c_dev->dma_chan); complete(&i2c_dev->dma_complete); } @@ -994,7 +976,6 @@ static void tegra_i2c_config_fifo_trig(struct tegra_i2c_dev *i2c_dev, { struct dma_slave_config slv_config = {0}; u32 val, reg, dma_burst, reg_offset; - struct dma_chan *chan; int err; if (i2c_dev->hw->has_mst_fifo) @@ -1011,7 +992,6 @@ static void tegra_i2c_config_fifo_trig(struct tegra_i2c_dev *i2c_dev, dma_burst = 8; if (i2c_dev->msg_read) { - chan = i2c_dev->rx_dma_chan; reg_offset = tegra_i2c_reg_addr(i2c_dev, I2C_RX_FIFO); slv_config.src_addr = i2c_dev->base_phys + reg_offset; @@ -1023,7 +1003,6 @@ static void tegra_i2c_config_fifo_trig(struct tegra_i2c_dev *i2c_dev, else val = I2C_FIFO_CONTROL_RX_TRIG(dma_burst); } else { - chan = i2c_dev->tx_dma_chan; reg_offset = tegra_i2c_reg_addr(i2c_dev, I2C_TX_FIFO); slv_config.dst_addr = i2c_dev->base_phys + reg_offset; @@ -1037,7 +1016,7 @@ static void tegra_i2c_config_fifo_trig(struct tegra_i2c_dev *i2c_dev, } slv_config.device_fc = true; - err = dmaengine_slave_config(chan, &slv_config); + err = dmaengine_slave_config(i2c_dev->dma_chan, &slv_config); if (err) { dev_err(i2c_dev->dev, "DMA config failed: %d\n", err); dev_err(i2c_dev->dev, "falling back to PIO\n"); @@ -1347,13 +1326,8 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev, * performs synchronization after the transfer's termination * and we want to get a completion if transfer succeeded. */ - dmaengine_synchronize(i2c_dev->msg_read ? - i2c_dev->rx_dma_chan : - i2c_dev->tx_dma_chan); - - dmaengine_terminate_sync(i2c_dev->msg_read ? - i2c_dev->rx_dma_chan : - i2c_dev->tx_dma_chan); + dmaengine_synchronize(i2c_dev->dma_chan); + dmaengine_terminate_sync(i2c_dev->dma_chan); if (!time_left && !completion_done(&i2c_dev->dma_complete)) { dev_err(i2c_dev->dev, "DMA transfer timed out\n"); @@ -1654,13 +1628,17 @@ static const struct tegra_i2c_hw_feature tegra194_i2c_hw = { static const struct of_device_id tegra_i2c_of_match[] = { { .compatible = "nvidia,tegra194-i2c", .data = &tegra194_i2c_hw, }, { .compatible = "nvidia,tegra186-i2c", .data = &tegra186_i2c_hw, }, +#if IS_ENABLED(CONFIG_ARCH_TEGRA_210_SOC) { .compatible = "nvidia,tegra210-i2c-vi", .data = &tegra210_i2c_hw, }, +#endif { .compatible = "nvidia,tegra210-i2c", .data = &tegra210_i2c_hw, }, { .compatible = "nvidia,tegra124-i2c", .data = &tegra124_i2c_hw, }, { .compatible = "nvidia,tegra114-i2c", .data = &tegra114_i2c_hw, }, { .compatible = "nvidia,tegra30-i2c", .data = &tegra30_i2c_hw, }, { .compatible = "nvidia,tegra20-i2c", .data = &tegra20_i2c_hw, }, +#if IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) { .compatible = "nvidia,tegra20-i2c-dvc", .data = &tegra20_i2c_hw, }, +#endif {}, }; MODULE_DEVICE_TABLE(of, tegra_i2c_of_match); @@ -1675,10 +1653,12 @@ static void tegra_i2c_parse_dt(struct tegra_i2c_dev *i2c_dev) multi_mode = device_property_read_bool(i2c_dev->dev, "multi-master"); i2c_dev->multimaster_mode = multi_mode; - if (of_device_is_compatible(np, "nvidia,tegra20-i2c-dvc")) + if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) && + of_device_is_compatible(np, "nvidia,tegra20-i2c-dvc")) i2c_dev->is_dvc = true; - if (of_device_is_compatible(np, "nvidia,tegra210-i2c-vi")) + if (IS_ENABLED(CONFIG_ARCH_TEGRA_210_SOC) && + of_device_is_compatible(np, "nvidia,tegra210-i2c-vi")) i2c_dev->is_vi = true; } @@ -1707,7 +1687,7 @@ static int tegra_i2c_init_clocks(struct tegra_i2c_dev *i2c_dev) if (i2c_dev->hw == &tegra20_i2c_hw || i2c_dev->hw == &tegra30_i2c_hw) i2c_dev->clocks[i2c_dev->nclocks++].id = "fast-clk"; - if (i2c_dev->is_vi) + if (IS_VI(i2c_dev)) i2c_dev->clocks[i2c_dev->nclocks++].id = "slow"; err = devm_clk_bulk_get(i2c_dev->dev, i2c_dev->nclocks, @@ -1825,7 +1805,7 @@ static int tegra_i2c_probe(struct platform_device *pdev) * VI I2C device shouldn't be marked as IRQ-safe because VI I2C won't * be used for atomic transfers. */ - if (!i2c_dev->is_vi) + if (!IS_VI(i2c_dev)) pm_runtime_irq_safe(i2c_dev->dev); pm_runtime_enable(i2c_dev->dev); @@ -1868,7 +1848,7 @@ release_clocks: return err; } -static int tegra_i2c_remove(struct platform_device *pdev) +static void tegra_i2c_remove(struct platform_device *pdev) { struct tegra_i2c_dev *i2c_dev = platform_get_drvdata(pdev); @@ -1877,8 +1857,6 @@ static int tegra_i2c_remove(struct platform_device *pdev) tegra_i2c_release_dma(i2c_dev); tegra_i2c_release_clocks(i2c_dev); - - return 0; } static int __maybe_unused tegra_i2c_runtime_resume(struct device *dev) @@ -1899,7 +1877,7 @@ static int __maybe_unused tegra_i2c_runtime_resume(struct device *dev) * power ON/OFF during runtime PM resume/suspend, meaning that * controller needs to be re-initialized after power ON. */ - if (i2c_dev->is_vi) { + if (IS_VI(i2c_dev)) { err = tegra_i2c_init(i2c_dev); if (err) goto disable_clocks; @@ -1987,7 +1965,7 @@ MODULE_DEVICE_TABLE(acpi, tegra_i2c_acpi_match); static struct platform_driver tegra_i2c_driver = { .probe = tegra_i2c_probe, - .remove = tegra_i2c_remove, + .remove_new = tegra_i2c_remove, .driver = { .name = "tegra-i2c", .of_match_table = tegra_i2c_of_match, diff --git a/drivers/i2c/busses/i2c-tiny-usb.c b/drivers/i2c/busses/i2c-tiny-usb.c index 7279ca0eaa2d..d1fa9ff5aeab 100644 --- a/drivers/i2c/busses/i2c-tiny-usb.c +++ b/drivers/i2c/busses/i2c-tiny-usb.c @@ -226,10 +226,8 @@ static int i2c_tiny_usb_probe(struct usb_interface *interface, /* allocate memory for our device state and initialize it */ dev = kzalloc(sizeof(*dev), GFP_KERNEL); - if (dev == NULL) { - dev_err(&interface->dev, "Out of memory\n"); + if (!dev) goto error; - } dev->usb_dev = usb_get_dev(interface_to_usbdev(interface)); dev->interface = interface; diff --git a/drivers/i2c/busses/i2c-uniphier-f.c b/drivers/i2c/busses/i2c-uniphier-f.c index d7b622891e52..dbc91c7c3788 100644 --- a/drivers/i2c/busses/i2c-uniphier-f.c +++ b/drivers/i2c/busses/i2c-uniphier-f.c @@ -540,21 +540,16 @@ static int uniphier_fi2c_probe(struct platform_device *pdev) return -EINVAL; } - priv->clk = devm_clk_get(dev, NULL); + priv->clk = devm_clk_get_enabled(dev, NULL); if (IS_ERR(priv->clk)) { - dev_err(dev, "failed to get clock\n"); + dev_err(dev, "failed to enable clock\n"); return PTR_ERR(priv->clk); } - ret = clk_prepare_enable(priv->clk); - if (ret) - return ret; - clk_rate = clk_get_rate(priv->clk); if (!clk_rate) { dev_err(dev, "input clock rate should not be zero\n"); - ret = -EINVAL; - goto disable_clk; + return -EINVAL; } priv->clk_cycle = clk_rate / bus_speed; @@ -575,25 +570,17 @@ static int uniphier_fi2c_probe(struct platform_device *pdev) pdev->name, priv); if (ret) { dev_err(dev, "failed to request irq %d\n", irq); - goto disable_clk; + return ret; } - ret = i2c_add_adapter(&priv->adap); -disable_clk: - if (ret) - clk_disable_unprepare(priv->clk); - - return ret; + return i2c_add_adapter(&priv->adap); } -static int uniphier_fi2c_remove(struct platform_device *pdev) +static void uniphier_fi2c_remove(struct platform_device *pdev) { struct uniphier_fi2c_priv *priv = platform_get_drvdata(pdev); i2c_del_adapter(&priv->adap); - clk_disable_unprepare(priv->clk); - - return 0; } static int __maybe_unused uniphier_fi2c_suspend(struct device *dev) @@ -631,7 +618,7 @@ MODULE_DEVICE_TABLE(of, uniphier_fi2c_match); static struct platform_driver uniphier_fi2c_drv = { .probe = uniphier_fi2c_probe, - .remove = uniphier_fi2c_remove, + .remove_new = uniphier_fi2c_remove, .driver = { .name = "uniphier-fi2c", .of_match_table = uniphier_fi2c_match, diff --git a/drivers/i2c/busses/i2c-uniphier.c b/drivers/i2c/busses/i2c-uniphier.c index e3ebae381f08..854ac25b5862 100644 --- a/drivers/i2c/busses/i2c-uniphier.c +++ b/drivers/i2c/busses/i2c-uniphier.c @@ -335,21 +335,16 @@ static int uniphier_i2c_probe(struct platform_device *pdev) return -EINVAL; } - priv->clk = devm_clk_get(dev, NULL); + priv->clk = devm_clk_get_enabled(dev, NULL); if (IS_ERR(priv->clk)) { - dev_err(dev, "failed to get clock\n"); + dev_err(dev, "failed to enable clock\n"); return PTR_ERR(priv->clk); } - ret = clk_prepare_enable(priv->clk); - if (ret) - return ret; - clk_rate = clk_get_rate(priv->clk); if (!clk_rate) { dev_err(dev, "input clock rate should not be zero\n"); - ret = -EINVAL; - goto disable_clk; + return -EINVAL; } priv->clk_cycle = clk_rate / bus_speed; @@ -369,25 +364,17 @@ static int uniphier_i2c_probe(struct platform_device *pdev) priv); if (ret) { dev_err(dev, "failed to request irq %d\n", irq); - goto disable_clk; + return ret; } - ret = i2c_add_adapter(&priv->adap); -disable_clk: - if (ret) - clk_disable_unprepare(priv->clk); - - return ret; + return i2c_add_adapter(&priv->adap); } -static int uniphier_i2c_remove(struct platform_device *pdev) +static void uniphier_i2c_remove(struct platform_device *pdev) { struct uniphier_i2c_priv *priv = platform_get_drvdata(pdev); i2c_del_adapter(&priv->adap); - clk_disable_unprepare(priv->clk); - - return 0; } static int __maybe_unused uniphier_i2c_suspend(struct device *dev) @@ -425,7 +412,7 @@ MODULE_DEVICE_TABLE(of, uniphier_i2c_match); static struct platform_driver uniphier_i2c_drv = { .probe = uniphier_i2c_probe, - .remove = uniphier_i2c_remove, + .remove_new = uniphier_i2c_remove, .driver = { .name = "uniphier-i2c", .of_match_table = uniphier_i2c_match, diff --git a/drivers/i2c/busses/i2c-versatile.c b/drivers/i2c/busses/i2c-versatile.c index 1ab419f8fa52..76abfa77e200 100644 --- a/drivers/i2c/busses/i2c-versatile.c +++ b/drivers/i2c/busses/i2c-versatile.c @@ -64,15 +64,13 @@ static const struct i2c_algo_bit_data i2c_versatile_algo = { static int i2c_versatile_probe(struct platform_device *dev) { struct i2c_versatile *i2c; - struct resource *r; int ret; i2c = devm_kzalloc(&dev->dev, sizeof(struct i2c_versatile), GFP_KERNEL); if (!i2c) return -ENOMEM; - r = platform_get_resource(dev, IORESOURCE_MEM, 0); - i2c->base = devm_ioremap_resource(&dev->dev, r); + i2c->base = devm_platform_get_and_ioremap_resource(dev, 0, NULL); if (IS_ERR(i2c->base)) return PTR_ERR(i2c->base); @@ -96,12 +94,11 @@ static int i2c_versatile_probe(struct platform_device *dev) return 0; } -static int i2c_versatile_remove(struct platform_device *dev) +static void i2c_versatile_remove(struct platform_device *dev) { struct i2c_versatile *i2c = platform_get_drvdata(dev); i2c_del_adapter(&i2c->adap); - return 0; } static const struct of_device_id i2c_versatile_match[] = { @@ -112,7 +109,7 @@ MODULE_DEVICE_TABLE(of, i2c_versatile_match); static struct platform_driver i2c_versatile_driver = { .probe = i2c_versatile_probe, - .remove = i2c_versatile_remove, + .remove_new = i2c_versatile_remove, .driver = { .name = "versatile-i2c", .of_match_table = i2c_versatile_match, diff --git a/drivers/i2c/busses/i2c-viperboard.c b/drivers/i2c/busses/i2c-viperboard.c index 8b5322c3bce0..9e153b5b0e8e 100644 --- a/drivers/i2c/busses/i2c-viperboard.c +++ b/drivers/i2c/busses/i2c-viperboard.c @@ -407,20 +407,18 @@ static int vprbrd_i2c_probe(struct platform_device *pdev) return 0; } -static int vprbrd_i2c_remove(struct platform_device *pdev) +static void vprbrd_i2c_remove(struct platform_device *pdev) { struct vprbrd_i2c *vb_i2c = platform_get_drvdata(pdev); i2c_del_adapter(&vb_i2c->i2c); - - return 0; } static struct platform_driver vprbrd_i2c_driver = { .driver.name = "viperboard-i2c", .driver.owner = THIS_MODULE, .probe = vprbrd_i2c_probe, - .remove = vprbrd_i2c_remove, + .remove_new = vprbrd_i2c_remove, }; static int __init vprbrd_i2c_init(void) diff --git a/drivers/i2c/busses/i2c-wmt.c b/drivers/i2c/busses/i2c-wmt.c index 7d4bc8736079..76118abc6e10 100644 --- a/drivers/i2c/busses/i2c-wmt.c +++ b/drivers/i2c/busses/i2c-wmt.c @@ -372,7 +372,6 @@ static int wmt_i2c_probe(struct platform_device *pdev) struct device_node *np = pdev->dev.of_node; struct wmt_i2c_dev *i2c_dev; struct i2c_adapter *adap; - struct resource *res; int err; u32 clk_rate; @@ -380,8 +379,7 @@ static int wmt_i2c_probe(struct platform_device *pdev) if (!i2c_dev) return -ENOMEM; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - i2c_dev->base = devm_ioremap_resource(&pdev->dev, res); + i2c_dev->base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL); if (IS_ERR(i2c_dev->base)) return PTR_ERR(i2c_dev->base); @@ -436,7 +434,7 @@ static int wmt_i2c_probe(struct platform_device *pdev) return 0; } -static int wmt_i2c_remove(struct platform_device *pdev) +static void wmt_i2c_remove(struct platform_device *pdev) { struct wmt_i2c_dev *i2c_dev = platform_get_drvdata(pdev); @@ -444,8 +442,6 @@ static int wmt_i2c_remove(struct platform_device *pdev) writew(0, i2c_dev->base + REG_IMR); clk_disable_unprepare(i2c_dev->clk); i2c_del_adapter(&i2c_dev->adapter); - - return 0; } static const struct of_device_id wmt_i2c_dt_ids[] = { @@ -455,7 +451,7 @@ static const struct of_device_id wmt_i2c_dt_ids[] = { static struct platform_driver wmt_i2c_driver = { .probe = wmt_i2c_probe, - .remove = wmt_i2c_remove, + .remove_new = wmt_i2c_remove, .driver = { .name = "wmt-i2c", .of_match_table = wmt_i2c_dt_ids, diff --git a/drivers/i2c/busses/i2c-xgene-slimpro.c b/drivers/i2c/busses/i2c-xgene-slimpro.c index 3538d36368a9..fbc1ffbd2fa7 100644 --- a/drivers/i2c/busses/i2c-xgene-slimpro.c +++ b/drivers/i2c/busses/i2c-xgene-slimpro.c @@ -560,7 +560,7 @@ mbox_err: return rc; } -static int xgene_slimpro_i2c_remove(struct platform_device *pdev) +static void xgene_slimpro_i2c_remove(struct platform_device *pdev) { struct slimpro_i2c_dev *ctx = platform_get_drvdata(pdev); @@ -570,8 +570,6 @@ static int xgene_slimpro_i2c_remove(struct platform_device *pdev) mbox_free_channel(ctx->mbox_chan); else pcc_mbox_free_channel(ctx->pcc_chan); - - return 0; } static const struct of_device_id xgene_slimpro_i2c_dt_ids[] = { @@ -591,7 +589,7 @@ MODULE_DEVICE_TABLE(acpi, xgene_slimpro_i2c_acpi_ids); static struct platform_driver xgene_slimpro_i2c_driver = { .probe = xgene_slimpro_i2c_probe, - .remove = xgene_slimpro_i2c_remove, + .remove_new = xgene_slimpro_i2c_remove, .driver = { .name = "xgene-slimpro-i2c", .of_match_table = of_match_ptr(xgene_slimpro_i2c_dt_ids), diff --git a/drivers/i2c/busses/i2c-xiic.c b/drivers/i2c/busses/i2c-xiic.c index 8a3d9817cb41..f879af4def5e 100644 --- a/drivers/i2c/busses/i2c-xiic.c +++ b/drivers/i2c/busses/i2c-xiic.c @@ -1256,16 +1256,11 @@ static int xiic_i2c_probe(struct platform_device *pdev) mutex_init(&i2c->lock); - i2c->clk = devm_clk_get(&pdev->dev, NULL); + i2c->clk = devm_clk_get_enabled(&pdev->dev, NULL); if (IS_ERR(i2c->clk)) return dev_err_probe(&pdev->dev, PTR_ERR(i2c->clk), - "input clock not found.\n"); + "failed to enable input clock.\n"); - ret = clk_prepare_enable(i2c->clk); - if (ret) { - dev_err(&pdev->dev, "Unable to enable clock.\n"); - return ret; - } i2c->dev = &pdev->dev; pm_runtime_set_autosuspend_delay(i2c->dev, XIIC_PM_TIMEOUT); pm_runtime_use_autosuspend(i2c->dev); @@ -1286,7 +1281,7 @@ static int xiic_i2c_probe(struct platform_device *pdev) if (ret < 0) { dev_err(&pdev->dev, "Cannot claim IRQ\n"); - goto err_clk_dis; + goto err_pm_disable; } i2c->singlemaster = @@ -1307,14 +1302,14 @@ static int xiic_i2c_probe(struct platform_device *pdev) ret = xiic_reinit(i2c); if (ret < 0) { dev_err(&pdev->dev, "Cannot xiic_reinit\n"); - goto err_clk_dis; + goto err_pm_disable; } /* add i2c adapter to i2c tree */ ret = i2c_add_adapter(&i2c->adap); if (ret) { xiic_deinit(i2c); - goto err_clk_dis; + goto err_pm_disable; } if (pdata) { @@ -1328,14 +1323,14 @@ static int xiic_i2c_probe(struct platform_device *pdev) return 0; -err_clk_dis: +err_pm_disable: pm_runtime_set_suspended(&pdev->dev); pm_runtime_disable(&pdev->dev); - clk_disable_unprepare(i2c->clk); + return ret; } -static int xiic_i2c_remove(struct platform_device *pdev) +static void xiic_i2c_remove(struct platform_device *pdev) { struct xiic_i2c *i2c = platform_get_drvdata(pdev); int ret; @@ -1352,12 +1347,9 @@ static int xiic_i2c_remove(struct platform_device *pdev) xiic_deinit(i2c); pm_runtime_put_sync(i2c->dev); - clk_disable_unprepare(i2c->clk); pm_runtime_disable(&pdev->dev); pm_runtime_set_suspended(&pdev->dev); pm_runtime_dont_use_autosuspend(&pdev->dev); - - return 0; } static int __maybe_unused xiic_i2c_runtime_suspend(struct device *dev) @@ -1390,7 +1382,7 @@ static const struct dev_pm_ops xiic_dev_pm_ops = { static struct platform_driver xiic_i2c_driver = { .probe = xiic_i2c_probe, - .remove = xiic_i2c_remove, + .remove_new = xiic_i2c_remove, .driver = { .name = DRIVER_NAME, .of_match_table = of_match_ptr(xiic_of_match), diff --git a/drivers/i2c/busses/i2c-xlp9xx.c b/drivers/i2c/busses/i2c-xlp9xx.c index 4e3b11c0f732..f59e8c544f36 100644 --- a/drivers/i2c/busses/i2c-xlp9xx.c +++ b/drivers/i2c/busses/i2c-xlp9xx.c @@ -559,7 +559,7 @@ static int xlp9xx_i2c_probe(struct platform_device *pdev) return 0; } -static int xlp9xx_i2c_remove(struct platform_device *pdev) +static void xlp9xx_i2c_remove(struct platform_device *pdev) { struct xlp9xx_i2c_dev *priv; @@ -568,8 +568,6 @@ static int xlp9xx_i2c_remove(struct platform_device *pdev) synchronize_irq(priv->irq); i2c_del_adapter(&priv->adapter); xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_CTRL, 0); - - return 0; } #ifdef CONFIG_ACPI @@ -583,7 +581,7 @@ MODULE_DEVICE_TABLE(acpi, xlp9xx_i2c_acpi_ids); static struct platform_driver xlp9xx_i2c_driver = { .probe = xlp9xx_i2c_probe, - .remove = xlp9xx_i2c_remove, + .remove_new = xlp9xx_i2c_remove, .driver = { .name = "xlp9xx-i2c", .acpi_match_table = ACPI_PTR(xlp9xx_i2c_acpi_ids), diff --git a/drivers/i2c/busses/scx200_acb.c b/drivers/i2c/busses/scx200_acb.c index 7b42a18bd05c..83c1db610f54 100644 --- a/drivers/i2c/busses/scx200_acb.c +++ b/drivers/i2c/busses/scx200_acb.c @@ -523,14 +523,12 @@ static void scx200_cleanup_iface(struct scx200_acb_iface *iface) kfree(iface); } -static int scx200_remove(struct platform_device *pdev) +static void scx200_remove(struct platform_device *pdev) { struct scx200_acb_iface *iface; iface = platform_get_drvdata(pdev); scx200_cleanup_iface(iface); - - return 0; } static struct platform_driver scx200_pci_driver = { @@ -538,7 +536,7 @@ static struct platform_driver scx200_pci_driver = { .name = "cs5535-smb", }, .probe = scx200_probe, - .remove = scx200_remove, + .remove_new = scx200_remove, }; static const struct pci_device_id scx200_isa[] = { diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c index ae3af738b03f..60746652fd52 100644 --- a/drivers/i2c/i2c-core-base.c +++ b/drivers/i2c/i2c-core-base.c @@ -114,6 +114,25 @@ const struct i2c_device_id *i2c_match_id(const struct i2c_device_id *id, } EXPORT_SYMBOL_GPL(i2c_match_id); +const void *i2c_get_match_data(const struct i2c_client *client) +{ + struct i2c_driver *driver = to_i2c_driver(client->dev.driver); + const struct i2c_device_id *match; + const void *data; + + data = device_get_match_data(&client->dev); + if (!data) { + match = i2c_match_id(driver->id_table, client); + if (!match) + return NULL; + + data = (const void *)match->driver_data; + } + + return data; +} +EXPORT_SYMBOL(i2c_get_match_data); + static int i2c_device_match(struct device *dev, struct device_driver *drv) { struct i2c_client *client = i2c_verify_client(dev); diff --git a/drivers/i2c/muxes/i2c-arb-gpio-challenge.c b/drivers/i2c/muxes/i2c-arb-gpio-challenge.c index 1c78657631f4..24168e9f7df4 100644 --- a/drivers/i2c/muxes/i2c-arb-gpio-challenge.c +++ b/drivers/i2c/muxes/i2c-arb-gpio-challenge.c @@ -174,13 +174,12 @@ static int i2c_arbitrator_probe(struct platform_device *pdev) return ret; } -static int i2c_arbitrator_remove(struct platform_device *pdev) +static void i2c_arbitrator_remove(struct platform_device *pdev) { struct i2c_mux_core *muxc = platform_get_drvdata(pdev); i2c_mux_del_adapters(muxc); i2c_put_adapter(muxc->parent); - return 0; } static const struct of_device_id i2c_arbitrator_of_match[] = { @@ -191,7 +190,7 @@ MODULE_DEVICE_TABLE(of, i2c_arbitrator_of_match); static struct platform_driver i2c_arbitrator_driver = { .probe = i2c_arbitrator_probe, - .remove = i2c_arbitrator_remove, + .remove_new = i2c_arbitrator_remove, .driver = { .name = "i2c-arb-gpio-challenge", .of_match_table = i2c_arbitrator_of_match, diff --git a/drivers/i2c/muxes/i2c-demux-pinctrl.c b/drivers/i2c/muxes/i2c-demux-pinctrl.c index f7a7405d4350..a3a122fae71e 100644 --- a/drivers/i2c/muxes/i2c-demux-pinctrl.c +++ b/drivers/i2c/muxes/i2c-demux-pinctrl.c @@ -282,7 +282,7 @@ err_rollback: return err; } -static int i2c_demux_pinctrl_remove(struct platform_device *pdev) +static void i2c_demux_pinctrl_remove(struct platform_device *pdev) { struct i2c_demux_pinctrl_priv *priv = platform_get_drvdata(pdev); int i; @@ -296,8 +296,6 @@ static int i2c_demux_pinctrl_remove(struct platform_device *pdev) of_node_put(priv->chan[i].parent_np); of_changeset_destroy(&priv->chan[i].chgset); } - - return 0; } static const struct of_device_id i2c_demux_pinctrl_of_match[] = { @@ -312,7 +310,7 @@ static struct platform_driver i2c_demux_pinctrl_driver = { .of_match_table = i2c_demux_pinctrl_of_match, }, .probe = i2c_demux_pinctrl_probe, - .remove = i2c_demux_pinctrl_remove, + .remove_new = i2c_demux_pinctrl_remove, }; module_platform_driver(i2c_demux_pinctrl_driver); diff --git a/drivers/i2c/muxes/i2c-mux-gpio.c b/drivers/i2c/muxes/i2c-mux-gpio.c index 73a23e117ebe..5d5cbe0130cd 100644 --- a/drivers/i2c/muxes/i2c-mux-gpio.c +++ b/drivers/i2c/muxes/i2c-mux-gpio.c @@ -225,14 +225,12 @@ alloc_failed: return ret; } -static int i2c_mux_gpio_remove(struct platform_device *pdev) +static void i2c_mux_gpio_remove(struct platform_device *pdev) { struct i2c_mux_core *muxc = platform_get_drvdata(pdev); i2c_mux_del_adapters(muxc); i2c_put_adapter(muxc->parent); - - return 0; } static const struct of_device_id i2c_mux_gpio_of_match[] = { @@ -243,7 +241,7 @@ MODULE_DEVICE_TABLE(of, i2c_mux_gpio_of_match); static struct platform_driver i2c_mux_gpio_driver = { .probe = i2c_mux_gpio_probe, - .remove = i2c_mux_gpio_remove, + .remove_new = i2c_mux_gpio_remove, .driver = { .name = "i2c-mux-gpio", .of_match_table = i2c_mux_gpio_of_match, diff --git a/drivers/i2c/muxes/i2c-mux-gpmux.c b/drivers/i2c/muxes/i2c-mux-gpmux.c index 33024acaac02..0405af0e1510 100644 --- a/drivers/i2c/muxes/i2c-mux-gpmux.c +++ b/drivers/i2c/muxes/i2c-mux-gpmux.c @@ -142,19 +142,17 @@ err_parent: return ret; } -static int i2c_mux_remove(struct platform_device *pdev) +static void i2c_mux_remove(struct platform_device *pdev) { struct i2c_mux_core *muxc = platform_get_drvdata(pdev); i2c_mux_del_adapters(muxc); i2c_put_adapter(muxc->parent); - - return 0; } static struct platform_driver i2c_mux_driver = { .probe = i2c_mux_probe, - .remove = i2c_mux_remove, + .remove_new = i2c_mux_remove, .driver = { .name = "i2c-mux-gpmux", .of_match_table = i2c_mux_of_match, diff --git a/drivers/i2c/muxes/i2c-mux-mlxcpld.c b/drivers/i2c/muxes/i2c-mux-mlxcpld.c index 1a879f6a31ef..3dda00f1df78 100644 --- a/drivers/i2c/muxes/i2c-mux-mlxcpld.c +++ b/drivers/i2c/muxes/i2c-mux-mlxcpld.c @@ -170,12 +170,11 @@ virt_reg_failed: return err; } -static int mlxcpld_mux_remove(struct platform_device *pdev) +static void mlxcpld_mux_remove(struct platform_device *pdev) { struct i2c_mux_core *muxc = platform_get_drvdata(pdev); i2c_mux_del_adapters(muxc); - return 0; } static struct platform_driver mlxcpld_mux_driver = { @@ -183,7 +182,7 @@ static struct platform_driver mlxcpld_mux_driver = { .name = "i2c-mux-mlxcpld", }, .probe = mlxcpld_mux_probe, - .remove = mlxcpld_mux_remove, + .remove_new = mlxcpld_mux_remove, }; module_platform_driver(mlxcpld_mux_driver); diff --git a/drivers/i2c/muxes/i2c-mux-pinctrl.c b/drivers/i2c/muxes/i2c-mux-pinctrl.c index d5ad904756fd..18236b9fa14a 100644 --- a/drivers/i2c/muxes/i2c-mux-pinctrl.c +++ b/drivers/i2c/muxes/i2c-mux-pinctrl.c @@ -166,14 +166,12 @@ err_put_parent: return ret; } -static int i2c_mux_pinctrl_remove(struct platform_device *pdev) +static void i2c_mux_pinctrl_remove(struct platform_device *pdev) { struct i2c_mux_core *muxc = platform_get_drvdata(pdev); i2c_mux_del_adapters(muxc); i2c_put_adapter(muxc->parent); - - return 0; } static const struct of_device_id i2c_mux_pinctrl_of_match[] = { @@ -188,7 +186,7 @@ static struct platform_driver i2c_mux_pinctrl_driver = { .of_match_table = i2c_mux_pinctrl_of_match, }, .probe = i2c_mux_pinctrl_probe, - .remove = i2c_mux_pinctrl_remove, + .remove_new = i2c_mux_pinctrl_remove, }; module_platform_driver(i2c_mux_pinctrl_driver); diff --git a/drivers/i2c/muxes/i2c-mux-reg.c b/drivers/i2c/muxes/i2c-mux-reg.c index 30a6de1694e0..9efc1ed01577 100644 --- a/drivers/i2c/muxes/i2c-mux-reg.c +++ b/drivers/i2c/muxes/i2c-mux-reg.c @@ -233,14 +233,12 @@ err_put_parent: return ret; } -static int i2c_mux_reg_remove(struct platform_device *pdev) +static void i2c_mux_reg_remove(struct platform_device *pdev) { struct i2c_mux_core *muxc = platform_get_drvdata(pdev); i2c_mux_del_adapters(muxc); i2c_put_adapter(muxc->parent); - - return 0; } static const struct of_device_id i2c_mux_reg_of_match[] = { @@ -251,7 +249,7 @@ MODULE_DEVICE_TABLE(of, i2c_mux_reg_of_match); static struct platform_driver i2c_mux_reg_driver = { .probe = i2c_mux_reg_probe, - .remove = i2c_mux_reg_remove, + .remove_new = i2c_mux_reg_remove, .driver = { .name = "i2c-mux-reg", .of_match_table = of_match_ptr(i2c_mux_reg_of_match), diff --git a/drivers/i3c/master/svc-i3c-master.c b/drivers/i3c/master/svc-i3c-master.c index e3f454123805..0d63b732ef0c 100644 --- a/drivers/i3c/master/svc-i3c-master.c +++ b/drivers/i3c/master/svc-i3c-master.c @@ -92,6 +92,7 @@ #define SVC_I3C_MINTCLR 0x094 #define SVC_I3C_MINTMASKED 0x098 #define SVC_I3C_MERRWARN 0x09C +#define SVC_I3C_MERRWARN_NACK BIT(2) #define SVC_I3C_MDMACTRL 0x0A0 #define SVC_I3C_MDATACTRL 0x0AC #define SVC_I3C_MDATACTRL_FLUSHTB BIT(0) @@ -145,6 +146,11 @@ struct svc_i3c_xfer { struct svc_i3c_cmd cmds[]; }; +struct svc_i3c_regs_save { + u32 mconfig; + u32 mdynaddr; +}; + /** * struct svc_i3c_master - Silvaco I3C Master structure * @base: I3C master controller @@ -173,6 +179,7 @@ struct svc_i3c_master { struct i3c_master_controller base; struct device *dev; void __iomem *regs; + struct svc_i3c_regs_save saved_regs; u32 free_slots; u8 addrs[SVC_I3C_MAX_DEVS]; struct i3c_dev_desc *descs[SVC_I3C_MAX_DEVS]; @@ -1008,6 +1015,11 @@ static int svc_i3c_master_xfer(struct svc_i3c_master *master, if (ret) goto emit_stop; + if (readl(master->regs + SVC_I3C_MERRWARN) & SVC_I3C_MERRWARN_NACK) { + ret = -ENXIO; + goto emit_stop; + } + if (rnw) ret = svc_i3c_master_read(master, in, xfer_len); else @@ -1090,12 +1102,6 @@ static void svc_i3c_master_start_xfer_locked(struct svc_i3c_master *master) if (!xfer) return; - ret = pm_runtime_resume_and_get(master->dev); - if (ret < 0) { - dev_err(master->dev, "<%s> Cannot get runtime PM.\n", __func__); - return; - } - svc_i3c_master_clear_merrwarn(master); svc_i3c_master_flush_fifo(master); @@ -1110,9 +1116,6 @@ static void svc_i3c_master_start_xfer_locked(struct svc_i3c_master *master) break; } - pm_runtime_mark_last_busy(master->dev); - pm_runtime_put_autosuspend(master->dev); - xfer->ret = ret; complete(&xfer->comp); @@ -1133,6 +1136,13 @@ static void svc_i3c_master_enqueue_xfer(struct svc_i3c_master *master, struct svc_i3c_xfer *xfer) { unsigned long flags; + int ret; + + ret = pm_runtime_resume_and_get(master->dev); + if (ret < 0) { + dev_err(master->dev, "<%s> Cannot get runtime PM.\n", __func__); + return; + } init_completion(&xfer->comp); spin_lock_irqsave(&master->xferqueue.lock, flags); @@ -1143,6 +1153,9 @@ static void svc_i3c_master_enqueue_xfer(struct svc_i3c_master *master, svc_i3c_master_start_xfer_locked(master); } spin_unlock_irqrestore(&master->xferqueue.lock, flags); + + pm_runtime_mark_last_busy(master->dev); + pm_runtime_put_autosuspend(master->dev); } static bool @@ -1579,10 +1592,28 @@ static void svc_i3c_master_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); } +static void svc_i3c_save_regs(struct svc_i3c_master *master) +{ + master->saved_regs.mconfig = readl(master->regs + SVC_I3C_MCONFIG); + master->saved_regs.mdynaddr = readl(master->regs + SVC_I3C_MDYNADDR); +} + +static void svc_i3c_restore_regs(struct svc_i3c_master *master) +{ + if (readl(master->regs + SVC_I3C_MDYNADDR) != + master->saved_regs.mdynaddr) { + writel(master->saved_regs.mconfig, + master->regs + SVC_I3C_MCONFIG); + writel(master->saved_regs.mdynaddr, + master->regs + SVC_I3C_MDYNADDR); + } +} + static int __maybe_unused svc_i3c_runtime_suspend(struct device *dev) { struct svc_i3c_master *master = dev_get_drvdata(dev); + svc_i3c_save_regs(master); svc_i3c_master_unprepare_clks(master); pinctrl_pm_select_sleep_state(dev); @@ -1596,6 +1627,8 @@ static int __maybe_unused svc_i3c_runtime_resume(struct device *dev) pinctrl_pm_select_default_state(dev); svc_i3c_master_prepare_clks(master); + svc_i3c_restore_regs(master); + return 0; } diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index eb2b09ef5d5b..08b8f27afbbf 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -735,6 +735,17 @@ config MAX1363 To compile this driver as a module, choose M here: the module will be called max1363. +config MAX77541_ADC + tristate "Analog Devices MAX77541 ADC driver" + depends on MFD_MAX77541 + help + This driver controls a Analog Devices MAX77541 ADC + via I2C bus. This device has one adc. Say yes here to build + support for Analog Devices MAX77541 ADC interface. + + To compile this driver as a module, choose M here: + the module will be called max77541-adc. + config MAX9611 tristate "Maxim max9611/max9612 ADC driver" depends on I2C diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile index e07e4a3e6237..eb6e891790fb 100644 --- a/drivers/iio/adc/Makefile +++ b/drivers/iio/adc/Makefile @@ -67,6 +67,7 @@ obj-$(CONFIG_MAX11205) += max11205.o obj-$(CONFIG_MAX11410) += max11410.o obj-$(CONFIG_MAX1241) += max1241.o obj-$(CONFIG_MAX1363) += max1363.o +obj-$(CONFIG_MAX77541_ADC) += max77541-adc.o obj-$(CONFIG_MAX9611) += max9611.o obj-$(CONFIG_MCP320X) += mcp320x.o obj-$(CONFIG_MCP3422) += mcp3422.o diff --git a/drivers/iio/adc/max77541-adc.c b/drivers/iio/adc/max77541-adc.c new file mode 100644 index 000000000000..21d024bde16b --- /dev/null +++ b/drivers/iio/adc/max77541-adc.c @@ -0,0 +1,194 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2022 Analog Devices, Inc. + * ADI MAX77541 ADC Driver with IIO interface + */ + +#include +#include +#include +#include +#include +#include + +#include + +enum max77541_adc_range { + LOW_RANGE, + MID_RANGE, + HIGH_RANGE, +}; + +enum max77541_adc_channel { + MAX77541_ADC_VSYS_V, + MAX77541_ADC_VOUT1_V, + MAX77541_ADC_VOUT2_V, + MAX77541_ADC_TEMP, +}; + +static int max77541_adc_offset(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2) +{ + switch (chan->channel) { + case MAX77541_ADC_TEMP: + *val = DIV_ROUND_CLOSEST(ABSOLUTE_ZERO_MILLICELSIUS, 1725); + return IIO_VAL_INT; + default: + return -EINVAL; + } +} + +static int max77541_adc_scale(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2) +{ + struct regmap **regmap = iio_priv(indio_dev); + unsigned int reg_val; + int ret; + + switch (chan->channel) { + case MAX77541_ADC_VSYS_V: + *val = 25; + return IIO_VAL_INT; + case MAX77541_ADC_VOUT1_V: + case MAX77541_ADC_VOUT2_V: + ret = regmap_read(*regmap, MAX77541_REG_M2_CFG1, ®_val); + if (ret) + return ret; + + reg_val = FIELD_GET(MAX77541_BITS_MX_CFG1_RNG, reg_val); + switch (reg_val) { + case LOW_RANGE: + *val = 6; + *val2 = 250000; + break; + case MID_RANGE: + *val = 12; + *val2 = 500000; + break; + case HIGH_RANGE: + *val = 25; + return IIO_VAL_INT; + default: + return -EINVAL; + } + + return IIO_VAL_INT_PLUS_MICRO; + case MAX77541_ADC_TEMP: + *val = 1725; + return IIO_VAL_INT; + default: + return -EINVAL; + } +} + +static int max77541_adc_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val) +{ + struct regmap **regmap = iio_priv(indio_dev); + int ret; + + ret = regmap_read(*regmap, chan->address, val); + if (ret) + return ret; + + return IIO_VAL_INT; +} + +#define MAX77541_ADC_CHANNEL_V(_channel, _name, _type, _reg) \ + { \ + .type = _type, \ + .indexed = 1, \ + .channel = _channel, \ + .address = _reg, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ + BIT(IIO_CHAN_INFO_SCALE), \ + .datasheet_name = _name, \ + } + +#define MAX77541_ADC_CHANNEL_TEMP(_channel, _name, _type, _reg) \ + { \ + .type = _type, \ + .indexed = 1, \ + .channel = _channel, \ + .address = _reg, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ + BIT(IIO_CHAN_INFO_SCALE) |\ + BIT(IIO_CHAN_INFO_OFFSET),\ + .datasheet_name = _name, \ + } + +static const struct iio_chan_spec max77541_adc_channels[] = { + MAX77541_ADC_CHANNEL_V(MAX77541_ADC_VSYS_V, "vsys_v", IIO_VOLTAGE, + MAX77541_REG_ADC_DATA_CH1), + MAX77541_ADC_CHANNEL_V(MAX77541_ADC_VOUT1_V, "vout1_v", IIO_VOLTAGE, + MAX77541_REG_ADC_DATA_CH2), + MAX77541_ADC_CHANNEL_V(MAX77541_ADC_VOUT2_V, "vout2_v", IIO_VOLTAGE, + MAX77541_REG_ADC_DATA_CH3), + MAX77541_ADC_CHANNEL_TEMP(MAX77541_ADC_TEMP, "temp", IIO_TEMP, + MAX77541_REG_ADC_DATA_CH6), +}; + +static int max77541_adc_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, long mask) +{ + switch (mask) { + case IIO_CHAN_INFO_OFFSET: + return max77541_adc_offset(indio_dev, chan, val, val2); + case IIO_CHAN_INFO_SCALE: + return max77541_adc_scale(indio_dev, chan, val, val2); + case IIO_CHAN_INFO_RAW: + return max77541_adc_raw(indio_dev, chan, val); + default: + return -EINVAL; + } +} + +static const struct iio_info max77541_adc_info = { + .read_raw = max77541_adc_read_raw, +}; + +static int max77541_adc_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct iio_dev *indio_dev; + struct regmap **regmap; + + indio_dev = devm_iio_device_alloc(dev, sizeof(*regmap)); + if (!indio_dev) + return -ENOMEM; + + regmap = iio_priv(indio_dev); + + *regmap = dev_get_regmap(dev->parent, NULL); + indio_dev->modes = INDIO_DIRECT_MODE; + + indio_dev->name = "max77541"; + indio_dev->info = &max77541_adc_info; + indio_dev->channels = max77541_adc_channels; + indio_dev->num_channels = ARRAY_SIZE(max77541_adc_channels); + + return devm_iio_device_register(dev, indio_dev); +} + +static const struct platform_device_id max77541_adc_platform_id[] = { + { "max77541-adc" }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(platform, max77541_adc_platform_id); + +static struct platform_driver max77541_adc_driver = { + .driver = { + .name = "max77541-adc", + }, + .probe = max77541_adc_probe, + .id_table = max77541_adc_platform_id, +}; +module_platform_driver(max77541_adc_driver); + +MODULE_AUTHOR("Okan Sahin "); +MODULE_DESCRIPTION("MAX77541 ADC driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index 2c5fdf848210..6046dfeca16f 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig @@ -94,6 +94,19 @@ 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" + 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. + + To compile this driver as a module, choose M here: the module + will be called leds-aw200xx. + config LEDS_AW2013 tristate "LED support for Awinic AW2013" depends on LEDS_CLASS && I2C && OF @@ -122,6 +135,17 @@ config LEDS_BCM6358 This option enables support for LEDs connected to the BCM6358 LED HW controller accessed via MMIO registers. +config LEDS_CHT_WCOVE + tristate "LED support for Intel Cherry Trail Whiskey Cove PMIC" + depends on LEDS_CLASS + depends on INTEL_SOC_PMIC_CHTWC + help + This option enables support for charger and general purpose LEDs + connected to the Intel Cherrytrail Whiskey Cove PMIC. + + To compile this driver as a module, choose M here: the module + will be called leds-cht-wcove. + config LEDS_CPCAP tristate "LED Support for Motorola CPCAP" depends on LEDS_CLASS @@ -676,7 +700,7 @@ config LEDS_LM355x config LEDS_OT200 tristate "LED support for the Bachmann OT200" - depends on LEDS_CLASS && HAS_IOMEM && (X86_32 || COMPILE_TEST) + depends on LEDS_CLASS && HAS_IOPORT && (X86_32 || COMPILE_TEST) help This option enables support for the LEDs on the Bachmann OT200. Say Y to enable LEDs on the Bachmann OT200. @@ -807,8 +831,7 @@ config LEDS_SPI_BYTE supported: Ubiquiti airCube ISP microcontroller based LED controller. config LEDS_TI_LMU_COMMON - tristate "LED driver for TI LMU" - depends on LEDS_CLASS + tristate "LED driver for TI LMU" if COMPILE_TEST select REGMAP help Say Y to enable the LED driver for TI LMU devices. @@ -817,16 +840,16 @@ config LEDS_TI_LMU_COMMON config LEDS_LM3697 tristate "LED driver for LM3697" - depends on LEDS_TI_LMU_COMMON - depends on I2C && OF + depends on LEDS_CLASS && I2C && OF + select LEDS_TI_LMU_COMMON help Say Y to enable the LM3697 LED driver for TI LMU devices. This supports the LED device LM3697. config LEDS_LM36274 tristate "LED driver for LM36274" - depends on LEDS_TI_LMU_COMMON - depends on MFD_TI_LMU + depends on LEDS_CLASS && MFD_TI_LMU + select LEDS_TI_LMU_COMMON help Say Y to enable the LM36274 LED driver for TI LMU devices. This supports the LED device LM36274. diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile index c07d1512c745..d71f1226540c 100644 --- a/drivers/leds/Makefile +++ b/drivers/leds/Makefile @@ -14,12 +14,14 @@ obj-$(CONFIG_LEDS_ADP5520) += leds-adp5520.o obj-$(CONFIG_LEDS_AN30259A) += leds-an30259a.o obj-$(CONFIG_LEDS_APU) += leds-apu.o obj-$(CONFIG_LEDS_ARIEL) += leds-ariel.o +obj-$(CONFIG_LEDS_AW200XX) += leds-aw200xx.o obj-$(CONFIG_LEDS_AW2013) += leds-aw2013.o obj-$(CONFIG_LEDS_BCM6328) += leds-bcm6328.o obj-$(CONFIG_LEDS_BCM6358) += leds-bcm6358.o obj-$(CONFIG_LEDS_BD2606MVV) += leds-bd2606mvv.o obj-$(CONFIG_LEDS_BD2802) += leds-bd2802.o obj-$(CONFIG_LEDS_BLINKM) += leds-blinkm.o +obj-$(CONFIG_LEDS_CHT_WCOVE) += leds-cht-wcove.o obj-$(CONFIG_LEDS_CLEVO_MAIL) += leds-clevo-mail.o obj-$(CONFIG_LEDS_COBALT_QUBE) += leds-cobalt-qube.o obj-$(CONFIG_LEDS_COBALT_RAQ) += leds-cobalt-raq.o diff --git a/drivers/leds/flash/leds-aat1290.c b/drivers/leds/flash/leds-aat1290.c index 589484b22c79..f12ecb2c6580 100644 --- a/drivers/leds/flash/leds-aat1290.c +++ b/drivers/leds/flash/leds-aat1290.c @@ -425,7 +425,7 @@ static void aat1290_init_v4l2_flash_config(struct aat1290_led *led, struct led_classdev *led_cdev = &led->fled_cdev.led_cdev; struct led_flash_setting *s; - strlcpy(v4l2_sd_cfg->dev_name, led_cdev->dev->kobj.name, + strscpy(v4l2_sd_cfg->dev_name, led_cdev->dev->kobj.name, sizeof(v4l2_sd_cfg->dev_name)); s = &v4l2_sd_cfg->intensity; diff --git a/drivers/leds/flash/leds-as3645a.c b/drivers/leds/flash/leds-as3645a.c index bb2249771acb..12c2609c1137 100644 --- a/drivers/leds/flash/leds-as3645a.c +++ b/drivers/leds/flash/leds-as3645a.c @@ -651,8 +651,8 @@ static int as3645a_v4l2_setup(struct as3645a *flash) }, }; - strlcpy(cfg.dev_name, led->dev->kobj.name, sizeof(cfg.dev_name)); - strlcpy(cfgind.dev_name, flash->iled_cdev.dev->kobj.name, + strscpy(cfg.dev_name, led->dev->kobj.name, sizeof(cfg.dev_name)); + strscpy(cfgind.dev_name, flash->iled_cdev.dev->kobj.name, sizeof(cfgind.dev_name)); flash->vf = v4l2_flash_init( @@ -759,7 +759,7 @@ static struct i2c_driver as3645a_i2c_driver = { .of_match_table = as3645a_of_table, .name = AS_NAME, }, - .probe_new = as3645a_probe, + .probe = as3645a_probe, .remove = as3645a_remove, .id_table = as3645a_id_table, }; diff --git a/drivers/leds/flash/leds-lm3601x.c b/drivers/leds/flash/leds-lm3601x.c index 78730e066a73..b6c524facf49 100644 --- a/drivers/leds/flash/leds-lm3601x.c +++ b/drivers/leds/flash/leds-lm3601x.c @@ -471,7 +471,7 @@ static struct i2c_driver lm3601x_i2c_driver = { .name = "lm3601x", .of_match_table = of_lm3601x_leds_match, }, - .probe_new = lm3601x_probe, + .probe = lm3601x_probe, .remove = lm3601x_remove, .id_table = lm3601x_id, }; diff --git a/drivers/leds/flash/leds-qcom-flash.c b/drivers/leds/flash/leds-qcom-flash.c index 90a24fa25a49..b089ca1a1901 100644 --- a/drivers/leds/flash/leds-qcom-flash.c +++ b/drivers/leds/flash/leds-qcom-flash.c @@ -18,7 +18,8 @@ #define FLASH_TYPE_VAL 0x18 #define FLASH_SUBTYPE_REG 0x05 -#define FLASH_SUBTYPE_3CH_VAL 0x04 +#define FLASH_SUBTYPE_3CH_PM8150_VAL 0x04 +#define FLASH_SUBTYPE_3CH_PMI8998_VAL 0x03 #define FLASH_SUBTYPE_4CH_VAL 0x07 #define FLASH_STS_3CH_OTST1 BIT(0) @@ -416,6 +417,14 @@ static int qcom_flash_led_brightness_set(struct led_classdev *led_cdev, bool enable = !!brightness; int rc; + rc = set_flash_strobe(led, SW_STROBE, false); + if (rc) + return rc; + + rc = set_flash_module_en(led, false); + if (rc) + return rc; + rc = set_flash_current(led, current_ma, TORCH_MODE); if (rc) return rc; @@ -529,9 +538,9 @@ static int qcom_flash_register_led_device(struct device *dev, struct led_init_data init_data; struct led_classdev_flash *flash = &led->flash; struct led_flash_setting *brightness, *timeout; - u32 count, current_ua, timeout_us; + u32 current_ua, timeout_us; u32 channels[4]; - int i, rc; + int i, rc, count; count = fwnode_property_count_u32(node, "led-sources"); if (count <= 0) { @@ -682,7 +691,7 @@ static int qcom_flash_led_probe(struct platform_device *pdev) return rc; } - if (val == FLASH_SUBTYPE_3CH_VAL) { + if (val == FLASH_SUBTYPE_3CH_PM8150_VAL || val == FLASH_SUBTYPE_3CH_PMI8998_VAL) { flash_data->hw_type = QCOM_MVFLASH_3CH; flash_data->max_channels = 3; regs = mvflash_3ch_regs; diff --git a/drivers/leds/flash/leds-rt4505.c b/drivers/leds/flash/leds-rt4505.c index e404fe8b0314..1ae5b387f4a5 100644 --- a/drivers/leds/flash/leds-rt4505.c +++ b/drivers/leds/flash/leds-rt4505.c @@ -419,7 +419,7 @@ static struct i2c_driver rt4505_driver = { .name = "rt4505", .of_match_table = of_match_ptr(rt4505_leds_match), }, - .probe_new = rt4505_probe, + .probe = rt4505_probe, .remove = rt4505_remove, .shutdown = rt4505_shutdown, }; diff --git a/drivers/leds/flash/leds-sgm3140.c b/drivers/leds/flash/leds-sgm3140.c index d3a30ad94ac4..d3f50dca5136 100644 --- a/drivers/leds/flash/leds-sgm3140.c +++ b/drivers/leds/flash/leds-sgm3140.c @@ -291,6 +291,7 @@ static int sgm3140_remove(struct platform_device *pdev) static const struct of_device_id sgm3140_dt_match[] = { { .compatible = "ocs,ocp8110" }, + { .compatible = "richtek,rt5033-led" }, { .compatible = "sgmicro,sgm3140" }, { /* sentinel */ } }; diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c index 9255bc11f99d..6dae56b914fe 100644 --- a/drivers/leds/led-class.c +++ b/drivers/leds/led-class.c @@ -409,7 +409,7 @@ static int led_classdev_next_name(const char *init_name, char *name, int ret = 0; struct device *dev; - strlcpy(name, init_name, len); + strscpy(name, init_name, len); while ((ret < len) && (dev = class_find_device_by_name(leds_class, name))) { diff --git a/drivers/leds/led-core.c b/drivers/leds/led-core.c index 4a97cb745788..b9b1295833c9 100644 --- a/drivers/leds/led-core.c +++ b/drivers/leds/led-core.c @@ -114,21 +114,14 @@ static void led_timer_function(struct timer_list *t) mod_timer(&led_cdev->blink_timer, jiffies + msecs_to_jiffies(delay)); } -static void set_brightness_delayed(struct work_struct *ws) +static void set_brightness_delayed_set_brightness(struct led_classdev *led_cdev, + unsigned int value) { - struct led_classdev *led_cdev = - container_of(ws, struct led_classdev, set_brightness_work); int ret = 0; - if (test_and_clear_bit(LED_BLINK_DISABLE, &led_cdev->work_flags)) { - led_cdev->delayed_set_value = LED_OFF; - led_stop_software_blink(led_cdev); - } - - ret = __led_set_brightness(led_cdev, led_cdev->delayed_set_value); + ret = __led_set_brightness(led_cdev, value); if (ret == -ENOTSUPP) - ret = __led_set_brightness_blocking(led_cdev, - led_cdev->delayed_set_value); + ret = __led_set_brightness_blocking(led_cdev, value); if (ret < 0 && /* LED HW might have been unplugged, therefore don't warn */ !(ret == -ENODEV && (led_cdev->flags & LED_UNREGISTERING) && @@ -137,6 +130,37 @@ static void set_brightness_delayed(struct work_struct *ws) "Setting an LED's brightness failed (%d)\n", ret); } +static void set_brightness_delayed(struct work_struct *ws) +{ + struct led_classdev *led_cdev = + container_of(ws, struct led_classdev, set_brightness_work); + + if (test_and_clear_bit(LED_BLINK_DISABLE, &led_cdev->work_flags)) { + led_stop_software_blink(led_cdev); + set_bit(LED_SET_BRIGHTNESS_OFF, &led_cdev->work_flags); + } + + /* + * Triggers may call led_set_brightness(LED_OFF), + * led_set_brightness(LED_FULL) in quick succession to disable blinking + * and turn the LED on. Both actions may have been scheduled to run + * before this work item runs once. To make sure this works properly + * handle LED_SET_BRIGHTNESS_OFF first. + */ + if (test_and_clear_bit(LED_SET_BRIGHTNESS_OFF, &led_cdev->work_flags)) + set_brightness_delayed_set_brightness(led_cdev, LED_OFF); + + if (test_and_clear_bit(LED_SET_BRIGHTNESS, &led_cdev->work_flags)) + set_brightness_delayed_set_brightness(led_cdev, led_cdev->delayed_set_value); + + if (test_and_clear_bit(LED_SET_BLINK, &led_cdev->work_flags)) { + unsigned long delay_on = led_cdev->delayed_delay_on; + unsigned long delay_off = led_cdev->delayed_delay_off; + + led_blink_set(led_cdev, &delay_on, &delay_off); + } +} + static void led_set_software_blink(struct led_classdev *led_cdev, unsigned long delay_on, unsigned long delay_off) @@ -229,6 +253,22 @@ void led_blink_set_oneshot(struct led_classdev *led_cdev, } EXPORT_SYMBOL_GPL(led_blink_set_oneshot); +void led_blink_set_nosleep(struct led_classdev *led_cdev, unsigned long delay_on, + unsigned long delay_off) +{ + /* If necessary delegate to a work queue task. */ + if (led_cdev->blink_set && led_cdev->brightness_set_blocking) { + led_cdev->delayed_delay_on = delay_on; + led_cdev->delayed_delay_off = delay_off; + set_bit(LED_SET_BLINK, &led_cdev->work_flags); + schedule_work(&led_cdev->set_brightness_work); + return; + } + + led_blink_set(led_cdev, &delay_on, &delay_off); +} +EXPORT_SYMBOL_GPL(led_blink_set_nosleep); + void led_stop_software_blink(struct led_classdev *led_cdev) { del_timer_sync(&led_cdev->blink_timer); @@ -271,8 +311,23 @@ void led_set_brightness_nopm(struct led_classdev *led_cdev, unsigned int value) if (!__led_set_brightness(led_cdev, value)) return; - /* If brightness setting can sleep, delegate it to a work queue task */ - led_cdev->delayed_set_value = value; + /* + * Brightness setting can sleep, delegate it to a work queue task. + * value 0 / LED_OFF is special, since it also disables hw-blinking + * (sw-blink disable is handled in led_set_brightness()). + * To avoid a hw-blink-disable getting lost when a second brightness + * change is done immediately afterwards (before the work runs), + * it uses a separate work_flag. + */ + if (value) { + led_cdev->delayed_set_value = value; + set_bit(LED_SET_BRIGHTNESS, &led_cdev->work_flags); + } else { + clear_bit(LED_SET_BRIGHTNESS, &led_cdev->work_flags); + clear_bit(LED_SET_BLINK, &led_cdev->work_flags); + set_bit(LED_SET_BRIGHTNESS_OFF, &led_cdev->work_flags); + } + schedule_work(&led_cdev->set_brightness_work); } EXPORT_SYMBOL_GPL(led_set_brightness_nopm); diff --git a/drivers/leds/led-triggers.c b/drivers/leds/led-triggers.c index 072491d3e17b..6a5e1f41f9a4 100644 --- a/drivers/leds/led-triggers.c +++ b/drivers/leds/led-triggers.c @@ -185,6 +185,7 @@ int led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trig) led_cdev->trigger = NULL; led_cdev->trigger_data = NULL; led_cdev->activated = false; + led_cdev->flags &= ~LED_INIT_DEFAULT_TRIGGER; led_set_brightness(led_cdev, LED_OFF); } if (trig) { @@ -393,8 +394,8 @@ void led_trigger_event(struct led_trigger *trig, EXPORT_SYMBOL_GPL(led_trigger_event); static void led_trigger_blink_setup(struct led_trigger *trig, - unsigned long *delay_on, - unsigned long *delay_off, + unsigned long delay_on, + unsigned long delay_off, int oneshot, int invert) { @@ -406,25 +407,25 @@ static void led_trigger_blink_setup(struct led_trigger *trig, rcu_read_lock(); list_for_each_entry_rcu(led_cdev, &trig->led_cdevs, trig_list) { if (oneshot) - led_blink_set_oneshot(led_cdev, delay_on, delay_off, + led_blink_set_oneshot(led_cdev, &delay_on, &delay_off, invert); else - led_blink_set(led_cdev, delay_on, delay_off); + led_blink_set_nosleep(led_cdev, delay_on, delay_off); } rcu_read_unlock(); } void led_trigger_blink(struct led_trigger *trig, - unsigned long *delay_on, - unsigned long *delay_off) + unsigned long delay_on, + unsigned long delay_off) { led_trigger_blink_setup(trig, delay_on, delay_off, 0, 0); } EXPORT_SYMBOL_GPL(led_trigger_blink); void led_trigger_blink_oneshot(struct led_trigger *trig, - unsigned long *delay_on, - unsigned long *delay_off, + unsigned long delay_on, + unsigned long delay_off, int invert) { led_trigger_blink_setup(trig, delay_on, delay_off, 1, invert); diff --git a/drivers/leds/leds-an30259a.c b/drivers/leds/leds-an30259a.c index 89df267853a9..24b1041213c2 100644 --- a/drivers/leds/leds-an30259a.c +++ b/drivers/leds/leds-an30259a.c @@ -346,7 +346,7 @@ static struct i2c_driver an30259a_driver = { .name = "leds-an30259a", .of_match_table = of_match_ptr(an30259a_match_table), }, - .probe_new = an30259a_probe, + .probe = an30259a_probe, .remove = an30259a_remove, .id_table = an30259a_id, }; diff --git a/drivers/leds/leds-aw200xx.c b/drivers/leds/leds-aw200xx.c new file mode 100644 index 000000000000..96979b8e09b7 --- /dev/null +++ b/drivers/leds/leds-aw200xx.c @@ -0,0 +1,594 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Awinic AW20036/AW20054/AW20072 LED driver + * + * Copyright (c) 2023, SberDevices. All Rights Reserved. + * + * Author: Martin Kurbanov + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define AW200XX_DIM_MAX (BIT(6) - 1) +#define AW200XX_FADE_MAX (BIT(8) - 1) +#define AW200XX_IMAX_DEFAULT_uA 60000 +#define AW200XX_IMAX_MAX_uA 160000 +#define AW200XX_IMAX_MIN_uA 3300 + +/* Page 0 */ +#define AW200XX_REG_PAGE0_BASE 0xc000 + +/* Select page register */ +#define AW200XX_REG_PAGE 0xF0 +#define AW200XX_PAGE_MASK (GENMASK(7, 6) | GENMASK(2, 0)) +#define AW200XX_PAGE_SHIFT 0 +#define AW200XX_NUM_PAGES 6 +#define AW200XX_PAGE_SIZE 256 +#define AW200XX_REG(page, reg) \ + (AW200XX_REG_PAGE0_BASE + (page) * AW200XX_PAGE_SIZE + (reg)) +#define AW200XX_REG_MAX \ + AW200XX_REG(AW200XX_NUM_PAGES - 1, AW200XX_PAGE_SIZE - 1) +#define AW200XX_PAGE0 0 +#define AW200XX_PAGE1 1 +#define AW200XX_PAGE2 2 +#define AW200XX_PAGE3 3 +#define AW200XX_PAGE4 4 +#define AW200XX_PAGE5 5 + +/* Chip ID register */ +#define AW200XX_REG_IDR AW200XX_REG(AW200XX_PAGE0, 0x00) +#define AW200XX_IDR_CHIPID 0x18 + +/* Sleep mode register */ +#define AW200XX_REG_SLPCR AW200XX_REG(AW200XX_PAGE0, 0x01) +#define AW200XX_SLPCR_ACTIVE 0x00 + +/* Reset register */ +#define AW200XX_REG_RSTR AW200XX_REG(AW200XX_PAGE0, 0x02) +#define AW200XX_RSTR_RESET 0x01 + +/* Global current configuration register */ +#define AW200XX_REG_GCCR AW200XX_REG(AW200XX_PAGE0, 0x03) +#define AW200XX_GCCR_IMAX_MASK GENMASK(7, 4) +#define AW200XX_GCCR_IMAX(x) ((x) << 4) +#define AW200XX_GCCR_ALLON BIT(3) + +/* Fast clear display control register */ +#define AW200XX_REG_FCD AW200XX_REG(AW200XX_PAGE0, 0x04) +#define AW200XX_FCD_CLEAR 0x01 + +/* Display size configuration */ +#define AW200XX_REG_DSIZE AW200XX_REG(AW200XX_PAGE0, 0x80) +#define AW200XX_DSIZE_COLUMNS_MAX 12 + +#define AW200XX_LED2REG(x, columns) \ + ((x) + (((x) / (columns)) * (AW200XX_DSIZE_COLUMNS_MAX - (columns)))) + +/* + * DIM current configuration register (page 4). + * The even address for current DIM configuration. + * The odd address for current FADE configuration + */ +#define AW200XX_REG_DIM(x, columns) \ + AW200XX_REG(AW200XX_PAGE4, AW200XX_LED2REG(x, columns) * 2) +#define AW200XX_REG_DIM2FADE(x) ((x) + 1) + +/* + * Duty ratio of display scan (see p.15 of datasheet for formula): + * duty = (592us / 600.5us) * (1 / (display_rows + 1)) + * + * Multiply to 1000 (MILLI) to improve the accuracy of calculations. + */ +#define AW200XX_DUTY_RATIO(rows) \ + (((592UL * USEC_PER_SEC) / 600500UL) * (MILLI / (rows)) / MILLI) + +struct aw200xx_chipdef { + u32 channels; + u32 display_size_rows_max; + u32 display_size_columns; +}; + +struct aw200xx_led { + struct led_classdev cdev; + struct aw200xx *chip; + int dim; + u32 num; +}; + +struct aw200xx { + const struct aw200xx_chipdef *cdef; + struct i2c_client *client; + struct regmap *regmap; + struct mutex mutex; + u32 num_leds; + u32 display_rows; + struct aw200xx_led leds[]; +}; + +static ssize_t dim_show(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + struct led_classdev *cdev = dev_get_drvdata(dev); + struct aw200xx_led *led = container_of(cdev, struct aw200xx_led, cdev); + int dim = led->dim; + + if (dim < 0) + return sysfs_emit(buf, "auto\n"); + + return sysfs_emit(buf, "%d\n", dim); +} + +static ssize_t dim_store(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + struct led_classdev *cdev = dev_get_drvdata(dev); + struct aw200xx_led *led = container_of(cdev, struct aw200xx_led, cdev); + struct aw200xx *chip = led->chip; + u32 columns = chip->cdef->display_size_columns; + int dim; + ssize_t ret; + + if (sysfs_streq(buf, "auto")) { + dim = -1; + } else { + ret = kstrtoint(buf, 0, &dim); + if (ret) + return ret; + + if (dim > AW200XX_DIM_MAX) + return -EINVAL; + } + + mutex_lock(&chip->mutex); + + if (dim >= 0) { + ret = regmap_write(chip->regmap, + AW200XX_REG_DIM(led->num, columns), dim); + if (ret) + goto out_unlock; + } + + led->dim = dim; + ret = count; + +out_unlock: + mutex_unlock(&chip->mutex); + return ret; +} +static DEVICE_ATTR_RW(dim); + +static struct attribute *dim_attrs[] = { + &dev_attr_dim.attr, + NULL +}; +ATTRIBUTE_GROUPS(dim); + +static int aw200xx_brightness_set(struct led_classdev *cdev, + enum led_brightness brightness) +{ + struct aw200xx_led *led = container_of(cdev, struct aw200xx_led, cdev); + struct aw200xx *chip = led->chip; + int dim; + u32 reg; + int ret; + + mutex_lock(&chip->mutex); + + reg = AW200XX_REG_DIM(led->num, chip->cdef->display_size_columns); + + dim = led->dim; + if (dim < 0) + dim = max_t(int, + brightness / (AW200XX_FADE_MAX / AW200XX_DIM_MAX), + 1); + + ret = regmap_write(chip->regmap, reg, dim); + if (ret) + goto out_unlock; + + ret = regmap_write(chip->regmap, + AW200XX_REG_DIM2FADE(reg), brightness); + +out_unlock: + mutex_unlock(&chip->mutex); + + return ret; +} + +static u32 aw200xx_imax_from_global(const struct aw200xx *const chip, + u32 global_imax_uA) +{ + u64 led_imax_uA; + + /* + * The output current of each LED (see p.14 of datasheet for formula): + * Iled = Imax * (dim / 63) * ((fade + 1) / 256) * duty + * + * The value of duty is determined by the following formula: + * duty = (592us / 600.5us) * (1 / (display_rows + 1)) + * + * Calculated for the maximum values of fade and dim. + * We divide by 1000 because we earlier multiplied by 1000 to improve + * accuracy when calculating the duty. + */ + led_imax_uA = global_imax_uA * AW200XX_DUTY_RATIO(chip->display_rows); + do_div(led_imax_uA, MILLI); + + return led_imax_uA; +} + +static u32 aw200xx_imax_to_global(const struct aw200xx *const chip, + u32 led_imax_uA) +{ + u32 duty = AW200XX_DUTY_RATIO(chip->display_rows); + + /* The output current of each LED (see p.14 of datasheet for formula) */ + return (led_imax_uA * 1000U) / duty; +} + +#define AW200XX_IMAX_MULTIPLIER1 10000 +#define AW200XX_IMAX_MULTIPLIER2 3333 +#define AW200XX_IMAX_BASE_VAL1 0 +#define AW200XX_IMAX_BASE_VAL2 8 + +/* + * The AW200XX has a 4-bit register (GCCR) to configure the global current, + * which ranges from 3.3mA to 160mA. The following table indicates the values + * of the global current, divided into two parts: + * + * +-----------+-----------------+-----------+-----------------+ + * | reg value | global max (mA) | reg value | global max (mA) | + * +-----------+-----------------+-----------+-----------------+ + * | 0 | 10 | 8 | 3.3 | + * | 1 | 20 | 9 | 6.7 | + * | 2 | 30 | 10 | 10 | + * | 3 | 40 | 11 | 13.3 | + * | 4 | 60 | 12 | 20 | + * | 5 | 80 | 13 | 26.7 | + * | 6 | 120 | 14 | 40 | + * | 7 | 160 | 15 | 53.3 | + * +-----------+-----------------+-----------+-----------------+ + * + * The left part with a multiplier of 10, and the right part with a multiplier + * of 3.3. + * So we have two formulas to calculate the global current: + * for the left part of the table: + * imax = coefficient * 10 + * + * for the right part of the table: + * imax = coefficient * 3.3 + * + * The coefficient table consists of the following values: + * 1, 2, 3, 4, 6, 8, 12, 16. + */ +static int aw200xx_set_imax(const struct aw200xx *const chip, + u32 led_imax_uA) +{ + u32 g_imax_uA = aw200xx_imax_to_global(chip, led_imax_uA); + u32 coeff_table[] = {1, 2, 3, 4, 6, 8, 12, 16}; + u32 gccr_imax = UINT_MAX; + u32 cur_imax = 0; + int i; + + for (i = 0; i < ARRAY_SIZE(coeff_table); i++) { + u32 imax; + + /* select closest ones */ + imax = coeff_table[i] * AW200XX_IMAX_MULTIPLIER1; + if (g_imax_uA >= imax && imax > cur_imax) { + cur_imax = imax; + gccr_imax = i + AW200XX_IMAX_BASE_VAL1; + } + + imax = coeff_table[i] * AW200XX_IMAX_MULTIPLIER2; + imax = DIV_ROUND_CLOSEST(imax, 100) * 100; + if (g_imax_uA >= imax && imax > cur_imax) { + cur_imax = imax; + gccr_imax = i + AW200XX_IMAX_BASE_VAL2; + } + } + + if (gccr_imax == UINT_MAX) + return -EINVAL; + + return regmap_update_bits(chip->regmap, AW200XX_REG_GCCR, + AW200XX_GCCR_IMAX_MASK, + AW200XX_GCCR_IMAX(gccr_imax)); +} + +static int aw200xx_chip_reset(const struct aw200xx *const chip) +{ + int ret; + + ret = regmap_write(chip->regmap, AW200XX_REG_RSTR, AW200XX_RSTR_RESET); + if (ret) + return ret; + + regcache_mark_dirty(chip->regmap); + return regmap_write(chip->regmap, AW200XX_REG_FCD, AW200XX_FCD_CLEAR); +} + +static int aw200xx_chip_init(const struct aw200xx *const chip) +{ + int ret; + + ret = regmap_write(chip->regmap, AW200XX_REG_DSIZE, + chip->display_rows - 1); + if (ret) + return ret; + + ret = regmap_write(chip->regmap, AW200XX_REG_SLPCR, + AW200XX_SLPCR_ACTIVE); + if (ret) + return ret; + + return regmap_update_bits(chip->regmap, AW200XX_REG_GCCR, + AW200XX_GCCR_ALLON, AW200XX_GCCR_ALLON); +} + +static int aw200xx_chip_check(const struct aw200xx *const chip) +{ + struct device *dev = &chip->client->dev; + u32 chipid; + int ret; + + ret = regmap_read(chip->regmap, AW200XX_REG_IDR, &chipid); + if (ret) + return dev_err_probe(dev, ret, "Failed to read chip ID\n"); + + if (chipid != AW200XX_IDR_CHIPID) + return dev_err_probe(dev, -ENODEV, + "Chip reported wrong ID: %x\n", chipid); + + return 0; +} + +static int aw200xx_probe_fw(struct device *dev, struct aw200xx *chip) +{ + struct fwnode_handle *child; + u32 current_min, current_max, min_uA; + int ret; + int i; + + ret = device_property_read_u32(dev, "awinic,display-rows", + &chip->display_rows); + 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, ret, + "Invalid leds display size %u\n", + chip->display_rows); + } + + current_max = aw200xx_imax_from_global(chip, AW200XX_IMAX_MAX_uA); + current_min = aw200xx_imax_from_global(chip, AW200XX_IMAX_MIN_uA); + min_uA = UINT_MAX; + i = 0; + + device_for_each_child_node(dev, child) { + struct led_init_data init_data = {}; + struct aw200xx_led *led; + u32 source, imax; + + ret = fwnode_property_read_u32(child, "reg", &source); + if (ret) { + dev_err(dev, "Missing reg property\n"); + chip->num_leds--; + continue; + } + + if (source >= chip->cdef->channels) { + dev_err(dev, "LED reg %u out of range (max %u)\n", + source, chip->cdef->channels); + chip->num_leds--; + continue; + } + + ret = fwnode_property_read_u32(child, "led-max-microamp", + &imax); + if (ret) { + dev_info(&chip->client->dev, + "DT property led-max-microamp is missing\n"); + } else if (imax < current_min || imax > current_max) { + dev_err(dev, "Invalid value %u for led-max-microamp\n", + imax); + chip->num_leds--; + continue; + } else { + min_uA = min(min_uA, imax); + } + + led = &chip->leds[i]; + led->dim = -1; + led->num = source; + led->chip = chip; + led->cdev.brightness_set_blocking = aw200xx_brightness_set; + led->cdev.groups = dim_groups; + init_data.fwnode = child; + + ret = devm_led_classdev_register_ext(dev, &led->cdev, + &init_data); + if (ret) { + fwnode_handle_put(child); + break; + } + + i++; + } + + if (!chip->num_leds) + return -EINVAL; + + if (min_uA == UINT_MAX) { + min_uA = aw200xx_imax_from_global(chip, + AW200XX_IMAX_DEFAULT_uA); + } + + return aw200xx_set_imax(chip, min_uA); +} + +static const struct regmap_range_cfg aw200xx_ranges[] = { + { + .name = "aw200xx", + .range_min = 0, + .range_max = AW200XX_REG_MAX, + .selector_reg = AW200XX_REG_PAGE, + .selector_mask = AW200XX_PAGE_MASK, + .selector_shift = AW200XX_PAGE_SHIFT, + .window_start = 0, + .window_len = AW200XX_PAGE_SIZE, + }, +}; + +static const struct regmap_range aw200xx_writeonly_ranges[] = { + regmap_reg_range(AW200XX_REG(AW200XX_PAGE1, 0x00), AW200XX_REG_MAX), +}; + +static const struct regmap_access_table aw200xx_readable_table = { + .no_ranges = aw200xx_writeonly_ranges, + .n_no_ranges = ARRAY_SIZE(aw200xx_writeonly_ranges), +}; + +static const struct regmap_range aw200xx_readonly_ranges[] = { + regmap_reg_range(AW200XX_REG_IDR, AW200XX_REG_IDR), +}; + +static const struct regmap_access_table aw200xx_writeable_table = { + .no_ranges = aw200xx_readonly_ranges, + .n_no_ranges = ARRAY_SIZE(aw200xx_readonly_ranges), +}; + +static const struct regmap_config aw200xx_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .max_register = AW200XX_REG_MAX, + .ranges = aw200xx_ranges, + .num_ranges = ARRAY_SIZE(aw200xx_ranges), + .rd_table = &aw200xx_readable_table, + .wr_table = &aw200xx_writeable_table, + .cache_type = REGCACHE_RBTREE, +}; + +static int aw200xx_probe(struct i2c_client *client) +{ + const struct aw200xx_chipdef *cdef; + struct aw200xx *chip; + int count; + int ret; + + cdef = device_get_match_data(&client->dev); + if (!cdef) + return -ENODEV; + + count = device_get_child_node_count(&client->dev); + if (!count || count > cdef->channels) + return dev_err_probe(&client->dev, -EINVAL, + "Incorrect number of leds (%d)", count); + + chip = devm_kzalloc(&client->dev, struct_size(chip, leds, count), + GFP_KERNEL); + if (!chip) + return -ENOMEM; + + chip->cdef = cdef; + chip->num_leds = count; + chip->client = client; + i2c_set_clientdata(client, chip); + + chip->regmap = devm_regmap_init_i2c(client, &aw200xx_regmap_config); + if (IS_ERR(chip->regmap)) + return PTR_ERR(chip->regmap); + + ret = aw200xx_chip_check(chip); + if (ret) + return ret; + + mutex_init(&chip->mutex); + + /* Need a lock now since after call aw200xx_probe_fw, sysfs nodes created */ + mutex_lock(&chip->mutex); + + ret = aw200xx_chip_reset(chip); + if (ret) + goto out_unlock; + + ret = aw200xx_probe_fw(&client->dev, chip); + if (ret) + goto out_unlock; + + ret = aw200xx_chip_init(chip); + +out_unlock: + mutex_unlock(&chip->mutex); + return ret; +} + +static void aw200xx_remove(struct i2c_client *client) +{ + struct aw200xx *chip = i2c_get_clientdata(client); + + aw200xx_chip_reset(chip); + mutex_destroy(&chip->mutex); +} + +static const struct aw200xx_chipdef aw20036_cdef = { + .channels = 36, + .display_size_rows_max = 3, + .display_size_columns = 12, +}; + +static const struct aw200xx_chipdef aw20054_cdef = { + .channels = 54, + .display_size_rows_max = 6, + .display_size_columns = 9, +}; + +static const struct aw200xx_chipdef aw20072_cdef = { + .channels = 72, + .display_size_rows_max = 6, + .display_size_columns = 12, +}; + +static const struct i2c_device_id aw200xx_id[] = { + { "aw20036" }, + { "aw20054" }, + { "aw20072" }, + {} +}; +MODULE_DEVICE_TABLE(i2c, aw200xx_id); + +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, }, + {} +}; +MODULE_DEVICE_TABLE(of, aw200xx_match_table); + +static struct i2c_driver aw200xx_driver = { + .driver = { + .name = "aw200xx", + .of_match_table = aw200xx_match_table, + }, + .probe_new = aw200xx_probe, + .remove = aw200xx_remove, + .id_table = aw200xx_id, +}; +module_i2c_driver(aw200xx_driver); + +MODULE_AUTHOR("Martin Kurbanov "); +MODULE_DESCRIPTION("AW200XX LED driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/leds/leds-aw2013.c b/drivers/leds/leds-aw2013.c index 0b52fc9097c6..59765640b70f 100644 --- a/drivers/leds/leds-aw2013.c +++ b/drivers/leds/leds-aw2013.c @@ -422,7 +422,7 @@ static struct i2c_driver aw2013_driver = { .name = "leds-aw2013", .of_match_table = of_match_ptr(aw2013_match_table), }, - .probe_new = aw2013_probe, + .probe = aw2013_probe, .remove = aw2013_remove, }; diff --git a/drivers/leds/leds-bd2606mvv.c b/drivers/leds/leds-bd2606mvv.c index 76f9d4d70f9a..3fda712d2f80 100644 --- a/drivers/leds/leds-bd2606mvv.c +++ b/drivers/leds/leds-bd2606mvv.c @@ -150,7 +150,7 @@ static struct i2c_driver bd2606mvv_driver = { .name = "leds-bd2606mvv", .of_match_table = of_match_ptr(of_bd2606mvv_leds_match), }, - .probe_new = bd2606mvv_probe, + .probe = bd2606mvv_probe, }; module_i2c_driver(bd2606mvv_driver); diff --git a/drivers/leds/leds-bd2802.c b/drivers/leds/leds-bd2802.c index 601185ddabcc..0792ea126cea 100644 --- a/drivers/leds/leds-bd2802.c +++ b/drivers/leds/leds-bd2802.c @@ -786,7 +786,7 @@ static struct i2c_driver bd2802_i2c_driver = { .name = "BD2802", .pm = &bd2802_pm, }, - .probe_new = bd2802_probe, + .probe = bd2802_probe, .remove = bd2802_remove, .id_table = bd2802_id, }; diff --git a/drivers/leds/leds-blinkm.c b/drivers/leds/leds-blinkm.c index 37f2f32ae42d..2782da1a1930 100644 --- a/drivers/leds/leds-blinkm.c +++ b/drivers/leds/leds-blinkm.c @@ -561,7 +561,7 @@ static int blinkm_detect(struct i2c_client *client, struct i2c_board_info *info) return -ENODEV; } - strlcpy(info->type, "blinkm", I2C_NAME_SIZE); + strscpy(info->type, "blinkm", I2C_NAME_SIZE); return 0; } @@ -730,7 +730,7 @@ static struct i2c_driver blinkm_driver = { .driver = { .name = "blinkm", }, - .probe_new = blinkm_probe, + .probe = blinkm_probe, .remove = blinkm_remove, .id_table = blinkm_id, .detect = blinkm_detect, diff --git a/drivers/leds/leds-cht-wcove.c b/drivers/leds/leds-cht-wcove.c new file mode 100644 index 000000000000..b4998402b8c6 --- /dev/null +++ b/drivers/leds/leds-cht-wcove.c @@ -0,0 +1,476 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Driver for LEDs connected to the Intel Cherry Trail Whiskey Cove PMIC + * + * Copyright 2019 Yauhen Kharuzhy + * Copyright 2023 Hans de Goede + * + * Register info comes from the Lenovo Yoga Book Android opensource code + * available from Lenovo. File lenovo_yb1_x90f_l_osc_201803.7z path in the 7z: + * YB1_source_code/kernel/cht/drivers/misc/charger_gp_led.c + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define CHT_WC_LED1_CTRL 0x5e1f +#define CHT_WC_LED1_FSM 0x5e20 +#define CHT_WC_LED1_PWM 0x5e21 + +#define CHT_WC_LED2_CTRL 0x4fdf +#define CHT_WC_LED2_FSM 0x4fe0 +#define CHT_WC_LED2_PWM 0x4fe1 + +#define CHT_WC_LED1_SWCTL BIT(0) /* HW or SW control of charging led */ +#define CHT_WC_LED1_ON BIT(1) + +#define CHT_WC_LED2_ON BIT(0) +#define CHT_WC_LED_I_MA2_5 (2 << 2) /* LED current limit */ +#define CHT_WC_LED_I_MASK GENMASK(3, 2) /* LED current limit mask */ + +#define CHT_WC_LED_F_1_4_HZ (0 << 4) +#define CHT_WC_LED_F_1_2_HZ (1 << 4) +#define CHT_WC_LED_F_1_HZ (2 << 4) +#define CHT_WC_LED_F_2_HZ (3 << 4) +#define CHT_WC_LED_F_MASK GENMASK(5, 4) + +#define CHT_WC_LED_EFF_OFF (0 << 1) +#define CHT_WC_LED_EFF_ON (1 << 1) +#define CHT_WC_LED_EFF_BLINKING (2 << 1) +#define CHT_WC_LED_EFF_BREATHING (3 << 1) +#define CHT_WC_LED_EFF_MASK GENMASK(2, 1) + +#define CHT_WC_LED_COUNT 2 + +struct cht_wc_led_regs { + /* Register addresses */ + u16 ctrl; + u16 fsm; + u16 pwm; + /* Mask + values for turning the LED on/off */ + u8 on_off_mask; + u8 on_val; + u8 off_val; +}; + +struct cht_wc_led_saved_regs { + unsigned int ctrl; + unsigned int fsm; + unsigned int pwm; +}; + +struct cht_wc_led { + struct led_classdev cdev; + const struct cht_wc_led_regs *regs; + struct regmap *regmap; + struct mutex mutex; + struct cht_wc_led_saved_regs saved_regs; +}; + +struct cht_wc_leds { + struct cht_wc_led leds[CHT_WC_LED_COUNT]; + /* Saved LED1 initial register values */ + struct cht_wc_led_saved_regs led1_initial_regs; +}; + +static const struct cht_wc_led_regs cht_wc_led_regs[CHT_WC_LED_COUNT] = { + { + .ctrl = CHT_WC_LED1_CTRL, + .fsm = CHT_WC_LED1_FSM, + .pwm = CHT_WC_LED1_PWM, + .on_off_mask = CHT_WC_LED1_SWCTL | CHT_WC_LED1_ON, + .on_val = CHT_WC_LED1_SWCTL | CHT_WC_LED1_ON, + .off_val = CHT_WC_LED1_SWCTL, + }, + { + .ctrl = CHT_WC_LED2_CTRL, + .fsm = CHT_WC_LED2_FSM, + .pwm = CHT_WC_LED2_PWM, + .on_off_mask = CHT_WC_LED2_ON, + .on_val = CHT_WC_LED2_ON, + .off_val = 0, + }, +}; + +static const char * const cht_wc_leds_names[CHT_WC_LED_COUNT] = { + "platform::" LED_FUNCTION_CHARGING, + "platform::" LED_FUNCTION_INDICATOR, +}; + +static int cht_wc_leds_brightness_set(struct led_classdev *cdev, + enum led_brightness value) +{ + struct cht_wc_led *led = container_of(cdev, struct cht_wc_led, cdev); + int ret; + + mutex_lock(&led->mutex); + + if (!value) { + ret = regmap_update_bits(led->regmap, led->regs->ctrl, + led->regs->on_off_mask, led->regs->off_val); + if (ret < 0) { + dev_err(cdev->dev, "Failed to turn off: %d\n", ret); + goto out; + } + + /* Disable HW blinking */ + ret = regmap_update_bits(led->regmap, led->regs->fsm, + CHT_WC_LED_EFF_MASK, CHT_WC_LED_EFF_ON); + if (ret < 0) + dev_err(cdev->dev, "Failed to update LED FSM reg: %d\n", ret); + } else { + ret = regmap_write(led->regmap, led->regs->pwm, value); + if (ret < 0) { + dev_err(cdev->dev, "Failed to set brightness: %d\n", ret); + goto out; + } + + ret = regmap_update_bits(led->regmap, led->regs->ctrl, + led->regs->on_off_mask, led->regs->on_val); + if (ret < 0) + dev_err(cdev->dev, "Failed to turn on: %d\n", ret); + } +out: + mutex_unlock(&led->mutex); + return ret; +} + +static enum led_brightness cht_wc_leds_brightness_get(struct led_classdev *cdev) +{ + struct cht_wc_led *led = container_of(cdev, struct cht_wc_led, cdev); + unsigned int val; + int ret; + + mutex_lock(&led->mutex); + + ret = regmap_read(led->regmap, led->regs->ctrl, &val); + if (ret < 0) { + dev_err(cdev->dev, "Failed to read LED CTRL reg: %d\n", ret); + ret = 0; + goto done; + } + + val &= led->regs->on_off_mask; + if (val != led->regs->on_val) { + ret = 0; + goto done; + } + + ret = regmap_read(led->regmap, led->regs->pwm, &val); + if (ret < 0) { + dev_err(cdev->dev, "Failed to read LED PWM reg: %d\n", ret); + ret = 0; + goto done; + } + + ret = val; +done: + mutex_unlock(&led->mutex); + + return ret; +} + +/* Return blinking period for given CTRL reg value */ +static unsigned long cht_wc_leds_get_period(int ctrl) +{ + ctrl &= CHT_WC_LED_F_MASK; + + switch (ctrl) { + case CHT_WC_LED_F_1_4_HZ: + return 1000 * 4; + case CHT_WC_LED_F_1_2_HZ: + return 1000 * 2; + case CHT_WC_LED_F_1_HZ: + return 1000; + case CHT_WC_LED_F_2_HZ: + return 1000 / 2; + } + + return 0; +} + +/* + * Find suitable hardware blink mode for given period. + * period < 750 ms - select 2 HZ + * 750 ms <= period < 1500 ms - select 1 HZ + * 1500 ms <= period < 3000 ms - select 1/2 HZ + * 3000 ms <= period < 5000 ms - select 1/4 HZ + * 5000 ms <= period - return -1 + */ +static int cht_wc_leds_find_freq(unsigned long period) +{ + if (period < 750) + return CHT_WC_LED_F_2_HZ; + else if (period < 1500) + return CHT_WC_LED_F_1_HZ; + else if (period < 3000) + return CHT_WC_LED_F_1_2_HZ; + else if (period < 5000) + return CHT_WC_LED_F_1_4_HZ; + else + return -1; +} + +static int cht_wc_leds_set_effect(struct led_classdev *cdev, + unsigned long *delay_on, + unsigned long *delay_off, + u8 effect) +{ + struct cht_wc_led *led = container_of(cdev, struct cht_wc_led, cdev); + int ctrl, ret; + + mutex_lock(&led->mutex); + + /* Blink with 1 Hz as default if nothing specified */ + if (!*delay_on && !*delay_off) + *delay_on = *delay_off = 500; + + ctrl = cht_wc_leds_find_freq(*delay_on + *delay_off); + if (ctrl < 0) { + /* Disable HW blinking */ + ret = regmap_update_bits(led->regmap, led->regs->fsm, + CHT_WC_LED_EFF_MASK, CHT_WC_LED_EFF_ON); + if (ret < 0) + dev_err(cdev->dev, "Failed to update LED FSM reg: %d\n", ret); + + /* Fallback to software timer */ + *delay_on = *delay_off = 0; + ret = -EINVAL; + goto done; + } + + ret = regmap_update_bits(led->regmap, led->regs->fsm, + CHT_WC_LED_EFF_MASK, effect); + if (ret < 0) + dev_err(cdev->dev, "Failed to update LED FSM reg: %d\n", ret); + + /* Set the frequency and make sure the LED is on */ + ret = regmap_update_bits(led->regmap, led->regs->ctrl, + CHT_WC_LED_F_MASK | led->regs->on_off_mask, + ctrl | led->regs->on_val); + if (ret < 0) + dev_err(cdev->dev, "Failed to update LED CTRL reg: %d\n", ret); + + *delay_off = *delay_on = cht_wc_leds_get_period(ctrl) / 2; + +done: + mutex_unlock(&led->mutex); + + return ret; +} + +static int cht_wc_leds_blink_set(struct led_classdev *cdev, + unsigned long *delay_on, + unsigned long *delay_off) +{ + u8 effect = CHT_WC_LED_EFF_BLINKING; + + /* + * The desired default behavior of LED1 / the charge LED is breathing + * while charging and on/solid when full. Since triggers cannot select + * breathing, blink_set() gets called when charging. Use slow breathing + * when the default "charging-blink-full-solid" trigger is used to + * achieve the desired default behavior. + */ + if (cdev->flags & LED_INIT_DEFAULT_TRIGGER) { + *delay_on = *delay_off = 1000; + effect = CHT_WC_LED_EFF_BREATHING; + } + + return cht_wc_leds_set_effect(cdev, delay_on, delay_off, effect); +} + +static int cht_wc_leds_pattern_set(struct led_classdev *cdev, + struct led_pattern *pattern, + u32 len, int repeat) +{ + unsigned long delay_off, delay_on; + + if (repeat > 0 || len != 2 || + pattern[0].brightness != 0 || pattern[1].brightness != 1 || + pattern[0].delta_t != pattern[1].delta_t || + (pattern[0].delta_t != 250 && pattern[0].delta_t != 500 && + pattern[0].delta_t != 1000 && pattern[0].delta_t != 2000)) + return -EINVAL; + + delay_off = pattern[0].delta_t; + delay_on = pattern[1].delta_t; + + return cht_wc_leds_set_effect(cdev, &delay_on, &delay_off, CHT_WC_LED_EFF_BREATHING); +} + +static int cht_wc_leds_pattern_clear(struct led_classdev *cdev) +{ + return cht_wc_leds_brightness_set(cdev, 0); +} + +static int cht_wc_led_save_regs(struct cht_wc_led *led, + struct cht_wc_led_saved_regs *saved_regs) +{ + int ret; + + ret = regmap_read(led->regmap, led->regs->ctrl, &saved_regs->ctrl); + if (ret < 0) + return ret; + + ret = regmap_read(led->regmap, led->regs->fsm, &saved_regs->fsm); + if (ret < 0) + return ret; + + return regmap_read(led->regmap, led->regs->pwm, &saved_regs->pwm); +} + +static void cht_wc_led_restore_regs(struct cht_wc_led *led, + const struct cht_wc_led_saved_regs *saved_regs) +{ + regmap_write(led->regmap, led->regs->ctrl, saved_regs->ctrl); + regmap_write(led->regmap, led->regs->fsm, saved_regs->fsm); + regmap_write(led->regmap, led->regs->pwm, saved_regs->pwm); +} + +static int cht_wc_leds_probe(struct platform_device *pdev) +{ + struct intel_soc_pmic *pmic = dev_get_drvdata(pdev->dev.parent); + struct cht_wc_leds *leds; + int ret; + int i; + + /* + * On the Lenovo Yoga Tab 3 the LED1 driver output is actually + * connected to a haptic feedback motor rather then a LED. + * So do not register a LED classdev there (LED2 is unused). + */ + if (pmic->cht_wc_model == INTEL_CHT_WC_LENOVO_YT3_X90) + return -ENODEV; + + leds = devm_kzalloc(&pdev->dev, sizeof(*leds), GFP_KERNEL); + if (!leds) + return -ENOMEM; + + /* + * LED1 might be in hw-controlled mode when this driver gets loaded; and + * since the PMIC is always powered by the battery any changes made are + * permanent. Save LED1 regs to restore them on remove() or shutdown(). + */ + leds->leds[0].regs = &cht_wc_led_regs[0]; + leds->leds[0].regmap = pmic->regmap; + ret = cht_wc_led_save_regs(&leds->leds[0], &leds->led1_initial_regs); + if (ret < 0) + return ret; + + /* Set LED1 default trigger based on machine model */ + switch (pmic->cht_wc_model) { + case INTEL_CHT_WC_GPD_WIN_POCKET: + leds->leds[0].cdev.default_trigger = "max170xx_battery-charging-blink-full-solid"; + break; + case INTEL_CHT_WC_XIAOMI_MIPAD2: + leds->leds[0].cdev.default_trigger = "bq27520-0-charging-blink-full-solid"; + break; + case INTEL_CHT_WC_LENOVO_YOGABOOK1: + leds->leds[0].cdev.default_trigger = "bq27542-0-charging-blink-full-solid"; + break; + default: + dev_warn(&pdev->dev, "Unknown model, no default charging trigger\n"); + break; + } + + for (i = 0; i < CHT_WC_LED_COUNT; i++) { + struct cht_wc_led *led = &leds->leds[i]; + + led->regs = &cht_wc_led_regs[i]; + led->regmap = pmic->regmap; + mutex_init(&led->mutex); + led->cdev.name = cht_wc_leds_names[i]; + led->cdev.brightness_set_blocking = cht_wc_leds_brightness_set; + led->cdev.brightness_get = cht_wc_leds_brightness_get; + led->cdev.blink_set = cht_wc_leds_blink_set; + led->cdev.pattern_set = cht_wc_leds_pattern_set; + led->cdev.pattern_clear = cht_wc_leds_pattern_clear; + led->cdev.max_brightness = 255; + + ret = led_classdev_register(&pdev->dev, &led->cdev); + if (ret < 0) + return ret; + } + + platform_set_drvdata(pdev, leds); + return 0; +} + +static void cht_wc_leds_remove(struct platform_device *pdev) +{ + struct cht_wc_leds *leds = platform_get_drvdata(pdev); + int i; + + for (i = 0; i < CHT_WC_LED_COUNT; i++) + led_classdev_unregister(&leds->leds[i].cdev); + + /* Restore LED1 regs if hw-control was active else leave LED1 off */ + if (!(leds->led1_initial_regs.ctrl & CHT_WC_LED1_SWCTL)) + cht_wc_led_restore_regs(&leds->leds[0], &leds->led1_initial_regs); +} + +static void cht_wc_leds_disable(struct platform_device *pdev) +{ + struct cht_wc_leds *leds = platform_get_drvdata(pdev); + int i; + + for (i = 0; i < CHT_WC_LED_COUNT; i++) + cht_wc_leds_brightness_set(&leds->leds[i].cdev, 0); + + /* Restore LED1 regs if hw-control was active else leave LED1 off */ + if (!(leds->led1_initial_regs.ctrl & CHT_WC_LED1_SWCTL)) + cht_wc_led_restore_regs(&leds->leds[0], &leds->led1_initial_regs); +} + +/* On suspend save current settings and turn LEDs off */ +static int cht_wc_leds_suspend(struct device *dev) +{ + struct cht_wc_leds *leds = dev_get_drvdata(dev); + int i, ret; + + for (i = 0; i < CHT_WC_LED_COUNT; i++) { + ret = cht_wc_led_save_regs(&leds->leds[i], &leds->leds[i].saved_regs); + if (ret < 0) + return ret; + } + + cht_wc_leds_disable(to_platform_device(dev)); + return 0; +} + +/* On resume restore the saved settings */ +static int cht_wc_leds_resume(struct device *dev) +{ + struct cht_wc_leds *leds = dev_get_drvdata(dev); + int i; + + for (i = 0; i < CHT_WC_LED_COUNT; i++) + cht_wc_led_restore_regs(&leds->leds[i], &leds->leds[i].saved_regs); + + return 0; +} + +static DEFINE_SIMPLE_DEV_PM_OPS(cht_wc_leds_pm, cht_wc_leds_suspend, cht_wc_leds_resume); + +static struct platform_driver cht_wc_leds_driver = { + .probe = cht_wc_leds_probe, + .remove_new = cht_wc_leds_remove, + .shutdown = cht_wc_leds_disable, + .driver = { + .name = "cht_wcove_leds", + .pm = pm_sleep_ptr(&cht_wc_leds_pm), + }, +}; +module_platform_driver(cht_wc_leds_driver); + +MODULE_ALIAS("platform:cht_wcove_leds"); +MODULE_DESCRIPTION("Intel Cherry Trail Whiskey Cove PMIC LEDs driver"); +MODULE_AUTHOR("Yauhen Kharuzhy "); +MODULE_LICENSE("GPL"); diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c index ce4e79939731..7bfe40a6bfdd 100644 --- a/drivers/leds/leds-gpio.c +++ b/drivers/leds/leds-gpio.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -77,6 +78,7 @@ static int create_gpio_led(const struct gpio_led *template, struct fwnode_handle *fwnode, gpio_blink_set_t blink_set) { struct led_init_data init_data = {}; + struct pinctrl *pinctrl; int ret, state; led_dat->cdev.default_trigger = template->default_trigger; @@ -119,6 +121,22 @@ static int create_gpio_led(const struct gpio_led *template, &init_data); } + if (ret) + return ret; + + pinctrl = devm_pinctrl_get_select_default(led_dat->cdev.dev); + if (IS_ERR(pinctrl)) { + ret = PTR_ERR(pinctrl); + if (ret != -ENODEV) { + dev_warn(led_dat->cdev.dev, + "Failed to select %pOF pinctrl: %d\n", + to_of_node(fwnode), ret); + } else { + /* pinctrl-%d not present, not an error */ + ret = 0; + } + } + return ret; } diff --git a/drivers/leds/leds-is31fl319x.c b/drivers/leds/leds-is31fl319x.c index 7c908414ac7e..66c65741202e 100644 --- a/drivers/leds/leds-is31fl319x.c +++ b/drivers/leds/leds-is31fl319x.c @@ -602,7 +602,7 @@ static struct i2c_driver is31fl319x_driver = { .name = "leds-is31fl319x", .of_match_table = of_is31fl319x_match, }, - .probe_new = is31fl319x_probe, + .probe = is31fl319x_probe, .id_table = is31fl319x_id, }; diff --git a/drivers/leds/leds-is31fl32xx.c b/drivers/leds/leds-is31fl32xx.c index 799191859ce0..72cb56d305c4 100644 --- a/drivers/leds/leds-is31fl32xx.c +++ b/drivers/leds/leds-is31fl32xx.c @@ -488,7 +488,7 @@ static struct i2c_driver is31fl32xx_driver = { .name = "is31fl32xx", .of_match_table = of_is31fl32xx_match, }, - .probe_new = is31fl32xx_probe, + .probe = is31fl32xx_probe, .remove = is31fl32xx_remove, .id_table = is31fl32xx_id, }; diff --git a/drivers/leds/leds-lm3530.c b/drivers/leds/leds-lm3530.c index a9a2018592ff..a2feef8e4ac5 100644 --- a/drivers/leds/leds-lm3530.c +++ b/drivers/leds/leds-lm3530.c @@ -484,7 +484,7 @@ static const struct i2c_device_id lm3530_id[] = { MODULE_DEVICE_TABLE(i2c, lm3530_id); static struct i2c_driver lm3530_i2c_driver = { - .probe_new = lm3530_probe, + .probe = lm3530_probe, .remove = lm3530_remove, .id_table = lm3530_id, .driver = { diff --git a/drivers/leds/leds-lm3532.c b/drivers/leds/leds-lm3532.c index a08c09129a68..13662a4aa1f2 100644 --- a/drivers/leds/leds-lm3532.c +++ b/drivers/leds/leds-lm3532.c @@ -726,7 +726,7 @@ static const struct i2c_device_id lm3532_id[] = { MODULE_DEVICE_TABLE(i2c, lm3532_id); static struct i2c_driver lm3532_i2c_driver = { - .probe_new = lm3532_probe, + .probe = lm3532_probe, .remove = lm3532_remove, .id_table = lm3532_id, .driver = { diff --git a/drivers/leds/leds-lm355x.c b/drivers/leds/leds-lm355x.c index 612873070ca4..f68771b9eac6 100644 --- a/drivers/leds/leds-lm355x.c +++ b/drivers/leds/leds-lm355x.c @@ -516,7 +516,7 @@ static struct i2c_driver lm355x_i2c_driver = { .name = LM355x_NAME, .pm = NULL, }, - .probe_new = lm355x_probe, + .probe = lm355x_probe, .remove = lm355x_remove, .id_table = lm355x_id, }; diff --git a/drivers/leds/leds-lm3642.c b/drivers/leds/leds-lm3642.c index b75ee3546c2e..6eee52e211be 100644 --- a/drivers/leds/leds-lm3642.c +++ b/drivers/leds/leds-lm3642.c @@ -401,7 +401,7 @@ static struct i2c_driver lm3642_i2c_driver = { .name = LM3642_NAME, .pm = NULL, }, - .probe_new = lm3642_probe, + .probe = lm3642_probe, .remove = lm3642_remove, .id_table = lm3642_id, }; diff --git a/drivers/leds/leds-lm3692x.c b/drivers/leds/leds-lm3692x.c index 66126d0666f5..f8ad61e47a19 100644 --- a/drivers/leds/leds-lm3692x.c +++ b/drivers/leds/leds-lm3692x.c @@ -518,7 +518,7 @@ static struct i2c_driver lm3692x_driver = { .name = "lm3692x", .of_match_table = of_lm3692x_leds_match, }, - .probe_new = lm3692x_probe, + .probe = lm3692x_probe, .remove = lm3692x_remove, .id_table = lm3692x_id, }; diff --git a/drivers/leds/leds-lm3697.c b/drivers/leds/leds-lm3697.c index 10e904bf40a0..cfb8ac220db6 100644 --- a/drivers/leds/leds-lm3697.c +++ b/drivers/leds/leds-lm3697.c @@ -376,7 +376,7 @@ static struct i2c_driver lm3697_driver = { .name = "lm3697", .of_match_table = of_lm3697_leds_match, }, - .probe_new = lm3697_probe, + .probe = lm3697_probe, .remove = lm3697_remove, .id_table = lm3697_id, }; diff --git a/drivers/leds/leds-lp3944.c b/drivers/leds/leds-lp3944.c index be47c66b2e00..8ea746c499d1 100644 --- a/drivers/leds/leds-lp3944.c +++ b/drivers/leds/leds-lp3944.c @@ -427,7 +427,7 @@ static struct i2c_driver lp3944_driver = { .driver = { .name = "lp3944", }, - .probe_new = lp3944_probe, + .probe = lp3944_probe, .remove = lp3944_remove, .id_table = lp3944_id, }; diff --git a/drivers/leds/leds-lp3952.c b/drivers/leds/leds-lp3952.c index 24b2e0f9080d..3bd55652a706 100644 --- a/drivers/leds/leds-lp3952.c +++ b/drivers/leds/leds-lp3952.c @@ -273,7 +273,7 @@ static struct i2c_driver lp3952_i2c_driver = { .driver = { .name = LP3952_NAME, }, - .probe_new = lp3952_probe, + .probe = lp3952_probe, .remove = lp3952_remove, .id_table = lp3952_id, }; diff --git a/drivers/leds/leds-lp50xx.c b/drivers/leds/leds-lp50xx.c index 28d6b39fa72d..68c4d9967d68 100644 --- a/drivers/leds/leds-lp50xx.c +++ b/drivers/leds/leds-lp50xx.c @@ -608,7 +608,7 @@ static struct i2c_driver lp50xx_driver = { .name = "lp50xx", .of_match_table = of_lp50xx_leds_match, }, - .probe_new = lp50xx_probe, + .probe = lp50xx_probe, .remove = lp50xx_remove, .id_table = lp50xx_id, }; diff --git a/drivers/leds/leds-lp5521.c b/drivers/leds/leds-lp5521.c index a004af8e22c7..030c040fdf6d 100644 --- a/drivers/leds/leds-lp5521.c +++ b/drivers/leds/leds-lp5521.c @@ -58,14 +58,11 @@ /* CONFIG register */ #define LP5521_PWM_HF 0x40 /* PWM: 0 = 256Hz, 1 = 558Hz */ #define LP5521_PWRSAVE_EN 0x20 /* 1 = Power save mode */ -#define LP5521_CP_MODE_OFF 0 /* Charge pump (CP) off */ -#define LP5521_CP_MODE_BYPASS 8 /* CP forced to bypass mode */ -#define LP5521_CP_MODE_1X5 0x10 /* CP forced to 1.5x mode */ -#define LP5521_CP_MODE_AUTO 0x18 /* Automatic mode selection */ +#define LP5521_CP_MODE_MASK 0x18 /* Charge pump mode */ +#define LP5521_CP_MODE_SHIFT 3 #define LP5521_R_TO_BATT 0x04 /* R out: 0 = CP, 1 = Vbat */ #define LP5521_CLK_INT 0x01 /* Internal clock */ -#define LP5521_DEFAULT_CFG \ - (LP5521_PWM_HF | LP5521_PWRSAVE_EN | LP5521_CP_MODE_AUTO) +#define LP5521_DEFAULT_CFG (LP5521_PWM_HF | LP5521_PWRSAVE_EN) /* Status */ #define LP5521_EXT_CLK_USED 0x08 @@ -310,6 +307,8 @@ static int lp5521_post_init_device(struct lp55xx_chip *chip) if (!lp55xx_is_extclk_used(chip)) val |= LP5521_CLK_INT; + val |= (chip->pdata->charge_pump_mode << LP5521_CP_MODE_SHIFT) & LP5521_CP_MODE_MASK; + ret = lp55xx_write(chip, LP5521_REG_CONFIG, val); if (ret) return ret; @@ -608,7 +607,7 @@ static struct i2c_driver lp5521_driver = { .name = "lp5521", .of_match_table = of_match_ptr(of_lp5521_leds_match), }, - .probe_new = lp5521_probe, + .probe = lp5521_probe, .remove = lp5521_remove, .id_table = lp5521_id, }; diff --git a/drivers/leds/leds-lp5523.c b/drivers/leds/leds-lp5523.c index 55da914b8e5c..daa6a165fba6 100644 --- a/drivers/leds/leds-lp5523.c +++ b/drivers/leds/leds-lp5523.c @@ -57,8 +57,11 @@ #define LP5523_AUTO_INC 0x40 #define LP5523_PWR_SAVE 0x20 #define LP5523_PWM_PWR_SAVE 0x04 -#define LP5523_CP_AUTO 0x18 +#define LP5523_CP_MODE_MASK 0x18 +#define LP5523_CP_MODE_SHIFT 3 #define LP5523_AUTO_CLK 0x02 +#define LP5523_DEFAULT_CONFIG \ + (LP5523_AUTO_INC | LP5523_PWR_SAVE | LP5523_AUTO_CLK | LP5523_PWM_PWR_SAVE) #define LP5523_EN_LEDTEST 0x80 #define LP5523_LEDTEST_DONE 0x80 @@ -125,6 +128,7 @@ static void lp5523_set_led_current(struct lp55xx_led *led, u8 led_current) static int lp5523_post_init_device(struct lp55xx_chip *chip) { int ret; + int val; ret = lp55xx_write(chip, LP5523_REG_ENABLE, LP5523_ENABLE); if (ret) @@ -133,10 +137,10 @@ static int lp5523_post_init_device(struct lp55xx_chip *chip) /* Chip startup time is 500 us, 1 - 2 ms gives some margin */ usleep_range(1000, 2000); - ret = lp55xx_write(chip, LP5523_REG_CONFIG, - LP5523_AUTO_INC | LP5523_PWR_SAVE | - LP5523_CP_AUTO | LP5523_AUTO_CLK | - LP5523_PWM_PWR_SAVE); + val = LP5523_DEFAULT_CONFIG; + val |= (chip->pdata->charge_pump_mode << LP5523_CP_MODE_SHIFT) & LP5523_CP_MODE_MASK; + + ret = lp55xx_write(chip, LP5523_REG_CONFIG, val); if (ret) return ret; @@ -983,7 +987,7 @@ static struct i2c_driver lp5523_driver = { .name = "lp5523x", .of_match_table = of_match_ptr(of_lp5523_leds_match), }, - .probe_new = lp5523_probe, + .probe = lp5523_probe, .remove = lp5523_remove, .id_table = lp5523_id, }; diff --git a/drivers/leds/leds-lp5562.c b/drivers/leds/leds-lp5562.c index b5d877faf6d7..4565cc12cea8 100644 --- a/drivers/leds/leds-lp5562.c +++ b/drivers/leds/leds-lp5562.c @@ -603,7 +603,7 @@ static struct i2c_driver lp5562_driver = { .name = "lp5562", .of_match_table = of_match_ptr(of_lp5562_leds_match), }, - .probe_new = lp5562_probe, + .probe = lp5562_probe, .remove = lp5562_remove, .id_table = lp5562_id, }; diff --git a/drivers/leds/leds-lp55xx-common.c b/drivers/leds/leds-lp55xx-common.c index c1940964067a..77bb26906ea6 100644 --- a/drivers/leds/leds-lp55xx-common.c +++ b/drivers/leds/leds-lp55xx-common.c @@ -18,6 +18,7 @@ #include #include #include +#include #include "leds-lp55xx-common.h" @@ -691,6 +692,14 @@ struct lp55xx_platform_data *lp55xx_of_populate_pdata(struct device *dev, i++; } + if (of_property_read_u32(np, "ti,charge-pump-mode", &pdata->charge_pump_mode)) + pdata->charge_pump_mode = LP55XX_CP_AUTO; + + if (pdata->charge_pump_mode > LP55XX_CP_AUTO) { + dev_err(dev, "invalid charge pump mode %d\n", pdata->charge_pump_mode); + return ERR_PTR(-EINVAL); + } + of_property_read_string(np, "label", &pdata->label); of_property_read_u8(np, "clock-mode", &pdata->clock_mode); diff --git a/drivers/leds/leds-lp8501.c b/drivers/leds/leds-lp8501.c index 165d6423a928..f11886aa8965 100644 --- a/drivers/leds/leds-lp8501.c +++ b/drivers/leds/leds-lp8501.c @@ -53,10 +53,10 @@ #define LP8501_PWM_PSAVE BIT(7) #define LP8501_AUTO_INC BIT(6) #define LP8501_PWR_SAVE BIT(5) -#define LP8501_CP_AUTO 0x18 +#define LP8501_CP_MODE_MASK 0x18 +#define LP8501_CP_MODE_SHIFT 3 #define LP8501_INT_CLK BIT(0) -#define LP8501_DEFAULT_CFG \ - (LP8501_PWM_PSAVE | LP8501_AUTO_INC | LP8501_PWR_SAVE | LP8501_CP_AUTO) +#define LP8501_DEFAULT_CFG (LP8501_PWM_PSAVE | LP8501_AUTO_INC | LP8501_PWR_SAVE) #define LP8501_REG_RESET 0x3D #define LP8501_RESET 0xFF @@ -102,6 +102,8 @@ static int lp8501_post_init_device(struct lp55xx_chip *chip) if (chip->pdata->clock_mode != LP55XX_CLOCK_EXT) val |= LP8501_INT_CLK; + val |= (chip->pdata->charge_pump_mode << LP8501_CP_MODE_SHIFT) & LP8501_CP_MODE_MASK; + ret = lp55xx_write(chip, LP8501_REG_CONFIG, val); if (ret) return ret; @@ -392,7 +394,7 @@ static struct i2c_driver lp8501_driver = { .name = "lp8501", .of_match_table = of_match_ptr(of_lp8501_leds_match), }, - .probe_new = lp8501_probe, + .probe = lp8501_probe, .remove = lp8501_remove, .id_table = lp8501_id, }; diff --git a/drivers/leds/leds-lp8860.c b/drivers/leds/leds-lp8860.c index 221b386443bc..19b621012e58 100644 --- a/drivers/leds/leds-lp8860.c +++ b/drivers/leds/leds-lp8860.c @@ -475,7 +475,7 @@ static struct i2c_driver lp8860_driver = { .name = "lp8860", .of_match_table = of_lp8860_leds_match, }, - .probe_new = lp8860_probe, + .probe = lp8860_probe, .remove = lp8860_remove, .id_table = lp8860_id, }; diff --git a/drivers/leds/leds-mt6323.c b/drivers/leds/leds-mt6323.c index 17ee88043f52..24f35bdb55fb 100644 --- a/drivers/leds/leds-mt6323.c +++ b/drivers/leds/leds-mt6323.c @@ -14,61 +14,54 @@ #include /* - * Register field for MT6323_TOP_CKPDN0 to enable + * Register field for TOP_CKPDN0 to enable * 32K clock common for LED device. */ -#define MT6323_RG_DRV_32K_CK_PDN BIT(11) -#define MT6323_RG_DRV_32K_CK_PDN_MASK BIT(11) +#define RG_DRV_32K_CK_PDN BIT(11) +#define RG_DRV_32K_CK_PDN_MASK BIT(11) + +/* 32K/1M/6M clock common for WLED device */ +#define RG_VWLED_1M_CK_PDN BIT(0) +#define RG_VWLED_32K_CK_PDN BIT(12) +#define RG_VWLED_6M_CK_PDN BIT(13) /* - * Register field for MT6323_TOP_CKPDN2 to enable + * Register field for TOP_CKPDN2 to enable * individual clock for LED device. */ -#define MT6323_RG_ISINK_CK_PDN(i) BIT(i) -#define MT6323_RG_ISINK_CK_PDN_MASK(i) BIT(i) +#define RG_ISINK_CK_PDN(i) BIT(i) +#define RG_ISINK_CK_PDN_MASK(i) BIT(i) /* - * Register field for MT6323_TOP_CKCON1 to select + * Register field for TOP_CKCON1 to select * clock source. */ -#define MT6323_RG_ISINK_CK_SEL_MASK(i) (BIT(10) << (i)) +#define RG_ISINK_CK_SEL_MASK(i) (BIT(10) << (i)) -/* - * Register for MT6323_ISINK_CON0 to setup the - * duty cycle of the blink. - */ -#define MT6323_ISINK_CON0(i) (MT6323_ISINK0_CON0 + 0x8 * (i)) -#define MT6323_ISINK_DIM_DUTY_MASK (0x1f << 8) -#define MT6323_ISINK_DIM_DUTY(i) (((i) << 8) & \ - MT6323_ISINK_DIM_DUTY_MASK) +#define ISINK_CON(r, i) (r + 0x8 * (i)) -/* Register to setup the period of the blink. */ -#define MT6323_ISINK_CON1(i) (MT6323_ISINK0_CON1 + 0x8 * (i)) -#define MT6323_ISINK_DIM_FSEL_MASK (0xffff) -#define MT6323_ISINK_DIM_FSEL(i) ((i) & MT6323_ISINK_DIM_FSEL_MASK) +/* ISINK_CON0: Register to setup the duty cycle of the blink. */ +#define ISINK_DIM_DUTY_MASK (0x1f << 8) +#define ISINK_DIM_DUTY(i) (((i) << 8) & ISINK_DIM_DUTY_MASK) -/* Register to control the brightness. */ -#define MT6323_ISINK_CON2(i) (MT6323_ISINK0_CON2 + 0x8 * (i)) -#define MT6323_ISINK_CH_STEP_SHIFT 12 -#define MT6323_ISINK_CH_STEP_MASK (0x7 << 12) -#define MT6323_ISINK_CH_STEP(i) (((i) << 12) & \ - MT6323_ISINK_CH_STEP_MASK) -#define MT6323_ISINK_SFSTR0_TC_MASK (0x3 << 1) -#define MT6323_ISINK_SFSTR0_TC(i) (((i) << 1) & \ - MT6323_ISINK_SFSTR0_TC_MASK) -#define MT6323_ISINK_SFSTR0_EN_MASK BIT(0) -#define MT6323_ISINK_SFSTR0_EN BIT(0) +/* ISINK_CON1: Register to setup the period of the blink. */ +#define ISINK_DIM_FSEL_MASK (0xffff) +#define ISINK_DIM_FSEL(i) ((i) & ISINK_DIM_FSEL_MASK) + +/* ISINK_CON2: Register to control the brightness. */ +#define ISINK_CH_STEP_SHIFT 12 +#define ISINK_CH_STEP_MASK (0x7 << 12) +#define ISINK_CH_STEP(i) (((i) << 12) & ISINK_CH_STEP_MASK) +#define ISINK_SFSTR0_TC_MASK (0x3 << 1) +#define ISINK_SFSTR0_TC(i) (((i) << 1) & ISINK_SFSTR0_TC_MASK) +#define ISINK_SFSTR0_EN_MASK BIT(0) +#define ISINK_SFSTR0_EN BIT(0) /* Register to LED channel enablement. */ -#define MT6323_ISINK_CH_EN_MASK(i) BIT(i) -#define MT6323_ISINK_CH_EN(i) BIT(i) +#define ISINK_CH_EN_MASK(i) BIT(i) +#define ISINK_CH_EN(i) BIT(i) -#define MT6323_MAX_PERIOD 10000 -#define MT6323_MAX_LEDS 4 -#define MT6323_MAX_BRIGHTNESS 6 -#define MT6323_UNIT_DUTY 3125 -#define MT6323_CAL_HW_DUTY(o, p) DIV_ROUND_CLOSEST((o) * 100000ul,\ - (p) * MT6323_UNIT_DUTY) +#define MAX_SUPPORTED_LEDS 8 struct mt6323_leds; @@ -86,12 +79,63 @@ struct mt6323_led { enum led_brightness current_brightness; }; +/** + * struct mt6323_regs - register spec for the LED device + * @top_ckpdn: Offset to ISINK_CKPDN[0..x] registers + * @num_top_ckpdn: Number of ISINK_CKPDN registers + * @top_ckcon: Offset to ISINK_CKCON[0..x] registers + * @num_top_ckcon: Number of ISINK_CKCON registers + * @isink_con: Offset to ISINKx_CON[0..x] registers + * @num_isink_con: Number of ISINKx_CON registers + * @isink_max_regs: Number of ISINK[0..x] registers + * @isink_en_ctrl: Offset to ISINK_EN_CTRL register + * @iwled_en_ctrl: Offset to IWLED_EN_CTRL register + */ +struct mt6323_regs { + const u16 *top_ckpdn; + u8 num_top_ckpdn; + const u16 *top_ckcon; + u8 num_top_ckcon; + const u16 *isink_con; + u8 num_isink_con; + u8 isink_max_regs; + u16 isink_en_ctrl; + u16 iwled_en_ctrl; +}; + +/** + * struct mt6323_hwspec - hardware specific parameters + * @max_period: Maximum period for all LEDs + * @max_leds: Maximum number of supported LEDs + * @max_wleds: Maximum number of WLEDs + * @max_brightness: Maximum brightness for all LEDs + * @unit_duty: Steps of duty per period + */ +struct mt6323_hwspec { + u16 max_period; + u8 max_leds; + u8 max_wleds; + u16 max_brightness; + u16 unit_duty; +}; + +/** + * struct mt6323_data - device specific data + * @regs: Register spec for this device + * @spec: Hardware specific parameters + */ +struct mt6323_data { + const struct mt6323_regs *regs; + const struct mt6323_hwspec *spec; +}; + /** * struct mt6323_leds - state container for holding LED controller * of the driver * @dev: the device pointer * @hw: the underlying hardware providing shared * bus for the register operations + * @pdata: device specific data * @lock: the lock among process context * @led: the array that contains the state of individual * LED device @@ -99,9 +143,10 @@ struct mt6323_led { struct mt6323_leds { struct device *dev; struct mt6397_chip *hw; + const struct mt6323_data *pdata; /* protect among process context */ struct mutex lock; - struct mt6323_led *led[MT6323_MAX_LEDS]; + struct mt6323_led *led[MAX_SUPPORTED_LEDS]; }; static int mt6323_led_hw_brightness(struct led_classdev *cdev, @@ -109,6 +154,7 @@ static int mt6323_led_hw_brightness(struct led_classdev *cdev, { struct mt6323_led *led = container_of(cdev, struct mt6323_led, cdev); struct mt6323_leds *leds = led->parent; + const struct mt6323_regs *regs = leds->pdata->regs; struct regmap *regmap = leds->hw->regmap; u32 con2_mask = 0, con2_val = 0; int ret; @@ -117,14 +163,14 @@ static int mt6323_led_hw_brightness(struct led_classdev *cdev, * Setup current output for the corresponding * brightness level. */ - con2_mask |= MT6323_ISINK_CH_STEP_MASK | - MT6323_ISINK_SFSTR0_TC_MASK | - MT6323_ISINK_SFSTR0_EN_MASK; - con2_val |= MT6323_ISINK_CH_STEP(brightness - 1) | - MT6323_ISINK_SFSTR0_TC(2) | - MT6323_ISINK_SFSTR0_EN; + con2_mask |= ISINK_CH_STEP_MASK | + ISINK_SFSTR0_TC_MASK | + ISINK_SFSTR0_EN_MASK; + con2_val |= ISINK_CH_STEP(brightness - 1) | + ISINK_SFSTR0_TC(2) | + ISINK_SFSTR0_EN; - ret = regmap_update_bits(regmap, MT6323_ISINK_CON2(led->id), + ret = regmap_update_bits(regmap, ISINK_CON(regs->isink_con[2], led->id), con2_mask, con2_val); return ret; } @@ -133,20 +179,21 @@ static int mt6323_led_hw_off(struct led_classdev *cdev) { struct mt6323_led *led = container_of(cdev, struct mt6323_led, cdev); struct mt6323_leds *leds = led->parent; + const struct mt6323_regs *regs = leds->pdata->regs; struct regmap *regmap = leds->hw->regmap; unsigned int status; int ret; - status = MT6323_ISINK_CH_EN(led->id); - ret = regmap_update_bits(regmap, MT6323_ISINK_EN_CTRL, - MT6323_ISINK_CH_EN_MASK(led->id), ~status); + status = ISINK_CH_EN(led->id); + ret = regmap_update_bits(regmap, regs->isink_en_ctrl, + ISINK_CH_EN_MASK(led->id), ~status); if (ret < 0) return ret; usleep_range(100, 300); - ret = regmap_update_bits(regmap, MT6323_TOP_CKPDN2, - MT6323_RG_ISINK_CK_PDN_MASK(led->id), - MT6323_RG_ISINK_CK_PDN(led->id)); + ret = regmap_update_bits(regmap, regs->top_ckpdn[2], + RG_ISINK_CK_PDN_MASK(led->id), + RG_ISINK_CK_PDN(led->id)); if (ret < 0) return ret; @@ -158,30 +205,31 @@ mt6323_get_led_hw_brightness(struct led_classdev *cdev) { struct mt6323_led *led = container_of(cdev, struct mt6323_led, cdev); struct mt6323_leds *leds = led->parent; + const struct mt6323_regs *regs = leds->pdata->regs; struct regmap *regmap = leds->hw->regmap; unsigned int status; int ret; - ret = regmap_read(regmap, MT6323_TOP_CKPDN2, &status); + ret = regmap_read(regmap, regs->top_ckpdn[2], &status); if (ret < 0) return ret; - if (status & MT6323_RG_ISINK_CK_PDN_MASK(led->id)) + if (status & RG_ISINK_CK_PDN_MASK(led->id)) return 0; - ret = regmap_read(regmap, MT6323_ISINK_EN_CTRL, &status); + ret = regmap_read(regmap, regs->isink_en_ctrl, &status); if (ret < 0) return ret; - if (!(status & MT6323_ISINK_CH_EN(led->id))) + if (!(status & ISINK_CH_EN(led->id))) return 0; - ret = regmap_read(regmap, MT6323_ISINK_CON2(led->id), &status); + ret = regmap_read(regmap, ISINK_CON(regs->isink_con[2], led->id), &status); if (ret < 0) return ret; - return ((status & MT6323_ISINK_CH_STEP_MASK) - >> MT6323_ISINK_CH_STEP_SHIFT) + 1; + return ((status & ISINK_CH_STEP_MASK) + >> ISINK_CH_STEP_SHIFT) + 1; } static int mt6323_led_hw_on(struct led_classdev *cdev, @@ -189,6 +237,7 @@ static int mt6323_led_hw_on(struct led_classdev *cdev, { struct mt6323_led *led = container_of(cdev, struct mt6323_led, cdev); struct mt6323_leds *leds = led->parent; + const struct mt6323_regs *regs = leds->pdata->regs; struct regmap *regmap = leds->hw->regmap; unsigned int status; int ret; @@ -198,23 +247,23 @@ static int mt6323_led_hw_on(struct led_classdev *cdev, * clock and channel and let work with continuous blink as * the default. */ - ret = regmap_update_bits(regmap, MT6323_TOP_CKCON1, - MT6323_RG_ISINK_CK_SEL_MASK(led->id), 0); + ret = regmap_update_bits(regmap, regs->top_ckcon[1], + RG_ISINK_CK_SEL_MASK(led->id), 0); if (ret < 0) return ret; - status = MT6323_RG_ISINK_CK_PDN(led->id); - ret = regmap_update_bits(regmap, MT6323_TOP_CKPDN2, - MT6323_RG_ISINK_CK_PDN_MASK(led->id), + status = RG_ISINK_CK_PDN(led->id); + ret = regmap_update_bits(regmap, regs->top_ckpdn[2], + RG_ISINK_CK_PDN_MASK(led->id), ~status); if (ret < 0) return ret; usleep_range(100, 300); - ret = regmap_update_bits(regmap, MT6323_ISINK_EN_CTRL, - MT6323_ISINK_CH_EN_MASK(led->id), - MT6323_ISINK_CH_EN(led->id)); + ret = regmap_update_bits(regmap, regs->isink_en_ctrl, + ISINK_CH_EN_MASK(led->id), + ISINK_CH_EN(led->id)); if (ret < 0) return ret; @@ -222,15 +271,15 @@ static int mt6323_led_hw_on(struct led_classdev *cdev, if (ret < 0) return ret; - ret = regmap_update_bits(regmap, MT6323_ISINK_CON0(led->id), - MT6323_ISINK_DIM_DUTY_MASK, - MT6323_ISINK_DIM_DUTY(31)); + ret = regmap_update_bits(regmap, ISINK_CON(regs->isink_con[0], led->id), + ISINK_DIM_DUTY_MASK, + ISINK_DIM_DUTY(31)); if (ret < 0) return ret; - ret = regmap_update_bits(regmap, MT6323_ISINK_CON1(led->id), - MT6323_ISINK_DIM_FSEL_MASK, - MT6323_ISINK_DIM_FSEL(1000)); + ret = regmap_update_bits(regmap, ISINK_CON(regs->isink_con[1], led->id), + ISINK_DIM_FSEL_MASK, + ISINK_DIM_FSEL(1000)); if (ret < 0) return ret; @@ -243,6 +292,8 @@ static int mt6323_led_set_blink(struct led_classdev *cdev, { struct mt6323_led *led = container_of(cdev, struct mt6323_led, cdev); struct mt6323_leds *leds = led->parent; + const struct mt6323_regs *regs = leds->pdata->regs; + const struct mt6323_hwspec *spec = leds->pdata->spec; struct regmap *regmap = leds->hw->regmap; unsigned long period; u8 duty_hw; @@ -265,14 +316,14 @@ static int mt6323_led_set_blink(struct led_classdev *cdev, */ period = *delay_on + *delay_off; - if (period > MT6323_MAX_PERIOD) + if (period > spec->max_period) return -EINVAL; /* * Calculate duty_hw based on the percentage of period during * which the led is ON. */ - duty_hw = MT6323_CAL_HW_DUTY(*delay_on, period); + duty_hw = DIV_ROUND_CLOSEST(*delay_on * 100000ul, period * spec->unit_duty); /* hardware doesn't support zero duty cycle. */ if (!duty_hw) @@ -290,15 +341,15 @@ static int mt6323_led_set_blink(struct led_classdev *cdev, led->current_brightness = cdev->max_brightness; } - ret = regmap_update_bits(regmap, MT6323_ISINK_CON0(led->id), - MT6323_ISINK_DIM_DUTY_MASK, - MT6323_ISINK_DIM_DUTY(duty_hw - 1)); + ret = regmap_update_bits(regmap, ISINK_CON(regs->isink_con[0], led->id), + ISINK_DIM_DUTY_MASK, + ISINK_DIM_DUTY(duty_hw - 1)); if (ret < 0) goto out; - ret = regmap_update_bits(regmap, MT6323_ISINK_CON1(led->id), - MT6323_ISINK_DIM_FSEL_MASK, - MT6323_ISINK_DIM_FSEL(period - 1)); + ret = regmap_update_bits(regmap, ISINK_CON(regs->isink_con[1], led->id), + ISINK_DIM_FSEL_MASK, + ISINK_DIM_FSEL(period - 1)); out: mutex_unlock(&leds->lock); @@ -335,6 +386,117 @@ out: return ret; } +static int mtk_wled_hw_on(struct led_classdev *cdev) +{ + struct mt6323_led *led = container_of(cdev, struct mt6323_led, cdev); + struct mt6323_leds *leds = led->parent; + const struct mt6323_regs *regs = leds->pdata->regs; + struct regmap *regmap = leds->hw->regmap; + int ret; + + ret = regmap_clear_bits(regmap, regs->top_ckpdn[0], RG_VWLED_32K_CK_PDN); + if (ret) + return ret; + + ret = regmap_clear_bits(regmap, regs->top_ckpdn[0], RG_VWLED_6M_CK_PDN); + if (ret) + return ret; + + ret = regmap_clear_bits(regmap, regs->top_ckpdn[0], RG_VWLED_1M_CK_PDN); + if (ret) + return ret; + + usleep_range(5000, 6000); + + /* Enable WLED channel pair */ + ret = regmap_set_bits(regmap, regs->iwled_en_ctrl, BIT(led->id)); + if (ret) + return ret; + + ret = regmap_set_bits(regmap, regs->iwled_en_ctrl, BIT(led->id + 1)); + if (ret) + return ret; + + return 0; +} + +static int mtk_wled_hw_off(struct led_classdev *cdev) +{ + struct mt6323_led *led = container_of(cdev, struct mt6323_led, cdev); + struct mt6323_leds *leds = led->parent; + const struct mt6323_regs *regs = leds->pdata->regs; + struct regmap *regmap = leds->hw->regmap; + int ret; + + ret = regmap_clear_bits(regmap, regs->iwled_en_ctrl, BIT(led->id + 1)); + if (ret) + return ret; + + ret = regmap_clear_bits(regmap, regs->iwled_en_ctrl, BIT(led->id)); + if (ret) + return ret; + + ret = regmap_set_bits(regmap, regs->top_ckpdn[0], RG_VWLED_32K_CK_PDN); + if (ret) + return ret; + + ret = regmap_set_bits(regmap, regs->top_ckpdn[0], RG_VWLED_6M_CK_PDN); + if (ret) + return ret; + + ret = regmap_set_bits(regmap, regs->top_ckpdn[0], RG_VWLED_1M_CK_PDN); + if (ret) + return ret; + + return 0; +} + +static enum led_brightness mt6323_get_wled_brightness(struct led_classdev *cdev) +{ + struct mt6323_led *led = container_of(cdev, struct mt6323_led, cdev); + struct mt6323_leds *leds = led->parent; + const struct mt6323_regs *regs = leds->pdata->regs; + struct regmap *regmap = leds->hw->regmap; + unsigned int status; + int ret; + + ret = regmap_read(regmap, regs->iwled_en_ctrl, &status); + if (ret) + return 0; + + /* Always two channels per WLED */ + status &= BIT(led->id) | BIT(led->id + 1); + + return status ? led->current_brightness : 0; +} + +static int mt6323_wled_set_brightness(struct led_classdev *cdev, + enum led_brightness brightness) +{ + struct mt6323_led *led = container_of(cdev, struct mt6323_led, cdev); + struct mt6323_leds *leds = led->parent; + int ret = 0; + + mutex_lock(&leds->lock); + + if (brightness) { + if (!led->current_brightness) + ret = mtk_wled_hw_on(cdev); + if (ret) + goto out; + } else { + ret = mtk_wled_hw_off(cdev); + if (ret) + goto out; + } + + led->current_brightness = brightness; +out: + mutex_unlock(&leds->lock); + + return ret; +} + static int mt6323_led_set_dt_default(struct led_classdev *cdev, struct device_node *np) { @@ -369,9 +531,12 @@ static int mt6323_led_probe(struct platform_device *pdev) struct mt6397_chip *hw = dev_get_drvdata(dev->parent); struct mt6323_leds *leds; struct mt6323_led *led; + const struct mt6323_regs *regs; + const struct mt6323_hwspec *spec; int ret; unsigned int status; u32 reg; + u8 max_leds; leds = devm_kzalloc(dev, sizeof(*leds), GFP_KERNEL); if (!leds) @@ -379,6 +544,10 @@ static int mt6323_led_probe(struct platform_device *pdev) platform_set_drvdata(pdev, leds); leds->dev = dev; + leds->pdata = device_get_match_data(dev); + regs = leds->pdata->regs; + spec = leds->pdata->spec; + max_leds = spec->max_leds + spec->max_wleds; /* * leds->hw points to the underlying bus for the register @@ -387,17 +556,18 @@ static int mt6323_led_probe(struct platform_device *pdev) leds->hw = hw; mutex_init(&leds->lock); - status = MT6323_RG_DRV_32K_CK_PDN; - ret = regmap_update_bits(leds->hw->regmap, MT6323_TOP_CKPDN0, - MT6323_RG_DRV_32K_CK_PDN_MASK, ~status); + status = RG_DRV_32K_CK_PDN; + ret = regmap_update_bits(leds->hw->regmap, regs->top_ckpdn[0], + RG_DRV_32K_CK_PDN_MASK, ~status); if (ret < 0) { dev_err(leds->dev, - "Failed to update MT6323_TOP_CKPDN0 Register\n"); + "Failed to update TOP_CKPDN0 Register\n"); return ret; } for_each_available_child_of_node(np, child) { struct led_init_data init_data = {}; + bool is_wled; ret = of_property_read_u32(child, "reg", ®); if (ret) { @@ -405,7 +575,8 @@ static int mt6323_led_probe(struct platform_device *pdev) goto put_child_node; } - if (reg >= MT6323_MAX_LEDS || leds->led[reg]) { + if (reg >= max_leds || reg >= MAX_SUPPORTED_LEDS || + leds->led[reg]) { dev_err(dev, "Invalid led reg %u\n", reg); ret = -EINVAL; goto put_child_node; @@ -417,14 +588,24 @@ static int mt6323_led_probe(struct platform_device *pdev) goto put_child_node; } + is_wled = of_property_read_bool(child, "mediatek,is-wled"); + leds->led[reg] = led; leds->led[reg]->id = reg; - leds->led[reg]->cdev.max_brightness = MT6323_MAX_BRIGHTNESS; - leds->led[reg]->cdev.brightness_set_blocking = - mt6323_led_set_brightness; - leds->led[reg]->cdev.blink_set = mt6323_led_set_blink; - leds->led[reg]->cdev.brightness_get = - mt6323_get_led_hw_brightness; + leds->led[reg]->cdev.max_brightness = spec->max_brightness; + + if (is_wled) { + leds->led[reg]->cdev.brightness_set_blocking = + mt6323_wled_set_brightness; + leds->led[reg]->cdev.brightness_get = + mt6323_get_wled_brightness; + } else { + leds->led[reg]->cdev.brightness_set_blocking = + mt6323_led_set_brightness; + leds->led[reg]->cdev.blink_set = mt6323_led_set_blink; + leds->led[reg]->cdev.brightness_get = + mt6323_get_led_hw_brightness; + } leds->led[reg]->parent = leds; ret = mt6323_led_set_dt_default(&leds->led[reg]->cdev, child); @@ -454,23 +635,88 @@ put_child_node: static int mt6323_led_remove(struct platform_device *pdev) { struct mt6323_leds *leds = platform_get_drvdata(pdev); + const struct mt6323_regs *regs = leds->pdata->regs; int i; /* Turn the LEDs off on driver removal. */ for (i = 0 ; leds->led[i] ; i++) mt6323_led_hw_off(&leds->led[i]->cdev); - regmap_update_bits(leds->hw->regmap, MT6323_TOP_CKPDN0, - MT6323_RG_DRV_32K_CK_PDN_MASK, - MT6323_RG_DRV_32K_CK_PDN); + regmap_update_bits(leds->hw->regmap, regs->top_ckpdn[0], + RG_DRV_32K_CK_PDN_MASK, + RG_DRV_32K_CK_PDN); mutex_destroy(&leds->lock); return 0; } +static const struct mt6323_regs mt6323_registers = { + .top_ckpdn = (const u16[]){ 0x102, 0x106, 0x10e }, + .num_top_ckpdn = 3, + .top_ckcon = (const u16[]){ 0x120, 0x126 }, + .num_top_ckcon = 2, + .isink_con = (const u16[]){ 0x330, 0x332, 0x334 }, + .num_isink_con = 3, + .isink_max_regs = 4, /* ISINK[0..3] */ + .isink_en_ctrl = 0x356, +}; + +static const struct mt6323_regs mt6331_registers = { + .top_ckpdn = (const u16[]){ 0x138, 0x13e, 0x144 }, + .num_top_ckpdn = 3, + .top_ckcon = (const u16[]){ 0x14c, 0x14a }, + .num_top_ckcon = 2, + .isink_con = (const u16[]){ 0x40c, 0x40e, 0x410, 0x412, 0x414 }, + .num_isink_con = 5, + .isink_max_regs = 4, /* ISINK[0..3] */ + .isink_en_ctrl = 0x43a, +}; + +static const struct mt6323_regs mt6332_registers = { + .top_ckpdn = (const u16[]){ 0x8094, 0x809a, 0x80a0 }, + .num_top_ckpdn = 3, + .top_ckcon = (const u16[]){ 0x80a6, 0x80ac }, + .num_top_ckcon = 2, + .isink_con = (const u16[]){ 0x8cd4 }, + .num_isink_con = 1, + .isink_max_regs = 12, /* IWLED[0..2, 3..9] */ + .iwled_en_ctrl = 0x8cda, +}; + +static const struct mt6323_hwspec mt6323_spec = { + .max_period = 10000, + .max_leds = 4, + .max_brightness = 6, + .unit_duty = 3125, +}; + +static const struct mt6323_hwspec mt6332_spec = { + /* There are no LEDs in MT6332. Only WLEDs are present. */ + .max_leds = 0, + .max_wleds = 1, + .max_brightness = 1024, +}; + +static const struct mt6323_data mt6323_pdata = { + .regs = &mt6323_registers, + .spec = &mt6323_spec, +}; + +static const struct mt6323_data mt6331_pdata = { + .regs = &mt6331_registers, + .spec = &mt6323_spec, +}; + +static const struct mt6323_data mt6332_pdata = { + .regs = &mt6332_registers, + .spec = &mt6332_spec, +}; + static const struct of_device_id mt6323_led_dt_match[] = { - { .compatible = "mediatek,mt6323-led" }, + { .compatible = "mediatek,mt6323-led", .data = &mt6323_pdata}, + { .compatible = "mediatek,mt6331-led", .data = &mt6331_pdata }, + { .compatible = "mediatek,mt6332-led", .data = &mt6332_pdata }, {}, }; MODULE_DEVICE_TABLE(of, mt6323_led_dt_match); diff --git a/drivers/leds/leds-pca9532.c b/drivers/leds/leds-pca9532.c index 15b1acfa442e..8b5c62083e50 100644 --- a/drivers/leds/leds-pca9532.c +++ b/drivers/leds/leds-pca9532.c @@ -102,7 +102,7 @@ static struct i2c_driver pca9532_driver = { .name = "leds-pca953x", .of_match_table = of_match_ptr(of_pca9532_leds_match), }, - .probe_new = pca9532_probe, + .probe = pca9532_probe, .remove = pca9532_remove, .id_table = pca9532_id, }; diff --git a/drivers/leds/leds-pca955x.c b/drivers/leds/leds-pca955x.c index 1edd092e7894..b10e1ef38db0 100644 --- a/drivers/leds/leds-pca955x.c +++ b/drivers/leds/leds-pca955x.c @@ -668,7 +668,7 @@ static struct i2c_driver pca955x_driver = { .name = "leds-pca955x", .of_match_table = of_pca955x_match, }, - .probe_new = pca955x_probe, + .probe = pca955x_probe, .id_table = pca955x_id, }; diff --git a/drivers/leds/leds-pca963x.c b/drivers/leds/leds-pca963x.c index 9cd476db601f..47223c850e4b 100644 --- a/drivers/leds/leds-pca963x.c +++ b/drivers/leds/leds-pca963x.c @@ -431,7 +431,7 @@ static struct i2c_driver pca963x_driver = { .name = "leds-pca963x", .of_match_table = of_pca963x_match, }, - .probe_new = pca963x_probe, + .probe = pca963x_probe, .id_table = pca963x_id, }; diff --git a/drivers/leds/leds-spi-byte.c b/drivers/leds/leds-spi-byte.c index 2bc5c99daf51..2c7ffc3c78e6 100644 --- a/drivers/leds/leds-spi-byte.c +++ b/drivers/leds/leds-spi-byte.c @@ -98,7 +98,7 @@ static int spi_byte_probe(struct spi_device *spi) return -ENOMEM; of_property_read_string(child, "label", &name); - strlcpy(led->name, name, sizeof(led->name)); + strscpy(led->name, name, sizeof(led->name)); led->spi = spi; mutex_init(&led->mutex); led->cdef = device_get_match_data(dev); diff --git a/drivers/leds/leds-tca6507.c b/drivers/leds/leds-tca6507.c index 634cabd5bb79..aab861771210 100644 --- a/drivers/leds/leds-tca6507.c +++ b/drivers/leds/leds-tca6507.c @@ -808,7 +808,7 @@ static struct i2c_driver tca6507_driver = { .name = "leds-tca6507", .of_match_table = of_match_ptr(of_tca6507_leds_match), }, - .probe_new = tca6507_probe, + .probe = tca6507_probe, .remove = tca6507_remove, .id_table = tca6507_id, }; diff --git a/drivers/leds/leds-tlc591xx.c b/drivers/leds/leds-tlc591xx.c index 7e31db50036f..dfc6fb2b3e52 100644 --- a/drivers/leds/leds-tlc591xx.c +++ b/drivers/leds/leds-tlc591xx.c @@ -230,7 +230,7 @@ static struct i2c_driver tlc591xx_driver = { .name = "tlc591xx", .of_match_table = of_match_ptr(of_tlc591xx_leds_match), }, - .probe_new = tlc591xx_probe, + .probe = tlc591xx_probe, .id_table = tlc591xx_id, }; diff --git a/drivers/leds/leds-turris-omnia.c b/drivers/leds/leds-turris-omnia.c index 013f551b32b2..64b2d7b6d3f3 100644 --- a/drivers/leds/leds-turris-omnia.c +++ b/drivers/leds/leds-turris-omnia.c @@ -271,7 +271,7 @@ static const struct i2c_device_id omnia_id[] = { MODULE_DEVICE_TABLE(i2c, omnia_id); static struct i2c_driver omnia_leds_driver = { - .probe_new = omnia_leds_probe, + .probe = omnia_leds_probe, .remove = omnia_leds_remove, .id_table = omnia_id, .driver = { diff --git a/drivers/leds/rgb/leds-qcom-lpg.c b/drivers/leds/rgb/leds-qcom-lpg.c index 1c849814a491..59581b3e25ca 100644 --- a/drivers/leds/rgb/leds-qcom-lpg.c +++ b/drivers/leds/rgb/leds-qcom-lpg.c @@ -1173,8 +1173,10 @@ static int lpg_add_led(struct lpg *lpg, struct device_node *np) i = 0; for_each_available_child_of_node(np, child) { ret = lpg_parse_channel(lpg, child, &led->channels[i]); - if (ret < 0) + if (ret < 0) { + of_node_put(child); return ret; + } info[i].color_index = led->channels[i]->color; info[i].intensity = 0; @@ -1352,8 +1354,10 @@ static int lpg_probe(struct platform_device *pdev) for_each_available_child_of_node(pdev->dev.of_node, np) { ret = lpg_add_led(lpg, np); - if (ret) + if (ret) { + of_node_put(np); return ret; + } } for (i = 0; i < lpg->num_channels; i++) @@ -1414,6 +1418,20 @@ static const struct lpg_data pm8994_lpg_data = { }, }; +/* PMI632 uses SDAM instead of LUT for pattern */ +static const struct lpg_data pmi632_lpg_data = { + .triled_base = 0xd000, + + .num_channels = 5, + .channels = (const struct lpg_channel_data[]) { + { .base = 0xb300, .triled_mask = BIT(7) }, + { .base = 0xb400, .triled_mask = BIT(6) }, + { .base = 0xb500, .triled_mask = BIT(5) }, + { .base = 0xb600 }, + { .base = 0xb700 }, + }, +}; + static const struct lpg_data pmi8994_lpg_data = { .lut_base = 0xb000, .lut_size = 24, @@ -1505,6 +1523,7 @@ static const struct of_device_id lpg_of_table[] = { { .compatible = "qcom,pm8916-pwm", .data = &pm8916_pwm_data }, { .compatible = "qcom,pm8941-lpg", .data = &pm8941_lpg_data }, { .compatible = "qcom,pm8994-lpg", .data = &pm8994_lpg_data }, + { .compatible = "qcom,pmi632-lpg", .data = &pmi632_lpg_data }, { .compatible = "qcom,pmi8994-lpg", .data = &pmi8994_lpg_data }, { .compatible = "qcom,pmi8998-lpg", .data = &pmi8998_lpg_data }, { .compatible = "qcom,pmc8180c-lpg", .data = &pm8150l_lpg_data }, diff --git a/drivers/leds/simple/Kconfig b/drivers/leds/simple/Kconfig index fd2b8225d926..44fa0f93cb3b 100644 --- a/drivers/leds/simple/Kconfig +++ b/drivers/leds/simple/Kconfig @@ -1,11 +1,36 @@ # SPDX-License-Identifier: GPL-2.0-only config LEDS_SIEMENS_SIMATIC_IPC tristate "LED driver for Siemens Simatic IPCs" - depends on LEDS_GPIO depends on SIEMENS_SIMATIC_IPC help This option enables support for the LEDs of several Industrial PCs from Siemens. - To compile this driver as a module, choose M here: the modules - will be called simatic-ipc-leds and simatic-ipc-leds-gpio. + To compile this driver as a module, choose M here: the module + will be called simatic-ipc-leds. + +config LEDS_SIEMENS_SIMATIC_IPC_APOLLOLAKE + tristate "LED driver for Siemens Simatic IPCs based on Intel Apollo Lake GPIO" + depends on LEDS_GPIO + depends on PINCTRL_BROXTON + depends on SIEMENS_SIMATIC_IPC + default LEDS_SIEMENS_SIMATIC_IPC + help + This option enables support for the LEDs of several Industrial PCs + from Siemens based on Apollo Lake GPIO i.e. IPC127E. + + To compile this driver as a module, choose M here: the module + will be called simatic-ipc-leds-gpio-apollolake. + +config LEDS_SIEMENS_SIMATIC_IPC_F7188X + tristate "LED driver for Siemens Simatic IPCs based on Nuvoton GPIO" + depends on LEDS_GPIO + depends on GPIO_F7188X + depends on SIEMENS_SIMATIC_IPC + default LEDS_SIEMENS_SIMATIC_IPC + help + This option enables support for the LEDs of several Industrial PCs + from Siemens based on Nuvoton GPIO i.e. IPC227G. + + To compile this driver as a module, choose M here: the module + will be called simatic-ipc-leds-gpio-f7188x. diff --git a/drivers/leds/simple/Makefile b/drivers/leds/simple/Makefile index 1c7ef5e1324b..e3e840cea275 100644 --- a/drivers/leds/simple/Makefile +++ b/drivers/leds/simple/Makefile @@ -1,3 +1,4 @@ # SPDX-License-Identifier: GPL-2.0 -obj-$(CONFIG_LEDS_SIEMENS_SIMATIC_IPC) += simatic-ipc-leds.o -obj-$(CONFIG_LEDS_SIEMENS_SIMATIC_IPC) += simatic-ipc-leds-gpio.o +obj-$(CONFIG_LEDS_SIEMENS_SIMATIC_IPC) += simatic-ipc-leds.o +obj-$(CONFIG_LEDS_SIEMENS_SIMATIC_IPC_APOLLOLAKE) += simatic-ipc-leds-gpio-core.o simatic-ipc-leds-gpio-apollolake.o +obj-$(CONFIG_LEDS_SIEMENS_SIMATIC_IPC_F7188X) += simatic-ipc-leds-gpio-core.o simatic-ipc-leds-gpio-f7188x.o diff --git a/drivers/leds/simple/simatic-ipc-leds-gpio-apollolake.c b/drivers/leds/simple/simatic-ipc-leds-gpio-apollolake.c new file mode 100644 index 000000000000..e1c712729dcf --- /dev/null +++ b/drivers/leds/simple/simatic-ipc-leds-gpio-apollolake.c @@ -0,0 +1,66 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Siemens SIMATIC IPC driver for GPIO based LEDs + * + * Copyright (c) Siemens AG, 2023 + * + * Author: + * Henning Schild + */ + +#include +#include +#include +#include +#include +#include + +#include "simatic-ipc-leds-gpio.h" + +static struct gpiod_lookup_table simatic_ipc_led_gpio_table = { + .dev_id = "leds-gpio", + .table = { + GPIO_LOOKUP_IDX("apollolake-pinctrl.0", 52, NULL, 0, GPIO_ACTIVE_LOW), + GPIO_LOOKUP_IDX("apollolake-pinctrl.0", 53, NULL, 1, GPIO_ACTIVE_LOW), + GPIO_LOOKUP_IDX("apollolake-pinctrl.0", 57, NULL, 2, GPIO_ACTIVE_LOW), + GPIO_LOOKUP_IDX("apollolake-pinctrl.0", 58, NULL, 3, GPIO_ACTIVE_LOW), + GPIO_LOOKUP_IDX("apollolake-pinctrl.0", 60, NULL, 4, GPIO_ACTIVE_LOW), + GPIO_LOOKUP_IDX("apollolake-pinctrl.0", 51, NULL, 5, GPIO_ACTIVE_LOW), + {} /* Terminating entry */ + }, +}; + +static struct gpiod_lookup_table simatic_ipc_led_gpio_table_extra = { + .dev_id = NULL, /* Filled during initialization */ + .table = { + GPIO_LOOKUP_IDX("apollolake-pinctrl.0", 56, NULL, 6, GPIO_ACTIVE_LOW), + GPIO_LOOKUP_IDX("apollolake-pinctrl.0", 59, NULL, 7, GPIO_ACTIVE_HIGH), + {} /* Terminating entry */ + }, +}; + +static int simatic_ipc_leds_gpio_apollolake_probe(struct platform_device *pdev) +{ + return simatic_ipc_leds_gpio_probe(pdev, &simatic_ipc_led_gpio_table, + &simatic_ipc_led_gpio_table_extra); +} + +static int simatic_ipc_leds_gpio_apollolake_remove(struct platform_device *pdev) +{ + return simatic_ipc_leds_gpio_remove(pdev, &simatic_ipc_led_gpio_table, + &simatic_ipc_led_gpio_table_extra); +} + +static struct platform_driver simatic_ipc_led_gpio_apollolake_driver = { + .probe = simatic_ipc_leds_gpio_apollolake_probe, + .remove = simatic_ipc_leds_gpio_apollolake_remove, + .driver = { + .name = KBUILD_MODNAME, + }, +}; +module_platform_driver(simatic_ipc_led_gpio_apollolake_driver); + +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:" KBUILD_MODNAME); +MODULE_SOFTDEP("pre: simatic-ipc-leds-gpio-core platform:apollolake-pinctrl"); +MODULE_AUTHOR("Henning Schild "); diff --git a/drivers/leds/simple/simatic-ipc-leds-gpio-core.c b/drivers/leds/simple/simatic-ipc-leds-gpio-core.c new file mode 100644 index 000000000000..2a21b663df87 --- /dev/null +++ b/drivers/leds/simple/simatic-ipc-leds-gpio-core.c @@ -0,0 +1,104 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Siemens SIMATIC IPC driver for GPIO based LEDs + * + * Copyright (c) Siemens AG, 2023 + * + * Author: + * Henning Schild + */ + +#include +#include +#include +#include +#include +#include + +#include "simatic-ipc-leds-gpio.h" + +static struct platform_device *simatic_leds_pdev; + +static const struct gpio_led simatic_ipc_gpio_leds[] = { + { .name = "red:" LED_FUNCTION_STATUS "-1" }, + { .name = "green:" LED_FUNCTION_STATUS "-1" }, + { .name = "red:" LED_FUNCTION_STATUS "-2" }, + { .name = "green:" LED_FUNCTION_STATUS "-2" }, + { .name = "red:" LED_FUNCTION_STATUS "-3" }, + { .name = "green:" LED_FUNCTION_STATUS "-3" }, +}; + +static const struct gpio_led_platform_data simatic_ipc_gpio_leds_pdata = { + .num_leds = ARRAY_SIZE(simatic_ipc_gpio_leds), + .leds = simatic_ipc_gpio_leds, +}; + +int simatic_ipc_leds_gpio_remove(struct platform_device *pdev, + struct gpiod_lookup_table *table, + struct gpiod_lookup_table *table_extra) +{ + gpiod_remove_lookup_table(table); + gpiod_remove_lookup_table(table_extra); + platform_device_unregister(simatic_leds_pdev); + + return 0; +} +EXPORT_SYMBOL_GPL(simatic_ipc_leds_gpio_remove); + +int simatic_ipc_leds_gpio_probe(struct platform_device *pdev, + struct gpiod_lookup_table *table, + struct gpiod_lookup_table *table_extra) +{ + const struct simatic_ipc_platform *plat = pdev->dev.platform_data; + struct device *dev = &pdev->dev; + struct gpio_desc *gpiod; + int err; + + switch (plat->devmode) { + case SIMATIC_IPC_DEVICE_127E: + case SIMATIC_IPC_DEVICE_227G: + break; + default: + return -ENODEV; + } + + gpiod_add_lookup_table(table); + simatic_leds_pdev = platform_device_register_resndata(NULL, + "leds-gpio", PLATFORM_DEVID_NONE, NULL, 0, + &simatic_ipc_gpio_leds_pdata, + sizeof(simatic_ipc_gpio_leds_pdata)); + if (IS_ERR(simatic_leds_pdev)) { + err = PTR_ERR(simatic_leds_pdev); + goto out; + } + + table_extra->dev_id = dev_name(dev); + gpiod_add_lookup_table(table_extra); + + /* PM_BIOS_BOOT_N */ + gpiod = gpiod_get_index(dev, NULL, 6, GPIOD_OUT_LOW); + if (IS_ERR(gpiod)) { + err = PTR_ERR(gpiod); + goto out; + } + gpiod_put(gpiod); + + /* PM_WDT_OUT */ + gpiod = gpiod_get_index(dev, NULL, 7, GPIOD_OUT_LOW); + if (IS_ERR(gpiod)) { + err = PTR_ERR(gpiod); + goto out; + } + gpiod_put(gpiod); + + return 0; +out: + simatic_ipc_leds_gpio_remove(pdev, table, table_extra); + + return err; +} +EXPORT_SYMBOL_GPL(simatic_ipc_leds_gpio_probe); + +MODULE_LICENSE("GPL v2"); +MODULE_SOFTDEP("pre: platform:leds-gpio"); +MODULE_AUTHOR("Henning Schild "); diff --git a/drivers/leds/simple/simatic-ipc-leds-gpio-f7188x.c b/drivers/leds/simple/simatic-ipc-leds-gpio-f7188x.c new file mode 100644 index 000000000000..583a6b6c7c22 --- /dev/null +++ b/drivers/leds/simple/simatic-ipc-leds-gpio-f7188x.c @@ -0,0 +1,66 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Siemens SIMATIC IPC driver for GPIO based LEDs + * + * Copyright (c) Siemens AG, 2023 + * + * Author: + * Henning Schild + */ + +#include +#include +#include +#include +#include +#include + +#include "simatic-ipc-leds-gpio.h" + +static struct gpiod_lookup_table simatic_ipc_led_gpio_table = { + .dev_id = "leds-gpio", + .table = { + GPIO_LOOKUP_IDX("gpio-f7188x-2", 0, NULL, 0, GPIO_ACTIVE_LOW), + GPIO_LOOKUP_IDX("gpio-f7188x-2", 1, NULL, 1, GPIO_ACTIVE_LOW), + GPIO_LOOKUP_IDX("gpio-f7188x-2", 2, NULL, 2, GPIO_ACTIVE_LOW), + GPIO_LOOKUP_IDX("gpio-f7188x-2", 3, NULL, 3, GPIO_ACTIVE_LOW), + GPIO_LOOKUP_IDX("gpio-f7188x-2", 4, NULL, 4, GPIO_ACTIVE_LOW), + GPIO_LOOKUP_IDX("gpio-f7188x-2", 5, NULL, 5, GPIO_ACTIVE_LOW), + {} /* Terminating entry */ + }, +}; + +static struct gpiod_lookup_table simatic_ipc_led_gpio_table_extra = { + .dev_id = NULL, /* Filled during initialization */ + .table = { + GPIO_LOOKUP_IDX("gpio-f7188x-3", 6, NULL, 6, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("gpio-f7188x-3", 7, NULL, 7, GPIO_ACTIVE_HIGH), + {} /* Terminating entry */ + }, +}; + +static int simatic_ipc_leds_gpio_f7188x_probe(struct platform_device *pdev) +{ + return simatic_ipc_leds_gpio_probe(pdev, &simatic_ipc_led_gpio_table, + &simatic_ipc_led_gpio_table_extra); +} + +static int simatic_ipc_leds_gpio_f7188x_remove(struct platform_device *pdev) +{ + return simatic_ipc_leds_gpio_remove(pdev, &simatic_ipc_led_gpio_table, + &simatic_ipc_led_gpio_table_extra); +} + +static struct platform_driver simatic_ipc_led_gpio_driver = { + .probe = simatic_ipc_leds_gpio_f7188x_probe, + .remove = simatic_ipc_leds_gpio_f7188x_remove, + .driver = { + .name = KBUILD_MODNAME, + }, +}; +module_platform_driver(simatic_ipc_led_gpio_driver); + +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:" KBUILD_MODNAME); +MODULE_SOFTDEP("pre: simatic-ipc-leds-gpio-core gpio_f7188x"); +MODULE_AUTHOR("Henning Schild "); diff --git a/drivers/leds/simple/simatic-ipc-leds-gpio.c b/drivers/leds/simple/simatic-ipc-leds-gpio.c deleted file mode 100644 index e8d329b5a68c..000000000000 --- a/drivers/leds/simple/simatic-ipc-leds-gpio.c +++ /dev/null @@ -1,139 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Siemens SIMATIC IPC driver for GPIO based LEDs - * - * Copyright (c) Siemens AG, 2022 - * - * Authors: - * Henning Schild - */ - -#include -#include -#include -#include -#include -#include - -static struct gpiod_lookup_table *simatic_ipc_led_gpio_table; - -static struct gpiod_lookup_table simatic_ipc_led_gpio_table_127e = { - .dev_id = "leds-gpio", - .table = { - GPIO_LOOKUP_IDX("apollolake-pinctrl.0", 52, NULL, 0, GPIO_ACTIVE_LOW), - GPIO_LOOKUP_IDX("apollolake-pinctrl.0", 53, NULL, 1, GPIO_ACTIVE_LOW), - GPIO_LOOKUP_IDX("apollolake-pinctrl.0", 57, NULL, 2, GPIO_ACTIVE_LOW), - GPIO_LOOKUP_IDX("apollolake-pinctrl.0", 58, NULL, 3, GPIO_ACTIVE_LOW), - GPIO_LOOKUP_IDX("apollolake-pinctrl.0", 60, NULL, 4, GPIO_ACTIVE_LOW), - GPIO_LOOKUP_IDX("apollolake-pinctrl.0", 51, NULL, 5, GPIO_ACTIVE_LOW), - GPIO_LOOKUP_IDX("apollolake-pinctrl.0", 56, NULL, 6, GPIO_ACTIVE_LOW), - GPIO_LOOKUP_IDX("apollolake-pinctrl.0", 59, NULL, 7, GPIO_ACTIVE_HIGH), - }, -}; - -static struct gpiod_lookup_table simatic_ipc_led_gpio_table_227g = { - .dev_id = "leds-gpio", - .table = { - GPIO_LOOKUP_IDX("gpio-f7188x-2", 0, NULL, 0, GPIO_ACTIVE_LOW), - GPIO_LOOKUP_IDX("gpio-f7188x-2", 1, NULL, 1, GPIO_ACTIVE_LOW), - GPIO_LOOKUP_IDX("gpio-f7188x-2", 2, NULL, 2, GPIO_ACTIVE_LOW), - GPIO_LOOKUP_IDX("gpio-f7188x-2", 3, NULL, 3, GPIO_ACTIVE_LOW), - GPIO_LOOKUP_IDX("gpio-f7188x-2", 4, NULL, 4, GPIO_ACTIVE_LOW), - GPIO_LOOKUP_IDX("gpio-f7188x-2", 5, NULL, 5, GPIO_ACTIVE_LOW), - GPIO_LOOKUP_IDX("gpio-f7188x-3", 6, NULL, 6, GPIO_ACTIVE_HIGH), - GPIO_LOOKUP_IDX("gpio-f7188x-3", 7, NULL, 7, GPIO_ACTIVE_HIGH), - } -}; - -static const struct gpio_led simatic_ipc_gpio_leds[] = { - { .name = "red:" LED_FUNCTION_STATUS "-1" }, - { .name = "green:" LED_FUNCTION_STATUS "-1" }, - { .name = "red:" LED_FUNCTION_STATUS "-2" }, - { .name = "green:" LED_FUNCTION_STATUS "-2" }, - { .name = "red:" LED_FUNCTION_STATUS "-3" }, - { .name = "green:" LED_FUNCTION_STATUS "-3" }, -}; - -static const struct gpio_led_platform_data simatic_ipc_gpio_leds_pdata = { - .num_leds = ARRAY_SIZE(simatic_ipc_gpio_leds), - .leds = simatic_ipc_gpio_leds, -}; - -static struct platform_device *simatic_leds_pdev; - -static int simatic_ipc_leds_gpio_remove(struct platform_device *pdev) -{ - gpiod_remove_lookup_table(simatic_ipc_led_gpio_table); - platform_device_unregister(simatic_leds_pdev); - - return 0; -} - -static int simatic_ipc_leds_gpio_probe(struct platform_device *pdev) -{ - const struct simatic_ipc_platform *plat = pdev->dev.platform_data; - struct gpio_desc *gpiod; - int err; - - switch (plat->devmode) { - case SIMATIC_IPC_DEVICE_127E: - if (!IS_ENABLED(CONFIG_PINCTRL_BROXTON)) - return -ENODEV; - simatic_ipc_led_gpio_table = &simatic_ipc_led_gpio_table_127e; - break; - case SIMATIC_IPC_DEVICE_227G: - if (!IS_ENABLED(CONFIG_GPIO_F7188X)) - return -ENODEV; - request_module("gpio-f7188x"); - simatic_ipc_led_gpio_table = &simatic_ipc_led_gpio_table_227g; - break; - default: - return -ENODEV; - } - - gpiod_add_lookup_table(simatic_ipc_led_gpio_table); - simatic_leds_pdev = platform_device_register_resndata(NULL, - "leds-gpio", PLATFORM_DEVID_NONE, NULL, 0, - &simatic_ipc_gpio_leds_pdata, - sizeof(simatic_ipc_gpio_leds_pdata)); - if (IS_ERR(simatic_leds_pdev)) { - err = PTR_ERR(simatic_leds_pdev); - goto out; - } - - /* PM_BIOS_BOOT_N */ - gpiod = gpiod_get_index(&simatic_leds_pdev->dev, NULL, 6, GPIOD_OUT_LOW); - if (IS_ERR(gpiod)) { - err = PTR_ERR(gpiod); - goto out; - } - gpiod_put(gpiod); - - /* PM_WDT_OUT */ - gpiod = gpiod_get_index(&simatic_leds_pdev->dev, NULL, 7, GPIOD_OUT_LOW); - if (IS_ERR(gpiod)) { - err = PTR_ERR(gpiod); - goto out; - } - gpiod_put(gpiod); - - return 0; -out: - simatic_ipc_leds_gpio_remove(pdev); - - return err; -} - -static struct platform_driver simatic_ipc_led_gpio_driver = { - .probe = simatic_ipc_leds_gpio_probe, - .remove = simatic_ipc_leds_gpio_remove, - .driver = { - .name = KBUILD_MODNAME, - } -}; -module_platform_driver(simatic_ipc_led_gpio_driver); - -MODULE_LICENSE("GPL v2"); -MODULE_ALIAS("platform:" KBUILD_MODNAME); -MODULE_SOFTDEP("pre: platform:leds-gpio"); -MODULE_AUTHOR("Henning Schild "); diff --git a/drivers/leds/simple/simatic-ipc-leds-gpio.h b/drivers/leds/simple/simatic-ipc-leds-gpio.h new file mode 100644 index 000000000000..bf258c32f83d --- /dev/null +++ b/drivers/leds/simple/simatic-ipc-leds-gpio.h @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Siemens SIMATIC IPC driver for GPIO based LEDs + * + * Copyright (c) Siemens AG, 2023 + * + * Author: + * Henning Schild + */ + +#ifndef _SIMATIC_IPC_LEDS_GPIO_H +#define _SIMATIC_IPC_LEDS_GPIO_H + +int simatic_ipc_leds_gpio_probe(struct platform_device *pdev, + struct gpiod_lookup_table *table, + struct gpiod_lookup_table *table_extra); + +int simatic_ipc_leds_gpio_remove(struct platform_device *pdev, + struct gpiod_lookup_table *table, + struct gpiod_lookup_table *table_extra); + +#endif /* _SIMATIC_IPC_LEDS_GPIO_H */ diff --git a/drivers/leds/simple/simatic-ipc-leds.c b/drivers/leds/simple/simatic-ipc-leds.c index 4894c228c165..2124f6d09930 100644 --- a/drivers/leds/simple/simatic-ipc-leds.c +++ b/drivers/leds/simple/simatic-ipc-leds.c @@ -126,7 +126,6 @@ static struct platform_driver simatic_ipc_led_driver = { .name = KBUILD_MODNAME, } }; - module_platform_driver(simatic_ipc_led_driver); MODULE_LICENSE("GPL v2"); diff --git a/drivers/leds/trigger/ledtrig-disk.c b/drivers/leds/trigger/ledtrig-disk.c index 0b7dfbd04273..e9b87ee944f2 100644 --- a/drivers/leds/trigger/ledtrig-disk.c +++ b/drivers/leds/trigger/ledtrig-disk.c @@ -19,16 +19,13 @@ DEFINE_LED_TRIGGER(ledtrig_disk_write); void ledtrig_disk_activity(bool write) { - unsigned long blink_delay = BLINK_DELAY; - - led_trigger_blink_oneshot(ledtrig_disk, - &blink_delay, &blink_delay, 0); + led_trigger_blink_oneshot(ledtrig_disk, BLINK_DELAY, BLINK_DELAY, 0); if (write) led_trigger_blink_oneshot(ledtrig_disk_write, - &blink_delay, &blink_delay, 0); + BLINK_DELAY, BLINK_DELAY, 0); else led_trigger_blink_oneshot(ledtrig_disk_read, - &blink_delay, &blink_delay, 0); + BLINK_DELAY, BLINK_DELAY, 0); } EXPORT_SYMBOL(ledtrig_disk_activity); diff --git a/drivers/leds/trigger/ledtrig-mtd.c b/drivers/leds/trigger/ledtrig-mtd.c index 8fa763c2269b..bbe6876a249d 100644 --- a/drivers/leds/trigger/ledtrig-mtd.c +++ b/drivers/leds/trigger/ledtrig-mtd.c @@ -22,12 +22,8 @@ DEFINE_LED_TRIGGER(ledtrig_nand); void ledtrig_mtd_activity(void) { - unsigned long blink_delay = BLINK_DELAY; - - led_trigger_blink_oneshot(ledtrig_mtd, - &blink_delay, &blink_delay, 0); - led_trigger_blink_oneshot(ledtrig_nand, - &blink_delay, &blink_delay, 0); + led_trigger_blink_oneshot(ledtrig_mtd, BLINK_DELAY, BLINK_DELAY, 0); + led_trigger_blink_oneshot(ledtrig_nand, BLINK_DELAY, BLINK_DELAY, 0); } EXPORT_SYMBOL(ledtrig_mtd_activity); diff --git a/drivers/leds/trigger/ledtrig-netdev.c b/drivers/leds/trigger/ledtrig-netdev.c index 32b66703068a..c9bc5a91ec83 100644 --- a/drivers/leds/trigger/ledtrig-netdev.c +++ b/drivers/leds/trigger/ledtrig-netdev.c @@ -462,8 +462,7 @@ static int netdev_trig_notify(struct notifier_block *nb, get_device_state(trigger_data); fallthrough; case NETDEV_REGISTER: - if (trigger_data->net_dev) - dev_put(trigger_data->net_dev); + dev_put(trigger_data->net_dev); dev_hold(dev); trigger_data->net_dev = dev; break; @@ -594,8 +593,7 @@ static void netdev_trig_deactivate(struct led_classdev *led_cdev) cancel_delayed_work_sync(&trigger_data->work); - if (trigger_data->net_dev) - dev_put(trigger_data->net_dev); + dev_put(trigger_data->net_dev); kfree(trigger_data); } diff --git a/drivers/mailbox/tegra-hsp.c b/drivers/mailbox/tegra-hsp.c index 573481e436f5..7f98e7436d94 100644 --- a/drivers/mailbox/tegra-hsp.c +++ b/drivers/mailbox/tegra-hsp.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2016-2023, NVIDIA CORPORATION. All rights reserved. */ #include @@ -97,6 +97,7 @@ struct tegra_hsp_soc { const struct tegra_hsp_db_map *map; bool has_per_mb_ie; bool has_128_bit_mb; + unsigned int reg_stride; }; struct tegra_hsp { @@ -279,7 +280,7 @@ tegra_hsp_doorbell_create(struct tegra_hsp *hsp, const char *name, return ERR_PTR(-ENOMEM); offset = (1 + (hsp->num_sm / 2) + hsp->num_ss + hsp->num_as) * SZ_64K; - offset += index * 0x100; + offset += index * hsp->soc->reg_stride; db->channel.regs = hsp->regs + offset; db->channel.hsp = hsp; @@ -916,24 +917,35 @@ static const struct tegra_hsp_soc tegra186_hsp_soc = { .map = tegra186_hsp_db_map, .has_per_mb_ie = false, .has_128_bit_mb = false, + .reg_stride = 0x100, }; static const struct tegra_hsp_soc tegra194_hsp_soc = { .map = tegra186_hsp_db_map, .has_per_mb_ie = true, .has_128_bit_mb = false, + .reg_stride = 0x100, }; static const struct tegra_hsp_soc tegra234_hsp_soc = { .map = tegra186_hsp_db_map, .has_per_mb_ie = false, .has_128_bit_mb = true, + .reg_stride = 0x100, +}; + +static const struct tegra_hsp_soc tegra264_hsp_soc = { + .map = tegra186_hsp_db_map, + .has_per_mb_ie = false, + .has_128_bit_mb = true, + .reg_stride = 0x1000, }; static const struct of_device_id tegra_hsp_match[] = { { .compatible = "nvidia,tegra186-hsp", .data = &tegra186_hsp_soc }, { .compatible = "nvidia,tegra194-hsp", .data = &tegra194_hsp_soc }, { .compatible = "nvidia,tegra234-hsp", .data = &tegra234_hsp_soc }, + { .compatible = "nvidia,tegra264-hsp", .data = &tegra264_hsp_soc }, { } }; diff --git a/drivers/mailbox/ti-msgmgr.c b/drivers/mailbox/ti-msgmgr.c index ddac423ac1a9..03048cbda525 100644 --- a/drivers/mailbox/ti-msgmgr.c +++ b/drivers/mailbox/ti-msgmgr.c @@ -430,14 +430,20 @@ static int ti_msgmgr_send_data(struct mbox_chan *chan, void *data) /* Ensure all unused data is 0 */ data_trail &= 0xFFFFFFFF >> (8 * (sizeof(u32) - trail_bytes)); writel(data_trail, data_reg); - data_reg++; + data_reg += sizeof(u32); } + /* * 'data_reg' indicates next register to write. If we did not already * write on tx complete reg(last reg), we must do so for transmit + * In addition, we also need to make sure all intermediate data + * registers(if any required), are reset to 0 for TISCI backward + * compatibility to be maintained. */ - if (data_reg <= qinst->queue_buff_end) - writel(0, qinst->queue_buff_end); + while (data_reg <= qinst->queue_buff_end) { + writel(0, data_reg); + data_reg += sizeof(u32); + } /* If we are in polled mode, wait for a response before proceeding */ if (ti_msgmgr_chan_has_polled_queue_rx(message->chan_rx)) diff --git a/drivers/mfd/88pm800.c b/drivers/mfd/88pm800.c index 4d9b61b92754..300caa067335 100644 --- a/drivers/mfd/88pm800.c +++ b/drivers/mfd/88pm800.c @@ -597,7 +597,7 @@ static struct i2c_driver pm800_driver = { .name = "88PM800", .pm = pm_sleep_ptr(&pm80x_pm_ops), }, - .probe_new = pm800_probe, + .probe = pm800_probe, .remove = pm800_remove, .id_table = pm80x_id_table, }; diff --git a/drivers/mfd/88pm805.c b/drivers/mfd/88pm805.c index 352f13cb1481..68417c3c4f5a 100644 --- a/drivers/mfd/88pm805.c +++ b/drivers/mfd/88pm805.c @@ -253,7 +253,7 @@ static struct i2c_driver pm805_driver = { .name = "88PM805", .pm = pm_sleep_ptr(&pm80x_pm_ops), }, - .probe_new = pm805_probe, + .probe = pm805_probe, .remove = pm805_remove, .id_table = pm80x_id_table, }; diff --git a/drivers/mfd/88pm80x.c b/drivers/mfd/88pm80x.c index ac4f08565f29..bbc1a87f0c8f 100644 --- a/drivers/mfd/88pm80x.c +++ b/drivers/mfd/88pm80x.c @@ -74,7 +74,6 @@ int pm80x_init(struct i2c_client *client) chip->irq = client->irq; chip->dev = &client->dev; - dev_set_drvdata(chip->dev, chip); i2c_set_clientdata(chip->client, chip); ret = regmap_read(chip->regmap, PM80X_CHIP_ID, &val); diff --git a/drivers/mfd/88pm860x-core.c b/drivers/mfd/88pm860x-core.c index aabac37c3502..151bf03e772d 100644 --- a/drivers/mfd/88pm860x-core.c +++ b/drivers/mfd/88pm860x-core.c @@ -1166,7 +1166,6 @@ static int pm860x_probe(struct i2c_client *client) chip->client = client; i2c_set_clientdata(client, chip); chip->dev = &client->dev; - dev_set_drvdata(chip->dev, chip); /* * Both client and companion client shares same platform driver. @@ -1251,7 +1250,7 @@ static struct i2c_driver pm860x_driver = { .pm = pm_sleep_ptr(&pm860x_pm_ops), .of_match_table = pm860x_dt_ids, }, - .probe_new = pm860x_probe, + .probe = pm860x_probe, .remove = pm860x_remove, .id_table = pm860x_id_table, }; diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index f89f455c130a..6f5b259a6d6a 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -266,8 +266,8 @@ config MFD_MADERA_SPI Support for the Cirrus Logic Madera platform audio SoC core functionality controlled via SPI. -config MFD_MAX597X - tristate "Maxim 597x power switch and monitor" +config MFD_MAX5970 + tristate "Maxim 5970/5978 power switch and monitor" depends on (I2C && OF) select MFD_SIMPLE_MFD_I2C help @@ -784,6 +784,19 @@ config MFD_MAX14577 additional drivers must be enabled in order to use the functionality of the device. +config MFD_MAX77541 + tristate "Analog Devices MAX77541/77540 PMIC Support" + depends on I2C=y + select MFD_CORE + select REGMAP_I2C + select REGMAP_IRQ + help + Say yes here to add support for Analog Devices MAX77541 and + MAX77540 Power Management ICs. This driver provides + common support for accessing the device; additional drivers + must be enabled in order to use the functionality of the device. + There are regulators and adc. + config MFD_MAX77620 bool "Maxim Semiconductor MAX77620 and MAX20024 PMIC Support" depends on I2C=y diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index 39c461536181..f3d1f1dc73b5 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -154,6 +154,7 @@ obj-$(CONFIG_MFD_DA9063) += da9063.o obj-$(CONFIG_MFD_DA9150) += da9150-core.o obj-$(CONFIG_MFD_MAX14577) += max14577.o +obj-$(CONFIG_MFD_MAX77541) += max77541.o obj-$(CONFIG_MFD_MAX77620) += max77620.o obj-$(CONFIG_MFD_MAX77650) += max77650.o obj-$(CONFIG_MFD_MAX77686) += max77686.o diff --git a/drivers/mfd/aat2870-core.c b/drivers/mfd/aat2870-core.c index f253da5b246b..2fee62f1016c 100644 --- a/drivers/mfd/aat2870-core.c +++ b/drivers/mfd/aat2870-core.c @@ -345,8 +345,6 @@ static int aat2870_i2c_probe(struct i2c_client *client) return -ENOMEM; aat2870->dev = &client->dev; - dev_set_drvdata(aat2870->dev, aat2870); - aat2870->client = client; i2c_set_clientdata(client, aat2870); @@ -451,7 +449,7 @@ static struct i2c_driver aat2870_i2c_driver = { .pm = pm_sleep_ptr(&aat2870_pm_ops), .suppress_bind_attrs = true, }, - .probe_new = aat2870_i2c_probe, + .probe = aat2870_i2c_probe, .id_table = aat2870_i2c_id_table, }; diff --git a/drivers/mfd/acer-ec-a500.c b/drivers/mfd/acer-ec-a500.c index 7fd8b9988075..feb757e90dc3 100644 --- a/drivers/mfd/acer-ec-a500.c +++ b/drivers/mfd/acer-ec-a500.c @@ -190,7 +190,7 @@ static struct i2c_driver a500_ec_driver = { .name = "acer-a500-embedded-controller", .of_match_table = a500_ec_match, }, - .probe_new = a500_ec_probe, + .probe = a500_ec_probe, .remove = a500_ec_remove, }; module_i2c_driver(a500_ec_driver); diff --git a/drivers/mfd/act8945a.c b/drivers/mfd/act8945a.c index bcf0fda15f0c..2406fcdff5f9 100644 --- a/drivers/mfd/act8945a.c +++ b/drivers/mfd/act8945a.c @@ -70,7 +70,7 @@ static struct i2c_driver act8945a_i2c_driver = { .name = "act8945a", .of_match_table = of_match_ptr(act8945a_of_match), }, - .probe_new = act8945a_i2c_probe, + .probe = act8945a_i2c_probe, .id_table = act8945a_i2c_id, }; diff --git a/drivers/mfd/adp5520.c b/drivers/mfd/adp5520.c index cb168efdbafe..bd6f4965ebc8 100644 --- a/drivers/mfd/adp5520.c +++ b/drivers/mfd/adp5520.c @@ -340,7 +340,7 @@ static struct i2c_driver adp5520_driver = { .pm = pm_sleep_ptr(&adp5520_pm), .suppress_bind_attrs = true, }, - .probe_new = adp5520_probe, + .probe = adp5520_probe, .id_table = adp5520_id, }; builtin_i2c_driver(adp5520_driver); diff --git a/drivers/mfd/arizona-i2c.c b/drivers/mfd/arizona-i2c.c index 43e393c8608d..9b7183ffc928 100644 --- a/drivers/mfd/arizona-i2c.c +++ b/drivers/mfd/arizona-i2c.c @@ -121,7 +121,7 @@ static struct i2c_driver arizona_i2c_driver = { .pm = pm_ptr(&arizona_pm_ops), .of_match_table = of_match_ptr(arizona_i2c_of_match), }, - .probe_new = arizona_i2c_probe, + .probe = arizona_i2c_probe, .remove = arizona_i2c_remove, .id_table = arizona_i2c_id, }; diff --git a/drivers/mfd/as3711.c b/drivers/mfd/as3711.c index 3facfdd28e81..c7e85ff38013 100644 --- a/drivers/mfd/as3711.c +++ b/drivers/mfd/as3711.c @@ -201,7 +201,7 @@ static struct i2c_driver as3711_i2c_driver = { .name = "as3711", .of_match_table = of_match_ptr(as3711_of_match), }, - .probe_new = as3711_i2c_probe, + .probe = as3711_i2c_probe, .id_table = as3711_i2c_id, }; diff --git a/drivers/mfd/as3722.c b/drivers/mfd/as3722.c index b6dda0eb8645..a2bf68afc131 100644 --- a/drivers/mfd/as3722.c +++ b/drivers/mfd/as3722.c @@ -445,7 +445,7 @@ static struct i2c_driver as3722_i2c_driver = { .of_match_table = as3722_of_match, .pm = &as3722_pm_ops, }, - .probe_new = as3722_i2c_probe, + .probe = as3722_i2c_probe, .id_table = as3722_i2c_id, }; diff --git a/drivers/mfd/atc260x-i2c.c b/drivers/mfd/atc260x-i2c.c index 8e1491167160..fb53b0432a31 100644 --- a/drivers/mfd/atc260x-i2c.c +++ b/drivers/mfd/atc260x-i2c.c @@ -53,7 +53,7 @@ static struct i2c_driver atc260x_i2c_driver = { .name = "atc260x", .of_match_table = atc260x_i2c_of_match, }, - .probe_new = atc260x_i2c_probe, + .probe = atc260x_i2c_probe, }; module_i2c_driver(atc260x_i2c_driver); diff --git a/drivers/mfd/axp20x-i2c.c b/drivers/mfd/axp20x-i2c.c index a49e5e217554..68d3560cfe4a 100644 --- a/drivers/mfd/axp20x-i2c.c +++ b/drivers/mfd/axp20x-i2c.c @@ -59,6 +59,7 @@ static void axp20x_i2c_remove(struct i2c_client *i2c) #ifdef CONFIG_OF static const struct of_device_id axp20x_i2c_of_match[] = { { .compatible = "x-powers,axp152", .data = (void *)AXP152_ID }, + { .compatible = "x-powers,axp192", .data = (void *)AXP192_ID }, { .compatible = "x-powers,axp202", .data = (void *)AXP202_ID }, { .compatible = "x-powers,axp209", .data = (void *)AXP209_ID }, { .compatible = "x-powers,axp221", .data = (void *)AXP221_ID }, @@ -74,6 +75,7 @@ MODULE_DEVICE_TABLE(of, axp20x_i2c_of_match); static const struct i2c_device_id axp20x_i2c_id[] = { { "axp152", 0 }, + { "axp192", 0 }, { "axp202", 0 }, { "axp209", 0 }, { "axp221", 0 }, @@ -103,7 +105,7 @@ static struct i2c_driver axp20x_i2c_driver = { .of_match_table = of_match_ptr(axp20x_i2c_of_match), .acpi_match_table = ACPI_PTR(axp20x_i2c_acpi_match), }, - .probe_new = axp20x_i2c_probe, + .probe = axp20x_i2c_probe, .remove = axp20x_i2c_remove, .id_table = axp20x_i2c_id, }; diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c index 07a846ecbf18..c03bc5cda080 100644 --- a/drivers/mfd/axp20x.c +++ b/drivers/mfd/axp20x.c @@ -34,6 +34,7 @@ static const char * const axp20x_model_names[] = { "AXP152", + "AXP192", "AXP202", "AXP209", "AXP221", @@ -94,6 +95,35 @@ static const struct regmap_access_table axp20x_volatile_table = { .n_yes_ranges = ARRAY_SIZE(axp20x_volatile_ranges), }; +static const struct regmap_range axp192_writeable_ranges[] = { + regmap_reg_range(AXP192_DATACACHE(0), AXP192_DATACACHE(5)), + regmap_reg_range(AXP192_PWR_OUT_CTRL, AXP192_IRQ5_STATE), + regmap_reg_range(AXP20X_DCDC_MODE, AXP192_N_RSTO_CTRL), + regmap_reg_range(AXP20X_CC_CTRL, AXP20X_CC_CTRL), +}; + +static const struct regmap_range axp192_volatile_ranges[] = { + regmap_reg_range(AXP20X_PWR_INPUT_STATUS, AXP192_USB_OTG_STATUS), + regmap_reg_range(AXP192_IRQ1_STATE, AXP192_IRQ4_STATE), + regmap_reg_range(AXP192_IRQ5_STATE, AXP192_IRQ5_STATE), + regmap_reg_range(AXP20X_ACIN_V_ADC_H, AXP20X_IPSOUT_V_HIGH_L), + regmap_reg_range(AXP20X_TIMER_CTRL, AXP20X_TIMER_CTRL), + regmap_reg_range(AXP192_GPIO2_0_STATE, AXP192_GPIO2_0_STATE), + regmap_reg_range(AXP192_GPIO4_3_STATE, AXP192_GPIO4_3_STATE), + regmap_reg_range(AXP192_N_RSTO_CTRL, AXP192_N_RSTO_CTRL), + regmap_reg_range(AXP20X_CHRG_CC_31_24, AXP20X_CC_CTRL), +}; + +static const struct regmap_access_table axp192_writeable_table = { + .yes_ranges = axp192_writeable_ranges, + .n_yes_ranges = ARRAY_SIZE(axp192_writeable_ranges), +}; + +static const struct regmap_access_table axp192_volatile_table = { + .yes_ranges = axp192_volatile_ranges, + .n_yes_ranges = ARRAY_SIZE(axp192_volatile_ranges), +}; + /* AXP22x ranges are shared with the AXP809, as they cover the same range */ static const struct regmap_range axp22x_writeable_ranges[] = { regmap_reg_range(AXP20X_DATACACHE(0), AXP20X_IRQ5_STATE), @@ -220,6 +250,19 @@ static const struct resource axp152_pek_resources[] = { DEFINE_RES_IRQ_NAMED(AXP152_IRQ_PEK_FAL_EDGE, "PEK_DBF"), }; +static const struct resource axp192_ac_power_supply_resources[] = { + DEFINE_RES_IRQ_NAMED(AXP192_IRQ_ACIN_PLUGIN, "ACIN_PLUGIN"), + DEFINE_RES_IRQ_NAMED(AXP192_IRQ_ACIN_REMOVAL, "ACIN_REMOVAL"), + DEFINE_RES_IRQ_NAMED(AXP192_IRQ_ACIN_OVER_V, "ACIN_OVER_V"), +}; + +static const struct resource axp192_usb_power_supply_resources[] = { + DEFINE_RES_IRQ_NAMED(AXP192_IRQ_VBUS_PLUGIN, "VBUS_PLUGIN"), + DEFINE_RES_IRQ_NAMED(AXP192_IRQ_VBUS_REMOVAL, "VBUS_REMOVAL"), + DEFINE_RES_IRQ_NAMED(AXP192_IRQ_VBUS_VALID, "VBUS_VALID"), + DEFINE_RES_IRQ_NAMED(AXP192_IRQ_VBUS_NOT_VALID, "VBUS_NOT_VALID"), +}; + static const struct resource axp20x_ac_power_supply_resources[] = { DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_ACIN_PLUGIN, "ACIN_PLUGIN"), DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_ACIN_REMOVAL, "ACIN_REMOVAL"), @@ -302,6 +345,15 @@ static const struct regmap_config axp152_regmap_config = { .cache_type = REGCACHE_RBTREE, }; +static const struct regmap_config axp192_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .wr_table = &axp192_writeable_table, + .volatile_table = &axp192_volatile_table, + .max_register = AXP20X_CC_CTRL, + .cache_type = REGCACHE_RBTREE, +}; + static const struct regmap_config axp20x_regmap_config = { .reg_bits = 8, .val_bits = 8, @@ -379,6 +431,42 @@ static const struct regmap_irq axp152_regmap_irqs[] = { INIT_REGMAP_IRQ(AXP152, GPIO0_INPUT, 2, 0), }; +static const struct regmap_irq axp192_regmap_irqs[] = { + INIT_REGMAP_IRQ(AXP192, ACIN_OVER_V, 0, 7), + INIT_REGMAP_IRQ(AXP192, ACIN_PLUGIN, 0, 6), + INIT_REGMAP_IRQ(AXP192, ACIN_REMOVAL, 0, 5), + INIT_REGMAP_IRQ(AXP192, VBUS_OVER_V, 0, 4), + INIT_REGMAP_IRQ(AXP192, VBUS_PLUGIN, 0, 3), + INIT_REGMAP_IRQ(AXP192, VBUS_REMOVAL, 0, 2), + INIT_REGMAP_IRQ(AXP192, VBUS_V_LOW, 0, 1), + INIT_REGMAP_IRQ(AXP192, BATT_PLUGIN, 1, 7), + INIT_REGMAP_IRQ(AXP192, BATT_REMOVAL, 1, 6), + INIT_REGMAP_IRQ(AXP192, BATT_ENT_ACT_MODE, 1, 5), + INIT_REGMAP_IRQ(AXP192, BATT_EXIT_ACT_MODE, 1, 4), + INIT_REGMAP_IRQ(AXP192, CHARG, 1, 3), + INIT_REGMAP_IRQ(AXP192, CHARG_DONE, 1, 2), + INIT_REGMAP_IRQ(AXP192, BATT_TEMP_HIGH, 1, 1), + INIT_REGMAP_IRQ(AXP192, BATT_TEMP_LOW, 1, 0), + INIT_REGMAP_IRQ(AXP192, DIE_TEMP_HIGH, 2, 7), + INIT_REGMAP_IRQ(AXP192, CHARG_I_LOW, 2, 6), + INIT_REGMAP_IRQ(AXP192, DCDC1_V_LONG, 2, 5), + INIT_REGMAP_IRQ(AXP192, DCDC2_V_LONG, 2, 4), + INIT_REGMAP_IRQ(AXP192, DCDC3_V_LONG, 2, 3), + INIT_REGMAP_IRQ(AXP192, PEK_SHORT, 2, 1), + INIT_REGMAP_IRQ(AXP192, PEK_LONG, 2, 0), + INIT_REGMAP_IRQ(AXP192, N_OE_PWR_ON, 3, 7), + INIT_REGMAP_IRQ(AXP192, N_OE_PWR_OFF, 3, 6), + INIT_REGMAP_IRQ(AXP192, VBUS_VALID, 3, 5), + INIT_REGMAP_IRQ(AXP192, VBUS_NOT_VALID, 3, 4), + INIT_REGMAP_IRQ(AXP192, VBUS_SESS_VALID, 3, 3), + INIT_REGMAP_IRQ(AXP192, VBUS_SESS_END, 3, 2), + INIT_REGMAP_IRQ(AXP192, LOW_PWR_LVL, 3, 0), + INIT_REGMAP_IRQ(AXP192, TIMER, 4, 7), + INIT_REGMAP_IRQ(AXP192, GPIO2_INPUT, 4, 2), + INIT_REGMAP_IRQ(AXP192, GPIO1_INPUT, 4, 1), + INIT_REGMAP_IRQ(AXP192, GPIO0_INPUT, 4, 0), +}; + static const struct regmap_irq axp20x_regmap_irqs[] = { INIT_REGMAP_IRQ(AXP20X, ACIN_OVER_V, 0, 7), INIT_REGMAP_IRQ(AXP20X, ACIN_PLUGIN, 0, 6), @@ -615,6 +703,32 @@ static const struct regmap_irq_chip axp152_regmap_irq_chip = { .num_regs = 3, }; +static unsigned int axp192_get_irq_reg(struct regmap_irq_chip_data *data, + unsigned int base, int index) +{ + /* linear mapping for IRQ1 to IRQ4 */ + if (index < 4) + return base + index; + + /* handle IRQ5 separately */ + if (base == AXP192_IRQ1_EN) + return AXP192_IRQ5_EN; + + return AXP192_IRQ5_STATE; +} + +static const struct regmap_irq_chip axp192_regmap_irq_chip = { + .name = "axp192_irq_chip", + .status_base = AXP192_IRQ1_STATE, + .ack_base = AXP192_IRQ1_STATE, + .unmask_base = AXP192_IRQ1_EN, + .init_ack_masked = true, + .irqs = axp192_regmap_irqs, + .num_irqs = ARRAY_SIZE(axp192_regmap_irqs), + .num_regs = 5, + .get_irq_reg = axp192_get_irq_reg, +}; + static const struct regmap_irq_chip axp20x_regmap_irq_chip = { .name = "axp20x_irq_chip", .status_base = AXP20X_IRQ1_STATE, @@ -705,6 +819,27 @@ static const struct regmap_irq_chip axp15060_regmap_irq_chip = { .num_regs = 2, }; +static const struct mfd_cell axp192_cells[] = { + { + .name = "axp192-adc", + .of_compatible = "x-powers,axp192-adc", + }, { + .name = "axp20x-battery-power-supply", + .of_compatible = "x-powers,axp192-battery-power-supply", + }, { + .name = "axp20x-ac-power-supply", + .of_compatible = "x-powers,axp202-ac-power-supply", + .num_resources = ARRAY_SIZE(axp192_ac_power_supply_resources), + .resources = axp192_ac_power_supply_resources, + }, { + .name = "axp20x-usb-power-supply", + .of_compatible = "x-powers,axp192-usb-power-supply", + .num_resources = ARRAY_SIZE(axp192_usb_power_supply_resources), + .resources = axp192_usb_power_supply_resources, + }, + { .name = "axp20x-regulator" }, +}; + static const struct mfd_cell axp20x_cells[] = { { .name = "axp20x-gpio", @@ -1022,6 +1157,12 @@ int axp20x_match_device(struct axp20x_dev *axp20x) axp20x->regmap_cfg = &axp152_regmap_config; axp20x->regmap_irq_chip = &axp152_regmap_irq_chip; break; + case AXP192_ID: + axp20x->nr_cells = ARRAY_SIZE(axp192_cells); + axp20x->cells = axp192_cells; + axp20x->regmap_cfg = &axp192_regmap_config; + axp20x->regmap_irq_chip = &axp192_regmap_irq_chip; + break; case AXP202_ID: case AXP209_ID: axp20x->nr_cells = ARRAY_SIZE(axp20x_cells); diff --git a/drivers/mfd/bcm590xx.c b/drivers/mfd/bcm590xx.c index 251d515478d5..9f39b46b87f4 100644 --- a/drivers/mfd/bcm590xx.c +++ b/drivers/mfd/bcm590xx.c @@ -108,7 +108,7 @@ static struct i2c_driver bcm590xx_i2c_driver = { .name = "bcm590xx", .of_match_table = bcm590xx_of_match, }, - .probe_new = bcm590xx_i2c_probe, + .probe = bcm590xx_i2c_probe, .id_table = bcm590xx_i2c_id, }; module_i2c_driver(bcm590xx_i2c_driver); diff --git a/drivers/mfd/bd9571mwv.c b/drivers/mfd/bd9571mwv.c index 60dc858c8117..819d09e4d100 100644 --- a/drivers/mfd/bd9571mwv.c +++ b/drivers/mfd/bd9571mwv.c @@ -278,7 +278,7 @@ static struct i2c_driver bd9571mwv_driver = { .name = "bd9571mwv", .of_match_table = bd9571mwv_of_match_table, }, - .probe_new = bd9571mwv_probe, + .probe = bd9571mwv_probe, .id_table = bd9571mwv_id_table, }; module_i2c_driver(bd9571mwv_driver); diff --git a/drivers/mfd/da903x.c b/drivers/mfd/da903x.c index 6570b33a5a77..e86b39de3303 100644 --- a/drivers/mfd/da903x.c +++ b/drivers/mfd/da903x.c @@ -543,7 +543,7 @@ static struct i2c_driver da903x_driver = { .driver = { .name = "da903x", }, - .probe_new = da903x_probe, + .probe = da903x_probe, .remove = da903x_remove, .id_table = da903x_id_table, }; diff --git a/drivers/mfd/da9052-i2c.c b/drivers/mfd/da9052-i2c.c index 03db7a2ccf7a..541e2d47677e 100644 --- a/drivers/mfd/da9052-i2c.c +++ b/drivers/mfd/da9052-i2c.c @@ -176,7 +176,7 @@ static void da9052_i2c_remove(struct i2c_client *client) } static struct i2c_driver da9052_i2c_driver = { - .probe_new = da9052_i2c_probe, + .probe = da9052_i2c_probe, .remove = da9052_i2c_remove, .id_table = da9052_i2c_id, .driver = { diff --git a/drivers/mfd/da9055-i2c.c b/drivers/mfd/da9055-i2c.c index 537fd5de3e6d..bbaf4f07f274 100644 --- a/drivers/mfd/da9055-i2c.c +++ b/drivers/mfd/da9055-i2c.c @@ -66,7 +66,7 @@ static const struct of_device_id da9055_of_match[] = { }; static struct i2c_driver da9055_i2c_driver = { - .probe_new = da9055_i2c_probe, + .probe = da9055_i2c_probe, .remove = da9055_i2c_remove, .id_table = da9055_i2c_id, .driver = { diff --git a/drivers/mfd/da9062-core.c b/drivers/mfd/da9062-core.c index d073d5f106ec..48f58b6f5629 100644 --- a/drivers/mfd/da9062-core.c +++ b/drivers/mfd/da9062-core.c @@ -726,7 +726,7 @@ static struct i2c_driver da9062_i2c_driver = { .name = "da9062", .of_match_table = da9062_dt_ids, }, - .probe_new = da9062_i2c_probe, + .probe = da9062_i2c_probe, .remove = da9062_i2c_remove, .id_table = da9062_i2c_id, }; diff --git a/drivers/mfd/da9063-i2c.c b/drivers/mfd/da9063-i2c.c index 03f8f95a1d62..d715cf9a9e68 100644 --- a/drivers/mfd/da9063-i2c.c +++ b/drivers/mfd/da9063-i2c.c @@ -469,7 +469,7 @@ static struct i2c_driver da9063_i2c_driver = { .name = "da9063", .of_match_table = da9063_dt_ids, }, - .probe_new = da9063_i2c_probe, + .probe = da9063_i2c_probe, .id_table = da9063_i2c_id, }; diff --git a/drivers/mfd/da9150-core.c b/drivers/mfd/da9150-core.c index d2c954103b2f..94d621e20635 100644 --- a/drivers/mfd/da9150-core.c +++ b/drivers/mfd/da9150-core.c @@ -510,7 +510,7 @@ static struct i2c_driver da9150_driver = { .name = "da9150", .of_match_table = da9150_of_match, }, - .probe_new = da9150_probe, + .probe = da9150_probe, .remove = da9150_remove, .shutdown = da9150_shutdown, .id_table = da9150_i2c_id, diff --git a/drivers/mfd/dln2.c b/drivers/mfd/dln2.c index c3149729cec2..c7510434380a 100644 --- a/drivers/mfd/dln2.c +++ b/drivers/mfd/dln2.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/mfd/ene-kb3930.c b/drivers/mfd/ene-kb3930.c index 3eff98e26bea..fa0ad2f14a39 100644 --- a/drivers/mfd/ene-kb3930.c +++ b/drivers/mfd/ene-kb3930.c @@ -196,7 +196,7 @@ static const struct of_device_id kb3930_dt_ids[] = { MODULE_DEVICE_TABLE(of, kb3930_dt_ids); static struct i2c_driver kb3930_driver = { - .probe_new = kb3930_probe, + .probe = kb3930_probe, .remove = kb3930_remove, .driver = { .name = "ene-kb3930", diff --git a/drivers/mfd/gateworks-gsc.c b/drivers/mfd/gateworks-gsc.c index c954ed265de8..b02bfdc871e9 100644 --- a/drivers/mfd/gateworks-gsc.c +++ b/drivers/mfd/gateworks-gsc.c @@ -264,7 +264,7 @@ static struct i2c_driver gsc_driver = { .name = "gateworks-gsc", .of_match_table = gsc_of_match, }, - .probe_new = gsc_probe, + .probe = gsc_probe, .remove = gsc_remove, }; module_i2c_driver(gsc_driver); diff --git a/drivers/mfd/intel-lpss-acpi.c b/drivers/mfd/intel-lpss-acpi.c index a143c8dca2d9..212818aef93e 100644 --- a/drivers/mfd/intel-lpss-acpi.c +++ b/drivers/mfd/intel-lpss-acpi.c @@ -183,6 +183,9 @@ static int intel_lpss_acpi_probe(struct platform_device *pdev) return -ENOMEM; info->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!info->mem) + return -ENODEV; + info->irq = platform_get_irq(pdev, 0); ret = intel_lpss_probe(&pdev->dev, info); diff --git a/drivers/mfd/intel-lpss.c b/drivers/mfd/intel-lpss.c index cfbee2cfba6b..9591b354072a 100644 --- a/drivers/mfd/intel-lpss.c +++ b/drivers/mfd/intel-lpss.c @@ -460,6 +460,7 @@ void intel_lpss_remove(struct device *dev) } EXPORT_SYMBOL_GPL(intel_lpss_remove); +#ifdef CONFIG_PM static int resume_lpss_device(struct device *dev, void *data) { if (!dev_pm_test_driver_flags(dev, DPM_FLAG_SMART_SUSPEND)) @@ -514,6 +515,7 @@ int intel_lpss_resume(struct device *dev) return 0; } EXPORT_SYMBOL_GPL(intel_lpss_resume); +#endif static int __init intel_lpss_init(void) { diff --git a/drivers/mfd/intel-m10-bmc-core.c b/drivers/mfd/intel-m10-bmc-core.c index dac9cf7bcb4a..8ad5b3821584 100644 --- a/drivers/mfd/intel-m10-bmc-core.c +++ b/drivers/mfd/intel-m10-bmc-core.c @@ -12,6 +12,91 @@ #include #include +void m10bmc_fw_state_set(struct intel_m10bmc *m10bmc, enum m10bmc_fw_state new_state) +{ + /* bmcfw_state is only needed if handshake_sys_reg_nranges > 0 */ + if (!m10bmc->info->handshake_sys_reg_nranges) + return; + + down_write(&m10bmc->bmcfw_lock); + m10bmc->bmcfw_state = new_state; + up_write(&m10bmc->bmcfw_lock); +} +EXPORT_SYMBOL_NS_GPL(m10bmc_fw_state_set, INTEL_M10_BMC_CORE); + +/* + * For some Intel FPGA devices, the BMC firmware is not available to service + * handshake registers during a secure update. + */ +static bool m10bmc_reg_always_available(struct intel_m10bmc *m10bmc, unsigned int offset) +{ + if (!m10bmc->info->handshake_sys_reg_nranges) + return true; + + return !regmap_reg_in_ranges(offset, m10bmc->info->handshake_sys_reg_ranges, + m10bmc->info->handshake_sys_reg_nranges); +} + +/* + * m10bmc_handshake_reg_unavailable - Checks if reg access collides with secure update state + * @m10bmc: M10 BMC structure + * + * For some Intel FPGA devices, the BMC firmware is not available to service + * handshake registers during a secure update erase and write phases. + * + * Context: @m10bmc->bmcfw_lock must be held. + */ +static bool m10bmc_handshake_reg_unavailable(struct intel_m10bmc *m10bmc) +{ + return m10bmc->bmcfw_state == M10BMC_FW_STATE_SEC_UPDATE_PREPARE || + m10bmc->bmcfw_state == M10BMC_FW_STATE_SEC_UPDATE_WRITE; +} + +/* + * This function helps to simplify the accessing of the system registers. + * + * The base of the system registers is configured through the struct + * csr_map. + */ +int m10bmc_sys_read(struct intel_m10bmc *m10bmc, unsigned int offset, unsigned int *val) +{ + const struct m10bmc_csr_map *csr_map = m10bmc->info->csr_map; + int ret; + + if (m10bmc_reg_always_available(m10bmc, offset)) + return m10bmc_raw_read(m10bmc, csr_map->base + offset, val); + + down_read(&m10bmc->bmcfw_lock); + if (m10bmc_handshake_reg_unavailable(m10bmc)) + ret = -EBUSY; /* Reg not available during secure update */ + else + ret = m10bmc_raw_read(m10bmc, csr_map->base + offset, val); + up_read(&m10bmc->bmcfw_lock); + + return ret; +} +EXPORT_SYMBOL_NS_GPL(m10bmc_sys_read, INTEL_M10_BMC_CORE); + +int m10bmc_sys_update_bits(struct intel_m10bmc *m10bmc, unsigned int offset, + unsigned int msk, unsigned int val) +{ + const struct m10bmc_csr_map *csr_map = m10bmc->info->csr_map; + int ret; + + if (m10bmc_reg_always_available(m10bmc, offset)) + return regmap_update_bits(m10bmc->regmap, csr_map->base + offset, msk, val); + + down_read(&m10bmc->bmcfw_lock); + if (m10bmc_handshake_reg_unavailable(m10bmc)) + ret = -EBUSY; /* Reg not available during secure update */ + else + ret = regmap_update_bits(m10bmc->regmap, csr_map->base + offset, msk, val); + up_read(&m10bmc->bmcfw_lock); + + return ret; +} +EXPORT_SYMBOL_NS_GPL(m10bmc_sys_update_bits, INTEL_M10_BMC_CORE); + static ssize_t bmc_version_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -98,7 +183,7 @@ const struct attribute_group *m10bmc_dev_groups[] = { &m10bmc_group, NULL, }; -EXPORT_SYMBOL_GPL(m10bmc_dev_groups); +EXPORT_SYMBOL_NS_GPL(m10bmc_dev_groups, INTEL_M10_BMC_CORE); int m10bmc_dev_init(struct intel_m10bmc *m10bmc, const struct intel_m10bmc_platform_info *info) { @@ -106,6 +191,7 @@ int m10bmc_dev_init(struct intel_m10bmc *m10bmc, const struct intel_m10bmc_platf m10bmc->info = info; dev_set_drvdata(m10bmc->dev, m10bmc); + init_rwsem(&m10bmc->bmcfw_lock); ret = devm_mfd_add_devices(m10bmc->dev, PLATFORM_DEVID_AUTO, info->cells, info->n_cells, @@ -115,7 +201,7 @@ int m10bmc_dev_init(struct intel_m10bmc *m10bmc, const struct intel_m10bmc_platf return ret; } -EXPORT_SYMBOL_GPL(m10bmc_dev_init); +EXPORT_SYMBOL_NS_GPL(m10bmc_dev_init, INTEL_M10_BMC_CORE); MODULE_DESCRIPTION("Intel MAX 10 BMC core driver"); MODULE_AUTHOR("Intel Corporation"); diff --git a/drivers/mfd/intel-m10-bmc-pmci.c b/drivers/mfd/intel-m10-bmc-pmci.c index 8821f1876dd6..0392ef8b57d8 100644 --- a/drivers/mfd/intel-m10-bmc-pmci.c +++ b/drivers/mfd/intel-m10-bmc-pmci.c @@ -453,3 +453,4 @@ module_dfl_driver(m10bmc_pmci_driver); MODULE_DESCRIPTION("MAX10 BMC PMCI-based interface"); MODULE_AUTHOR("Intel Corporation"); MODULE_LICENSE("GPL"); +MODULE_IMPORT_NS(INTEL_M10_BMC_CORE); diff --git a/drivers/mfd/intel-m10-bmc-spi.c b/drivers/mfd/intel-m10-bmc-spi.c index 957200e17fed..cbeb7de9e041 100644 --- a/drivers/mfd/intel-m10-bmc-spi.c +++ b/drivers/mfd/intel-m10-bmc-spi.c @@ -116,12 +116,20 @@ static struct mfd_cell m10bmc_d5005_subdevs[] = { { .name = "d5005bmc-sec-update" }, }; +static const struct regmap_range m10bmc_d5005_fw_handshake_regs[] = { + regmap_reg_range(M10BMC_N3000_TELEM_START, M10BMC_D5005_TELEM_END), +}; + static struct mfd_cell m10bmc_pacn3000_subdevs[] = { { .name = "n3000bmc-hwmon" }, { .name = "n3000bmc-retimer" }, { .name = "n3000bmc-sec-update" }, }; +static const struct regmap_range m10bmc_n3000_fw_handshake_regs[] = { + regmap_reg_range(M10BMC_N3000_TELEM_START, M10BMC_N3000_TELEM_END), +}; + static struct mfd_cell m10bmc_n5010_subdevs[] = { { .name = "n5010bmc-hwmon" }, }; @@ -129,18 +137,24 @@ static struct mfd_cell m10bmc_n5010_subdevs[] = { static const struct intel_m10bmc_platform_info m10bmc_spi_n3000 = { .cells = m10bmc_pacn3000_subdevs, .n_cells = ARRAY_SIZE(m10bmc_pacn3000_subdevs), + .handshake_sys_reg_ranges = m10bmc_n3000_fw_handshake_regs, + .handshake_sys_reg_nranges = ARRAY_SIZE(m10bmc_n3000_fw_handshake_regs), .csr_map = &m10bmc_n3000_csr_map, }; static const struct intel_m10bmc_platform_info m10bmc_spi_d5005 = { .cells = m10bmc_d5005_subdevs, .n_cells = ARRAY_SIZE(m10bmc_d5005_subdevs), + .handshake_sys_reg_ranges = m10bmc_d5005_fw_handshake_regs, + .handshake_sys_reg_nranges = ARRAY_SIZE(m10bmc_d5005_fw_handshake_regs), .csr_map = &m10bmc_n3000_csr_map, }; static const struct intel_m10bmc_platform_info m10bmc_spi_n5010 = { .cells = m10bmc_n5010_subdevs, .n_cells = ARRAY_SIZE(m10bmc_n5010_subdevs), + .handshake_sys_reg_ranges = m10bmc_n3000_fw_handshake_regs, + .handshake_sys_reg_nranges = ARRAY_SIZE(m10bmc_n3000_fw_handshake_regs), .csr_map = &m10bmc_n3000_csr_map, }; @@ -166,3 +180,4 @@ MODULE_DESCRIPTION("Intel MAX 10 BMC SPI bus interface"); MODULE_AUTHOR("Intel Corporation"); MODULE_LICENSE("GPL v2"); MODULE_ALIAS("spi:intel-m10-bmc"); +MODULE_IMPORT_NS(INTEL_M10_BMC_CORE); diff --git a/drivers/mfd/intel_soc_pmic_chtdc_ti.c b/drivers/mfd/intel_soc_pmic_chtdc_ti.c index 282b8fd08009..992855bfda3e 100644 --- a/drivers/mfd/intel_soc_pmic_chtdc_ti.c +++ b/drivers/mfd/intel_soc_pmic_chtdc_ti.c @@ -172,7 +172,7 @@ static struct i2c_driver chtdc_ti_i2c_driver = { .pm = pm_sleep_ptr(&chtdc_ti_pm_ops), .acpi_match_table = chtdc_ti_acpi_ids, }, - .probe_new = chtdc_ti_probe, + .probe = chtdc_ti_probe, .shutdown = chtdc_ti_shutdown, }; module_i2c_driver(chtdc_ti_i2c_driver); diff --git a/drivers/mfd/intel_soc_pmic_chtwc.c b/drivers/mfd/intel_soc_pmic_chtwc.c index 871776d511e3..7fce3ef7ab45 100644 --- a/drivers/mfd/intel_soc_pmic_chtwc.c +++ b/drivers/mfd/intel_soc_pmic_chtwc.c @@ -272,7 +272,7 @@ static struct i2c_driver cht_wc_driver = { .pm = pm_sleep_ptr(&cht_wc_pm_ops), .acpi_match_table = cht_wc_acpi_ids, }, - .probe_new = cht_wc_probe, + .probe = cht_wc_probe, .shutdown = cht_wc_shutdown, .id_table = cht_wc_i2c_id, }; diff --git a/drivers/mfd/intel_soc_pmic_crc.c b/drivers/mfd/intel_soc_pmic_crc.c index b745ace46e5b..581f81cbaa24 100644 --- a/drivers/mfd/intel_soc_pmic_crc.c +++ b/drivers/mfd/intel_soc_pmic_crc.c @@ -263,7 +263,7 @@ static struct i2c_driver crystal_cove_i2c_driver = { .pm = pm_sleep_ptr(&crystal_cove_pm_ops), .acpi_match_table = crystal_cove_acpi_match, }, - .probe_new = crystal_cove_i2c_probe, + .probe = crystal_cove_i2c_probe, .remove = crystal_cove_i2c_remove, .shutdown = crystal_cove_shutdown, }; diff --git a/drivers/mfd/iqs62x.c b/drivers/mfd/iqs62x.c index 1895fce25b06..dfe9cb79e6a1 100644 --- a/drivers/mfd/iqs62x.c +++ b/drivers/mfd/iqs62x.c @@ -1069,7 +1069,7 @@ static struct i2c_driver iqs62x_i2c_driver = { .of_match_table = iqs62x_of_match, .pm = &iqs62x_pm, }, - .probe_new = iqs62x_probe, + .probe = iqs62x_probe, .remove = iqs62x_remove, }; module_i2c_driver(iqs62x_i2c_driver); diff --git a/drivers/mfd/khadas-mcu.c b/drivers/mfd/khadas-mcu.c index 1c807c0e6d25..61396d824f16 100644 --- a/drivers/mfd/khadas-mcu.c +++ b/drivers/mfd/khadas-mcu.c @@ -134,7 +134,7 @@ static struct i2c_driver khadas_mcu_driver = { .name = "khadas-mcu-core", .of_match_table = of_match_ptr(khadas_mcu_of_match), }, - .probe_new = khadas_mcu_probe, + .probe = khadas_mcu_probe, }; module_i2c_driver(khadas_mcu_driver); diff --git a/drivers/mfd/lm3533-core.c b/drivers/mfd/lm3533-core.c index 946f94f3a3c3..c211183cecb2 100644 --- a/drivers/mfd/lm3533-core.c +++ b/drivers/mfd/lm3533-core.c @@ -485,8 +485,6 @@ static int lm3533_device_init(struct lm3533 *lm3533) lm3533->gpio_hwen = pdata->gpio_hwen; - dev_set_drvdata(lm3533->dev, lm3533); - if (gpio_is_valid(lm3533->gpio_hwen)) { ret = devm_gpio_request_one(lm3533->dev, lm3533->gpio_hwen, GPIOF_OUT_INIT_LOW, "lm3533-hwen"); @@ -626,7 +624,7 @@ static struct i2c_driver lm3533_i2c_driver = { .name = "lm3533", }, .id_table = lm3533_i2c_ids, - .probe_new = lm3533_i2c_probe, + .probe = lm3533_i2c_probe, .remove = lm3533_i2c_remove, }; diff --git a/drivers/mfd/lochnagar-i2c.c b/drivers/mfd/lochnagar-i2c.c index 3a65d9938902..3c8843117080 100644 --- a/drivers/mfd/lochnagar-i2c.c +++ b/drivers/mfd/lochnagar-i2c.c @@ -382,7 +382,7 @@ static struct i2c_driver lochnagar_i2c_driver = { .of_match_table = of_match_ptr(lochnagar_of_match), .suppress_bind_attrs = true, }, - .probe_new = lochnagar_i2c_probe, + .probe = lochnagar_i2c_probe, }; static int __init lochnagar_i2c_init(void) diff --git a/drivers/mfd/lp3943.c b/drivers/mfd/lp3943.c index f9f39b53d030..7f749a23dca8 100644 --- a/drivers/mfd/lp3943.c +++ b/drivers/mfd/lp3943.c @@ -140,7 +140,7 @@ MODULE_DEVICE_TABLE(of, lp3943_of_match); #endif static struct i2c_driver lp3943_driver = { - .probe_new = lp3943_probe, + .probe = lp3943_probe, .driver = { .name = "lp3943", .of_match_table = of_match_ptr(lp3943_of_match), diff --git a/drivers/mfd/lp873x.c b/drivers/mfd/lp873x.c index c81c5c9ad748..6639f0fad4ea 100644 --- a/drivers/mfd/lp873x.c +++ b/drivers/mfd/lp873x.c @@ -78,7 +78,7 @@ static struct i2c_driver lp873x_driver = { .name = "lp873x", .of_match_table = of_lp873x_match_table, }, - .probe_new = lp873x_probe, + .probe = lp873x_probe, .id_table = lp873x_id_table, }; module_i2c_driver(lp873x_driver); diff --git a/drivers/mfd/lp87565.c b/drivers/mfd/lp87565.c index 568f0f01ea0d..88ce4d7c50a7 100644 --- a/drivers/mfd/lp87565.c +++ b/drivers/mfd/lp87565.c @@ -119,7 +119,7 @@ static struct i2c_driver lp87565_driver = { .name = "lp87565", .of_match_table = of_lp87565_match_table, }, - .probe_new = lp87565_probe, + .probe = lp87565_probe, .shutdown = lp87565_shutdown, .id_table = lp87565_id_table, }; diff --git a/drivers/mfd/lp8788.c b/drivers/mfd/lp8788.c index 18583addaae2..f371eeb042e0 100644 --- a/drivers/mfd/lp8788.c +++ b/drivers/mfd/lp8788.c @@ -225,7 +225,7 @@ static struct i2c_driver lp8788_driver = { .driver = { .name = "lp8788", }, - .probe_new = lp8788_probe, + .probe = lp8788_probe, .remove = lp8788_remove, .id_table = lp8788_ids, }; diff --git a/drivers/mfd/madera-i2c.c b/drivers/mfd/madera-i2c.c index 47e65d88feb0..0968aa9733ac 100644 --- a/drivers/mfd/madera-i2c.c +++ b/drivers/mfd/madera-i2c.c @@ -139,7 +139,7 @@ static struct i2c_driver madera_i2c_driver = { .pm = &madera_pm_ops, .of_match_table = of_match_ptr(madera_of_match), }, - .probe_new = madera_i2c_probe, + .probe = madera_i2c_probe, .remove = madera_i2c_remove, .id_table = madera_i2c_id, }; diff --git a/drivers/mfd/max14577.c b/drivers/mfd/max14577.c index 0e3731e9e9b5..25ed8846b7fb 100644 --- a/drivers/mfd/max14577.c +++ b/drivers/mfd/max14577.c @@ -518,7 +518,7 @@ static struct i2c_driver max14577_i2c_driver = { .pm = pm_sleep_ptr(&max14577_pm), .of_match_table = max14577_dt_match, }, - .probe_new = max14577_i2c_probe, + .probe = max14577_i2c_probe, .remove = max14577_i2c_remove, .id_table = max14577_i2c_id, }; diff --git a/drivers/mfd/max77541.c b/drivers/mfd/max77541.c new file mode 100644 index 000000000000..e147e949c2b3 --- /dev/null +++ b/drivers/mfd/max77541.c @@ -0,0 +1,224 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2022 Analog Devices, Inc. + * Driver for the MAX77540 and MAX77541 + */ + +#include +#include +#include +#include +#include +#include + +static const struct regmap_config max77541_regmap_config = { + .reg_bits = 8, + .val_bits = 8, +}; + +static const struct regmap_irq max77541_src_irqs[] = { + { .mask = MAX77541_BIT_INT_SRC_TOPSYS }, + { .mask = MAX77541_BIT_INT_SRC_BUCK }, +}; + +static const struct regmap_irq_chip max77541_src_irq_chip = { + .name = "max77541-src", + .status_base = MAX77541_REG_INT_SRC, + .mask_base = MAX77541_REG_INT_SRC_M, + .num_regs = 1, + .irqs = max77541_src_irqs, + .num_irqs = ARRAY_SIZE(max77541_src_irqs), +}; + +static const struct regmap_irq max77541_topsys_irqs[] = { + { .mask = MAX77541_BIT_TOPSYS_INT_TJ_120C }, + { .mask = MAX77541_BIT_TOPSYS_INT_TJ_140C }, + { .mask = MAX77541_BIT_TOPSYS_INT_TSHDN }, + { .mask = MAX77541_BIT_TOPSYS_INT_UVLO }, + { .mask = MAX77541_BIT_TOPSYS_INT_ALT_SWO }, + { .mask = MAX77541_BIT_TOPSYS_INT_EXT_FREQ_DET }, +}; + +static const struct regmap_irq_chip max77541_topsys_irq_chip = { + .name = "max77541-topsys", + .status_base = MAX77541_REG_TOPSYS_INT, + .mask_base = MAX77541_REG_TOPSYS_INT_M, + .num_regs = 1, + .irqs = max77541_topsys_irqs, + .num_irqs = ARRAY_SIZE(max77541_topsys_irqs), +}; + +static const struct regmap_irq max77541_buck_irqs[] = { + { .mask = MAX77541_BIT_BUCK_INT_M1_POK_FLT }, + { .mask = MAX77541_BIT_BUCK_INT_M2_POK_FLT }, + { .mask = MAX77541_BIT_BUCK_INT_M1_SCFLT }, + { .mask = MAX77541_BIT_BUCK_INT_M2_SCFLT }, +}; + +static const struct regmap_irq_chip max77541_buck_irq_chip = { + .name = "max77541-buck", + .status_base = MAX77541_REG_BUCK_INT, + .mask_base = MAX77541_REG_BUCK_INT_M, + .num_regs = 1, + .irqs = max77541_buck_irqs, + .num_irqs = ARRAY_SIZE(max77541_buck_irqs), +}; + +static const struct regmap_irq max77541_adc_irqs[] = { + { .mask = MAX77541_BIT_ADC_INT_CH1_I }, + { .mask = MAX77541_BIT_ADC_INT_CH2_I }, + { .mask = MAX77541_BIT_ADC_INT_CH3_I }, + { .mask = MAX77541_BIT_ADC_INT_CH6_I }, +}; + +static const struct regmap_irq_chip max77541_adc_irq_chip = { + .name = "max77541-adc", + .status_base = MAX77541_REG_ADC_INT, + .mask_base = MAX77541_REG_ADC_INT_M, + .num_regs = 1, + .irqs = max77541_adc_irqs, + .num_irqs = ARRAY_SIZE(max77541_adc_irqs), +}; + +static const struct mfd_cell max77540_devs[] = { + MFD_CELL_OF("max77540-regulator", NULL, NULL, 0, 0, NULL), +}; + +static const struct mfd_cell max77541_devs[] = { + MFD_CELL_OF("max77541-regulator", NULL, NULL, 0, 0, NULL), + MFD_CELL_OF("max77541-adc", NULL, NULL, 0, 0, NULL), +}; + +static int max77541_pmic_irq_init(struct device *dev) +{ + struct max77541 *max77541 = dev_get_drvdata(dev); + int irq = max77541->i2c->irq; + int ret; + + ret = devm_regmap_add_irq_chip(dev, max77541->regmap, irq, + IRQF_ONESHOT | IRQF_SHARED, 0, + &max77541_src_irq_chip, + &max77541->irq_data); + if (ret) + return ret; + + ret = devm_regmap_add_irq_chip(dev, max77541->regmap, irq, + IRQF_ONESHOT | IRQF_SHARED, 0, + &max77541_topsys_irq_chip, + &max77541->irq_topsys); + if (ret) + return ret; + + ret = devm_regmap_add_irq_chip(dev, max77541->regmap, irq, + IRQF_ONESHOT | IRQF_SHARED, 0, + &max77541_buck_irq_chip, + &max77541->irq_buck); + if (ret) + return ret; + + if (max77541->id == MAX77541) { + ret = devm_regmap_add_irq_chip(dev, max77541->regmap, irq, + IRQF_ONESHOT | IRQF_SHARED, 0, + &max77541_adc_irq_chip, + &max77541->irq_adc); + if (ret) + return ret; + } + + return 0; +} + +static int max77541_pmic_setup(struct device *dev) +{ + struct max77541 *max77541 = dev_get_drvdata(dev); + const struct mfd_cell *cells; + int n_devs; + int ret; + + switch (max77541->id) { + case MAX77540: + cells = max77540_devs; + n_devs = ARRAY_SIZE(max77540_devs); + break; + case MAX77541: + cells = max77541_devs; + n_devs = ARRAY_SIZE(max77541_devs); + break; + default: + return -EINVAL; + } + + ret = max77541_pmic_irq_init(dev); + if (ret) + return dev_err_probe(dev, ret, "Failed to initialize IRQ\n"); + + ret = device_init_wakeup(dev, true); + if (ret) + return dev_err_probe(dev, ret, "Unable to init wakeup\n"); + + return devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE, + cells, n_devs, NULL, 0, NULL); +} + +static int max77541_probe(struct i2c_client *client) +{ + const struct i2c_device_id *id = i2c_client_get_device_id(client); + struct device *dev = &client->dev; + struct max77541 *max77541; + + max77541 = devm_kzalloc(dev, sizeof(*max77541), GFP_KERNEL); + if (!max77541) + return -ENOMEM; + + i2c_set_clientdata(client, max77541); + max77541->i2c = client; + + max77541->id = (enum max7754x_ids)device_get_match_data(dev); + if (!max77541->id) + max77541->id = (enum max7754x_ids)id->driver_data; + + if (!max77541->id) + return -EINVAL; + + max77541->regmap = devm_regmap_init_i2c(client, + &max77541_regmap_config); + if (IS_ERR(max77541->regmap)) + return dev_err_probe(dev, PTR_ERR(max77541->regmap), + "Failed to allocate register map\n"); + + return max77541_pmic_setup(dev); +} + +static const struct of_device_id max77541_of_id[] = { + { + .compatible = "adi,max77540", + .data = (void *)MAX77540, + }, + { + .compatible = "adi,max77541", + .data = (void *)MAX77541, + }, + { } +}; +MODULE_DEVICE_TABLE(of, max77541_of_id); + +static const struct i2c_device_id max77541_id[] = { + { "max77540", MAX77540 }, + { "max77541", MAX77541 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, max77541_id); + +static struct i2c_driver max77541_driver = { + .driver = { + .name = "max77541", + .of_match_table = max77541_of_id, + }, + .probe = max77541_probe, + .id_table = max77541_id, +}; +module_i2c_driver(max77541_driver); + +MODULE_DESCRIPTION("MAX7740/MAX7741 Driver"); +MODULE_AUTHOR("Okan Sahin "); +MODULE_LICENSE("GPL"); diff --git a/drivers/mfd/max77620.c b/drivers/mfd/max77620.c index cbd2297126f0..5811ed8f4840 100644 --- a/drivers/mfd/max77620.c +++ b/drivers/mfd/max77620.c @@ -698,7 +698,7 @@ static struct i2c_driver max77620_driver = { .name = "max77620", .pm = pm_sleep_ptr(&max77620_pm_ops), }, - .probe_new = max77620_probe, + .probe = max77620_probe, .id_table = max77620_id, }; builtin_i2c_driver(max77620_driver); diff --git a/drivers/mfd/max77650.c b/drivers/mfd/max77650.c index 3c07fcdd9d07..75b5dc44e38c 100644 --- a/drivers/mfd/max77650.c +++ b/drivers/mfd/max77650.c @@ -222,7 +222,7 @@ static struct i2c_driver max77650_i2c_driver = { .name = "max77650", .of_match_table = max77650_of_match, }, - .probe_new = max77650_i2c_probe, + .probe = max77650_i2c_probe, }; module_i2c_driver(max77650_i2c_driver); diff --git a/drivers/mfd/max77686.c b/drivers/mfd/max77686.c index f8e863f3fc95..01833086ca7d 100644 --- a/drivers/mfd/max77686.c +++ b/drivers/mfd/max77686.c @@ -269,7 +269,7 @@ static struct i2c_driver max77686_i2c_driver = { .pm = pm_sleep_ptr(&max77686_pm), .of_match_table = max77686_pmic_dt_match, }, - .probe_new = max77686_i2c_probe, + .probe = max77686_i2c_probe, }; module_i2c_driver(max77686_i2c_driver); diff --git a/drivers/mfd/max77693.c b/drivers/mfd/max77693.c index 3995e8769f49..1c485a4c3dcf 100644 --- a/drivers/mfd/max77693.c +++ b/drivers/mfd/max77693.c @@ -356,7 +356,7 @@ static struct i2c_driver max77693_i2c_driver = { .pm = &max77693_pm, .of_match_table = of_match_ptr(max77693_dt_match), }, - .probe_new = max77693_i2c_probe, + .probe = max77693_i2c_probe, .remove = max77693_i2c_remove, .id_table = max77693_i2c_id, }; diff --git a/drivers/mfd/max77714.c b/drivers/mfd/max77714.c index 143a432ea343..c618605a3fb2 100644 --- a/drivers/mfd/max77714.c +++ b/drivers/mfd/max77714.c @@ -143,7 +143,7 @@ static struct i2c_driver max77714_driver = { .name = "max77714", .of_match_table = max77714_dt_match, }, - .probe_new = max77714_probe, + .probe = max77714_probe, }; module_i2c_driver(max77714_driver); diff --git a/drivers/mfd/max77843.c b/drivers/mfd/max77843.c index 8ff0723808c8..b3689c13a14d 100644 --- a/drivers/mfd/max77843.c +++ b/drivers/mfd/max77843.c @@ -207,7 +207,7 @@ static struct i2c_driver max77843_i2c_driver = { .of_match_table = max77843_dt_match, .suppress_bind_attrs = true, }, - .probe_new = max77843_probe, + .probe = max77843_probe, .id_table = max77843_id, }; diff --git a/drivers/mfd/max8907.c b/drivers/mfd/max8907.c index a69b865c6eac..78b5ee688dec 100644 --- a/drivers/mfd/max8907.c +++ b/drivers/mfd/max8907.c @@ -201,8 +201,6 @@ static int max8907_i2c_probe(struct i2c_client *i2c) } max8907->dev = &i2c->dev; - dev_set_drvdata(max8907->dev, max8907); - max8907->i2c_gen = i2c; i2c_set_clientdata(i2c, max8907); max8907->regmap_gen = devm_regmap_init_i2c(i2c, @@ -313,7 +311,7 @@ static struct i2c_driver max8907_i2c_driver = { .name = "max8907", .of_match_table = of_match_ptr(max8907_of_match), }, - .probe_new = max8907_i2c_probe, + .probe = max8907_i2c_probe, .remove = max8907_i2c_remove, .id_table = max8907_i2c_id, }; diff --git a/drivers/mfd/max8925-i2c.c b/drivers/mfd/max8925-i2c.c index 4057fd15c29e..7608000488f9 100644 --- a/drivers/mfd/max8925-i2c.c +++ b/drivers/mfd/max8925-i2c.c @@ -172,7 +172,6 @@ static int max8925_probe(struct i2c_client *client) chip->i2c = client; chip->dev = &client->dev; i2c_set_clientdata(client, chip); - dev_set_drvdata(chip->dev, chip); mutex_init(&chip->io_lock); chip->rtc = i2c_new_dummy_device(chip->i2c->adapter, RTC_I2C_ADDR); @@ -240,7 +239,7 @@ static struct i2c_driver max8925_driver = { .pm = pm_sleep_ptr(&max8925_pm_ops), .of_match_table = max8925_dt_ids, }, - .probe_new = max8925_probe, + .probe = max8925_probe, .remove = max8925_remove, .id_table = max8925_id_table, }; diff --git a/drivers/mfd/max8997.c b/drivers/mfd/max8997.c index 79d551b86150..94c09a5eab32 100644 --- a/drivers/mfd/max8997.c +++ b/drivers/mfd/max8997.c @@ -478,7 +478,7 @@ static struct i2c_driver max8997_i2c_driver = { .suppress_bind_attrs = true, .of_match_table = of_match_ptr(max8997_pmic_dt_match), }, - .probe_new = max8997_i2c_probe, + .probe = max8997_i2c_probe, .id_table = max8997_i2c_id, }; diff --git a/drivers/mfd/max8998.c b/drivers/mfd/max8998.c index 122f7b931f5a..33a3ec5464fb 100644 --- a/drivers/mfd/max8998.c +++ b/drivers/mfd/max8998.c @@ -348,7 +348,7 @@ static struct i2c_driver max8998_i2c_driver = { .suppress_bind_attrs = true, .of_match_table = of_match_ptr(max8998_dt_match), }, - .probe_new = max8998_i2c_probe, + .probe = max8998_i2c_probe, .id_table = max8998_i2c_id, }; diff --git a/drivers/mfd/mc13xxx-i2c.c b/drivers/mfd/mc13xxx-i2c.c index 633b973a5ba7..de59b498c925 100644 --- a/drivers/mfd/mc13xxx-i2c.c +++ b/drivers/mfd/mc13xxx-i2c.c @@ -95,7 +95,7 @@ static struct i2c_driver mc13xxx_i2c_driver = { .name = "mc13xxx", .of_match_table = mc13xxx_dt_ids, }, - .probe_new = mc13xxx_i2c_probe, + .probe = mc13xxx_i2c_probe, .remove = mc13xxx_i2c_remove, }; diff --git a/drivers/mfd/menelaus.c b/drivers/mfd/menelaus.c index c2866a11c1d2..662604ea97f2 100644 --- a/drivers/mfd/menelaus.c +++ b/drivers/mfd/menelaus.c @@ -1240,7 +1240,7 @@ static struct i2c_driver menelaus_i2c_driver = { .driver = { .name = DRIVER_NAME, }, - .probe_new = menelaus_probe, + .probe = menelaus_probe, .remove = menelaus_remove, .id_table = menelaus_id, }; diff --git a/drivers/mfd/menf21bmc.c b/drivers/mfd/menf21bmc.c index 9092fac46e35..1d36095155e0 100644 --- a/drivers/mfd/menf21bmc.c +++ b/drivers/mfd/menf21bmc.c @@ -111,7 +111,7 @@ MODULE_DEVICE_TABLE(i2c, menf21bmc_id_table); static struct i2c_driver menf21bmc_driver = { .driver.name = "menf21bmc", .id_table = menf21bmc_id_table, - .probe_new = menf21bmc_probe, + .probe = menf21bmc_probe, }; module_i2c_driver(menf21bmc_driver); diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c index 695d50b3bac6..0ed7c0d7784e 100644 --- a/drivers/mfd/mfd-core.c +++ b/drivers/mfd/mfd-core.c @@ -102,7 +102,6 @@ static int mfd_match_of_node_to_dev(struct platform_device *pdev, { #if IS_ENABLED(CONFIG_OF) struct mfd_of_node_entry *of_entry; - const __be32 *reg; u64 of_node_addr; /* Skip if OF node has previously been allocated to a device */ @@ -115,13 +114,10 @@ static int mfd_match_of_node_to_dev(struct platform_device *pdev, goto allocate_of_node; /* We only care about each node's first defined address */ - reg = of_get_address(np, 0, NULL, NULL); - if (!reg) + if (of_property_read_reg(np, 0, &of_node_addr, NULL)) /* OF node does not contatin a 'reg' property to match to */ return -EAGAIN; - of_node_addr = of_read_number(reg, of_n_addr_cells(np)); - if (cell->of_reg != of_node_addr) /* No match */ return -EAGAIN; diff --git a/drivers/mfd/mp2629.c b/drivers/mfd/mp2629.c index 16840ec5fd1c..717b704c3c6b 100644 --- a/drivers/mfd/mp2629.c +++ b/drivers/mfd/mp2629.c @@ -70,7 +70,7 @@ static struct i2c_driver mp2629_driver = { .name = "mp2629", .of_match_table = mp2629_of_match, }, - .probe_new = mp2629_probe, + .probe = mp2629_probe, }; module_i2c_driver(mp2629_driver); diff --git a/drivers/mfd/mt6360-core.c b/drivers/mfd/mt6360-core.c index d3b32eb79837..2685efa5c9e2 100644 --- a/drivers/mfd/mt6360-core.c +++ b/drivers/mfd/mt6360-core.c @@ -623,7 +623,7 @@ static struct i2c_driver mt6360_driver = { .pm = &mt6360_pm_ops, .of_match_table = of_match_ptr(mt6360_of_id), }, - .probe_new = mt6360_probe, + .probe = mt6360_probe, }; module_i2c_driver(mt6360_driver); diff --git a/drivers/mfd/mt6370.c b/drivers/mfd/mt6370.c index cf19cce2fdc0..c126ccb25d66 100644 --- a/drivers/mfd/mt6370.c +++ b/drivers/mfd/mt6370.c @@ -303,7 +303,7 @@ static struct i2c_driver mt6370_driver = { .name = "mt6370", .of_match_table = mt6370_match_table, }, - .probe_new = mt6370_probe, + .probe = mt6370_probe, }; module_i2c_driver(mt6370_driver); diff --git a/drivers/mfd/ntxec.c b/drivers/mfd/ntxec.c index b02785b10d48..4416cd37e539 100644 --- a/drivers/mfd/ntxec.c +++ b/drivers/mfd/ntxec.c @@ -260,7 +260,7 @@ static struct i2c_driver ntxec_driver = { .name = "ntxec", .of_match_table = of_ntxec_match_table, }, - .probe_new = ntxec_probe, + .probe = ntxec_probe, .remove = ntxec_remove, }; module_i2c_driver(ntxec_driver); diff --git a/drivers/mfd/palmas.c b/drivers/mfd/palmas.c index b8383c6cba3f..a36f12402987 100644 --- a/drivers/mfd/palmas.c +++ b/drivers/mfd/palmas.c @@ -725,7 +725,7 @@ static struct i2c_driver palmas_i2c_driver = { .name = "palmas", .of_match_table = of_palmas_match_tbl, }, - .probe_new = palmas_i2c_probe, + .probe = palmas_i2c_probe, .remove = palmas_i2c_remove, .id_table = palmas_i2c_id, }; diff --git a/drivers/mfd/pcf50633-core.c b/drivers/mfd/pcf50633-core.c index 0e4fc99e9f49..014a68711b18 100644 --- a/drivers/mfd/pcf50633-core.c +++ b/drivers/mfd/pcf50633-core.c @@ -282,7 +282,7 @@ static struct i2c_driver pcf50633_driver = { .pm = pm_sleep_ptr(&pcf50633_pm), }, .id_table = pcf50633_id_table, - .probe_new = pcf50633_probe, + .probe = pcf50633_probe, .remove = pcf50633_remove, }; diff --git a/drivers/mfd/qcom-pm8008.c b/drivers/mfd/qcom-pm8008.c index 837246aab4ac..94a8cca1d955 100644 --- a/drivers/mfd/qcom-pm8008.c +++ b/drivers/mfd/qcom-pm8008.c @@ -199,15 +199,15 @@ static const struct of_device_id pm8008_match[] = { { .compatible = "qcom,pm8008", }, { }, }; +MODULE_DEVICE_TABLE(of, pm8008_match); static struct i2c_driver pm8008_mfd_driver = { .driver = { .name = "pm8008", .of_match_table = pm8008_match, }, - .probe_new = pm8008_probe, + .probe = pm8008_probe, }; module_i2c_driver(pm8008_mfd_driver); MODULE_LICENSE("GPL v2"); -MODULE_ALIAS("i2c:qcom-pm8008"); diff --git a/drivers/mfd/rc5t583-irq.c b/drivers/mfd/rc5t583-irq.c index 621ea61fa7c6..97f52b671520 100644 --- a/drivers/mfd/rc5t583-irq.c +++ b/drivers/mfd/rc5t583-irq.c @@ -8,9 +8,9 @@ * based on code * Copyright (C) 2011 RICOH COMPANY,LTD */ +#include #include #include -#include #include enum int_type { diff --git a/drivers/mfd/rc5t583.c b/drivers/mfd/rc5t583.c index df83cc399315..5e81f011363f 100644 --- a/drivers/mfd/rc5t583.c +++ b/drivers/mfd/rc5t583.c @@ -288,7 +288,7 @@ static struct i2c_driver rc5t583_i2c_driver = { .driver = { .name = "rc5t583", }, - .probe_new = rc5t583_i2c_probe, + .probe = rc5t583_i2c_probe, .id_table = rc5t583_i2c_id, }; diff --git a/drivers/mfd/retu-mfd.c b/drivers/mfd/retu-mfd.c index d71483859e2e..b50cfa7f4b8f 100644 --- a/drivers/mfd/retu-mfd.c +++ b/drivers/mfd/retu-mfd.c @@ -318,7 +318,7 @@ static struct i2c_driver retu_driver = { .name = "retu-mfd", .of_match_table = retu_of_match, }, - .probe_new = retu_probe, + .probe = retu_probe, .remove = retu_remove, .id_table = retu_id, }; diff --git a/drivers/mfd/rk8xx-i2c.c b/drivers/mfd/rk8xx-i2c.c index 2822bfa8a04a..1a98feea97e2 100644 --- a/drivers/mfd/rk8xx-i2c.c +++ b/drivers/mfd/rk8xx-i2c.c @@ -173,7 +173,7 @@ static struct i2c_driver rk8xx_i2c_driver = { .of_match_table = rk8xx_i2c_of_match, .pm = &rk8xx_i2c_pm_ops, }, - .probe_new = rk8xx_i2c_probe, + .probe = rk8xx_i2c_probe, .shutdown = rk8xx_i2c_shutdown, }; module_i2c_driver(rk8xx_i2c_driver); diff --git a/drivers/mfd/rn5t618.c b/drivers/mfd/rn5t618.c index 2f59230749cd..333fef8729a5 100644 --- a/drivers/mfd/rn5t618.c +++ b/drivers/mfd/rn5t618.c @@ -280,7 +280,7 @@ static struct i2c_driver rn5t618_i2c_driver = { .of_match_table = of_match_ptr(rn5t618_of_match), .pm = &rn5t618_i2c_dev_pm_ops, }, - .probe_new = rn5t618_i2c_probe, + .probe = rn5t618_i2c_probe, .remove = rn5t618_i2c_remove, }; diff --git a/drivers/mfd/rohm-bd71828.c b/drivers/mfd/rohm-bd71828.c index 7eb920633ee9..93d80a79b901 100644 --- a/drivers/mfd/rohm-bd71828.c +++ b/drivers/mfd/rohm-bd71828.c @@ -564,7 +564,7 @@ static struct i2c_driver bd71828_drv = { .name = "rohm-bd71828", .of_match_table = bd71828_of_match, }, - .probe_new = &bd71828_i2c_probe, + .probe = bd71828_i2c_probe, }; module_i2c_driver(bd71828_drv); diff --git a/drivers/mfd/rohm-bd718x7.c b/drivers/mfd/rohm-bd718x7.c index 378eb1a692e4..0b58ecc78334 100644 --- a/drivers/mfd/rohm-bd718x7.c +++ b/drivers/mfd/rohm-bd718x7.c @@ -208,7 +208,7 @@ static struct i2c_driver bd718xx_i2c_driver = { .name = "rohm-bd718x7", .of_match_table = bd718xx_of_match, }, - .probe_new = bd718xx_i2c_probe, + .probe = bd718xx_i2c_probe, }; static int __init bd718xx_i2c_init(void) diff --git a/drivers/mfd/rohm-bd9576.c b/drivers/mfd/rohm-bd9576.c index 6491e385d980..645673322ec0 100644 --- a/drivers/mfd/rohm-bd9576.c +++ b/drivers/mfd/rohm-bd9576.c @@ -178,7 +178,7 @@ static struct i2c_driver bd957x_drv = { .name = "rohm-bd957x", .of_match_table = bd957x_of_match, }, - .probe_new = &bd957x_i2c_probe, + .probe = bd957x_i2c_probe, }; module_i2c_driver(bd957x_drv); diff --git a/drivers/mfd/rsmu_i2c.c b/drivers/mfd/rsmu_i2c.c index 807c32101460..26972a5aff45 100644 --- a/drivers/mfd/rsmu_i2c.c +++ b/drivers/mfd/rsmu_i2c.c @@ -279,7 +279,7 @@ static struct i2c_driver rsmu_i2c_driver = { .name = "rsmu-i2c", .of_match_table = of_match_ptr(rsmu_i2c_of_match), }, - .probe_new = rsmu_i2c_probe, + .probe = rsmu_i2c_probe, .remove = rsmu_i2c_remove, .id_table = rsmu_i2c_id, }; diff --git a/drivers/mfd/rt4831.c b/drivers/mfd/rt4831.c index c6d34dc2b520..f8d6dc55b558 100644 --- a/drivers/mfd/rt4831.c +++ b/drivers/mfd/rt4831.c @@ -109,7 +109,7 @@ static struct i2c_driver rt4831_driver = { .name = "rt4831", .of_match_table = rt4831_of_match, }, - .probe_new = rt4831_probe, + .probe = rt4831_probe, .remove = rt4831_remove, }; module_i2c_driver(rt4831_driver); diff --git a/drivers/mfd/rt5033.c b/drivers/mfd/rt5033.c index a5e520fe50a1..67b0a228db24 100644 --- a/drivers/mfd/rt5033.c +++ b/drivers/mfd/rt5033.c @@ -40,9 +40,6 @@ static const struct mfd_cell rt5033_devs[] = { { .name = "rt5033-charger", .of_compatible = "richtek,rt5033-charger", - }, { - .name = "rt5033-battery", - .of_compatible = "richtek,rt5033-battery", }, { .name = "rt5033-led", .of_compatible = "richtek,rt5033-led", @@ -58,7 +55,7 @@ static const struct regmap_config rt5033_regmap_config = { static int rt5033_i2c_probe(struct i2c_client *i2c) { struct rt5033_dev *rt5033; - unsigned int dev_id; + unsigned int dev_id, chip_rev; int ret; rt5033 = devm_kzalloc(&i2c->dev, sizeof(*rt5033), GFP_KERNEL); @@ -81,7 +78,8 @@ static int rt5033_i2c_probe(struct i2c_client *i2c) dev_err(&i2c->dev, "Device not found\n"); return -ENODEV; } - dev_info(&i2c->dev, "Device found Device ID: %04x\n", dev_id); + chip_rev = dev_id & RT5033_CHIP_REV_MASK; + dev_info(&i2c->dev, "Device found (rev. %d)\n", chip_rev); ret = regmap_add_irq_chip(rt5033->regmap, rt5033->irq, IRQF_TRIGGER_FALLING | IRQF_ONESHOT, @@ -122,7 +120,7 @@ static struct i2c_driver rt5033_driver = { .name = "rt5033", .of_match_table = rt5033_dt_match, }, - .probe_new = rt5033_i2c_probe, + .probe = rt5033_i2c_probe, .id_table = rt5033_i2c_id, }; module_i2c_driver(rt5033_driver); diff --git a/drivers/mfd/rt5120.c b/drivers/mfd/rt5120.c index 829b7a0a0781..58d9a124d795 100644 --- a/drivers/mfd/rt5120.c +++ b/drivers/mfd/rt5120.c @@ -114,7 +114,7 @@ static struct i2c_driver rt5120_driver = { .name = "rt5120", .of_match_table = rt5120_device_match_table, }, - .probe_new = rt5120_probe, + .probe = rt5120_probe, }; module_i2c_driver(rt5120_driver); diff --git a/drivers/mfd/sec-core.c b/drivers/mfd/sec-core.c index c2d0ed496959..d2f631901886 100644 --- a/drivers/mfd/sec-core.c +++ b/drivers/mfd/sec-core.c @@ -450,7 +450,7 @@ static struct i2c_driver sec_pmic_driver = { .pm = pm_sleep_ptr(&sec_pmic_pm_ops), .of_match_table = sec_dt_match, }, - .probe_new = sec_pmic_probe, + .probe = sec_pmic_probe, .shutdown = sec_pmic_shutdown, }; module_i2c_driver(sec_pmic_driver); diff --git a/drivers/mfd/si476x-i2c.c b/drivers/mfd/si476x-i2c.c index 22131cf85e3f..899c0b5ea3aa 100644 --- a/drivers/mfd/si476x-i2c.c +++ b/drivers/mfd/si476x-i2c.c @@ -866,7 +866,7 @@ static struct i2c_driver si476x_core_driver = { .driver = { .name = "si476x-core", }, - .probe_new = si476x_core_probe, + .probe = si476x_core_probe, .remove = si476x_core_remove, .id_table = si476x_id, }; diff --git a/drivers/mfd/simple-mfd-i2c.c b/drivers/mfd/simple-mfd-i2c.c index 20782b4dd172..6eda79533208 100644 --- a/drivers/mfd/simple-mfd-i2c.c +++ b/drivers/mfd/simple-mfd-i2c.c @@ -72,28 +72,28 @@ static const struct simple_mfd_data silergy_sy7636a = { .mfd_cell_size = ARRAY_SIZE(sy7636a_cells), }; -static const struct mfd_cell max597x_cells[] = { - { .name = "max597x-regulator", }, - { .name = "max597x-iio", }, - { .name = "max597x-led", }, +static const struct mfd_cell max5970_cells[] = { + { .name = "max5970-regulator", }, + { .name = "max5970-iio", }, + { .name = "max5970-led", }, }; -static const struct simple_mfd_data maxim_max597x = { - .mfd_cell = max597x_cells, - .mfd_cell_size = ARRAY_SIZE(max597x_cells), +static const struct simple_mfd_data maxim_max5970 = { + .mfd_cell = max5970_cells, + .mfd_cell_size = ARRAY_SIZE(max5970_cells), }; static const struct of_device_id simple_mfd_i2c_of_match[] = { { .compatible = "kontron,sl28cpld" }, { .compatible = "silergy,sy7636a", .data = &silergy_sy7636a}, - { .compatible = "maxim,max5970", .data = &maxim_max597x}, - { .compatible = "maxim,max5978", .data = &maxim_max597x}, + { .compatible = "maxim,max5970", .data = &maxim_max5970}, + { .compatible = "maxim,max5978", .data = &maxim_max5970}, {} }; MODULE_DEVICE_TABLE(of, simple_mfd_i2c_of_match); static struct i2c_driver simple_mfd_i2c_driver = { - .probe_new = simple_mfd_i2c_probe, + .probe = simple_mfd_i2c_probe, .driver = { .name = "simple-mfd-i2c", .of_match_table = simple_mfd_i2c_of_match, diff --git a/drivers/mfd/sky81452.c b/drivers/mfd/sky81452.c index 2515ecae1d3f..771b62a5c70f 100644 --- a/drivers/mfd/sky81452.c +++ b/drivers/mfd/sky81452.c @@ -77,7 +77,7 @@ static struct i2c_driver sky81452_driver = { .name = "sky81452", .of_match_table = of_match_ptr(sky81452_of_match), }, - .probe_new = sky81452_probe, + .probe = sky81452_probe, .id_table = sky81452_ids, }; diff --git a/drivers/mfd/smpro-core.c b/drivers/mfd/smpro-core.c index d7729cf70378..59d31590c69b 100644 --- a/drivers/mfd/smpro-core.c +++ b/drivers/mfd/smpro-core.c @@ -125,7 +125,7 @@ static const struct of_device_id smpro_core_of_match[] = { MODULE_DEVICE_TABLE(of, smpro_core_of_match); static struct i2c_driver smpro_core_driver = { - .probe_new = smpro_core_probe, + .probe = smpro_core_probe, .driver = { .name = "smpro-core", .of_match_table = smpro_core_of_match, diff --git a/drivers/mfd/stmfx.c b/drivers/mfd/stmfx.c index e281971ba54e..c02cbd9c2f5d 100644 --- a/drivers/mfd/stmfx.c +++ b/drivers/mfd/stmfx.c @@ -330,9 +330,8 @@ static int stmfx_chip_init(struct i2c_client *client) stmfx->vdd = devm_regulator_get_optional(&client->dev, "vdd"); ret = PTR_ERR_OR_ZERO(stmfx->vdd); if (ret) { - if (ret == -ENODEV) - stmfx->vdd = NULL; - else + stmfx->vdd = NULL; + if (ret != -ENODEV) return dev_err_probe(&client->dev, ret, "Failed to get VDD regulator\n"); } @@ -387,7 +386,7 @@ static int stmfx_chip_init(struct i2c_client *client) err: if (stmfx->vdd) - return regulator_disable(stmfx->vdd); + regulator_disable(stmfx->vdd); return ret; } @@ -553,7 +552,7 @@ static struct i2c_driver stmfx_driver = { .of_match_table = stmfx_of_match, .pm = pm_sleep_ptr(&stmfx_dev_pm_ops), }, - .probe_new = stmfx_probe, + .probe = stmfx_probe, .remove = stmfx_remove, }; module_i2c_driver(stmfx_driver); diff --git a/drivers/mfd/stmpe-i2c.c b/drivers/mfd/stmpe-i2c.c index 7998e0db1e15..1d7b401776d1 100644 --- a/drivers/mfd/stmpe-i2c.c +++ b/drivers/mfd/stmpe-i2c.c @@ -118,7 +118,7 @@ static struct i2c_driver stmpe_i2c_driver = { .pm = pm_sleep_ptr(&stmpe_dev_pm_ops), .of_match_table = stmpe_of_match, }, - .probe_new = stmpe_i2c_probe, + .probe = stmpe_i2c_probe, .remove = stmpe_i2c_remove, .id_table = stmpe_i2c_id, }; diff --git a/drivers/mfd/stmpe.c b/drivers/mfd/stmpe.c index a92301dfc712..9c3cf58457a7 100644 --- a/drivers/mfd/stmpe.c +++ b/drivers/mfd/stmpe.c @@ -1485,9 +1485,9 @@ int stmpe_probe(struct stmpe_client_info *ci, enum stmpe_partnum partnum) void stmpe_remove(struct stmpe *stmpe) { - if (!IS_ERR(stmpe->vio)) + if (!IS_ERR(stmpe->vio) && regulator_is_enabled(stmpe->vio)) regulator_disable(stmpe->vio); - if (!IS_ERR(stmpe->vcc)) + if (!IS_ERR(stmpe->vcc) && regulator_is_enabled(stmpe->vcc)) regulator_disable(stmpe->vcc); __stmpe_disable(stmpe, STMPE_BLOCK_ADC); diff --git a/drivers/mfd/stpmic1.c b/drivers/mfd/stpmic1.c index 8db1530d9bac..3cc7492f828f 100644 --- a/drivers/mfd/stpmic1.c +++ b/drivers/mfd/stpmic1.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -19,7 +20,7 @@ static const struct regmap_range stpmic1_readable_ranges[] = { regmap_reg_range(TURN_ON_SR, VERSION_SR), - regmap_reg_range(SWOFF_PWRCTRL_CR, LDO6_STDBY_CR), + regmap_reg_range(MAIN_CR, LDO6_STDBY_CR), regmap_reg_range(BST_SW_CR, BST_SW_CR), regmap_reg_range(INT_PENDING_R1, INT_PENDING_R4), regmap_reg_range(INT_CLEAR_R1, INT_CLEAR_R4), @@ -30,7 +31,7 @@ static const struct regmap_range stpmic1_readable_ranges[] = { }; static const struct regmap_range stpmic1_writeable_ranges[] = { - regmap_reg_range(SWOFF_PWRCTRL_CR, LDO6_STDBY_CR), + regmap_reg_range(MAIN_CR, LDO6_STDBY_CR), regmap_reg_range(BST_SW_CR, BST_SW_CR), regmap_reg_range(INT_CLEAR_R1, INT_CLEAR_R4), regmap_reg_range(INT_SET_MASK_R1, INT_SET_MASK_R4), @@ -117,6 +118,16 @@ static const struct regmap_irq_chip stpmic1_regmap_irq_chip = { .num_irqs = ARRAY_SIZE(stpmic1_irqs), }; +static int stpmic1_power_off(struct sys_off_data *data) +{ + struct stpmic1 *ddata = data->cb_data; + + regmap_update_bits(ddata->regmap, MAIN_CR, + SOFTWARE_SWITCH_OFF, SOFTWARE_SWITCH_OFF); + + return NOTIFY_DONE; +} + static int stpmic1_probe(struct i2c_client *i2c) { struct stpmic1 *ddata; @@ -159,6 +170,16 @@ static int stpmic1_probe(struct i2c_client *i2c) return ret; } + ret = devm_register_sys_off_handler(ddata->dev, + SYS_OFF_MODE_POWER_OFF, + SYS_OFF_PRIO_DEFAULT, + stpmic1_power_off, + ddata); + if (ret) { + dev_err(ddata->dev, "failed to register sys-off handler: %d\n", ret); + return ret; + } + return devm_of_platform_populate(dev); } @@ -201,7 +222,7 @@ static struct i2c_driver stpmic1_driver = { .of_match_table = of_match_ptr(stpmic1_of_match), .pm = pm_sleep_ptr(&stpmic1_pm), }, - .probe_new = stpmic1_probe, + .probe = stpmic1_probe, }; module_i2c_driver(stpmic1_driver); diff --git a/drivers/mfd/stw481x.c b/drivers/mfd/stw481x.c index 2a8fc9d1c806..f35c3af680dd 100644 --- a/drivers/mfd/stw481x.c +++ b/drivers/mfd/stw481x.c @@ -239,7 +239,7 @@ static struct i2c_driver stw481x_driver = { .name = "stw481x", .of_match_table = stw481x_match, }, - .probe_new = stw481x_probe, + .probe = stw481x_probe, .id_table = stw481x_id, }; diff --git a/drivers/mfd/tc3589x.c b/drivers/mfd/tc3589x.c index cbfe19d1b145..16df64e3c0be 100644 --- a/drivers/mfd/tc3589x.c +++ b/drivers/mfd/tc3589x.c @@ -485,7 +485,7 @@ static struct i2c_driver tc3589x_driver = { .pm = pm_sleep_ptr(&tc3589x_dev_pm_ops), .of_match_table = of_match_ptr(tc3589x_match), }, - .probe_new = tc3589x_probe, + .probe = tc3589x_probe, .remove = tc3589x_remove, .id_table = tc3589x_id, }; diff --git a/drivers/mfd/ti-lmu.c b/drivers/mfd/ti-lmu.c index 9921320be255..4f06adad7b5e 100644 --- a/drivers/mfd/ti-lmu.c +++ b/drivers/mfd/ti-lmu.c @@ -217,7 +217,7 @@ static const struct i2c_device_id ti_lmu_ids[] = { MODULE_DEVICE_TABLE(i2c, ti_lmu_ids); static struct i2c_driver ti_lmu_driver = { - .probe_new = ti_lmu_probe, + .probe = ti_lmu_probe, .driver = { .name = "ti-lmu", .of_match_table = ti_lmu_of_match, diff --git a/drivers/mfd/tps6105x.c b/drivers/mfd/tps6105x.c index a66cb911998d..5601f6d0d874 100644 --- a/drivers/mfd/tps6105x.c +++ b/drivers/mfd/tps6105x.c @@ -209,7 +209,7 @@ static struct i2c_driver tps6105x_driver = { .name = "tps6105x", .of_match_table = tps6105x_of_match, }, - .probe_new = tps6105x_probe, + .probe = tps6105x_probe, .remove = tps6105x_remove, .id_table = tps6105x_id, }; diff --git a/drivers/mfd/tps65010.c b/drivers/mfd/tps65010.c index faea4ff44c6f..2b9105295f30 100644 --- a/drivers/mfd/tps65010.c +++ b/drivers/mfd/tps65010.c @@ -664,7 +664,7 @@ static struct i2c_driver tps65010_driver = { .driver = { .name = "tps65010", }, - .probe_new = tps65010_probe, + .probe = tps65010_probe, .remove = tps65010_remove, .id_table = tps65010_id, }; diff --git a/drivers/mfd/tps6507x.c b/drivers/mfd/tps6507x.c index 500b594de316..9716bf703c7a 100644 --- a/drivers/mfd/tps6507x.c +++ b/drivers/mfd/tps6507x.c @@ -122,7 +122,7 @@ static struct i2c_driver tps6507x_i2c_driver = { .name = "tps6507x", .of_match_table = of_match_ptr(tps6507x_of_match), }, - .probe_new = tps6507x_i2c_probe, + .probe = tps6507x_i2c_probe, .id_table = tps6507x_i2c_id, }; diff --git a/drivers/mfd/tps65086.c b/drivers/mfd/tps65086.c index 9494c1d71b86..6a21000aad4a 100644 --- a/drivers/mfd/tps65086.c +++ b/drivers/mfd/tps65086.c @@ -129,7 +129,7 @@ static struct i2c_driver tps65086_driver = { .name = "tps65086", .of_match_table = tps65086_of_match_table, }, - .probe_new = tps65086_probe, + .probe = tps65086_probe, .remove = tps65086_remove, .id_table = tps65086_id_table, }; diff --git a/drivers/mfd/tps65090.c b/drivers/mfd/tps65090.c index af718a9c58b3..a35ad70755fb 100644 --- a/drivers/mfd/tps65090.c +++ b/drivers/mfd/tps65090.c @@ -236,7 +236,7 @@ static struct i2c_driver tps65090_driver = { .suppress_bind_attrs = true, .of_match_table = of_match_ptr(tps65090_of_match), }, - .probe_new = tps65090_i2c_probe, + .probe = tps65090_i2c_probe, .id_table = tps65090_id_table, }; diff --git a/drivers/mfd/tps65217.c b/drivers/mfd/tps65217.c index eebd60601b01..60599291b315 100644 --- a/drivers/mfd/tps65217.c +++ b/drivers/mfd/tps65217.c @@ -402,7 +402,7 @@ static struct i2c_driver tps65217_driver = { .of_match_table = tps65217_of_match, }, .id_table = tps65217_id_table, - .probe_new = tps65217_probe, + .probe = tps65217_probe, .remove = tps65217_remove, }; diff --git a/drivers/mfd/tps65218.c b/drivers/mfd/tps65218.c index ea69dcef91ec..619bf7adb20c 100644 --- a/drivers/mfd/tps65218.c +++ b/drivers/mfd/tps65218.c @@ -347,7 +347,7 @@ static struct i2c_driver tps65218_driver = { .name = "tps65218", .of_match_table = of_tps65218_match_table, }, - .probe_new = tps65218_probe, + .probe = tps65218_probe, .id_table = tps65218_id_table, }; diff --git a/drivers/mfd/tps65219.c b/drivers/mfd/tps65219.c index 0e402fda206b..0e0c42e4fdfc 100644 --- a/drivers/mfd/tps65219.c +++ b/drivers/mfd/tps65219.c @@ -25,13 +25,21 @@ static int tps65219_cold_reset(struct tps65219 *tps) TPS65219_MFP_COLD_RESET_I2C_CTRL_MASK); } -static int tps65219_restart(struct notifier_block *this, - unsigned long reboot_mode, void *cmd) +static int tps65219_soft_shutdown(struct tps65219 *tps) { - struct tps65219 *tps; + return regmap_update_bits(tps->regmap, TPS65219_REG_MFP_CTRL, + TPS65219_MFP_I2C_OFF_REQ_MASK, + TPS65219_MFP_I2C_OFF_REQ_MASK); +} - tps = container_of(this, struct tps65219, nb); +static int tps65219_power_off_handler(struct sys_off_data *data) +{ + tps65219_soft_shutdown(data->cb_data); + return NOTIFY_DONE; +} +static int tps65219_restart(struct tps65219 *tps, unsigned long reboot_mode) +{ if (reboot_mode == REBOOT_WARM) tps65219_warm_reset(tps); else @@ -40,10 +48,11 @@ static int tps65219_restart(struct notifier_block *this, return NOTIFY_DONE; } -static struct notifier_block pmic_rst_restart_nb = { - .notifier_call = tps65219_restart, - .priority = 200, -}; +static int tps65219_restart_handler(struct sys_off_data *data) +{ + tps65219_restart(data->cb_data, data->mode); + return NOTIFY_DONE; +} static const struct resource tps65219_pwrbutton_resources[] = { DEFINE_RES_IRQ_NAMED(TPS65219_INT_PB_FALLING_EDGE_DETECT, "falling"), @@ -106,7 +115,7 @@ static const struct mfd_cell tps65219_cells[] = { .resources = tps65219_regulator_resources, .num_resources = ARRAY_SIZE(tps65219_regulator_resources), }, - { .name = "tps65219-gpios", }, + { .name = "tps65219-gpio", }, }; static const struct mfd_cell tps65219_pwrbutton_cell = { @@ -269,13 +278,22 @@ static int tps65219_probe(struct i2c_client *client) } } - tps->nb = pmic_rst_restart_nb; - ret = register_restart_handler(&tps->nb); + ret = devm_register_restart_handler(tps->dev, + tps65219_restart_handler, + tps); + if (ret) { dev_err(tps->dev, "cannot register restart handler, %d\n", ret); return ret; } + ret = devm_register_power_off_handler(tps->dev, + tps65219_power_off_handler, + tps); + if (ret) { + dev_err(tps->dev, "failed to register power-off handler: %d\n", ret); + return ret; + } return 0; } @@ -290,7 +308,7 @@ static struct i2c_driver tps65219_driver = { .name = "tps65219", .of_match_table = of_tps65219_match_table, }, - .probe_new = tps65219_probe, + .probe = tps65219_probe, }; module_i2c_driver(tps65219_driver); diff --git a/drivers/mfd/tps6586x.c b/drivers/mfd/tps6586x.c index 90e23232b6b0..55675ceedcd3 100644 --- a/drivers/mfd/tps6586x.c +++ b/drivers/mfd/tps6586x.c @@ -619,7 +619,7 @@ static struct i2c_driver tps6586x_driver = { .of_match_table = of_match_ptr(tps6586x_of_match), .pm = &tps6586x_pm_ops, }, - .probe_new = tps6586x_i2c_probe, + .probe = tps6586x_i2c_probe, .remove = tps6586x_i2c_remove, .id_table = tps6586x_id_table, }; diff --git a/drivers/mfd/tps65910.c b/drivers/mfd/tps65910.c index 821c0277a2ed..41408df1712f 100644 --- a/drivers/mfd/tps65910.c +++ b/drivers/mfd/tps65910.c @@ -535,7 +535,7 @@ static struct i2c_driver tps65910_i2c_driver = { .name = "tps65910", .of_match_table = of_match_ptr(tps65910_of_match), }, - .probe_new = tps65910_i2c_probe, + .probe = tps65910_i2c_probe, .id_table = tps65910_i2c_id, }; diff --git a/drivers/mfd/tps65912-i2c.c b/drivers/mfd/tps65912-i2c.c index 1bf945966bf7..3c5ac781b6c1 100644 --- a/drivers/mfd/tps65912-i2c.c +++ b/drivers/mfd/tps65912-i2c.c @@ -60,7 +60,7 @@ static struct i2c_driver tps65912_i2c_driver = { .name = "tps65912", .of_match_table = tps65912_i2c_of_match_table, }, - .probe_new = tps65912_i2c_probe, + .probe = tps65912_i2c_probe, .remove = tps65912_i2c_remove, .id_table = tps65912_i2c_id_table, }; diff --git a/drivers/mfd/tps6594-i2c.c b/drivers/mfd/tps6594-i2c.c index 449d5c61bc9f..899c88c0fe77 100644 --- a/drivers/mfd/tps6594-i2c.c +++ b/drivers/mfd/tps6594-i2c.c @@ -222,7 +222,7 @@ static int tps6594_i2c_probe(struct i2c_client *client) match = of_match_device(tps6594_i2c_of_match_table, dev); if (!match) - return dev_err_probe(dev, PTR_ERR(match), "Failed to find matching chip ID\n"); + return dev_err_probe(dev, -EINVAL, "Failed to find matching chip ID\n"); tps->chip_id = (unsigned long)match->data; crc8_populate_msb(tps6594_i2c_crc_table, TPS6594_CRC8_POLYNOMIAL); @@ -235,7 +235,7 @@ static struct i2c_driver tps6594_i2c_driver = { .name = "tps6594", .of_match_table = tps6594_i2c_of_match_table, }, - .probe_new = tps6594_i2c_probe, + .probe = tps6594_i2c_probe, }; module_i2c_driver(tps6594_i2c_driver); diff --git a/drivers/mfd/tps6594-spi.c b/drivers/mfd/tps6594-spi.c index a938a191744f..f4b4f37f957f 100644 --- a/drivers/mfd/tps6594-spi.c +++ b/drivers/mfd/tps6594-spi.c @@ -107,7 +107,7 @@ static int tps6594_spi_probe(struct spi_device *spi) match = of_match_device(tps6594_spi_of_match_table, dev); if (!match) - return dev_err_probe(dev, PTR_ERR(match), "Failed to find matching chip ID\n"); + return dev_err_probe(dev, -EINVAL, "Failed to find matching chip ID\n"); tps->chip_id = (unsigned long)match->data; crc8_populate_msb(tps6594_spi_crc_table, TPS6594_CRC8_POLYNOMIAL); diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c index e801b7ce010f..ce01a87f8dc3 100644 --- a/drivers/mfd/twl-core.c +++ b/drivers/mfd/twl-core.c @@ -890,7 +890,7 @@ static struct i2c_driver twl_driver = { .driver.name = DRIVER_NAME, .driver.pm = &twl_dev_pm_ops, .id_table = twl_ids, - .probe_new = twl_probe, + .probe = twl_probe, .remove = twl_remove, }; builtin_i2c_driver(twl_driver); diff --git a/drivers/mfd/twl6040.c b/drivers/mfd/twl6040.c index e982119bbefa..d85675a4d9a8 100644 --- a/drivers/mfd/twl6040.c +++ b/drivers/mfd/twl6040.c @@ -608,7 +608,7 @@ static const struct regmap_config twl6040_regmap_config = { .volatile_reg = twl6040_volatile_reg, .writeable_reg = twl6040_writeable_reg, - .cache_type = REGCACHE_RBTREE, + .cache_type = REGCACHE_MAPLE, .use_single_read = true, .use_single_write = true, }; @@ -829,7 +829,7 @@ static struct i2c_driver twl6040_driver = { .driver = { .name = "twl6040", }, - .probe_new = twl6040_probe, + .probe = twl6040_probe, .remove = twl6040_remove, .id_table = twl6040_i2c_id, }; diff --git a/drivers/mfd/wcd934x.c b/drivers/mfd/wcd934x.c index 07e884087f2c..6b942d5270c1 100644 --- a/drivers/mfd/wcd934x.c +++ b/drivers/mfd/wcd934x.c @@ -227,10 +227,9 @@ static int wcd934x_slim_probe(struct slim_device *sdev) "Failed to get IRQ\n"); ddata->extclk = devm_clk_get(dev, "extclk"); - if (IS_ERR(ddata->extclk)) { - dev_err(dev, "Failed to get extclk"); - return PTR_ERR(ddata->extclk); - } + if (IS_ERR(ddata->extclk)) + return dev_err_probe(dev, PTR_ERR(ddata->extclk), + "Failed to get extclk"); ddata->supplies[0].supply = "vdd-buck"; ddata->supplies[1].supply = "vdd-buck-sido"; @@ -239,16 +238,12 @@ static int wcd934x_slim_probe(struct slim_device *sdev) ddata->supplies[4].supply = "vdd-io"; ret = regulator_bulk_get(dev, WCD934X_MAX_SUPPLY, ddata->supplies); - if (ret) { - dev_err(dev, "Failed to get supplies: err = %d\n", ret); - return ret; - } + if (ret) + return dev_err_probe(dev, ret, "Failed to get supplies\n"); ret = regulator_bulk_enable(WCD934X_MAX_SUPPLY, ddata->supplies); - if (ret) { - dev_err(dev, "Failed to enable supplies: err = %d\n", ret); - return ret; - } + if (ret) + return dev_err_probe(dev, ret, "Failed to enable supplies\n"); /* * For WCD934X, it takes about 600us for the Vout_A and @@ -258,8 +253,9 @@ static int wcd934x_slim_probe(struct slim_device *sdev) usleep_range(600, 650); reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW); if (IS_ERR(reset_gpio)) { - return dev_err_probe(dev, PTR_ERR(reset_gpio), - "Failed to get reset gpio: err = %ld\n", PTR_ERR(reset_gpio)); + ret = dev_err_probe(dev, PTR_ERR(reset_gpio), + "Failed to get reset gpio\n"); + goto err_disable_regulators; } msleep(20); gpiod_set_value(reset_gpio, 1); @@ -269,6 +265,10 @@ static int wcd934x_slim_probe(struct slim_device *sdev) dev_set_drvdata(dev, ddata); return 0; + +err_disable_regulators: + regulator_bulk_disable(WCD934X_MAX_SUPPLY, ddata->supplies); + return ret; } static void wcd934x_slim_remove(struct slim_device *sdev) diff --git a/drivers/mfd/wl1273-core.c b/drivers/mfd/wl1273-core.c index a5d6128fc67d..e2a7fccaed01 100644 --- a/drivers/mfd/wl1273-core.c +++ b/drivers/mfd/wl1273-core.c @@ -232,7 +232,7 @@ static struct i2c_driver wl1273_core_driver = { .driver = { .name = WL1273_FM_DRIVER_NAME, }, - .probe_new = wl1273_core_probe, + .probe = wl1273_core_probe, .id_table = wl1273_driver_id_table, }; diff --git a/drivers/mfd/wm831x-core.c b/drivers/mfd/wm831x-core.c index d2f444d2ae78..e86b6a4896a6 100644 --- a/drivers/mfd/wm831x-core.c +++ b/drivers/mfd/wm831x-core.c @@ -1430,7 +1430,7 @@ struct regmap_config wm831x_regmap_config = { .reg_bits = 16, .val_bits = 16, - .cache_type = REGCACHE_RBTREE, + .cache_type = REGCACHE_MAPLE, .max_register = WM831X_DBE_CHECK_DATA, .readable_reg = wm831x_reg_readable, diff --git a/drivers/mfd/wm831x-i2c.c b/drivers/mfd/wm831x-i2c.c index 9dbe96e2d46a..997837f13180 100644 --- a/drivers/mfd/wm831x-i2c.c +++ b/drivers/mfd/wm831x-i2c.c @@ -102,7 +102,7 @@ static struct i2c_driver wm831x_i2c_driver = { .of_match_table = of_match_ptr(wm831x_of_match), .suppress_bind_attrs = true, }, - .probe_new = wm831x_i2c_probe, + .probe = wm831x_i2c_probe, .id_table = wm831x_i2c_id, }; diff --git a/drivers/mfd/wm8350-i2c.c b/drivers/mfd/wm8350-i2c.c index 1fa1dfbc9e31..c2a7d7069975 100644 --- a/drivers/mfd/wm8350-i2c.c +++ b/drivers/mfd/wm8350-i2c.c @@ -52,7 +52,7 @@ static struct i2c_driver wm8350_i2c_driver = { .name = "wm8350", .suppress_bind_attrs = true, }, - .probe_new = wm8350_i2c_probe, + .probe = wm8350_i2c_probe, .id_table = wm8350_i2c_id, }; diff --git a/drivers/mfd/wm8400-core.c b/drivers/mfd/wm8400-core.c index 5e1599ac9abc..75483c9be0c4 100644 --- a/drivers/mfd/wm8400-core.c +++ b/drivers/mfd/wm8400-core.c @@ -54,8 +54,6 @@ static int wm8400_init(struct wm8400 *wm8400, unsigned int reg; int ret; - dev_set_drvdata(wm8400->dev, wm8400); - /* Check that this is actually a WM8400 */ ret = regmap_read(wm8400->regmap, WM8400_RESET_ID, ®); if (ret != 0) { @@ -145,7 +143,7 @@ static struct i2c_driver wm8400_i2c_driver = { .driver = { .name = "WM8400", }, - .probe_new = wm8400_i2c_probe, + .probe = wm8400_i2c_probe, .id_table = wm8400_i2c_id, }; #endif diff --git a/drivers/mfd/wm8994-core.c b/drivers/mfd/wm8994-core.c index c419ab0c0eae..1e4f1694f065 100644 --- a/drivers/mfd/wm8994-core.c +++ b/drivers/mfd/wm8994-core.c @@ -320,8 +320,6 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq) if (ret != 0) return ret; - dev_set_drvdata(wm8994->dev, wm8994); - /* Add the on-chip regulators first for bootstrapping */ ret = mfd_add_devices(wm8994->dev, 0, wm8994_regulator_devs, @@ -672,7 +670,7 @@ static struct i2c_driver wm8994_i2c_driver = { .pm = pm_ptr(&wm8994_pm_ops), .of_match_table = wm8994_of_match, }, - .probe_new = wm8994_i2c_probe, + .probe = wm8994_i2c_probe, .remove = wm8994_i2c_remove, .id_table = wm8994_i2c_id, }; diff --git a/drivers/misc/eeprom/at24.c b/drivers/misc/eeprom/at24.c index 938c4f41b98c..5aae2f9bdd51 100644 --- a/drivers/misc/eeprom/at24.c +++ b/drivers/misc/eeprom/at24.c @@ -761,7 +761,8 @@ static int at24_probe(struct i2c_client *client) pm_runtime_disable(dev); if (!pm_runtime_status_suspended(dev)) regulator_disable(at24->vcc_reg); - return PTR_ERR(at24->nvmem); + return dev_err_probe(dev, PTR_ERR(at24->nvmem), + "failed to register nvmem\n"); } /* diff --git a/drivers/net/arcnet/arcnet.c b/drivers/net/arcnet/arcnet.c index 1bad1866ae46..99265667538c 100644 --- a/drivers/net/arcnet/arcnet.c +++ b/drivers/net/arcnet/arcnet.c @@ -196,13 +196,10 @@ static void arcnet_dump_packet(struct net_device *dev, int bufnum, void arcnet_led_event(struct net_device *dev, enum arcnet_led_event event) { struct arcnet_local *lp = netdev_priv(dev); - unsigned long led_delay = 350; - unsigned long tx_delay = 50; switch (event) { case ARCNET_LED_EVENT_RECON: - led_trigger_blink_oneshot(lp->recon_led_trig, - &led_delay, &led_delay, 0); + led_trigger_blink_oneshot(lp->recon_led_trig, 350, 350, 0); break; case ARCNET_LED_EVENT_OPEN: led_trigger_event(lp->tx_led_trig, LED_OFF); @@ -213,8 +210,7 @@ void arcnet_led_event(struct net_device *dev, enum arcnet_led_event event) led_trigger_event(lp->recon_led_trig, LED_OFF); break; case ARCNET_LED_EVENT_TX: - led_trigger_blink_oneshot(lp->tx_led_trig, - &tx_delay, &tx_delay, 0); + led_trigger_blink_oneshot(lp->tx_led_trig, 50, 50, 0); break; } } diff --git a/drivers/parisc/ccio-dma.c b/drivers/parisc/ccio-dma.c index a66386043aa6..9bf652bd002c 100644 --- a/drivers/parisc/ccio-dma.c +++ b/drivers/parisc/ccio-dma.c @@ -97,7 +97,6 @@ #define DBG_RUN_SG(x...) #endif -#define CCIO_INLINE inline #define WRITE_U32(value, addr) __raw_writel(value, addr) #define READ_U32(addr) __raw_readl(addr) @@ -330,7 +329,8 @@ static int ioc_count; /** * ccio_alloc_range - Allocate pages in the ioc's resource map. * @ioc: The I/O Controller. - * @pages_needed: The requested number of pages to be mapped into the + * @dev: The PCI device. + * @size: The requested number of bytes to be mapped into the * I/O Pdir... * * This function searches the resource map of the ioc to locate a range @@ -552,7 +552,7 @@ static u32 hint_lookup[] = { * (Load Coherence Index) instruction. The 8 bits used for the virtual * index are bits 12:19 of the value returned by LCI. */ -static void CCIO_INLINE +static void ccio_io_pdir_entry(u64 *pdir_ptr, space_t sid, unsigned long vba, unsigned long hints) { @@ -623,7 +623,7 @@ ccio_io_pdir_entry(u64 *pdir_ptr, space_t sid, unsigned long vba, * * FIXME: Can we change the byte_cnt to pages_mapped? */ -static CCIO_INLINE void +static void ccio_clear_io_tlb(struct ioc *ioc, dma_addr_t iovp, size_t byte_cnt) { u32 chain_size = 1 << ioc->chainid_shift; @@ -656,7 +656,7 @@ ccio_clear_io_tlb(struct ioc *ioc, dma_addr_t iovp, size_t byte_cnt) * * FIXME: Can we change byte_cnt to pages_mapped? */ -static CCIO_INLINE void +static void ccio_mark_invalid(struct ioc *ioc, dma_addr_t iova, size_t byte_cnt) { u32 iovp = (u32)CCIO_IOVP(iova); @@ -795,9 +795,10 @@ ccio_map_page(struct device *dev, struct page *page, unsigned long offset, /** * ccio_unmap_page - Unmap an address range from the IOMMU. * @dev: The PCI device. - * @addr: The start address of the DMA region. + * @iova: The start address of the DMA region. * @size: The length of the DMA region. * @direction: The direction of the DMA transaction (to/from device). + * @attrs: attributes */ static void ccio_unmap_page(struct device *dev, dma_addr_t iova, size_t size, @@ -838,6 +839,8 @@ ccio_unmap_page(struct device *dev, dma_addr_t iova, size_t size, * @dev: The PCI device. * @size: The length of the DMA region. * @dma_handle: The DMA address handed back to the device (not the cpu). + * @flag: allocation flags + * @attrs: attributes * * This function implements the pci_alloc_consistent function. */ @@ -872,6 +875,7 @@ ccio_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t flag, * @size: The length of the DMA region. * @cpu_addr: The cpu address returned from the ccio_alloc_consistent. * @dma_handle: The device address returned from the ccio_alloc_consistent. + * @attrs: attributes * * This function implements the pci_free_consistent function. */ @@ -901,6 +905,7 @@ ccio_free(struct device *dev, size_t size, void *cpu_addr, * @sglist: The scatter/gather list to be mapped in the IOMMU. * @nents: The number of entries in the scatter/gather list. * @direction: The direction of the DMA transaction (to/from device). + * @attrs: attributes * * This function implements the pci_map_sg function. */ @@ -980,6 +985,7 @@ ccio_map_sg(struct device *dev, struct scatterlist *sglist, int nents, * @sglist: The scatter/gather list to be unmapped from the IOMMU. * @nents: The number of entries in the scatter/gather list. * @direction: The direction of the DMA transaction (to/from device). + * @attrs: attributes * * This function implements the pci_unmap_sg function. */ diff --git a/drivers/parisc/dino.c b/drivers/parisc/dino.c index e33036281327..f89f9fb4c84b 100644 --- a/drivers/parisc/dino.c +++ b/drivers/parisc/dino.c @@ -924,8 +924,6 @@ static const char cujo_vers[][4] = { "2.0" }; -void ccio_cujo20_fixup(struct parisc_device *dev, u32 iovp); - /* ** Determine if dino should claim this chip (return 0) or not (return 1). ** If so, initialize the chip appropriately (card-mode vs bridge mode). @@ -1086,9 +1084,8 @@ static struct parisc_driver dino_driver __refdata = { * This is the only routine which is NOT static. * Must be called exactly once before pci_init(). */ -int __init dino_init(void) +void __init dino_init(void) { register_parisc_driver(&dino_driver); - return 0; } diff --git a/drivers/parisc/eisa.c b/drivers/parisc/eisa.c index f96e5eaee87e..45e487388c6e 100644 --- a/drivers/parisc/eisa.c +++ b/drivers/parisc/eisa.c @@ -400,7 +400,7 @@ static struct parisc_driver eisa_driver __refdata = { .probe = eisa_probe, }; -void __init eisa_init(void) +void __init parisc_eisa_init(void) { register_parisc_driver(&eisa_driver); } diff --git a/drivers/parisc/lba_pci.c b/drivers/parisc/lba_pci.c index afc6e66ddc31..702bfd64e6e1 100644 --- a/drivers/parisc/lba_pci.c +++ b/drivers/parisc/lba_pci.c @@ -404,7 +404,7 @@ static int elroy_cfg_read(struct pci_bus *bus, unsigned int devfn, int pos, int static void lba_wr_cfg(struct lba_device *d, u32 tok, u8 reg, u32 data, u32 size) { - int error = 0; + int error __maybe_unused = 0; u32 arb_mask = 0; u32 error_config = 0; u32 status_control = 0; @@ -1018,7 +1018,7 @@ static void lba_pat_resources(struct parisc_device *pa_dev, struct lba_device *lba_dev) { unsigned long bytecnt; - long io_count; + long io_count __maybe_unused; long status; /* PDC return status */ long pa_count; pdc_pat_cell_mod_maddr_block_t *pa_pdc_cell; /* PA_VIEW */ @@ -1164,10 +1164,6 @@ lba_pat_resources(struct parisc_device *pa_dev, struct lba_device *lba_dev) #endif /* CONFIG_64BIT */ -extern void sba_distributed_lmmio(struct parisc_device *, struct resource *); -extern void sba_directed_lmmio(struct parisc_device *, struct resource *); - - static void lba_legacy_resources(struct parisc_device *pa_dev, struct lba_device *lba_dev) { diff --git a/drivers/parisc/pdc_stable.c b/drivers/parisc/pdc_stable.c index 2a18f7ba2398..633266447e2f 100644 --- a/drivers/parisc/pdc_stable.c +++ b/drivers/parisc/pdc_stable.c @@ -509,6 +509,8 @@ static struct pdcspath_entry *pdcspath_entries[] = { /** * pdcs_size_read - Stable Storage size output. + * @kobj: The kobject used to share data with userspace. + * @attr: The kobject attributes. * @buf: The output buffer to write to. */ static ssize_t pdcs_size_read(struct kobject *kobj, @@ -528,6 +530,8 @@ static ssize_t pdcs_size_read(struct kobject *kobj, /** * pdcs_auto_read - Stable Storage autoboot/search flag output. + * @kobj: The kobject used to share data with userspace. + * @attr: The kobject attributes. * @buf: The output buffer to write to. * @knob: The PF_AUTOBOOT or PF_AUTOSEARCH flag */ @@ -554,6 +558,8 @@ static ssize_t pdcs_auto_read(struct kobject *kobj, /** * pdcs_autoboot_read - Stable Storage autoboot flag output. + * @kobj: The kobject used to share data with userspace. + * @attr: The kobject attributes. * @buf: The output buffer to write to. */ static ssize_t pdcs_autoboot_read(struct kobject *kobj, @@ -564,6 +570,8 @@ static ssize_t pdcs_autoboot_read(struct kobject *kobj, /** * pdcs_autosearch_read - Stable Storage autoboot flag output. + * @kobj: The kobject used to share data with userspace. + * @attr: The kobject attributes. * @buf: The output buffer to write to. */ static ssize_t pdcs_autosearch_read(struct kobject *kobj, @@ -574,6 +582,8 @@ static ssize_t pdcs_autosearch_read(struct kobject *kobj, /** * pdcs_timer_read - Stable Storage timer count output (in seconds). + * @kobj: The kobject used to share data with userspace. + * @attr: The kobject attributes. * @buf: The output buffer to write to. * * The value of the timer field correponds to a number of seconds in powers of 2. @@ -601,6 +611,8 @@ static ssize_t pdcs_timer_read(struct kobject *kobj, /** * pdcs_osid_read - Stable Storage OS ID register output. + * @kobj: The kobject used to share data with userspace. + * @attr: The kobject attributes. * @buf: The output buffer to write to. */ static ssize_t pdcs_osid_read(struct kobject *kobj, @@ -619,6 +631,8 @@ static ssize_t pdcs_osid_read(struct kobject *kobj, /** * pdcs_osdep1_read - Stable Storage OS-Dependent data area 1 output. + * @kobj: The kobject used to share data with userspace. + * @attr: The kobject attributes. * @buf: The output buffer to write to. * * This can hold 16 bytes of OS-Dependent data. @@ -645,6 +659,8 @@ static ssize_t pdcs_osdep1_read(struct kobject *kobj, /** * pdcs_diagnostic_read - Stable Storage Diagnostic register output. + * @kobj: The kobject used to share data with userspace. + * @attr: The kobject attributes. * @buf: The output buffer to write to. * * I have NFC how to interpret the content of that register ;-). @@ -669,6 +685,8 @@ static ssize_t pdcs_diagnostic_read(struct kobject *kobj, /** * pdcs_fastsize_read - Stable Storage FastSize register output. + * @kobj: The kobject used to share data with userspace. + * @attr: The kobject attributes. * @buf: The output buffer to write to. * * This register holds the amount of system RAM to be tested during boot sequence. @@ -697,6 +715,8 @@ static ssize_t pdcs_fastsize_read(struct kobject *kobj, /** * pdcs_osdep2_read - Stable Storage OS-Dependent data area 2 output. + * @kobj: The kobject used to share data with userspace. + * @attr: The kobject attributes. * @buf: The output buffer to write to. * * This can hold pdcs_size - 224 bytes of OS-Dependent data, when available. @@ -729,6 +749,8 @@ static ssize_t pdcs_osdep2_read(struct kobject *kobj, /** * pdcs_auto_write - This function handles autoboot/search flag modifying. + * @kobj: The kobject used to share data with userspace. + * @attr: The kobject attributes. * @buf: The input buffer to read from. * @count: The number of bytes to be read. * @knob: The PF_AUTOBOOT or PF_AUTOSEARCH flag @@ -801,6 +823,8 @@ parse_error: /** * pdcs_autoboot_write - This function handles autoboot flag modifying. + * @kobj: The kobject used to share data with userspace. + * @attr: The kobject attributes. * @buf: The input buffer to read from. * @count: The number of bytes to be read. * @@ -817,6 +841,8 @@ static ssize_t pdcs_autoboot_write(struct kobject *kobj, /** * pdcs_autosearch_write - This function handles autosearch flag modifying. + * @kobj: The kobject used to share data with userspace. + * @attr: The kobject attributes. * @buf: The input buffer to read from. * @count: The number of bytes to be read. * @@ -833,6 +859,8 @@ static ssize_t pdcs_autosearch_write(struct kobject *kobj, /** * pdcs_osdep1_write - Stable Storage OS-Dependent data area 1 input. + * @kobj: The kobject used to share data with userspace. + * @attr: The kobject attributes. * @buf: The input buffer to read from. * @count: The number of bytes to be read. * @@ -870,6 +898,8 @@ static ssize_t pdcs_osdep1_write(struct kobject *kobj, /** * pdcs_osdep2_write - Stable Storage OS-Dependent data area 2 input. + * @kobj: The kobject used to share data with userspace. + * @attr: The kobject attributes. * @buf: The input buffer to read from. * @count: The number of bytes to be read. * @@ -1023,7 +1053,7 @@ pdcs_unregister_pathentries(void) static int __init pdc_stable_init(void) { - int rc = 0, error = 0; + int rc = 0, error; u32 result; /* find the size of the stable storage */ @@ -1052,6 +1082,10 @@ pdc_stable_init(void) /* Don't forget the root entries */ error = sysfs_create_group(stable_kobj, &pdcs_attr_group); + if (error) { + rc = -ENOMEM; + goto fail_ksetreg; + } /* register the paths kset as a child of the stable kset */ paths_kset = kset_create_and_add("paths", NULL, stable_kobj); diff --git a/drivers/parisc/sba_iommu.c b/drivers/parisc/sba_iommu.c index ecd870087a3d..bf3405f4289e 100644 --- a/drivers/parisc/sba_iommu.c +++ b/drivers/parisc/sba_iommu.c @@ -95,8 +95,6 @@ #define DBG_RES(x...) #endif -#define SBA_INLINE __inline__ - #define DEFAULT_DMA_HINT_REG 0 struct sba_device *sba_list; @@ -332,13 +330,14 @@ static unsigned long ptr_to_pide(struct ioc *ioc, unsigned long *res_ptr, /** * sba_search_bitmap - find free space in IO PDIR resource bitmap * @ioc: IO MMU structure which owns the pdir we are interested in. + * @dev: device to query the bitmap for * @bits_wanted: number of entries we need. * * Find consecutive free bits in resource bitmap. * Each bit represents one entry in the IO Pdir. * Cool perf optimization: search for log2(size) bits at a time. */ -static SBA_INLINE unsigned long +static unsigned long sba_search_bitmap(struct ioc *ioc, struct device *dev, unsigned long bits_wanted) { @@ -431,6 +430,7 @@ sba_search_bitmap(struct ioc *ioc, struct device *dev, /** * sba_alloc_range - find free bits and mark them in IO PDIR resource bitmap * @ioc: IO MMU structure which owns the pdir we are interested in. + * @dev: device for which pages should be alloced * @size: number of bytes to create a mapping for * * Given a size, find consecutive unmarked and then mark those bits in the @@ -490,7 +490,7 @@ sba_alloc_range(struct ioc *ioc, struct device *dev, size_t size) * * clear bits in the ioc's resource map */ -static SBA_INLINE void +static void sba_free_range(struct ioc *ioc, dma_addr_t iova, size_t size) { unsigned long iovp = SBA_IOVP(ioc, iova); @@ -568,7 +568,7 @@ typedef unsigned long space_t; * IOMMU uses little endian for the pdir. */ -static void SBA_INLINE +static void sba_io_pdir_entry(u64 *pdir_ptr, space_t sid, unsigned long vba, unsigned long hint) { @@ -609,7 +609,7 @@ sba_io_pdir_entry(u64 *pdir_ptr, space_t sid, unsigned long vba, * must be a power of 2. The "Cool perf optimization" in the * allocation routine helps keep that true. */ -static SBA_INLINE void +static void sba_mark_invalid(struct ioc *ioc, dma_addr_t iova, size_t byte_cnt) { u32 iovp = (u32) SBA_IOVP(ioc,iova); @@ -793,6 +793,7 @@ sba_map_page(struct device *dev, struct page *page, unsigned long offset, * @iova: IOVA of driver buffer previously mapped. * @size: number of bytes mapped in driver buffer. * @direction: R/W or both. + * @attrs: attributes * * See Documentation/core-api/dma-api-howto.rst */ @@ -872,6 +873,8 @@ sba_unmap_page(struct device *dev, dma_addr_t iova, size_t size, * @hwdev: instance of PCI owned by the driver that's asking. * @size: number of bytes mapped in driver buffer. * @dma_handle: IOVA of new buffer. + * @gfp: allocation flags + * @attrs: attributes * * See Documentation/core-api/dma-api-howto.rst */ @@ -902,7 +905,8 @@ static void *sba_alloc(struct device *hwdev, size_t size, dma_addr_t *dma_handle * @hwdev: instance of PCI owned by the driver that's asking. * @size: number of bytes mapped in driver buffer. * @vaddr: virtual address IOVA of "consistent" buffer. - * @dma_handler: IO virtual address of "consistent" buffer. + * @dma_handle: IO virtual address of "consistent" buffer. + * @attrs: attributes * * See Documentation/core-api/dma-api-howto.rst */ @@ -938,6 +942,7 @@ int dump_run_sg = 0; * @sglist: array of buffer/length pairs * @nents: number of entries in list * @direction: R/W or both. + * @attrs: attributes * * See Documentation/core-api/dma-api-howto.rst */ @@ -946,7 +951,7 @@ sba_map_sg(struct device *dev, struct scatterlist *sglist, int nents, enum dma_data_direction direction, unsigned long attrs) { struct ioc *ioc; - int coalesced, filled = 0; + int filled = 0; unsigned long flags; DBG_RUN_SG("%s() START %d entries\n", __func__, nents); @@ -985,7 +990,7 @@ sba_map_sg(struct device *dev, struct scatterlist *sglist, int nents, ** w/o this association, we wouldn't have coherent DMA! ** Access to the virtual address is what forces a two pass algorithm. */ - coalesced = iommu_coalesce_chunks(ioc, dev, sglist, nents, sba_alloc_range); + iommu_coalesce_chunks(ioc, dev, sglist, nents, sba_alloc_range); /* ** Program the I/O Pdir @@ -1022,6 +1027,7 @@ sba_map_sg(struct device *dev, struct scatterlist *sglist, int nents, * @sglist: array of buffer/length pairs * @nents: number of entries in list * @direction: R/W or both. + * @attrs: attributes * * See Documentation/core-api/dma-api-howto.rst */ @@ -1229,8 +1235,6 @@ struct ibase_data_struct { static int setup_ibase_imask_callback(struct device *dev, void *data) { - /* lba_set_iregs() is in drivers/parisc/lba_pci.c */ - extern void lba_set_iregs(struct parisc_device *, u32, u32); struct parisc_device *lba = to_parisc_device(dev); struct ibase_data_struct *ibd = data; int rope_num = (lba->hpa.start >> 13) & 0xf; @@ -1992,7 +1996,7 @@ void __init sba_init(void) /** * sba_get_iommu - Assign the iommu pointer for the pci bus controller. - * @dev: The parisc device. + * @pci_hba: The parisc device. * * Returns the appropriate IOMMU data for the given parisc PCI controller. * This is cached and used later for PCI DMA Mapping. @@ -2012,7 +2016,7 @@ void * sba_get_iommu(struct parisc_device *pci_hba) /** * sba_directed_lmmio - return first directed LMMIO range routed to rope - * @pa_dev: The parisc device. + * @pci_hba: The parisc device. * @r: resource PCI host controller wants start/end fields assigned. * * For the given parisc PCI controller, determine if any direct ranges @@ -2054,7 +2058,7 @@ void sba_directed_lmmio(struct parisc_device *pci_hba, struct resource *r) /** * sba_distributed_lmmio - return portion of distributed LMMIO range - * @pa_dev: The parisc device. + * @pci_hba: The parisc device. * @r: resource PCI host controller wants start/end fields assigned. * * For the given parisc PCI controller, return portion of distributed LMMIO diff --git a/drivers/platform/x86/simatic-ipc.c b/drivers/platform/x86/simatic-ipc.c index b3622419cd1a..c773995b230d 100644 --- a/drivers/platform/x86/simatic-ipc.c +++ b/drivers/platform/x86/simatic-ipc.c @@ -68,9 +68,10 @@ static int register_platform_devices(u32 station_id) } if (ledmode != SIMATIC_IPC_DEVICE_NONE) { - if (ledmode == SIMATIC_IPC_DEVICE_127E || - ledmode == SIMATIC_IPC_DEVICE_227G) - pdevname = KBUILD_MODNAME "_leds_gpio"; + if (ledmode == SIMATIC_IPC_DEVICE_127E) + pdevname = KBUILD_MODNAME "_leds_gpio_apollolake"; + if (ledmode == SIMATIC_IPC_DEVICE_227G) + pdevname = KBUILD_MODNAME "_leds_gpio_f7188x"; platform_data.devmode = ledmode; ipc_led_platform_device = platform_device_register_data(NULL, diff --git a/drivers/power/supply/Kconfig b/drivers/power/supply/Kconfig index 4a5e8e1d1237..862f9fe93120 100644 --- a/drivers/power/supply/Kconfig +++ b/drivers/power/supply/Kconfig @@ -766,6 +766,14 @@ config BATTERY_RT5033 The fuelgauge calculates and determines the battery state of charge according to battery open circuit voltage. +config CHARGER_RT5033 + tristate "RT5033 battery charger support" + depends on MFD_RT5033 + help + This adds support for battery charger in Richtek RT5033 PMIC. + The device supports pre-charge mode, fast charge mode and + constant voltage mode. + config CHARGER_RT9455 tristate "Richtek RT9455 battery charger driver" depends on I2C diff --git a/drivers/power/supply/Makefile b/drivers/power/supply/Makefile index 4adbfba02d05..dfc624bbcf1d 100644 --- a/drivers/power/supply/Makefile +++ b/drivers/power/supply/Makefile @@ -54,6 +54,7 @@ obj-$(CONFIG_BATTERY_MAX17040) += max17040_battery.o obj-$(CONFIG_BATTERY_MAX17042) += max17042_battery.o obj-$(CONFIG_BATTERY_MAX1721X) += max1721x_battery.o obj-$(CONFIG_BATTERY_RT5033) += rt5033_battery.o +obj-$(CONFIG_CHARGER_RT5033) += rt5033_charger.o obj-$(CONFIG_CHARGER_RT9455) += rt9455_charger.o obj-$(CONFIG_CHARGER_RT9467) += rt9467-charger.o obj-$(CONFIG_CHARGER_RT9471) += rt9471.o diff --git a/drivers/power/supply/power_supply_leds.c b/drivers/power/supply/power_supply_leds.c index 0674483279d7..c7db29d5fcb8 100644 --- a/drivers/power/supply/power_supply_leds.c +++ b/drivers/power/supply/power_supply_leds.c @@ -22,8 +22,6 @@ static void power_supply_update_bat_leds(struct power_supply *psy) { union power_supply_propval status; - unsigned long delay_on = 0; - unsigned long delay_off = 0; if (power_supply_get_property(psy, POWER_SUPPLY_PROP_STATUS, &status)) return; @@ -43,8 +41,7 @@ static void power_supply_update_bat_leds(struct power_supply *psy) led_trigger_event(psy->charging_full_trig, LED_FULL); led_trigger_event(psy->charging_trig, LED_FULL); led_trigger_event(psy->full_trig, LED_OFF); - led_trigger_blink(psy->charging_blink_full_solid_trig, - &delay_on, &delay_off); + led_trigger_blink(psy->charging_blink_full_solid_trig, 0, 0); break; default: led_trigger_event(psy->charging_full_trig, LED_OFF); diff --git a/drivers/power/supply/rt5033_battery.c b/drivers/power/supply/rt5033_battery.c index 5c04cf305219..94d2dea7ef5e 100644 --- a/drivers/power/supply/rt5033_battery.c +++ b/drivers/power/supply/rt5033_battery.c @@ -6,11 +6,33 @@ * Author: Beomho Seo */ +#include #include #include #include +#include #include -#include + +struct rt5033_battery { + struct i2c_client *client; + struct regmap *regmap; + struct power_supply *psy; +}; + +static int rt5033_battery_get_status(struct i2c_client *client) +{ + struct rt5033_battery *battery = i2c_get_clientdata(client); + union power_supply_propval val; + int ret; + + ret = power_supply_get_property_from_supplier(battery->psy, + POWER_SUPPLY_PROP_STATUS, + &val); + if (ret) + val.intval = POWER_SUPPLY_STATUS_UNKNOWN; + + return val.intval; +} static int rt5033_battery_get_capacity(struct i2c_client *client) { @@ -84,6 +106,9 @@ static int rt5033_battery_get_property(struct power_supply *psy, case POWER_SUPPLY_PROP_CAPACITY: val->intval = rt5033_battery_get_capacity(battery->client); break; + case POWER_SUPPLY_PROP_STATUS: + val->intval = rt5033_battery_get_status(battery->client); + break; default: return -EINVAL; } @@ -96,6 +121,7 @@ static enum power_supply_property rt5033_battery_props[] = { POWER_SUPPLY_PROP_VOLTAGE_OCV, POWER_SUPPLY_PROP_PRESENT, POWER_SUPPLY_PROP_CAPACITY, + POWER_SUPPLY_PROP_STATUS, }; static const struct regmap_config rt5033_battery_regmap_config = { @@ -117,7 +143,6 @@ static int rt5033_battery_probe(struct i2c_client *client) struct i2c_adapter *adapter = client->adapter; struct power_supply_config psy_cfg = {}; struct rt5033_battery *battery; - u32 ret; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE)) return -EIO; @@ -135,15 +160,14 @@ static int rt5033_battery_probe(struct i2c_client *client) } i2c_set_clientdata(client, battery); + psy_cfg.of_node = client->dev.of_node; psy_cfg.drv_data = battery; battery->psy = power_supply_register(&client->dev, &rt5033_battery_desc, &psy_cfg); - if (IS_ERR(battery->psy)) { - dev_err(&client->dev, "Failed to register power supply\n"); - ret = PTR_ERR(battery->psy); - return ret; - } + if (IS_ERR(battery->psy)) + return dev_err_probe(&client->dev, PTR_ERR(battery->psy), + "Failed to register power supply\n"); return 0; } diff --git a/drivers/power/supply/rt5033_charger.c b/drivers/power/supply/rt5033_charger.c new file mode 100644 index 000000000000..5218dfbf5e1b --- /dev/null +++ b/drivers/power/supply/rt5033_charger.c @@ -0,0 +1,472 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Battery charger driver for RT5033 + * + * Copyright (C) 2014 Samsung Electronics, Co., Ltd. + * Author: Beomho Seo + */ + +#include +#include +#include +#include +#include +#include + +struct rt5033_charger_data { + unsigned int pre_uamp; + unsigned int pre_uvolt; + unsigned int const_uvolt; + unsigned int eoc_uamp; + unsigned int fast_uamp; +}; + +struct rt5033_charger { + struct device *dev; + struct regmap *regmap; + struct power_supply *psy; + struct rt5033_charger_data *chg; +}; + +static int rt5033_get_charger_state(struct rt5033_charger *charger) +{ + struct regmap *regmap = charger->regmap; + unsigned int reg_data; + int state; + + if (!regmap) + return POWER_SUPPLY_STATUS_UNKNOWN; + + regmap_read(regmap, RT5033_REG_CHG_STAT, ®_data); + + switch (reg_data & RT5033_CHG_STAT_MASK) { + case RT5033_CHG_STAT_DISCHARGING: + state = POWER_SUPPLY_STATUS_DISCHARGING; + break; + case RT5033_CHG_STAT_CHARGING: + state = POWER_SUPPLY_STATUS_CHARGING; + break; + case RT5033_CHG_STAT_FULL: + state = POWER_SUPPLY_STATUS_FULL; + break; + case RT5033_CHG_STAT_NOT_CHARGING: + state = POWER_SUPPLY_STATUS_NOT_CHARGING; + break; + default: + state = POWER_SUPPLY_STATUS_UNKNOWN; + } + + return state; +} + +static int rt5033_get_charger_type(struct rt5033_charger *charger) +{ + struct regmap *regmap = charger->regmap; + unsigned int reg_data; + int state; + + regmap_read(regmap, RT5033_REG_CHG_STAT, ®_data); + + switch (reg_data & RT5033_CHG_STAT_TYPE_MASK) { + case RT5033_CHG_STAT_TYPE_FAST: + state = POWER_SUPPLY_CHARGE_TYPE_FAST; + break; + case RT5033_CHG_STAT_TYPE_PRE: + state = POWER_SUPPLY_CHARGE_TYPE_TRICKLE; + break; + default: + state = POWER_SUPPLY_CHARGE_TYPE_NONE; + } + + return state; +} + +static int rt5033_get_charger_current_limit(struct rt5033_charger *charger) +{ + struct regmap *regmap = charger->regmap; + unsigned int state, reg_data, data; + + regmap_read(regmap, RT5033_REG_CHG_CTRL5, ®_data); + + state = (reg_data & RT5033_CHGCTRL5_ICHG_MASK) + >> RT5033_CHGCTRL5_ICHG_SHIFT; + + data = RT5033_CHARGER_FAST_CURRENT_MIN + + RT5033_CHARGER_FAST_CURRENT_STEP_NUM * state; + + return data; +} + +static int rt5033_get_charger_const_voltage(struct rt5033_charger *charger) +{ + struct regmap *regmap = charger->regmap; + unsigned int state, reg_data, data; + + regmap_read(regmap, RT5033_REG_CHG_CTRL2, ®_data); + + state = (reg_data & RT5033_CHGCTRL2_CV_MASK) + >> RT5033_CHGCTRL2_CV_SHIFT; + + data = RT5033_CHARGER_CONST_VOLTAGE_LIMIT_MIN + + RT5033_CHARGER_CONST_VOLTAGE_STEP_NUM * state; + + return data; +} + +static inline int rt5033_init_const_charge(struct rt5033_charger *charger) +{ + struct rt5033_charger_data *chg = charger->chg; + int ret; + unsigned int val; + u8 reg_data; + + /* Set constant voltage mode */ + if (chg->const_uvolt < RT5033_CHARGER_CONST_VOLTAGE_LIMIT_MIN || + chg->const_uvolt > RT5033_CHARGER_CONST_VOLTAGE_LIMIT_MAX) { + dev_err(charger->dev, + "Value 'constant-charge-voltage-max-microvolt' out of range\n"); + return -EINVAL; + } + + if (chg->const_uvolt == RT5033_CHARGER_CONST_VOLTAGE_LIMIT_MIN) + reg_data = 0x00; + else if (chg->const_uvolt == RT5033_CHARGER_CONST_VOLTAGE_LIMIT_MAX) + reg_data = RT5033_CV_MAX_VOLTAGE; + else { + val = chg->const_uvolt; + val -= RT5033_CHARGER_CONST_VOLTAGE_LIMIT_MIN; + val /= RT5033_CHARGER_CONST_VOLTAGE_STEP_NUM; + reg_data = val; + } + + ret = regmap_update_bits(charger->regmap, RT5033_REG_CHG_CTRL2, + RT5033_CHGCTRL2_CV_MASK, + reg_data << RT5033_CHGCTRL2_CV_SHIFT); + if (ret) { + dev_err(charger->dev, "Failed regmap update\n"); + return -EINVAL; + } + + /* Set end of charge current */ + if (chg->eoc_uamp < RT5033_CHARGER_EOC_MIN || + chg->eoc_uamp > RT5033_CHARGER_EOC_MAX) { + dev_err(charger->dev, + "Value 'charge-term-current-microamp' out of range\n"); + return -EINVAL; + } + + if (chg->eoc_uamp == RT5033_CHARGER_EOC_MIN) + reg_data = 0x01; + else if (chg->eoc_uamp == RT5033_CHARGER_EOC_MAX) + reg_data = 0x07; + else { + val = chg->eoc_uamp; + if (val < RT5033_CHARGER_EOC_REF) { + val -= RT5033_CHARGER_EOC_MIN; + val /= RT5033_CHARGER_EOC_STEP_NUM1; + reg_data = 0x01 + val; + } else if (val > RT5033_CHARGER_EOC_REF) { + val -= RT5033_CHARGER_EOC_REF; + val /= RT5033_CHARGER_EOC_STEP_NUM2; + reg_data = 0x04 + val; + } else { + reg_data = 0x04; + } + } + + ret = regmap_update_bits(charger->regmap, RT5033_REG_CHG_CTRL4, + RT5033_CHGCTRL4_EOC_MASK, reg_data); + if (ret) { + dev_err(charger->dev, "Failed regmap update\n"); + return -EINVAL; + } + + return 0; +} + +static inline int rt5033_init_fast_charge(struct rt5033_charger *charger) +{ + struct rt5033_charger_data *chg = charger->chg; + int ret; + unsigned int val; + u8 reg_data; + + /* Set limit input current */ + ret = regmap_update_bits(charger->regmap, RT5033_REG_CHG_CTRL1, + RT5033_CHGCTRL1_IAICR_MASK, RT5033_AICR_2000_MODE); + if (ret) { + dev_err(charger->dev, "Failed regmap update\n"); + return -EINVAL; + } + + /* Set fast-charge mode charging current */ + if (chg->fast_uamp < RT5033_CHARGER_FAST_CURRENT_MIN || + chg->fast_uamp > RT5033_CHARGER_FAST_CURRENT_MAX) { + dev_err(charger->dev, + "Value 'constant-charge-current-max-microamp' out of range\n"); + return -EINVAL; + } + + if (chg->fast_uamp == RT5033_CHARGER_FAST_CURRENT_MIN) + reg_data = 0x00; + else if (chg->fast_uamp == RT5033_CHARGER_FAST_CURRENT_MAX) + reg_data = RT5033_CHG_MAX_CURRENT; + else { + val = chg->fast_uamp; + val -= RT5033_CHARGER_FAST_CURRENT_MIN; + val /= RT5033_CHARGER_FAST_CURRENT_STEP_NUM; + reg_data = val; + } + + ret = regmap_update_bits(charger->regmap, RT5033_REG_CHG_CTRL5, + RT5033_CHGCTRL5_ICHG_MASK, + reg_data << RT5033_CHGCTRL5_ICHG_SHIFT); + if (ret) { + dev_err(charger->dev, "Failed regmap update\n"); + return -EINVAL; + } + + return 0; +} + +static inline int rt5033_init_pre_charge(struct rt5033_charger *charger) +{ + struct rt5033_charger_data *chg = charger->chg; + int ret; + unsigned int val; + u8 reg_data; + + /* Set pre-charge threshold voltage */ + if (chg->pre_uvolt < RT5033_CHARGER_PRE_THRESHOLD_LIMIT_MIN || + chg->pre_uvolt > RT5033_CHARGER_PRE_THRESHOLD_LIMIT_MAX) { + dev_err(charger->dev, + "Value 'precharge-upper-limit-microvolt' out of range\n"); + return -EINVAL; + } + + if (chg->pre_uvolt == RT5033_CHARGER_PRE_THRESHOLD_LIMIT_MIN) + reg_data = 0x00; + else if (chg->pre_uvolt == RT5033_CHARGER_PRE_THRESHOLD_LIMIT_MAX) + reg_data = 0x0f; + else { + val = chg->pre_uvolt; + val -= RT5033_CHARGER_PRE_THRESHOLD_LIMIT_MIN; + val /= RT5033_CHARGER_PRE_THRESHOLD_STEP_NUM; + reg_data = val; + } + + ret = regmap_update_bits(charger->regmap, RT5033_REG_CHG_CTRL5, + RT5033_CHGCTRL5_VPREC_MASK, reg_data); + if (ret) { + dev_err(charger->dev, "Failed regmap update\n"); + return -EINVAL; + } + + /* Set pre-charge mode charging current */ + if (chg->pre_uamp < RT5033_CHARGER_PRE_CURRENT_LIMIT_MIN || + chg->pre_uamp > RT5033_CHARGER_PRE_CURRENT_LIMIT_MAX) { + dev_err(charger->dev, + "Value 'precharge-current-microamp' out of range\n"); + return -EINVAL; + } + + if (chg->pre_uamp == RT5033_CHARGER_PRE_CURRENT_LIMIT_MIN) + reg_data = 0x00; + else if (chg->pre_uamp == RT5033_CHARGER_PRE_CURRENT_LIMIT_MAX) + reg_data = RT5033_CHG_MAX_PRE_CURRENT; + else { + val = chg->pre_uamp; + val -= RT5033_CHARGER_PRE_CURRENT_LIMIT_MIN; + val /= RT5033_CHARGER_PRE_CURRENT_STEP_NUM; + reg_data = val; + } + + ret = regmap_update_bits(charger->regmap, RT5033_REG_CHG_CTRL4, + RT5033_CHGCTRL4_IPREC_MASK, + reg_data << RT5033_CHGCTRL4_IPREC_SHIFT); + if (ret) { + dev_err(charger->dev, "Failed regmap update\n"); + return -EINVAL; + } + + return 0; +} + +static int rt5033_charger_reg_init(struct rt5033_charger *charger) +{ + int ret = 0; + + /* Enable charging termination */ + ret = regmap_update_bits(charger->regmap, RT5033_REG_CHG_CTRL1, + RT5033_CHGCTRL1_TE_EN_MASK, RT5033_TE_ENABLE); + if (ret) { + dev_err(charger->dev, "Failed to enable charging termination.\n"); + return -EINVAL; + } + + /* + * Disable minimum input voltage regulation (MIVR), this improves + * the charging performance. + */ + ret = regmap_update_bits(charger->regmap, RT5033_REG_CHG_CTRL4, + RT5033_CHGCTRL4_MIVR_MASK, RT5033_CHARGER_MIVR_DISABLE); + if (ret) { + dev_err(charger->dev, "Failed to disable MIVR.\n"); + return -EINVAL; + } + + ret = rt5033_init_pre_charge(charger); + if (ret) + return ret; + + ret = rt5033_init_fast_charge(charger); + if (ret) + return ret; + + ret = rt5033_init_const_charge(charger); + if (ret) + return ret; + + return 0; +} + +static enum power_supply_property rt5033_charger_props[] = { + POWER_SUPPLY_PROP_STATUS, + POWER_SUPPLY_PROP_CHARGE_TYPE, + POWER_SUPPLY_PROP_CURRENT_MAX, + POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE, + POWER_SUPPLY_PROP_MODEL_NAME, + POWER_SUPPLY_PROP_MANUFACTURER, + POWER_SUPPLY_PROP_ONLINE, +}; + +static int rt5033_charger_get_property(struct power_supply *psy, + enum power_supply_property psp, + union power_supply_propval *val) +{ + struct rt5033_charger *charger = power_supply_get_drvdata(psy); + + switch (psp) { + case POWER_SUPPLY_PROP_STATUS: + val->intval = rt5033_get_charger_state(charger); + break; + case POWER_SUPPLY_PROP_CHARGE_TYPE: + val->intval = rt5033_get_charger_type(charger); + break; + case POWER_SUPPLY_PROP_CURRENT_MAX: + val->intval = rt5033_get_charger_current_limit(charger); + break; + case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE: + val->intval = rt5033_get_charger_const_voltage(charger); + break; + case POWER_SUPPLY_PROP_MODEL_NAME: + val->strval = RT5033_CHARGER_MODEL; + break; + case POWER_SUPPLY_PROP_MANUFACTURER: + val->strval = RT5033_MANUFACTURER; + break; + case POWER_SUPPLY_PROP_ONLINE: + val->intval = (rt5033_get_charger_state(charger) == + POWER_SUPPLY_STATUS_CHARGING); + break; + default: + return -EINVAL; + } + + return 0; +} + +static struct rt5033_charger_data *rt5033_charger_dt_init( + struct rt5033_charger *charger) +{ + struct rt5033_charger_data *chg; + struct power_supply_battery_info *info; + int ret; + + chg = devm_kzalloc(charger->dev, sizeof(*chg), GFP_KERNEL); + if (!chg) + return ERR_PTR(-ENOMEM); + + ret = power_supply_get_battery_info(charger->psy, &info); + if (ret) + return ERR_PTR(dev_err_probe(charger->dev, -EINVAL, + "missing battery info\n")); + + /* Assign data. Validity will be checked in the init functions. */ + chg->pre_uamp = info->precharge_current_ua; + chg->fast_uamp = info->constant_charge_current_max_ua; + chg->eoc_uamp = info->charge_term_current_ua; + chg->pre_uvolt = info->precharge_voltage_max_uv; + chg->const_uvolt = info->constant_charge_voltage_max_uv; + + return chg; +} + +static const struct power_supply_desc rt5033_charger_desc = { + .name = "rt5033-charger", + .type = POWER_SUPPLY_TYPE_USB, + .properties = rt5033_charger_props, + .num_properties = ARRAY_SIZE(rt5033_charger_props), + .get_property = rt5033_charger_get_property, +}; + +static int rt5033_charger_probe(struct platform_device *pdev) +{ + struct rt5033_charger *charger; + struct power_supply_config psy_cfg = {}; + int ret; + + charger = devm_kzalloc(&pdev->dev, sizeof(*charger), GFP_KERNEL); + if (!charger) + return -ENOMEM; + + platform_set_drvdata(pdev, charger); + charger->dev = &pdev->dev; + charger->regmap = dev_get_regmap(pdev->dev.parent, NULL); + + psy_cfg.of_node = pdev->dev.of_node; + psy_cfg.drv_data = charger; + + charger->psy = devm_power_supply_register(&pdev->dev, + &rt5033_charger_desc, + &psy_cfg); + if (IS_ERR(charger->psy)) + return dev_err_probe(&pdev->dev, PTR_ERR(charger->psy), + "Failed to register power supply\n"); + + charger->chg = rt5033_charger_dt_init(charger); + if (IS_ERR_OR_NULL(charger->chg)) + return PTR_ERR(charger->chg); + + ret = rt5033_charger_reg_init(charger); + if (ret) + return ret; + + return 0; +} + +static const struct platform_device_id rt5033_charger_id[] = { + { "rt5033-charger", }, + { } +}; +MODULE_DEVICE_TABLE(platform, rt5033_charger_id); + +static const struct of_device_id rt5033_charger_of_match[] = { + { .compatible = "richtek,rt5033-charger", }, + { } +}; +MODULE_DEVICE_TABLE(of, rt5033_charger_of_match); + +static struct platform_driver rt5033_charger_driver = { + .driver = { + .name = "rt5033-charger", + .of_match_table = rt5033_charger_of_match, + }, + .probe = rt5033_charger_probe, + .id_table = rt5033_charger_id, +}; +module_platform_driver(rt5033_charger_driver); + +MODULE_DESCRIPTION("Richtek RT5033 charger driver"); +MODULE_AUTHOR("Beomho Seo "); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 2c2405024ace..08d33290296b 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -556,6 +556,17 @@ config REGULATOR_MAX597X The MAX5970/5978 is a smart switch with no output regulation, but fault protection and voltage and current monitoring capabilities. +config REGULATOR_MAX77541 + tristate "Analog Devices MAX77541/77540 Regulator" + depends on MFD_MAX77541 + help + This driver controls a Analog Devices MAX77541/77540 regulators + via I2C bus. Both MAX77540 and MAX77541 are dual-phase + high-efficiency buck converter. Say Y here to + enable the regulator driver. + Say M here if you want to include support for the regulator as a + module. + config REGULATOR_MAX77620 tristate "Maxim 77620/MAX20024 voltage regulator" depends on MFD_MAX77620 || COMPILE_TEST diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index ebfa75379c20..15e0d614ff66 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -68,6 +68,7 @@ obj-$(CONFIG_REGULATOR_LTC3676) += ltc3676.o obj-$(CONFIG_REGULATOR_MAX14577) += max14577-regulator.o obj-$(CONFIG_REGULATOR_MAX1586) += max1586.o obj-$(CONFIG_REGULATOR_MAX597X) += max597x-regulator.o +obj-$(CONFIG_REGULATOR_MAX77541) += max77541-regulator.o obj-$(CONFIG_REGULATOR_MAX77620) += max77620-regulator.o obj-$(CONFIG_REGULATOR_MAX77650) += max77650-regulator.o obj-$(CONFIG_REGULATOR_MAX8649) += max8649.o diff --git a/drivers/regulator/max77541-regulator.c b/drivers/regulator/max77541-regulator.c new file mode 100644 index 000000000000..2976f9cb3e26 --- /dev/null +++ b/drivers/regulator/max77541-regulator.c @@ -0,0 +1,153 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2022 Analog Devices, Inc. + * ADI Regulator driver for the MAX77540 and MAX77541 + */ + +#include +#include +#include +#include +#include + +static const struct regulator_ops max77541_buck_ops = { + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, + .list_voltage = regulator_list_voltage_pickable_linear_range, + .get_voltage_sel = regulator_get_voltage_sel_pickable_regmap, + .set_voltage_sel = regulator_set_voltage_sel_pickable_regmap, +}; + +static const struct linear_range max77540_buck_ranges[] = { + /* Ranges when VOLT_SEL bits are 0x00 */ + REGULATOR_LINEAR_RANGE(500000, 0x00, 0x8B, 5000), + REGULATOR_LINEAR_RANGE(1200000, 0x8C, 0xFF, 0), + /* Ranges when VOLT_SEL bits are 0x40 */ + REGULATOR_LINEAR_RANGE(1200000, 0x00, 0x8B, 10000), + REGULATOR_LINEAR_RANGE(2400000, 0x8C, 0xFF, 0), + /* Ranges when VOLT_SEL bits are 0x80 */ + REGULATOR_LINEAR_RANGE(2000000, 0x00, 0x9F, 20000), + REGULATOR_LINEAR_RANGE(5200000, 0xA0, 0xFF, 0), +}; + +static const struct linear_range max77541_buck_ranges[] = { + /* Ranges when VOLT_SEL bits are 0x00 */ + REGULATOR_LINEAR_RANGE(300000, 0x00, 0xB3, 5000), + REGULATOR_LINEAR_RANGE(1200000, 0xB4, 0xFF, 0), + /* Ranges when VOLT_SEL bits are 0x40 */ + REGULATOR_LINEAR_RANGE(1200000, 0x00, 0x8B, 10000), + REGULATOR_LINEAR_RANGE(2400000, 0x8C, 0xFF, 0), + /* Ranges when VOLT_SEL bits are 0x80 */ + REGULATOR_LINEAR_RANGE(2000000, 0x00, 0x9F, 20000), + REGULATOR_LINEAR_RANGE(5200000, 0xA0, 0xFF, 0), +}; + +static const unsigned int max77541_buck_volt_range_sel[] = { + 0x00, 0x00, 0x40, 0x40, 0x80, 0x80, +}; + +enum max77541_regulators { + MAX77541_BUCK1 = 1, + MAX77541_BUCK2, +}; + +#define MAX77540_BUCK(_id, _ops) \ + { .id = MAX77541_BUCK ## _id, \ + .name = "buck"#_id, \ + .of_match = "buck"#_id, \ + .regulators_node = "regulators", \ + .enable_reg = MAX77541_REG_EN_CTRL, \ + .enable_mask = MAX77541_BIT_M ## _id ## _EN, \ + .ops = &(_ops), \ + .type = REGULATOR_VOLTAGE, \ + .linear_ranges = max77540_buck_ranges, \ + .n_linear_ranges = ARRAY_SIZE(max77540_buck_ranges), \ + .vsel_reg = MAX77541_REG_M ## _id ## _VOUT, \ + .vsel_mask = MAX77541_BITS_MX_VOUT, \ + .vsel_range_reg = MAX77541_REG_M ## _id ## _CFG1, \ + .vsel_range_mask = MAX77541_BITS_MX_CFG1_RNG, \ + .linear_range_selectors = max77541_buck_volt_range_sel, \ + .owner = THIS_MODULE, \ + } + +#define MAX77541_BUCK(_id, _ops) \ + { .id = MAX77541_BUCK ## _id, \ + .name = "buck"#_id, \ + .of_match = "buck"#_id, \ + .regulators_node = "regulators", \ + .enable_reg = MAX77541_REG_EN_CTRL, \ + .enable_mask = MAX77541_BIT_M ## _id ## _EN, \ + .ops = &(_ops), \ + .type = REGULATOR_VOLTAGE, \ + .linear_ranges = max77541_buck_ranges, \ + .n_linear_ranges = ARRAY_SIZE(max77541_buck_ranges), \ + .vsel_reg = MAX77541_REG_M ## _id ## _VOUT, \ + .vsel_mask = MAX77541_BITS_MX_VOUT, \ + .vsel_range_reg = MAX77541_REG_M ## _id ## _CFG1, \ + .vsel_range_mask = MAX77541_BITS_MX_CFG1_RNG, \ + .linear_range_selectors = max77541_buck_volt_range_sel, \ + .owner = THIS_MODULE, \ + } + +static const struct regulator_desc max77540_regulators_desc[] = { + MAX77540_BUCK(1, max77541_buck_ops), + MAX77540_BUCK(2, max77541_buck_ops), +}; + +static const struct regulator_desc max77541_regulators_desc[] = { + MAX77541_BUCK(1, max77541_buck_ops), + MAX77541_BUCK(2, max77541_buck_ops), +}; + +static int max77541_regulator_probe(struct platform_device *pdev) +{ + struct regulator_config config = {}; + const struct regulator_desc *desc; + struct device *dev = &pdev->dev; + struct regulator_dev *rdev; + struct max77541 *max77541 = dev_get_drvdata(dev->parent); + unsigned int i; + + config.dev = dev->parent; + + switch (max77541->id) { + case MAX77540: + desc = max77540_regulators_desc; + break; + case MAX77541: + desc = max77541_regulators_desc; + break; + default: + return -EINVAL; + } + + for (i = 0; i < MAX77541_MAX_REGULATORS; i++) { + rdev = devm_regulator_register(dev, &desc[i], &config); + if (IS_ERR(rdev)) + return dev_err_probe(dev, PTR_ERR(rdev), + "Failed to register regulator\n"); + } + + return 0; +} + +static const struct platform_device_id max77541_regulator_platform_id[] = { + { "max77540-regulator" }, + { "max77541-regulator" }, + { } +}; +MODULE_DEVICE_TABLE(platform, max77541_regulator_platform_id); + +static struct platform_driver max77541_regulator_driver = { + .driver = { + .name = "max77541-regulator", + }, + .probe = max77541_regulator_probe, + .id_table = max77541_regulator_platform_id, +}; +module_platform_driver(max77541_regulator_driver); + +MODULE_AUTHOR("Okan Sahin "); +MODULE_DESCRIPTION("MAX77540/MAX77541 regulator driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index ffca9a8bb878..05f4b2d66290 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -956,6 +956,7 @@ comment "Platform RTC drivers" config RTC_DRV_CMOS tristate "PC-style 'CMOS'" depends on X86 || ARM || PPC || MIPS || SPARC64 + depends on HAS_IOPORT || MACH_DECSTATION default y if X86 select RTC_MC146818_LIB help @@ -976,6 +977,7 @@ config RTC_DRV_CMOS config RTC_DRV_ALPHA bool "Alpha PC-style CMOS" depends on ALPHA + depends on HAS_IOPORT select RTC_MC146818_LIB default y help @@ -1193,7 +1195,7 @@ config RTC_DRV_MSM6242 config RTC_DRV_BQ4802 tristate "TI BQ4802" - depends on HAS_IOMEM + depends on HAS_IOMEM && HAS_IOPORT help If you say Y here you will get support for the TI BQ4802 RTC chip. @@ -1685,6 +1687,19 @@ config RTC_DRV_JZ4740 This driver can also be built as a module. If so, the module will be called rtc-jz4740. +config RTC_DRV_LOONGSON + tristate "Loongson On-chip RTC" + depends on MACH_LOONGSON32 || MACH_LOONGSON64 || COMPILE_TEST + select REGMAP_MMIO + help + This is a driver for the Loongson on-chip Counter0 (Time-Of-Year + counter) to be used as a RTC. + It can be found on Loongson-1 series cpu, Loongson-2K series cpu + and Loongson LS7A bridge chips. + + This driver can also be built as a module. If so, the module + will be called rtc-loongson. + config RTC_DRV_LPC24XX tristate "NXP RTC for LPC178x/18xx/408x/43xx" depends on ARCH_LPC18XX || COMPILE_TEST @@ -1726,16 +1741,6 @@ config RTC_DRV_TEGRA This drive can also be built as a module. If so, the module will be called rtc-tegra. -config RTC_DRV_LOONGSON1 - tristate "loongson1 RTC support" - depends on MACH_LOONGSON32 - help - This is a driver for the loongson1 on-chip Counter0 (Time-Of-Year - counter) to be used as a RTC. - - This driver can also be built as a module. If so, the module - will be called rtc-ls1x. - config RTC_DRV_MXC tristate "Freescale MXC Real Time Clock" depends on ARCH_MXC || COMPILE_TEST diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index ea445d1ebb17..fd209883ee2e 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -78,7 +78,7 @@ obj-$(CONFIG_RTC_DRV_ISL12022) += rtc-isl12022.o obj-$(CONFIG_RTC_DRV_ISL12026) += rtc-isl12026.o obj-$(CONFIG_RTC_DRV_ISL1208) += rtc-isl1208.o obj-$(CONFIG_RTC_DRV_JZ4740) += rtc-jz4740.o -obj-$(CONFIG_RTC_DRV_LOONGSON1) += rtc-ls1x.o +obj-$(CONFIG_RTC_DRV_LOONGSON) += rtc-loongson.o obj-$(CONFIG_RTC_DRV_LP8788) += rtc-lp8788.o obj-$(CONFIG_RTC_DRV_LPC24XX) += rtc-lpc24xx.o obj-$(CONFIG_RTC_DRV_LPC32XX) += rtc-lpc32xx.o diff --git a/drivers/rtc/rtc-ab-b5ze-s3.c b/drivers/rtc/rtc-ab-b5ze-s3.c index f2b0971d2c65..100062001831 100644 --- a/drivers/rtc/rtc-ab-b5ze-s3.c +++ b/drivers/rtc/rtc-ab-b5ze-s3.c @@ -944,7 +944,7 @@ static struct i2c_driver abb5zes3_driver = { .pm = &abb5zes3_rtc_pm_ops, .of_match_table = of_match_ptr(abb5zes3_dt_match), }, - .probe_new = abb5zes3_probe, + .probe = abb5zes3_probe, .id_table = abb5zes3_id, }; module_i2c_driver(abb5zes3_driver); diff --git a/drivers/rtc/rtc-ab-eoz9.c b/drivers/rtc/rtc-ab-eoz9.c index 34611f6dedcb..04e1b8e93bc1 100644 --- a/drivers/rtc/rtc-ab-eoz9.c +++ b/drivers/rtc/rtc-ab-eoz9.c @@ -455,7 +455,7 @@ static const struct hwmon_channel_info abeoz9_temp = { .config = abeoz9_temp_config, }; -static const struct hwmon_channel_info *abeoz9_info[] = { +static const struct hwmon_channel_info * const abeoz9_info[] = { &abeoz9_chip, &abeoz9_temp, NULL @@ -584,7 +584,7 @@ static struct i2c_driver abeoz9_driver = { .name = "rtc-ab-eoz9", .of_match_table = of_match_ptr(abeoz9_dt_match), }, - .probe_new = abeoz9_probe, + .probe = abeoz9_probe, .id_table = abeoz9_id, }; diff --git a/drivers/rtc/rtc-abx80x.c b/drivers/rtc/rtc-abx80x.c index f34a2e59cac7..e08d3181bd2a 100644 --- a/drivers/rtc/rtc-abx80x.c +++ b/drivers/rtc/rtc-abx80x.c @@ -992,7 +992,7 @@ static struct i2c_driver abx80x_driver = { .name = "rtc-abx80x", .of_match_table = of_match_ptr(abx80x_of_match), }, - .probe_new = abx80x_probe, + .probe = abx80x_probe, .id_table = abx80x_id, }; diff --git a/drivers/rtc/rtc-bq32k.c b/drivers/rtc/rtc-bq32k.c index 967ddc6bf76d..591e42391747 100644 --- a/drivers/rtc/rtc-bq32k.c +++ b/drivers/rtc/rtc-bq32k.c @@ -320,7 +320,7 @@ static struct i2c_driver bq32k_driver = { .name = "bq32k", .of_match_table = of_match_ptr(bq32k_of_match), }, - .probe_new = bq32k_probe, + .probe = bq32k_probe, .remove = bq32k_remove, .id_table = bq32k_id, }; diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index e86ba84df6cb..cb5acecc11aa 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c @@ -2011,7 +2011,7 @@ static struct i2c_driver ds1307_driver = { .name = "rtc-ds1307", .of_match_table = ds1307_of_match, }, - .probe_new = ds1307_probe, + .probe = ds1307_probe, .id_table = ds1307_id, }; diff --git a/drivers/rtc/rtc-ds1374.c b/drivers/rtc/rtc-ds1374.c index 7f089f066163..4a5005cb23f5 100644 --- a/drivers/rtc/rtc-ds1374.c +++ b/drivers/rtc/rtc-ds1374.c @@ -572,7 +572,7 @@ static struct i2c_driver ds1374_driver = { .of_match_table = of_match_ptr(ds1374_of_match), .pm = &ds1374_pm, }, - .probe_new = ds1374_probe, + .probe = ds1374_probe, .remove = ds1374_remove, .id_table = ds1374_id, }; diff --git a/drivers/rtc/rtc-ds1672.c b/drivers/rtc/rtc-ds1672.c index a3bb2cd9c881..641799f30baa 100644 --- a/drivers/rtc/rtc-ds1672.c +++ b/drivers/rtc/rtc-ds1672.c @@ -149,7 +149,7 @@ static struct i2c_driver ds1672_driver = { .name = "rtc-ds1672", .of_match_table = of_match_ptr(ds1672_of_match), }, - .probe_new = ds1672_probe, + .probe = ds1672_probe, .id_table = ds1672_id, }; diff --git a/drivers/rtc/rtc-ds3232.c b/drivers/rtc/rtc-ds3232.c index dd31a60c1fc6..89d7b085f721 100644 --- a/drivers/rtc/rtc-ds3232.c +++ b/drivers/rtc/rtc-ds3232.c @@ -359,7 +359,7 @@ static const struct hwmon_channel_info ds3232_hwmon_temp = { .config = ds3232_hwmon_temp_config, }; -static const struct hwmon_channel_info *ds3232_hwmon_info[] = { +static const struct hwmon_channel_info * const ds3232_hwmon_info[] = { &ds3232_hwmon_chip, &ds3232_hwmon_temp, NULL @@ -603,7 +603,7 @@ static struct i2c_driver ds3232_driver = { .of_match_table = of_match_ptr(ds3232_of_match), .pm = &ds3232_pm_ops, }, - .probe_new = ds3232_i2c_probe, + .probe = ds3232_i2c_probe, .id_table = ds3232_id, }; diff --git a/drivers/rtc/rtc-em3027.c b/drivers/rtc/rtc-em3027.c index 53f9f9391a5f..fc772eae5da5 100644 --- a/drivers/rtc/rtc-em3027.c +++ b/drivers/rtc/rtc-em3027.c @@ -147,7 +147,7 @@ static struct i2c_driver em3027_driver = { .name = "rtc-em3027", .of_match_table = of_match_ptr(em3027_of_match), }, - .probe_new = em3027_probe, + .probe = em3027_probe, .id_table = em3027_id, }; diff --git a/drivers/rtc/rtc-fm3130.c b/drivers/rtc/rtc-fm3130.c index f59bb81f23c0..400ce4ad0c49 100644 --- a/drivers/rtc/rtc-fm3130.c +++ b/drivers/rtc/rtc-fm3130.c @@ -517,7 +517,7 @@ static struct i2c_driver fm3130_driver = { .driver = { .name = "rtc-fm3130", }, - .probe_new = fm3130_probe, + .probe = fm3130_probe, .id_table = fm3130_id, }; diff --git a/drivers/rtc/rtc-hym8563.c b/drivers/rtc/rtc-hym8563.c index 7d5a298a9a3b..b018535c842b 100644 --- a/drivers/rtc/rtc-hym8563.c +++ b/drivers/rtc/rtc-hym8563.c @@ -576,7 +576,7 @@ static struct i2c_driver hym8563_driver = { .pm = &hym8563_pm_ops, .of_match_table = hym8563_dt_idtable, }, - .probe_new = hym8563_probe, + .probe = hym8563_probe, .id_table = hym8563_id, }; diff --git a/drivers/rtc/rtc-isl12022.c b/drivers/rtc/rtc-isl12022.c index e68a79b5e00e..a613257d1574 100644 --- a/drivers/rtc/rtc-isl12022.c +++ b/drivers/rtc/rtc-isl12022.c @@ -89,7 +89,7 @@ static int isl12022_hwmon_read(struct device *dev, return -EOPNOTSUPP; } -static const struct hwmon_channel_info *isl12022_hwmon_info[] = { +static const struct hwmon_channel_info * const isl12022_hwmon_info[] = { HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT), NULL }; @@ -262,7 +262,7 @@ static struct i2c_driver isl12022_driver = { .name = "rtc-isl12022", .of_match_table = isl12022_dt_match, }, - .probe_new = isl12022_probe, + .probe = isl12022_probe, .id_table = isl12022_id, }; diff --git a/drivers/rtc/rtc-isl12026.c b/drivers/rtc/rtc-isl12026.c index 1bfca39079d4..5abff5d348ac 100644 --- a/drivers/rtc/rtc-isl12026.c +++ b/drivers/rtc/rtc-isl12026.c @@ -490,7 +490,7 @@ static struct i2c_driver isl12026_driver = { .name = "rtc-isl12026", .of_match_table = isl12026_dt_match, }, - .probe_new = isl12026_probe_new, + .probe = isl12026_probe_new, .remove = isl12026_remove, }; diff --git a/drivers/rtc/rtc-isl1208.c b/drivers/rtc/rtc-isl1208.c index 73cc6aaf9b8b..b0712b4e3648 100644 --- a/drivers/rtc/rtc-isl1208.c +++ b/drivers/rtc/rtc-isl1208.c @@ -6,6 +6,7 @@ */ #include +#include #include #include #include @@ -68,42 +69,60 @@ static struct i2c_driver isl1208_driver; -/* ISL1208 various variants */ -enum isl1208_id { - TYPE_ISL1208 = 0, - TYPE_ISL1209, - TYPE_ISL1218, - TYPE_ISL1219, - ISL_LAST_ID -}; - /* Chip capabilities table */ -static const struct isl1208_config { - const char name[8]; +struct isl1208_config { unsigned int nvmem_length; unsigned has_tamper:1; unsigned has_timestamp:1; -} isl1208_configs[] = { - [TYPE_ISL1208] = { "isl1208", 2, false, false }, - [TYPE_ISL1209] = { "isl1209", 2, true, false }, - [TYPE_ISL1218] = { "isl1218", 8, false, false }, - [TYPE_ISL1219] = { "isl1219", 2, true, true }, + unsigned has_inverted_osc_bit:1; +}; + +static const struct isl1208_config config_isl1208 = { + .nvmem_length = 2, + .has_tamper = false, + .has_timestamp = false +}; + +static const struct isl1208_config config_isl1209 = { + .nvmem_length = 2, + .has_tamper = true, + .has_timestamp = false +}; + +static const struct isl1208_config config_isl1218 = { + .nvmem_length = 8, + .has_tamper = false, + .has_timestamp = false +}; + +static const struct isl1208_config config_isl1219 = { + .nvmem_length = 2, + .has_tamper = true, + .has_timestamp = true +}; + +static const struct isl1208_config config_raa215300_a0 = { + .nvmem_length = 2, + .has_tamper = false, + .has_timestamp = false, + .has_inverted_osc_bit = true }; static const struct i2c_device_id isl1208_id[] = { - { "isl1208", TYPE_ISL1208 }, - { "isl1209", TYPE_ISL1209 }, - { "isl1218", TYPE_ISL1218 }, - { "isl1219", TYPE_ISL1219 }, + { "isl1208", .driver_data = (kernel_ulong_t)&config_isl1208 }, + { "isl1209", .driver_data = (kernel_ulong_t)&config_isl1209 }, + { "isl1218", .driver_data = (kernel_ulong_t)&config_isl1218 }, + { "isl1219", .driver_data = (kernel_ulong_t)&config_isl1219 }, + { "raa215300_a0", .driver_data = (kernel_ulong_t)&config_raa215300_a0 }, { } }; MODULE_DEVICE_TABLE(i2c, isl1208_id); static const __maybe_unused struct of_device_id isl1208_of_match[] = { - { .compatible = "isil,isl1208", .data = &isl1208_configs[TYPE_ISL1208] }, - { .compatible = "isil,isl1209", .data = &isl1208_configs[TYPE_ISL1209] }, - { .compatible = "isil,isl1218", .data = &isl1208_configs[TYPE_ISL1218] }, - { .compatible = "isil,isl1219", .data = &isl1208_configs[TYPE_ISL1219] }, + { .compatible = "isil,isl1208", .data = &config_isl1208 }, + { .compatible = "isil,isl1209", .data = &config_isl1209 }, + { .compatible = "isil,isl1218", .data = &config_isl1218 }, + { .compatible = "isil,isl1219", .data = &config_isl1219 }, { } }; MODULE_DEVICE_TABLE(of, isl1208_of_match); @@ -166,6 +185,20 @@ isl1208_i2c_validate_client(struct i2c_client *client) return 0; } +static int isl1208_set_xtoscb(struct i2c_client *client, int sr, int xtosb_val) +{ + /* Do nothing if bit is already set to desired value */ + if ((sr & ISL1208_REG_SR_XTOSCB) == xtosb_val) + return 0; + + if (xtosb_val) + sr |= ISL1208_REG_SR_XTOSCB; + else + sr &= ~ISL1208_REG_SR_XTOSCB; + + return i2c_smbus_write_byte_data(client, ISL1208_REG_SR, sr); +} + static int isl1208_i2c_get_sr(struct i2c_client *client) { @@ -502,7 +535,6 @@ isl1208_i2c_set_time(struct i2c_client *client, struct rtc_time const *tm) return 0; } - static int isl1208_rtc_set_time(struct device *dev, struct rtc_time *tm) { @@ -796,12 +828,26 @@ static int isl1208_setup_irq(struct i2c_client *client, int irq) return rc; } +static int +isl1208_clk_present(struct i2c_client *client, const char *name) +{ + struct clk *clk; + + clk = devm_clk_get_optional(&client->dev, name); + if (IS_ERR(clk)) + return PTR_ERR(clk); + + return !!clk; +} + static int isl1208_probe(struct i2c_client *client) { - int rc = 0; struct isl1208_state *isl1208; int evdet_irq = -1; + int xtosb_val = 0; + int rc = 0; + int sr; if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) return -ENODEV; @@ -823,9 +869,22 @@ isl1208_probe(struct i2c_client *client) } else { const struct i2c_device_id *id = i2c_match_id(isl1208_id, client); - if (id->driver_data >= ISL_LAST_ID) + if (!id) return -ENODEV; - isl1208->config = &isl1208_configs[id->driver_data]; + isl1208->config = (struct isl1208_config *)id->driver_data; + } + + rc = isl1208_clk_present(client, "xin"); + if (rc < 0) + return rc; + + if (!rc) { + rc = isl1208_clk_present(client, "clkin"); + if (rc < 0) + return rc; + + if (rc) + xtosb_val = 1; } isl1208->rtc = devm_rtc_allocate_device(&client->dev); @@ -839,13 +898,20 @@ isl1208_probe(struct i2c_client *client) isl1208->nvmem_config.size = isl1208->config->nvmem_length; isl1208->nvmem_config.priv = isl1208; - rc = isl1208_i2c_get_sr(client); - if (rc < 0) { + sr = isl1208_i2c_get_sr(client); + if (sr < 0) { dev_err(&client->dev, "reading status failed\n"); - return rc; + return sr; } - if (rc & ISL1208_REG_SR_RTCF) + if (isl1208->config->has_inverted_osc_bit) + xtosb_val = !xtosb_val; + + rc = isl1208_set_xtoscb(client, sr, xtosb_val); + if (rc) + return rc; + + if (sr & ISL1208_REG_SR_RTCF) dev_warn(&client->dev, "rtc power failure detected, " "please set clock.\n"); @@ -908,7 +974,7 @@ static struct i2c_driver isl1208_driver = { .name = "rtc-isl1208", .of_match_table = of_match_ptr(isl1208_of_match), }, - .probe_new = isl1208_probe, + .probe = isl1208_probe, .id_table = isl1208_id, }; diff --git a/drivers/rtc/rtc-loongson.c b/drivers/rtc/rtc-loongson.c new file mode 100644 index 000000000000..e8ffc1ab90b0 --- /dev/null +++ b/drivers/rtc/rtc-loongson.c @@ -0,0 +1,397 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Loongson RTC driver + * + * Maintained out-of-tree by Huacai Chen . + * Rewritten for mainline by WANG Xuerui . + * Binbin Zhou + */ + +#include +#include +#include +#include +#include +#include +#include + +/* Time Of Year(TOY) counters registers */ +#define TOY_TRIM_REG 0x20 /* Must be initialized to 0 */ +#define TOY_WRITE0_REG 0x24 /* TOY low 32-bits value (write-only) */ +#define TOY_WRITE1_REG 0x28 /* TOY high 32-bits value (write-only) */ +#define TOY_READ0_REG 0x2c /* TOY low 32-bits value (read-only) */ +#define TOY_READ1_REG 0x30 /* TOY high 32-bits value (read-only) */ +#define TOY_MATCH0_REG 0x34 /* TOY timing interrupt 0 */ +#define TOY_MATCH1_REG 0x38 /* TOY timing interrupt 1 */ +#define TOY_MATCH2_REG 0x3c /* TOY timing interrupt 2 */ + +/* RTC counters registers */ +#define RTC_CTRL_REG 0x40 /* TOY and RTC control register */ +#define RTC_TRIM_REG 0x60 /* Must be initialized to 0 */ +#define RTC_WRITE0_REG 0x64 /* RTC counters value (write-only) */ +#define RTC_READ0_REG 0x68 /* RTC counters value (read-only) */ +#define RTC_MATCH0_REG 0x6c /* RTC timing interrupt 0 */ +#define RTC_MATCH1_REG 0x70 /* RTC timing interrupt 1 */ +#define RTC_MATCH2_REG 0x74 /* RTC timing interrupt 2 */ + +/* bitmask of TOY_WRITE0_REG */ +#define TOY_MON GENMASK(31, 26) +#define TOY_DAY GENMASK(25, 21) +#define TOY_HOUR GENMASK(20, 16) +#define TOY_MIN GENMASK(15, 10) +#define TOY_SEC GENMASK(9, 4) +#define TOY_MSEC GENMASK(3, 0) + +/* bitmask of TOY_MATCH0/1/2_REG */ +#define TOY_MATCH_YEAR GENMASK(31, 26) +#define TOY_MATCH_MON GENMASK(25, 22) +#define TOY_MATCH_DAY GENMASK(21, 17) +#define TOY_MATCH_HOUR GENMASK(16, 12) +#define TOY_MATCH_MIN GENMASK(11, 6) +#define TOY_MATCH_SEC GENMASK(5, 0) + +/* bitmask of RTC_CTRL_REG */ +#define RTC_ENABLE BIT(13) /* 1: RTC counters enable */ +#define TOY_ENABLE BIT(11) /* 1: TOY counters enable */ +#define OSC_ENABLE BIT(8) /* 1: 32.768k crystal enable */ +#define TOY_ENABLE_MASK (TOY_ENABLE | OSC_ENABLE) + +/* PM domain registers */ +#define PM1_STS_REG 0x0c /* Power management 1 status register */ +#define RTC_STS BIT(10) /* RTC status */ +#define PM1_EN_REG 0x10 /* Power management 1 enable register */ +#define RTC_EN BIT(10) /* RTC event enable */ + +/* + * According to the LS1C manual, RTC_CTRL and alarm-related registers are not defined. + * Accessing the relevant registers will cause the system to hang. + */ +#define LS1C_RTC_CTRL_WORKAROUND BIT(0) + +struct loongson_rtc_config { + u32 pm_offset; /* Offset of PM domain, for RTC alarm wakeup */ + u32 flags; /* Workaround bits */ +}; + +struct loongson_rtc_priv { + spinlock_t lock; /* protects PM registers access */ + u32 fix_year; /* RTC alarm year compensation value */ + struct rtc_device *rtcdev; + struct regmap *regmap; + void __iomem *pm_base; /* PM domain base, for RTC alarm wakeup */ + const struct loongson_rtc_config *config; +}; + +static const struct loongson_rtc_config ls1b_rtc_config = { + .pm_offset = 0, + .flags = 0, +}; + +static const struct loongson_rtc_config ls1c_rtc_config = { + .pm_offset = 0, + .flags = LS1C_RTC_CTRL_WORKAROUND, +}; + +static const struct loongson_rtc_config generic_rtc_config = { + .pm_offset = 0x100, + .flags = 0, +}; + +static const struct loongson_rtc_config ls2k1000_rtc_config = { + .pm_offset = 0x800, + .flags = 0, +}; + +static const struct regmap_config loongson_rtc_regmap_config = { + .reg_bits = 32, + .val_bits = 32, + .reg_stride = 4, +}; + +/* RTC alarm irq handler */ +static irqreturn_t loongson_rtc_isr(int irq, void *id) +{ + struct loongson_rtc_priv *priv = (struct loongson_rtc_priv *)id; + + rtc_update_irq(priv->rtcdev, 1, RTC_AF | RTC_IRQF); + return IRQ_HANDLED; +} + +/* For ACPI fixed event handler */ +static u32 loongson_rtc_handler(void *id) +{ + struct loongson_rtc_priv *priv = (struct loongson_rtc_priv *)id; + + spin_lock(&priv->lock); + /* Disable RTC alarm wakeup and interrupt */ + writel(readl(priv->pm_base + PM1_EN_REG) & ~RTC_EN, + priv->pm_base + PM1_EN_REG); + + /* Clear RTC interrupt status */ + writel(RTC_STS, priv->pm_base + PM1_STS_REG); + spin_unlock(&priv->lock); + + /* + * The TOY_MATCH0_REG should be cleared 0 here, + * otherwise the interrupt cannot be cleared. + */ + return regmap_write(priv->regmap, TOY_MATCH0_REG, 0); +} + +static int loongson_rtc_set_enabled(struct device *dev) +{ + struct loongson_rtc_priv *priv = dev_get_drvdata(dev); + + if (priv->config->flags & LS1C_RTC_CTRL_WORKAROUND) + return 0; + + /* Enable RTC TOY counters and crystal */ + return regmap_update_bits(priv->regmap, RTC_CTRL_REG, TOY_ENABLE_MASK, + TOY_ENABLE_MASK); +} + +static bool loongson_rtc_get_enabled(struct device *dev) +{ + int ret; + u32 ctrl_data; + struct loongson_rtc_priv *priv = dev_get_drvdata(dev); + + if (priv->config->flags & LS1C_RTC_CTRL_WORKAROUND) + return true; + + ret = regmap_read(priv->regmap, RTC_CTRL_REG, &ctrl_data); + if (ret < 0) + return false; + + return ctrl_data & TOY_ENABLE_MASK; +} + +static int loongson_rtc_read_time(struct device *dev, struct rtc_time *tm) +{ + int ret; + u32 rtc_data[2]; + struct loongson_rtc_priv *priv = dev_get_drvdata(dev); + + if (!loongson_rtc_get_enabled(dev)) + return -EINVAL; + + ret = regmap_bulk_read(priv->regmap, TOY_READ0_REG, rtc_data, + ARRAY_SIZE(rtc_data)); + if (ret < 0) + return ret; + + tm->tm_sec = FIELD_GET(TOY_SEC, rtc_data[0]); + tm->tm_min = FIELD_GET(TOY_MIN, rtc_data[0]); + tm->tm_hour = FIELD_GET(TOY_HOUR, rtc_data[0]); + tm->tm_mday = FIELD_GET(TOY_DAY, rtc_data[0]); + tm->tm_mon = FIELD_GET(TOY_MON, rtc_data[0]) - 1; + tm->tm_year = rtc_data[1]; + + /* Prepare for RTC alarm year compensation value. */ + priv->fix_year = tm->tm_year / 64 * 64; + return 0; +} + +static int loongson_rtc_set_time(struct device *dev, struct rtc_time *tm) +{ + int ret; + u32 rtc_data[2]; + struct loongson_rtc_priv *priv = dev_get_drvdata(dev); + + rtc_data[0] = FIELD_PREP(TOY_SEC, tm->tm_sec) + | FIELD_PREP(TOY_MIN, tm->tm_min) + | FIELD_PREP(TOY_HOUR, tm->tm_hour) + | FIELD_PREP(TOY_DAY, tm->tm_mday) + | FIELD_PREP(TOY_MON, tm->tm_mon + 1); + rtc_data[1] = tm->tm_year; + + ret = regmap_bulk_write(priv->regmap, TOY_WRITE0_REG, rtc_data, + ARRAY_SIZE(rtc_data)); + if (ret < 0) + return ret; + + return loongson_rtc_set_enabled(dev); +} + +static int loongson_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) +{ + int ret; + u32 alarm_data; + struct loongson_rtc_priv *priv = dev_get_drvdata(dev); + + ret = regmap_read(priv->regmap, TOY_MATCH0_REG, &alarm_data); + if (ret < 0) + return ret; + + alrm->time.tm_sec = FIELD_GET(TOY_MATCH_SEC, alarm_data); + alrm->time.tm_min = FIELD_GET(TOY_MATCH_MIN, alarm_data); + alrm->time.tm_hour = FIELD_GET(TOY_MATCH_HOUR, alarm_data); + alrm->time.tm_mday = FIELD_GET(TOY_MATCH_DAY, alarm_data); + alrm->time.tm_mon = FIELD_GET(TOY_MATCH_MON, alarm_data) - 1; + /* + * This is a hardware bug: the year field of SYS_TOYMATCH is only 6 bits, + * making it impossible to save year values larger than 64. + * + * SYS_TOYMATCH is used to match the alarm time value and determine if + * an alarm is triggered, so we must keep the lower 6 bits of the year + * value constant during the value conversion. + * + * In summary, we need to manually add 64(or a multiple of 64) to the + * year value to avoid the invalid alarm prompt at startup. + */ + alrm->time.tm_year = FIELD_GET(TOY_MATCH_YEAR, alarm_data) + priv->fix_year; + + alrm->enabled = !!(readl(priv->pm_base + PM1_EN_REG) & RTC_EN); + return 0; +} + +static int loongson_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) +{ + u32 val; + struct loongson_rtc_priv *priv = dev_get_drvdata(dev); + + spin_lock(&priv->lock); + val = readl(priv->pm_base + PM1_EN_REG); + /* Enable RTC alarm wakeup */ + writel(enabled ? val | RTC_EN : val & ~RTC_EN, + priv->pm_base + PM1_EN_REG); + spin_unlock(&priv->lock); + + return 0; +} + +static int loongson_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) +{ + int ret; + u32 alarm_data; + struct loongson_rtc_priv *priv = dev_get_drvdata(dev); + + alarm_data = FIELD_PREP(TOY_MATCH_SEC, alrm->time.tm_sec) + | FIELD_PREP(TOY_MATCH_MIN, alrm->time.tm_min) + | FIELD_PREP(TOY_MATCH_HOUR, alrm->time.tm_hour) + | FIELD_PREP(TOY_MATCH_DAY, alrm->time.tm_mday) + | FIELD_PREP(TOY_MATCH_MON, alrm->time.tm_mon + 1) + | FIELD_PREP(TOY_MATCH_YEAR, alrm->time.tm_year - priv->fix_year); + + ret = regmap_write(priv->regmap, TOY_MATCH0_REG, alarm_data); + if (ret < 0) + return ret; + + return loongson_rtc_alarm_irq_enable(dev, alrm->enabled); +} + +static const struct rtc_class_ops loongson_rtc_ops = { + .read_time = loongson_rtc_read_time, + .set_time = loongson_rtc_set_time, + .read_alarm = loongson_rtc_read_alarm, + .set_alarm = loongson_rtc_set_alarm, + .alarm_irq_enable = loongson_rtc_alarm_irq_enable, +}; + +static int loongson_rtc_probe(struct platform_device *pdev) +{ + int ret, alarm_irq; + void __iomem *regs; + struct loongson_rtc_priv *priv; + struct device *dev = &pdev->dev; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + regs = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(regs)) + return dev_err_probe(dev, PTR_ERR(regs), + "devm_platform_ioremap_resource failed\n"); + + priv->regmap = devm_regmap_init_mmio(dev, regs, + &loongson_rtc_regmap_config); + if (IS_ERR(priv->regmap)) + return dev_err_probe(dev, PTR_ERR(priv->regmap), + "devm_regmap_init_mmio failed\n"); + + priv->config = device_get_match_data(dev); + spin_lock_init(&priv->lock); + platform_set_drvdata(pdev, priv); + + priv->rtcdev = devm_rtc_allocate_device(dev); + if (IS_ERR(priv->rtcdev)) + return dev_err_probe(dev, PTR_ERR(priv->rtcdev), + "devm_rtc_allocate_device failed\n"); + + /* Get RTC alarm irq */ + alarm_irq = platform_get_irq(pdev, 0); + if (alarm_irq > 0) { + ret = devm_request_irq(dev, alarm_irq, loongson_rtc_isr, + 0, "loongson-alarm", priv); + if (ret < 0) + return dev_err_probe(dev, ret, "Unable to request irq %d\n", + alarm_irq); + + priv->pm_base = regs - priv->config->pm_offset; + device_init_wakeup(dev, 1); + + if (has_acpi_companion(dev)) + acpi_install_fixed_event_handler(ACPI_EVENT_RTC, + loongson_rtc_handler, priv); + } else { + /* Loongson-1C RTC does not support alarm */ + clear_bit(RTC_FEATURE_ALARM, priv->rtcdev->features); + } + + /* Loongson RTC does not support UIE */ + clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, priv->rtcdev->features); + priv->rtcdev->ops = &loongson_rtc_ops; + priv->rtcdev->range_min = RTC_TIMESTAMP_BEGIN_2000; + priv->rtcdev->range_max = RTC_TIMESTAMP_END_2099; + + return devm_rtc_register_device(priv->rtcdev); +} + +static void loongson_rtc_remove(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct loongson_rtc_priv *priv = dev_get_drvdata(dev); + + if (!test_bit(RTC_FEATURE_ALARM, priv->rtcdev->features)) + return; + + if (has_acpi_companion(dev)) + acpi_remove_fixed_event_handler(ACPI_EVENT_RTC, + loongson_rtc_handler); + + device_init_wakeup(dev, 0); + loongson_rtc_alarm_irq_enable(dev, 0); +} + +static const struct of_device_id loongson_rtc_of_match[] = { + { .compatible = "loongson,ls1b-rtc", .data = &ls1b_rtc_config }, + { .compatible = "loongson,ls1c-rtc", .data = &ls1c_rtc_config }, + { .compatible = "loongson,ls7a-rtc", .data = &generic_rtc_config }, + { .compatible = "loongson,ls2k1000-rtc", .data = &ls2k1000_rtc_config }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, loongson_rtc_of_match); + +static const struct acpi_device_id loongson_rtc_acpi_match[] = { + { "LOON0001", .driver_data = (kernel_ulong_t)&generic_rtc_config }, + { } +}; +MODULE_DEVICE_TABLE(acpi, loongson_rtc_acpi_match); + +static struct platform_driver loongson_rtc_driver = { + .probe = loongson_rtc_probe, + .remove_new = loongson_rtc_remove, + .driver = { + .name = "loongson-rtc", + .of_match_table = loongson_rtc_of_match, + .acpi_match_table = loongson_rtc_acpi_match, + }, +}; +module_platform_driver(loongson_rtc_driver); + +MODULE_DESCRIPTION("Loongson RTC driver"); +MODULE_AUTHOR("Binbin Zhou "); +MODULE_AUTHOR("WANG Xuerui "); +MODULE_AUTHOR("Huacai Chen "); +MODULE_LICENSE("GPL"); diff --git a/drivers/rtc/rtc-ls1x.c b/drivers/rtc/rtc-ls1x.c deleted file mode 100644 index 5af26dc5c2a3..000000000000 --- a/drivers/rtc/rtc-ls1x.c +++ /dev/null @@ -1,192 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (c) 2011 Zhao Zhang - * - * Derived from driver/rtc/rtc-au1xxx.c - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define LS1X_RTC_REG_OFFSET (LS1X_RTC_BASE + 0x20) -#define LS1X_RTC_REGS(x) \ - ((void __iomem *)KSEG1ADDR(LS1X_RTC_REG_OFFSET + (x))) - -/*RTC programmable counters 0 and 1*/ -#define SYS_COUNTER_CNTRL (LS1X_RTC_REGS(0x20)) -#define SYS_CNTRL_ERS (1 << 23) -#define SYS_CNTRL_RTS (1 << 20) -#define SYS_CNTRL_RM2 (1 << 19) -#define SYS_CNTRL_RM1 (1 << 18) -#define SYS_CNTRL_RM0 (1 << 17) -#define SYS_CNTRL_RS (1 << 16) -#define SYS_CNTRL_BP (1 << 14) -#define SYS_CNTRL_REN (1 << 13) -#define SYS_CNTRL_BRT (1 << 12) -#define SYS_CNTRL_TEN (1 << 11) -#define SYS_CNTRL_BTT (1 << 10) -#define SYS_CNTRL_E0 (1 << 8) -#define SYS_CNTRL_ETS (1 << 7) -#define SYS_CNTRL_32S (1 << 5) -#define SYS_CNTRL_TTS (1 << 4) -#define SYS_CNTRL_TM2 (1 << 3) -#define SYS_CNTRL_TM1 (1 << 2) -#define SYS_CNTRL_TM0 (1 << 1) -#define SYS_CNTRL_TS (1 << 0) - -/* Programmable Counter 0 Registers */ -#define SYS_TOYTRIM (LS1X_RTC_REGS(0)) -#define SYS_TOYWRITE0 (LS1X_RTC_REGS(4)) -#define SYS_TOYWRITE1 (LS1X_RTC_REGS(8)) -#define SYS_TOYREAD0 (LS1X_RTC_REGS(0xC)) -#define SYS_TOYREAD1 (LS1X_RTC_REGS(0x10)) -#define SYS_TOYMATCH0 (LS1X_RTC_REGS(0x14)) -#define SYS_TOYMATCH1 (LS1X_RTC_REGS(0x18)) -#define SYS_TOYMATCH2 (LS1X_RTC_REGS(0x1C)) - -/* Programmable Counter 1 Registers */ -#define SYS_RTCTRIM (LS1X_RTC_REGS(0x40)) -#define SYS_RTCWRITE0 (LS1X_RTC_REGS(0x44)) -#define SYS_RTCREAD0 (LS1X_RTC_REGS(0x48)) -#define SYS_RTCMATCH0 (LS1X_RTC_REGS(0x4C)) -#define SYS_RTCMATCH1 (LS1X_RTC_REGS(0x50)) -#define SYS_RTCMATCH2 (LS1X_RTC_REGS(0x54)) - -#define LS1X_SEC_OFFSET (4) -#define LS1X_MIN_OFFSET (10) -#define LS1X_HOUR_OFFSET (16) -#define LS1X_DAY_OFFSET (21) -#define LS1X_MONTH_OFFSET (26) - - -#define LS1X_SEC_MASK (0x3f) -#define LS1X_MIN_MASK (0x3f) -#define LS1X_HOUR_MASK (0x1f) -#define LS1X_DAY_MASK (0x1f) -#define LS1X_MONTH_MASK (0x3f) -#define LS1X_YEAR_MASK (0xffffffff) - -#define ls1x_get_sec(t) (((t) >> LS1X_SEC_OFFSET) & LS1X_SEC_MASK) -#define ls1x_get_min(t) (((t) >> LS1X_MIN_OFFSET) & LS1X_MIN_MASK) -#define ls1x_get_hour(t) (((t) >> LS1X_HOUR_OFFSET) & LS1X_HOUR_MASK) -#define ls1x_get_day(t) (((t) >> LS1X_DAY_OFFSET) & LS1X_DAY_MASK) -#define ls1x_get_month(t) (((t) >> LS1X_MONTH_OFFSET) & LS1X_MONTH_MASK) - -#define RTC_CNTR_OK (SYS_CNTRL_E0 | SYS_CNTRL_32S) - -static int ls1x_rtc_read_time(struct device *dev, struct rtc_time *rtm) -{ - unsigned long v; - time64_t t; - - v = readl(SYS_TOYREAD0); - t = readl(SYS_TOYREAD1); - - memset(rtm, 0, sizeof(struct rtc_time)); - t = mktime64((t & LS1X_YEAR_MASK), ls1x_get_month(v), - ls1x_get_day(v), ls1x_get_hour(v), - ls1x_get_min(v), ls1x_get_sec(v)); - rtc_time64_to_tm(t, rtm); - - return 0; -} - -static int ls1x_rtc_set_time(struct device *dev, struct rtc_time *rtm) -{ - unsigned long v, t, c; - int ret = -ETIMEDOUT; - - v = ((rtm->tm_mon + 1) << LS1X_MONTH_OFFSET) - | (rtm->tm_mday << LS1X_DAY_OFFSET) - | (rtm->tm_hour << LS1X_HOUR_OFFSET) - | (rtm->tm_min << LS1X_MIN_OFFSET) - | (rtm->tm_sec << LS1X_SEC_OFFSET); - - writel(v, SYS_TOYWRITE0); - c = 0x10000; - /* add timeout check counter, for more safe */ - while ((readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_TS) && --c) - usleep_range(1000, 3000); - - if (!c) { - dev_err(dev, "set time timeout!\n"); - goto err; - } - - t = rtm->tm_year + 1900; - writel(t, SYS_TOYWRITE1); - c = 0x10000; - while ((readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_TS) && --c) - usleep_range(1000, 3000); - - if (!c) { - dev_err(dev, "set time timeout!\n"); - goto err; - } - return 0; -err: - return ret; -} - -static const struct rtc_class_ops ls1x_rtc_ops = { - .read_time = ls1x_rtc_read_time, - .set_time = ls1x_rtc_set_time, -}; - -static int ls1x_rtc_probe(struct platform_device *pdev) -{ - struct rtc_device *rtcdev; - unsigned long v; - - v = readl(SYS_COUNTER_CNTRL); - if (!(v & RTC_CNTR_OK)) { - dev_err(&pdev->dev, "rtc counters not working\n"); - return -ENODEV; - } - - /* set to 1 HZ if needed */ - if (readl(SYS_TOYTRIM) != 32767) { - v = 0x100000; - while ((readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_TTS) && --v) - usleep_range(1000, 3000); - - if (!v) { - dev_err(&pdev->dev, "time out\n"); - return -ETIMEDOUT; - } - writel(32767, SYS_TOYTRIM); - } - /* this loop coundn't be endless */ - while (readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_TTS) - usleep_range(1000, 3000); - - rtcdev = devm_rtc_allocate_device(&pdev->dev); - if (IS_ERR(rtcdev)) - return PTR_ERR(rtcdev); - - platform_set_drvdata(pdev, rtcdev); - rtcdev->ops = &ls1x_rtc_ops; - rtcdev->range_min = RTC_TIMESTAMP_BEGIN_1900; - rtcdev->range_max = RTC_TIMESTAMP_END_2099; - - return devm_rtc_register_device(rtcdev); -} - -static struct platform_driver ls1x_rtc_driver = { - .driver = { - .name = "ls1x-rtc", - }, - .probe = ls1x_rtc_probe, -}; - -module_platform_driver(ls1x_rtc_driver); - -MODULE_AUTHOR("zhao zhang "); -MODULE_LICENSE("GPL"); diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c index c1963f7c424d..3cc5151e0986 100644 --- a/drivers/rtc/rtc-m41t80.c +++ b/drivers/rtc/rtc-m41t80.c @@ -1013,7 +1013,7 @@ static struct i2c_driver m41t80_driver = { .of_match_table = of_match_ptr(m41t80_of_match), .pm = &m41t80_pm, }, - .probe_new = m41t80_probe, + .probe = m41t80_probe, .remove = m41t80_remove, .id_table = m41t80_id, }; diff --git a/drivers/rtc/rtc-max6900.c b/drivers/rtc/rtc-max6900.c index 0a33851cc51f..31b910e4d91a 100644 --- a/drivers/rtc/rtc-max6900.c +++ b/drivers/rtc/rtc-max6900.c @@ -224,7 +224,7 @@ static struct i2c_driver max6900_driver = { .driver = { .name = "rtc-max6900", }, - .probe_new = max6900_probe, + .probe = max6900_probe, .id_table = max6900_id, }; diff --git a/drivers/rtc/rtc-nct3018y.c b/drivers/rtc/rtc-nct3018y.c index 0a3b14c95d90..a4e3f924837e 100644 --- a/drivers/rtc/rtc-nct3018y.c +++ b/drivers/rtc/rtc-nct3018y.c @@ -540,7 +540,7 @@ static struct i2c_driver nct3018y_driver = { .name = "rtc-nct3018y", .of_match_table = of_match_ptr(nct3018y_of_match), }, - .probe_new = nct3018y_probe, + .probe = nct3018y_probe, .id_table = nct3018y_id, }; diff --git a/drivers/rtc/rtc-pcf2127.c b/drivers/rtc/rtc-pcf2127.c index 87f4fc9df68b..ee03b04b74ba 100644 --- a/drivers/rtc/rtc-pcf2127.c +++ b/drivers/rtc/rtc-pcf2127.c @@ -923,7 +923,7 @@ static struct i2c_driver pcf2127_i2c_driver = { .name = "rtc-pcf2127-i2c", .of_match_table = of_match_ptr(pcf2127_of_match), }, - .probe_new = pcf2127_i2c_probe, + .probe = pcf2127_i2c_probe, .id_table = pcf2127_i2c_id, }; diff --git a/drivers/rtc/rtc-pcf85063.c b/drivers/rtc/rtc-pcf85063.c index 71a456355981..e517abfaee2a 100644 --- a/drivers/rtc/rtc-pcf85063.c +++ b/drivers/rtc/rtc-pcf85063.c @@ -681,7 +681,7 @@ static struct i2c_driver pcf85063_driver = { .name = "rtc-pcf85063", .of_match_table = of_match_ptr(pcf85063_of_match), }, - .probe_new = pcf85063_probe, + .probe = pcf85063_probe, .id_table = pcf85063_ids, }; diff --git a/drivers/rtc/rtc-pcf8523.c b/drivers/rtc/rtc-pcf8523.c index e7115ebef707..d1efde3e7a80 100644 --- a/drivers/rtc/rtc-pcf8523.c +++ b/drivers/rtc/rtc-pcf8523.c @@ -488,7 +488,7 @@ static struct i2c_driver pcf8523_driver = { .name = "rtc-pcf8523", .of_match_table = pcf8523_of_match, }, - .probe_new = pcf8523_probe, + .probe = pcf8523_probe, .id_table = pcf8523_id, }; module_i2c_driver(pcf8523_driver); diff --git a/drivers/rtc/rtc-pcf85363.c b/drivers/rtc/rtc-pcf85363.c index 8958eadf1c3e..65b8b1338dbb 100644 --- a/drivers/rtc/rtc-pcf85363.c +++ b/drivers/rtc/rtc-pcf85363.c @@ -475,7 +475,7 @@ static struct i2c_driver pcf85363_driver = { .name = "pcf85363", .of_match_table = of_match_ptr(dev_ids), }, - .probe_new = pcf85363_probe, + .probe = pcf85363_probe, }; module_i2c_driver(pcf85363_driver); diff --git a/drivers/rtc/rtc-pcf8563.c b/drivers/rtc/rtc-pcf8563.c index 7e720472213c..ea82b89d8929 100644 --- a/drivers/rtc/rtc-pcf8563.c +++ b/drivers/rtc/rtc-pcf8563.c @@ -612,7 +612,7 @@ static struct i2c_driver pcf8563_driver = { .name = "rtc-pcf8563", .of_match_table = of_match_ptr(pcf8563_of_match), }, - .probe_new = pcf8563_probe, + .probe = pcf8563_probe, .id_table = pcf8563_id, }; diff --git a/drivers/rtc/rtc-pcf8583.c b/drivers/rtc/rtc-pcf8583.c index 87074d178274..a7e0fc360b6a 100644 --- a/drivers/rtc/rtc-pcf8583.c +++ b/drivers/rtc/rtc-pcf8583.c @@ -306,7 +306,7 @@ static struct i2c_driver pcf8583_driver = { .driver = { .name = "pcf8583", }, - .probe_new = pcf8583_probe, + .probe = pcf8583_probe, .id_table = pcf8583_id, }; diff --git a/drivers/rtc/rtc-rs5c372.c b/drivers/rtc/rtc-rs5c372.c index b4c5d016eca3..a5a6c8772ecd 100644 --- a/drivers/rtc/rtc-rs5c372.c +++ b/drivers/rtc/rtc-rs5c372.c @@ -921,7 +921,7 @@ static struct i2c_driver rs5c372_driver = { .name = "rtc-rs5c372", .of_match_table = of_match_ptr(rs5c372_of_match), }, - .probe_new = rs5c372_probe, + .probe = rs5c372_probe, .remove = rs5c372_remove, .id_table = rs5c372_id, }; diff --git a/drivers/rtc/rtc-rv3028.c b/drivers/rtc/rtc-rv3028.c index ec5d7a614e2d..076e56f4e01a 100644 --- a/drivers/rtc/rtc-rv3028.c +++ b/drivers/rtc/rtc-rv3028.c @@ -994,13 +994,20 @@ static const __maybe_unused struct of_device_id rv3028_of_match[] = { }; MODULE_DEVICE_TABLE(of, rv3028_of_match); +static const struct i2c_device_id rv3028_id_table[] = { + { .name = "rv3028", }, + { } +}; +MODULE_DEVICE_TABLE(i2c, rv3028_id_table); + static struct i2c_driver rv3028_driver = { .driver = { .name = "rtc-rv3028", .acpi_match_table = rv3028_i2c_acpi_match, .of_match_table = of_match_ptr(rv3028_of_match), }, - .probe_new = rv3028_probe, + .id_table = rv3028_id_table, + .probe = rv3028_probe, }; module_i2c_driver(rv3028_driver); diff --git a/drivers/rtc/rtc-rv3029c2.c b/drivers/rtc/rtc-rv3029c2.c index 0852f6709a85..4a81feeb00ff 100644 --- a/drivers/rtc/rtc-rv3029c2.c +++ b/drivers/rtc/rtc-rv3029c2.c @@ -824,7 +824,7 @@ static struct i2c_driver rv3029_driver = { .name = "rv3029", .of_match_table = of_match_ptr(rv3029_of_match), }, - .probe_new = rv3029_i2c_probe, + .probe = rv3029_i2c_probe, .id_table = rv3029_id, }; diff --git a/drivers/rtc/rtc-rv3032.c b/drivers/rtc/rtc-rv3032.c index 1ff4f2e6fa77..6b8eb2039a33 100644 --- a/drivers/rtc/rtc-rv3032.c +++ b/drivers/rtc/rtc-rv3032.c @@ -842,7 +842,7 @@ static int rv3032_hwmon_read(struct device *dev, enum hwmon_sensor_types type, return err; } -static const struct hwmon_channel_info *rv3032_hwmon_info[] = { +static const struct hwmon_channel_info * const rv3032_hwmon_info[] = { HWMON_CHANNEL_INFO(chip, HWMON_C_REGISTER_TZ), HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_MAX_HYST), NULL @@ -998,7 +998,7 @@ static struct i2c_driver rv3032_driver = { .acpi_match_table = rv3032_i2c_acpi_match, .of_match_table = of_match_ptr(rv3032_of_match), }, - .probe_new = rv3032_probe, + .probe = rv3032_probe, }; module_i2c_driver(rv3032_driver); diff --git a/drivers/rtc/rtc-rv8803.c b/drivers/rtc/rtc-rv8803.c index 25c3b9e4f515..98679cae13e8 100644 --- a/drivers/rtc/rtc-rv8803.c +++ b/drivers/rtc/rtc-rv8803.c @@ -739,7 +739,7 @@ static struct i2c_driver rv8803_driver = { .name = "rtc-rv8803", .of_match_table = of_match_ptr(rv8803_of_match), }, - .probe_new = rv8803_probe, + .probe = rv8803_probe, .id_table = rv8803_id, }; module_i2c_driver(rv8803_driver); diff --git a/drivers/rtc/rtc-rx6110.c b/drivers/rtc/rtc-rx6110.c index 37608883a796..8702db6096ba 100644 --- a/drivers/rtc/rtc-rx6110.c +++ b/drivers/rtc/rtc-rx6110.c @@ -462,7 +462,7 @@ static struct i2c_driver rx6110_i2c_driver = { .name = RX6110_DRIVER_NAME, .acpi_match_table = rx6110_i2c_acpi_match, }, - .probe_new = rx6110_i2c_probe, + .probe = rx6110_i2c_probe, .id_table = rx6110_i2c_id, }; diff --git a/drivers/rtc/rtc-rx8010.c b/drivers/rtc/rtc-rx8010.c index b9c8dad26208..f44e212c07de 100644 --- a/drivers/rtc/rtc-rx8010.c +++ b/drivers/rtc/rtc-rx8010.c @@ -424,7 +424,7 @@ static struct i2c_driver rx8010_driver = { .name = "rtc-rx8010", .of_match_table = of_match_ptr(rx8010_of_match), }, - .probe_new = rx8010_probe, + .probe = rx8010_probe, .id_table = rx8010_id, }; diff --git a/drivers/rtc/rtc-rx8025.c b/drivers/rtc/rtc-rx8025.c index 331c20d4d843..aabe62c283a1 100644 --- a/drivers/rtc/rtc-rx8025.c +++ b/drivers/rtc/rtc-rx8025.c @@ -581,7 +581,7 @@ static struct i2c_driver rx8025_driver = { .driver = { .name = "rtc-rx8025", }, - .probe_new = rx8025_probe, + .probe = rx8025_probe, .id_table = rx8025_id, }; diff --git a/drivers/rtc/rtc-rx8581.c b/drivers/rtc/rtc-rx8581.c index 14edb7534c97..82881fd2e14a 100644 --- a/drivers/rtc/rtc-rx8581.c +++ b/drivers/rtc/rtc-rx8581.c @@ -325,7 +325,7 @@ static struct i2c_driver rx8581_driver = { .name = "rtc-rx8581", .of_match_table = of_match_ptr(rx8581_of_match), }, - .probe_new = rx8581_probe, + .probe = rx8581_probe, .id_table = rx8581_id, }; diff --git a/drivers/rtc/rtc-s35390a.c b/drivers/rtc/rtc-s35390a.c index b18daaf72b17..90a3028ac574 100644 --- a/drivers/rtc/rtc-s35390a.c +++ b/drivers/rtc/rtc-s35390a.c @@ -499,7 +499,7 @@ static struct i2c_driver s35390a_driver = { .name = "rtc-s35390a", .of_match_table = of_match_ptr(s35390a_of_match), }, - .probe_new = s35390a_probe, + .probe = s35390a_probe, .id_table = s35390a_id, }; diff --git a/drivers/rtc/rtc-sd3078.c b/drivers/rtc/rtc-sd3078.c index e2f90d768ca8..7760394ccd2d 100644 --- a/drivers/rtc/rtc-sd3078.c +++ b/drivers/rtc/rtc-sd3078.c @@ -217,7 +217,7 @@ static struct i2c_driver sd3078_driver = { .name = "sd3078", .of_match_table = of_match_ptr(rtc_dt_match), }, - .probe_new = sd3078_probe, + .probe = sd3078_probe, .id_table = sd3078_id, }; diff --git a/drivers/rtc/rtc-st-lpc.c b/drivers/rtc/rtc-st-lpc.c index 0f8e4231098e..d492a2d26600 100644 --- a/drivers/rtc/rtc-st-lpc.c +++ b/drivers/rtc/rtc-st-lpc.c @@ -228,17 +228,13 @@ static int st_rtc_probe(struct platform_device *pdev) enable_irq_wake(rtc->irq); disable_irq(rtc->irq); - rtc->clk = clk_get(&pdev->dev, NULL); - if (IS_ERR(rtc->clk)) { - dev_err(&pdev->dev, "Unable to request clock\n"); - return PTR_ERR(rtc->clk); - } - - clk_prepare_enable(rtc->clk); + rtc->clk = devm_clk_get_enabled(&pdev->dev, NULL); + if (IS_ERR(rtc->clk)) + return dev_err_probe(&pdev->dev, PTR_ERR(rtc->clk), + "Unable to request clock\n"); rtc->clkrate = clk_get_rate(rtc->clk); if (!rtc->clkrate) { - clk_disable_unprepare(rtc->clk); dev_err(&pdev->dev, "Unable to fetch clock rate\n"); return -EINVAL; } @@ -252,10 +248,8 @@ static int st_rtc_probe(struct platform_device *pdev) do_div(rtc->rtc_dev->range_max, rtc->clkrate); ret = devm_rtc_register_device(rtc->rtc_dev); - if (ret) { - clk_disable_unprepare(rtc->clk); + if (ret) return ret; - } return 0; } diff --git a/drivers/rtc/rtc-stm32.c b/drivers/rtc/rtc-stm32.c index 229cb2847cc4..3d36e11cff80 100644 --- a/drivers/rtc/rtc-stm32.c +++ b/drivers/rtc/rtc-stm32.c @@ -114,7 +114,6 @@ struct stm32_rtc_data { void (*clear_events)(struct stm32_rtc *rtc, unsigned int flags); bool has_pclk; bool need_dbp; - bool has_wakeirq; }; struct stm32_rtc { @@ -127,7 +126,6 @@ struct stm32_rtc { struct clk *rtc_ck; const struct stm32_rtc_data *data; int irq_alarm; - int wakeirq_alarm; }; static void stm32_rtc_wpr_unlock(struct stm32_rtc *rtc) @@ -547,7 +545,6 @@ static void stm32_rtc_clear_events(struct stm32_rtc *rtc, static const struct stm32_rtc_data stm32_rtc_data = { .has_pclk = false, .need_dbp = true, - .has_wakeirq = false, .regs = { .tr = 0x00, .dr = 0x04, @@ -569,7 +566,6 @@ static const struct stm32_rtc_data stm32_rtc_data = { static const struct stm32_rtc_data stm32h7_rtc_data = { .has_pclk = true, .need_dbp = true, - .has_wakeirq = false, .regs = { .tr = 0x00, .dr = 0x04, @@ -600,7 +596,6 @@ static void stm32mp1_rtc_clear_events(struct stm32_rtc *rtc, static const struct stm32_rtc_data stm32mp1_data = { .has_pclk = true, .need_dbp = false, - .has_wakeirq = true, .regs = { .tr = 0x00, .dr = 0x04, @@ -779,19 +774,12 @@ static int stm32_rtc_probe(struct platform_device *pdev) } ret = device_init_wakeup(&pdev->dev, true); - if (rtc->data->has_wakeirq) { - rtc->wakeirq_alarm = platform_get_irq(pdev, 1); - if (rtc->wakeirq_alarm > 0) { - ret = dev_pm_set_dedicated_wake_irq(&pdev->dev, - rtc->wakeirq_alarm); - } else { - ret = rtc->wakeirq_alarm; - if (rtc->wakeirq_alarm == -EPROBE_DEFER) - goto err; - } - } if (ret) - dev_warn(&pdev->dev, "alarm can't wake up the system: %d", ret); + goto err; + + ret = dev_pm_set_wake_irq(&pdev->dev, rtc->irq_alarm); + if (ret) + goto err; platform_set_drvdata(pdev, rtc); @@ -879,9 +867,6 @@ static int stm32_rtc_suspend(struct device *dev) if (rtc->data->has_pclk) clk_disable_unprepare(rtc->pclk); - if (device_may_wakeup(dev)) - return enable_irq_wake(rtc->irq_alarm); - return 0; } @@ -903,9 +888,6 @@ static int stm32_rtc_resume(struct device *dev) return ret; } - if (device_may_wakeup(dev)) - return disable_irq_wake(rtc->irq_alarm); - return ret; } #endif diff --git a/drivers/rtc/rtc-x1205.c b/drivers/rtc/rtc-x1205.c index f587afa84357..807f953ae0ae 100644 --- a/drivers/rtc/rtc-x1205.c +++ b/drivers/rtc/rtc-x1205.c @@ -679,7 +679,7 @@ static struct i2c_driver x1205_driver = { .name = "rtc-x1205", .of_match_table = x1205_dt_ids, }, - .probe_new = x1205_probe, + .probe = x1205_probe, .remove = x1205_remove, .id_table = x1205_id, }; diff --git a/drivers/usb/common/led.c b/drivers/usb/common/led.c index 0865dd44a80a..1de18d90b134 100644 --- a/drivers/usb/common/led.c +++ b/drivers/usb/common/led.c @@ -14,8 +14,6 @@ #define BLINK_DELAY 30 -static unsigned long usb_blink_delay = BLINK_DELAY; - DEFINE_LED_TRIGGER(ledtrig_usb_gadget); DEFINE_LED_TRIGGER(ledtrig_usb_host); @@ -32,7 +30,7 @@ void usb_led_activity(enum usb_led_event ev) break; } /* led_trigger_blink_oneshot() handles trig == NULL gracefully */ - led_trigger_blink_oneshot(trig, &usb_blink_delay, &usb_blink_delay, 0); + led_trigger_blink_oneshot(trig, BLINK_DELAY, BLINK_DELAY, 0); } EXPORT_SYMBOL_GPL(usb_led_activity); diff --git a/drivers/usb/typec/ucsi/psy.c b/drivers/usb/typec/ucsi/psy.c index 56bf56517f75..384b42267f1f 100644 --- a/drivers/usb/typec/ucsi/psy.c +++ b/drivers/usb/typec/ucsi/psy.c @@ -27,8 +27,20 @@ static enum power_supply_property ucsi_psy_props[] = { POWER_SUPPLY_PROP_VOLTAGE_NOW, POWER_SUPPLY_PROP_CURRENT_MAX, POWER_SUPPLY_PROP_CURRENT_NOW, + POWER_SUPPLY_PROP_SCOPE, }; +static int ucsi_psy_get_scope(struct ucsi_connector *con, + union power_supply_propval *val) +{ + u8 scope = POWER_SUPPLY_SCOPE_UNKNOWN; + struct device *dev = con->ucsi->dev; + + device_property_read_u8(dev, "scope", &scope); + val->intval = scope; + return 0; +} + static int ucsi_psy_get_online(struct ucsi_connector *con, union power_supply_propval *val) { @@ -194,6 +206,8 @@ static int ucsi_psy_get_prop(struct power_supply *psy, return ucsi_psy_get_current_max(con, val); case POWER_SUPPLY_PROP_CURRENT_NOW: return ucsi_psy_get_current_now(con, val); + case POWER_SUPPLY_PROP_SCOPE: + return ucsi_psy_get_scope(con, val); default: return -EINVAL; } diff --git a/drivers/video/backlight/adp8860_bl.c b/drivers/video/backlight/adp8860_bl.c index a479aab90f78..f51ada4795e8 100644 --- a/drivers/video/backlight/adp8860_bl.c +++ b/drivers/video/backlight/adp8860_bl.c @@ -803,8 +803,8 @@ static struct i2c_driver adp8860_driver = { .name = KBUILD_MODNAME, .pm = &adp8860_i2c_pm_ops, }, - .probe_new = adp8860_probe, - .remove = adp8860_remove, + .probe = adp8860_probe, + .remove = adp8860_remove, .id_table = adp8860_id, }; diff --git a/drivers/video/backlight/adp8870_bl.c b/drivers/video/backlight/adp8870_bl.c index d6b0007db649..6bb18dc970e9 100644 --- a/drivers/video/backlight/adp8870_bl.c +++ b/drivers/video/backlight/adp8870_bl.c @@ -973,8 +973,8 @@ static struct i2c_driver adp8870_driver = { .name = KBUILD_MODNAME, .pm = &adp8870_i2c_pm_ops, }, - .probe_new = adp8870_probe, - .remove = adp8870_remove, + .probe = adp8870_probe, + .remove = adp8870_remove, .id_table = adp8870_id, }; diff --git a/drivers/video/backlight/arcxcnn_bl.c b/drivers/video/backlight/arcxcnn_bl.c index 088bcca547dd..1d5a570cfe02 100644 --- a/drivers/video/backlight/arcxcnn_bl.c +++ b/drivers/video/backlight/arcxcnn_bl.c @@ -392,7 +392,7 @@ static struct i2c_driver arcxcnn_driver = { .name = "arcxcnn_bl", .of_match_table = arcxcnn_dt_ids, }, - .probe_new = arcxcnn_probe, + .probe = arcxcnn_probe, .remove = arcxcnn_remove, .id_table = arcxcnn_ids, }; diff --git a/drivers/video/backlight/bd6107.c b/drivers/video/backlight/bd6107.c index f4db6c064635..7df25faa07a5 100644 --- a/drivers/video/backlight/bd6107.c +++ b/drivers/video/backlight/bd6107.c @@ -192,7 +192,7 @@ static struct i2c_driver bd6107_driver = { .driver = { .name = "bd6107", }, - .probe_new = bd6107_probe, + .probe = bd6107_probe, .remove = bd6107_remove, .id_table = bd6107_ids, }; diff --git a/drivers/video/backlight/ktz8866.c b/drivers/video/backlight/ktz8866.c index d38c13ad39c7..9c980f2571ee 100644 --- a/drivers/video/backlight/ktz8866.c +++ b/drivers/video/backlight/ktz8866.c @@ -196,7 +196,7 @@ static struct i2c_driver ktz8866_driver = { .name = "ktz8866", .of_match_table = ktz8866_match_table, }, - .probe_new = ktz8866_probe, + .probe = ktz8866_probe, .remove = ktz8866_remove, .id_table = ktz8866_ids, }; diff --git a/drivers/video/backlight/led_bl.c b/drivers/video/backlight/led_bl.c index a1b6a2ad73a0..3259292fda76 100644 --- a/drivers/video/backlight/led_bl.c +++ b/drivers/video/backlight/led_bl.c @@ -209,8 +209,11 @@ static int led_bl_probe(struct platform_device *pdev) return PTR_ERR(priv->bl_dev); } - for (i = 0; i < priv->nb_leds; i++) + for (i = 0; i < priv->nb_leds; i++) { + mutex_lock(&priv->leds[i]->led_access); led_sysfs_disable(priv->leds[i]); + mutex_unlock(&priv->leds[i]->led_access); + } backlight_update_status(priv->bl_dev); diff --git a/drivers/video/backlight/lm3630a_bl.c b/drivers/video/backlight/lm3630a_bl.c index d8c42acecb5d..8fcb62be597b 100644 --- a/drivers/video/backlight/lm3630a_bl.c +++ b/drivers/video/backlight/lm3630a_bl.c @@ -202,7 +202,9 @@ static int lm3630a_bank_a_update_status(struct backlight_device *bl) usleep_range(1000, 2000); /* minimum brightness is 0x04 */ ret = lm3630a_write(pchip, REG_BRT_A, bl->props.brightness); - if (bl->props.brightness < 0x4) + + if (backlight_is_blank(bl) || (backlight_get_brightness(bl) < 0x4)) + /* turn the string off */ ret |= lm3630a_update(pchip, REG_CTRL, LM3630A_LEDA_ENABLE, 0); else ret |= lm3630a_update(pchip, REG_CTRL, @@ -277,7 +279,9 @@ static int lm3630a_bank_b_update_status(struct backlight_device *bl) usleep_range(1000, 2000); /* minimum brightness is 0x04 */ ret = lm3630a_write(pchip, REG_BRT_B, bl->props.brightness); - if (bl->props.brightness < 0x4) + + if (backlight_is_blank(bl) || (backlight_get_brightness(bl) < 0x4)) + /* turn the string off */ ret |= lm3630a_update(pchip, REG_CTRL, LM3630A_LEDB_ENABLE, 0); else ret |= lm3630a_update(pchip, REG_CTRL, @@ -616,7 +620,7 @@ static struct i2c_driver lm3630a_i2c_driver = { .name = LM3630A_NAME, .of_match_table = lm3630a_match_table, }, - .probe_new = lm3630a_probe, + .probe = lm3630a_probe, .remove = lm3630a_remove, .id_table = lm3630a_id, }; diff --git a/drivers/video/backlight/lm3639_bl.c b/drivers/video/backlight/lm3639_bl.c index a836628ce06e..5246c171497d 100644 --- a/drivers/video/backlight/lm3639_bl.c +++ b/drivers/video/backlight/lm3639_bl.c @@ -411,7 +411,7 @@ static struct i2c_driver lm3639_i2c_driver = { .driver = { .name = LM3639_NAME, }, - .probe_new = lm3639_probe, + .probe = lm3639_probe, .remove = lm3639_remove, .id_table = lm3639_id, }; diff --git a/drivers/video/backlight/lp855x_bl.c b/drivers/video/backlight/lp855x_bl.c index a57c9ef3b1cc..1c9e921bca14 100644 --- a/drivers/video/backlight/lp855x_bl.c +++ b/drivers/video/backlight/lp855x_bl.c @@ -218,23 +218,10 @@ err: static void lp855x_pwm_ctrl(struct lp855x *lp, int br, int max_br) { - struct pwm_device *pwm; struct pwm_state state; - /* request pwm device with the consumer name */ - if (!lp->pwm) { - pwm = devm_pwm_get(lp->dev, lp->chipname); - if (IS_ERR(pwm)) - return; + pwm_get_state(lp->pwm, &state); - lp->pwm = pwm; - - pwm_init_state(lp->pwm, &state); - } else { - pwm_get_state(lp->pwm, &state); - } - - state.period = lp->pdata->period_ns; state.duty_cycle = div_u64(br * state.period, max_br); state.enabled = state.duty_cycle; @@ -339,6 +326,7 @@ static int lp855x_parse_dt(struct lp855x *lp) of_property_read_string(node, "bl-name", &pdata->name); of_property_read_u8(node, "dev-ctrl", &pdata->device_control); of_property_read_u8(node, "init-brt", &pdata->initial_brightness); + /* Deprecated, specify period in pwms property instead */ of_property_read_u32(node, "pwm-period", &pdata->period_ns); /* Fill ROM platform data if defined */ @@ -399,6 +387,7 @@ static int lp855x_probe(struct i2c_client *cl) const struct i2c_device_id *id = i2c_client_get_device_id(cl); const struct acpi_device_id *acpi_id = NULL; struct device *dev = &cl->dev; + struct pwm_state pwmstate; struct lp855x *lp; int ret; @@ -457,11 +446,6 @@ static int lp855x_probe(struct i2c_client *cl) } } - if (lp->pdata->period_ns > 0) - lp->mode = PWM_BASED; - else - lp->mode = REGISTER_BASED; - lp->supply = devm_regulator_get(dev, "power"); if (IS_ERR(lp->supply)) { if (PTR_ERR(lp->supply) == -EPROBE_DEFER) @@ -472,11 +456,31 @@ static int lp855x_probe(struct i2c_client *cl) lp->enable = devm_regulator_get_optional(dev, "enable"); if (IS_ERR(lp->enable)) { ret = PTR_ERR(lp->enable); - if (ret == -ENODEV) { + if (ret == -ENODEV) lp->enable = NULL; - } else { + else return dev_err_probe(dev, ret, "getting enable regulator\n"); - } + } + + lp->pwm = devm_pwm_get(lp->dev, lp->chipname); + if (IS_ERR(lp->pwm)) { + ret = PTR_ERR(lp->pwm); + if (ret == -ENODEV || ret == -EINVAL) + lp->pwm = NULL; + else + return dev_err_probe(dev, ret, "getting PWM\n"); + + lp->mode = REGISTER_BASED; + dev_dbg(dev, "mode: register based\n"); + } else { + pwm_init_state(lp->pwm, &pwmstate); + /* Legacy platform data compatibility */ + if (lp->pdata->period_ns > 0) + pwmstate.period = lp->pdata->period_ns; + pwm_apply_state(lp->pwm, &pwmstate); + + lp->mode = PWM_BASED; + dev_dbg(dev, "mode: PWM based\n"); } if (lp->supply) { @@ -587,7 +591,7 @@ static struct i2c_driver lp855x_driver = { .of_match_table = of_match_ptr(lp855x_dt_ids), .acpi_match_table = ACPI_PTR(lp855x_acpi_match), }, - .probe_new = lp855x_probe, + .probe = lp855x_probe, .remove = lp855x_remove, .id_table = lp855x_ids, }; diff --git a/drivers/video/backlight/lv5207lp.c b/drivers/video/backlight/lv5207lp.c index 00673c8b66ac..56695ce67e48 100644 --- a/drivers/video/backlight/lv5207lp.c +++ b/drivers/video/backlight/lv5207lp.c @@ -141,7 +141,7 @@ static struct i2c_driver lv5207lp_driver = { .driver = { .name = "lv5207lp", }, - .probe_new = lv5207lp_probe, + .probe = lv5207lp_probe, .remove = lv5207lp_remove, .id_table = lv5207lp_ids, }; diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c index fce412234d10..a51fbab96368 100644 --- a/drivers/video/backlight/pwm_bl.c +++ b/drivers/video/backlight/pwm_bl.c @@ -54,8 +54,7 @@ static void pwm_backlight_power_on(struct pwm_bl_data *pb) if (pb->post_pwm_on_delay) msleep(pb->post_pwm_on_delay); - if (pb->enable_gpio) - gpiod_set_value_cansleep(pb->enable_gpio, 1); + gpiod_set_value_cansleep(pb->enable_gpio, 1); pb->enabled = true; } @@ -65,8 +64,7 @@ static void pwm_backlight_power_off(struct pwm_bl_data *pb) if (!pb->enabled) return; - if (pb->enable_gpio) - gpiod_set_value_cansleep(pb->enable_gpio, 0); + gpiod_set_value_cansleep(pb->enable_gpio, 0); if (pb->pwm_off_delay) msleep(pb->pwm_off_delay); @@ -429,8 +427,7 @@ static int pwm_backlight_initial_power_state(const struct pwm_bl_data *pb) * Synchronize the enable_gpio with the observed state of the * hardware. */ - if (pb->enable_gpio) - gpiod_direction_output(pb->enable_gpio, active); + gpiod_direction_output(pb->enable_gpio, active); /* * Do not change pb->enabled here! pb->enabled essentially diff --git a/drivers/video/fbdev/stifb.c b/drivers/video/fbdev/stifb.c index 66d82f6d17c7..c746deb79afc 100644 --- a/drivers/video/fbdev/stifb.c +++ b/drivers/video/fbdev/stifb.c @@ -71,9 +71,9 @@ #include