summaryrefslogtreecommitdiff
path: root/drivers/mfd
diff options
context:
space:
mode:
authorStephen Rothwell <sfr@canb.auug.org.au>2019-05-02 14:30:50 +1000
committerStephen Rothwell <sfr@canb.auug.org.au>2019-05-02 14:30:50 +1000
commita5cfa7e2a85ed20fd41fe8d7ef0a5fd932e1f9f1 (patch)
tree73fe9b256b44aa268711e9086f4b2340f687a36a /drivers/mfd
parent7b8e2983b65e6f89b1079ce23049b3cdb7b54a5c (diff)
parent7f042743306c3a9dc071952065514e2ae1814c1a (diff)
downloadlinux-next-a5cfa7e2a85ed20fd41fe8d7ef0a5fd932e1f9f1.tar.gz
Merge remote-tracking branch 'mfd/for-mfd-next'
Diffstat (limited to 'drivers/mfd')
-rw-r--r--drivers/mfd/Kconfig62
-rw-r--r--drivers/mfd/atmel-hlcdc.c1
-rw-r--r--drivers/mfd/axp20x-i2c.c2
-rw-r--r--drivers/mfd/axp20x.c11
-rw-r--r--drivers/mfd/cros_ec_dev.c16
-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_soc_pmic_chtwc.c1
-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/syscon.c19
-rw-r--r--drivers/mfd/twl6040.c13
16 files changed, 127 insertions, 121 deletions
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 26ad6468d13a..d5a8e064965f 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -16,7 +16,7 @@ config MFD_CS5535
depends on PCI && (X86_32 || (X86 && COMPILE_TEST))
---help---
This is the core driver for CS5535/CS5536 MFD functions. This is
- necessary for using the board's GPIO and MFGPT functionality.
+ necessary for using the board's GPIO and MFGPT functionality.
config MFD_ALTERA_A10SR
bool "Altera Arria10 DevKit System Resource chip"
@@ -213,13 +213,13 @@ config MFD_CROS_EC
protocol for talking to the EC is defined by the bus driver.
config MFD_CROS_EC_CHARDEV
- tristate "Chrome OS Embedded Controller userspace device interface"
- depends on MFD_CROS_EC
- ---help---
- This driver adds support to talk with the ChromeOS EC from userspace.
+ tristate "Chrome OS Embedded Controller userspace device interface"
+ depends on MFD_CROS_EC
+ ---help---
+ This driver adds support to talk with the ChromeOS EC from userspace.
- If you have a supported Chromebook, choose Y or M here.
- The module will be called cros_ec_dev.
+ If you have a supported Chromebook, choose Y or M here.
+ The module will be called cros_ec_dev.
config MFD_MADERA
tristate "Cirrus Logic Madera codecs"
@@ -867,7 +867,7 @@ config MFD_CPCAP
At least Motorola Droid 4 is known to use CPCAP.
config MFD_VIPERBOARD
- tristate "Nano River Technologies Viperboard"
+ tristate "Nano River Technologies Viperboard"
select MFD_CORE
depends on USB
default n
@@ -903,15 +903,15 @@ config PCF50633_ADC
tristate "NXP PCF50633 ADC"
depends on MFD_PCF50633
help
- Say yes here if you want to include support for ADC in the
- NXP PCF50633 chip.
+ Say yes here if you want to include support for ADC in the
+ NXP PCF50633 chip.
config PCF50633_GPIO
tristate "NXP PCF50633 GPIO"
depends on MFD_PCF50633
help
- Say yes here if you want to include support GPIO for pins on
- the PCF50633 chip.
+ Say yes here if you want to include support GPIO for pins on
+ the PCF50633 chip.
config UCB1400_CORE
tristate "Philips UCB1400 Core driver"
@@ -1026,7 +1026,7 @@ config MFD_RN5T618
select REGMAP_I2C
help
Say yes here to add support for the Ricoh RN5T567,
- RN5T618, RC5T619 PMIC.
+ RN5T618, RC5T619 PMIC.
This driver provides common support for accessing the device,
additional drivers must be enabled in order to use the
functionality of the device.
@@ -1079,9 +1079,9 @@ config MFD_SM501_GPIO
bool "Export GPIO via GPIO layer"
depends on MFD_SM501 && GPIOLIB
---help---
- This option uses the gpio library layer to export the 64 GPIO
- lines on the SM501. The platform data is used to supply the
- base number for the first GPIO line to register.
+ This option uses the gpio library layer to export the 64 GPIO
+ lines on the SM501. The platform data is used to supply the
+ base number for the first GPIO line to register.
config MFD_SKY81452
tristate "Skyworks Solutions SKY81452"
@@ -1096,16 +1096,16 @@ config MFD_SKY81452
will be called sky81452.
config MFD_SMSC
- bool "SMSC ECE1099 series chips"
- depends on I2C=y
- select MFD_CORE
- select REGMAP_I2C
- help
- If you say yes here you get support for the
- ece1099 chips from SMSC.
+ bool "SMSC ECE1099 series chips"
+ depends on I2C=y
+ select MFD_CORE
+ select REGMAP_I2C
+ help
+ If you say yes here you get support for the
+ ece1099 chips from SMSC.
- To compile this driver as a module, choose M here: the
- module will be called smsc.
+ To compile this driver as a module, choose M here: the
+ module will be called smsc.
config MFD_SC27XX_PMIC
tristate "Spreadtrum SC27xx PMICs"
@@ -1171,12 +1171,12 @@ config AB8500_CORE
This chip embeds various other multimedia funtionalities as well.
config AB8500_DEBUG
- bool "Enable debug info via debugfs"
- depends on AB8500_GPADC && DEBUG_FS
- default y if DEBUG_FS
- help
- Select this option if you want debug information using the debug
- filesystem, debugfs.
+ bool "Enable debug info via debugfs"
+ depends on AB8500_GPADC && DEBUG_FS
+ default y if DEBUG_FS
+ help
+ Select this option if you want debug information using the debug
+ filesystem, debugfs.
config AB8500_GPADC
bool "ST-Ericsson AB8500 GPADC driver"
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[] = {
{ .compatible = "atmel,sama5d2-hlcdc" },
{ .compatible = "atmel,sama5d3-hlcdc" },
{ .compatible = "atmel,sama5d4-hlcdc" },
+ { .compatible = "microchip,sam9x60-hlcdc" },
{ /* sentinel */ },
};
MODULE_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[] = {
{ .compatible = "x-powers,axp202", .data = (void *)AXP202_ID },
{ .compatible = "x-powers,axp209", .data = (void *)AXP209_ID },
{ .compatible = "x-powers,axp221", .data = (void *)AXP221_ID },
+ { .compatible = "x-powers,axp223", .data = (void *)AXP223_ID },
{ .compatible = "x-powers,axp806", .data = (void *)AXP806_ID },
{ },
};
@@ -75,6 +76,7 @@ static const struct i2c_device_id axp20x_i2c_id[] = {
{ "axp202", 0 },
{ "axp209", 0 },
{ "axp221", 0 },
+ { "axp223", 0 },
{ "axp806", 0 },
{ },
};
diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
index 3c97f2c0fdfe..902f9f27e748 100644
--- a/drivers/mfd/axp20x.c
+++ b/drivers/mfd/axp20x.c
@@ -198,6 +198,12 @@ static const struct resource axp22x_usb_power_supply_resources[] = {
DEFINE_RES_IRQ_NAMED(AXP22X_IRQ_VBUS_REMOVAL, "VBUS_REMOVAL"),
};
+/* AXP803 and AXP813/AXP818 share the same interrupts */
+static const struct resource axp803_usb_power_supply_resources[] = {
+ DEFINE_RES_IRQ_NAMED(AXP803_IRQ_VBUS_PLUGIN, "VBUS_PLUGIN"),
+ DEFINE_RES_IRQ_NAMED(AXP803_IRQ_VBUS_REMOVAL, "VBUS_REMOVAL"),
+};
+
static const struct resource axp22x_pek_resources[] = {
DEFINE_RES_IRQ_NAMED(AXP22X_IRQ_PEK_RIS_EDGE, "PEK_DBR"),
DEFINE_RES_IRQ_NAMED(AXP22X_IRQ_PEK_FAL_EDGE, "PEK_DBF"),
@@ -793,6 +799,11 @@ static const struct mfd_cell axp813_cells[] = {
.of_compatible = "x-powers,axp813-ac-power-supply",
.num_resources = ARRAY_SIZE(axp20x_ac_power_supply_resources),
.resources = axp20x_ac_power_supply_resources,
+ }, {
+ .name = "axp20x-usb-power-supply",
+ .num_resources = ARRAY_SIZE(axp803_usb_power_supply_resources),
+ .resources = axp803_usb_power_supply_resources,
+ .of_compatible = "x-powers,axp813-usb-power-supply",
},
};
diff --git a/drivers/mfd/cros_ec_dev.c b/drivers/mfd/cros_ec_dev.c
index d275deaecb12..a3b319913097 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[] = {
};
static const struct mfd_cell cros_usbpd_charger_cells[] = {
- { .name = "cros-usbpd-charger" }
+ { .name = "cros-usbpd-charger" },
+ { .name = "cros-usbpd-logger" },
};
static const struct mfd_cell cros_ec_platform_cells[] = {
@@ -419,6 +420,19 @@ static int ec_device_probe(struct platform_device *pdev)
cdev_init(&ec->cdev, &fops);
/*
+ * Check whether this is actually an Integrated Sensor Hub (ISH)
+ * rather than an EC.
+ */
+ if (cros_ec_check_features(ec, EC_FEATURE_ISH)) {
+ dev_info(dev, "CrOS ISH MCU detected.\n");
+ /*
+ * Help userspace differentiating ECs from ISH MCU,
+ * regardless of the probing order.
+ */
+ ec_platform->ec_name = CROS_EC_DEV_ISH_NAME;
+ }
+
+ /*
* Add the class device
* Link to the character device for creating the /dev entry
* in devtmpfs.
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[] = {
{ 0x00000448, 0x0a83 }, /* R1096 (0x448) - eDRE Enable */
{ 0x0000044a, 0x0000 }, /* R1098 (0x44a) - eDRE Manual */
{ 0x00000450, 0x0000 }, /* R1104 (0x450) - DAC AEC Control 1 */
+ { 0x00000451, 0x0000 }, /* R1105 (0x451) - DAC AEC Control 2 */
{ 0x00000458, 0x0000 }, /* R1112 (0x458) - Noise Gate Control */
{ 0x00000490, 0x0069 }, /* R1168 (0x490) - PDM SPK1 CTRL 1 */
{ 0x00000491, 0x0000 }, /* R1169 (0x491) - PDM SPK1 CTRL 2 */
@@ -970,6 +971,7 @@ static bool cs47l35_16bit_readable_register(struct device *dev,
case MADERA_EDRE_ENABLE:
case MADERA_EDRE_MANUAL:
case MADERA_DAC_AEC_CONTROL_1:
+ case MADERA_DAC_AEC_CONTROL_2:
case MADERA_NOISE_GATE_CONTROL:
case MADERA_PDM_SPK1_CTRL_1:
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[] = {
{ 0x00000440, 0x003f }, /* R1088 (0x440) - DRE Enable */
{ 0x00000448, 0x003f }, /* R1096 (0x448) - eDRE Enable */
{ 0x00000450, 0x0000 }, /* R1104 (0x450) - DAC AEC Control 1 */
+ { 0x00000451, 0x0000 }, /* R1104 (0x450) - DAC AEC Control 2 */
{ 0x00000458, 0x0000 }, /* R1112 (0x458) - Noise Gate Control */
{ 0x00000490, 0x0069 }, /* R1168 (0x490) - PDM SPK1 CTRL 1 */
{ 0x00000491, 0x0000 }, /* R1169 (0x491) - PDM SPK1 CTRL 2 */
@@ -1692,6 +1693,7 @@ static bool cs47l90_16bit_readable_register(struct device *dev,
case MADERA_DRE_ENABLE:
case MADERA_EDRE_ENABLE:
case MADERA_DAC_AEC_CONTROL_1:
+ case MADERA_DAC_AEC_CONTROL_2:
case MADERA_NOISE_GATE_CONTROL:
case MADERA_PDM_SPK1_CTRL_1:
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 @@
+// SPDX-License-Identifier: GPL-2.0+
/*
- * da9063-core.c: Device access for Dialog DA9063 modules
+ * Device access for Dialog DA9063 modules
*
* Copyright 2012 Dialog Semiconductors Ltd.
* Copyright 2013 Philipp Zabel, Pengutronix
@@ -7,11 +8,6 @@
* Author: Krystian Garbaciak, Dialog Semiconductor
* Author: Michal Hajduk, Dialog Semiconductor
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
*/
#include <linux/kernel.h>
@@ -26,7 +22,6 @@
#include <linux/regmap.h>
#include <linux/mfd/da9063/core.h>
-#include <linux/mfd/da9063/pdata.h>
#include <linux/mfd/da9063/registers.h>
#include <linux/proc_fs.h>
@@ -165,7 +160,6 @@ static int da9063_clear_fault_log(struct da9063 *da9063)
int da9063_device_init(struct da9063 *da9063, unsigned int irq)
{
- struct da9063_pdata *pdata = da9063->dev->platform_data;
int model, variant_id, variant_code;
int ret;
@@ -173,24 +167,10 @@ int da9063_device_init(struct da9063 *da9063, unsigned int irq)
if (ret < 0)
dev_err(da9063->dev, "Cannot clear fault log\n");
- if (pdata) {
- da9063->flags = pdata->flags;
- da9063->irq_base = pdata->irq_base;
- } else {
- da9063->flags = 0;
- da9063->irq_base = -1;
- }
+ da9063->flags = 0;
+ da9063->irq_base = -1;
da9063->chip_irq = irq;
- if (pdata && pdata->init != NULL) {
- ret = pdata->init(da9063);
- if (ret != 0) {
- dev_err(da9063->dev,
- "Platform initialization failed.\n");
- return ret;
- }
- }
-
ret = regmap_read(da9063->regmap, DA9063_REG_CHIP_ID, &model);
if (ret < 0) {
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 @@
-/* da9063-i2c.c: Interrupt support for Dialog DA9063
+// SPDX-License-Identifier: GPL-2.0+
+/* I2C support for Dialog DA9063
*
* Copyright 2012 Dialog Semiconductor Ltd.
* Copyright 2013 Philipp Zabel, Pengutronix
*
* Author: Krystian Garbaciak, Dialog Semiconductor
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
*/
#include <linux/kernel.h>
@@ -22,7 +17,6 @@
#include <linux/mfd/core.h>
#include <linux/mfd/da9063/core.h>
-#include <linux/mfd/da9063/pdata.h>
#include <linux/mfd/da9063/registers.h>
#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 @@
-/* da9063-irq.c: Interrupts support for Dialog DA9063
+// SPDX-License-Identifier: GPL-2.0+
+/* Interrupt support for Dialog DA9063
*
* Copyright 2012 Dialog Semiconductor Ltd.
* Copyright 2013 Philipp Zabel, Pengutronix
*
* Author: Michal Hajduk, Dialog Semiconductor
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
*/
#include <linux/kernel.h>
@@ -19,7 +14,6 @@
#include <linux/interrupt.h>
#include <linux/regmap.h>
#include <linux/mfd/da9063/core.h>
-#include <linux/mfd/da9063/pdata.h>
#define DA9063_REG_EVENT_A_OFFSET 0
#define DA9063_REG_EVENT_B_OFFSET 1
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[] = {
.resources = cht_wc_ext_charger_resources,
},
{ .name = "cht_wcove_region", },
+ { .name = "cht_wcove_leds", },
};
/*
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)
return 0;
}
-static const struct i2c_device_id rk808_ids[] = {
- { "rk805" },
- { "rk808" },
- { "rk818" },
- { },
-};
-MODULE_DEVICE_TABLE(i2c, rk808_ids);
-
static struct i2c_driver rk808_i2c_driver = {
.driver = {
.name = "rk808",
@@ -583,7 +575,6 @@ static struct i2c_driver rk808_i2c_driver = {
},
.probe = rk808_probe,
.remove = rk808_remove,
- .id_table = rk808_ids,
};
module_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 @@
#include <linux/regmap.h>
static const struct mfd_cell s5m8751_devs[] = {
- {
- .name = "s5m8751-pmic",
- }, {
- .name = "s5m-charger",
- }, {
- .name = "s5m8751-codec",
- },
+ { .name = "s5m8751-pmic", },
+ { .name = "s5m-charger", },
+ { .name = "s5m8751-codec", },
};
static const struct mfd_cell s5m8763_devs[] = {
- {
- .name = "s5m8763-pmic",
- }, {
- .name = "s5m-rtc",
- }, {
- .name = "s5m-charger",
- },
+ { .name = "s5m8763-pmic", },
+ { .name = "s5m-rtc", },
+ { .name = "s5m-charger", },
};
static const struct mfd_cell s5m8767_devs[] = {
+ { .name = "s5m8767-pmic", },
+ { .name = "s5m-rtc", },
{
- .name = "s5m8767-pmic",
- }, {
- .name = "s5m-rtc",
- }, {
.name = "s5m8767-clk",
.of_compatible = "samsung,s5m8767-clk",
- }
+ },
};
static const struct mfd_cell s2mps11_devs[] = {
+ { .name = "s2mps11-regulator", },
+ { .name = "s2mps14-rtc", },
{
- .name = "s2mps11-regulator",
- }, {
- .name = "s2mps14-rtc",
- }, {
.name = "s2mps11-clk",
.of_compatible = "samsung,s2mps11-clk",
- }
+ },
};
static const struct mfd_cell s2mps13_devs[] = {
@@ -79,37 +67,30 @@ static const struct mfd_cell s2mps13_devs[] = {
};
static const struct mfd_cell s2mps14_devs[] = {
+ { .name = "s2mps14-regulator", },
+ { .name = "s2mps14-rtc", },
{
- .name = "s2mps14-regulator",
- }, {
- .name = "s2mps14-rtc",
- }, {
.name = "s2mps14-clk",
.of_compatible = "samsung,s2mps14-clk",
- }
+ },
};
static const struct mfd_cell s2mps15_devs[] = {
+ { .name = "s2mps15-regulator", },
+ { .name = "s2mps15-rtc", },
{
- .name = "s2mps15-regulator",
- }, {
- .name = "s2mps15-rtc",
- }, {
.name = "s2mps13-clk",
.of_compatible = "samsung,s2mps13-clk",
},
};
static const struct mfd_cell s2mpa01_devs[] = {
- {
- .name = "s2mpa01-pmic",
- },
+ { .name = "s2mpa01-pmic", },
+ { .name = "s2mps14-rtc", },
};
static const struct mfd_cell s2mpu02_devs[] = {
- {
- .name = "s2mpu02-regulator",
- },
+ { .name = "s2mpu02-regulator", },
};
#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)
case S5M8767X:
sec_irq_chip = &s5m8767_irq_chip;
break;
+ case S2MPA01:
+ sec_irq_chip = &s2mps14_irq_chip;
+ break;
case S2MPS11X:
sec_irq_chip = &s2mps11_irq_chip;
break;
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 @@
* (at your option) any later version.
*/
+#include <linux/clk.h>
#include <linux/err.h>
#include <linux/hwspinlock.h>
#include <linux/io.h>
@@ -45,6 +46,7 @@ static const struct regmap_config syscon_regmap_config = {
static struct syscon *of_syscon_register(struct device_node *np)
{
+ struct clk *clk;
struct syscon *syscon;
struct regmap *regmap;
void __iomem *base;
@@ -119,6 +121,18 @@ static struct syscon *of_syscon_register(struct device_node *np)
goto err_regmap;
}
+ clk = of_clk_get(np, 0);
+ if (IS_ERR(clk)) {
+ ret = PTR_ERR(clk);
+ /* clock is optional */
+ if (ret != -ENOENT)
+ goto err_clk;
+ } else {
+ ret = regmap_mmio_attach_clk(regmap, clk);
+ if (ret)
+ goto err_attach;
+ }
+
syscon->regmap = regmap;
syscon->np = np;
@@ -128,6 +142,11 @@ static struct syscon *of_syscon_register(struct device_node *np)
return syscon;
+err_attach:
+ if (!IS_ERR(clk))
+ clk_put(clk);
+err_clk:
+ regmap_exit(regmap);
err_regmap:
iounmap(base);
err_map:
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)
}
}
+ /*
+ * Register access can produce errors after power-up unless we
+ * wait at least 8ms based on measurements on duovero.
+ */
+ usleep_range(10000, 12000);
+
/* Sync with the HW */
- regcache_sync(twl6040->regmap);
+ ret = regcache_sync(twl6040->regmap);
+ if (ret) {
+ dev_err(twl6040->dev, "Failed to sync with the HW: %i\n",
+ ret);
+ goto out;
+ }
/* Default PLL configuration after power up */
twl6040->pll = TWL6040_SYSCLK_SEL_LPPLL;