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

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

Pull MFD updates from Lee Jones:
"Core Frameworks
- Make better attempt at matching device with the correct OF node
- Allow batch removal of hierarchical sub-devices

New Drivers
- Add STM32 Clocksource driver
- Add support for Khadas System Control Microcontroller

Driver Removal
- Remove unused driver for TI's SMSC ECE1099

New Device Support
- Add support for Intel Emmitsburg PCH to Intel LPSS PCI
- Add support for Intel Tiger Lake PCH-H to Intel LPSS PCI
- Add support for Dialog DA revision to Dialog DA9063

New Functionality
- Add support for AXP803 to be probed by I2C

Fix-ups
- Numerous W=1 warning fixes
- Device Tree changes (stm32-lptimer, gateworks-gsc, khadas,mcu, stmfx, cros-ec, j721e-system-controller)
- Enabled Regmap 'fast I/O' in stm32-lptimer
- Change BUG_ON to WARN_ON in arizona-core
- Remove superfluous code/initialisation (madera, max14577)
- Trivial formatting/spelling issues (madera-core, madera-i2c, da9055, max77693-private)
- Switch to of_platform_populate() in sprd-sc27xx-spi
- Expand out set/get brightness/pwm macros in lm3533-ctrlbank
- Disable IRQs on suspend in motorola-cpcap
- Clean-up error handling in intel_soc_pmic_mrfld
- Ensure correct removal order of sub-devices in madera
- Many s/HTTP/HTTPS/ link changes
- Ensure name used with Regmap is unique in syscon

Bug Fixes
- Properly 'put' clock on unbind and error in arizona-core
- Fix revision handling in da9063
- Fix 'assignment of read-only location' error in kempld-core
- Avoid using the Regmap API when atomic in rn5t618
- Redefine volatile register description in rn5t618
- Use locking to protect event handler in dln2"

* tag 'mfd-next-5.9-1' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd: (76 commits)
mfd: syscon: Use a unique name with regmap_config
mfd: Replace HTTP links with HTTPS ones
mfd: dln2: Run event handler loop under spinlock
mfd: madera: Improve handling of regulator unbinding
mfd: mfd-core: Add mechanism for removal of a subset of children
mfd: intel_soc_pmic_mrfld: Simplify the return expression of intel_scu_ipc_dev_iowrite8()
mfd: max14577: Remove redundant initialization of variable current_bits
mfd: rn5t618: Fix caching of battery related registers
mfd: max77693-private: Drop a duplicated word
mfd: da9055: pdata.h: Drop a duplicated word
mfd: rn5t618: Make restart handler atomic safe
mfd: kempld-core: Fix 'assignment of read-only location' error
mfd: axp20x: Allow the AXP803 to be probed by I2C
mfd: da9063: Add support for latest DA silicon revision
mfd: da9063: Fix revision handling to correctly select reg tables
dt-bindings: mfd: st,stmfx: Remove I2C unit name
dt-bindings: mfd: ti,j721e-system-controller.yaml: Add J721e system controller
mfd: motorola-cpcap: Disable interrupt for suspend
mfd: smsc-ece1099: Remove driver
mfd: core: Add OF_MFD_CELL_REG() helper
...

