Commit 8403ce70 authored by Linus Torvalds's avatar Linus Torvalds

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

Pull MFD updates from Lee Jones:
 "New Device Support:
   - Add support for Watchdog to ChromeOS Embedded Controller
   - Add support for GPIOs to ChromeOS Embedded Controller
   - Add supprt for Sound to MediaTek MT6357 CODEC

  New Functionality:
   - Add power-off functionality to Texas Instruments TWL series CODECs

  Fix-ups:
   - Device Tree binding adaptions/conversions/creation
   - Use/convert to new/better APIs/helpers/MACROs instead of
     hand-rolling implementations
   - Trivial; spelling, whitespace, clean-ups, etc
   - Remove superfluous code and simplify overall
   - Fix include lists; alphabetise, remove unused, explicitly add used
   - Use dev_err_probe() to clean-up error paths
   - Convert used cache type over to the Maple Tree in many instances
   - Constify a bunch of static structs
   - Refrain from over-riding resources provided via the firmware

  Bug Fixes:
   - Fix a clock related firmware bug on Dell XPS 9530 et al.
   - Repair incorrect IRQ designations
   - Increase buffer sizes to omit various snprintf compiler errors
   - Ensure errors are handled properly
   - Balance references and prevent resource leaks
   - Rectify Power Key interrupt processing
   - Fix Kconfig related build errors
   - Correct a bunch of register start-up default values"

* tag 'mfd-next-6.9' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd: (65 commits)
  mfd: cs42l43: Fix wrong GPIO_FN_SEL and SPI_CLK_CONFIG1 defaults
  mfd: cs42l43: Fix wrong register defaults
  mfd: mt6397-core: Register mt6357 sound codec
  dt-bindings: mfd: syscon: Add ti,am62-usb-phy-ctrl compatible
  dt-bindings: mfd: dlg,da9063: Make #interrupt-cells required
  dt-bindings: mfd: Convert atmel-flexcom to json-schema
  mfd: kempld-core: Don't replace resources provided by ACPI
  mfd: cros_ec_dev: Add GPIO device if feature present on EC
  dt-bindings: mfd: cros-ec: Add properties for GPIO controller
  mfd: twl: Select MFD_CORE
  mfd: core: Constify the struct device_type usage
  mfd: rk8xx-core: Fix interrupt processing order for power key button
  mfd: twl4030-power: Accept standard property for power controller
  mfd: twl-core: Add power off implementation for twl603x
  dt-bindings: mfd: ti,twl: Document system-power-controller
  mfd: altera-sysmgr: Call of_node_put() only when of_parse_phandle() takes a ref
  mfd: syscon: Remove extern from function prototypes
  mfd: syscon: Call of_node_put() only when of_parse_phandle() takes a ref
  mfd: mc13xxx: Use bitfield helpers
  mfd: rc5t583: Convert to use maple tree register cache
  ...
