summaryrefslogtreecommitdiffstats
path: root/drivers/mfd
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-05-14 13:39:08 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2019-05-14 13:39:08 -0400
commitebcf5bb28241fe3ddc9e786e3816848a10f688b8 (patch)
tree28c8ce0f20c690b0ac2492e034fab34ad89aa9d1 /drivers/mfd
parent414147d99b928c574ed76e9374a5d2cb77866a29 (diff)
parented835136ee679dc528333c454ca4d1543c5aab76 (diff)
Merge tag 'mfd-next-5.2' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd
Pull MFD updates from Lee Jones: "Core Framework: - Document (kerneldoc) core mfd_add_devices() API New Drivers: - Altera SOCFPGA System Manager - Maxim MAX77650/77651 PMIC - Maxim MAX77663 PMIC - ST Multi-Function eXpander (STMFX) New Device Support: - LEDs support in Intel Cherry Trail Whiskey Cove PMIC - RTC support in SAMSUNG Electronics S2MPA01 PMIC - SAM9X60 support in Atmel HLCDC (High-end LCD Controller) - USB X-Powers AXP 8xx PMICs - Integrated Sensor Hub (ISH) in ChromeOS EC - USB PD Logger in ChromeOS EC - AXP223 in X-Powers AXP series PMICs - Power Supply in X-Powers AXP 803 PMICs - Comet Lake in Intel Low Power Subsystem - Fingerprint MCU in ChromeOS EC - Touchpad MCU in ChromeOS EC - Move TI LM3532 support to LED New Functionality: - max77650, max77620: Add/extend DT support - max77620 power-off - syscon clocking - croc_ec host sleep event Fix-ups: - Trivial; Formatting, spelling, etc; Kconfig, sec-core, ab8500-debugfs - Remove unused functionality; rk808, da9063-* - SPDX conversion; da9063-*, atmel-*, - Adapt/add new register definitions; cs47l35-tables, cs47l90-tables, imx6q-iomuxc-gpr - Fix-up DT bindings; ti-lmu, cirrus,lochnagar - Simply obtaining driver data; ssbi, t7l66xb, tc6387xb, tc6393xb Bug Fixes: - Fix incorrect defined values; max77620, da9063 - Fix device initialisation; twl6040 - Reset device on init; intel-lpss - Fix build warnings when !OF; sun6i-prcm - Register OF match tables; tps65912-spi - Fix DMI matching; intel_quark_i2c_gpio" * tag 'mfd-next-5.2' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd: (65 commits) mfd: Use dev_get_drvdata() directly mfd: cros_ec: Instantiate properly CrOS Touchpad MCU device mfd: cros_ec: Instantiate properly CrOS FP MCU device mfd: cros_ec: Update the EC feature codes mfd: intel-lpss: Add Intel Comet Lake PCI IDs mfd: lochnagar: Add links to binding docs for sound and hwmon mfd: ab8500-debugfs: Fix a typo ("deubgfs") mfd: imx6sx: Add MQS register definition for iomuxc gpr dt-bindings: mfd: LMU: Fix lm3632 dt binding example mfd: intel_quark_i2c_gpio: Adjust IOT2000 matching mfd: da9063: Fix OTP control register names to match datasheets for DA9063/63L mfd: tps65912-spi: Add missing of table registration mfd: axp20x: Add USB power supply mfd cell to AXP803 mfd: sun6i-prcm: Fix build warning for non-OF configurations mfd: intel-lpss: Set the device in reset state when init platform/chrome: Add support for v1 of host sleep event mfd: cros_ec: Add host_sleep_event_v1 command mfd: cros_ec: Instantiate the CrOS USB PD logger driver mfd: cs47l90: Make DAC_AEC_CONTROL_2 readable mfd: cs47l35: Make DAC_AEC_CONTROL_2 readable ...
Diffstat (limited to 'drivers/mfd')
-rw-r--r--drivers/mfd/Kconfig99
-rw-r--r--drivers/mfd/Makefile4
-rw-r--r--drivers/mfd/ab8500-debugfs.c2
-rw-r--r--drivers/mfd/altera-sysmgr.c211
-rw-r--r--drivers/mfd/atmel-hlcdc.c1
-rw-r--r--drivers/mfd/axp20x-i2c.c2
-rw-r--r--drivers/mfd/axp20x.c16
-rw-r--r--drivers/mfd/cros_ec.c39
-rw-r--r--drivers/mfd/cros_ec_dev.c36
-rw-r--r--drivers/mfd/cs47l35-tables.c2
-rw-r--r--drivers/mfd/cs47l90-tables.c2
-rw-r--r--drivers/mfd/da9063-core.c28
-rw-r--r--drivers/mfd/da9063-i2c.c10
-rw-r--r--drivers/mfd/da9063-irq.c10
-rw-r--r--drivers/mfd/intel-lpss-pci.c13
-rw-r--r--drivers/mfd/intel-lpss.c3
-rw-r--r--drivers/mfd/intel_quark_i2c_gpio.c10
-rw-r--r--drivers/mfd/intel_soc_pmic_chtwc.c1
-rw-r--r--drivers/mfd/max77620.c87
-rw-r--r--drivers/mfd/max77650.c232
-rw-r--r--drivers/mfd/mfd-core.c13
-rw-r--r--drivers/mfd/rk808.c9
-rw-r--r--drivers/mfd/sec-core.c59
-rw-r--r--drivers/mfd/sec-irq.c3
-rw-r--r--drivers/mfd/ssbi.c6
-rw-r--r--drivers/mfd/stmfx.c545
-rw-r--r--drivers/mfd/sun6i-prcm.c3
-rw-r--r--drivers/mfd/syscon.c19
-rw-r--r--drivers/mfd/t7l66xb.c12
-rw-r--r--drivers/mfd/tc6387xb.c12
-rw-r--r--drivers/mfd/tc6393xb.c23
-rw-r--r--drivers/mfd/tps65912-spi.c1
-rw-r--r--drivers/mfd/twl6040.c13
33 files changed, 1350 insertions, 176 deletions
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 26ad6468d13a..294d9567cc71 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -16,7 +16,7 @@ config MFD_CS5535
16 depends on PCI && (X86_32 || (X86 && COMPILE_TEST)) 16 depends on PCI && (X86_32 || (X86 && COMPILE_TEST))
17 ---help--- 17 ---help---
18 This is the core driver for CS5535/CS5536 MFD functions. This is 18 This is the core driver for CS5535/CS5536 MFD functions. This is
19 necessary for using the board's GPIO and MFGPT functionality. 19 necessary for using the board's GPIO and MFGPT functionality.
20 20
21config MFD_ALTERA_A10SR 21config MFD_ALTERA_A10SR
22 bool "Altera Arria10 DevKit System Resource chip" 22 bool "Altera Arria10 DevKit System Resource chip"
@@ -29,6 +29,16 @@ config MFD_ALTERA_A10SR
29 accessing the external gpio extender (LEDs & buttons) and 29 accessing the external gpio extender (LEDs & buttons) and
30 power supply alarms (hwmon). 30 power supply alarms (hwmon).
31 31
32config MFD_ALTERA_SYSMGR
33 bool "Altera SOCFPGA System Manager"
34 depends on (ARCH_SOCFPGA || ARCH_STRATIX10) && OF
35 select MFD_SYSCON
36 help
37 Select this to get System Manager support for all Altera branded
38 SOCFPGAs. The SOCFPGA System Manager handles all SOCFPGAs by
39 using regmap_mmio accesses for ARM32 parts and SMC calls to
40 EL3 for ARM64 parts.
41
32config MFD_ACT8945A 42config MFD_ACT8945A
33 tristate "Active-semi ACT8945A" 43 tristate "Active-semi ACT8945A"
34 select MFD_CORE 44 select MFD_CORE
@@ -213,13 +223,13 @@ config MFD_CROS_EC
213 protocol for talking to the EC is defined by the bus driver. 223 protocol for talking to the EC is defined by the bus driver.
214 224
215config MFD_CROS_EC_CHARDEV 225config MFD_CROS_EC_CHARDEV
216 tristate "Chrome OS Embedded Controller userspace device interface" 226 tristate "Chrome OS Embedded Controller userspace device interface"
217 depends on MFD_CROS_EC 227 depends on MFD_CROS_EC
218 ---help--- 228 ---help---
219 This driver adds support to talk with the ChromeOS EC from userspace. 229 This driver adds support to talk with the ChromeOS EC from userspace.
220 230
221 If you have a supported Chromebook, choose Y or M here. 231 If you have a supported Chromebook, choose Y or M here.
222 The module will be called cros_ec_dev. 232 The module will be called cros_ec_dev.
223 233
224config MFD_MADERA 234config MFD_MADERA
225 tristate "Cirrus Logic Madera codecs" 235 tristate "Cirrus Logic Madera codecs"
@@ -733,6 +743,20 @@ config MFD_MAX77620
733 provides common support for accessing the device; additional drivers 743 provides common support for accessing the device; additional drivers
734 must be enabled in order to use the functionality of the device. 744 must be enabled in order to use the functionality of the device.
735 745
746config MFD_MAX77650
747 tristate "Maxim MAX77650/77651 PMIC Support"
748 depends on I2C
749 depends on OF || COMPILE_TEST
750 select MFD_CORE
751 select REGMAP_I2C
752 help
753 Say Y here to add support for Maxim Semiconductor MAX77650 and
754 MAX77651 Power Management ICs. This is the core multifunction
755 driver for interacting with the device. The module name is
756 'max77650'. Additional drivers can be enabled in order to use
757 the following functionalities of the device: GPIO, regulator,
758 charger, LED, onkey.
759
736config MFD_MAX77686 760config MFD_MAX77686
737 tristate "Maxim Semiconductor MAX77686/802 PMIC Support" 761 tristate "Maxim Semiconductor MAX77686/802 PMIC Support"
738 depends on I2C 762 depends on I2C
@@ -867,7 +891,7 @@ config MFD_CPCAP
867 At least Motorola Droid 4 is known to use CPCAP. 891 At least Motorola Droid 4 is known to use CPCAP.
868 892
869config MFD_VIPERBOARD 893config MFD_VIPERBOARD
870 tristate "Nano River Technologies Viperboard" 894 tristate "Nano River Technologies Viperboard"
871 select MFD_CORE 895 select MFD_CORE
872 depends on USB 896 depends on USB
873 default n 897 default n
@@ -903,15 +927,15 @@ config PCF50633_ADC
903 tristate "NXP PCF50633 ADC" 927 tristate "NXP PCF50633 ADC"
904 depends on MFD_PCF50633 928 depends on MFD_PCF50633
905 help 929 help
906 Say yes here if you want to include support for ADC in the 930 Say yes here if you want to include support for ADC in the
907 NXP PCF50633 chip. 931 NXP PCF50633 chip.
908 932
909config PCF50633_GPIO 933config PCF50633_GPIO
910 tristate "NXP PCF50633 GPIO" 934 tristate "NXP PCF50633 GPIO"
911 depends on MFD_PCF50633 935 depends on MFD_PCF50633
912 help 936 help
913 Say yes here if you want to include support GPIO for pins on 937 Say yes here if you want to include support GPIO for pins on
914 the PCF50633 chip. 938 the PCF50633 chip.
915 939
916config UCB1400_CORE 940config UCB1400_CORE
917 tristate "Philips UCB1400 Core driver" 941 tristate "Philips UCB1400 Core driver"
@@ -1026,7 +1050,7 @@ config MFD_RN5T618
1026 select REGMAP_I2C 1050 select REGMAP_I2C
1027 help 1051 help
1028 Say yes here to add support for the Ricoh RN5T567, 1052 Say yes here to add support for the Ricoh RN5T567,
1029 RN5T618, RC5T619 PMIC. 1053 RN5T618, RC5T619 PMIC.
1030 This driver provides common support for accessing the device, 1054 This driver provides common support for accessing the device,
1031 additional drivers must be enabled in order to use the 1055 additional drivers must be enabled in order to use the
1032 functionality of the device. 1056 functionality of the device.
@@ -1079,9 +1103,9 @@ config MFD_SM501_GPIO
1079 bool "Export GPIO via GPIO layer" 1103 bool "Export GPIO via GPIO layer"
1080 depends on MFD_SM501 && GPIOLIB 1104 depends on MFD_SM501 && GPIOLIB
1081 ---help--- 1105 ---help---
1082 This option uses the gpio library layer to export the 64 GPIO 1106 This option uses the gpio library layer to export the 64 GPIO
1083 lines on the SM501. The platform data is used to supply the 1107 lines on the SM501. The platform data is used to supply the
1084 base number for the first GPIO line to register. 1108 base number for the first GPIO line to register.
1085 1109
1086config MFD_SKY81452 1110config MFD_SKY81452
1087 tristate "Skyworks Solutions SKY81452" 1111 tristate "Skyworks Solutions SKY81452"
@@ -1096,16 +1120,16 @@ config MFD_SKY81452
1096 will be called sky81452. 1120 will be called sky81452.
1097 1121
1098config MFD_SMSC 1122config MFD_SMSC
1099 bool "SMSC ECE1099 series chips" 1123 bool "SMSC ECE1099 series chips"
1100 depends on I2C=y 1124 depends on I2C=y
1101 select MFD_CORE 1125 select MFD_CORE
1102 select REGMAP_I2C 1126 select REGMAP_I2C
1103 help 1127 help
1104 If you say yes here you get support for the 1128 If you say yes here you get support for the
1105 ece1099 chips from SMSC. 1129 ece1099 chips from SMSC.
1106 1130
1107 To compile this driver as a module, choose M here: the 1131 To compile this driver as a module, choose M here: the
1108 module will be called smsc. 1132 module will be called smsc.
1109 1133
1110config MFD_SC27XX_PMIC 1134config MFD_SC27XX_PMIC
1111 tristate "Spreadtrum SC27xx PMICs" 1135 tristate "Spreadtrum SC27xx PMICs"
@@ -1171,12 +1195,12 @@ config AB8500_CORE
1171 This chip embeds various other multimedia funtionalities as well. 1195 This chip embeds various other multimedia funtionalities as well.
1172 1196
1173config AB8500_DEBUG 1197config AB8500_DEBUG
1174 bool "Enable debug info via debugfs" 1198 bool "Enable debug info via debugfs"
1175 depends on AB8500_GPADC && DEBUG_FS 1199 depends on AB8500_GPADC && DEBUG_FS
1176 default y if DEBUG_FS 1200 default y if DEBUG_FS
1177 help 1201 help
1178 Select this option if you want debug information using the debug 1202 Select this option if you want debug information using the debug
1179 filesystem, debugfs. 1203 filesystem, debugfs.
1180 1204
1181config AB8500_GPADC 1205config AB8500_GPADC
1182 bool "ST-Ericsson AB8500 GPADC driver" 1206 bool "ST-Ericsson AB8500 GPADC driver"
@@ -1907,6 +1931,19 @@ config MFD_STPMIC1
1907 To compile this driver as a module, choose M here: the 1931 To compile this driver as a module, choose M here: the
1908 module will be called stpmic1. 1932 module will be called stpmic1.
1909 1933
1934config MFD_STMFX
1935 tristate "Support for STMicroelectronics Multi-Function eXpander (STMFX)"
1936 depends on I2C
1937 depends on OF || COMPILE_TEST
1938 select MFD_CORE
1939 select REGMAP_I2C
1940 help
1941 Support for the STMicroelectronics Multi-Function eXpander.
1942
1943 This driver provides common support for accessing the device,
1944 additional drivers must be enabled in order to use the functionality
1945 of the device.
1946
1910menu "Multimedia Capabilities Port drivers" 1947menu "Multimedia Capabilities Port drivers"
1911 depends on ARCH_SA1100 1948 depends on ARCH_SA1100
1912 1949
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index b4569ed7f3f3..52b1a90ff515 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -155,6 +155,7 @@ obj-$(CONFIG_MFD_DA9150) += da9150-core.o
155 155
156obj-$(CONFIG_MFD_MAX14577) += max14577.o 156obj-$(CONFIG_MFD_MAX14577) += max14577.o
157obj-$(CONFIG_MFD_MAX77620) += max77620.o 157obj-$(CONFIG_MFD_MAX77620) += max77620.o
158obj-$(CONFIG_MFD_MAX77650) += max77650.o
158obj-$(CONFIG_MFD_MAX77686) += max77686.o 159obj-$(CONFIG_MFD_MAX77686) += max77686.o
159obj-$(CONFIG_MFD_MAX77693) += max77693.o 160obj-$(CONFIG_MFD_MAX77693) += max77693.o
160obj-$(CONFIG_MFD_MAX77843) += max77843.o 161obj-$(CONFIG_MFD_MAX77843) += max77843.o
@@ -237,6 +238,7 @@ obj-$(CONFIG_INTEL_SOC_PMIC_CHTDC_TI) += intel_soc_pmic_chtdc_ti.o
237obj-$(CONFIG_MFD_MT6397) += mt6397-core.o 238obj-$(CONFIG_MFD_MT6397) += mt6397-core.o
238 239
239obj-$(CONFIG_MFD_ALTERA_A10SR) += altera-a10sr.o 240obj-$(CONFIG_MFD_ALTERA_A10SR) += altera-a10sr.o
241obj-$(CONFIG_MFD_ALTERA_SYSMGR) += altera-sysmgr.o
240obj-$(CONFIG_MFD_STPMIC1) += stpmic1.o 242obj-$(CONFIG_MFD_STPMIC1) += stpmic1.o
241obj-$(CONFIG_MFD_SUN4I_GPADC) += sun4i-gpadc.o 243obj-$(CONFIG_MFD_SUN4I_GPADC) += sun4i-gpadc.o
242 244
@@ -246,4 +248,4 @@ obj-$(CONFIG_MFD_MXS_LRADC) += mxs-lradc.o
246obj-$(CONFIG_MFD_SC27XX_PMIC) += sprd-sc27xx-spi.o 248obj-$(CONFIG_MFD_SC27XX_PMIC) += sprd-sc27xx-spi.o
247obj-$(CONFIG_RAVE_SP_CORE) += rave-sp.o 249obj-$(CONFIG_RAVE_SP_CORE) += rave-sp.o
248obj-$(CONFIG_MFD_ROHM_BD718XX) += rohm-bd718x7.o 250obj-$(CONFIG_MFD_ROHM_BD718XX) += rohm-bd718x7.o
249 251obj-$(CONFIG_MFD_STMFX) += stmfx.o
diff --git a/drivers/mfd/ab8500-debugfs.c b/drivers/mfd/ab8500-debugfs.c
index 8d652b2f9d14..f70d3f6a959b 100644
--- a/drivers/mfd/ab8500-debugfs.c
+++ b/drivers/mfd/ab8500-debugfs.c
@@ -2587,7 +2587,7 @@ static ssize_t ab8500_unsubscribe_write(struct file *file,
2587} 2587}
2588 2588
2589/* 2589/*
2590 * - several deubgfs nodes fops 2590 * - several debugfs nodes fops
2591 */ 2591 */
2592 2592
2593static const struct file_operations ab8500_bank_fops = { 2593static const struct file_operations ab8500_bank_fops = {
diff --git a/drivers/mfd/altera-sysmgr.c b/drivers/mfd/altera-sysmgr.c
new file mode 100644
index 000000000000..8976f82785bb
--- /dev/null
+++ b/drivers/mfd/altera-sysmgr.c
@@ -0,0 +1,211 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (C) 2018-2019, Intel Corporation.
4 * Copyright (C) 2012 Freescale Semiconductor, Inc.
5 * Copyright (C) 2012 Linaro Ltd.
6 *
7 * Based on syscon driver.
8 */
9
10#include <linux/arm-smccc.h>
11#include <linux/err.h>
12#include <linux/io.h>
13#include <linux/mfd/altera-sysmgr.h>
14#include <linux/mfd/syscon.h>
15#include <linux/module.h>
16#include <linux/of.h>
17#include <linux/of_address.h>
18#include <linux/of_platform.h>
19#include <linux/regmap.h>
20#include <linux/slab.h>
21
22/**
23 * struct altr_sysmgr - Altera SOCFPGA System Manager
24 * @regmap: the regmap used for System Manager accesses.
25 * @base : the base address for the System Manager
26 */
27struct altr_sysmgr {
28 struct regmap *regmap;
29 resource_size_t *base;
30};
31
32static struct platform_driver altr_sysmgr_driver;
33
34/**
35 * s10_protected_reg_write
36 * Write to a protected SMC register.
37 * @base: Base address of System Manager
38 * @reg: Address offset of register
39 * @val: Value to write
40 * Return: INTEL_SIP_SMC_STATUS_OK (0) on success
41 * INTEL_SIP_SMC_REG_ERROR on error
42 * INTEL_SIP_SMC_RETURN_UNKNOWN_FUNCTION if not supported
43 */
44static int s10_protected_reg_write(void *base,
45 unsigned int reg, unsigned int val)
46{
47 struct arm_smccc_res result;
48 unsigned long sysmgr_base = (unsigned long)base;
49
50 arm_smccc_smc(INTEL_SIP_SMC_REG_WRITE, sysmgr_base + reg,
51 val, 0, 0, 0, 0, 0, &result);
52
53 return (int)result.a0;
54}
55
56/**
57 * s10_protected_reg_read
58 * Read the status of a protected SMC register
59 * @base: Base address of System Manager.
60 * @reg: Address of register
61 * @val: Value read.
62 * Return: INTEL_SIP_SMC_STATUS_OK (0) on success
63 * INTEL_SIP_SMC_REG_ERROR on error
64 * INTEL_SIP_SMC_RETURN_UNKNOWN_FUNCTION if not supported
65 */
66static int s10_protected_reg_read(void *base,
67 unsigned int reg, unsigned int *val)
68{
69 struct arm_smccc_res result;
70 unsigned long sysmgr_base = (unsigned long)base;
71
72 arm_smccc_smc(INTEL_SIP_SMC_REG_READ, sysmgr_base + reg,
73 0, 0, 0, 0, 0, 0, &result);
74
75 *val = (unsigned int)result.a1;
76
77 return (int)result.a0;
78}
79
80static struct regmap_config altr_sysmgr_regmap_cfg = {
81 .name = "altr_sysmgr",
82 .reg_bits = 32,
83 .reg_stride = 4,
84 .val_bits = 32,
85 .fast_io = true,
86 .use_single_read = true,
87 .use_single_write = true,
88};
89
90/**
91 * sysmgr_match_phandle
92 * Matching function used by driver_find_device().
93 * Return: True if match is found, otherwise false.
94 */
95static int sysmgr_match_phandle(struct device *dev, void *data)
96{
97 return dev->of_node == (struct device_node *)data;
98}
99
100/**
101 * altr_sysmgr_regmap_lookup_by_phandle
102 * Find the sysmgr previous configured in probe() and return regmap property.
103 * Return: regmap if found or error if not found.
104 */
105struct regmap *altr_sysmgr_regmap_lookup_by_phandle(struct device_node *np,
106 const char *property)
107{
108 struct device *dev;
109 struct altr_sysmgr *sysmgr;
110 struct device_node *sysmgr_np;
111
112 if (property)
113 sysmgr_np = of_parse_phandle(np, property, 0);
114 else
115 sysmgr_np = np;
116
117 if (!sysmgr_np)
118 return ERR_PTR(-ENODEV);
119
120 dev = driver_find_device(&altr_sysmgr_driver.driver, NULL,
121 (void *)sysmgr_np, sysmgr_match_phandle);
122 of_node_put(sysmgr_np);
123 if (!dev)
124 return ERR_PTR(-EPROBE_DEFER);
125
126 sysmgr = dev_get_drvdata(dev);
127
128 return sysmgr->regmap;
129}
130EXPORT_SYMBOL_GPL(altr_sysmgr_regmap_lookup_by_phandle);
131
132static int sysmgr_probe(struct platform_device *pdev)
133{
134 struct altr_sysmgr *sysmgr;
135 struct regmap *regmap;
136 struct resource *res;
137 struct regmap_config sysmgr_config = altr_sysmgr_regmap_cfg;
138 struct device *dev = &pdev->dev;
139 struct device_node *np = dev->of_node;
140
141 sysmgr = devm_kzalloc(dev, sizeof(*sysmgr), GFP_KERNEL);
142 if (!sysmgr)
143 return -ENOMEM;
144
145 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
146 if (!res)
147 return -ENOENT;
148
149 sysmgr_config.max_register = resource_size(res) -
150 sysmgr_config.reg_stride;
151 if (of_device_is_compatible(np, "altr,sys-mgr-s10")) {
152 /* Need physical address for SMCC call */
153 sysmgr->base = (resource_size_t *)res->start;
154 sysmgr_config.reg_read = s10_protected_reg_read;
155 sysmgr_config.reg_write = s10_protected_reg_write;
156
157 regmap = devm_regmap_init(dev, NULL, sysmgr->base,
158 &sysmgr_config);
159 } else {
160 sysmgr->base = devm_ioremap(dev, res->start,
161 resource_size(res));
162 if (!sysmgr->base)
163 return -ENOMEM;
164
165 sysmgr_config.max_register = res->end - res->start - 3;
166 regmap = devm_regmap_init_mmio(dev, sysmgr->base,
167 &sysmgr_config);
168 }
169
170 if (IS_ERR(regmap)) {
171 pr_err("regmap init failed\n");
172 return PTR_ERR(regmap);
173 }
174
175 sysmgr->regmap = regmap;
176
177 platform_set_drvdata(pdev, sysmgr);
178
179 return 0;
180}
181
182static const struct of_device_id altr_sysmgr_of_match[] = {
183 { .compatible = "altr,sys-mgr" },
184 { .compatible = "altr,sys-mgr-s10" },
185 {},
186};
187MODULE_DEVICE_TABLE(of, altr_sysmgr_of_match);
188
189static struct platform_driver altr_sysmgr_driver = {
190 .probe = sysmgr_probe,
191 .driver = {
192 .name = "altr,system_manager",
193 .of_match_table = altr_sysmgr_of_match,
194 },
195};
196
197static int __init altr_sysmgr_init(void)
198{
199 return platform_driver_register(&altr_sysmgr_driver);
200}
201core_initcall(altr_sysmgr_init);
202
203static void __exit altr_sysmgr_exit(void)
204{
205 platform_driver_unregister(&altr_sysmgr_driver);
206}
207module_exit(altr_sysmgr_exit);
208
209MODULE_AUTHOR("Thor Thayer <>");
210MODULE_DESCRIPTION("SOCFPGA System Manager driver");
211MODULE_LICENSE("GPL v2");
diff --git a/drivers/mfd/atmel-hlcdc.c b/drivers/mfd/atmel-hlcdc.c
index e82543bcfdc8..35a9e16f9902 100644
--- a/drivers/mfd/atmel-hlcdc.c
+++ b/drivers/mfd/atmel-hlcdc.c
@@ -141,6 +141,7 @@ static const struct of_device_id atmel_hlcdc_match[] = {
141 { .compatible = "atmel,sama5d2-hlcdc" }, 141 { .compatible = "atmel,sama5d2-hlcdc" },
142 { .compatible = "atmel,sama5d3-hlcdc" }, 142 { .compatible = "atmel,sama5d3-hlcdc" },
143 { .compatible = "atmel,sama5d4-hlcdc" }, 143 { .compatible = "atmel,sama5d4-hlcdc" },
144 { .compatible = "microchip,sam9x60-hlcdc" },
144 { /* sentinel */ }, 145 { /* sentinel */ },
145}; 146};
146MODULE_DEVICE_TABLE(of, atmel_hlcdc_match); 147MODULE_DEVICE_TABLE(of, atmel_hlcdc_match);
diff --git a/drivers/mfd/axp20x-i2c.c b/drivers/mfd/axp20x-i2c.c
index a7b7c5423ea5..c2e8a0dee7f8 100644
--- a/drivers/mfd/axp20x-i2c.c
+++ b/drivers/mfd/axp20x-i2c.c
@@ -65,6 +65,7 @@ static const struct of_device_id axp20x_i2c_of_match[] = {
65 { .compatible = "x-powers,axp202", .data = (void *)AXP202_ID }, 65 { .compatible = "x-powers,axp202", .data = (void *)AXP202_ID },
66 { .compatible = "x-powers,axp209", .data = (void *)AXP209_ID }, 66 { .compatible = "x-powers,axp209", .data = (void *)AXP209_ID },
67 { .compatible = "x-powers,axp221", .data = (void *)AXP221_ID }, 67 { .compatible = "x-powers,axp221", .data = (void *)AXP221_ID },
68 { .compatible = "x-powers,axp223", .data = (void *)AXP223_ID },
68 { .compatible = "x-powers,axp806", .data = (void *)AXP806_ID }, 69 { .compatible = "x-powers,axp806", .data = (void *)AXP806_ID },
69 { }, 70 { },
70}; 71};
@@ -75,6 +76,7 @@ static const struct i2c_device_id axp20x_i2c_id[] = {
75 { "axp202", 0 }, 76 { "axp202", 0 },
76 { "axp209", 0 }, 77 { "axp209", 0 },
77 { "axp221", 0 }, 78 { "axp221", 0 },
79 { "axp223", 0 },
78 { "axp806", 0 }, 80 { "axp806", 0 },
79 { }, 81 { },
80}; 82};
diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
index 3c97f2c0fdfe..2215660dfa05 100644
--- a/drivers/mfd/axp20x.c
+++ b/drivers/mfd/axp20x.c
@@ -198,6 +198,12 @@ static const struct resource axp22x_usb_power_supply_resources[] = {
198 DEFINE_RES_IRQ_NAMED(AXP22X_IRQ_VBUS_REMOVAL, "VBUS_REMOVAL"), 198 DEFINE_RES_IRQ_NAMED(AXP22X_IRQ_VBUS_REMOVAL, "VBUS_REMOVAL"),
199}; 199};
200 200
201/* AXP803 and AXP813/AXP818 share the same interrupts */
202static const struct resource axp803_usb_power_supply_resources[] = {
203 DEFINE_RES_IRQ_NAMED(AXP803_IRQ_VBUS_PLUGIN, "VBUS_PLUGIN"),
204 DEFINE_RES_IRQ_NAMED(AXP803_IRQ_VBUS_REMOVAL, "VBUS_REMOVAL"),
205};
206
201static const struct resource axp22x_pek_resources[] = { 207static const struct resource axp22x_pek_resources[] = {
202 DEFINE_RES_IRQ_NAMED(AXP22X_IRQ_PEK_RIS_EDGE, "PEK_DBR"), 208 DEFINE_RES_IRQ_NAMED(AXP22X_IRQ_PEK_RIS_EDGE, "PEK_DBR"),
203 DEFINE_RES_IRQ_NAMED(AXP22X_IRQ_PEK_FAL_EDGE, "PEK_DBF"), 209 DEFINE_RES_IRQ_NAMED(AXP22X_IRQ_PEK_FAL_EDGE, "PEK_DBF"),
@@ -741,6 +747,11 @@ static const struct mfd_cell axp803_cells[] = {
741 .of_compatible = "x-powers,axp813-ac-power-supply", 747 .of_compatible = "x-powers,axp813-ac-power-supply",
742 .num_resources = ARRAY_SIZE(axp20x_ac_power_supply_resources), 748 .num_resources = ARRAY_SIZE(axp20x_ac_power_supply_resources),
743 .resources = axp20x_ac_power_supply_resources, 749 .resources = axp20x_ac_power_supply_resources,
750 }, {
751 .name = "axp20x-usb-power-supply",
752 .num_resources = ARRAY_SIZE(axp803_usb_power_supply_resources),
753 .resources = axp803_usb_power_supply_resources,
754 .of_compatible = "x-powers,axp813-usb-power-supply",
744 }, 755 },
745 { .name = "axp20x-regulator" }, 756 { .name = "axp20x-regulator" },
746}; 757};
@@ -793,6 +804,11 @@ static const struct mfd_cell axp813_cells[] = {
793 .of_compatible = "x-powers,axp813-ac-power-supply", 804 .of_compatible = "x-powers,axp813-ac-power-supply",
794 .num_resources = ARRAY_SIZE(axp20x_ac_power_supply_resources), 805 .num_resources = ARRAY_SIZE(axp20x_ac_power_supply_resources),
795 .resources = axp20x_ac_power_supply_resources, 806 .resources = axp20x_ac_power_supply_resources,
807 }, {
808 .name = "axp20x-usb-power-supply",
809 .num_resources = ARRAY_SIZE(axp803_usb_power_supply_resources),
810 .resources = axp803_usb_power_supply_resources,
811 .of_compatible = "x-powers,axp813-usb-power-supply",
796 }, 812 },
797}; 813};
798 814
diff --git a/drivers/mfd/cros_ec.c b/drivers/mfd/cros_ec.c
index 6acfe036d522..bd2bcdd4718b 100644
--- a/drivers/mfd/cros_ec.c
+++ b/drivers/mfd/cros_ec.c
@@ -75,20 +75,49 @@ static irqreturn_t ec_irq_thread(int irq, void *data)
75 75
76static int cros_ec_sleep_event(struct cros_ec_device *ec_dev, u8 sleep_event) 76static int cros_ec_sleep_event(struct cros_ec_device *ec_dev, u8 sleep_event)
77{ 77{
78 int ret;
78 struct { 79 struct {
79 struct cros_ec_command msg; 80 struct cros_ec_command msg;
80 struct ec_params_host_sleep_event req; 81 union {
82 struct ec_params_host_sleep_event req0;
83 struct ec_params_host_sleep_event_v1 req1;
84 struct ec_response_host_sleep_event_v1 resp1;
85 } u;
81 } __packed buf; 86 } __packed buf;
82 87
83 memset(&buf, 0, sizeof(buf)); 88 memset(&buf, 0, sizeof(buf));
84 89
85 buf.req.sleep_event = sleep_event; 90 if (ec_dev->host_sleep_v1) {
91 buf.u.req1.sleep_event = sleep_event;
92 buf.u.req1.suspend_params.sleep_timeout_ms =
93 EC_HOST_SLEEP_TIMEOUT_DEFAULT;
94
95 buf.msg.outsize = sizeof(buf.u.req1);
96 if ((sleep_event == HOST_SLEEP_EVENT_S3_RESUME) ||
97 (sleep_event == HOST_SLEEP_EVENT_S0IX_RESUME))
98 buf.msg.insize = sizeof(buf.u.resp1);
99
100 buf.msg.version = 1;
101
102 } else {
103 buf.u.req0.sleep_event = sleep_event;
104 buf.msg.outsize = sizeof(buf.u.req0);
105 }
86 106
87 buf.msg.command = EC_CMD_HOST_SLEEP_EVENT; 107 buf.msg.command = EC_CMD_HOST_SLEEP_EVENT;
88 buf.msg.version = 0;
89 buf.msg.outsize = sizeof(buf.req);
90 108
91 return cros_ec_cmd_xfer(ec_dev, &buf.msg); 109 ret = cros_ec_cmd_xfer(ec_dev, &buf.msg);
110
111 /* For now, report failure to transition to S0ix with a warning. */
112 if (ret >= 0 && ec_dev->host_sleep_v1 &&
113 (sleep_event == HOST_SLEEP_EVENT_S0IX_RESUME))
114 WARN_ONCE(buf.u.resp1.resume_response.sleep_transitions &
115 EC_HOST_RESUME_SLEEP_TIMEOUT,
116 "EC detected sleep transition timeout. Total slp_s0 transitions: %d",
117 buf.u.resp1.resume_response.sleep_transitions &
118 EC_HOST_RESUME_SLEEP_TRANSITIONS_MASK);
119
120 return ret;
92} 121}
93 122
94int cros_ec_register(struct cros_ec_device *ec_dev) 123int cros_ec_register(struct cros_ec_device *ec_dev)
diff --git a/drivers/mfd/cros_ec_dev.c b/drivers/mfd/cros_ec_dev.c
index d275deaecb12..54a58df571b6 100644
--- a/drivers/mfd/cros_ec_dev.c
+++ b/drivers/mfd/cros_ec_dev.c
@@ -385,7 +385,8 @@ static const struct mfd_cell cros_ec_rtc_cells[] = {
385}; 385};
386 386
387static const struct mfd_cell cros_usbpd_charger_cells[] = { 387static const struct mfd_cell cros_usbpd_charger_cells[] = {
388 { .name = "cros-usbpd-charger" } 388 { .name = "cros-usbpd-charger" },
389 { .name = "cros-usbpd-logger" },
389}; 390};
390 391
391static const struct mfd_cell cros_ec_platform_cells[] = { 392static const struct mfd_cell cros_ec_platform_cells[] = {
@@ -418,6 +419,39 @@ static int ec_device_probe(struct platform_device *pdev)
418 device_initialize(&ec->class_dev); 419 device_initialize(&ec->class_dev);
419 cdev_init(&ec->cdev, &fops); 420 cdev_init(&ec->cdev, &fops);
420 421
422 /* Check whether this is actually a Fingerprint MCU rather than an EC */
423 if (cros_ec_check_features(ec, EC_FEATURE_FINGERPRINT)) {
424 dev_info(dev, "CrOS Fingerprint MCU detected.\n");
425 /*
426 * Help userspace differentiating ECs from FP MCU,
427 * regardless of the probing order.
428 */
429 ec_platform->ec_name = CROS_EC_DEV_FP_NAME;
430 }
431
432 /*
433 * Check whether this is actually an Integrated Sensor Hub (ISH)
434 * rather than an EC.
435 */
436 if (cros_ec_check_features(ec, EC_FEATURE_ISH)) {
437 dev_info(dev, "CrOS ISH MCU detected.\n");
438 /*
439 * Help userspace differentiating ECs from ISH MCU,
440 * regardless of the probing order.
441 */
442 ec_platform->ec_name = CROS_EC_DEV_ISH_NAME;
443 }
444
445 /* Check whether this is actually a Touchpad MCU rather than an EC */
446 if (cros_ec_check_features(ec, EC_FEATURE_TOUCHPAD)) {
447 dev_info(dev, "CrOS Touchpad MCU detected.\n");
448 /*
449 * Help userspace differentiating ECs from TP MCU,
450 * regardless of the probing order.
451 */
452 ec_platform->ec_name = CROS_EC_DEV_TP_NAME;
453 }
454
421 /* 455 /*
422 * Add the class device 456 * Add the class device
423 * Link to the character device for creating the /dev entry 457 * Link to the character device for creating the /dev entry
diff --git a/drivers/mfd/cs47l35-tables.c b/drivers/mfd/cs47l35-tables.c
index 604c9dd14df5..338b825127f1 100644
--- a/drivers/mfd/cs47l35-tables.c
+++ b/drivers/mfd/cs47l35-tables.c
@@ -178,6 +178,7 @@ static const struct reg_default cs47l35_reg_default[] = {
178 { 0x00000448, 0x0a83 }, /* R1096 (0x448) - eDRE Enable */ 178 { 0x00000448, 0x0a83 }, /* R1096 (0x448) - eDRE Enable */
179 { 0x0000044a, 0x0000 }, /* R1098 (0x44a) - eDRE Manual */ 179 { 0x0000044a, 0x0000 }, /* R1098 (0x44a) - eDRE Manual */
180 { 0x00000450, 0x0000 }, /* R1104 (0x450) - DAC AEC Control 1 */ 180 { 0x00000450, 0x0000 }, /* R1104 (0x450) - DAC AEC Control 1 */
181 { 0x00000451, 0x0000 }, /* R1105 (0x451) - DAC AEC Control 2 */
181 { 0x00000458, 0x0000 }, /* R1112 (0x458) - Noise Gate Control */ 182 { 0x00000458, 0x0000 }, /* R1112 (0x458) - Noise Gate Control */
182 { 0x00000490, 0x0069 }, /* R1168 (0x490) - PDM SPK1 CTRL 1 */ 183 { 0x00000490, 0x0069 }, /* R1168 (0x490) - PDM SPK1 CTRL 1 */
183 { 0x00000491, 0x0000 }, /* R1169 (0x491) - PDM SPK1 CTRL 2 */ 184 { 0x00000491, 0x0000 }, /* R1169 (0x491) - PDM SPK1 CTRL 2 */
@@ -970,6 +971,7 @@ static bool cs47l35_16bit_readable_register(struct device *dev,
970 case MADERA_EDRE_ENABLE: 971 case MADERA_EDRE_ENABLE:
971 case MADERA_EDRE_MANUAL: 972 case MADERA_EDRE_MANUAL:
972 case MADERA_DAC_AEC_CONTROL_1: 973 case MADERA_DAC_AEC_CONTROL_1:
974 case MADERA_DAC_AEC_CONTROL_2:
973 case MADERA_NOISE_GATE_CONTROL: 975 case MADERA_NOISE_GATE_CONTROL:
974 case MADERA_PDM_SPK1_CTRL_1: 976 case MADERA_PDM_SPK1_CTRL_1:
975 case MADERA_PDM_SPK1_CTRL_2: 977 case MADERA_PDM_SPK1_CTRL_2:
diff --git a/drivers/mfd/cs47l90-tables.c b/drivers/mfd/cs47l90-tables.c
index 77207d98f0cc..c040d3d7232a 100644
--- a/drivers/mfd/cs47l90-tables.c
+++ b/drivers/mfd/cs47l90-tables.c
@@ -263,6 +263,7 @@ static const struct reg_default cs47l90_reg_default[] = {
263 { 0x00000440, 0x003f }, /* R1088 (0x440) - DRE Enable */ 263 { 0x00000440, 0x003f }, /* R1088 (0x440) - DRE Enable */
264 { 0x00000448, 0x003f }, /* R1096 (0x448) - eDRE Enable */ 264 { 0x00000448, 0x003f }, /* R1096 (0x448) - eDRE Enable */
265 { 0x00000450, 0x0000 }, /* R1104 (0x450) - DAC AEC Control 1 */ 265 { 0x00000450, 0x0000 }, /* R1104 (0x450) - DAC AEC Control 1 */
266 { 0x00000451, 0x0000 }, /* R1104 (0x450) - DAC AEC Control 2 */
266 { 0x00000458, 0x0000 }, /* R1112 (0x458) - Noise Gate Control */ 267 { 0x00000458, 0x0000 }, /* R1112 (0x458) - Noise Gate Control */
267 { 0x00000490, 0x0069 }, /* R1168 (0x490) - PDM SPK1 CTRL 1 */ 268 { 0x00000490, 0x0069 }, /* R1168 (0x490) - PDM SPK1 CTRL 1 */
268 { 0x00000491, 0x0000 }, /* R1169 (0x491) - PDM SPK1 CTRL 2 */ 269 { 0x00000491, 0x0000 }, /* R1169 (0x491) - PDM SPK1 CTRL 2 */
@@ -1692,6 +1693,7 @@ static bool cs47l90_16bit_readable_register(struct device *dev,
1692 case MADERA_DRE_ENABLE: 1693 case MADERA_DRE_ENABLE:
1693 case MADERA_EDRE_ENABLE: 1694 case MADERA_EDRE_ENABLE:
1694 case MADERA_DAC_AEC_CONTROL_1: 1695 case MADERA_DAC_AEC_CONTROL_1:
1696 case MADERA_DAC_AEC_CONTROL_2:
1695 case MADERA_NOISE_GATE_CONTROL: 1697 case MADERA_NOISE_GATE_CONTROL:
1696 case MADERA_PDM_SPK1_CTRL_1: 1698 case MADERA_PDM_SPK1_CTRL_1:
1697 case MADERA_PDM_SPK1_CTRL_2: 1699 case MADERA_PDM_SPK1_CTRL_2:
diff --git a/drivers/mfd/da9063-core.c b/drivers/mfd/da9063-core.c
index 6e4ce49b4405..b125f90dd375 100644
--- a/drivers/mfd/da9063-core.c
+++ b/drivers/mfd/da9063-core.c
@@ -1,5 +1,6 @@
1// SPDX-License-Identifier: GPL-2.0+
1/* 2/*
2 * da9063-core.c: Device access for Dialog DA9063 modules 3 * Device access for Dialog DA9063 modules
3 * 4 *
4 * Copyright 2012 Dialog Semiconductors Ltd. 5 * Copyright 2012 Dialog Semiconductors Ltd.
5 * Copyright 2013 Philipp Zabel, Pengutronix 6 * Copyright 2013 Philipp Zabel, Pengutronix
@@ -7,11 +8,6 @@
7 * Author: Krystian Garbaciak, Dialog Semiconductor 8 * Author: Krystian Garbaciak, Dialog Semiconductor
8 * Author: Michal Hajduk, Dialog Semiconductor 9 * Author: Michal Hajduk, Dialog Semiconductor
9 * 10 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 *
15 */ 11 */
16 12
17#include <linux/kernel.h> 13#include <linux/kernel.h>
@@ -26,7 +22,6 @@
26#include <linux/regmap.h> 22#include <linux/regmap.h>
27 23
28#include <linux/mfd/da9063/core.h> 24#include <linux/mfd/da9063/core.h>
29#include <linux/mfd/da9063/pdata.h>
30#include <linux/mfd/da9063/registers.h> 25#include <linux/mfd/da9063/registers.h>
31 26
32#include <linux/proc_fs.h> 27#include <linux/proc_fs.h>
@@ -165,7 +160,6 @@ static int da9063_clear_fault_log(struct da9063 *da9063)
165 160
166int da9063_device_init(struct da9063 *da9063, unsigned int irq) 161int da9063_device_init(struct da9063 *da9063, unsigned int irq)
167{ 162{
168 struct da9063_pdata *pdata = da9063->dev->platform_data;
169 int model, variant_id, variant_code; 163 int model, variant_id, variant_code;
170 int ret; 164 int ret;
171 165
@@ -173,24 +167,10 @@ int da9063_device_init(struct da9063 *da9063, unsigned int irq)
173 if (ret < 0) 167 if (ret < 0)
174 dev_err(da9063->dev, "Cannot clear fault log\n"); 168 dev_err(da9063->dev, "Cannot clear fault log\n");
175 169
176 if (pdata) { 170 da9063->flags = 0;
177 da9063->flags = pdata->flags; 171 da9063->irq_base = -1;
178 da9063->irq_base = pdata->irq_base;
179 } else {
180 da9063->flags = 0;
181 da9063->irq_base = -1;
182 }
183 da9063->chip_irq = irq; 172 da9063->chip_irq = irq;
184 173
185 if (pdata && pdata->init != NULL) {
186 ret = pdata->init(da9063);
187 if (ret != 0) {
188 dev_err(da9063->dev,
189 "Platform initialization failed.\n");
190 return ret;
191 }
192 }
193
194 ret = regmap_read(da9063->regmap, DA9063_REG_CHIP_ID, &model); 174 ret = regmap_read(da9063->regmap, DA9063_REG_CHIP_ID, &model);
195 if (ret < 0) { 175 if (ret < 0) {
196 dev_err(da9063->dev, "Cannot read chip model id.\n"); 176 dev_err(da9063->dev, "Cannot read chip model id.\n");
diff --git a/drivers/mfd/da9063-i2c.c b/drivers/mfd/da9063-i2c.c
index 50a24b1921d0..455de74c0dd2 100644
--- a/drivers/mfd/da9063-i2c.c
+++ b/drivers/mfd/da9063-i2c.c
@@ -1,15 +1,10 @@
1/* da9063-i2c.c: Interrupt support for Dialog DA9063 1// SPDX-License-Identifier: GPL-2.0+
2/* I2C support for Dialog DA9063
2 * 3 *
3 * Copyright 2012 Dialog Semiconductor Ltd. 4 * Copyright 2012 Dialog Semiconductor Ltd.
4 * Copyright 2013 Philipp Zabel, Pengutronix 5 * Copyright 2013 Philipp Zabel, Pengutronix
5 * 6 *
6 * Author: Krystian Garbaciak, Dialog Semiconductor 7 * Author: Krystian Garbaciak, Dialog Semiconductor
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 *
13 */ 8 */
14 9
15#include <linux/kernel.h> 10#include <linux/kernel.h>
@@ -22,7 +17,6 @@
22 17
23#include <linux/mfd/core.h> 18#include <linux/mfd/core.h>
24#include <linux/mfd/da9063/core.h> 19#include <linux/mfd/da9063/core.h>
25#include <linux/mfd/da9063/pdata.h>
26#include <linux/mfd/da9063/registers.h> 20#include <linux/mfd/da9063/registers.h>
27 21
28#include <linux/of.h> 22#include <linux/of.h>
diff --git a/drivers/mfd/da9063-irq.c b/drivers/mfd/da9063-irq.c
index ecc0c8ce6c58..e2bbedf58e68 100644
--- a/drivers/mfd/da9063-irq.c
+++ b/drivers/mfd/da9063-irq.c
@@ -1,15 +1,10 @@
1/* da9063-irq.c: Interrupts support for Dialog DA9063 1// SPDX-License-Identifier: GPL-2.0+
2/* Interrupt support for Dialog DA9063
2 * 3 *
3 * Copyright 2012 Dialog Semiconductor Ltd. 4 * Copyright 2012 Dialog Semiconductor Ltd.
4 * Copyright 2013 Philipp Zabel, Pengutronix 5 * Copyright 2013 Philipp Zabel, Pengutronix
5 * 6 *
6 * Author: Michal Hajduk, Dialog Semiconductor 7 * Author: Michal Hajduk, Dialog Semiconductor
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 *
13 */ 8 */
14 9
15#include <linux/kernel.h> 10#include <linux/kernel.h>
@@ -19,7 +14,6 @@
19#include <linux/interrupt.h> 14#include <linux/interrupt.h>
20#include <linux/regmap.h> 15#include <linux/regmap.h>
21#include <linux/mfd/da9063/core.h> 16#include <linux/mfd/da9063/core.h>
22#include <linux/mfd/da9063/pdata.h>
23 17
24#define DA9063_REG_EVENT_A_OFFSET 0 18#define DA9063_REG_EVENT_A_OFFSET 0
25#define DA9063_REG_EVENT_B_OFFSET 1 19#define DA9063_REG_EVENT_B_OFFSET 1
diff --git a/drivers/mfd/intel-lpss-pci.c b/drivers/mfd/intel-lpss-pci.c
index cba2eb166650..6b111be944d9 100644
--- a/drivers/mfd/intel-lpss-pci.c
+++ b/drivers/mfd/intel-lpss-pci.c
@@ -129,6 +129,19 @@ static const struct intel_lpss_platform_info cnl_i2c_info = {
129}; 129};
130 130
131static const struct pci_device_id intel_lpss_pci_ids[] = { 131static const struct pci_device_id intel_lpss_pci_ids[] = {
132 /* CML */
133 { PCI_VDEVICE(INTEL, 0x02a8), (kernel_ulong_t)&spt_uart_info },
134 { PCI_VDEVICE(INTEL, 0x02a9), (kernel_ulong_t)&spt_uart_info },
135 { PCI_VDEVICE(INTEL, 0x02aa), (kernel_ulong_t)&spt_info },
136 { PCI_VDEVICE(INTEL, 0x02ab), (kernel_ulong_t)&spt_info },
137 { PCI_VDEVICE(INTEL, 0x02c5), (kernel_ulong_t)&cnl_i2c_info },
138 { PCI_VDEVICE(INTEL, 0x02c6), (kernel_ulong_t)&cnl_i2c_info },
139 { PCI_VDEVICE(INTEL, 0x02c7), (kernel_ulong_t)&spt_uart_info },
140 { PCI_VDEVICE(INTEL, 0x02e8), (kernel_ulong_t)&cnl_i2c_info },
141 { PCI_VDEVICE(INTEL, 0x02e9), (kernel_ulong_t)&cnl_i2c_info },
142 { PCI_VDEVICE(INTEL, 0x02ea), (kernel_ulong_t)&cnl_i2c_info },
143 { PCI_VDEVICE(INTEL, 0x02eb), (kernel_ulong_t)&cnl_i2c_info },
144 { PCI_VDEVICE(INTEL, 0x02fb), (kernel_ulong_t)&spt_info },
132 /* BXT A-Step */ 145 /* BXT A-Step */
133 { PCI_VDEVICE(INTEL, 0x0aac), (kernel_ulong_t)&bxt_i2c_info }, 146 { PCI_VDEVICE(INTEL, 0x0aac), (kernel_ulong_t)&bxt_i2c_info },
134 { PCI_VDEVICE(INTEL, 0x0aae), (kernel_ulong_t)&bxt_i2c_info }, 147 { PCI_VDEVICE(INTEL, 0x0aae), (kernel_ulong_t)&bxt_i2c_info },
diff --git a/drivers/mfd/intel-lpss.c b/drivers/mfd/intel-lpss.c
index 45221e092ecf..7e425ff53491 100644
--- a/drivers/mfd/intel-lpss.c
+++ b/drivers/mfd/intel-lpss.c
@@ -273,6 +273,9 @@ static void intel_lpss_init_dev(const struct intel_lpss *lpss)
273{ 273{
274 u32 value = LPSS_PRIV_SSP_REG_DIS_DMA_FIN; 274 u32 value = LPSS_PRIV_SSP_REG_DIS_DMA_FIN;
275 275
276 /* Set the device in reset state */
277 writel(0, lpss->priv + LPSS_PRIV_RESETS);
278
276 intel_lpss_deassert_reset(lpss); 279 intel_lpss_deassert_reset(lpss);
277 280
278 intel_lpss_set_remap_addr(lpss); 281 intel_lpss_set_remap_addr(lpss);
diff --git a/drivers/mfd/intel_quark_i2c_gpio.c b/drivers/mfd/intel_quark_i2c_gpio.c
index 5bddb84cfc1f..11adbf77960d 100644
--- a/drivers/mfd/intel_quark_i2c_gpio.c
+++ b/drivers/mfd/intel_quark_i2c_gpio.c
@@ -74,16 +74,6 @@ static const struct dmi_system_id dmi_platform_info[] = {
74 { 74 {
75 .matches = { 75 .matches = {
76 DMI_EXACT_MATCH(DMI_BOARD_NAME, "SIMATIC IOT2000"), 76 DMI_EXACT_MATCH(DMI_BOARD_NAME, "SIMATIC IOT2000"),
77 DMI_EXACT_MATCH(DMI_BOARD_ASSET_TAG,
78 "6ES7647-0AA00-0YA2"),
79 },
80 .driver_data = (void *)400000,
81 },
82 {
83 .matches = {
84 DMI_EXACT_MATCH(DMI_BOARD_NAME, "SIMATIC IOT2000"),
85 DMI_EXACT_MATCH(DMI_BOARD_ASSET_TAG,
86 "6ES7647-0AA00-1YA2"),
87 }, 77 },
88 .driver_data = (void *)400000, 78 .driver_data = (void *)400000,
89 }, 79 },
diff --git a/drivers/mfd/intel_soc_pmic_chtwc.c b/drivers/mfd/intel_soc_pmic_chtwc.c
index 64a3aece9c5e..be84bb2aa837 100644
--- a/drivers/mfd/intel_soc_pmic_chtwc.c
+++ b/drivers/mfd/intel_soc_pmic_chtwc.c
@@ -60,6 +60,7 @@ static struct mfd_cell cht_wc_dev[] = {
60 .resources = cht_wc_ext_charger_resources, 60 .resources = cht_wc_ext_charger_resources,
61 }, 61 },
62 { .name = "cht_wcove_region", }, 62 { .name = "cht_wcove_region", },
63 { .name = "cht_wcove_leds", },
63}; 64};
64 65
65/* 66/*
diff --git a/drivers/mfd/max77620.c b/drivers/mfd/max77620.c
index d8ddd1a6f304..436361ce3737 100644
--- a/drivers/mfd/max77620.c
+++ b/drivers/mfd/max77620.c
@@ -37,6 +37,8 @@
37#include <linux/regmap.h> 37#include <linux/regmap.h>
38#include <linux/slab.h> 38#include <linux/slab.h>
39 39
40static struct max77620_chip *max77620_scratch;
41
40static const struct resource gpio_resources[] = { 42static const struct resource gpio_resources[] = {
41 DEFINE_RES_IRQ(MAX77620_IRQ_TOP_GPIO), 43 DEFINE_RES_IRQ(MAX77620_IRQ_TOP_GPIO),
42}; 44};
@@ -111,6 +113,26 @@ static const struct mfd_cell max20024_children[] = {
111 }, 113 },
112}; 114};
113 115
116static const struct mfd_cell max77663_children[] = {
117 { .name = "max77620-pinctrl", },
118 { .name = "max77620-clock", },
119 { .name = "max77663-pmic", },
120 { .name = "max77620-watchdog", },
121 {
122 .name = "max77620-gpio",
123 .resources = gpio_resources,
124 .num_resources = ARRAY_SIZE(gpio_resources),
125 }, {
126 .name = "max77620-rtc",
127 .resources = rtc_resources,
128 .num_resources = ARRAY_SIZE(rtc_resources),
129 }, {
130 .name = "max77663-power",
131 .resources = power_resources,
132 .num_resources = ARRAY_SIZE(power_resources),
133 },
134};
135
114static const struct regmap_range max77620_readable_ranges[] = { 136static const struct regmap_range max77620_readable_ranges[] = {
115 regmap_reg_range(MAX77620_REG_CNFGGLBL1, MAX77620_REG_DVSSD4), 137 regmap_reg_range(MAX77620_REG_CNFGGLBL1, MAX77620_REG_DVSSD4),
116}; 138};
@@ -171,6 +193,35 @@ static const struct regmap_config max20024_regmap_config = {
171 .volatile_table = &max77620_volatile_table, 193 .volatile_table = &max77620_volatile_table,
172}; 194};
173 195
196static const struct regmap_range max77663_readable_ranges[] = {
197 regmap_reg_range(MAX77620_REG_CNFGGLBL1, MAX77620_REG_CID5),
198};
199
200static const struct regmap_access_table max77663_readable_table = {
201 .yes_ranges = max77663_readable_ranges,
202 .n_yes_ranges = ARRAY_SIZE(max77663_readable_ranges),
203};
204
205static const struct regmap_range max77663_writable_ranges[] = {
206 regmap_reg_range(MAX77620_REG_CNFGGLBL1, MAX77620_REG_CID5),
207};
208
209static const struct regmap_access_table max77663_writable_table = {
210 .yes_ranges = max77663_writable_ranges,
211 .n_yes_ranges = ARRAY_SIZE(max77663_writable_ranges),
212};
213
214static const struct regmap_config max77663_regmap_config = {
215 .name = "power-slave",
216 .reg_bits = 8,
217 .val_bits = 8,
218 .max_register = MAX77620_REG_CID5 + 1,
219 .cache_type = REGCACHE_RBTREE,
220 .rd_table = &max77663_readable_table,
221 .wr_table = &max77663_writable_table,
222 .volatile_table = &max77620_volatile_table,
223};
224
174/* 225/*
175 * MAX77620 and MAX20024 has the following steps of the interrupt handling 226 * MAX77620 and MAX20024 has the following steps of the interrupt handling
176 * for TOP interrupts: 227 * for TOP interrupts:
@@ -240,6 +291,9 @@ static int max77620_get_fps_period_reg_value(struct max77620_chip *chip,
240 case MAX77620: 291 case MAX77620:
241 fps_min_period = MAX77620_FPS_PERIOD_MIN_US; 292 fps_min_period = MAX77620_FPS_PERIOD_MIN_US;
242 break; 293 break;
294 case MAX77663:
295 fps_min_period = MAX20024_FPS_PERIOD_MIN_US;
296 break;
243 default: 297 default:
244 return -EINVAL; 298 return -EINVAL;
245 } 299 }
@@ -274,6 +328,9 @@ static int max77620_config_fps(struct max77620_chip *chip,
274 case MAX77620: 328 case MAX77620:
275 fps_max_period = MAX77620_FPS_PERIOD_MAX_US; 329 fps_max_period = MAX77620_FPS_PERIOD_MAX_US;
276 break; 330 break;
331 case MAX77663:
332 fps_max_period = MAX20024_FPS_PERIOD_MAX_US;
333 break;
277 default: 334 default:
278 return -EINVAL; 335 return -EINVAL;
279 } 336 }
@@ -375,6 +432,9 @@ static int max77620_initialise_fps(struct max77620_chip *chip)
375 } 432 }
376 433
377skip_fps: 434skip_fps:
435 if (chip->chip_id == MAX77663)
436 return 0;
437
378 /* Enable wake on EN0 pin */ 438 /* Enable wake on EN0 pin */
379 ret = regmap_update_bits(chip->rmap, MAX77620_REG_ONOFFCNFG2, 439 ret = regmap_update_bits(chip->rmap, MAX77620_REG_ONOFFCNFG2,
380 MAX77620_ONOFFCNFG2_WK_EN0, 440 MAX77620_ONOFFCNFG2_WK_EN0,
@@ -423,6 +483,15 @@ static int max77620_read_es_version(struct max77620_chip *chip)
423 return ret; 483 return ret;
424} 484}
425 485
486static void max77620_pm_power_off(void)
487{
488 struct max77620_chip *chip = max77620_scratch;
489
490 regmap_update_bits(chip->rmap, MAX77620_REG_ONOFFCNFG1,
491 MAX77620_ONOFFCNFG1_SFT_RST,
492 MAX77620_ONOFFCNFG1_SFT_RST);
493}
494
426static int max77620_probe(struct i2c_client *client, 495static int max77620_probe(struct i2c_client *client,
427 const struct i2c_device_id *id) 496 const struct i2c_device_id *id)
428{ 497{
@@ -430,6 +499,7 @@ static int max77620_probe(struct i2c_client *client,
430 struct max77620_chip *chip; 499 struct max77620_chip *chip;
431 const struct mfd_cell *mfd_cells; 500 const struct mfd_cell *mfd_cells;
432 int n_mfd_cells; 501 int n_mfd_cells;
502 bool pm_off;
433 int ret; 503 int ret;
434 504
435 chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL); 505 chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
@@ -453,6 +523,11 @@ static int max77620_probe(struct i2c_client *client,
453 n_mfd_cells = ARRAY_SIZE(max20024_children); 523 n_mfd_cells = ARRAY_SIZE(max20024_children);
454 rmap_config = &max20024_regmap_config; 524 rmap_config = &max20024_regmap_config;
455 break; 525 break;
526 case MAX77663:
527 mfd_cells = max77663_children;
528 n_mfd_cells = ARRAY_SIZE(max77663_children);
529 rmap_config = &max77663_regmap_config;
530 break;
456 default: 531 default:
457 dev_err(chip->dev, "ChipID is invalid %d\n", chip->chip_id); 532 dev_err(chip->dev, "ChipID is invalid %d\n", chip->chip_id);
458 return -EINVAL; 533 return -EINVAL;
@@ -491,6 +566,12 @@ static int max77620_probe(struct i2c_client *client,
491 return ret; 566 return ret;
492 } 567 }
493 568
569 pm_off = of_device_is_system_power_controller(client->dev.of_node);
570 if (pm_off && !pm_power_off) {
571 max77620_scratch = chip;
572 pm_power_off = max77620_pm_power_off;
573 }
574
494 return 0; 575 return 0;
495} 576}
496 577
@@ -546,6 +627,9 @@ static int max77620_i2c_suspend(struct device *dev)
546 return ret; 627 return ret;
547 } 628 }
548 629
630 if (chip->chip_id == MAX77663)
631 goto out;
632
549 /* Disable WK_EN0 */ 633 /* Disable WK_EN0 */
550 ret = regmap_update_bits(chip->rmap, MAX77620_REG_ONOFFCNFG2, 634 ret = regmap_update_bits(chip->rmap, MAX77620_REG_ONOFFCNFG2,
551 MAX77620_ONOFFCNFG2_WK_EN0, 0); 635 MAX77620_ONOFFCNFG2_WK_EN0, 0);
@@ -581,7 +665,7 @@ static int max77620_i2c_resume(struct device *dev)
581 * For MAX20024: No need to configure WKEN0 on resume as 665 * For MAX20024: No need to configure WKEN0 on resume as
582 * it is configured on Init. 666 * it is configured on Init.
583 */ 667 */
584 if (chip->chip_id == MAX20024) 668 if (chip->chip_id == MAX20024 || chip->chip_id == MAX77663)
585 goto out; 669 goto out;
586 670
587 /* Enable WK_EN0 */ 671 /* Enable WK_EN0 */
@@ -603,6 +687,7 @@ out:
603static const struct i2c_device_id max77620_id[] = { 687static const struct i2c_device_id max77620_id[] = {
604 {"max77620", MAX77620}, 688 {"max77620", MAX77620},
605 {"max20024", MAX20024}, 689 {"max20024", MAX20024},
690 {"max77663", MAX77663},
606 {}, 691 {},
607}; 692};
608 693
diff --git a/drivers/mfd/max77650.c b/drivers/mfd/max77650.c
new file mode 100644
index 000000000000..60e07aca6ae5
--- /dev/null
+++ b/drivers/mfd/max77650.c
@@ -0,0 +1,232 @@
1// SPDX-License-Identifier: GPL-2.0
2//
3// Copyright (C) 2018 BayLibre SAS
4// Author: Bartosz Golaszewski <bgolaszewski@baylibre.com>
5//
6// Core MFD driver for MAXIM 77650/77651 charger/power-supply.
7// Programming manual: https://pdfserv.maximintegrated.com/en/an/AN6428.pdf
8
9#include <linux/i2c.h>
10#include <linux/interrupt.h>
11#include <linux/irq.h>
12#include <linux/mfd/core.h>
13#include <linux/mfd/max77650.h>
14#include <linux/module.h>
15#include <linux/of.h>
16#include <linux/regmap.h>
17
18#define MAX77650_INT_GPI_F_MSK BIT(0)
19#define MAX77650_INT_GPI_R_MSK BIT(1)
20#define MAX77650_INT_GPI_MSK \
21 (MAX77650_INT_GPI_F_MSK | MAX77650_INT_GPI_R_MSK)
22#define MAX77650_INT_nEN_F_MSK BIT(2)
23#define MAX77650_INT_nEN_R_MSK BIT(3)
24#define MAX77650_INT_TJAL1_R_MSK BIT(4)
25#define MAX77650_INT_TJAL2_R_MSK BIT(5)
26#define MAX77650_INT_DOD_R_MSK BIT(6)
27
28#define MAX77650_INT_THM_MSK BIT(0)
29#define MAX77650_INT_CHG_MSK BIT(1)
30#define MAX77650_INT_CHGIN_MSK BIT(2)
31#define MAX77650_INT_TJ_REG_MSK BIT(3)
32#define MAX77650_INT_CHGIN_CTRL_MSK BIT(4)
33#define MAX77650_INT_SYS_CTRL_MSK BIT(5)
34#define MAX77650_INT_SYS_CNFG_MSK BIT(6)
35
36#define MAX77650_INT_GLBL_OFFSET 0
37#define MAX77650_INT_CHG_OFFSET 1
38
39#define MAX77650_SBIA_LPM_MASK BIT(5)
40#define MAX77650_SBIA_LPM_DISABLED 0x00
41
42enum {
43 MAX77650_INT_GPI,
44 MAX77650_INT_nEN_F,
45 MAX77650_INT_nEN_R,
46 MAX77650_INT_TJAL1_R,
47 MAX77650_INT_TJAL2_R,
48 MAX77650_INT_DOD_R,
49 MAX77650_INT_THM,
50 MAX77650_INT_CHG,
51 MAX77650_INT_CHGIN,
52 MAX77650_INT_TJ_REG,
53 MAX77650_INT_CHGIN_CTRL,
54 MAX77650_INT_SYS_CTRL,
55 MAX77650_INT_SYS_CNFG,
56};
57
58static const struct resource max77650_charger_resources[] = {
59 DEFINE_RES_IRQ_NAMED(MAX77650_INT_CHG, "CHG"),
60 DEFINE_RES_IRQ_NAMED(MAX77650_INT_CHGIN, "CHGIN"),
61};
62
63static const struct resource max77650_gpio_resources[] = {
64 DEFINE_RES_IRQ_NAMED(MAX77650_INT_GPI, "GPI"),
65};
66
67static const struct resource max77650_onkey_resources[] = {
68 DEFINE_RES_IRQ_NAMED(MAX77650_INT_nEN_F, "nEN_F"),
69 DEFINE_RES_IRQ_NAMED(MAX77650_INT_nEN_R, "nEN_R"),
70};
71
72static const struct mfd_cell max77650_cells[] = {
73 {
74 .name = "max77650-regulator",
75 .of_compatible = "maxim,max77650-regulator",
76 }, {
77 .name = "max77650-charger",
78 .of_compatible = "maxim,max77650-charger",
79 .resources = max77650_charger_resources,
80 .num_resources = ARRAY_SIZE(max77650_charger_resources),
81 }, {
82 .name = "max77650-gpio",
83 .of_compatible = "maxim,max77650-gpio",
84 .resources = max77650_gpio_resources,
85 .num_resources = ARRAY_SIZE(max77650_gpio_resources),
86 }, {
87 .name = "max77650-led",
88 .of_compatible = "maxim,max77650-led",
89 }, {
90 .name = "max77650-onkey",
91 .of_compatible = "maxim,max77650-onkey",
92 .resources = max77650_onkey_resources,
93 .num_resources = ARRAY_SIZE(max77650_onkey_resources),
94 },
95};
96
97static const struct regmap_irq max77650_irqs[] = {
98 [MAX77650_INT_GPI] = {
99 .reg_offset = MAX77650_INT_GLBL_OFFSET,
100 .mask = MAX77650_INT_GPI_MSK,
101 .type = {
102 .type_falling_val = MAX77650_INT_GPI_F_MSK,
103 .type_rising_val = MAX77650_INT_GPI_R_MSK,
104 .types_supported = IRQ_TYPE_EDGE_BOTH,
105 },
106 },
107 REGMAP_IRQ_REG(MAX77650_INT_nEN_F,
108 MAX77650_INT_GLBL_OFFSET, MAX77650_INT_nEN_F_MSK),
109 REGMAP_IRQ_REG(MAX77650_INT_nEN_R,
110 MAX77650_INT_GLBL_OFFSET, MAX77650_INT_nEN_R_MSK),
111 REGMAP_IRQ_REG(MAX77650_INT_TJAL1_R,
112 MAX77650_INT_GLBL_OFFSET, MAX77650_INT_TJAL1_R_MSK),
113 REGMAP_IRQ_REG(MAX77650_INT_TJAL2_R,
114 MAX77650_INT_GLBL_OFFSET, MAX77650_INT_TJAL2_R_MSK),
115 REGMAP_IRQ_REG(MAX77650_INT_DOD_R,
116 MAX77650_INT_GLBL_OFFSET, MAX77650_INT_DOD_R_MSK),
117 REGMAP_IRQ_REG(MAX77650_INT_THM,
118 MAX77650_INT_CHG_OFFSET, MAX77650_INT_THM_MSK),
119 REGMAP_IRQ_REG(MAX77650_INT_CHG,
120 MAX77650_INT_CHG_OFFSET, MAX77650_INT_CHG_MSK),
121 REGMAP_IRQ_REG(MAX77650_INT_CHGIN,
122 MAX77650_INT_CHG_OFFSET, MAX77650_INT_CHGIN_MSK),
123 REGMAP_IRQ_REG(MAX77650_INT_TJ_REG,
124 MAX77650_INT_CHG_OFFSET, MAX77650_INT_TJ_REG_MSK),
125 REGMAP_IRQ_REG(MAX77650_INT_CHGIN_CTRL,
126 MAX77650_INT_CHG_OFFSET, MAX77650_INT_CHGIN_CTRL_MSK),
127 REGMAP_IRQ_REG(MAX77650_INT_SYS_CTRL,
128 MAX77650_INT_CHG_OFFSET, MAX77650_INT_SYS_CTRL_MSK),
129 REGMAP_IRQ_REG(MAX77650_INT_SYS_CNFG,
130 MAX77650_INT_CHG_OFFSET, MAX77650_INT_SYS_CNFG_MSK),
131};
132
133static const struct regmap_irq_chip max77650_irq_chip = {
134 .name = "max77650-irq",
135 .irqs = max77650_irqs,
136 .num_irqs = ARRAY_SIZE(max77650_irqs),
137 .num_regs = 2,
138 .status_base = MAX77650_REG_INT_GLBL,
139 .mask_base = MAX77650_REG_INTM_GLBL,
140 .type_in_mask = true,
141 .type_invert = true,
142 .init_ack_masked = true,
143 .clear_on_unmask = true,
144};
145
146static const struct regmap_config max77650_regmap_config = {
147 .name = "max77650",
148 .reg_bits = 8,
149 .val_bits = 8,
150};
151
152static int max77650_i2c_probe(struct i2c_client *i2c)
153{
154 struct regmap_irq_chip_data *irq_data;
155 struct device *dev = &i2c->dev;
156 struct irq_domain *domain;
157 struct regmap *map;
158 unsigned int val;
159 int rv, id;
160
161 map = devm_regmap_init_i2c(i2c, &max77650_regmap_config);
162 if (IS_ERR(map)) {
163 dev_err(dev, "Unable to initialise I2C Regmap\n");
164 return PTR_ERR(map);
165 }
166
167 rv = regmap_read(map, MAX77650_REG_CID, &val);
168 if (rv) {
169 dev_err(dev, "Unable to read Chip ID\n");
170 return rv;
171 }
172
173 id = MAX77650_CID_BITS(val);
174 switch (id) {
175 case MAX77650_CID_77650A:
176 case MAX77650_CID_77650C:
177 case MAX77650_CID_77651A:
178 case MAX77650_CID_77651B:
179 break;
180 default:
181 dev_err(dev, "Chip not supported - ID: 0x%02x\n", id);
182 return -ENODEV;
183 }
184
185 /*
186 * This IC has a low-power mode which reduces the quiescent current
187 * consumption to ~5.6uA but is only suitable for systems consuming
188 * less than ~2mA. Since this is not likely the case even on
189 * linux-based wearables - keep the chip in normal power mode.
190 */
191 rv = regmap_update_bits(map,
192 MAX77650_REG_CNFG_GLBL,
193 MAX77650_SBIA_LPM_MASK,
194 MAX77650_SBIA_LPM_DISABLED);
195 if (rv) {
196 dev_err(dev, "Unable to change the power mode\n");
197 return rv;
198 }
199
200 rv = devm_regmap_add_irq_chip(dev, map, i2c->irq,
201 IRQF_ONESHOT | IRQF_SHARED, 0,
202 &max77650_irq_chip, &irq_data);
203 if (rv) {
204 dev_err(dev, "Unable to add Regmap IRQ chip\n");
205 return rv;
206 }
207
208 domain = regmap_irq_get_domain(irq_data);
209
210 return devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE,
211 max77650_cells, ARRAY_SIZE(max77650_cells),
212 NULL, 0, domain);
213}
214
215static const struct of_device_id max77650_of_match[] = {
216 { .compatible = "maxim,max77650" },
217 { }
218};
219MODULE_DEVICE_TABLE(of, max77650_of_match);
220
221static struct i2c_driver max77650_i2c_driver = {
222 .driver = {
223 .name = "max77650",
224 .of_match_table = of_match_ptr(max77650_of_match),
225 },
226 .probe_new = max77650_i2c_probe,
227};
228module_i2c_driver(max77650_i2c_driver);
229
230MODULE_DESCRIPTION("MAXIM 77650/77651 multi-function core driver");
231MODULE_AUTHOR("Bartosz Golaszewski <bgolaszewski@baylibre.com>");
232MODULE_LICENSE("GPL v2");
diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c
index 94e3f32ce935..1ade4c8cc91f 100644
--- a/drivers/mfd/mfd-core.c
+++ b/drivers/mfd/mfd-core.c
@@ -269,6 +269,19 @@ fail_alloc:
269 return ret; 269 return ret;
270} 270}
271 271
272/**
273 * mfd_add_devices - register child devices
274 *
275 * @parent: Pointer to parent device.
276 * @id: Can be PLATFORM_DEVID_AUTO to let the Platform API take care
277 * of device numbering, or will be added to a device's cell_id.
278 * @cells: Array of (struct mfd_cell)s describing child devices.
279 * @n_devs: Number of child devices to register.
280 * @mem_base: Parent register range resource for child devices.
281 * @irq_base: Base of the range of virtual interrupt numbers allocated for
282 * this MFD device. Unused if @domain is specified.
283 * @domain: Interrupt domain to create mappings for hardware interrupts.
284 */
272int mfd_add_devices(struct device *parent, int id, 285int mfd_add_devices(struct device *parent, int id,
273 const struct mfd_cell *cells, int n_devs, 286 const struct mfd_cell *cells, int n_devs,
274 struct resource *mem_base, 287 struct resource *mem_base,
diff --git a/drivers/mfd/rk808.c b/drivers/mfd/rk808.c
index 216fbf6adec9..94377782d208 100644
--- a/drivers/mfd/rk808.c
+++ b/drivers/mfd/rk808.c
@@ -568,14 +568,6 @@ static int rk808_remove(struct i2c_client *client)
568 return 0; 568 return 0;
569} 569}
570 570
571static const struct i2c_device_id rk808_ids[] = {
572 { "rk805" },
573 { "rk808" },
574 { "rk818" },
575 { },
576};
577MODULE_DEVICE_TABLE(i2c, rk808_ids);
578
579static struct i2c_driver rk808_i2c_driver = { 571static struct i2c_driver rk808_i2c_driver = {
580 .driver = { 572 .driver = {
581 .name = "rk808", 573 .name = "rk808",
@@ -583,7 +575,6 @@ static struct i2c_driver rk808_i2c_driver = {
583 }, 575 },
584 .probe = rk808_probe, 576 .probe = rk808_probe,
585 .remove = rk808_remove, 577 .remove = rk808_remove,
586 .id_table = rk808_ids,
587}; 578};
588 579
589module_i2c_driver(rk808_i2c_driver); 580module_i2c_driver(rk808_i2c_driver);
diff --git a/drivers/mfd/sec-core.c b/drivers/mfd/sec-core.c
index 521319086c81..95473ff9bb4b 100644
--- a/drivers/mfd/sec-core.c
+++ b/drivers/mfd/sec-core.c
@@ -28,45 +28,33 @@
28#include <linux/regmap.h> 28#include <linux/regmap.h>
29 29
30static const struct mfd_cell s5m8751_devs[] = { 30static const struct mfd_cell s5m8751_devs[] = {
31 { 31 { .name = "s5m8751-pmic", },
32 .name = "s5m8751-pmic", 32 { .name = "s5m-charger", },
33 }, { 33 { .name = "s5m8751-codec", },
34 .name = "s5m-charger",
35 }, {
36 .name = "s5m8751-codec",
37 },
38}; 34};
39 35
40static const struct mfd_cell s5m8763_devs[] = { 36static const struct mfd_cell s5m8763_devs[] = {
41 { 37 { .name = "s5m8763-pmic", },
42 .name = "s5m8763-pmic", 38 { .name = "s5m-rtc", },
43 }, { 39 { .name = "s5m-charger", },
44 .name = "s5m-rtc",
45 }, {
46 .name = "s5m-charger",
47 },
48}; 40};
49 41
50static const struct mfd_cell s5m8767_devs[] = { 42static const struct mfd_cell s5m8767_devs[] = {
43 { .name = "s5m8767-pmic", },
44 { .name = "s5m-rtc", },
51 { 45 {
52 .name = "s5m8767-pmic",
53 }, {
54 .name = "s5m-rtc",
55 }, {
56 .name = "s5m8767-clk", 46 .name = "s5m8767-clk",
57 .of_compatible = "samsung,s5m8767-clk", 47 .of_compatible = "samsung,s5m8767-clk",
58 } 48 },
59}; 49};
60 50
61static const struct mfd_cell s2mps11_devs[] = { 51static const struct mfd_cell s2mps11_devs[] = {
52 { .name = "s2mps11-regulator", },
53 { .name = "s2mps14-rtc", },
62 { 54 {
63 .name = "s2mps11-regulator",
64 }, {
65 .name = "s2mps14-rtc",
66 }, {
67 .name = "s2mps11-clk", 55 .name = "s2mps11-clk",
68 .of_compatible = "samsung,s2mps11-clk", 56 .of_compatible = "samsung,s2mps11-clk",
69 } 57 },
70}; 58};
71 59
72static const struct mfd_cell s2mps13_devs[] = { 60static const struct mfd_cell s2mps13_devs[] = {
@@ -79,37 +67,30 @@ static const struct mfd_cell s2mps13_devs[] = {
79}; 67};
80 68
81static const struct mfd_cell s2mps14_devs[] = { 69static const struct mfd_cell s2mps14_devs[] = {
70 { .name = "s2mps14-regulator", },
71 { .name = "s2mps14-rtc", },
82 { 72 {
83 .name = "s2mps14-regulator",
84 }, {
85 .name = "s2mps14-rtc",
86 }, {
87 .name = "s2mps14-clk", 73 .name = "s2mps14-clk",
88 .of_compatible = "samsung,s2mps14-clk", 74 .of_compatible = "samsung,s2mps14-clk",
89 } 75 },
90}; 76};
91 77
92static const struct mfd_cell s2mps15_devs[] = { 78static const struct mfd_cell s2mps15_devs[] = {
79 { .name = "s2mps15-regulator", },
80 { .name = "s2mps15-rtc", },
93 { 81 {
94 .name = "s2mps15-regulator",
95 }, {
96 .name = "s2mps15-rtc",
97 }, {
98 .name = "s2mps13-clk", 82 .name = "s2mps13-clk",
99 .of_compatible = "samsung,s2mps13-clk", 83 .of_compatible = "samsung,s2mps13-clk",
100 }, 84 },
101}; 85};
102 86
103static const struct mfd_cell s2mpa01_devs[] = { 87static const struct mfd_cell s2mpa01_devs[] = {
104 { 88 { .name = "s2mpa01-pmic", },
105 .name = "s2mpa01-pmic", 89 { .name = "s2mps14-rtc", },
106 },
107}; 90};
108 91
109static const struct mfd_cell s2mpu02_devs[] = { 92static const struct mfd_cell s2mpu02_devs[] = {
110 { 93 { .name = "s2mpu02-regulator", },
111 .name = "s2mpu02-regulator",
112 },
113}; 94};
114 95
115#ifdef CONFIG_OF 96#ifdef CONFIG_OF
diff --git a/drivers/mfd/sec-irq.c b/drivers/mfd/sec-irq.c
index ad0099077e7e..a98c5d165039 100644
--- a/drivers/mfd/sec-irq.c
+++ b/drivers/mfd/sec-irq.c
@@ -455,6 +455,9 @@ int sec_irq_init(struct sec_pmic_dev *sec_pmic)
455 case S5M8767X: 455 case S5M8767X:
456 sec_irq_chip = &s5m8767_irq_chip; 456 sec_irq_chip = &s5m8767_irq_chip;
457 break; 457 break;
458 case S2MPA01:
459 sec_irq_chip = &s2mps14_irq_chip;
460 break;
458 case S2MPS11X: 461 case S2MPS11X:
459 sec_irq_chip = &s2mps11_irq_chip; 462 sec_irq_chip = &s2mps11_irq_chip;
460 break; 463 break;
diff --git a/drivers/mfd/ssbi.c b/drivers/mfd/ssbi.c
index 36b96fee4ce6..0ae27cd30268 100644
--- a/drivers/mfd/ssbi.c
+++ b/drivers/mfd/ssbi.c
@@ -80,8 +80,6 @@ struct ssbi {
80 int (*write)(struct ssbi *, u16 addr, const u8 *buf, int len); 80 int (*write)(struct ssbi *, u16 addr, const u8 *buf, int len);
81}; 81};
82 82
83#define to_ssbi(dev) platform_get_drvdata(to_platform_device(dev))
84
85static inline u32 ssbi_readl(struct ssbi *ssbi, u32 reg) 83static inline u32 ssbi_readl(struct ssbi *ssbi, u32 reg)
86{ 84{
87 return readl(ssbi->base + reg); 85 return readl(ssbi->base + reg);
@@ -243,7 +241,7 @@ err:
243 241
244int ssbi_read(struct device *dev, u16 addr, u8 *buf, int len) 242int ssbi_read(struct device *dev, u16 addr, u8 *buf, int len)
245{ 243{
246 struct ssbi *ssbi = to_ssbi(dev); 244 struct ssbi *ssbi = dev_get_drvdata(dev);
247 unsigned long flags; 245 unsigned long flags;
248 int ret; 246 int ret;
249 247
@@ -257,7 +255,7 @@ EXPORT_SYMBOL_GPL(ssbi_read);
257 255
258int ssbi_write(struct device *dev, u16 addr, const u8 *buf, int len) 256int ssbi_write(struct device *dev, u16 addr, const u8 *buf, int len)
259{ 257{
260 struct ssbi *ssbi = to_ssbi(dev); 258 struct ssbi *ssbi = dev_get_drvdata(dev);
261 unsigned long flags; 259 unsigned long flags;
262 int ret; 260 int ret;
263 261
diff --git a/drivers/mfd/stmfx.c b/drivers/mfd/stmfx.c
new file mode 100644
index 000000000000..fe8efba2d45f
--- /dev/null
+++ b/drivers/mfd/stmfx.c
@@ -0,0 +1,545 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Driver for STMicroelectronics Multi-Function eXpander (STMFX) core
4 *
5 * Copyright (C) 2019 STMicroelectronics
6 * Author(s): Amelie Delaunay <amelie.delaunay@st.com>.
7 */
8#include <linux/bitfield.h>
9#include <linux/i2c.h>
10#include <linux/interrupt.h>
11#include <linux/irq.h>
12#include <linux/mfd/core.h>
13#include <linux/mfd/stmfx.h>
14#include <linux/module.h>
15#include <linux/regulator/consumer.h>
16
17static bool stmfx_reg_volatile(struct device *dev, unsigned int reg)
18{
19 switch (reg) {
20 case STMFX_REG_SYS_CTRL:
21 case STMFX_REG_IRQ_SRC_EN:
22 case STMFX_REG_IRQ_PENDING:
23 case STMFX_REG_IRQ_GPI_PENDING1:
24 case STMFX_REG_IRQ_GPI_PENDING2:
25 case STMFX_REG_IRQ_GPI_PENDING3:
26 case STMFX_REG_GPIO_STATE1:
27 case STMFX_REG_GPIO_STATE2:
28 case STMFX_REG_GPIO_STATE3:
29 case STMFX_REG_IRQ_GPI_SRC1:
30 case STMFX_REG_IRQ_GPI_SRC2:
31 case STMFX_REG_IRQ_GPI_SRC3:
32 case STMFX_REG_GPO_SET1:
33 case STMFX_REG_GPO_SET2:
34 case STMFX_REG_GPO_SET3:
35 case STMFX_REG_GPO_CLR1:
36 case STMFX_REG_GPO_CLR2:
37 case STMFX_REG_GPO_CLR3:
38 return true;
39 default:
40 return false;
41 }
42}
43
44static bool stmfx_reg_writeable(struct device *dev, unsigned int reg)
45{
46 return (reg >= STMFX_REG_SYS_CTRL);
47}
48
49static const struct regmap_config stmfx_regmap_config = {
50 .reg_bits = 8,
51 .reg_stride = 1,
52 .val_bits = 8,
53 .max_register = STMFX_REG_MAX,
54 .volatile_reg = stmfx_reg_volatile,
55 .writeable_reg = stmfx_reg_writeable,
56 .cache_type = REGCACHE_RBTREE,
57};
58
59static const struct resource stmfx_pinctrl_resources[] = {
60 DEFINE_RES_IRQ(STMFX_REG_IRQ_SRC_EN_GPIO),
61};
62
63static const struct resource stmfx_idd_resources[] = {
64 DEFINE_RES_IRQ(STMFX_REG_IRQ_SRC_EN_IDD),
65 DEFINE_RES_IRQ(STMFX_REG_IRQ_SRC_EN_ERROR),
66};
67
68static const struct resource stmfx_ts_resources[] = {
69 DEFINE_RES_IRQ(STMFX_REG_IRQ_SRC_EN_TS_DET),
70 DEFINE_RES_IRQ(STMFX_REG_IRQ_SRC_EN_TS_NE),
71 DEFINE_RES_IRQ(STMFX_REG_IRQ_SRC_EN_TS_TH),
72 DEFINE_RES_IRQ(STMFX_REG_IRQ_SRC_EN_TS_FULL),
73 DEFINE_RES_IRQ(STMFX_REG_IRQ_SRC_EN_TS_OVF),
74};
75
76static struct mfd_cell stmfx_cells[] = {
77 {
78 .of_compatible = "st,stmfx-0300-pinctrl",
79 .name = "stmfx-pinctrl",
80 .resources = stmfx_pinctrl_resources,
81 .num_resources = ARRAY_SIZE(stmfx_pinctrl_resources),
82 },
83 {
84 .of_compatible = "st,stmfx-0300-idd",
85 .name = "stmfx-idd",
86 .resources = stmfx_idd_resources,
87 .num_resources = ARRAY_SIZE(stmfx_idd_resources),
88 },
89 {
90 .of_compatible = "st,stmfx-0300-ts",
91 .name = "stmfx-ts",
92 .resources = stmfx_ts_resources,
93 .num_resources = ARRAY_SIZE(stmfx_ts_resources),
94 },
95};
96
97static u8 stmfx_func_to_mask(u32 func)
98{
99 u8 mask = 0;
100
101 if (func & STMFX_FUNC_GPIO)
102 mask |= STMFX_REG_SYS_CTRL_GPIO_EN;
103
104 if ((func & STMFX_FUNC_ALTGPIO_LOW) || (func & STMFX_FUNC_ALTGPIO_HIGH))
105 mask |= STMFX_REG_SYS_CTRL_ALTGPIO_EN;
106
107 if (func & STMFX_FUNC_TS)
108 mask |= STMFX_REG_SYS_CTRL_TS_EN;
109
110 if (func & STMFX_FUNC_IDD)
111 mask |= STMFX_REG_SYS_CTRL_IDD_EN;
112
113 return mask;
114}
115
116int stmfx_function_enable(struct stmfx *stmfx, u32 func)
117{
118 u32 sys_ctrl;
119 u8 mask;
120 int ret;
121
122 ret = regmap_read(stmfx->map, STMFX_REG_SYS_CTRL, &sys_ctrl);
123 if (ret)
124 return ret;
125
126 /*
127 * IDD and TS have priority in STMFX FW, so if IDD and TS are enabled,
128 * ALTGPIO function is disabled by STMFX FW. If IDD or TS is enabled,
129 * the number of aGPIO available decreases. To avoid GPIO management
130 * disturbance, abort IDD or TS function enable in this case.
131 */
132 if (((func & STMFX_FUNC_IDD) || (func & STMFX_FUNC_TS)) &&
133 (sys_ctrl & STMFX_REG_SYS_CTRL_ALTGPIO_EN)) {
134 dev_err(stmfx->dev, "ALTGPIO function already enabled\n");
135 return -EBUSY;
136 }
137
138 /* If TS is enabled, aGPIO[3:0] cannot be used */
139 if ((func & STMFX_FUNC_ALTGPIO_LOW) &&
140 (sys_ctrl & STMFX_REG_SYS_CTRL_TS_EN)) {
141 dev_err(stmfx->dev, "TS in use, aGPIO[3:0] unavailable\n");
142 return -EBUSY;
143 }
144
145 /* If IDD is enabled, aGPIO[7:4] cannot be used */
146 if ((func & STMFX_FUNC_ALTGPIO_HIGH) &&
147 (sys_ctrl & STMFX_REG_SYS_CTRL_IDD_EN)) {
148 dev_err(stmfx->dev, "IDD in use, aGPIO[7:4] unavailable\n");
149 return -EBUSY;
150 }
151
152 mask = stmfx_func_to_mask(func);
153
154 return regmap_update_bits(stmfx->map, STMFX_REG_SYS_CTRL, mask, mask);
155}
156EXPORT_SYMBOL_GPL(stmfx_function_enable);
157
158int stmfx_function_disable(struct stmfx *stmfx, u32 func)
159{
160 u8 mask = stmfx_func_to_mask(func);
161
162 return regmap_update_bits(stmfx->map, STMFX_REG_SYS_CTRL, mask, 0);
163}
164EXPORT_SYMBOL_GPL(stmfx_function_disable);
165
166static void stmfx_irq_bus_lock(struct irq_data *data)
167{
168 struct stmfx *stmfx = irq_data_get_irq_chip_data(data);
169
170 mutex_lock(&stmfx->lock);
171}
172
173static void stmfx_irq_bus_sync_unlock(struct irq_data *data)
174{
175 struct stmfx *stmfx = irq_data_get_irq_chip_data(data);
176
177 regmap_write(stmfx->map, STMFX_REG_IRQ_SRC_EN, stmfx->irq_src);
178
179 mutex_unlock(&stmfx->lock);
180}
181
182static void stmfx_irq_mask(struct irq_data *data)
183{
184 struct stmfx *stmfx = irq_data_get_irq_chip_data(data);
185
186 stmfx->irq_src &= ~BIT(data->hwirq % 8);
187}
188
189static void stmfx_irq_unmask(struct irq_data *data)
190{
191 struct stmfx *stmfx = irq_data_get_irq_chip_data(data);
192
193 stmfx->irq_src |= BIT(data->hwirq % 8);
194}
195
196static struct irq_chip stmfx_irq_chip = {
197 .name = "stmfx-core",
198 .irq_bus_lock = stmfx_irq_bus_lock,
199 .irq_bus_sync_unlock = stmfx_irq_bus_sync_unlock,
200 .irq_mask = stmfx_irq_mask,
201 .irq_unmask = stmfx_irq_unmask,
202};
203
204static irqreturn_t stmfx_irq_handler(int irq, void *data)
205{
206 struct stmfx *stmfx = data;
207 unsigned long n, pending;
208 u32 ack;
209 int ret;
210
211 ret = regmap_read(stmfx->map, STMFX_REG_IRQ_PENDING,
212 (u32 *)&pending);
213 if (ret)
214 return IRQ_NONE;
215
216 /*
217 * There is no ACK for GPIO, MFX_REG_IRQ_PENDING_GPIO is a logical OR
218 * of MFX_REG_IRQ_GPI _PENDING1/_PENDING2/_PENDING3
219 */
220 ack = pending & ~BIT(STMFX_REG_IRQ_SRC_EN_GPIO);
221 if (ack) {
222 ret = regmap_write(stmfx->map, STMFX_REG_IRQ_ACK, ack);
223 if (ret)
224 return IRQ_NONE;
225 }
226
227 for_each_set_bit(n, &pending, STMFX_REG_IRQ_SRC_MAX)
228 handle_nested_irq(irq_find_mapping(stmfx->irq_domain, n));
229
230 return IRQ_HANDLED;
231}
232
233static int stmfx_irq_map(struct irq_domain *d, unsigned int virq,
234 irq_hw_number_t hwirq)
235{
236 irq_set_chip_data(virq, d->host_data);
237 irq_set_chip_and_handler(virq, &stmfx_irq_chip, handle_simple_irq);
238 irq_set_nested_thread(virq, 1);
239 irq_set_noprobe(virq);
240
241 return 0;
242}
243
244static void stmfx_irq_unmap(struct irq_domain *d, unsigned int virq)
245{
246 irq_set_chip_and_handler(virq, NULL, NULL);
247 irq_set_chip_data(virq, NULL);
248}
249
250static const struct irq_domain_ops stmfx_irq_ops = {
251 .map = stmfx_irq_map,
252 .unmap = stmfx_irq_unmap,
253};
254
255static void stmfx_irq_exit(struct i2c_client *client)
256{
257 struct stmfx *stmfx = i2c_get_clientdata(client);
258 int hwirq;
259
260 for (hwirq = 0; hwirq < STMFX_REG_IRQ_SRC_MAX; hwirq++)
261 irq_dispose_mapping(irq_find_mapping(stmfx->irq_domain, hwirq));
262
263 irq_domain_remove(stmfx->irq_domain);
264}
265
266static int stmfx_irq_init(struct i2c_client *client)
267{
268 struct stmfx *stmfx = i2c_get_clientdata(client);
269 u32 irqoutpin = 0, irqtrigger;
270 int ret;
271
272 stmfx->irq_domain = irq_domain_add_simple(stmfx->dev->of_node,
273 STMFX_REG_IRQ_SRC_MAX, 0,
274 &stmfx_irq_ops, stmfx);
275 if (!stmfx->irq_domain) {
276 dev_err(stmfx->dev, "Failed to create IRQ domain\n");
277 return -EINVAL;
278 }
279
280 if (!of_property_read_bool(stmfx->dev->of_node, "drive-open-drain"))
281 irqoutpin |= STMFX_REG_IRQ_OUT_PIN_TYPE;
282
283 irqtrigger = irq_get_trigger_type(client->irq);
284 if ((irqtrigger & IRQ_TYPE_EDGE_RISING) ||
285 (irqtrigger & IRQ_TYPE_LEVEL_HIGH))
286 irqoutpin |= STMFX_REG_IRQ_OUT_PIN_POL;
287
288 ret = regmap_write(stmfx->map, STMFX_REG_IRQ_OUT_PIN, irqoutpin);
289 if (ret)
290 return ret;
291
292 ret = devm_request_threaded_irq(stmfx->dev, client->irq,
293 NULL, stmfx_irq_handler,
294 irqtrigger | IRQF_ONESHOT,
295 "stmfx", stmfx);
296 if (ret)
297 stmfx_irq_exit(client);
298
299 return ret;
300}
301
302static int stmfx_chip_reset(struct stmfx *stmfx)
303{
304 int ret;
305
306 ret = regmap_write(stmfx->map, STMFX_REG_SYS_CTRL,
307 STMFX_REG_SYS_CTRL_SWRST);
308 if (ret)
309 return ret;
310
311 msleep(STMFX_BOOT_TIME_MS);
312
313 return ret;
314}
315
316static int stmfx_chip_init(struct i2c_client *client)
317{
318 struct stmfx *stmfx = i2c_get_clientdata(client);
319 u32 id;
320 u8 version[2];
321 int ret;
322
323 stmfx->vdd = devm_regulator_get_optional(&client->dev, "vdd");
324 ret = PTR_ERR_OR_ZERO(stmfx->vdd);
325 if (ret == -ENODEV) {
326 stmfx->vdd = NULL;
327 } else if (ret == -EPROBE_DEFER) {
328 return ret;
329 } else if (ret) {
330 dev_err(&client->dev, "Failed to get VDD regulator: %d\n", ret);
331 return ret;
332 }
333
334 if (stmfx->vdd) {
335 ret = regulator_enable(stmfx->vdd);
336 if (ret) {
337 dev_err(&client->dev, "VDD enable failed: %d\n", ret);
338 return ret;
339 }
340 }
341
342 ret = regmap_read(stmfx->map, STMFX_REG_CHIP_ID, &id);
343 if (ret) {
344 dev_err(&client->dev, "Error reading chip ID: %d\n", ret);
345 goto err;
346 }
347
348 /*
349 * Check that ID is the complement of the I2C address:
350 * STMFX I2C address follows the 7-bit format (MSB), that's why
351 * client->addr is shifted.
352 *
353 * STMFX_I2C_ADDR| STMFX | Linux
354 * input pin | I2C device address | I2C device address
355 *---------------------------------------------------------
356 * 0 | b: 1000 010x h:0x84 | 0x42
357 * 1 | b: 1000 011x h:0x86 | 0x43
358 */
359 if (FIELD_GET(STMFX_REG_CHIP_ID_MASK, ~id) != (client->addr << 1)) {
360 dev_err(&client->dev, "Unknown chip ID: %#x\n", id);
361 ret = -EINVAL;
362 goto err;
363 }
364
365 ret = regmap_bulk_read(stmfx->map, STMFX_REG_FW_VERSION_MSB,
366 version, ARRAY_SIZE(version));
367 if (ret) {
368 dev_err(&client->dev, "Error reading FW version: %d\n", ret);
369 goto err;
370 }
371
372 dev_info(&client->dev, "STMFX id: %#x, fw version: %x.%02x\n",
373 id, version[0], version[1]);
374
375 ret = stmfx_chip_reset(stmfx);
376 if (ret) {
377 dev_err(&client->dev, "Failed to reset chip: %d\n", ret);
378 goto err;
379 }
380
381 return 0;
382
383err:
384 if (stmfx->vdd)
385 return regulator_disable(stmfx->vdd);
386
387 return ret;
388}
389
390static int stmfx_chip_exit(struct i2c_client *client)
391{
392 struct stmfx *stmfx = i2c_get_clientdata(client);
393
394 regmap_write(stmfx->map, STMFX_REG_IRQ_SRC_EN, 0);
395 regmap_write(stmfx->map, STMFX_REG_SYS_CTRL, 0);
396
397 if (stmfx->vdd)
398 return regulator_disable(stmfx->vdd);
399
400 return 0;
401}
402
403static int stmfx_probe(struct i2c_client *client,
404 const struct i2c_device_id *id)
405{
406 struct device *dev = &client->dev;
407 struct stmfx *stmfx;
408 int ret;
409
410 stmfx = devm_kzalloc(dev, sizeof(*stmfx), GFP_KERNEL);
411 if (!stmfx)
412 return -ENOMEM;
413
414 i2c_set_clientdata(client, stmfx);
415
416 stmfx->dev = dev;
417
418 stmfx->map = devm_regmap_init_i2c(client, &stmfx_regmap_config);
419 if (IS_ERR(stmfx->map)) {
420 ret = PTR_ERR(stmfx->map);
421 dev_err(dev, "Failed to allocate register map: %d\n", ret);
422 return ret;
423 }
424
425 mutex_init(&stmfx->lock);
426
427 ret = stmfx_chip_init(client);
428 if (ret) {
429 if (ret == -ETIMEDOUT)
430 return -EPROBE_DEFER;
431 return ret;
432 }
433
434 if (client->irq < 0) {
435 dev_err(dev, "Failed to get IRQ: %d\n", client->irq);
436 ret = client->irq;
437 goto err_chip_exit;
438 }
439
440 ret = stmfx_irq_init(client);
441 if (ret)
442 goto err_chip_exit;
443
444 ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE,
445 stmfx_cells, ARRAY_SIZE(stmfx_cells), NULL,
446 0, stmfx->irq_domain);
447 if (ret)
448 goto err_irq_exit;
449
450 return 0;
451
452err_irq_exit:
453 stmfx_irq_exit(client);
454err_chip_exit:
455 stmfx_chip_exit(client);
456
457 return ret;
458}
459
460static int stmfx_remove(struct i2c_client *client)
461{
462 stmfx_irq_exit(client);
463
464 return stmfx_chip_exit(client);
465}
466
467#ifdef CONFIG_PM_SLEEP
468static int stmfx_suspend(struct device *dev)
469{
470 struct stmfx *stmfx = dev_get_drvdata(dev);
471 int ret;
472
473 ret = regmap_raw_read(stmfx->map, STMFX_REG_SYS_CTRL,
474 &stmfx->bkp_sysctrl, sizeof(stmfx->bkp_sysctrl));
475 if (ret)
476 return ret;
477
478 ret = regmap_raw_read(stmfx->map, STMFX_REG_IRQ_OUT_PIN,
479 &stmfx->bkp_irqoutpin,
480 sizeof(stmfx->bkp_irqoutpin));
481 if (ret)
482 return ret;
483
484 if (stmfx->vdd)
485 return regulator_disable(stmfx->vdd);
486
487 return 0;
488}
489
490static int stmfx_resume(struct device *dev)
491{
492 struct stmfx *stmfx = dev_get_drvdata(dev);
493 int ret;
494
495 if (stmfx->vdd) {
496 ret = regulator_enable(stmfx->vdd);
497 if (ret) {
498 dev_err(stmfx->dev,
499 "VDD enable failed: %d\n", ret);
500 return ret;
501 }
502 }
503
504 ret = regmap_raw_write(stmfx->map, STMFX_REG_SYS_CTRL,
505 &stmfx->bkp_sysctrl, sizeof(stmfx->bkp_sysctrl));
506 if (ret)
507 return ret;
508
509 ret = regmap_raw_write(stmfx->map, STMFX_REG_IRQ_OUT_PIN,
510 &stmfx->bkp_irqoutpin,
511 sizeof(stmfx->bkp_irqoutpin));
512 if (ret)
513 return ret;
514
515 ret = regmap_raw_write(stmfx->map, STMFX_REG_IRQ_SRC_EN,
516 &stmfx->irq_src, sizeof(stmfx->irq_src));
517 if (ret)
518 return ret;
519
520 return 0;
521}
522#endif
523
524static SIMPLE_DEV_PM_OPS(stmfx_dev_pm_ops, stmfx_suspend, stmfx_resume);
525
526static const struct of_device_id stmfx_of_match[] = {
527 { .compatible = "st,stmfx-0300", },
528 {},
529};
530MODULE_DEVICE_TABLE(of, stmfx_of_match);
531
532static struct i2c_driver stmfx_driver = {
533 .driver = {
534 .name = "stmfx-core",
535 .of_match_table = of_match_ptr(stmfx_of_match),
536 .pm = &stmfx_dev_pm_ops,
537 },
538 .probe = stmfx_probe,
539 .remove = stmfx_remove,
540};
541module_i2c_driver(stmfx_driver);
542
543MODULE_DESCRIPTION("STMFX core driver");
544MODULE_AUTHOR("Amelie Delaunay <amelie.delaunay@st.com>");
545MODULE_LICENSE("GPL v2");
diff --git a/drivers/mfd/sun6i-prcm.c b/drivers/mfd/sun6i-prcm.c
index 2b658bed47db..2f12a415b807 100644
--- a/drivers/mfd/sun6i-prcm.c
+++ b/drivers/mfd/sun6i-prcm.c
@@ -148,13 +148,12 @@ static const struct of_device_id sun6i_prcm_dt_ids[] = {
148 148
149static int sun6i_prcm_probe(struct platform_device *pdev) 149static int sun6i_prcm_probe(struct platform_device *pdev)
150{ 150{
151 struct device_node *np = pdev->dev.of_node;
152 const struct of_device_id *match; 151 const struct of_device_id *match;
153 const struct prcm_data *data; 152 const struct prcm_data *data;
154 struct resource *res; 153 struct resource *res;
155 int ret; 154 int ret;
156 155
157 match = of_match_node(sun6i_prcm_dt_ids, np); 156 match = of_match_node(sun6i_prcm_dt_ids, pdev->dev.of_node);
158 if (!match) 157 if (!match)
159 return -EINVAL; 158 return -EINVAL;
160 159
diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c
index 0ecdffb3d967..f6922a0f8058 100644
--- a/drivers/mfd/syscon.c
+++ b/drivers/mfd/syscon.c
@@ -12,6 +12,7 @@
12 * (at your option) any later version. 12 * (at your option) any later version.
13 */ 13 */
14 14
15#include <linux/clk.h>
15#include <linux/err.h> 16#include <linux/err.h>
16#include <linux/hwspinlock.h> 17#include <linux/hwspinlock.h>
17#include <linux/io.h> 18#include <linux/io.h>
@@ -45,6 +46,7 @@ static const struct regmap_config syscon_regmap_config = {
45 46
46static struct syscon *of_syscon_register(struct device_node *np) 47static struct syscon *of_syscon_register(struct device_node *np)
47{ 48{
49 struct clk *clk;
48 struct syscon *syscon; 50 struct syscon *syscon;
49 struct regmap *regmap; 51 struct regmap *regmap;
50 void __iomem *base; 52 void __iomem *base;
@@ -119,6 +121,18 @@ static struct syscon *of_syscon_register(struct device_node *np)
119 goto err_regmap; 121 goto err_regmap;
120 } 122 }
121 123
124 clk = of_clk_get(np, 0);
125 if (IS_ERR(clk)) {
126 ret = PTR_ERR(clk);
127 /* clock is optional */
128 if (ret != -ENOENT)
129 goto err_clk;
130 } else {
131 ret = regmap_mmio_attach_clk(regmap, clk);
132 if (ret)
133 goto err_attach;
134 }
135
122 syscon->regmap = regmap; 136 syscon->regmap = regmap;
123 syscon->np = np; 137 syscon->np = np;
124 138
@@ -128,6 +142,11 @@ static struct syscon *of_syscon_register(struct device_node *np)
128 142
129 return syscon; 143 return syscon;
130 144
145err_attach:
146 if (!IS_ERR(clk))
147 clk_put(clk);
148err_clk:
149 regmap_exit(regmap);
131err_regmap: 150err_regmap:
132 iounmap(base); 151 iounmap(base);
133err_map: 152err_map:
diff --git a/drivers/mfd/t7l66xb.c b/drivers/mfd/t7l66xb.c
index 43d8683266de..e9cfb147345e 100644
--- a/drivers/mfd/t7l66xb.c
+++ b/drivers/mfd/t7l66xb.c
@@ -82,8 +82,7 @@ struct t7l66xb {
82 82
83static int t7l66xb_mmc_enable(struct platform_device *mmc) 83static int t7l66xb_mmc_enable(struct platform_device *mmc)
84{ 84{
85 struct platform_device *dev = to_platform_device(mmc->dev.parent); 85 struct t7l66xb *t7l66xb = dev_get_drvdata(mmc->dev.parent);
86 struct t7l66xb *t7l66xb = platform_get_drvdata(dev);
87 unsigned long flags; 86 unsigned long flags;
88 u8 dev_ctl; 87 u8 dev_ctl;
89 int ret; 88 int ret;
@@ -108,8 +107,7 @@ static int t7l66xb_mmc_enable(struct platform_device *mmc)
108 107
109static int t7l66xb_mmc_disable(struct platform_device *mmc) 108static int t7l66xb_mmc_disable(struct platform_device *mmc)
110{ 109{
111 struct platform_device *dev = to_platform_device(mmc->dev.parent); 110 struct t7l66xb *t7l66xb = dev_get_drvdata(mmc->dev.parent);
112 struct t7l66xb *t7l66xb = platform_get_drvdata(dev);
113 unsigned long flags; 111 unsigned long flags;
114 u8 dev_ctl; 112 u8 dev_ctl;
115 113
@@ -128,16 +126,14 @@ static int t7l66xb_mmc_disable(struct platform_device *mmc)
128 126
129static void t7l66xb_mmc_pwr(struct platform_device *mmc, int state) 127static void t7l66xb_mmc_pwr(struct platform_device *mmc, int state)
130{ 128{
131 struct platform_device *dev = to_platform_device(mmc->dev.parent); 129 struct t7l66xb *t7l66xb = dev_get_drvdata(mmc->dev.parent);
132 struct t7l66xb *t7l66xb = platform_get_drvdata(dev);
133 130
134 tmio_core_mmc_pwr(t7l66xb->scr + 0x200, 0, state); 131 tmio_core_mmc_pwr(t7l66xb->scr + 0x200, 0, state);
135} 132}
136 133
137static void t7l66xb_mmc_clk_div(struct platform_device *mmc, int state) 134static void t7l66xb_mmc_clk_div(struct platform_device *mmc, int state)
138{ 135{
139 struct platform_device *dev = to_platform_device(mmc->dev.parent); 136 struct t7l66xb *t7l66xb = dev_get_drvdata(mmc->dev.parent);
140 struct t7l66xb *t7l66xb = platform_get_drvdata(dev);
141 137
142 tmio_core_mmc_clk_div(t7l66xb->scr + 0x200, 0, state); 138 tmio_core_mmc_clk_div(t7l66xb->scr + 0x200, 0, state);
143} 139}
diff --git a/drivers/mfd/tc6387xb.c b/drivers/mfd/tc6387xb.c
index 85fab3729102..f417c6fecfe2 100644
--- a/drivers/mfd/tc6387xb.c
+++ b/drivers/mfd/tc6387xb.c
@@ -80,16 +80,14 @@ static int tc6387xb_resume(struct platform_device *dev)
80 80
81static void tc6387xb_mmc_pwr(struct platform_device *mmc, int state) 81static void tc6387xb_mmc_pwr(struct platform_device *mmc, int state)
82{ 82{
83 struct platform_device *dev = to_platform_device(mmc->dev.parent); 83 struct tc6387xb *tc6387xb = dev_get_drvdata(mmc->dev.parent);
84 struct tc6387xb *tc6387xb = platform_get_drvdata(dev);
85 84
86 tmio_core_mmc_pwr(tc6387xb->scr + 0x200, 0, state); 85 tmio_core_mmc_pwr(tc6387xb->scr + 0x200, 0, state);
87} 86}
88 87
89static void tc6387xb_mmc_clk_div(struct platform_device *mmc, int state) 88static void tc6387xb_mmc_clk_div(struct platform_device *mmc, int state)
90{ 89{
91 struct platform_device *dev = to_platform_device(mmc->dev.parent); 90 struct tc6387xb *tc6387xb = dev_get_drvdata(mmc->dev.parent);
92 struct tc6387xb *tc6387xb = platform_get_drvdata(dev);
93 91
94 tmio_core_mmc_clk_div(tc6387xb->scr + 0x200, 0, state); 92 tmio_core_mmc_clk_div(tc6387xb->scr + 0x200, 0, state);
95} 93}
@@ -97,8 +95,7 @@ static void tc6387xb_mmc_clk_div(struct platform_device *mmc, int state)
97 95
98static int tc6387xb_mmc_enable(struct platform_device *mmc) 96static int tc6387xb_mmc_enable(struct platform_device *mmc)
99{ 97{
100 struct platform_device *dev = to_platform_device(mmc->dev.parent); 98 struct tc6387xb *tc6387xb = dev_get_drvdata(mmc->dev.parent);
101 struct tc6387xb *tc6387xb = platform_get_drvdata(dev);
102 99
103 clk_prepare_enable(tc6387xb->clk32k); 100 clk_prepare_enable(tc6387xb->clk32k);
104 101
@@ -110,8 +107,7 @@ static int tc6387xb_mmc_enable(struct platform_device *mmc)
110 107
111static int tc6387xb_mmc_disable(struct platform_device *mmc) 108static int tc6387xb_mmc_disable(struct platform_device *mmc)
112{ 109{
113 struct platform_device *dev = to_platform_device(mmc->dev.parent); 110 struct tc6387xb *tc6387xb = dev_get_drvdata(mmc->dev.parent);
114 struct tc6387xb *tc6387xb = platform_get_drvdata(dev);
115 111
116 clk_disable_unprepare(tc6387xb->clk32k); 112 clk_disable_unprepare(tc6387xb->clk32k);
117 113
diff --git a/drivers/mfd/tc6393xb.c b/drivers/mfd/tc6393xb.c
index 0c9f0390e891..6943048a64c2 100644
--- a/drivers/mfd/tc6393xb.c
+++ b/drivers/mfd/tc6393xb.c
@@ -122,14 +122,13 @@ enum {
122 122
123static int tc6393xb_nand_enable(struct platform_device *nand) 123static int tc6393xb_nand_enable(struct platform_device *nand)
124{ 124{
125 struct platform_device *dev = to_platform_device(nand->dev.parent); 125 struct tc6393xb *tc6393xb = dev_get_drvdata(nand->dev.parent);
126 struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
127 unsigned long flags; 126 unsigned long flags;
128 127
129 raw_spin_lock_irqsave(&tc6393xb->lock, flags); 128 raw_spin_lock_irqsave(&tc6393xb->lock, flags);
130 129
131 /* SMD buffer on */ 130 /* SMD buffer on */
132 dev_dbg(&dev->dev, "SMD buffer on\n"); 131 dev_dbg(nand->dev.parent, "SMD buffer on\n");
133 tmio_iowrite8(0xff, tc6393xb->scr + SCR_GPI_BCR(1)); 132 tmio_iowrite8(0xff, tc6393xb->scr + SCR_GPI_BCR(1));
134 133
135 raw_spin_unlock_irqrestore(&tc6393xb->lock, flags); 134 raw_spin_unlock_irqrestore(&tc6393xb->lock, flags);
@@ -312,8 +311,7 @@ static int tc6393xb_fb_disable(struct platform_device *dev)
312 311
313int tc6393xb_lcd_set_power(struct platform_device *fb, bool on) 312int tc6393xb_lcd_set_power(struct platform_device *fb, bool on)
314{ 313{
315 struct platform_device *dev = to_platform_device(fb->dev.parent); 314 struct tc6393xb *tc6393xb = dev_get_drvdata(fb->dev.parent);
316 struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
317 u8 fer; 315 u8 fer;
318 unsigned long flags; 316 unsigned long flags;
319 317
@@ -334,8 +332,7 @@ EXPORT_SYMBOL(tc6393xb_lcd_set_power);
334 332
335int tc6393xb_lcd_mode(struct platform_device *fb, 333int tc6393xb_lcd_mode(struct platform_device *fb,
336 const struct fb_videomode *mode) { 334 const struct fb_videomode *mode) {
337 struct platform_device *dev = to_platform_device(fb->dev.parent); 335 struct tc6393xb *tc6393xb = dev_get_drvdata(fb->dev.parent);
338 struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
339 unsigned long flags; 336 unsigned long flags;
340 337
341 raw_spin_lock_irqsave(&tc6393xb->lock, flags); 338 raw_spin_lock_irqsave(&tc6393xb->lock, flags);
@@ -351,8 +348,7 @@ EXPORT_SYMBOL(tc6393xb_lcd_mode);
351 348
352static int tc6393xb_mmc_enable(struct platform_device *mmc) 349static int tc6393xb_mmc_enable(struct platform_device *mmc)
353{ 350{
354 struct platform_device *dev = to_platform_device(mmc->dev.parent); 351 struct tc6393xb *tc6393xb = dev_get_drvdata(mmc->dev.parent);
355 struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
356 352
357 tmio_core_mmc_enable(tc6393xb->scr + 0x200, 0, 353 tmio_core_mmc_enable(tc6393xb->scr + 0x200, 0,
358 tc6393xb_mmc_resources[0].start & 0xfffe); 354 tc6393xb_mmc_resources[0].start & 0xfffe);
@@ -362,8 +358,7 @@ static int tc6393xb_mmc_enable(struct platform_device *mmc)
362 358
363static int tc6393xb_mmc_resume(struct platform_device *mmc) 359static int tc6393xb_mmc_resume(struct platform_device *mmc)
364{ 360{
365 struct platform_device *dev = to_platform_device(mmc->dev.parent); 361 struct tc6393xb *tc6393xb = dev_get_drvdata(mmc->dev.parent);
366 struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
367 362
368 tmio_core_mmc_resume(tc6393xb->scr + 0x200, 0, 363 tmio_core_mmc_resume(tc6393xb->scr + 0x200, 0,
369 tc6393xb_mmc_resources[0].start & 0xfffe); 364 tc6393xb_mmc_resources[0].start & 0xfffe);
@@ -373,16 +368,14 @@ static int tc6393xb_mmc_resume(struct platform_device *mmc)
373 368
374static void tc6393xb_mmc_pwr(struct platform_device *mmc, int state) 369static void tc6393xb_mmc_pwr(struct platform_device *mmc, int state)
375{ 370{
376 struct platform_device *dev = to_platform_device(mmc->dev.parent); 371 struct tc6393xb *tc6393xb = dev_get_drvdata(mmc->dev.parent);
377 struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
378 372
379 tmio_core_mmc_pwr(tc6393xb->scr + 0x200, 0, state); 373 tmio_core_mmc_pwr(tc6393xb->scr + 0x200, 0, state);
380} 374}
381 375
382static void tc6393xb_mmc_clk_div(struct platform_device *mmc, int state) 376static void tc6393xb_mmc_clk_div(struct platform_device *mmc, int state)
383{ 377{
384 struct platform_device *dev = to_platform_device(mmc->dev.parent); 378 struct tc6393xb *tc6393xb = dev_get_drvdata(mmc->dev.parent);
385 struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
386 379
387 tmio_core_mmc_clk_div(tc6393xb->scr + 0x200, 0, state); 380 tmio_core_mmc_clk_div(tc6393xb->scr + 0x200, 0, state);
388} 381}
diff --git a/drivers/mfd/tps65912-spi.c b/drivers/mfd/tps65912-spi.c
index 3bd75061f777..f78be039e463 100644
--- a/drivers/mfd/tps65912-spi.c
+++ b/drivers/mfd/tps65912-spi.c
@@ -27,6 +27,7 @@ static const struct of_device_id tps65912_spi_of_match_table[] = {
27 { .compatible = "ti,tps65912", }, 27 { .compatible = "ti,tps65912", },
28 { /* sentinel */ } 28 { /* sentinel */ }
29}; 29};
30MODULE_DEVICE_TABLE(of, tps65912_spi_of_match_table);
30 31
31static int tps65912_spi_probe(struct spi_device *spi) 32static int tps65912_spi_probe(struct spi_device *spi)
32{ 33{
diff --git a/drivers/mfd/twl6040.c b/drivers/mfd/twl6040.c
index 7c3c5fd5fcd0..86052c5c6069 100644
--- a/drivers/mfd/twl6040.c
+++ b/drivers/mfd/twl6040.c
@@ -322,8 +322,19 @@ int twl6040_power(struct twl6040 *twl6040, int on)
322 } 322 }
323 } 323 }
324 324
325 /*
326 * Register access can produce errors after power-up unless we
327 * wait at least 8ms based on measurements on duovero.
328 */
329 usleep_range(10000, 12000);
330
325 /* Sync with the HW */ 331 /* Sync with the HW */
326 regcache_sync(twl6040->regmap); 332 ret = regcache_sync(twl6040->regmap);
333 if (ret) {
334 dev_err(twl6040->dev, "Failed to sync with the HW: %i\n",
335 ret);
336 goto out;
337 }
327 338
328 /* Default PLL configuration after power up */ 339 /* Default PLL configuration after power up */
329 twl6040->pll = TWL6040_SYSCLK_SEL_LPPLL; 340 twl6040->pll = TWL6040_SYSCLK_SEL_LPPLL;