summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2023-11-03 03:40:51 +0300
committerLinus Torvalds <torvalds@linux-foundation.org>2023-11-03 03:40:51 +0300
commit27bc0782ef8ec26ed94b9fa16c75c11fdb3cd78b (patch)
treeffaaa95c5a435ef5f3afc234f32481feb12d0de2
parentedd8e84ae9514e93368f56c3715b11af52df6c3b (diff)
parent2b481822446e30943fb7c02744a7b49ebec0e696 (diff)
downloadlinux-27bc0782ef8ec26ed94b9fa16c75c11fdb3cd78b.tar.xz
Merge tag 'mfd-next-6.7' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd
Pull MFD updates from Lee Jones: "Core Frameworks: - Allow all MFD Cell properties to be filled in dynamically at runtime - Skip disabled device nodes and continue to look for subsequent devices New Device Support: - Add support for Lunar Lake-M PCI to Intel LPSS PCI - Add support for Denverton to Intel ICH LPC New Functionality: - Add support for Clocks to Texas Instruments TWL* Core - Add support for Interrupts to STMicroelectronics STM32 Timers Fix-ups: - Convert to new devm-* (managed) power-off API - Remove superfluous code - Bunch of Device Tree additions, conversions and adaptions - Simplify obtaining resources (memory, device data) using unified API helpers - Trivial coding-style / spelling type clean-ups - Constify / staticify changes - Expand or edit on existing documentation - Convert some Regmap configurations to use the Maple Tree cache - Apply new __counted_by() annotation to several data structures containing flexible arrays - Replace strncpy() with strscpy() Bug Fixes: - Remove double put creating reference imbalances - Ensure headphone/lineout detection gets set when booting with ACPI" * tag 'mfd-next-6.7' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd: (73 commits) mfd: lpc_ich: Mark *_gpio_offsets data with const spmi: rename spmi device lookup helper spmi: document spmi_device_from_of() refcounting dt-bindings: mfd: armltd: Move Arm board syscon's to separate schema mfd: rk8xx: Add support for RK806 power off mfd: rk8xx: Add support for standard system-power-controller property dt-bindings: mfd: rk806: Allow system-power-controller property dt-bindings: mfd: rk8xx: Deprecate rockchip,system-power-controller dt-bindings: mfd: max8925: Convert to DT schema format mfd: Use i2c_get_match_data() in a selection of drivers mfd: Use device_get_match_data() in a bunch of drivers mfd: mc13xxx-spi/wm831x-spi: Use spi_get_device_match_data() mfd: motorola-cpcap: Drop unnecessary of_match_device() call mfd: arizona-spi: Set pdata.hpdet_channel for ACPI enumerated devs mfd: qcom-spmi-pmic: Switch to EXPORT_SYMBOL_GPL() mfd: qcom-spmi-pmic: Fix revid implementation mfd: qcom-spmi-pmic: Fix reference leaks in revid helper mfd: intel-m10-bmc: Change contact for ABI docs mfd: max8907: Convert to use maple tree register cache mfd: max77686: Convert to use maple tree register cache ...
-rw-r--r--Documentation/ABI/testing/sysfs-driver-intel-m10-bmc4
-rw-r--r--Documentation/devicetree/bindings/arm/arm,integrator.yaml39
-rw-r--r--Documentation/devicetree/bindings/arm/arm,realview.yaml37
-rw-r--r--Documentation/devicetree/bindings/arm/arm,versatile.yaml40
-rw-r--r--Documentation/devicetree/bindings/input/twl4030-pwrbutton.txt2
-rw-r--r--Documentation/devicetree/bindings/leds/backlight/max8925-backlight.txt10
-rw-r--r--Documentation/devicetree/bindings/leds/register-bit-led.yaml2
-rw-r--r--Documentation/devicetree/bindings/mfd/arm,dev-platforms-syscon.yaml67
-rw-r--r--Documentation/devicetree/bindings/mfd/max8925.txt64
-rw-r--r--Documentation/devicetree/bindings/mfd/max8998.txt125
-rw-r--r--Documentation/devicetree/bindings/mfd/maxim,max5970.yaml5
-rw-r--r--Documentation/devicetree/bindings/mfd/maxim,max8925.yaml145
-rw-r--r--Documentation/devicetree/bindings/mfd/maxim,max8998.yaml324
-rw-r--r--Documentation/devicetree/bindings/mfd/mediatek,mt6357.yaml2
-rw-r--r--Documentation/devicetree/bindings/mfd/mt6397.txt4
-rw-r--r--Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml11
-rw-r--r--Documentation/devicetree/bindings/mfd/qcom,tcsr.yaml1
-rw-r--r--Documentation/devicetree/bindings/mfd/qcom-pm8xxx.yaml26
-rw-r--r--Documentation/devicetree/bindings/mfd/rockchip,rk805.yaml4
-rw-r--r--Documentation/devicetree/bindings/mfd/rockchip,rk806.yaml2
-rw-r--r--Documentation/devicetree/bindings/mfd/rockchip,rk808.yaml4
-rw-r--r--Documentation/devicetree/bindings/mfd/rockchip,rk809.yaml6
-rw-r--r--Documentation/devicetree/bindings/mfd/rockchip,rk817.yaml3
-rw-r--r--Documentation/devicetree/bindings/mfd/rockchip,rk818.yaml4
-rw-r--r--Documentation/devicetree/bindings/mfd/stericsson,db8500-prcmu.yaml2
-rw-r--r--Documentation/devicetree/bindings/mfd/syscon.yaml2
-rw-r--r--Documentation/devicetree/bindings/mfd/ti,lp87524-q1.yaml1
-rw-r--r--Documentation/devicetree/bindings/mfd/ti,lp87561-q1.yaml1
-rw-r--r--Documentation/devicetree/bindings/mfd/ti,lp87565-q1.yaml1
-rw-r--r--Documentation/devicetree/bindings/mfd/ti,twl.yaml67
-rw-r--r--Documentation/devicetree/bindings/mfd/twl-family.txt46
-rw-r--r--Documentation/devicetree/bindings/mfd/x-powers,axp152.yaml5
-rw-r--r--Documentation/devicetree/bindings/power/supply/max8925_battery.txt18
-rw-r--r--drivers/i2c/i2c-core.h2
-rw-r--r--drivers/mfd/arizona-i2c.c11
-rw-r--r--drivers/mfd/arizona-spi.c3
-rw-r--r--drivers/mfd/atmel-hlcdc.c1
-rw-r--r--drivers/mfd/axp20x.c66
-rw-r--r--drivers/mfd/db8500-prcmu.c4
-rw-r--r--drivers/mfd/dln2.c1
-rw-r--r--drivers/mfd/hi6421-pmic-core.c9
-rw-r--r--drivers/mfd/intel-lpss-pci.c13
-rw-r--r--drivers/mfd/iqs62x.c2
-rw-r--r--drivers/mfd/lochnagar-i2c.c9
-rw-r--r--drivers/mfd/lp87565.c9
-rw-r--r--drivers/mfd/lpc_ich.c127
-rw-r--r--drivers/mfd/madera-i2c.c9
-rw-r--r--drivers/mfd/max14577.c14
-rw-r--r--drivers/mfd/max77541.c6
-rw-r--r--drivers/mfd/max77620.c6
-rw-r--r--drivers/mfd/max77686.c2
-rw-r--r--drivers/mfd/max8907.c4
-rw-r--r--drivers/mfd/max8997.c12
-rw-r--r--drivers/mfd/max8998.c12
-rw-r--r--drivers/mfd/mc13xxx-spi.c14
-rw-r--r--drivers/mfd/mfd-core.c17
-rw-r--r--drivers/mfd/motorola-cpcap.c7
-rw-r--r--drivers/mfd/mxs-lradc.c9
-rw-r--r--drivers/mfd/palmas.c60
-rw-r--r--drivers/mfd/qcom-spmi-pmic.c109
-rw-r--r--drivers/mfd/qcom_rpm.c8
-rw-r--r--drivers/mfd/rk8xx-core.c7
-rw-r--r--drivers/mfd/rk8xx-i2c.c6
-rw-r--r--drivers/mfd/rn5t618.c11
-rw-r--r--drivers/mfd/stm32-timers.c46
-rw-r--r--drivers/mfd/tps65086.c2
-rw-r--r--drivers/mfd/tps65090.c2
-rw-r--r--drivers/mfd/tps65218.c2
-rw-r--r--drivers/mfd/tps6586x.c52
-rw-r--r--drivers/mfd/tps65910.c13
-rw-r--r--drivers/mfd/tps65912-core.c2
-rw-r--r--drivers/mfd/twl-core.c18
-rw-r--r--drivers/mfd/twl4030-power.c9
-rw-r--r--drivers/mfd/twl6030-irq.c10
-rw-r--r--drivers/mfd/wcd934x.c2
-rw-r--r--drivers/mfd/wm831x-i2c.c16
-rw-r--r--drivers/mfd/wm831x-spi.c16
-rw-r--r--drivers/mfd/wm8994-core.c11
-rw-r--r--drivers/spmi/spmi.c9
-rw-r--r--include/linux/mfd/abx500/ab8500.h6
-rw-r--r--include/linux/mfd/core.h2
-rw-r--r--include/linux/mfd/lpc_ich.h7
-rw-r--r--include/linux/mfd/stm32-timers.h11
-rw-r--r--include/linux/reboot.h3
-rw-r--r--include/linux/spmi.h2
-rw-r--r--kernel/reboot.c4
86 files changed, 1159 insertions, 730 deletions
diff --git a/Documentation/ABI/testing/sysfs-driver-intel-m10-bmc b/Documentation/ABI/testing/sysfs-driver-intel-m10-bmc
index a8ab58035c95..c12316dfd973 100644
--- a/Documentation/ABI/testing/sysfs-driver-intel-m10-bmc
+++ b/Documentation/ABI/testing/sysfs-driver-intel-m10-bmc
@@ -17,7 +17,7 @@ Description: Read only. Returns the firmware version of Intel MAX10
What: /sys/bus/.../drivers/intel-m10-bmc/.../mac_address
Date: January 2021
KernelVersion: 5.12
-Contact: Russ Weight <russell.h.weight@intel.com>
+Contact: Peter Colberg <peter.colberg@intel.com>
Description: Read only. Returns the first MAC address in a block
of sequential MAC addresses assigned to the board
that is managed by the Intel MAX10 BMC. It is stored in
@@ -28,7 +28,7 @@ Description: Read only. Returns the first MAC address in a block
What: /sys/bus/.../drivers/intel-m10-bmc/.../mac_count
Date: January 2021
KernelVersion: 5.12
-Contact: Russ Weight <russell.h.weight@intel.com>
+Contact: Peter Colberg <peter.colberg@intel.com>
Description: Read only. Returns the number of sequential MAC
addresses assigned to the board managed by the Intel
MAX10 BMC. This value is stored in FLASH and is mirrored
diff --git a/Documentation/devicetree/bindings/arm/arm,integrator.yaml b/Documentation/devicetree/bindings/arm/arm,integrator.yaml
index 98ff5698ae1f..1bdbd1b7ee38 100644
--- a/Documentation/devicetree/bindings/arm/arm,integrator.yaml
+++ b/Documentation/devicetree/bindings/arm/arm,integrator.yaml
@@ -40,45 +40,6 @@ properties:
items:
- const: arm,integrator-sp
- core-module@10000000:
- type: object
- description: the root node in the Integrator platforms must contain
- a core module child node. They are always at physical address
- 0x10000000 in all the Integrator variants.
- properties:
- compatible:
- items:
- - const: arm,core-module-integrator
- - const: syscon
- - const: simple-mfd
- reg:
- maxItems: 1
-
- required:
- - compatible
- - reg
-
-patternProperties:
- "^syscon@[0-9a-f]+$":
- description: All Integrator boards must provide a system controller as a
- node in the root of the device tree.
- type: object
- properties:
- compatible:
- items:
- - enum:
- - arm,integrator-ap-syscon
- - arm,integrator-cp-syscon
- - arm,integrator-sp-syscon
- - const: syscon
- reg:
- maxItems: 1
-
- required:
- - compatible
- - reg
-
-
required:
- compatible
- core-module@10000000
diff --git a/Documentation/devicetree/bindings/arm/arm,realview.yaml b/Documentation/devicetree/bindings/arm/arm,realview.yaml
index 8d3ed2e4ed31..d1bdee98f9af 100644
--- a/Documentation/devicetree/bindings/arm/arm,realview.yaml
+++ b/Documentation/devicetree/bindings/arm/arm,realview.yaml
@@ -75,43 +75,6 @@ properties:
type: object
description: All RealView boards must provide a syscon system controller
node inside the soc node.
- properties:
- compatible:
- oneOf:
- - items:
- - const: arm,realview-eb11mp-revb-syscon
- - const: arm,realview-eb-syscon
- - const: syscon
- - const: simple-mfd
- - items:
- - const: arm,realview-eb11mp-revc-syscon
- - const: arm,realview-eb-syscon
- - const: syscon
- - const: simple-mfd
- - items:
- - const: arm,realview-eb-syscon
- - const: syscon
- - const: simple-mfd
- - items:
- - const: arm,realview-pb1176-syscon
- - const: syscon
- - const: simple-mfd
- - items:
- - const: arm,realview-pb11mp-syscon
- - const: syscon
- - const: simple-mfd
- - items:
- - const: arm,realview-pba8-syscon
- - const: syscon
- - const: simple-mfd
- - items:
- - const: arm,realview-pbx-syscon
- - const: syscon
- - const: simple-mfd
-
- required:
- - compatible
- - reg
required:
- compatible
diff --git a/Documentation/devicetree/bindings/arm/arm,versatile.yaml b/Documentation/devicetree/bindings/arm/arm,versatile.yaml
index 13e52ba92060..7a3caf6af200 100644
--- a/Documentation/devicetree/bindings/arm/arm,versatile.yaml
+++ b/Documentation/devicetree/bindings/arm/arm,versatile.yaml
@@ -14,6 +14,14 @@ description: |+
with various pluggable interface boards, in essence the Versatile PB version
is a superset of the Versatile AB version.
+ The root node in the Versatile platforms must contain a core module child
+ node. They are always at physical address 0x10000000 in all the Versatile
+ variants.
+
+ When fitted with the IB2 Interface Board, the Versatile AB will present an
+ optional system controller node which controls the extra peripherals on the
+ interface board.
+
properties:
$nodename:
const: '/'
@@ -32,38 +40,6 @@ properties:
items:
- const: arm,versatile-pb
- core-module@10000000:
- type: object
- description: the root node in the Versatile platforms must contain
- a core module child node. They are always at physical address
- 0x10000000 in all the Versatile variants.
- properties:
- compatible:
- items:
- - const: arm,core-module-versatile
- - const: syscon
- - const: simple-mfd
- reg:
- maxItems: 1
-
- required:
- - compatible
- - reg
-
-patternProperties:
- "^syscon@[0-9a-f]+$":
- type: object
- description: When fitted with the IB2 Interface Board, the Versatile
- AB will present an optional system controller node which controls the
- extra peripherals on the interface board.
- properties:
- compatible:
- contains:
- const: arm,versatile-ib2-syscon
- required:
- - compatible
- - reg
-
required:
- compatible
- core-module@10000000
diff --git a/Documentation/devicetree/bindings/input/twl4030-pwrbutton.txt b/Documentation/devicetree/bindings/input/twl4030-pwrbutton.txt
index f5021214edec..6c201a2ba8ac 100644
--- a/Documentation/devicetree/bindings/input/twl4030-pwrbutton.txt
+++ b/Documentation/devicetree/bindings/input/twl4030-pwrbutton.txt
@@ -1,7 +1,7 @@
Texas Instruments TWL family (twl4030) pwrbutton module
This module is part of the TWL4030. For more details about the whole
-chip see Documentation/devicetree/bindings/mfd/twl-family.txt.
+chip see Documentation/devicetree/bindings/mfd/ti,twl.yaml.
This module provides a simple power button event via an Interrupt.
diff --git a/Documentation/devicetree/bindings/leds/backlight/max8925-backlight.txt b/Documentation/devicetree/bindings/leds/backlight/max8925-backlight.txt
deleted file mode 100644
index b4cffdaa4137..000000000000
--- a/Documentation/devicetree/bindings/leds/backlight/max8925-backlight.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-88pm860x-backlight bindings
-
-Optional properties:
- - maxim,max8925-dual-string: whether support dual string
-
-Example:
-
- backlights {
- maxim,max8925-dual-string = <0>;
- };
diff --git a/Documentation/devicetree/bindings/leds/register-bit-led.yaml b/Documentation/devicetree/bindings/leds/register-bit-led.yaml
index ed26ec19ecbd..20930d327ae9 100644
--- a/Documentation/devicetree/bindings/leds/register-bit-led.yaml
+++ b/Documentation/devicetree/bindings/leds/register-bit-led.yaml
@@ -60,7 +60,7 @@ examples:
- |
syscon@10000000 {
- compatible = "arm,realview-pb1176-syscon", "syscon";
+ compatible = "arm,realview-pb1176-syscon", "syscon", "simple-mfd";
reg = <0x10000000 0x1000>;
#address-cells = <1>;
#size-cells = <1>;
diff --git a/Documentation/devicetree/bindings/mfd/arm,dev-platforms-syscon.yaml b/Documentation/devicetree/bindings/mfd/arm,dev-platforms-syscon.yaml
new file mode 100644
index 000000000000..46b164ae0831
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/arm,dev-platforms-syscon.yaml
@@ -0,0 +1,67 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mfd/arm,dev-platforms-syscon.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Arm Ltd Developer Platforms System Controllers
+
+maintainers:
+ - Linus Walleij <linus.walleij@linaro.org>
+
+description:
+ The Arm Ltd Integrator, Realview, and Versatile families of developer
+ platforms are contain various system controller blocks. Often these blocks
+ are part of a daughterboard or motherboard module.
+
+properties:
+ compatible:
+ oneOf:
+ - items:
+ - enum:
+ - arm,integrator-ap-syscon
+ - arm,integrator-cp-syscon
+ - arm,integrator-sp-syscon
+ - arm,im-pd1-syscon
+ - const: syscon
+ - items:
+ - enum:
+ - arm,core-module-integrator
+ - arm,integrator-ap-syscon
+ - arm,integrator-cp-syscon
+ - arm,integrator-sp-syscon
+ - arm,realview-eb-syscon
+ - arm,realview-pb1176-syscon
+ - arm,realview-pb11mp-syscon
+ - arm,realview-pba8-syscon
+ - arm,realview-pbx-syscon
+ - arm,versatile-ib2-syscon
+ - const: syscon
+ - const: simple-mfd
+ - items:
+ - enum:
+ - arm,realview-eb11mp-revb-syscon
+ - arm,realview-eb11mp-revc-syscon
+ - const: arm,realview-eb-syscon
+ - const: syscon
+ - const: simple-mfd
+
+ reg:
+ maxItems: 1
+
+ ranges: true
+
+ '#address-cells':
+ const: 1
+
+ '#size-cells':
+ const: 1
+
+required:
+ - compatible
+ - reg
+
+additionalProperties:
+ type: object
+
+...
diff --git a/Documentation/devicetree/bindings/mfd/max8925.txt b/Documentation/devicetree/bindings/mfd/max8925.txt
deleted file mode 100644
index 4f0dc6638e5e..000000000000
--- a/Documentation/devicetree/bindings/mfd/max8925.txt
+++ /dev/null
@@ -1,64 +0,0 @@
-* Maxim max8925 Power Management IC
-
-Required parent device properties:
-- compatible : "maxim,max8925"
-- reg : the I2C slave address for the max8925 chip
-- interrupts : IRQ line for the max8925 chip
-- interrupt-controller: describes the max8925 as an interrupt
- controller (has its own domain)
-- #interrupt-cells : should be 1.
- - The cell is the max8925 local IRQ number
-
-Optional parent device properties:
-- maxim,tsc-irq: there are 2 IRQ lines for max8925, one is indicated in
- interrupts property, the other is indicated here.
-
-max8925 consists of a large and varied group of sub-devices:
-
-Device Supply Names Description
------- ------------ -----------
-max8925-onkey : : On key
-max8925-rtc : : RTC
-max8925-regulator : : Regulators
-max8925-backlight : : Backlight
-max8925-touch : : Touchscreen
-max8925-power : : Charger
-
-Example:
-
- pmic: max8925@3c {
- compatible = "maxim,max8925";
- reg = <0x3c>;
- interrupts = <1>;
- interrupt-parent = <&intcmux4>;
- interrupt-controller;
- #interrupt-cells = <1>;
- maxim,tsc-irq = <0>;
-
- regulators {
- SDV1 {
- regulator-min-microvolt = <637500>;
- regulator-max-microvolt = <1425000>;
- regulator-boot-on;
- regulator-always-on;
- };
-
- LDO1 {
- regulator-min-microvolt = <750000>;
- regulator-max-microvolt = <3900000>;
- regulator-boot-on;
- regulator-always-on;
- };
-
- };
- backlight {
- maxim,max8925-dual-string = <0>;
- };
- charger {
- batt-detect = <0>;
- topoff-threshold = <1>;
- fast-charge = <7>;
- no-temp-support = <0>;
- no-insert-detect = <0>;
- };
- };
diff --git a/Documentation/devicetree/bindings/mfd/max8998.txt b/Documentation/devicetree/bindings/mfd/max8998.txt
deleted file mode 100644
index 4ed52184d081..000000000000
--- a/Documentation/devicetree/bindings/mfd/max8998.txt
+++ /dev/null
@@ -1,125 +0,0 @@
-* Maxim MAX8998, National/TI LP3974 multi-function device
-
-The Maxim MAX8998 is a multi-function device which includes voltage/current
-regulators, real time clock, battery charging controller and several
-other sub-blocks. It is interfaced using an I2C interface. Each sub-block
-is addressed by the host system using different i2c slave address.
-
-PMIC sub-block
---------------
-
-The PMIC sub-block contains a number of voltage and current regulators,
-with controllable parameters and dynamic voltage scaling capability.
-In addition, it includes a real time clock and battery charging controller
-as well. It is accessible at I2C address 0x66.
-
-Required properties:
-- compatible: Should be one of the following:
- - "maxim,max8998" for Maxim MAX8998
- - "national,lp3974" or "ti,lp3974" for National/TI LP3974.
-- reg: Specifies the i2c slave address of the pmic block. It should be 0x66.
-
-Optional properties:
-- interrupts: Interrupt specifiers for two interrupt sources.
- - First interrupt specifier is for main interrupt.
- - Second interrupt specifier is for power-on/-off interrupt.
-- max8998,pmic-buck1-dvs-gpios: GPIO specifiers for two host gpios used
- for buck 1 dvs. The format of the gpio specifier depends on the gpio
- controller.
-- max8998,pmic-buck2-dvs-gpio: GPIO specifier for host gpio used
- for buck 2 dvs. The format of the gpio specifier depends on the gpio
- controller.
-- max8998,pmic-buck1-default-dvs-idx: Default voltage setting selected from
- the possible 4 options selectable by the dvs gpios. The value of this
- property should be 0, 1, 2 or 3. If not specified or out of range,
- a default value of 0 is taken.
-- max8998,pmic-buck2-default-dvs-idx: Default voltage setting selected from
- the possible 2 options selectable by the dvs gpios. The value of this
- property should be 0 or 1. If not specified or out of range, a default
- value of 0 is taken.
-- max8998,pmic-buck-voltage-lock: If present, disallows changing of
- preprogrammed buck dvfs voltages.
-
-Additional properties required if max8998,pmic-buck1-dvs-gpios is defined:
-- max8998,pmic-buck1-dvs-voltage: An array of 4 voltage values in microvolts
- for buck1 regulator that can be selected using dvs gpio.
-
-Additional properties required if max8998,pmic-buck2-dvs-gpio is defined:
-- max8998,pmic-buck2-dvs-voltage: An array of 2 voltage values in microvolts
- for buck2 regulator that can be selected using dvs gpio.
-
-Regulators: All the regulators of MAX8998 to be instantiated shall be
-listed in a child node named 'regulators'. Each regulator is represented
-by a child node of the 'regulators' node.
-
- regulator-name {
- /* standard regulator bindings here */
- };
-
-Following regulators of the MAX8998 PMIC block are supported. Note that
-the 'n' in regulator name, as in LDOn or BUCKn, represents the LDO or BUCK
-number as described in MAX8998 datasheet.
-
- - LDOn
- - valid values for n are 2 to 17
- - Example: LDO2, LDO10, LDO17
- - BUCKn
- - valid values for n are 1 to 4.
- - Example: BUCK1, BUCK2, BUCK3, BUCK4
-
- - ENVICHG: Battery Charging Current Monitor Output. This is a fixed
- voltage type regulator
-
- - ESAFEOUT1: (ldo19)
- - ESAFEOUT2: (ld020)
-
- - CHARGER: main battery charger current control
-
-Standard regulator bindings are used inside regulator subnodes. Check
- Documentation/devicetree/bindings/regulator/regulator.txt
-for more details.
-
-Example:
-
- pmic@66 {
- compatible = "maxim,max8998-pmic";
- reg = <0x66>;
- interrupt-parent = <&wakeup_eint>;
- interrupts = <4 0>, <3 0>;
-
- /* Buck 1 DVS settings */
- max8998,pmic-buck1-default-dvs-idx = <0>;
- max8998,pmic-buck1-dvs-gpios = <&gpx0 0 1 0 0>, /* SET1 */
- <&gpx0 1 1 0 0>; /* SET2 */
- max8998,pmic-buck1-dvs-voltage = <1350000>, <1300000>,
- <1000000>, <950000>;
-
- /* Buck 2 DVS settings */
- max8998,pmic-buck2-default-dvs-idx = <0>;
- max8998,pmic-buck2-dvs-gpio = <&gpx0 0 3 0 0>; /* SET3 */
- max8998,pmic-buck2-dvs-voltage = <1350000>, <1300000>;
-
- /* Regulators to instantiate */
- regulators {
- ldo2_reg: LDO2 {
- regulator-name = "VDD_ALIVE_1.1V";
- regulator-min-microvolt = <1100000>;
- regulator-max-microvolt = <1100000>;
- regulator-always-on;
- };
-
- buck1_reg: BUCK1 {
- regulator-name = "VDD_ARM_1.2V";
- regulator-min-microvolt = <950000>;
- regulator-max-microvolt = <1350000>;
- regulator-always-on;
- regulator-boot-on;
- };
-
- charger_reg: CHARGER {
- regulator-name = "CHARGER";
- regulator-min-microamp = <90000>;
- regulator-max-microamp = <800000>;
- };
- };
- };
diff --git a/Documentation/devicetree/bindings/mfd/maxim,max5970.yaml b/Documentation/devicetree/bindings/mfd/maxim,max5970.yaml
index da67742c5aa9..0da5cae3852e 100644
--- a/Documentation/devicetree/bindings/mfd/maxim,max5970.yaml
+++ b/Documentation/devicetree/bindings/mfd/maxim,max5970.yaml
@@ -45,8 +45,13 @@ properties:
patternProperties:
"^led@[0-3]$":
$ref: /schemas/leds/common.yaml#
+ unevaluatedProperties: false
type: object
+ properties:
+ reg:
+ maximum: 3
+
additionalProperties: false
vss1-supply:
diff --git a/Documentation/devicetree/bindings/mfd/maxim,max8925.yaml b/Documentation/devicetree/bindings/mfd/maxim,max8925.yaml
new file mode 100644
index 000000000000..86dd810851ab
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/maxim,max8925.yaml
@@ -0,0 +1,145 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mfd/maxim,max8925.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MAX8925 PMIC from Maxim Integrated.
+
+maintainers:
+ - Lee Jones <lee@kernel.org>
+
+properties:
+ compatible:
+ const: maxim,max8925
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ interrupt-controller: true
+
+ "#interrupt-cells":
+ const: 1
+ description:
+ The cell is the IRQ number
+
+ maxim,tsc-irq:
+ description: second interrupt from max8925
+ $ref: /schemas/types.yaml#/definitions/uint32
+
+ regulators:
+ type: object
+
+ patternProperties:
+ "^SDV[1-3]$|^LDO[1-9]$|^LDO1[0-9]$|^LDO20$":
+ description: regulator configuration for SDV1-3 and LDO1-20
+ $ref: /schemas/regulator/regulator.yaml
+ unevaluatedProperties: false
+
+ additionalProperties: false
+
+ backlight:
+ type: object
+ properties:
+ maxim,max8925-dual-string:
+ description: set to 1 to support dual string
+ $ref: /schemas/types.yaml#/definitions/uint32
+ enum: [0, 1]
+ default: 0
+
+ additionalProperties: false
+
+ charger:
+ type: object
+ properties:
+ batt-detect:
+ description: set to 1 if battery detection via ID pin is supported
+ $ref: /schemas/types.yaml#/definitions/uint32
+ enum: [0, 1]
+ default: 0
+
+ topoff-threshold:
+ description: charging current in topoff mode, configures bits 5-6 in CHG_CNTL1
+ $ref: /schemas/types.yaml#/definitions/uint32
+ minimum: 0
+ maximum: 3
+ default: 0
+
+ fast-charge:
+ description: set charging current in fast mode, configures bits 0-3 in CHG_CNTL1
+ $ref: /schemas/types.yaml#/definitions/uint32
+ minimum: 0
+ maximum: 7
+ default: 0
+
+ no-temp-support:
+ description: set to 1 if temperature sensing is not supported
+ $ref: /schemas/types.yaml#/definitions/uint32
+ enum: [0, 1]
+ default: 0
+
+ no-insert-detect:
+ description: set to 1 if AC detection is not supported
+ $ref: /schemas/types.yaml#/definitions/uint32
+ enum: [0, 1]
+ default: 0
+
+ additionalProperties: false
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - interrupt-controller
+ - "#interrupt-cells"
+ - regulators
+
+additionalProperties: false
+
+examples:
+ - |
+ i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pmic@3c {
+ compatible = "maxim,max8925";
+ reg = <0x3c>;
+ interrupts = <1>;
+ interrupt-parent = <&intcmux4>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ maxim,tsc-irq = <0>;
+
+ regulators {
+ SDV1 {
+ regulator-min-microvolt = <637500>;
+ regulator-max-microvolt = <1425000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ LDO1 {
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <3900000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ };
+
+ backlight {
+ maxim,max8925-dual-string = <0>;
+ };
+
+ charger {
+ batt-detect = <0>;
+ topoff-threshold = <1>;
+ fast-charge = <7>;
+ no-temp-support = <0>;
+ no-insert-detect = <0>;
+ };
+ };
+ };
diff --git a/Documentation/devicetree/bindings/mfd/maxim,max8998.yaml b/Documentation/devicetree/bindings/mfd/maxim,max8998.yaml
new file mode 100644
index 000000000000..f3c3f64fd012
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/maxim,max8998.yaml
@@ -0,0 +1,324 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mfd/maxim,max8998.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Maxim MAX8998, National/TI LP3974 Power Management IC
+
+maintainers:
+ - Krzysztof Kozlowski <krzk@kernel.org>
+
+description:
+ The Maxim MAX8998 is a Power Management IC which includes voltage/current
+ regulators, real time clock, battery charging controller and several other
+ sub-blocks. It is interfaced using an I2C interface. Each sub-block is
+ addressed by the host system using different i2c slave address.
+
+properties:
+ compatible:
+ enum:
+ - maxim,max8998
+ - national,lp3974
+ - ti,lp3974
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ minItems: 1
+ items:
+ - description: Main interrupt
+ - description: Power-on/-off interrupt
+
+ max8998,pmic-buck1-dvs-gpios:
+ maxItems: 2
+ description:
+ Two host gpios used for buck1 DVS.
+
+ max8998,pmic-buck2-dvs-gpio:
+ maxItems: 1
+ description:
+ Host gpio used for buck2 DVS.
+
+ max8998,pmic-buck1-default-dvs-idx:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ enum: [0, 1, 2, 3]
+ default: 0
+ description:
+ Default voltage setting selected from the possible 4 options selectable
+ by the DVS gpios.
+
+ max8998,pmic-buck2-default-dvs-idx:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ enum: [0, 1]
+ default: 0
+ description:
+ Default voltage setting selected from the possible 2 options selectable
+ by the DVS GPIOs.
+
+ max8998,pmic-buck-voltage-lock:
+ type: boolean
+ description:
+ If present, disallows changing of preprogrammed buck DVS voltages.
+
+ max8998,pmic-buck1-dvs-voltage:
+ $ref: /schemas/types.yaml#/definitions/uint32-array
+ maxItems: 4
+ description:
+ Four voltage values in microvolts for buck1 regulator that can be
+ selected using DVS GPIO.
+
+ max8998,pmic-buck2-dvs-voltage:
+ $ref: /schemas/types.yaml#/definitions/uint32-array
+ maxItems: 2
+ description:
+ Two voltage values in microvolts for buck2 regulator that can be
+ selected using DVS GPIO.
+
+ regulators:
+ type: object
+ additionalProperties: false
+
+ properties:
+ CHARGER:
+ type: object
+ $ref: /schemas/regulator/regulator.yaml#
+ unevaluatedProperties: false
+ description:
+ CHARGER is main battery charger current control, wrongly represented
+ as regulator.
+
+ properties:
+ regulator-min-microamp:
+ minimum: 90000
+ maximum: 800000
+
+ regulator-max-microamp:
+ minimum: 90000
+ maximum: 800000
+
+ regulator-min-microvolt: false
+ regulator-max-microvolt: false
+
+ required:
+ - regulator-name
+
+ patternProperties:
+ "^(LDO([2-9]|1[0-7])|BUCK[1-4])$":
+ type: object
+ $ref: /schemas/regulator/regulator.yaml#
+ unevaluatedProperties: false
+
+ required:
+ - regulator-name
+
+ "^(EN32KHz-AP|EN32KHz-CP|ENVICHG|ESAFEOUT[12])$":
+ type: object
+ $ref: /schemas/regulator/regulator.yaml#
+ unevaluatedProperties: false
+ description: |
+ EN32KHz-AP and EN32KHz-CP are 32768 Hz clocks, wrongly represented as
+ regulators.
+ ENVICHG is a Battery Charging Current Monitor Output.
+
+ properties:
+ regulator-min-microvolt: false
+ regulator-max-microvolt: false
+
+ required:
+ - regulator-name
+
+dependencies:
+ max8998,pmic-buck1-dvs-gpios: [ "max8998,pmic-buck1-dvs-voltage" ]
+ max8998,pmic-buck2-dvs-gpio: [ "max8998,pmic-buck2-dvs-voltage" ]
+
+required:
+ - compatible
+ - reg
+ - regulators
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/gpio/gpio.h>
+ #include <dt-bindings/interrupt-controller/irq.h>
+
+ i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pmic@66 {
+ compatible = "national,lp3974";
+ reg = <0x66>;
+ interrupts-extended = <&gpx0 7 IRQ_TYPE_LEVEL_LOW>,
+ <&gpx2 7 IRQ_TYPE_LEVEL_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&lp3974_irq>;
+
+ max8998,pmic-buck1-default-dvs-idx = <0>;
+ max8998,pmic-buck1-dvs-gpios = <&gpx0 5 GPIO_ACTIVE_HIGH>,
+ <&gpx0 6 GPIO_ACTIVE_HIGH>;
+ max8998,pmic-buck1-dvs-voltage = <1100000>, <1000000>,
+ <1100000>, <1000000>;
+ max8998,pmic-buck2-default-dvs-idx = <0>;
+ max8998,pmic-buck2-dvs-gpio = <&gpe2 0 GPIO_ACTIVE_HIGH>;
+ max8998,pmic-buck2-dvs-voltage = <1200000>, <1100000>;
+
+ regulators {
+ LDO2 {
+ regulator-name = "VALIVE_1.2V";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ };
+
+ LDO3 {
+ regulator-name = "VUSB+MIPI_1.1V";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-always-on;
+ };
+
+ LDO4 {
+ regulator-name = "VADC_3.3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ LDO5 {
+ regulator-name = "VTF_2.8V";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ LDO6 {
+ regulator-name = "LDO6";
+ regulator-min-microvolt = <2000000>;
+ regulator-max-microvolt = <2000000>;
+ };
+
+ LDO7 {
+ regulator-name = "VLCD+VMIPI_1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ LDO8 {
+ regulator-name = "VUSB+VDAC_3.3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ LDO9 {
+ regulator-name = "VCC_2.8V";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-always-on;
+ };
+
+ LDO10 {
+ regulator-name = "VPLL_1.1V";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ LDO11 {
+ regulator-name = "CAM_AF_3.3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ LDO12 {
+ regulator-name = "PS_2.8V";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ LDO13 {
+ regulator-name = "VHIC_1.2V";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ LDO14 {
+ regulator-name = "CAM_I_HOST_1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ LDO15 {
+ regulator-name = "CAM_S_DIG+FM33_CORE_1.2V";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ LDO16 {
+ regulator-name = "CAM_S_ANA_2.8V";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ LDO17 {
+ regulator-name = "VCC_3.0V_LCD";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ };
+
+ BUCK1 {
+ regulator-name = "VINT_1.1V";
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ BUCK2 {
+ regulator-name = "VG3D_1.1V";
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-boot-on;
+ };
+
+ BUCK3 {
+ regulator-name = "VCC_1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ BUCK4 {
+ regulator-name = "VMEM_1.2V";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ };
+
+ EN32KHz-AP {
+ regulator-name = "32KHz AP";
+ regulator-always-on;
+ };
+
+ EN32KHz-CP {
+ regulator-name = "32KHz CP";
+ };
+
+ ENVICHG {
+ regulator-name = "VICHG";
+ };
+
+ ESAFEOUT1 {
+ regulator-name = "SAFEOUT1";
+ };
+
+ ESAFEOUT2 {
+ regulator-name = "SAFEOUT2";
+ regulator-boot-on;
+ };
+ };
+ };
+ };
diff --git a/Documentation/devicetree/bindings/mfd/mediatek,mt6357.yaml b/Documentation/devicetree/bindings/mfd/mediatek,mt6357.yaml
index fc2a53148e1c..37423c2e0fdf 100644
--- a/Documentation/devicetree/bindings/mfd/mediatek,mt6357.yaml
+++ b/Documentation/devicetree/bindings/mfd/mediatek,mt6357.yaml
@@ -40,6 +40,7 @@ properties:
regulators:
type: object
$ref: /schemas/regulator/mediatek,mt6357-regulator.yaml
+ unevaluatedProperties: false
description:
List of MT6357 BUCKs and LDOs regulators.
@@ -59,6 +60,7 @@ properties:
keys:
type: object
$ref: /schemas/input/mediatek,pmic-keys.yaml
+ unevaluatedProperties: false
description:
MT6357 power and home keys.
diff --git a/Documentation/devicetree/bindings/mfd/mt6397.txt b/Documentation/devicetree/bindings/mfd/mt6397.txt
index 294693a8906c..10540aa7afa1 100644
--- a/Documentation/devicetree/bindings/mfd/mt6397.txt
+++ b/Documentation/devicetree/bindings/mfd/mt6397.txt
@@ -22,8 +22,9 @@ compatible:
"mediatek,mt6323" for PMIC MT6323
"mediatek,mt6331" for PMIC MT6331 and MT6332
"mediatek,mt6357" for PMIC MT6357
- "mediatek,mt6358" for PMIC MT6358 and MT6366
+ "mediatek,mt6358" for PMIC MT6358
"mediatek,mt6359" for PMIC MT6359
+ "mediatek,mt6366", "mediatek,mt6358" for PMIC MT6366
"mediatek,mt6397" for PMIC MT6397
Optional subnodes:
@@ -40,6 +41,7 @@ Optional subnodes:
- compatible: "mediatek,mt6323-regulator"
see ../regulator/mt6323-regulator.txt
- compatible: "mediatek,mt6358-regulator"
+ - compatible: "mediatek,mt6366-regulator", "mediatek-mt6358-regulator"
see ../regulator/mt6358-regulator.txt
- compatible: "mediatek,mt6397-regulator"
see ../regulator/mt6397-regulator.txt
diff --git a/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml b/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml
index 9f03436b1cdc..9fa568603930 100644
--- a/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml
+++ b/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml
@@ -58,6 +58,7 @@ properties:
- qcom,pm8350
- qcom,pm8350b
- qcom,pm8350c
+ - qcom,pm8450
- qcom,pm8550
- qcom,pm8550b
- qcom,pm8550ve
@@ -168,6 +169,10 @@ patternProperties:
type: object
$ref: /schemas/thermal/qcom,spmi-temp-alarm.yaml#
+ "^typec@[0-9a-f]+$":
+ type: object
+ $ref: /schemas/usb/qcom,pmic-typec.yaml#
+
"^usb-detect@[0-9a-f]+$":
type: object
$ref: /schemas/extcon/qcom,pm8941-misc.yaml#
@@ -234,13 +239,13 @@ examples:
interrupt-controller;
#interrupt-cells = <4>;
- pmi8998_lsid0: pmic@2 {
+ pmic@2 {
compatible = "qcom,pmi8998", "qcom,spmi-pmic";
reg = <0x2 SPMI_USID>;
#address-cells = <1>;
#size-cells = <0>;
- pmi8998_gpio: gpio@c000 {
+ gpio@c000 {
compatible = "qcom,pmi8998-gpio", "qcom,spmi-gpio";
reg = <0xc000>;
gpio-controller;
@@ -325,7 +330,7 @@ examples:
};
};
- pm6150_gpio: gpio@c000 {
+ gpio@c000 {
compatible = "qcom,pm6150-gpio", "qcom,spmi-gpio";
reg = <0xc000>;
gpio-controller;
diff --git a/Documentation/devicetree/bindings/mfd/qcom,tcsr.yaml b/Documentation/devicetree/bindings/mfd/qcom,tcsr.yaml
index 5ad9d5deaaf8..33c3d023a106 100644
--- a/Documentation/devicetree/bindings/mfd/qcom,tcsr.yaml
+++ b/Documentation/devicetree/bindings/mfd/qcom,tcsr.yaml
@@ -27,6 +27,7 @@ properties:
- qcom,sdm845-tcsr
- qcom,sdx55-tcsr
- qcom,sdx65-tcsr
+ - qcom,sm4450-tcsr
- qcom,sm8150-tcsr
- qcom,sm8450-tcsr
- qcom,tcsr-apq8064
diff --git a/Documentation/devicetree/bindings/mfd/qcom-pm8xxx.yaml b/Documentation/devicetree/bindings/mfd/qcom-pm8xxx.yaml
index 9c51c1b19067..7fe3875a5996 100644
--- a/Documentation/devicetree/bindings/mfd/qcom-pm8xxx.yaml
+++ b/Documentation/devicetree/bindings/mfd/qcom-pm8xxx.yaml
@@ -43,13 +43,37 @@ properties:
interrupt-controller: true
patternProperties:
+ "gpio@[0-9a-f]+$":
+ type: object
+ $ref: /schemas/pinctrl/qcom,pmic-gpio.yaml#
+
+ "keypad@[0-9a-f]+$":
+ type: object
+ $ref: /schemas/input/qcom,pm8921-keypad.yaml#
+
"led@[0-9a-f]+$":
type: object
$ref: /schemas/leds/qcom,pm8058-led.yaml#
+ "mpps@[0-9a-f]+$":
+ type: object
+ $ref: /schemas/pinctrl/qcom,pmic-mpp.yaml#
+
+ "pwrkey@[0-9a-f]+$":
+ type: object
+ $ref: /schemas/input/qcom,pm8921-pwrkey.yaml#
+
"rtc@[0-9a-f]+$":
type: object
- $ref: ../rtc/qcom-pm8xxx-rtc.yaml
+ $ref: /schemas/rtc/qcom-pm8xxx-rtc.yaml#
+
+ "vibrator@[0-9a-f]+$":
+ type: object
+ $ref: /schemas/input/qcom,pm8xxx-vib.yaml#
+
+ "xoadc@[0-9a-f]+$":
+ type: object
+ $ref: /schemas/iio/adc/qcom,pm8018-adc.yaml#
required:
- compatible
diff --git a/Documentation/devicetree/bindings/mfd/rockchip,rk805.yaml b/Documentation/devicetree/bindings/mfd/rockchip,rk805.yaml
index 4992f71b6fc3..44f8188360dd 100644
--- a/Documentation/devicetree/bindings/mfd/rockchip,rk805.yaml
+++ b/Documentation/devicetree/bindings/mfd/rockchip,rk805.yaml
@@ -42,9 +42,12 @@ properties:
rockchip,system-power-controller:
type: boolean
+ deprecated: true
description:
Telling whether or not this PMIC is controlling the system power.
+ system-power-controller: true
+
wakeup-source:
type: boolean
description:
@@ -80,6 +83,7 @@ properties:
"^(DCDC_REG[1-4]|LDO_REG[1-3])$":
type: object
$ref: ../regulator/regulator.yaml#
+ unevaluatedProperties: false
unevaluatedProperties: false
allOf:
diff --git a/Documentation/devicetree/bindings/mfd/rockchip,rk806.yaml b/Documentation/devicetree/bindings/mfd/rockchip,rk806.yaml
index cf2500f2e9a0..3c2b06629b75 100644
--- a/Documentation/devicetree/bindings/mfd/rockchip,rk806.yaml
+++ b/Documentation/devicetree/bindings/mfd/rockchip,rk806.yaml
@@ -29,6 +29,8 @@ properties:
'#gpio-cells':
const: 2
+ system-power-controller: true
+
vcc1-supply:
description:
The input supply for dcdc-reg1.
diff --git a/Documentation/devicetree/bindings/mfd/rockchip,rk808.yaml b/Documentation/devicetree/bindings/mfd/rockchip,rk808.yaml
index f5908fa01a61..d2ac6fbd5ce6 100644
--- a/Documentation/devicetree/bindings/mfd/rockchip,rk808.yaml
+++ b/Documentation/devicetree/bindings/mfd/rockchip,rk808.yaml
@@ -37,9 +37,12 @@ properties:
rockchip,system-power-controller:
type: boolean
+ deprecated: true
description:
Telling whether or not this PMIC is controlling the system power.
+ system-power-controller: true
+
wakeup-source:
type: boolean
description:
@@ -107,6 +110,7 @@ properties:
"^(DCDC_REG[1-4]|LDO_REG[1-8]|SWITCH_REG[1-2])$":
type: object
$ref: ../regulator/regulator.yaml#
+ unevaluatedProperties: false
unevaluatedProperties: false
required:
diff --git a/Documentation/devicetree/bindings/mfd/rockchip,rk809.yaml b/Documentation/devicetree/bindings/mfd/rockchip,rk809.yaml
index 7fb849ac74a7..839c0521f1e5 100644
--- a/Documentation/devicetree/bindings/mfd/rockchip,rk809.yaml
+++ b/Documentation/devicetree/bindings/mfd/rockchip,rk809.yaml
@@ -37,9 +37,12 @@ properties:
rockchip,system-power-controller:
type: boolean
+ deprecated: true
description:
Telling whether or not this PMIC is controlling the system power.
+ system-power-controller: true
+
wakeup-source:
type: boolean
description:
@@ -86,7 +89,8 @@ properties:
patternProperties:
"^(LDO_REG[1-9]|DCDC_REG[1-5]|SWITCH_REG[1-2])$":
type: object
- $ref: ../regulator/regulator.yaml#
+ $ref: /schemas/regulator/regulator.yaml#
+ unevaluatedProperties: false
unevaluatedProperties: false
allOf:
diff --git a/Documentation/devicetree/bindings/mfd/rockchip,rk817.yaml b/Documentation/devicetree/bindings/mfd/rockchip,rk817.yaml
index 269fb85b2027..92b1592e8942 100644
--- a/Documentation/devicetree/bindings/mfd/rockchip,rk817.yaml
+++ b/Documentation/devicetree/bindings/mfd/rockchip,rk817.yaml
@@ -38,9 +38,12 @@ properties:
rockchip,system-power-controller:
type: boolean
+ deprecated: true
description:
Telling whether or not this PMIC is controlling the system power.
+ system-power-controller: true
+
wakeup-source:
type: boolean
description:
diff --git a/Documentation/devicetree/bindings/mfd/rockchip,rk818.yaml b/Documentation/devicetree/bindings/mfd/rockchip,rk818.yaml
index b57c4b005cf4..fd4b9de364aa 100644
--- a/Documentation/devicetree/bindings/mfd/rockchip,rk818.yaml
+++ b/Documentation/devicetree/bindings/mfd/rockchip,rk818.yaml
@@ -37,9 +37,12 @@ properties:
rockchip,system-power-controller:
type: boolean
+ deprecated: true
description:
Telling whether or not this PMIC is controlling the system power.
+ system-power-controller: true
+
wakeup-source:
type: boolean
description:
@@ -99,6 +102,7 @@ properties:
"^(DCDC_REG[1-4]|DCDC_BOOST|LDO_REG[1-9]|SWITCH_REG|HDMI_SWITCH|OTG_SWITCH)$":
type: object
$ref: ../regulator/regulator.yaml#
+ unevaluatedProperties: false
unevaluatedProperties: false
required:
diff --git a/Documentation/devicetree/bindings/mfd/stericsson,db8500-prcmu.yaml b/Documentation/devicetree/bindings/mfd/stericsson,db8500-prcmu.yaml
index 5e0002f099e4..cb2a42caabb5 100644
--- a/Documentation/devicetree/bindings/mfd/stericsson,db8500-prcmu.yaml
+++ b/Documentation/devicetree/bindings/mfd/stericsson,db8500-prcmu.yaml
@@ -75,7 +75,7 @@ properties:
unevaluatedProperties: false
db8500_varm:
- description: The voltage for the ARM Cortex A-9 CPU.
+ description: The voltage for the ARM Cortex-A9 CPU.
type: object
$ref: ../regulator/regulator.yaml#
unevaluatedProperties: false
diff --git a/Documentation/devicetree/bindings/mfd/syscon.yaml b/Documentation/devicetree/bindings/mfd/syscon.yaml
index c77d7b155a4c..084b5c2a2a3c 100644
--- a/Documentation/devicetree/bindings/mfd/syscon.yaml
+++ b/Documentation/devicetree/bindings/mfd/syscon.yaml
@@ -63,6 +63,7 @@ properties:
- rockchip,px30-qos
- rockchip,rk3036-qos
- rockchip,rk3066-qos
+ - rockchip,rk3128-qos
- rockchip,rk3228-qos
- rockchip,rk3288-qos
- rockchip,rk3368-qos
@@ -71,6 +72,7 @@ properties:
- rockchip,rk3588-qos
- rockchip,rv1126-qos
- starfive,jh7100-sysmain
+ - ti,am654-dss-oldi-io-ctrl
- const: syscon
diff --git a/Documentation/devicetree/bindings/mfd/ti,lp87524-q1.yaml b/Documentation/devicetree/bindings/mfd/ti,lp87524-q1.yaml
index f6cac4b1079c..ae149eb8593d 100644
--- a/Documentation/devicetree/bindings/mfd/ti,lp87524-q1.yaml
+++ b/Documentation/devicetree/bindings/mfd/ti,lp87524-q1.yaml
@@ -37,6 +37,7 @@ properties:
"^buck[0123]$":
type: object
$ref: /schemas/regulator/regulator.yaml#
+ unevaluatedProperties: false
required:
- buck0
diff --git a/Documentation/devicetree/bindings/mfd/ti,lp87561-q1.yaml b/Documentation/devicetree/bindings/mfd/ti,lp87561-q1.yaml
index dc5a29b5ef7d..5167d6eb904a 100644
--- a/Documentation/devicetree/bindings/mfd/ti,lp87561-q1.yaml
+++ b/Documentation/devicetree/bindings/mfd/ti,lp87561-q1.yaml
@@ -41,6 +41,7 @@ properties:
buck3210:
type: object
$ref: /schemas/regulator/regulator.yaml#
+ unevaluatedProperties: false
required:
- buck3210
diff --git a/Documentation/devicetree/bindings/mfd/ti,lp87565-q1.yaml b/Documentation/devicetree/bindings/mfd/ti,lp87565-q1.yaml
index 012d25111054..eca430edf608 100644
--- a/Documentation/devicetree/bindings/mfd/ti,lp87565-q1.yaml
+++ b/Documentation/devicetree/bindings/mfd/ti,lp87565-q1.yaml
@@ -47,6 +47,7 @@ properties:
"^buck(10|23)$":
type: object
$ref: /schemas/regulator/regulator.yaml#
+ unevaluatedProperties: false
required:
- buck10
diff --git a/Documentation/devicetree/bindings/mfd/ti,twl.yaml b/Documentation/devicetree/bindings/mfd/ti,twl.yaml
new file mode 100644
index 000000000000..c04d57ba22b4
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/ti,twl.yaml
@@ -0,0 +1,67 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mfd/ti,twl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Texas Instruments TWL family
+
+maintainers:
+ - Andreas Kemnade <andreas@kemnade.info>
+
+description: |
+ The TWLs are Integrated Power Management Chips.
+ Some version might contain much more analog function like
+ USB transceiver or Audio amplifier.
+ These chips are connected to an i2c bus.
+
+properties:
+ compatible:
+ description:
+ TWL4030 for integrated power-management/audio CODEC device used in OMAP3
+ based boards
+ TWL6030/32 for integrated power-management used in OMAP4 based boards
+ enum:
+ - ti,twl4030
+ - ti,twl6030
+ - ti,twl6032
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ interrupt-controller: true
+
+ "#interrupt-cells":
+ const: 1
+
+ "#clock-cells":
+ const: 1
+
+additionalProperties: false
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - interrupt-controller
+ - "#interrupt-cells"
+
+examples:
+ - |
+ i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pmic@48 {
+ compatible = "ti,twl6030";
+ reg = <0x48>;
+ interrupts = <39>; /* IRQ_SYS_1N cascaded to gic */
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ interrupt-parent = <&gic>;
+ };
+ };
+
diff --git a/Documentation/devicetree/bindings/mfd/twl-family.txt b/Documentation/devicetree/bindings/mfd/twl-family.txt
deleted file mode 100644
index c2f9302965de..000000000000
--- a/Documentation/devicetree/bindings/mfd/twl-family.txt
+++ /dev/null
@@ -1,46 +0,0 @@
-Texas Instruments TWL family
-
-The TWLs are Integrated Power Management Chips.
-Some version might contain much more analog function like
-USB transceiver or Audio amplifier.
-These chips are connected to an i2c bus.
-
-
-Required properties:
-- compatible : Must be "ti,twl4030";
- For Integrated power-management/audio CODEC device used in OMAP3
- based boards
-- compatible : Must be "ti,twl6030";
- For Integrated power-management used in OMAP4 based boards
-- interrupts : This i2c device has an IRQ line connected to the main SoC
-- interrupt-controller : Since the twl support several interrupts internally,
- it is considered as an interrupt controller cascaded to the SoC one.
-- #interrupt-cells = <1>;
-
-Optional node:
-- Child nodes contain in the twl. The twl family is made of several variants
- that support a different number of features.
- The children nodes will thus depend of the capability of the variant.
-
-
-Example:
-/*
- * Integrated Power Management Chip
- * https://www.ti.com/lit/ds/symlink/twl6030.pdf
- */
-twl@48 {
- compatible = "ti,twl6030";
- reg = <0x48>;
- interrupts = <39>; /* IRQ_SYS_1N cascaded to gic */
- interrupt-controller;
- #interrupt-cells = <1>;
- interrupt-parent = <&gic>;
- #address-cells = <1>;
- #size-cells = <0>;
-
- twl_rtc {
- compatible = "ti,twl_rtc";
- interrupts = <11>;
- reg = <0>;
- };
-};
diff --git a/Documentation/devicetree/bindings/mfd/x-powers,axp152.yaml b/Documentation/devicetree/bindings/mfd/x-powers,axp152.yaml
index 9ad55746133b..06f1779835a1 100644
--- a/Documentation/devicetree/bindings/mfd/x-powers,axp152.yaml
+++ b/Documentation/devicetree/bindings/mfd/x-powers,axp152.yaml
@@ -67,7 +67,10 @@ allOf:
properties:
compatible:
contains:
- const: x-powers,axp305
+ enum:
+ - x-powers,axp15060
+ - x-powers,axp305
+ - x-powers,axp313a
then:
required:
diff --git a/Documentation/devicetree/bindings/power/supply/max8925_battery.txt b/Documentation/devicetree/bindings/power/supply/max8925_battery.txt
deleted file mode 100644
index d7e3e0c0f71d..000000000000
--- a/Documentation/devicetree/bindings/power/supply/max8925_battery.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-max8925-battery bindings
-~~~~~~~~~~~~~~~~
-
-Optional properties :
- - batt-detect: whether support battery detect
- - topoff-threshold: set charging current in topoff mode
- - fast-charge: set charging current in fast mode
- - no-temp-support: whether support temperature protection detect
- - no-insert-detect: whether support insert detect
-
-Example:
- charger {
- batt-detect = <0>;
- topoff-threshold = <1>;
- fast-charge = <7>;
- no-temp-support = <0>;
- no-insert-detect = <0>;
- };
diff --git a/drivers/i2c/i2c-core.h b/drivers/i2c/i2c-core.h
index 1247e6e6e975..05b8b8dfa9bd 100644
--- a/drivers/i2c/i2c-core.h
+++ b/drivers/i2c/i2c-core.h
@@ -29,7 +29,7 @@ int i2c_dev_irq_from_resources(const struct resource *resources,
*/
static inline bool i2c_in_atomic_xfer_mode(void)
{
- return system_state > SYSTEM_RUNNING && irqs_disabled();
+ return system_state > SYSTEM_RUNNING && !preemptible();
}
static inline int __i2c_lock_bus_helper(struct i2c_adapter *adap)
diff --git a/drivers/mfd/arizona-i2c.c b/drivers/mfd/arizona-i2c.c
index 9b7183ffc928..10e76fc8f12e 100644
--- a/drivers/mfd/arizona-i2c.c
+++ b/drivers/mfd/arizona-i2c.c
@@ -22,19 +22,12 @@
static int arizona_i2c_probe(struct i2c_client *i2c)
{
- const struct i2c_device_id *id = i2c_client_get_device_id(i2c);
- const void *match_data;
struct arizona *arizona;
const struct regmap_config *regmap_config = NULL;
- unsigned long type = 0;
+ unsigned long type;
int ret;
- match_data = device_get_match_data(&i2c->dev);
- if (match_data)
- type = (unsigned long)match_data;
- else if (id)
- type = id->driver_data;
-
+ type = (uintptr_t)i2c_get_match_data(i2c);
switch (type) {
case WM5102:
if (IS_ENABLED(CONFIG_MFD_WM5102))
diff --git a/drivers/mfd/arizona-spi.c b/drivers/mfd/arizona-spi.c
index 02cf4f3e91d7..de5d894ac04a 100644
--- a/drivers/mfd/arizona-spi.c
+++ b/drivers/mfd/arizona-spi.c
@@ -159,6 +159,9 @@ static int arizona_spi_acpi_probe(struct arizona *arizona)
arizona->pdata.micd_ranges = arizona_micd_aosp_ranges;
arizona->pdata.num_micd_ranges = ARRAY_SIZE(arizona_micd_aosp_ranges);
+ /* Use left headphone speaker for HP vs line-out detection */
+ arizona->pdata.hpdet_channel = ARIZONA_ACCDET_MODE_HPL;
+
return 0;
}
diff --git a/drivers/mfd/atmel-hlcdc.c b/drivers/mfd/atmel-hlcdc.c
index 20de7f49a830..4c4e35d404f3 100644
--- a/drivers/mfd/atmel-hlcdc.c
+++ b/drivers/mfd/atmel-hlcdc.c
@@ -139,6 +139,7 @@ static const struct of_device_id atmel_hlcdc_match[] = {
{ .compatible = "atmel,sama5d3-hlcdc" },
{ .compatible = "atmel,sama5d4-hlcdc" },
{ .compatible = "microchip,sam9x60-hlcdc" },
+ { .compatible = "microchip,sam9x75-xlcdc" },
{ /* sentinel */ },
};
MODULE_DEVICE_TABLE(of, atmel_hlcdc_match);
diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
index 87603eeaa277..deaa969bab4e 100644
--- a/drivers/mfd/axp20x.c
+++ b/drivers/mfd/axp20x.c
@@ -22,7 +22,8 @@
#include <linux/mfd/axp20x.h>
#include <linux/mfd/core.h>
#include <linux/module.h>
-#include <linux/of_device.h>
+#include <linux/of.h>
+#include <linux/property.h>
#include <linux/reboot.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
@@ -1131,25 +1132,10 @@ static int axp20x_power_off(struct sys_off_data *data)
int axp20x_match_device(struct axp20x_dev *axp20x)
{
struct device *dev = axp20x->dev;
- const struct acpi_device_id *acpi_id;
- const struct of_device_id *of_id;
-
- if (dev->of_node) {
- of_id = of_match_device(dev->driver->of_match_table, dev);
- if (!of_id) {
- dev_err(dev, "Unable to match OF ID\n");
- return -ENODEV;
- }
- axp20x->variant = (long)of_id->data;
- } else {
- acpi_id = acpi_match_device(dev->driver->acpi_match_table, dev);
- if (!acpi_id || !acpi_id->driver_data) {
- dev_err(dev, "Unable to match ACPI ID and data\n");
- return -ENODEV;
- }
- axp20x->variant = (long)acpi_id->driver_data;
- }
+ const struct mfd_cell *cells_no_irq = NULL;
+ int nr_cells_no_irq = 0;
+ axp20x->variant = (long)device_get_match_data(dev);
switch (axp20x->variant) {
case AXP152_ID:
axp20x->nr_cells = ARRAY_SIZE(axp152_cells);
@@ -1207,14 +1193,15 @@ int axp20x_match_device(struct axp20x_dev *axp20x)
* if there is no interrupt line.
*/
if (of_property_read_bool(axp20x->dev->of_node,
- "x-powers,self-working-mode") &&
- axp20x->irq > 0) {
+ "x-powers,self-working-mode")) {
axp20x->nr_cells = ARRAY_SIZE(axp806_self_working_cells);
axp20x->cells = axp806_self_working_cells;
} else {
axp20x->nr_cells = ARRAY_SIZE(axp806_cells);
axp20x->cells = axp806_cells;
}
+ nr_cells_no_irq = ARRAY_SIZE(axp806_cells);
+ cells_no_irq = axp806_cells;
axp20x->regmap_cfg = &axp806_regmap_config;
axp20x->regmap_irq_chip = &axp806_regmap_irq_chip;
break;
@@ -1238,24 +1225,8 @@ int axp20x_match_device(struct axp20x_dev *axp20x)
axp20x->regmap_irq_chip = &axp803_regmap_irq_chip;
break;
case AXP15060_ID:
- /*
- * Don't register the power key part if there is no interrupt
- * line.
- *
- * Since most use cases of AXP PMICs are Allwinner SOCs, board
- * designers follow Allwinner's reference design and connects
- * IRQ line to SOC, there's no need for those variants to deal
- * with cases that IRQ isn't connected. However, AXP15660 is
- * used by some other vendors' SOCs that didn't connect IRQ
- * line, we need to deal with this case.
- */
- if (axp20x->irq > 0) {
- axp20x->nr_cells = ARRAY_SIZE(axp15060_cells);
- axp20x->cells = axp15060_cells;
- } else {
- axp20x->nr_cells = ARRAY_SIZE(axp_regulator_only_cells);
- axp20x->cells = axp_regulator_only_cells;
- }
+ axp20x->nr_cells = ARRAY_SIZE(axp15060_cells);
+ axp20x->cells = axp15060_cells;
axp20x->regmap_cfg = &axp15060_regmap_config;
axp20x->regmap_irq_chip = &axp15060_regmap_irq_chip;
break;
@@ -1263,6 +1234,23 @@ int axp20x_match_device(struct axp20x_dev *axp20x)
dev_err(dev, "unsupported AXP20X ID %lu\n", axp20x->variant);
return -EINVAL;
}
+
+ /*
+ * Use an alternative cell array when no interrupt line is connected,
+ * since IRQs are required by some drivers.
+ * The default is the safe "regulator-only", as this works fine without
+ * an interrupt specified.
+ */
+ if (axp20x->irq <= 0) {
+ if (cells_no_irq) {
+ axp20x->nr_cells = nr_cells_no_irq;
+ axp20x->cells = cells_no_irq;
+ } else {
+ axp20x->nr_cells = ARRAY_SIZE(axp_regulator_only_cells);
+ axp20x->cells = axp_regulator_only_cells;
+ }
+ }
+
dev_info(dev, "AXP20x variant %s found\n",
axp20x_model_names[axp20x->variant]);
diff --git a/drivers/mfd/db8500-prcmu.c b/drivers/mfd/db8500-prcmu.c
index 27a881da4d6e..5b3e355e78f6 100644
--- a/drivers/mfd/db8500-prcmu.c
+++ b/drivers/mfd/db8500-prcmu.c
@@ -2639,9 +2639,9 @@ static void dbx500_fw_version_init(struct device_node *np)
fw_info.version.api_version = (version >> 8) & 0xFF;
fw_info.version.func_version = (version >> 16) & 0xFF;
fw_info.version.errata = (version >> 24) & 0xFF;
- strncpy(fw_info.version.project_name,
+ strscpy(fw_info.version.project_name,
fw_project_name(fw_info.version.project),
- PRCMU_FW_PROJECT_NAME_LEN);
+ sizeof(fw_info.version.project_name));
fw_info.valid = true;
pr_info("PRCMU firmware: %s(%d), version %d.%d.%d\n",
fw_info.version.project_name,
diff --git a/drivers/mfd/dln2.c b/drivers/mfd/dln2.c
index c7510434380a..fbbe82c6e75b 100644
--- a/drivers/mfd/dln2.c
+++ b/drivers/mfd/dln2.c
@@ -826,7 +826,6 @@ out_stop_rx:
dln2_stop_rx_urbs(dln2);
out_free:
- usb_put_dev(dln2->usb_dev);
dln2_free(dln2);
return ret;
diff --git a/drivers/mfd/hi6421-pmic-core.c b/drivers/mfd/hi6421-pmic-core.c
index a6a890537a1e..5af24a438329 100644
--- a/drivers/mfd/hi6421-pmic-core.c
+++ b/drivers/mfd/hi6421-pmic-core.c
@@ -15,8 +15,9 @@
#include <linux/mfd/core.h>
#include <linux/mfd/hi6421-pmic.h>
#include <linux/module.h>
-#include <linux/of_device.h>
+#include <linux/of.h>
#include <linux/platform_device.h>
+#include <linux/property.h>
#include <linux/regmap.h>
static const struct mfd_cell hi6421_devs[] = {
@@ -50,16 +51,12 @@ MODULE_DEVICE_TABLE(of, of_hi6421_pmic_match);
static int hi6421_pmic_probe(struct platform_device *pdev)
{
struct hi6421_pmic *pmic;
- const struct of_device_id *id;
const struct mfd_cell *subdevs;
enum hi6421_type type;
void __iomem *base;
int n_subdevs, ret;
- id = of_match_device(of_hi6421_pmic_match, &pdev->dev);
- if (!id)
- return -EINVAL;
- type = (uintptr_t)id->data;
+ type = (uintptr_t)device_get_match_data(&pdev->dev);
pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL);
if (!pmic)
diff --git a/drivers/mfd/intel-lpss-pci.c b/drivers/mfd/intel-lpss-pci.c
index 699f44ffff0e..ae5759200622 100644
--- a/drivers/mfd/intel-lpss-pci.c
+++ b/drivers/mfd/intel-lpss-pci.c
@@ -561,6 +561,19 @@ static const struct pci_device_id intel_lpss_pci_ids[] = {
{ PCI_VDEVICE(INTEL, 0xa3e2), (kernel_ulong_t)&spt_i2c_info },
{ PCI_VDEVICE(INTEL, 0xa3e3), (kernel_ulong_t)&spt_i2c_info },
{ PCI_VDEVICE(INTEL, 0xa3e6), (kernel_ulong_t)&spt_uart_info },
+ /* LNL-M */
+ { PCI_VDEVICE(INTEL, 0xa825), (kernel_ulong_t)&bxt_uart_info },
+ { PCI_VDEVICE(INTEL, 0xa826), (kernel_ulong_t)&bxt_uart_info },
+ { PCI_VDEVICE(INTEL, 0xa827), (kernel_ulong_t)&tgl_info },
+ { PCI_VDEVICE(INTEL, 0xa830), (kernel_ulong_t)&tgl_info },
+ { PCI_VDEVICE(INTEL, 0xa846), (kernel_ulong_t)&tgl_info },
+ { PCI_VDEVICE(INTEL, 0xa850), (kernel_ulong_t)&ehl_i2c_info },
+ { PCI_VDEVICE(INTEL, 0xa851), (kernel_ulong_t)&ehl_i2c_info },
+ { PCI_VDEVICE(INTEL, 0xa852), (kernel_ulong_t)&bxt_uart_info },
+ { PCI_VDEVICE(INTEL, 0xa878), (kernel_ulong_t)&ehl_i2c_info },
+ { PCI_VDEVICE(INTEL, 0xa879), (kernel_ulong_t)&ehl_i2c_info },
+ { PCI_VDEVICE(INTEL, 0xa87a), (kernel_ulong_t)&ehl_i2c_info },
+ { PCI_VDEVICE(INTEL, 0xa87b), (kernel_ulong_t)&ehl_i2c_info },
{ }
};
MODULE_DEVICE_TABLE(pci, intel_lpss_pci_ids);
diff --git a/drivers/mfd/iqs62x.c b/drivers/mfd/iqs62x.c
index e03b4d38fbb0..1b465590567c 100644
--- a/drivers/mfd/iqs62x.c
+++ b/drivers/mfd/iqs62x.c
@@ -96,7 +96,7 @@ struct iqs62x_fw_blk {
u8 addr;
u8 mask;
u8 len;
- u8 data[];
+ u8 data[] __counted_by(len);
};
struct iqs62x_info {
diff --git a/drivers/mfd/lochnagar-i2c.c b/drivers/mfd/lochnagar-i2c.c
index 59092f839d65..0b76fcccd0bd 100644
--- a/drivers/mfd/lochnagar-i2c.c
+++ b/drivers/mfd/lochnagar-i2c.c
@@ -15,8 +15,8 @@
#include <linux/i2c.h>
#include <linux/lockdep.h>
#include <linux/mfd/core.h>
+#include <linux/mod_devicetable.h>
#include <linux/mutex.h>
-#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/regmap.h>
@@ -270,7 +270,6 @@ static int lochnagar_i2c_probe(struct i2c_client *i2c)
{
struct device *dev = &i2c->dev;
const struct lochnagar_config *config = NULL;
- const struct of_device_id *of_id;
struct lochnagar *lochnagar;
struct gpio_desc *reset, *present;
unsigned int val;
@@ -282,11 +281,7 @@ static int lochnagar_i2c_probe(struct i2c_client *i2c)
if (!lochnagar)
return -ENOMEM;
- of_id = of_match_device(lochnagar_of_match, dev);
- if (!of_id)
- return -EINVAL;
-
- config = of_id->data;
+ config = i2c_get_match_data(i2c);
lochnagar->dev = dev;
mutex_init(&lochnagar->analogue_config_lock);
diff --git a/drivers/mfd/lp87565.c b/drivers/mfd/lp87565.c
index 1b7f8349911d..08c62ddfb4f5 100644
--- a/drivers/mfd/lp87565.c
+++ b/drivers/mfd/lp87565.c
@@ -6,10 +6,11 @@
*/
#include <linux/gpio/consumer.h>
+#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/mfd/core.h>
+#include <linux/mod_devicetable.h>
#include <linux/module.h>
-#include <linux/of_device.h>
#include <linux/regmap.h>
#include <linux/mfd/lp87565.h>
@@ -46,7 +47,6 @@ MODULE_DEVICE_TABLE(of, of_lp87565_match_table);
static int lp87565_probe(struct i2c_client *client)
{
struct lp87565 *lp87565;
- const struct of_device_id *of_id;
int ret;
unsigned int otpid;
@@ -89,10 +89,7 @@ static int lp87565_probe(struct i2c_client *client)
}
lp87565->rev = otpid & LP87565_OTP_REV_OTP_ID;
-
- of_id = of_match_device(of_lp87565_match_table, &client->dev);
- if (of_id)
- lp87565->dev_type = (uintptr_t)of_id->data;
+ lp87565->dev_type = (uintptr_t)i2c_get_match_data(client);
i2c_set_clientdata(client, lp87565);
diff --git a/drivers/mfd/lpc_ich.c b/drivers/mfd/lpc_ich.c
index 7b1c597b6879..73a0e7f9bd31 100644
--- a/drivers/mfd/lpc_ich.c
+++ b/drivers/mfd/lpc_ich.c
@@ -85,19 +85,6 @@
#define wdt_mem_res(i) wdt_res(ICH_RES_MEM_OFF, i)
#define wdt_res(b, i) (&wdt_ich_res[(b) + (i)])
-struct lpc_ich_priv {
- int chipset;
-
- int abase; /* ACPI base */
- int actrl_pbase; /* ACPI control or PMC base */
- int gbase; /* GPIO base */
- int gctrl; /* GPIO control */
-
- int abase_save; /* Cached ACPI base value */
- int actrl_pbase_save; /* Cached ACPI control or PMC base value */
- int gctrl_save; /* Cached GPIO control value */
-};
-
static struct resource wdt_ich_res[] = {
/* ACPI - TCO */
{
@@ -144,22 +131,33 @@ static struct mfd_cell lpc_ich_gpio_cell = {
.ignore_resource_conflicts = true,
};
+#define INTEL_GPIO_RESOURCE_SIZE 0x1000
+
+struct lpc_ich_gpio_info {
+ const char *hid;
+ const struct mfd_cell *devices;
+ size_t nr_devices;
+ struct resource **resources;
+ size_t nr_resources;
+ const resource_size_t *offsets;
+};
+
#define APL_GPIO_NORTH 0
#define APL_GPIO_NORTHWEST 1
#define APL_GPIO_WEST 2
#define APL_GPIO_SOUTHWEST 3
+
#define APL_GPIO_NR_DEVICES 4
+#define APL_GPIO_NR_RESOURCES 4
/* Offset data for Apollo Lake GPIO controllers */
-static resource_size_t apl_gpio_offsets[APL_GPIO_NR_DEVICES] = {
+static const resource_size_t apl_gpio_offsets[APL_GPIO_NR_RESOURCES] = {
[APL_GPIO_NORTH] = 0xc50000,
[APL_GPIO_NORTHWEST] = 0xc40000,
[APL_GPIO_WEST] = 0xc70000,
[APL_GPIO_SOUTHWEST] = 0xc00000,
};
-#define APL_GPIO_RESOURCE_SIZE 0x1000
-
#define APL_GPIO_IRQ 14
static struct resource apl_gpio_resources[APL_GPIO_NR_DEVICES][2] = {
@@ -181,6 +179,13 @@ static struct resource apl_gpio_resources[APL_GPIO_NR_DEVICES][2] = {
},
};
+static struct resource *apl_gpio_mem_resources[APL_GPIO_NR_RESOURCES] = {
+ [APL_GPIO_NORTH] = &apl_gpio_resources[APL_GPIO_NORTH][0],
+ [APL_GPIO_NORTHWEST] = &apl_gpio_resources[APL_GPIO_NORTHWEST][0],
+ [APL_GPIO_WEST] = &apl_gpio_resources[APL_GPIO_WEST][0],
+ [APL_GPIO_SOUTHWEST] = &apl_gpio_resources[APL_GPIO_SOUTHWEST][0],
+};
+
static const struct mfd_cell apl_gpio_devices[APL_GPIO_NR_DEVICES] = {
[APL_GPIO_NORTH] = {
.name = "apollolake-pinctrl",
@@ -212,6 +217,58 @@ static const struct mfd_cell apl_gpio_devices[APL_GPIO_NR_DEVICES] = {
},
};
+static const struct lpc_ich_gpio_info apl_gpio_info = {
+ .hid = "INT3452",
+ .devices = apl_gpio_devices,
+ .nr_devices = ARRAY_SIZE(apl_gpio_devices),
+ .resources = apl_gpio_mem_resources,
+ .nr_resources = ARRAY_SIZE(apl_gpio_mem_resources),
+ .offsets = apl_gpio_offsets,
+};
+
+#define DNV_GPIO_NORTH 0
+#define DNV_GPIO_SOUTH 1
+
+#define DNV_GPIO_NR_DEVICES 1
+#define DNV_GPIO_NR_RESOURCES 2
+
+/* Offset data for Denverton GPIO controllers */
+static const resource_size_t dnv_gpio_offsets[DNV_GPIO_NR_RESOURCES] = {
+ [DNV_GPIO_NORTH] = 0xc20000,
+ [DNV_GPIO_SOUTH] = 0xc50000,
+};
+
+#define DNV_GPIO_IRQ 14
+
+static struct resource dnv_gpio_resources[DNV_GPIO_NR_RESOURCES + 1] = {
+ [DNV_GPIO_NORTH] = DEFINE_RES_MEM(0, 0),
+ [DNV_GPIO_SOUTH] = DEFINE_RES_MEM(0, 0),
+ DEFINE_RES_IRQ(DNV_GPIO_IRQ),
+};
+
+static struct resource *dnv_gpio_mem_resources[DNV_GPIO_NR_RESOURCES] = {
+ [DNV_GPIO_NORTH] = &dnv_gpio_resources[DNV_GPIO_NORTH],
+ [DNV_GPIO_SOUTH] = &dnv_gpio_resources[DNV_GPIO_SOUTH],
+};
+
+static const struct mfd_cell dnv_gpio_devices[DNV_GPIO_NR_DEVICES] = {
+ {
+ .name = "denverton-pinctrl",
+ .num_resources = ARRAY_SIZE(dnv_gpio_resources),
+ .resources = dnv_gpio_resources,
+ .ignore_resource_conflicts = true,
+ },
+};
+
+static const struct lpc_ich_gpio_info dnv_gpio_info = {
+ .hid = "INTC3000",
+ .devices = dnv_gpio_devices,
+ .nr_devices = ARRAY_SIZE(dnv_gpio_devices),
+ .resources = dnv_gpio_mem_resources,
+ .nr_resources = ARRAY_SIZE(dnv_gpio_mem_resources),
+ .offsets = dnv_gpio_offsets,
+};
+
static struct mfd_cell lpc_ich_spi_cell = {
.name = "intel-spi",
.num_resources = ARRAY_SIZE(intel_spi_res),
@@ -289,10 +346,24 @@ enum lpc_chipsets {
LPC_LEWISBURG, /* Lewisburg */
LPC_9S, /* 9 Series */
LPC_APL, /* Apollo Lake SoC */
+ LPC_DNV, /* Denverton SoC */
LPC_GLK, /* Gemini Lake SoC */
LPC_COUGARMOUNTAIN,/* Cougar Mountain SoC*/
};
+struct lpc_ich_priv {
+ enum lpc_chipsets chipset;
+
+ int abase; /* ACPI base */
+ int actrl_pbase; /* ACPI control or PMC base */
+ int gbase; /* GPIO base */
+ int gctrl; /* GPIO control */
+
+ int abase_save; /* Cached ACPI base value */
+ int actrl_pbase_save; /* Cached ACPI control or PMC base value */
+ int gctrl_save; /* Cached GPIO control value */
+};
+
static struct lpc_ich_info lpc_chipset_info[] = {
[LPC_ICH] = {
.name = "ICH",
@@ -618,8 +689,13 @@ static struct lpc_ich_info lpc_chipset_info[] = {
[LPC_APL] = {
.name = "Apollo Lake SoC",
.iTCO_version = 5,
+ .gpio_info = &apl_gpio_info,
.spi_type = INTEL_SPI_BXT,
},
+ [LPC_DNV] = {
+ .name = "Denverton SoC",
+ .gpio_info = &dnv_gpio_info,
+ },
[LPC_GLK] = {
.name = "Gemini Lake SoC",
.spi_type = INTEL_SPI_BXT,
@@ -638,6 +714,7 @@ static struct lpc_ich_info lpc_chipset_info[] = {
*/
static const struct pci_device_id lpc_ich_ids[] = {
{ PCI_VDEVICE(INTEL, 0x0f1c), LPC_BAYTRAIL},
+ { PCI_VDEVICE(INTEL, 0x19dc), LPC_DNV},
{ PCI_VDEVICE(INTEL, 0x1c41), LPC_CPT},
{ PCI_VDEVICE(INTEL, 0x1c42), LPC_CPTD},
{ PCI_VDEVICE(INTEL, 0x1c43), LPC_CPTM},
@@ -1156,30 +1233,32 @@ wdt_done:
static int lpc_ich_init_pinctrl(struct pci_dev *dev)
{
+ struct lpc_ich_priv *priv = pci_get_drvdata(dev);
+ const struct lpc_ich_gpio_info *info = lpc_chipset_info[priv->chipset].gpio_info;
struct resource base;
unsigned int i;
int ret;
/* Check, if GPIO has been exported as an ACPI device */
- if (acpi_dev_present("INT3452", NULL, -1))
+ if (acpi_dev_present(info->hid, NULL, -1))
return -EEXIST;
ret = p2sb_bar(dev->bus, 0, &base);
if (ret)
return ret;
- for (i = 0; i < ARRAY_SIZE(apl_gpio_devices); i++) {
- struct resource *mem = &apl_gpio_resources[i][0];
- resource_size_t offset = apl_gpio_offsets[i];
+ for (i = 0; i < info->nr_resources; i++) {
+ struct resource *mem = info->resources[i];
+ resource_size_t offset = info->offsets[i];
/* Fill MEM resource */
mem->start = base.start + offset;
- mem->end = base.start + offset + APL_GPIO_RESOURCE_SIZE - 1;
+ mem->end = base.start + offset + INTEL_GPIO_RESOURCE_SIZE - 1;
mem->flags = base.flags;
}
- return mfd_add_devices(&dev->dev, 0, apl_gpio_devices,
- ARRAY_SIZE(apl_gpio_devices), NULL, 0, NULL);
+ return mfd_add_devices(&dev->dev, 0, info->devices, info->nr_devices,
+ NULL, 0, NULL);
}
static bool lpc_ich_byt_set_writeable(void __iomem *base, void *data)
@@ -1332,7 +1411,7 @@ static int lpc_ich_probe(struct pci_dev *dev,
cell_added = true;
}
- if (priv->chipset == LPC_APL) {
+ if (lpc_chipset_info[priv->chipset].gpio_info) {
ret = lpc_ich_init_pinctrl(dev);
if (!ret)
cell_added = true;
diff --git a/drivers/mfd/madera-i2c.c b/drivers/mfd/madera-i2c.c
index a404ea26bc79..0986e4a99f4a 100644
--- a/drivers/mfd/madera-i2c.c
+++ b/drivers/mfd/madera-i2c.c
@@ -18,21 +18,14 @@
static int madera_i2c_probe(struct i2c_client *i2c)
{
- const struct i2c_device_id *id = i2c_client_get_device_id(i2c);
struct madera *madera;
const struct regmap_config *regmap_16bit_config = NULL;
const struct regmap_config *regmap_32bit_config = NULL;
- const void *of_data;
unsigned long type;
const char *name;
int ret;
- of_data = of_device_get_match_data(&i2c->dev);
- if (of_data)
- type = (unsigned long)of_data;
- else
- type = id->driver_data;
-
+ type = (uintptr_t)i2c_get_match_data(i2c);
switch (type) {
case CS47L15:
if (IS_ENABLED(CONFIG_MFD_CS47L15)) {
diff --git a/drivers/mfd/max14577.c b/drivers/mfd/max14577.c
index 1f4f5002595c..8f7472c76009 100644
--- a/drivers/mfd/max14577.c
+++ b/drivers/mfd/max14577.c
@@ -9,9 +9,10 @@
// This driver is based on max8997.c
#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/interrupt.h>
-#include <linux/of_device.h>
#include <linux/mfd/core.h>
#include <linux/mfd/max14577.h>
#include <linux/mfd/max14577-private.h>
@@ -357,7 +358,6 @@ static void max77836_remove(struct max14577 *max14577)
static int max14577_i2c_probe(struct i2c_client *i2c)
{
- const struct i2c_device_id *id = i2c_client_get_device_id(i2c);
struct max14577 *max14577;
struct max14577_platform_data *pdata = dev_get_platdata(&i2c->dev);
struct device_node *np = i2c->dev.of_node;
@@ -397,15 +397,7 @@ static int max14577_i2c_probe(struct i2c_client *i2c)
return ret;
}
- if (np) {
- const struct of_device_id *of_id;
-
- of_id = of_match_device(max14577_dt_match, &i2c->dev);
- if (of_id)
- max14577->dev_type = (uintptr_t)of_id->data;
- } else {
- max14577->dev_type = id->driver_data;
- }
+ max14577->dev_type = (enum maxim_device_type)i2c_get_match_data(i2c);
max14577_print_dev_type(max14577);
diff --git a/drivers/mfd/max77541.c b/drivers/mfd/max77541.c
index 10c2e274b4af..d77c31c86e43 100644
--- a/drivers/mfd/max77541.c
+++ b/drivers/mfd/max77541.c
@@ -162,7 +162,6 @@ static int max77541_pmic_setup(struct device *dev)
static int max77541_probe(struct i2c_client *client)
{
- const struct i2c_device_id *id = i2c_client_get_device_id(client);
struct device *dev = &client->dev;
struct max77541 *max77541;
@@ -173,10 +172,7 @@ static int max77541_probe(struct i2c_client *client)
i2c_set_clientdata(client, max77541);
max77541->i2c = client;
- max77541->id = (uintptr_t)device_get_match_data(dev);
- if (!max77541->id)
- max77541->id = (enum max7754x_ids)id->driver_data;
-
+ max77541->id = (uintptr_t)i2c_get_match_data(client);
if (!max77541->id)
return -EINVAL;
diff --git a/drivers/mfd/max77620.c b/drivers/mfd/max77620.c
index e63e8e47d908..74ef3f6d576c 100644
--- a/drivers/mfd/max77620.c
+++ b/drivers/mfd/max77620.c
@@ -172,7 +172,7 @@ static const struct regmap_config max77620_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.max_register = MAX77620_REG_DVSSD4 + 1,
- .cache_type = REGCACHE_RBTREE,
+ .cache_type = REGCACHE_MAPLE,
.rd_table = &max77620_readable_table,
.wr_table = &max77620_writable_table,
.volatile_table = &max77620_volatile_table,
@@ -184,7 +184,7 @@ static const struct regmap_config max20024_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.max_register = MAX20024_REG_MAX_ADD + 1,
- .cache_type = REGCACHE_RBTREE,
+ .cache_type = REGCACHE_MAPLE,
.rd_table = &max20024_readable_table,
.wr_table = &max77620_writable_table,
.volatile_table = &max77620_volatile_table,
@@ -213,7 +213,7 @@ static const struct regmap_config max77663_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.max_register = MAX77620_REG_CID5 + 1,
- .cache_type = REGCACHE_RBTREE,
+ .cache_type = REGCACHE_MAPLE,
.rd_table = &max77663_readable_table,
.wr_table = &max77663_writable_table,
.volatile_table = &max77620_volatile_table,
diff --git a/drivers/mfd/max77686.c b/drivers/mfd/max77686.c
index 91c286c4571c..0118a444a68b 100644
--- a/drivers/mfd/max77686.c
+++ b/drivers/mfd/max77686.c
@@ -108,7 +108,7 @@ static const struct regmap_config max77802_regmap_config = {
.precious_reg = max77802_is_precious_reg,
.volatile_reg = max77802_is_volatile_reg,
.name = "max77802-pmic",
- .cache_type = REGCACHE_RBTREE,
+ .cache_type = REGCACHE_MAPLE,
};
static const struct regmap_irq max77686_irqs[] = {
diff --git a/drivers/mfd/max8907.c b/drivers/mfd/max8907.c
index 8bbe7979db91..accf426234b6 100644
--- a/drivers/mfd/max8907.c
+++ b/drivers/mfd/max8907.c
@@ -63,7 +63,7 @@ static const struct regmap_config max8907_regmap_gen_config = {
.precious_reg = max8907_gen_is_precious_reg,
.writeable_reg = max8907_gen_is_writeable_reg,
.max_register = MAX8907_REG_LDO20VOUT,
- .cache_type = REGCACHE_RBTREE,
+ .cache_type = REGCACHE_MAPLE,
};
static bool max8907_rtc_is_volatile_reg(struct device *dev, unsigned int reg)
@@ -108,7 +108,7 @@ static const struct regmap_config max8907_regmap_rtc_config = {
.precious_reg = max8907_rtc_is_precious_reg,
.writeable_reg = max8907_rtc_is_writeable_reg,
.max_register = MAX8907_REG_MPL_CNTL,
- .cache_type = REGCACHE_RBTREE,
+ .cache_type = REGCACHE_MAPLE,
};
static const struct regmap_irq max8907_chg_irqs[] = {
diff --git a/drivers/mfd/max8997.c b/drivers/mfd/max8997.c
index 110bef71f208..ffe96b40368e 100644
--- a/drivers/mfd/max8997.c
+++ b/drivers/mfd/max8997.c
@@ -142,18 +142,8 @@ static struct max8997_platform_data *max8997_i2c_parse_dt_pdata(
return pd;
}
-static inline unsigned long max8997_i2c_get_driver_data(struct i2c_client *i2c,
- const struct i2c_device_id *id)
-{
- if (i2c->dev.of_node)
- return (unsigned long)of_device_get_match_data(&i2c->dev);
-
- return id->driver_data;
-}
-
static int max8997_i2c_probe(struct i2c_client *i2c)
{
- const struct i2c_device_id *id = i2c_client_get_device_id(i2c);
struct max8997_dev *max8997;
struct max8997_platform_data *pdata = dev_get_platdata(&i2c->dev);
int ret = 0;
@@ -166,7 +156,7 @@ static int max8997_i2c_probe(struct i2c_client *i2c)
i2c_set_clientdata(i2c, max8997);
max8997->dev = &i2c->dev;
max8997->i2c = i2c;
- max8997->type = max8997_i2c_get_driver_data(i2c, id);
+ max8997->type = (uintptr_t)i2c_get_match_data(i2c);
max8997->irq = i2c->irq;
if (IS_ENABLED(CONFIG_OF) && max8997->dev->of_node) {
diff --git a/drivers/mfd/max8998.c b/drivers/mfd/max8998.c
index 4cc426a6c767..6ba27171da28 100644
--- a/drivers/mfd/max8998.c
+++ b/drivers/mfd/max8998.c
@@ -152,18 +152,8 @@ static struct max8998_platform_data *max8998_i2c_parse_dt_pdata(
return pd;
}
-static inline unsigned long max8998_i2c_get_driver_data(struct i2c_client *i2c,
- const struct i2c_device_id *id)
-{
- if (i2c->dev.of_node)
- return (unsigned long)of_device_get_match_data(&i2c->dev);
-
- return id->driver_data;
-}
-
static int max8998_i2c_probe(struct i2c_client *i2c)
{
- const struct i2c_device_id *id = i2c_client_get_device_id(i2c);
struct max8998_platform_data *pdata = dev_get_platdata(&i2c->dev);
struct max8998_dev *max8998;
int ret = 0;
@@ -183,7 +173,7 @@ static int max8998_i2c_probe(struct i2c_client *i2c)
max8998->dev = &i2c->dev;
max8998->i2c = i2c;
max8998->irq = i2c->irq;
- max8998->type = max8998_i2c_get_driver_data(i2c, id);
+ max8998->type = (uintptr_t)i2c_get_match_data(i2c);
max8998->pdata = pdata;
if (pdata) {
max8998->ono = pdata->ono;
diff --git a/drivers/mfd/mc13xxx-spi.c b/drivers/mfd/mc13xxx-spi.c
index f70d79aa5a83..c973e2579bdf 100644
--- a/drivers/mfd/mc13xxx-spi.c
+++ b/drivers/mfd/mc13xxx-spi.c
@@ -8,13 +8,12 @@
*/
#include <linux/slab.h>
+#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <linux/mfd/core.h>
#include <linux/mfd/mc13xxx.h>
-#include <linux/of.h>
-#include <linux/of_device.h>
#include <linux/err.h>
#include <linux/spi/spi.h>
@@ -151,16 +150,7 @@ static int mc13xxx_spi_probe(struct spi_device *spi)
return ret;
}
- if (spi->dev.of_node) {
- const struct of_device_id *of_id =
- of_match_device(mc13xxx_dt_ids, &spi->dev);
-
- mc13xxx->variant = of_id->data;
- } else {
- const struct spi_device_id *id_entry = spi_get_device_id(spi);
-
- mc13xxx->variant = (void *)id_entry->driver_data;
- }
+ mc13xxx->variant = spi_get_device_match_data(spi);
return mc13xxx_common_init(&spi->dev);
}
diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c
index 0ed7c0d7784e..2b85509a90fc 100644
--- a/drivers/mfd/mfd-core.c
+++ b/drivers/mfd/mfd-core.c
@@ -146,6 +146,7 @@ static int mfd_add_device(struct device *parent, int id,
struct platform_device *pdev;
struct device_node *np = NULL;
struct mfd_of_node_entry *of_entry, *tmp;
+ bool disabled = false;
int ret = -ENOMEM;
int platform_id;
int r;
@@ -183,11 +184,10 @@ static int mfd_add_device(struct device *parent, int id,
if (IS_ENABLED(CONFIG_OF) && parent->of_node && cell->of_compatible) {
for_each_child_of_node(parent->of_node, np) {
if (of_device_is_compatible(np, cell->of_compatible)) {
- /* Ignore 'disabled' devices error free */
+ /* Skip 'disabled' devices */
if (!of_device_is_available(np)) {
- of_node_put(np);
- ret = 0;
- goto fail_alias;
+ disabled = true;
+ continue;
}
ret = mfd_match_of_node_to_dev(pdev, np, cell);
@@ -197,10 +197,17 @@ static int mfd_add_device(struct device *parent, int id,
if (ret)
goto fail_alias;
- break;
+ goto match;
}
}
+ if (disabled) {
+ /* Ignore 'disabled' devices error free */
+ ret = 0;
+ goto fail_alias;
+ }
+
+match:
if (!pdev->dev.of_node)
pr_warn("%s: Failed to locate of_node [id: %d]\n",
cell->name, platform_id);
diff --git a/drivers/mfd/motorola-cpcap.c b/drivers/mfd/motorola-cpcap.c
index a19691ba8d8b..d8243b956f87 100644
--- a/drivers/mfd/motorola-cpcap.c
+++ b/drivers/mfd/motorola-cpcap.c
@@ -11,7 +11,7 @@
#include <linux/irq.h>
#include <linux/kernel.h>
#include <linux/module.h>
-#include <linux/of_device.h>
+#include <linux/mod_devicetable.h>
#include <linux/regmap.h>
#include <linux/sysfs.h>
@@ -290,14 +290,9 @@ static const struct mfd_cell cpcap_mfd_devices[] = {
static int cpcap_probe(struct spi_device *spi)
{
- const struct of_device_id *match;
struct cpcap_ddata *cpcap;
int ret;
- match = of_match_device(cpcap_of_match, &spi->dev);
- if (!match)
- return -ENODEV;
-
cpcap = devm_kzalloc(&spi->dev, sizeof(*cpcap), GFP_KERNEL);
if (!cpcap)
return -ENOMEM;
diff --git a/drivers/mfd/mxs-lradc.c b/drivers/mfd/mxs-lradc.c
index 21f3033d6eb5..ec1b356562b9 100644
--- a/drivers/mfd/mxs-lradc.c
+++ b/drivers/mfd/mxs-lradc.c
@@ -16,8 +16,8 @@
#include <linux/mfd/mxs-lradc.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/of_device.h>
#include <linux/platform_device.h>
+#include <linux/property.h>
#include <linux/slab.h>
#define ADC_CELL 0
@@ -125,7 +125,6 @@ MODULE_DEVICE_TABLE(of, mxs_lradc_dt_ids);
static int mxs_lradc_probe(struct platform_device *pdev)
{
- const struct of_device_id *of_id;
struct device *dev = &pdev->dev;
struct device_node *node = dev->of_node;
struct mxs_lradc *lradc;
@@ -138,11 +137,7 @@ static int mxs_lradc_probe(struct platform_device *pdev)
if (!lradc)
return -ENOMEM;
- of_id = of_match_device(mxs_lradc_dt_ids, &pdev->dev);
- if (!of_id)
- return -EINVAL;
-
- lradc->soc = (uintptr_t)of_id->data;
+ lradc->soc = (enum mxs_lradc_id)device_get_match_data(&pdev->dev);
lradc->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(lradc->clk)) {
diff --git a/drivers/mfd/palmas.c b/drivers/mfd/palmas.c
index 6e562bab62e4..7fc886f4f80e 100644
--- a/drivers/mfd/palmas.c
+++ b/drivers/mfd/palmas.c
@@ -296,7 +296,7 @@ static const struct regmap_irq palmas_irqs[] = {
},
};
-static struct regmap_irq_chip palmas_irq_chip = {
+static const struct regmap_irq_chip palmas_irq_chip = {
.name = "palmas",
.irqs = palmas_irqs,
.num_irqs = ARRAY_SIZE(palmas_irqs),
@@ -309,7 +309,7 @@ static struct regmap_irq_chip palmas_irq_chip = {
PALMAS_INT1_MASK),
};
-static struct regmap_irq_chip tps65917_irq_chip = {
+static const struct regmap_irq_chip tps65917_irq_chip = {
.name = "tps65917",
.irqs = tps65917_irqs,
.num_irqs = ARRAY_SIZE(tps65917_irqs),
@@ -463,51 +463,29 @@ static void palmas_power_off(void)
__func__, ret);
}
-static unsigned int palmas_features = PALMAS_PMIC_FEATURE_SMPS10_BOOST;
-static unsigned int tps659038_features;
-
struct palmas_driver_data {
- unsigned int *features;
- struct regmap_irq_chip *irq_chip;
+ unsigned int features;
+ const struct regmap_irq_chip *irq_chip;
};
-static struct palmas_driver_data palmas_data = {
- .features = &palmas_features,
+static const struct palmas_driver_data palmas_data = {
+ .features = PALMAS_PMIC_FEATURE_SMPS10_BOOST,
.irq_chip = &palmas_irq_chip,
};
-static struct palmas_driver_data tps659038_data = {
- .features = &tps659038_features,
+static const struct palmas_driver_data tps659038_data = {
.irq_chip = &palmas_irq_chip,
};
-static struct palmas_driver_data tps65917_data = {
- .features = &tps659038_features,
+static const struct palmas_driver_data tps65917_data = {
.irq_chip = &tps65917_irq_chip,
};
-static const struct of_device_id of_palmas_match_tbl[] = {
- {
- .compatible = "ti,palmas",
- .data = &palmas_data,
- },
- {
- .compatible = "ti,tps659038",
- .data = &tps659038_data,
- },
- {
- .compatible = "ti,tps65917",
- .data = &tps65917_data,
- },
- { },
-};
-MODULE_DEVICE_TABLE(of, of_palmas_match_tbl);
-
static int palmas_i2c_probe(struct i2c_client *i2c)
{
struct palmas *palmas;
struct palmas_platform_data *pdata;
- struct palmas_driver_data *driver_data;
+ const struct palmas_driver_data *driver_data;
struct device_node *node = i2c->dev.of_node;
int ret = 0, i;
unsigned int reg, addr;
@@ -535,8 +513,8 @@ static int palmas_i2c_probe(struct i2c_client *i2c)
palmas->dev = &i2c->dev;
palmas->irq = i2c->irq;
- driver_data = (struct palmas_driver_data *) device_get_match_data(&i2c->dev);
- palmas->features = *driver_data->features;
+ driver_data = i2c_get_match_data(i2c);
+ palmas->features = driver_data->features;
for (i = 0; i < PALMAS_NUM_CLIENTS; i++) {
if (i == 0)
@@ -712,11 +690,19 @@ static void palmas_i2c_remove(struct i2c_client *i2c)
}
}
+static const struct of_device_id of_palmas_match_tbl[] = {
+ { .compatible = "ti,palmas", .data = &palmas_data },
+ { .compatible = "ti,tps659038", .data = &tps659038_data },
+ { .compatible = "ti,tps65917", .data = &tps65917_data },
+ { }
+};
+MODULE_DEVICE_TABLE(of, of_palmas_match_tbl);
+
static const struct i2c_device_id palmas_i2c_id[] = {
- { "palmas", },
- { "twl6035", },
- { "twl6037", },
- { "tps65913", },
+ { "palmas", (kernel_ulong_t)&palmas_data },
+ { "twl6035", (kernel_ulong_t)&palmas_data },
+ { "twl6037", (kernel_ulong_t)&palmas_data },
+ { "tps65913", (kernel_ulong_t)&palmas_data },
{ /* end */ }
};
MODULE_DEVICE_TABLE(i2c, palmas_i2c_id);
diff --git a/drivers/mfd/qcom-spmi-pmic.c b/drivers/mfd/qcom-spmi-pmic.c
index 7e2cd79d17eb..4549fa9f7d4b 100644
--- a/drivers/mfd/qcom-spmi-pmic.c
+++ b/drivers/mfd/qcom-spmi-pmic.c
@@ -8,10 +8,12 @@
#include <linux/gfp.h>
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_platform.h>
#include <linux/spmi.h>
#include <linux/types.h>
#include <linux/regmap.h>
-#include <linux/of_platform.h>
#include <soc/qcom/qcom-spmi-pmic.h>
#define PMIC_REV2 0x101
@@ -30,6 +32,8 @@ struct qcom_spmi_dev {
struct qcom_spmi_pmic pmic;
};
+static DEFINE_MUTEX(pmic_spmi_revid_lock);
+
#define N_USIDS(n) ((void *)n)
static const struct of_device_id pmic_spmi_id_table[] = {
@@ -76,24 +80,21 @@ static const struct of_device_id pmic_spmi_id_table[] = {
*
* This only supports PMICs with 1 or 2 USIDs.
*/
-static struct spmi_device *qcom_pmic_get_base_usid(struct device *dev)
+static struct spmi_device *qcom_pmic_get_base_usid(struct spmi_device *sdev, struct qcom_spmi_dev *ctx)
{
- struct spmi_device *sdev;
- struct qcom_spmi_dev *ctx;
struct device_node *spmi_bus;
- struct device_node *other_usid = NULL;
+ struct device_node *child;
int function_parent_usid, ret;
u32 pmic_addr;
- sdev = to_spmi_device(dev);
- ctx = dev_get_drvdata(&sdev->dev);
-
/*
* Quick return if the function device is already in the base
* USID. This will always be hit for PMICs with only 1 USID.
*/
- if (sdev->usid % ctx->num_usids == 0)
+ if (sdev->usid % ctx->num_usids == 0) {
+ get_device(&sdev->dev);
return sdev;
+ }
function_parent_usid = sdev->usid;
@@ -105,28 +106,61 @@ static struct spmi_device *qcom_pmic_get_base_usid(struct device *dev)
* device for USID 2.
*/
spmi_bus = of_get_parent(sdev->dev.of_node);
- do {
- other_usid = of_get_next_child(spmi_bus, other_usid);
-
- ret = of_property_read_u32_index(other_usid, "reg", 0, &pmic_addr);
- if (ret)
- return ERR_PTR(ret);
+ sdev = ERR_PTR(-ENODATA);
+ for_each_child_of_node(spmi_bus, child) {
+ ret = of_property_read_u32_index(child, "reg", 0, &pmic_addr);
+ if (ret) {
+ of_node_put(child);
+ sdev = ERR_PTR(ret);
+ break;
+ }
- sdev = spmi_device_from_of(other_usid);
if (pmic_addr == function_parent_usid - (ctx->num_usids - 1)) {
- if (!sdev)
+ sdev = spmi_find_device_by_of_node(child);
+ if (!sdev) {
/*
- * If the base USID for this PMIC hasn't probed yet
- * but the secondary USID has, then we need to defer
- * the function driver so that it will attempt to
- * probe again when the base USID is ready.
+ * If the base USID for this PMIC hasn't been
+ * registered yet then we need to defer.
*/
- return ERR_PTR(-EPROBE_DEFER);
- return sdev;
+ sdev = ERR_PTR(-EPROBE_DEFER);
+ }
+ of_node_put(child);
+ break;
}
- } while (other_usid->sibling);
+ }
- return ERR_PTR(-ENODATA);
+ of_node_put(spmi_bus);
+
+ return sdev;
+}
+
+static int pmic_spmi_get_base_revid(struct spmi_device *sdev, struct qcom_spmi_dev *ctx)
+{
+ struct qcom_spmi_dev *base_ctx;
+ struct spmi_device *base;
+ int ret = 0;
+
+ base = qcom_pmic_get_base_usid(sdev, ctx);
+ if (IS_ERR(base))
+ return PTR_ERR(base);
+
+ /*
+ * Copy revid info from base device if it has probed and is still
+ * bound to its driver.
+ */
+ mutex_lock(&pmic_spmi_revid_lock);
+ base_ctx = spmi_device_get_drvdata(base);
+ if (!base_ctx) {
+ ret = -EPROBE_DEFER;
+ goto out_unlock;
+ }
+ memcpy(&ctx->pmic, &base_ctx->pmic, sizeof(ctx->pmic));
+out_unlock:
+ mutex_unlock(&pmic_spmi_revid_lock);
+
+ put_device(&base->dev);
+
+ return ret;
}
static int pmic_spmi_load_revid(struct regmap *map, struct device *dev,
@@ -204,16 +238,12 @@ const struct qcom_spmi_pmic *qcom_pmic_get(struct device *dev)
if (!of_match_device(pmic_spmi_id_table, dev->parent))
return ERR_PTR(-EINVAL);
- sdev = qcom_pmic_get_base_usid(dev->parent);
-
- if (IS_ERR(sdev))
- return ERR_CAST(sdev);
-
+ sdev = to_spmi_device(dev->parent);
spmi = dev_get_drvdata(&sdev->dev);
return &spmi->pmic;
}
-EXPORT_SYMBOL(qcom_pmic_get);
+EXPORT_SYMBOL_GPL(qcom_pmic_get);
static const struct regmap_config spmi_regmap_config = {
.reg_bits = 16,
@@ -236,23 +266,38 @@ static int pmic_spmi_probe(struct spmi_device *sdev)
if (!ctx)
return -ENOMEM;
- ctx->num_usids = (uintptr_t)of_device_get_match_data(&sdev->dev);
+ ctx->num_usids = (uintptr_t)device_get_match_data(&sdev->dev);
/* Only the first slave id for a PMIC contains this information */
if (sdev->usid % ctx->num_usids == 0) {
ret = pmic_spmi_load_revid(regmap, &sdev->dev, &ctx->pmic);
if (ret < 0)
return ret;
+ } else {
+ ret = pmic_spmi_get_base_revid(sdev, ctx);
+ if (ret)
+ return ret;
}
+
+ mutex_lock(&pmic_spmi_revid_lock);
spmi_device_set_drvdata(sdev, ctx);
+ mutex_unlock(&pmic_spmi_revid_lock);
return devm_of_platform_populate(&sdev->dev);
}
+static void pmic_spmi_remove(struct spmi_device *sdev)
+{
+ mutex_lock(&pmic_spmi_revid_lock);
+ spmi_device_set_drvdata(sdev, NULL);
+ mutex_unlock(&pmic_spmi_revid_lock);
+}
+
MODULE_DEVICE_TABLE(of, pmic_spmi_id_table);
static struct spmi_driver pmic_spmi_driver = {
.probe = pmic_spmi_probe,
+ .remove = pmic_spmi_remove,
.driver = {
.name = "pmic-spmi",
.of_match_table = pmic_spmi_id_table,
diff --git a/drivers/mfd/qcom_rpm.c b/drivers/mfd/qcom_rpm.c
index 086611322874..27446f43e3f3 100644
--- a/drivers/mfd/qcom_rpm.c
+++ b/drivers/mfd/qcom_rpm.c
@@ -7,6 +7,8 @@
#include <linux/module.h>
#include <linux/platform_device.h>
+#include <linux/property.h>
+#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/io.h>
#include <linux/interrupt.h>
@@ -528,7 +530,6 @@ static irqreturn_t qcom_rpm_wakeup_interrupt(int irq, void *dev)
static int qcom_rpm_probe(struct platform_device *pdev)
{
- const struct of_device_id *match;
struct device_node *syscon_np;
struct qcom_rpm *rpm;
u32 fw_version[3];
@@ -570,10 +571,9 @@ static int qcom_rpm_probe(struct platform_device *pdev)
if (irq_wakeup < 0)
return irq_wakeup;
- match = of_match_device(qcom_rpm_of_match, &pdev->dev);
- if (!match)
+ rpm->data = device_get_match_data(&pdev->dev);
+ if (!rpm->data)
return -ENODEV;
- rpm->data = match->data;
rpm->status_regs = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
if (IS_ERR(rpm->status_regs))
diff --git a/drivers/mfd/rk8xx-core.c b/drivers/mfd/rk8xx-core.c
index 11a831e92da8..c47164a3ec1d 100644
--- a/drivers/mfd/rk8xx-core.c
+++ b/drivers/mfd/rk8xx-core.c
@@ -525,6 +525,10 @@ static int rk808_power_off(struct sys_off_data *data)
reg = RK805_DEV_CTRL_REG;
bit = DEV_OFF;
break;
+ case RK806_ID:
+ reg = RK806_SYS_CFG3;
+ bit = DEV_OFF;
+ break;
case RK808_ID:
reg = RK808_DEVCTRL_REG,
bit = DEV_OFF_RST;
@@ -685,7 +689,8 @@ int rk8xx_probe(struct device *dev, int variant, unsigned int irq, struct regmap
if (ret)
return dev_err_probe(dev, ret, "failed to add MFD devices\n");
- if (device_property_read_bool(dev, "rockchip,system-power-controller")) {
+ if (device_property_read_bool(dev, "rockchip,system-power-controller") ||
+ device_property_read_bool(dev, "system-power-controller")) {
ret = devm_register_sys_off_handler(dev,
SYS_OFF_MODE_POWER_OFF_PREPARE, SYS_OFF_PRIO_HIGH,
&rk808_power_off, rk808);
diff --git a/drivers/mfd/rk8xx-i2c.c b/drivers/mfd/rk8xx-i2c.c
index 1a98feea97e2..75b5cf09d5a0 100644
--- a/drivers/mfd/rk8xx-i2c.c
+++ b/drivers/mfd/rk8xx-i2c.c
@@ -80,7 +80,7 @@ static const struct regmap_config rk818_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.max_register = RK818_USB_CTRL_REG,
- .cache_type = REGCACHE_RBTREE,
+ .cache_type = REGCACHE_MAPLE,
.volatile_reg = rk808_is_volatile_reg,
};
@@ -88,7 +88,7 @@ static const struct regmap_config rk805_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.max_register = RK805_OFF_SOURCE_REG,
- .cache_type = REGCACHE_RBTREE,
+ .cache_type = REGCACHE_MAPLE,
.volatile_reg = rk808_is_volatile_reg,
};
@@ -96,7 +96,7 @@ static const struct regmap_config rk808_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.max_register = RK808_IO_POL_REG,
- .cache_type = REGCACHE_RBTREE,
+ .cache_type = REGCACHE_MAPLE,
.volatile_reg = rk808_is_volatile_reg,
};
diff --git a/drivers/mfd/rn5t618.c b/drivers/mfd/rn5t618.c
index 0fe616b2db8e..7336e6d8a001 100644
--- a/drivers/mfd/rn5t618.c
+++ b/drivers/mfd/rn5t618.c
@@ -13,7 +13,7 @@
#include <linux/mfd/core.h>
#include <linux/mfd/rn5t618.h>
#include <linux/module.h>
-#include <linux/of_device.h>
+#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/reboot.h>
#include <linux/regmap.h>
@@ -179,22 +179,15 @@ MODULE_DEVICE_TABLE(of, rn5t618_of_match);
static int rn5t618_i2c_probe(struct i2c_client *i2c)
{
- const struct of_device_id *of_id;
struct rn5t618 *priv;
int ret;
- of_id = of_match_device(rn5t618_of_match, &i2c->dev);
- if (!of_id) {
- dev_err(&i2c->dev, "Failed to find matching DT ID\n");
- return -EINVAL;
- }
-
priv = devm_kzalloc(&i2c->dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
i2c_set_clientdata(i2c, priv);
- priv->variant = (long)of_id->data;
+ priv->variant = (long)i2c_get_match_data(i2c);
priv->irq = i2c->irq;
priv->dev = &i2c->dev;
diff --git a/drivers/mfd/stm32-timers.c b/drivers/mfd/stm32-timers.c
index 732a28db80fa..a656a1c186a8 100644
--- a/drivers/mfd/stm32-timers.c
+++ b/drivers/mfd/stm32-timers.c
@@ -215,6 +215,48 @@ static void stm32_timers_dma_remove(struct device *dev,
dma_release_channel(ddata->dma.chans[i]);
}
+static const char * const stm32_timers_irq_name[STM32_TIMERS_MAX_IRQS] = {
+ "brk", "up", "trg-com", "cc"
+};
+
+static int stm32_timers_irq_probe(struct platform_device *pdev,
+ struct stm32_timers *ddata)
+{
+ int i, ret;
+
+ /*
+ * STM32 Timer may have either:
+ * - a unique global interrupt line
+ * - four dedicated interrupt lines that may be handled separately.
+ * Optionally get them here, to be used by child devices.
+ */
+ ret = platform_get_irq_byname_optional(pdev, "global");
+ if (ret < 0 && ret != -ENXIO) {
+ return ret;
+ } else if (ret != -ENXIO) {
+ ddata->irq[STM32_TIMERS_IRQ_GLOBAL_BRK] = ret;
+ ddata->nr_irqs = 1;
+ return 0;
+ }
+
+ for (i = 0; i < STM32_TIMERS_MAX_IRQS; i++) {
+ ret = platform_get_irq_byname_optional(pdev, stm32_timers_irq_name[i]);
+ if (ret < 0 && ret != -ENXIO) {
+ return ret;
+ } else if (ret != -ENXIO) {
+ ddata->irq[i] = ret;
+ ddata->nr_irqs++;
+ }
+ }
+
+ if (ddata->nr_irqs && ddata->nr_irqs != STM32_TIMERS_MAX_IRQS) {
+ dev_err(&pdev->dev, "Invalid number of IRQs %d\n", ddata->nr_irqs);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
static int stm32_timers_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
@@ -245,6 +287,10 @@ static int stm32_timers_probe(struct platform_device *pdev)
stm32_timers_get_arr_size(ddata);
+ ret = stm32_timers_irq_probe(pdev, ddata);
+ if (ret)
+ return ret;
+
ret = stm32_timers_dma_probe(dev, ddata);
if (ret) {
stm32_timers_dma_remove(dev, ddata);
diff --git a/drivers/mfd/tps65086.c b/drivers/mfd/tps65086.c
index 9bb7d7d8dcfc..152179ee11ca 100644
--- a/drivers/mfd/tps65086.c
+++ b/drivers/mfd/tps65086.c
@@ -34,7 +34,7 @@ static const struct regmap_access_table tps65086_volatile_table = {
static const struct regmap_config tps65086_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
- .cache_type = REGCACHE_RBTREE,
+ .cache_type = REGCACHE_MAPLE,
.volatile_table = &tps65086_volatile_table,
};
diff --git a/drivers/mfd/tps65090.c b/drivers/mfd/tps65090.c
index 9245e11219f3..b764badaa62a 100644
--- a/drivers/mfd/tps65090.c
+++ b/drivers/mfd/tps65090.c
@@ -151,7 +151,7 @@ static const struct regmap_config tps65090_regmap_config = {
.val_bits = 8,
.max_register = TPS65090_MAX_REG,
.num_reg_defaults_raw = TPS65090_NUM_REGS,
- .cache_type = REGCACHE_RBTREE,
+ .cache_type = REGCACHE_MAPLE,
.volatile_reg = is_volatile_reg,
};
diff --git a/drivers/mfd/tps65218.c b/drivers/mfd/tps65218.c
index 11e4e52b56be..427a2b97f117 100644
--- a/drivers/mfd/tps65218.c
+++ b/drivers/mfd/tps65218.c
@@ -127,7 +127,7 @@ static const struct regmap_access_table tps65218_volatile_table = {
static const struct regmap_config tps65218_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
- .cache_type = REGCACHE_RBTREE,
+ .cache_type = REGCACHE_MAPLE,
.volatile_table = &tps65218_volatile_table,
};
diff --git a/drivers/mfd/tps6586x.c b/drivers/mfd/tps6586x.c
index 55675ceedcd3..03c65bbf2143 100644
--- a/drivers/mfd/tps6586x.c
+++ b/drivers/mfd/tps6586x.c
@@ -22,6 +22,7 @@
#include <linux/err.h>
#include <linux/i2c.h>
#include <linux/platform_device.h>
+#include <linux/reboot.h>
#include <linux/regmap.h>
#include <linux/of.h>
@@ -29,6 +30,7 @@
#include <linux/mfd/tps6586x.h>
#define TPS6586X_SUPPLYENE 0x14
+#define SOFT_RST_BIT BIT(0)
#define EXITSLREQ_BIT BIT(1)
#define SLEEP_MODE_BIT BIT(3)
@@ -454,16 +456,37 @@ static const struct regmap_config tps6586x_regmap_config = {
.val_bits = 8,
.max_register = TPS6586X_MAX_REGISTER,
.volatile_reg = is_volatile_reg,
- .cache_type = REGCACHE_RBTREE,
+ .cache_type = REGCACHE_MAPLE,
};
-static struct device *tps6586x_dev;
-static void tps6586x_power_off(void)
+static int tps6586x_power_off_handler(struct sys_off_data *data)
{
- if (tps6586x_clr_bits(tps6586x_dev, TPS6586X_SUPPLYENE, EXITSLREQ_BIT))
- return;
+ int ret;
+
+ /* Put the PMIC into sleep state. This takes at least 20ms. */
+ ret = tps6586x_clr_bits(data->dev, TPS6586X_SUPPLYENE, EXITSLREQ_BIT);
+ if (ret)
+ return notifier_from_errno(ret);
+
+ ret = tps6586x_set_bits(data->dev, TPS6586X_SUPPLYENE, SLEEP_MODE_BIT);
+ if (ret)
+ return notifier_from_errno(ret);
+
+ mdelay(50);
+ return notifier_from_errno(-ETIME);
+}
+
+static int tps6586x_restart_handler(struct sys_off_data *data)
+{
+ int ret;
+
+ /* Put the PMIC into hard reboot state. This takes at least 20ms. */
+ ret = tps6586x_set_bits(data->dev, TPS6586X_SUPPLYENE, SOFT_RST_BIT);
+ if (ret)
+ return notifier_from_errno(ret);
- tps6586x_set_bits(tps6586x_dev, TPS6586X_SUPPLYENE, SLEEP_MODE_BIT);
+ mdelay(50);
+ return notifier_from_errno(-ETIME);
}
static void tps6586x_print_version(struct i2c_client *client, int version)
@@ -559,9 +582,20 @@ static int tps6586x_i2c_probe(struct i2c_client *client)
goto err_add_devs;
}
- if (pdata->pm_off && !pm_power_off) {
- tps6586x_dev = &client->dev;
- pm_power_off = tps6586x_power_off;
+ if (pdata->pm_off) {
+ ret = devm_register_power_off_handler(&client->dev, &tps6586x_power_off_handler,
+ NULL);
+ if (ret) {
+ dev_err(&client->dev, "register power off handler failed: %d\n", ret);
+ goto err_add_devs;
+ }
+
+ ret = devm_register_restart_handler(&client->dev, &tps6586x_restart_handler,
+ NULL);
+ if (ret) {
+ dev_err(&client->dev, "register restart handler failed: %d\n", ret);
+ goto err_add_devs;
+ }
}
return 0;
diff --git a/drivers/mfd/tps65910.c b/drivers/mfd/tps65910.c
index 41408df1712f..8fb0384d5a8e 100644
--- a/drivers/mfd/tps65910.c
+++ b/drivers/mfd/tps65910.c
@@ -19,7 +19,7 @@
#include <linux/regmap.h>
#include <linux/mfd/tps65910.h>
#include <linux/of.h>
-#include <linux/of_device.h>
+#include <linux/property.h>
static const struct resource rtc_resources[] = {
{
@@ -281,7 +281,7 @@ static const struct regmap_config tps65910_regmap_config = {
.val_bits = 8,
.volatile_reg = is_volatile_reg,
.max_register = TPS65910_MAX_REGISTER - 1,
- .cache_type = REGCACHE_RBTREE,
+ .cache_type = REGCACHE_MAPLE,
};
static int tps65910_ck32k_init(struct tps65910 *tps65910,
@@ -374,16 +374,9 @@ static struct tps65910_board *tps65910_parse_dt(struct i2c_client *client,
struct device_node *np = client->dev.of_node;
struct tps65910_board *board_info;
unsigned int prop;
- const struct of_device_id *match;
int ret;
- match = of_match_device(tps65910_of_match, &client->dev);
- if (!match) {
- dev_err(&client->dev, "Failed to find matching dt id\n");
- return NULL;
- }
-
- *chip_id = (unsigned long)match->data;
+ *chip_id = (unsigned long)device_get_match_data(&client->dev);
board_info = devm_kzalloc(&client->dev, sizeof(*board_info),
GFP_KERNEL);
diff --git a/drivers/mfd/tps65912-core.c b/drivers/mfd/tps65912-core.c
index 7d994b8a5965..2305ea60367a 100644
--- a/drivers/mfd/tps65912-core.c
+++ b/drivers/mfd/tps65912-core.c
@@ -81,7 +81,7 @@ static const struct regmap_access_table tps65912_volatile_table = {
const struct regmap_config tps65912_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
- .cache_type = REGCACHE_RBTREE,
+ .cache_type = REGCACHE_MAPLE,
.volatile_table = &tps65912_volatile_table,
};
EXPORT_SYMBOL_GPL(tps65912_regmap_config);
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
index ce01a87f8dc3..6e384a79e341 100644
--- a/drivers/mfd/twl-core.c
+++ b/drivers/mfd/twl-core.c
@@ -31,6 +31,8 @@
#include <linux/regulator/machine.h>
#include <linux/i2c.h>
+
+#include <linux/mfd/core.h>
#include <linux/mfd/twl.h>
/* Register descriptions for audio */
@@ -312,7 +314,7 @@ static const struct regmap_config twl4030_regmap_config[4] = {
.reg_defaults = twl4030_49_defaults,
.num_reg_defaults = ARRAY_SIZE(twl4030_49_defaults),
- .cache_type = REGCACHE_RBTREE,
+ .cache_type = REGCACHE_MAPLE,
},
{
/* Address 0x4a */
@@ -690,6 +692,10 @@ static struct of_dev_auxdata twl_auxdata_lookup[] = {
{ /* sentinel */ },
};
+static const struct mfd_cell twl6032_cells[] = {
+ { .name = "twl6032-clk" },
+};
+
/* NOTE: This driver only handles a single twl4030/tps659x0 chip */
static int
twl_probe(struct i2c_client *client)
@@ -836,6 +842,16 @@ twl_probe(struct i2c_client *client)
TWL4030_DCDC_GLOBAL_CFG);
}
+ if (id->driver_data == (TWL6030_CLASS | TWL6032_SUBCLASS)) {
+ status = devm_mfd_add_devices(&client->dev,
+ PLATFORM_DEVID_NONE,
+ twl6032_cells,
+ ARRAY_SIZE(twl6032_cells),
+ NULL, 0, NULL);
+ if (status < 0)
+ goto free;
+ }
+
status = of_platform_populate(node, NULL, twl_auxdata_lookup,
&client->dev);
diff --git a/drivers/mfd/twl4030-power.c b/drivers/mfd/twl4030-power.c
index e35b0f788c50..1595e9c76132 100644
--- a/drivers/mfd/twl4030-power.c
+++ b/drivers/mfd/twl4030-power.c
@@ -27,8 +27,8 @@
#include <linux/pm.h>
#include <linux/mfd/twl.h>
#include <linux/platform_device.h>
+#include <linux/property.h>
#include <linux/of.h>
-#include <linux/of_device.h>
#include <asm/mach-types.h>
@@ -883,7 +883,6 @@ static int twl4030_power_probe(struct platform_device *pdev)
{
const struct twl4030_power_data *pdata = dev_get_platdata(&pdev->dev);
struct device_node *node = pdev->dev.of_node;
- const struct of_device_id *match;
int err = 0;
int err2 = 0;
u8 val;
@@ -904,10 +903,8 @@ static int twl4030_power_probe(struct platform_device *pdev)
return err;
}
- match = of_match_device(of_match_ptr(twl4030_power_of_match),
- &pdev->dev);
- if (match && match->data)
- pdata = match->data;
+ if (node)
+ pdata = device_get_match_data(&pdev->dev);
if (pdata) {
err = twl4030_power_configure_scripts(pdata);
diff --git a/drivers/mfd/twl6030-irq.c b/drivers/mfd/twl6030-irq.c
index 3c03681c124c..f9fce8408c2c 100644
--- a/drivers/mfd/twl6030-irq.c
+++ b/drivers/mfd/twl6030-irq.c
@@ -24,10 +24,10 @@
#include <linux/kthread.h>
#include <linux/mfd/twl.h>
#include <linux/platform_device.h>
+#include <linux/property.h>
#include <linux/suspend.h>
#include <linux/of.h>
#include <linux/irqdomain.h>
-#include <linux/of_device.h>
#include "twl-core.h"
@@ -368,10 +368,10 @@ int twl6030_init_irq(struct device *dev, int irq_num)
int nr_irqs;
int status;
u8 mask[3];
- const struct of_device_id *of_id;
+ const int *irq_tbl;
- of_id = of_match_device(twl6030_of_match, dev);
- if (!of_id || !of_id->data) {
+ irq_tbl = device_get_match_data(dev);
+ if (!irq_tbl) {
dev_err(dev, "Unknown TWL device model\n");
return -EINVAL;
}
@@ -409,7 +409,7 @@ int twl6030_init_irq(struct device *dev, int irq_num)
twl6030_irq->pm_nb.notifier_call = twl6030_irq_pm_notifier;
atomic_set(&twl6030_irq->wakeirqs, 0);
- twl6030_irq->irq_mapping_tbl = of_id->data;
+ twl6030_irq->irq_mapping_tbl = irq_tbl;
twl6030_irq->irq_domain =
irq_domain_add_linear(node, nr_irqs,
diff --git a/drivers/mfd/wcd934x.c b/drivers/mfd/wcd934x.c
index 6b942d5270c1..7b9873b72c37 100644
--- a/drivers/mfd/wcd934x.c
+++ b/drivers/mfd/wcd934x.c
@@ -112,7 +112,7 @@ static const struct regmap_range_cfg wcd934x_ranges[] = {
static struct regmap_config wcd934x_regmap_config = {
.reg_bits = 16,
.val_bits = 8,
- .cache_type = REGCACHE_RBTREE,
+ .cache_type = REGCACHE_MAPLE,
.max_register = 0xffff,
.can_multi_write = true,
.ranges = wcd934x_ranges,
diff --git a/drivers/mfd/wm831x-i2c.c b/drivers/mfd/wm831x-i2c.c
index 694ddbbf0372..9bee007f9c99 100644
--- a/drivers/mfd/wm831x-i2c.c
+++ b/drivers/mfd/wm831x-i2c.c
@@ -15,7 +15,6 @@
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/of.h>
-#include <linux/of_device.h>
#include <linux/regmap.h>
#include <linux/mfd/wm831x/core.h>
@@ -23,22 +22,15 @@
static int wm831x_i2c_probe(struct i2c_client *i2c)
{
- const struct i2c_device_id *id = i2c_client_get_device_id(i2c);
struct wm831x_pdata *pdata = dev_get_platdata(&i2c->dev);
- const struct of_device_id *of_id;
struct wm831x *wm831x;
enum wm831x_parent type;
int ret;
- if (i2c->dev.of_node) {
- of_id = of_match_device(wm831x_of_match, &i2c->dev);
- if (!of_id) {
- dev_err(&i2c->dev, "Failed to match device\n");
- return -ENODEV;
- }
- type = (uintptr_t)of_id->data;
- } else {
- type = (enum wm831x_parent)id->driver_data;
+ type = (uintptr_t)i2c_get_match_data(i2c);
+ if (!type) {
+ dev_err(&i2c->dev, "Failed to match device\n");
+ return -ENODEV;
}
wm831x = devm_kzalloc(&i2c->dev, sizeof(struct wm831x), GFP_KERNEL);
diff --git a/drivers/mfd/wm831x-spi.c b/drivers/mfd/wm831x-spi.c
index 76be7ef5c970..54c87267917b 100644
--- a/drivers/mfd/wm831x-spi.c
+++ b/drivers/mfd/wm831x-spi.c
@@ -10,7 +10,6 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/of.h>
-#include <linux/of_device.h>
#include <linux/pm.h>
#include <linux/spi/spi.h>
#include <linux/regmap.h>
@@ -21,21 +20,14 @@
static int wm831x_spi_probe(struct spi_device *spi)
{
struct wm831x_pdata *pdata = dev_get_platdata(&spi->dev);
- const struct spi_device_id *id = spi_get_device_id(spi);
- const struct of_device_id *of_id;
struct wm831x *wm831x;
enum wm831x_parent type;
int ret;
- if (spi->dev.of_node) {
- of_id = of_match_device(wm831x_of_match, &spi->dev);
- if (!of_id) {
- dev_err(&spi->dev, "Failed to match device\n");
- return -ENODEV;
- }
- type = (uintptr_t)of_id->data;
- } else {
- type = (enum wm831x_parent)id->driver_data;
+ type = (uintptr_t)spi_get_device_match_data(spi);
+ if (!type) {
+ dev_err(&spi->dev, "Failed to match device\n");
+ return -ENODEV;
}
wm831x = devm_kzalloc(&spi->dev, sizeof(struct wm831x), GFP_KERNEL);
diff --git a/drivers/mfd/wm8994-core.c b/drivers/mfd/wm8994-core.c
index aba7af688175..d5ac066f9db4 100644
--- a/drivers/mfd/wm8994-core.c
+++ b/drivers/mfd/wm8994-core.c
@@ -15,7 +15,6 @@
#include <linux/delay.h>
#include <linux/mfd/core.h>
#include <linux/of.h>
-#include <linux/of_device.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
@@ -612,8 +611,6 @@ MODULE_DEVICE_TABLE(of, wm8994_of_match);
static int wm8994_i2c_probe(struct i2c_client *i2c)
{
- const struct i2c_device_id *id = i2c_client_get_device_id(i2c);
- const struct of_device_id *of_id;
struct wm8994 *wm8994;
int ret;
@@ -625,13 +622,7 @@ static int wm8994_i2c_probe(struct i2c_client *i2c)
wm8994->dev = &i2c->dev;
wm8994->irq = i2c->irq;
- if (i2c->dev.of_node) {
- of_id = of_match_device(wm8994_of_match, &i2c->dev);
- if (of_id)
- wm8994->type = (uintptr_t)of_id->data;
- } else {
- wm8994->type = id->driver_data;
- }
+ wm8994->type = (enum wm8994_type)i2c_get_match_data(i2c);
wm8994->regmap = devm_regmap_init_i2c(i2c, &wm8994_base_regmap_config);
if (IS_ERR(wm8994->regmap)) {
diff --git a/drivers/spmi/spmi.c b/drivers/spmi/spmi.c
index 7313d4c18a04..93cd4a34debc 100644
--- a/drivers/spmi/spmi.c
+++ b/drivers/spmi/spmi.c
@@ -388,13 +388,16 @@ static struct bus_type spmi_bus_type = {
};
/**
- * spmi_device_from_of() - get the associated SPMI device from a device node
+ * spmi_find_device_by_of_node() - look up an SPMI device from a device node
*
* @np: device node
*
+ * Takes a reference to the embedded struct device which needs to be dropped
+ * after use.
+ *
* Returns the struct spmi_device associated with a device node or NULL.
*/
-struct spmi_device *spmi_device_from_of(struct device_node *np)
+struct spmi_device *spmi_find_device_by_of_node(struct device_node *np)
{
struct device *dev = bus_find_device_by_of_node(&spmi_bus_type, np);
@@ -402,7 +405,7 @@ struct spmi_device *spmi_device_from_of(struct device_node *np)
return to_spmi_device(dev);
return NULL;
}
-EXPORT_SYMBOL_GPL(spmi_device_from_of);
+EXPORT_SYMBOL_GPL(spmi_find_device_by_of_node);
/**
* spmi_device_alloc() - Allocate a new SPMI device
diff --git a/include/linux/mfd/abx500/ab8500.h b/include/linux/mfd/abx500/ab8500.h
index 09fb3c56e7d7..76d326ea8eba 100644
--- a/include/linux/mfd/abx500/ab8500.h
+++ b/include/linux/mfd/abx500/ab8500.h
@@ -499,13 +499,7 @@ static inline int is_ab9540_2p0_or_earlier(struct ab8500 *ab)
void ab8500_override_turn_on_stat(u8 mask, u8 set);
-#ifdef CONFIG_AB8500_DEBUG
-extern int prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size);
-void ab8500_dump_all_banks(struct device *dev);
-void ab8500_debug_register_interrupt(int line);
-#else
static inline void ab8500_dump_all_banks(struct device *dev) {}
static inline void ab8500_debug_register_interrupt(int line) {}
-#endif
#endif /* MFD_AB8500_H */
diff --git a/include/linux/mfd/core.h b/include/linux/mfd/core.h
index 47e7a3a61ce6..e8bcad641d8c 100644
--- a/include/linux/mfd/core.h
+++ b/include/linux/mfd/core.h
@@ -92,7 +92,7 @@ struct mfd_cell {
* (above) when matching OF nodes with devices that have identical
* compatible strings
*/
- const u64 of_reg;
+ u64 of_reg;
/* Set to 'true' to use 'of_reg' (above) - allows for of_reg=0 */
bool use_of_reg;
diff --git a/include/linux/mfd/lpc_ich.h b/include/linux/mfd/lpc_ich.h
index ea4a4b1b246a..1fbda1f8967d 100644
--- a/include/linux/mfd/lpc_ich.h
+++ b/include/linux/mfd/lpc_ich.h
@@ -15,7 +15,7 @@
#define ICH_RES_GPE0 1
/* GPIO compatibility */
-enum {
+enum lpc_gpio_versions {
ICH_I3100_GPIO,
ICH_V5_GPIO,
ICH_V6_GPIO,
@@ -26,11 +26,14 @@ enum {
AVOTON_GPIO,
};
+struct lpc_ich_gpio_info;
+
struct lpc_ich_info {
char name[32];
unsigned int iTCO_version;
- unsigned int gpio_version;
+ enum lpc_gpio_versions gpio_version;
enum intel_spi_type spi_type;
+ const struct lpc_ich_gpio_info *gpio_info;
u8 use_gpio;
};
diff --git a/include/linux/mfd/stm32-timers.h b/include/linux/mfd/stm32-timers.h
index 1b94325febb3..ca35af30745f 100644
--- a/include/linux/mfd/stm32-timers.h
+++ b/include/linux/mfd/stm32-timers.h
@@ -102,6 +102,15 @@ enum stm32_timers_dmas {
STM32_TIMERS_MAX_DMAS,
};
+/* STM32 Timer may have either a unique global interrupt or 4 interrupt lines */
+enum stm32_timers_irqs {
+ STM32_TIMERS_IRQ_GLOBAL_BRK, /* global or brk IRQ */
+ STM32_TIMERS_IRQ_UP,
+ STM32_TIMERS_IRQ_TRG_COM,
+ STM32_TIMERS_IRQ_CC,
+ STM32_TIMERS_MAX_IRQS,
+};
+
/**
* struct stm32_timers_dma - STM32 timer DMA handling.
* @completion: end of DMA transfer completion
@@ -123,6 +132,8 @@ struct stm32_timers {
struct regmap *regmap;
u32 max_arr;
struct stm32_timers_dma dma; /* Only to be used by the parent */
+ unsigned int nr_irqs;
+ int irq[STM32_TIMERS_MAX_IRQS];
};
#if IS_REACHABLE(CONFIG_MFD_STM32_TIMERS)
diff --git a/include/linux/reboot.h b/include/linux/reboot.h
index 2b6bb593be5b..c4cc3b89ced1 100644
--- a/include/linux/reboot.h
+++ b/include/linux/reboot.h
@@ -129,11 +129,14 @@ enum sys_off_mode {
* @cb_data: User's callback data.
* @cmd: Command string. Currently used only by the sys-off restart mode,
* NULL otherwise.
+ * @dev: Device of the sys-off handler. Only if known (devm_register_*),
+ * NULL otherwise.
*/
struct sys_off_data {
int mode;
void *cb_data;
const char *cmd;
+ struct device *dev;
};
struct sys_off_handler *
diff --git a/include/linux/spmi.h b/include/linux/spmi.h
index eac1956a8727..2a4ce4144f9f 100644
--- a/include/linux/spmi.h
+++ b/include/linux/spmi.h
@@ -166,7 +166,7 @@ static inline void spmi_driver_unregister(struct spmi_driver *sdrv)
struct device_node;
-struct spmi_device *spmi_device_from_of(struct device_node *np);
+struct spmi_device *spmi_find_device_by_of_node(struct device_node *np);
int spmi_register_read(struct spmi_device *sdev, u8 addr, u8 *buf);
int spmi_ext_register_read(struct spmi_device *sdev, u8 addr, u8 *buf,
size_t len);
diff --git a/kernel/reboot.c b/kernel/reboot.c
index 3bba88c7ffc6..395a0ea3c7a8 100644
--- a/kernel/reboot.c
+++ b/kernel/reboot.c
@@ -55,6 +55,7 @@ struct sys_off_handler {
enum sys_off_mode mode;
bool blocking;
void *list;
+ struct device *dev;
};
/*
@@ -74,6 +75,7 @@ void __weak (*pm_power_off)(void);
void emergency_restart(void)
{
kmsg_dump(KMSG_DUMP_EMERG);
+ system_state = SYSTEM_RESTART;
machine_emergency_restart();
}
EXPORT_SYMBOL_GPL(emergency_restart);
@@ -323,6 +325,7 @@ static int sys_off_notify(struct notifier_block *nb,
data.cb_data = handler->cb_data;
data.mode = mode;
data.cmd = cmd;
+ data.dev = handler->dev;
return handler->sys_off_cb(&data);
}
@@ -510,6 +513,7 @@ int devm_register_sys_off_handler(struct device *dev,
handler = register_sys_off_handler(mode, priority, callback, cb_data);
if (IS_ERR(handler))
return PTR_ERR(handler);
+ handler->dev = dev;
return devm_add_action_or_reset(dev, devm_unregister_sys_off_handler,
handler);