aboutsummaryrefslogtreecommitdiff
path: root/drivers/mfd
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mfd')
-rw-r--r--drivers/mfd/Kconfig6
-rw-r--r--drivers/mfd/asic3.c9
-rw-r--r--drivers/mfd/atmel-smc.c4
-rw-r--r--drivers/mfd/axp20x.c9
-rw-r--r--drivers/mfd/bcm2835-pm.c74
-rw-r--r--drivers/mfd/cros_ec_dev.c9
-rw-r--r--drivers/mfd/db8500-prcmu.c2
-rw-r--r--drivers/mfd/dln2.c17
-rw-r--r--drivers/mfd/intel-lpss-pci.c13
-rw-r--r--drivers/mfd/intel-m10-bmc.c2
-rw-r--r--drivers/mfd/intel_soc_pmic_bxtwc.c194
-rw-r--r--drivers/mfd/intel_soc_pmic_chtwc.c27
-rw-r--r--drivers/mfd/lp873x.c10
-rw-r--r--drivers/mfd/lpc_ich.c161
-rw-r--r--drivers/mfd/max77620.c2
-rw-r--r--drivers/mfd/max77714.c4
-rw-r--r--drivers/mfd/mfd-core.c31
-rw-r--r--drivers/mfd/mt6358-irq.c24
-rw-r--r--drivers/mfd/mt6397-core.c91
-rw-r--r--drivers/mfd/mt6397-irq.c9
-rw-r--r--drivers/mfd/qcom-pm8008.c53
-rw-r--r--drivers/mfd/qcom-spmi-pmic.c272
-rw-r--r--drivers/mfd/syscon.c3
-rw-r--r--drivers/mfd/t7l66xb.c6
-rw-r--r--drivers/mfd/tc6393xb.c5
-rw-r--r--drivers/mfd/tps65086.c10
-rw-r--r--drivers/mfd/tps65217.c10
-rw-r--r--drivers/mfd/tps65218.c10
-rw-r--r--drivers/mfd/tps65912-core.c10
-rw-r--r--drivers/mfd/tps65912-i2c.c10
-rw-r--r--drivers/mfd/tps65912-spi.c10
-rw-r--r--drivers/mfd/twl-core.c323
-rw-r--r--drivers/mfd/ucb1400_core.c6
33 files changed, 680 insertions, 746 deletions
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 3b59456f5545..abb58ab1a1a4 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -572,6 +572,7 @@ config LPC_ICH
tristate "Intel ICH LPC"
depends on PCI
select MFD_CORE
+ select P2SB if X86
help
The LPC bridge function of the Intel ICH provides support for
many functional units. This driver provides needed support for
@@ -1357,12 +1358,13 @@ config MFD_STA2X11
select REGMAP_MMIO
config MFD_SUN6I_PRCM
- bool "Allwinner A31 PRCM controller"
+ bool "Allwinner A31/A23/A33 PRCM controller"
depends on ARCH_SUNXI || COMPILE_TEST
select MFD_CORE
help
Support for the PRCM (Power/Reset/Clock Management) unit available
- in A31 SoC.
+ in the A31, A23, and A33 SoCs. Other Allwinner SoCs contain similar
+ hardware, but they do not use this driver.
config MFD_SYSCON
bool "System Controller Register R/W Based on Regmap"
diff --git a/drivers/mfd/asic3.c b/drivers/mfd/asic3.c
index 56338f9dbd0b..4fb7e35eb5ed 100644
--- a/drivers/mfd/asic3.c
+++ b/drivers/mfd/asic3.c
@@ -596,12 +596,11 @@ static __init int asic3_gpio_probe(struct platform_device *pdev,
return gpiochip_add_data(&asic->gpio, asic);
}
-static int asic3_gpio_remove(struct platform_device *pdev)
+static void asic3_gpio_remove(struct platform_device *pdev)
{
struct asic3 *asic = platform_get_drvdata(pdev);
gpiochip_remove(&asic->gpio);
- return 0;
}
static void asic3_clk_enable(struct asic3 *asic, struct asic3_clk *clk)
@@ -1030,7 +1029,6 @@ static int __init asic3_probe(struct platform_device *pdev)
static int asic3_remove(struct platform_device *pdev)
{
- int ret;
struct asic3 *asic = platform_get_drvdata(pdev);
asic3_set_register(asic, ASIC3_OFFSET(EXTCF, SELECT),
@@ -1038,9 +1036,8 @@ static int asic3_remove(struct platform_device *pdev)
asic3_mfd_remove(pdev);
- ret = asic3_gpio_remove(pdev);
- if (ret < 0)
- return ret;
+ asic3_gpio_remove(pdev);
+
asic3_irq_remove(pdev);
asic3_write_register(asic, ASIC3_OFFSET(CLOCK, SEL), 0);
diff --git a/drivers/mfd/atmel-smc.c b/drivers/mfd/atmel-smc.c
index d96f1d689e7f..f3bad2b52f17 100644
--- a/drivers/mfd/atmel-smc.c
+++ b/drivers/mfd/atmel-smc.c
@@ -240,7 +240,7 @@ EXPORT_SYMBOL_GPL(atmel_smc_cs_conf_set_cycle);
* @conf: the SMC CS conf to apply
*
* Applies an SMC CS configuration.
- * Only valid on at91sam9/avr32 SoCs.
+ * Only valid on at91sam9 SoCs.
*/
void atmel_smc_cs_conf_apply(struct regmap *regmap, int cs,
const struct atmel_smc_cs_conf *conf)
@@ -281,7 +281,7 @@ EXPORT_SYMBOL_GPL(atmel_hsmc_cs_conf_apply);
* @conf: the SMC CS conf object to store the current conf
*
* Retrieve the SMC CS configuration.
- * Only valid on at91sam9/avr32 SoCs.
+ * Only valid on at91sam9 SoCs.
*/
void atmel_smc_cs_conf_get(struct regmap *regmap, int cs,
struct atmel_smc_cs_conf *conf)
diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
index 8161a5dc68e8..88a212a8168c 100644
--- a/drivers/mfd/axp20x.c
+++ b/drivers/mfd/axp20x.c
@@ -619,6 +619,9 @@ static const struct mfd_cell axp20x_cells[] = {
static const struct mfd_cell axp221_cells[] = {
{
+ .name = "axp20x-gpio",
+ .of_compatible = "x-powers,axp221-gpio",
+ }, {
.name = "axp221-pek",
.num_resources = ARRAY_SIZE(axp22x_pek_resources),
.resources = axp22x_pek_resources,
@@ -645,6 +648,9 @@ static const struct mfd_cell axp221_cells[] = {
static const struct mfd_cell axp223_cells[] = {
{
+ .name = "axp20x-gpio",
+ .of_compatible = "x-powers,axp221-gpio",
+ }, {
.name = "axp221-pek",
.num_resources = ARRAY_SIZE(axp22x_pek_resources),
.resources = axp22x_pek_resources,
@@ -785,6 +791,9 @@ static const struct mfd_cell axp806_cells[] = {
static const struct mfd_cell axp809_cells[] = {
{
+ .name = "axp20x-gpio",
+ .of_compatible = "x-powers,axp221-gpio",
+ }, {
.name = "axp221-pek",
.num_resources = ARRAY_SIZE(axp809_pek_resources),
.resources = axp809_pek_resources,
diff --git a/drivers/mfd/bcm2835-pm.c b/drivers/mfd/bcm2835-pm.c
index 42fe67f1538e..49cd1f03884a 100644
--- a/drivers/mfd/bcm2835-pm.c
+++ b/drivers/mfd/bcm2835-pm.c
@@ -25,9 +25,52 @@ static const struct mfd_cell bcm2835_power_devs[] = {
{ .name = "bcm2835-power" },
};
+static int bcm2835_pm_get_pdata(struct platform_device *pdev,
+ struct bcm2835_pm *pm)
+{
+ if (of_find_property(pm->dev->of_node, "reg-names", NULL)) {
+ struct resource *res;
+
+ pm->base = devm_platform_ioremap_resource_byname(pdev, "pm");
+ if (IS_ERR(pm->base))
+ return PTR_ERR(pm->base);
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "asb");
+ if (res) {
+ pm->asb = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(pm->asb))
+ pm->asb = NULL;
+ }
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+ "rpivid_asb");
+ if (res) {
+ pm->rpivid_asb = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(pm->rpivid_asb))
+ pm->rpivid_asb = NULL;
+ }
+
+ return 0;
+ }
+
+ /* If no 'reg-names' property is found we can assume we're using old DTB. */
+ pm->base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(pm->base))
+ return PTR_ERR(pm->base);
+
+ pm->asb = devm_platform_ioremap_resource(pdev, 1);
+ if (IS_ERR(pm->asb))
+ pm->asb = NULL;
+
+ pm->rpivid_asb = devm_platform_ioremap_resource(pdev, 2);
+ if (IS_ERR(pm->rpivid_asb))
+ pm->rpivid_asb = NULL;
+
+ return 0;
+}
+
static int bcm2835_pm_probe(struct platform_device *pdev)
{
- struct resource *res;
struct device *dev = &pdev->dev;
struct bcm2835_pm *pm;
int ret;
@@ -39,10 +82,9 @@ static int bcm2835_pm_probe(struct platform_device *pdev)
pm->dev = dev;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- pm->base = devm_ioremap_resource(dev, res);
- if (IS_ERR(pm->base))
- return PTR_ERR(pm->base);
+ ret = bcm2835_pm_get_pdata(pdev, pm);
+ if (ret)
+ return ret;
ret = devm_mfd_add_devices(dev, -1,
bcm2835_pm_devs, ARRAY_SIZE(bcm2835_pm_devs),
@@ -50,30 +92,22 @@ static int bcm2835_pm_probe(struct platform_device *pdev)
if (ret)
return ret;
- /* We'll use the presence of the AXI ASB regs in the
+ /*
+ * We'll use the presence of the AXI ASB regs in the
* bcm2835-pm binding as the key for whether we can reference
* the full PM register range and support power domains.
*/
- res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
- if (res) {
- pm->asb = devm_ioremap_resource(dev, res);
- if (IS_ERR(pm->asb))
- return PTR_ERR(pm->asb);
-
- ret = devm_mfd_add_devices(dev, -1,
- bcm2835_power_devs,
- ARRAY_SIZE(bcm2835_power_devs),
- NULL, 0, NULL);
- if (ret)
- return ret;
- }
-
+ if (pm->asb)
+ return devm_mfd_add_devices(dev, -1, bcm2835_power_devs,
+ ARRAY_SIZE(bcm2835_power_devs),
+ NULL, 0, NULL);
return 0;
}
static const struct of_device_id bcm2835_pm_of_match[] = {
{ .compatible = "brcm,bcm2835-pm-wdt", },
{ .compatible = "brcm,bcm2835-pm", },
+ { .compatible = "brcm,bcm2711-pm", },
{},
};
MODULE_DEVICE_TABLE(of, bcm2835_pm_of_match);
diff --git a/drivers/mfd/cros_ec_dev.c b/drivers/mfd/cros_ec_dev.c
index 596731caf407..344ad03bdc42 100644
--- a/drivers/mfd/cros_ec_dev.c
+++ b/drivers/mfd/cros_ec_dev.c
@@ -65,6 +65,11 @@ static const struct cros_feature_to_name cros_mcu_devices[] = {
.desc = "System Control Processor",
},
{
+ .id = EC_FEATURE_SCP_C1,
+ .name = CROS_EC_DEV_SCP_C1_NAME,
+ .desc = "System Control Processor 2nd Core",
+ },
+ {
.id = EC_FEATURE_TOUCHPAD,
.name = CROS_EC_DEV_TP_NAME,
.desc = "Touchpad",
@@ -250,8 +255,8 @@ static int ec_device_probe(struct platform_device *pdev)
* The PCHG device cannot be detected by sending EC_FEATURE_GET_CMD, but
* it can be detected by querying the number of peripheral chargers.
*/
- retval = cros_ec_command(ec->ec_dev, 0, EC_CMD_PCHG_COUNT, NULL, 0,
- &pchg_count, sizeof(pchg_count));
+ retval = cros_ec_cmd(ec->ec_dev, 0, EC_CMD_PCHG_COUNT, NULL, 0,
+ &pchg_count, sizeof(pchg_count));
if (retval >= 0 && pchg_count.port_count) {
retval = mfd_add_hotplug_devices(ec->dev,
cros_ec_pchg_cells,
diff --git a/drivers/mfd/db8500-prcmu.c b/drivers/mfd/db8500-prcmu.c
index 56c61c99eb23..27a881da4d6e 100644
--- a/drivers/mfd/db8500-prcmu.c
+++ b/drivers/mfd/db8500-prcmu.c
@@ -798,7 +798,7 @@ void db8500_prcmu_get_abb_event_buffer(void __iomem **buf)
* @opp: The new ARM operating point to which transition is to be made
* Returns: 0 on success, non-zero on failure
*
- * This function sets the the operating point of the ARM.
+ * This function sets the operating point of the ARM.
*/
int db8500_prcmu_set_arm_opp(u8 opp)
{
diff --git a/drivers/mfd/dln2.c b/drivers/mfd/dln2.c
index 852129ea0766..6cd0b0c752d6 100644
--- a/drivers/mfd/dln2.c
+++ b/drivers/mfd/dln2.c
@@ -91,11 +91,6 @@ struct dln2_mod_rx_slots {
spinlock_t lock;
};
-enum dln2_endpoint {
- DLN2_EP_OUT = 0,
- DLN2_EP_IN = 1,
-};
-
struct dln2_dev {
struct usb_device *usb_dev;
struct usb_interface *interface;
@@ -777,16 +772,12 @@ static int dln2_probe(struct usb_interface *interface,
int ret;
int i, j;
- if (hostif->desc.bInterfaceNumber != 0 ||
- hostif->desc.bNumEndpoints < 2)
+ if (hostif->desc.bInterfaceNumber != 0)
return -ENODEV;
- epout = &hostif->endpoint[DLN2_EP_OUT].desc;
- if (!usb_endpoint_is_bulk_out(epout))
- return -ENODEV;
- epin = &hostif->endpoint[DLN2_EP_IN].desc;
- if (!usb_endpoint_is_bulk_in(epin))
- return -ENODEV;
+ ret = usb_find_common_endpoints(hostif, &epin, &epout, NULL, NULL);
+ if (ret)
+ return ret;
dln2 = kzalloc(sizeof(*dln2), GFP_KERNEL);
if (!dln2)
diff --git a/drivers/mfd/intel-lpss-pci.c b/drivers/mfd/intel-lpss-pci.c
index f7950d2197df..bb08b7a73fe1 100644
--- a/drivers/mfd/intel-lpss-pci.c
+++ b/drivers/mfd/intel-lpss-pci.c
@@ -385,6 +385,19 @@ static const struct pci_device_id intel_lpss_pci_ids[] = {
{ PCI_VDEVICE(INTEL, 0x7afc), (kernel_ulong_t)&bxt_i2c_info },
{ PCI_VDEVICE(INTEL, 0x7afd), (kernel_ulong_t)&bxt_i2c_info },
{ PCI_VDEVICE(INTEL, 0x7afe), (kernel_ulong_t)&bxt_uart_info },
+ /* MTL-P */
+ { PCI_VDEVICE(INTEL, 0x7e25), (kernel_ulong_t)&bxt_uart_info },
+ { PCI_VDEVICE(INTEL, 0x7e26), (kernel_ulong_t)&bxt_uart_info },
+ { PCI_VDEVICE(INTEL, 0x7e27), (kernel_ulong_t)&bxt_info },
+ { PCI_VDEVICE(INTEL, 0x7e30), (kernel_ulong_t)&bxt_info },
+ { PCI_VDEVICE(INTEL, 0x7e46), (kernel_ulong_t)&bxt_info },
+ { PCI_VDEVICE(INTEL, 0x7e50), (kernel_ulong_t)&bxt_i2c_info },
+ { PCI_VDEVICE(INTEL, 0x7e51), (kernel_ulong_t)&bxt_i2c_info },
+ { PCI_VDEVICE(INTEL, 0x7e52), (kernel_ulong_t)&bxt_uart_info },
+ { PCI_VDEVICE(INTEL, 0x7e78), (kernel_ulong_t)&bxt_i2c_info },
+ { PCI_VDEVICE(INTEL, 0x7e79), (kernel_ulong_t)&bxt_i2c_info },
+ { PCI_VDEVICE(INTEL, 0x7e7a), (kernel_ulong_t)&bxt_i2c_info },
+ { PCI_VDEVICE(INTEL, 0x7e7b), (kernel_ulong_t)&bxt_i2c_info },
/* LKF */
{ PCI_VDEVICE(INTEL, 0x98a8), (kernel_ulong_t)&bxt_uart_info },
{ PCI_VDEVICE(INTEL, 0x98a9), (kernel_ulong_t)&bxt_uart_info },
diff --git a/drivers/mfd/intel-m10-bmc.c b/drivers/mfd/intel-m10-bmc.c
index 8db3bcf5fccc..f4d0d72573c8 100644
--- a/drivers/mfd/intel-m10-bmc.c
+++ b/drivers/mfd/intel-m10-bmc.c
@@ -26,7 +26,7 @@ static struct mfd_cell m10bmc_d5005_subdevs[] = {
static struct mfd_cell m10bmc_pacn3000_subdevs[] = {
{ .name = "n3000bmc-hwmon" },
{ .name = "n3000bmc-retimer" },
- { .name = "n3000bmc-secure" },
+ { .name = "n3000bmc-sec-update" },
};
static struct mfd_cell m10bmc_n5010_subdevs[] = {
diff --git a/drivers/mfd/intel_soc_pmic_bxtwc.c b/drivers/mfd/intel_soc_pmic_bxtwc.c
index bc069c4daa60..8dac0d41f64f 100644
--- a/drivers/mfd/intel_soc_pmic_bxtwc.c
+++ b/drivers/mfd/intel_soc_pmic_bxtwc.c
@@ -2,10 +2,11 @@
/*
* MFD core driver for Intel Broxton Whiskey Cove PMIC
*
- * Copyright (C) 2015 Intel Corporation. All rights reserved.
+ * Copyright (C) 2015-2017, 2022 Intel Corporation. All rights reserved.
*/
#include <linux/acpi.h>
+#include <linux/bits.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/interrupt.h>
@@ -18,9 +19,9 @@
#include <asm/intel_scu_ipc.h>
/* PMIC device registers */
-#define REG_ADDR_MASK 0xFF00
+#define REG_ADDR_MASK GENMASK(15, 8)
#define REG_ADDR_SHIFT 8
-#define REG_OFFSET_MASK 0xFF
+#define REG_OFFSET_MASK GENMASK(7, 0)
/* Interrupt Status Registers */
#define BXTWC_IRQLVL1 0x4E02
@@ -112,29 +113,29 @@ static const struct regmap_irq bxtwc_regmap_irqs[] = {
};
static const struct regmap_irq bxtwc_regmap_irqs_pwrbtn[] = {
- REGMAP_IRQ_REG(BXTWC_PWRBTN_IRQ, 0, 0x01),
+ REGMAP_IRQ_REG(BXTWC_PWRBTN_IRQ, 0, BIT(0)),
};
static const struct regmap_irq bxtwc_regmap_irqs_bcu[] = {
- REGMAP_IRQ_REG(BXTWC_BCU_IRQ, 0, 0x1f),
+ REGMAP_IRQ_REG(BXTWC_BCU_IRQ, 0, GENMASK(4, 0)),
};
static const struct regmap_irq bxtwc_regmap_irqs_adc[] = {
- REGMAP_IRQ_REG(BXTWC_ADC_IRQ, 0, 0xff),
+ REGMAP_IRQ_REG(BXTWC_ADC_IRQ, 0, GENMASK(7, 0)),
};
static const struct regmap_irq bxtwc_regmap_irqs_chgr[] = {
- REGMAP_IRQ_REG(BXTWC_USBC_IRQ, 0, 0x20),
- REGMAP_IRQ_REG(BXTWC_CHGR0_IRQ, 0, 0x1f),
- REGMAP_IRQ_REG(BXTWC_CHGR1_IRQ, 1, 0x1f),
+ REGMAP_IRQ_REG(BXTWC_USBC_IRQ, 0, BIT(5)),
+ REGMAP_IRQ_REG(BXTWC_CHGR0_IRQ, 0, GENMASK(4, 0)),
+ REGMAP_IRQ_REG(BXTWC_CHGR1_IRQ, 1, GENMASK(4, 0)),
};
static const struct regmap_irq bxtwc_regmap_irqs_tmu[] = {
- REGMAP_IRQ_REG(BXTWC_TMU_IRQ, 0, 0x06),
+ REGMAP_IRQ_REG(BXTWC_TMU_IRQ, 0, GENMASK(2, 1)),
};
static const struct regmap_irq bxtwc_regmap_irqs_crit[] = {
- REGMAP_IRQ_REG(BXTWC_CRIT_IRQ, 0, 0x03),
+ REGMAP_IRQ_REG(BXTWC_CRIT_IRQ, 0, GENMASK(1, 0)),
};
static struct regmap_irq_chip bxtwc_regmap_irq_chip = {
@@ -333,17 +334,19 @@ static unsigned long bxtwc_reg_addr;
static ssize_t addr_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
- return sprintf(buf, "0x%lx\n", bxtwc_reg_addr);
+ return sysfs_emit(buf, "0x%lx\n", bxtwc_reg_addr);
}
static ssize_t addr_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
- if (kstrtoul(buf, 0, &bxtwc_reg_addr)) {
- dev_err(dev, "Invalid register address\n");
- return -EINVAL;
- }
- return (ssize_t)count;
+ int ret;
+
+ ret = kstrtoul(buf, 0, &bxtwc_reg_addr);
+ if (ret)
+ return ret;
+
+ return count;
}
static ssize_t val_show(struct device *dev,
@@ -354,12 +357,12 @@ static ssize_t val_show(struct device *dev,
struct intel_soc_pmic *pmic = dev_get_drvdata(dev);
ret = regmap_read(pmic->regmap, bxtwc_reg_addr, &val);
- if (ret < 0) {
+ if (ret) {
dev_err(dev, "Failed to read 0x%lx\n", bxtwc_reg_addr);
- return -EIO;
+ return ret;
}
- return sprintf(buf, "0x%02x\n", val);
+ return sysfs_emit(buf, "0x%02x\n", val);
}
static ssize_t val_store(struct device *dev,
@@ -377,7 +380,7 @@ static ssize_t val_store(struct device *dev,
if (ret) {
dev_err(dev, "Failed to write value 0x%02x to address 0x%lx",
val, bxtwc_reg_addr);
- return -EIO;
+ return ret;
}
return count;
}
@@ -394,6 +397,11 @@ static const struct attribute_group bxtwc_group = {
.attrs = bxtwc_attrs,
};
+static const struct attribute_group *bxtwc_groups[] = {
+ &bxtwc_group,
+ NULL
+};
+
static const struct regmap_config bxtwc_regmap_config = {
.reg_bits = 16,
.val_bits = 8,
@@ -410,12 +418,9 @@ static int bxtwc_add_chained_irq_chip(struct intel_soc_pmic *pmic,
int irq;
irq = regmap_irq_get_virq(pdata, pirq);
- if (irq < 0) {
- dev_err(pmic->dev,
- "Failed to get parent vIRQ(%d) for chip %s, ret:%d\n",
- pirq, chip->name, irq);
- return irq;
- }
+ if (irq < 0)
+ return dev_err_probe(pmic->dev, irq, "Failed to get parent vIRQ(%d) for chip %s\n",
+ pirq, chip->name);
return devm_regmap_add_irq_chip(pmic->dev, pmic->regmap, irq, irq_flags,
0, chip, data);
@@ -423,25 +428,19 @@ static int bxtwc_add_chained_irq_chip(struct intel_soc_pmic *pmic,
static int bxtwc_probe(struct platform_device *pdev)
{
+ struct device *dev = &pdev->dev;
int ret;
- acpi_handle handle;
acpi_status status;
unsigned long long hrv;
struct intel_soc_pmic *pmic;
- handle = ACPI_HANDLE(&pdev->dev);
- status = acpi_evaluate_integer(handle, "_HRV", NULL, &hrv);
- if (ACPI_FAILURE(status)) {
- dev_err(&pdev->dev, "Failed to get PMIC hardware revision\n");
- return -ENODEV;
- }
- if (hrv != BROXTON_PMIC_WC_HRV) {
- dev_err(&pdev->dev, "Invalid PMIC hardware revision: %llu\n",
- hrv);
- return -ENODEV;
- }
+ status = acpi_evaluate_integer(ACPI_HANDLE(dev), "_HRV", NULL, &hrv);
+ if (ACPI_FAILURE(status))
+ return dev_err_probe(dev, -ENODEV, "Failed to get PMIC hardware revision\n");
+ if (hrv != BROXTON_PMIC_WC_HRV)
+ return dev_err_probe(dev, -ENODEV, "Invalid PMIC hardware revision: %llu\n", hrv);
- pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL);
+ pmic = devm_kzalloc(dev, sizeof(*pmic), GFP_KERNEL);
if (!pmic)
return -ENOMEM;
@@ -450,49 +449,39 @@ static int bxtwc_probe(struct platform_device *pdev)
return ret;
pmic->irq = ret;
- dev_set_drvdata(&pdev->dev, pmic);
- pmic->dev = &pdev->dev;
+ platform_set_drvdata(pdev, pmic);
+ pmic->dev = dev;
- pmic->scu = devm_intel_scu_ipc_dev_get(&pdev->dev);
+ pmic->scu = devm_intel_scu_ipc_dev_get(dev);
if (!pmic->scu)
return -EPROBE_DEFER;
- pmic->regmap = devm_regmap_init(&pdev->dev, NULL, pmic,
- &bxtwc_regmap_config);
- if (IS_ERR(pmic->regmap)) {
- ret = PTR_ERR(pmic->regmap);
- dev_err(&pdev->dev, "Failed to initialise regmap: %d\n", ret);
- return ret;
- }
+ pmic->regmap = devm_regmap_init(dev, NULL, pmic, &bxtwc_regmap_config);
+ if (IS_ERR(pmic->regmap))
+ return dev_err_probe(dev, PTR_ERR(pmic->regmap), "Failed to initialise regmap\n");
- ret = devm_regmap_add_irq_chip(&pdev->dev, pmic->regmap, pmic->irq,
+ ret = devm_regmap_add_irq_chip(dev, pmic->regmap, pmic->irq,
IRQF_ONESHOT | IRQF_SHARED,
0, &bxtwc_regmap_irq_chip,
&pmic->irq_chip_data);
- if (ret) {
- dev_err(&pdev->dev, "Failed to add IRQ chip\n");
- return ret;
- }
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to add IRQ chip\n");
ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data,
BXTWC_PWRBTN_LVL1_IRQ,
IRQF_ONESHOT,
&bxtwc_regmap_irq_chip_pwrbtn,
&pmic->irq_chip_data_pwrbtn);
- if (ret) {
- dev_err(&pdev->dev, "Failed to add PWRBTN IRQ chip\n");
- return ret;
- }
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to add PWRBTN IRQ chip\n");
ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data,
BXTWC_TMU_LVL1_IRQ,
IRQF_ONESHOT,
&bxtwc_regmap_irq_chip_tmu,
&pmic->irq_chip_data_tmu);
- if (ret) {
- dev_err(&pdev->dev, "Failed to add TMU IRQ chip\n");
- return ret;
- }
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to add TMU IRQ chip\n");
/* Add chained IRQ handler for BCU IRQs */
ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data,
@@ -500,12 +489,8 @@ static int bxtwc_probe(struct platform_device *pdev)
IRQF_ONESHOT,
&bxtwc_regmap_irq_chip_bcu,
&pmic->irq_chip_data_bcu);
-
-
- if (ret) {
- dev_err(&pdev->dev, "Failed to add BUC IRQ chip\n");
- return ret;
- }
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to add BUC IRQ chip\n");
/* Add chained IRQ handler for ADC IRQs */
ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data,
@@ -513,12 +498,8 @@ static int bxtwc_probe(struct platform_device *pdev)
IRQF_ONESHOT,
&bxtwc_regmap_irq_chip_adc,
&pmic->irq_chip_data_adc);
-
-
- if (ret) {
- dev_err(&pdev->dev, "Failed to add ADC IRQ chip\n");
- return ret;
- }
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to add ADC IRQ chip\n");
/* Add chained IRQ handler for CHGR IRQs */
ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data,
@@ -526,12 +507,8 @@ static int bxtwc_probe(struct platform_device *pdev)
IRQF_ONESHOT,
&bxtwc_regmap_irq_chip_chgr,
&pmic->irq_chip_data_chgr);
-
-
- if (ret) {
- dev_err(&pdev->dev, "Failed to add CHGR IRQ chip\n");
- return ret;
- }
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to add CHGR IRQ chip\n");
/* Add chained IRQ handler for CRIT IRQs */
ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data,
@@ -539,54 +516,33 @@ static int bxtwc_probe(struct platform_device *pdev)
IRQF_ONESHOT,
&bxtwc_regmap_irq_chip_crit,
&pmic->irq_chip_data_crit);
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to add CRIT IRQ chip\n");
-
- if (ret) {
- dev_err(&pdev->dev, "Failed to add CRIT IRQ chip\n");
- return ret;
- }
-
- ret = devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_NONE, bxt_wc_dev,
- ARRAY_SIZE(bxt_wc_dev), NULL, 0, NULL);
- if (ret) {
- dev_err(&pdev->dev, "Failed to add devices\n");
- return ret;
- }
-
- ret = sysfs_create_group(&pdev->dev.kobj, &bxtwc_group);
- if (ret) {
- dev_err(&pdev->dev, "Failed to create sysfs group %d\n", ret);
- return ret;
- }
+ ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE, bxt_wc_dev, ARRAY_SIZE(bxt_wc_dev),
+ NULL, 0, NULL);
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to add devices\n");
/*
- * There is known hw bug. Upon reset BIT 5 of register
+ * There is a known H/W bug. Upon reset, BIT 5 of register
* BXTWC_CHGR_LVL1_IRQ is 0 which is the expected value. However,
* later it's set to 1(masked) automatically by hardware. So we
- * have the software workaround here to unmaksed it in order to let
- * charger interrutp work.
+ * place the software workaround here to unmask it again in order
+ * to re-enable the charger interrupt.
*/
- regmap_update_bits(pmic->regmap, BXTWC_MIRQLVL1,
- BXTWC_MIRQLVL1_MCHGR, 0);
-
- return 0;
-}
-
-static int bxtwc_remove(struct platform_device *pdev)
-{
- sysfs_remove_group(&pdev->dev.kobj, &bxtwc_group);
+ regmap_update_bits(pmic->regmap, BXTWC_MIRQLVL1, BXTWC_MIRQLVL1_MCHGR, 0);
return 0;
}
static void bxtwc_shutdown(struct platform_device *pdev)
{
- struct intel_soc_pmic *pmic = dev_get_drvdata(&pdev->dev);
+ struct intel_soc_pmic *pmic = platform_get_drvdata(pdev);
disable_irq(pmic->irq);
}
-#ifdef CONFIG_PM_SLEEP
static int bxtwc_suspend(struct device *dev)
{
struct intel_soc_pmic *pmic = dev_get_drvdata(dev);
@@ -603,8 +559,8 @@ static int bxtwc_resume(struct device *dev)
enable_irq(pmic->irq);
return 0;
}
-#endif
-static SIMPLE_DEV_PM_OPS(bxtwc_pm_ops, bxtwc_suspend, bxtwc_resume);
+
+static DEFINE_SIMPLE_DEV_PM_OPS(bxtwc_pm_ops, bxtwc_suspend, bxtwc_resume);
static const struct acpi_device_id bxtwc_acpi_ids[] = {
{ "INT34D3", },
@@ -614,16 +570,16 @@ MODULE_DEVICE_TABLE(acpi, bxtwc_acpi_ids);
static struct platform_driver bxtwc_driver = {
.probe = bxtwc_probe,
- .remove = bxtwc_remove,
.shutdown = bxtwc_shutdown,
.driver = {
.name = "BXTWC PMIC",
- .pm = &bxtwc_pm_ops,
- .acpi_match_table = ACPI_PTR(bxtwc_acpi_ids),
+ .pm = pm_sleep_ptr(&bxtwc_pm_ops),
+ .acpi_match_table = bxtwc_acpi_ids,
+ .dev_groups = bxtwc_groups,
},
};
module_platform_driver(bxtwc_driver);
MODULE_LICENSE("GPL v2");
-MODULE_AUTHOR("Qipeng Zha<[email protected]>");
+MODULE_AUTHOR("Qipeng Zha <[email protected]>");
diff --git a/drivers/mfd/intel_soc_pmic_chtwc.c b/drivers/mfd/intel_soc_pmic_chtwc.c
index 4eab191e053a..9216f0d34206 100644
--- a/drivers/mfd/intel_soc_pmic_chtwc.c
+++ b/drivers/mfd/intel_soc_pmic_chtwc.c
@@ -179,18 +179,13 @@ static int cht_wc_probe(struct i2c_client *client)
int ret;
status = acpi_evaluate_integer(ACPI_HANDLE(dev), "_HRV", NULL, &hrv);
- if (ACPI_FAILURE(status)) {
- dev_err(dev, "Failed to get PMIC hardware revision\n");
- return -ENODEV;
- }
- if (hrv != CHT_WC_HRV) {
- dev_err(dev, "Invalid PMIC hardware revision: %llu\n", hrv);
- return -ENODEV;
- }
- if (client->irq < 0) {
- dev_err(dev, "Invalid IRQ\n");
- return -EINVAL;
- }
+ if (ACPI_FAILURE(status))
+ return dev_err_probe(dev, -ENODEV, "Failed to get PMIC hardware revision\n");
+ if (hrv != CHT_WC_HRV)
+ return dev_err_probe(dev, -ENODEV, "Invalid PMIC hardware revision: %llu\n", hrv);
+
+ if (client->irq < 0)
+ return dev_err_probe(dev, -EINVAL, "Invalid IRQ\n");
pmic = devm_kzalloc(dev, sizeof(*pmic), GFP_KERNEL);
if (!pmic)
@@ -227,7 +222,7 @@ static void cht_wc_shutdown(struct i2c_client *client)
disable_irq(pmic->irq);
}
-static int __maybe_unused cht_wc_suspend(struct device *dev)
+static int cht_wc_suspend(struct device *dev)
{
struct intel_soc_pmic *pmic = dev_get_drvdata(dev);
@@ -236,7 +231,7 @@ static int __maybe_unused cht_wc_suspend(struct device *dev)
return 0;
}
-static int __maybe_unused cht_wc_resume(struct device *dev)
+static int cht_wc_resume(struct device *dev)
{
struct intel_soc_pmic *pmic = dev_get_drvdata(dev);
@@ -244,7 +239,7 @@ static int __maybe_unused cht_wc_resume(struct device *dev)
return 0;
}
-static SIMPLE_DEV_PM_OPS(cht_wc_pm_ops, cht_wc_suspend, cht_wc_resume);
+static DEFINE_SIMPLE_DEV_PM_OPS(cht_wc_pm_ops, cht_wc_suspend, cht_wc_resume);
static const struct i2c_device_id cht_wc_i2c_id[] = {
{ }
@@ -258,7 +253,7 @@ static const struct acpi_device_id cht_wc_acpi_ids[] = {
static struct i2c_driver cht_wc_driver = {
.driver = {
.name = "CHT Whiskey Cove PMIC",
- .pm = &cht_wc_pm_ops,
+ .pm = pm_sleep_ptr(&cht_wc_pm_ops),
.acpi_match_table = cht_wc_acpi_ids,
},
.probe_new = cht_wc_probe,
diff --git a/drivers/mfd/lp873x.c b/drivers/mfd/lp873x.c
index 858c9e0a49a4..b6166dec492d 100644
--- a/drivers/mfd/lp873x.c
+++ b/drivers/mfd/lp873x.c
@@ -1,16 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (C) 2016 Texas Instruments Incorporated - https://www.ti.com/
*
* Author: Keerthy <[email protected]>
- *
- * 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 version 2.
- *
- * This program is distributed "as is" WITHOUT ANY WARRANTY of any
- * kind, whether express or implied; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
*/
#include <linux/interrupt.h>
diff --git a/drivers/mfd/lpc_ich.c b/drivers/mfd/lpc_ich.c
index 9ffab9aafd81..650951f89f1c 100644
--- a/drivers/mfd/lpc_ich.c
+++ b/drivers/mfd/lpc_ich.c
@@ -8,7 +8,8 @@
* Configuration Registers.
*
* This driver is derived from lpc_sch.
-
+ *
+ * Copyright (c) 2017, 2021-2022 Intel Corporation
* Copyright (c) 2011 Extreme Engineering Solution, Inc.
* Author: Aaron Sierra <[email protected]>
*
@@ -42,9 +43,11 @@
#include <linux/errno.h>
#include <linux/acpi.h>
#include <linux/pci.h>
+#include <linux/pinctrl/pinctrl.h>
#include <linux/mfd/core.h>
#include <linux/mfd/lpc_ich.h>
#include <linux/platform_data/itco_wdt.h>
+#include <linux/platform_data/x86/p2sb.h>
#define ACPIBASE 0x40
#define ACPIBASE_GPE_OFF 0x28
@@ -71,8 +74,6 @@
#define BCR 0xdc
#define BCR_WPD BIT(0)
-#define SPIBASE_APL_SZ 4096
-
#define GPIOBASE_ICH0 0x58
#define GPIOCTRL_ICH0 0x5C
#define GPIOBASE_ICH6 0x48
@@ -143,6 +144,73 @@ static struct mfd_cell lpc_ich_gpio_cell = {
.ignore_resource_conflicts = true,
};
+#define APL_GPIO_NORTH 0
+#define APL_GPIO_NORTHWEST 1
+#define APL_GPIO_WEST 2
+#define APL_GPIO_SOUTHWEST 3
+#define APL_GPIO_NR_DEVICES 4
+
+/* Offset data for Apollo Lake GPIO controllers */
+static resource_size_t apl_gpio_offsets[APL_GPIO_NR_DEVICES] = {
+ [APL_GPIO_NORTH] = 0xc50000,
+ [APL_GPIO_NORTHWEST] = 0xc40000,
+ [APL_GPIO_WEST] = 0xc70000,
+ [APL_GPIO_SOUTHWEST] = 0xc00000,
+};
+
+#define APL_GPIO_RESOURCE_SIZE 0x1000
+
+#define APL_GPIO_IRQ 14
+
+static struct resource apl_gpio_resources[APL_GPIO_NR_DEVICES][2] = {
+ [APL_GPIO_NORTH] = {
+ DEFINE_RES_MEM(0, 0),
+ DEFINE_RES_IRQ(APL_GPIO_IRQ),
+ },
+ [APL_GPIO_NORTHWEST] = {
+ DEFINE_RES_MEM(0, 0),
+ DEFINE_RES_IRQ(APL_GPIO_IRQ),
+ },
+ [APL_GPIO_WEST] = {
+ DEFINE_RES_MEM(0, 0),
+ DEFINE_RES_IRQ(APL_GPIO_IRQ),
+ },
+ [APL_GPIO_SOUTHWEST] = {
+ DEFINE_RES_MEM(0, 0),
+ DEFINE_RES_IRQ(APL_GPIO_IRQ),
+ },
+};
+
+static const struct mfd_cell apl_gpio_devices[APL_GPIO_NR_DEVICES] = {
+ [APL_GPIO_NORTH] = {
+ .name = "apollolake-pinctrl",
+ .id = APL_GPIO_NORTH,
+ .num_resources = ARRAY_SIZE(apl_gpio_resources[APL_GPIO_NORTH]),
+ .resources = apl_gpio_resources[APL_GPIO_NORTH],
+ .ignore_resource_conflicts = true,
+ },
+ [APL_GPIO_NORTHWEST] = {
+ .name = "apollolake-pinctrl",
+ .id = APL_GPIO_NORTHWEST,
+ .num_resources = ARRAY_SIZE(apl_gpio_resources[APL_GPIO_NORTHWEST]),
+ .resources = apl_gpio_resources[APL_GPIO_NORTHWEST],
+ .ignore_resource_conflicts = true,
+ },
+ [APL_GPIO_WEST] = {
+ .name = "apollolake-pinctrl",
+ .id = APL_GPIO_WEST,
+ .num_resources = ARRAY_SIZE(apl_gpio_resources[APL_GPIO_WEST]),
+ .resources = apl_gpio_resources[APL_GPIO_WEST],
+ .ignore_resource_conflicts = true,
+ },
+ [APL_GPIO_SOUTHWEST] = {
+ .name = "apollolake-pinctrl",
+ .id = APL_GPIO_SOUTHWEST,
+ .num_resources = ARRAY_SIZE(apl_gpio_resources[APL_GPIO_SOUTHWEST]),
+ .resources = apl_gpio_resources[APL_GPIO_SOUTHWEST],
+ .ignore_resource_conflicts = true,
+ },
+};
static struct mfd_cell lpc_ich_spi_cell = {
.name = "intel-spi",
@@ -1086,6 +1154,34 @@ wdt_done:
return ret;
}
+static int lpc_ich_init_pinctrl(struct pci_dev *dev)
+{
+ struct resource base;
+ unsigned int i;
+ int ret;
+
+ /* Check, if GPIO has been exported as an ACPI device */
+ if (acpi_dev_present("INT3452", NULL, -1))
+ return -EEXIST;
+
+ ret = p2sb_bar(dev->bus, 0, &base);
+ if (ret)
+ return ret;
+
+ for (i = 0; i < ARRAY_SIZE(apl_gpio_devices); i++) {
+ struct resource *mem = &apl_gpio_resources[i][0];
+ resource_size_t offset = apl_gpio_offsets[i];
+
+ /* Fill MEM resource */
+ mem->start = base.start + offset;
+ mem->end = base.start + offset + APL_GPIO_RESOURCE_SIZE - 1;
+ mem->flags = base.flags;
+ }
+
+ return mfd_add_devices(&dev->dev, 0, apl_gpio_devices,
+ ARRAY_SIZE(apl_gpio_devices), NULL, 0, NULL);
+}
+
static bool lpc_ich_byt_set_writeable(void __iomem *base, void *data)
{
u32 val;
@@ -1100,35 +1196,32 @@ static bool lpc_ich_byt_set_writeable(void __iomem *base, void *data)
return val & BYT_BCR_WPD;
}
-static bool lpc_ich_lpt_set_writeable(void __iomem *base, void *data)
+static bool lpc_ich_set_writeable(struct pci_bus *bus, unsigned int devfn)
{
- struct pci_dev *pdev = data;
u32 bcr;
- pci_read_config_dword(pdev, BCR, &bcr);
+ pci_bus_read_config_dword(bus, devfn, BCR, &bcr);
if (!(bcr & BCR_WPD)) {
bcr |= BCR_WPD;
- pci_write_config_dword(pdev, BCR, bcr);
- pci_read_config_dword(pdev, BCR, &bcr);
+ pci_bus_write_config_dword(bus, devfn, BCR, bcr);
+ pci_bus_read_config_dword(bus, devfn, BCR, &bcr);
}
return bcr & BCR_WPD;
}
-static bool lpc_ich_bxt_set_writeable(void __iomem *base, void *data)
+static bool lpc_ich_lpt_set_writeable(void __iomem *base, void *data)
{
- unsigned int spi = PCI_DEVFN(13, 2);
- struct pci_bus *bus = data;
- u32 bcr;
+ struct pci_dev *pdev = data;
- pci_bus_read_config_dword(bus, spi, BCR, &bcr);
- if (!(bcr & BCR_WPD)) {
- bcr |= BCR_WPD;
- pci_bus_write_config_dword(bus, spi, BCR, bcr);
- pci_bus_read_config_dword(bus, spi, BCR, &bcr);
- }
+ return lpc_ich_set_writeable(pdev->bus, pdev->devfn);
+}
- return bcr & BCR_WPD;
+static bool lpc_ich_bxt_set_writeable(void __iomem *base, void *data)
+{
+ struct pci_dev *pdev = data;
+
+ return lpc_ich_set_writeable(pdev->bus, PCI_DEVFN(13, 2));
}
static int lpc_ich_init_spi(struct pci_dev *dev)
@@ -1137,6 +1230,7 @@ static int lpc_ich_init_spi(struct pci_dev *dev)
struct resource *res = &intel_spi_res[0];
struct intel_spi_boardinfo *info;
u32 spi_base, rcba;
+ int ret;
info = devm_kzalloc(&dev->dev, sizeof(*info), GFP_KERNEL);
if (!info)
@@ -1167,30 +1261,19 @@ static int lpc_ich_init_spi(struct pci_dev *dev)
}
break;
- case INTEL_SPI_BXT: {
- unsigned int p2sb = PCI_DEVFN(13, 0);
- unsigned int spi = PCI_DEVFN(13, 2);
- struct pci_bus *bus = dev->bus;
-
+ case INTEL_SPI_BXT:
/*
* The P2SB is hidden by BIOS and we need to unhide it in
* order to read BAR of the SPI flash device. Once that is
* done we hide it again.
*/
- pci_bus_write_config_byte(bus, p2sb, 0xe1, 0x0);
- pci_bus_read_config_dword(bus, spi, PCI_BASE_ADDRESS_0,
- &spi_base);
- if (spi_base != ~0) {
- res->start = spi_base & 0xfffffff0;
- res->end = res->start + SPIBASE_APL_SZ - 1;
-
- info->set_writeable = lpc_ich_bxt_set_writeable;
- info->data = bus;
- }
+ ret = p2sb_bar(dev->bus, PCI_DEVFN(13, 2), res);
+ if (ret)
+ return ret;
- pci_bus_write_config_byte(bus, p2sb, 0xe1, 0x1);
+ info->set_writeable = lpc_ich_bxt_set_writeable;
+ info->data = dev;
break;
- }
default:
return -EINVAL;
@@ -1249,6 +1332,12 @@ static int lpc_ich_probe(struct pci_dev *dev,
cell_added = true;
}
+ if (priv->chipset == LPC_APL) {
+ ret = lpc_ich_init_pinctrl(dev);
+ if (!ret)
+ cell_added = true;
+ }
+
if (lpc_chipset_info[priv->chipset].spi_type) {
ret = lpc_ich_init_spi(dev);
if (!ret)
diff --git a/drivers/mfd/max77620.c b/drivers/mfd/max77620.c
index fec2096474ad..a6661e07035b 100644
--- a/drivers/mfd/max77620.c
+++ b/drivers/mfd/max77620.c
@@ -419,9 +419,11 @@ static int max77620_initialise_fps(struct max77620_chip *chip)
ret = max77620_config_fps(chip, fps_child);
if (ret < 0) {
of_node_put(fps_child);
+ of_node_put(fps_np);
return ret;
}
}
+ of_node_put(fps_np);
config = chip->enable_global_lpm ? MAX77620_ONOFFCNFG2_SLP_LPM_MSK : 0;
ret = regmap_update_bits(chip->rmap, MAX77620_REG_ONOFFCNFG2,
diff --git a/drivers/mfd/max77714.c b/drivers/mfd/max77714.c
index d1e4247800d2..143a432ea343 100644
--- a/drivers/mfd/max77714.c
+++ b/drivers/mfd/max77714.c
@@ -3,7 +3,7 @@
* Maxim MAX77714 Core Driver
*
* Copyright (C) 2022 Luca Ceresoli
- * Author: Luca Ceresoli <[email protected]>
+ * Author: Luca Ceresoli <[email protected]>
*/
#include <linux/i2c.h>
@@ -148,5 +148,5 @@ static struct i2c_driver max77714_driver = {
module_i2c_driver(max77714_driver);
MODULE_DESCRIPTION("Maxim MAX77714 MFD core driver");
-MODULE_AUTHOR("Luca Ceresoli <[email protected]>");
+MODULE_AUTHOR("Luca Ceresoli <[email protected]>");
MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c
index 684a011a6396..8b058200d5ad 100644
--- a/drivers/mfd/mfd-core.c
+++ b/drivers/mfd/mfd-core.c
@@ -60,12 +60,29 @@ int mfd_cell_disable(struct platform_device *pdev)
EXPORT_SYMBOL(mfd_cell_disable);
#if IS_ENABLED(CONFIG_ACPI)
+struct match_ids_walk_data {
+ struct acpi_device_id *ids;
+ struct acpi_device *adev;
+};
+
+static int match_device_ids(struct acpi_device *adev, void *data)
+{
+ struct match_ids_walk_data *wd = data;
+
+ if (!acpi_match_device_ids(adev, wd->ids)) {
+ wd->adev = adev;
+ return 1;
+ }
+
+ return 0;
+}
+
static void mfd_acpi_add_device(const struct mfd_cell *cell,
struct platform_device *pdev)
{
const struct mfd_cell_acpi_match *match = cell->acpi_match;
- struct acpi_device *parent, *child;
struct acpi_device *adev = NULL;
+ struct acpi_device *parent;
parent = ACPI_COMPANION(pdev->dev.parent);
if (!parent)
@@ -83,14 +100,14 @@ static void mfd_acpi_add_device(const struct mfd_cell *cell,
if (match) {
if (match->pnpid) {
struct acpi_device_id ids[2] = {};
+ struct match_ids_walk_data wd = {
+ .adev = NULL,
+ .ids = ids,
+ };
strlcpy(ids[0].id, match->pnpid, sizeof(ids[0].id));
- list_for_each_entry(child, &parent->children, node) {
- if (!acpi_match_device_ids(child, ids)) {
- adev = child;
- break;
- }
- }
+ acpi_dev_for_each_child(parent, match_device_ids, &wd);
+ adev = wd.adev;
} else {
adev = acpi_find_child_device(parent, match->adr, false);
}
diff --git a/drivers/mfd/mt6358-irq.c b/drivers/mfd/mt6358-irq.c
index ea5e452510eb..389756436af6 100644
--- a/drivers/mfd/mt6358-irq.c
+++ b/drivers/mfd/mt6358-irq.c
@@ -3,6 +3,8 @@
// Copyright (c) 2020 MediaTek Inc.
#include <linux/interrupt.h>
+#include <linux/mfd/mt6357/core.h>
+#include <linux/mfd/mt6357/registers.h>
#include <linux/mfd/mt6358/core.h>
#include <linux/mfd/mt6358/registers.h>
#include <linux/mfd/mt6359/core.h>
@@ -17,6 +19,17 @@
#define MTK_PMIC_REG_WIDTH 16
+static const struct irq_top_t mt6357_ints[] = {
+ MT6357_TOP_GEN(BUCK),
+ MT6357_TOP_GEN(LDO),
+ MT6357_TOP_GEN(PSC),
+ MT6357_TOP_GEN(SCK),
+ MT6357_TOP_GEN(BM),
+ MT6357_TOP_GEN(HK),
+ MT6357_TOP_GEN(AUD),
+ MT6357_TOP_GEN(MISC),
+};
+
static const struct irq_top_t mt6358_ints[] = {
MT6358_TOP_GEN(BUCK),
MT6358_TOP_GEN(LDO),
@@ -39,6 +52,13 @@ static const struct irq_top_t mt6359_ints[] = {
MT6359_TOP_GEN(MISC),
};
+static struct pmic_irq_data mt6357_irqd = {
+ .num_top = ARRAY_SIZE(mt6357_ints),
+ .num_pmic_irqs = MT6357_IRQ_NR,
+ .top_int_status_reg = MT6357_TOP_INT_STATUS0,
+ .pmic_ints = mt6357_ints,
+};
+
static struct pmic_irq_data mt6358_irqd = {
.num_top = ARRAY_SIZE(mt6358_ints),
.num_pmic_irqs = MT6358_IRQ_NR,
@@ -211,6 +231,10 @@ int mt6358_irq_init(struct mt6397_chip *chip)
struct pmic_irq_data *irqd;
switch (chip->chip_id) {
+ case MT6357_CHIP_ID:
+ chip->irq_data = &mt6357_irqd;
+ break;
+
case MT6358_CHIP_ID:
case MT6366_CHIP_ID:
chip->irq_data = &mt6358_irqd;
diff --git a/drivers/mfd/mt6397-core.c b/drivers/mfd/mt6397-core.c
index 1a368ad08f58..f6c1f80f94a4 100644
--- a/drivers/mfd/mt6397-core.c
+++ b/drivers/mfd/mt6397-core.c
@@ -12,10 +12,14 @@
#include <linux/regmap.h>
#include <linux/mfd/core.h>
#include <linux/mfd/mt6323/core.h>
+#include <linux/mfd/mt6331/core.h>
+#include <linux/mfd/mt6357/core.h>
#include <linux/mfd/mt6358/core.h>
#include <linux/mfd/mt6359/core.h>
#include <linux/mfd/mt6397/core.h>
#include <linux/mfd/mt6323/registers.h>
+#include <linux/mfd/mt6331/registers.h>
+#include <linux/mfd/mt6357/registers.h>
#include <linux/mfd/mt6358/registers.h>
#include <linux/mfd/mt6359/registers.h>
#include <linux/mfd/mt6397/registers.h>
@@ -23,6 +27,12 @@
#define MT6323_RTC_BASE 0x8000
#define MT6323_RTC_SIZE 0x40
+#define MT6357_RTC_BASE 0x0588
+#define MT6357_RTC_SIZE 0x3c
+
+#define MT6331_RTC_BASE 0x4000
+#define MT6331_RTC_SIZE 0x40
+
#define MT6358_RTC_BASE 0x0588
#define MT6358_RTC_SIZE 0x3c
@@ -37,6 +47,16 @@ static const struct resource mt6323_rtc_resources[] = {
DEFINE_RES_IRQ(MT6323_IRQ_STATUS_RTC),
};
+static const struct resource mt6357_rtc_resources[] = {
+ DEFINE_RES_MEM(MT6357_RTC_BASE, MT6357_RTC_SIZE),
+ DEFINE_RES_IRQ(MT6357_IRQ_RTC),
+};
+
+static const struct resource mt6331_rtc_resources[] = {
+ DEFINE_RES_MEM(MT6331_RTC_BASE, MT6331_RTC_SIZE),
+ DEFINE_RES_IRQ(MT6331_IRQ_STATUS_RTC),
+};
+
static const struct resource mt6358_rtc_resources[] = {
DEFINE_RES_MEM(MT6358_RTC_BASE, MT6358_RTC_SIZE),
DEFINE_RES_IRQ(MT6358_IRQ_RTC),
@@ -66,6 +86,18 @@ static const struct resource mt6323_keys_resources[] = {
DEFINE_RES_IRQ_NAMED(MT6323_IRQ_STATUS_FCHRKEY, "homekey"),
};
+static const struct resource mt6357_keys_resources[] = {
+ DEFINE_RES_IRQ_NAMED(MT6357_IRQ_PWRKEY, "powerkey"),
+ DEFINE_RES_IRQ_NAMED(MT6357_IRQ_HOMEKEY, "homekey"),
+ DEFINE_RES_IRQ_NAMED(MT6357_IRQ_PWRKEY_R, "powerkey_r"),
+ DEFINE_RES_IRQ_NAMED(MT6357_IRQ_HOMEKEY_R, "homekey_r"),
+};
+
+static const struct resource mt6331_keys_resources[] = {
+ DEFINE_RES_IRQ_NAMED(MT6331_IRQ_STATUS_PWRKEY, "powerkey"),
+ DEFINE_RES_IRQ_NAMED(MT6331_IRQ_STATUS_HOMEKEY, "homekey"),
+};
+
static const struct resource mt6397_keys_resources[] = {
DEFINE_RES_IRQ_NAMED(MT6397_IRQ_PWRKEY, "powerkey"),
DEFINE_RES_IRQ_NAMED(MT6397_IRQ_HOMEKEY, "homekey"),
@@ -100,6 +132,43 @@ static const struct mfd_cell mt6323_devs[] = {
},
};
+static const struct mfd_cell mt6357_devs[] = {
+ {
+ .name = "mt6357-regulator",
+ }, {
+ .name = "mt6357-rtc",
+ .num_resources = ARRAY_SIZE(mt6357_rtc_resources),
+ .resources = mt6357_rtc_resources,
+ .of_compatible = "mediatek,mt6357-rtc",
+ }, {
+ .name = "mtk-pmic-keys",
+ .num_resources = ARRAY_SIZE(mt6357_keys_resources),
+ .resources = mt6357_keys_resources,
+ .of_compatible = "mediatek,mt6357-keys"
+ },
+};
+
+/* MT6331 is always used in combination with MT6332 */
+static const struct mfd_cell mt6331_mt6332_devs[] = {
+ {
+ .name = "mt6331-rtc",
+ .num_resources = ARRAY_SIZE(mt6331_rtc_resources),
+ .resources = mt6331_rtc_resources,
+ .of_compatible = "mediatek,mt6331-rtc",
+ }, {
+ .name = "mt6331-regulator",
+ .of_compatible = "mediatek,mt6331-regulator"
+ }, {
+ .name = "mt6332-regulator",
+ .of_compatible = "mediatek,mt6332-regulator"
+ }, {
+ .name = "mtk-pmic-keys",
+ .num_resources = ARRAY_SIZE(mt6331_keys_resources),
+ .resources = mt6331_keys_resources,
+ .of_compatible = "mediatek,mt6331-keys"
+ },
+};
+
static const struct mfd_cell mt6358_devs[] = {
{
.name = "mt6358-regulator",
@@ -179,6 +248,22 @@ static const struct chip_data mt6323_core = {
.irq_init = mt6397_irq_init,
};
+static const struct chip_data mt6357_core = {
+ .cid_addr = MT6357_SWCID,
+ .cid_shift = 8,
+ .cells = mt6357_devs,
+ .cell_size = ARRAY_SIZE(mt6357_devs),
+ .irq_init = mt6358_irq_init,
+};
+
+static const struct chip_data mt6331_mt6332_core = {
+ .cid_addr = MT6331_HWCID,
+ .cid_shift = 0,
+ .cells = mt6331_mt6332_devs,
+ .cell_size = ARRAY_SIZE(mt6331_mt6332_devs),
+ .irq_init = mt6397_irq_init,
+};
+
static const struct chip_data mt6358_core = {
.cid_addr = MT6358_SWCID,
.cid_shift = 8,
@@ -262,6 +347,12 @@ static const struct of_device_id mt6397_of_match[] = {
.compatible = "mediatek,mt6323",
.data = &mt6323_core,
}, {
+ .compatible = "mediatek,mt6331",
+ .data = &mt6331_mt6332_core,
+ }, {
+ .compatible = "mediatek,mt6357",
+ .data = &mt6357_core,
+ }, {
.compatible = "mediatek,mt6358",
.data = &mt6358_core,
}, {
diff --git a/drivers/mfd/mt6397-irq.c b/drivers/mfd/mt6397-irq.c
index 2924919da991..eff53fed8fe7 100644
--- a/drivers/mfd/mt6397-irq.c
+++ b/drivers/mfd/mt6397-irq.c
@@ -12,6 +12,8 @@
#include <linux/suspend.h>
#include <linux/mfd/mt6323/core.h>
#include <linux/mfd/mt6323/registers.h>
+#include <linux/mfd/mt6331/core.h>
+#include <linux/mfd/mt6331/registers.h>
#include <linux/mfd/mt6397/core.h>
#include <linux/mfd/mt6397/registers.h>
@@ -172,7 +174,12 @@ int mt6397_irq_init(struct mt6397_chip *chip)
chip->int_status[0] = MT6323_INT_STATUS0;
chip->int_status[1] = MT6323_INT_STATUS1;
break;
-
+ case MT6331_CHIP_ID:
+ chip->int_con[0] = MT6331_INT_CON0;
+ chip->int_con[1] = MT6331_INT_CON1;
+ chip->int_status[0] = MT6331_INT_STATUS_CON0;
+ chip->int_status[1] = MT6331_INT_STATUS_CON1;
+ break;
case MT6391_CHIP_ID:
case MT6397_CHIP_ID:
chip->int_con[0] = MT6397_INT_CON0;
diff --git a/drivers/mfd/qcom-pm8008.c b/drivers/mfd/qcom-pm8008.c
index c472d7f8103c..4b8ff947762f 100644
--- a/drivers/mfd/qcom-pm8008.c
+++ b/drivers/mfd/qcom-pm8008.c
@@ -54,13 +54,6 @@ enum {
#define PM8008_PERIPH_OFFSET(paddr) (paddr - PM8008_PERIPH_0_BASE)
-struct pm8008_data {
- struct device *dev;
- struct regmap *regmap;
- int irq;
- struct regmap_irq_chip_data *irq_data;
-};
-
static unsigned int p0_offs[] = {PM8008_PERIPH_OFFSET(PM8008_PERIPH_0_BASE)};
static unsigned int p1_offs[] = {PM8008_PERIPH_OFFSET(PM8008_PERIPH_1_BASE)};
static unsigned int p2_offs[] = {PM8008_PERIPH_OFFSET(PM8008_PERIPH_2_BASE)};
@@ -150,7 +143,7 @@ static struct regmap_config qcom_mfd_regmap_cfg = {
.max_register = 0xFFFF,
};
-static int pm8008_init(struct pm8008_data *chip)
+static int pm8008_init(struct regmap *regmap)
{
int rc;
@@ -160,34 +153,31 @@ static int pm8008_init(struct pm8008_data *chip)
* This is required to enable the writing of TYPE registers in
* regmap_irq_sync_unlock().
*/
- rc = regmap_write(chip->regmap,
- (PM8008_TEMP_ALARM_ADDR | INT_SET_TYPE_OFFSET),
- BIT(0));
+ rc = regmap_write(regmap, (PM8008_TEMP_ALARM_ADDR | INT_SET_TYPE_OFFSET), BIT(0));
if (rc)
return rc;
/* Do the same for GPIO1 and GPIO2 peripherals */
- rc = regmap_write(chip->regmap,
- (PM8008_GPIO1_ADDR | INT_SET_TYPE_OFFSET), BIT(0));
+ rc = regmap_write(regmap, (PM8008_GPIO1_ADDR | INT_SET_TYPE_OFFSET), BIT(0));
if (rc)
return rc;
- rc = regmap_write(chip->regmap,
- (PM8008_GPIO2_ADDR | INT_SET_TYPE_OFFSET), BIT(0));
+ rc = regmap_write(regmap, (PM8008_GPIO2_ADDR | INT_SET_TYPE_OFFSET), BIT(0));
return rc;
}
-static int pm8008_probe_irq_peripherals(struct pm8008_data *chip,
+static int pm8008_probe_irq_peripherals(struct device *dev,
+ struct regmap *regmap,
int client_irq)
{
int rc, i;
struct regmap_irq_type *type;
struct regmap_irq_chip_data *irq_data;
- rc = pm8008_init(chip);
+ rc = pm8008_init(regmap);
if (rc) {
- dev_err(chip->dev, "Init failed: %d\n", rc);
+ dev_err(dev, "Init failed: %d\n", rc);
return rc;
}
@@ -207,10 +197,10 @@ static int pm8008_probe_irq_peripherals(struct pm8008_data *chip,
IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW);
}
- rc = devm_regmap_add_irq_chip(chip->dev, chip->regmap, client_irq,
+ rc = devm_regmap_add_irq_chip(dev, regmap, client_irq,
IRQF_SHARED, 0, &pm8008_irq_chip, &irq_data);
if (rc) {
- dev_err(chip->dev, "Failed to add IRQ chip: %d\n", rc);
+ dev_err(dev, "Failed to add IRQ chip: %d\n", rc);
return rc;
}
@@ -220,26 +210,23 @@ static int pm8008_probe_irq_peripherals(struct pm8008_data *chip,
static int pm8008_probe(struct i2c_client *client)
{
int rc;
- struct pm8008_data *chip;
-
- chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
- if (!chip)
- return -ENOMEM;
+ struct device *dev;
+ struct regmap *regmap;
- chip->dev = &client->dev;
- chip->regmap = devm_regmap_init_i2c(client, &qcom_mfd_regmap_cfg);
- if (!chip->regmap)
+ dev = &client->dev;
+ regmap = devm_regmap_init_i2c(client, &qcom_mfd_regmap_cfg);
+ if (!regmap)
return -ENODEV;
- i2c_set_clientdata(client, chip);
+ i2c_set_clientdata(client, regmap);
- if (of_property_read_bool(chip->dev->of_node, "interrupt-controller")) {
- rc = pm8008_probe_irq_peripherals(chip, client->irq);
+ if (of_property_read_bool(dev->of_node, "interrupt-controller")) {
+ rc = pm8008_probe_irq_peripherals(dev, regmap, client->irq);
if (rc)
- dev_err(chip->dev, "Failed to probe irq periphs: %d\n", rc);
+ dev_err(dev, "Failed to probe irq periphs: %d\n", rc);
}
- return devm_of_platform_populate(chip->dev);
+ return devm_of_platform_populate(dev);
}
static const struct of_device_id pm8008_match[] = {
diff --git a/drivers/mfd/qcom-spmi-pmic.c b/drivers/mfd/qcom-spmi-pmic.c
index 1cacc00aa6c9..00003a868d28 100644
--- a/drivers/mfd/qcom-spmi-pmic.c
+++ b/drivers/mfd/qcom-spmi-pmic.c
@@ -3,120 +3,166 @@
* Copyright (c) 2014, The Linux Foundation. All rights reserved.
*/
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/gfp.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/spmi.h>
+#include <linux/types.h>
#include <linux/regmap.h>
#include <linux/of_platform.h>
+#include <soc/qcom/qcom-spmi-pmic.h>
#define PMIC_REV2 0x101
#define PMIC_REV3 0x102
#define PMIC_REV4 0x103
#define PMIC_TYPE 0x104
#define PMIC_SUBTYPE 0x105
+#define PMIC_FAB_ID 0x1f2
#define PMIC_TYPE_VALUE 0x51
-#define COMMON_SUBTYPE 0x00
-#define PM8941_SUBTYPE 0x01
-#define PM8841_SUBTYPE 0x02
-#define PM8019_SUBTYPE 0x03
-#define PM8226_SUBTYPE 0x04
-#define PM8110_SUBTYPE 0x05
-#define PMA8084_SUBTYPE 0x06
-#define PMI8962_SUBTYPE 0x07
-#define PMD9635_SUBTYPE 0x08
-#define PM8994_SUBTYPE 0x09
-#define PMI8994_SUBTYPE 0x0a
-#define PM8916_SUBTYPE 0x0b
-#define PM8004_SUBTYPE 0x0c
-#define PM8909_SUBTYPE 0x0d
-#define PM8028_SUBTYPE 0x0e
-#define PM8901_SUBTYPE 0x0f
-#define PM8950_SUBTYPE 0x10
-#define PMI8950_SUBTYPE 0x11
-#define PM8998_SUBTYPE 0x14
-#define PMI8998_SUBTYPE 0x15
-#define PM8005_SUBTYPE 0x18
-#define PM660L_SUBTYPE 0x1A
-#define PM660_SUBTYPE 0x1B
-#define PM8150_SUBTYPE 0x1E
-#define PM8150L_SUBTYPE 0x1f
-#define PM8150B_SUBTYPE 0x20
-#define PMK8002_SUBTYPE 0x21
-#define PM8009_SUBTYPE 0x24
-#define PM8150C_SUBTYPE 0x26
-#define SMB2351_SUBTYPE 0x29
+#define PMIC_REV4_V2 0x02
+
+struct qcom_spmi_dev {
+ int num_usids;
+ struct qcom_spmi_pmic pmic;
+};
+
+#define N_USIDS(n) ((void *)n)
static const struct of_device_id pmic_spmi_id_table[] = {
- { .compatible = "qcom,pm660", .data = (void *)PM660_SUBTYPE },
- { .compatible = "qcom,pm660l", .data = (void *)PM660L_SUBTYPE },
- { .compatible = "qcom,pm8004", .data = (void *)PM8004_SUBTYPE },
- { .compatible = "qcom,pm8005", .data = (void *)PM8005_SUBTYPE },
- { .compatible = "qcom,pm8019", .data = (void *)PM8019_SUBTYPE },
- { .compatible = "qcom,pm8028", .data = (void *)PM8028_SUBTYPE },
- { .compatible = "qcom,pm8110", .data = (void *)PM8110_SUBTYPE },
- { .compatible = "qcom,pm8150", .data = (void *)PM8150_SUBTYPE },
- { .compatible = "qcom,pm8150b", .data = (void *)PM8150B_SUBTYPE },
- { .compatible = "qcom,pm8150c", .data = (void *)PM8150C_SUBTYPE },
- { .compatible = "qcom,pm8150l", .data = (void *)PM8150L_SUBTYPE },
- { .compatible = "qcom,pm8226", .data = (void *)PM8226_SUBTYPE },
- { .compatible = "qcom,pm8841", .data = (void *)PM8841_SUBTYPE },
- { .compatible = "qcom,pm8901", .data = (void *)PM8901_SUBTYPE },
- { .compatible = "qcom,pm8909", .data = (void *)PM8909_SUBTYPE },
- { .compatible = "qcom,pm8916", .data = (void *)PM8916_SUBTYPE },
- { .compatible = "qcom,pm8941", .data = (void *)PM8941_SUBTYPE },
- { .compatible = "qcom,pm8950", .data = (void *)PM8950_SUBTYPE },
- { .compatible = "qcom,pm8994", .data = (void *)PM8994_SUBTYPE },
- { .compatible = "qcom,pm8998", .data = (void *)PM8998_SUBTYPE },
- { .compatible = "qcom,pma8084", .data = (void *)PMA8084_SUBTYPE },
- { .compatible = "qcom,pmd9635", .data = (void *)PMD9635_SUBTYPE },
- { .compatible = "qcom,pmi8950", .data = (void *)PMI8950_SUBTYPE },
- { .compatible = "qcom,pmi8962", .data = (void *)PMI8962_SUBTYPE },
- { .compatible = "qcom,pmi8994", .data = (void *)PMI8994_SUBTYPE },
- { .compatible = "qcom,pmi8998", .data = (void *)PMI8998_SUBTYPE },
- { .compatible = "qcom,pmk8002", .data = (void *)PMK8002_SUBTYPE },
- { .compatible = "qcom,smb2351", .data = (void *)SMB2351_SUBTYPE },
- { .compatible = "qcom,spmi-pmic", .data = (void *)COMMON_SUBTYPE },
+ { .compatible = "qcom,pm660", .data = N_USIDS(2) },
+ { .compatible = "qcom,pm660l", .data = N_USIDS(2) },
+ { .compatible = "qcom,pm8004", .data = N_USIDS(2) },
+ { .compatible = "qcom,pm8005", .data = N_USIDS(2) },
+ { .compatible = "qcom,pm8019", .data = N_USIDS(2) },
+ { .compatible = "qcom,pm8028", .data = N_USIDS(2) },
+ { .compatible = "qcom,pm8110", .data = N_USIDS(2) },
+ { .compatible = "qcom,pm8150", .data = N_USIDS(2) },
+ { .compatible = "qcom,pm8150b", .data = N_USIDS(2) },
+ { .compatible = "qcom,pm8150c", .data = N_USIDS(2) },
+ { .compatible = "qcom,pm8150l", .data = N_USIDS(2) },
+ { .compatible = "qcom,pm8226", .data = N_USIDS(2) },
+ { .compatible = "qcom,pm8841", .data = N_USIDS(2) },
+ { .compatible = "qcom,pm8901", .data = N_USIDS(2) },
+ { .compatible = "qcom,pm8909", .data = N_USIDS(2) },
+ { .compatible = "qcom,pm8916", .data = N_USIDS(2) },
+ { .compatible = "qcom,pm8941", .data = N_USIDS(2) },
+ { .compatible = "qcom,pm8950", .data = N_USIDS(2) },
+ { .compatible = "qcom,pm8994", .data = N_USIDS(2) },
+ { .compatible = "qcom,pm8998", .data = N_USIDS(2) },
+ { .compatible = "qcom,pma8084", .data = N_USIDS(2) },
+ { .compatible = "qcom,pmd9635", .data = N_USIDS(2) },
+ { .compatible = "qcom,pmi8950", .data = N_USIDS(2) },
+ { .compatible = "qcom,pmi8962", .data = N_USIDS(2) },
+ { .compatible = "qcom,pmi8994", .data = N_USIDS(2) },
+ { .compatible = "qcom,pmi8998", .data = N_USIDS(2) },
+ { .compatible = "qcom,pmk8002", .data = N_USIDS(2) },
+ { .compatible = "qcom,smb2351", .data = N_USIDS(2) },
+ { .compatible = "qcom,spmi-pmic", .data = N_USIDS(1) },
{ }
};
-static void pmic_spmi_show_revid(struct regmap *map, struct device *dev)
+/*
+ * A PMIC can be represented by multiple SPMI devices, but
+ * only the base PMIC device will contain a reference to
+ * the revision information.
+ *
+ * This function takes a pointer to a pmic device and
+ * returns a pointer to the base PMIC device.
+ *
+ * This only supports PMICs with 1 or 2 USIDs.
+ */
+static struct spmi_device *qcom_pmic_get_base_usid(struct device *dev)
{
- unsigned int rev2, minor, major, type, subtype;
- const char *name = "unknown";
- int ret, i;
+ struct spmi_device *sdev;
+ struct qcom_spmi_dev *ctx;
+ struct device_node *spmi_bus;
+ struct device_node *other_usid = NULL;
+ int function_parent_usid, ret;
+ u32 pmic_addr;
- ret = regmap_read(map, PMIC_TYPE, &type);
- if (ret < 0)
- return;
+ sdev = to_spmi_device(dev);
+ ctx = dev_get_drvdata(&sdev->dev);
- if (type != PMIC_TYPE_VALUE)
- return;
+ /*
+ * Quick return if the function device is already in the base
+ * USID. This will always be hit for PMICs with only 1 USID.
+ */
+ if (sdev->usid % ctx->num_usids == 0)
+ return sdev;
- ret = regmap_read(map, PMIC_SUBTYPE, &subtype);
+ function_parent_usid = sdev->usid;
+
+ /*
+ * Walk through the list of PMICs until we find the sibling USID.
+ * The goal is to find the first USID which is less than the
+ * number of USIDs in the PMIC array, e.g. for a PMIC with 2 USIDs
+ * where the function device is under USID 3, we want to find the
+ * device for USID 2.
+ */
+ spmi_bus = of_get_parent(sdev->dev.of_node);
+ do {
+ other_usid = of_get_next_child(spmi_bus, other_usid);
+
+ ret = of_property_read_u32_index(other_usid, "reg", 0, &pmic_addr);
+ if (ret)
+ return ERR_PTR(ret);
+
+ sdev = spmi_device_from_of(other_usid);
+ if (pmic_addr == function_parent_usid - (ctx->num_usids - 1)) {
+ if (!sdev)
+ /*
+ * If the base USID for this PMIC hasn't probed yet
+ * but the secondary USID has, then we need to defer
+ * the function driver so that it will attempt to
+ * probe again when the base USID is ready.
+ */
+ return ERR_PTR(-EPROBE_DEFER);
+ return sdev;
+ }
+ } while (other_usid->sibling);
+
+ return ERR_PTR(-ENODATA);
+}
+
+static int pmic_spmi_load_revid(struct regmap *map, struct device *dev,
+ struct qcom_spmi_pmic *pmic)
+{
+ int ret;
+
+ ret = regmap_read(map, PMIC_TYPE, &pmic->type);
if (ret < 0)
- return;
+ return ret;
- for (i = 0; i < ARRAY_SIZE(pmic_spmi_id_table); i++) {
- if (subtype == (unsigned long)pmic_spmi_id_table[i].data)
- break;
- }
+ if (pmic->type != PMIC_TYPE_VALUE)
+ return ret;
- if (i != ARRAY_SIZE(pmic_spmi_id_table))
- name = pmic_spmi_id_table[i].compatible;
+ ret = regmap_read(map, PMIC_SUBTYPE, &pmic->subtype);
+ if (ret < 0)
+ return ret;
+
+ pmic->name = of_match_device(pmic_spmi_id_table, dev)->compatible;
- ret = regmap_read(map, PMIC_REV2, &rev2);
+ ret = regmap_read(map, PMIC_REV2, &pmic->rev2);
if (ret < 0)
- return;
+ return ret;
- ret = regmap_read(map, PMIC_REV3, &minor);
+ ret = regmap_read(map, PMIC_REV3, &pmic->minor);
if (ret < 0)
- return;
+ return ret;
- ret = regmap_read(map, PMIC_REV4, &major);
+ ret = regmap_read(map, PMIC_REV4, &pmic->major);
if (ret < 0)
- return;
+ return ret;
+
+ if (pmic->subtype == PMI8998_SUBTYPE || pmic->subtype == PM660_SUBTYPE) {
+ ret = regmap_read(map, PMIC_FAB_ID, &pmic->fab_id);
+ if (ret < 0)
+ return ret;
+ }
/*
* In early versions of PM8941 and PM8226, the major revision number
@@ -124,16 +170,50 @@ static void pmic_spmi_show_revid(struct regmap *map, struct device *dev)
* Increment the major revision number here if the chip is an early
* version of PM8941 or PM8226.
*/
- if ((subtype == PM8941_SUBTYPE || subtype == PM8226_SUBTYPE) &&
- major < 0x02)
- major++;
+ if ((pmic->subtype == PM8941_SUBTYPE || pmic->subtype == PM8226_SUBTYPE) &&
+ pmic->major < PMIC_REV4_V2)
+ pmic->major++;
+
+ if (pmic->subtype == PM8110_SUBTYPE)
+ pmic->minor = pmic->rev2;
- if (subtype == PM8110_SUBTYPE)
- minor = rev2;
+ dev_dbg(dev, "%x: %s v%d.%d\n",
+ pmic->subtype, pmic->name, pmic->major, pmic->minor);
- dev_dbg(dev, "%x: %s v%d.%d\n", subtype, name, major, minor);
+ return 0;
}
+/**
+ * qcom_pmic_get() - Get a pointer to the base PMIC device
+ *
+ * This function takes a struct device for a driver which is a child of a PMIC.
+ * And locates the PMIC revision information for it.
+ *
+ * @dev: the pmic function device
+ * @return: the struct qcom_spmi_pmic* pointer associated with the function device
+ */
+const struct qcom_spmi_pmic *qcom_pmic_get(struct device *dev)
+{
+ struct spmi_device *sdev;
+ struct qcom_spmi_dev *spmi;
+
+ /*
+ * Make sure the device is actually a child of a PMIC
+ */
+ if (!of_match_device(pmic_spmi_id_table, dev->parent))
+ return ERR_PTR(-EINVAL);
+
+ sdev = qcom_pmic_get_base_usid(dev->parent);
+
+ if (IS_ERR(sdev))
+ return ERR_CAST(sdev);
+
+ spmi = dev_get_drvdata(&sdev->dev);
+
+ return &spmi->pmic;
+}
+EXPORT_SYMBOL(qcom_pmic_get);
+
static const struct regmap_config spmi_regmap_config = {
.reg_bits = 16,
.val_bits = 8,
@@ -144,14 +224,26 @@ static const struct regmap_config spmi_regmap_config = {
static int pmic_spmi_probe(struct spmi_device *sdev)
{
struct regmap *regmap;
+ struct qcom_spmi_dev *ctx;
+ int ret;
regmap = devm_regmap_init_spmi_ext(sdev, &spmi_regmap_config);
if (IS_ERR(regmap))
return PTR_ERR(regmap);
+ ctx = devm_kzalloc(&sdev->dev, sizeof(*ctx), GFP_KERNEL);
+ if (!ctx)
+ return -ENOMEM;
+
+ ctx->num_usids = (uintptr_t)of_device_get_match_data(&sdev->dev);
+
/* Only the first slave id for a PMIC contains this information */
- if (sdev->usid % 2 == 0)
- pmic_spmi_show_revid(regmap, &sdev->dev);
+ if (sdev->usid % ctx->num_usids == 0) {
+ ret = pmic_spmi_load_revid(regmap, &sdev->dev, &ctx->pmic);
+ if (ret < 0)
+ return ret;
+ }
+ spmi_device_set_drvdata(sdev, ctx);
return devm_of_platform_populate(&sdev->dev);
}
diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c
index 191fdb87c424..bdb2ce7ff03b 100644
--- a/drivers/mfd/syscon.c
+++ b/drivers/mfd/syscon.c
@@ -101,8 +101,7 @@ static struct syscon *of_syscon_register(struct device_node *np, bool check_clk)
}
}
- syscon_config.name = kasprintf(GFP_KERNEL, "%pOFn@%llx", np,
- (u64)res.start);
+ syscon_config.name = kasprintf(GFP_KERNEL, "%pOFn@%pa", np, &res.start);
syscon_config.reg_stride = reg_io_width;
syscon_config.val_bits = reg_io_width * 8;
syscon_config.max_register = resource_size(&res) - reg_io_width;
diff --git a/drivers/mfd/t7l66xb.c b/drivers/mfd/t7l66xb.c
index 5369c67e3280..663ffd4b8570 100644
--- a/drivers/mfd/t7l66xb.c
+++ b/drivers/mfd/t7l66xb.c
@@ -397,11 +397,8 @@ err_noirq:
static int t7l66xb_remove(struct platform_device *dev)
{
- struct t7l66xb_platform_data *pdata = dev_get_platdata(&dev->dev);
struct t7l66xb *t7l66xb = platform_get_drvdata(dev);
- int ret;
- ret = pdata->disable(dev);
clk_disable_unprepare(t7l66xb->clk48m);
clk_put(t7l66xb->clk48m);
clk_disable_unprepare(t7l66xb->clk32k);
@@ -412,8 +409,7 @@ static int t7l66xb_remove(struct platform_device *dev)
mfd_remove_devices(&dev->dev);
kfree(t7l66xb);
- return ret;
-
+ return 0;
}
static struct platform_driver t7l66xb_platform_driver = {
diff --git a/drivers/mfd/tc6393xb.c b/drivers/mfd/tc6393xb.c
index 0be5731685b4..aa903a31dd43 100644
--- a/drivers/mfd/tc6393xb.c
+++ b/drivers/mfd/tc6393xb.c
@@ -798,20 +798,19 @@ static int tc6393xb_remove(struct platform_device *dev)
{
struct tc6393xb_platform_data *tcpd = dev_get_platdata(&dev->dev);
struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
- int ret;
mfd_remove_devices(&dev->dev);
tc6393xb_detach_irq(dev);
- ret = tcpd->disable(dev);
+ tcpd->disable(dev);
clk_disable_unprepare(tc6393xb->clk);
iounmap(tc6393xb->scr);
release_resource(&tc6393xb->rscr);
clk_put(tc6393xb->clk);
kfree(tc6393xb);
- return ret;
+ return 0;
}
#ifdef CONFIG_PM
diff --git a/drivers/mfd/tps65086.c b/drivers/mfd/tps65086.c
index 3bd5728844a0..cbae9777a24e 100644
--- a/drivers/mfd/tps65086.c
+++ b/drivers/mfd/tps65086.c
@@ -1,16 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (C) 2015 Texas Instruments Incorporated - https://www.ti.com/
* Andrew F. Davis <[email protected]>
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed "as is" WITHOUT ANY WARRANTY of any
- * kind, whether expressed or implied; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License version 2 for more details.
- *
* Based on the TPS65912 driver
*/
diff --git a/drivers/mfd/tps65217.c b/drivers/mfd/tps65217.c
index 8027b0a9e14f..8e8da204a02e 100644
--- a/drivers/mfd/tps65217.c
+++ b/drivers/mfd/tps65217.c
@@ -1,18 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0-only
/*
* tps65217.c
*
* TPS65217 chip family multi-function driver
*
* Copyright (C) 2011 Texas Instruments Incorporated - https://www.ti.com/
- *
- * 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 version 2.
- *
- * This program is distributed "as is" WITHOUT ANY WARRANTY of any
- * kind, whether express or implied; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
*/
#include <linux/device.h>
diff --git a/drivers/mfd/tps65218.c b/drivers/mfd/tps65218.c
index 167e9fc308ef..49bb8fd168f8 100644
--- a/drivers/mfd/tps65218.c
+++ b/drivers/mfd/tps65218.c
@@ -1,16 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-only
/*
* Driver for TPS65218 Integrated power management chipsets
*
* Copyright (C) 2014 Texas Instruments Incorporated - https://www.ti.com/
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed "as is" WITHOUT ANY WARRANTY of any
- * kind, whether expressed or implied; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License version 2 for more details.
*/
#include <linux/kernel.h>
diff --git a/drivers/mfd/tps65912-core.c b/drivers/mfd/tps65912-core.c
index c282a05e7146..7d994b8a5965 100644
--- a/drivers/mfd/tps65912-core.c
+++ b/drivers/mfd/tps65912-core.c
@@ -1,18 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0-only
/*
* Core functions for TI TPS65912x PMICs
*
* Copyright (C) 2015 Texas Instruments Incorporated - https://www.ti.com/
* Andrew F. Davis <[email protected]>
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed "as is" WITHOUT ANY WARRANTY of any
- * kind, whether expressed or implied; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License version 2 for more details.
- *
* Based on the TPS65218 driver and the previous TPS65912 driver by
* Margarita Olaya Cabrera <[email protected]>
*/
diff --git a/drivers/mfd/tps65912-i2c.c b/drivers/mfd/tps65912-i2c.c
index 06eb2784d322..afb7f7d97dc0 100644
--- a/drivers/mfd/tps65912-i2c.c
+++ b/drivers/mfd/tps65912-i2c.c
@@ -1,18 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0-only
/*
* I2C access driver for TI TPS65912x PMICs
*
* Copyright (C) 2015 Texas Instruments Incorporated - https://www.ti.com/
* Andrew F. Davis <[email protected]>
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed "as is" WITHOUT ANY WARRANTY of any
- * kind, whether expressed or implied; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License version 2 for more details.
- *
* Based on the TPS65218 driver and the previous TPS65912 driver by
* Margarita Olaya Cabrera <[email protected]>
*/
diff --git a/drivers/mfd/tps65912-spi.c b/drivers/mfd/tps65912-spi.c
index bba38fbc781d..9e976f9c6bbe 100644
--- a/drivers/mfd/tps65912-spi.c
+++ b/drivers/mfd/tps65912-spi.c
@@ -1,18 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0-only
/*
* SPI access driver for TI TPS65912x PMICs
*
* Copyright (C) 2015 Texas Instruments Incorporated - https://www.ti.com/
* Andrew F. Davis <[email protected]>
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed "as is" WITHOUT ANY WARRANTY of any
- * kind, whether expressed or implied; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License version 2 for more details.
- *
* Based on the TPS65218 driver and the previous TPS65912 driver by
* Margarita Olaya Cabrera <[email protected]>
*/
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
index bd6659cf3bc0..2cb9326f3e61 100644
--- a/drivers/mfd/twl-core.c
+++ b/drivers/mfd/twl-core.c
@@ -656,309 +656,6 @@ static inline struct device *add_child(unsigned mod_no, const char *name,
can_wakeup, irq0, irq1);
}
-static struct device *
-add_regulator_linked(int num, struct regulator_init_data *pdata,
- struct regulator_consumer_supply *consumers,
- unsigned num_consumers, unsigned long features)
-{
- struct twl_regulator_driver_data drv_data;
-
- /* regulator framework demands init_data ... */
- if (!pdata)
- return NULL;
-
- if (consumers) {
- pdata->consumer_supplies = consumers;
- pdata->num_consumer_supplies = num_consumers;
- }
-
- if (pdata->driver_data) {
- /* If we have existing drv_data, just add the flags */
- struct twl_regulator_driver_data *tmp;
- tmp = pdata->driver_data;
- tmp->features |= features;
- } else {
- /* add new driver data struct, used only during init */
- drv_data.features = features;
- drv_data.set_voltage = NULL;
- drv_data.get_voltage = NULL;
- drv_data.data = NULL;
- pdata->driver_data = &drv_data;
- }
-
- /* NOTE: we currently ignore regulator IRQs, e.g. for short circuits */
- return add_numbered_child(TWL_MODULE_PM_MASTER, "twl_reg", num,
- pdata, sizeof(*pdata), false, 0, 0);
-}
-
-static struct device *
-add_regulator(int num, struct regulator_init_data *pdata,
- unsigned long features)
-{
- return add_regulator_linked(num, pdata, NULL, 0, features);
-}
-
-/*
- * NOTE: We know the first 8 IRQs after pdata->base_irq are
- * for the PIH, and the next are for the PWR_INT SIH, since
- * that's how twl_init_irq() sets things up.
- */
-
-static int
-add_children(struct twl4030_platform_data *pdata, unsigned irq_base,
- unsigned long features)
-{
- struct device *child;
-
- if (IS_ENABLED(CONFIG_GPIO_TWL4030) && pdata->gpio) {
- child = add_child(TWL4030_MODULE_GPIO, "twl4030_gpio",
- pdata->gpio, sizeof(*pdata->gpio),
- false, irq_base + GPIO_INTR_OFFSET, 0);
- if (IS_ERR(child))
- return PTR_ERR(child);
- }
-
- if (IS_ENABLED(CONFIG_KEYBOARD_TWL4030) && pdata->keypad) {
- child = add_child(TWL4030_MODULE_KEYPAD, "twl4030_keypad",
- pdata->keypad, sizeof(*pdata->keypad),
- true, irq_base + KEYPAD_INTR_OFFSET, 0);
- if (IS_ERR(child))
- return PTR_ERR(child);
- }
-
- if (IS_ENABLED(CONFIG_TWL4030_MADC) && pdata->madc &&
- twl_class_is_4030()) {
- child = add_child(TWL4030_MODULE_MADC, "twl4030_madc",
- pdata->madc, sizeof(*pdata->madc),
- true, irq_base + MADC_INTR_OFFSET, 0);
- if (IS_ERR(child))
- return PTR_ERR(child);
- }
-
- if (IS_ENABLED(CONFIG_RTC_DRV_TWL4030)) {
- /*
- * REVISIT platform_data here currently might expose the
- * "msecure" line ... but for now we just expect board
- * setup to tell the chip "it's always ok to SET_TIME".
- * Eventually, Linux might become more aware of such
- * HW security concerns, and "least privilege".
- */
- child = add_child(TWL_MODULE_RTC, "twl_rtc", NULL, 0,
- true, irq_base + RTC_INTR_OFFSET, 0);
- if (IS_ERR(child))
- return PTR_ERR(child);
- }
-
- if (IS_ENABLED(CONFIG_PWM_TWL)) {
- child = add_child(TWL_MODULE_PWM, "twl-pwm", NULL, 0,
- false, 0, 0);
- if (IS_ERR(child))
- return PTR_ERR(child);
- }
-
- if (IS_ENABLED(CONFIG_PWM_TWL_LED)) {
- child = add_child(TWL_MODULE_LED, "twl-pwmled", NULL, 0,
- false, 0, 0);
- if (IS_ERR(child))
- return PTR_ERR(child);
- }
-
- if (IS_ENABLED(CONFIG_TWL4030_USB) && pdata->usb &&
- twl_class_is_4030()) {
-
- static struct regulator_consumer_supply usb1v5 = {
- .supply = "usb1v5",
- };
- static struct regulator_consumer_supply usb1v8 = {
- .supply = "usb1v8",
- };
- static struct regulator_consumer_supply usb3v1 = {
- .supply = "usb3v1",
- };
-
- /* First add the regulators so that they can be used by transceiver */
- if (IS_ENABLED(CONFIG_REGULATOR_TWL4030)) {
- /* this is a template that gets copied */
- struct regulator_init_data usb_fixed = {
- .constraints.valid_modes_mask =
- REGULATOR_MODE_NORMAL
- | REGULATOR_MODE_STANDBY,
- .constraints.valid_ops_mask =
- REGULATOR_CHANGE_MODE
- | REGULATOR_CHANGE_STATUS,
- };
-
- child = add_regulator_linked(TWL4030_REG_VUSB1V5,
- &usb_fixed, &usb1v5, 1,
- features);
- if (IS_ERR(child))
- return PTR_ERR(child);
-
- child = add_regulator_linked(TWL4030_REG_VUSB1V8,
- &usb_fixed, &usb1v8, 1,
- features);
- if (IS_ERR(child))
- return PTR_ERR(child);
-
- child = add_regulator_linked(TWL4030_REG_VUSB3V1,
- &usb_fixed, &usb3v1, 1,
- features);
- if (IS_ERR(child))
- return PTR_ERR(child);
-
- }
-
- child = add_child(TWL_MODULE_USB, "twl4030_usb",
- pdata->usb, sizeof(*pdata->usb), true,
- /* irq0 = USB_PRES, irq1 = USB */
- irq_base + USB_PRES_INTR_OFFSET,
- irq_base + USB_INTR_OFFSET);
-
- if (IS_ERR(child))
- return PTR_ERR(child);
-
- /* we need to connect regulators to this transceiver */
- if (IS_ENABLED(CONFIG_REGULATOR_TWL4030) && child) {
- usb1v5.dev_name = dev_name(child);
- usb1v8.dev_name = dev_name(child);
- usb3v1.dev_name = dev_name(child);
- }
- }
-
- if (IS_ENABLED(CONFIG_TWL4030_WATCHDOG) && twl_class_is_4030()) {
- child = add_child(TWL_MODULE_PM_RECEIVER, "twl4030_wdt", NULL,
- 0, false, 0, 0);
- if (IS_ERR(child))
- return PTR_ERR(child);
- }
-
- if (IS_ENABLED(CONFIG_INPUT_TWL4030_PWRBUTTON) && twl_class_is_4030()) {
- child = add_child(TWL_MODULE_PM_MASTER, "twl4030_pwrbutton",
- NULL, 0, true, irq_base + 8 + 0, 0);
- if (IS_ERR(child))
- return PTR_ERR(child);
- }
-
- if (IS_ENABLED(CONFIG_MFD_TWL4030_AUDIO) && pdata->audio &&
- twl_class_is_4030()) {
- child = add_child(TWL4030_MODULE_AUDIO_VOICE, "twl4030-audio",
- pdata->audio, sizeof(*pdata->audio),
- false, 0, 0);
- if (IS_ERR(child))
- return PTR_ERR(child);
- }
-
- /* twl4030 regulators */
- if (IS_ENABLED(CONFIG_REGULATOR_TWL4030) && twl_class_is_4030()) {
- child = add_regulator(TWL4030_REG_VPLL1, pdata->vpll1,
- features);
- if (IS_ERR(child))
- return PTR_ERR(child);
-
- child = add_regulator(TWL4030_REG_VIO, pdata->vio,
- features);
- if (IS_ERR(child))
- return PTR_ERR(child);
-
- child = add_regulator(TWL4030_REG_VDD1, pdata->vdd1,
- features);
- if (IS_ERR(child))
- return PTR_ERR(child);
-
- child = add_regulator(TWL4030_REG_VDD2, pdata->vdd2,
- features);
- if (IS_ERR(child))
- return PTR_ERR(child);
-
- child = add_regulator(TWL4030_REG_VMMC1, pdata->vmmc1,
- features);
- if (IS_ERR(child))
- return PTR_ERR(child);
-
- child = add_regulator(TWL4030_REG_VDAC, pdata->vdac,
- features);
- if (IS_ERR(child))
- return PTR_ERR(child);
-
- child = add_regulator((features & TWL4030_VAUX2)
- ? TWL4030_REG_VAUX2_4030
- : TWL4030_REG_VAUX2,
- pdata->vaux2, features);
- if (IS_ERR(child))
- return PTR_ERR(child);
-
- child = add_regulator(TWL4030_REG_VINTANA1, pdata->vintana1,
- features);
- if (IS_ERR(child))
- return PTR_ERR(child);
-
- child = add_regulator(TWL4030_REG_VINTANA2, pdata->vintana2,
- features);
- if (IS_ERR(child))
- return PTR_ERR(child);
-
- child = add_regulator(TWL4030_REG_VINTDIG, pdata->vintdig,
- features);
- if (IS_ERR(child))
- return PTR_ERR(child);
- }
-
- /* maybe add LDOs that are omitted on cost-reduced parts */
- if (IS_ENABLED(CONFIG_REGULATOR_TWL4030) && !(features & TPS_SUBSET)
- && twl_class_is_4030()) {
- child = add_regulator(TWL4030_REG_VPLL2, pdata->vpll2,
- features);
- if (IS_ERR(child))
- return PTR_ERR(child);
-
- child = add_regulator(TWL4030_REG_VMMC2, pdata->vmmc2,
- features);
- if (IS_ERR(child))
- return PTR_ERR(child);
-
- child = add_regulator(TWL4030_REG_VSIM, pdata->vsim,
- features);
- if (IS_ERR(child))
- return PTR_ERR(child);
-
- child = add_regulator(TWL4030_REG_VAUX1, pdata->vaux1,
- features);
- if (IS_ERR(child))
- return PTR_ERR(child);
-
- child = add_regulator(TWL4030_REG_VAUX3, pdata->vaux3,
- features);
- if (IS_ERR(child))
- return PTR_ERR(child);
-
- child = add_regulator(TWL4030_REG_VAUX4, pdata->vaux4,
- features);
- if (IS_ERR(child))
- return PTR_ERR(child);
- }
-
- if (IS_ENABLED(CONFIG_CHARGER_TWL4030) && pdata->bci &&
- !(features & (TPS_SUBSET | TWL5031))) {
- child = add_child(TWL_MODULE_MAIN_CHARGE, "twl4030_bci",
- pdata->bci, sizeof(*pdata->bci), false,
- /* irq0 = CHG_PRES, irq1 = BCI */
- irq_base + BCI_PRES_INTR_OFFSET,
- irq_base + BCI_INTR_OFFSET);
- if (IS_ERR(child))
- return PTR_ERR(child);
- }
-
- if (IS_ENABLED(CONFIG_TWL4030_POWER) && pdata->power) {
- child = add_child(TWL_MODULE_PM_MASTER, "twl4030_power",
- pdata->power, sizeof(*pdata->power), false,
- 0, 0);
- if (IS_ERR(child))
- return PTR_ERR(child);
- }
-
- return 0;
-}
-
/*----------------------------------------------------------------------*/
/*
@@ -987,8 +684,7 @@ static inline int unprotect_pm_master(void)
return e;
}
-static void clocks_init(struct device *dev,
- struct twl4030_clock_init_data *clock)
+static void clocks_init(struct device *dev)
{
int e = 0;
struct clk *osc;
@@ -1018,8 +714,6 @@ static void clocks_init(struct device *dev,
}
ctrl |= HIGH_PERF_SQ;
- if (clock && clock->ck32k_lowpwr_enable)
- ctrl |= CK32K_LOWPWR_EN;
e |= unprotect_pm_master();
/* effect->MADC+USB ck en */
@@ -1063,7 +757,6 @@ static struct of_dev_auxdata twl_auxdata_lookup[] = {
static int
twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
- struct twl4030_platform_data *pdata = dev_get_platdata(&client->dev);
struct device_node *node = client->dev.of_node;
struct platform_device *pdev;
const struct regmap_config *twl_regmap_config;
@@ -1071,7 +764,7 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
int status;
unsigned i, num_slaves;
- if (!node && !pdata) {
+ if (!node) {
dev_err(&client->dev, "no platform data\n");
return -EINVAL;
}
@@ -1161,7 +854,7 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
twl_priv->ready = true;
/* setup clock framework */
- clocks_init(&client->dev, pdata ? pdata->clock : NULL);
+ clocks_init(&client->dev);
/* read TWL IDCODE Register */
if (twl_class_is_4030()) {
@@ -1209,14 +902,8 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
TWL4030_DCDC_GLOBAL_CFG);
}
- if (node) {
- if (pdata)
- twl_auxdata_lookup[0].platform_data = pdata->gpio;
- status = of_platform_populate(node, NULL, twl_auxdata_lookup,
- &client->dev);
- } else {
- status = add_children(pdata, irq_base, id->driver_data);
- }
+ status = of_platform_populate(node, NULL, twl_auxdata_lookup,
+ &client->dev);
fail:
if (status < 0)
diff --git a/drivers/mfd/ucb1400_core.c b/drivers/mfd/ucb1400_core.c
index 8c3832a58ef6..ac1d18039568 100644
--- a/drivers/mfd/ucb1400_core.c
+++ b/drivers/mfd/ucb1400_core.c
@@ -72,11 +72,9 @@ static int ucb1400_core_probe(struct device *dev)
/* GPIO */
ucb_gpio.ac97 = ac97;
- if (pdata) {
- ucb_gpio.gpio_setup = pdata->gpio_setup;
- ucb_gpio.gpio_teardown = pdata->gpio_teardown;
+ if (pdata)
ucb_gpio.gpio_offset = pdata->gpio_offset;
- }
+
ucb->ucb1400_gpio = platform_device_alloc("ucb1400_gpio", -1);
if (!ucb->ucb1400_gpio) {
err = -ENOMEM;