mirror of
https://github.com/torvalds/linux.git
synced 2024-11-25 05:32:00 +00:00
- 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 sets set when booting with ACPI -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEdrbJNaO+IJqU8IdIUa+KL4f8d2EFAmVDsQcACgkQUa+KL4f8 d2FvXRAAjCwKTtj1cUOw7aiCknPuwHj5NoOvannEZN47/kzzbi35YX2oTOE3mSqc 11U6OLLZ8kpLAvKEy6l82puvDmXRDkQ7eXTFicDgLM2c+FNt3RnfffH+Njr6L8fx a5ncAMTesnCXJAfS/8PfsONvRylGl/zQ/zmeSWvukfVa4BVAWIYcJiRnjjOL/jGf /POTf8ihUjScCeNlRbsx28jOHDZo6RWCMauKywShuSweX/wMuRD8FwBXp8YmcsLH LsYng06Xm+pNtMXv7VB4MQRztRAW7oHduvh/OQ0HkjzlxN8M+wpeZveyq3/i6ut2 q54TlnlLsmmOh42tmgC7sSwmVmegLTnsoEpNJeYl0AJzNvuJ7W+VdDRuUe6mYwDV 5MBThe0MGtLtthglNRR1s7pII18ffz4hDQQFExQ5Ai6ZvYu4b57TB+mKas4cTt9T 7WnoLuPiQW0SPNPWQAYtUDAF16pQmIRME2KYaNIUxGqfDK6GX4EaEQ7//0PHOchE kdip5vDFhiTunHLOjf1Se7ZJO0KFEg/hECTq1tcYUDHSopO5hTwhy6Wcd56xyrKP dkFn+6dl0bGqBCgxDjlJ7tPJ1m2PEDv1MbV1yO3vIU89PPTPotfUPBud1I/H2IN5 wDWTULgWxyCJqlWXZ3HjwCsRXF6H4F4A57ffJukmvivqDcXam9Y= =rwPH -----END PGP SIGNATURE----- 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 ...
This commit is contained in:
commit
27bc0782ef
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
||||
|
@ -1,10 +0,0 @@
|
||||
88pm860x-backlight bindings
|
||||
|
||||
Optional properties:
|
||||
- maxim,max8925-dual-string: whether support dual string
|
||||
|
||||
Example:
|
||||
|
||||
backlights {
|
||||
maxim,max8925-dual-string = <0>;
|
||||
};
|
@ -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>;
|
||||
|
@ -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
|
||||
|
||||
...
|
@ -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>;
|
||||
};
|
||||
};
|
@ -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>;
|
||||
};
|
||||
};
|
||||
};
|
@ -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:
|
||||
|
145
Documentation/devicetree/bindings/mfd/maxim,max8925.yaml
Normal file
145
Documentation/devicetree/bindings/mfd/maxim,max8925.yaml
Normal file
@ -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>;
|
||||
};
|
||||
};
|
||||
};
|
324
Documentation/devicetree/bindings/mfd/maxim,max8998.yaml
Normal file
324
Documentation/devicetree/bindings/mfd/maxim,max8998.yaml
Normal file
@ -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;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
@ -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.
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -29,6 +29,8 @@ properties:
|
||||
'#gpio-cells':
|
||||
const: 2
|
||||
|
||||
system-power-controller: true
|
||||
|
||||
vcc1-supply:
|
||||
description:
|
||||
The input supply for dcdc-reg1.
|
||||
|
@ -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:
|
||||
|
@ -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:
|
||||
|
@ -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:
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -37,6 +37,7 @@ properties:
|
||||
"^buck[0123]$":
|
||||
type: object
|
||||
$ref: /schemas/regulator/regulator.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
required:
|
||||
- buck0
|
||||
|
@ -41,6 +41,7 @@ properties:
|
||||
buck3210:
|
||||
type: object
|
||||
$ref: /schemas/regulator/regulator.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
required:
|
||||
- buck3210
|
||||
|
@ -47,6 +47,7 @@ properties:
|
||||
"^buck(10|23)$":
|
||||
type: object
|
||||
$ref: /schemas/regulator/regulator.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
required:
|
||||
- buck10
|
||||
|
67
Documentation/devicetree/bindings/mfd/ti,twl.yaml
Normal file
67
Documentation/devicetree/bindings/mfd/ti,twl.yaml
Normal file
@ -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>;
|
||||
};
|
||||
};
|
||||
|
@ -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>;
|
||||
};
|
||||
};
|
@ -67,7 +67,10 @@ allOf:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: x-powers,axp305
|
||||
enum:
|
||||
- x-powers,axp15060
|
||||
- x-powers,axp305
|
||||
- x-powers,axp313a
|
||||
|
||||
then:
|
||||
required:
|
||||
|
@ -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>;
|
||||
};
|
@ -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)
|
||||
|
@ -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))
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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]);
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -96,7 +96,7 @@ struct iqs62x_fw_blk {
|
||||
u8 addr;
|
||||
u8 mask;
|
||||
u8 len;
|
||||
u8 data[];
|
||||
u8 data[] __counted_by(len);
|
||||
};
|
||||
|
||||
struct iqs62x_info {
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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)) {
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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[] = {
|
||||
|
@ -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[] = {
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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)) {
|
||||
|
@ -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);
|
||||
|
@ -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 = spmi_device_from_of(other_usid);
|
||||
if (pmic_addr == function_parent_usid - (ctx->num_usids - 1)) {
|
||||
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.
|
||||
*/
|
||||
return ERR_PTR(-EPROBE_DEFER);
|
||||
return sdev;
|
||||
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;
|
||||
}
|
||||
} while (other_usid->sibling);
|
||||
|
||||
return ERR_PTR(-ENODATA);
|
||||
if (pmic_addr == function_parent_usid - (ctx->num_usids - 1)) {
|
||||
sdev = spmi_find_device_by_of_node(child);
|
||||
if (!sdev) {
|
||||
/*
|
||||
* If the base USID for this PMIC hasn't been
|
||||
* registered yet then we need to defer.
|
||||
*/
|
||||
sdev = ERR_PTR(-EPROBE_DEFER);
|
||||
}
|
||||
of_node_put(child);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
|
@ -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))
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
};
|
||||
|
||||
|
@ -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,
|
||||
};
|
||||
|
||||
|
@ -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,
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
|
||||
tps6586x_set_bits(tps6586x_dev, TPS6586X_SUPPLYENE, SLEEP_MODE_BIT);
|
||||
/* 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);
|
||||
|
||||
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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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)) {
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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 *
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user