+1723 -844
-76
Documentation/devicetree/bindings/mfd/cros-ec.txt
··· 1 - ChromeOS Embedded Controller 2 - 3 - Google's ChromeOS EC is a Cortex-M device which talks to the AP and 4 - implements various function such as keyboard and battery charging. 5 - 6 - The EC can be connect through various means (I2C, SPI, LPC, RPMSG) and the 7 - compatible string used depends on the interface. Each connection method has 8 - its own driver which connects to the top level interface-agnostic EC driver. 9 - Other Linux driver (such as cros-ec-keyb for the matrix keyboard) connect to 10 - the top-level driver. 11 - 12 - Required properties (I2C): 13 - - compatible: "google,cros-ec-i2c" 14 - - reg: I2C slave address 15 - 16 - Required properties (SPI): 17 - - compatible: "google,cros-ec-spi" 18 - - reg: SPI chip select 19 - 20 - Required properties (RPMSG): 21 - - compatible: "google,cros-ec-rpmsg" 22 - 23 - Optional properties (SPI): 24 - - google,cros-ec-spi-pre-delay: Some implementations of the EC need a little 25 - time to wake up from sleep before they can receive SPI transfers at a high 26 - clock rate. This property specifies the delay, in usecs, between the 27 - assertion of the CS to the start of the first clock pulse. 28 - - google,cros-ec-spi-msg-delay: Some implementations of the EC require some 29 - additional processing time in order to accept new transactions. If the delay 30 - between transactions is not long enough the EC may not be able to respond 31 - properly to subsequent transactions and cause them to hang. This property 32 - specifies the delay, in usecs, introduced between transactions to account 33 - for the time required by the EC to get back into a state in which new data 34 - can be accepted. 35 - 36 - Required properties (LPC): 37 - - compatible: "google,cros-ec-lpc" 38 - - reg: List of (IO address, size) pairs defining the interface uses 39 - 40 - Optional properties (all): 41 - - google,has-vbc-nvram: Some implementations of the EC include a small 42 - nvram space used to store verified boot context data. This boolean flag 43 - is used to specify whether this nvram is present or not. 44 - 45 - Example for I2C: 46 - 47 - i2c@12ca0000 { 48 - cros-ec@1e { 49 - reg = <0x1e>; 50 - compatible = "google,cros-ec-i2c"; 51 - interrupts = <14 0>; 52 - interrupt-parent = <&wakeup_eint>; 53 - wakeup-source; 54 - }; 55 - 56 - 57 - Example for SPI: 58 - 59 - spi@131b0000 { 60 - ec@0 { 61 - compatible = "google,cros-ec-spi"; 62 - reg = <0x0>; 63 - interrupts = <14 0>; 64 - interrupt-parent = <&wakeup_eint>; 65 - wakeup-source; 66 - spi-max-frequency = <5000000>; 67 - controller-data { 68 - cs-gpio = <&gpf0 3 4 3 0>; 69 - samsung,spi-cs; 70 - samsung,spi-feedback-delay = <2>; 71 - }; 72 - }; 73 - }; 74 - 75 - 76 - Example for LPC is not supplied as it is not yet implemented.
+3 -2
Documentation/devicetree/bindings/mfd/gateworks-gsc.yaml
··· 79 79 description: | 80 80 conversion mode: 81 81 0 - temperature, in C*10 82 - 1 - pre-scaled voltage value 82 + 1 - pre-scaled 24-bit voltage value 83 83 2 - scaled voltage based on an optional resistor divider 84 84 and optional offset 85 + 3 - pre-scaled 16-bit voltage value 85 86 $ref: /schemas/types.yaml#/definitions/uint32 86 - enum: [0, 1, 2] 87 + enum: [0, 1, 2, 3] 87 88 88 89 gw,voltage-divider-ohms: 89 90 description: Values of resistors for divider on raw ADC input
+129
Documentation/devicetree/bindings/mfd/google,cros-ec.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/google,cros-ec.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: ChromeOS Embedded Controller 8 + 9 + maintainers: 10 + - Benson Leung <bleung@chromium.org> 11 + - Enric Balletbo i Serra <enric.balletbo@collabora.com> 12 + - Guenter Roeck <groeck@chromium.org> 13 + 14 + description: 15 + Google's ChromeOS EC is a microcontroller which talks to the AP and 16 + implements various functions such as keyboard and battery charging. 17 + The EC can be connected through various interfaces (I2C, SPI, and others) 18 + and the compatible string specifies which interface is being used. 19 + 20 + properties: 21 + compatible: 22 + oneOf: 23 + - description: 24 + For implementations of the EC is connected through I2C. 25 + const: google,cros-ec-i2c 26 + - description: 27 + For implementations of the EC is connected through SPI. 28 + const: google,cros-ec-spi 29 + - description: 30 + For implementations of the EC is connected through RPMSG. 31 + const: google,cros-ec-rpmsg 32 + 33 + google,cros-ec-spi-pre-delay: 34 + description: 35 + This property specifies the delay in usecs between the 36 + assertion of the CS and the first clock pulse. 37 + allOf: 38 + - $ref: /schemas/types.yaml#/definitions/uint32 39 + - default: 0 40 + - minimum: 0 41 + 42 + google,cros-ec-spi-msg-delay: 43 + description: 44 + This property specifies the delay in usecs between messages. 45 + allOf: 46 + - $ref: /schemas/types.yaml#/definitions/uint32 47 + - default: 0 48 + - minimum: 0 49 + 50 + google,has-vbc-nvram: 51 + description: 52 + Some implementations of the EC include a small nvram space used to 53 + store verified boot context data. This boolean flag is used to specify 54 + whether this nvram is present or not. 55 + type: boolean 56 + 57 + spi-max-frequency: 58 + description: Maximum SPI frequency of the device in Hz. 59 + 60 + reg: 61 + maxItems: 1 62 + 63 + interrupts: 64 + maxItems: 1 65 + 66 + required: 67 + - compatible 68 + 69 + if: 70 + properties: 71 + compatible: 72 + contains: 73 + enum: 74 + - google,cros-ec-i2c 75 + - google,cros-ec-rpmsg 76 + then: 77 + properties: 78 + google,cros-ec-spi-pre-delay: false 79 + google,cros-ec-spi-msg-delay: false 80 + spi-max-frequency: false 81 + 82 + additionalProperties: false 83 + 84 + examples: 85 + # Example for I2C 86 + - | 87 + #include <dt-bindings/gpio/gpio.h> 88 + #include <dt-bindings/interrupt-controller/irq.h> 89 + 90 + i2c0 { 91 + #address-cells = <1>; 92 + #size-cells = <0>; 93 + 94 + cros-ec@1e { 95 + compatible = "google,cros-ec-i2c"; 96 + reg = <0x1e>; 97 + interrupts = <6 0>; 98 + interrupt-parent = <&gpio0>; 99 + }; 100 + }; 101 + 102 + # Example for SPI 103 + - | 104 + #include <dt-bindings/gpio/gpio.h> 105 + #include <dt-bindings/interrupt-controller/irq.h> 106 + 107 + spi0 { 108 + #address-cells = <1>; 109 + #size-cells = <0>; 110 + 111 + cros-ec@0 { 112 + compatible = "google,cros-ec-spi"; 113 + reg = <0x0>; 114 + google,cros-ec-spi-msg-delay = <30>; 115 + google,cros-ec-spi-pre-delay = <10>; 116 + interrupts = <99 0>; 117 + interrupt-parent = <&gpio7>; 118 + spi-max-frequency = <5000000>; 119 + }; 120 + }; 121 + 122 + # Example for RPMSG 123 + - | 124 + scp0 { 125 + cros-ec { 126 + compatible = "google,cros-ec-rpmsg"; 127 + }; 128 + }; 129 + ...
+44
Documentation/devicetree/bindings/mfd/khadas,mcu.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/khadas,mcu.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Khadas on-board Microcontroller Device Tree Bindings 8 + 9 + maintainers: 10 + - Neil Armstrong <narmstrong@baylibre.com> 11 + 12 + description: | 13 + Khadas embeds a microcontroller on their VIM and Edge boards adding some 14 + system feature as PWM Fan control (for VIM2 rev14 or VIM3), User memory 15 + storage, IR/Key resume control, system power LED control and more. 16 + 17 + properties: 18 + compatible: 19 + enum: 20 + - khadas,mcu # MCU revision is discoverable 21 + 22 + "#cooling-cells": # Only needed for boards having FAN control feature 23 + const: 2 24 + 25 + reg: 26 + maxItems: 1 27 + 28 + required: 29 + - compatible 30 + - reg 31 + 32 + additionalProperties: false 33 + 34 + examples: 35 + - | 36 + i2c { 37 + #address-cells = <1>; 38 + #size-cells = <0>; 39 + khadas_mcu: system-controller@18 { 40 + compatible = "khadas,mcu"; 41 + reg = <0x18>; 42 + #cooling-cells = <2>; 43 + }; 44 + };
+5
Documentation/devicetree/bindings/mfd/st,stm32-lptimer.yaml
··· 33 33 items: 34 34 - const: mux 35 35 36 + interrupts: 37 + maxItems: 1 38 + 36 39 "#address-cells": 37 40 const: 1 38 41 ··· 109 106 examples: 110 107 - | 111 108 #include <dt-bindings/clock/stm32mp1-clks.h> 109 + #include <dt-bindings/interrupt-controller/arm-gic.h> 112 110 timer@40002400 { 113 111 compatible = "st,stm32-lptimer"; 114 112 reg = <0x40002400 0x400>; 115 113 clocks = <&timer_clk>; 116 114 clock-names = "mux"; 115 + interrupts-extended = <&exti 47 IRQ_TYPE_LEVEL_HIGH>; 117 116 #address-cells = <1>; 118 117 #size-cells = <0>; 119 118
+122
Documentation/devicetree/bindings/mfd/st,stmfx.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/st,stmfx.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: STMicroelectonics Multi-Function eXpander (STMFX) bindings 8 + 9 + description: ST Multi-Function eXpander (STMFX) is a slave controller using I2C for 10 + communication with the main MCU. Its main features are GPIO expansion, 11 + main MCU IDD measurement (IDD is the amount of current that flows 12 + through VDD) and resistive touchscreen controller. 13 + 14 + maintainers: 15 + - Amelie Delaunay <amelie.delaunay@st.com> 16 + 17 + properties: 18 + compatible: 19 + const: st,stmfx-0300 20 + 21 + reg: 22 + enum: [ 0x42, 0x43 ] 23 + 24 + interrupts: 25 + maxItems: 1 26 + 27 + drive-open-drain: true 28 + 29 + vdd-supply: 30 + maxItems: 1 31 + 32 + pinctrl: 33 + type: object 34 + 35 + properties: 36 + compatible: 37 + const: st,stmfx-0300-pinctrl 38 + 39 + "#gpio-cells": 40 + const: 2 41 + 42 + "#interrupt-cells": 43 + const: 2 44 + 45 + gpio-controller: true 46 + 47 + interrupt-controller: true 48 + 49 + gpio-ranges: 50 + description: if all STMFX pins[24:0] are available (no other STMFX function in use), 51 + you should use gpio-ranges = <&stmfx_pinctrl 0 0 24>; 52 + if agpio[3:0] are not available (STMFX Touchscreen function in use), 53 + you should use gpio-ranges = <&stmfx_pinctrl 0 0 16>, <&stmfx_pinctrl 20 20 4>; 54 + if agpio[7:4] are not available (STMFX IDD function in use), 55 + you should use gpio-ranges = <&stmfx_pinctrl 0 0 20>; 56 + maxItems: 1 57 + 58 + patternProperties: 59 + "^[a-zA-Z]*-pins$": 60 + type: object 61 + 62 + allOf: 63 + - $ref: ../pinctrl/pinmux-node.yaml 64 + 65 + properties: 66 + pins: true 67 + bias-disable: true 68 + bias-pull-up: true 69 + bias-pull-pin-default: true 70 + bias-pull-down: true 71 + drive-open-drain: true 72 + drive-push-pull: true 73 + output-high: true 74 + output-low: true 75 + 76 + additionalProperties: false 77 + 78 + required: 79 + - compatible 80 + - "#gpio-cells" 81 + - "#interrupt-cells" 82 + - gpio-controller 83 + - interrupt-controller 84 + - gpio-ranges 85 + 86 + additionalProperties: false 87 + 88 + required: 89 + - compatible 90 + - reg 91 + - interrupts 92 + 93 + examples: 94 + - | 95 + #include <dt-bindings/interrupt-controller/arm-gic.h> 96 + i2c { 97 + #address-cells = <1>; 98 + #size-cells = <0>; 99 + stmfx@42 { 100 + compatible = "st,stmfx-0300"; 101 + reg = <0x42>; 102 + interrupts = <8 IRQ_TYPE_EDGE_RISING>; 103 + interrupt-parent = <&gpioi>; 104 + vdd-supply = <&v3v3>; 105 + 106 + stmfx_pinctrl: pinctrl { 107 + compatible = "st,stmfx-0300-pinctrl"; 108 + #gpio-cells = <2>; 109 + #interrupt-cells = <2>; 110 + gpio-controller; 111 + interrupt-controller; 112 + gpio-ranges = <&stmfx_pinctrl 0 0 24>; 113 + 114 + joystick_pins: joystick-pins { 115 + pins = "gpio0", "gpio1", "gpio2", "gpio3", "gpio4"; 116 + drive-push-pull; 117 + bias-pull-up; 118 + }; 119 + }; 120 + }; 121 + }; 122 + ...
-28
Documentation/devicetree/bindings/mfd/stmfx.txt
··· 1 - STMicroelectonics Multi-Function eXpander (STMFX) Core bindings 2 - 3 - ST Multi-Function eXpander (STMFX) is a slave controller using I2C for 4 - communication with the main MCU. Its main features are GPIO expansion, main 5 - MCU IDD measurement (IDD is the amount of current that flows through VDD) and 6 - resistive touchscreen controller. 7 - 8 - Required properties: 9 - - compatible: should be "st,stmfx-0300". 10 - - reg: I2C slave address of the device. 11 - - interrupts: interrupt specifier triggered by MFX_IRQ_OUT signal. 12 - Please refer to ../interrupt-controller/interrupt.txt 13 - 14 - Optional properties: 15 - - drive-open-drain: configure MFX_IRQ_OUT as open drain. 16 - - vdd-supply: phandle of the regulator supplying STMFX. 17 - 18 - Example: 19 - 20 - stmfx: stmfx@42 { 21 - compatible = "st,stmfx-0300"; 22 - reg = <0x42>; 23 - interrupts = <8 IRQ_TYPE_EDGE_RISING>; 24 - interrupt-parent = <&gpioi>; 25 - vdd-supply = <&v3v3>; 26 - }; 27 - 28 - Please refer to ../pinctrl/pinctrl-stmfx.txt for STMFX GPIO expander function bindings.
+1 -1
Documentation/devicetree/bindings/mfd/twl-family.txt
··· 26 26 Example: 27 27 /* 28 28 * Integrated Power Management Chip 29 - * http://www.ti.com/lit/ds/symlink/twl6030.pdf 29 + * https://www.ti.com/lit/ds/symlink/twl6030.pdf 30 30 */ 31 31 twl@48 { 32 32 compatible = "ti,twl6030";
-116
Documentation/devicetree/bindings/pinctrl/pinctrl-stmfx.txt
··· 1 - STMicroelectronics Multi-Function eXpander (STMFX) GPIO expander bindings 2 - 3 - ST Multi-Function eXpander (STMFX) offers up to 24 GPIOs expansion. 4 - Please refer to ../mfd/stmfx.txt for STMFX Core bindings. 5 - 6 - Required properties: 7 - - compatible: should be "st,stmfx-0300-pinctrl". 8 - - #gpio-cells: should be <2>, the first cell is the GPIO number and the second 9 - cell is the gpio flags in accordance with <dt-bindings/gpio/gpio.h>. 10 - - gpio-controller: marks the device as a GPIO controller. 11 - - #interrupt-cells: should be <2>, the first cell is the GPIO number and the 12 - second cell is the interrupt flags in accordance with 13 - <dt-bindings/interrupt-controller/irq.h>. 14 - - interrupt-controller: marks the device as an interrupt controller. 15 - - gpio-ranges: specifies the mapping between gpio controller and pin 16 - controller pins. Check "Concerning gpio-ranges property" below. 17 - Please refer to ../gpio/gpio.txt. 18 - 19 - Please refer to pinctrl-bindings.txt for pin configuration. 20 - 21 - Required properties for pin configuration sub-nodes: 22 - - pins: list of pins to which the configuration applies. 23 - 24 - Optional properties for pin configuration sub-nodes (pinconf-generic ones): 25 - - bias-disable: disable any bias on the pin. 26 - - bias-pull-up: the pin will be pulled up. 27 - - bias-pull-pin-default: use the pin-default pull state. 28 - - bias-pull-down: the pin will be pulled down. 29 - - drive-open-drain: the pin will be driven with open drain. 30 - - drive-push-pull: the pin will be driven actively high and low. 31 - - output-high: the pin will be configured as an output driving high level. 32 - - output-low: the pin will be configured as an output driving low level. 33 - 34 - Note that STMFX pins[15:0] are called "gpio[15:0]", and STMFX pins[23:16] are 35 - called "agpio[7:0]". Example, to refer to pin 18 of STMFX, use "agpio2". 36 - 37 - Concerning gpio-ranges property: 38 - - if all STMFX pins[24:0] are available (no other STMFX function in use), you 39 - should use gpio-ranges = <&stmfx_pinctrl 0 0 24>; 40 - - if agpio[3:0] are not available (STMFX Touchscreen function in use), you 41 - should use gpio-ranges = <&stmfx_pinctrl 0 0 16>, <&stmfx_pinctrl 20 20 4>; 42 - - if agpio[7:4] are not available (STMFX IDD function in use), you 43 - should use gpio-ranges = <&stmfx_pinctrl 0 0 20>; 44 - 45 - 46 - Example: 47 - 48 - stmfx: stmfx@42 { 49 - ... 50 - 51 - stmfx_pinctrl: stmfx-pin-controller { 52 - compatible = "st,stmfx-0300-pinctrl"; 53 - #gpio-cells = <2>; 54 - #interrupt-cells = <2>; 55 - gpio-controller; 56 - interrupt-controller; 57 - gpio-ranges = <&stmfx_pinctrl 0 0 24>; 58 - 59 - joystick_pins: joystick { 60 - pins = "gpio0", "gpio1", "gpio2", "gpio3", "gpio4"; 61 - drive-push-pull; 62 - bias-pull-up; 63 - }; 64 - }; 65 - }; 66 - 67 - Example of STMFX GPIO consumers: 68 - 69 - joystick { 70 - compatible = "gpio-keys"; 71 - #address-cells = <1>; 72 - #size-cells = <0>; 73 - pinctrl-0 = <&joystick_pins>; 74 - pinctrl-names = "default"; 75 - button-0 { 76 - label = "JoySel"; 77 - linux,code = <KEY_ENTER>; 78 - interrupt-parent = <&stmfx_pinctrl>; 79 - interrupts = <0 IRQ_TYPE_EDGE_RISING>; 80 - }; 81 - button-1 { 82 - label = "JoyDown"; 83 - linux,code = <KEY_DOWN>; 84 - interrupt-parent = <&stmfx_pinctrl>; 85 - interrupts = <1 IRQ_TYPE_EDGE_RISING>; 86 - }; 87 - button-2 { 88 - label = "JoyLeft"; 89 - linux,code = <KEY_LEFT>; 90 - interrupt-parent = <&stmfx_pinctrl>; 91 - interrupts = <2 IRQ_TYPE_EDGE_RISING>; 92 - }; 93 - button-3 { 94 - label = "JoyRight"; 95 - linux,code = <KEY_RIGHT>; 96 - interrupt-parent = <&stmfx_pinctrl>; 97 - interrupts = <3 IRQ_TYPE_EDGE_RISING>; 98 - }; 99 - button-4 { 100 - label = "JoyUp"; 101 - linux,code = <KEY_UP>; 102 - interrupt-parent = <&stmfx_pinctrl>; 103 - interrupts = <4 IRQ_TYPE_EDGE_RISING>; 104 - }; 105 - }; 106 - 107 - leds { 108 - compatible = "gpio-leds"; 109 - orange { 110 - gpios = <&stmfx_pinctrl 17 1>; 111 - }; 112 - 113 - blue { 114 - gpios = <&stmfx_pinctrl 19 1>; 115 - }; 116 - }
-1
Documentation/driver-api/index.rst
··· 100 100 rfkill 101 101 serial/index 102 102 sm501 103 - smsc_ece1099 104 103 switchtec 105 104 sync_file 106 105 vfio-mediated-device
-60
Documentation/driver-api/smsc_ece1099.rst
··· 1 - ================================================= 2 - Msc Keyboard Scan Expansion/GPIO Expansion device 3 - ================================================= 4 - 5 - What is smsc-ece1099? 6 - ---------------------- 7 - 8 - The ECE1099 is a 40-Pin 3.3V Keyboard Scan Expansion 9 - or GPIO Expansion device. The device supports a keyboard 10 - scan matrix of 23x8. The device is connected to a Master 11 - via the SMSC BC-Link interface or via the SMBus. 12 - Keypad scan Input(KSI) and Keypad Scan Output(KSO) signals 13 - are multiplexed with GPIOs. 14 - 15 - Interrupt generation 16 - -------------------- 17 - 18 - Interrupts can be generated by an edge detection on a GPIO 19 - pin or an edge detection on one of the bus interface pins. 20 - Interrupts can also be detected on the keyboard scan interface. 21 - The bus interrupt pin (BC_INT# or SMBUS_INT#) is asserted if 22 - any bit in one of the Interrupt Status registers is 1 and 23 - the corresponding Interrupt Mask bit is also 1. 24 - 25 - In order for software to determine which device is the source 26 - of an interrupt, it should first read the Group Interrupt Status Register 27 - to determine which Status register group is a source for the interrupt. 28 - Software should read both the Status register and the associated Mask register, 29 - then AND the two values together. Bits that are 1 in the result of the AND 30 - are active interrupts. Software clears an interrupt by writing a 1 to the 31 - corresponding bit in the Status register. 32 - 33 - Communication Protocol 34 - ---------------------- 35 - 36 - - SMbus slave Interface 37 - The host processor communicates with the ECE1099 device 38 - through a series of read/write registers via the SMBus 39 - interface. SMBus is a serial communication protocol between 40 - a computer host and its peripheral devices. The SMBus data 41 - rate is 10KHz minimum to 400 KHz maximum 42 - 43 - - Slave Bus Interface 44 - The ECE1099 device SMBus implementation is a subset of the 45 - SMBus interface to the host. The device is a slave-only SMBus device. 46 - The implementation in the device is a subset of SMBus since it 47 - only supports four protocols. 48 - 49 - The Write Byte, Read Byte, Send Byte, and Receive Byte protocols are the 50 - only valid SMBus protocols for the device. 51 - 52 - - BC-LinkTM Interface 53 - The BC-Link is a proprietary bus that allows communication 54 - between a Master device and a Companion device. The Master 55 - device uses this serial bus to read and write registers 56 - located on the Companion device. The bus comprises three signals, 57 - BC_CLK, BC_DAT and BC_INT#. The Master device always provides the 58 - clock, BC_CLK, and the Companion device is the source for an 59 - independent asynchronous interrupt signal, BC_INT#. The ECE1099 60 - supports BC-Link speeds up to 24MHz.
+41
MAINTAINERS
··· 9678 9678 F: include/linux/kgdb.h 9679 9679 F: kernel/debug/ 9680 9680 9681 + KHADAS MCU MFD DRIVER 9682 + M: Neil Armstrong <narmstrong@baylibre.com> 9683 + L: linux-amlogic@lists.infradead.org 9684 + S: Maintained 9685 + F: Documentation/devicetree/bindings/mfd/khadas,mcu.yaml 9686 + F: drivers/mfd/khadas-mcu.c 9687 + F: include/linux/mfd/khadas-mcu.h 9688 + F: drivers/thermal/khadas_mcu_fan.c 9689 + 9681 9690 KMEMLEAK 9682 9691 M: Catalin Marinas <catalin.marinas@arm.com> 9683 9692 S: Maintained ··· 14896 14887 S: Odd Fixes 14897 14888 F: drivers/tty/serial/rp2.* 14898 14889 14890 + ROHM BD99954 CHARGER IC 14891 + R: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com> 14892 + L: linux-power@fi.rohmeurope.com 14893 + S: Supported 14894 + F: drivers/power/supply/bd99954-charger.c 14895 + F: drivers/power/supply/bd99954-charger.h 14896 + 14899 14897 ROHM BH1750 AMBIENT LIGHT SENSOR DRIVER 14900 14898 M: Tomasz Duszynski <tduszyns@gmail.com> 14901 14899 S: Maintained ··· 14919 14903 F: drivers/mfd/bd9571mwv.c 14920 14904 F: drivers/regulator/bd9571mwv-regulator.c 14921 14905 F: include/linux/mfd/bd9571mwv.h 14906 + 14907 + ROHM POWER MANAGEMENT IC DEVICE DRIVERS 14908 + R: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com> 14909 + L: linux-power@fi.rohmeurope.com 14910 + S: Supported 14911 + F: Documentation/devicetree/bindings/mfd/rohm,bd70528-pmic.txt 14912 + F: Documentation/devicetree/bindings/regulator/rohm,bd70528-regulator.txt 14913 + F: drivers/clk/clk-bd718x7.c 14914 + F: drivers/gpio/gpio-bd70528.c 14915 + F: drivers/gpio/gpio-bd71828.c 14916 + F: drivers/mfd/rohm-bd70528.c 14917 + F: drivers/mfd/rohm-bd71828.c 14918 + F: drivers/mfd/rohm-bd718x7.c 14919 + F: drivers/power/supply/bd70528-charger.c 14920 + F: drivers/regulator/bd70528-regulator.c 14921 + F: drivers/regulator/bd71828-regulator.c 14922 + F: drivers/regulator/bd718x7-regulator.c 14923 + F: drivers/regulator/rohm-regulator.c 14924 + F: drivers/rtc/rtc-bd70528.c 14925 + F: drivers/watchdog/bd70528_wdt.c 14926 + F: include/linux/mfd/rohm-bd70528.h 14927 + F: include/linux/mfd/rohm-bd71828.h 14928 + F: include/linux/mfd/rohm-bd718x7.h 14929 + F: include/linux/mfd/rohm-generic.h 14930 + F: include/linux/mfd/rohm-shared.h 14922 14931 14923 14932 ROSE NETWORK LAYER 14924 14933 M: Ralf Baechle <ralf@linux-mips.org>
+4
drivers/clocksource/Kconfig
··· 291 291 select CLKSRC_MMIO 292 292 select TIMER_OF 293 293 294 + config CLKSRC_STM32_LP 295 + bool "Low power clocksource for STM32 SoCs" 296 + depends on MFD_STM32_LPTIMER || COMPILE_TEST 297 + 294 298 config CLKSRC_MPS2 295 299 bool "Clocksource for MPS2 SoCs" if COMPILE_TEST 296 300 depends on GENERIC_SCHED_CLOCK
+1
drivers/clocksource/Makefile
··· 45 45 obj-$(CONFIG_CADENCE_TTC_TIMER) += timer-cadence-ttc.o 46 46 obj-$(CONFIG_CLKSRC_EFM32) += timer-efm32.o 47 47 obj-$(CONFIG_CLKSRC_STM32) += timer-stm32.o 48 + obj-$(CONFIG_CLKSRC_STM32_LP) += timer-stm32-lp.o 48 49 obj-$(CONFIG_CLKSRC_EXYNOS_MCT) += exynos_mct.o 49 50 obj-$(CONFIG_CLKSRC_LPC32XX) += timer-lpc32xx.o 50 51 obj-$(CONFIG_CLKSRC_MPS2) += mps2-timer.o
+221
drivers/clocksource/timer-stm32-lp.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Copyright (C) STMicroelectronics 2019 - All Rights Reserved 4 + * Authors: Benjamin Gaignard <benjamin.gaignard@st.com> for STMicroelectronics. 5 + * Pascal Paillet <p.paillet@st.com> for STMicroelectronics. 6 + */ 7 + 8 + #include <linux/clk.h> 9 + #include <linux/clockchips.h> 10 + #include <linux/interrupt.h> 11 + #include <linux/mfd/stm32-lptimer.h> 12 + #include <linux/module.h> 13 + #include <linux/of_address.h> 14 + #include <linux/of_irq.h> 15 + #include <linux/platform_device.h> 16 + #include <linux/pm_wakeirq.h> 17 + 18 + #define CFGR_PSC_OFFSET 9 19 + #define STM32_LP_RATING 1000 20 + #define STM32_TARGET_CLKRATE (32000 * HZ) 21 + #define STM32_LP_MAX_PSC 7 22 + 23 + struct stm32_lp_private { 24 + struct regmap *reg; 25 + struct clock_event_device clkevt; 26 + unsigned long period; 27 + struct device *dev; 28 + }; 29 + 30 + static struct stm32_lp_private* 31 + to_priv(struct clock_event_device *clkevt) 32 + { 33 + return container_of(clkevt, struct stm32_lp_private, clkevt); 34 + } 35 + 36 + static int stm32_clkevent_lp_shutdown(struct clock_event_device *clkevt) 37 + { 38 + struct stm32_lp_private *priv = to_priv(clkevt); 39 + 40 + regmap_write(priv->reg, STM32_LPTIM_CR, 0); 41 + regmap_write(priv->reg, STM32_LPTIM_IER, 0); 42 + /* clear pending flags */ 43 + regmap_write(priv->reg, STM32_LPTIM_ICR, STM32_LPTIM_ARRMCF); 44 + 45 + return 0; 46 + } 47 + 48 + static int stm32_clkevent_lp_set_timer(unsigned long evt, 49 + struct clock_event_device *clkevt, 50 + int is_periodic) 51 + { 52 + struct stm32_lp_private *priv = to_priv(clkevt); 53 + 54 + /* disable LPTIMER to be able to write into IER register*/ 55 + regmap_write(priv->reg, STM32_LPTIM_CR, 0); 56 + /* enable ARR interrupt */ 57 + regmap_write(priv->reg, STM32_LPTIM_IER, STM32_LPTIM_ARRMIE); 58 + /* enable LPTIMER to be able to write into ARR register */ 59 + regmap_write(priv->reg, STM32_LPTIM_CR, STM32_LPTIM_ENABLE); 60 + /* set next event counter */ 61 + regmap_write(priv->reg, STM32_LPTIM_ARR, evt); 62 + 63 + /* start counter */ 64 + if (is_periodic) 65 + regmap_write(priv->reg, STM32_LPTIM_CR, 66 + STM32_LPTIM_CNTSTRT | STM32_LPTIM_ENABLE); 67 + else 68 + regmap_write(priv->reg, STM32_LPTIM_CR, 69 + STM32_LPTIM_SNGSTRT | STM32_LPTIM_ENABLE); 70 + 71 + return 0; 72 + } 73 + 74 + static int stm32_clkevent_lp_set_next_event(unsigned long evt, 75 + struct clock_event_device *clkevt) 76 + { 77 + return stm32_clkevent_lp_set_timer(evt, clkevt, 78 + clockevent_state_periodic(clkevt)); 79 + } 80 + 81 + static int stm32_clkevent_lp_set_periodic(struct clock_event_device *clkevt) 82 + { 83 + struct stm32_lp_private *priv = to_priv(clkevt); 84 + 85 + return stm32_clkevent_lp_set_timer(priv->period, clkevt, true); 86 + } 87 + 88 + static int stm32_clkevent_lp_set_oneshot(struct clock_event_device *clkevt) 89 + { 90 + struct stm32_lp_private *priv = to_priv(clkevt); 91 + 92 + return stm32_clkevent_lp_set_timer(priv->period, clkevt, false); 93 + } 94 + 95 + static irqreturn_t stm32_clkevent_lp_irq_handler(int irq, void *dev_id) 96 + { 97 + struct clock_event_device *clkevt = (struct clock_event_device *)dev_id; 98 + struct stm32_lp_private *priv = to_priv(clkevt); 99 + 100 + regmap_write(priv->reg, STM32_LPTIM_ICR, STM32_LPTIM_ARRMCF); 101 + 102 + if (clkevt->event_handler) 103 + clkevt->event_handler(clkevt); 104 + 105 + return IRQ_HANDLED; 106 + } 107 + 108 + static void stm32_clkevent_lp_set_prescaler(struct stm32_lp_private *priv, 109 + unsigned long *rate) 110 + { 111 + int i; 112 + 113 + for (i = 0; i <= STM32_LP_MAX_PSC; i++) { 114 + if (DIV_ROUND_CLOSEST(*rate, 1 << i) < STM32_TARGET_CLKRATE) 115 + break; 116 + } 117 + 118 + regmap_write(priv->reg, STM32_LPTIM_CFGR, i << CFGR_PSC_OFFSET); 119 + 120 + /* Adjust rate and period given the prescaler value */ 121 + *rate = DIV_ROUND_CLOSEST(*rate, (1 << i)); 122 + priv->period = DIV_ROUND_UP(*rate, HZ); 123 + } 124 + 125 + static void stm32_clkevent_lp_init(struct stm32_lp_private *priv, 126 + struct device_node *np, unsigned long rate) 127 + { 128 + priv->clkevt.name = np->full_name; 129 + priv->clkevt.cpumask = cpu_possible_mask; 130 + priv->clkevt.features = CLOCK_EVT_FEAT_PERIODIC | 131 + CLOCK_EVT_FEAT_ONESHOT; 132 + priv->clkevt.set_state_shutdown = stm32_clkevent_lp_shutdown; 133 + priv->clkevt.set_state_periodic = stm32_clkevent_lp_set_periodic; 134 + priv->clkevt.set_state_oneshot = stm32_clkevent_lp_set_oneshot; 135 + priv->clkevt.set_next_event = stm32_clkevent_lp_set_next_event; 136 + priv->clkevt.rating = STM32_LP_RATING; 137 + 138 + clockevents_config_and_register(&priv->clkevt, rate, 0x1, 139 + STM32_LPTIM_MAX_ARR); 140 + } 141 + 142 + static int stm32_clkevent_lp_probe(struct platform_device *pdev) 143 + { 144 + struct stm32_lptimer *ddata = dev_get_drvdata(pdev->dev.parent); 145 + struct stm32_lp_private *priv; 146 + unsigned long rate; 147 + int ret, irq; 148 + 149 + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); 150 + if (!priv) 151 + return -ENOMEM; 152 + 153 + priv->reg = ddata->regmap; 154 + ret = clk_prepare_enable(ddata->clk); 155 + if (ret) 156 + return -EINVAL; 157 + 158 + rate = clk_get_rate(ddata->clk); 159 + if (!rate) { 160 + ret = -EINVAL; 161 + goto out_clk_disable; 162 + } 163 + 164 + irq = platform_get_irq(to_platform_device(pdev->dev.parent), 0); 165 + if (irq <= 0) { 166 + ret = irq; 167 + goto out_clk_disable; 168 + } 169 + 170 + if (of_property_read_bool(pdev->dev.parent->of_node, "wakeup-source")) { 171 + ret = device_init_wakeup(&pdev->dev, true); 172 + if (ret) 173 + goto out_clk_disable; 174 + 175 + ret = dev_pm_set_wake_irq(&pdev->dev, irq); 176 + if (ret) 177 + goto out_clk_disable; 178 + } 179 + 180 + ret = devm_request_irq(&pdev->dev, irq, stm32_clkevent_lp_irq_handler, 181 + IRQF_TIMER, pdev->name, &priv->clkevt); 182 + if (ret) 183 + goto out_clk_disable; 184 + 185 + stm32_clkevent_lp_set_prescaler(priv, &rate); 186 + 187 + stm32_clkevent_lp_init(priv, pdev->dev.parent->of_node, rate); 188 + 189 + priv->dev = &pdev->dev; 190 + 191 + return 0; 192 + 193 + out_clk_disable: 194 + clk_disable_unprepare(ddata->clk); 195 + return ret; 196 + } 197 + 198 + static int stm32_clkevent_lp_remove(struct platform_device *pdev) 199 + { 200 + return -EBUSY; /* cannot unregister clockevent */ 201 + } 202 + 203 + static const struct of_device_id stm32_clkevent_lp_of_match[] = { 204 + { .compatible = "st,stm32-lptimer-timer", }, 205 + {}, 206 + }; 207 + MODULE_DEVICE_TABLE(of, stm32_clkevent_lp_of_match); 208 + 209 + static struct platform_driver stm32_clkevent_lp_driver = { 210 + .probe = stm32_clkevent_lp_probe, 211 + .remove = stm32_clkevent_lp_remove, 212 + .driver = { 213 + .name = "stm32-lptimer-timer", 214 + .of_match_table = of_match_ptr(stm32_clkevent_lp_of_match), 215 + }, 216 + }; 217 + module_platform_driver(stm32_clkevent_lp_driver); 218 + 219 + MODULE_ALIAS("platform:stm32-lptimer-timer"); 220 + MODULE_DESCRIPTION("STMicroelectronics STM32 clockevent low power driver"); 221 + MODULE_LICENSE("GPL v2");
+21 -12
drivers/mfd/Kconfig
··· 1193 1193 This driver can also be built as a module. If so, the module 1194 1194 will be called sky81452. 1195 1195 1196 - config MFD_SMSC 1197 - bool "SMSC ECE1099 series chips" 1198 - depends on I2C=y 1199 - select MFD_CORE 1200 - select REGMAP_I2C 1201 - help 1202 - If you say yes here you get support for the 1203 - ece1099 chips from SMSC. 1204 - 1205 - To compile this driver as a module, choose M here: the 1206 - module will be called smsc. 1207 - 1208 1196 config MFD_SC27XX_PMIC 1209 1197 tristate "Spreadtrum SC27xx PMICs" 1210 1198 depends on ARCH_SPRD || COMPILE_TEST ··· 2040 2052 Support for the Qualcomm WCD9340/WCD9341 Codec. 2041 2053 This driver provides common support WCD934x audio codec and its 2042 2054 associated Pin Controller, Soundwire Controller and Audio codec. 2055 + 2056 + config MFD_KHADAS_MCU 2057 + tristate "Support for Khadas System control Microcontroller" 2058 + depends on I2C 2059 + depends on ARCH_MESON || ARCH_ROCKCHIP || COMPILE_TEST 2060 + select MFD_CORE 2061 + select REGMAP_I2C 2062 + help 2063 + Support for the Khadas System control Microcontroller interface 2064 + present on their VIM and Edge boards. 2065 + 2066 + This Microcontroller is present on the Khadas VIM1, VIM2, VIM3 and 2067 + Edge boards. 2068 + 2069 + It provides multiple boot control features like password check, 2070 + power-on options, power-off control and system FAN control on recent 2071 + boards. 2072 + 2073 + This driver provides common support for accessing the device, 2074 + additional drivers must be enabled in order to use the functionality 2075 + of the device. 2043 2076 2044 2077 menu "Multimedia Capabilities Port drivers" 2045 2078 depends on ARCH_SA1100
+1 -1
drivers/mfd/Makefile
··· 127 127 obj-$(CONFIG_MCP) += mcp-core.o 128 128 obj-$(CONFIG_MCP_SA11X0) += mcp-sa11x0.o 129 129 obj-$(CONFIG_MCP_UCB1200) += ucb1x00-core.o 130 - obj-$(CONFIG_MFD_SMSC) += smsc-ece1099.o 131 130 obj-$(CONFIG_MCP_UCB1200_TS) += ucb1x00-ts.o 132 131 133 132 ifeq ($(CONFIG_SA1100_ASSABET),y) ··· 261 262 obj-$(CONFIG_MFD_ROHM_BD71828) += rohm-bd71828.o 262 263 obj-$(CONFIG_MFD_ROHM_BD718XX) += rohm-bd718x7.o 263 264 obj-$(CONFIG_MFD_STMFX) += stmfx.o 265 + obj-$(CONFIG_MFD_KHADAS_MCU) += khadas-mcu.o 264 266 265 267 obj-$(CONFIG_SGI_MFD_IOC3) += ioc3.o
+1 -1
drivers/mfd/ab3100-core.c
··· 498 498 int i = 0; 499 499 500 500 /* Get userspace string and assure termination */ 501 - buf_size = min(count, (sizeof(buf)-1)); 501 + buf_size = min((ssize_t)count, (ssize_t)(sizeof(buf)-1)); 502 502 if (copy_from_user(buf, user_buf, buf_size)) 503 503 return -EFAULT; 504 504 buf[buf_size] = 0;
+10 -10
drivers/mfd/ab3100-otp.c
··· 29 29 30 30 /** 31 31 * struct ab3100_otp 32 - * @dev containing device 33 - * @locked whether the OTP is locked, after locking, no more bits 32 + * @dev: containing device 33 + * @locked: whether the OTP is locked, after locking, no more bits 34 34 * can be changed but before locking it is still possible 35 35 * to change bits from 1->0. 36 - * @freq clocking frequency for the OTP, this frequency is either 36 + * @freq: clocking frequency for the OTP, this frequency is either 37 37 * 32768Hz or 1MHz/30 38 - * @paf product activation flag, indicates whether this is a real 38 + * @paf: product activation flag, indicates whether this is a real 39 39 * product (paf true) or a lab board etc (paf false) 40 - * @imeich if this is set it is possible to override the 40 + * @imeich: if this is set it is possible to override the 41 41 * IMEI number found in the tac, fac and svn fields with 42 42 * (secured) software 43 - * @cid customer ID 44 - * @tac type allocation code of the IMEI 45 - * @fac final assembly code of the IMEI 46 - * @svn software version number of the IMEI 47 - * @debugfs a debugfs file used when dumping to file 43 + * @cid: customer ID 44 + * @tac: type allocation code of the IMEI 45 + * @fac: final assembly code of the IMEI 46 + * @svn: software version number of the IMEI 47 + * @debugfs: a debugfs file used when dumping to file 48 48 */ 49 49 struct ab3100_otp { 50 50 struct device *dev;
+1 -1
drivers/mfd/ab8500-debugfs.c
··· 1801 1801 int buf_size, ret; 1802 1802 1803 1803 /* Get userspace string and assure termination */ 1804 - buf_size = min(count, (sizeof(buf)-1)); 1804 + buf_size = min((int)count, (int)(sizeof(buf)-1)); 1805 1805 if (copy_from_user(buf, user_buf, buf_size)) 1806 1806 return -EFAULT; 1807 1807 buf[buf_size] = 0;
+9 -10
drivers/mfd/altera-sysmgr.c
··· 22 22 /** 23 23 * struct altr_sysmgr - Altera SOCFPGA System Manager 24 24 * @regmap: the regmap used for System Manager accesses. 25 - * @base : the base address for the System Manager 26 25 */ 27 26 struct altr_sysmgr { 28 27 struct regmap *regmap; 29 - resource_size_t *base; 30 28 }; 31 29 32 30 static struct platform_driver altr_sysmgr_driver; ··· 89 91 * altr_sysmgr_regmap_lookup_by_phandle 90 92 * Find the sysmgr previous configured in probe() and return regmap property. 91 93 * Return: regmap if found or error if not found. 94 + * 95 + * @np: Pointer to device's Device Tree node 96 + * @property: Device Tree property name which references the sysmgr 92 97 */ 93 98 struct regmap *altr_sysmgr_regmap_lookup_by_phandle(struct device_node *np, 94 99 const char *property) ··· 128 127 struct regmap_config sysmgr_config = altr_sysmgr_regmap_cfg; 129 128 struct device *dev = &pdev->dev; 130 129 struct device_node *np = dev->of_node; 130 + void __iomem *base; 131 131 132 132 sysmgr = devm_kzalloc(dev, sizeof(*sysmgr), GFP_KERNEL); 133 133 if (!sysmgr) ··· 141 139 sysmgr_config.max_register = resource_size(res) - 142 140 sysmgr_config.reg_stride; 143 141 if (of_device_is_compatible(np, "altr,sys-mgr-s10")) { 144 - /* Need physical address for SMCC call */ 145 - sysmgr->base = (resource_size_t *)res->start; 146 142 sysmgr_config.reg_read = s10_protected_reg_read; 147 143 sysmgr_config.reg_write = s10_protected_reg_write; 148 144 149 - regmap = devm_regmap_init(dev, NULL, sysmgr->base, 145 + /* Need physical address for SMCC call */ 146 + regmap = devm_regmap_init(dev, NULL, (void *)res->start, 150 147 &sysmgr_config); 151 148 } else { 152 - sysmgr->base = devm_ioremap(dev, res->start, 153 - resource_size(res)); 154 - if (!sysmgr->base) 149 + base = devm_ioremap(dev, res->start, resource_size(res)); 150 + if (!base) 155 151 return -ENOMEM; 156 152 157 153 sysmgr_config.max_register = res->end - res->start - 3; 158 - regmap = devm_regmap_init_mmio(dev, sysmgr->base, 159 - &sysmgr_config); 154 + regmap = devm_regmap_init_mmio(dev, base, &sysmgr_config); 160 155 } 161 156 162 157 if (IS_ERR(regmap)) {
+19 -1
drivers/mfd/arizona-core.c
··· 80 80 { 81 81 mutex_lock(&arizona->clk_lock); 82 82 83 - BUG_ON(arizona->clk32k_ref <= 0); 83 + WARN_ON(arizona->clk32k_ref <= 0); 84 84 85 85 arizona->clk32k_ref--; 86 86 ··· 1426 1426 arizona_irq_exit(arizona); 1427 1427 err_pm: 1428 1428 pm_runtime_disable(arizona->dev); 1429 + 1430 + switch (arizona->pdata.clk32k_src) { 1431 + case ARIZONA_32KZ_MCLK1: 1432 + case ARIZONA_32KZ_MCLK2: 1433 + arizona_clk32k_disable(arizona); 1434 + break; 1435 + default: 1436 + break; 1437 + } 1429 1438 err_reset: 1430 1439 arizona_enable_reset(arizona); 1431 1440 regulator_disable(arizona->dcvdd); ··· 1456 1447 1457 1448 regulator_disable(arizona->dcvdd); 1458 1449 regulator_put(arizona->dcvdd); 1450 + 1451 + switch (arizona->pdata.clk32k_src) { 1452 + case ARIZONA_32KZ_MCLK1: 1453 + case ARIZONA_32KZ_MCLK2: 1454 + arizona_clk32k_disable(arizona); 1455 + break; 1456 + default: 1457 + break; 1458 + } 1459 1459 1460 1460 mfd_remove_devices(arizona->dev); 1461 1461 arizona_free_irq(arizona, ARIZONA_IRQ_UNDERCLOCKED, arizona);
+2 -2
drivers/mfd/atmel-smc.c
··· 237 237 * atmel_smc_cs_conf_apply - apply an SMC CS conf 238 238 * @regmap: the SMC regmap 239 239 * @cs: the CS id 240 - * @conf the SMC CS conf to apply 240 + * @conf: the SMC CS conf to apply 241 241 * 242 242 * Applies an SMC CS configuration. 243 243 * Only valid on at91sam9/avr32 SoCs. ··· 257 257 * @regmap: the HSMC regmap 258 258 * @cs: the CS id 259 259 * @layout: the layout of registers 260 - * @conf the SMC CS conf to apply 260 + * @conf: the SMC CS conf to apply 261 261 * 262 262 * Applies an SMC CS configuration. 263 263 * Only valid on post-sama5 SoCs.
+4
drivers/mfd/axp20x-i2c.c
··· 63 63 { .compatible = "x-powers,axp209", .data = (void *)AXP209_ID }, 64 64 { .compatible = "x-powers,axp221", .data = (void *)AXP221_ID }, 65 65 { .compatible = "x-powers,axp223", .data = (void *)AXP223_ID }, 66 + { .compatible = "x-powers,axp803", .data = (void *)AXP803_ID }, 66 67 { .compatible = "x-powers,axp806", .data = (void *)AXP806_ID }, 67 68 { }, 68 69 }; ··· 75 74 { "axp209", 0 }, 76 75 { "axp221", 0 }, 77 76 { "axp223", 0 }, 77 + { "axp803", 0 }, 78 78 { "axp806", 0 }, 79 79 { }, 80 80 }; 81 81 MODULE_DEVICE_TABLE(i2c, axp20x_i2c_id); 82 82 83 + #ifdef CONFIG_ACPI 83 84 static const struct acpi_device_id axp20x_i2c_acpi_match[] = { 84 85 { 85 86 .id = "INT33F4", ··· 90 87 { }, 91 88 }; 92 89 MODULE_DEVICE_TABLE(acpi, axp20x_i2c_acpi_match); 90 + #endif 93 91 94 92 static struct i2c_driver axp20x_i2c_driver = { 95 93 .driver = {
+2 -2
drivers/mfd/cros_ec_dev.c
··· 24 24 }; 25 25 26 26 /** 27 - * cros_feature_to_name - CrOS feature id to name/short description. 27 + * struct cros_feature_to_name - CrOS feature id to name/short description. 28 28 * @id: The feature identifier. 29 29 * @name: Device name associated with the feature id. 30 30 * @desc: Short name that will be displayed. ··· 36 36 }; 37 37 38 38 /** 39 - * cros_feature_to_cells - CrOS feature id to mfd cells association. 39 + * struct cros_feature_to_cells - CrOS feature id to mfd cells association. 40 40 * @id: The feature identifier. 41 41 * @mfd_cells: Pointer to the array of mfd cells that needs to be added. 42 42 * @num_cells: Number of mfd cells into the array.
-31
drivers/mfd/da9063-core.c
··· 160 160 161 161 int da9063_device_init(struct da9063 *da9063, unsigned int irq) 162 162 { 163 - int model, variant_id, variant_code; 164 163 int ret; 165 164 166 165 ret = da9063_clear_fault_log(da9063); ··· 169 170 da9063->flags = 0; 170 171 da9063->irq_base = -1; 171 172 da9063->chip_irq = irq; 172 - 173 - ret = regmap_read(da9063->regmap, DA9063_REG_CHIP_ID, &model); 174 - if (ret < 0) { 175 - dev_err(da9063->dev, "Cannot read chip model id.\n"); 176 - return -EIO; 177 - } 178 - if (model != PMIC_CHIP_ID_DA9063) { 179 - dev_err(da9063->dev, "Invalid chip model id: 0x%02x\n", model); 180 - return -ENODEV; 181 - } 182 - 183 - ret = regmap_read(da9063->regmap, DA9063_REG_CHIP_VARIANT, &variant_id); 184 - if (ret < 0) { 185 - dev_err(da9063->dev, "Cannot read chip variant id.\n"); 186 - return -EIO; 187 - } 188 - 189 - variant_code = variant_id >> DA9063_CHIP_VARIANT_SHIFT; 190 - 191 - dev_info(da9063->dev, 192 - "Device detected (chip-ID: 0x%02X, var-ID: 0x%02X)\n", 193 - model, variant_id); 194 - 195 - if (variant_code < PMIC_DA9063_BB && variant_code != PMIC_DA9063_AD) { 196 - dev_err(da9063->dev, 197 - "Cannot support variant code: 0x%02X\n", variant_code); 198 - return -ENODEV; 199 - } 200 - 201 - da9063->variant_code = variant_code; 202 173 203 174 ret = da9063_irq_init(da9063); 204 175 if (ret) {
+246 -25
drivers/mfd/da9063-i2c.c
··· 22 22 #include <linux/of.h> 23 23 #include <linux/regulator/of_regulator.h> 24 24 25 + /* 26 + * Raw I2C access required for just accessing chip and variant info before we 27 + * know which device is present. The info read from the device using this 28 + * approach is then used to select the correct regmap tables. 29 + */ 30 + 31 + #define DA9063_REG_PAGE_SIZE 0x100 32 + #define DA9063_REG_PAGED_ADDR_MASK 0xFF 33 + 34 + enum da9063_page_sel_buf_fmt { 35 + DA9063_PAGE_SEL_BUF_PAGE_REG = 0, 36 + DA9063_PAGE_SEL_BUF_PAGE_VAL, 37 + DA9063_PAGE_SEL_BUF_SIZE, 38 + }; 39 + 40 + enum da9063_paged_read_msgs { 41 + DA9063_PAGED_READ_MSG_PAGE_SEL = 0, 42 + DA9063_PAGED_READ_MSG_REG_SEL, 43 + DA9063_PAGED_READ_MSG_DATA, 44 + DA9063_PAGED_READ_MSG_CNT, 45 + }; 46 + 47 + static int da9063_i2c_blockreg_read(struct i2c_client *client, u16 addr, 48 + u8 *buf, int count) 49 + { 50 + struct i2c_msg xfer[DA9063_PAGED_READ_MSG_CNT]; 51 + u8 page_sel_buf[DA9063_PAGE_SEL_BUF_SIZE]; 52 + u8 page_num, paged_addr; 53 + int ret; 54 + 55 + /* Determine page info based on register address */ 56 + page_num = (addr / DA9063_REG_PAGE_SIZE); 57 + if (page_num > 1) { 58 + dev_err(&client->dev, "Invalid register address provided\n"); 59 + return -EINVAL; 60 + } 61 + 62 + paged_addr = (addr % DA9063_REG_PAGE_SIZE) & DA9063_REG_PAGED_ADDR_MASK; 63 + page_sel_buf[DA9063_PAGE_SEL_BUF_PAGE_REG] = DA9063_REG_PAGE_CON; 64 + page_sel_buf[DA9063_PAGE_SEL_BUF_PAGE_VAL] = 65 + (page_num << DA9063_I2C_PAGE_SEL_SHIFT) & DA9063_REG_PAGE_MASK; 66 + 67 + /* Write reg address, page selection */ 68 + xfer[DA9063_PAGED_READ_MSG_PAGE_SEL].addr = client->addr; 69 + xfer[DA9063_PAGED_READ_MSG_PAGE_SEL].flags = 0; 70 + xfer[DA9063_PAGED_READ_MSG_PAGE_SEL].len = DA9063_PAGE_SEL_BUF_SIZE; 71 + xfer[DA9063_PAGED_READ_MSG_PAGE_SEL].buf = page_sel_buf; 72 + 73 + /* Select register address */ 74 + xfer[DA9063_PAGED_READ_MSG_REG_SEL].addr = client->addr; 75 + xfer[DA9063_PAGED_READ_MSG_REG_SEL].flags = 0; 76 + xfer[DA9063_PAGED_READ_MSG_REG_SEL].len = sizeof(paged_addr); 77 + xfer[DA9063_PAGED_READ_MSG_REG_SEL].buf = &paged_addr; 78 + 79 + /* Read data */ 80 + xfer[DA9063_PAGED_READ_MSG_DATA].addr = client->addr; 81 + xfer[DA9063_PAGED_READ_MSG_DATA].flags = I2C_M_RD; 82 + xfer[DA9063_PAGED_READ_MSG_DATA].len = count; 83 + xfer[DA9063_PAGED_READ_MSG_DATA].buf = buf; 84 + 85 + ret = i2c_transfer(client->adapter, xfer, DA9063_PAGED_READ_MSG_CNT); 86 + if (ret < 0) { 87 + dev_err(&client->dev, "Paged block read failed: %d\n", ret); 88 + return ret; 89 + } 90 + 91 + if (ret != DA9063_PAGED_READ_MSG_CNT) { 92 + dev_err(&client->dev, "Paged block read failed to complete\n"); 93 + return -EIO; 94 + } 95 + 96 + return 0; 97 + } 98 + 99 + enum { 100 + DA9063_DEV_ID_REG = 0, 101 + DA9063_VAR_ID_REG, 102 + DA9063_CHIP_ID_REGS, 103 + }; 104 + 105 + static int da9063_get_device_type(struct i2c_client *i2c, struct da9063 *da9063) 106 + { 107 + u8 buf[DA9063_CHIP_ID_REGS]; 108 + int ret; 109 + 110 + ret = da9063_i2c_blockreg_read(i2c, DA9063_REG_DEVICE_ID, buf, 111 + DA9063_CHIP_ID_REGS); 112 + if (ret) 113 + return ret; 114 + 115 + if (buf[DA9063_DEV_ID_REG] != PMIC_CHIP_ID_DA9063) { 116 + dev_err(da9063->dev, 117 + "Invalid chip device ID: 0x%02x\n", 118 + buf[DA9063_DEV_ID_REG]); 119 + return -ENODEV; 120 + } 121 + 122 + dev_info(da9063->dev, 123 + "Device detected (chip-ID: 0x%02X, var-ID: 0x%02X)\n", 124 + buf[DA9063_DEV_ID_REG], buf[DA9063_VAR_ID_REG]); 125 + 126 + da9063->variant_code = 127 + (buf[DA9063_VAR_ID_REG] & DA9063_VARIANT_ID_MRC_MASK) 128 + >> DA9063_VARIANT_ID_MRC_SHIFT; 129 + 130 + return 0; 131 + } 132 + 133 + /* 134 + * Variant specific regmap configs 135 + */ 136 + 25 137 static const struct regmap_range da9063_ad_readable_ranges[] = { 26 138 regmap_reg_range(DA9063_REG_PAGE_CON, DA9063_AD_REG_SECOND_D), 27 139 regmap_reg_range(DA9063_REG_SEQ, DA9063_REG_ID_32_31), 28 140 regmap_reg_range(DA9063_REG_SEQ_A, DA9063_REG_AUTO3_LOW), 29 141 regmap_reg_range(DA9063_REG_T_OFFSET, DA9063_AD_REG_GP_ID_19), 30 - regmap_reg_range(DA9063_REG_CHIP_ID, DA9063_REG_CHIP_VARIANT), 142 + regmap_reg_range(DA9063_REG_DEVICE_ID, DA9063_REG_VARIANT_ID), 31 143 }; 32 144 33 145 static const struct regmap_range da9063_ad_writeable_ranges[] = { ··· 184 72 regmap_reg_range(DA9063_REG_SEQ, DA9063_REG_ID_32_31), 185 73 regmap_reg_range(DA9063_REG_SEQ_A, DA9063_REG_AUTO3_LOW), 186 74 regmap_reg_range(DA9063_REG_T_OFFSET, DA9063_BB_REG_GP_ID_19), 187 - regmap_reg_range(DA9063_REG_CHIP_ID, DA9063_REG_CHIP_VARIANT), 75 + regmap_reg_range(DA9063_REG_DEVICE_ID, DA9063_REG_VARIANT_ID), 188 76 }; 189 77 190 78 static const struct regmap_range da9063_bb_writeable_ranges[] = { ··· 197 85 regmap_reg_range(DA9063_BB_REG_GP_ID_0, DA9063_BB_REG_GP_ID_19), 198 86 }; 199 87 200 - static const struct regmap_range da9063_bb_volatile_ranges[] = { 88 + static const struct regmap_range da9063_bb_da_volatile_ranges[] = { 201 89 regmap_reg_range(DA9063_REG_PAGE_CON, DA9063_REG_EVENT_D), 202 90 regmap_reg_range(DA9063_REG_CONTROL_A, DA9063_REG_CONTROL_B), 203 91 regmap_reg_range(DA9063_REG_CONTROL_E, DA9063_REG_CONTROL_F), ··· 219 107 .n_yes_ranges = ARRAY_SIZE(da9063_bb_writeable_ranges), 220 108 }; 221 109 222 - static const struct regmap_access_table da9063_bb_volatile_table = { 223 - .yes_ranges = da9063_bb_volatile_ranges, 224 - .n_yes_ranges = ARRAY_SIZE(da9063_bb_volatile_ranges), 110 + static const struct regmap_access_table da9063_bb_da_volatile_table = { 111 + .yes_ranges = da9063_bb_da_volatile_ranges, 112 + .n_yes_ranges = ARRAY_SIZE(da9063_bb_da_volatile_ranges), 225 113 }; 226 114 227 115 static const struct regmap_range da9063l_bb_readable_ranges[] = { ··· 229 117 regmap_reg_range(DA9063_REG_SEQ, DA9063_REG_ID_32_31), 230 118 regmap_reg_range(DA9063_REG_SEQ_A, DA9063_REG_AUTO3_LOW), 231 119 regmap_reg_range(DA9063_REG_T_OFFSET, DA9063_BB_REG_GP_ID_19), 232 - regmap_reg_range(DA9063_REG_CHIP_ID, DA9063_REG_CHIP_VARIANT), 120 + regmap_reg_range(DA9063_REG_DEVICE_ID, DA9063_REG_VARIANT_ID), 233 121 }; 234 122 235 123 static const struct regmap_range da9063l_bb_writeable_ranges[] = { ··· 241 129 regmap_reg_range(DA9063_BB_REG_GP_ID_0, DA9063_BB_REG_GP_ID_19), 242 130 }; 243 131 244 - static const struct regmap_range da9063l_bb_volatile_ranges[] = { 132 + static const struct regmap_range da9063l_bb_da_volatile_ranges[] = { 245 133 regmap_reg_range(DA9063_REG_PAGE_CON, DA9063_REG_EVENT_D), 246 134 regmap_reg_range(DA9063_REG_CONTROL_A, DA9063_REG_CONTROL_B), 247 135 regmap_reg_range(DA9063_REG_CONTROL_E, DA9063_REG_CONTROL_F), ··· 263 151 .n_yes_ranges = ARRAY_SIZE(da9063l_bb_writeable_ranges), 264 152 }; 265 153 266 - static const struct regmap_access_table da9063l_bb_volatile_table = { 267 - .yes_ranges = da9063l_bb_volatile_ranges, 268 - .n_yes_ranges = ARRAY_SIZE(da9063l_bb_volatile_ranges), 154 + static const struct regmap_access_table da9063l_bb_da_volatile_table = { 155 + .yes_ranges = da9063l_bb_da_volatile_ranges, 156 + .n_yes_ranges = ARRAY_SIZE(da9063l_bb_da_volatile_ranges), 157 + }; 158 + 159 + static const struct regmap_range da9063_da_readable_ranges[] = { 160 + regmap_reg_range(DA9063_REG_PAGE_CON, DA9063_BB_REG_SECOND_D), 161 + regmap_reg_range(DA9063_REG_SEQ, DA9063_REG_ID_32_31), 162 + regmap_reg_range(DA9063_REG_SEQ_A, DA9063_REG_AUTO3_LOW), 163 + regmap_reg_range(DA9063_REG_T_OFFSET, DA9063_BB_REG_GP_ID_11), 164 + regmap_reg_range(DA9063_REG_DEVICE_ID, DA9063_REG_VARIANT_ID), 165 + }; 166 + 167 + static const struct regmap_range da9063_da_writeable_ranges[] = { 168 + regmap_reg_range(DA9063_REG_PAGE_CON, DA9063_REG_PAGE_CON), 169 + regmap_reg_range(DA9063_REG_FAULT_LOG, DA9063_REG_VSYS_MON), 170 + regmap_reg_range(DA9063_REG_COUNT_S, DA9063_BB_REG_ALARM_Y), 171 + regmap_reg_range(DA9063_REG_SEQ, DA9063_REG_ID_32_31), 172 + regmap_reg_range(DA9063_REG_SEQ_A, DA9063_REG_AUTO3_LOW), 173 + regmap_reg_range(DA9063_REG_CONFIG_I, DA9063_BB_REG_MON_REG_4), 174 + regmap_reg_range(DA9063_BB_REG_GP_ID_0, DA9063_BB_REG_GP_ID_11), 175 + }; 176 + 177 + static const struct regmap_access_table da9063_da_readable_table = { 178 + .yes_ranges = da9063_da_readable_ranges, 179 + .n_yes_ranges = ARRAY_SIZE(da9063_da_readable_ranges), 180 + }; 181 + 182 + static const struct regmap_access_table da9063_da_writeable_table = { 183 + .yes_ranges = da9063_da_writeable_ranges, 184 + .n_yes_ranges = ARRAY_SIZE(da9063_da_writeable_ranges), 185 + }; 186 + 187 + static const struct regmap_range da9063l_da_readable_ranges[] = { 188 + regmap_reg_range(DA9063_REG_PAGE_CON, DA9063_REG_MON_A10_RES), 189 + regmap_reg_range(DA9063_REG_SEQ, DA9063_REG_ID_32_31), 190 + regmap_reg_range(DA9063_REG_SEQ_A, DA9063_REG_AUTO3_LOW), 191 + regmap_reg_range(DA9063_REG_T_OFFSET, DA9063_BB_REG_GP_ID_11), 192 + regmap_reg_range(DA9063_REG_DEVICE_ID, DA9063_REG_VARIANT_ID), 193 + }; 194 + 195 + static const struct regmap_range da9063l_da_writeable_ranges[] = { 196 + regmap_reg_range(DA9063_REG_PAGE_CON, DA9063_REG_PAGE_CON), 197 + regmap_reg_range(DA9063_REG_FAULT_LOG, DA9063_REG_VSYS_MON), 198 + regmap_reg_range(DA9063_REG_SEQ, DA9063_REG_ID_32_31), 199 + regmap_reg_range(DA9063_REG_SEQ_A, DA9063_REG_AUTO3_LOW), 200 + regmap_reg_range(DA9063_REG_CONFIG_I, DA9063_BB_REG_MON_REG_4), 201 + regmap_reg_range(DA9063_BB_REG_GP_ID_0, DA9063_BB_REG_GP_ID_11), 202 + }; 203 + 204 + static const struct regmap_access_table da9063l_da_readable_table = { 205 + .yes_ranges = da9063l_da_readable_ranges, 206 + .n_yes_ranges = ARRAY_SIZE(da9063l_da_readable_ranges), 207 + }; 208 + 209 + static const struct regmap_access_table da9063l_da_writeable_table = { 210 + .yes_ranges = da9063l_da_writeable_ranges, 211 + .n_yes_ranges = ARRAY_SIZE(da9063l_da_writeable_ranges), 269 212 }; 270 213 271 214 static const struct regmap_range_cfg da9063_range_cfg[] = { 272 215 { 273 216 .range_min = DA9063_REG_PAGE_CON, 274 - .range_max = DA9063_REG_CHIP_VARIANT, 217 + .range_max = DA9063_REG_CONFIG_ID, 275 218 .selector_reg = DA9063_REG_PAGE_CON, 276 219 .selector_mask = 1 << DA9063_I2C_PAGE_SEL_SHIFT, 277 220 .selector_shift = DA9063_I2C_PAGE_SEL_SHIFT, ··· 340 173 .val_bits = 8, 341 174 .ranges = da9063_range_cfg, 342 175 .num_ranges = ARRAY_SIZE(da9063_range_cfg), 343 - .max_register = DA9063_REG_CHIP_VARIANT, 176 + .max_register = DA9063_REG_CONFIG_ID, 344 177 345 178 .cache_type = REGCACHE_RBTREE, 346 179 }; ··· 366 199 da9063->chip_irq = i2c->irq; 367 200 da9063->type = id->driver_data; 368 201 369 - if (da9063->variant_code == PMIC_DA9063_AD) { 370 - da9063_regmap_config.rd_table = &da9063_ad_readable_table; 371 - da9063_regmap_config.wr_table = &da9063_ad_writeable_table; 372 - da9063_regmap_config.volatile_table = &da9063_ad_volatile_table; 373 - } else if (da9063->type == PMIC_TYPE_DA9063L) { 374 - da9063_regmap_config.rd_table = &da9063l_bb_readable_table; 375 - da9063_regmap_config.wr_table = &da9063l_bb_writeable_table; 376 - da9063_regmap_config.volatile_table = &da9063l_bb_volatile_table; 377 - } else { 378 - da9063_regmap_config.rd_table = &da9063_bb_readable_table; 379 - da9063_regmap_config.wr_table = &da9063_bb_writeable_table; 380 - da9063_regmap_config.volatile_table = &da9063_bb_volatile_table; 202 + ret = da9063_get_device_type(i2c, da9063); 203 + if (ret) 204 + return ret; 205 + 206 + switch (da9063->type) { 207 + case PMIC_TYPE_DA9063: 208 + switch (da9063->variant_code) { 209 + case PMIC_DA9063_AD: 210 + da9063_regmap_config.rd_table = 211 + &da9063_ad_readable_table; 212 + da9063_regmap_config.wr_table = 213 + &da9063_ad_writeable_table; 214 + da9063_regmap_config.volatile_table = 215 + &da9063_ad_volatile_table; 216 + break; 217 + case PMIC_DA9063_BB: 218 + case PMIC_DA9063_CA: 219 + da9063_regmap_config.rd_table = 220 + &da9063_bb_readable_table; 221 + da9063_regmap_config.wr_table = 222 + &da9063_bb_writeable_table; 223 + da9063_regmap_config.volatile_table = 224 + &da9063_bb_da_volatile_table; 225 + break; 226 + case PMIC_DA9063_DA: 227 + da9063_regmap_config.rd_table = 228 + &da9063_da_readable_table; 229 + da9063_regmap_config.wr_table = 230 + &da9063_da_writeable_table; 231 + da9063_regmap_config.volatile_table = 232 + &da9063_bb_da_volatile_table; 233 + break; 234 + default: 235 + dev_err(da9063->dev, 236 + "Chip variant not supported for DA9063\n"); 237 + return -ENODEV; 238 + } 239 + break; 240 + case PMIC_TYPE_DA9063L: 241 + switch (da9063->variant_code) { 242 + case PMIC_DA9063_BB: 243 + case PMIC_DA9063_CA: 244 + da9063_regmap_config.rd_table = 245 + &da9063l_bb_readable_table; 246 + da9063_regmap_config.wr_table = 247 + &da9063l_bb_writeable_table; 248 + da9063_regmap_config.volatile_table = 249 + &da9063l_bb_da_volatile_table; 250 + break; 251 + case PMIC_DA9063_DA: 252 + da9063_regmap_config.rd_table = 253 + &da9063l_da_readable_table; 254 + da9063_regmap_config.wr_table = 255 + &da9063l_da_writeable_table; 256 + da9063_regmap_config.volatile_table = 257 + &da9063l_bb_da_volatile_table; 258 + break; 259 + default: 260 + dev_err(da9063->dev, 261 + "Chip variant not supported for DA9063L\n"); 262 + return -ENODEV; 263 + } 264 + break; 265 + default: 266 + dev_err(da9063->dev, "Chip type not supported\n"); 267 + return -ENODEV; 381 268 } 382 269 383 270 da9063->regmap = devm_regmap_init_i2c(i2c, &da9063_regmap_config);
+2 -4
drivers/mfd/db8500-prcmu.c
··· 2276 2276 * 2277 2277 * Saves the reset reason code and then sets the APE_SOFTRST register which 2278 2278 * fires interrupt to fw 2279 + * 2280 + * @reset_code: The reason for system reset 2279 2281 */ 2280 2282 void db8500_prcmu_system_reset(u16 reset_code) 2281 2283 { ··· 3006 3004 return mfd_add_devices(parent, 0, ab850x_cell, 1, NULL, 0, NULL); 3007 3005 } 3008 3006 3009 - /** 3010 - * prcmu_fw_init - arch init call for the Linux PRCMU fw init logic 3011 - * 3012 - */ 3013 3007 static int db8500_prcmu_probe(struct platform_device *pdev) 3014 3008 { 3015 3009 struct device_node *np = pdev->dev.of_node;
+4
drivers/mfd/dln2.c
··· 287 287 len = urb->actual_length - sizeof(struct dln2_header); 288 288 289 289 if (handle == DLN2_HANDLE_EVENT) { 290 + unsigned long flags; 291 + 292 + spin_lock_irqsave(&dln2->event_cb_lock, flags); 290 293 dln2_run_event_callbacks(dln2, id, echo, data, len); 294 + spin_unlock_irqrestore(&dln2->event_cb_lock, flags); 291 295 } else { 292 296 /* URB will be re-submitted in _dln2_transfer (free_rx_slot) */ 293 297 if (dln2_transfer_complete(dln2, urb, handle, echo))
+1 -1
drivers/mfd/hi6421-pmic-core.c
··· 5 5 * Copyright (c) <2011-2014> HiSilicon Technologies Co., Ltd. 6 6 * http://www.hisilicon.com 7 7 * Copyright (c) <2013-2017> Linaro Ltd. 8 - * http://www.linaro.org 8 + * https://www.linaro.org 9 9 * 10 10 * Author: Guodong Xu <guodong.xu@linaro.org> 11 11 */
+19
drivers/mfd/intel-lpss-pci.c
··· 201 201 { PCI_VDEVICE(INTEL, 0x1ac4), (kernel_ulong_t)&bxt_info }, 202 202 { PCI_VDEVICE(INTEL, 0x1ac6), (kernel_ulong_t)&bxt_info }, 203 203 { PCI_VDEVICE(INTEL, 0x1aee), (kernel_ulong_t)&bxt_uart_info }, 204 + /* EBG */ 205 + { PCI_VDEVICE(INTEL, 0x1bad), (kernel_ulong_t)&bxt_uart_info }, 206 + { PCI_VDEVICE(INTEL, 0x1bae), (kernel_ulong_t)&bxt_uart_info }, 204 207 /* GLK */ 205 208 { PCI_VDEVICE(INTEL, 0x31ac), (kernel_ulong_t)&glk_i2c_info }, 206 209 { PCI_VDEVICE(INTEL, 0x31ae), (kernel_ulong_t)&glk_i2c_info }, ··· 233 230 { PCI_VDEVICE(INTEL, 0x34ea), (kernel_ulong_t)&bxt_i2c_info }, 234 231 { PCI_VDEVICE(INTEL, 0x34eb), (kernel_ulong_t)&bxt_i2c_info }, 235 232 { PCI_VDEVICE(INTEL, 0x34fb), (kernel_ulong_t)&spt_info }, 233 + /* TGL-H */ 234 + { PCI_VDEVICE(INTEL, 0x43a7), (kernel_ulong_t)&bxt_uart_info }, 235 + { PCI_VDEVICE(INTEL, 0x43a8), (kernel_ulong_t)&bxt_uart_info }, 236 + { PCI_VDEVICE(INTEL, 0x43a9), (kernel_ulong_t)&bxt_uart_info }, 237 + { PCI_VDEVICE(INTEL, 0x43aa), (kernel_ulong_t)&bxt_info }, 238 + { PCI_VDEVICE(INTEL, 0x43ab), (kernel_ulong_t)&bxt_info }, 239 + { PCI_VDEVICE(INTEL, 0x43ad), (kernel_ulong_t)&bxt_i2c_info }, 240 + { PCI_VDEVICE(INTEL, 0x43ae), (kernel_ulong_t)&bxt_i2c_info }, 241 + { PCI_VDEVICE(INTEL, 0x43d8), (kernel_ulong_t)&bxt_i2c_info }, 242 + { PCI_VDEVICE(INTEL, 0x43da), (kernel_ulong_t)&bxt_uart_info }, 243 + { PCI_VDEVICE(INTEL, 0x43e8), (kernel_ulong_t)&bxt_i2c_info }, 244 + { PCI_VDEVICE(INTEL, 0x43e9), (kernel_ulong_t)&bxt_i2c_info }, 245 + { PCI_VDEVICE(INTEL, 0x43ea), (kernel_ulong_t)&bxt_i2c_info }, 246 + { PCI_VDEVICE(INTEL, 0x43eb), (kernel_ulong_t)&bxt_i2c_info }, 247 + { PCI_VDEVICE(INTEL, 0x43fb), (kernel_ulong_t)&bxt_info }, 248 + { PCI_VDEVICE(INTEL, 0x43fd), (kernel_ulong_t)&bxt_info }, 236 249 /* EHL */ 237 250 { PCI_VDEVICE(INTEL, 0x4b28), (kernel_ulong_t)&bxt_uart_info }, 238 251 { PCI_VDEVICE(INTEL, 0x4b29), (kernel_ulong_t)&bxt_uart_info },
+1 -6
drivers/mfd/intel_soc_pmic_mrfld.c
··· 91 91 { 92 92 struct intel_soc_pmic *pmic = context; 93 93 u8 ipc_in = val; 94 - int ret; 95 94 96 - ret = intel_scu_ipc_dev_iowrite8(pmic->scu, reg, ipc_in); 97 - if (ret) 98 - return ret; 99 - 100 - return 0; 95 + return intel_scu_ipc_dev_iowrite8(pmic->scu, reg, ipc_in); 101 96 } 102 97 103 98 static const struct regmap_config bcove_regmap_config = {
+11 -19
drivers/mfd/kempld-core.c
··· 79 79 KEMPLD_UART, 80 80 }; 81 81 82 - static const struct mfd_cell kempld_devs[] = { 83 - [KEMPLD_I2C] = { 84 - .name = "kempld-i2c", 85 - }, 86 - [KEMPLD_WDT] = { 87 - .name = "kempld-wdt", 88 - }, 89 - [KEMPLD_GPIO] = { 90 - .name = "kempld-gpio", 91 - }, 92 - [KEMPLD_UART] = { 93 - .name = "kempld-uart", 94 - }, 82 + static const char *kempld_dev_names[] = { 83 + [KEMPLD_I2C] = "kempld-i2c", 84 + [KEMPLD_WDT] = "kempld-wdt", 85 + [KEMPLD_GPIO] = "kempld-gpio", 86 + [KEMPLD_UART] = "kempld-uart", 95 87 }; 96 88 97 - #define KEMPLD_MAX_DEVS ARRAY_SIZE(kempld_devs) 89 + #define KEMPLD_MAX_DEVS ARRAY_SIZE(kempld_dev_names) 98 90 99 91 static int kempld_register_cells_generic(struct kempld_device_data *pld) 100 92 { 101 - struct mfd_cell devs[KEMPLD_MAX_DEVS]; 93 + struct mfd_cell devs[KEMPLD_MAX_DEVS] = {}; 102 94 int i = 0; 103 95 104 96 if (pld->feature_mask & KEMPLD_FEATURE_BIT_I2C) 105 - devs[i++] = kempld_devs[KEMPLD_I2C]; 97 + devs[i++].name = kempld_dev_names[KEMPLD_I2C]; 106 98 107 99 if (pld->feature_mask & KEMPLD_FEATURE_BIT_WATCHDOG) 108 - devs[i++] = kempld_devs[KEMPLD_WDT]; 100 + devs[i++].name = kempld_dev_names[KEMPLD_WDT]; 109 101 110 102 if (pld->feature_mask & KEMPLD_FEATURE_BIT_GPIO) 111 - devs[i++] = kempld_devs[KEMPLD_GPIO]; 103 + devs[i++].name = kempld_dev_names[KEMPLD_GPIO]; 112 104 113 105 if (pld->feature_mask & KEMPLD_FEATURE_MASK_UART) 114 - devs[i++] = kempld_devs[KEMPLD_UART]; 106 + devs[i++].name = kempld_dev_names[KEMPLD_UART]; 115 107 116 108 return mfd_add_devices(pld->dev, -1, devs, i, NULL, 0, NULL); 117 109 }
+142
drivers/mfd/khadas-mcu.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Driver for Khadas System control Microcontroller 4 + * 5 + * Copyright (C) 2020 BayLibre SAS 6 + * 7 + * Author(s): Neil Armstrong <narmstrong@baylibre.com> 8 + */ 9 + #include <linux/bitfield.h> 10 + #include <linux/i2c.h> 11 + #include <linux/mfd/core.h> 12 + #include <linux/mfd/khadas-mcu.h> 13 + #include <linux/module.h> 14 + #include <linux/regmap.h> 15 + 16 + static bool khadas_mcu_reg_volatile(struct device *dev, unsigned int reg) 17 + { 18 + if (reg >= KHADAS_MCU_USER_DATA_0_REG && 19 + reg < KHADAS_MCU_PWR_OFF_CMD_REG) 20 + return true; 21 + 22 + switch (reg) { 23 + case KHADAS_MCU_PWR_OFF_CMD_REG: 24 + case KHADAS_MCU_PASSWD_START_REG: 25 + case KHADAS_MCU_CHECK_VEN_PASSWD_REG: 26 + case KHADAS_MCU_CHECK_USER_PASSWD_REG: 27 + case KHADAS_MCU_WOL_INIT_START_REG: 28 + case KHADAS_MCU_CMD_FAN_STATUS_CTRL_REG: 29 + return true; 30 + default: 31 + return false; 32 + } 33 + } 34 + 35 + static bool khadas_mcu_reg_writeable(struct device *dev, unsigned int reg) 36 + { 37 + switch (reg) { 38 + case KHADAS_MCU_PASSWD_VEN_0_REG: 39 + case KHADAS_MCU_PASSWD_VEN_1_REG: 40 + case KHADAS_MCU_PASSWD_VEN_2_REG: 41 + case KHADAS_MCU_PASSWD_VEN_3_REG: 42 + case KHADAS_MCU_PASSWD_VEN_4_REG: 43 + case KHADAS_MCU_PASSWD_VEN_5_REG: 44 + case KHADAS_MCU_MAC_0_REG: 45 + case KHADAS_MCU_MAC_1_REG: 46 + case KHADAS_MCU_MAC_2_REG: 47 + case KHADAS_MCU_MAC_3_REG: 48 + case KHADAS_MCU_MAC_4_REG: 49 + case KHADAS_MCU_MAC_5_REG: 50 + case KHADAS_MCU_USID_0_REG: 51 + case KHADAS_MCU_USID_1_REG: 52 + case KHADAS_MCU_USID_2_REG: 53 + case KHADAS_MCU_USID_3_REG: 54 + case KHADAS_MCU_USID_4_REG: 55 + case KHADAS_MCU_USID_5_REG: 56 + case KHADAS_MCU_VERSION_0_REG: 57 + case KHADAS_MCU_VERSION_1_REG: 58 + case KHADAS_MCU_DEVICE_NO_0_REG: 59 + case KHADAS_MCU_DEVICE_NO_1_REG: 60 + case KHADAS_MCU_FACTORY_TEST_REG: 61 + case KHADAS_MCU_SHUTDOWN_NORMAL_STATUS_REG: 62 + return false; 63 + default: 64 + return true; 65 + } 66 + } 67 + 68 + static const struct regmap_config khadas_mcu_regmap_config = { 69 + .reg_bits = 8, 70 + .reg_stride = 1, 71 + .val_bits = 8, 72 + .max_register = KHADAS_MCU_CMD_FAN_STATUS_CTRL_REG, 73 + .volatile_reg = khadas_mcu_reg_volatile, 74 + .writeable_reg = khadas_mcu_reg_writeable, 75 + .cache_type = REGCACHE_RBTREE, 76 + }; 77 + 78 + static struct mfd_cell khadas_mcu_fan_cells[] = { 79 + /* VIM1/2 Rev13+ and VIM3 only */ 80 + { .name = "khadas-mcu-fan-ctrl", }, 81 + }; 82 + 83 + static struct mfd_cell khadas_mcu_cells[] = { 84 + { .name = "khadas-mcu-user-mem", }, 85 + }; 86 + 87 + static int khadas_mcu_probe(struct i2c_client *client, 88 + const struct i2c_device_id *id) 89 + { 90 + struct device *dev = &client->dev; 91 + struct khadas_mcu *ddata; 92 + int ret; 93 + 94 + ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL); 95 + if (!ddata) 96 + return -ENOMEM; 97 + 98 + i2c_set_clientdata(client, ddata); 99 + 100 + ddata->dev = dev; 101 + 102 + ddata->regmap = devm_regmap_init_i2c(client, &khadas_mcu_regmap_config); 103 + if (IS_ERR(ddata->regmap)) { 104 + ret = PTR_ERR(ddata->regmap); 105 + dev_err(dev, "Failed to allocate register map: %d\n", ret); 106 + return ret; 107 + } 108 + 109 + ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE, 110 + khadas_mcu_cells, 111 + ARRAY_SIZE(khadas_mcu_cells), 112 + NULL, 0, NULL); 113 + if (ret) 114 + return ret; 115 + 116 + if (of_find_property(dev->of_node, "#cooling-cells", NULL)) 117 + return devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE, 118 + khadas_mcu_fan_cells, 119 + ARRAY_SIZE(khadas_mcu_fan_cells), 120 + NULL, 0, NULL); 121 + 122 + return 0; 123 + } 124 + 125 + static const struct of_device_id khadas_mcu_of_match[] = { 126 + { .compatible = "khadas,mcu", }, 127 + {}, 128 + }; 129 + MODULE_DEVICE_TABLE(of, khadas_mcu_of_match); 130 + 131 + static struct i2c_driver khadas_mcu_driver = { 132 + .driver = { 133 + .name = "khadas-mcu-core", 134 + .of_match_table = of_match_ptr(khadas_mcu_of_match), 135 + }, 136 + .probe = khadas_mcu_probe, 137 + }; 138 + module_i2c_driver(khadas_mcu_driver); 139 + 140 + MODULE_DESCRIPTION("Khadas MCU core driver"); 141 + MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>"); 142 + MODULE_LICENSE("GPL v2");
+54 -36
drivers/mfd/lm3533-ctrlbank.c
··· 17 17 #define LM3533_MAX_CURRENT_MAX 29800 18 18 #define LM3533_MAX_CURRENT_STEP 800 19 19 20 - #define LM3533_BRIGHTNESS_MAX 255 21 20 #define LM3533_PWM_MAX 0x3f 22 21 23 22 #define LM3533_REG_PWM_BASE 0x14 ··· 88 89 } 89 90 EXPORT_SYMBOL_GPL(lm3533_ctrlbank_set_max_current); 90 91 91 - #define lm3533_ctrlbank_set(_name, _NAME) \ 92 - int lm3533_ctrlbank_set_##_name(struct lm3533_ctrlbank *cb, u8 val) \ 93 - { \ 94 - u8 reg; \ 95 - int ret; \ 96 - \ 97 - if (val > LM3533_##_NAME##_MAX) \ 98 - return -EINVAL; \ 99 - \ 100 - reg = lm3533_ctrlbank_get_reg(cb, LM3533_REG_##_NAME##_BASE); \ 101 - ret = lm3533_write(cb->lm3533, reg, val); \ 102 - if (ret) \ 103 - dev_err(cb->dev, "failed to set " #_name "\n"); \ 104 - \ 105 - return ret; \ 106 - } \ 107 - EXPORT_SYMBOL_GPL(lm3533_ctrlbank_set_##_name); 92 + int lm3533_ctrlbank_set_brightness(struct lm3533_ctrlbank *cb, u8 val) 93 + { 94 + u8 reg; 95 + int ret; 108 96 109 - #define lm3533_ctrlbank_get(_name, _NAME) \ 110 - int lm3533_ctrlbank_get_##_name(struct lm3533_ctrlbank *cb, u8 *val) \ 111 - { \ 112 - u8 reg; \ 113 - int ret; \ 114 - \ 115 - reg = lm3533_ctrlbank_get_reg(cb, LM3533_REG_##_NAME##_BASE); \ 116 - ret = lm3533_read(cb->lm3533, reg, val); \ 117 - if (ret) \ 118 - dev_err(cb->dev, "failed to get " #_name "\n"); \ 119 - \ 120 - return ret; \ 121 - } \ 122 - EXPORT_SYMBOL_GPL(lm3533_ctrlbank_get_##_name); 97 + reg = lm3533_ctrlbank_get_reg(cb, LM3533_REG_BRIGHTNESS_BASE); 98 + ret = lm3533_write(cb->lm3533, reg, val); 99 + if (ret) 100 + dev_err(cb->dev, "failed to set brightness\n"); 123 101 124 - lm3533_ctrlbank_set(brightness, BRIGHTNESS); 125 - lm3533_ctrlbank_get(brightness, BRIGHTNESS); 102 + return ret; 103 + } 104 + EXPORT_SYMBOL_GPL(lm3533_ctrlbank_set_brightness); 105 + 106 + int lm3533_ctrlbank_get_brightness(struct lm3533_ctrlbank *cb, u8 *val) 107 + { 108 + u8 reg; 109 + int ret; 110 + 111 + reg = lm3533_ctrlbank_get_reg(cb, LM3533_REG_BRIGHTNESS_BASE); 112 + ret = lm3533_read(cb->lm3533, reg, val); 113 + if (ret) 114 + dev_err(cb->dev, "failed to get brightness\n"); 115 + 116 + return ret; 117 + } 118 + EXPORT_SYMBOL_GPL(lm3533_ctrlbank_get_brightness); 126 119 127 120 /* 128 121 * PWM-input control mask: ··· 126 135 * bit 1 - PWM-input enabled in Zone 0 127 136 * bit 0 - PWM-input enabled 128 137 */ 129 - lm3533_ctrlbank_set(pwm, PWM); 130 - lm3533_ctrlbank_get(pwm, PWM); 138 + int lm3533_ctrlbank_set_pwm(struct lm3533_ctrlbank *cb, u8 val) 139 + { 140 + u8 reg; 141 + int ret; 131 142 143 + if (val > LM3533_PWM_MAX) 144 + return -EINVAL; 145 + 146 + reg = lm3533_ctrlbank_get_reg(cb, LM3533_REG_PWM_BASE); 147 + ret = lm3533_write(cb->lm3533, reg, val); 148 + if (ret) 149 + dev_err(cb->dev, "failed to set PWM mask\n"); 150 + 151 + return ret; 152 + } 153 + EXPORT_SYMBOL_GPL(lm3533_ctrlbank_set_pwm); 154 + 155 + int lm3533_ctrlbank_get_pwm(struct lm3533_ctrlbank *cb, u8 *val) 156 + { 157 + u8 reg; 158 + int ret; 159 + 160 + reg = lm3533_ctrlbank_get_reg(cb, LM3533_REG_PWM_BASE); 161 + ret = lm3533_read(cb->lm3533, reg, val); 162 + if (ret) 163 + dev_err(cb->dev, "failed to get PWM mask\n"); 164 + 165 + return ret; 166 + } 167 + EXPORT_SYMBOL_GPL(lm3533_ctrlbank_get_pwm); 132 168 133 169 MODULE_AUTHOR("Johan Hovold <jhovold@gmail.com>"); 134 170 MODULE_DESCRIPTION("LM3533 Control Bank interface");
+1 -1
drivers/mfd/lp873x.c
··· 1 1 /* 2 - * Copyright (C) 2016 Texas Instruments Incorporated - http://www.ti.com/ 2 + * Copyright (C) 2016 Texas Instruments Incorporated - https://www.ti.com/ 3 3 * 4 4 * Author: Keerthy <j-keerthy@ti.com> 5 5 *
+1 -1
drivers/mfd/lp87565.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 2 /* 3 - * Copyright (C) 2017 Texas Instruments Incorporated - http://www.ti.com/ 3 + * Copyright (C) 2017 Texas Instruments Incorporated - https://www.ti.com/ 4 4 * 5 5 * Author: Keerthy <j-keerthy@ti.com> 6 6 */
+20 -13
drivers/mfd/madera-core.c
··· 44 44 }; 45 45 46 46 static const struct mfd_cell madera_ldo1_devs[] = { 47 - { .name = "madera-ldo1" }, 47 + { 48 + .name = "madera-ldo1", 49 + .level = MFD_DEP_LEVEL_HIGH, 50 + }, 48 51 }; 49 52 50 53 static const char * const cs47l15_supplies[] = { ··· 58 55 59 56 static const struct mfd_cell cs47l15_devs[] = { 60 57 { .name = "madera-pinctrl", }, 61 - { .name = "madera-irq" }, 62 - { .name = "madera-gpio" }, 58 + { .name = "madera-irq", }, 59 + { .name = "madera-gpio", }, 63 60 { 64 61 .name = "madera-extcon", 65 62 .parent_supplies = cs47l15_supplies, ··· 111 108 static const struct mfd_cell cs47l85_devs[] = { 112 109 { .name = "madera-pinctrl", }, 113 110 { .name = "madera-irq", }, 114 - { .name = "madera-micsupp" }, 111 + { .name = "madera-micsupp", }, 115 112 { .name = "madera-gpio", }, 116 113 { 117 114 .name = "madera-extcon", ··· 158 155 }; 159 156 160 157 static const struct mfd_cell cs47l92_devs[] = { 161 - { .name = "madera-pinctrl" }, 158 + { .name = "madera-pinctrl", }, 162 159 { .name = "madera-irq", }, 163 160 { .name = "madera-micsupp", }, 164 - { .name = "madera-gpio" }, 161 + { .name = "madera-gpio", }, 165 162 { 166 163 .name = "madera-extcon", 167 164 .parent_supplies = cs47l92_supplies, ··· 746 743 /* Prevent any IRQs being serviced while we clean up */ 747 744 disable_irq(madera->irq); 748 745 749 - /* 750 - * DCVDD could be supplied by a child node, we must disable it before 751 - * removing the children, and prevent PM runtime from turning it back on 752 - */ 753 - pm_runtime_disable(madera->dev); 746 + pm_runtime_get_sync(madera->dev); 754 747 755 - clk_disable_unprepare(madera->mclk[MADERA_MCLK2].clk); 748 + mfd_remove_devices(madera->dev); 749 + 750 + pm_runtime_disable(madera->dev); 756 751 757 752 regulator_disable(madera->dcvdd); 758 753 regulator_put(madera->dcvdd); 759 754 760 - mfd_remove_devices(madera->dev); 755 + mfd_remove_devices_late(madera->dev); 756 + 757 + pm_runtime_set_suspended(madera->dev); 758 + pm_runtime_put_noidle(madera->dev); 759 + 760 + clk_disable_unprepare(madera->mclk[MADERA_MCLK2].clk); 761 + 761 762 madera_enable_hard_reset(madera); 762 763 763 764 regulator_bulk_disable(madera->num_core_supplies,
-1
drivers/mfd/madera-i2c.c
··· 88 88 if (!madera) 89 89 return -ENOMEM; 90 90 91 - 92 91 madera->regmap = devm_regmap_init_i2c(i2c, regmap_16bit_config); 93 92 if (IS_ERR(madera->regmap)) { 94 93 ret = PTR_ERR(madera->regmap);
+1 -1
drivers/mfd/max14577.c
··· 61 61 int maxim_charger_calc_reg_current(const struct maxim_charger_current *limits, 62 62 unsigned int min_ua, unsigned int max_ua, u8 *dst) 63 63 { 64 - unsigned int current_bits = 0xf; 64 + unsigned int current_bits; 65 65 66 66 if (min_ua > max_ua) 67 67 return -EINVAL;
+108 -13
drivers/mfd/mfd-core.c
··· 10 10 #include <linux/kernel.h> 11 11 #include <linux/platform_device.h> 12 12 #include <linux/acpi.h> 13 + #include <linux/list.h> 13 14 #include <linux/property.h> 14 15 #include <linux/mfd/core.h> 15 16 #include <linux/pm_runtime.h> ··· 18 17 #include <linux/module.h> 19 18 #include <linux/irqdomain.h> 20 19 #include <linux/of.h> 20 + #include <linux/of_address.h> 21 21 #include <linux/regulator/consumer.h> 22 + 23 + static LIST_HEAD(mfd_of_node_list); 24 + 25 + struct mfd_of_node_entry { 26 + struct list_head list; 27 + struct device *dev; 28 + struct device_node *np; 29 + }; 22 30 23 31 static struct device_type mfd_dev_type = { 24 32 .name = "mfd_device", ··· 117 107 } 118 108 #endif 119 109 110 + static int mfd_match_of_node_to_dev(struct platform_device *pdev, 111 + struct device_node *np, 112 + const struct mfd_cell *cell) 113 + { 114 + #if IS_ENABLED(CONFIG_OF) 115 + struct mfd_of_node_entry *of_entry; 116 + const __be32 *reg; 117 + u64 of_node_addr; 118 + 119 + /* Skip devices 'disabled' by Device Tree */ 120 + if (!of_device_is_available(np)) 121 + return -ENODEV; 122 + 123 + /* Skip if OF node has previously been allocated to a device */ 124 + list_for_each_entry(of_entry, &mfd_of_node_list, list) 125 + if (of_entry->np == np) 126 + return -EAGAIN; 127 + 128 + if (!cell->use_of_reg) 129 + /* No of_reg defined - allocate first free compatible match */ 130 + goto allocate_of_node; 131 + 132 + /* We only care about each node's first defined address */ 133 + reg = of_get_address(np, 0, NULL, NULL); 134 + if (!reg) 135 + /* OF node does not contatin a 'reg' property to match to */ 136 + return -EAGAIN; 137 + 138 + of_node_addr = of_read_number(reg, of_n_addr_cells(np)); 139 + 140 + if (cell->of_reg != of_node_addr) 141 + /* No match */ 142 + return -EAGAIN; 143 + 144 + allocate_of_node: 145 + of_entry = kzalloc(sizeof(*of_entry), GFP_KERNEL); 146 + if (!of_entry) 147 + return -ENOMEM; 148 + 149 + of_entry->dev = &pdev->dev; 150 + of_entry->np = np; 151 + list_add_tail(&of_entry->list, &mfd_of_node_list); 152 + 153 + pdev->dev.of_node = np; 154 + pdev->dev.fwnode = &np->fwnode; 155 + #endif 156 + return 0; 157 + } 158 + 120 159 static int mfd_add_device(struct device *parent, int id, 121 160 const struct mfd_cell *cell, 122 161 struct resource *mem_base, ··· 174 115 struct resource *res; 175 116 struct platform_device *pdev; 176 117 struct device_node *np = NULL; 118 + struct mfd_of_node_entry *of_entry, *tmp; 177 119 int ret = -ENOMEM; 178 120 int platform_id; 179 121 int r; ··· 209 149 if (ret < 0) 210 150 goto fail_res; 211 151 212 - if (parent->of_node && cell->of_compatible) { 152 + if (IS_ENABLED(CONFIG_OF) && parent->of_node && cell->of_compatible) { 213 153 for_each_child_of_node(parent->of_node, np) { 214 154 if (of_device_is_compatible(np, cell->of_compatible)) { 215 - if (!of_device_is_available(np)) { 216 - /* Ignore disabled devices error free */ 217 - ret = 0; 155 + ret = mfd_match_of_node_to_dev(pdev, np, cell); 156 + if (ret == -EAGAIN) 157 + continue; 158 + if (ret) 218 159 goto fail_alias; 219 - } 220 - pdev->dev.of_node = np; 221 - pdev->dev.fwnode = &np->fwnode; 160 + 222 161 break; 223 162 } 224 163 } 164 + 165 + if (!pdev->dev.of_node) 166 + pr_warn("%s: Failed to locate of_node [id: %d]\n", 167 + cell->name, platform_id); 225 168 } 226 169 227 170 mfd_acpi_add_device(cell, pdev); ··· 233 170 ret = platform_device_add_data(pdev, 234 171 cell->platform_data, cell->pdata_size); 235 172 if (ret) 236 - goto fail_alias; 173 + goto fail_of_entry; 237 174 } 238 175 239 176 if (cell->properties) { 240 177 ret = platform_device_add_properties(pdev, cell->properties); 241 178 if (ret) 242 - goto fail_alias; 179 + goto fail_of_entry; 243 180 } 244 181 245 182 for (r = 0; r < cell->num_resources; r++) { ··· 276 213 if (has_acpi_companion(&pdev->dev)) { 277 214 ret = acpi_check_resource_conflict(&res[r]); 278 215 if (ret) 279 - goto fail_alias; 216 + goto fail_of_entry; 280 217 } 281 218 } 282 219 } 283 220 284 221 ret = platform_device_add_resources(pdev, res, cell->num_resources); 285 222 if (ret) 286 - goto fail_alias; 223 + goto fail_of_entry; 287 224 288 225 ret = platform_device_add(pdev); 289 226 if (ret) 290 - goto fail_alias; 227 + goto fail_of_entry; 291 228 292 229 if (cell->pm_runtime_no_callbacks) 293 230 pm_runtime_no_callbacks(&pdev->dev); ··· 296 233 297 234 return 0; 298 235 236 + fail_of_entry: 237 + list_for_each_entry_safe(of_entry, tmp, &mfd_of_node_list, list) 238 + if (of_entry->dev == &pdev->dev) { 239 + list_del(&of_entry->list); 240 + kfree(of_entry); 241 + } 299 242 fail_alias: 300 243 regulator_bulk_unregister_supply_alias(&pdev->dev, 301 244 cell->parent_supplies, ··· 356 287 { 357 288 struct platform_device *pdev; 358 289 const struct mfd_cell *cell; 290 + int *level = data; 359 291 360 292 if (dev->type != &mfd_dev_type) 361 293 return 0; ··· 364 294 pdev = to_platform_device(dev); 365 295 cell = mfd_get_cell(pdev); 366 296 297 + if (level && cell->level > *level) 298 + return 0; 299 + 367 300 regulator_bulk_unregister_supply_alias(dev, cell->parent_supplies, 368 301 cell->num_parent_supplies); 302 + 303 + kfree(cell); 369 304 370 305 platform_device_unregister(pdev); 371 306 return 0; 372 307 } 373 308 309 + void mfd_remove_devices_late(struct device *parent) 310 + { 311 + int level = MFD_DEP_LEVEL_HIGH; 312 + 313 + device_for_each_child_reverse(parent, &level, mfd_remove_devices_fn); 314 + } 315 + EXPORT_SYMBOL(mfd_remove_devices_late); 316 + 374 317 void mfd_remove_devices(struct device *parent) 375 318 { 376 - device_for_each_child_reverse(parent, NULL, mfd_remove_devices_fn); 319 + int level = MFD_DEP_LEVEL_NORMAL; 320 + 321 + device_for_each_child_reverse(parent, &level, mfd_remove_devices_fn); 377 322 } 378 323 EXPORT_SYMBOL(mfd_remove_devices); 379 324 ··· 403 318 * Returns 0 on success or an appropriate negative error number on failure. 404 319 * All child-devices of the MFD will automatically be removed when it gets 405 320 * unbinded. 321 + * 322 + * @dev: Pointer to parent device. 323 + * @id: Can be PLATFORM_DEVID_AUTO to let the Platform API take care 324 + * of device numbering, or will be added to a device's cell_id. 325 + * @cells: Array of (struct mfd_cell)s describing child devices. 326 + * @n_devs: Number of child devices to register. 327 + * @mem_base: Parent register range resource for child devices. 328 + * @irq_base: Base of the range of virtual interrupt numbers allocated for 329 + * this MFD device. Unused if @domain is specified. 330 + * @domain: Interrupt domain to create mappings for hardware interrupts. 406 331 */ 407 332 int devm_mfd_add_devices(struct device *dev, int id, 408 333 const struct mfd_cell *cells, int n_devs,
+23
drivers/mfd/motorola-cpcap.c
··· 214 214 .val_format_endian = REGMAP_ENDIAN_LITTLE, 215 215 }; 216 216 217 + #ifdef CONFIG_PM_SLEEP 218 + static int cpcap_suspend(struct device *dev) 219 + { 220 + struct spi_device *spi = to_spi_device(dev); 221 + 222 + disable_irq(spi->irq); 223 + 224 + return 0; 225 + } 226 + 227 + static int cpcap_resume(struct device *dev) 228 + { 229 + struct spi_device *spi = to_spi_device(dev); 230 + 231 + enable_irq(spi->irq); 232 + 233 + return 0; 234 + } 235 + #endif 236 + 237 + static SIMPLE_DEV_PM_OPS(cpcap_pm, cpcap_suspend, cpcap_resume); 238 + 217 239 static const struct mfd_cell cpcap_mfd_devices[] = { 218 240 { 219 241 .name = "cpcap_adc", ··· 335 313 .driver = { 336 314 .name = "cpcap-core", 337 315 .of_match_table = cpcap_of_match, 316 + .pm = &cpcap_pm, 338 317 }, 339 318 .probe = cpcap_probe, 340 319 };
+4 -2
drivers/mfd/omap-usb-host.c
··· 2 2 /** 3 3 * omap-usb-host.c - The USBHS core driver for OMAP EHCI & OHCI 4 4 * 5 - * Copyright (C) 2011-2013 Texas Instruments Incorporated - http://www.ti.com 5 + * Copyright (C) 2011-2013 Texas Instruments Incorporated - https://www.ti.com 6 6 * Author: Keshava Munegowda <keshava_mgowda@ti.com> 7 7 * Author: Roger Quadros <rogerq@ti.com> 8 8 */ ··· 120 120 121 121 /*-------------------------------------------------------------------------*/ 122 122 123 - /** 123 + /* 124 124 * Map 'enum usbhs_omap_port_mode' found in <linux/platform_data/usb-omap.h> 125 125 * to the device tree binding portN-mode found in 126 126 * 'Documentation/devicetree/bindings/mfd/omap-usb-host.txt' ··· 526 526 * usbhs_omap_probe - initialize TI-based HCDs 527 527 * 528 528 * Allocates basic resources for this USB host controller. 529 + * 530 + * @pdev: Pointer to this device's platform device structure 529 531 */ 530 532 static int usbhs_omap_probe(struct platform_device *pdev) 531 533 {
+3 -1
drivers/mfd/omap-usb-tll.c
··· 2 2 /** 3 3 * omap-usb-tll.c - The USB TLL driver for OMAP EHCI & OHCI 4 4 * 5 - * Copyright (C) 2012-2013 Texas Instruments Incorporated - http://www.ti.com 5 + * Copyright (C) 2012-2013 Texas Instruments Incorporated - https://www.ti.com 6 6 * Author: Keshava Munegowda <keshava_mgowda@ti.com> 7 7 * Author: Roger Quadros <rogerq@ti.com> 8 8 */ ··· 199 199 * usbtll_omap_probe - initialize TI-based HCDs 200 200 * 201 201 * Allocates basic resources for this USB host controller. 202 + * 203 + * @pdev: Pointer to this device's platform device structure 202 204 */ 203 205 static int usbtll_omap_probe(struct platform_device *pdev) 204 206 {
+1 -1
drivers/mfd/rave-sp.c
··· 96 96 * @data: Buffer to store reply payload in 97 97 * @code: Expected reply code 98 98 * @ackid: Expected reply ACK ID 99 - * @completion: Successful reply reception completion 99 + * @received: Successful reply reception completion 100 100 */ 101 101 struct rave_sp_reply { 102 102 size_t length;
+36 -10
drivers/mfd/rn5t618.c
··· 44 44 case RN5T618_INTMON: 45 45 case RN5T618_RTC_CTRL1 ... RN5T618_RTC_CTRL2: 46 46 case RN5T618_RTC_SECONDS ... RN5T618_RTC_YEAR: 47 + case RN5T618_CHGSTATE: 48 + case RN5T618_CHGCTRL_IRR ... RN5T618_CHGERR_MONI: 49 + case RN5T618_CONTROL ... RN5T618_CC_AVEREG0: 47 50 return true; 48 51 default: 49 52 return false; ··· 80 77 .mask_invert = true, 81 78 }; 82 79 83 - static struct rn5t618 *rn5t618_pm_power_off; 80 + static struct i2c_client *rn5t618_pm_power_off; 84 81 static struct notifier_block rn5t618_restart_handler; 85 82 86 83 static int rn5t618_irq_init(struct rn5t618 *rn5t618) ··· 113 110 114 111 static void rn5t618_trigger_poweroff_sequence(bool repower) 115 112 { 113 + int ret; 114 + 116 115 /* disable automatic repower-on */ 117 - regmap_update_bits(rn5t618_pm_power_off->regmap, RN5T618_REPCNT, 118 - RN5T618_REPCNT_REPWRON, 119 - repower ? RN5T618_REPCNT_REPWRON : 0); 116 + ret = i2c_smbus_read_byte_data(rn5t618_pm_power_off, RN5T618_REPCNT); 117 + if (ret < 0) 118 + goto err; 119 + 120 + ret &= ~RN5T618_REPCNT_REPWRON; 121 + if (repower) 122 + ret |= RN5T618_REPCNT_REPWRON; 123 + 124 + ret = i2c_smbus_write_byte_data(rn5t618_pm_power_off, 125 + RN5T618_REPCNT, (u8)ret); 126 + if (ret < 0) 127 + goto err; 128 + 120 129 /* start power-off sequence */ 121 - regmap_update_bits(rn5t618_pm_power_off->regmap, RN5T618_SLPCNT, 122 - RN5T618_SLPCNT_SWPWROFF, RN5T618_SLPCNT_SWPWROFF); 130 + ret = i2c_smbus_read_byte_data(rn5t618_pm_power_off, RN5T618_SLPCNT); 131 + if (ret < 0) 132 + goto err; 133 + 134 + ret |= RN5T618_SLPCNT_SWPWROFF; 135 + 136 + ret = i2c_smbus_write_byte_data(rn5t618_pm_power_off, 137 + RN5T618_SLPCNT, (u8)ret); 138 + if (ret < 0) 139 + goto err; 140 + 141 + return; 142 + 143 + err: 144 + dev_alert(&rn5t618_pm_power_off->dev, "Failed to shutdown (err = %d)\n", ret); 123 145 } 124 146 125 147 static void rn5t618_power_off(void) ··· 217 189 return ret; 218 190 } 219 191 220 - rn5t618_pm_power_off = priv; 192 + rn5t618_pm_power_off = i2c; 221 193 if (of_device_is_system_power_controller(i2c->dev.of_node)) { 222 194 if (!pm_power_off) 223 195 pm_power_off = rn5t618_power_off; ··· 239 211 240 212 static int rn5t618_i2c_remove(struct i2c_client *i2c) 241 213 { 242 - struct rn5t618 *priv = i2c_get_clientdata(i2c); 243 - 244 - if (priv == rn5t618_pm_power_off) { 214 + if (i2c == rn5t618_pm_power_off) { 245 215 rn5t618_pm_power_off = NULL; 246 216 pm_power_off = NULL; 247 217 }
+36 -38
drivers/mfd/si476x-cmd.c
··· 241 241 /** 242 242 * si476x_core_send_command() - sends a command to si476x and waits its 243 243 * response 244 - * @core: si476x_device structure for the device we are 244 + * @core: si476x_device structure for the device we are 245 245 * communicating with 246 246 * @command: command id 247 247 * @args: command arguments we are sending 248 248 * @argn: actual size of @args 249 - * @response: buffer to place the expected response from the device 250 - * @respn: actual size of @response 249 + * @resp: buffer to place the expected response from the device 250 + * @respn: actual size of @resp 251 251 * @usecs: amount of time to wait before reading the response (in 252 252 * usecs) 253 253 * ··· 496 496 * enable 1MOhm pulldown 497 497 * SI476X_DFS_DAUDIO - set the pin to be a part of digital 498 498 * audio interface 499 - * @dout - DOUT pin function configuration: 499 + * @dout: - DOUT pin function configuration: 500 500 * SI476X_DOUT_NOOP - do not modify the behaviour 501 501 * SI476X_DOUT_TRISTATE - put the pin in tristate condition, 502 502 * enable 1MOhm pulldown ··· 504 504 * port 1 505 505 * SI476X_DOUT_I2S_INPUT - set this pin to be digital in on I2S 506 506 * port 1 507 - * @xout - XOUT pin function configuration: 507 + * @xout: - XOUT pin function configuration: 508 508 * SI476X_XOUT_NOOP - do not modify the behaviour 509 509 * SI476X_XOUT_TRISTATE - put the pin in tristate condition, 510 510 * enable 1MOhm pulldown ··· 540 540 541 541 /** 542 542 * si476x_cmd_zif_pin_cfg - send 'ZIF_PIN_CFG_COMMAND' 543 - * @core - device to send the command to 544 - * @iqclk - IQCL pin function configuration: 543 + * @core: - device to send the command to 544 + * @iqclk: - IQCL pin function configuration: 545 545 * SI476X_IQCLK_NOOP - do not modify the behaviour 546 546 * SI476X_IQCLK_TRISTATE - put the pin in tristate condition, 547 547 * enable 1MOhm pulldown 548 548 * SI476X_IQCLK_IQ - set pin to be a part of I/Q interace 549 549 * in master mode 550 - * @iqfs - IQFS pin function configuration: 550 + * @iqfs: - IQFS pin function configuration: 551 551 * SI476X_IQFS_NOOP - do not modify the behaviour 552 552 * SI476X_IQFS_TRISTATE - put the pin in tristate condition, 553 553 * enable 1MOhm pulldown 554 554 * SI476X_IQFS_IQ - set pin to be a part of I/Q interace 555 555 * in master mode 556 - * @iout - IOUT pin function configuration: 556 + * @iout: - IOUT pin function configuration: 557 557 * SI476X_IOUT_NOOP - do not modify the behaviour 558 558 * SI476X_IOUT_TRISTATE - put the pin in tristate condition, 559 559 * enable 1MOhm pulldown 560 560 * SI476X_IOUT_OUTPUT - set pin to be I out 561 - * @qout - QOUT pin function configuration: 561 + * @qout: - QOUT pin function configuration: 562 562 * SI476X_QOUT_NOOP - do not modify the behaviour 563 563 * SI476X_QOUT_TRISTATE - put the pin in tristate condition, 564 564 * enable 1MOhm pulldown ··· 590 590 /** 591 591 * si476x_cmd_ic_link_gpo_ctl_pin_cfg - send 592 592 * 'IC_LINK_GPIO_CTL_PIN_CFG' comand to the device 593 - * @core - device to send the command to 594 - * @icin - ICIN pin function configuration: 593 + * @core: - device to send the command to 594 + * @icin: - ICIN pin function configuration: 595 595 * SI476X_ICIN_NOOP - do not modify the behaviour 596 596 * SI476X_ICIN_TRISTATE - put the pin in tristate condition, 597 597 * enable 1MOhm pulldown 598 598 * SI476X_ICIN_GPO1_HIGH - set pin to be an output, drive it high 599 599 * SI476X_ICIN_GPO1_LOW - set pin to be an output, drive it low 600 600 * SI476X_ICIN_IC_LINK - set the pin to be a part of Inter-Chip link 601 - * @icip - ICIP pin function configuration: 601 + * @icip: - ICIP pin function configuration: 602 602 * SI476X_ICIP_NOOP - do not modify the behaviour 603 603 * SI476X_ICIP_TRISTATE - put the pin in tristate condition, 604 604 * enable 1MOhm pulldown 605 605 * SI476X_ICIP_GPO1_HIGH - set pin to be an output, drive it high 606 606 * SI476X_ICIP_GPO1_LOW - set pin to be an output, drive it low 607 607 * SI476X_ICIP_IC_LINK - set the pin to be a part of Inter-Chip link 608 - * @icon - ICON pin function configuration: 608 + * @icon: - ICON pin function configuration: 609 609 * SI476X_ICON_NOOP - do not modify the behaviour 610 610 * SI476X_ICON_TRISTATE - put the pin in tristate condition, 611 611 * enable 1MOhm pulldown 612 612 * SI476X_ICON_I2S - set the pin to be a part of audio 613 613 * interface in slave mode (DCLK) 614 614 * SI476X_ICON_IC_LINK - set the pin to be a part of Inter-Chip link 615 - * @icop - ICOP pin function configuration: 615 + * @icop: - ICOP pin function configuration: 616 616 * SI476X_ICOP_NOOP - do not modify the behaviour 617 617 * SI476X_ICOP_TRISTATE - put the pin in tristate condition, 618 618 * enable 1MOhm pulldown ··· 647 647 /** 648 648 * si476x_cmd_ana_audio_pin_cfg - send 'ANA_AUDIO_PIN_CFG' to the 649 649 * device 650 - * @core - device to send the command to 651 - * @lrout - LROUT pin function configuration: 650 + * @core: - device to send the command to 651 + * @lrout: - LROUT pin function configuration: 652 652 * SI476X_LROUT_NOOP - do not modify the behaviour 653 653 * SI476X_LROUT_TRISTATE - put the pin in tristate condition, 654 654 * enable 1MOhm pulldown ··· 675 675 676 676 /** 677 677 * si476x_cmd_intb_pin_cfg - send 'INTB_PIN_CFG' command to the device 678 - * @core - device to send the command to 679 - * @intb - INTB pin function configuration: 678 + * @core: - device to send the command to 679 + * @intb: - INTB pin function configuration: 680 680 * SI476X_INTB_NOOP - do not modify the behaviour 681 681 * SI476X_INTB_TRISTATE - put the pin in tristate condition, 682 682 * enable 1MOhm pulldown 683 683 * SI476X_INTB_DAUDIO - set pin to be a part of digital 684 684 * audio interface in slave mode 685 685 * SI476X_INTB_IRQ - set pin to be an interrupt request line 686 - * @a1 - A1 pin function configuration: 686 + * @a1: - A1 pin function configuration: 687 687 * SI476X_A1_NOOP - do not modify the behaviour 688 688 * SI476X_A1_TRISTATE - put the pin in tristate condition, 689 689 * enable 1MOhm pulldown ··· 728 728 /** 729 729 * si476x_cmd_am_rsq_status - send 'AM_RSQ_STATUS' command to the 730 730 * device 731 - * @core - device to send the command to 732 - * @rsqack - if set command clears RSQINT, SNRINT, SNRLINT, RSSIHINT, 733 - * RSSSILINT, BLENDINT, MULTHINT and MULTLINT 734 - * @attune - when set the values in the status report are the values 735 - * that were calculated at tune 736 - * @cancel - abort ongoing seek/tune opertation 737 - * @stcack - clear the STCINT bin in status register 738 - * @report - all signal quality information retured by the command 731 + * @core: - device to send the command to 732 + * @rsqargs: - pointer to a structure containing a group of sub-args 733 + * relevant to sending the RSQ status command 734 + * @report: - all signal quality information retured by the command 739 735 * (if NULL then the output of the command is ignored) 740 736 * 741 737 * Function returns 0 on success and negative error code on failure ··· 858 862 /** 859 863 * si476x_cmd_fm_seek_start - send 'FM_SEEK_START' command to the 860 864 * device 861 - * @core - device to send the command to 862 - * @seekup - if set the direction of the search is 'up' 863 - * @wrap - if set seek wraps when hitting band limit 865 + * @core: - device to send the command to 866 + * @seekup: - if set the direction of the search is 'up' 867 + * @wrap: - if set seek wraps when hitting band limit 864 868 * 865 869 * This function begins search for a valid station. The station is 866 870 * considered valid when 'FM_VALID_SNR_THRESHOLD' and ··· 886 890 /** 887 891 * si476x_cmd_fm_rds_status - send 'FM_RDS_STATUS' command to the 888 892 * device 889 - * @core - device to send the command to 890 - * @status_only - if set the data is not removed from RDSFIFO, 893 + * @core: - device to send the command to 894 + * @status_only: - if set the data is not removed from RDSFIFO, 891 895 * RDSFIFOUSED is not decremented and data in all the 892 896 * rest RDS data contains the last valid info received 893 - * @mtfifo if set the command clears RDS receive FIFO 894 - * @intack if set the command clards the RDSINT bit. 897 + * @mtfifo: if set the command clears RDS receive FIFO 898 + * @intack: if set the command clards the RDSINT bit. 899 + * @report: - all signal quality information retured by the command 900 + * (if NULL then the output of the command is ignored) 895 901 * 896 902 * Function returns 0 on success and negative error code on failure 897 903 */ ··· 1034 1036 /** 1035 1037 * si476x_cmd_am_seek_start - send 'FM_SEEK_START' command to the 1036 1038 * device 1037 - * @core - device to send the command to 1038 - * @seekup - if set the direction of the search is 'up' 1039 - * @wrap - if set seek wraps when hitting band limit 1039 + * @core: - device to send the command to 1040 + * @seekup: - if set the direction of the search is 'up' 1041 + * @wrap: - if set seek wraps when hitting band limit 1040 1042 * 1041 1043 * This function begins search for a valid station. The station is 1042 1044 * considered valid when 'FM_VALID_SNR_THRESHOLD' and
+6 -1
drivers/mfd/si476x-i2c.c
··· 534 534 /** 535 535 * si476x_firmware_version_to_revision() 536 536 * @core: Core device structure 537 + * @func: Selects the boot function of the device: 538 + * *_BOOTLOADER - Boot loader 539 + * *_FM_RECEIVER - FM receiver 540 + * *_AM_RECEIVER - AM receiver 541 + * *_WB_RECEIVER - Weatherband receiver 537 542 * @major: Firmware major number 538 543 * @minor1: Firmware first minor number 539 544 * @minor2: Firmware second minor number ··· 588 583 goto unknown_revision; 589 584 } 590 585 case SI476X_FUNC_BOOTLOADER: 591 - default: /* FALLTHROUG */ 586 + default: /* FALLTHROUGH */ 592 587 BUG(); 593 588 return -1; 594 589 }
-87
drivers/mfd/smsc-ece1099.c
··· 1 - /* 2 - * TI SMSC MFD Driver 3 - * 4 - * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com 5 - * 6 - * Author: Sourav Poddar <sourav.poddar@ti.com> 7 - * 8 - * This program is free software; you can redistribute it and/or modify it 9 - * under the terms of the GNU General Public License as published by the 10 - * Free Software Foundation; GPL v2. 11 - * 12 - */ 13 - 14 - #include <linux/init.h> 15 - #include <linux/slab.h> 16 - #include <linux/i2c.h> 17 - #include <linux/gpio.h> 18 - #include <linux/workqueue.h> 19 - #include <linux/irq.h> 20 - #include <linux/regmap.h> 21 - #include <linux/err.h> 22 - #include <linux/mfd/core.h> 23 - #include <linux/mfd/smsc.h> 24 - #include <linux/of_platform.h> 25 - 26 - static const struct regmap_config smsc_regmap_config = { 27 - .reg_bits = 8, 28 - .val_bits = 8, 29 - .max_register = SMSC_VEN_ID_H, 30 - .cache_type = REGCACHE_RBTREE, 31 - }; 32 - 33 - static int smsc_i2c_probe(struct i2c_client *i2c, 34 - const struct i2c_device_id *id) 35 - { 36 - struct smsc *smsc; 37 - int devid, rev, venid_l, venid_h; 38 - int ret; 39 - 40 - smsc = devm_kzalloc(&i2c->dev, sizeof(*smsc), GFP_KERNEL); 41 - if (!smsc) 42 - return -ENOMEM; 43 - 44 - smsc->regmap = devm_regmap_init_i2c(i2c, &smsc_regmap_config); 45 - if (IS_ERR(smsc->regmap)) 46 - return PTR_ERR(smsc->regmap); 47 - 48 - i2c_set_clientdata(i2c, smsc); 49 - smsc->dev = &i2c->dev; 50 - 51 - #ifdef CONFIG_OF 52 - of_property_read_u32(i2c->dev.of_node, "clock", &smsc->clk); 53 - #endif 54 - 55 - regmap_read(smsc->regmap, SMSC_DEV_ID, &devid); 56 - regmap_read(smsc->regmap, SMSC_DEV_REV, &rev); 57 - regmap_read(smsc->regmap, SMSC_VEN_ID_L, &venid_l); 58 - regmap_read(smsc->regmap, SMSC_VEN_ID_H, &venid_h); 59 - 60 - dev_info(&i2c->dev, "SMSCxxx devid: %02x rev: %02x venid: %02x\n", 61 - devid, rev, (venid_h << 8) | venid_l); 62 - 63 - ret = regmap_write(smsc->regmap, SMSC_CLK_CTRL, smsc->clk); 64 - if (ret) 65 - return ret; 66 - 67 - #ifdef CONFIG_OF 68 - if (i2c->dev.of_node) 69 - ret = devm_of_platform_populate(&i2c->dev); 70 - #endif 71 - 72 - return ret; 73 - } 74 - 75 - static const struct i2c_device_id smsc_i2c_id[] = { 76 - { "smscece1099", 0}, 77 - {}, 78 - }; 79 - 80 - static struct i2c_driver smsc_i2c_driver = { 81 - .driver = { 82 - .name = "smsc", 83 - }, 84 - .probe = smsc_i2c_probe, 85 - .id_table = smsc_i2c_id, 86 - }; 87 - builtin_i2c_driver(smsc_i2c_driver);
+6 -76
drivers/mfd/sprd-sc27xx-spi.c
··· 7 7 #include <linux/kernel.h> 8 8 #include <linux/module.h> 9 9 #include <linux/mfd/core.h> 10 + #include <linux/mfd/sc27xx-pmic.h> 10 11 #include <linux/of_device.h> 12 + #include <linux/of_platform.h> 11 13 #include <linux/regmap.h> 12 14 #include <linux/spi/spi.h> 13 15 #include <uapi/linux/usb/charger.h> ··· 94 92 return type; 95 93 } 96 94 EXPORT_SYMBOL_GPL(sprd_pmic_detect_charger_type); 97 - 98 - static const struct mfd_cell sprd_pmic_devs[] = { 99 - { 100 - .name = "sc27xx-wdt", 101 - .of_compatible = "sprd,sc2731-wdt", 102 - }, { 103 - .name = "sc27xx-rtc", 104 - .of_compatible = "sprd,sc2731-rtc", 105 - }, { 106 - .name = "sc27xx-charger", 107 - .of_compatible = "sprd,sc2731-charger", 108 - }, { 109 - .name = "sc27xx-chg-timer", 110 - .of_compatible = "sprd,sc2731-chg-timer", 111 - }, { 112 - .name = "sc27xx-fast-chg", 113 - .of_compatible = "sprd,sc2731-fast-chg", 114 - }, { 115 - .name = "sc27xx-chg-wdt", 116 - .of_compatible = "sprd,sc2731-chg-wdt", 117 - }, { 118 - .name = "sc27xx-typec", 119 - .of_compatible = "sprd,sc2731-typec", 120 - }, { 121 - .name = "sc27xx-flash", 122 - .of_compatible = "sprd,sc2731-flash", 123 - }, { 124 - .name = "sc27xx-eic", 125 - .of_compatible = "sprd,sc2731-eic", 126 - }, { 127 - .name = "sc27xx-efuse", 128 - .of_compatible = "sprd,sc2731-efuse", 129 - }, { 130 - .name = "sc27xx-thermal", 131 - .of_compatible = "sprd,sc2731-thermal", 132 - }, { 133 - .name = "sc27xx-adc", 134 - .of_compatible = "sprd,sc2731-adc", 135 - }, { 136 - .name = "sc27xx-audio-codec", 137 - .of_compatible = "sprd,sc2731-audio-codec", 138 - }, { 139 - .name = "sc27xx-regulator", 140 - .of_compatible = "sprd,sc2731-regulator", 141 - }, { 142 - .name = "sc27xx-vibrator", 143 - .of_compatible = "sprd,sc2731-vibrator", 144 - }, { 145 - .name = "sc27xx-keypad-led", 146 - .of_compatible = "sprd,sc2731-keypad-led", 147 - }, { 148 - .name = "sc27xx-bltc", 149 - .of_compatible = "sprd,sc2731-bltc", 150 - }, { 151 - .name = "sc27xx-fgu", 152 - .of_compatible = "sprd,sc2731-fgu", 153 - }, { 154 - .name = "sc27xx-7sreset", 155 - .of_compatible = "sprd,sc2731-7sreset", 156 - }, { 157 - .name = "sc27xx-poweroff", 158 - .of_compatible = "sprd,sc2731-poweroff", 159 - }, { 160 - .name = "sc27xx-syscon", 161 - .of_compatible = "sprd,sc2731-syscon", 162 - }, 163 - }; 164 95 165 96 static int sprd_pmic_spi_write(void *context, const void *data, size_t count) 166 97 { ··· 185 250 return -ENOMEM; 186 251 187 252 ddata->irq_chip.irqs = ddata->irqs; 188 - for (i = 0; i < pdata->num_irqs; i++) { 189 - ddata->irqs[i].reg_offset = i / pdata->num_irqs; 190 - ddata->irqs[i].mask = BIT(i % pdata->num_irqs); 191 - } 253 + for (i = 0; i < pdata->num_irqs; i++) 254 + ddata->irqs[i].mask = BIT(i); 192 255 193 256 ret = devm_regmap_add_irq_chip(&spi->dev, ddata->regmap, ddata->irq, 194 257 IRQF_ONESHOT | IRQF_NO_SUSPEND, 0, ··· 196 263 return ret; 197 264 } 198 265 199 - ret = devm_mfd_add_devices(&spi->dev, PLATFORM_DEVID_AUTO, 200 - sprd_pmic_devs, ARRAY_SIZE(sprd_pmic_devs), 201 - NULL, 0, 202 - regmap_irq_get_domain(ddata->irq_data)); 266 + ret = devm_of_platform_populate(&spi->dev); 203 267 if (ret) { 204 - dev_err(&spi->dev, "Failed to register device %d\n", ret); 268 + dev_err(&spi->dev, "Failed to populate sub-devices %d\n", ret); 205 269 return ret; 206 270 } 207 271
+1
drivers/mfd/stm32-lptimer.c
··· 17 17 .val_bits = 32, 18 18 .reg_stride = sizeof(u32), 19 19 .max_register = STM32_LPTIM_MAX_REGISTER, 20 + .fast_io = true, 20 21 }; 21 22 22 23 static int stm32_lptimer_detect_encoder(struct stm32_lptimer *ddata)
+3 -1
drivers/mfd/syscon.c
··· 101 101 } 102 102 } 103 103 104 - syscon_config.name = of_node_full_name(np); 104 + syscon_config.name = kasprintf(GFP_KERNEL, "%pOFn@%llx", np, 105 + (u64)res.start); 105 106 syscon_config.reg_stride = reg_io_width; 106 107 syscon_config.val_bits = reg_io_width * 8; 107 108 syscon_config.max_register = resource_size(&res) - reg_io_width; 108 109 109 110 regmap = regmap_init_mmio(NULL, base, &syscon_config); 111 + kfree(syscon_config.name); 110 112 if (IS_ERR(regmap)) { 111 113 pr_err("regmap init failed\n"); 112 114 ret = PTR_ERR(regmap);
+1 -1
drivers/mfd/tc3589x.c
··· 18 18 #include <linux/mfd/tc3589x.h> 19 19 #include <linux/err.h> 20 20 21 - /** 21 + /* 22 22 * enum tc3589x_version - indicates the TC3589x version 23 23 */ 24 24 enum tc3589x_version {
+1 -1
drivers/mfd/ti_am335x_tscadc.c
··· 1 1 /* 2 2 * TI Touch Screen / ADC MFD driver 3 3 * 4 - * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ 4 + * Copyright (C) 2012 Texas Instruments Incorporated - https://www.ti.com/ 5 5 * 6 6 * This program is free software; you can redistribute it and/or 7 7 * modify it under the terms of the GNU General Public License as
+2 -3
drivers/mfd/tps65010.c
··· 404 404 tps65010_interrupt(tps); 405 405 406 406 if (test_and_clear_bit(FLAG_VBUS_CHANGED, &tps->flags)) { 407 - int status; 408 407 u8 chgconfig, tmp; 409 408 410 409 chgconfig = i2c_smbus_read_byte_data(tps->client, ··· 414 415 else if (tps->vbus >= 100) 415 416 chgconfig |= TPS_VBUS_CHARGING; 416 417 417 - status = i2c_smbus_write_byte_data(tps->client, 418 - TPS_CHGCONFIG, chgconfig); 418 + i2c_smbus_write_byte_data(tps->client, 419 + TPS_CHGCONFIG, chgconfig); 419 420 420 421 /* vbus update fails unless VBUS is connected! */ 421 422 tmp = i2c_smbus_read_byte_data(tps->client, TPS_CHGCONFIG);
+1 -1
drivers/mfd/tps65086.c
··· 1 1 /* 2 - * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/ 2 + * Copyright (C) 2015 Texas Instruments Incorporated - https://www.ti.com/ 3 3 * Andrew F. Davis <afd@ti.com> 4 4 * 5 5 * This program is free software; you can redistribute it and/or
+3 -3
drivers/mfd/tps65217.c
··· 3 3 * 4 4 * TPS65217 chip family multi-function driver 5 5 * 6 - * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ 6 + * Copyright (C) 2011 Texas Instruments Incorporated - https://www.ti.com/ 7 7 * 8 8 * This program is free software; you can redistribute it and/or 9 9 * modify it under the terms of the GNU General Public License as ··· 205 205 /** 206 206 * tps65217_reg_write: Write a single tps65217 register. 207 207 * 208 - * @tps65217: Device to write to. 208 + * @tps: Device to write to. 209 209 * @reg: Register to write to. 210 210 * @val: Value to write. 211 211 * @level: Password protected level ··· 250 250 /** 251 251 * tps65217_update_bits: Modify bits w.r.t mask, val and level. 252 252 * 253 - * @tps65217: Device to write to. 253 + * @tps: Device to write to. 254 254 * @reg: Register to read-write to. 255 255 * @mask: Mask. 256 256 * @val: Value to write.
+3 -3
drivers/mfd/tps65218.c
··· 1 1 /* 2 2 * Driver for TPS65218 Integrated power management chipsets 3 3 * 4 - * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/ 4 + * Copyright (C) 2014 Texas Instruments Incorporated - https://www.ti.com/ 5 5 * 6 6 * This program is free software; you can redistribute it and/or 7 7 * modify it under the terms of the GNU General Public License version 2 as ··· 48 48 /** 49 49 * tps65218_reg_write: Write a single tps65218 register. 50 50 * 51 - * @tps65218: Device to write to. 51 + * @tps: Device to write to. 52 52 * @reg: Register to write to. 53 53 * @val: Value to write. 54 54 * @level: Password protected level ··· 79 79 /** 80 80 * tps65218_update_bits: Modify bits w.r.t mask, val and level. 81 81 * 82 - * @tps65218: Device to write to. 82 + * @tps: Device to write to. 83 83 * @reg: Register to read-write to. 84 84 * @mask: Mask. 85 85 * @val: Value to write.
+4 -3
drivers/mfd/tps6586x.c
··· 309 309 static irqreturn_t tps6586x_irq(int irq, void *data) 310 310 { 311 311 struct tps6586x *tps6586x = data; 312 - u32 acks; 312 + uint32_t acks; 313 + __le32 val; 313 314 int ret = 0; 314 315 315 316 ret = tps6586x_reads(tps6586x->dev, TPS6586X_INT_ACK1, 316 - sizeof(acks), (uint8_t *)&acks); 317 + sizeof(acks), (uint8_t *)&val); 317 318 318 319 if (ret < 0) { 319 320 dev_err(tps6586x->dev, "failed to read interrupt status\n"); 320 321 return IRQ_NONE; 321 322 } 322 323 323 - acks = le32_to_cpu(acks); 324 + acks = le32_to_cpu(val); 324 325 325 326 while (acks) { 326 327 int i = __ffs(acks);
+1 -1
drivers/mfd/tps65912-core.c
··· 1 1 /* 2 2 * Core functions for TI TPS65912x PMICs 3 3 * 4 - * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/ 4 + * Copyright (C) 2015 Texas Instruments Incorporated - https://www.ti.com/ 5 5 * Andrew F. Davis <afd@ti.com> 6 6 * 7 7 * This program is free software; you can redistribute it and/or
+1 -1
drivers/mfd/tps65912-i2c.c
··· 1 1 /* 2 2 * I2C access driver for TI TPS65912x PMICs 3 3 * 4 - * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/ 4 + * Copyright (C) 2015 Texas Instruments Incorporated - https://www.ti.com/ 5 5 * Andrew F. Davis <afd@ti.com> 6 6 * 7 7 * This program is free software; you can redistribute it and/or
+1 -1
drivers/mfd/tps65912-spi.c
··· 1 1 /* 2 2 * SPI access driver for TI TPS65912x PMICs 3 3 * 4 - * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/ 4 + * Copyright (C) 2015 Texas Instruments Incorporated - https://www.ti.com/ 5 5 * Andrew F. Davis <afd@ti.com> 6 6 * 7 7 * This program is free software; you can redistribute it and/or
+2 -2
drivers/mfd/twl4030-irq.c
··· 477 477 478 478 if (agent->imr_change_pending) { 479 479 union { 480 - u32 word; 480 + __le32 word; 481 481 u8 bytes[4]; 482 482 } imr; 483 483 ··· 561 561 int status; 562 562 union { 563 563 u8 bytes[4]; 564 - u32 word; 564 + __le32 word; 565 565 } isr; 566 566 567 567 /* FIXME need retry-on-error ... */
+4
drivers/mfd/wm831x-core.c
··· 114 114 * The WM831x has a user key preventing writes to particularly 115 115 * critical registers. This function locks those registers, 116 116 * allowing writes to them. 117 + * 118 + * @wm831x: pointer to local driver data structure 117 119 */ 118 120 void wm831x_reg_lock(struct wm831x *wm831x) 119 121 { ··· 142 140 * The WM831x has a user key preventing writes to particularly 143 141 * critical registers. This function locks those registers, 144 142 * preventing spurious writes. 143 + * 144 + * @wm831x: pointer to local driver data structure 145 145 */ 146 146 int wm831x_reg_unlock(struct wm831x *wm831x) 147 147 {
+4
drivers/mfd/wm8350-core.c
··· 131 131 * The WM8350 has a hardware lock which can be used to prevent writes to 132 132 * some registers (generally those which can cause particularly serious 133 133 * problems if misused). This function enables that lock. 134 + * 135 + * @wm8350: pointer to local driver data structure 134 136 */ 135 137 int wm8350_reg_lock(struct wm8350 *wm8350) 136 138 { ··· 162 160 * problems if misused). This function disables that lock so updates 163 161 * can be performed. For maximum safety this should be done only when 164 162 * required. 163 + * 164 + * @wm8350: pointer to local driver data structure 165 165 */ 166 166 int wm8350_reg_unlock(struct wm8350 *wm8350) 167 167 {
+2
drivers/mfd/wm8400-core.c
··· 108 108 /** 109 109 * wm8400_reset_codec_reg_cache - Reset cached codec registers to 110 110 * their default values. 111 + * 112 + * @wm8400: pointer to local driver data structure 111 113 */ 112 114 void wm8400_reset_codec_reg_cache(struct wm8400 *wm8400) 113 115 {
+11
drivers/thermal/Kconfig
··· 499 499 help 500 500 Support for the Spreadtrum thermal sensor driver in the Linux thermal 501 501 framework. 502 + 503 + config KHADAS_MCU_FAN_THERMAL 504 + tristate "Khadas MCU controller FAN cooling support" 505 + depends on OF || COMPILE_TEST 506 + depends on MFD_KHADAS_MCU 507 + select MFD_CORE 508 + select REGMAP 509 + help 510 + If you say yes here you get support for the FAN controlled 511 + by the Microcontroller found on the Khadas VIM boards. 512 + 502 513 endif
+1
drivers/thermal/Makefile
··· 61 61 obj-$(CONFIG_UNIPHIER_THERMAL) += uniphier_thermal.o 62 62 obj-$(CONFIG_AMLOGIC_THERMAL) += amlogic_thermal.o 63 63 obj-$(CONFIG_SPRD_THERMAL) += sprd_thermal.o 64 + obj-$(CONFIG_KHADAS_MCU_FAN_THERMAL) += khadas_mcu_fan.o
+162
drivers/thermal/khadas_mcu_fan.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + /* 3 + * Khadas MCU Controlled FAN driver 4 + * 5 + * Copyright (C) 2020 BayLibre SAS 6 + * Author(s): Neil Armstrong <narmstrong@baylibre.com> 7 + */ 8 + 9 + #include <linux/module.h> 10 + #include <linux/of.h> 11 + #include <linux/platform_device.h> 12 + #include <linux/mfd/khadas-mcu.h> 13 + #include <linux/regmap.h> 14 + #include <linux/sysfs.h> 15 + #include <linux/thermal.h> 16 + 17 + #define MAX_LEVEL 3 18 + 19 + struct khadas_mcu_fan_ctx { 20 + struct khadas_mcu *mcu; 21 + unsigned int level; 22 + struct thermal_cooling_device *cdev; 23 + }; 24 + 25 + static int khadas_mcu_fan_set_level(struct khadas_mcu_fan_ctx *ctx, 26 + unsigned int level) 27 + { 28 + int ret; 29 + 30 + ret = regmap_write(ctx->mcu->regmap, KHADAS_MCU_CMD_FAN_STATUS_CTRL_REG, 31 + level); 32 + if (ret) 33 + return ret; 34 + 35 + ctx->level = level; 36 + 37 + return 0; 38 + } 39 + 40 + static int khadas_mcu_fan_get_max_state(struct thermal_cooling_device *cdev, 41 + unsigned long *state) 42 + { 43 + *state = MAX_LEVEL; 44 + 45 + return 0; 46 + } 47 + 48 + static int khadas_mcu_fan_get_cur_state(struct thermal_cooling_device *cdev, 49 + unsigned long *state) 50 + { 51 + struct khadas_mcu_fan_ctx *ctx = cdev->devdata; 52 + 53 + *state = ctx->level; 54 + 55 + return 0; 56 + } 57 + 58 + static int 59 + khadas_mcu_fan_set_cur_state(struct thermal_cooling_device *cdev, 60 + unsigned long state) 61 + { 62 + struct khadas_mcu_fan_ctx *ctx = cdev->devdata; 63 + 64 + if (state > MAX_LEVEL) 65 + return -EINVAL; 66 + 67 + if (state == ctx->level) 68 + return 0; 69 + 70 + return khadas_mcu_fan_set_level(ctx, state); 71 + } 72 + 73 + static const struct thermal_cooling_device_ops khadas_mcu_fan_cooling_ops = { 74 + .get_max_state = khadas_mcu_fan_get_max_state, 75 + .get_cur_state = khadas_mcu_fan_get_cur_state, 76 + .set_cur_state = khadas_mcu_fan_set_cur_state, 77 + }; 78 + 79 + static int khadas_mcu_fan_probe(struct platform_device *pdev) 80 + { 81 + struct khadas_mcu *mcu = dev_get_drvdata(pdev->dev.parent); 82 + struct thermal_cooling_device *cdev; 83 + struct device *dev = &pdev->dev; 84 + struct khadas_mcu_fan_ctx *ctx; 85 + int ret; 86 + 87 + ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); 88 + if (!ctx) 89 + return -ENOMEM; 90 + ctx->mcu = mcu; 91 + platform_set_drvdata(pdev, ctx); 92 + 93 + cdev = devm_thermal_of_cooling_device_register(dev->parent, 94 + dev->parent->of_node, "khadas-mcu-fan", ctx, 95 + &khadas_mcu_fan_cooling_ops); 96 + if (IS_ERR(cdev)) { 97 + ret = PTR_ERR(cdev); 98 + dev_err(dev, "Failed to register khadas-mcu-fan as cooling device: %d\n", 99 + ret); 100 + return ret; 101 + } 102 + ctx->cdev = cdev; 103 + thermal_cdev_update(cdev); 104 + 105 + return 0; 106 + } 107 + 108 + static void khadas_mcu_fan_shutdown(struct platform_device *pdev) 109 + { 110 + struct khadas_mcu_fan_ctx *ctx = platform_get_drvdata(pdev); 111 + 112 + khadas_mcu_fan_set_level(ctx, 0); 113 + } 114 + 115 + #ifdef CONFIG_PM_SLEEP 116 + static int khadas_mcu_fan_suspend(struct device *dev) 117 + { 118 + struct khadas_mcu_fan_ctx *ctx = dev_get_drvdata(dev); 119 + unsigned int level_save = ctx->level; 120 + int ret; 121 + 122 + ret = khadas_mcu_fan_set_level(ctx, 0); 123 + if (ret) 124 + return ret; 125 + 126 + ctx->level = level_save; 127 + 128 + return 0; 129 + } 130 + 131 + static int khadas_mcu_fan_resume(struct device *dev) 132 + { 133 + struct khadas_mcu_fan_ctx *ctx = dev_get_drvdata(dev); 134 + 135 + return khadas_mcu_fan_set_level(ctx, ctx->level); 136 + } 137 + #endif 138 + 139 + static SIMPLE_DEV_PM_OPS(khadas_mcu_fan_pm, khadas_mcu_fan_suspend, 140 + khadas_mcu_fan_resume); 141 + 142 + static const struct platform_device_id khadas_mcu_fan_id_table[] = { 143 + { .name = "khadas-mcu-fan-ctrl", }, 144 + {}, 145 + }; 146 + MODULE_DEVICE_TABLE(platform, khadas_mcu_fan_id_table); 147 + 148 + static struct platform_driver khadas_mcu_fan_driver = { 149 + .probe = khadas_mcu_fan_probe, 150 + .shutdown = khadas_mcu_fan_shutdown, 151 + .driver = { 152 + .name = "khadas-mcu-fan-ctrl", 153 + .pm = &khadas_mcu_fan_pm, 154 + }, 155 + .id_table = khadas_mcu_fan_id_table, 156 + }; 157 + 158 + module_platform_driver(khadas_mcu_fan_driver); 159 + 160 + MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>"); 161 + MODULE_DESCRIPTION("Khadas MCU FAN driver"); 162 + MODULE_LICENSE("GPL");
+31 -11
include/linux/mfd/core.h
··· 14 14 15 15 #define MFD_RES_SIZE(arr) (sizeof(arr) / sizeof(struct resource)) 16 16 17 - #define MFD_CELL_ALL(_name, _res, _pdata, _pdsize, _id, _compat, _match)\ 17 + #define MFD_CELL_ALL(_name, _res, _pdata, _pdsize, _id, _compat, _of_reg, _use_of_reg, _match) \ 18 18 { \ 19 19 .name = (_name), \ 20 20 .resources = (_res), \ ··· 22 22 .platform_data = (_pdata), \ 23 23 .pdata_size = (_pdsize), \ 24 24 .of_compatible = (_compat), \ 25 + .of_reg = (_of_reg), \ 26 + .use_of_reg = (_use_of_reg), \ 25 27 .acpi_match = (_match), \ 26 28 .id = (_id), \ 27 29 } 28 30 29 - #define OF_MFD_CELL(_name, _res, _pdata, _pdsize,_id, _compat) \ 30 - MFD_CELL_ALL(_name, _res, _pdata, _pdsize, _id, _compat, NULL) \ 31 + #define OF_MFD_CELL_REG(_name, _res, _pdata, _pdsize, _id, _compat, _of_reg) \ 32 + MFD_CELL_ALL(_name, _res, _pdata, _pdsize, _id, _compat, _of_reg, true, NULL) 31 33 32 - #define ACPI_MFD_CELL(_name, _res, _pdata, _pdsize, _id, _match) \ 33 - MFD_CELL_ALL(_name, _res, _pdata, _pdsize, _id, NULL, _match) \ 34 + #define OF_MFD_CELL(_name, _res, _pdata, _pdsize, _id, _compat) \ 35 + MFD_CELL_ALL(_name, _res, _pdata, _pdsize, _id, _compat, 0, false, NULL) 34 36 35 - #define MFD_CELL_BASIC(_name, _res, _pdata, _pdsize, _id) \ 36 - MFD_CELL_ALL(_name, _res, _pdata, _pdsize, _id, NULL, NULL) \ 37 + #define ACPI_MFD_CELL(_name, _res, _pdata, _pdsize, _id, _match) \ 38 + MFD_CELL_ALL(_name, _res, _pdata, _pdsize, _id, NULL, 0, false, _match) 37 39 38 - #define MFD_CELL_RES(_name, _res) \ 39 - MFD_CELL_ALL(_name, _res, NULL, 0, 0, NULL, NULL) \ 40 + #define MFD_CELL_BASIC(_name, _res, _pdata, _pdsize, _id) \ 41 + MFD_CELL_ALL(_name, _res, _pdata, _pdsize, _id, NULL, 0, false, NULL) 40 42 41 - #define MFD_CELL_NAME(_name) \ 42 - MFD_CELL_ALL(_name, NULL, NULL, 0, 0, NULL, NULL) \ 43 + #define MFD_CELL_RES(_name, _res) \ 44 + MFD_CELL_ALL(_name, _res, NULL, 0, 0, NULL, 0, false, NULL) 45 + 46 + #define MFD_CELL_NAME(_name) \ 47 + MFD_CELL_ALL(_name, NULL, NULL, 0, 0, NULL, 0, false, NULL) 48 + 49 + #define MFD_DEP_LEVEL_NORMAL 0 50 + #define MFD_DEP_LEVEL_HIGH 1 43 51 44 52 struct irq_domain; 45 53 struct property_entry; ··· 66 58 struct mfd_cell { 67 59 const char *name; 68 60 int id; 61 + int level; 69 62 70 63 int (*enable)(struct platform_device *dev); 71 64 int (*disable)(struct platform_device *dev); ··· 86 77 * See: Documentation/devicetree/usage-model.rst Chapter 2.2 for details 87 78 */ 88 79 const char *of_compatible; 80 + 81 + /* 82 + * Address as defined in Device Tree. Used to compement 'of_compatible' 83 + * (above) when matching OF nodes with devices that have identical 84 + * compatible strings 85 + */ 86 + const u64 of_reg; 87 + 88 + /* Set to 'true' to use 'of_reg' (above) - allows for of_reg=0 */ 89 + bool use_of_reg; 89 90 90 91 /* Matches ACPI */ 91 92 const struct mfd_cell_acpi_match *acpi_match; ··· 154 135 } 155 136 156 137 extern void mfd_remove_devices(struct device *parent); 138 + extern void mfd_remove_devices_late(struct device *parent); 157 139 158 140 extern int devm_mfd_add_devices(struct device *dev, int id, 159 141 const struct mfd_cell *cells, int n_devs,
+1 -1
include/linux/mfd/da9055/pdata.h
··· 35 35 int *gpio_rsel; 36 36 /* 37 37 * Regulator mode control bits value (GPI offset) that 38 - * that controls the regulator state, 0 if not available. 38 + * controls the regulator state, 0 if not available. 39 39 */ 40 40 enum gpio_select *reg_ren; 41 41 /*
+1
include/linux/mfd/da9063/core.h
··· 35 35 PMIC_DA9063_AD = 0x3, 36 36 PMIC_DA9063_BB = 0x5, 37 37 PMIC_DA9063_CA = 0x6, 38 + PMIC_DA9063_DA = 0x7, 38 39 }; 39 40 40 41 /* Interrupts */
+10 -5
include/linux/mfd/da9063/registers.h
··· 292 292 #define DA9063_BB_REG_GP_ID_19 0x134 293 293 294 294 /* Chip ID and variant */ 295 - #define DA9063_REG_CHIP_ID 0x181 296 - #define DA9063_REG_CHIP_VARIANT 0x182 295 + #define DA9063_REG_DEVICE_ID 0x181 296 + #define DA9063_REG_VARIANT_ID 0x182 297 + #define DA9063_REG_CUSTOMER_ID 0x183 298 + #define DA9063_REG_CONFIG_ID 0x184 297 299 298 300 /* 299 301 * PMIC registers bits ··· 931 929 #define DA9063_RTC_CLOCK 0x40 932 930 #define DA9063_OUT_32K_EN 0x80 933 931 934 - /* DA9063_REG_CHIP_VARIANT */ 935 - #define DA9063_CHIP_VARIANT_SHIFT 4 936 - 937 932 /* DA9063_REG_BUCK_ILIM_A (addr=0x9A) */ 938 933 #define DA9063_BIO_ILIM_MASK 0x0F 939 934 #define DA9063_BMEM_ILIM_MASK 0xF0 ··· 1063 1064 #define DA9063_MON_A10_IDX_LDO8 0x03 1064 1065 #define DA9063_MON_A10_IDX_LDO9 0x04 1065 1066 #define DA9063_MON_A10_IDX_LDO10 0x05 1067 + 1068 + /* DA9063_REG_VARIANT_ID (addr=0x182) */ 1069 + #define DA9063_VARIANT_ID_VRC_SHIFT 0 1070 + #define DA9063_VARIANT_ID_VRC_MASK 0x0F 1071 + #define DA9063_VARIANT_ID_MRC_SHIFT 4 1072 + #define DA9063_VARIANT_ID_MRC_MASK 0xF0 1066 1073 1067 1074 #endif /* _DA9063_REG_H */
+1 -1
include/linux/mfd/hi6421-pmic.h
··· 5 5 * Copyright (c) <2011-2014> HiSilicon Technologies Co., Ltd. 6 6 * http://www.hisilicon.com 7 7 * Copyright (c) <2013-2014> Linaro Ltd. 8 - * http://www.linaro.org 8 + * https://www.linaro.org 9 9 * 10 10 * Author: Guodong Xu <guodong.xu@linaro.org> 11 11 */
+91
include/linux/mfd/khadas-mcu.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * Khadas System control Microcontroller Register map 4 + * 5 + * Copyright (C) 2020 BayLibre SAS 6 + * 7 + * Author(s): Neil Armstrong <narmstrong@baylibre.com> 8 + */ 9 + 10 + #ifndef MFD_KHADAS_MCU_H 11 + #define MFD_KHADAS_MCU_H 12 + 13 + #define KHADAS_MCU_PASSWD_VEN_0_REG 0x00 /* RO */ 14 + #define KHADAS_MCU_PASSWD_VEN_1_REG 0x01 /* RO */ 15 + #define KHADAS_MCU_PASSWD_VEN_2_REG 0x02 /* RO */ 16 + #define KHADAS_MCU_PASSWD_VEN_3_REG 0x03 /* RO */ 17 + #define KHADAS_MCU_PASSWD_VEN_4_REG 0x04 /* RO */ 18 + #define KHADAS_MCU_PASSWD_VEN_5_REG 0x05 /* RO */ 19 + #define KHADAS_MCU_MAC_0_REG 0x06 /* RO */ 20 + #define KHADAS_MCU_MAC_1_REG 0x07 /* RO */ 21 + #define KHADAS_MCU_MAC_2_REG 0x08 /* RO */ 22 + #define KHADAS_MCU_MAC_3_REG 0x09 /* RO */ 23 + #define KHADAS_MCU_MAC_4_REG 0x0a /* RO */ 24 + #define KHADAS_MCU_MAC_5_REG 0x0b /* RO */ 25 + #define KHADAS_MCU_USID_0_REG 0x0c /* RO */ 26 + #define KHADAS_MCU_USID_1_REG 0x0d /* RO */ 27 + #define KHADAS_MCU_USID_2_REG 0x0e /* RO */ 28 + #define KHADAS_MCU_USID_3_REG 0x0f /* RO */ 29 + #define KHADAS_MCU_USID_4_REG 0x10 /* RO */ 30 + #define KHADAS_MCU_USID_5_REG 0x11 /* RO */ 31 + #define KHADAS_MCU_VERSION_0_REG 0x12 /* RO */ 32 + #define KHADAS_MCU_VERSION_1_REG 0x13 /* RO */ 33 + #define KHADAS_MCU_DEVICE_NO_0_REG 0x14 /* RO */ 34 + #define KHADAS_MCU_DEVICE_NO_1_REG 0x15 /* RO */ 35 + #define KHADAS_MCU_FACTORY_TEST_REG 0x16 /* R */ 36 + #define KHADAS_MCU_BOOT_MODE_REG 0x20 /* RW */ 37 + #define KHADAS_MCU_BOOT_EN_WOL_REG 0x21 /* RW */ 38 + #define KHADAS_MCU_BOOT_EN_RTC_REG 0x22 /* RW */ 39 + #define KHADAS_MCU_BOOT_EN_EXP_REG 0x23 /* RW */ 40 + #define KHADAS_MCU_BOOT_EN_IR_REG 0x24 /* RW */ 41 + #define KHADAS_MCU_BOOT_EN_DCIN_REG 0x25 /* RW */ 42 + #define KHADAS_MCU_BOOT_EN_KEY_REG 0x26 /* RW */ 43 + #define KHADAS_MCU_KEY_MODE_REG 0x27 /* RW */ 44 + #define KHADAS_MCU_LED_MODE_ON_REG 0x28 /* RW */ 45 + #define KHADAS_MCU_LED_MODE_OFF_REG 0x29 /* RW */ 46 + #define KHADAS_MCU_SHUTDOWN_NORMAL_REG 0x2c /* RW */ 47 + #define KHADAS_MCU_MAC_SWITCH_REG 0x2d /* RW */ 48 + #define KHADAS_MCU_MCU_SLEEP_MODE_REG 0x2e /* RW */ 49 + #define KHADAS_MCU_IR_CODE1_0_REG 0x2f /* RW */ 50 + #define KHADAS_MCU_IR_CODE1_1_REG 0x30 /* RW */ 51 + #define KHADAS_MCU_IR_CODE1_2_REG 0x31 /* RW */ 52 + #define KHADAS_MCU_IR_CODE1_3_REG 0x32 /* RW */ 53 + #define KHADAS_MCU_USB_PCIE_SWITCH_REG 0x33 /* RW */ 54 + #define KHADAS_MCU_IR_CODE2_0_REG 0x34 /* RW */ 55 + #define KHADAS_MCU_IR_CODE2_1_REG 0x35 /* RW */ 56 + #define KHADAS_MCU_IR_CODE2_2_REG 0x36 /* RW */ 57 + #define KHADAS_MCU_IR_CODE2_3_REG 0x37 /* RW */ 58 + #define KHADAS_MCU_PASSWD_USER_0_REG 0x40 /* RW */ 59 + #define KHADAS_MCU_PASSWD_USER_1_REG 0x41 /* RW */ 60 + #define KHADAS_MCU_PASSWD_USER_2_REG 0x42 /* RW */ 61 + #define KHADAS_MCU_PASSWD_USER_3_REG 0x43 /* RW */ 62 + #define KHADAS_MCU_PASSWD_USER_4_REG 0x44 /* RW */ 63 + #define KHADAS_MCU_PASSWD_USER_5_REG 0x45 /* RW */ 64 + #define KHADAS_MCU_USER_DATA_0_REG 0x46 /* RW 56 bytes */ 65 + #define KHADAS_MCU_PWR_OFF_CMD_REG 0x80 /* WO */ 66 + #define KHADAS_MCU_PASSWD_START_REG 0x81 /* WO */ 67 + #define KHADAS_MCU_CHECK_VEN_PASSWD_REG 0x82 /* WO */ 68 + #define KHADAS_MCU_CHECK_USER_PASSWD_REG 0x83 /* WO */ 69 + #define KHADAS_MCU_SHUTDOWN_NORMAL_STATUS_REG 0x86 /* RO */ 70 + #define KHADAS_MCU_WOL_INIT_START_REG 0x87 /* WO */ 71 + #define KHADAS_MCU_CMD_FAN_STATUS_CTRL_REG 0x88 /* WO */ 72 + 73 + enum { 74 + KHADAS_BOARD_VIM1 = 0x1, 75 + KHADAS_BOARD_VIM2, 76 + KHADAS_BOARD_VIM3, 77 + KHADAS_BOARD_EDGE = 0x11, 78 + KHADAS_BOARD_EDGE_V, 79 + }; 80 + 81 + /** 82 + * struct khadas_mcu - Khadas MCU structure 83 + * @device: device reference used for logs 84 + * @regmap: register map 85 + */ 86 + struct khadas_mcu { 87 + struct device *dev; 88 + struct regmap *regmap; 89 + }; 90 + 91 + #endif /* MFD_KHADAS_MCU_H */
+1 -1
include/linux/mfd/lp873x.h
··· 1 1 /* 2 2 * Functions to access LP873X power management chip. 3 3 * 4 - * Copyright (C) 2016 Texas Instruments Incorporated - http://www.ti.com/ 4 + * Copyright (C) 2016 Texas Instruments Incorporated - https://www.ti.com/ 5 5 * 6 6 * This program is free software; you can redistribute it and/or 7 7 * modify it under the terms of the GNU General Public License as
+1 -1
include/linux/mfd/lp87565.h
··· 2 2 /* 3 3 * Functions to access LP87565 power management chip. 4 4 * 5 - * Copyright (C) 2017 Texas Instruments Incorporated - http://www.ti.com/ 5 + * Copyright (C) 2017 Texas Instruments Incorporated - https://www.ti.com/ 6 6 */ 7 7 8 8 #ifndef __LINUX_MFD_LP87565_H
-1
include/linux/mfd/madera/pdata.h
··· 21 21 22 22 struct gpio_desc; 23 23 struct pinctrl_map; 24 - struct madera_codec_pdata; 25 24 26 25 /** 27 26 * struct madera_pdata - Configuration data for Madera devices
+1 -1
include/linux/mfd/max77693-private.h
··· 131 131 #define FLASH_INT_FLED1_SHORT BIT(3) 132 132 #define FLASH_INT_OVER_CURRENT BIT(4) 133 133 134 - /* Fast charge timer in in hours */ 134 + /* Fast charge timer in hours */ 135 135 #define DEFAULT_FAST_CHARGE_TIMER 4 136 136 /* microamps */ 137 137 #define DEFAULT_TOP_OFF_THRESHOLD_CURRENT 150000
-104
include/linux/mfd/smsc.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 - /* 3 - * SMSC ECE1099 4 - * 5 - * Copyright 2012 Texas Instruments Inc. 6 - * 7 - * Author: Sourav Poddar <sourav.poddar@ti.com> 8 - */ 9 - 10 - #ifndef __LINUX_MFD_SMSC_H 11 - #define __LINUX_MFD_SMSC_H 12 - 13 - #include <linux/regmap.h> 14 - 15 - #define SMSC_ID_ECE1099 1 16 - #define SMSC_NUM_CLIENTS 2 17 - 18 - #define SMSC_BASE_ADDR 0x38 19 - #define OMAP_GPIO_SMSC_IRQ 151 20 - 21 - #define SMSC_MAXGPIO 32 22 - #define SMSC_BANK(offs) ((offs) >> 3) 23 - #define SMSC_BIT(offs) (1u << ((offs) & 0x7)) 24 - 25 - struct smsc { 26 - struct device *dev; 27 - struct i2c_client *i2c_clients[SMSC_NUM_CLIENTS]; 28 - struct regmap *regmap; 29 - int clk; 30 - /* Stored chip id */ 31 - int id; 32 - }; 33 - 34 - struct smsc_gpio; 35 - struct smsc_keypad; 36 - 37 - static inline int smsc_read(struct device *child, unsigned int reg, 38 - unsigned int *dest) 39 - { 40 - struct smsc *smsc = dev_get_drvdata(child->parent); 41 - 42 - return regmap_read(smsc->regmap, reg, dest); 43 - } 44 - 45 - static inline int smsc_write(struct device *child, unsigned int reg, 46 - unsigned int value) 47 - { 48 - struct smsc *smsc = dev_get_drvdata(child->parent); 49 - 50 - return regmap_write(smsc->regmap, reg, value); 51 - } 52 - 53 - /* Registers for SMSC */ 54 - #define SMSC_RESET 0xF5 55 - #define SMSC_GRP_INT 0xF9 56 - #define SMSC_CLK_CTRL 0xFA 57 - #define SMSC_WKUP_CTRL 0xFB 58 - #define SMSC_DEV_ID 0xFC 59 - #define SMSC_DEV_REV 0xFD 60 - #define SMSC_VEN_ID_L 0xFE 61 - #define SMSC_VEN_ID_H 0xFF 62 - 63 - /* CLK VALUE */ 64 - #define SMSC_CLK_VALUE 0x13 65 - 66 - /* Registers for function GPIO INPUT */ 67 - #define SMSC_GPIO_DATA_IN_START 0x00 68 - 69 - /* Registers for function GPIO OUPUT */ 70 - #define SMSC_GPIO_DATA_OUT_START 0x05 71 - 72 - /* Definitions for SMSC GPIO CONFIGURATION REGISTER*/ 73 - #define SMSC_GPIO_INPUT_LOW 0x01 74 - #define SMSC_GPIO_INPUT_RISING 0x09 75 - #define SMSC_GPIO_INPUT_FALLING 0x11 76 - #define SMSC_GPIO_INPUT_BOTH_EDGE 0x19 77 - #define SMSC_GPIO_OUTPUT_PP 0x21 78 - #define SMSC_GPIO_OUTPUT_OP 0x31 79 - 80 - #define GRP_INT_STAT 0xf9 81 - #define SMSC_GPI_INT 0x0f 82 - #define SMSC_CFG_START 0x0A 83 - 84 - /* Registers for SMSC GPIO INTERRUPT STATUS REGISTER*/ 85 - #define SMSC_GPIO_INT_STAT_START 0x32 86 - 87 - /* Registers for SMSC GPIO INTERRUPT MASK REGISTER*/ 88 - #define SMSC_GPIO_INT_MASK_START 0x37 89 - 90 - /* Registers for SMSC function KEYPAD*/ 91 - #define SMSC_KP_OUT 0x40 92 - #define SMSC_KP_IN 0x41 93 - #define SMSC_KP_INT_STAT 0x42 94 - #define SMSC_KP_INT_MASK 0x43 95 - 96 - /* Definitions for keypad */ 97 - #define SMSC_KP_KSO 0x70 98 - #define SMSC_KP_KSI 0x51 99 - #define SMSC_KSO_ALL_LOW 0x20 100 - #define SMSC_KP_SET_LOW_PWR 0x0B 101 - #define SMSC_KP_SET_HIGH 0xFF 102 - #define SMSC_KSO_EVAL 0x00 103 - 104 - #endif /* __LINUX_MFD_SMSC_H */
+5
include/linux/mfd/stm32-lptimer.h
··· 27 27 #define STM32_LPTIM_CMPOK BIT(3) 28 28 29 29 /* STM32_LPTIM_ICR - bit fields */ 30 + #define STM32_LPTIM_ARRMCF BIT(1) 30 31 #define STM32_LPTIM_CMPOKCF_ARROKCF GENMASK(4, 3) 32 + 33 + /* STM32_LPTIM_IER - bit flieds */ 34 + #define STM32_LPTIM_ARRMIE BIT(1) 31 35 32 36 /* STM32_LPTIM_CR - bit fields */ 33 37 #define STM32_LPTIM_CNTSTRT BIT(2) 38 + #define STM32_LPTIM_SNGSTRT BIT(1) 34 39 #define STM32_LPTIM_ENABLE BIT(0) 35 40 36 41 /* STM32_LPTIM_CFGR - bit fields */
+1 -1
include/linux/mfd/ti_am335x_tscadc.h
··· 4 4 /* 5 5 * TI Touch Screen / ADC MFD driver 6 6 * 7 - * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ 7 + * Copyright (C) 2012 Texas Instruments Incorporated - https://www.ti.com/ 8 8 * 9 9 * This program is free software; you can redistribute it and/or 10 10 * modify it under the terms of the GNU General Public License as
+1 -1
include/linux/mfd/tps65086.h
··· 1 1 /* 2 - * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/ 2 + * Copyright (C) 2015 Texas Instruments Incorporated - https://www.ti.com/ 3 3 * Andrew F. Davis <afd@ti.com> 4 4 * 5 5 * This program is free software; you can redistribute it and/or
+1 -1
include/linux/mfd/tps65217.h
··· 3 3 * 4 4 * Functions to access TPS65217 power management chip. 5 5 * 6 - * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ 6 + * Copyright (C) 2011 Texas Instruments Incorporated - https://www.ti.com/ 7 7 * 8 8 * This program is free software; you can redistribute it and/or 9 9 * modify it under the terms of the GNU General Public License as
+1 -1
include/linux/mfd/tps65218.h
··· 3 3 * 4 4 * Functions to access TPS65219 power management chip. 5 5 * 6 - * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/ 6 + * Copyright (C) 2014 Texas Instruments Incorporated - https://www.ti.com/ 7 7 * 8 8 * This program is free software; you can redistribute it and/or 9 9 * modify it under the terms of the GNU General Public License version 2 as
+1 -1
include/linux/mfd/tps65912.h
··· 1 1 /* 2 - * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/ 2 + * Copyright (C) 2015 Texas Instruments Incorporated - https://www.ti.com/ 3 3 * Andrew F. Davis <afd@ti.com> 4 4 * 5 5 * This program is free software; you can redistribute it and/or