1

- 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:
Linus Torvalds 2023-11-02 14:40:51 -10:00
commit 27bc0782ef
86 changed files with 1163 additions and 734 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -1,10 +0,0 @@
88pm860x-backlight bindings
Optional properties:
- maxim,max8925-dual-string: whether support dual string
Example:
backlights {
maxim,max8925-dual-string = <0>;
};

View File

@ -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>;

View File

@ -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
...

View File

@ -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>;
};
};

View File

@ -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>;
};
};
};

View File

@ -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:

View 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>;
};
};
};

View 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;
};
};
};
};

View File

@ -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.

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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:

View File

@ -29,6 +29,8 @@ properties:
'#gpio-cells':
const: 2
system-power-controller: true
vcc1-supply:
description:
The input supply for dcdc-reg1.

View File

@ -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:

View File

@ -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:

View File

@ -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:

View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -37,6 +37,7 @@ properties:
"^buck[0123]$":
type: object
$ref: /schemas/regulator/regulator.yaml#
unevaluatedProperties: false
required:
- buck0

View File

@ -41,6 +41,7 @@ properties:
buck3210:
type: object
$ref: /schemas/regulator/regulator.yaml#
unevaluatedProperties: false
required:
- buck3210

View File

@ -47,6 +47,7 @@ properties:
"^buck(10|23)$":
type: object
$ref: /schemas/regulator/regulator.yaml#
unevaluatedProperties: false
required:
- buck10

View 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>;
};
};

View File

@ -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>;
};
};

View File

@ -67,7 +67,10 @@ allOf:
properties:
compatible:
contains:
const: x-powers,axp305
enum:
- x-powers,axp15060
- x-powers,axp305
- x-powers,axp313a
then:
required:

View File

@ -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>;
};

View File

@ -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)

View File

@ -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))

View File

@ -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;
}

View File

@ -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);

View File

@ -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]);

View File

@ -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,

View File

@ -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;

View File

@ -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)

View File

@ -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);

View File

@ -96,7 +96,7 @@ struct iqs62x_fw_blk {
u8 addr;
u8 mask;
u8 len;
u8 data[];
u8 data[] __counted_by(len);
};
struct iqs62x_info {

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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)) {

View File

@ -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);

View File

@ -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;

View File

@ -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,

View File

@ -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[] = {

View File

@ -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[] = {

View File

@ -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) {

View File

@ -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;

View File

@ -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);
}

View File

@ -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);

View File

@ -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;

View File

@ -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)) {

View File

@ -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);

View File

@ -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,

View File

@ -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))

View File

@ -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);

View File

@ -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,
};

View File

@ -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;

View File

@ -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);

View File

@ -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,
};

View File

@ -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,
};

View File

@ -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,
};

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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,

View File

@ -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,

View File

@ -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);

View File

@ -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);

View File

@ -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)) {

View File

@ -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

View File

@ -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 */

View File

@ -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;

View File

@ -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;
};

View File

@ -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)

View File

@ -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 *

View File

@ -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);

View File

@ -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);