diff options
Diffstat (limited to 'drivers/mfd')
| -rw-r--r-- | drivers/mfd/Kconfig | 16 | ||||
| -rw-r--r-- | drivers/mfd/Makefile | 1 | ||||
| -rw-r--r-- | drivers/mfd/altera-sysmgr.c | 2 | ||||
| -rw-r--r-- | drivers/mfd/bcm2835-pm.c | 1 | ||||
| -rw-r--r-- | drivers/mfd/da9055-core.c | 2 | ||||
| -rw-r--r-- | drivers/mfd/da9063-i2c.c | 3 | ||||
| -rw-r--r-- | drivers/mfd/ls2k-bmc-core.c | 2 | ||||
| -rw-r--r-- | drivers/mfd/macsmc.c | 6 | ||||
| -rw-r--r-- | drivers/mfd/max77620.c | 15 | ||||
| -rw-r--r-- | drivers/mfd/mt6358-irq.c | 1 | ||||
| -rw-r--r-- | drivers/mfd/mt6397-irq.c | 1 | ||||
| -rw-r--r-- | drivers/mfd/qnap-mcu.c | 80 | ||||
| -rw-r--r-- | drivers/mfd/rohm-bd718x7.c | 9 | ||||
| -rw-r--r-- | drivers/mfd/sec-acpm.c | 23 | ||||
| -rw-r--r-- | drivers/mfd/sec-irq.c | 73 | ||||
| -rw-r--r-- | drivers/mfd/simple-mfd-i2c.c | 18 | ||||
| -rw-r--r-- | drivers/mfd/syscon.c | 2 | ||||
| -rw-r--r-- | drivers/mfd/tqmx86.c | 8 | ||||
| -rw-r--r-- | drivers/mfd/wl1273-core.c | 262 |
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"); |
