summaryrefslogtreecommitdiff
path: root/drivers/mfd
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mfd')
-rw-r--r--drivers/mfd/Kconfig16
-rw-r--r--drivers/mfd/Makefile1
-rw-r--r--drivers/mfd/altera-sysmgr.c2
-rw-r--r--drivers/mfd/bcm2835-pm.c1
-rw-r--r--drivers/mfd/da9055-core.c2
-rw-r--r--drivers/mfd/da9063-i2c.c3
-rw-r--r--drivers/mfd/ls2k-bmc-core.c2
-rw-r--r--drivers/mfd/macsmc.c6
-rw-r--r--drivers/mfd/max77620.c15
-rw-r--r--drivers/mfd/mt6358-irq.c1
-rw-r--r--drivers/mfd/mt6397-irq.c1
-rw-r--r--drivers/mfd/qnap-mcu.c80
-rw-r--r--drivers/mfd/rohm-bd718x7.c9
-rw-r--r--drivers/mfd/sec-acpm.c23
-rw-r--r--drivers/mfd/sec-irq.c73
-rw-r--r--drivers/mfd/simple-mfd-i2c.c18
-rw-r--r--drivers/mfd/syscon.c2
-rw-r--r--drivers/mfd/tqmx86.c8
-rw-r--r--drivers/mfd/wl1273-core.c262
19 files changed, 198 insertions, 327 deletions
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 219ee6ddf516..aace5766b38a 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -45,7 +45,8 @@ config MFD_ALTERA_A10SR
config MFD_ALTERA_SYSMGR
bool "Altera SOCFPGA System Manager"
- depends on ARCH_INTEL_SOCFPGA && OF
+ depends on ARCH_INTEL_SOCFPGA || COMPILE_TEST
+ depends on OF
select MFD_SYSCON
help
Select this to get System Manager support for all Altera branded
@@ -895,7 +896,7 @@ config MFD_88PM886_PMIC
config MFD_MAX5970
tristate "Maxim 5970/5978 power switch and monitor"
- depends on I2C && OF
+ depends on I2C
select MFD_SIMPLE_MFD_I2C
help
This driver controls a Maxim 5970/5978 switch via I2C bus.
@@ -1274,7 +1275,6 @@ config MFD_SPACEMIT_P1
tristate "SpacemiT P1 PMIC"
depends on ARCH_SPACEMIT || COMPILE_TEST
depends on I2C
- select I2C_K1
select MFD_SIMPLE_MFD_I2C
help
This option supports the I2C-based SpacemiT P1 PMIC, which
@@ -2002,16 +2002,6 @@ config MENELAUS
and other features that are often used in portable devices like
cell phones and PDAs.
-config MFD_WL1273_CORE
- tristate "TI WL1273 FM radio"
- depends on I2C
- select MFD_CORE
- default n
- help
- This is the core driver for the TI WL1273 FM radio. This MFD
- driver connects the radio-wl1273 V4L2 module and the wl1273
- audio codec.
-
config MFD_LM3533
tristate "TI/National Semiconductor LM3533 Lighting Power chip"
depends on I2C
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 566952f191b5..e75e8045c28a 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -207,7 +207,6 @@ obj-$(CONFIG_MFD_RDC321X) += rdc321x-southbridge.o
obj-$(CONFIG_MFD_JANZ_CMODIO) += janz-cmodio.o
obj-$(CONFIG_MFD_TPS6586X) += tps6586x.o
obj-$(CONFIG_MFD_VX855) += vx855.o
-obj-$(CONFIG_MFD_WL1273_CORE) += wl1273-core.o
si476x-core-y := si476x-cmd.o si476x-prop.o si476x-i2c.o
obj-$(CONFIG_MFD_SI476X_CORE) += si476x-core.o
diff --git a/drivers/mfd/altera-sysmgr.c b/drivers/mfd/altera-sysmgr.c
index fb5f988e61f3..90c6902d537d 100644
--- a/drivers/mfd/altera-sysmgr.c
+++ b/drivers/mfd/altera-sysmgr.c
@@ -117,6 +117,8 @@ struct regmap *altr_sysmgr_regmap_lookup_by_phandle(struct device_node *np,
sysmgr = dev_get_drvdata(dev);
+ put_device(dev);
+
return sysmgr->regmap;
}
EXPORT_SYMBOL_GPL(altr_sysmgr_regmap_lookup_by_phandle);
diff --git a/drivers/mfd/bcm2835-pm.c b/drivers/mfd/bcm2835-pm.c
index 3cb2b9423121..8bed59816e82 100644
--- a/drivers/mfd/bcm2835-pm.c
+++ b/drivers/mfd/bcm2835-pm.c
@@ -108,6 +108,7 @@ static const struct of_device_id bcm2835_pm_of_match[] = {
{ .compatible = "brcm,bcm2835-pm-wdt", },
{ .compatible = "brcm,bcm2835-pm", },
{ .compatible = "brcm,bcm2711-pm", },
+ { .compatible = "brcm,bcm2712-pm", },
{},
};
MODULE_DEVICE_TABLE(of, bcm2835_pm_of_match);
diff --git a/drivers/mfd/da9055-core.c b/drivers/mfd/da9055-core.c
index 1f727ef60d63..158590ad37d4 100644
--- a/drivers/mfd/da9055-core.c
+++ b/drivers/mfd/da9055-core.c
@@ -387,7 +387,7 @@ int da9055_device_init(struct da9055 *da9055)
return 0;
err:
- mfd_remove_devices(da9055->dev);
+ regmap_del_irq_chip(da9055->chip_irq, da9055->irq_data);
return ret;
}
diff --git a/drivers/mfd/da9063-i2c.c b/drivers/mfd/da9063-i2c.c
index 1ec9ab56442d..a803b7440f09 100644
--- a/drivers/mfd/da9063-i2c.c
+++ b/drivers/mfd/da9063-i2c.c
@@ -469,6 +469,9 @@ static int da9063_i2c_probe(struct i2c_client *i2c)
}
}
+ /* Reserve our unused second address so userspace won't interfere */
+ devm_i2c_new_dummy_device(&i2c->dev, i2c->adapter, i2c->addr + 1);
+
return da9063_device_init(da9063, i2c->irq);
}
diff --git a/drivers/mfd/ls2k-bmc-core.c b/drivers/mfd/ls2k-bmc-core.c
index 69387dad6661..e42f1de9e641 100644
--- a/drivers/mfd/ls2k-bmc-core.c
+++ b/drivers/mfd/ls2k-bmc-core.c
@@ -265,7 +265,7 @@ static int ls2k_bmc_recover_pci_data(void *data)
if (!ls2k_bmc_bar0_addr_is_set(parent))
break;
mdelay(1);
- };
+ }
if (i == 0)
return false;
diff --git a/drivers/mfd/macsmc.c b/drivers/mfd/macsmc.c
index e6cdae221f1d..e3893e255ce5 100644
--- a/drivers/mfd/macsmc.c
+++ b/drivers/mfd/macsmc.c
@@ -173,7 +173,7 @@ int apple_smc_read(struct apple_smc *smc, smc_key key, void *buf, size_t size)
}
EXPORT_SYMBOL(apple_smc_read);
-int apple_smc_write(struct apple_smc *smc, smc_key key, void *buf, size_t size)
+int apple_smc_write(struct apple_smc *smc, smc_key key, const void *buf, size_t size)
{
guard(mutex)(&smc->mutex);
@@ -181,7 +181,7 @@ int apple_smc_write(struct apple_smc *smc, smc_key key, void *buf, size_t size)
}
EXPORT_SYMBOL(apple_smc_write);
-int apple_smc_rw(struct apple_smc *smc, smc_key key, void *wbuf, size_t wsize,
+int apple_smc_rw(struct apple_smc *smc, smc_key key, const void *wbuf, size_t wsize,
void *rbuf, size_t rsize)
{
guard(mutex)(&smc->mutex);
@@ -239,7 +239,7 @@ int apple_smc_enter_atomic(struct apple_smc *smc)
}
EXPORT_SYMBOL(apple_smc_enter_atomic);
-int apple_smc_write_atomic(struct apple_smc *smc, smc_key key, void *buf, size_t size)
+int apple_smc_write_atomic(struct apple_smc *smc, smc_key key, const void *buf, size_t size)
{
guard(spinlock_irqsave)(&smc->lock);
u8 result;
diff --git a/drivers/mfd/max77620.c b/drivers/mfd/max77620.c
index 21d2ab3db254..3af2974b3023 100644
--- a/drivers/mfd/max77620.c
+++ b/drivers/mfd/max77620.c
@@ -254,7 +254,7 @@ static int max77620_irq_global_unmask(void *irq_drv_data)
return ret;
}
-static struct regmap_irq_chip max77620_top_irq_chip = {
+static const struct regmap_irq_chip max77620_top_irq_chip = {
.name = "max77620-top",
.irqs = max77620_top_irqs,
.num_irqs = ARRAY_SIZE(max77620_top_irqs),
@@ -498,6 +498,7 @@ static int max77620_probe(struct i2c_client *client)
const struct i2c_device_id *id = i2c_client_get_device_id(client);
const struct regmap_config *rmap_config;
struct max77620_chip *chip;
+ struct regmap_irq_chip *chip_desc;
const struct mfd_cell *mfd_cells;
int n_mfd_cells;
bool pm_off;
@@ -508,6 +509,14 @@ static int max77620_probe(struct i2c_client *client)
return -ENOMEM;
i2c_set_clientdata(client, chip);
+
+ chip_desc = devm_kmemdup(&client->dev, &max77620_top_irq_chip,
+ sizeof(max77620_top_irq_chip),
+ GFP_KERNEL);
+ if (!chip_desc)
+ return -ENOMEM;
+ chip_desc->irq_drv_data = chip;
+
chip->dev = &client->dev;
chip->chip_irq = client->irq;
chip->chip_id = (enum max77620_chip_id)id->driver_data;
@@ -544,11 +553,9 @@ static int max77620_probe(struct i2c_client *client)
if (ret < 0)
return ret;
- max77620_top_irq_chip.irq_drv_data = chip;
ret = devm_regmap_add_irq_chip(chip->dev, chip->rmap, client->irq,
IRQF_ONESHOT | IRQF_SHARED, 0,
- &max77620_top_irq_chip,
- &chip->top_irq_data);
+ chip_desc, &chip->top_irq_data);
if (ret < 0) {
dev_err(chip->dev, "Failed to add regmap irq: %d\n", ret);
return ret;
diff --git a/drivers/mfd/mt6358-irq.c b/drivers/mfd/mt6358-irq.c
index f467b00d2366..74cf20843044 100644
--- a/drivers/mfd/mt6358-irq.c
+++ b/drivers/mfd/mt6358-irq.c
@@ -285,6 +285,7 @@ int mt6358_irq_init(struct mt6397_chip *chip)
if (ret) {
dev_err(chip->dev, "Failed to register IRQ=%d, ret=%d\n",
chip->irq, ret);
+ irq_domain_remove(chip->irq_domain);
return ret;
}
diff --git a/drivers/mfd/mt6397-irq.c b/drivers/mfd/mt6397-irq.c
index 0e463026c5a9..5d2e5459f744 100644
--- a/drivers/mfd/mt6397-irq.c
+++ b/drivers/mfd/mt6397-irq.c
@@ -229,6 +229,7 @@ int mt6397_irq_init(struct mt6397_chip *chip)
if (ret) {
dev_err(chip->dev, "failed to register irq=%d; err: %d\n",
chip->irq, ret);
+ irq_domain_remove(chip->irq_domain);
return ret;
}
diff --git a/drivers/mfd/qnap-mcu.c b/drivers/mfd/qnap-mcu.c
index 4ec1f4cf902f..f81c69f22254 100644
--- a/drivers/mfd/qnap-mcu.c
+++ b/drivers/mfd/qnap-mcu.c
@@ -19,6 +19,7 @@
/* The longest command found so far is 5 bytes long */
#define QNAP_MCU_MAX_CMD_SIZE 5
#define QNAP_MCU_MAX_DATA_SIZE 36
+#define QNAP_MCU_ERROR_SIZE 2
#define QNAP_MCU_CHECKSUM_SIZE 1
#define QNAP_MCU_RX_BUFFER_SIZE \
@@ -78,6 +79,13 @@ static u8 qnap_mcu_csum(const u8 *buf, size_t size)
return csum;
}
+static bool qnap_mcu_verify_checksum(const u8 *buf, size_t size)
+{
+ u8 crc = qnap_mcu_csum(buf, size - QNAP_MCU_CHECKSUM_SIZE);
+
+ return crc == buf[size - QNAP_MCU_CHECKSUM_SIZE];
+}
+
static int qnap_mcu_write(struct qnap_mcu *mcu, const u8 *data, u8 data_size)
{
unsigned char tx[QNAP_MCU_TX_BUFFER_SIZE];
@@ -96,6 +104,48 @@ static int qnap_mcu_write(struct qnap_mcu *mcu, const u8 *data, u8 data_size)
return serdev_device_write(mcu->serdev, tx, length, HZ);
}
+static bool qnap_mcu_is_error_msg(size_t size)
+{
+ return (size == QNAP_MCU_ERROR_SIZE + QNAP_MCU_CHECKSUM_SIZE);
+}
+
+static bool qnap_mcu_reply_is_generic_error(unsigned char *buf, size_t size)
+{
+ if (!qnap_mcu_is_error_msg(size))
+ return false;
+
+ if (buf[0] == '@' && buf[1] == '9')
+ return true;
+
+ return false;
+}
+
+static bool qnap_mcu_reply_is_checksum_error(unsigned char *buf, size_t size)
+{
+ if (!qnap_mcu_is_error_msg(size))
+ return false;
+
+ if (buf[0] == '@' && buf[1] == '8')
+ return true;
+
+ return false;
+}
+
+static bool qnap_mcu_reply_is_any_error(struct qnap_mcu *mcu, unsigned char *buf, size_t size)
+{
+ if (qnap_mcu_reply_is_generic_error(buf, size)) {
+ dev_err(&mcu->serdev->dev, "Controller sent generic error response\n");
+ return true;
+ }
+
+ if (qnap_mcu_reply_is_checksum_error(buf, size)) {
+ dev_err(&mcu->serdev->dev, "Controller received invalid checksum for the command\n");
+ return true;
+ }
+
+ return false;
+}
+
static size_t qnap_mcu_receive_buf(struct serdev_device *serdev, const u8 *buf, size_t size)
{
struct device *dev = &serdev->dev;
@@ -130,6 +180,24 @@ static size_t qnap_mcu_receive_buf(struct serdev_device *serdev, const u8 *buf,
}
/*
+ * We received everything the uart had to offer for now.
+ * This could mean that either the uart will send more in a 2nd
+ * receive run, or that the MCU cut the reply short because it
+ * sent an error code instead of the expected reply.
+ *
+ * So check if the received data has the correct size for an error
+ * reply and if it matches, is an actual error code.
+ */
+ if (qnap_mcu_is_error_msg(reply->received) &&
+ qnap_mcu_verify_checksum(reply->data, reply->received) &&
+ qnap_mcu_reply_is_any_error(mcu, reply->data, reply->received)) {
+ /* The reply was an error code, we're done */
+ reply->length = 0;
+
+ complete(&reply->done);
+ }
+
+ /*
* The only way to get out of the above loop and end up here
* is through consuming all of the supplied data, so here we
* report that we processed it all.
@@ -150,7 +218,6 @@ int qnap_mcu_exec(struct qnap_mcu *mcu,
size_t length = reply_data_size + QNAP_MCU_CHECKSUM_SIZE;
struct qnap_mcu_reply *reply = &mcu->reply;
int ret = 0;
- u8 crc;
if (length > sizeof(rx)) {
dev_err(&mcu->serdev->dev, "expected data too big for receive buffer");
@@ -175,12 +242,14 @@ int qnap_mcu_exec(struct qnap_mcu *mcu,
return -ETIMEDOUT;
}
- crc = qnap_mcu_csum(rx, reply_data_size);
- if (crc != rx[reply_data_size]) {
- dev_err(&mcu->serdev->dev, "Invalid Checksum received\n");
- return -EIO;
+ if (!qnap_mcu_verify_checksum(rx, reply->received)) {
+ dev_err(&mcu->serdev->dev, "Invalid Checksum received from controller\n");
+ return -EPROTO;
}
+ if (qnap_mcu_reply_is_any_error(mcu, rx, reply->received))
+ return -EPROTO;
+
memcpy(reply_data, rx, reply_data_size);
return 0;
@@ -264,6 +333,7 @@ static const struct qnap_mcu_variant qnap_ts433_mcu = {
};
static struct mfd_cell qnap_mcu_cells[] = {
+ { .name = "qnap-mcu-eeprom", },
{ .name = "qnap-mcu-input", },
{ .name = "qnap-mcu-leds", },
{ .name = "qnap-mcu-hwmon", }
diff --git a/drivers/mfd/rohm-bd718x7.c b/drivers/mfd/rohm-bd718x7.c
index 25e494a93d48..ff714fd4f54d 100644
--- a/drivers/mfd/rohm-bd718x7.c
+++ b/drivers/mfd/rohm-bd718x7.c
@@ -72,14 +72,13 @@ static const struct regmap_irq_chip bd718xx_irq_chip = {
.init_ack_masked = true,
};
-static const struct regmap_range pmic_status_range = {
- .range_min = BD718XX_REG_IRQ,
- .range_max = BD718XX_REG_POW_STATE,
+static const struct regmap_range pmic_status_range[] = {
+ regmap_reg_range(BD718XX_REG_IRQ, BD718XX_REG_POW_STATE),
};
static const struct regmap_access_table volatile_regs = {
- .yes_ranges = &pmic_status_range,
- .n_yes_ranges = 1,
+ .yes_ranges = &pmic_status_range[0],
+ .n_yes_ranges = ARRAY_SIZE(pmic_status_range),
};
static const struct regmap_config bd718xx_regmap_config = {
diff --git a/drivers/mfd/sec-acpm.c b/drivers/mfd/sec-acpm.c
index 8b31c816d65b..36622069a788 100644
--- a/drivers/mfd/sec-acpm.c
+++ b/drivers/mfd/sec-acpm.c
@@ -325,11 +325,6 @@ static struct regmap *sec_pmic_acpm_regmap_init(struct device *dev,
return regmap;
}
-static void sec_pmic_acpm_mask_common_irqs(void *regmap_common)
-{
- regmap_write(regmap_common, S2MPG10_COMMON_INT_MASK, S2MPG10_COMMON_INT_SRC);
-}
-
static int sec_pmic_acpm_probe(struct platform_device *pdev)
{
struct regmap *regmap_common, *regmap_pmic, *regmap;
@@ -360,15 +355,10 @@ static int sec_pmic_acpm_probe(struct platform_device *pdev)
shared_ctx->speedy_channel = pdata->speedy_channel;
regmap_common = sec_pmic_acpm_regmap_init(dev, shared_ctx, SEC_PMIC_ACPM_ACCESSTYPE_COMMON,
- pdata->regmap_cfg_common, false);
+ pdata->regmap_cfg_common, true);
if (IS_ERR(regmap_common))
return PTR_ERR(regmap_common);
- /* Mask all interrupts from 'common' block, until successful init */
- ret = regmap_write(regmap_common, S2MPG10_COMMON_INT_MASK, S2MPG10_COMMON_INT_SRC);
- if (ret)
- return dev_err_probe(dev, ret, "failed to mask common block interrupts\n");
-
regmap_pmic = sec_pmic_acpm_regmap_init(dev, shared_ctx, SEC_PMIC_ACPM_ACCESSTYPE_PMIC,
pdata->regmap_cfg_pmic, false);
if (IS_ERR(regmap_pmic))
@@ -391,17 +381,6 @@ static int sec_pmic_acpm_probe(struct platform_device *pdev)
if (device_property_read_bool(dev, "wakeup-source"))
devm_device_init_wakeup(dev);
- /* Unmask PMIC interrupt from 'common' block, now that everything is in place. */
- ret = regmap_clear_bits(regmap_common, S2MPG10_COMMON_INT_MASK,
- S2MPG10_COMMON_INT_SRC_PMIC);
- if (ret)
- return dev_err_probe(dev, ret, "failed to unmask PMIC interrupt\n");
-
- /* Mask all interrupts from 'common' block on shutdown */
- ret = devm_add_action_or_reset(dev, sec_pmic_acpm_mask_common_irqs, regmap_common);
- if (ret)
- return ret;
-
return 0;
}
diff --git a/drivers/mfd/sec-irq.c b/drivers/mfd/sec-irq.c
index c5c80b1ba104..74ac70002d1f 100644
--- a/drivers/mfd/sec-irq.c
+++ b/drivers/mfd/sec-irq.c
@@ -20,6 +20,12 @@
#include "sec-core.h"
static const struct regmap_irq s2mpg10_irqs[] = {
+ REGMAP_IRQ_REG(S2MPG10_COMMON_IRQ_PMIC, 0, S2MPG10_COMMON_INT_SRC_PMIC),
+ /* No documentation or other reference for remaining bits */
+ REGMAP_IRQ_REG(S2MPG10_COMMON_IRQ_UNUSED, 0, GENMASK(7, 1)),
+};
+
+static const struct regmap_irq s2mpg10_pmic_irqs[] = {
REGMAP_IRQ_REG(S2MPG10_IRQ_PWRONF, 0, S2MPG10_IRQ_PWRONF_MASK),
REGMAP_IRQ_REG(S2MPG10_IRQ_PWRONR, 0, S2MPG10_IRQ_PWRONR_MASK),
REGMAP_IRQ_REG(S2MPG10_IRQ_JIGONBF, 0, S2MPG10_IRQ_JIGONBF_MASK),
@@ -183,11 +189,20 @@ static const struct regmap_irq s5m8767_irqs[] = {
/* All S2MPG10 interrupt sources are read-only and don't require clearing */
static const struct regmap_irq_chip s2mpg10_irq_chip = {
.name = "s2mpg10",
+ .status_base = S2MPG10_COMMON_INT,
+ .mask_base = S2MPG10_COMMON_INT_MASK,
+ .num_regs = 1,
.irqs = s2mpg10_irqs,
.num_irqs = ARRAY_SIZE(s2mpg10_irqs),
- .num_regs = 6,
+};
+
+static const struct regmap_irq_chip s2mpg10_irq_chip_pmic = {
+ .name = "s2mpg10-pmic",
.status_base = S2MPG10_PMIC_INT1,
.mask_base = S2MPG10_PMIC_INT1M,
+ .num_regs = 6,
+ .irqs = s2mpg10_pmic_irqs,
+ .num_irqs = ARRAY_SIZE(s2mpg10_pmic_irqs),
};
static const struct regmap_irq_chip s2mps11_irq_chip = {
@@ -253,6 +268,59 @@ static const struct regmap_irq_chip s5m8767_irq_chip = {
.ack_base = S5M8767_REG_INT1,
};
+static int s2mpg1x_add_chained_irq_chip(struct device *dev, struct regmap *regmap, int pirq,
+ struct regmap_irq_chip_data *parent,
+ const struct regmap_irq_chip *chip,
+ struct regmap_irq_chip_data **data)
+{
+ int irq, ret;
+
+ irq = regmap_irq_get_virq(parent, pirq);
+ if (irq < 0)
+ return dev_err_probe(dev, irq, "Failed to get parent vIRQ(%d) for chip %s\n", pirq,
+ chip->name);
+
+ ret = devm_regmap_add_irq_chip(dev, regmap, irq, IRQF_ONESHOT | IRQF_SHARED, 0, chip, data);
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to add %s IRQ chip\n", chip->name);
+
+ return 0;
+}
+
+static int sec_irq_init_s2mpg1x(struct sec_pmic_dev *sec_pmic)
+{
+ const struct regmap_irq_chip *irq_chip, *chained_irq_chip;
+ struct regmap_irq_chip_data *irq_data;
+ struct regmap *regmap_common;
+ int chained_pirq;
+ int ret;
+
+ switch (sec_pmic->device_type) {
+ case S2MPG10:
+ irq_chip = &s2mpg10_irq_chip;
+ chained_irq_chip = &s2mpg10_irq_chip_pmic;
+ chained_pirq = S2MPG10_COMMON_IRQ_PMIC;
+ break;
+ default:
+ return dev_err_probe(sec_pmic->dev, -EINVAL, "Unsupported device type %d\n",
+ sec_pmic->device_type);
+ }
+
+ regmap_common = dev_get_regmap(sec_pmic->dev, "common");
+ if (!regmap_common)
+ return dev_err_probe(sec_pmic->dev, -EINVAL, "No 'common' regmap %d\n",
+ sec_pmic->device_type);
+
+ ret = devm_regmap_add_irq_chip(sec_pmic->dev, regmap_common, sec_pmic->irq, IRQF_ONESHOT, 0,
+ irq_chip, &irq_data);
+ if (ret)
+ return dev_err_probe(sec_pmic->dev, ret, "Failed to add %s IRQ chip\n",
+ irq_chip->name);
+
+ return s2mpg1x_add_chained_irq_chip(sec_pmic->dev, sec_pmic->regmap_pmic, chained_pirq,
+ irq_data, chained_irq_chip, &sec_pmic->irq_data);
+}
+
int sec_irq_init(struct sec_pmic_dev *sec_pmic)
{
const struct regmap_irq_chip *sec_irq_chip;
@@ -268,8 +336,7 @@ int sec_irq_init(struct sec_pmic_dev *sec_pmic)
sec_irq_chip = &s2mps14_irq_chip;
break;
case S2MPG10:
- sec_irq_chip = &s2mpg10_irq_chip;
- break;
+ return sec_irq_init_s2mpg1x(sec_pmic);
case S2MPS11X:
sec_irq_chip = &s2mps11_irq_chip;
break;
diff --git a/drivers/mfd/simple-mfd-i2c.c b/drivers/mfd/simple-mfd-i2c.c
index 0a607a1e3ca1..8b751d8e3b5a 100644
--- a/drivers/mfd/simple-mfd-i2c.c
+++ b/drivers/mfd/simple-mfd-i2c.c
@@ -15,12 +15,18 @@
* will be subsequently registered.
*/
+#include <linux/array_size.h>
+#include <linux/dev_printk.h>
+#include <linux/err.h>
#include <linux/i2c.h>
-#include <linux/kernel.h>
#include <linux/mfd/core.h>
+#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/property.h>
#include <linux/regmap.h>
+#include <linux/stddef.h>
#include "simple-mfd-i2c.h"
@@ -114,11 +120,11 @@ static const struct of_device_id simple_mfd_i2c_of_match[] = {
{ .compatible = "fsl,lx2160aqds-fpga" },
{ .compatible = "fsl,lx2160ardb-fpga" },
{ .compatible = "kontron,sl28cpld" },
- { .compatible = "maxim,max5970", .data = &maxim_max5970},
- { .compatible = "maxim,max5978", .data = &maxim_max5970},
- { .compatible = "maxim,max77705-battery", .data = &maxim_mon_max77705},
- { .compatible = "silergy,sy7636a", .data = &silergy_sy7636a},
- { .compatible = "spacemit,p1", .data = &spacemit_p1, },
+ { .compatible = "maxim,max5970", .data = &maxim_max5970 },
+ { .compatible = "maxim,max5978", .data = &maxim_max5970 },
+ { .compatible = "maxim,max77705-battery", .data = &maxim_mon_max77705 },
+ { .compatible = "silergy,sy7636a", .data = &silergy_sy7636a },
+ { .compatible = "spacemit,p1", .data = &spacemit_p1 },
{}
};
MODULE_DEVICE_TABLE(of, simple_mfd_i2c_of_match);
diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c
index ae71a2710bed..e5d5def594f6 100644
--- a/drivers/mfd/syscon.c
+++ b/drivers/mfd/syscon.c
@@ -183,7 +183,7 @@ static struct regmap *device_node_get_regmap(struct device_node *np,
if (create_regmap)
syscon = of_syscon_register(np, check_res);
else
- syscon = ERR_PTR(-EINVAL);
+ syscon = ERR_PTR(-EPROBE_DEFER);
}
mutex_unlock(&syscon_list_lock);
diff --git a/drivers/mfd/tqmx86.c b/drivers/mfd/tqmx86.c
index 1cba3b67b0fb..1c2fe3f91238 100644
--- a/drivers/mfd/tqmx86.c
+++ b/drivers/mfd/tqmx86.c
@@ -43,6 +43,8 @@
#define TQMX86_REG_BOARD_ID_E40C2 15
#define TQMX86_REG_BOARD_ID_130UC 16
#define TQMX86_REG_BOARD_ID_E41S 19
+#define TQMX86_REG_BOARD_ID_CU1_HPCM 24
+#define TQMX86_REG_BOARD_ID_CU2_HPCM 25
#define TQMX86_REG_BOARD_REV 0x01
#define TQMX86_REG_IO_EXT_INT 0x06
#define TQMX86_REG_IO_EXT_INT_NONE 0
@@ -165,6 +167,10 @@ static const char *tqmx86_board_id_to_name(u8 board_id, u8 sauc)
return "TQMx130UC";
case TQMX86_REG_BOARD_ID_E41S:
return "TQMxE41S";
+ case TQMX86_REG_BOARD_ID_CU1_HPCM:
+ return "TQMxCU1-HPCM";
+ case TQMX86_REG_BOARD_ID_CU2_HPCM:
+ return "TQMxCU2-HPCM";
default:
return "Unknown";
}
@@ -185,6 +191,8 @@ static int tqmx86_board_id_to_clk_rate(struct device *dev, u8 board_id)
case TQMX86_REG_BOARD_ID_E40C2:
case TQMX86_REG_BOARD_ID_130UC:
case TQMX86_REG_BOARD_ID_E41S:
+ case TQMX86_REG_BOARD_ID_CU1_HPCM:
+ case TQMX86_REG_BOARD_ID_CU2_HPCM:
return 24000;
case TQMX86_REG_BOARD_ID_E39MS:
case TQMX86_REG_BOARD_ID_E39C1:
diff --git a/drivers/mfd/wl1273-core.c b/drivers/mfd/wl1273-core.c
deleted file mode 100644
index 2f185e93318e..000000000000
--- a/drivers/mfd/wl1273-core.c
+++ /dev/null
@@ -1,262 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * MFD driver for wl1273 FM radio and audio codec submodules.
- *
- * Copyright (C) 2011 Nokia Corporation
- * Author: Matti Aaltonen <matti.j.aaltonen@nokia.com>
- */
-
-#include <linux/mfd/wl1273-core.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-
-#define DRIVER_DESC "WL1273 FM Radio Core"
-
-static const struct i2c_device_id wl1273_driver_id_table[] = {
- { WL1273_FM_DRIVER_NAME },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, wl1273_driver_id_table);
-
-static int wl1273_fm_read_reg(struct wl1273_core *core, u8 reg, u16 *value)
-{
- struct i2c_client *client = core->client;
- u8 b[2];
- int r;
-
- r = i2c_smbus_read_i2c_block_data(client, reg, sizeof(b), b);
- if (r != 2) {
- dev_err(&client->dev, "%s: Read: %d fails.\n", __func__, reg);
- return -EREMOTEIO;
- }
-
- *value = (u16)b[0] << 8 | b[1];
-
- return 0;
-}
-
-static int wl1273_fm_write_cmd(struct wl1273_core *core, u8 cmd, u16 param)
-{
- struct i2c_client *client = core->client;
- u8 buf[] = { (param >> 8) & 0xff, param & 0xff };
- int r;
-
- r = i2c_smbus_write_i2c_block_data(client, cmd, sizeof(buf), buf);
- if (r) {
- dev_err(&client->dev, "%s: Cmd: %d fails.\n", __func__, cmd);
- return r;
- }
-
- return 0;
-}
-
-static int wl1273_fm_write_data(struct wl1273_core *core, u8 *data, u16 len)
-{
- struct i2c_client *client = core->client;
- struct i2c_msg msg;
- int r;
-
- msg.addr = client->addr;
- msg.flags = 0;
- msg.buf = data;
- msg.len = len;
-
- r = i2c_transfer(client->adapter, &msg, 1);
- if (r != 1) {
- dev_err(&client->dev, "%s: write error.\n", __func__);
- return -EREMOTEIO;
- }
-
- return 0;
-}
-
-/**
- * wl1273_fm_set_audio() - Set audio mode.
- * @core: A pointer to the device struct.
- * @new_mode: The new audio mode.
- *
- * Audio modes are WL1273_AUDIO_DIGITAL and WL1273_AUDIO_ANALOG.
- */
-static int wl1273_fm_set_audio(struct wl1273_core *core, unsigned int new_mode)
-{
- int r = 0;
-
- if (core->mode == WL1273_MODE_OFF ||
- core->mode == WL1273_MODE_SUSPENDED)
- return -EPERM;
-
- if (core->mode == WL1273_MODE_RX && new_mode == WL1273_AUDIO_DIGITAL) {
- r = wl1273_fm_write_cmd(core, WL1273_PCM_MODE_SET,
- WL1273_PCM_DEF_MODE);
- if (r)
- goto out;
-
- r = wl1273_fm_write_cmd(core, WL1273_I2S_MODE_CONFIG_SET,
- core->i2s_mode);
- if (r)
- goto out;
-
- r = wl1273_fm_write_cmd(core, WL1273_AUDIO_ENABLE,
- WL1273_AUDIO_ENABLE_I2S);
- if (r)
- goto out;
-
- } else if (core->mode == WL1273_MODE_RX &&
- new_mode == WL1273_AUDIO_ANALOG) {
- r = wl1273_fm_write_cmd(core, WL1273_AUDIO_ENABLE,
- WL1273_AUDIO_ENABLE_ANALOG);
- if (r)
- goto out;
-
- } else if (core->mode == WL1273_MODE_TX &&
- new_mode == WL1273_AUDIO_DIGITAL) {
- r = wl1273_fm_write_cmd(core, WL1273_I2S_MODE_CONFIG_SET,
- core->i2s_mode);
- if (r)
- goto out;
-
- r = wl1273_fm_write_cmd(core, WL1273_AUDIO_IO_SET,
- WL1273_AUDIO_IO_SET_I2S);
- if (r)
- goto out;
-
- } else if (core->mode == WL1273_MODE_TX &&
- new_mode == WL1273_AUDIO_ANALOG) {
- r = wl1273_fm_write_cmd(core, WL1273_AUDIO_IO_SET,
- WL1273_AUDIO_IO_SET_ANALOG);
- if (r)
- goto out;
- }
-
- core->audio_mode = new_mode;
-out:
- return r;
-}
-
-/**
- * wl1273_fm_set_volume() - Set volume.
- * @core: A pointer to the device struct.
- * @volume: The new volume value.
- */
-static int wl1273_fm_set_volume(struct wl1273_core *core, unsigned int volume)
-{
- int r;
-
- if (volume > WL1273_MAX_VOLUME)
- return -EINVAL;
-
- if (core->volume == volume)
- return 0;
-
- r = wl1273_fm_write_cmd(core, WL1273_VOLUME_SET, volume);
- if (r)
- return r;
-
- core->volume = volume;
- return 0;
-}
-
-static int wl1273_core_probe(struct i2c_client *client)
-{
- struct wl1273_fm_platform_data *pdata = dev_get_platdata(&client->dev);
- struct wl1273_core *core;
- struct mfd_cell *cell;
- int children = 0;
- int r = 0;
-
- dev_dbg(&client->dev, "%s\n", __func__);
-
- if (!pdata) {
- dev_err(&client->dev, "No platform data.\n");
- return -EINVAL;
- }
-
- if (!(pdata->children & WL1273_RADIO_CHILD)) {
- dev_err(&client->dev, "Cannot function without radio child.\n");
- return -EINVAL;
- }
-
- core = devm_kzalloc(&client->dev, sizeof(*core), GFP_KERNEL);
- if (!core)
- return -ENOMEM;
-
- core->pdata = pdata;
- core->client = client;
- mutex_init(&core->lock);
-
- i2c_set_clientdata(client, core);
-
- dev_dbg(&client->dev, "%s: Have V4L2.\n", __func__);
-
- cell = &core->cells[children];
- cell->name = "wl1273_fm_radio";
- cell->platform_data = &core;
- cell->pdata_size = sizeof(core);
- children++;
-
- core->read = wl1273_fm_read_reg;
- core->write = wl1273_fm_write_cmd;
- core->write_data = wl1273_fm_write_data;
- core->set_audio = wl1273_fm_set_audio;
- core->set_volume = wl1273_fm_set_volume;
-
- if (pdata->children & WL1273_CODEC_CHILD) {
- cell = &core->cells[children];
-
- dev_dbg(&client->dev, "%s: Have codec.\n", __func__);
- cell->name = "wl1273-codec";
- cell->platform_data = &core;
- cell->pdata_size = sizeof(core);
- children++;
- }
-
- dev_dbg(&client->dev, "%s: number of children: %d.\n",
- __func__, children);
-
- r = devm_mfd_add_devices(&client->dev, -1, core->cells,
- children, NULL, 0, NULL);
- if (r)
- goto err;
-
- return 0;
-
-err:
- pdata->free_resources();
-
- dev_dbg(&client->dev, "%s\n", __func__);
-
- return r;
-}
-
-static struct i2c_driver wl1273_core_driver = {
- .driver = {
- .name = WL1273_FM_DRIVER_NAME,
- },
- .probe = wl1273_core_probe,
- .id_table = wl1273_driver_id_table,
-};
-
-static int __init wl1273_core_init(void)
-{
- int r;
-
- r = i2c_add_driver(&wl1273_core_driver);
- if (r) {
- pr_err(WL1273_FM_DRIVER_NAME
- ": driver registration failed\n");
- return r;
- }
-
- return r;
-}
-
-static void __exit wl1273_core_exit(void)
-{
- i2c_del_driver(&wl1273_core_driver);
-}
-late_initcall(wl1273_core_init);
-module_exit(wl1273_core_exit);
-
-MODULE_AUTHOR("Matti Aaltonen <matti.j.aaltonen@nokia.com>");
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE("GPL");