parents a3df5d54 78334c34
* Dialog DA9061/62/63 OnKey Module
This module is part of the DA9061/DA9062/DA9063. For more details about entire
DA9062 and DA9061 chips see Documentation/devicetree/bindings/mfd/da9062.txt
For DA9063 see Documentation/devicetree/bindings/mfd/dlg,da9063.yaml
This module provides the KEY_POWER event.
Required properties:
- compatible: should be one of the following valid compatible string lines:
"dlg,da9061-onkey", "dlg,da9062-onkey"
"dlg,da9062-onkey"
"dlg,da9063-onkey"
Optional properties:
- dlg,disable-key-power : Disable power-down using a long key-press. If this
entry exists the OnKey driver will remove support for the KEY_POWER key
press when triggered using a long press of the OnKey.
Example: DA9063
pmic0: da9063@58 {
onkey {
compatible = "dlg,da9063-onkey";
dlg,disable-key-power;
};
};
Example: DA9062
pmic0: da9062@58 {
onkey {
compatible = "dlg,da9062-onkey";
dlg,disable-key-power;
};
};
Example: DA9061 using a fall-back compatible for the DA9062 onkey driver
pmic0: da9061@58 {
onkey {
compatible = "dlg,da9061-onkey", "dlg,da9062-onkey";
dlg,disable-key-power;
};
};
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/input/dlg,da9062-onkey.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Dialog DA9061/62/63 OnKey Module
maintainers:
- Biju Das <biju.das.jz@bp.renesas.com>
description: |
This module is part of the DA9061/DA9062/DA9063. For more details about entire
DA906{1,2,3} chips see Documentation/devicetree/bindings/mfd/dlg,da9063.yaml
This module provides the KEY_POWER event.
properties:
compatible:
oneOf:
- enum:
- dlg,da9062-onkey
- dlg,da9063-onkey
- items:
- const: dlg,da9061-onkey
- const: dlg,da9062-onkey
dlg,disable-key-power:
type: boolean
description:
Disable power-down using a long key-press. If this entry exists
the OnKey driver will remove support for the KEY_POWER key press
when triggered using a long press of the OnKey.
required:
- compatible
additionalProperties: false
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/mfd/atmel,hlcdc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Atmel's HLCD Controller
maintainers:
- Nicolas Ferre <nicolas.ferre@microchip.com>
- Alexandre Belloni <alexandre.belloni@bootlin.com>
- Claudiu Beznea <claudiu.beznea@tuxon.dev>
description:
The Atmel HLCDC (HLCD Controller) IP available on Atmel SoCs exposes two
subdevices, a PWM chip and a Display Controller.
properties:
compatible:
enum:
- atmel,at91sam9n12-hlcdc
- atmel,at91sam9x5-hlcdc
- atmel,sama5d2-hlcdc
- atmel,sama5d3-hlcdc
- atmel,sama5d4-hlcdc
- microchip,sam9x60-hlcdc
- microchip,sam9x75-xlcdc
reg:
maxItems: 1
interrupts:
maxItems: 1
clocks:
minItems: 3
clock-names:
items:
- const: periph_clk
- const: sys_clk
- const: slow_clk
- const: lvds_pll_clk
minItems: 3
display-controller:
$ref: /schemas/display/atmel/atmel,hlcdc-display-controller.yaml
pwm:
$ref: /schemas/pwm/atmel,hlcdc-pwm.yaml
required:
- compatible
- reg
- clocks
- clock-names
- interrupts
additionalProperties: false
examples:
- |
#include <dt-bindings/clock/at91.h>
#include <dt-bindings/dma/at91.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
lcd_controller: lcd-controller@f0030000 {
compatible = "atmel,sama5d3-hlcdc";
reg = <0xf0030000 0x2000>;
clocks = <&lcdc_clk>, <&lcdck>, <&clk32k>;
clock-names = "periph_clk", "sys_clk", "slow_clk";
interrupts = <36 IRQ_TYPE_LEVEL_HIGH 0>;
display-controller {
compatible = "atmel,hlcdc-display-controller";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_lcd_base &pinctrl_lcd_rgb888>;
#address-cells = <1>;
#size-cells = <0>;
port@0 {
#address-cells = <1>;
#size-cells = <0>;
reg = <0>;
hlcdc_panel_output: endpoint@0 {
reg = <0>;
remote-endpoint = <&panel_input>;
};
};
};
pwm {
compatible = "atmel,hlcdc-pwm";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_lcd_pwm>;
#pwm-cells = <3>;
};
};
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/mfd/atmel,sama5d2-flexcom.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Microchip Flexcom (Flexible Serial Communication Unit)
maintainers:
- Kavyasree Kotagiri <kavyasree.kotagiri@microchip.com>
description:
The Microchip Flexcom is just a wrapper which embeds a SPI controller,
an I2C controller and an USART. Only one function can be used at a
time and is chosen at boot time according to the device tree.
properties:
compatible:
oneOf:
- const: atmel,sama5d2-flexcom
- items:
- const: microchip,sam9x7-flexcom
- const: atmel,sama5d2-flexcom
- items:
- const: microchip,sama7g5-flexcom
- const: atmel,sama5d2-flexcom
reg:
maxItems: 1
clocks:
maxItems: 1
"#address-cells":
const: 1
"#size-cells":
const: 1
ranges:
description:
One range for the full I/O register region. (including USART,
TWI and SPI registers).
items:
maxItems: 3
atmel,flexcom-mode:
description: |
Specifies the flexcom mode as follows:
1: USART
2: SPI
3: I2C.
$ref: /schemas/types.yaml#/definitions/uint32
enum: [1, 2, 3]
patternProperties:
"^serial@[0-9a-f]+$":
type: object
description:
Child node describing USART. See atmel-usart.txt for details
of USART bindings.
"^spi@[0-9a-f]+$":
type: object
description:
Child node describing SPI. See ../spi/spi_atmel.txt for details
of SPI bindings.
"^i2c@[0-9a-f]+$":
$ref: /schemas/i2c/atmel,at91sam-i2c.yaml
description:
Child node describing I2C.
required:
- compatible
- reg
- clocks
- "#address-cells"
- "#size-cells"
- ranges
- atmel,flexcom-mode
additionalProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/arm-gic.h>
flx0: flexcom@f8034000 {
compatible = "atmel,sama5d2-flexcom";
reg = <0xf8034000 0x200>;
clocks = <&flx0_clk>;
#address-cells = <1>;
#size-cells = <1>;
ranges = <0x0 0xf8034000 0x800>;
atmel,flexcom-mode = <2>;
};
...
* Device tree bindings for Atmel Flexcom (Flexible Serial Communication Unit)
The Atmel Flexcom is just a wrapper which embeds a SPI controller, an I2C
controller and an USART. Only one function can be used at a time and is chosen
at boot time according to the device tree.
Required properties:
- compatible: Should be "atmel,sama5d2-flexcom"
or "microchip,sam9x7-flexcom", "atmel,sama5d2-flexcom"
- reg: Should be the offset/length value for Flexcom dedicated
I/O registers (without USART, TWI or SPI registers).
- clocks: Should be the Flexcom peripheral clock from PMC.
- #address-cells: Should be <1>
- #size-cells: Should be <1>
- ranges: Should be one range for the full I/O register region
(including USART, TWI and SPI registers).
- atmel,flexcom-mode: Should be one of the following values:
- <1> for USART
- <2> for SPI
- <3> for I2C
Required child:
A single available child device of type matching the "atmel,flexcom-mode"
property.
The phandle provided by the clocks property of the child is the same as one for
the Flexcom parent.
For other properties, please refer to the documentations of the respective
device:
- ../serial/atmel-usart.txt
- ../spi/spi_atmel.txt
- ../i2c/i2c-at91.txt
Example:
flexcom@f8034000 {
compatible = "atmel,sama5d2-flexcom";
reg = <0xf8034000 0x200>;
clocks = <&flx0_clk>;
#address-cells = <1>;
#size-cells = <1>;
ranges = <0x0 0xf8034000 0x800>;
atmel,flexcom-mode = <2>;
spi@400 {
compatible = "atmel,at91rm9200-spi";
reg = <0x400 0x200>;
interrupts = <19 IRQ_TYPE_LEVEL_HIGH 7>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_flx0_default>;
#address-cells = <1>;
#size-cells = <0>;
clocks = <&flx0_clk>;
clock-names = "spi_clk";
atmel,fifo-size = <32>;
flash@0 {
compatible = "atmel,at25f512b";
reg = <0>;
spi-max-frequency = <20000000>;
};
};
};
Device-Tree bindings for Atmel's HLCDC (High LCD Controller) MFD driver
Required properties:
- compatible: value should be one of the following:
"atmel,at91sam9n12-hlcdc"
"atmel,at91sam9x5-hlcdc"
"atmel,sama5d2-hlcdc"
"atmel,sama5d3-hlcdc"
"atmel,sama5d4-hlcdc"
"microchip,sam9x60-hlcdc"
"microchip,sam9x75-xlcdc"
- reg: base address and size of the HLCDC device registers.
- clock-names: the name of the 3 clocks requested by the HLCDC device.
Should contain "periph_clk", "sys_clk" and "slow_clk".
- clocks: should contain the 3 clocks requested by the HLCDC device.
- interrupts: should contain the description of the HLCDC interrupt line
The HLCDC IP exposes two subdevices:
- a PWM chip: see ../pwm/atmel-hlcdc-pwm.txt
- a Display Controller: see ../display/atmel/hlcdc-dc.txt
Example:
hlcdc: hlcdc@f0030000 {
compatible = "atmel,sama5d3-hlcdc";
reg = <0xf0030000 0x2000>;
clocks = <&lcdc_clk>, <&lcdck>, <&clk32k>;
clock-names = "periph_clk","sys_clk", "slow_clk";
interrupts = <36 IRQ_TYPE_LEVEL_HIGH 0>;
hlcdc-display-controller {
compatible = "atmel,hlcdc-display-controller";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_lcd_base &pinctrl_lcd_rgb888>;
#address-cells = <1>;
#size-cells = <0>;
port@0 {
#address-cells = <1>;
#size-cells = <0>;
reg = <0>;
hlcdc_panel_output: endpoint@0 {
reg = <0>;
remote-endpoint = <&panel_input>;
};
};
};
hlcdc_pwm: hlcdc-pwm {
compatible = "atmel,hlcdc-pwm";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_lcd_pwm>;
#pwm-cells = <3>;
};
};
* Dialog DA9062 Power Management Integrated Circuit (PMIC)
Product information for the DA9062 and DA9061 devices can be found here:
- https://www.dialog-semiconductor.com/products/da9062
- https://www.dialog-semiconductor.com/products/da9061
The DA9062 PMIC consists of:
Device Supply Names Description
------ ------------ -----------
da9062-regulator : : LDOs & BUCKs
da9062-rtc : : Real-Time Clock
da9062-onkey : : On Key
da9062-watchdog : : Watchdog Timer
da9062-thermal : : Thermal
da9062-gpio : : GPIOs
The DA9061 PMIC consists of:
Device Supply Names Description
------ ------------ -----------
da9062-regulator : : LDOs & BUCKs
da9062-onkey : : On Key
da9062-watchdog : : Watchdog Timer
da9062-thermal : : Thermal
======
Required properties:
- compatible : Should be
"dlg,da9062" for DA9062
"dlg,da9061" for DA9061
- reg : Specifies the I2C slave address (this defaults to 0x58 but it can be
modified to match the chip's OTP settings).
Optional properties:
- gpio-controller : Marks the device as a gpio controller.
- #gpio-cells : Should be two. The first cell is the pin number and the
second cell is used to specify the gpio polarity.
See Documentation/devicetree/bindings/gpio/gpio.txt for further information on
GPIO bindings.
- interrupts : IRQ line information.
- interrupt-controller
See Documentation/devicetree/bindings/interrupt-controller/interrupts.txt for
further information on IRQ bindings.
Sub-nodes:
- regulators : This node defines the settings for the LDOs and BUCKs.
The DA9062 regulators are bound using their names listed below:
buck1 : BUCK_1
buck2 : BUCK_2
buck3 : BUCK_3
buck4 : BUCK_4
ldo1 : LDO_1
ldo2 : LDO_2
ldo3 : LDO_3
ldo4 : LDO_4
The DA9061 regulators are bound using their names listed below:
buck1 : BUCK_1
buck2 : BUCK_2
buck3 : BUCK_3
ldo1 : LDO_1
ldo2 : LDO_2
ldo3 : LDO_3
ldo4 : LDO_4
The component follows the standard regulator framework and the bindings
details of individual regulator device can be found in:
Documentation/devicetree/bindings/regulator/regulator.txt
regulator-initial-mode may be specified for buck regulators using mode values
from include/dt-bindings/regulator/dlg,da9063-regulator.h.
- rtc : This node defines settings required for the Real-Time Clock associated
with the DA9062. There are currently no entries in this binding, however
compatible = "dlg,da9062-rtc" should be added if a node is created.
- onkey : See ../input/da9062-onkey.txt
- watchdog: See ../watchdog/da9062-wdt.txt
- thermal : See ../thermal/da9062-thermal.txt
Example:
pmic0: da9062@58 {
compatible = "dlg,da9062";
reg = <0x58>;
interrupt-parent = <&gpio6>;
interrupts = <11 IRQ_TYPE_LEVEL_LOW>;
interrupt-controller;
rtc {
compatible = "dlg,da9062-rtc";
};
regulators {
DA9062_BUCK1: buck1 {
regulator-name = "BUCK1";
regulator-min-microvolt = <300000>;
regulator-max-microvolt = <1570000>;
regulator-min-microamp = <500000>;
regulator-max-microamp = <2000000>;
regulator-initial-mode = <DA9063_BUCK_MODE_SYNC>;
regulator-boot-on;
};
DA9062_LDO1: ldo1 {
regulator-name = "LDO_1";
regulator-min-microvolt = <900000>;
regulator-max-microvolt = <3600000>;
regulator-boot-on;
};
};
};
......@@ -4,7 +4,7 @@
$id: http://devicetree.org/schemas/mfd/dlg,da9063.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Dialog DA9063/DA9063L Power Management Integrated Circuit (PMIC)
title: Dialog DA906{3L,3,2,1} Power Management Integrated Circuit (PMIC)
maintainers:
- Steve Twiss <stwiss.opensource@diasemi.com>
......@@ -17,10 +17,17 @@ description: |
moment where all voltage monitors are disabled. Next, as da9063 only supports
UV *and* OV monitoring, both must be set to the same severity and value
(0: disable, 1: enable).
Product information for the DA906{3L,3,2,1} devices can be found here:
- https://www.dialog-semiconductor.com/products/da9063l
- https://www.dialog-semiconductor.com/products/da9063
- https://www.dialog-semiconductor.com/products/da9062
- https://www.dialog-semiconductor.com/products/da9061
properties:
compatible:
enum:
- dlg,da9061
- dlg,da9062
- dlg,da9063
- dlg,da9063l
......@@ -35,20 +42,28 @@ properties:
"#interrupt-cells":
const: 2
dlg,use-sw-pm:
type: boolean
description:
Disable the watchdog during suspend.
Only use this option if you can't use the watchdog automatic suspend
function during a suspend (see register CONTROL_B).
gpio-controller: true
watchdog:
"#gpio-cells":
const: 2
gpio:
type: object
$ref: /schemas/watchdog/watchdog.yaml#
unevaluatedProperties: false
additionalProperties: false
properties:
compatible:
const: dlg,da9063-watchdog
const: dlg,da9062-gpio
onkey:
$ref: /schemas/input/dlg,da9062-onkey.yaml
regulators:
type: object
additionalProperties: false
patternProperties:
"^(ldo([1-9]|1[01])|bcore([1-2]|s-merged)|b(pro|mem|io|peri)|bmem-bio-merged|buck[1-4])$":
$ref: /schemas/regulator/regulator.yaml
unevaluatedProperties: false
rtc:
type: object
......@@ -56,37 +71,86 @@ properties:
unevaluatedProperties: false
properties:
compatible:
const: dlg,da9063-rtc
enum:
- dlg,da9062-rtc
- dlg,da9063-rtc
onkey:
type: object
$ref: /schemas/input/input.yaml#
unevaluatedProperties: false
properties:
compatible:
const: dlg,da9063-onkey
thermal:
$ref: /schemas/thermal/dlg,da9062-thermal.yaml
dlg,disable-key-power:
type: boolean
description: |
Disable power-down using a long key-press.
If this entry does not exist then by default the key-press triggered
power down is enabled and the OnKey will support both KEY_POWER and
KEY_SLEEP.
watchdog:
$ref: /schemas/watchdog/dlg,da9062-watchdog.yaml
regulators:
patternProperties:
"^(.+-hog(-[0-9]+)?)$":
type: object
additionalProperties: false
patternProperties:
"^(ldo([1-9]|1[01])|bcore([1-2]|s-merged)|b(pro|mem|io|peri)|bmem-bio-merged)$":
$ref: /schemas/regulator/regulator.yaml
unevaluatedProperties: false
required:
- gpio-hog
required:
- compatible
- reg
- interrupts
- interrupt-controller
allOf:
- if:
properties:
compatible:
contains:
enum:
- dlg,da9063
- dlg,da9063l
then:
properties:
gpio-controller: false
"#gpio-cells": false
gpio: false
regulators:
patternProperties:
"^buck[1-4]$": false
thermal: false
required:
- interrupts
- interrupt-controller
- '#interrupt-cells'
- if:
properties:
compatible:
contains:
enum:
- dlg,da9062
then:
properties:
regulators:
patternProperties:
"^(ldo([5-9]|10|11)|bcore([1-2]|s-merged)|b(pro|mem|io|peri)|bmem-bio-merged)$": false
required:
- gpio
- onkey
- rtc
- thermal
- watchdog
- if:
properties:
compatible:
contains:
enum:
- dlg,da9061
then:
properties:
gpio-controller: false
"#gpio-cells": false
gpio: false
regulators:
patternProperties:
"^(ldo([5-9]|10|11)|bcore([1-2]|s-merged)|b(pro|mem|io|peri)|bmem-bio-merged|buck4)$": false
rtc: false
required:
- onkey
- thermal
- watchdog
additionalProperties: false
......@@ -99,10 +163,10 @@ examples:
pmic@58 {
compatible = "dlg,da9063";
reg = <0x58>;
#interrupt-cells = <2>;
interrupt-parent = <&gpio6>;
interrupts = <11 IRQ_TYPE_LEVEL_LOW>;
interrupt-controller;
#interrupt-cells = <2>;
rtc {
compatible = "dlg,da9063-rtc";
......@@ -143,4 +207,121 @@ examples:
};
};
};
- |
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/regulator/dlg,da9063-regulator.h>
i2c {
#address-cells = <1>;
#size-cells = <0>;
pmic@58 {
compatible = "dlg,da9062";
reg = <0x58>;
gpio-controller;
#gpio-cells = <2>;
sd0-pwr-sel-hog {
gpio-hog;
gpios = <1 0>;
input;
line-name = "SD0_PWR_SEL";
};
sd1-pwr-sel-hog {
gpio-hog;
gpios = <2 0>;
input;
line-name = "SD1_PWR_SEL";
};
sw-et0-en-hog {
gpio-hog;
gpios = <3 0>;
input;
line-name = "SW_ET0_EN#";
};
pmic-good-hog {
gpio-hog;
gpios = <4 0>;
output-high;
line-name = "PMIC_PGOOD";
};
gpio {
compatible = "dlg,da9062-gpio";
};
onkey {
compatible = "dlg,da9062-onkey";
};
regulators {
buck1 {
regulator-name = "vdd_arm";
regulator-min-microvolt = <925000>;
regulator-max-microvolt = <1380000>;
regulator-initial-mode = <DA9063_BUCK_MODE_SYNC>;
regulator-always-on;
};
buck2 {
regulator-name = "vdd_soc";
regulator-min-microvolt = <1150000>;
regulator-max-microvolt = <1380000>;
regulator-initial-mode = <DA9063_BUCK_MODE_SYNC>;
regulator-always-on;
};
buck3 {
regulator-name = "vdd_ddr3";
regulator-min-microvolt = <1500000>;
regulator-max-microvolt = <1500000>;
regulator-initial-mode = <DA9063_BUCK_MODE_SYNC>;
regulator-always-on;
};
buck4 {
regulator-name = "vdd_eth";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <1200000>;
regulator-initial-mode = <DA9063_BUCK_MODE_SYNC>;
regulator-always-on;
};
ldo1 {
regulator-name = "vdd_snvs";
regulator-min-microvolt = <3000000>;
regulator-max-microvolt = <3000000>;
regulator-always-on;
};
ldo2 {
regulator-name = "vdd_high";
regulator-min-microvolt = <3000000>;
regulator-max-microvolt = <3000000>;
regulator-always-on;
};
ldo3 {
regulator-name = "vdd_eth_io";
regulator-min-microvolt = <2500000>;
regulator-max-microvolt = <2500000>;
};
ldo4 {
regulator-name = "vdd_emmc";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-always-on;
};
};
rtc {
compatible = "dlg,da9062-rtc";
};
thermal {
compatible = "dlg,da9062-thermal";
};
watchdog {
compatible = "dlg,da9062-watchdog";
dlg,use-sw-pm;
};
};
};
...
......@@ -93,6 +93,11 @@ properties:
'#size-cells':
const: 0
'#gpio-cells':
const: 2
gpio-controller: true
typec:
$ref: /schemas/chrome/google,cros-ec-typec.yaml#
......@@ -275,6 +280,8 @@ examples:
interrupts = <99 0>;
interrupt-parent = <&gpio7>;
spi-max-frequency = <5000000>;
#gpio-cells = <2>;
gpio-controller;
proximity {
compatible = "google,cros-ec-mkbp-proximity";
......
......@@ -31,7 +31,7 @@ properties:
maxItems: 1
firmware-name:
$ref: /schemas/types.yaml#/definitions/string
maxItems: 1
description:
Specifies the name of the calibration and configuration file selected by
the driver. If this property is omitted, the name is chosen based on the
......
......@@ -19,6 +19,7 @@ properties:
- enum:
- qcom,msm8976-tcsr
- qcom,msm8998-tcsr
- qcom,qcm2290-tcsr
- qcom,qcs404-tcsr
- qcom,sc7180-tcsr
- qcom,sc7280-tcsr
......@@ -28,6 +29,7 @@ properties:
- qcom,sdx55-tcsr
- qcom,sdx65-tcsr
- qcom,sm4450-tcsr
- qcom,sm6115-tcsr
- qcom,sm8150-tcsr
- qcom,sm8250-tcsr
- qcom,sm8350-tcsr
......
......@@ -72,7 +72,10 @@ properties:
- rockchip,rk3588-qos
- rockchip,rv1126-qos
- starfive,jh7100-sysmain
- ti,am62-usb-phy-ctrl
- ti,am654-dss-oldi-io-ctrl
- ti,am654-serdes-ctrl
- ti,j784s4-pcie-ctrl
- const: syscon
......
......@@ -34,6 +34,8 @@ properties:
interrupt-controller: true
system-power-controller: true
"#interrupt-cells":
const: 1
......
* Dialog DA9062/61 TJUNC Thermal Module
This module is part of the DA9061/DA9062. For more details about entire
DA9062 and DA9061 chips see Documentation/devicetree/bindings/mfd/da9062.txt
Junction temperature thermal module uses an interrupt signal to identify
high THERMAL_TRIP_HOT temperatures for the PMIC device.
Required properties:
- compatible: should be one of the following valid compatible string lines:
"dlg,da9061-thermal", "dlg,da9062-thermal"
"dlg,da9062-thermal"
Optional properties:
- polling-delay-passive : Specify the polling period, measured in
milliseconds, between thermal zone device update checks.
Example: DA9062
pmic0: da9062@58 {
thermal {
compatible = "dlg,da9062-thermal";
polling-delay-passive = <3000>;
};
};
Example: DA9061 using a fall-back compatible for the DA9062 onkey driver
pmic0: da9061@58 {
thermal {
compatible = "dlg,da9061-thermal", "dlg,da9062-thermal";
polling-delay-passive = <3000>;
};
};
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/thermal/dlg,da9062-thermal.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Dialog DA9062/61 TJUNC Thermal Module
maintainers:
- Biju Das <biju.das.jz@bp.renesas.com>
description: |
This module is part of the DA9061/DA9062. For more details about entire
DA906{1,2} chips see Documentation/devicetree/bindings/mfd/dlg,da9063.yaml
Junction temperature thermal module uses an interrupt signal to identify
high THERMAL_TRIP_HOT temperatures for the PMIC device.
properties:
compatible:
oneOf:
- const: dlg,da9062-thermal
- items:
- const: dlg,da9061-thermal
- const: dlg,da9062-thermal
polling-delay-passive:
description:
Specify the polling period, measured in milliseconds, between
thermal zone device update checks.
required:
- compatible
additionalProperties: false
......@@ -5012,6 +5012,12 @@ R: Sami Kyöstilä <skyostil@chromium.org>
S: Maintained
F: drivers/platform/chrome/cros_hps_i2c.c
CHROMEOS EC WATCHDOG
M: Lukasz Majczak <lma@chromium.org>
L: chrome-platform@lists.linux.dev
S: Maintained
F: drivers/watchdog/cros_ec_wdt.c
CHRONTEL CH7322 CEC DRIVER
M: Joe Tessler <jrt@google.com>
L: linux-media@vger.kernel.org
......@@ -6181,16 +6187,16 @@ DIALOG SEMICONDUCTOR DRIVERS
M: Support Opensource <support.opensource@diasemi.com>
S: Supported
W: http://www.dialog-semiconductor.com/products
F: Documentation/devicetree/bindings/input/da90??-onkey.txt
F: Documentation/devicetree/bindings/input/dlg,da72??.txt
F: Documentation/devicetree/bindings/input/dlg,da9062-onkey.yaml
F: Documentation/devicetree/bindings/mfd/da90*.txt
F: Documentation/devicetree/bindings/mfd/dlg,da90*.yaml
F: Documentation/devicetree/bindings/regulator/da92*.txt
F: Documentation/devicetree/bindings/regulator/dlg,da9*.yaml
F: Documentation/devicetree/bindings/regulator/dlg,slg51000.yaml
F: Documentation/devicetree/bindings/sound/da[79]*.txt
F: Documentation/devicetree/bindings/thermal/da90??-thermal.txt
F: Documentation/devicetree/bindings/watchdog/dlg,da90??-watchdog.yaml
F: Documentation/devicetree/bindings/thermal/dlg,da9062-thermal.yaml
F: Documentation/devicetree/bindings/watchdog/dlg,da9062-watchdog.yaml
F: Documentation/hwmon/da90??.rst
F: drivers/gpio/gpio-da90??.c
F: drivers/hwmon/da90??-hwmon.c
......
......@@ -1773,6 +1773,7 @@ config TWL4030_CORE
bool "TI TWL4030/TWL5030/TWL6030/TPS659x0 Support"
depends on I2C=y
select IRQ_DOMAIN
select MFD_CORE
select REGMAP_I2C
help
Say yes here if you have TWL4030 / TWL6030 family chip on your board.
......
......@@ -72,7 +72,7 @@ static const struct regmap_config ac100_regmap_config = {
.wr_table = &ac100_writeable_table,
.volatile_table = &ac100_volatile_table,
.max_register = AC100_RTC_GP(15),
.cache_type = REGCACHE_RBTREE,
.cache_type = REGCACHE_MAPLE,
};
static struct mfd_cell ac100_cells[] = {
......
......@@ -109,7 +109,9 @@ struct regmap *altr_sysmgr_regmap_lookup_by_phandle(struct device_node *np,
dev = driver_find_device_by_of_node(&altr_sysmgr_driver.driver,
(void *)sysmgr_np);
of_node_put(sysmgr_np);
if (property)
of_node_put(sysmgr_np);
if (!dev)
return ERR_PTR(-EPROBE_DEFER);
......
......@@ -106,7 +106,7 @@ static const struct regmap_config as3711_regmap_config = {
.precious_reg = as3711_precious_reg,
.max_register = AS3711_MAX_REG,
.num_reg_defaults_raw = AS3711_NUM_REGS,
.cache_type = REGCACHE_RBTREE,
.cache_type = REGCACHE_MAPLE,
};
#ifdef CONFIG_OF
......
......@@ -299,7 +299,7 @@ static const struct regmap_config as3722_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.max_register = AS3722_MAX_REGISTER,
.cache_type = REGCACHE_RBTREE,
.cache_type = REGCACHE_MAPLE,
.rd_table = &as3722_readable_table,
.wr_table = &as3722_writable_table,
.volatile_table = &as3722_volatile_table,
......
......@@ -352,7 +352,7 @@ static const struct regmap_config axp192_regmap_config = {
.wr_table = &axp192_writeable_table,
.volatile_table = &axp192_volatile_table,
.max_register = AXP20X_CC_CTRL,
.cache_type = REGCACHE_RBTREE,
.cache_type = REGCACHE_MAPLE,
};
static const struct regmap_config axp20x_regmap_config = {
......@@ -388,7 +388,7 @@ static const struct regmap_config axp313a_regmap_config = {
.wr_table = &axp313a_writeable_table,
.volatile_table = &axp313a_volatile_table,
.max_register = AXP313A_IRQ_STATE,
.cache_type = REGCACHE_RBTREE,
.cache_type = REGCACHE_MAPLE,
};
static const struct regmap_config axp806_regmap_config = {
......
......@@ -27,14 +27,14 @@ static const struct regmap_config bcm590xx_regmap_config_pri = {
.reg_bits = 8,
.val_bits = 8,
.max_register = BCM590XX_MAX_REGISTER_PRI,
.cache_type = REGCACHE_RBTREE,
.cache_type = REGCACHE_MAPLE,
};
static const struct regmap_config bcm590xx_regmap_config_sec = {
.reg_bits = 8,
.val_bits = 8,
.max_register = BCM590XX_MAX_REGISTER_SEC,
.cache_type = REGCACHE_RBTREE,
.cache_type = REGCACHE_MAPLE,
};
static int bcm590xx_i2c_probe(struct i2c_client *i2c_pri)
......
......@@ -67,7 +67,7 @@ static const struct regmap_access_table bd9571mwv_volatile_table = {
static const struct regmap_config bd9571mwv_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.cache_type = REGCACHE_RBTREE,
.cache_type = REGCACHE_MAPLE,
.rd_table = &bd9571mwv_readable_table,
.wr_table = &bd9571mwv_writable_table,
.volatile_table = &bd9571mwv_volatile_table,
......@@ -152,7 +152,7 @@ static const struct regmap_access_table bd9574mwf_volatile_table = {
static const struct regmap_config bd9574mwf_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.cache_type = REGCACHE_RBTREE,
.cache_type = REGCACHE_MAPLE,
.rd_table = &bd9574mwf_readable_table,
.wr_table = &bd9574mwf_writable_table,
.volatile_table = &bd9574mwf_volatile_table,
......
......@@ -74,6 +74,10 @@ static const struct mfd_cell cros_ec_cec_cells[] = {
{ .name = "cros-ec-cec", },
};
static const struct mfd_cell cros_ec_gpio_cells[] = {
{ .name = "cros-ec-gpio", },
};
static const struct mfd_cell cros_ec_rtc_cells[] = {
{ .name = "cros-ec-rtc", },
};
......@@ -91,12 +95,21 @@ static const struct mfd_cell cros_usbpd_notify_cells[] = {
{ .name = "cros-usbpd-notify", },
};
static const struct mfd_cell cros_ec_wdt_cells[] = {
{ .name = "cros-ec-wdt", }
};
static const struct cros_feature_to_cells cros_subdevices[] = {
{
.id = EC_FEATURE_CEC,
.mfd_cells = cros_ec_cec_cells,
.num_cells = ARRAY_SIZE(cros_ec_cec_cells),
},
{
.id = EC_FEATURE_GPIO,
.mfd_cells = cros_ec_gpio_cells,
.num_cells = ARRAY_SIZE(cros_ec_gpio_cells),
},
{
.id = EC_FEATURE_RTC,
.mfd_cells = cros_ec_rtc_cells,
......@@ -107,6 +120,11 @@ static const struct cros_feature_to_cells cros_subdevices[] = {
.mfd_cells = cros_usbpd_charger_cells,
.num_cells = ARRAY_SIZE(cros_usbpd_charger_cells),
},
{
.id = EC_FEATURE_HANG_DETECT,
.mfd_cells = cros_ec_wdt_cells,
.num_cells = ARRAY_SIZE(cros_ec_wdt_cells),
},
};
static const struct mfd_cell cros_ec_platform_cells[] = {
......
......@@ -6,11 +6,15 @@
* Cirrus Logic International Semiconductor Ltd.
*/
#include <linux/array_size.h>
#include <linux/err.h>
#include <linux/errno.h>
#include <linux/i2c.h>
#include <linux/mfd/cs42l43.h>
#include <linux/mfd/cs42l43-regs.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/pm.h>
#include <linux/regmap.h>
#include "cs42l43.h"
......@@ -34,7 +38,6 @@ static const struct regmap_config cs42l43_i2c_regmap = {
static int cs42l43_i2c_probe(struct i2c_client *i2c)
{
struct cs42l43 *cs42l43;
int ret;
cs42l43 = devm_kzalloc(&i2c->dev, sizeof(*cs42l43), GFP_KERNEL);
if (!cs42l43)
......@@ -46,11 +49,9 @@ static int cs42l43_i2c_probe(struct i2c_client *i2c)
cs42l43->attached = true;
cs42l43->regmap = devm_regmap_init_i2c(i2c, &cs42l43_i2c_regmap);
if (IS_ERR(cs42l43->regmap)) {
ret = PTR_ERR(cs42l43->regmap);
dev_err(cs42l43->dev, "Failed to allocate regmap: %d\n", ret);
return ret;
}
if (IS_ERR(cs42l43->regmap))
return dev_err_probe(cs42l43->dev, PTR_ERR(cs42l43->regmap),
"Failed to allocate regmap\n");
return cs42l43_dev_probe(cs42l43);
}
......
......@@ -6,11 +6,15 @@
* Cirrus Logic International Semiconductor Ltd.
*/
#include <linux/array_size.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/errno.h>
#include <linux/mfd/cs42l43.h>
#include <linux/mfd/cs42l43-regs.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/pm.h>
#include <linux/regmap.h>
#include <linux/soundwire/sdw.h>
#include <linux/soundwire/sdw_registers.h>
#include <linux/soundwire/sdw_type.h>
......@@ -167,7 +171,6 @@ static int cs42l43_sdw_probe(struct sdw_slave *sdw, const struct sdw_device_id *
{
struct cs42l43 *cs42l43;
struct device *dev = &sdw->dev;
int ret;
cs42l43 = devm_kzalloc(dev, sizeof(*cs42l43), GFP_KERNEL);
if (!cs42l43)
......@@ -177,11 +180,9 @@ static int cs42l43_sdw_probe(struct sdw_slave *sdw, const struct sdw_device_id *
cs42l43->sdw = sdw;
cs42l43->regmap = devm_regmap_init_sdw(sdw, &cs42l43_sdw_regmap);
if (IS_ERR(cs42l43->regmap)) {
ret = PTR_ERR(cs42l43->regmap);
dev_err(cs42l43->dev, "Failed to allocate regmap: %d\n", ret);
return ret;
}
if (IS_ERR(cs42l43->regmap))
return dev_err_probe(cs42l43->dev, PTR_ERR(cs42l43->regmap),
"Failed to allocate regmap\n");
return cs42l43_dev_probe(cs42l43);
}
......
......@@ -6,51 +6,57 @@
* Cirrus Logic International Semiconductor Ltd.
*/
#include <linux/array_size.h>
#include <linux/bitops.h>
#include <linux/build_bug.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/errno.h>
#include <linux/firmware.h>
#include <linux/gpio/consumer.h>
#include <linux/jiffies.h>
#include <linux/mfd/core.h>
#include <linux/mfd/cs42l43.h>
#include <linux/mfd/cs42l43-regs.h>
#include <linux/module.h>
#include <linux/pm.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <linux/soundwire/sdw.h>
#include <linux/types.h>
#include "cs42l43.h"
#define CS42L43_RESET_DELAY 20
#define CS42L43_RESET_DELAY_MS 20
#define CS42L43_SDW_ATTACH_TIMEOUT 500
#define CS42L43_SDW_DETACH_TIMEOUT 100
#define CS42L43_SDW_ATTACH_TIMEOUT_MS 500
#define CS42L43_SDW_DETACH_TIMEOUT_MS 100
#define CS42L43_MCU_BOOT_STAGE1 1
#define CS42L43_MCU_BOOT_STAGE2 2
#define CS42L43_MCU_BOOT_STAGE3 3
#define CS42L43_MCU_BOOT_STAGE4 4
#define CS42L43_MCU_POLL 5000
#define CS42L43_MCU_CMD_TIMEOUT 20000
#define CS42L43_MCU_POLL_US 5000
#define CS42L43_MCU_CMD_TIMEOUT_US 20000
#define CS42L43_MCU_UPDATE_FORMAT 3
#define CS42L43_MCU_UPDATE_OFFSET 0x100000
#define CS42L43_MCU_UPDATE_TIMEOUT 500000
#define CS42L43_MCU_UPDATE_TIMEOUT_US 500000
#define CS42L43_MCU_UPDATE_RETRIES 5
#define CS42L43_MCU_SUPPORTED_REV 0x2105
#define CS42L43_MCU_SHADOW_REGS_REQUIRED_REV 0x2200
#define CS42L43_MCU_SUPPORTED_BIOS_REV 0x0001
#define CS42L43_VDDP_DELAY 50
#define CS42L43_VDDD_DELAY 1000
#define CS42L43_VDDP_DELAY_US 50
#define CS42L43_VDDD_DELAY_US 1000
#define CS42L43_AUTOSUSPEND_TIME 250
#define CS42L43_AUTOSUSPEND_TIME_MS 250
struct cs42l43_patch_header {
__le16 version;
__le16 size;
u8 reserved;
u8 secure;
__u8 reserved;
__u8 secure;
__le16 bss_size;
__le32 apply_addr;
__le32 checksum;
......@@ -84,7 +90,7 @@ const struct reg_default cs42l43_reg_default[CS42L43_N_DEFAULTS] = {
{ CS42L43_DRV_CTRL_5, 0x136C00C0 },
{ CS42L43_GPIO_CTRL1, 0x00000707 },
{ CS42L43_GPIO_CTRL2, 0x00000000 },
{ CS42L43_GPIO_FN_SEL, 0x00000000 },
{ CS42L43_GPIO_FN_SEL, 0x00000004 },
{ CS42L43_MCLK_SRC_SEL, 0x00000000 },
{ CS42L43_SAMPLE_RATE1, 0x00000003 },
{ CS42L43_SAMPLE_RATE2, 0x00000003 },
......@@ -131,38 +137,38 @@ const struct reg_default cs42l43_reg_default[CS42L43_N_DEFAULTS] = {
{ CS42L43_ASP_TX_CH4_CTRL, 0x00170091 },
{ CS42L43_ASP_TX_CH5_CTRL, 0x001700C1 },
{ CS42L43_ASP_TX_CH6_CTRL, 0x001700F1 },
{ CS42L43_ASPTX1_INPUT, 0x00800000 },
{ CS42L43_ASPTX2_INPUT, 0x00800000 },
{ CS42L43_ASPTX3_INPUT, 0x00800000 },
{ CS42L43_ASPTX4_INPUT, 0x00800000 },
{ CS42L43_ASPTX5_INPUT, 0x00800000 },
{ CS42L43_ASPTX6_INPUT, 0x00800000 },
{ CS42L43_SWIRE_DP1_CH1_INPUT, 0x00800000 },
{ CS42L43_SWIRE_DP1_CH2_INPUT, 0x00800000 },
{ CS42L43_SWIRE_DP1_CH3_INPUT, 0x00800000 },
{ CS42L43_SWIRE_DP1_CH4_INPUT, 0x00800000 },
{ CS42L43_SWIRE_DP2_CH1_INPUT, 0x00800000 },
{ CS42L43_SWIRE_DP2_CH2_INPUT, 0x00800000 },
{ CS42L43_SWIRE_DP3_CH1_INPUT, 0x00800000 },
{ CS42L43_SWIRE_DP3_CH2_INPUT, 0x00800000 },
{ CS42L43_SWIRE_DP4_CH1_INPUT, 0x00800000 },
{ CS42L43_SWIRE_DP4_CH2_INPUT, 0x00800000 },
{ CS42L43_ASRC_INT1_INPUT1, 0x00800000 },
{ CS42L43_ASRC_INT2_INPUT1, 0x00800000 },
{ CS42L43_ASRC_INT3_INPUT1, 0x00800000 },
{ CS42L43_ASRC_INT4_INPUT1, 0x00800000 },
{ CS42L43_ASRC_DEC1_INPUT1, 0x00800000 },
{ CS42L43_ASRC_DEC2_INPUT1, 0x00800000 },
{ CS42L43_ASRC_DEC3_INPUT1, 0x00800000 },
{ CS42L43_ASRC_DEC4_INPUT1, 0x00800000 },
{ CS42L43_ISRC1INT1_INPUT1, 0x00800000 },
{ CS42L43_ISRC1INT2_INPUT1, 0x00800000 },
{ CS42L43_ISRC1DEC1_INPUT1, 0x00800000 },
{ CS42L43_ISRC1DEC2_INPUT1, 0x00800000 },
{ CS42L43_ISRC2INT1_INPUT1, 0x00800000 },
{ CS42L43_ISRC2INT2_INPUT1, 0x00800000 },
{ CS42L43_ISRC2DEC1_INPUT1, 0x00800000 },
{ CS42L43_ISRC2DEC2_INPUT1, 0x00800000 },
{ CS42L43_ASPTX1_INPUT, 0x00000000 },
{ CS42L43_ASPTX2_INPUT, 0x00000000 },
{ CS42L43_ASPTX3_INPUT, 0x00000000 },
{ CS42L43_ASPTX4_INPUT, 0x00000000 },
{ CS42L43_ASPTX5_INPUT, 0x00000000 },
{ CS42L43_ASPTX6_INPUT, 0x00000000 },
{ CS42L43_SWIRE_DP1_CH1_INPUT, 0x00000000 },
{ CS42L43_SWIRE_DP1_CH2_INPUT, 0x00000000 },
{ CS42L43_SWIRE_DP1_CH3_INPUT, 0x00000000 },
{ CS42L43_SWIRE_DP1_CH4_INPUT, 0x00000000 },
{ CS42L43_SWIRE_DP2_CH1_INPUT, 0x00000000 },
{ CS42L43_SWIRE_DP2_CH2_INPUT, 0x00000000 },
{ CS42L43_SWIRE_DP3_CH1_INPUT, 0x00000000 },
{ CS42L43_SWIRE_DP3_CH2_INPUT, 0x00000000 },
{ CS42L43_SWIRE_DP4_CH1_INPUT, 0x00000000 },
{ CS42L43_SWIRE_DP4_CH2_INPUT, 0x00000000 },
{ CS42L43_ASRC_INT1_INPUT1, 0x00000000 },
{ CS42L43_ASRC_INT2_INPUT1, 0x00000000 },
{ CS42L43_ASRC_INT3_INPUT1, 0x00000000 },
{ CS42L43_ASRC_INT4_INPUT1, 0x00000000 },
{ CS42L43_ASRC_DEC1_INPUT1, 0x00000000 },
{ CS42L43_ASRC_DEC2_INPUT1, 0x00000000 },
{ CS42L43_ASRC_DEC3_INPUT1, 0x00000000 },
{ CS42L43_ASRC_DEC4_INPUT1, 0x00000000 },
{ CS42L43_ISRC1INT1_INPUT1, 0x00000000 },
{ CS42L43_ISRC1INT2_INPUT1, 0x00000000 },
{ CS42L43_ISRC1DEC1_INPUT1, 0x00000000 },
{ CS42L43_ISRC1DEC2_INPUT1, 0x00000000 },
{ CS42L43_ISRC2INT1_INPUT1, 0x00000000 },
{ CS42L43_ISRC2INT2_INPUT1, 0x00000000 },
{ CS42L43_ISRC2DEC1_INPUT1, 0x00000000 },
{ CS42L43_ISRC2DEC2_INPUT1, 0x00000000 },
{ CS42L43_EQ1MIX_INPUT1, 0x00800000 },
{ CS42L43_EQ1MIX_INPUT2, 0x00800000 },
{ CS42L43_EQ1MIX_INPUT3, 0x00800000 },
......@@ -171,8 +177,8 @@ const struct reg_default cs42l43_reg_default[CS42L43_N_DEFAULTS] = {
{ CS42L43_EQ2MIX_INPUT2, 0x00800000 },
{ CS42L43_EQ2MIX_INPUT3, 0x00800000 },
{ CS42L43_EQ2MIX_INPUT4, 0x00800000 },
{ CS42L43_SPDIF1_INPUT1, 0x00800000 },
{ CS42L43_SPDIF2_INPUT1, 0x00800000 },
{ CS42L43_SPDIF1_INPUT1, 0x00000000 },
{ CS42L43_SPDIF2_INPUT1, 0x00000000 },
{ CS42L43_AMP1MIX_INPUT1, 0x00800000 },
{ CS42L43_AMP1MIX_INPUT2, 0x00800000 },
{ CS42L43_AMP1MIX_INPUT3, 0x00800000 },
......@@ -217,7 +223,7 @@ const struct reg_default cs42l43_reg_default[CS42L43_N_DEFAULTS] = {
{ CS42L43_CTRL_REG, 0x00000006 },
{ CS42L43_FDIV_FRAC, 0x40000000 },
{ CS42L43_CAL_RATIO, 0x00000080 },
{ CS42L43_SPI_CLK_CONFIG1, 0x00000000 },
{ CS42L43_SPI_CLK_CONFIG1, 0x00000001 },
{ CS42L43_SPI_CONFIG1, 0x00000000 },
{ CS42L43_SPI_CONFIG2, 0x00000000 },
{ CS42L43_SPI_CONFIG3, 0x00000001 },
......@@ -532,10 +538,10 @@ static int cs42l43_soft_reset(struct cs42l43 *cs42l43)
regcache_cache_only(cs42l43->regmap, true);
regmap_multi_reg_write_bypassed(cs42l43->regmap, reset, ARRAY_SIZE(reset));
msleep(CS42L43_RESET_DELAY);
msleep(CS42L43_RESET_DELAY_MS);
if (cs42l43->sdw) {
unsigned long timeout = msecs_to_jiffies(CS42L43_SDW_DETACH_TIMEOUT);
unsigned long timeout = msecs_to_jiffies(CS42L43_SDW_DETACH_TIMEOUT_MS);
unsigned long time;
time = wait_for_completion_timeout(&cs42l43->device_detach, timeout);
......@@ -555,7 +561,7 @@ static int cs42l43_soft_reset(struct cs42l43 *cs42l43)
static int cs42l43_wait_for_attach(struct cs42l43 *cs42l43)
{
if (!cs42l43->attached) {
unsigned long timeout = msecs_to_jiffies(CS42L43_SDW_ATTACH_TIMEOUT);
unsigned long timeout = msecs_to_jiffies(CS42L43_SDW_ATTACH_TIMEOUT_MS);
unsigned long time;
time = wait_for_completion_timeout(&cs42l43->device_attach, timeout);
......@@ -597,7 +603,7 @@ static int cs42l43_mcu_stage_2_3(struct cs42l43 *cs42l43, bool shadow)
ret = regmap_read_poll_timeout(cs42l43->regmap, CS42L43_BOOT_STATUS,
val, (val == CS42L43_MCU_BOOT_STAGE3),
CS42L43_MCU_POLL, CS42L43_MCU_CMD_TIMEOUT);
CS42L43_MCU_POLL_US, CS42L43_MCU_CMD_TIMEOUT_US);
if (ret) {
dev_err(cs42l43->dev, "Failed to move to stage 3: %d, 0x%x\n", ret, val);
return ret;
......@@ -646,7 +652,7 @@ static int cs42l43_mcu_disable(struct cs42l43 *cs42l43)
ret = regmap_read_poll_timeout(cs42l43->regmap, CS42L43_SOFT_INT_SHADOW, val,
(val & CS42L43_CONTROL_APPLIED_INT_MASK),
CS42L43_MCU_POLL, CS42L43_MCU_CMD_TIMEOUT);
CS42L43_MCU_POLL_US, CS42L43_MCU_CMD_TIMEOUT_US);
if (ret) {
dev_err(cs42l43->dev, "Failed to disable firmware: %d, 0x%x\n", ret, val);
return ret;
......@@ -690,7 +696,7 @@ static void cs42l43_mcu_load_firmware(const struct firmware *firmware, void *con
ret = regmap_read_poll_timeout(cs42l43->regmap, CS42L43_SOFT_INT_SHADOW, val,
(val & CS42L43_PATCH_APPLIED_INT_MASK),
CS42L43_MCU_POLL, CS42L43_MCU_UPDATE_TIMEOUT);
CS42L43_MCU_POLL_US, CS42L43_MCU_UPDATE_TIMEOUT_US);
if (ret) {
dev_err(cs42l43->dev, "Failed to update firmware: %d, 0x%x\n", ret, val);
cs42l43->firmware_error = ret;
......@@ -951,7 +957,7 @@ static int cs42l43_power_up(struct cs42l43 *cs42l43)
}
/* vdd-p must be on for 50uS before any other supply */
usleep_range(CS42L43_VDDP_DELAY, 2 * CS42L43_VDDP_DELAY);
usleep_range(CS42L43_VDDP_DELAY_US, 2 * CS42L43_VDDP_DELAY_US);
gpiod_set_value_cansleep(cs42l43->reset, 1);
......@@ -967,7 +973,7 @@ static int cs42l43_power_up(struct cs42l43 *cs42l43)
goto err_core_supplies;
}
usleep_range(CS42L43_VDDD_DELAY, 2 * CS42L43_VDDD_DELAY);
usleep_range(CS42L43_VDDD_DELAY_US, 2 * CS42L43_VDDD_DELAY_US);
return 0;
......@@ -1051,7 +1057,7 @@ int cs42l43_dev_probe(struct cs42l43 *cs42l43)
if (ret)
return ret;
pm_runtime_set_autosuspend_delay(cs42l43->dev, CS42L43_AUTOSUSPEND_TIME);
pm_runtime_set_autosuspend_delay(cs42l43->dev, CS42L43_AUTOSUSPEND_TIME_MS);
pm_runtime_use_autosuspend(cs42l43->dev);
pm_runtime_set_active(cs42l43->dev);
/*
......@@ -1059,7 +1065,9 @@ int cs42l43_dev_probe(struct cs42l43 *cs42l43)
* the boot work runs.
*/
pm_runtime_get_noresume(cs42l43->dev);
devm_pm_runtime_enable(cs42l43->dev);
ret = devm_pm_runtime_enable(cs42l43->dev);
if (ret)
return ret;
queue_work(system_long_wq, &cs42l43->boot_work);
......
......@@ -6,15 +6,17 @@
* Cirrus Logic International Semiconductor Ltd.
*/
#include <linux/mfd/cs42l43.h>
#include <linux/pm.h>
#include <linux/regmap.h>
#ifndef CS42L43_CORE_INT_H
#define CS42L43_CORE_INT_H
#define CS42L43_N_DEFAULTS 176
struct dev_pm_ops;
struct device;
struct reg_default;
struct cs42l43;
extern const struct dev_pm_ops cs42l43_pm_ops;
extern const struct reg_default cs42l43_reg_default[CS42L43_N_DEFAULTS];
......
......@@ -533,7 +533,7 @@ const struct regmap_config da9052_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.cache_type = REGCACHE_RBTREE,
.cache_type = REGCACHE_MAPLE,
.max_register = DA9052_PAGE1_CON_REG,
.readable_reg = da9052_reg_readable,
......
......@@ -245,7 +245,7 @@ const struct regmap_config da9055_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.cache_type = REGCACHE_RBTREE,
.cache_type = REGCACHE_MAPLE,
.max_register = DA9055_MAX_REGISTER_CNT,
.readable_reg = da9055_register_readable,
......
......@@ -476,7 +476,7 @@ static struct regmap_config da9061_regmap_config = {
.ranges = da9061_range_cfg,
.num_ranges = ARRAY_SIZE(da9061_range_cfg),
.max_register = DA9062AA_CONFIG_ID,
.cache_type = REGCACHE_RBTREE,
.cache_type = REGCACHE_MAPLE,
.rd_table = &da9061_aa_readable_table,
.wr_table = &da9061_aa_writeable_table,
.volatile_table = &da9061_aa_volatile_table,
......@@ -582,7 +582,7 @@ static struct regmap_config da9062_regmap_config = {
.ranges = da9062_range_cfg,
.num_ranges = ARRAY_SIZE(da9062_range_cfg),
.max_register = DA9062AA_CONFIG_ID,
.cache_type = REGCACHE_RBTREE,
.cache_type = REGCACHE_MAPLE,
.rd_table = &da9062_aa_readable_table,
.wr_table = &da9062_aa_writeable_table,
.volatile_table = &da9062_aa_volatile_table,
......
......@@ -342,7 +342,7 @@ static struct regmap_config da9063_regmap_config = {
.num_ranges = ARRAY_SIZE(da9063_range_cfg),
.max_register = DA9063_REG_CONFIG_ID,
.cache_type = REGCACHE_RBTREE,
.cache_type = REGCACHE_MAPLE,
};
static const struct of_device_id da9063_dt_ids[] = {
......
......@@ -169,7 +169,7 @@ static const struct regmap_config da9150_regmap_config = {
.num_ranges = ARRAY_SIZE(da9150_range_cfg),
.max_register = DA9150_TBAT_RES_B,
.cache_type = REGCACHE_RBTREE,
.cache_type = REGCACHE_MAPLE,
.volatile_reg = da9150_volatile_reg,
};
......
......@@ -23,12 +23,22 @@
#include "intel-lpss.h"
/* Some DSDTs have an unused GEXP ACPI device conflicting with I2C4 resources */
static const struct pci_device_id ignore_resource_conflicts_ids[] = {
/* Microsoft Surface Go (version 1) I2C4 */
{ PCI_DEVICE_SUB(PCI_VENDOR_ID_INTEL, 0x9d64, 0x152d, 0x1182), },
/* Microsoft Surface Go 2 I2C4 */
{ PCI_DEVICE_SUB(PCI_VENDOR_ID_INTEL, 0x9d64, 0x152d, 0x1237), },
static const struct pci_device_id quirk_ids[] = {
{
/* Microsoft Surface Go (version 1) I2C4 */
PCI_DEVICE_SUB(PCI_VENDOR_ID_INTEL, 0x9d64, 0x152d, 0x1182),
.driver_data = QUIRK_IGNORE_RESOURCE_CONFLICTS,
},
{
/* Microsoft Surface Go 2 I2C4 */
PCI_DEVICE_SUB(PCI_VENDOR_ID_INTEL, 0x9d64, 0x152d, 0x1237),
.driver_data = QUIRK_IGNORE_RESOURCE_CONFLICTS,
},
{
/* Dell XPS 9530 (2023) */
PCI_DEVICE_SUB(PCI_VENDOR_ID_INTEL, 0x51fb, 0x1028, 0x0beb),
.driver_data = QUIRK_CLOCK_DIVIDER_UNITY,
},
{ }
};
......@@ -36,6 +46,7 @@ static int intel_lpss_pci_probe(struct pci_dev *pdev,
const struct pci_device_id *id)
{
const struct intel_lpss_platform_info *data = (void *)id->driver_data;
const struct pci_device_id *quirk_pci_info;
struct intel_lpss_platform_info *info;
int ret;
......@@ -55,8 +66,9 @@ static int intel_lpss_pci_probe(struct pci_dev *pdev,
info->mem = pci_resource_n(pdev, 0);
info->irq = pci_irq_vector(pdev, 0);
if (pci_match_id(ignore_resource_conflicts_ids, pdev))
info->ignore_resource_conflicts = true;
quirk_pci_info = pci_match_id(quirk_ids, pdev);
if (quirk_pci_info)
info->quirks = quirk_pci_info->driver_data;
pdev->d3cold_delay = 0;
......
......@@ -300,6 +300,7 @@ static int intel_lpss_register_clock_divider(struct intel_lpss *lpss,
{
char name[32];
struct clk *tmp = *clk;
int ret;
snprintf(name, sizeof(name), "%s-enable", devname);
tmp = clk_register_gate(NULL, name, __clk_get_name(tmp), 0,
......@@ -316,6 +317,12 @@ static int intel_lpss_register_clock_divider(struct intel_lpss *lpss,
return PTR_ERR(tmp);
*clk = tmp;
if (lpss->info->quirks & QUIRK_CLOCK_DIVIDER_UNITY) {
ret = clk_set_rate(tmp, lpss->info->clk_rate);
if (ret)
return ret;
}
snprintf(name, sizeof(name), "%s-update", devname);
tmp = clk_register_gate(NULL, name, __clk_get_name(tmp),
CLK_SET_RATE_PARENT, lpss->priv, 31, 0, NULL);
......@@ -412,7 +419,7 @@ int intel_lpss_probe(struct device *dev,
return ret;
lpss->cell->swnode = info->swnode;
lpss->cell->ignore_resource_conflicts = info->ignore_resource_conflicts;
lpss->cell->ignore_resource_conflicts = info->quirks & QUIRK_IGNORE_RESOURCE_CONFLICTS;
intel_lpss_init_dev(lpss);
......
......@@ -11,16 +11,28 @@
#ifndef __MFD_INTEL_LPSS_H
#define __MFD_INTEL_LPSS_H
#include <linux/bits.h>
#include <linux/pm.h>
/*
* Some DSDTs have an unused GEXP ACPI device conflicting with I2C4 resources.
* Set to ignore resource conflicts with ACPI declared SystemMemory regions.
*/
#define QUIRK_IGNORE_RESOURCE_CONFLICTS BIT(0)
/*
* Some devices have misconfigured clock divider due to a firmware bug.
* Set this to force the clock divider to 1:1 ratio.
*/
#define QUIRK_CLOCK_DIVIDER_UNITY BIT(1)
struct device;
struct resource;
struct software_node;
struct intel_lpss_platform_info {
struct resource *mem;
bool ignore_resource_conflicts;
int irq;
unsigned int quirks;
unsigned long clk_rate;
const char *clk_con_id;
const struct software_node *swnode;
......
......@@ -428,50 +428,13 @@ static int kempld_detect_device(struct kempld_device_data *pld)
#ifdef CONFIG_ACPI
static int kempld_get_acpi_data(struct platform_device *pdev)
{
struct list_head resource_list;
struct resource *resources;
struct resource_entry *rentry;
struct device *dev = &pdev->dev;
struct acpi_device *acpi_dev = ACPI_COMPANION(dev);
const struct kempld_platform_data *pdata;
int ret;
int count;
pdata = acpi_device_get_match_data(dev);
ret = platform_device_add_data(pdev, pdata,
sizeof(struct kempld_platform_data));
if (ret)
return ret;
INIT_LIST_HEAD(&resource_list);
ret = acpi_dev_get_resources(acpi_dev, &resource_list, NULL, NULL);
if (ret < 0)
goto out;
count = ret;
if (count == 0) {
ret = platform_device_add_resources(pdev, pdata->ioresource, 1);
goto out;
}
resources = devm_kcalloc(&acpi_dev->dev, count, sizeof(*resources),
GFP_KERNEL);
if (!resources) {
ret = -ENOMEM;
goto out;
}
count = 0;
list_for_each_entry(rentry, &resource_list, node) {
memcpy(&resources[count], rentry->res,
sizeof(*resources));
count++;
}
ret = platform_device_add_resources(pdev, resources, count);
out:
acpi_dev_free_resource_list(&resource_list);
return ret;
}
......
......@@ -72,7 +72,7 @@ static const struct regmap_config khadas_mcu_regmap_config = {
.max_register = KHADAS_MCU_CMD_FAN_STATUS_CTRL_REG,
.volatile_reg = khadas_mcu_reg_volatile,
.writeable_reg = khadas_mcu_reg_writeable,
.cache_type = REGCACHE_RBTREE,
.cache_type = REGCACHE_MAPLE,
};
static struct mfd_cell khadas_mcu_fan_cells[] = {
......
......@@ -70,7 +70,7 @@ static const struct regmap_config lochnagar1_i2c_regmap = {
.use_single_read = true,
.use_single_write = true,
.cache_type = REGCACHE_RBTREE,
.cache_type = REGCACHE_MAPLE,
};
static const struct reg_sequence lochnagar1_patch[] = {
......@@ -163,7 +163,7 @@ static const struct regmap_config lochnagar2_i2c_regmap = {
.readable_reg = lochnagar2_readable_register,
.volatile_reg = lochnagar2_volatile_register,
.cache_type = REGCACHE_RBTREE,
.cache_type = REGCACHE_MAPLE,
};
static const struct reg_sequence lochnagar2_patch[] = {
......
......@@ -38,6 +38,7 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/align.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/errno.h>
......@@ -1321,7 +1322,7 @@ static int lpc_ich_init_spi(struct pci_dev *dev)
case INTEL_SPI_BYT:
pci_read_config_dword(dev, SPIBASE_BYT, &spi_base);
if (spi_base & SPIBASE_BYT_EN) {
res->start = spi_base & ~(SPIBASE_BYT_SZ - 1);
res->start = ALIGN_DOWN(spi_base, SPIBASE_BYT_SZ);
res->end = res->start + SPIBASE_BYT_SZ - 1;
info->set_writeable = lpc_ich_byt_set_writeable;
......
......@@ -7,6 +7,7 @@
* Copyright 2009 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de>
*/
#include <linux/bitfield.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
......@@ -174,28 +175,27 @@ int mc13xxx_irq_free(struct mc13xxx *mc13xxx, int irq, void *dev)
}
EXPORT_SYMBOL(mc13xxx_irq_free);
#define maskval(reg, mask) (((reg) & (mask)) >> __ffs(mask))
static void mc13xxx_print_revision(struct mc13xxx *mc13xxx, u32 revision)
{
dev_info(mc13xxx->dev, "%s: rev: %d.%d, "
"fin: %d, fab: %d, icid: %d/%d\n",
mc13xxx->variant->name,
maskval(revision, MC13XXX_REVISION_REVFULL),
maskval(revision, MC13XXX_REVISION_REVMETAL),
maskval(revision, MC13XXX_REVISION_FIN),
maskval(revision, MC13XXX_REVISION_FAB),
maskval(revision, MC13XXX_REVISION_ICID),
maskval(revision, MC13XXX_REVISION_ICIDCODE));
FIELD_GET(MC13XXX_REVISION_REVFULL, revision),
FIELD_GET(MC13XXX_REVISION_REVMETAL, revision),
FIELD_GET(MC13XXX_REVISION_FIN, revision),
FIELD_GET(MC13XXX_REVISION_FAB, revision),
FIELD_GET(MC13XXX_REVISION_ICID, revision),
FIELD_GET(MC13XXX_REVISION_ICIDCODE, revision));
}
static void mc34708_print_revision(struct mc13xxx *mc13xxx, u32 revision)
{
dev_info(mc13xxx->dev, "%s: rev %d.%d, fin: %d, fab: %d\n",
mc13xxx->variant->name,
maskval(revision, MC34708_REVISION_REVFULL),
maskval(revision, MC34708_REVISION_REVMETAL),
maskval(revision, MC34708_REVISION_FIN),
maskval(revision, MC34708_REVISION_FAB));
FIELD_GET(MC34708_REVISION_REVFULL, revision),
FIELD_GET(MC34708_REVISION_REVMETAL, revision),
FIELD_GET(MC34708_REVISION_FIN, revision),
FIELD_GET(MC34708_REVISION_FAB, revision));
}
/* These are only exported for mc13xxx-i2c and mc13xxx-spi */
......
......@@ -41,7 +41,7 @@ static void mcp_bus_remove(struct device *dev)
drv->remove(mcp);
}
static struct bus_type mcp_bus_type = {
static const struct bus_type mcp_bus_type = {
.name = "mcp",
.match = mcp_bus_match,
.probe = mcp_bus_probe,
......
......@@ -29,7 +29,7 @@ struct mfd_of_node_entry {
struct device_node *np;
};
static struct device_type mfd_dev_type = {
static const struct device_type mfd_dev_type = {
.name = "mfd_device",
};
......
......@@ -141,6 +141,9 @@ static const struct mfd_cell mt6357_devs[] = {
.num_resources = ARRAY_SIZE(mt6357_rtc_resources),
.resources = mt6357_rtc_resources,
.of_compatible = "mediatek,mt6357-rtc",
}, {
.name = "mt6357-sound",
.of_compatible = "mediatek,mt6357-sound"
}, {
.name = "mtk-pmic-keys",
.num_resources = ARRAY_SIZE(mt6357_keys_resources),
......
......@@ -699,7 +699,7 @@ static int usbhs_omap_probe(struct platform_device *pdev)
}
for (i = 0; i < omap->nports; i++) {
char clkname[30];
char clkname[40];
/* clock names are indexed from 1*/
snprintf(clkname, sizeof(clkname),
......
......@@ -358,7 +358,7 @@ int rave_sp_exec(struct rave_sp *sp,
ackid = atomic_inc_return(&sp->ackid);
reply.ackid = ackid;
reply.code = rave_sp_reply_code((u8)command),
reply.code = rave_sp_reply_code((u8)command);
mutex_lock(&sp->bus_lock);
......
......@@ -230,7 +230,7 @@ static const struct regmap_config rc5t583_regmap_config = {
.volatile_reg = volatile_reg,
.max_register = RC5T583_MAX_REG,
.num_reg_defaults_raw = RC5T583_NUM_REGS,
.cache_type = REGCACHE_RBTREE,
.cache_type = REGCACHE_MAPLE,
};
static int rc5t583_i2c_probe(struct i2c_client *i2c)
......
......@@ -43,8 +43,8 @@ static struct resource rk806_pwrkey_resources[] = {
};
static const struct resource rk817_pwrkey_resources[] = {
DEFINE_RES_IRQ(RK817_IRQ_PWRON_RISE),
DEFINE_RES_IRQ(RK817_IRQ_PWRON_FALL),
DEFINE_RES_IRQ(RK817_IRQ_PWRON_RISE),
};
static const struct resource rk817_charger_resources[] = {
......
......@@ -34,7 +34,7 @@ static const struct regmap_config rk806_regmap_config_spi = {
.reg_bits = 16,
.val_bits = 8,
.max_register = RK806_BUCK_RSERVE_REG5,
.cache_type = REGCACHE_RBTREE,
.cache_type = REGCACHE_MAPLE,
.volatile_table = &rk806_volatile_table,
};
......
......@@ -62,7 +62,7 @@ static const struct regmap_config rn5t618_regmap_config = {
.val_bits = 8,
.volatile_reg = rn5t618_volatile_reg,
.max_register = RN5T618_MAX_REG,
.cache_type = REGCACHE_RBTREE,
.cache_type = REGCACHE_MAPLE,
};
static const struct regmap_irq rc5t619_irqs[] = {
......
......@@ -197,7 +197,7 @@ static const struct regmap_config bd71815_regmap = {
.val_bits = 8,
.volatile_table = &bd71815_volatile_regs,
.max_register = BD71815_MAX_REGISTER - 1,
.cache_type = REGCACHE_RBTREE,
.cache_type = REGCACHE_MAPLE,
};
static const struct regmap_config bd71828_regmap = {
......@@ -205,7 +205,7 @@ static const struct regmap_config bd71828_regmap = {
.val_bits = 8,
.volatile_table = &bd71828_volatile_regs,
.max_register = BD71828_MAX_REGISTER,
.cache_type = REGCACHE_RBTREE,
.cache_type = REGCACHE_MAPLE,
};
/*
......
......@@ -87,7 +87,7 @@ static const struct regmap_config bd718xx_regmap_config = {
.val_bits = 8,
.volatile_table = &volatile_regs,
.max_register = BD718XX_MAX_REGISTER - 1,
.cache_type = REGCACHE_RBTREE,
.cache_type = REGCACHE_MAPLE,
};
static int bd718xx_init_press_duration(struct regmap *regmap,
......
......@@ -62,7 +62,7 @@ static struct regmap_config bd957x_regmap = {
.val_bits = 8,
.volatile_table = &volatile_regs,
.max_register = BD957X_MAX_REGISTER,
.cache_type = REGCACHE_RBTREE,
.cache_type = REGCACHE_MAPLE,
};
static struct regmap_irq bd9576_irqs[] = {
......
......@@ -188,7 +188,7 @@ static const struct regmap_config rsmu_sabre_regmap_config = {
.ranges = rsmu_sabre_range_cfg,
.num_ranges = ARRAY_SIZE(rsmu_sabre_range_cfg),
.volatile_reg = rsmu_sabre_volatile_reg,
.cache_type = REGCACHE_RBTREE,
.cache_type = REGCACHE_MAPLE,
.can_multi_write = true,
};
......
......@@ -222,7 +222,7 @@ static const struct regmap_config si476x_regmap_config = {
.reg_read = si476x_core_regmap_read,
.reg_write = si476x_core_regmap_write,
.cache_type = REGCACHE_RBTREE,
.cache_type = REGCACHE_MAPLE,
};
struct regmap *devm_regmap_init_si476x(struct si476x_core *core)
......
......@@ -53,7 +53,7 @@ static const struct regmap_config stmfx_regmap_config = {
.max_register = STMFX_REG_MAX,
.volatile_reg = stmfx_reg_volatile,
.writeable_reg = stmfx_reg_writeable,
.cache_type = REGCACHE_RBTREE,
.cache_type = REGCACHE_MAPLE,
};
static const struct resource stmfx_pinctrl_resources[] = {
......
......@@ -63,7 +63,7 @@ static const struct regmap_access_table stpmic1_volatile_table = {
static const struct regmap_config stpmic1_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.cache_type = REGCACHE_RBTREE,
.cache_type = REGCACHE_MAPLE,
.max_register = PMIC_MAX_REGISTER_ADDRESS,
.rd_table = &stpmic1_readable_table,
.wr_table = &stpmic1_writeable_table,
......
......@@ -238,7 +238,9 @@ struct regmap *syscon_regmap_lookup_by_phandle(struct device_node *np,
return ERR_PTR(-ENODEV);
regmap = syscon_node_to_regmap(syscon_np);
of_node_put(syscon_np);
if (property)
of_node_put(syscon_np);
return regmap;
}
......
......@@ -124,6 +124,11 @@
#define TWL6030_BASEADD_RSV 0x0000
#define TWL6030_BASEADD_ZERO 0x0000
/* Some fields in TWL6030_PHOENIX_DEV_ON */
#define TWL6030_APP_DEVOFF BIT(0)
#define TWL6030_CON_DEVOFF BIT(1)
#define TWL6030_MOD_DEVOFF BIT(2)
/* Few power values */
#define R_CFG_BOOT 0x05
......@@ -687,6 +692,20 @@ static void twl_remove(struct i2c_client *client)
twl_priv->ready = false;
}
static void twl6030_power_off(void)
{
int err;
u8 val;
err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &val, TWL6030_PHOENIX_DEV_ON);
if (err)
return;
val |= TWL6030_APP_DEVOFF | TWL6030_CON_DEVOFF | TWL6030_MOD_DEVOFF;
twl_i2c_write_u8(TWL_MODULE_PM_MASTER, val, TWL6030_PHOENIX_DEV_ON);
}
static struct of_dev_auxdata twl_auxdata_lookup[] = {
OF_DEV_AUXDATA("ti,twl4030-gpio", 0, "twl4030-gpio", NULL),
{ /* sentinel */ },
......@@ -852,6 +871,15 @@ twl_probe(struct i2c_client *client)
goto free;
}
if (twl_class_is_6030()) {
if (of_device_is_system_power_controller(node)) {
if (!pm_power_off)
pm_power_off = twl6030_power_off;
else
dev_warn(&client->dev, "Poweroff callback already assigned\n");
}
}
status = of_platform_populate(node, NULL, twl_auxdata_lookup,
&client->dev);
......
......@@ -686,6 +686,9 @@ static bool twl4030_power_use_poweroff(const struct twl4030_power_data *pdata,
if (of_property_read_bool(node, "ti,use_poweroff"))
return true;
if (of_device_is_system_power_controller(node->parent))
return true;
return false;
}
......
......@@ -1922,7 +1922,7 @@ const struct regmap_config wm5102_spi_regmap = {
.readable_reg = wm5102_readable_register,
.volatile_reg = wm5102_volatile_register,
.cache_type = REGCACHE_RBTREE,
.cache_type = REGCACHE_MAPLE,
.reg_defaults = wm5102_reg_default,
.num_reg_defaults = ARRAY_SIZE(wm5102_reg_default),
};
......
......@@ -3202,7 +3202,7 @@ const struct regmap_config wm5110_spi_regmap = {
.readable_reg = wm5110_readable_register,
.volatile_reg = wm5110_volatile_register,
.cache_type = REGCACHE_RBTREE,
.cache_type = REGCACHE_MAPLE,
.reg_defaults = wm5110_reg_default,
.num_reg_defaults = ARRAY_SIZE(wm5110_reg_default),
};
......
......@@ -152,7 +152,7 @@ static irqreturn_t wm831x_auxadc_irq(int irq, void *irq_data)
static int wm831x_auxadc_read_polled(struct wm831x *wm831x,
enum wm831x_auxadc input)
{
int ret, src, timeout;
int ret, src;
mutex_lock(&wm831x->auxadc_lock);
......@@ -179,32 +179,25 @@ static int wm831x_auxadc_read_polled(struct wm831x *wm831x,
goto disable;
}
/* If we're not using interrupts then poll the
* interrupt status register */
timeout = 5;
while (timeout) {
msleep(1);
/* If we're not using interrupts then read the interrupt status register */
msleep(20);
ret = wm831x_reg_read(wm831x,
WM831X_INTERRUPT_STATUS_1);
if (ret < 0) {
dev_err(wm831x->dev,
"ISR 1 read failed: %d\n", ret);
goto disable;
}
ret = wm831x_reg_read(wm831x, WM831X_INTERRUPT_STATUS_1);
if (ret < 0) {
dev_err(wm831x->dev,
"ISR 1 read failed: %d\n", ret);
goto disable;
}
/* Did it complete? */
if (ret & WM831X_AUXADC_DATA_EINT) {
wm831x_reg_write(wm831x,
WM831X_INTERRUPT_STATUS_1,
WM831X_AUXADC_DATA_EINT);
break;
} else {
dev_err(wm831x->dev,
"AUXADC conversion timeout\n");
ret = -EBUSY;
goto disable;
}
/* Did it complete? */
if (ret & WM831X_AUXADC_DATA_EINT) {
wm831x_reg_write(wm831x, WM831X_INTERRUPT_STATUS_1,
WM831X_AUXADC_DATA_EINT);
} else {
dev_err(wm831x->dev,
"AUXADC conversion timeout\n");
ret = -EBUSY;
goto disable;
}
ret = wm831x_reg_read(wm831x, WM831X_AUXADC_DATA);
......
......@@ -325,7 +325,7 @@ const struct regmap_config wm8350_regmap = {
.reg_bits = 8,
.val_bits = 16,
.cache_type = REGCACHE_RBTREE,
.cache_type = REGCACHE_MAPLE,
.max_register = WM8350_MAX_REGISTER,
.readable_reg = wm8350_readable,
......
......@@ -100,7 +100,7 @@ static const struct regmap_config wm8400_regmap_config = {
.volatile_reg = wm8400_volatile,
.cache_type = REGCACHE_RBTREE,
.cache_type = REGCACHE_MAPLE,
};
/**
......
......@@ -95,7 +95,7 @@ static const struct regmap_config wm9705_regmap_config = {
.reg_stride = 2,
.val_bits = 16,
.max_register = 0x7e,
.cache_type = REGCACHE_RBTREE,
.cache_type = REGCACHE_MAPLE,
.reg_defaults = wm9705_reg_defaults,
.num_reg_defaults = ARRAY_SIZE(wm9705_reg_defaults),
......@@ -163,7 +163,7 @@ static const struct regmap_config wm9712_regmap_config = {
.reg_stride = 2,
.val_bits = 16,
.max_register = 0x7e,
.cache_type = REGCACHE_RBTREE,
.cache_type = REGCACHE_MAPLE,
.reg_defaults = wm9712_reg_defaults,
.num_reg_defaults = ARRAY_SIZE(wm9712_reg_defaults),
......@@ -234,7 +234,7 @@ static const struct regmap_config wm9713_regmap_config = {
.reg_stride = 2,
.val_bits = 16,
.max_register = 0x7e,
.cache_type = REGCACHE_RBTREE,
.cache_type = REGCACHE_MAPLE,
.reg_defaults = wm9713_reg_defaults,
.num_reg_defaults = ARRAY_SIZE(wm9713_reg_defaults),
......
......@@ -11,7 +11,9 @@
#include <linux/errno.h>
#include <linux/mfd/cs42l43.h>
#include <linux/mfd/cs42l43-regs.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
......
......@@ -181,6 +181,17 @@ config BD957XMUF_WATCHDOG
watchdog. Alternatively say M to compile the driver as a module,
which will be called bd9576_wdt.
config CROS_EC_WATCHDOG
tristate "ChromeOS EC-based watchdog"
select WATCHDOG_CORE
depends on CROS_EC
help
Watchdog driver for Chromebook devices equipped with embedded controller.
Trigger event is recorded in EC and checked on the subsequent boot.
To compile this driver as a module, choose M here: the
module will be called cros_ec_wdt.
config DA9052_WATCHDOG
tristate "Dialog DA9052 Watchdog"
depends on PMIC_DA9052 || COMPILE_TEST
......
......@@ -217,6 +217,7 @@ obj-$(CONFIG_XEN_WDT) += xen_wdt.o
# Architecture Independent
obj-$(CONFIG_BD957XMUF_WATCHDOG) += bd9576_wdt.o
obj-$(CONFIG_CROS_EC_WATCHDOG) += cros_ec_wdt.o
obj-$(CONFIG_DA9052_WATCHDOG) += da9052_wdt.o
obj-$(CONFIG_DA9055_WATCHDOG) += da9055_wdt.o
obj-$(CONFIG_DA9062_WATCHDOG) += da9062_wdt.o
......
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright 2024 Google LLC.
* Author: Lukasz Majczak <lma@chromium.com>
*/
#include <linux/err.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mod_devicetable.h>
#include <linux/platform_data/cros_ec_commands.h>
#include <linux/platform_data/cros_ec_proto.h>
#include <linux/platform_device.h>
#include <linux/watchdog.h>
#define CROS_EC_WATCHDOG_DEFAULT_TIME 30 /* seconds */
#define DRV_NAME "cros-ec-wdt"
union cros_ec_wdt_data {
struct ec_params_hang_detect req;
struct ec_response_hang_detect resp;
} __packed;
static int cros_ec_wdt_send_cmd(struct cros_ec_device *cros_ec,
union cros_ec_wdt_data *arg)
{
int ret;
struct {
struct cros_ec_command msg;
union cros_ec_wdt_data data;
} __packed buf = {
.msg = {
.version = 0,
.command = EC_CMD_HANG_DETECT,
.insize = (arg->req.command == EC_HANG_DETECT_CMD_GET_STATUS) ?
sizeof(struct ec_response_hang_detect) :
0,
.outsize = sizeof(struct ec_params_hang_detect),
},
.data.req = arg->req
};
ret = cros_ec_cmd_xfer_status(cros_ec, &buf.msg);
if (ret < 0)
return ret;
arg->resp = buf.data.resp;
return 0;
}
static int cros_ec_wdt_ping(struct watchdog_device *wdd)
{
struct cros_ec_device *cros_ec = watchdog_get_drvdata(wdd);
union cros_ec_wdt_data arg;
int ret;
arg.req.command = EC_HANG_DETECT_CMD_RELOAD;
ret = cros_ec_wdt_send_cmd(cros_ec, &arg);
if (ret < 0)
dev_dbg(wdd->parent, "Failed to ping watchdog (%d)", ret);
return ret;
}
static int cros_ec_wdt_start(struct watchdog_device *wdd)
{
struct cros_ec_device *cros_ec = watchdog_get_drvdata(wdd);
union cros_ec_wdt_data arg;
int ret;
/* Prepare watchdog on EC side */
arg.req.command = EC_HANG_DETECT_CMD_SET_TIMEOUT;
arg.req.reboot_timeout_sec = wdd->timeout;
ret = cros_ec_wdt_send_cmd(cros_ec, &arg);
if (ret < 0)
dev_dbg(wdd->parent, "Failed to start watchdog (%d)", ret);
return ret;
}
static int cros_ec_wdt_stop(struct watchdog_device *wdd)
{
struct cros_ec_device *cros_ec = watchdog_get_drvdata(wdd);
union cros_ec_wdt_data arg;
int ret;
arg.req.command = EC_HANG_DETECT_CMD_CANCEL;
ret = cros_ec_wdt_send_cmd(cros_ec, &arg);
if (ret < 0)
dev_dbg(wdd->parent, "Failed to stop watchdog (%d)", ret);
return ret;
}
static int cros_ec_wdt_set_timeout(struct watchdog_device *wdd, unsigned int t)
{
unsigned int old_timeout = wdd->timeout;
int ret;
wdd->timeout = t;
ret = cros_ec_wdt_start(wdd);
if (ret < 0)
wdd->timeout = old_timeout;
return ret;
}
static const struct watchdog_info cros_ec_wdt_ident = {
.options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
.firmware_version = 0,
.identity = DRV_NAME,
};
static const struct watchdog_ops cros_ec_wdt_ops = {
.owner = THIS_MODULE,
.ping = cros_ec_wdt_ping,
.start = cros_ec_wdt_start,
.stop = cros_ec_wdt_stop,
.set_timeout = cros_ec_wdt_set_timeout,
};
static int cros_ec_wdt_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct cros_ec_dev *ec_dev = dev_get_drvdata(dev->parent);
struct cros_ec_device *cros_ec = ec_dev->ec_dev;
struct watchdog_device *wdd;
union cros_ec_wdt_data arg;
int ret = 0;
wdd = devm_kzalloc(&pdev->dev, sizeof(*wdd), GFP_KERNEL);
if (!wdd)
return -ENOMEM;
arg.req.command = EC_HANG_DETECT_CMD_GET_STATUS;
ret = cros_ec_wdt_send_cmd(cros_ec, &arg);
if (ret < 0)
return dev_err_probe(dev, ret, "Failed to get watchdog bootstatus");
wdd->parent = &pdev->dev;
wdd->info = &cros_ec_wdt_ident;
wdd->ops = &cros_ec_wdt_ops;
wdd->timeout = CROS_EC_WATCHDOG_DEFAULT_TIME;
wdd->min_timeout = EC_HANG_DETECT_MIN_TIMEOUT;
wdd->max_timeout = EC_HANG_DETECT_MAX_TIMEOUT;
if (arg.resp.status == EC_HANG_DETECT_AP_BOOT_EC_WDT)
wdd->bootstatus = WDIOF_CARDRESET;
arg.req.command = EC_HANG_DETECT_CMD_CLEAR_STATUS;
ret = cros_ec_wdt_send_cmd(cros_ec, &arg);
if (ret < 0)
return dev_err_probe(dev, ret, "Failed to clear watchdog bootstatus");
watchdog_stop_on_reboot(wdd);
watchdog_stop_on_unregister(wdd);
watchdog_set_drvdata(wdd, cros_ec);
platform_set_drvdata(pdev, wdd);
return devm_watchdog_register_device(dev, wdd);
}
static int __maybe_unused cros_ec_wdt_suspend(struct platform_device *pdev, pm_message_t state)
{
struct watchdog_device *wdd = platform_get_drvdata(pdev);
int ret = 0;
if (watchdog_active(wdd))
ret = cros_ec_wdt_stop(wdd);
return ret;
}
static int __maybe_unused cros_ec_wdt_resume(struct platform_device *pdev)
{
struct watchdog_device *wdd = platform_get_drvdata(pdev);
int ret = 0;
if (watchdog_active(wdd))
ret = cros_ec_wdt_start(wdd);
return ret;
}
static const struct platform_device_id cros_ec_wdt_id[] = {
{ DRV_NAME, 0 },
{}
};
static struct platform_driver cros_ec_wdt_driver = {
.probe = cros_ec_wdt_probe,
.suspend = pm_ptr(cros_ec_wdt_suspend),
.resume = pm_ptr(cros_ec_wdt_resume),
.driver = {
.name = DRV_NAME,
},
.id_table = cros_ec_wdt_id,
};
module_platform_driver(cros_ec_wdt_driver);
MODULE_DEVICE_TABLE(platform, cros_ec_wdt_id);
MODULE_DESCRIPTION("Cros EC Watchdog Device Driver");
MODULE_LICENSE("GPL");
......@@ -6,20 +6,21 @@
* Cirrus Logic International Semiconductor Ltd.
*/
#ifndef CS42L43_CORE_EXT_H
#define CS42L43_CORE_EXT_H
#include <linux/completion.h>
#include <linux/device.h>
#include <linux/gpio/consumer.h>
#include <linux/mutex.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/soundwire/sdw.h>
#include <linux/workqueue.h>
#ifndef CS42L43_CORE_EXT_H
#define CS42L43_CORE_EXT_H
#define CS42L43_N_SUPPLIES 3
struct device;
struct gpio_desc;
struct sdw_slave;
enum cs42l43_irq_numbers {
CS42L43_PLL_LOST_LOCK,
CS42L43_PLL_READY,
......
......@@ -81,8 +81,8 @@
#define SUN4I_GPADC_TEMP_DATA 0x20
#define SUN4I_GPADC_DATA 0x24
#define SUN4I_GPADC_IRQ_FIFO_DATA 0
#define SUN4I_GPADC_IRQ_TEMP_DATA 1
#define SUN4I_GPADC_IRQ_FIFO_DATA 1
#define SUN4I_GPADC_IRQ_TEMP_DATA 2
/* 10s delay before suspending the IP */
#define SUN4I_GPADC_AUTOSUSPEND_DELAY 10000
......
......@@ -17,20 +17,17 @@
struct device_node;
#ifdef CONFIG_MFD_SYSCON
extern struct regmap *device_node_to_regmap(struct device_node *np);
extern struct regmap *syscon_node_to_regmap(struct device_node *np);
extern struct regmap *syscon_regmap_lookup_by_compatible(const char *s);
extern struct regmap *syscon_regmap_lookup_by_phandle(
struct device_node *np,
const char *property);
extern struct regmap *syscon_regmap_lookup_by_phandle_args(
struct device_node *np,
const char *property,
int arg_count,
unsigned int *out_args);
extern struct regmap *syscon_regmap_lookup_by_phandle_optional(
struct device_node *np,
const char *property);
struct regmap *device_node_to_regmap(struct device_node *np);
struct regmap *syscon_node_to_regmap(struct device_node *np);
struct regmap *syscon_regmap_lookup_by_compatible(const char *s);
struct regmap *syscon_regmap_lookup_by_phandle(struct device_node *np,
const char *property);
struct regmap *syscon_regmap_lookup_by_phandle_args(struct device_node *np,
const char *property,
int arg_count,
unsigned int *out_args);
struct regmap *syscon_regmap_lookup_by_phandle_optional(struct device_node *np,
const char *property);
#else
static inline struct regmap *device_node_to_regmap(struct device_node *np)
{
......
......@@ -461,6 +461,7 @@ static inline int twl6030_mmc_card_detect(struct device *dev, int slot)
#define TWL4030_PM_MASTER_GLOBAL_TST 0xb6
#define TWL6030_PHOENIX_DEV_ON 0x06
/*----------------------------------------------------------------------*/
/* Power bus message definitions */
......
......@@ -3961,60 +3961,52 @@ struct ec_response_i2c_passthru {
} __ec_align1;
/*****************************************************************************/
/* Power button hang detect */
/* AP hang detect */
#define EC_CMD_HANG_DETECT 0x009F
/* Reasons to start hang detection timer */
/* Power button pressed */
#define EC_HANG_START_ON_POWER_PRESS BIT(0)
/* Lid closed */
#define EC_HANG_START_ON_LID_CLOSE BIT(1)
/* Lid opened */
#define EC_HANG_START_ON_LID_OPEN BIT(2)
/* Start of AP S3->S0 transition (booting or resuming from suspend) */
#define EC_HANG_START_ON_RESUME BIT(3)
/* Reasons to cancel hang detection */
#define EC_HANG_DETECT_MIN_TIMEOUT 5
#define EC_HANG_DETECT_MAX_TIMEOUT 65535
/* Power button released */
#define EC_HANG_STOP_ON_POWER_RELEASE BIT(8)
/* EC hang detect commands */
enum ec_hang_detect_cmds {
/* Reload AP hang detect timer. */
EC_HANG_DETECT_CMD_RELOAD = 0x0,
/* Any host command from AP received */
#define EC_HANG_STOP_ON_HOST_COMMAND BIT(9)
/* Stop AP hang detect timer. */
EC_HANG_DETECT_CMD_CANCEL = 0x1,
/* Stop on end of AP S0->S3 transition (suspending or shutting down) */
#define EC_HANG_STOP_ON_SUSPEND BIT(10)
/* Configure watchdog with given reboot timeout and
* cancel currently running AP hang detect timer.
*/
EC_HANG_DETECT_CMD_SET_TIMEOUT = 0x2,
/*
* If this flag is set, all the other fields are ignored, and the hang detect
* timer is started. This provides the AP a way to start the hang timer
* without reconfiguring any of the other hang detect settings. Note that
* you must previously have configured the timeouts.
*/
#define EC_HANG_START_NOW BIT(30)
/* Get last hang status - whether the AP boot was clear or not */
EC_HANG_DETECT_CMD_GET_STATUS = 0x3,
/*
* If this flag is set, all the other fields are ignored (including
* EC_HANG_START_NOW). This provides the AP a way to stop the hang timer
* without reconfiguring any of the other hang detect settings.
*/
#define EC_HANG_STOP_NOW BIT(31)
/* Clear last hang status. Called when AP is rebooting/shutting down
* gracefully.
*/
EC_HANG_DETECT_CMD_CLEAR_STATUS = 0x4
};
struct ec_params_hang_detect {
/* Flags; see EC_HANG_* */
uint32_t flags;
/* Timeout in msec before generating host event, if enabled */
uint16_t host_event_timeout_msec;
uint16_t command; /* enum ec_hang_detect_cmds */
/* Timeout in seconds before generating reboot */
uint16_t reboot_timeout_sec;
} __ec_align2;
/* Timeout in msec before generating warm reboot, if enabled */
uint16_t warm_reboot_timeout_msec;
} __ec_align4;
/* Status codes that describe whether AP has boot normally or the hang has been
* detected and EC has reset AP
*/
enum ec_hang_detect_status {
EC_HANG_DETECT_AP_BOOT_NORMAL = 0x0,
EC_HANG_DETECT_AP_BOOT_EC_WDT = 0x1,
EC_HANG_DETECT_AP_BOOT_COUNT,
};
struct ec_response_hang_detect {
uint8_t status; /* enum ec_hang_detect_status */
} __ec_align1;
/*****************************************************************************/
/* Commands for battery charging */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment