Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'mfd-next-6.18' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd

Pull MFD updates from Lee Jones:
"This round of updates contains a fair amount of new device support, a
couple of fixes and some refactoring. The most notable additions
include new drivers for Loongson's Security Engine, RNG and TPM, new
drivers for TI's TPS6594 Power Button and BQ257xx Charger ICs.

The rest of the set provides a return value check fix and a
refactoring to use a more modern GPIO API for the VEXPRESS sysreg
driver, the removal of a deprecated IRQ ACK function from the MC13xxx
RTC driver and a new DT binding for the aforementioned TI BQ257xx
charger.

New Support & Features:
- Add a suite of drivers for the Loongson Security Engine, including
the core controller, a Random Number Generator (RNG) and Trusted
Platform Module (TPM) support.
- Introduce support for the TI TPS6594 PMIC's power button, including
the input driver, MFD cell registration, and a system power-off
handler.
- Add comprehensive support for the TI BQ257xx series of charger ICs,
including the core MFD driver and a power supply driver for the
charger functionality.

Improvements & Fixes:
- Check the return value of devm_gpiochip_add_data() in the VEXPRESS
sysreg driver to prevent potential silent failures.

Cleanups & Refactoring:
- Add a MAINTAINERS entry for the new Loongson Security Engine
drivers.
- Convert the VEXPRESS sysreg driver to use the modern generic GPIO
chip API.

Removals:
- Remove the deprecated and unused mc13xxx_irq_ack() function from
the MC13xxx RTC, input and touchscreen drivers.

Device Tree Bindings Updates:
- Add device tree bindings for the TI BQ25703A charger"

* tag 'mfd-next-6.18' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd: (69 commits)
mfd: simple-mfd-i2c: Add compatible string for LX2160ARDB
mfd: simple-mfd-i2c: Keep compatible strings in alphabetical order
dt-bindings: mfd: twl: Add missing sub-nodes for TWL4030 & TWL603x
dt-bindings: watchdog: Add SMARC-sAM67 support
dt-bindings: mfd: tps6594: Allow gpio-line-names
mfd: intel-lpss: Add Intel Wildcat Lake LPSS PCI IDs
mfd: 88pm886: Add GPADC cell
mfd: vexpress-sysreg: Use more common syntax for compound literals
mfd: rz-mtu3: Fix MTU5 NFCR register offset
mfd: max77705: Setup the core driver as an interrupt controller
mfd: cs42l43: Remove IRQ masking in suspend
mfd: cs42l43: Move IRQ enable/disable to encompass force suspend
mfd: ls2kbmc: Add Loongson-2K BMC reset function support
mfd: ls2kbmc: Introduce Loongson-2K BMC core driver
mfd: bd71828, bd71815: Prepare for power-supply support
dt-bindings: mfd: aspeed: Add AST2700 SCU compatibles
dt-bindings: mfd: Convert aspeed,ast2400-p2a-ctrl to DT schema
dt-bindings: mfd: fsl,mc13xxx: Add buttons node
dt-bindings: mfd: fsl,mc13xxx: Convert txt to DT schema
mfd: macsmc: Add "apple,t8103-smc" compatible
...

+3673 -519
+1 -1
Documentation/devicetree/bindings/gpio/kontron,sl28cpld-gpio.yaml
··· 11 11 12 12 description: | 13 13 This module is part of the sl28cpld multi-function device. For more 14 - details see ../mfd/kontron,sl28cpld.yaml. 14 + details see ../embedded-controller/kontron,sl28cpld.yaml. 15 15 16 16 There are three flavors of the GPIO controller, one full featured 17 17 input/output with interrupt support (kontron,sl28cpld-gpio), one
+1 -1
Documentation/devicetree/bindings/hwmon/kontron,sl28cpld-hwmon.yaml
··· 11 11 12 12 description: | 13 13 This module is part of the sl28cpld multi-function device. For more 14 - details see ../mfd/kontron,sl28cpld.yaml. 14 + details see ../embedded-controller/kontron,sl28cpld.yaml. 15 15 16 16 properties: 17 17 compatible:
+1 -1
Documentation/devicetree/bindings/interrupt-controller/kontron,sl28cpld-intc.yaml
··· 11 11 12 12 description: | 13 13 This module is part of the sl28cpld multi-function device. For more 14 - details see ../mfd/kontron,sl28cpld.yaml. 14 + details see ../embedded-controller/kontron,sl28cpld.yaml. 15 15 16 16 The following interrupts are available. All types and levels are fixed 17 17 and handled by the board management controller.
+32 -1
Documentation/devicetree/bindings/mfd/aspeed,ast2x00-scu.yaml
··· 48 48 49 49 patternProperties: 50 50 '^p2a-control@[0-9a-f]+$': 51 - description: See Documentation/devicetree/bindings/misc/aspeed-p2a-ctrl.txt 51 + description: > 52 + PCI-to-AHB Bridge Control 53 + 54 + The bridge is available on platforms with the VGA enabled on the Aspeed 55 + device. In this case, the host has access to a 64KiB window into all of 56 + the BMC's memory. The BMC can disable this bridge. If the bridge is 57 + enabled, the host has read access to all the regions of memory, however 58 + the host only has read and write access depending on a register 59 + controlled by the BMC. 52 60 type: object 61 + additionalProperties: false 62 + 63 + properties: 64 + compatible: 65 + enum: 66 + - aspeed,ast2400-p2a-ctrl 67 + - aspeed,ast2500-p2a-ctrl 68 + reg: 69 + maxItems: 1 70 + 71 + memory-region: 72 + maxItems: 1 73 + description: 74 + A reserved_memory region to be used for the PCI to AHB mapping 75 + 76 + required: 77 + - compatible 78 + - reg 53 79 54 80 '^pinctrl(@[0-9a-f]+)?$': 55 81 type: object ··· 152 126 #address-cells = <1>; 153 127 #size-cells = <1>; 154 128 ranges = <0x0 0x1e6e2000 0x1000>; 129 + 130 + p2a-control@2c { 131 + compatible = "aspeed,ast2400-p2a-ctrl"; 132 + reg = <0x2c 0x4>; 133 + }; 155 134 156 135 silicon-id@7c { 157 136 compatible = "aspeed,ast2500-silicon-id", "aspeed,silicon-id";
+3
Documentation/devicetree/bindings/mfd/aspeed-lpc.yaml
··· 137 137 reg: 138 138 maxItems: 1 139 139 140 + clocks: 141 + maxItems: 1 142 + 140 143 interrupts: 141 144 maxItems: 1 142 145
+288
Documentation/devicetree/bindings/mfd/fsl,mc13xxx.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/mfd/fsl,mc13xxx.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Freescale MC13xxx Power Management Integrated Circuits (PMIC) 8 + 9 + maintainers: 10 + - Alexander Kurz <akurz@blala.de> 11 + 12 + description: > 13 + The MC13xxx PMIC series consists of the three models MC13783, MC13892 14 + and MC34708 and provide regulators and other features like RTC, ADC, 15 + LED, touchscreen, codec and input buttons. 16 + 17 + Link to datasheets 18 + https://www.nxp.com/docs/en/data-sheet/MC13783.pdf 19 + https://www.nxp.com/docs/en/data-sheet/MC13892.pdf 20 + https://www.nxp.com/docs/en/data-sheet/MC34708.pdf 21 + 22 + properties: 23 + compatible: 24 + enum: 25 + - fsl,mc13783 26 + - fsl,mc13892 27 + - fsl,mc34708 28 + 29 + reg: 30 + description: I2C slave address or SPI chip select number. 31 + maxItems: 1 32 + 33 + spi-max-frequency: true 34 + 35 + spi-cs-high: true 36 + 37 + system-power-controller: true 38 + 39 + interrupts: 40 + maxItems: 1 41 + 42 + buttons: 43 + type: object 44 + properties: 45 + "#address-cells": 46 + const: 1 47 + 48 + "#size-cells": 49 + const: 0 50 + 51 + patternProperties: 52 + "^onkey@[0-2]$": 53 + $ref: /schemas/input/input.yaml# 54 + unevaluatedProperties: false 55 + type: object 56 + 57 + properties: 58 + reg: 59 + description: | 60 + One of 61 + MC13783 BUTTON IDs: 62 + 0: ONOFD1 63 + 1: ONOFD2 64 + 2: ONOFD3 65 + 66 + MC13892 BUTTON IDs: 67 + 0: PWRON1 68 + 1: PWRON2 69 + 2: PWRON3 70 + 71 + MC34708 BUTTON IDs: 72 + 0: PWRON1 73 + 1: PWRON2 74 + maximum: 2 75 + 76 + debounce-delay-ms: 77 + enum: [0, 30, 150, 750] 78 + default: 30 79 + description: 80 + Sets the debouncing delay in milliseconds. 81 + 82 + active-low: 83 + description: Set active when pin is pulled low. 84 + 85 + linux,code: true 86 + 87 + fsl,enable-reset: 88 + description: 89 + Setting of the global reset option. 90 + type: boolean 91 + 92 + unevaluatedProperties: false 93 + 94 + leds: 95 + type: object 96 + $ref: /schemas/leds/common.yaml# 97 + 98 + properties: 99 + reg: 100 + description: | 101 + One of 102 + MC13783 LED IDs 103 + 0: Main display 104 + 1: AUX display 105 + 2: Keypad 106 + 3: Red 1 107 + 4: Green 1 108 + 5: Blue 1 109 + 6: Red 2 110 + 7: Green 2 111 + 8: Blue 2 112 + 9: Red 3 113 + 10: Green 3 114 + 11: Blue 3 115 + 116 + MC13892 LED IDs 117 + 0: Main display 118 + 1: AUX display 119 + 2: Keypad 120 + 3: Red 121 + 4: Green 122 + 5: Blue 123 + 124 + MC34708 LED IDs 125 + 0: Charger Red 126 + 1: Charger Green 127 + maxItems: 1 128 + 129 + led-control: 130 + $ref: /schemas/types.yaml#/definitions/uint32-array 131 + description: | 132 + Setting for LED-Control register array length depends on model, 133 + mc13783: 6, mc13892: 4, mc34708: 1 134 + 135 + regulators: 136 + type: object 137 + 138 + additionalProperties: 139 + type: object 140 + 141 + description: | 142 + List of child nodes specifying the regulators, depending on chip variant. 143 + Each child node is defined using the standard binding for regulators and 144 + the optional regulator properties defined below. 145 + 146 + fsl,mc13xxx-uses-adc: 147 + type: boolean 148 + description: Indicate the ADC is being used 149 + 150 + fsl,mc13xxx-uses-codec: 151 + type: boolean 152 + description: Indicate the Audio Codec is being used 153 + 154 + fsl,mc13xxx-uses-rtc: 155 + type: boolean 156 + description: Indicate the RTC is being used 157 + 158 + fsl,mc13xxx-uses-touch: 159 + type: boolean 160 + description: Indicate the touchscreen controller is being used 161 + 162 + required: 163 + - compatible 164 + - reg 165 + 166 + allOf: 167 + - if: 168 + properties: 169 + compatible: 170 + contains: 171 + const: fsl,mc13783 172 + then: 173 + properties: 174 + leds: 175 + properties: 176 + led-control: 177 + minItems: 6 178 + maxItems: 6 179 + regulators: 180 + patternProperties: 181 + "^gpo[1-4]|pwgt[12]spi|sw[12][ab]|sw3|vaudio|vcam|vdig|vesim|vgen|viohi|violo|vmmc[12]|vrf[12]|vrfbg|vrfcp|vrfdig|vrfref|vsim|vvib$": 182 + type: object 183 + $ref: /schemas/regulator/regulator.yaml# 184 + 185 + unevaluatedProperties: false 186 + 187 + - if: 188 + properties: 189 + compatible: 190 + contains: 191 + const: fsl,mc13892 192 + then: 193 + properties: 194 + leds: 195 + properties: 196 + led-control: 197 + minItems: 4 198 + maxItems: 4 199 + regulators: 200 + patternProperties: 201 + "^gpo[1-4]|pwgt[12]spi|sw[1-4]|swbst|vaudio|vcam|vcoincell|vdig|vgen[1-3]|viohi|vpll|vsd|vusb|vusb2|vvideo$": 202 + type: object 203 + $ref: /schemas/regulator/regulator.yaml# 204 + 205 + unevaluatedProperties: false 206 + 207 + - if: 208 + properties: 209 + compatible: 210 + contains: 211 + const: fsl,mc34708 212 + then: 213 + properties: 214 + buttons: 215 + patternProperties: 216 + "^onkey@[0-2]$": 217 + properties: 218 + reg: 219 + maximum: 1 220 + leds: 221 + properties: 222 + led-control: 223 + minItems: 1 224 + maxItems: 1 225 + 226 + additionalProperties: false 227 + 228 + examples: 229 + - | 230 + #include <dt-bindings/gpio/gpio.h> 231 + #include <dt-bindings/interrupt-controller/irq.h> 232 + #include <dt-bindings/leds/common.h> 233 + 234 + spi { 235 + #address-cells = <1>; 236 + #size-cells = <0>; 237 + 238 + pmic: mc13892@0 { 239 + compatible = "fsl,mc13892"; 240 + reg = <0>; 241 + spi-max-frequency = <1000000>; 242 + spi-cs-high; 243 + interrupt-parent = <&gpio0>; 244 + interrupts = <8 IRQ_TYPE_LEVEL_HIGH>; 245 + fsl,mc13xxx-uses-rtc; 246 + fsl,mc13xxx-uses-adc; 247 + 248 + buttons { 249 + #address-cells = <1>; 250 + #size-cells = <0>; 251 + 252 + onkey@0 { 253 + reg = <0>; 254 + debounce-delay-ms = <30>; 255 + active-low; 256 + fsl,enable-reset; 257 + }; 258 + }; 259 + 260 + leds { 261 + #address-cells = <1>; 262 + #size-cells = <0>; 263 + led-control = <0x000 0x000 0x0e0 0x000>; 264 + 265 + sysled@3 { 266 + reg = <3>; 267 + label = "system:red:live"; 268 + linux,default-trigger = "heartbeat"; 269 + }; 270 + }; 271 + 272 + regulators { 273 + sw1_reg: sw1 { 274 + regulator-min-microvolt = <600000>; 275 + regulator-max-microvolt = <1375000>; 276 + regulator-boot-on; 277 + regulator-always-on; 278 + }; 279 + 280 + sw2_reg: sw2 { 281 + regulator-min-microvolt = <900000>; 282 + regulator-max-microvolt = <1850000>; 283 + regulator-boot-on; 284 + regulator-always-on; 285 + }; 286 + }; 287 + }; 288 + };
+1 -1
Documentation/devicetree/bindings/mfd/gateworks-gsc.yaml Documentation/devicetree/bindings/embedded-controller/gw,gsc.yaml
··· 1 1 # SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause 2 2 %YAML 1.2 3 3 --- 4 - $id: http://devicetree.org/schemas/mfd/gateworks-gsc.yaml# 4 + $id: http://devicetree.org/schemas/embedded-controller/gw,gsc.yaml# 5 5 $schema: http://devicetree.org/meta-schemas/core.yaml# 6 6 7 7 title: Gateworks System Controller
+1 -1
Documentation/devicetree/bindings/mfd/google,cros-ec.yaml Documentation/devicetree/bindings/embedded-controller/google,cros-ec.yaml
··· 1 1 # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 2 %YAML 1.2 3 3 --- 4 - $id: http://devicetree.org/schemas/mfd/google,cros-ec.yaml# 4 + $id: http://devicetree.org/schemas/embedded-controller/google,cros-ec.yaml# 5 5 $schema: http://devicetree.org/meta-schemas/core.yaml# 6 6 7 7 title: ChromeOS Embedded Controller
+7 -2
Documentation/devicetree/bindings/mfd/kontron,sl28cpld.yaml Documentation/devicetree/bindings/embedded-controller/kontron,sl28cpld.yaml
··· 1 1 # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 2 %YAML 1.2 3 3 --- 4 - $id: http://devicetree.org/schemas/mfd/kontron,sl28cpld.yaml# 4 + $id: http://devicetree.org/schemas/embedded-controller/kontron,sl28cpld.yaml# 5 5 $schema: http://devicetree.org/meta-schemas/core.yaml# 6 6 7 7 title: Kontron's sl28cpld board management controller ··· 16 16 17 17 properties: 18 18 compatible: 19 - const: kontron,sl28cpld 19 + oneOf: 20 + - items: 21 + - enum: 22 + - kontron,sa67mcu 23 + - const: kontron,sl28cpld 24 + - const: kontron,sl28cpld 20 25 21 26 reg: 22 27 description:
-156
Documentation/devicetree/bindings/mfd/mc13xxx.txt
··· 1 - * Freescale MC13783/MC13892 Power Management Integrated Circuit (PMIC) 2 - 3 - Required properties: 4 - - compatible : Should be "fsl,mc13783" or "fsl,mc13892" 5 - 6 - Optional properties: 7 - - fsl,mc13xxx-uses-adc : Indicate the ADC is being used 8 - - fsl,mc13xxx-uses-codec : Indicate the Audio Codec is being used 9 - - fsl,mc13xxx-uses-rtc : Indicate the RTC is being used 10 - - fsl,mc13xxx-uses-touch : Indicate the touchscreen controller is being used 11 - 12 - Sub-nodes: 13 - - codec: Contain the Audio Codec node. 14 - - adc-port: Contain PMIC SSI port number used for ADC. 15 - - dac-port: Contain PMIC SSI port number used for DAC. 16 - - leds : Contain the led nodes and initial register values in property 17 - "led-control". Number of register depends of used IC, for MC13783 is 6, 18 - for MC13892 is 4, for MC34708 is 1. See datasheet for bits definitions of 19 - these registers. 20 - - #address-cells: Must be 1. 21 - - #size-cells: Must be 0. 22 - Each led node should contain "reg", which used as LED ID (described below). 23 - Optional properties "label" and "linux,default-trigger" is described in 24 - Documentation/devicetree/bindings/leds/common.txt. 25 - - regulators : Contain the regulator nodes. The regulators are bound using 26 - their names as listed below with their registers and bits for enabling. 27 - 28 - MC13783 LED IDs: 29 - 0 : Main display 30 - 1 : AUX display 31 - 2 : Keypad 32 - 3 : Red 1 33 - 4 : Green 1 34 - 5 : Blue 1 35 - 6 : Red 2 36 - 7 : Green 2 37 - 8 : Blue 2 38 - 9 : Red 3 39 - 10 : Green 3 40 - 11 : Blue 3 41 - 42 - MC13892 LED IDs: 43 - 0 : Main display 44 - 1 : AUX display 45 - 2 : Keypad 46 - 3 : Red 47 - 4 : Green 48 - 5 : Blue 49 - 50 - MC34708 LED IDs: 51 - 0 : Charger Red 52 - 1 : Charger Green 53 - 54 - MC13783 regulators: 55 - sw1a : regulator SW1A (register 24, bit 0) 56 - sw1b : regulator SW1B (register 25, bit 0) 57 - sw2a : regulator SW2A (register 26, bit 0) 58 - sw2b : regulator SW2B (register 27, bit 0) 59 - sw3 : regulator SW3 (register 29, bit 20) 60 - vaudio : regulator VAUDIO (register 32, bit 0) 61 - viohi : regulator VIOHI (register 32, bit 3) 62 - violo : regulator VIOLO (register 32, bit 6) 63 - vdig : regulator VDIG (register 32, bit 9) 64 - vgen : regulator VGEN (register 32, bit 12) 65 - vrfdig : regulator VRFDIG (register 32, bit 15) 66 - vrfref : regulator VRFREF (register 32, bit 18) 67 - vrfcp : regulator VRFCP (register 32, bit 21) 68 - vsim : regulator VSIM (register 33, bit 0) 69 - vesim : regulator VESIM (register 33, bit 3) 70 - vcam : regulator VCAM (register 33, bit 6) 71 - vrfbg : regulator VRFBG (register 33, bit 9) 72 - vvib : regulator VVIB (register 33, bit 11) 73 - vrf1 : regulator VRF1 (register 33, bit 12) 74 - vrf2 : regulator VRF2 (register 33, bit 15) 75 - vmmc1 : regulator VMMC1 (register 33, bit 18) 76 - vmmc2 : regulator VMMC2 (register 33, bit 21) 77 - gpo1 : regulator GPO1 (register 34, bit 6) 78 - gpo2 : regulator GPO2 (register 34, bit 8) 79 - gpo3 : regulator GPO3 (register 34, bit 10) 80 - gpo4 : regulator GPO4 (register 34, bit 12) 81 - pwgt1spi : regulator PWGT1SPI (register 34, bit 15) 82 - pwgt2spi : regulator PWGT2SPI (register 34, bit 16) 83 - 84 - MC13892 regulators: 85 - vcoincell : regulator VCOINCELL (register 13, bit 23) 86 - sw1 : regulator SW1 (register 24, bit 0) 87 - sw2 : regulator SW2 (register 25, bit 0) 88 - sw3 : regulator SW3 (register 26, bit 0) 89 - sw4 : regulator SW4 (register 27, bit 0) 90 - swbst : regulator SWBST (register 29, bit 20) 91 - vgen1 : regulator VGEN1 (register 32, bit 0) 92 - viohi : regulator VIOHI (register 32, bit 3) 93 - vdig : regulator VDIG (register 32, bit 9) 94 - vgen2 : regulator VGEN2 (register 32, bit 12) 95 - vpll : regulator VPLL (register 32, bit 15) 96 - vusb2 : regulator VUSB2 (register 32, bit 18) 97 - vgen3 : regulator VGEN3 (register 33, bit 0) 98 - vcam : regulator VCAM (register 33, bit 6) 99 - vvideo : regulator VVIDEO (register 33, bit 12) 100 - vaudio : regulator VAUDIO (register 33, bit 15) 101 - vsd : regulator VSD (register 33, bit 18) 102 - gpo1 : regulator GPO1 (register 34, bit 6) 103 - gpo2 : regulator GPO2 (register 34, bit 8) 104 - gpo3 : regulator GPO3 (register 34, bit 10) 105 - gpo4 : regulator GPO4 (register 34, bit 12) 106 - pwgt1spi : regulator PWGT1SPI (register 34, bit 15) 107 - pwgt2spi : regulator PWGT2SPI (register 34, bit 16) 108 - vusb : regulator VUSB (register 50, bit 3) 109 - 110 - The bindings details of individual regulator device can be found in: 111 - Documentation/devicetree/bindings/regulator/regulator.txt 112 - 113 - Examples: 114 - 115 - ecspi@70010000 { /* ECSPI1 */ 116 - cs-gpios = <&gpio4 24 0>, /* GPIO4_24 */ 117 - <&gpio4 25 0>; /* GPIO4_25 */ 118 - 119 - pmic: mc13892@0 { 120 - #address-cells = <1>; 121 - #size-cells = <0>; 122 - compatible = "fsl,mc13892"; 123 - spi-max-frequency = <6000000>; 124 - reg = <0>; 125 - interrupt-parent = <&gpio0>; 126 - interrupts = <8>; 127 - 128 - leds { 129 - #address-cells = <1>; 130 - #size-cells = <0>; 131 - led-control = <0x000 0x000 0x0e0 0x000>; 132 - 133 - sysled@3 { 134 - reg = <3>; 135 - label = "system:red:live"; 136 - linux,default-trigger = "heartbeat"; 137 - }; 138 - }; 139 - 140 - regulators { 141 - sw1_reg: mc13892__sw1 { 142 - regulator-min-microvolt = <600000>; 143 - regulator-max-microvolt = <1375000>; 144 - regulator-boot-on; 145 - regulator-always-on; 146 - }; 147 - 148 - sw2_reg: mc13892__sw2 { 149 - regulator-min-microvolt = <900000>; 150 - regulator-max-microvolt = <1850000>; 151 - regulator-boot-on; 152 - regulator-always-on; 153 - }; 154 - }; 155 - }; 156 - };
+4
Documentation/devicetree/bindings/mfd/qnap,ts433-mcu.yaml
··· 16 16 properties: 17 17 compatible: 18 18 enum: 19 + - qnap,ts233-mcu 19 20 - qnap,ts433-mcu 21 + 22 + nvmem-layout: 23 + $ref: /schemas/nvmem/layouts/nvmem-layout.yaml 20 24 21 25 patternProperties: 22 26 "^fan-[0-9]+$":
+86
Documentation/devicetree/bindings/mfd/spacemit,p1.yaml
··· 1 + # SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/mfd/spacemit,p1.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: SpacemiT P1 Power Management Integrated Circuit 8 + 9 + maintainers: 10 + - Troy Mitchell <troy.mitchell@linux.spacemit.com> 11 + 12 + description: 13 + P1 is an I2C-controlled PMIC produced by SpacemiT. It implements six 14 + constant-on-time buck converters and twelve low-dropout regulators. 15 + It also contains a load switch, watchdog timer, real-time clock, eight 16 + 12-bit ADC channels, and six GPIOs. Additional details are available 17 + in the "Power Stone/P1" section at the following link. 18 + https://developer.spacemit.com/documentation 19 + 20 + properties: 21 + compatible: 22 + const: spacemit,p1 23 + 24 + reg: 25 + maxItems: 1 26 + 27 + interrupts: 28 + maxItems: 1 29 + 30 + vin-supply: 31 + description: Input supply phandle. 32 + 33 + regulators: 34 + type: object 35 + 36 + patternProperties: 37 + "^(buck[1-6]|aldo[1-4]|dldo[1-7])$": 38 + type: object 39 + $ref: /schemas/regulator/regulator.yaml# 40 + unevaluatedProperties: false 41 + 42 + unevaluatedProperties: false 43 + 44 + required: 45 + - compatible 46 + - reg 47 + - interrupts 48 + 49 + unevaluatedProperties: false 50 + 51 + examples: 52 + - | 53 + i2c { 54 + #address-cells = <1>; 55 + #size-cells = <0>; 56 + 57 + pmic@41 { 58 + compatible = "spacemit,p1"; 59 + reg = <0x41>; 60 + interrupts = <64>; 61 + 62 + regulators { 63 + buck1 { 64 + regulator-name = "buck1"; 65 + regulator-min-microvolt = <500000>; 66 + regulator-max-microvolt = <3450000>; 67 + regulator-ramp-delay = <5000>; 68 + regulator-always-on; 69 + }; 70 + 71 + aldo1 { 72 + regulator-name = "aldo1"; 73 + regulator-min-microvolt = <500000>; 74 + regulator-max-microvolt = <3400000>; 75 + regulator-boot-on; 76 + }; 77 + 78 + dldo1 { 79 + regulator-name = "dldo1"; 80 + regulator-min-microvolt = <500000>; 81 + regulator-max-microvolt = <3400000>; 82 + regulator-boot-on; 83 + }; 84 + }; 85 + }; 86 + };
+4
Documentation/devicetree/bindings/mfd/syscon.yaml
··· 79 79 - marvell,armada-3700-cpu-misc 80 80 - marvell,armada-3700-nb-pm 81 81 - marvell,armada-3700-avs 82 + - marvell,armada-3700-usb2-host-device-misc 82 83 - marvell,armada-3700-usb2-host-misc 83 84 - marvell,dove-global-config 84 85 - mediatek,mt2701-pctl-a-syscfg ··· 91 90 - mediatek,mt8173-pctl-a-syscfg 92 91 - mediatek,mt8365-syscfg 93 92 - microchip,lan966x-cpu-syscon 93 + - microchip,mpfs-control-scb 94 94 - microchip,mpfs-sysreg-scb 95 95 - microchip,sam9x60-sfr 96 96 - microchip,sama7d65-ddr3phy ··· 187 185 - marvell,armada-3700-cpu-misc 188 186 - marvell,armada-3700-nb-pm 189 187 - marvell,armada-3700-avs 188 + - marvell,armada-3700-usb2-host-device-misc 190 189 - marvell,armada-3700-usb2-host-misc 191 190 - marvell,dove-global-config 192 191 - mediatek,mt2701-pctl-a-syscfg ··· 200 197 - mediatek,mt8365-infracfg-nao 201 198 - mediatek,mt8365-syscfg 202 199 - microchip,lan966x-cpu-syscon 200 + - microchip,mpfs-control-scb 203 201 - microchip,mpfs-sysreg-scb 204 202 - microchip,sam9x60-sfr 205 203 - microchip,sama7d65-ddr3phy
+117
Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/mfd/ti,bq25703a.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: BQ25703A Charger Manager/Buck/Boost Converter 8 + 9 + maintainers: 10 + - Chris Morgan <macromorgan@hotmail.com> 11 + 12 + allOf: 13 + - $ref: /schemas/power/supply/power-supply.yaml# 14 + 15 + properties: 16 + compatible: 17 + const: ti,bq25703a 18 + 19 + reg: 20 + const: 0x6b 21 + 22 + input-current-limit-microamp: 23 + description: 24 + Maximum total input current allowed used for both charging and 25 + powering the device. 26 + minimum: 50000 27 + maximum: 6400000 28 + default: 3250000 29 + 30 + interrupts: 31 + maxItems: 1 32 + 33 + monitored-battery: 34 + description: 35 + A minimum of constant-charge-current-max-microamp, 36 + constant-charge-voltage-max-microvolt, and 37 + voltage-min-design-microvolt are required. 38 + 39 + regulators: 40 + type: object 41 + additionalProperties: false 42 + description: 43 + Boost converter regulator output of bq257xx. 44 + 45 + properties: 46 + vbus: 47 + type: object 48 + $ref: /schemas/regulator/regulator.yaml 49 + additionalProperties: false 50 + 51 + properties: 52 + regulator-name: true 53 + regulator-min-microamp: 54 + minimum: 0 55 + maximum: 6350000 56 + regulator-max-microamp: 57 + minimum: 0 58 + maximum: 6350000 59 + regulator-min-microvolt: 60 + minimum: 4480000 61 + maximum: 20800000 62 + regulator-max-microvolt: 63 + minimum: 4480000 64 + maximum: 20800000 65 + enable-gpios: 66 + description: 67 + The BQ25703 may require both a register write and a GPIO 68 + toggle to enable the boost regulator. 69 + 70 + required: 71 + - regulator-name 72 + - regulator-min-microamp 73 + - regulator-max-microamp 74 + - regulator-min-microvolt 75 + - regulator-max-microvolt 76 + 77 + unevaluatedProperties: false 78 + 79 + required: 80 + - compatible 81 + - reg 82 + - input-current-limit-microamp 83 + - monitored-battery 84 + - power-supplies 85 + 86 + examples: 87 + - | 88 + #include <dt-bindings/gpio/gpio.h> 89 + #include <dt-bindings/interrupt-controller/irq.h> 90 + #include <dt-bindings/pinctrl/rockchip.h> 91 + i2c { 92 + #address-cells = <1>; 93 + #size-cells = <0>; 94 + 95 + bq25703: charger@6b { 96 + compatible = "ti,bq25703a"; 97 + reg = <0x6b>; 98 + input-current-limit-microamp = <5000000>; 99 + interrupt-parent = <&gpio0>; 100 + interrupts = <RK_PD5 IRQ_TYPE_LEVEL_LOW>; 101 + monitored-battery = <&battery>; 102 + power-supplies = <&fusb302>; 103 + 104 + regulators { 105 + usb_otg_vbus: vbus { 106 + enable-gpios = <&gpio4 RK_PA6 GPIO_ACTIVE_HIGH>; 107 + regulator-max-microamp = <960000>; 108 + regulator-max-microvolt = <5088000>; 109 + regulator-min-microamp = <512000>; 110 + regulator-min-microvolt = <4992000>; 111 + regulator-name = "usb_otg_vbus"; 112 + }; 113 + }; 114 + }; 115 + }; 116 + 117 + ...
+1
Documentation/devicetree/bindings/mfd/ti,tps6594.yaml
··· 41 41 system-power-controller: true 42 42 43 43 gpio-controller: true 44 + gpio-line-names: true 44 45 45 46 '#gpio-cells': 46 47 const: 2
+272 -45
Documentation/devicetree/bindings/mfd/ti,twl.yaml
··· 11 11 12 12 description: | 13 13 The TWLs are Integrated Power Management Chips. 14 - Some version might contain much more analog function like 14 + Some versions might contain much more analog functions like 15 15 USB transceiver or Audio amplifier. 16 - These chips are connected to an i2c bus. 16 + These chips are connected to an I2C bus. 17 17 18 18 allOf: 19 19 - if: ··· 49 49 ti,retain-on-reset: false 50 50 51 51 properties: 52 - madc: 53 - type: object 54 - $ref: /schemas/iio/adc/ti,twl4030-madc.yaml 55 - unevaluatedProperties: false 56 - 57 52 charger: 58 - type: object 59 53 $ref: /schemas/power/supply/twl4030-charger.yaml 60 54 unevaluatedProperties: false 61 55 62 - pwrbutton: 63 - type: object 64 - additionalProperties: false 65 - properties: 66 - compatible: 67 - const: ti,twl4030-pwrbutton 68 - interrupts: 69 - items: 70 - - items: 71 - const: 8 56 + gpadc: false 72 57 73 - watchdog: 74 - type: object 75 - additionalProperties: false 76 - properties: 77 - compatible: 78 - const: ti,twl4030-wdt 58 + usb-comparator: false 59 + 79 60 - if: 80 61 properties: 81 62 compatible: ··· 87 106 88 107 properties: 89 108 charger: 90 - type: object 91 - properties: 92 - compatible: 93 - const: ti,twl6030-charger 109 + $ref: /schemas/power/supply/ti,twl6030-charger.yaml 110 + unevaluatedProperties: false 111 + 94 112 gpadc: 95 - type: object 96 113 properties: 97 114 compatible: 98 115 const: ti,twl6030-gpadc 116 + 117 + pwrbutton: false 118 + 119 + madc: false 120 + 121 + watchdog: false 122 + 123 + audio: false 124 + 125 + keypad: false 126 + 127 + twl4030-usb: false 128 + 129 + gpio: false 130 + 131 + power: false 132 + 99 133 - if: 100 134 properties: 101 135 compatible: ··· 138 142 139 143 properties: 140 144 charger: 141 - type: object 142 - properties: 143 - compatible: 144 - items: 145 - - const: ti,twl6032-charger 146 - - const: ti,twl6030-charger 145 + $ref: /schemas/power/supply/ti,twl6030-charger.yaml 146 + unevaluatedProperties: false 147 + 147 148 gpadc: 148 - type: object 149 149 properties: 150 150 compatible: 151 151 const: ti,twl6032-gpadc 152 152 153 + pwrbutton: false 154 + 155 + madc: false 156 + 157 + watchdog: false 158 + 159 + audio: false 160 + 161 + keypad: false 162 + 163 + twl4030-usb: false 164 + 165 + gpio: false 166 + 167 + power: false 168 + 153 169 properties: 154 170 compatible: 155 - description: 156 - TWL4030 for integrated power-management/audio CODEC device used in OMAP3 157 - based boards 171 + description: > 172 + TWL4030 for integrated power-management/audio CODEC device used in 173 + OMAP3 based boards. 174 + 158 175 TWL6030/32 for integrated power-management used in OMAP4 based boards 159 176 enum: 160 177 - ti,twl4030 ··· 190 181 "#clock-cells": 191 182 const: 1 192 183 184 + clocks: 185 + maxItems: 1 186 + 187 + clock-names: 188 + const: fck 189 + 193 190 charger: 194 191 type: object 195 - additionalProperties: true 192 + 196 193 properties: 197 194 compatible: true 195 + 198 196 required: 199 197 - compatible 200 198 201 199 rtc: 202 200 type: object 203 201 additionalProperties: false 202 + 204 203 properties: 205 204 compatible: 206 205 const: ti,twl4030-rtc 207 206 interrupts: 208 207 maxItems: 1 209 208 209 + madc: 210 + type: object 211 + $ref: /schemas/iio/adc/ti,twl4030-madc.yaml 212 + unevaluatedProperties: false 213 + 214 + pwrbutton: 215 + type: object 216 + additionalProperties: false 217 + 218 + properties: 219 + compatible: 220 + const: ti,twl4030-pwrbutton 221 + interrupts: 222 + items: 223 + - items: 224 + const: 8 225 + 226 + watchdog: 227 + type: object 228 + additionalProperties: false 229 + 230 + properties: 231 + compatible: 232 + const: ti,twl4030-wdt 233 + 234 + audio: 235 + type: object 236 + additionalProperties: true 237 + 238 + properties: 239 + compatible: 240 + const: ti,twl4030-audio 241 + 242 + required: 243 + - compatible 244 + 245 + keypad: 246 + type: object 247 + additionalProperties: true 248 + 249 + properties: 250 + compatible: 251 + const: ti,twl4030-keypad 252 + 253 + required: 254 + - compatible 255 + 256 + twl4030-usb: 257 + type: object 258 + additionalProperties: true 259 + 260 + properties: 261 + compatible: 262 + const: ti,twl4030-usb 263 + 264 + required: 265 + - compatible 266 + 267 + gpio: 268 + type: object 269 + additionalProperties: true 270 + 271 + properties: 272 + compatible: 273 + const: ti,twl4030-gpio 274 + 275 + required: 276 + - compatible 277 + 278 + power: 279 + type: object 280 + additionalProperties: false 281 + description: > 282 + The power management module inside the TWL4030 provides several 283 + facilities to control the power resources, including power scripts. 284 + 285 + For now, the binding only supports the complete shutdown of the 286 + system after poweroff. 287 + 288 + Board-specific compatible strings may be used for platform-specific 289 + power configurations. 290 + 291 + A board-specific compatible string (e.g., ti,twl4030-power-omap3-evm) 292 + may be paired with a generic fallback (generally for power saving mode). 293 + 294 + properties: 295 + compatible: 296 + oneOf: 297 + # Case 1: A single compatible string is provided. 298 + - enum: 299 + - ti,twl4030-power 300 + - ti,twl4030-power-reset 301 + - ti,twl4030-power-idle 302 + - ti,twl4030-power-idle-osc-off 303 + - ti,twl4030-power-omap3-sdp 304 + - ti,twl4030-power-omap3-ldp 305 + - ti,twl4030-power-omap3-evm 306 + 307 + # Case 2: The specific, valid fallback for 'idle-osc-off'. 308 + - items: 309 + - const: ti,twl4030-power-idle-osc-off 310 + - const: ti,twl4030-power-idle 311 + 312 + # Case 3: The specific, valid fallback for 'omap3-evm'. 313 + - items: 314 + - const: ti,twl4030-power-omap3-evm 315 + - const: ti,twl4030-power-idle 316 + 317 + ti,system-power-controller: 318 + type: boolean 319 + deprecated: true 320 + description: > 321 + DEPRECATED. The standard 'system-power-controller' 322 + property on the parent node should be used instead. 323 + 324 + ti,use_poweroff: 325 + type: boolean 326 + deprecated: true 327 + description: DEPRECATED, to be removed. 328 + 329 + required: 330 + - compatible 331 + 332 + gpadc: 333 + type: object 334 + $ref: /schemas/iio/adc/ti,twl6030-gpadc.yaml 335 + unevaluatedProperties: false 336 + 337 + properties: 338 + compatible: true 339 + 340 + usb-comparator: 341 + type: object 342 + additionalProperties: true 343 + 344 + properties: 345 + compatible: 346 + const: ti,twl6030-usb 347 + 348 + required: 349 + - compatible 350 + 351 + pwm: 352 + type: object 353 + $ref: /schemas/pwm/pwm.yaml# 354 + unevaluatedProperties: false 355 + description: 356 + PWM controllers (PWM1 and PWM2 on TWL4030, PWM0 and PWM1 on TWL6030/32). 357 + 358 + properties: 359 + compatible: 360 + enum: 361 + - ti,twl4030-pwm 362 + - ti,twl6030-pwm 363 + 364 + '#pwm-cells': 365 + const: 2 366 + 367 + required: 368 + - compatible 369 + - '#pwm-cells' 370 + 371 + pwmled: 372 + type: object 373 + $ref: /schemas/pwm/pwm.yaml# 374 + unevaluatedProperties: false 375 + description: > 376 + PWM controllers connected to LED terminals (PWMA and PWMB on TWL4030. 377 + 378 + LED PWM on TWL6030/32, mainly used as charging indicator LED). 379 + 380 + properties: 381 + compatible: 382 + enum: 383 + - ti,twl4030-pwmled 384 + - ti,twl6030-pwmled 385 + 386 + '#pwm-cells': 387 + const: 2 388 + 389 + required: 390 + - compatible 391 + - '#pwm-cells' 392 + 210 393 patternProperties: 211 394 "^regulator-": 212 395 type: object 213 396 unevaluatedProperties: false 214 397 $ref: /schemas/regulator/regulator.yaml 398 + 215 399 properties: 216 400 compatible: true 217 401 regulator-initial-mode: ··· 413 211 # with low power consumption with low load current capability 414 212 - 0x0e # Active mode, the regulator can deliver its nominal output 415 213 # voltage with full-load current capability 214 + 416 215 ti,retain-on-reset: 417 - description: 418 - Does not turn off the supplies during warm 419 - reset. Could be needed for VMMC, as TWL6030 420 - reset sequence for this signal does not comply 421 - with the SD specification. 216 + description: > 217 + Does not turn off the supplies during warm reset. 218 + 219 + Could be needed for VMMC, as TWL6030 reset sequence for 220 + this signal does not comply with the SD specification. 422 221 type: boolean 423 222 424 223 unevaluatedProperties: false ··· 474 271 compatible = "ti,twl6030-vmmc"; 475 272 ti,retain-on-reset; 476 273 }; 274 + 275 + pwm { 276 + compatible = "ti,twl6030-pwm"; 277 + #pwm-cells = <2>; 278 + }; 279 + 280 + pwmled { 281 + compatible = "ti,twl6030-pwmled"; 282 + #pwm-cells = <2>; 283 + }; 477 284 }; 478 285 }; 479 286 ··· 537 324 538 325 watchdog { 539 326 compatible = "ti,twl4030-wdt"; 327 + }; 328 + 329 + power { 330 + compatible = "ti,twl4030-power"; 331 + }; 332 + 333 + pwm { 334 + compatible = "ti,twl4030-pwm"; 335 + #pwm-cells = <2>; 336 + }; 337 + 338 + pwmled { 339 + compatible = "ti,twl4030-pwmled"; 340 + #pwm-cells = <2>; 540 341 }; 541 342 }; 542 343 };
-48
Documentation/devicetree/bindings/mfd/twl4030-power.txt
··· 1 - Texas Instruments TWL family (twl4030) reset and power management module 2 - 3 - The power management module inside the TWL family provides several facilities 4 - to control the power resources, including power scripts. For now, the 5 - binding only supports the complete shutdown of the system after poweroff. 6 - 7 - Required properties: 8 - - compatible : must be one of the following 9 - "ti,twl4030-power" 10 - "ti,twl4030-power-reset" 11 - "ti,twl4030-power-idle" 12 - "ti,twl4030-power-idle-osc-off" 13 - 14 - The use of ti,twl4030-power-reset is recommended at least on 15 - 3530 that needs a special configuration for warm reset to work. 16 - 17 - When using ti,twl4030-power-idle, the TI recommended configuration 18 - for idle modes is loaded to the tlw4030 PMIC. 19 - 20 - When using ti,twl4030-power-idle-osc-off, the TI recommended 21 - configuration is used with the external oscillator being shut 22 - down during off-idle. Note that this does not work on all boards 23 - depending on how the external oscillator is wired. 24 - 25 - Optional properties: 26 - 27 - - ti,system-power-controller: This indicates that TWL4030 is the 28 - power supply master of the system. With this flag, the chip will 29 - initiate an ACTIVE-to-OFF or SLEEP-to-OFF transition when the 30 - system poweroffs. 31 - 32 - - ti,use_poweroff: Deprecated name for ti,system-power-controller 33 - 34 - Example: 35 - &i2c1 { 36 - clock-frequency = <2600000>; 37 - 38 - twl: twl@48 { 39 - reg = <0x48>; 40 - interrupts = <7>; /* SYS_NIRQ cascaded to intc */ 41 - interrupt-parent = <&intc>; 42 - 43 - twl_power: power { 44 - compatible = "ti,twl4030-power"; 45 - ti,use_poweroff; 46 - }; 47 - }; 48 - };
-46
Documentation/devicetree/bindings/misc/aspeed-p2a-ctrl.txt
··· 1 - ====================================================================== 2 - Device tree bindings for Aspeed AST2400/AST2500 PCI-to-AHB Bridge Control Driver 3 - ====================================================================== 4 - 5 - The bridge is available on platforms with the VGA enabled on the Aspeed device. 6 - In this case, the host has access to a 64KiB window into all of the BMC's 7 - memory. The BMC can disable this bridge. If the bridge is enabled, the host 8 - has read access to all the regions of memory, however the host only has read 9 - and write access depending on a register controlled by the BMC. 10 - 11 - Required properties: 12 - =================== 13 - 14 - - compatible: must be one of: 15 - - "aspeed,ast2400-p2a-ctrl" 16 - - "aspeed,ast2500-p2a-ctrl" 17 - 18 - Optional properties: 19 - =================== 20 - 21 - - reg: A hint for the memory regions associated with the P2A controller 22 - - memory-region: A phandle to a reserved_memory region to be used for the PCI 23 - to AHB mapping 24 - 25 - The p2a-control node should be the child of a syscon node with the required 26 - property: 27 - 28 - - compatible : Should be one of the following: 29 - "aspeed,ast2400-scu", "syscon", "simple-mfd" 30 - "aspeed,ast2500-scu", "syscon", "simple-mfd" 31 - 32 - Example 33 - =================== 34 - 35 - g4 Example 36 - ---------- 37 - 38 - syscon: scu@1e6e2000 { 39 - compatible = "aspeed,ast2400-scu", "syscon", "simple-mfd"; 40 - reg = <0x1e6e2000 0x1a8>; 41 - 42 - p2a: p2a-control { 43 - compatible = "aspeed,ast2400-p2a-ctrl"; 44 - memory-region = <&reserved_memory>; 45 - }; 46 - };
+1 -1
Documentation/devicetree/bindings/platform/acer,aspire1-ec.yaml Documentation/devicetree/bindings/embedded-controller/acer,aspire1-ec.yaml
··· 1 1 # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 2 %YAML 1.2 3 3 --- 4 - $id: http://devicetree.org/schemas/platform/acer,aspire1-ec.yaml# 4 + $id: http://devicetree.org/schemas/embedded-controller/acer,aspire1-ec.yaml# 5 5 $schema: http://devicetree.org/meta-schemas/core.yaml# 6 6 7 7 title: Acer Aspire 1 Embedded Controller
+1 -1
Documentation/devicetree/bindings/platform/huawei,gaokun-ec.yaml Documentation/devicetree/bindings/embedded-controller/huawei,gaokun3-ec.yaml
··· 1 1 # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 2 %YAML 1.2 3 3 --- 4 - $id: http://devicetree.org/schemas/platform/huawei,gaokun-ec.yaml# 4 + $id: http://devicetree.org/schemas/embedded-controller/huawei,gaokun3-ec.yaml# 5 5 $schema: http://devicetree.org/meta-schemas/core.yaml# 6 6 7 7 title: Huawei Matebook E Go Embedded Controller
+1 -1
Documentation/devicetree/bindings/platform/lenovo,yoga-c630-ec.yaml Documentation/devicetree/bindings/embedded-controller/lenovo,yoga-c630-ec.yaml
··· 1 1 # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 2 %YAML 1.2 3 3 --- 4 - $id: http://devicetree.org/schemas/platform/lenovo,yoga-c630-ec.yaml# 4 + $id: http://devicetree.org/schemas/embedded-controller/lenovo,yoga-c630-ec.yaml# 5 5 $schema: http://devicetree.org/meta-schemas/core.yaml# 6 6 7 7 title: Lenovo Yoga C630 Embedded Controller.
+1 -1
Documentation/devicetree/bindings/platform/microsoft,surface-sam.yaml Documentation/devicetree/bindings/embedded-controller/microsoft,surface-sam.yaml
··· 1 1 # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 2 %YAML 1.2 3 3 --- 4 - $id: http://devicetree.org/schemas/platform/microsoft,surface-sam.yaml# 4 + $id: http://devicetree.org/schemas/embedded-controller/microsoft,surface-sam.yaml# 5 5 $schema: http://devicetree.org/meta-schemas/core.yaml# 6 6 7 7 title: Surface System Aggregator Module (SAM, SSAM)
+1 -1
Documentation/devicetree/bindings/pwm/google,cros-ec-pwm.yaml
··· 14 14 Google's ChromeOS EC PWM is a simple PWM attached to the Embedded Controller 15 15 (EC) and controlled via a host-command interface. 16 16 An EC PWM node should be only found as a sub-node of the EC node (see 17 - Documentation/devicetree/bindings/mfd/google,cros-ec.yaml). 17 + Documentation/devicetree/bindings/embedded-controller/google,cros-ec.yaml). 18 18 19 19 allOf: 20 20 - $ref: pwm.yaml#
+1 -1
Documentation/devicetree/bindings/pwm/kontron,sl28cpld-pwm.yaml
··· 11 11 12 12 description: | 13 13 This module is part of the sl28cpld multi-function device. For more 14 - details see ../mfd/kontron,sl28cpld.yaml. 14 + details see ../embedded-controller/kontron,sl28cpld.yaml. 15 15 16 16 The controller supports one PWM channel and supports only four distinct 17 17 frequencies (250Hz, 500Hz, 1kHz, 2kHz).
-17
Documentation/devicetree/bindings/pwm/ti,twl-pwm.txt
··· 1 - Texas Instruments TWL series PWM drivers 2 - 3 - Supported PWMs: 4 - On TWL4030 series: PWM1 and PWM2 5 - On TWL6030 series: PWM0 and PWM1 6 - 7 - Required properties: 8 - - compatible: "ti,twl4030-pwm" or "ti,twl6030-pwm" 9 - - #pwm-cells: should be 2. See pwm.yaml in this directory for a description of 10 - the cells format. 11 - 12 - Example: 13 - 14 - twl_pwm: pwm { 15 - compatible = "ti,twl6030-pwm"; 16 - #pwm-cells = <2>; 17 - };
-17
Documentation/devicetree/bindings/pwm/ti,twl-pwmled.txt
··· 1 - Texas Instruments TWL series PWM drivers connected to LED terminals 2 - 3 - Supported PWMs: 4 - On TWL4030 series: PWMA and PWMB (connected to LEDA and LEDB terminals) 5 - On TWL6030 series: LED PWM (mainly used as charging indicator LED) 6 - 7 - Required properties: 8 - - compatible: "ti,twl4030-pwmled" or "ti,twl6030-pwmled" 9 - - #pwm-cells: should be 2. See pwm.yaml in this directory for a description of 10 - the cells format. 11 - 12 - Example: 13 - 14 - twl_pwmled: pwmled { 15 - compatible = "ti,twl6030-pwmled"; 16 - #pwm-cells = <2>; 17 - };
+2 -2
Documentation/devicetree/bindings/remoteproc/mtk,scp.yaml
··· 58 58 maxItems: 1 59 59 60 60 cros-ec-rpmsg: 61 - $ref: /schemas/mfd/google,cros-ec.yaml 61 + $ref: /schemas/embedded-controller/google,cros-ec.yaml 62 62 description: 63 63 This subnode represents the rpmsg device. The properties 64 64 of this node are defined by the individual bindings for ··· 126 126 maxItems: 1 127 127 128 128 cros-ec-rpmsg: 129 - $ref: /schemas/mfd/google,cros-ec.yaml 129 + $ref: /schemas/embedded-controller/google,cros-ec.yaml 130 130 description: 131 131 This subnode represents the rpmsg device. The properties 132 132 of this node are defined by the individual bindings for
+1 -1
Documentation/devicetree/bindings/sound/google,cros-ec-codec.yaml
··· 15 15 Embedded Controller (EC) and is controlled via a host-command 16 16 interface. An EC codec node should only be found inside the "codecs" 17 17 subnode of a cros-ec node. 18 - (see Documentation/devicetree/bindings/mfd/google,cros-ec.yaml). 18 + (see Documentation/devicetree/bindings/embedded-controller/google,cros-ec.yaml). 19 19 20 20 allOf: 21 21 - $ref: dai-common.yaml#
+7 -2
Documentation/devicetree/bindings/watchdog/kontron,sl28cpld-wdt.yaml
··· 11 11 12 12 description: | 13 13 This module is part of the sl28cpld multi-function device. For more 14 - details see ../mfd/kontron,sl28cpld.yaml. 14 + details see ../embedded-controller/kontron,sl28cpld.yaml. 15 15 16 16 allOf: 17 17 - $ref: watchdog.yaml# 18 18 19 19 properties: 20 20 compatible: 21 - const: kontron,sl28cpld-wdt 21 + oneOf: 22 + - items: 23 + - enum: 24 + - kontron,sa67mcu-wdt 25 + - const: kontron,sl28cpld-wdt 26 + - const: kontron,sl28cpld-wdt 22 27 23 28 reg: 24 29 maxItems: 1
+18 -3
MAINTAINERS
··· 10185 10185 GATEWORKS SYSTEM CONTROLLER (GSC) DRIVER 10186 10186 M: Tim Harvey <tharvey@gateworks.com> 10187 10187 S: Maintained 10188 - F: Documentation/devicetree/bindings/mfd/gateworks-gsc.yaml 10188 + F: Documentation/devicetree/bindings/embedded-controller/gw,gsc.yaml 10189 10189 F: Documentation/hwmon/gsc-hwmon.rst 10190 10190 F: drivers/hwmon/gsc-hwmon.c 10191 10191 F: drivers/mfd/gateworks-gsc.c ··· 11366 11366 HUAWEI MATEBOOK E GO EMBEDDED CONTROLLER DRIVER 11367 11367 M: Pengyu Luo <mitltlatltl@gmail.com> 11368 11368 S: Maintained 11369 - F: Documentation/devicetree/bindings/platform/huawei,gaokun-ec.yaml 11369 + F: Documentation/devicetree/bindings/embedded-controller/huawei,gaokun3-ec.yaml 11370 11370 F: drivers/platform/arm64/huawei-gaokun-ec.c 11371 11371 F: drivers/power/supply/huawei-gaokun-battery.c 11372 11372 F: drivers/usb/typec/ucsi/ucsi_huawei_gaokun.c ··· 14417 14417 F: Documentation/devicetree/bindings/pwm/loongson,ls7a-pwm.yaml 14418 14418 F: drivers/pwm/pwm-loongson.c 14419 14419 14420 + LOONGSON SECURITY ENGINE DRIVERS 14421 + M: Qunqin Zhao <zhaoqunqin@loongson.cn> 14422 + L: linux-crypto@vger.kernel.org 14423 + S: Maintained 14424 + F: drivers/char/tpm/tpm_loongson.c 14425 + F: drivers/crypto/loongson/ 14426 + F: drivers/mfd/loongson-se.c 14427 + F: include/linux/mfd/loongson-se.h 14428 + 14420 14429 LOONGSON-2 SOC SERIES CLOCK DRIVER 14421 14430 M: Yinbo Zhu <zhuyinbo@loongson.cn> 14422 14431 L: linux-clk@vger.kernel.org ··· 14480 14471 S: Maintained 14481 14472 F: Documentation/devicetree/bindings/thermal/loongson,ls2k-thermal.yaml 14482 14473 F: drivers/thermal/loongson2_thermal.c 14474 + 14475 + LOONGSON-2K Board Management Controller (BMC) DRIVER 14476 + M: Binbin Zhou <zhoubinbin@loongson.cn> 14477 + M: Chong Qiao <qiaochong@loongson.cn> 14478 + S: Maintained 14479 + F: drivers/mfd/ls2k-bmc-core.c 14483 14480 14484 14481 LOONGSON EDAC DRIVER 14485 14482 M: Zhao Qunqin <zhaoqunqin@loongson.cn> ··· 23327 23312 SL28 CPLD MFD DRIVER 23328 23313 M: Michael Walle <mwalle@kernel.org> 23329 23314 S: Maintained 23315 + F: Documentation/devicetree/bindings/embedded-controller/kontron,sl28cpld.yaml 23330 23316 F: Documentation/devicetree/bindings/gpio/kontron,sl28cpld-gpio.yaml 23331 23317 F: Documentation/devicetree/bindings/hwmon/kontron,sl28cpld-hwmon.yaml 23332 23318 F: Documentation/devicetree/bindings/interrupt-controller/kontron,sl28cpld-intc.yaml 23333 - F: Documentation/devicetree/bindings/mfd/kontron,sl28cpld.yaml 23334 23319 F: Documentation/devicetree/bindings/pwm/kontron,sl28cpld-pwm.yaml 23335 23320 F: Documentation/devicetree/bindings/watchdog/kontron,sl28cpld-wdt.yaml 23336 23321 F: drivers/gpio/gpio-sl28cpld.c
+9
drivers/char/tpm/Kconfig
··· 189 189 will be accessible from within Linux. To compile this driver 190 190 as a module, choose M here; the module will be called tpm_ibmvtpm. 191 191 192 + config TCG_LOONGSON 193 + tristate "Loongson TPM Interface" 194 + depends on MFD_LOONGSON_SE 195 + help 196 + If you want to make Loongson TPM support available, say Yes and 197 + it will be accessible from within Linux. To compile this 198 + driver as a module, choose M here; the module will be called 199 + tpm_loongson. 200 + 192 201 config TCG_XEN 193 202 tristate "XEN TPM Interface" 194 203 depends on TCG_TPM && XEN
+1
drivers/char/tpm/Makefile
··· 46 46 obj-$(CONFIG_TCG_VTPM_PROXY) += tpm_vtpm_proxy.o 47 47 obj-$(CONFIG_TCG_FTPM_TEE) += tpm_ftpm_tee.o 48 48 obj-$(CONFIG_TCG_SVSM) += tpm_svsm.o 49 + obj-$(CONFIG_TCG_LOONGSON) += tpm_loongson.o
+84
drivers/char/tpm/tpm_loongson.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* Copyright (c) 2025 Loongson Technology Corporation Limited. */ 3 + 4 + #include <linux/device.h> 5 + #include <linux/mfd/loongson-se.h> 6 + #include <linux/platform_device.h> 7 + #include <linux/wait.h> 8 + 9 + #include "tpm.h" 10 + 11 + struct tpm_loongson_cmd { 12 + u32 cmd_id; 13 + u32 data_off; 14 + u32 data_len; 15 + u32 pad[5]; 16 + }; 17 + 18 + static int tpm_loongson_recv(struct tpm_chip *chip, u8 *buf, size_t count) 19 + { 20 + struct loongson_se_engine *tpm_engine = dev_get_drvdata(&chip->dev); 21 + struct tpm_loongson_cmd *cmd_ret = tpm_engine->command_ret; 22 + 23 + if (cmd_ret->data_len > count) 24 + return -EIO; 25 + 26 + memcpy(buf, tpm_engine->data_buffer, cmd_ret->data_len); 27 + 28 + return cmd_ret->data_len; 29 + } 30 + 31 + static int tpm_loongson_send(struct tpm_chip *chip, u8 *buf, size_t bufsiz, size_t count) 32 + { 33 + struct loongson_se_engine *tpm_engine = dev_get_drvdata(&chip->dev); 34 + struct tpm_loongson_cmd *cmd = tpm_engine->command; 35 + 36 + if (count > tpm_engine->buffer_size) 37 + return -E2BIG; 38 + 39 + cmd->data_len = count; 40 + memcpy(tpm_engine->data_buffer, buf, count); 41 + 42 + return loongson_se_send_engine_cmd(tpm_engine); 43 + } 44 + 45 + static const struct tpm_class_ops tpm_loongson_ops = { 46 + .flags = TPM_OPS_AUTO_STARTUP, 47 + .recv = tpm_loongson_recv, 48 + .send = tpm_loongson_send, 49 + }; 50 + 51 + static int tpm_loongson_probe(struct platform_device *pdev) 52 + { 53 + struct loongson_se_engine *tpm_engine; 54 + struct device *dev = &pdev->dev; 55 + struct tpm_loongson_cmd *cmd; 56 + struct tpm_chip *chip; 57 + 58 + tpm_engine = loongson_se_init_engine(dev->parent, SE_ENGINE_TPM); 59 + if (!tpm_engine) 60 + return -ENODEV; 61 + cmd = tpm_engine->command; 62 + cmd->cmd_id = SE_CMD_TPM; 63 + cmd->data_off = tpm_engine->buffer_off; 64 + 65 + chip = tpmm_chip_alloc(dev, &tpm_loongson_ops); 66 + if (IS_ERR(chip)) 67 + return PTR_ERR(chip); 68 + chip->flags = TPM_CHIP_FLAG_TPM2 | TPM_CHIP_FLAG_IRQ; 69 + dev_set_drvdata(&chip->dev, tpm_engine); 70 + 71 + return tpm_chip_register(chip); 72 + } 73 + 74 + static struct platform_driver tpm_loongson = { 75 + .probe = tpm_loongson_probe, 76 + .driver = { 77 + .name = "tpm_loongson", 78 + }, 79 + }; 80 + module_platform_driver(tpm_loongson); 81 + 82 + MODULE_ALIAS("platform:tpm_loongson"); 83 + MODULE_LICENSE("GPL"); 84 + MODULE_DESCRIPTION("Loongson TPM driver");
+1
drivers/crypto/Kconfig
··· 840 840 If unsure say Y. 841 841 842 842 source "drivers/crypto/hisilicon/Kconfig" 843 + source "drivers/crypto/loongson/Kconfig" 843 844 844 845 source "drivers/crypto/amlogic/Kconfig" 845 846
+1
drivers/crypto/Makefile
··· 44 44 obj-$(CONFIG_CRYPTO_DEV_ARTPEC6) += axis/ 45 45 obj-y += xilinx/ 46 46 obj-y += hisilicon/ 47 + obj-y += loongson/ 47 48 obj-$(CONFIG_CRYPTO_DEV_AMLOGIC_GXL) += amlogic/ 48 49 obj-y += intel/ 49 50 obj-y += starfive/
+5
drivers/crypto/loongson/Kconfig
··· 1 + config CRYPTO_DEV_LOONGSON_RNG 2 + tristate "Support for Loongson RNG Driver" 3 + depends on MFD_LOONGSON_SE 4 + help 5 + Support for Loongson RNG Driver.
+1
drivers/crypto/loongson/Makefile
··· 1 + obj-$(CONFIG_CRYPTO_DEV_LOONGSON_RNG) += loongson-rng.o
+209
drivers/crypto/loongson/loongson-rng.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* Copyright (c) 2019 HiSilicon Limited. */ 3 + /* Copyright (c) 2025 Loongson Technology Corporation Limited. */ 4 + 5 + #include <linux/crypto.h> 6 + #include <linux/err.h> 7 + #include <linux/hw_random.h> 8 + #include <linux/io.h> 9 + #include <linux/iopoll.h> 10 + #include <linux/kernel.h> 11 + #include <linux/list.h> 12 + #include <linux/mfd/loongson-se.h> 13 + #include <linux/module.h> 14 + #include <linux/mutex.h> 15 + #include <linux/platform_device.h> 16 + #include <linux/random.h> 17 + #include <crypto/internal/rng.h> 18 + 19 + #define SE_SEED_SIZE 32 20 + 21 + struct loongson_rng_list { 22 + struct mutex lock; 23 + struct list_head list; 24 + int registered; 25 + }; 26 + 27 + struct loongson_rng { 28 + u32 used; 29 + struct loongson_se_engine *engine; 30 + struct list_head list; 31 + struct mutex lock; 32 + }; 33 + 34 + struct loongson_rng_ctx { 35 + struct loongson_rng *rng; 36 + }; 37 + 38 + struct loongson_rng_cmd { 39 + u32 cmd_id; 40 + union { 41 + u32 len; 42 + u32 ret; 43 + } u; 44 + u32 seed_off; 45 + u32 out_off; 46 + u32 pad[4]; 47 + }; 48 + 49 + static struct loongson_rng_list rng_devices = { 50 + .lock = __MUTEX_INITIALIZER(rng_devices.lock), 51 + .list = LIST_HEAD_INIT(rng_devices.list), 52 + }; 53 + 54 + static int loongson_rng_generate(struct crypto_rng *tfm, const u8 *src, 55 + unsigned int slen, u8 *dstn, unsigned int dlen) 56 + { 57 + struct loongson_rng_ctx *ctx = crypto_rng_ctx(tfm); 58 + struct loongson_rng *rng = ctx->rng; 59 + struct loongson_rng_cmd *cmd = rng->engine->command; 60 + int err, len; 61 + 62 + mutex_lock(&rng->lock); 63 + cmd->seed_off = 0; 64 + do { 65 + len = min(dlen, rng->engine->buffer_size); 66 + cmd = rng->engine->command; 67 + cmd->u.len = len; 68 + err = loongson_se_send_engine_cmd(rng->engine); 69 + if (err) 70 + break; 71 + 72 + cmd = rng->engine->command_ret; 73 + if (cmd->u.ret) { 74 + err = -EIO; 75 + break; 76 + } 77 + 78 + memcpy(dstn, rng->engine->data_buffer, len); 79 + dlen -= len; 80 + dstn += len; 81 + } while (dlen > 0); 82 + mutex_unlock(&rng->lock); 83 + 84 + return err; 85 + } 86 + 87 + static int loongson_rng_init(struct crypto_tfm *tfm) 88 + { 89 + struct loongson_rng_ctx *ctx = crypto_tfm_ctx(tfm); 90 + struct loongson_rng *rng; 91 + u32 min_used = U32_MAX; 92 + 93 + mutex_lock(&rng_devices.lock); 94 + list_for_each_entry(rng, &rng_devices.list, list) { 95 + if (rng->used < min_used) { 96 + ctx->rng = rng; 97 + min_used = rng->used; 98 + } 99 + } 100 + ctx->rng->used++; 101 + mutex_unlock(&rng_devices.lock); 102 + 103 + return 0; 104 + } 105 + 106 + static void loongson_rng_exit(struct crypto_tfm *tfm) 107 + { 108 + struct loongson_rng_ctx *ctx = crypto_tfm_ctx(tfm); 109 + 110 + mutex_lock(&rng_devices.lock); 111 + ctx->rng->used--; 112 + mutex_unlock(&rng_devices.lock); 113 + } 114 + 115 + static int loongson_rng_seed(struct crypto_rng *tfm, const u8 *seed, 116 + unsigned int slen) 117 + { 118 + struct loongson_rng_ctx *ctx = crypto_rng_ctx(tfm); 119 + struct loongson_rng *rng = ctx->rng; 120 + struct loongson_rng_cmd *cmd; 121 + int err; 122 + 123 + if (slen < SE_SEED_SIZE) 124 + return -EINVAL; 125 + 126 + slen = min(slen, rng->engine->buffer_size); 127 + 128 + mutex_lock(&rng->lock); 129 + cmd = rng->engine->command; 130 + cmd->u.len = slen; 131 + cmd->seed_off = rng->engine->buffer_off; 132 + memcpy(rng->engine->data_buffer, seed, slen); 133 + err = loongson_se_send_engine_cmd(rng->engine); 134 + if (err) 135 + goto out; 136 + 137 + cmd = rng->engine->command_ret; 138 + if (cmd->u.ret) 139 + err = -EIO; 140 + out: 141 + mutex_unlock(&rng->lock); 142 + 143 + return err; 144 + } 145 + 146 + static struct rng_alg loongson_rng_alg = { 147 + .generate = loongson_rng_generate, 148 + .seed = loongson_rng_seed, 149 + .seedsize = SE_SEED_SIZE, 150 + .base = { 151 + .cra_name = "stdrng", 152 + .cra_driver_name = "loongson_stdrng", 153 + .cra_priority = 300, 154 + .cra_ctxsize = sizeof(struct loongson_rng_ctx), 155 + .cra_module = THIS_MODULE, 156 + .cra_init = loongson_rng_init, 157 + .cra_exit = loongson_rng_exit, 158 + }, 159 + }; 160 + 161 + static int loongson_rng_probe(struct platform_device *pdev) 162 + { 163 + struct loongson_rng_cmd *cmd; 164 + struct loongson_rng *rng; 165 + int ret = 0; 166 + 167 + rng = devm_kzalloc(&pdev->dev, sizeof(*rng), GFP_KERNEL); 168 + if (!rng) 169 + return -ENOMEM; 170 + 171 + rng->engine = loongson_se_init_engine(pdev->dev.parent, SE_ENGINE_RNG); 172 + if (!rng->engine) 173 + return -ENODEV; 174 + cmd = rng->engine->command; 175 + cmd->cmd_id = SE_CMD_RNG; 176 + cmd->out_off = rng->engine->buffer_off; 177 + mutex_init(&rng->lock); 178 + 179 + mutex_lock(&rng_devices.lock); 180 + 181 + if (!rng_devices.registered) { 182 + ret = crypto_register_rng(&loongson_rng_alg); 183 + if (ret) { 184 + dev_err(&pdev->dev, "failed to register crypto(%d)\n", ret); 185 + goto out; 186 + } 187 + rng_devices.registered = 1; 188 + } 189 + 190 + list_add_tail(&rng->list, &rng_devices.list); 191 + out: 192 + mutex_unlock(&rng_devices.lock); 193 + 194 + return ret; 195 + } 196 + 197 + static struct platform_driver loongson_rng_driver = { 198 + .probe = loongson_rng_probe, 199 + .driver = { 200 + .name = "loongson-rng", 201 + }, 202 + }; 203 + module_platform_driver(loongson_rng_driver); 204 + 205 + MODULE_ALIAS("platform:loongson-rng"); 206 + MODULE_LICENSE("GPL"); 207 + MODULE_AUTHOR("Yinggang Gu <guyinggang@loongson.cn>"); 208 + MODULE_AUTHOR("Qunqin Zhao <zhaoqunqin@loongson.cn>"); 209 + MODULE_DESCRIPTION("Loongson Random Number Generator driver");
+10
drivers/input/misc/Kconfig
··· 516 516 To compile this driver as a module, choose M here. The module will 517 517 be called tps65219-pwrbutton. 518 518 519 + config INPUT_TPS6594_PWRBUTTON 520 + tristate "TPS6594 Power button driver" 521 + depends on MFD_TPS6594 522 + help 523 + Say Y here if you want to enable power button reporting for 524 + TPS6594 Power Management IC devices. 525 + 526 + To compile this driver as a module, choose M here. The module will 527 + be called tps6594-pwrbutton. 528 + 519 529 config INPUT_AXP20X_PEK 520 530 tristate "X-Powers AXP20X power button driver" 521 531 depends on MFD_AXP20X
+1
drivers/input/misc/Makefile
··· 84 84 obj-$(CONFIG_INPUT_STPMIC1_ONKEY) += stpmic1_onkey.o 85 85 obj-$(CONFIG_INPUT_TPS65218_PWRBUTTON) += tps65218-pwrbutton.o 86 86 obj-$(CONFIG_INPUT_TPS65219_PWRBUTTON) += tps65219-pwrbutton.o 87 + obj-$(CONFIG_INPUT_TPS6594_PWRBUTTON) += tps6594-pwrbutton.o 87 88 obj-$(CONFIG_INPUT_TWL4030_PWRBUTTON) += twl4030-pwrbutton.o 88 89 obj-$(CONFIG_INPUT_TWL4030_VIBRA) += twl4030-vibra.o 89 90 obj-$(CONFIG_INPUT_TWL6040_VIBRA) += twl6040-vibra.o
-1
drivers/input/misc/mc13783-pwrbutton.c
··· 57 57 struct mc13783_pwrb *priv = _priv; 58 58 int val; 59 59 60 - mc13xxx_irq_ack(priv->mc13783, irq); 61 60 mc13xxx_reg_read(priv->mc13783, MC13783_REG_INTERRUPT_SENSE_1, &val); 62 61 63 62 switch (irq) {
+126
drivers/input/misc/tps6594-pwrbutton.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * power button driver for TI TPS6594 PMICs 4 + * 5 + * Copyright (C) 2025 Critical Link LLC - https://www.criticallink.com/ 6 + */ 7 + #include <linux/init.h> 8 + #include <linux/input.h> 9 + #include <linux/interrupt.h> 10 + #include <linux/kernel.h> 11 + #include <linux/mfd/tps6594.h> 12 + #include <linux/module.h> 13 + #include <linux/platform_device.h> 14 + #include <linux/regmap.h> 15 + #include <linux/slab.h> 16 + 17 + struct tps6594_pwrbutton { 18 + struct device *dev; 19 + struct input_dev *idev; 20 + char phys[32]; 21 + }; 22 + 23 + static irqreturn_t tps6594_pb_push_irq(int irq, void *_pwr) 24 + { 25 + struct tps6594_pwrbutton *pwr = _pwr; 26 + 27 + input_report_key(pwr->idev, KEY_POWER, 1); 28 + pm_wakeup_event(pwr->dev, 0); 29 + input_sync(pwr->idev); 30 + 31 + return IRQ_HANDLED; 32 + } 33 + 34 + static irqreturn_t tps6594_pb_release_irq(int irq, void *_pwr) 35 + { 36 + struct tps6594_pwrbutton *pwr = _pwr; 37 + 38 + input_report_key(pwr->idev, KEY_POWER, 0); 39 + input_sync(pwr->idev); 40 + 41 + return IRQ_HANDLED; 42 + } 43 + 44 + static int tps6594_pb_probe(struct platform_device *pdev) 45 + { 46 + struct device *dev = &pdev->dev; 47 + struct tps6594_pwrbutton *pwr; 48 + struct input_dev *idev; 49 + int error; 50 + int push_irq; 51 + int release_irq; 52 + 53 + pwr = devm_kzalloc(dev, sizeof(*pwr), GFP_KERNEL); 54 + if (!pwr) 55 + return -ENOMEM; 56 + 57 + idev = devm_input_allocate_device(dev); 58 + if (!idev) 59 + return -ENOMEM; 60 + 61 + idev->name = pdev->name; 62 + snprintf(pwr->phys, sizeof(pwr->phys), "%s/input0", 63 + pdev->name); 64 + idev->phys = pwr->phys; 65 + idev->id.bustype = BUS_I2C; 66 + 67 + input_set_capability(idev, EV_KEY, KEY_POWER); 68 + 69 + pwr->dev = dev; 70 + pwr->idev = idev; 71 + device_init_wakeup(dev, true); 72 + 73 + push_irq = platform_get_irq(pdev, 0); 74 + if (push_irq < 0) 75 + return -EINVAL; 76 + 77 + release_irq = platform_get_irq(pdev, 1); 78 + if (release_irq < 0) 79 + return -EINVAL; 80 + 81 + error = devm_request_threaded_irq(dev, push_irq, NULL, 82 + tps6594_pb_push_irq, 83 + IRQF_ONESHOT, 84 + pdev->resource[0].name, pwr); 85 + if (error) { 86 + dev_err(dev, "failed to request push IRQ #%d: %d\n", push_irq, 87 + error); 88 + return error; 89 + } 90 + 91 + error = devm_request_threaded_irq(dev, release_irq, NULL, 92 + tps6594_pb_release_irq, 93 + IRQF_ONESHOT, 94 + pdev->resource[1].name, pwr); 95 + if (error) { 96 + dev_err(dev, "failed to request release IRQ #%d: %d\n", 97 + release_irq, error); 98 + return error; 99 + } 100 + 101 + error = input_register_device(idev); 102 + if (error) { 103 + dev_err(dev, "Can't register power button: %d\n", error); 104 + return error; 105 + } 106 + 107 + return 0; 108 + } 109 + 110 + static const struct platform_device_id tps6594_pwrbtn_id_table[] = { 111 + { "tps6594-pwrbutton", }, 112 + { /* sentinel */ } 113 + }; 114 + MODULE_DEVICE_TABLE(platform, tps6594_pwrbtn_id_table); 115 + 116 + static struct platform_driver tps6594_pb_driver = { 117 + .probe = tps6594_pb_probe, 118 + .driver = { 119 + .name = "tps6594_pwrbutton", 120 + }, 121 + .id_table = tps6594_pwrbtn_id_table, 122 + }; 123 + module_platform_driver(tps6594_pb_driver); 124 + 125 + MODULE_DESCRIPTION("TPS6594 Power Button"); 126 + MODULE_LICENSE("GPL");
-4
drivers/input/touchscreen/mc13783_ts.c
··· 42 42 { 43 43 struct mc13783_ts_priv *priv = data; 44 44 45 - mc13xxx_irq_ack(priv->mc13xxx, irq); 46 - 47 45 /* 48 46 * Kick off reading coordinates. Note that if work happens already 49 47 * be queued for future execution (it rearms itself) it will not ··· 134 136 int ret; 135 137 136 138 mc13xxx_lock(priv->mc13xxx); 137 - 138 - mc13xxx_irq_ack(priv->mc13xxx, MC13XXX_IRQ_TS); 139 139 140 140 ret = mc13xxx_irq_request(priv->mc13xxx, MC13XXX_IRQ_TS, 141 141 mc13783_ts_handler, MC13783_TS_NAME, priv);
+1
drivers/mfd/88pm886.c
··· 35 35 }; 36 36 37 37 static const struct mfd_cell pm886_devs[] = { 38 + MFD_CELL_NAME("88pm886-gpadc"), 38 39 MFD_CELL_RES("88pm886-onkey", pm886_onkey_resources), 39 40 MFD_CELL_NAME("88pm886-regulator"), 40 41 MFD_CELL_NAME("88pm886-rtc"),
+51 -1
drivers/mfd/Kconfig
··· 129 129 select MFD_CORE 130 130 depends on I2C=y 131 131 depends on GPIOLIB || COMPILE_TEST 132 + depends on GPIOLIB_LEGACY 132 133 help 133 134 If you say yes here you get support for the AAT2870. 134 135 This driver provides common support for accessing the device, ··· 1254 1253 Say M here if you want to include support for the Qualcomm RPM as a 1255 1254 module. This will build a module called "qcom_rpm". 1256 1255 1256 + config MFD_SPACEMIT_P1 1257 + tristate "SpacemiT P1 PMIC" 1258 + depends on ARCH_SPACEMIT || COMPILE_TEST 1259 + depends on I2C 1260 + select I2C_K1 1261 + select MFD_SIMPLE_MFD_I2C 1262 + help 1263 + This option supports the I2C-based SpacemiT P1 PMIC, which 1264 + contains regulators, a power switch, GPIOs, an RTC, and more. 1265 + This option is selected when any of the supported sub-devices 1266 + is configured. The basic functionality is implemented by the 1267 + simple MFD I2C driver. 1268 + 1257 1269 config MFD_SPMI_PMIC 1258 1270 tristate "Qualcomm SPMI PMICs" 1259 1271 depends on ARCH_QCOM || COMPILE_TEST ··· 1440 1426 config MFD_SI476X_CORE 1441 1427 tristate "Silicon Laboratories 4761/64/68 AM/FM radio." 1442 1428 depends on I2C 1429 + depends on GPIOLIB_LEGACY 1443 1430 select MFD_CORE 1444 1431 select REGMAP_I2C 1445 1432 help ··· 1670 1655 TI LMU MFD supports LM3532, LM3631, LM3632, LM3633, LM3695 and 1671 1656 LM36274. It consists of backlight, LED and regulator driver. 1672 1657 It provides consistent device controls for lighting functions. 1658 + 1659 + config MFD_BQ257XX 1660 + tristate "TI BQ257XX Buck/Boost Charge Controller" 1661 + depends on I2C 1662 + select MFD_CORE 1663 + select REGMAP_I2C 1664 + help 1665 + Support Texas Instruments BQ25703 Buck/Boost converter with 1666 + charge controller. It consists of regulators that provide 1667 + system voltage and OTG voltage, and a charger manager for 1668 + batteries containing one or more cells. 1673 1669 1674 1670 config MFD_OMAP_USB_HOST 1675 1671 bool "TI OMAP USBHS core and TLL driver" ··· 2018 1992 multifunction device which exposes numerous platform devices. 2019 1993 2020 1994 The timberdale FPGA can be found on the Intel Atom development board 2021 - for in-vehicle infontainment, called Russellville. 1995 + for in-vehicle infotainment, called Russellville. 2022 1996 2023 1997 config MFD_TC3589X 2024 1998 bool "Toshiba TC35892 and variants" ··· 2468 2442 This driver provides common support for accessing the device, 2469 2443 additional drivers must be enabled in order to use the functionality 2470 2444 of the device. 2445 + 2446 + config MFD_LOONGSON_SE 2447 + tristate "Loongson Security Engine chip controller driver" 2448 + depends on LOONGARCH && ACPI 2449 + select MFD_CORE 2450 + help 2451 + The Loongson Security Engine chip supports RNG, SM2, SM3 and 2452 + SM4 accelerator engines. Each engine have its own DMA buffer 2453 + provided by the controller. The kernel cannot directly send 2454 + commands to the engine and must first send them to the controller, 2455 + which will forward them to the corresponding engine. 2456 + 2457 + config MFD_LS2K_BMC_CORE 2458 + bool "Loongson-2K Board Management Controller Support" 2459 + depends on PCI && ACPI_GENERIC_GSI 2460 + select MFD_CORE 2461 + help 2462 + Say yes here to add support for the Loongson-2K BMC which is a Board 2463 + Management Controller connected to the PCIe bus. The device supports 2464 + multiple sub-devices like display and IPMI. This driver provides common 2465 + support for accessing the devices. 2466 + 2467 + The display is enabled by default in the driver, while the IPMI interface 2468 + is enabled independently through the IPMI_LS2K option in the IPMI section. 2471 2469 2472 2470 config MFD_QNAP_MCU 2473 2471 tristate "QNAP microcontroller unit core driver"
+5
drivers/mfd/Makefile
··· 13 13 obj-$(CONFIG_ARCH_BCM2835) += bcm2835-pm.o 14 14 obj-$(CONFIG_MFD_BCM590XX) += bcm590xx.o 15 15 obj-$(CONFIG_MFD_BD9571MWV) += bd9571mwv.o 16 + obj-$(CONFIG_MFD_BQ257XX) += bq257xx.o 16 17 obj-$(CONFIG_MFD_CGBC) += cgbc-core.o 17 18 obj-$(CONFIG_MFD_CROS_EC_DEV) += cros_ec_dev.o 18 19 obj-$(CONFIG_MFD_CS42L43) += cs42l43.o ··· 290 289 obj-$(CONFIG_MFD_INTEL_M10_BMC_SPI) += intel-m10-bmc-spi.o 291 290 obj-$(CONFIG_MFD_INTEL_M10_BMC_PMCI) += intel-m10-bmc-pmci.o 292 291 292 + obj-$(CONFIG_MFD_LS2K_BMC_CORE) += ls2k-bmc-core.o 293 + 293 294 obj-$(CONFIG_MFD_ATC260X) += atc260x-core.o 294 295 obj-$(CONFIG_MFD_ATC260X_I2C) += atc260x-i2c.o 295 296 ··· 301 298 obj-$(CONFIG_MFD_RSMU_SPI) += rsmu_spi.o rsmu_core.o 302 299 303 300 obj-$(CONFIG_MFD_UPBOARD_FPGA) += upboard-fpga.o 301 + 302 + obj-$(CONFIG_MFD_LOONGSON_SE) += loongson-se.o
-1
drivers/mfd/adp5585.c
··· 432 432 "Invalid value(%u) for adi,reset-pulse-width-us\n", 433 433 prop_val); 434 434 } 435 - return ret; 436 435 } 437 436 438 437 return 0;
+4 -1
drivers/mfd/arizona-irq.c
··· 136 136 dev_err(arizona->dev, 137 137 "Failed to read main IRQ status: %d\n", ret); 138 138 } 139 - 139 + #ifdef CONFIG_GPIOLIB_LEGACY 140 140 /* 141 141 * Poll the IRQ pin status to see if we're really done 142 142 * if the interrupt controller can't do it for us. ··· 150 150 !gpio_get_value_cansleep(arizona->pdata.irq_gpio)) { 151 151 poll = true; 152 152 } 153 + #endif 153 154 } while (poll); 154 155 155 156 pm_runtime_put_autosuspend(arizona->dev); ··· 350 349 goto err_map_main_irq; 351 350 } 352 351 352 + #ifdef CONFIG_GPIOLIB_LEGACY 353 353 /* Used to emulate edge trigger and to work around broken pinmux */ 354 354 if (arizona->pdata.irq_gpio) { 355 355 if (gpio_to_irq(arizona->pdata.irq_gpio) != arizona->irq) { ··· 370 368 arizona->pdata.irq_gpio = 0; 371 369 } 372 370 } 371 + #endif 373 372 374 373 ret = request_threaded_irq(arizona->irq, NULL, arizona_irq_thread, 375 374 flags, "arizona", arizona);
+99
drivers/mfd/bq257xx.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * BQ257XX Core Driver 4 + * Copyright (C) 2025 Chris Morgan <macromorgan@hotmail.com> 5 + */ 6 + 7 + #include <linux/device.h> 8 + #include <linux/i2c.h> 9 + #include <linux/mfd/bq257xx.h> 10 + #include <linux/mfd/core.h> 11 + #include <linux/regmap.h> 12 + 13 + static const struct regmap_range bq25703_readonly_reg_ranges[] = { 14 + regmap_reg_range(BQ25703_CHARGER_STATUS, BQ25703_MANUFACT_DEV_ID), 15 + }; 16 + 17 + static const struct regmap_access_table bq25703_writeable_regs = { 18 + .no_ranges = bq25703_readonly_reg_ranges, 19 + .n_no_ranges = ARRAY_SIZE(bq25703_readonly_reg_ranges), 20 + }; 21 + 22 + static const struct regmap_range bq25703_volatile_reg_ranges[] = { 23 + regmap_reg_range(BQ25703_CHARGE_OPTION_0, BQ25703_IIN_HOST), 24 + regmap_reg_range(BQ25703_CHARGER_STATUS, BQ25703_ADC_OPTION), 25 + }; 26 + 27 + static const struct regmap_access_table bq25703_volatile_regs = { 28 + .yes_ranges = bq25703_volatile_reg_ranges, 29 + .n_yes_ranges = ARRAY_SIZE(bq25703_volatile_reg_ranges), 30 + }; 31 + 32 + static const struct regmap_config bq25703_regmap_config = { 33 + .reg_bits = 8, 34 + .val_bits = 16, 35 + .max_register = BQ25703_ADC_OPTION, 36 + .cache_type = REGCACHE_MAPLE, 37 + .wr_table = &bq25703_writeable_regs, 38 + .volatile_table = &bq25703_volatile_regs, 39 + .val_format_endian = REGMAP_ENDIAN_LITTLE, 40 + }; 41 + 42 + static const struct mfd_cell cells[] = { 43 + MFD_CELL_NAME("bq257xx-regulator"), 44 + MFD_CELL_NAME("bq257xx-charger"), 45 + }; 46 + 47 + static int bq257xx_probe(struct i2c_client *client) 48 + { 49 + struct bq257xx_device *ddata; 50 + int ret; 51 + 52 + ddata = devm_kzalloc(&client->dev, sizeof(*ddata), GFP_KERNEL); 53 + if (!ddata) 54 + return -ENOMEM; 55 + 56 + ddata->client = client; 57 + 58 + ddata->regmap = devm_regmap_init_i2c(client, &bq25703_regmap_config); 59 + if (IS_ERR(ddata->regmap)) { 60 + return dev_err_probe(&client->dev, PTR_ERR(ddata->regmap), 61 + "Failed to allocate register map\n"); 62 + } 63 + 64 + i2c_set_clientdata(client, ddata); 65 + 66 + ret = devm_mfd_add_devices(&client->dev, PLATFORM_DEVID_AUTO, 67 + cells, ARRAY_SIZE(cells), NULL, 0, NULL); 68 + if (ret) 69 + return dev_err_probe(&client->dev, ret, 70 + "Failed to register child devices\n"); 71 + 72 + return ret; 73 + } 74 + 75 + static const struct i2c_device_id bq257xx_i2c_ids[] = { 76 + { "bq25703a" }, 77 + {} 78 + }; 79 + MODULE_DEVICE_TABLE(i2c, bq257xx_i2c_ids); 80 + 81 + static const struct of_device_id bq257xx_of_match[] = { 82 + { .compatible = "ti,bq25703a" }, 83 + {} 84 + }; 85 + MODULE_DEVICE_TABLE(of, bq257xx_of_match); 86 + 87 + static struct i2c_driver bq257xx_driver = { 88 + .driver = { 89 + .name = "bq257xx", 90 + .of_match_table = bq257xx_of_match, 91 + }, 92 + .probe = bq257xx_probe, 93 + .id_table = bq257xx_i2c_ids, 94 + }; 95 + module_i2c_driver(bq257xx_driver); 96 + 97 + MODULE_DESCRIPTION("bq257xx buck/boost/charger driver"); 98 + MODULE_AUTHOR("Chris Morgan <macromorgan@hotmail.com>"); 99 + MODULE_LICENSE("GPL");
+3 -29
drivers/mfd/cs42l43.c
··· 1117 1117 static int cs42l43_suspend(struct device *dev) 1118 1118 { 1119 1119 struct cs42l43 *cs42l43 = dev_get_drvdata(dev); 1120 - static const struct reg_sequence mask_all[] = { 1121 - { CS42L43_DECIM_MASK, 0xFFFFFFFF, }, 1122 - { CS42L43_EQ_MIX_MASK, 0xFFFFFFFF, }, 1123 - { CS42L43_ASP_MASK, 0xFFFFFFFF, }, 1124 - { CS42L43_PLL_MASK, 0xFFFFFFFF, }, 1125 - { CS42L43_SOFT_MASK, 0xFFFFFFFF, }, 1126 - { CS42L43_SWIRE_MASK, 0xFFFFFFFF, }, 1127 - { CS42L43_MSM_MASK, 0xFFFFFFFF, }, 1128 - { CS42L43_ACC_DET_MASK, 0xFFFFFFFF, }, 1129 - { CS42L43_I2C_TGT_MASK, 0xFFFFFFFF, }, 1130 - { CS42L43_SPI_MSTR_MASK, 0xFFFFFFFF, }, 1131 - { CS42L43_SW_TO_SPI_BRIDGE_MASK, 0xFFFFFFFF, }, 1132 - { CS42L43_OTP_MASK, 0xFFFFFFFF, }, 1133 - { CS42L43_CLASS_D_AMP_MASK, 0xFFFFFFFF, }, 1134 - { CS42L43_GPIO_INT_MASK, 0xFFFFFFFF, }, 1135 - { CS42L43_ASRC_MASK, 0xFFFFFFFF, }, 1136 - { CS42L43_HPOUT_MASK, 0xFFFFFFFF, }, 1137 - }; 1138 1120 int ret; 1139 1121 1140 1122 ret = pm_runtime_resume_and_get(dev); ··· 1125 1143 return ret; 1126 1144 } 1127 1145 1128 - /* The IRQs will be re-enabled on resume by the cache sync */ 1129 - ret = regmap_multi_reg_write_bypassed(cs42l43->regmap, 1130 - mask_all, ARRAY_SIZE(mask_all)); 1131 - if (ret) { 1132 - dev_err(cs42l43->dev, "Failed to mask IRQs: %d\n", ret); 1133 - return ret; 1134 - } 1146 + disable_irq(cs42l43->irq); 1135 1147 1136 1148 ret = pm_runtime_force_suspend(dev); 1137 1149 if (ret) { ··· 1139 1163 ret = cs42l43_power_down(cs42l43); 1140 1164 if (ret) 1141 1165 return ret; 1142 - 1143 - disable_irq(cs42l43->irq); 1144 1166 1145 1167 return 0; 1146 1168 } ··· 1170 1196 if (ret) 1171 1197 return ret; 1172 1198 1173 - enable_irq(cs42l43->irq); 1174 - 1175 1199 ret = pm_runtime_force_resume(dev); 1176 1200 if (ret) { 1177 1201 dev_err(cs42l43->dev, "Failed to force resume: %d\n", ret); 1178 1202 return ret; 1179 1203 } 1204 + 1205 + enable_irq(cs42l43->irq); 1180 1206 1181 1207 return 0; 1182 1208 }
+21 -6
drivers/mfd/da9063-i2c.c
··· 37 37 DA9063_PAGE_SEL_BUF_SIZE, 38 38 }; 39 39 40 + enum da9063_page_sel_msgs { 41 + DA9063_PAGE_SEL_MSG = 0, 42 + DA9063_PAGE_SEL_CNT, 43 + }; 44 + 40 45 enum da9063_paged_read_msgs { 41 - DA9063_PAGED_READ_MSG_PAGE_SEL = 0, 42 - DA9063_PAGED_READ_MSG_REG_SEL, 46 + DA9063_PAGED_READ_MSG_REG_SEL = 0, 43 47 DA9063_PAGED_READ_MSG_DATA, 44 48 DA9063_PAGED_READ_MSG_CNT, 45 49 }; ··· 69 65 (page_num << DA9063_I2C_PAGE_SEL_SHIFT) & DA9063_REG_PAGE_MASK; 70 66 71 67 /* Write reg address, page selection */ 72 - xfer[DA9063_PAGED_READ_MSG_PAGE_SEL].addr = client->addr; 73 - xfer[DA9063_PAGED_READ_MSG_PAGE_SEL].flags = 0; 74 - xfer[DA9063_PAGED_READ_MSG_PAGE_SEL].len = DA9063_PAGE_SEL_BUF_SIZE; 75 - xfer[DA9063_PAGED_READ_MSG_PAGE_SEL].buf = page_sel_buf; 68 + xfer[DA9063_PAGE_SEL_MSG].addr = client->addr; 69 + xfer[DA9063_PAGE_SEL_MSG].flags = 0; 70 + xfer[DA9063_PAGE_SEL_MSG].len = DA9063_PAGE_SEL_BUF_SIZE; 71 + xfer[DA9063_PAGE_SEL_MSG].buf = page_sel_buf; 72 + 73 + ret = i2c_transfer(client->adapter, xfer, DA9063_PAGE_SEL_CNT); 74 + if (ret < 0) { 75 + dev_err(&client->dev, "Page switch failed: %d\n", ret); 76 + return ret; 77 + } 78 + 79 + if (ret != DA9063_PAGE_SEL_CNT) { 80 + dev_err(&client->dev, "Page switch failed to complete\n"); 81 + return -EIO; 82 + } 76 83 77 84 /* Select register address */ 78 85 xfer[DA9063_PAGED_READ_MSG_REG_SEL].addr = client->addr;
-1
drivers/mfd/exynos-lpass.c
··· 101 101 .reg_stride = 4, 102 102 .val_bits = 32, 103 103 .max_register = 0xfc, 104 - .fast_io = true, 105 104 }; 106 105 107 106 static void exynos_lpass_disable_lpass(void *data)
-1
drivers/mfd/fsl-imx25-tsadc.c
··· 17 17 #include <linux/regmap.h> 18 18 19 19 static const struct regmap_config mx25_tsadc_regmap_config = { 20 - .fast_io = true, 21 20 .max_register = 8, 22 21 .reg_bits = 32, 23 22 .val_bits = 32,
+13
drivers/mfd/intel-lpss-pci.c
··· 367 367 { PCI_VDEVICE(INTEL, 0x4b79), (kernel_ulong_t)&ehl_i2c_info }, 368 368 { PCI_VDEVICE(INTEL, 0x4b7a), (kernel_ulong_t)&ehl_i2c_info }, 369 369 { PCI_VDEVICE(INTEL, 0x4b7b), (kernel_ulong_t)&ehl_i2c_info }, 370 + /* WCL */ 371 + { PCI_VDEVICE(INTEL, 0x4d25), (kernel_ulong_t)&bxt_uart_info }, 372 + { PCI_VDEVICE(INTEL, 0x4d26), (kernel_ulong_t)&bxt_uart_info }, 373 + { PCI_VDEVICE(INTEL, 0x4d27), (kernel_ulong_t)&tgl_spi_info }, 374 + { PCI_VDEVICE(INTEL, 0x4d30), (kernel_ulong_t)&tgl_spi_info }, 375 + { PCI_VDEVICE(INTEL, 0x4d46), (kernel_ulong_t)&tgl_spi_info }, 376 + { PCI_VDEVICE(INTEL, 0x4d50), (kernel_ulong_t)&ehl_i2c_info }, 377 + { PCI_VDEVICE(INTEL, 0x4d51), (kernel_ulong_t)&ehl_i2c_info }, 378 + { PCI_VDEVICE(INTEL, 0x4d52), (kernel_ulong_t)&bxt_uart_info }, 379 + { PCI_VDEVICE(INTEL, 0x4d78), (kernel_ulong_t)&ehl_i2c_info }, 380 + { PCI_VDEVICE(INTEL, 0x4d79), (kernel_ulong_t)&ehl_i2c_info }, 381 + { PCI_VDEVICE(INTEL, 0x4d7a), (kernel_ulong_t)&ehl_i2c_info }, 382 + { PCI_VDEVICE(INTEL, 0x4d7b), (kernel_ulong_t)&ehl_i2c_info }, 370 383 /* JSL */ 371 384 { PCI_VDEVICE(INTEL, 0x4da8), (kernel_ulong_t)&spt_uart_info }, 372 385 { PCI_VDEVICE(INTEL, 0x4da9), (kernel_ulong_t)&spt_uart_info },
+2
drivers/mfd/intel_soc_pmic_chtdc_ti.c
··· 82 82 .reg_bits = 8, 83 83 .val_bits = 8, 84 84 .max_register = 0xff, 85 + /* The hardware does not support reading multiple registers at once */ 86 + .use_single_read = true, 85 87 }; 86 88 87 89 static const struct regmap_irq chtdc_ti_irqs[] = {
+19 -17
drivers/mfd/kempld-core.c
··· 141 141 }; 142 142 143 143 kempld_pdev = platform_device_register_full(&pdevinfo); 144 - if (IS_ERR(kempld_pdev)) 145 - return PTR_ERR(kempld_pdev); 146 144 147 - return 0; 145 + return PTR_ERR_OR_ZERO(kempld_pdev); 148 146 } 149 147 150 148 /** ··· 777 779 static int __init kempld_init(void) 778 780 { 779 781 const struct dmi_system_id *id; 780 - int ret = -ENODEV; 781 782 782 - for (id = dmi_first_match(kempld_dmi_table); id; id = dmi_first_match(id + 1)) { 783 - /* Check, if user asked for the exact device ID match */ 784 - if (force_device_id[0] && !strstr(id->ident, force_device_id)) 785 - continue; 786 - 787 - ret = kempld_create_platform_device(&kempld_platform_data_generic); 788 - if (ret) 789 - continue; 790 - 791 - break; 783 + /* 784 + * This custom DMI iteration allows the driver to be initialized in three ways: 785 + * - When a forced_device_id string matches any ident in the kempld_dmi_table, 786 + * regardless of whether the DMI device is present in the system dmi table. 787 + * - When a matching entry is present in the DMI system tabe. 788 + * - Through alternative mechanisms like ACPI. 789 + */ 790 + if (force_device_id[0]) { 791 + for (id = kempld_dmi_table; id->matches[0].slot != DMI_NONE; id++) 792 + if (strstr(id->ident, force_device_id)) 793 + if (!kempld_create_platform_device(&kempld_platform_data_generic)) 794 + break; 795 + if (id->matches[0].slot == DMI_NONE) 796 + return -ENODEV; 797 + } else { 798 + for (id = dmi_first_match(kempld_dmi_table); id; id = dmi_first_match(id+1)) 799 + if (kempld_create_platform_device(&kempld_platform_data_generic)) 800 + break; 792 801 } 793 - if (ret) 794 - return ret; 795 - 796 802 return platform_driver_register(&kempld_driver); 797 803 } 798 804
+253
drivers/mfd/loongson-se.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + /* 3 + * Copyright (C) 2025 Loongson Technology Corporation Limited 4 + * 5 + * Author: Yinggang Gu <guyinggang@loongson.cn> 6 + * Author: Qunqin Zhao <zhaoqunqin@loongson.cn> 7 + */ 8 + 9 + #include <linux/acpi.h> 10 + #include <linux/delay.h> 11 + #include <linux/device.h> 12 + #include <linux/dma-mapping.h> 13 + #include <linux/errno.h> 14 + #include <linux/init.h> 15 + #include <linux/interrupt.h> 16 + #include <linux/iopoll.h> 17 + #include <linux/kernel.h> 18 + #include <linux/mfd/core.h> 19 + #include <linux/mfd/loongson-se.h> 20 + #include <linux/module.h> 21 + #include <linux/platform_device.h> 22 + 23 + struct loongson_se { 24 + void __iomem *base; 25 + spinlock_t dev_lock; 26 + struct completion cmd_completion; 27 + 28 + void *dmam_base; 29 + int dmam_size; 30 + 31 + struct mutex engine_init_lock; 32 + struct loongson_se_engine engines[SE_ENGINE_MAX]; 33 + }; 34 + 35 + struct loongson_se_controller_cmd { 36 + u32 command_id; 37 + u32 info[7]; 38 + }; 39 + 40 + static int loongson_se_poll(struct loongson_se *se, u32 int_bit) 41 + { 42 + u32 status; 43 + int err; 44 + 45 + spin_lock_irq(&se->dev_lock); 46 + 47 + /* Notify the controller that the engine needs to be started */ 48 + writel(int_bit, se->base + SE_L2SINT_SET); 49 + 50 + /* Polling until the controller has forwarded the engine command */ 51 + err = readl_relaxed_poll_timeout_atomic(se->base + SE_L2SINT_STAT, status, 52 + !(status & int_bit), 53 + 1, LOONGSON_ENGINE_CMD_TIMEOUT_US); 54 + 55 + spin_unlock_irq(&se->dev_lock); 56 + 57 + return err; 58 + } 59 + 60 + static int loongson_se_send_controller_cmd(struct loongson_se *se, 61 + struct loongson_se_controller_cmd *cmd) 62 + { 63 + u32 *send_cmd = (u32 *)cmd; 64 + int err, i; 65 + 66 + for (i = 0; i < SE_SEND_CMD_REG_LEN; i++) 67 + writel(send_cmd[i], se->base + SE_SEND_CMD_REG + i * 4); 68 + 69 + err = loongson_se_poll(se, SE_INT_CONTROLLER); 70 + if (err) 71 + return err; 72 + 73 + return wait_for_completion_interruptible(&se->cmd_completion); 74 + } 75 + 76 + int loongson_se_send_engine_cmd(struct loongson_se_engine *engine) 77 + { 78 + /* 79 + * After engine initialization, the controller already knows 80 + * where to obtain engine commands from. Now all we need to 81 + * do is notify the controller that the engine needs to be started. 82 + */ 83 + int err = loongson_se_poll(engine->se, BIT(engine->id)); 84 + 85 + if (err) 86 + return err; 87 + 88 + return wait_for_completion_interruptible(&engine->completion); 89 + } 90 + EXPORT_SYMBOL_GPL(loongson_se_send_engine_cmd); 91 + 92 + struct loongson_se_engine *loongson_se_init_engine(struct device *dev, int id) 93 + { 94 + struct loongson_se *se = dev_get_drvdata(dev); 95 + struct loongson_se_engine *engine = &se->engines[id]; 96 + struct loongson_se_controller_cmd cmd; 97 + 98 + engine->se = se; 99 + engine->id = id; 100 + init_completion(&engine->completion); 101 + 102 + /* Divide DMA memory equally among all engines */ 103 + engine->buffer_size = se->dmam_size / SE_ENGINE_MAX; 104 + engine->buffer_off = (se->dmam_size / SE_ENGINE_MAX) * id; 105 + engine->data_buffer = se->dmam_base + engine->buffer_off; 106 + 107 + /* 108 + * There has no engine0, use its data buffer as command buffer for other 109 + * engines. The DMA memory size is obtained from the ACPI table, which 110 + * ensures that the data buffer size of engine0 is larger than the 111 + * command buffer size of all engines. 112 + */ 113 + engine->command = se->dmam_base + id * (2 * SE_ENGINE_CMD_SIZE); 114 + engine->command_ret = engine->command + SE_ENGINE_CMD_SIZE; 115 + 116 + mutex_lock(&se->engine_init_lock); 117 + 118 + /* Tell the controller where to find engine command */ 119 + cmd.command_id = SE_CMD_SET_ENGINE_CMDBUF; 120 + cmd.info[0] = id; 121 + cmd.info[1] = engine->command - se->dmam_base; 122 + cmd.info[2] = 2 * SE_ENGINE_CMD_SIZE; 123 + 124 + if (loongson_se_send_controller_cmd(se, &cmd)) 125 + engine = NULL; 126 + 127 + mutex_unlock(&se->engine_init_lock); 128 + 129 + return engine; 130 + } 131 + EXPORT_SYMBOL_GPL(loongson_se_init_engine); 132 + 133 + static irqreturn_t se_irq_handler(int irq, void *dev_id) 134 + { 135 + struct loongson_se *se = dev_id; 136 + u32 int_status; 137 + int id; 138 + 139 + spin_lock(&se->dev_lock); 140 + 141 + int_status = readl(se->base + SE_S2LINT_STAT); 142 + 143 + /* For controller */ 144 + if (int_status & SE_INT_CONTROLLER) { 145 + complete(&se->cmd_completion); 146 + int_status &= ~SE_INT_CONTROLLER; 147 + writel(SE_INT_CONTROLLER, se->base + SE_S2LINT_CL); 148 + } 149 + 150 + /* For engines */ 151 + while (int_status) { 152 + id = __ffs(int_status); 153 + complete(&se->engines[id].completion); 154 + int_status &= ~BIT(id); 155 + writel(BIT(id), se->base + SE_S2LINT_CL); 156 + } 157 + 158 + spin_unlock(&se->dev_lock); 159 + 160 + return IRQ_HANDLED; 161 + } 162 + 163 + static int loongson_se_init(struct loongson_se *se, dma_addr_t addr, int size) 164 + { 165 + struct loongson_se_controller_cmd cmd; 166 + int err; 167 + 168 + cmd.command_id = SE_CMD_START; 169 + err = loongson_se_send_controller_cmd(se, &cmd); 170 + if (err) 171 + return err; 172 + 173 + cmd.command_id = SE_CMD_SET_DMA; 174 + cmd.info[0] = lower_32_bits(addr); 175 + cmd.info[1] = upper_32_bits(addr); 176 + cmd.info[2] = size; 177 + 178 + return loongson_se_send_controller_cmd(se, &cmd); 179 + } 180 + 181 + static const struct mfd_cell engines[] = { 182 + { .name = "loongson-rng" }, 183 + { .name = "tpm_loongson" }, 184 + }; 185 + 186 + static int loongson_se_probe(struct platform_device *pdev) 187 + { 188 + struct device *dev = &pdev->dev; 189 + struct loongson_se *se; 190 + int nr_irq, irq, err, i; 191 + dma_addr_t paddr; 192 + 193 + se = devm_kmalloc(dev, sizeof(*se), GFP_KERNEL); 194 + if (!se) 195 + return -ENOMEM; 196 + 197 + dev_set_drvdata(dev, se); 198 + init_completion(&se->cmd_completion); 199 + spin_lock_init(&se->dev_lock); 200 + mutex_init(&se->engine_init_lock); 201 + 202 + dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64)); 203 + if (device_property_read_u32(dev, "dmam_size", &se->dmam_size)) 204 + return -ENODEV; 205 + 206 + se->dmam_base = dmam_alloc_coherent(dev, se->dmam_size, &paddr, GFP_KERNEL); 207 + if (!se->dmam_base) 208 + return -ENOMEM; 209 + 210 + se->base = devm_platform_ioremap_resource(pdev, 0); 211 + if (IS_ERR(se->base)) 212 + return PTR_ERR(se->base); 213 + 214 + writel(SE_INT_ALL, se->base + SE_S2LINT_EN); 215 + 216 + nr_irq = platform_irq_count(pdev); 217 + if (nr_irq <= 0) 218 + return -ENODEV; 219 + 220 + for (i = 0; i < nr_irq; i++) { 221 + irq = platform_get_irq(pdev, i); 222 + err = devm_request_irq(dev, irq, se_irq_handler, 0, "loongson-se", se); 223 + if (err) 224 + dev_err(dev, "failed to request IRQ: %d\n", irq); 225 + } 226 + 227 + err = loongson_se_init(se, paddr, se->dmam_size); 228 + if (err) 229 + return err; 230 + 231 + return devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE, engines, 232 + ARRAY_SIZE(engines), NULL, 0, NULL); 233 + } 234 + 235 + static const struct acpi_device_id loongson_se_acpi_match[] = { 236 + { "LOON0011", 0 }, 237 + { } 238 + }; 239 + MODULE_DEVICE_TABLE(acpi, loongson_se_acpi_match); 240 + 241 + static struct platform_driver loongson_se_driver = { 242 + .probe = loongson_se_probe, 243 + .driver = { 244 + .name = "loongson-se", 245 + .acpi_match_table = loongson_se_acpi_match, 246 + }, 247 + }; 248 + module_platform_driver(loongson_se_driver); 249 + 250 + MODULE_LICENSE("GPL"); 251 + MODULE_AUTHOR("Yinggang Gu <guyinggang@loongson.cn>"); 252 + MODULE_AUTHOR("Qunqin Zhao <zhaoqunqin@loongson.cn>"); 253 + MODULE_DESCRIPTION("Loongson Security Engine chip controller driver");
+528
drivers/mfd/ls2k-bmc-core.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Loongson-2K Board Management Controller (BMC) Core Driver. 4 + * 5 + * Copyright (C) 2024-2025 Loongson Technology Corporation Limited. 6 + * 7 + * Authors: 8 + * Chong Qiao <qiaochong@loongson.cn> 9 + * Binbin Zhou <zhoubinbin@loongson.cn> 10 + */ 11 + 12 + #include <linux/aperture.h> 13 + #include <linux/bitfield.h> 14 + #include <linux/delay.h> 15 + #include <linux/errno.h> 16 + #include <linux/init.h> 17 + #include <linux/iopoll.h> 18 + #include <linux/kbd_kern.h> 19 + #include <linux/kernel.h> 20 + #include <linux/mfd/core.h> 21 + #include <linux/module.h> 22 + #include <linux/pci.h> 23 + #include <linux/pci_ids.h> 24 + #include <linux/platform_data/simplefb.h> 25 + #include <linux/platform_device.h> 26 + #include <linux/stop_machine.h> 27 + #include <linux/vt_kern.h> 28 + 29 + /* LS2K BMC resources */ 30 + #define LS2K_DISPLAY_RES_START (SZ_16M + SZ_2M) 31 + #define LS2K_IPMI_RES_SIZE 0x1C 32 + #define LS2K_IPMI0_RES_START (SZ_16M + 0xF00000) 33 + #define LS2K_IPMI1_RES_START (LS2K_IPMI0_RES_START + LS2K_IPMI_RES_SIZE) 34 + #define LS2K_IPMI2_RES_START (LS2K_IPMI1_RES_START + LS2K_IPMI_RES_SIZE) 35 + #define LS2K_IPMI3_RES_START (LS2K_IPMI2_RES_START + LS2K_IPMI_RES_SIZE) 36 + #define LS2K_IPMI4_RES_START (LS2K_IPMI3_RES_START + LS2K_IPMI_RES_SIZE) 37 + 38 + #define LS7A_PCI_CFG_SIZE 0x100 39 + 40 + /* LS7A bridge registers */ 41 + #define LS7A_PCIE_PORT_CTL0 0x0 42 + #define LS7A_PCIE_PORT_STS1 0xC 43 + #define LS7A_GEN2_CTL 0x80C 44 + #define LS7A_SYMBOL_TIMER 0x71C 45 + 46 + /* Bits of LS7A_PCIE_PORT_CTL0 */ 47 + #define LS2K_BMC_PCIE_LTSSM_ENABLE BIT(3) 48 + 49 + /* Bits of LS7A_PCIE_PORT_STS1 */ 50 + #define LS2K_BMC_PCIE_LTSSM_STS GENMASK(5, 0) 51 + #define LS2K_BMC_PCIE_CONNECTED 0x11 52 + 53 + #define LS2K_BMC_PCIE_DELAY_US 1000 54 + #define LS2K_BMC_PCIE_TIMEOUT_US 1000000 55 + 56 + /* Bits of LS7A_GEN2_CTL */ 57 + #define LS7A_GEN2_SPEED_CHANG BIT(17) 58 + #define LS7A_CONF_PHY_TX BIT(18) 59 + 60 + /* Bits of LS7A_SYMBOL_TIMER */ 61 + #define LS7A_MASK_LEN_MATCH BIT(26) 62 + 63 + /* Interval between interruptions */ 64 + #define LS2K_BMC_INT_INTERVAL (60 * HZ) 65 + 66 + /* Maximum time to wait for U-Boot and DDR to be ready with ms. */ 67 + #define LS2K_BMC_RESET_WAIT_TIME 10000 68 + 69 + /* It's an experience value */ 70 + #define LS7A_BAR0_CHECK_MAX_TIMES 2000 71 + 72 + #define PCI_REG_STRIDE 0x4 73 + 74 + #define LS2K_BMC_RESET_GPIO 14 75 + #define LOONGSON_GPIO_REG_BASE 0x1FE00500 76 + #define LOONGSON_GPIO_REG_SIZE 0x18 77 + #define LOONGSON_GPIO_OEN 0x0 78 + #define LOONGSON_GPIO_FUNC 0x4 79 + #define LOONGSON_GPIO_INTPOL 0x10 80 + #define LOONGSON_GPIO_INTEN 0x14 81 + 82 + #define LOONGSON_IO_INT_BASE 16 83 + #define LS2K_BMC_RESET_GPIO_INT_VEC (LS2K_BMC_RESET_GPIO % 8) 84 + #define LS2K_BMC_RESET_GPIO_GSI (LOONGSON_IO_INT_BASE + LS2K_BMC_RESET_GPIO_INT_VEC) 85 + 86 + enum { 87 + LS2K_BMC_DISPLAY, 88 + LS2K_BMC_IPMI0, 89 + LS2K_BMC_IPMI1, 90 + LS2K_BMC_IPMI2, 91 + LS2K_BMC_IPMI3, 92 + LS2K_BMC_IPMI4, 93 + }; 94 + 95 + static struct resource ls2k_display_resources[] = { 96 + DEFINE_RES_MEM_NAMED(LS2K_DISPLAY_RES_START, SZ_4M, "simpledrm-res"), 97 + }; 98 + 99 + static struct resource ls2k_ipmi0_resources[] = { 100 + DEFINE_RES_MEM_NAMED(LS2K_IPMI0_RES_START, LS2K_IPMI_RES_SIZE, "ipmi0-res"), 101 + }; 102 + 103 + static struct resource ls2k_ipmi1_resources[] = { 104 + DEFINE_RES_MEM_NAMED(LS2K_IPMI1_RES_START, LS2K_IPMI_RES_SIZE, "ipmi1-res"), 105 + }; 106 + 107 + static struct resource ls2k_ipmi2_resources[] = { 108 + DEFINE_RES_MEM_NAMED(LS2K_IPMI2_RES_START, LS2K_IPMI_RES_SIZE, "ipmi2-res"), 109 + }; 110 + 111 + static struct resource ls2k_ipmi3_resources[] = { 112 + DEFINE_RES_MEM_NAMED(LS2K_IPMI3_RES_START, LS2K_IPMI_RES_SIZE, "ipmi3-res"), 113 + }; 114 + 115 + static struct resource ls2k_ipmi4_resources[] = { 116 + DEFINE_RES_MEM_NAMED(LS2K_IPMI4_RES_START, LS2K_IPMI_RES_SIZE, "ipmi4-res"), 117 + }; 118 + 119 + static struct mfd_cell ls2k_bmc_cells[] = { 120 + [LS2K_BMC_DISPLAY] = { 121 + .name = "simple-framebuffer", 122 + .num_resources = ARRAY_SIZE(ls2k_display_resources), 123 + .resources = ls2k_display_resources 124 + }, 125 + [LS2K_BMC_IPMI0] = { 126 + .name = "ls2k-ipmi-si", 127 + .num_resources = ARRAY_SIZE(ls2k_ipmi0_resources), 128 + .resources = ls2k_ipmi0_resources 129 + }, 130 + [LS2K_BMC_IPMI1] = { 131 + .name = "ls2k-ipmi-si", 132 + .num_resources = ARRAY_SIZE(ls2k_ipmi1_resources), 133 + .resources = ls2k_ipmi1_resources 134 + }, 135 + [LS2K_BMC_IPMI2] = { 136 + .name = "ls2k-ipmi-si", 137 + .num_resources = ARRAY_SIZE(ls2k_ipmi2_resources), 138 + .resources = ls2k_ipmi2_resources 139 + }, 140 + [LS2K_BMC_IPMI3] = { 141 + .name = "ls2k-ipmi-si", 142 + .num_resources = ARRAY_SIZE(ls2k_ipmi3_resources), 143 + .resources = ls2k_ipmi3_resources 144 + }, 145 + [LS2K_BMC_IPMI4] = { 146 + .name = "ls2k-ipmi-si", 147 + .num_resources = ARRAY_SIZE(ls2k_ipmi4_resources), 148 + .resources = ls2k_ipmi4_resources 149 + }, 150 + }; 151 + 152 + /* Index of the BMC PCI configuration space to be restored at BMC reset. */ 153 + struct ls2k_bmc_pci_data { 154 + u32 pci_command; 155 + u32 base_address0; 156 + u32 interrupt_line; 157 + }; 158 + 159 + /* Index of the parent PCI configuration space to be restored at BMC reset. */ 160 + struct ls2k_bmc_bridge_pci_data { 161 + u32 pci_command; 162 + u32 base_address[6]; 163 + u32 rom_addreess; 164 + u32 interrupt_line; 165 + u32 msi_hi; 166 + u32 msi_lo; 167 + u32 devctl; 168 + u32 linkcap; 169 + u32 linkctl_sts; 170 + u32 symbol_timer; 171 + u32 gen2_ctrl; 172 + }; 173 + 174 + struct ls2k_bmc_ddata { 175 + struct device *dev; 176 + struct work_struct bmc_reset_work; 177 + struct ls2k_bmc_pci_data bmc_pci_data; 178 + struct ls2k_bmc_bridge_pci_data bridge_pci_data; 179 + }; 180 + 181 + static bool ls2k_bmc_bar0_addr_is_set(struct pci_dev *pdev) 182 + { 183 + u32 addr; 184 + 185 + pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0, &addr); 186 + 187 + return addr & PCI_BASE_ADDRESS_MEM_MASK ? true : false; 188 + } 189 + 190 + static bool ls2k_bmc_pcie_is_connected(struct pci_dev *parent, struct ls2k_bmc_ddata *ddata) 191 + { 192 + void __iomem *base; 193 + int val, ret; 194 + 195 + base = pci_iomap(parent, 0, LS7A_PCI_CFG_SIZE); 196 + if (!base) 197 + return false; 198 + 199 + val = readl(base + LS7A_PCIE_PORT_CTL0); 200 + writel(val | LS2K_BMC_PCIE_LTSSM_ENABLE, base + LS7A_PCIE_PORT_CTL0); 201 + 202 + ret = readl_poll_timeout_atomic(base + LS7A_PCIE_PORT_STS1, val, 203 + (val & LS2K_BMC_PCIE_LTSSM_STS) == LS2K_BMC_PCIE_CONNECTED, 204 + LS2K_BMC_PCIE_DELAY_US, LS2K_BMC_PCIE_TIMEOUT_US); 205 + if (ret) { 206 + pci_iounmap(parent, base); 207 + dev_err(ddata->dev, "PCI-E training failed status=0x%x\n", val); 208 + return false; 209 + } 210 + 211 + pci_iounmap(parent, base); 212 + return true; 213 + } 214 + 215 + static void ls2k_bmc_restore_bridge_pci_data(struct pci_dev *parent, struct ls2k_bmc_ddata *ddata) 216 + { 217 + int base, i = 0; 218 + 219 + pci_write_config_dword(parent, PCI_COMMAND, ddata->bridge_pci_data.pci_command); 220 + 221 + for (base = PCI_BASE_ADDRESS_0; base <= PCI_BASE_ADDRESS_5; base += PCI_REG_STRIDE, i++) 222 + pci_write_config_dword(parent, base, ddata->bridge_pci_data.base_address[i]); 223 + 224 + pci_write_config_dword(parent, PCI_ROM_ADDRESS, ddata->bridge_pci_data.rom_addreess); 225 + pci_write_config_dword(parent, PCI_INTERRUPT_LINE, ddata->bridge_pci_data.interrupt_line); 226 + 227 + pci_write_config_dword(parent, parent->msi_cap + PCI_MSI_ADDRESS_LO, 228 + ddata->bridge_pci_data.msi_lo); 229 + pci_write_config_dword(parent, parent->msi_cap + PCI_MSI_ADDRESS_HI, 230 + ddata->bridge_pci_data.msi_hi); 231 + pci_write_config_dword(parent, parent->pcie_cap + PCI_EXP_DEVCTL, 232 + ddata->bridge_pci_data.devctl); 233 + pci_write_config_dword(parent, parent->pcie_cap + PCI_EXP_LNKCAP, 234 + ddata->bridge_pci_data.linkcap); 235 + pci_write_config_dword(parent, parent->pcie_cap + PCI_EXP_LNKCTL, 236 + ddata->bridge_pci_data.linkctl_sts); 237 + 238 + pci_write_config_dword(parent, LS7A_GEN2_CTL, ddata->bridge_pci_data.gen2_ctrl); 239 + pci_write_config_dword(parent, LS7A_SYMBOL_TIMER, ddata->bridge_pci_data.symbol_timer); 240 + } 241 + 242 + static int ls2k_bmc_recover_pci_data(void *data) 243 + { 244 + struct ls2k_bmc_ddata *ddata = data; 245 + struct pci_dev *pdev = to_pci_dev(ddata->dev); 246 + struct pci_dev *parent = pdev->bus->self; 247 + u32 i; 248 + 249 + /* 250 + * Clear the bus, io and mem resources of the PCI-E bridge to zero, so that 251 + * the processor can not access the LS2K PCI-E port, to avoid crashing due to 252 + * the lack of return signal from accessing the LS2K PCI-E port. 253 + */ 254 + pci_write_config_dword(parent, PCI_BASE_ADDRESS_2, 0); 255 + pci_write_config_dword(parent, PCI_BASE_ADDRESS_3, 0); 256 + pci_write_config_dword(parent, PCI_BASE_ADDRESS_4, 0); 257 + 258 + /* 259 + * When the LS2K BMC is reset, the LS7A PCI-E port is also reset, and its PCI 260 + * BAR0 register is cleared. Due to the time gap between the GPIO interrupt 261 + * generation and the LS2K BMC reset, the LS7A PCI BAR0 register is read to 262 + * determine whether the reset has begun. 263 + */ 264 + for (i = LS7A_BAR0_CHECK_MAX_TIMES; i > 0 ; i--) { 265 + if (!ls2k_bmc_bar0_addr_is_set(parent)) 266 + break; 267 + mdelay(1); 268 + }; 269 + 270 + if (i == 0) 271 + return false; 272 + 273 + ls2k_bmc_restore_bridge_pci_data(parent, ddata); 274 + 275 + /* Check if PCI-E is connected */ 276 + if (!ls2k_bmc_pcie_is_connected(parent, ddata)) 277 + return false; 278 + 279 + /* Waiting for U-Boot and DDR ready */ 280 + mdelay(LS2K_BMC_RESET_WAIT_TIME); 281 + if (!ls2k_bmc_bar0_addr_is_set(parent)) 282 + return false; 283 + 284 + /* Restore LS2K BMC PCI-E config data */ 285 + pci_write_config_dword(pdev, PCI_COMMAND, ddata->bmc_pci_data.pci_command); 286 + pci_write_config_dword(pdev, PCI_BASE_ADDRESS_0, ddata->bmc_pci_data.base_address0); 287 + pci_write_config_dword(pdev, PCI_INTERRUPT_LINE, ddata->bmc_pci_data.interrupt_line); 288 + 289 + return 0; 290 + } 291 + 292 + static void ls2k_bmc_events_fn(struct work_struct *work) 293 + { 294 + struct ls2k_bmc_ddata *ddata = container_of(work, struct ls2k_bmc_ddata, bmc_reset_work); 295 + 296 + /* 297 + * The PCI-E is lost when the BMC resets, at which point access to the PCI-E 298 + * from other CPUs is suspended to prevent a crash. 299 + */ 300 + stop_machine(ls2k_bmc_recover_pci_data, ddata, NULL); 301 + 302 + if (IS_ENABLED(CONFIG_VT)) { 303 + /* Re-push the display due to previous PCI-E loss. */ 304 + set_console(vt_move_to_console(MAX_NR_CONSOLES - 1, 1)); 305 + } 306 + } 307 + 308 + static irqreturn_t ls2k_bmc_interrupt(int irq, void *arg) 309 + { 310 + struct ls2k_bmc_ddata *ddata = arg; 311 + static unsigned long last_jiffies; 312 + 313 + if (system_state != SYSTEM_RUNNING) 314 + return IRQ_HANDLED; 315 + 316 + /* Skip interrupt in LS2K_BMC_INT_INTERVAL */ 317 + if (time_after(jiffies, last_jiffies + LS2K_BMC_INT_INTERVAL)) { 318 + schedule_work(&ddata->bmc_reset_work); 319 + last_jiffies = jiffies; 320 + } 321 + 322 + return IRQ_HANDLED; 323 + } 324 + 325 + /* 326 + * Saves the BMC parent device (LS7A) and its own PCI configuration space registers 327 + * that need to be restored after BMC reset. 328 + */ 329 + static void ls2k_bmc_save_pci_data(struct pci_dev *pdev, struct ls2k_bmc_ddata *ddata) 330 + { 331 + struct pci_dev *parent = pdev->bus->self; 332 + int base, i = 0; 333 + 334 + pci_read_config_dword(parent, PCI_COMMAND, &ddata->bridge_pci_data.pci_command); 335 + 336 + for (base = PCI_BASE_ADDRESS_0; base <= PCI_BASE_ADDRESS_5; base += PCI_REG_STRIDE, i++) 337 + pci_read_config_dword(parent, base, &ddata->bridge_pci_data.base_address[i]); 338 + 339 + pci_read_config_dword(parent, PCI_ROM_ADDRESS, &ddata->bridge_pci_data.rom_addreess); 340 + pci_read_config_dword(parent, PCI_INTERRUPT_LINE, &ddata->bridge_pci_data.interrupt_line); 341 + 342 + pci_read_config_dword(parent, parent->msi_cap + PCI_MSI_ADDRESS_LO, 343 + &ddata->bridge_pci_data.msi_lo); 344 + pci_read_config_dword(parent, parent->msi_cap + PCI_MSI_ADDRESS_HI, 345 + &ddata->bridge_pci_data.msi_hi); 346 + 347 + pci_read_config_dword(parent, parent->pcie_cap + PCI_EXP_DEVCTL, 348 + &ddata->bridge_pci_data.devctl); 349 + pci_read_config_dword(parent, parent->pcie_cap + PCI_EXP_LNKCAP, 350 + &ddata->bridge_pci_data.linkcap); 351 + pci_read_config_dword(parent, parent->pcie_cap + PCI_EXP_LNKCTL, 352 + &ddata->bridge_pci_data.linkctl_sts); 353 + 354 + pci_read_config_dword(parent, LS7A_GEN2_CTL, &ddata->bridge_pci_data.gen2_ctrl); 355 + ddata->bridge_pci_data.gen2_ctrl |= FIELD_PREP(LS7A_GEN2_SPEED_CHANG, 0x1) | 356 + FIELD_PREP(LS7A_CONF_PHY_TX, 0x0); 357 + 358 + pci_read_config_dword(parent, LS7A_SYMBOL_TIMER, &ddata->bridge_pci_data.symbol_timer); 359 + ddata->bridge_pci_data.symbol_timer |= LS7A_MASK_LEN_MATCH; 360 + 361 + pci_read_config_dword(pdev, PCI_COMMAND, &ddata->bmc_pci_data.pci_command); 362 + pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0, &ddata->bmc_pci_data.base_address0); 363 + pci_read_config_dword(pdev, PCI_INTERRUPT_LINE, &ddata->bmc_pci_data.interrupt_line); 364 + } 365 + 366 + static int ls2k_bmc_init(struct ls2k_bmc_ddata *ddata) 367 + { 368 + struct pci_dev *pdev = to_pci_dev(ddata->dev); 369 + void __iomem *gpio_base; 370 + int gpio_irq, ret, val; 371 + 372 + ls2k_bmc_save_pci_data(pdev, ddata); 373 + 374 + INIT_WORK(&ddata->bmc_reset_work, ls2k_bmc_events_fn); 375 + 376 + ret = devm_request_irq(&pdev->dev, pdev->irq, ls2k_bmc_interrupt, 377 + IRQF_SHARED | IRQF_TRIGGER_FALLING, "ls2kbmc pcie", ddata); 378 + if (ret) { 379 + dev_err(ddata->dev, "Failed to request LS2KBMC PCI-E IRQ %d.\n", pdev->irq); 380 + return ret; 381 + } 382 + 383 + gpio_base = ioremap(LOONGSON_GPIO_REG_BASE, LOONGSON_GPIO_REG_SIZE); 384 + if (!gpio_base) 385 + return -ENOMEM; 386 + 387 + /* Disable GPIO output */ 388 + val = readl(gpio_base + LOONGSON_GPIO_OEN); 389 + writel(val | BIT(LS2K_BMC_RESET_GPIO), gpio_base + LOONGSON_GPIO_OEN); 390 + 391 + /* Enable GPIO functionality */ 392 + val = readl(gpio_base + LOONGSON_GPIO_FUNC); 393 + writel(val & ~BIT(LS2K_BMC_RESET_GPIO), gpio_base + LOONGSON_GPIO_FUNC); 394 + 395 + /* Set GPIO interrupts to low-level active */ 396 + val = readl(gpio_base + LOONGSON_GPIO_INTPOL); 397 + writel(val & ~BIT(LS2K_BMC_RESET_GPIO), gpio_base + LOONGSON_GPIO_INTPOL); 398 + 399 + /* Enable GPIO interrupts */ 400 + val = readl(gpio_base + LOONGSON_GPIO_INTEN); 401 + writel(val | BIT(LS2K_BMC_RESET_GPIO), gpio_base + LOONGSON_GPIO_INTEN); 402 + 403 + iounmap(gpio_base); 404 + 405 + /* 406 + * Since gpio_chip->to_irq is not implemented in the Loongson-3 GPIO driver, 407 + * acpi_register_gsi() is used to obtain the GPIO IRQ. The GPIO interrupt is a 408 + * watchdog interrupt that is triggered when the BMC resets. 409 + */ 410 + gpio_irq = acpi_register_gsi(NULL, LS2K_BMC_RESET_GPIO_GSI, ACPI_EDGE_SENSITIVE, 411 + ACPI_ACTIVE_LOW); 412 + if (gpio_irq < 0) 413 + return gpio_irq; 414 + 415 + ret = devm_request_irq(ddata->dev, gpio_irq, ls2k_bmc_interrupt, 416 + IRQF_SHARED | IRQF_TRIGGER_FALLING, "ls2kbmc gpio", ddata); 417 + if (ret) 418 + dev_err(ddata->dev, "Failed to request LS2KBMC GPIO IRQ %d.\n", gpio_irq); 419 + 420 + acpi_unregister_gsi(LS2K_BMC_RESET_GPIO_GSI); 421 + return ret; 422 + } 423 + 424 + /* 425 + * Currently the Loongson-2K BMC hardware does not have an I2C interface to adapt to the 426 + * resolution. We set the resolution by presetting "video=1280x1024-16@2M" to the BMC memory. 427 + */ 428 + static int ls2k_bmc_parse_mode(struct pci_dev *pdev, struct simplefb_platform_data *pd) 429 + { 430 + char *mode; 431 + int depth, ret; 432 + 433 + /* The last 16M of PCI BAR0 is used to store the resolution string. */ 434 + mode = devm_ioremap(&pdev->dev, pci_resource_start(pdev, 0) + SZ_16M, SZ_16M); 435 + if (!mode) 436 + return -ENOMEM; 437 + 438 + /* The resolution field starts with the flag "video=". */ 439 + if (!strncmp(mode, "video=", 6)) 440 + mode = mode + 6; 441 + 442 + ret = kstrtoint(strsep(&mode, "x"), 10, &pd->width); 443 + if (ret) 444 + return ret; 445 + 446 + ret = kstrtoint(strsep(&mode, "-"), 10, &pd->height); 447 + if (ret) 448 + return ret; 449 + 450 + ret = kstrtoint(strsep(&mode, "@"), 10, &depth); 451 + if (ret) 452 + return ret; 453 + 454 + pd->stride = pd->width * depth / 8; 455 + pd->format = depth == 32 ? "a8r8g8b8" : "r5g6b5"; 456 + 457 + return 0; 458 + } 459 + 460 + static int ls2k_bmc_probe(struct pci_dev *dev, const struct pci_device_id *id) 461 + { 462 + struct simplefb_platform_data pd; 463 + struct ls2k_bmc_ddata *ddata; 464 + resource_size_t base; 465 + int ret; 466 + 467 + ret = pci_enable_device(dev); 468 + if (ret) 469 + return ret; 470 + 471 + ddata = devm_kzalloc(&dev->dev, sizeof(*ddata), GFP_KERNEL); 472 + if (IS_ERR(ddata)) { 473 + ret = -ENOMEM; 474 + goto disable_pci; 475 + } 476 + 477 + ddata->dev = &dev->dev; 478 + 479 + ret = ls2k_bmc_init(ddata); 480 + if (ret) 481 + goto disable_pci; 482 + 483 + ret = ls2k_bmc_parse_mode(dev, &pd); 484 + if (ret) 485 + goto disable_pci; 486 + 487 + ls2k_bmc_cells[LS2K_BMC_DISPLAY].platform_data = &pd; 488 + ls2k_bmc_cells[LS2K_BMC_DISPLAY].pdata_size = sizeof(pd); 489 + base = dev->resource[0].start + LS2K_DISPLAY_RES_START; 490 + 491 + /* Remove conflicting efifb device */ 492 + ret = aperture_remove_conflicting_devices(base, SZ_4M, "simple-framebuffer"); 493 + if (ret) { 494 + dev_err(&dev->dev, "Failed to removed firmware framebuffers: %d\n", ret); 495 + goto disable_pci; 496 + } 497 + 498 + return devm_mfd_add_devices(&dev->dev, PLATFORM_DEVID_AUTO, 499 + ls2k_bmc_cells, ARRAY_SIZE(ls2k_bmc_cells), 500 + &dev->resource[0], 0, NULL); 501 + 502 + disable_pci: 503 + pci_disable_device(dev); 504 + return ret; 505 + } 506 + 507 + static void ls2k_bmc_remove(struct pci_dev *dev) 508 + { 509 + pci_disable_device(dev); 510 + } 511 + 512 + static struct pci_device_id ls2k_bmc_devices[] = { 513 + { PCI_DEVICE(PCI_VENDOR_ID_LOONGSON, 0x1a05) }, 514 + { } 515 + }; 516 + MODULE_DEVICE_TABLE(pci, ls2k_bmc_devices); 517 + 518 + static struct pci_driver ls2k_bmc_driver = { 519 + .name = "ls2k-bmc", 520 + .id_table = ls2k_bmc_devices, 521 + .probe = ls2k_bmc_probe, 522 + .remove = ls2k_bmc_remove, 523 + }; 524 + module_pci_driver(ls2k_bmc_driver); 525 + 526 + MODULE_DESCRIPTION("Loongson-2K Board Management Controller (BMC) Core driver"); 527 + MODULE_AUTHOR("Loongson Technology Corporation Limited"); 528 + MODULE_LICENSE("GPL");
+3 -2
drivers/mfd/macsmc.c
··· 429 429 430 430 ret = devm_add_action_or_reset(dev, apple_smc_rtkit_shutdown, smc); 431 431 if (ret) 432 - return dev_err_probe(dev, ret, "Failed to register rtkit shutdown action"); 432 + return ret; 433 433 434 434 ret = apple_rtkit_start_ep(smc->rtk, SMC_ENDPOINT); 435 435 if (ret) ··· 465 465 apple_smc_write_flag(smc, SMC_KEY(NTAP), true); 466 466 ret = devm_add_action_or_reset(dev, apple_smc_disable_notifications, smc); 467 467 if (ret) 468 - return dev_err_probe(dev, ret, "Failed to register notification disable action"); 468 + return ret; 469 469 470 470 ret = devm_mfd_add_devices(smc->dev, PLATFORM_DEVID_NONE, 471 471 apple_smc_devs, ARRAY_SIZE(apple_smc_devs), ··· 478 478 } 479 479 480 480 static const struct of_device_id apple_smc_of_match[] = { 481 + { .compatible = "apple,t8103-smc" }, 481 482 { .compatible = "apple,smc" }, 482 483 {}, 483 484 };
+2 -2
drivers/mfd/madera-core.c
··· 456 456 struct device *dev = madera->dev; 457 457 unsigned int hwid; 458 458 int (*patch_fn)(struct madera *) = NULL; 459 - const struct mfd_cell *mfd_devs; 459 + const struct mfd_cell *mfd_devs = NULL; 460 460 int n_devs = 0; 461 461 int i, ret; 462 462 ··· 670 670 goto err_reset; 671 671 } 672 672 673 - if (!n_devs) { 673 + if (!n_devs || !mfd_devs) { 674 674 dev_err(madera->dev, "Device ID 0x%x not a %s\n", hwid, 675 675 madera->type_name); 676 676 ret = -ENODEV;
+14 -21
drivers/mfd/max77705.c
··· 61 61 .max_register = MAX77705_PMIC_REG_USBC_RESET, 62 62 }; 63 63 64 - static const struct regmap_irq max77705_topsys_irqs[] = { 65 - { .mask = MAX77705_SYSTEM_IRQ_BSTEN_INT, }, 66 - { .mask = MAX77705_SYSTEM_IRQ_SYSUVLO_INT, }, 67 - { .mask = MAX77705_SYSTEM_IRQ_SYSOVLO_INT, }, 68 - { .mask = MAX77705_SYSTEM_IRQ_TSHDN_INT, }, 69 - { .mask = MAX77705_SYSTEM_IRQ_TM_INT, }, 64 + static const struct regmap_irq max77705_irqs[] = { 65 + { .mask = MAX77705_SRC_IRQ_CHG, }, 66 + { .mask = MAX77705_SRC_IRQ_TOP, }, 67 + { .mask = MAX77705_SRC_IRQ_FG, }, 68 + { .mask = MAX77705_SRC_IRQ_USBC, }, 70 69 }; 71 70 72 - static const struct regmap_irq_chip max77705_topsys_irq_chip = { 73 - .name = "max77705-topsys", 74 - .status_base = MAX77705_PMIC_REG_SYSTEM_INT, 75 - .mask_base = MAX77705_PMIC_REG_SYSTEM_INT_MASK, 71 + static const struct regmap_irq_chip max77705_irq_chip = { 72 + .name = "max77705", 73 + .status_base = MAX77705_PMIC_REG_INTSRC, 74 + .ack_base = MAX77705_PMIC_REG_INTSRC, 75 + .mask_base = MAX77705_PMIC_REG_INTSRC_MASK, 76 76 .num_regs = 1, 77 - .irqs = max77705_topsys_irqs, 78 - .num_irqs = ARRAY_SIZE(max77705_topsys_irqs), 77 + .irqs = max77705_irqs, 78 + .num_irqs = ARRAY_SIZE(max77705_irqs), 79 79 }; 80 80 81 81 static int max77705_i2c_probe(struct i2c_client *i2c) ··· 110 110 111 111 ret = devm_regmap_add_irq_chip(dev, max77705->regmap, 112 112 i2c->irq, 113 - IRQF_ONESHOT | IRQF_SHARED, 0, 114 - &max77705_topsys_irq_chip, 113 + IRQF_ONESHOT, 0, 114 + &max77705_irq_chip, 115 115 &irq_data); 116 116 if (ret) 117 117 return dev_err_probe(dev, ret, "Failed to add IRQ chip\n"); 118 - 119 - /* Unmask interrupts from all blocks in interrupt source register */ 120 - ret = regmap_update_bits(max77705->regmap, 121 - MAX77705_PMIC_REG_INTSRC_MASK, 122 - MAX77705_SRC_IRQ_ALL, (unsigned int)~MAX77705_SRC_IRQ_ALL); 123 - if (ret < 0) 124 - return dev_err_probe(dev, ret, "Could not unmask interrupts in INTSRC\n"); 125 118 126 119 domain = regmap_irq_get_domain(irq_data); 127 120
+2 -2
drivers/mfd/max8997.c
··· 438 438 439 439 disable_irq(max8997->irq); 440 440 if (device_may_wakeup(dev)) 441 - irq_set_irq_wake(max8997->irq, 1); 441 + enable_irq_wake(max8997->irq); 442 442 return 0; 443 443 } 444 444 ··· 448 448 struct max8997_dev *max8997 = i2c_get_clientdata(i2c); 449 449 450 450 if (device_may_wakeup(dev)) 451 - irq_set_irq_wake(max8997->irq, 0); 451 + disable_irq_wake(max8997->irq); 452 452 enable_irq(max8997->irq); 453 453 return max8997_irq_resume(max8997); 454 454 }
+2 -2
drivers/mfd/max8998.c
··· 234 234 struct max8998_dev *max8998 = i2c_get_clientdata(i2c); 235 235 236 236 if (device_may_wakeup(dev)) 237 - irq_set_irq_wake(max8998->irq, 1); 237 + enable_irq_wake(max8998->irq); 238 238 return 0; 239 239 } 240 240 ··· 244 244 struct max8998_dev *max8998 = i2c_get_clientdata(i2c); 245 245 246 246 if (device_may_wakeup(dev)) 247 - irq_set_irq_wake(max8998->irq, 0); 247 + disable_irq_wake(max8998->irq); 248 248 /* 249 249 * In LP3974, if IRQ registers are not "read & clear" 250 250 * when it's set during sleep, the interrupt becomes
+1
drivers/mfd/mfd-core.c
··· 131 131 of_entry->np = np; 132 132 list_add_tail(&of_entry->list, &mfd_of_node_list); 133 133 134 + of_node_get(np); 134 135 device_set_node(&pdev->dev, of_fwnode_handle(np)); 135 136 #endif 136 137 return 0;
+24 -15
drivers/mfd/qnap-mcu.c
··· 150 150 size_t length = reply_data_size + QNAP_MCU_CHECKSUM_SIZE; 151 151 struct qnap_mcu_reply *reply = &mcu->reply; 152 152 int ret = 0; 153 + u8 crc; 153 154 154 155 if (length > sizeof(rx)) { 155 156 dev_err(&mcu->serdev->dev, "expected data too big for receive buffer"); 156 157 return -EINVAL; 157 158 } 158 159 159 - mutex_lock(&mcu->bus_lock); 160 + guard(mutex)(&mcu->bus_lock); 160 161 161 162 reply->data = rx; 162 163 reply->length = length; 163 164 reply->received = 0; 164 165 reinit_completion(&reply->done); 165 166 166 - qnap_mcu_write(mcu, cmd_data, cmd_data_size); 167 + ret = qnap_mcu_write(mcu, cmd_data, cmd_data_size); 168 + if (ret < 0) 169 + return ret; 167 170 168 171 serdev_device_wait_until_sent(mcu->serdev, msecs_to_jiffies(QNAP_MCU_TIMEOUT_MS)); 169 172 170 173 if (!wait_for_completion_timeout(&reply->done, msecs_to_jiffies(QNAP_MCU_TIMEOUT_MS))) { 171 174 dev_err(&mcu->serdev->dev, "Command timeout\n"); 172 - ret = -ETIMEDOUT; 173 - } else { 174 - u8 crc = qnap_mcu_csum(rx, reply_data_size); 175 - 176 - if (crc != rx[reply_data_size]) { 177 - dev_err(&mcu->serdev->dev, 178 - "Invalid Checksum received\n"); 179 - ret = -EIO; 180 - } else { 181 - memcpy(reply_data, rx, reply_data_size); 182 - } 175 + return -ETIMEDOUT; 183 176 } 184 177 185 - mutex_unlock(&mcu->bus_lock); 186 - return ret; 178 + crc = qnap_mcu_csum(rx, reply_data_size); 179 + if (crc != rx[reply_data_size]) { 180 + dev_err(&mcu->serdev->dev, "Invalid Checksum received\n"); 181 + return -EIO; 182 + } 183 + 184 + memcpy(reply_data, rx, reply_data_size); 185 + 186 + return 0; 187 187 } 188 188 EXPORT_SYMBOL_GPL(qnap_mcu_exec); 189 189 ··· 246 246 247 247 return NOTIFY_DONE; 248 248 } 249 + 250 + static const struct qnap_mcu_variant qnap_ts233_mcu = { 251 + .baud_rate = 115200, 252 + .num_drives = 2, 253 + .fan_pwm_min = 51, /* Specified in original model.conf */ 254 + .fan_pwm_max = 255, 255 + .usb_led = true, 256 + }; 249 257 250 258 static const struct qnap_mcu_variant qnap_ts433_mcu = { 251 259 .baud_rate = 115200, ··· 327 319 } 328 320 329 321 static const struct of_device_id qnap_mcu_dt_ids[] = { 322 + { .compatible = "qnap,ts233-mcu", .data = &qnap_ts233_mcu }, 330 323 { .compatible = "qnap,ts433-mcu", .data = &qnap_ts433_mcu }, 331 324 { /* sentinel */ } 332 325 };
+35 -9
drivers/mfd/rohm-bd71828.c
··· 45 45 46 46 static const struct resource bd71815_power_irqs[] = { 47 47 DEFINE_RES_IRQ_NAMED(BD71815_INT_DCIN_RMV, "bd71815-dcin-rmv"), 48 - DEFINE_RES_IRQ_NAMED(BD71815_INT_CLPS_OUT, "bd71815-clps-out"), 49 - DEFINE_RES_IRQ_NAMED(BD71815_INT_CLPS_IN, "bd71815-clps-in"), 48 + DEFINE_RES_IRQ_NAMED(BD71815_INT_CLPS_OUT, "bd71815-dcin-clps-out"), 49 + DEFINE_RES_IRQ_NAMED(BD71815_INT_CLPS_IN, "bd71815-dcin-clps-in"), 50 50 DEFINE_RES_IRQ_NAMED(BD71815_INT_DCIN_OVP_RES, "bd71815-dcin-ovp-res"), 51 51 DEFINE_RES_IRQ_NAMED(BD71815_INT_DCIN_OVP_DET, "bd71815-dcin-ovp-det"), 52 52 DEFINE_RES_IRQ_NAMED(BD71815_INT_DCIN_MON_RES, "bd71815-dcin-mon-res"), ··· 56 56 DEFINE_RES_IRQ_NAMED(BD71815_INT_VSYS_LOW_RES, "bd71815-vsys-low-res"), 57 57 DEFINE_RES_IRQ_NAMED(BD71815_INT_VSYS_LOW_DET, "bd71815-vsys-low-det"), 58 58 DEFINE_RES_IRQ_NAMED(BD71815_INT_VSYS_MON_RES, "bd71815-vsys-mon-res"), 59 - DEFINE_RES_IRQ_NAMED(BD71815_INT_VSYS_MON_RES, "bd71815-vsys-mon-det"), 59 + DEFINE_RES_IRQ_NAMED(BD71815_INT_VSYS_MON_DET, "bd71815-vsys-mon-det"), 60 60 DEFINE_RES_IRQ_NAMED(BD71815_INT_CHG_WDG_TEMP, "bd71815-chg-wdg-temp"), 61 61 DEFINE_RES_IRQ_NAMED(BD71815_INT_CHG_WDG_TIME, "bd71815-chg-wdg"), 62 62 DEFINE_RES_IRQ_NAMED(BD71815_INT_CHG_RECHARGE_RES, "bd71815-rechg-res"), ··· 87 87 DEFINE_RES_IRQ_NAMED(BD71815_INT_BAT_OVER_CURR_2_DET, "bd71815-bat-oc2-det"), 88 88 DEFINE_RES_IRQ_NAMED(BD71815_INT_BAT_OVER_CURR_3_RES, "bd71815-bat-oc3-res"), 89 89 DEFINE_RES_IRQ_NAMED(BD71815_INT_BAT_OVER_CURR_3_DET, "bd71815-bat-oc3-det"), 90 - DEFINE_RES_IRQ_NAMED(BD71815_INT_TEMP_BAT_LOW_RES, "bd71815-bat-low-res"), 91 - DEFINE_RES_IRQ_NAMED(BD71815_INT_TEMP_BAT_LOW_DET, "bd71815-bat-low-det"), 92 - DEFINE_RES_IRQ_NAMED(BD71815_INT_TEMP_BAT_HI_RES, "bd71815-bat-hi-res"), 93 - DEFINE_RES_IRQ_NAMED(BD71815_INT_TEMP_BAT_HI_DET, "bd71815-bat-hi-det"), 90 + DEFINE_RES_IRQ_NAMED(BD71815_INT_TEMP_BAT_LOW_RES, "bd71815-temp-bat-low-res"), 91 + DEFINE_RES_IRQ_NAMED(BD71815_INT_TEMP_BAT_LOW_DET, "bd71815-temp-bat-low-det"), 92 + DEFINE_RES_IRQ_NAMED(BD71815_INT_TEMP_BAT_HI_RES, "bd71815-temp-bat-hi-res"), 93 + DEFINE_RES_IRQ_NAMED(BD71815_INT_TEMP_BAT_HI_DET, "bd71815-temp-bat-hi-det"), 94 94 }; 95 95 96 96 static const struct mfd_cell bd71815_mfd_cells[] = { ··· 109 109 }, 110 110 }; 111 111 112 - static const struct mfd_cell bd71828_mfd_cells[] = { 112 + static const struct resource bd71828_power_irqs[] = { 113 + DEFINE_RES_IRQ_NAMED(BD71828_INT_CHG_TOPOFF_TO_DONE, 114 + "bd71828-chg-done"), 115 + DEFINE_RES_IRQ_NAMED(BD71828_INT_DCIN_DET, "bd71828-pwr-dcin-in"), 116 + DEFINE_RES_IRQ_NAMED(BD71828_INT_DCIN_RMV, "bd71828-pwr-dcin-out"), 117 + DEFINE_RES_IRQ_NAMED(BD71828_INT_BAT_LOW_VOLT_RES, 118 + "bd71828-vbat-normal"), 119 + DEFINE_RES_IRQ_NAMED(BD71828_INT_BAT_LOW_VOLT_DET, "bd71828-vbat-low"), 120 + DEFINE_RES_IRQ_NAMED(BD71828_INT_TEMP_BAT_HI_DET, "bd71828-btemp-hi"), 121 + DEFINE_RES_IRQ_NAMED(BD71828_INT_TEMP_BAT_HI_RES, "bd71828-btemp-cool"), 122 + DEFINE_RES_IRQ_NAMED(BD71828_INT_TEMP_BAT_LOW_DET, "bd71828-btemp-lo"), 123 + DEFINE_RES_IRQ_NAMED(BD71828_INT_TEMP_BAT_LOW_RES, 124 + "bd71828-btemp-warm"), 125 + DEFINE_RES_IRQ_NAMED(BD71828_INT_TEMP_CHIP_OVER_VF_DET, 126 + "bd71828-temp-hi"), 127 + DEFINE_RES_IRQ_NAMED(BD71828_INT_TEMP_CHIP_OVER_VF_RES, 128 + "bd71828-temp-norm"), 129 + DEFINE_RES_IRQ_NAMED(BD71828_INT_TEMP_CHIP_OVER_125_DET, 130 + "bd71828-temp-125-over"), 131 + DEFINE_RES_IRQ_NAMED(BD71828_INT_TEMP_CHIP_OVER_125_RES, 132 + "bd71828-temp-125-under"), 133 + }; 134 + 135 + static struct mfd_cell bd71828_mfd_cells[] = { 113 136 { .name = "bd71828-pmic", }, 114 137 { .name = "bd71828-gpio", }, 115 138 { .name = "bd71828-led", .of_compatible = "rohm,bd71828-leds" }, ··· 141 118 * BD70528 clock gate are the register address and mask. 142 119 */ 143 120 { .name = "bd71828-clk", }, 144 - { .name = "bd71827-power", }, 145 121 { 122 + .name = "bd71828-power", 123 + .resources = bd71828_power_irqs, 124 + .num_resources = ARRAY_SIZE(bd71828_power_irqs), 125 + }, { 146 126 .name = "bd71828-rtc", 147 127 .resources = bd71828_rtc_irqs, 148 128 .num_resources = ARRAY_SIZE(bd71828_rtc_irqs),
+1 -1
drivers/mfd/rz-mtu3.c
··· 32 32 [RZ_MTU3_CHAN_2] = MTU_8BIT_CH_1_2(0x204, 0x092, 0x205, 0x200, 0x20c, 0x201, 0x202), 33 33 [RZ_MTU3_CHAN_3] = MTU_8BIT_CH_3_4_6_7(0x008, 0x093, 0x02c, 0x000, 0x04c, 0x002, 0x004, 0x005, 0x038), 34 34 [RZ_MTU3_CHAN_4] = MTU_8BIT_CH_3_4_6_7(0x009, 0x094, 0x02d, 0x001, 0x04d, 0x003, 0x006, 0x007, 0x039), 35 - [RZ_MTU3_CHAN_5] = MTU_8BIT_CH_5(0xab2, 0x1eb, 0xab4, 0xab6, 0xa84, 0xa85, 0xa86, 0xa94, 0xa95, 0xa96, 0xaa4, 0xaa5, 0xaa6), 35 + [RZ_MTU3_CHAN_5] = MTU_8BIT_CH_5(0xab2, 0x895, 0xab4, 0xab6, 0xa84, 0xa85, 0xa86, 0xa94, 0xa95, 0xa96, 0xaa4, 0xaa5, 0xaa6), 36 36 [RZ_MTU3_CHAN_6] = MTU_8BIT_CH_3_4_6_7(0x808, 0x893, 0x82c, 0x800, 0x84c, 0x802, 0x804, 0x805, 0x838), 37 37 [RZ_MTU3_CHAN_7] = MTU_8BIT_CH_3_4_6_7(0x809, 0x894, 0x82d, 0x801, 0x84d, 0x803, 0x806, 0x807, 0x839), 38 38 [RZ_MTU3_CHAN_8] = MTU_8BIT_CH_8(0x404, 0x098, 0x400, 0x406, 0x401, 0x402, 0x403)
+21 -1
drivers/mfd/simple-mfd-i2c.c
··· 93 93 .mfd_cell_size = ARRAY_SIZE(max77705_sensor_cells), 94 94 }; 95 95 96 + static const struct regmap_config spacemit_p1_regmap_config = { 97 + .reg_bits = 8, 98 + .val_bits = 8, 99 + }; 100 + 101 + static const struct mfd_cell spacemit_p1_cells[] = { 102 + { .name = "spacemit-p1-regulator", }, 103 + { .name = "spacemit-p1-rtc", }, 104 + }; 105 + 106 + static const struct simple_mfd_data spacemit_p1 = { 107 + .regmap_config = &spacemit_p1_regmap_config, 108 + .mfd_cell = spacemit_p1_cells, 109 + .mfd_cell_size = ARRAY_SIZE(spacemit_p1_cells), 110 + }; 111 + 96 112 static const struct of_device_id simple_mfd_i2c_of_match[] = { 113 + { .compatible = "fsl,ls1028aqds-fpga" }, 114 + { .compatible = "fsl,lx2160aqds-fpga" }, 115 + { .compatible = "fsl,lx2160ardb-fpga" }, 97 116 { .compatible = "kontron,sl28cpld" }, 98 - { .compatible = "silergy,sy7636a", .data = &silergy_sy7636a}, 99 117 { .compatible = "maxim,max5970", .data = &maxim_max5970}, 100 118 { .compatible = "maxim,max5978", .data = &maxim_max5970}, 101 119 { .compatible = "maxim,max77705-battery", .data = &maxim_mon_max77705}, 120 + { .compatible = "silergy,sy7636a", .data = &silergy_sy7636a}, 121 + { .compatible = "spacemit,p1", .data = &spacemit_p1, }, 102 122 {} 103 123 }; 104 124 MODULE_DEVICE_TABLE(of, simple_mfd_i2c_of_match);
-1
drivers/mfd/stm32-lptimer.c
··· 19 19 .val_bits = 32, 20 20 .reg_stride = sizeof(u32), 21 21 .max_register = STM32_LPTIM_MAX_REGISTER, 22 - .fast_io = true, 23 22 }; 24 23 25 24 static int stm32_lptimer_detect_encoder(struct stm32_lptimer *ddata)
+2 -13
drivers/mfd/stmpe-i2c.c
··· 122 122 .remove = stmpe_i2c_remove, 123 123 .id_table = stmpe_i2c_id, 124 124 }; 125 - 126 - static int __init stmpe_init(void) 127 - { 128 - return i2c_add_driver(&stmpe_i2c_driver); 129 - } 130 - subsys_initcall(stmpe_init); 131 - 132 - static void __exit stmpe_exit(void) 133 - { 134 - i2c_del_driver(&stmpe_i2c_driver); 135 - } 136 - module_exit(stmpe_exit); 125 + module_i2c_driver(stmpe_i2c_driver); 137 126 138 127 MODULE_DESCRIPTION("STMPE MFD I2C Interface Driver"); 139 128 MODULE_AUTHOR("Rabin Vincent <rabin.vincent@stericsson.com>"); 140 - MODULE_LICENSE("GPL v2"); 129 + MODULE_LICENSE("GPL");
+2 -13
drivers/mfd/stmpe-spi.c
··· 141 141 .remove = stmpe_spi_remove, 142 142 .id_table = stmpe_spi_id, 143 143 }; 144 - 145 - static int __init stmpe_init(void) 146 - { 147 - return spi_register_driver(&stmpe_spi_driver); 148 - } 149 - subsys_initcall(stmpe_init); 150 - 151 - static void __exit stmpe_exit(void) 152 - { 153 - spi_unregister_driver(&stmpe_spi_driver); 154 - } 155 - module_exit(stmpe_exit); 144 + module_spi_driver(stmpe_spi_driver); 156 145 157 146 MODULE_DESCRIPTION("STMPE MFD SPI Interface Driver"); 158 147 MODULE_AUTHOR("Viresh Kumar <vireshk@kernel.org>"); 159 - MODULE_LICENSE("GPL v2"); 148 + MODULE_LICENSE("GPL");
+3
drivers/mfd/stmpe.c
··· 1486 1486 1487 1487 void stmpe_remove(struct stmpe *stmpe) 1488 1488 { 1489 + if (stmpe->domain) 1490 + irq_domain_remove(stmpe->domain); 1491 + 1489 1492 if (!IS_ERR(stmpe->vio) && regulator_is_enabled(stmpe->vio)) 1490 1493 regulator_disable(stmpe->vio); 1491 1494 if (!IS_ERR(stmpe->vcc) && regulator_is_enabled(stmpe->vcc))
-1
drivers/mfd/sun4i-gpadc.c
··· 72 72 .reg_bits = 32, 73 73 .val_bits = 32, 74 74 .reg_stride = 4, 75 - .fast_io = true, 76 75 }; 77 76 78 77 static const struct of_device_id sun4i_gpadc_of_match[] = {
+57 -2
drivers/mfd/tps6594-core.c
··· 10 10 * Copyright (C) 2023 BayLibre Incorporated - https://www.baylibre.com/ 11 11 */ 12 12 13 + #include <linux/bitfield.h> 13 14 #include <linux/completion.h> 14 15 #include <linux/delay.h> 15 16 #include <linux/interrupt.h> 16 17 #include <linux/module.h> 17 18 #include <linux/of.h> 19 + #include <linux/reboot.h> 18 20 19 21 #include <linux/mfd/core.h> 20 22 #include <linux/mfd/tps6594.h> 21 23 22 24 #define TPS6594_CRC_SYNC_TIMEOUT_MS 150 25 + #define TPS65224_EN_SEL_PB 1 26 + #define TPS65224_GPIO3_SEL_PB 3 23 27 24 28 /* Completion to synchronize CRC feature enabling on all PMICs */ 25 29 static DECLARE_COMPLETION(tps6594_crc_comp); ··· 130 126 DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_TIMER, TPS6594_IRQ_NAME_TIMER), 131 127 DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_ALARM, TPS6594_IRQ_NAME_ALARM), 132 128 DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_POWER_UP, TPS6594_IRQ_NAME_POWERUP), 129 + }; 130 + 131 + static const struct resource tps6594_pwrbutton_resources[] = { 132 + DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_PB_FALL, TPS65224_IRQ_NAME_PB_FALL), 133 + DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_PB_RISE, TPS65224_IRQ_NAME_PB_RISE), 134 + DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_PB_SHORT, TPS65224_IRQ_NAME_PB_SHORT), 133 135 }; 134 136 135 137 static const struct mfd_cell tps6594_common_cells[] = { ··· 328 318 DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_REG_UNLOCK, TPS65224_IRQ_NAME_REG_UNLOCK), 329 319 DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_TWARN, TPS65224_IRQ_NAME_TWARN), 330 320 DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_PB_LONG, TPS65224_IRQ_NAME_PB_LONG), 331 - DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_PB_FALL, TPS65224_IRQ_NAME_PB_FALL), 332 - DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_PB_RISE, TPS65224_IRQ_NAME_PB_RISE), 333 321 DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_TSD_ORD, TPS65224_IRQ_NAME_TSD_ORD), 334 322 DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_BIST_FAIL, TPS65224_IRQ_NAME_BIST_FAIL), 335 323 DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_REG_CRC_ERR, TPS65224_IRQ_NAME_REG_CRC_ERR), ··· 353 345 MFD_CELL_RES("tps6594-pfsm", tps65224_pfsm_resources), 354 346 MFD_CELL_RES("tps6594-pinctrl", tps65224_pinctrl_resources), 355 347 MFD_CELL_RES("tps6594-regulator", tps65224_regulator_resources), 348 + }; 349 + 350 + static const struct mfd_cell tps6594_pwrbutton_cell = { 351 + .name = "tps6594-pwrbutton", 352 + .resources = tps6594_pwrbutton_resources, 353 + .num_resources = ARRAY_SIZE(tps6594_pwrbutton_resources), 356 354 }; 357 355 358 356 static const struct regmap_irq tps65224_irqs[] = { ··· 690 676 return ret; 691 677 } 692 678 679 + static int tps6594_power_off_handler(struct sys_off_data *data) 680 + { 681 + struct tps6594 *tps = data->cb_data; 682 + int ret; 683 + 684 + ret = regmap_update_bits(tps->regmap, TPS6594_REG_FSM_I2C_TRIGGERS, 685 + TPS6594_BIT_TRIGGER_I2C(0), TPS6594_BIT_TRIGGER_I2C(0)); 686 + if (ret) 687 + return notifier_from_errno(ret); 688 + 689 + return NOTIFY_DONE; 690 + } 691 + 693 692 int tps6594_device_init(struct tps6594 *tps, bool enable_crc) 694 693 { 695 694 struct device *dev = tps->dev; 696 695 int ret; 697 696 struct regmap_irq_chip *irq_chip; 697 + unsigned int pwr_on, gpio3_cfg; 698 698 const struct mfd_cell *cells; 699 699 int n_cells; 700 700 ··· 755 727 if (ret) 756 728 return dev_err_probe(dev, ret, "Failed to add common child devices\n"); 757 729 730 + /* If either the PB/EN/VSENSE or GPIO3 is configured as PB, register a driver for it */ 731 + if (tps->chip_id == TPS65224 || tps->chip_id == TPS652G1) { 732 + ret = regmap_read(tps->regmap, TPS6594_REG_NPWRON_CONF, &pwr_on); 733 + if (ret) 734 + return dev_err_probe(dev, ret, "Failed to read PB/EN/VSENSE config\n"); 735 + 736 + ret = regmap_read(tps->regmap, TPS6594_REG_GPIOX_CONF(2), &gpio3_cfg); 737 + if (ret) 738 + return dev_err_probe(dev, ret, "Failed to read GPIO3 config\n"); 739 + 740 + if (FIELD_GET(TPS65224_MASK_EN_PB_VSENSE_CONFIG, pwr_on) == TPS65224_EN_SEL_PB || 741 + FIELD_GET(TPS65224_MASK_GPIO_SEL, gpio3_cfg) == TPS65224_GPIO3_SEL_PB) { 742 + ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_AUTO, 743 + &tps6594_pwrbutton_cell, 1, NULL, 0, 744 + regmap_irq_get_domain(tps->irq_data)); 745 + if (ret) 746 + return dev_err_probe(dev, ret, 747 + "Failed to add power button device.\n"); 748 + } 749 + } 750 + 758 751 /* No RTC for LP8764, TPS65224 and TPS652G1 */ 759 752 if (tps->chip_id != LP8764 && tps->chip_id != TPS65224 && tps->chip_id != TPS652G1) { 760 753 ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_AUTO, tps6594_rtc_cells, ··· 783 734 regmap_irq_get_domain(tps->irq_data)); 784 735 if (ret) 785 736 return dev_err_probe(dev, ret, "Failed to add RTC child device\n"); 737 + } 738 + 739 + if (of_device_is_system_power_controller(dev->of_node)) { 740 + ret = devm_register_power_off_handler(tps->dev, tps6594_power_off_handler, tps); 741 + if (ret) 742 + return dev_err_probe(dev, ret, "Failed to register power-off handler\n"); 786 743 } 787 744 788 745 return 0;
+1 -1
drivers/mfd/vexpress-sysreg.c
··· 120 120 if (!mmc_gpio_chip) 121 121 return -ENOMEM; 122 122 123 - config = (typeof(config)){ 123 + config = (struct gpio_generic_chip_config) { 124 124 .dev = &pdev->dev, 125 125 .sz = 4, 126 126 .dat = base + SYS_MCI,
+7
drivers/power/supply/Kconfig
··· 767 767 rail, ADC for battery and system monitoring, and push-button 768 768 controller. 769 769 770 + config CHARGER_BQ257XX 771 + tristate "TI BQ257XX battery charger family" 772 + depends on MFD_BQ257XX 773 + help 774 + Say Y to enable support for the TI BQ257XX family of battery 775 + charging integrated circuits. 776 + 770 777 config CHARGER_BQ25890 771 778 tristate "TI BQ25890 battery charger driver" 772 779 depends on I2C
+1
drivers/power/supply/Makefile
··· 97 97 obj-$(CONFIG_CHARGER_BQ24257) += bq24257_charger.o 98 98 obj-$(CONFIG_CHARGER_BQ24735) += bq24735-charger.o 99 99 obj-$(CONFIG_CHARGER_BQ2515X) += bq2515x_charger.o 100 + obj-$(CONFIG_CHARGER_BQ257XX) += bq257xx_charger.o 100 101 obj-$(CONFIG_CHARGER_BQ25890) += bq25890_charger.o 101 102 obj-$(CONFIG_CHARGER_BQ25980) += bq25980_charger.o 102 103 obj-$(CONFIG_CHARGER_BQ256XX) += bq256xx_charger.o
+755
drivers/power/supply/bq257xx_charger.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * BQ257XX Battery Charger Driver 4 + * Copyright (C) 2025 Chris Morgan <macromorgan@hotmail.com> 5 + */ 6 + 7 + #include <linux/bitfield.h> 8 + #include <linux/i2c.h> 9 + #include <linux/interrupt.h> 10 + #include <linux/mfd/bq257xx.h> 11 + #include <linux/platform_device.h> 12 + #include <linux/power_supply.h> 13 + #include <linux/property.h> 14 + #include <linux/regmap.h> 15 + 16 + /* Forward declaration of driver data. */ 17 + struct bq257xx_chg; 18 + 19 + /** 20 + * struct bq257xx_chip_info - chip specific routines 21 + * @bq257xx_hw_init: init function for hw 22 + * @bq257xx_hw_shutdown: shutdown function for hw 23 + * @bq257xx_get_state: get and update state of hardware 24 + * @bq257xx_set_ichg: set maximum charge current (in uA) 25 + * @bq257xx_set_vbatreg: set maximum charge voltage (in uV) 26 + * @bq257xx_set_iindpm: set maximum input current (in uA) 27 + */ 28 + struct bq257xx_chip_info { 29 + int (*bq257xx_hw_init)(struct bq257xx_chg *pdata); 30 + void (*bq257xx_hw_shutdown)(struct bq257xx_chg *pdata); 31 + int (*bq257xx_get_state)(struct bq257xx_chg *pdata); 32 + int (*bq257xx_set_ichg)(struct bq257xx_chg *pdata, int ichg); 33 + int (*bq257xx_set_vbatreg)(struct bq257xx_chg *pdata, int vbatreg); 34 + int (*bq257xx_set_iindpm)(struct bq257xx_chg *pdata, int iindpm); 35 + }; 36 + 37 + /** 38 + * struct bq257xx_chg - driver data for charger 39 + * @chip: hw specific functions 40 + * @bq: parent MFD device 41 + * @charger: power supply device 42 + * @online: charger input is present 43 + * @fast_charge: charger is in fast charge mode 44 + * @pre_charge: charger is in pre-charge mode 45 + * @ov_fault: charger reports over voltage fault 46 + * @batoc_fault: charger reports battery over current fault 47 + * @oc_fault: charger reports over current fault 48 + * @usb_type: USB type reported from parent power supply 49 + * @supplied: Status of parent power supply 50 + * @iindpm_max: maximum input current limit (uA) 51 + * @vbat_max: maximum charge voltage (uV) 52 + * @ichg_max: maximum charge current (uA) 53 + * @vsys_min: minimum system voltage (uV) 54 + */ 55 + struct bq257xx_chg { 56 + const struct bq257xx_chip_info *chip; 57 + struct bq257xx_device *bq; 58 + struct power_supply *charger; 59 + bool online; 60 + bool fast_charge; 61 + bool pre_charge; 62 + bool ov_fault; 63 + bool batoc_fault; 64 + bool oc_fault; 65 + int usb_type; 66 + int supplied; 67 + u32 iindpm_max; 68 + u32 vbat_max; 69 + u32 ichg_max; 70 + u32 vsys_min; 71 + }; 72 + 73 + /** 74 + * bq25703_get_state() - Get the current state of the device 75 + * @pdata: driver platform data 76 + * 77 + * Get the current state of the charger. Check if the charger is 78 + * powered, what kind of charge state (if any) the device is in, 79 + * and if there are any active faults. 80 + * 81 + * Return: Returns 0 on success, or error on failure to read device. 82 + */ 83 + static int bq25703_get_state(struct bq257xx_chg *pdata) 84 + { 85 + unsigned int reg; 86 + int ret; 87 + 88 + ret = regmap_read(pdata->bq->regmap, BQ25703_CHARGER_STATUS, &reg); 89 + if (ret) 90 + return ret; 91 + 92 + pdata->online = reg & BQ25703_STS_AC_STAT; 93 + pdata->fast_charge = reg & BQ25703_STS_IN_FCHRG; 94 + pdata->pre_charge = reg & BQ25703_STS_IN_PCHRG; 95 + pdata->ov_fault = reg & BQ25703_STS_FAULT_ACOV; 96 + pdata->batoc_fault = reg & BQ25703_STS_FAULT_BATOC; 97 + pdata->oc_fault = reg & BQ25703_STS_FAULT_ACOC; 98 + 99 + return 0; 100 + } 101 + 102 + /** 103 + * bq25703_get_min_vsys() - Get the minimum system voltage 104 + * @pdata: driver platform data 105 + * @intval: value for minimum voltage 106 + * 107 + * Return: Returns 0 on success or error on failure to read. 108 + */ 109 + static int bq25703_get_min_vsys(struct bq257xx_chg *pdata, int *intval) 110 + { 111 + unsigned int reg; 112 + int ret; 113 + 114 + ret = regmap_read(pdata->bq->regmap, BQ25703_MIN_VSYS, 115 + &reg); 116 + if (ret) 117 + return ret; 118 + 119 + reg = FIELD_GET(BQ25703_MINVSYS_MASK, reg); 120 + *intval = (reg * BQ25703_MINVSYS_STEP_UV) + BQ25703_MINVSYS_MIN_UV; 121 + 122 + return ret; 123 + } 124 + 125 + /** 126 + * bq25703_set_min_vsys() - Set the minimum system voltage 127 + * @pdata: driver platform data 128 + * @vsys: voltage value to set in uV. 129 + * 130 + * This function takes a requested minimum system voltage value, clamps 131 + * it between the minimum supported value by the charger and a user 132 + * defined minimum system value, and then writes the value to the 133 + * appropriate register. 134 + * 135 + * Return: Returns 0 on success or error if an error occurs. 136 + */ 137 + static int bq25703_set_min_vsys(struct bq257xx_chg *pdata, int vsys) 138 + { 139 + unsigned int reg; 140 + int vsys_min = pdata->vsys_min; 141 + 142 + vsys = clamp(vsys, BQ25703_MINVSYS_MIN_UV, vsys_min); 143 + reg = ((vsys - BQ25703_MINVSYS_MIN_UV) / BQ25703_MINVSYS_STEP_UV); 144 + reg = FIELD_PREP(BQ25703_MINVSYS_MASK, reg); 145 + 146 + return regmap_write(pdata->bq->regmap, BQ25703_MIN_VSYS, 147 + reg); 148 + } 149 + 150 + /** 151 + * bq25703_get_cur() - Get the reported current from the battery 152 + * @pdata: driver platform data 153 + * @intval: value of reported battery current 154 + * 155 + * Read the reported current from the battery. Since value is always 156 + * positive set sign to negative if discharging. 157 + * 158 + * Return: Returns 0 on success or error if unable to read value. 159 + */ 160 + static int bq25703_get_cur(struct bq257xx_chg *pdata, int *intval) 161 + { 162 + unsigned int reg; 163 + int ret; 164 + 165 + ret = regmap_read(pdata->bq->regmap, BQ25703_ADCIBAT_CHG, &reg); 166 + if (ret < 0) 167 + return ret; 168 + 169 + if (pdata->online) 170 + *intval = FIELD_GET(BQ25703_ADCIBAT_CHG_MASK, reg) * 171 + BQ25703_ADCIBAT_CHG_STEP_UA; 172 + else 173 + *intval = -(FIELD_GET(BQ25703_ADCIBAT_DISCHG_MASK, reg) * 174 + BQ25703_ADCIBAT_DIS_STEP_UA); 175 + 176 + return ret; 177 + } 178 + 179 + /** 180 + * bq25703_get_ichg_cur() - Get the maximum reported charge current 181 + * @pdata: driver platform data 182 + * @intval: value of maximum reported charge current 183 + * 184 + * Get the maximum reported charge current from the battery. 185 + * 186 + * Return: Returns 0 on success or error if unable to read value. 187 + */ 188 + static int bq25703_get_ichg_cur(struct bq257xx_chg *pdata, int *intval) 189 + { 190 + unsigned int reg; 191 + int ret; 192 + 193 + ret = regmap_read(pdata->bq->regmap, BQ25703_CHARGE_CURRENT, &reg); 194 + if (ret) 195 + return ret; 196 + 197 + *intval = FIELD_GET(BQ25703_ICHG_MASK, reg) * BQ25703_ICHG_STEP_UA; 198 + 199 + return ret; 200 + } 201 + 202 + /** 203 + * bq25703_set_ichg_cur() - Set the maximum charge current 204 + * @pdata: driver platform data 205 + * @ichg: current value to set in uA. 206 + * 207 + * This function takes a requested maximum charge current value, clamps 208 + * it between the minimum supported value by the charger and a user 209 + * defined maximum charging value, and then writes the value to the 210 + * appropriate register. 211 + * 212 + * Return: Returns 0 on success or error if an error occurs. 213 + */ 214 + static int bq25703_set_ichg_cur(struct bq257xx_chg *pdata, int ichg) 215 + { 216 + unsigned int reg; 217 + int ichg_max = pdata->ichg_max; 218 + 219 + ichg = clamp(ichg, BQ25703_ICHG_MIN_UA, ichg_max); 220 + reg = FIELD_PREP(BQ25703_ICHG_MASK, (ichg / BQ25703_ICHG_STEP_UA)); 221 + 222 + return regmap_write(pdata->bq->regmap, BQ25703_CHARGE_CURRENT, 223 + reg); 224 + } 225 + 226 + /** 227 + * bq25703_get_chrg_volt() - Get the maximum set charge voltage 228 + * @pdata: driver platform data 229 + * @intval: maximum charge voltage value 230 + * 231 + * Return: Returns 0 on success or error if unable to read value. 232 + */ 233 + static int bq25703_get_chrg_volt(struct bq257xx_chg *pdata, int *intval) 234 + { 235 + unsigned int reg; 236 + int ret; 237 + 238 + ret = regmap_read(pdata->bq->regmap, BQ25703_MAX_CHARGE_VOLT, 239 + &reg); 240 + if (ret) 241 + return ret; 242 + 243 + *intval = FIELD_GET(BQ25703_MAX_CHARGE_VOLT_MASK, reg) * 244 + BQ25703_VBATREG_STEP_UV; 245 + 246 + return ret; 247 + } 248 + 249 + /** 250 + * bq25703_set_chrg_volt() - Set the maximum charge voltage 251 + * @pdata: driver platform data 252 + * @vbat: voltage value to set in uV. 253 + * 254 + * This function takes a requested maximum charge voltage value, clamps 255 + * it between the minimum supported value by the charger and a user 256 + * defined maximum charging value, and then writes the value to the 257 + * appropriate register. 258 + * 259 + * Return: Returns 0 on success or error if an error occurs. 260 + */ 261 + static int bq25703_set_chrg_volt(struct bq257xx_chg *pdata, int vbat) 262 + { 263 + unsigned int reg; 264 + int vbat_max = pdata->vbat_max; 265 + 266 + vbat = clamp(vbat, BQ25703_VBATREG_MIN_UV, vbat_max); 267 + 268 + reg = FIELD_PREP(BQ25703_MAX_CHARGE_VOLT_MASK, 269 + (vbat / BQ25703_VBATREG_STEP_UV)); 270 + 271 + return regmap_write(pdata->bq->regmap, BQ25703_MAX_CHARGE_VOLT, 272 + reg); 273 + } 274 + 275 + /** 276 + * bq25703_get_iindpm() - Get the maximum set input current 277 + * @pdata: driver platform data 278 + * @intval: maximum input current value 279 + * 280 + * Read the actual input current limit from the device into intval. 281 + * This can differ from the value programmed due to some autonomous 282 + * functions that may be enabled (but are not currently). This is why 283 + * there is a different register used. 284 + * 285 + * Return: Returns 0 on success or error if unable to read register 286 + * value. 287 + */ 288 + static int bq25703_get_iindpm(struct bq257xx_chg *pdata, int *intval) 289 + { 290 + unsigned int reg; 291 + int ret; 292 + 293 + ret = regmap_read(pdata->bq->regmap, BQ25703_IIN_DPM, &reg); 294 + if (ret) 295 + return ret; 296 + 297 + reg = FIELD_GET(BQ25703_IINDPM_MASK, reg); 298 + *intval = (reg * BQ25703_IINDPM_STEP_UA) + BQ25703_IINDPM_OFFSET_UA; 299 + 300 + return ret; 301 + } 302 + 303 + /** 304 + * bq25703_set_iindpm() - Set the maximum input current 305 + * @pdata: driver platform data 306 + * @iindpm: current value in uA. 307 + * 308 + * This function takes a requested maximum input current value, clamps 309 + * it between the minimum supported value by the charger and a user 310 + * defined maximum input value, and then writes the value to the 311 + * appropriate register. 312 + * 313 + * Return: Returns 0 on success or error if an error occurs. 314 + */ 315 + static int bq25703_set_iindpm(struct bq257xx_chg *pdata, int iindpm) 316 + { 317 + unsigned int reg; 318 + int iindpm_max = pdata->iindpm_max; 319 + 320 + iindpm = clamp(iindpm, BQ25703_IINDPM_MIN_UA, iindpm_max); 321 + 322 + reg = ((iindpm - BQ25703_IINDPM_OFFSET_UA) / BQ25703_IINDPM_STEP_UA); 323 + 324 + return regmap_write(pdata->bq->regmap, BQ25703_IIN_HOST, 325 + FIELD_PREP(BQ25703_IINDPM_MASK, reg)); 326 + } 327 + 328 + /** 329 + * bq25703_get_vbat() - Get the reported voltage from the battery 330 + * @pdata: driver platform data 331 + * @intval: value of reported battery voltage 332 + * 333 + * Read value of battery voltage into intval. 334 + * 335 + * Return: Returns 0 on success or error if unable to read value. 336 + */ 337 + static int bq25703_get_vbat(struct bq257xx_chg *pdata, int *intval) 338 + { 339 + unsigned int reg; 340 + int ret; 341 + 342 + ret = regmap_read(pdata->bq->regmap, BQ25703_ADCVSYSVBAT, &reg); 343 + if (ret) 344 + return ret; 345 + 346 + reg = FIELD_GET(BQ25703_ADCVBAT_MASK, reg); 347 + *intval = (reg * BQ25703_ADCVSYSVBAT_STEP) + BQ25703_ADCVSYSVBAT_OFFSET_UV; 348 + 349 + return ret; 350 + } 351 + 352 + /** 353 + * bq25703_hw_init() - Set all the required registers to init the charger 354 + * @pdata: driver platform data 355 + * 356 + * Initialize the BQ25703 by first disabling the watchdog timer (which 357 + * shuts off the charger in the absence of periodic writes). Then, set 358 + * the charge current, charge voltage, minimum system voltage, and 359 + * input current limit. Disable low power mode to allow ADCs and 360 + * interrupts. Enable the ADC, start the ADC, set the ADC scale to 361 + * full, and enable each individual ADC channel. 362 + * 363 + * Return: Returns 0 on success or error code on error. 364 + */ 365 + static int bq25703_hw_init(struct bq257xx_chg *pdata) 366 + { 367 + struct regmap *regmap = pdata->bq->regmap; 368 + int ret = 0; 369 + 370 + regmap_update_bits(regmap, BQ25703_CHARGE_OPTION_0, 371 + BQ25703_WDTMR_ADJ_MASK, 372 + FIELD_PREP(BQ25703_WDTMR_ADJ_MASK, 373 + BQ25703_WDTMR_DISABLE)); 374 + 375 + ret = pdata->chip->bq257xx_set_ichg(pdata, pdata->ichg_max); 376 + if (ret) 377 + return ret; 378 + 379 + ret = pdata->chip->bq257xx_set_vbatreg(pdata, pdata->vbat_max); 380 + if (ret) 381 + return ret; 382 + 383 + ret = bq25703_set_min_vsys(pdata, pdata->vsys_min); 384 + if (ret) 385 + return ret; 386 + 387 + ret = pdata->chip->bq257xx_set_iindpm(pdata, pdata->iindpm_max); 388 + if (ret) 389 + return ret; 390 + 391 + /* Disable low power mode by writing 0 to the register. */ 392 + regmap_update_bits(regmap, BQ25703_CHARGE_OPTION_0, 393 + BQ25703_EN_LWPWR, 0); 394 + 395 + /* Enable the ADC. */ 396 + regmap_update_bits(regmap, BQ25703_ADC_OPTION, 397 + BQ25703_ADC_CONV_EN, BQ25703_ADC_CONV_EN); 398 + 399 + /* Start the ADC. */ 400 + regmap_update_bits(regmap, BQ25703_ADC_OPTION, 401 + BQ25703_ADC_START, BQ25703_ADC_START); 402 + 403 + /* Set the scale of the ADC. */ 404 + regmap_update_bits(regmap, BQ25703_ADC_OPTION, 405 + BQ25703_ADC_FULL_SCALE, BQ25703_ADC_FULL_SCALE); 406 + 407 + /* Enable each of the ADC channels available. */ 408 + regmap_update_bits(regmap, BQ25703_ADC_OPTION, 409 + BQ25703_ADC_CH_MASK, 410 + (BQ25703_ADC_CMPIN_EN | BQ25703_ADC_VBUS_EN | 411 + BQ25703_ADC_PSYS_EN | BQ25703_ADC_IIN_EN | 412 + BQ25703_ADC_IDCHG_EN | BQ25703_ADC_ICHG_EN | 413 + BQ25703_ADC_VSYS_EN | BQ25703_ADC_VBAT_EN)); 414 + 415 + return ret; 416 + } 417 + 418 + /** 419 + * bq25703_hw_shutdown() - Set registers for shutdown 420 + * @pdata: driver platform data 421 + * 422 + * Enable low power mode for the device while in shutdown. 423 + */ 424 + static void bq25703_hw_shutdown(struct bq257xx_chg *pdata) 425 + { 426 + regmap_update_bits(pdata->bq->regmap, BQ25703_CHARGE_OPTION_0, 427 + BQ25703_EN_LWPWR, BQ25703_EN_LWPWR); 428 + } 429 + 430 + static int bq257xx_set_charger_property(struct power_supply *psy, 431 + enum power_supply_property prop, 432 + const union power_supply_propval *val) 433 + { 434 + struct bq257xx_chg *pdata = power_supply_get_drvdata(psy); 435 + 436 + switch (prop) { 437 + case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: 438 + return pdata->chip->bq257xx_set_iindpm(pdata, val->intval); 439 + 440 + case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX: 441 + return pdata->chip->bq257xx_set_vbatreg(pdata, val->intval); 442 + 443 + case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX: 444 + return pdata->chip->bq257xx_set_ichg(pdata, val->intval); 445 + 446 + default: 447 + break; 448 + } 449 + 450 + return -EINVAL; 451 + } 452 + 453 + static int bq257xx_get_charger_property(struct power_supply *psy, 454 + enum power_supply_property psp, 455 + union power_supply_propval *val) 456 + { 457 + struct bq257xx_chg *pdata = power_supply_get_drvdata(psy); 458 + int ret = 0; 459 + 460 + ret = pdata->chip->bq257xx_get_state(pdata); 461 + if (ret) 462 + return ret; 463 + 464 + switch (psp) { 465 + case POWER_SUPPLY_PROP_STATUS: 466 + if (!pdata->online) 467 + val->intval = POWER_SUPPLY_STATUS_DISCHARGING; 468 + else if (pdata->fast_charge || pdata->pre_charge) 469 + val->intval = POWER_SUPPLY_STATUS_CHARGING; 470 + else 471 + val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; 472 + break; 473 + 474 + case POWER_SUPPLY_PROP_HEALTH: 475 + if (pdata->ov_fault || pdata->batoc_fault) 476 + val->intval = POWER_SUPPLY_HEALTH_OVERVOLTAGE; 477 + else if (pdata->oc_fault) 478 + val->intval = POWER_SUPPLY_HEALTH_OVERCURRENT; 479 + else 480 + val->intval = POWER_SUPPLY_HEALTH_GOOD; 481 + break; 482 + 483 + case POWER_SUPPLY_PROP_MANUFACTURER: 484 + val->strval = "Texas Instruments"; 485 + break; 486 + 487 + case POWER_SUPPLY_PROP_ONLINE: 488 + val->intval = pdata->online; 489 + break; 490 + 491 + case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: 492 + return bq25703_get_iindpm(pdata, &val->intval); 493 + 494 + case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX: 495 + return bq25703_get_chrg_volt(pdata, &val->intval); 496 + 497 + case POWER_SUPPLY_PROP_CURRENT_NOW: 498 + return bq25703_get_cur(pdata, &val->intval); 499 + 500 + case POWER_SUPPLY_PROP_VOLTAGE_NOW: 501 + return bq25703_get_vbat(pdata, &val->intval); 502 + 503 + case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX: 504 + return bq25703_get_ichg_cur(pdata, &val->intval); 505 + 506 + case POWER_SUPPLY_PROP_VOLTAGE_MIN: 507 + return bq25703_get_min_vsys(pdata, &val->intval); 508 + 509 + case POWER_SUPPLY_PROP_USB_TYPE: 510 + val->intval = pdata->usb_type; 511 + break; 512 + 513 + default: 514 + return -EINVAL; 515 + } 516 + 517 + return ret; 518 + } 519 + 520 + static enum power_supply_property bq257xx_power_supply_props[] = { 521 + POWER_SUPPLY_PROP_MANUFACTURER, 522 + POWER_SUPPLY_PROP_STATUS, 523 + POWER_SUPPLY_PROP_ONLINE, 524 + POWER_SUPPLY_PROP_HEALTH, 525 + POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT, 526 + POWER_SUPPLY_PROP_CURRENT_NOW, 527 + POWER_SUPPLY_PROP_VOLTAGE_NOW, 528 + POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX, 529 + POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX, 530 + POWER_SUPPLY_PROP_VOLTAGE_MIN, 531 + POWER_SUPPLY_PROP_USB_TYPE, 532 + }; 533 + 534 + static int bq257xx_property_is_writeable(struct power_supply *psy, 535 + enum power_supply_property prop) 536 + { 537 + switch (prop) { 538 + case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX: 539 + case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX: 540 + case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: 541 + return true; 542 + default: 543 + return false; 544 + } 545 + } 546 + 547 + /** 548 + * bq257xx_external_power_changed() - Handler for external power change 549 + * @psy: Power supply data 550 + * 551 + * When the external power into the charger is changed, check the USB 552 + * type so that it can be reported. Additionally, update the max input 553 + * current and max charging current to the value reported if it is a 554 + * USB PD charger, otherwise use the default value. Note that each time 555 + * a charger is removed the max charge current register is erased, so 556 + * it must be set again each time the input changes or the device will 557 + * not charge. 558 + */ 559 + static void bq257xx_external_power_changed(struct power_supply *psy) 560 + { 561 + struct bq257xx_chg *pdata = power_supply_get_drvdata(psy); 562 + union power_supply_propval val; 563 + int ret; 564 + int imax = pdata->iindpm_max; 565 + 566 + pdata->chip->bq257xx_get_state(pdata); 567 + 568 + pdata->supplied = power_supply_am_i_supplied(pdata->charger); 569 + if (pdata->supplied < 0) 570 + return; 571 + 572 + if (pdata->supplied == 0) 573 + goto out; 574 + 575 + ret = power_supply_get_property_from_supplier(psy, 576 + POWER_SUPPLY_PROP_USB_TYPE, 577 + &val); 578 + if (ret) 579 + return; 580 + 581 + pdata->usb_type = val.intval; 582 + 583 + if ((pdata->usb_type == POWER_SUPPLY_USB_TYPE_PD) || 584 + (pdata->usb_type == POWER_SUPPLY_USB_TYPE_PD_DRP) || 585 + (pdata->usb_type == POWER_SUPPLY_USB_TYPE_PD_PPS)) { 586 + ret = power_supply_get_property_from_supplier(psy, 587 + POWER_SUPPLY_PROP_CURRENT_MAX, 588 + &val); 589 + if (ret) 590 + return; 591 + 592 + if (val.intval) 593 + imax = val.intval; 594 + } 595 + 596 + if (pdata->supplied) { 597 + pdata->chip->bq257xx_set_ichg(pdata, pdata->ichg_max); 598 + pdata->chip->bq257xx_set_iindpm(pdata, imax); 599 + pdata->chip->bq257xx_set_vbatreg(pdata, pdata->vbat_max); 600 + } 601 + 602 + out: 603 + power_supply_changed(psy); 604 + } 605 + 606 + static irqreturn_t bq257xx_irq_handler_thread(int irq, void *private) 607 + { 608 + struct bq257xx_chg *pdata = private; 609 + 610 + bq257xx_external_power_changed(pdata->charger); 611 + return IRQ_HANDLED; 612 + } 613 + 614 + static const struct power_supply_desc bq257xx_power_supply_desc = { 615 + .name = "bq257xx-charger", 616 + .type = POWER_SUPPLY_TYPE_USB, 617 + .usb_types = BIT(POWER_SUPPLY_USB_TYPE_C) | 618 + BIT(POWER_SUPPLY_USB_TYPE_PD) | 619 + BIT(POWER_SUPPLY_USB_TYPE_PD_DRP) | 620 + BIT(POWER_SUPPLY_USB_TYPE_PD_PPS) | 621 + BIT(POWER_SUPPLY_USB_TYPE_UNKNOWN), 622 + .properties = bq257xx_power_supply_props, 623 + .num_properties = ARRAY_SIZE(bq257xx_power_supply_props), 624 + .get_property = bq257xx_get_charger_property, 625 + .set_property = bq257xx_set_charger_property, 626 + .property_is_writeable = bq257xx_property_is_writeable, 627 + .external_power_changed = bq257xx_external_power_changed, 628 + }; 629 + 630 + static const struct bq257xx_chip_info bq25703_chip_info = { 631 + .bq257xx_hw_init = &bq25703_hw_init, 632 + .bq257xx_hw_shutdown = &bq25703_hw_shutdown, 633 + .bq257xx_get_state = &bq25703_get_state, 634 + .bq257xx_set_ichg = &bq25703_set_ichg_cur, 635 + .bq257xx_set_vbatreg = &bq25703_set_chrg_volt, 636 + .bq257xx_set_iindpm = &bq25703_set_iindpm, 637 + }; 638 + 639 + /** 640 + * bq257xx_parse_dt() - Parse the device tree for required properties 641 + * @pdata: driver platform data 642 + * @psy_cfg: power supply config data 643 + * @dev: device struct 644 + * 645 + * Read the device tree to identify the minimum system voltage, the 646 + * maximum charge current, the maximum charge voltage, and the maximum 647 + * input current. 648 + * 649 + * Return: Returns 0 on success or error code on error. 650 + */ 651 + static int bq257xx_parse_dt(struct bq257xx_chg *pdata, 652 + struct power_supply_config *psy_cfg, struct device *dev) 653 + { 654 + struct power_supply_battery_info *bat_info; 655 + int ret; 656 + 657 + ret = power_supply_get_battery_info(pdata->charger, 658 + &bat_info); 659 + if (ret) 660 + return dev_err_probe(dev, ret, 661 + "Unable to get battery info\n"); 662 + 663 + if ((bat_info->voltage_min_design_uv <= 0) || 664 + (bat_info->constant_charge_voltage_max_uv <= 0) || 665 + (bat_info->constant_charge_current_max_ua <= 0)) 666 + return dev_err_probe(dev, -EINVAL, 667 + "Required bat info missing or invalid\n"); 668 + 669 + pdata->vsys_min = bat_info->voltage_min_design_uv; 670 + pdata->vbat_max = bat_info->constant_charge_voltage_max_uv; 671 + pdata->ichg_max = bat_info->constant_charge_current_max_ua; 672 + 673 + power_supply_put_battery_info(pdata->charger, bat_info); 674 + 675 + ret = device_property_read_u32(dev, 676 + "input-current-limit-microamp", 677 + &pdata->iindpm_max); 678 + if (ret) 679 + pdata->iindpm_max = BQ25703_IINDPM_DEFAULT_UA; 680 + 681 + return 0; 682 + } 683 + 684 + static int bq257xx_charger_probe(struct platform_device *pdev) 685 + { 686 + struct device *dev = &pdev->dev; 687 + struct bq257xx_device *bq = dev_get_drvdata(pdev->dev.parent); 688 + struct bq257xx_chg *pdata; 689 + struct power_supply_config psy_cfg = { }; 690 + int ret; 691 + 692 + device_set_of_node_from_dev(dev, pdev->dev.parent); 693 + 694 + pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); 695 + if (!pdata) 696 + return -ENOMEM; 697 + 698 + pdata->bq = bq; 699 + pdata->chip = &bq25703_chip_info; 700 + 701 + platform_set_drvdata(pdev, pdata); 702 + 703 + psy_cfg.drv_data = pdata; 704 + psy_cfg.fwnode = dev_fwnode(dev); 705 + 706 + pdata->charger = devm_power_supply_register(dev, 707 + &bq257xx_power_supply_desc, 708 + &psy_cfg); 709 + if (IS_ERR(pdata->charger)) 710 + return dev_err_probe(dev, PTR_ERR(pdata->charger), 711 + "Power supply register charger failed\n"); 712 + 713 + ret = bq257xx_parse_dt(pdata, &psy_cfg, dev); 714 + if (ret) 715 + return ret; 716 + 717 + ret = pdata->chip->bq257xx_hw_init(pdata); 718 + if (ret) 719 + return dev_err_probe(dev, ret, "Cannot initialize the charger\n"); 720 + 721 + platform_set_drvdata(pdev, pdata); 722 + 723 + if (bq->client->irq) { 724 + ret = devm_request_threaded_irq(dev, bq->client->irq, NULL, 725 + bq257xx_irq_handler_thread, 726 + IRQF_TRIGGER_RISING | 727 + IRQF_TRIGGER_FALLING | 728 + IRQF_ONESHOT, 729 + dev_name(&bq->client->dev), pdata); 730 + if (ret < 0) 731 + dev_err_probe(dev, ret, "Charger get irq failed\n"); 732 + } 733 + 734 + return ret; 735 + } 736 + 737 + static void bq257xx_charger_shutdown(struct platform_device *pdev) 738 + { 739 + struct bq257xx_chg *pdata = platform_get_drvdata(pdev); 740 + 741 + pdata->chip->bq257xx_hw_shutdown(pdata); 742 + } 743 + 744 + static struct platform_driver bq257xx_chg_driver = { 745 + .driver = { 746 + .name = "bq257xx-charger", 747 + }, 748 + .probe = bq257xx_charger_probe, 749 + .shutdown = bq257xx_charger_shutdown, 750 + }; 751 + module_platform_driver(bq257xx_chg_driver); 752 + 753 + MODULE_DESCRIPTION("bq257xx charger driver"); 754 + MODULE_AUTHOR("Chris Morgan <macromorgan@hotmail.com>"); 755 + MODULE_LICENSE("GPL");
+8
drivers/regulator/Kconfig
··· 297 297 This driver can also be built as a module. If so, the module 298 298 will be called bd96801-regulator. 299 299 300 + config REGULATOR_BQ257XX 301 + tristate "TI BQ257XX regulator family" 302 + depends on MFD_BQ257XX 303 + depends on GPIOLIB || COMPILE_TEST 304 + help 305 + Say Y to enable support for the boost regulator function of 306 + the BQ257XX family of charger circuits. 307 + 300 308 config REGULATOR_CPCAP 301 309 tristate "Motorola CPCAP regulator" 302 310 depends on MFD_CPCAP
+1
drivers/regulator/Makefile
··· 38 38 obj-$(CONFIG_REGULATOR_BD718XX) += bd718x7-regulator.o 39 39 obj-$(CONFIG_REGULATOR_BD9571MWV) += bd9571mwv-regulator.o 40 40 obj-$(CONFIG_REGULATOR_BD957XMUF) += bd9576-regulator.o 41 + obj-$(CONFIG_REGULATOR_BQ257XX) += bq257xx-regulator.o 41 42 obj-$(CONFIG_REGULATOR_DA903X) += da903x-regulator.o 42 43 obj-$(CONFIG_REGULATOR_BD96801) += bd96801-regulator.o 43 44 obj-$(CONFIG_REGULATOR_DA9052) += da9052-regulator.o
+186
drivers/regulator/bq257xx-regulator.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * BQ257XX Battery Charger Driver 4 + * Copyright (C) 2025 Chris Morgan <macromorgan@hotmail.com> 5 + */ 6 + 7 + #include <linux/bitfield.h> 8 + #include <linux/err.h> 9 + #include <linux/gpio/consumer.h> 10 + #include <linux/mfd/bq257xx.h> 11 + #include <linux/of.h> 12 + #include <linux/platform_device.h> 13 + #include <linux/regmap.h> 14 + #include <linux/regulator/driver.h> 15 + #include <linux/regulator/of_regulator.h> 16 + 17 + struct bq257xx_reg_data { 18 + struct bq257xx_device *bq; 19 + struct regulator_dev *bq257xx_reg; 20 + struct gpio_desc *otg_en_gpio; 21 + struct regulator_desc desc; 22 + }; 23 + 24 + static int bq25703_vbus_get_cur_limit(struct regulator_dev *rdev) 25 + { 26 + struct bq257xx_reg_data *pdata = rdev_get_drvdata(rdev); 27 + int ret; 28 + unsigned int reg; 29 + 30 + ret = regmap_read(pdata->bq->regmap, BQ25703_OTG_CURRENT, &reg); 31 + if (ret) 32 + return ret; 33 + return FIELD_GET(BQ25703_OTG_CUR_MASK, reg) * BQ25703_OTG_CUR_STEP_UA; 34 + } 35 + 36 + /* 37 + * Check if the minimum current and maximum current requested are 38 + * sane values, then set the register accordingly. 39 + */ 40 + static int bq25703_vbus_set_cur_limit(struct regulator_dev *rdev, 41 + int min_uA, int max_uA) 42 + { 43 + struct bq257xx_reg_data *pdata = rdev_get_drvdata(rdev); 44 + unsigned int reg; 45 + 46 + if ((min_uA > BQ25703_OTG_CUR_MAX_UA) || (max_uA < 0)) 47 + return -EINVAL; 48 + 49 + reg = (max_uA / BQ25703_OTG_CUR_STEP_UA); 50 + 51 + /* Catch rounding errors since our step is 50000uA. */ 52 + if ((reg * BQ25703_OTG_CUR_STEP_UA) < min_uA) 53 + return -EINVAL; 54 + 55 + return regmap_write(pdata->bq->regmap, BQ25703_OTG_CURRENT, 56 + FIELD_PREP(BQ25703_OTG_CUR_MASK, reg)); 57 + } 58 + 59 + static int bq25703_vbus_enable(struct regulator_dev *rdev) 60 + { 61 + struct bq257xx_reg_data *pdata = rdev_get_drvdata(rdev); 62 + 63 + if (pdata->otg_en_gpio) 64 + gpiod_set_value_cansleep(pdata->otg_en_gpio, 1); 65 + return regulator_enable_regmap(rdev); 66 + } 67 + 68 + static int bq25703_vbus_disable(struct regulator_dev *rdev) 69 + { 70 + struct bq257xx_reg_data *pdata = rdev_get_drvdata(rdev); 71 + 72 + if (pdata->otg_en_gpio) 73 + gpiod_set_value_cansleep(pdata->otg_en_gpio, 0); 74 + return regulator_disable_regmap(rdev); 75 + } 76 + 77 + static const struct regulator_ops bq25703_vbus_ops = { 78 + .enable = bq25703_vbus_enable, 79 + .disable = bq25703_vbus_disable, 80 + .is_enabled = regulator_is_enabled_regmap, 81 + .list_voltage = regulator_list_voltage_linear, 82 + .get_voltage_sel = regulator_get_voltage_sel_regmap, 83 + .set_voltage_sel = regulator_set_voltage_sel_regmap, 84 + .get_current_limit = bq25703_vbus_get_cur_limit, 85 + .set_current_limit = bq25703_vbus_set_cur_limit, 86 + }; 87 + 88 + static const struct regulator_desc bq25703_vbus_desc = { 89 + .name = "vbus", 90 + .of_match = of_match_ptr("vbus"), 91 + .regulators_node = of_match_ptr("regulators"), 92 + .type = REGULATOR_VOLTAGE, 93 + .owner = THIS_MODULE, 94 + .ops = &bq25703_vbus_ops, 95 + .min_uV = BQ25703_OTG_VOLT_MIN_UV, 96 + .uV_step = BQ25703_OTG_VOLT_STEP_UV, 97 + .n_voltages = BQ25703_OTG_VOLT_NUM_VOLT, 98 + .enable_mask = BQ25703_EN_OTG_MASK, 99 + .enable_reg = BQ25703_CHARGE_OPTION_3, 100 + .enable_val = BQ25703_EN_OTG_MASK, 101 + .disable_val = 0, 102 + .vsel_reg = BQ25703_OTG_VOLT, 103 + .vsel_mask = BQ25703_OTG_VOLT_MASK, 104 + }; 105 + 106 + /* Get optional GPIO for OTG regulator enable. */ 107 + static void bq257xx_reg_dt_parse_gpio(struct platform_device *pdev) 108 + { 109 + struct device_node *child, *subchild; 110 + struct bq257xx_reg_data *pdata = platform_get_drvdata(pdev); 111 + 112 + child = of_get_child_by_name(pdev->dev.of_node, 113 + pdata->desc.regulators_node); 114 + if (!child) 115 + return; 116 + 117 + subchild = of_get_child_by_name(child, pdata->desc.of_match); 118 + if (!subchild) 119 + return; 120 + 121 + of_node_put(child); 122 + 123 + pdata->otg_en_gpio = devm_fwnode_gpiod_get_index(&pdev->dev, 124 + of_fwnode_handle(subchild), 125 + "enable", 0, 126 + GPIOD_OUT_LOW, 127 + pdata->desc.of_match); 128 + 129 + of_node_put(subchild); 130 + 131 + if (IS_ERR(pdata->otg_en_gpio)) { 132 + dev_err(&pdev->dev, "Error getting enable gpio: %ld\n", 133 + PTR_ERR(pdata->otg_en_gpio)); 134 + return; 135 + } 136 + } 137 + 138 + static int bq257xx_regulator_probe(struct platform_device *pdev) 139 + { 140 + struct device *dev = &pdev->dev; 141 + struct bq257xx_device *bq = dev_get_drvdata(pdev->dev.parent); 142 + struct bq257xx_reg_data *pdata; 143 + struct device_node *np = dev->of_node; 144 + struct regulator_config cfg = {}; 145 + 146 + pdev->dev.of_node = pdev->dev.parent->of_node; 147 + pdev->dev.of_node_reused = true; 148 + 149 + pdata = devm_kzalloc(&pdev->dev, sizeof(struct bq257xx_reg_data), GFP_KERNEL); 150 + if (!pdata) 151 + return -ENOMEM; 152 + 153 + pdata->bq = bq; 154 + pdata->desc = bq25703_vbus_desc; 155 + 156 + platform_set_drvdata(pdev, pdata); 157 + bq257xx_reg_dt_parse_gpio(pdev); 158 + 159 + cfg.dev = &pdev->dev; 160 + cfg.driver_data = pdata; 161 + cfg.of_node = np; 162 + cfg.regmap = dev_get_regmap(pdev->dev.parent, NULL); 163 + if (!cfg.regmap) 164 + return -ENODEV; 165 + 166 + pdata->bq257xx_reg = devm_regulator_register(dev, &pdata->desc, &cfg); 167 + if (IS_ERR(pdata->bq257xx_reg)) { 168 + return dev_err_probe(&pdev->dev, PTR_ERR(pdata->bq257xx_reg), 169 + "error registering bq257xx regulator"); 170 + } 171 + 172 + return 0; 173 + } 174 + 175 + static struct platform_driver bq257xx_reg_driver = { 176 + .driver = { 177 + .name = "bq257xx-regulator", 178 + }, 179 + .probe = bq257xx_regulator_probe, 180 + }; 181 + 182 + module_platform_driver(bq257xx_reg_driver); 183 + 184 + MODULE_DESCRIPTION("bq257xx regulator driver"); 185 + MODULE_AUTHOR("Chris Morgan <macromorgan@hotmail.com>"); 186 + MODULE_LICENSE("GPL");
-13
drivers/rtc/rtc-mc13xxx.c
··· 137 137 } 138 138 139 139 if (!priv->valid) { 140 - ret = mc13xxx_irq_ack(priv->mc13xxx, MC13XXX_IRQ_RTCRST); 141 - if (unlikely(ret)) 142 - goto out; 143 - 144 140 ret = mc13xxx_irq_unmask(priv->mc13xxx, MC13XXX_IRQ_RTCRST); 145 141 } 146 142 ··· 204 208 if (unlikely(ret)) 205 209 goto out; 206 210 207 - ret = mc13xxx_irq_ack(priv->mc13xxx, MC13XXX_IRQ_TODA); 208 - if (unlikely(ret)) 209 - goto out; 210 - 211 211 s1970 = rtc_tm_to_time64(&alarm->time); 212 212 213 213 dev_dbg(dev, "%s: %s %lld\n", __func__, alarm->enabled ? "on" : "off", ··· 231 239 static irqreturn_t mc13xxx_rtc_alarm_handler(int irq, void *dev) 232 240 { 233 241 struct mc13xxx_rtc *priv = dev; 234 - struct mc13xxx *mc13xxx = priv->mc13xxx; 235 242 236 243 rtc_update_irq(priv->rtc, 1, RTC_IRQF | RTC_AF); 237 - 238 - mc13xxx_irq_ack(mc13xxx, irq); 239 244 240 245 return IRQ_HANDLED; 241 246 } ··· 281 292 priv->rtc->range_max = (timeu64_t)(1 << 15) * SEC_PER_DAY - 1; 282 293 283 294 mc13xxx_lock(mc13xxx); 284 - 285 - mc13xxx_irq_ack(mc13xxx, MC13XXX_IRQ_RTCRST); 286 295 287 296 ret = mc13xxx_irq_request(mc13xxx, MC13XXX_IRQ_RTCRST, 288 297 mc13xxx_rtc_reset_handler, DRIVER_NAME, priv);
+6
include/linux/mfd/arizona/pdata.h
··· 117 117 /** Check for line output with HPDET method */ 118 118 bool hpdet_acc_id_line; 119 119 120 + #ifdef CONFIG_GPIOLIB_LEGACY 120 121 /** GPIO used for mic isolation with HPDET */ 121 122 int hpdet_id_gpio; 123 + #endif 122 124 123 125 /** Channel to use for headphone detection */ 124 126 unsigned int hpdet_channel; ··· 131 129 /** Extra debounce timeout used during initial mic detection (ms) */ 132 130 unsigned int micd_detect_debounce; 133 131 132 + #ifdef CONFIG_GPIOLIB_LEGACY 134 133 /** GPIO for mic detection polarity */ 135 134 int micd_pol_gpio; 135 + #endif 136 136 137 137 /** Mic detect ramp rate */ 138 138 unsigned int micd_bias_start_time; ··· 188 184 /** Haptic actuator type */ 189 185 unsigned int hap_act; 190 186 187 + #ifdef CONFIG_GPIOLIB_LEGACY 191 188 /** GPIO for primary IRQ (used for edge triggered emulation) */ 192 189 int irq_gpio; 190 + #endif 193 191 194 192 /** General purpose switch control */ 195 193 unsigned int gpsw;
+104
include/linux/mfd/bq257xx.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * Register definitions for TI BQ257XX 4 + * Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com/ 5 + */ 6 + 7 + #define BQ25703_CHARGE_OPTION_0 0x00 8 + #define BQ25703_CHARGE_CURRENT 0x02 9 + #define BQ25703_MAX_CHARGE_VOLT 0x04 10 + #define BQ25703_OTG_VOLT 0x06 11 + #define BQ25703_OTG_CURRENT 0x08 12 + #define BQ25703_INPUT_VOLTAGE 0x0a 13 + #define BQ25703_MIN_VSYS 0x0c 14 + #define BQ25703_IIN_HOST 0x0e 15 + #define BQ25703_CHARGER_STATUS 0x20 16 + #define BQ25703_PROCHOT_STATUS 0x22 17 + #define BQ25703_IIN_DPM 0x24 18 + #define BQ25703_ADCIBAT_CHG 0x28 19 + #define BQ25703_ADCIINCMPIN 0x2a 20 + #define BQ25703_ADCVSYSVBAT 0x2c 21 + #define BQ25703_MANUFACT_DEV_ID 0x2e 22 + #define BQ25703_CHARGE_OPTION_1 0x30 23 + #define BQ25703_CHARGE_OPTION_2 0x32 24 + #define BQ25703_CHARGE_OPTION_3 0x34 25 + #define BQ25703_ADC_OPTION 0x3a 26 + 27 + #define BQ25703_EN_LWPWR BIT(15) 28 + #define BQ25703_WDTMR_ADJ_MASK GENMASK(14, 13) 29 + #define BQ25703_WDTMR_DISABLE 0 30 + #define BQ25703_WDTMR_5_SEC 1 31 + #define BQ25703_WDTMR_88_SEC 2 32 + #define BQ25703_WDTMR_175_SEC 3 33 + 34 + #define BQ25703_ICHG_MASK GENMASK(12, 6) 35 + #define BQ25703_ICHG_STEP_UA 64000 36 + #define BQ25703_ICHG_MIN_UA 64000 37 + #define BQ25703_ICHG_MAX_UA 8128000 38 + 39 + #define BQ25703_MAX_CHARGE_VOLT_MASK GENMASK(15, 4) 40 + #define BQ25703_VBATREG_STEP_UV 16000 41 + #define BQ25703_VBATREG_MIN_UV 1024000 42 + #define BQ25703_VBATREG_MAX_UV 19200000 43 + 44 + #define BQ25703_OTG_VOLT_MASK GENMASK(13, 6) 45 + #define BQ25703_OTG_VOLT_STEP_UV 64000 46 + #define BQ25703_OTG_VOLT_MIN_UV 4480000 47 + #define BQ25703_OTG_VOLT_MAX_UV 20800000 48 + #define BQ25703_OTG_VOLT_NUM_VOLT 256 49 + 50 + #define BQ25703_OTG_CUR_MASK GENMASK(14, 8) 51 + #define BQ25703_OTG_CUR_STEP_UA 50000 52 + #define BQ25703_OTG_CUR_MAX_UA 6350000 53 + 54 + #define BQ25703_MINVSYS_MASK GENMASK(13, 8) 55 + #define BQ25703_MINVSYS_STEP_UV 256000 56 + #define BQ25703_MINVSYS_MIN_UV 1024000 57 + #define BQ25703_MINVSYS_MAX_UV 16128000 58 + 59 + #define BQ25703_STS_AC_STAT BIT(15) 60 + #define BQ25703_STS_IN_FCHRG BIT(10) 61 + #define BQ25703_STS_IN_PCHRG BIT(9) 62 + #define BQ25703_STS_FAULT_ACOV BIT(7) 63 + #define BQ25703_STS_FAULT_BATOC BIT(6) 64 + #define BQ25703_STS_FAULT_ACOC BIT(5) 65 + 66 + #define BQ25703_IINDPM_MASK GENMASK(14, 8) 67 + #define BQ25703_IINDPM_STEP_UA 50000 68 + #define BQ25703_IINDPM_MIN_UA 50000 69 + #define BQ25703_IINDPM_MAX_UA 6400000 70 + #define BQ25703_IINDPM_DEFAULT_UA 3300000 71 + #define BQ25703_IINDPM_OFFSET_UA 50000 72 + 73 + #define BQ25703_ADCIBAT_DISCHG_MASK GENMASK(6, 0) 74 + #define BQ25703_ADCIBAT_CHG_MASK GENMASK(14, 8) 75 + #define BQ25703_ADCIBAT_CHG_STEP_UA 64000 76 + #define BQ25703_ADCIBAT_DIS_STEP_UA 256000 77 + 78 + #define BQ25703_ADCIIN GENMASK(15, 8) 79 + #define BQ25703_ADCIINCMPIN_STEP 50000 80 + 81 + #define BQ25703_ADCVSYS_MASK GENMASK(15, 8) 82 + #define BQ25703_ADCVBAT_MASK GENMASK(7, 0) 83 + #define BQ25703_ADCVSYSVBAT_OFFSET_UV 2880000 84 + #define BQ25703_ADCVSYSVBAT_STEP 64000 85 + 86 + #define BQ25703_ADC_CH_MASK GENMASK(7, 0) 87 + #define BQ25703_ADC_CONV_EN BIT(15) 88 + #define BQ25703_ADC_START BIT(14) 89 + #define BQ25703_ADC_FULL_SCALE BIT(13) 90 + #define BQ25703_ADC_CMPIN_EN BIT(7) 91 + #define BQ25703_ADC_VBUS_EN BIT(6) 92 + #define BQ25703_ADC_PSYS_EN BIT(5) 93 + #define BQ25703_ADC_IIN_EN BIT(4) 94 + #define BQ25703_ADC_IDCHG_EN BIT(3) 95 + #define BQ25703_ADC_ICHG_EN BIT(2) 96 + #define BQ25703_ADC_VSYS_EN BIT(1) 97 + #define BQ25703_ADC_VBAT_EN BIT(0) 98 + 99 + #define BQ25703_EN_OTG_MASK BIT(12) 100 + 101 + struct bq257xx_device { 102 + struct i2c_client *client; 103 + struct regmap *regmap; 104 + };
+53
include/linux/mfd/loongson-se.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 + /* Copyright (C) 2025 Loongson Technology Corporation Limited */ 3 + 4 + #ifndef __MFD_LOONGSON_SE_H__ 5 + #define __MFD_LOONGSON_SE_H__ 6 + 7 + #define LOONGSON_ENGINE_CMD_TIMEOUT_US 10000 8 + #define SE_SEND_CMD_REG 0x0 9 + #define SE_SEND_CMD_REG_LEN 0x8 10 + /* Controller command ID */ 11 + #define SE_CMD_START 0x0 12 + #define SE_CMD_SET_DMA 0x3 13 + #define SE_CMD_SET_ENGINE_CMDBUF 0x4 14 + 15 + #define SE_S2LINT_STAT 0x88 16 + #define SE_S2LINT_EN 0x8c 17 + #define SE_S2LINT_CL 0x94 18 + #define SE_L2SINT_STAT 0x98 19 + #define SE_L2SINT_SET 0xa0 20 + 21 + #define SE_INT_ALL 0xffffffff 22 + #define SE_INT_CONTROLLER BIT(0) 23 + 24 + #define SE_ENGINE_MAX 16 25 + #define SE_ENGINE_RNG 1 26 + #define SE_CMD_RNG 0x100 27 + 28 + #define SE_ENGINE_TPM 5 29 + #define SE_CMD_TPM 0x500 30 + 31 + #define SE_ENGINE_CMD_SIZE 32 32 + 33 + struct loongson_se_engine { 34 + struct loongson_se *se; 35 + int id; 36 + 37 + /* Command buffer */ 38 + void *command; 39 + void *command_ret; 40 + 41 + void *data_buffer; 42 + uint buffer_size; 43 + /* Data buffer offset to DMA base */ 44 + uint buffer_off; 45 + 46 + struct completion completion; 47 + 48 + }; 49 + 50 + struct loongson_se_engine *loongson_se_init_engine(struct device *dev, int id); 51 + int loongson_se_send_engine_cmd(struct loongson_se_engine *engine); 52 + 53 + #endif
-6
include/linux/mfd/mc13xxx.h
··· 31 31 unsigned int mode, unsigned int channel, 32 32 u8 ato, bool atox, unsigned int *sample); 33 33 34 - /* Deprecated calls */ 35 - static inline int mc13xxx_irq_ack(struct mc13xxx *mc13xxx, int irq) 36 - { 37 - return 0; 38 - } 39 - 40 34 static inline int mc13xxx_irq_request_nounmask(struct mc13xxx *mc13xxx, int irq, 41 35 irq_handler_t handler, 42 36 const char *name, void *dev)
+2
include/linux/mfd/qnap-mcu.h
··· 7 7 #ifndef _LINUX_QNAP_MCU_H_ 8 8 #define _LINUX_QNAP_MCU_H_ 9 9 10 + #include <linux/types.h> 11 + 10 12 struct qnap_mcu; 11 13 12 14 struct qnap_mcu_variant {
+63
include/linux/mfd/rohm-bd71828.h
··· 189 189 /* Charger/Battey */ 190 190 #define BD71828_REG_CHG_STATE 0x65 191 191 #define BD71828_REG_CHG_FULL 0xd2 192 + #define BD71828_REG_CHG_EN 0x6F 193 + #define BD71828_REG_DCIN_STAT 0x68 194 + #define BD71828_MASK_DCIN_DET 0x01 195 + #define BD71828_REG_VDCIN_U 0x9c 196 + #define BD71828_MASK_CHG_EN 0x01 197 + #define BD71828_CHG_MASK_DCIN_U 0x0f 198 + #define BD71828_REG_BAT_STAT 0x67 199 + #define BD71828_REG_BAT_TEMP 0x6c 200 + #define BD71828_MASK_BAT_TEMP 0x07 201 + #define BD71828_BAT_TEMP_OPEN 0x07 202 + #define BD71828_MASK_BAT_DET 0x20 203 + #define BD71828_MASK_BAT_DET_DONE 0x10 204 + #define BD71828_REG_CHG_STATE 0x65 205 + #define BD71828_REG_VBAT_U 0x8c 206 + #define BD71828_MASK_VBAT_U 0x0f 207 + #define BD71828_REG_VBAT_REX_AVG_U 0x92 208 + 209 + #define BD71828_REG_OCV_PWRON_U 0x8A 210 + 211 + #define BD71828_REG_VBAT_MIN_AVG_U 0x8e 212 + #define BD71828_REG_VBAT_MIN_AVG_L 0x8f 213 + 214 + #define BD71828_REG_CC_CNT3 0xb5 215 + #define BD71828_REG_CC_CNT2 0xb6 216 + #define BD71828_REG_CC_CNT1 0xb7 217 + #define BD71828_REG_CC_CNT0 0xb8 218 + #define BD71828_REG_CC_CURCD_AVG_U 0xb2 219 + #define BD71828_MASK_CC_CURCD_AVG_U 0x3f 220 + #define BD71828_MASK_CC_CUR_DIR 0x80 221 + #define BD71828_REG_VM_BTMP_U 0xa1 222 + #define BD71828_REG_VM_BTMP_L 0xa2 223 + #define BD71828_MASK_VM_BTMP_U 0x0f 224 + #define BD71828_REG_COULOMB_CTRL 0xc4 225 + #define BD71828_REG_COULOMB_CTRL2 0xd2 226 + #define BD71828_MASK_REX_CC_CLR 0x01 227 + #define BD71828_MASK_FULL_CC_CLR 0x10 228 + #define BD71828_REG_CC_CNT_FULL3 0xbd 229 + #define BD71828_REG_CC_CNT_CHG3 0xc1 230 + 231 + #define BD71828_REG_VBAT_INITIAL1_U 0x86 232 + #define BD71828_REG_VBAT_INITIAL1_L 0x87 233 + 234 + #define BD71828_REG_VBAT_INITIAL2_U 0x88 235 + #define BD71828_REG_VBAT_INITIAL2_L 0x89 236 + 237 + #define BD71828_REG_IBAT_U 0xb0 238 + #define BD71828_REG_IBAT_L 0xb1 239 + 240 + #define BD71828_REG_IBAT_AVG_U 0xb2 241 + #define BD71828_REG_IBAT_AVG_L 0xb3 242 + 243 + #define BD71828_REG_VSYS_AVG_U 0x96 244 + #define BD71828_REG_VSYS_AVG_L 0x97 245 + #define BD71828_REG_VSYS_MIN_AVG_U 0x98 246 + #define BD71828_REG_VSYS_MIN_AVG_L 0x99 247 + #define BD71828_REG_CHG_SET1 0x75 248 + #define BD71828_REG_ALM_VBAT_LIMIT_U 0xaa 249 + #define BD71828_REG_BATCAP_MON_LIMIT_U 0xcc 250 + #define BD71828_REG_CONF 0x64 251 + 252 + #define BD71828_REG_DCIN_CLPS 0x71 253 + 254 + #define BD71828_REG_MEAS_CLEAR 0xaf 192 255 193 256 /* LEDs */ 194 257 #define BD71828_REG_LED_CTRL 0x4A
+1
sound/soc/codecs/Kconfig
··· 1902 1902 1903 1903 config SND_SOC_SI476X 1904 1904 tristate 1905 + depends on MFD_SI476X_CORE 1905 1906 1906 1907 config SND_SOC_SIGMADSP 1907 1908 tristate
+16 -1
sound/soc/codecs/arizona-jack.c
··· 461 461 bool *mic) 462 462 { 463 463 struct arizona *arizona = info->arizona; 464 + #ifdef CONFIG_GPIOLIB_LEGACY 464 465 int id_gpio = arizona->pdata.hpdet_id_gpio; 466 + #else 467 + int id_gpio = 0; 468 + #endif 465 469 466 470 if (!arizona->pdata.hpdet_acc_id) 467 471 return 0; ··· 476 472 */ 477 473 info->hpdet_res[info->num_hpdet_res++] = *reading; 478 474 475 + #ifdef CONFIG_GPIOLIB_LEGACY 479 476 /* Only check the mic directly if we didn't already ID it */ 480 477 if (id_gpio && info->num_hpdet_res == 1) { 481 478 dev_dbg(arizona->dev, "Measuring mic\n"); ··· 494 489 ARIZONA_HP_POLL, ARIZONA_HP_POLL); 495 490 return -EAGAIN; 496 491 } 492 + #endif 497 493 498 494 /* OK, got both. Now, compare... */ 499 495 dev_dbg(arizona->dev, "HPDET measured %d %d\n", ··· 535 529 { 536 530 struct arizona_priv *info = data; 537 531 struct arizona *arizona = info->arizona; 532 + #ifdef CONFIG_GPIOLIB_LEGACY 538 533 int id_gpio = arizona->pdata.hpdet_id_gpio; 534 + #endif 539 535 int ret, reading, state, report; 540 536 bool mic = false; 541 537 ··· 593 585 594 586 arizona_extcon_hp_clamp(info, false); 595 587 588 + #ifdef CONFIG_GPIOLIB_LEGACY 596 589 if (id_gpio) 597 590 gpio_set_value_cansleep(id_gpio, 0); 591 + #endif 598 592 599 593 /* If we have a mic then reenable MICDET */ 600 594 if (state && (mic || info->mic)) ··· 1327 1317 regmap_update_bits(arizona->regmap, ARIZONA_GP_SWITCH_1, 1328 1318 ARIZONA_SW1_MODE_MASK, arizona->pdata.gpsw); 1329 1319 1320 + #ifdef CONFIG_GPIOLIB_LEGACY 1330 1321 if (pdata->micd_pol_gpio > 0) { 1331 1322 if (info->micd_modes[0].gpio) 1332 1323 mode = GPIOF_OUT_INIT_HIGH; ··· 1343 1332 } 1344 1333 1345 1334 info->micd_pol_gpio = gpio_to_desc(pdata->micd_pol_gpio); 1346 - } else { 1335 + } else 1336 + #endif 1337 + { 1347 1338 if (info->micd_modes[0].gpio) 1348 1339 mode = GPIOD_OUT_HIGH; 1349 1340 else ··· 1366 1353 } 1367 1354 } 1368 1355 1356 + #ifdef CONFIG_GPIOLIB_LEGACY 1369 1357 if (arizona->pdata.hpdet_id_gpio > 0) { 1370 1358 ret = devm_gpio_request_one(dev, arizona->pdata.hpdet_id_gpio, 1371 1359 GPIOF_OUT_INIT_LOW, ··· 1378 1364 return ret; 1379 1365 } 1380 1366 } 1367 + #endif 1381 1368 1382 1369 return 0; 1383 1370 }