From 6377cfa3b857ced301f2079ac97de6c19057ab65 Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Fri, 21 Dec 2018 14:46:32 +0100 Subject: mfd: stmpe: Preparations for STMPE ADC driver This prepares the MFD for the STMPE ADC driver. This commit introduces devicetree settings that are used by the ADC and adds an init function. Common ADC settings that are shared with the touchscreen driver can now reside in the overlying MFD. Signed-off-by: Stefan Agner Signed-off-by: Max Krummenacher Signed-off-by: Philippe Schenker Signed-off-by: Lee Jones --- drivers/mfd/Kconfig | 3 ++- drivers/mfd/stmpe.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+), 1 deletion(-) (limited to 'drivers/mfd') diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 8c5dfdce4326..bba159e8eaa4 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -1204,7 +1204,7 @@ config MFD_STMPE Currently supported devices are: - STMPE811: GPIO, Touchscreen + STMPE811: GPIO, Touchscreen, ADC STMPE1601: GPIO, Keypad STMPE1801: GPIO, Keypad STMPE2401: GPIO, Keypad @@ -1217,6 +1217,7 @@ config MFD_STMPE GPIO: stmpe-gpio Keypad: stmpe-keypad Touchscreen: stmpe-ts + ADC: stmpe-adc menu "STMicroelectronics STMPE Interface Drivers" depends on MFD_STMPE diff --git a/drivers/mfd/stmpe.c b/drivers/mfd/stmpe.c index 566caca4efd8..f582531a8f3e 100644 --- a/drivers/mfd/stmpe.c +++ b/drivers/mfd/stmpe.c @@ -463,6 +463,28 @@ static const struct mfd_cell stmpe_ts_cell = { .num_resources = ARRAY_SIZE(stmpe_ts_resources), }; +/* + * ADC (STMPE811) + */ + +static struct resource stmpe_adc_resources[] = { + { + .name = "STMPE_TEMP_SENS", + .flags = IORESOURCE_IRQ, + }, + { + .name = "STMPE_ADC", + .flags = IORESOURCE_IRQ, + }, +}; + +static const struct mfd_cell stmpe_adc_cell = { + .name = "stmpe-adc", + .of_compatible = "st,stmpe-adc", + .resources = stmpe_adc_resources, + .num_resources = ARRAY_SIZE(stmpe_adc_resources), +}; + /* * STMPE811 or STMPE610 */ @@ -497,6 +519,11 @@ static struct stmpe_variant_block stmpe811_blocks[] = { .irq = STMPE811_IRQ_TOUCH_DET, .block = STMPE_BLOCK_TOUCHSCREEN, }, + { + .cell = &stmpe_adc_cell, + .irq = STMPE811_IRQ_TEMP_SENS, + .block = STMPE_BLOCK_ADC, + }, }; static int stmpe811_enable(struct stmpe *stmpe, unsigned int blocks, @@ -517,6 +544,35 @@ static int stmpe811_enable(struct stmpe *stmpe, unsigned int blocks, enable ? 0 : mask); } +int stmpe811_adc_common_init(struct stmpe *stmpe) +{ + int ret; + u8 adc_ctrl1, adc_ctrl1_mask; + + adc_ctrl1 = STMPE_SAMPLE_TIME(stmpe->sample_time) | + STMPE_MOD_12B(stmpe->mod_12b) | + STMPE_REF_SEL(stmpe->ref_sel); + adc_ctrl1_mask = STMPE_SAMPLE_TIME(0xff) | STMPE_MOD_12B(0xff) | + STMPE_REF_SEL(0xff); + + ret = stmpe_set_bits(stmpe, STMPE811_REG_ADC_CTRL1, + adc_ctrl1_mask, adc_ctrl1); + if (ret) { + dev_err(stmpe->dev, "Could not setup ADC\n"); + return ret; + } + + ret = stmpe_set_bits(stmpe, STMPE811_REG_ADC_CTRL2, + STMPE_ADC_FREQ(0xff), STMPE_ADC_FREQ(stmpe->adc_freq)); + if (ret) { + dev_err(stmpe->dev, "Could not setup ADC\n"); + return ret; + } + + return 0; +} +EXPORT_SYMBOL_GPL(stmpe811_adc_common_init); + static int stmpe811_get_altfunc(struct stmpe *stmpe, enum stmpe_block block) { /* 0 for touchscreen, 1 for GPIO */ @@ -1325,6 +1381,7 @@ int stmpe_probe(struct stmpe_client_info *ci, enum stmpe_partnum partnum) struct device_node *np = ci->dev->of_node; struct stmpe *stmpe; int ret; + u32 val; pdata = devm_kzalloc(ci->dev, sizeof(*pdata), GFP_KERNEL); if (!pdata) @@ -1342,6 +1399,15 @@ int stmpe_probe(struct stmpe_client_info *ci, enum stmpe_partnum partnum) mutex_init(&stmpe->irq_lock); mutex_init(&stmpe->lock); + if (!of_property_read_u32(np, "st,sample-time", &val)) + stmpe->sample_time = val; + if (!of_property_read_u32(np, "st,mod-12b", &val)) + stmpe->mod_12b = val; + if (!of_property_read_u32(np, "st,ref-sel", &val)) + stmpe->ref_sel = val; + if (!of_property_read_u32(np, "st,adc-freq", &val)) + stmpe->adc_freq = val; + stmpe->dev = ci->dev; stmpe->client = ci->client; stmpe->pdata = pdata; @@ -1433,6 +1499,8 @@ int stmpe_remove(struct stmpe *stmpe) if (!IS_ERR(stmpe->vcc)) regulator_disable(stmpe->vcc); + __stmpe_disable(stmpe, STMPE_BLOCK_ADC); + mfd_remove_devices(stmpe->dev); return 0; -- cgit v1.2.1 From 51908d2e9b7c7730608a19f24fc8718af745bb2f Mon Sep 17 00:00:00 2001 From: Pascal PAILLET-LME Date: Mon, 14 Jan 2019 10:05:16 +0000 Subject: mfd: stpmic1: Add STPMIC1 driver STPMIC1 is a PMIC from STMicroelectronics. The STPMIC1 integrates 10 regulators, 3 power switches, a watchdog and an input for a power on key. Signed-off-by: Pascal Paillet Signed-off-by: Lee Jones --- drivers/mfd/Kconfig | 16 ++++ drivers/mfd/Makefile | 1 + drivers/mfd/stpmic1.c | 213 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 230 insertions(+) create mode 100644 drivers/mfd/stpmic1.c (limited to 'drivers/mfd') diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 8c5dfdce4326..0761cb83d174 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -1871,6 +1871,22 @@ config MFD_STM32_TIMERS for PWM and IIO Timer. This driver allow to share the registers between the others drivers. +config MFD_STPMIC1 + tristate "Support for STPMIC1 PMIC" + depends on (I2C=y && OF) + select REGMAP_I2C + select REGMAP_IRQ + select MFD_CORE + help + Support for ST Microelectronics STPMIC1 PMIC. STPMIC1 has power on + key, watchdog and regulator functionalities which are supported via + the relevant subsystems. This driver provides core support for the + STPMIC1. In order to use the actual functionaltiy of the device other + drivers must be enabled. + + To compile this driver as a module, choose M here: the + module will be called stpmic1. + menu "Multimedia Capabilities Port drivers" depends on ARCH_SA1100 diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index 12980a4ad460..a62fb0112d9f 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -233,6 +233,7 @@ obj-$(CONFIG_INTEL_SOC_PMIC_CHTDC_TI) += intel_soc_pmic_chtdc_ti.o obj-$(CONFIG_MFD_MT6397) += mt6397-core.o obj-$(CONFIG_MFD_ALTERA_A10SR) += altera-a10sr.o +obj-$(CONFIG_MFD_STPMIC1) += stpmic1.o obj-$(CONFIG_MFD_SUN4I_GPADC) += sun4i-gpadc.o obj-$(CONFIG_MFD_STM32_LPTIMER) += stm32-lptimer.o diff --git a/drivers/mfd/stpmic1.c b/drivers/mfd/stpmic1.c new file mode 100644 index 000000000000..7dfbe8906cb8 --- /dev/null +++ b/drivers/mfd/stpmic1.c @@ -0,0 +1,213 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) STMicroelectronics 2018 +// Author: Pascal Paillet + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define STPMIC1_MAIN_IRQ 0 + +static const struct regmap_range stpmic1_readable_ranges[] = { + regmap_reg_range(TURN_ON_SR, VERSION_SR), + regmap_reg_range(SWOFF_PWRCTRL_CR, LDO6_STDBY_CR), + regmap_reg_range(BST_SW_CR, BST_SW_CR), + regmap_reg_range(INT_PENDING_R1, INT_PENDING_R4), + regmap_reg_range(INT_CLEAR_R1, INT_CLEAR_R4), + regmap_reg_range(INT_MASK_R1, INT_MASK_R4), + regmap_reg_range(INT_SET_MASK_R1, INT_SET_MASK_R4), + regmap_reg_range(INT_CLEAR_MASK_R1, INT_CLEAR_MASK_R4), + regmap_reg_range(INT_SRC_R1, INT_SRC_R1), +}; + +static const struct regmap_range stpmic1_writeable_ranges[] = { + regmap_reg_range(SWOFF_PWRCTRL_CR, LDO6_STDBY_CR), + regmap_reg_range(BST_SW_CR, BST_SW_CR), + regmap_reg_range(INT_CLEAR_R1, INT_CLEAR_R4), + regmap_reg_range(INT_SET_MASK_R1, INT_SET_MASK_R4), + regmap_reg_range(INT_CLEAR_MASK_R1, INT_CLEAR_MASK_R4), +}; + +static const struct regmap_range stpmic1_volatile_ranges[] = { + regmap_reg_range(TURN_ON_SR, VERSION_SR), + regmap_reg_range(WCHDG_CR, WCHDG_CR), + regmap_reg_range(INT_PENDING_R1, INT_PENDING_R4), + regmap_reg_range(INT_SRC_R1, INT_SRC_R4), +}; + +static const struct regmap_access_table stpmic1_readable_table = { + .yes_ranges = stpmic1_readable_ranges, + .n_yes_ranges = ARRAY_SIZE(stpmic1_readable_ranges), +}; + +static const struct regmap_access_table stpmic1_writeable_table = { + .yes_ranges = stpmic1_writeable_ranges, + .n_yes_ranges = ARRAY_SIZE(stpmic1_writeable_ranges), +}; + +static const struct regmap_access_table stpmic1_volatile_table = { + .yes_ranges = stpmic1_volatile_ranges, + .n_yes_ranges = ARRAY_SIZE(stpmic1_volatile_ranges), +}; + +const struct regmap_config stpmic1_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .cache_type = REGCACHE_RBTREE, + .max_register = PMIC_MAX_REGISTER_ADDRESS, + .rd_table = &stpmic1_readable_table, + .wr_table = &stpmic1_writeable_table, + .volatile_table = &stpmic1_volatile_table, +}; + +static const struct regmap_irq stpmic1_irqs[] = { + REGMAP_IRQ_REG(IT_PONKEY_F, 0, 0x01), + REGMAP_IRQ_REG(IT_PONKEY_R, 0, 0x02), + REGMAP_IRQ_REG(IT_WAKEUP_F, 0, 0x04), + REGMAP_IRQ_REG(IT_WAKEUP_R, 0, 0x08), + REGMAP_IRQ_REG(IT_VBUS_OTG_F, 0, 0x10), + REGMAP_IRQ_REG(IT_VBUS_OTG_R, 0, 0x20), + REGMAP_IRQ_REG(IT_SWOUT_F, 0, 0x40), + REGMAP_IRQ_REG(IT_SWOUT_R, 0, 0x80), + + REGMAP_IRQ_REG(IT_CURLIM_BUCK1, 1, 0x01), + REGMAP_IRQ_REG(IT_CURLIM_BUCK2, 1, 0x02), + REGMAP_IRQ_REG(IT_CURLIM_BUCK3, 1, 0x04), + REGMAP_IRQ_REG(IT_CURLIM_BUCK4, 1, 0x08), + REGMAP_IRQ_REG(IT_OCP_OTG, 1, 0x10), + REGMAP_IRQ_REG(IT_OCP_SWOUT, 1, 0x20), + REGMAP_IRQ_REG(IT_OCP_BOOST, 1, 0x40), + REGMAP_IRQ_REG(IT_OVP_BOOST, 1, 0x80), + + REGMAP_IRQ_REG(IT_CURLIM_LDO1, 2, 0x01), + REGMAP_IRQ_REG(IT_CURLIM_LDO2, 2, 0x02), + REGMAP_IRQ_REG(IT_CURLIM_LDO3, 2, 0x04), + REGMAP_IRQ_REG(IT_CURLIM_LDO4, 2, 0x08), + REGMAP_IRQ_REG(IT_CURLIM_LDO5, 2, 0x10), + REGMAP_IRQ_REG(IT_CURLIM_LDO6, 2, 0x20), + REGMAP_IRQ_REG(IT_SHORT_SWOTG, 2, 0x40), + REGMAP_IRQ_REG(IT_SHORT_SWOUT, 2, 0x80), + + REGMAP_IRQ_REG(IT_TWARN_F, 3, 0x01), + REGMAP_IRQ_REG(IT_TWARN_R, 3, 0x02), + REGMAP_IRQ_REG(IT_VINLOW_F, 3, 0x04), + REGMAP_IRQ_REG(IT_VINLOW_R, 3, 0x08), + REGMAP_IRQ_REG(IT_SWIN_F, 3, 0x40), + REGMAP_IRQ_REG(IT_SWIN_R, 3, 0x80), +}; + +static const struct regmap_irq_chip stpmic1_regmap_irq_chip = { + .name = "pmic_irq", + .status_base = INT_PENDING_R1, + .mask_base = INT_CLEAR_MASK_R1, + .unmask_base = INT_SET_MASK_R1, + .ack_base = INT_CLEAR_R1, + .num_regs = STPMIC1_PMIC_NUM_IRQ_REGS, + .irqs = stpmic1_irqs, + .num_irqs = ARRAY_SIZE(stpmic1_irqs), +}; + +static int stpmic1_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) +{ + struct stpmic1 *ddata; + struct device *dev = &i2c->dev; + int ret; + struct device_node *np = dev->of_node; + u32 reg; + + ddata = devm_kzalloc(dev, sizeof(struct stpmic1), GFP_KERNEL); + if (!ddata) + return -ENOMEM; + + i2c_set_clientdata(i2c, ddata); + ddata->dev = dev; + + ddata->regmap = devm_regmap_init_i2c(i2c, &stpmic1_regmap_config); + if (IS_ERR(ddata->regmap)) + return PTR_ERR(ddata->regmap); + + ddata->irq = of_irq_get(np, STPMIC1_MAIN_IRQ); + if (ddata->irq < 0) { + dev_err(dev, "Failed to get main IRQ: %d\n", ddata->irq); + return ddata->irq; + } + + ret = regmap_read(ddata->regmap, VERSION_SR, ®); + if (ret) { + dev_err(dev, "Unable to read PMIC version\n"); + return ret; + } + dev_info(dev, "PMIC Chip Version: 0x%x\n", reg); + + /* Initialize PMIC IRQ Chip & associated IRQ domains */ + ret = devm_regmap_add_irq_chip(dev, ddata->regmap, ddata->irq, + IRQF_ONESHOT | IRQF_SHARED, + 0, &stpmic1_regmap_irq_chip, + &ddata->irq_data); + if (ret) { + dev_err(dev, "IRQ Chip registration failed: %d\n", ret); + return ret; + } + + return devm_of_platform_populate(dev); +} + +#ifdef CONFIG_PM_SLEEP +static int stpmic1_suspend(struct device *dev) +{ + struct i2c_client *i2c = to_i2c_client(dev); + struct stpmic1 *pmic_dev = i2c_get_clientdata(i2c); + + disable_irq(pmic_dev->irq); + + return 0; +} + +static int stpmic1_resume(struct device *dev) +{ + struct i2c_client *i2c = to_i2c_client(dev); + struct stpmic1 *pmic_dev = i2c_get_clientdata(i2c); + int ret; + + ret = regcache_sync(pmic_dev->regmap); + if (ret) + return ret; + + enable_irq(pmic_dev->irq); + + return 0; +} +#endif + +static SIMPLE_DEV_PM_OPS(stpmic1_pm, stpmic1_suspend, stpmic1_resume); + +static const struct of_device_id stpmic1_of_match[] = { + { .compatible = "st,stpmic1", }, + {}, +}; +MODULE_DEVICE_TABLE(of, stpmic1_of_match); + +static struct i2c_driver stpmic1_driver = { + .driver = { + .name = "stpmic1", + .of_match_table = of_match_ptr(stpmic1_of_match), + .pm = &stpmic1_pm, + }, + .probe = stpmic1_probe, +}; + +module_i2c_driver(stpmic1_driver); + +MODULE_DESCRIPTION("STPMIC1 PMIC Driver"); +MODULE_AUTHOR("Pascal Paillet "); +MODULE_LICENSE("GPL v2"); -- cgit v1.2.1 From 4bc59c2f7e306775f3d2e1bbafaa854dd1e09335 Mon Sep 17 00:00:00 2001 From: Enric Balletbo i Serra Date: Wed, 12 Dec 2018 18:33:56 +0100 Subject: mfd / platform: cros_ec: Use devm_mfd_add_devices Use devm_mfd_add_devices() for adding cros-ec core MFD child devices. This reduces the need of remove callback from platform/chrome for removing the MFD child devices. Signed-off-by: Enric Balletbo i Serra Reviewed-by: Guenter Roeck Signed-off-by: Lee Jones --- drivers/mfd/cros_ec.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) (limited to 'drivers/mfd') diff --git a/drivers/mfd/cros_ec.c b/drivers/mfd/cros_ec.c index fe6f83766144..6acfe036d522 100644 --- a/drivers/mfd/cros_ec.c +++ b/drivers/mfd/cros_ec.c @@ -129,8 +129,8 @@ int cros_ec_register(struct cros_ec_device *ec_dev) } } - err = mfd_add_devices(ec_dev->dev, PLATFORM_DEVID_AUTO, &ec_cell, 1, - NULL, ec_dev->irq, NULL); + err = devm_mfd_add_devices(ec_dev->dev, PLATFORM_DEVID_AUTO, &ec_cell, + 1, NULL, ec_dev->irq, NULL); if (err) { dev_err(dev, "Failed to register Embedded Controller subdevice %d\n", @@ -147,7 +147,7 @@ int cros_ec_register(struct cros_ec_device *ec_dev) * - the EC is responsive at init time (it is not true for a * sensor hub. */ - err = mfd_add_devices(ec_dev->dev, PLATFORM_DEVID_AUTO, + err = devm_mfd_add_devices(ec_dev->dev, PLATFORM_DEVID_AUTO, &ec_pd_cell, 1, NULL, ec_dev->irq, NULL); if (err) { dev_err(dev, @@ -181,14 +181,6 @@ int cros_ec_register(struct cros_ec_device *ec_dev) } EXPORT_SYMBOL(cros_ec_register); -int cros_ec_remove(struct cros_ec_device *ec_dev) -{ - mfd_remove_devices(ec_dev->dev); - - return 0; -} -EXPORT_SYMBOL(cros_ec_remove); - #ifdef CONFIG_PM_SLEEP int cros_ec_suspend(struct cros_ec_device *ec_dev) { -- cgit v1.2.1 From ecf8a6cd949ef236ce435ae488ceb6b3354e677e Mon Sep 17 00:00:00 2001 From: Enric Balletbo i Serra Date: Wed, 12 Dec 2018 18:33:57 +0100 Subject: mfd / platform: cros_ec: Move lightbar attributes to its own driver The entire way how cros sysfs attibutes are created is broken. cros_ec_lightbar should be its own driver and its attributes should be associated with a lightbar driver not the mfd driver. In order to retain the path, the lightbar attributes are attached to the cros_class. The patch also adds the sysfs documentation. Signed-off-by: Enric Balletbo i Serra Reviewed-by: Guenter Roeck Signed-off-by: Lee Jones --- drivers/mfd/cros_ec_dev.c | 24 +++++++++++++----------- drivers/mfd/cros_ec_dev.h | 6 ------ 2 files changed, 13 insertions(+), 17 deletions(-) (limited to 'drivers/mfd') diff --git a/drivers/mfd/cros_ec_dev.c b/drivers/mfd/cros_ec_dev.c index 2d0fee488c5a..b227718e0ec2 100644 --- a/drivers/mfd/cros_ec_dev.c +++ b/drivers/mfd/cros_ec_dev.c @@ -36,7 +36,6 @@ static int ec_major; static const struct attribute_group *cros_ec_groups[] = { &cros_ec_attr_group, - &cros_ec_lightbar_attr_group, &cros_ec_vbc_attr_group, NULL, }; @@ -395,6 +394,10 @@ static const struct mfd_cell cros_usbpd_charger_cells[] = { { .name = "cros-usbpd-charger" } }; +static const struct mfd_cell cros_ec_platform_cells[] = { + { .name = "cros-ec-lightbar" }, +}; + static int ec_device_probe(struct platform_device *pdev) { int retval = -ENOMEM; @@ -470,9 +473,6 @@ static int ec_device_probe(struct platform_device *pdev) retval); } - /* Take control of the lightbar from the EC. */ - lb_manual_suspend_ctrl(ec, 1); - /* We can now add the sysfs class, we know which parameter to show */ retval = cdev_device_add(&ec->cdev, &ec->class_dev); if (retval) { @@ -480,6 +480,15 @@ static int ec_device_probe(struct platform_device *pdev) goto failed; } + retval = mfd_add_devices(ec->dev, PLATFORM_DEVID_AUTO, + cros_ec_platform_cells, + ARRAY_SIZE(cros_ec_platform_cells), + NULL, 0, NULL); + if (retval) + dev_warn(ec->dev, + "failed to add cros-ec platform devices: %d\n", + retval); + if (cros_ec_debugfs_init(ec)) dev_warn(dev, "failed to create debugfs directory\n"); @@ -494,9 +503,6 @@ static int ec_device_remove(struct platform_device *pdev) { struct cros_ec_dev *ec = dev_get_drvdata(&pdev->dev); - /* Let the EC take over the lightbar again. */ - lb_manual_suspend_ctrl(ec, 0); - cros_ec_debugfs_remove(ec); mfd_remove_devices(ec->dev); @@ -525,8 +531,6 @@ static __maybe_unused int ec_device_suspend(struct device *dev) cros_ec_debugfs_suspend(ec); - lb_suspend(ec); - return 0; } @@ -536,8 +540,6 @@ static __maybe_unused int ec_device_resume(struct device *dev) cros_ec_debugfs_resume(ec); - lb_resume(ec); - return 0; } diff --git a/drivers/mfd/cros_ec_dev.h b/drivers/mfd/cros_ec_dev.h index 978d836a0248..ec750433455a 100644 --- a/drivers/mfd/cros_ec_dev.h +++ b/drivers/mfd/cros_ec_dev.h @@ -44,10 +44,4 @@ struct cros_ec_readmem { #define CROS_EC_DEV_IOCXCMD _IOWR(CROS_EC_DEV_IOC, 0, struct cros_ec_command) #define CROS_EC_DEV_IOCRDMEM _IOWR(CROS_EC_DEV_IOC, 1, struct cros_ec_readmem) -/* Lightbar utilities */ -extern bool ec_has_lightbar(struct cros_ec_dev *ec); -extern int lb_manual_suspend_ctrl(struct cros_ec_dev *ec, uint8_t enable); -extern int lb_suspend(struct cros_ec_dev *ec); -extern int lb_resume(struct cros_ec_dev *ec); - #endif /* _CROS_EC_DEV_H_ */ -- cgit v1.2.1 From acb9900f9e8074858738f48bee9a705138961258 Mon Sep 17 00:00:00 2001 From: Enric Balletbo i Serra Date: Wed, 12 Dec 2018 18:33:58 +0100 Subject: mfd / platform: cros_ec: Move vbc attributes to its own driver The entire way how cros sysfs attibutes are created is broken. cros_ec_vbc should be its own driver and its attributes should be associated with a vbc driver not the mfd driver. In order to retain the path, the vbc attributes are attached to the cros_class. The patch also adds the sysfs documentation. Signed-off-by: Enric Balletbo i Serra Reviewed-by: Guenter Roeck Signed-off-by: Lee Jones --- drivers/mfd/cros_ec_dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/mfd') diff --git a/drivers/mfd/cros_ec_dev.c b/drivers/mfd/cros_ec_dev.c index b227718e0ec2..40c98808fa1c 100644 --- a/drivers/mfd/cros_ec_dev.c +++ b/drivers/mfd/cros_ec_dev.c @@ -36,7 +36,6 @@ static int ec_major; static const struct attribute_group *cros_ec_groups[] = { &cros_ec_attr_group, - &cros_ec_vbc_attr_group, NULL, }; @@ -396,6 +395,7 @@ static const struct mfd_cell cros_usbpd_charger_cells[] = { static const struct mfd_cell cros_ec_platform_cells[] = { { .name = "cros-ec-lightbar" }, + { .name = "cros-ec-vbc" }, }; static int ec_device_probe(struct platform_device *pdev) -- cgit v1.2.1 From 6fce0a2cf5a050e8a3326556d7d293e69be303be Mon Sep 17 00:00:00 2001 From: Enric Balletbo i Serra Date: Wed, 12 Dec 2018 18:33:59 +0100 Subject: mfd / platform: cros_ec: Move debugfs attributes to its own driver The entire way how cros debugfs attibutes are created is broken. cros_ec_debugfs should be its own driver and its attributes should be associated with a debugfs driver not the mfd driver. Signed-off-by: Enric Balletbo i Serra Reviewed-by: Guenter Roeck Signed-off-by: Lee Jones --- drivers/mfd/cros_ec_dev.c | 41 +---------------------------------------- 1 file changed, 1 insertion(+), 40 deletions(-) (limited to 'drivers/mfd') diff --git a/drivers/mfd/cros_ec_dev.c b/drivers/mfd/cros_ec_dev.c index 40c98808fa1c..9955937b821d 100644 --- a/drivers/mfd/cros_ec_dev.c +++ b/drivers/mfd/cros_ec_dev.c @@ -394,6 +394,7 @@ static const struct mfd_cell cros_usbpd_charger_cells[] = { }; static const struct mfd_cell cros_ec_platform_cells[] = { + { .name = "cros-ec-debugfs" }, { .name = "cros-ec-lightbar" }, { .name = "cros-ec-vbc" }, }; @@ -489,9 +490,6 @@ static int ec_device_probe(struct platform_device *pdev) "failed to add cros-ec platform devices: %d\n", retval); - if (cros_ec_debugfs_init(ec)) - dev_warn(dev, "failed to create debugfs directory\n"); - return 0; failed: @@ -503,62 +501,25 @@ static int ec_device_remove(struct platform_device *pdev) { struct cros_ec_dev *ec = dev_get_drvdata(&pdev->dev); - cros_ec_debugfs_remove(ec); - mfd_remove_devices(ec->dev); cdev_del(&ec->cdev); device_unregister(&ec->class_dev); return 0; } -static void ec_device_shutdown(struct platform_device *pdev) -{ - struct cros_ec_dev *ec = dev_get_drvdata(&pdev->dev); - - /* Be sure to clear up debugfs delayed works */ - cros_ec_debugfs_remove(ec); -} - static const struct platform_device_id cros_ec_id[] = { { DRV_NAME, 0 }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(platform, cros_ec_id); -static __maybe_unused int ec_device_suspend(struct device *dev) -{ - struct cros_ec_dev *ec = dev_get_drvdata(dev); - - cros_ec_debugfs_suspend(ec); - - return 0; -} - -static __maybe_unused int ec_device_resume(struct device *dev) -{ - struct cros_ec_dev *ec = dev_get_drvdata(dev); - - cros_ec_debugfs_resume(ec); - - return 0; -} - -static const struct dev_pm_ops cros_ec_dev_pm_ops = { -#ifdef CONFIG_PM_SLEEP - .suspend = ec_device_suspend, - .resume = ec_device_resume, -#endif -}; - static struct platform_driver cros_ec_dev_driver = { .driver = { .name = DRV_NAME, - .pm = &cros_ec_dev_pm_ops, }, .id_table = cros_ec_id, .probe = ec_device_probe, .remove = ec_device_remove, - .shutdown = ec_device_shutdown, }; static int __init cros_ec_dev_init(void) -- cgit v1.2.1 From 6fd7f2bbd4422e7635bc771cd1ec440378158cb1 Mon Sep 17 00:00:00 2001 From: Enric Balletbo i Serra Date: Wed, 12 Dec 2018 18:34:00 +0100 Subject: mfd / platform: cros_ec: Move device sysfs attributes to its own driver The entire way how cros debugfs attibutes are created is broken. cros_ec_sysfs should be its own driver and its attributes should be associated with the sysfs driver not the mfd driver. The patch also adds the sysfs documentation. Signed-off-by: Enric Balletbo i Serra Reviewed-by: Guenter Roeck Signed-off-by: Lee Jones --- drivers/mfd/Kconfig | 1 - drivers/mfd/cros_ec_dev.c | 7 +------ 2 files changed, 1 insertion(+), 7 deletions(-) (limited to 'drivers/mfd') diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index f461460a2aeb..2acc105e43cc 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -215,7 +215,6 @@ config MFD_CROS_EC config MFD_CROS_EC_CHARDEV tristate "Chrome OS Embedded Controller userspace device interface" depends on MFD_CROS_EC - select CROS_EC_CTL ---help--- This driver adds support to talk with the ChromeOS EC from userspace. diff --git a/drivers/mfd/cros_ec_dev.c b/drivers/mfd/cros_ec_dev.c index 9955937b821d..b9ec2a798dbb 100644 --- a/drivers/mfd/cros_ec_dev.c +++ b/drivers/mfd/cros_ec_dev.c @@ -34,15 +34,9 @@ #define CROS_MAX_DEV 128 static int ec_major; -static const struct attribute_group *cros_ec_groups[] = { - &cros_ec_attr_group, - NULL, -}; - static struct class cros_class = { .owner = THIS_MODULE, .name = "chromeos", - .dev_groups = cros_ec_groups, }; /* Basic communication */ @@ -396,6 +390,7 @@ static const struct mfd_cell cros_usbpd_charger_cells[] = { static const struct mfd_cell cros_ec_platform_cells[] = { { .name = "cros-ec-debugfs" }, { .name = "cros-ec-lightbar" }, + { .name = "cros-ec-sysfs" }, { .name = "cros-ec-vbc" }, }; -- cgit v1.2.1 From 0545625baa5981bb0a583e6a6045155936d3ea95 Mon Sep 17 00:00:00 2001 From: Enric Balletbo i Serra Date: Wed, 12 Dec 2018 18:34:01 +0100 Subject: mfd / platform: cros_ec_vbc: Instantiate only if the EC has a VBC NVRAM The cros-ec-vbc driver is DT-only and there is a DT property that indicates if the EC has the VCB NVRAM, in such case instantiate the driver but don't instantiate on the other cases. To do this move the check code to its parent instead of play with the attribute group visibility. This changes a bit the actual behaviour. Before the patch if an EC doesn't have a VBC NVRAM an empty vbc folder is created in /sys/class/chromeos/, after the patch the empty folder is not created, so, the folder is only created if the vbc is set. Signed-off-by: Enric Balletbo i Serra Reviewed-by: Guenter Roeck Signed-off-by: Lee Jones --- drivers/mfd/cros_ec_dev.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'drivers/mfd') diff --git a/drivers/mfd/cros_ec_dev.c b/drivers/mfd/cros_ec_dev.c index b9ec2a798dbb..ed809fc97df8 100644 --- a/drivers/mfd/cros_ec_dev.c +++ b/drivers/mfd/cros_ec_dev.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -391,12 +392,16 @@ static const struct mfd_cell cros_ec_platform_cells[] = { { .name = "cros-ec-debugfs" }, { .name = "cros-ec-lightbar" }, { .name = "cros-ec-sysfs" }, - { .name = "cros-ec-vbc" }, +}; + +static const struct mfd_cell cros_ec_vbc_cells[] = { + { .name = "cros-ec-vbc" } }; static int ec_device_probe(struct platform_device *pdev) { int retval = -ENOMEM; + struct device_node *node; struct device *dev = &pdev->dev; struct cros_ec_platform *ec_platform = dev_get_platdata(dev); struct cros_ec_dev *ec = kzalloc(sizeof(*ec), GFP_KERNEL); @@ -485,6 +490,18 @@ static int ec_device_probe(struct platform_device *pdev) "failed to add cros-ec platform devices: %d\n", retval); + /* Check whether this EC instance has a VBC NVRAM */ + node = ec->ec_dev->dev->of_node; + if (of_property_read_bool(node, "google,has-vbc-nvram")) { + retval = mfd_add_devices(ec->dev, PLATFORM_DEVID_AUTO, + cros_ec_vbc_cells, + ARRAY_SIZE(cros_ec_vbc_cells), + NULL, 0, NULL); + if (retval) + dev_warn(ec->dev, "failed to add VBC devices: %d\n", + retval); + } + return 0; failed: -- cgit v1.2.1 From 17f808a7fec32cf3610f92a095b562c915fd254a Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Sun, 13 Jan 2019 13:36:32 -0500 Subject: mfd: aat2870-core: Make it explicitly non-modular The Kconfig currently controlling compilation of this code is: drivers/mfd/Kconfig:config MFD_AAT2870_CORE drivers/mfd/Kconfig: bool "AnalogicTech AAT2870" ...meaning that it currently is not being built as a module by anyone. Lets remove the modular code that is essentially orphaned, so that when reading the driver there is no doubt it is builtin-only. We explicitly disallow a driver unbind, since that doesn't have a sensible use case anyway, and it allows us to drop the ".remove" code for non-modular drivers. Since module_init was not in use by this code, the init ordering remains unchanged with this commit. Also note that MODULE_DEVICE_TABLE is a no-op for non-modular code. We also delete the MODULE_LICENSE tag etc. since all that information is already contained at the top of the file in the comments. Signed-off-by: Paul Gortmaker Acked-by: Linus Walleij Acked-by: Jin Park Signed-off-by: Lee Jones --- drivers/mfd/aat2870-core.c | 40 +++------------------------------------- 1 file changed, 3 insertions(+), 37 deletions(-) (limited to 'drivers/mfd') diff --git a/drivers/mfd/aat2870-core.c b/drivers/mfd/aat2870-core.c index 3ba19a45f199..9d3d90d386c2 100644 --- a/drivers/mfd/aat2870-core.c +++ b/drivers/mfd/aat2870-core.c @@ -20,7 +20,6 @@ */ #include -#include #include #include #include @@ -349,18 +348,10 @@ static void aat2870_init_debugfs(struct aat2870_data *aat2870) "Failed to create debugfs register file\n"); } -static void aat2870_uninit_debugfs(struct aat2870_data *aat2870) -{ - debugfs_remove_recursive(aat2870->dentry_root); -} #else static inline void aat2870_init_debugfs(struct aat2870_data *aat2870) { } - -static inline void aat2870_uninit_debugfs(struct aat2870_data *aat2870) -{ -} #endif /* CONFIG_DEBUG_FS */ static int aat2870_i2c_probe(struct i2c_client *client, @@ -440,20 +431,6 @@ out_disable: return ret; } -static int aat2870_i2c_remove(struct i2c_client *client) -{ - struct aat2870_data *aat2870 = i2c_get_clientdata(client); - - aat2870_uninit_debugfs(aat2870); - - mfd_remove_devices(aat2870->dev); - aat2870_disable(aat2870); - if (aat2870->uninit) - aat2870->uninit(aat2870); - - return 0; -} - #ifdef CONFIG_PM_SLEEP static int aat2870_i2c_suspend(struct device *dev) { @@ -492,15 +469,14 @@ static const struct i2c_device_id aat2870_i2c_id_table[] = { { "aat2870", 0 }, { } }; -MODULE_DEVICE_TABLE(i2c, aat2870_i2c_id_table); static struct i2c_driver aat2870_i2c_driver = { .driver = { - .name = "aat2870", - .pm = &aat2870_pm_ops, + .name = "aat2870", + .pm = &aat2870_pm_ops, + .suppress_bind_attrs = true, }, .probe = aat2870_i2c_probe, - .remove = aat2870_i2c_remove, .id_table = aat2870_i2c_id_table, }; @@ -509,13 +485,3 @@ static int __init aat2870_init(void) return i2c_add_driver(&aat2870_i2c_driver); } subsys_initcall(aat2870_init); - -static void __exit aat2870_exit(void) -{ - i2c_del_driver(&aat2870_i2c_driver); -} -module_exit(aat2870_exit); - -MODULE_DESCRIPTION("Core support for the AnalogicTech AAT2870"); -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Jin Park "); -- cgit v1.2.1 From 6b09274bacc76101293d6d8ccbded51448b11fd1 Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Sun, 13 Jan 2019 13:36:33 -0500 Subject: mfd: adp5520: Make it explicitly non-modular The Makefile/Kconfig currently controlling compilation of this code is: drivers/mfd/Makefile:obj-$(CONFIG_PMIC_ADP5520) += adp5520.o drivers/mfd/Kconfig:config PMIC_ADP5520 drivers/mfd/Kconfig: bool "Analog Devices ADP5520/01 MFD PMIC Core Support" ...meaning that it currently is not being built as a module by anyone. Lets remove the modular code that is essentially orphaned, so that when reading the driver there is no doubt it is builtin-only. We explicitly disallow a driver unbind, since that doesn't have a sensible use case anyway, and it allows us to drop the ".remove" code for non-modular drivers. Since module_i2c_driver() uses the same init level priority as builtin_i2c_driver() the init ordering remains unchanged with this commit. Also note that MODULE_DEVICE_TABLE is a no-op for non-modular code. We also delete the MODULE_LICENSE tag etc. since all that information was (or is now) contained at the top of the file in the comments. Signed-off-by: Paul Gortmaker Acked-by: Linus Walleij Acked-by: Michael Hennerich Signed-off-by: Lee Jones --- drivers/mfd/adp5520.c | 30 +++++++----------------------- 1 file changed, 7 insertions(+), 23 deletions(-) (limited to 'drivers/mfd') diff --git a/drivers/mfd/adp5520.c b/drivers/mfd/adp5520.c index be0497b96720..2cdd39cb8a18 100644 --- a/drivers/mfd/adp5520.c +++ b/drivers/mfd/adp5520.c @@ -7,6 +7,8 @@ * * Copyright 2009 Analog Devices Inc. * + * Author: Michael Hennerich + * * Derived from da903x: * Copyright (C) 2008 Compulab, Ltd. * Mike Rapoport @@ -18,7 +20,7 @@ */ #include -#include +#include #include #include #include @@ -304,18 +306,6 @@ out_free_irq: return ret; } -static int adp5520_remove(struct i2c_client *client) -{ - struct adp5520_chip *chip = dev_get_drvdata(&client->dev); - - if (chip->irq) - free_irq(chip->irq, chip); - - adp5520_remove_subdevs(chip); - adp5520_write(chip->dev, ADP5520_MODE_STATUS, 0); - return 0; -} - #ifdef CONFIG_PM_SLEEP static int adp5520_suspend(struct device *dev) { @@ -346,20 +336,14 @@ static const struct i2c_device_id adp5520_id[] = { { "pmic-adp5501", ID_ADP5501 }, { } }; -MODULE_DEVICE_TABLE(i2c, adp5520_id); static struct i2c_driver adp5520_driver = { .driver = { - .name = "adp5520", - .pm = &adp5520_pm, + .name = "adp5520", + .pm = &adp5520_pm, + .suppress_bind_attrs = true, }, .probe = adp5520_probe, - .remove = adp5520_remove, .id_table = adp5520_id, }; - -module_i2c_driver(adp5520_driver); - -MODULE_AUTHOR("Michael Hennerich "); -MODULE_DESCRIPTION("ADP5520(01) PMIC-MFD Driver"); -MODULE_LICENSE("GPL"); +builtin_i2c_driver(adp5520_driver); -- cgit v1.2.1 From 1e89d907460628fe8cc8e0bb604879d2e055d744 Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Sun, 13 Jan 2019 13:36:34 -0500 Subject: mfd: as3711: Make it explicitly non-modular The Kconfig currently controlling compilation of this code is: drivers/mfd/Kconfig:config MFD_AS3711 drivers/mfd/Kconfig: bool "AMS AS3711" ...meaning that it currently is not being built as a module by anyone. Lets remove the modular code that is essentially orphaned, so that when reading the driver there is no doubt it is builtin-only. Since module_init was not in use by this code, the init ordering remains unchanged with this commit. We don't replace module.h with init.h since the file already has that. Also note that MODULE_DEVICE_TABLE is a no-op for non-modular code. We also delete the MODULE_LICENSE tag etc. since all that information is already contained at the top of the file in the comments. Signed-off-by: Paul Gortmaker Acked-by: Linus Walleij Signed-off-by: Lee Jones --- drivers/mfd/as3711.c | 14 -------------- 1 file changed, 14 deletions(-) (limited to 'drivers/mfd') diff --git a/drivers/mfd/as3711.c b/drivers/mfd/as3711.c index 67b12417585d..7a74a874b93c 100644 --- a/drivers/mfd/as3711.c +++ b/drivers/mfd/as3711.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include @@ -118,7 +117,6 @@ static const struct of_device_id as3711_of_match[] = { {.compatible = "ams,as3711",}, {} }; -MODULE_DEVICE_TABLE(of, as3711_of_match); #endif static int as3711_i2c_probe(struct i2c_client *client, @@ -202,8 +200,6 @@ static const struct i2c_device_id as3711_i2c_id[] = { {} }; -MODULE_DEVICE_TABLE(i2c, as3711_i2c_id); - static struct i2c_driver as3711_i2c_driver = { .driver = { .name = "as3711", @@ -219,13 +215,3 @@ static int __init as3711_i2c_init(void) } /* Initialise early */ subsys_initcall(as3711_i2c_init); - -static void __exit as3711_i2c_exit(void) -{ - i2c_del_driver(&as3711_i2c_driver); -} -module_exit(as3711_i2c_exit); - -MODULE_AUTHOR("Guennadi Liakhovetski "); -MODULE_DESCRIPTION("AS3711 PMIC driver"); -MODULE_LICENSE("GPL v2"); -- cgit v1.2.1 From adef9cf549be912f559e82918ecbe18d54649cee Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Sun, 13 Jan 2019 13:36:35 -0500 Subject: mfd: db8500-prcmu: Drop unused MODULE_ tags from non-modular code The Kconfig currently controlling compilation of this code is: drivers/mfd/Kconfig:config MFD_DB8500_PRCMU drivers/mfd/Kconfig: bool "ST-Ericsson DB8500 Power Reset Control Management Unit" ...meaning that it currently is not being built as a module by anyone. Lets remove the couple traces of modular infrastructure use, so that when reading the driver there is no doubt it is builtin-only. We delete the MODULE_LICENSE tag etc. since all that information is already contained at the top of the file in the comments. We replace module.h with init.h and export.h ; the latter since the file does export some symbols. Signed-off-by: Paul Gortmaker Reviewed-by: Linus Walleij Signed-off-by: Lee Jones --- drivers/mfd/db8500-prcmu.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'drivers/mfd') diff --git a/drivers/mfd/db8500-prcmu.c b/drivers/mfd/db8500-prcmu.c index aec20e1c7d3d..65666b624ae8 100644 --- a/drivers/mfd/db8500-prcmu.c +++ b/drivers/mfd/db8500-prcmu.c @@ -1,4 +1,6 @@ /* + * DB8500 PRCM Unit driver + * * Copyright (C) STMicroelectronics 2009 * Copyright (C) ST-Ericsson SA 2010 * @@ -10,7 +12,8 @@ * U8500 PRCM Unit interface driver * */ -#include +#include +#include #include #include #include @@ -3188,9 +3191,4 @@ static int __init db8500_prcmu_init(void) { return platform_driver_register(&db8500_prcmu_driver); } - core_initcall(db8500_prcmu_init); - -MODULE_AUTHOR("Mattias Nilsson "); -MODULE_DESCRIPTION("DB8500 PRCM Unit driver"); -MODULE_LICENSE("GPL v2"); -- cgit v1.2.1 From 11165223e9a617798268a1c743364ead4395b905 Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Sun, 13 Jan 2019 13:36:36 -0500 Subject: mfd: htc-i2cpld: Make it explicitly non-modular The Kconfig for this option is currently: config HTC_I2CPLD bool "HTC I2C PLD chip support" ...meaning that it currently is not being built as a module by anyone. Lets remove the modular code that is essentially orphaned, so that when reading the driver there is no doubt it is builtin-only. Since module_init translates to device_initcall in the non-modular case, the init ordering remains unchanged with this commit. We also delete the MODULE_LICENSE tag etc. since all that information is already contained at the top of the file in the comments. Signed-off-by: Paul Gortmaker Acked-by: Linus Walleij Signed-off-by: Lee Jones --- drivers/mfd/htc-i2cpld.c | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) (limited to 'drivers/mfd') diff --git a/drivers/mfd/htc-i2cpld.c b/drivers/mfd/htc-i2cpld.c index 01572b5e79e8..af3c66355270 100644 --- a/drivers/mfd/htc-i2cpld.c +++ b/drivers/mfd/htc-i2cpld.c @@ -27,7 +27,6 @@ #include #include -#include #include #include #include @@ -614,8 +613,6 @@ static const struct i2c_device_id htcpld_chip_id[] = { { "htcpld-chip", 0 }, { } }; -MODULE_DEVICE_TABLE(i2c, htcpld_chip_id); - static struct i2c_driver htcpld_chip_driver = { .driver = { @@ -643,17 +640,4 @@ static int __init htcpld_core_init(void) /* Probe for our chips */ return platform_driver_probe(&htcpld_core_driver, htcpld_core_probe); } - -static void __exit htcpld_core_exit(void) -{ - i2c_del_driver(&htcpld_chip_driver); - platform_driver_unregister(&htcpld_core_driver); -} - -module_init(htcpld_core_init); -module_exit(htcpld_core_exit); - -MODULE_AUTHOR("Cory Maccarrone "); -MODULE_DESCRIPTION("I2C HTC PLD Driver"); -MODULE_LICENSE("GPL"); - +device_initcall(htcpld_core_init); -- cgit v1.2.1 From b51bf15c6cdcbbb2462d7985b86667cdce3a4b92 Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Sun, 13 Jan 2019 13:36:37 -0500 Subject: mfd: max8925-core: Drop unused MODULE_ tags from non-modular code The Kconfig currently controlling compilation of this code is: drivers/mfd/Kconfig:config MFD_MAX8925 drivers/mfd/Kconfig: bool "Maxim Semiconductor MAX8925 PMIC Support" ...meaning that it currently is not being built as a module by anyone. Lets remove the couple traces of modular infrastructure use, so that when reading the driver there is no doubt it is builtin-only. We delete the MODULE_LICENSE tag etc. since all that information is already contained at the top of the file in the comments. Signed-off-by: Paul Gortmaker Acked-by: Linus Walleij Signed-off-by: Lee Jones --- drivers/mfd/max8925-core.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'drivers/mfd') diff --git a/drivers/mfd/max8925-core.c b/drivers/mfd/max8925-core.c index fd8b15cd84fd..87c724ba9793 100644 --- a/drivers/mfd/max8925-core.c +++ b/drivers/mfd/max8925-core.c @@ -10,7 +10,7 @@ */ #include -#include +#include #include #include #include @@ -919,8 +919,3 @@ void max8925_device_exit(struct max8925_chip *chip) free_irq(chip->tsc_irq, chip); mfd_remove_devices(chip->dev); } - - -MODULE_DESCRIPTION("PMIC Driver for Maxim MAX8925"); -MODULE_AUTHOR("Haojian Zhuang Date: Sun, 13 Jan 2019 13:36:38 -0500 Subject: mfd: rc5t583: Make it explicitly non-modular The Kconfig currently controlling compilation of this code is: drivers/mfd/Kconfig:config MFD_RC5T583 drivers/mfd/Kconfig: bool "Ricoh RC5T583 Power Management system device" ...meaning that it currently is not being built as a module by anyone. Lets remove the modular code that is essentially orphaned, so that when reading the driver there is no doubt it is builtin-only. Since module_init was not in use by this code, the init ordering remains unchanged with this commit. Also note that MODULE_DEVICE_TABLE is a no-op for non-modular code. We also delete the MODULE_LICENSE tag etc. since all that information is already contained at the top of the file in the comments. Signed-off-by: Paul Gortmaker Acked-by: Linus Walleij Acked-by: Laxman Dewangan Signed-off-by: Lee Jones --- drivers/mfd/rc5t583.c | 14 -------------- 1 file changed, 14 deletions(-) (limited to 'drivers/mfd') diff --git a/drivers/mfd/rc5t583.c b/drivers/mfd/rc5t583.c index fd46de02b715..c5cc5cb3dde7 100644 --- a/drivers/mfd/rc5t583.c +++ b/drivers/mfd/rc5t583.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include @@ -298,8 +297,6 @@ static const struct i2c_device_id rc5t583_i2c_id[] = { {} }; -MODULE_DEVICE_TABLE(i2c, rc5t583_i2c_id); - static struct i2c_driver rc5t583_i2c_driver = { .driver = { .name = "rc5t583", @@ -313,14 +310,3 @@ static int __init rc5t583_i2c_init(void) return i2c_add_driver(&rc5t583_i2c_driver); } subsys_initcall(rc5t583_i2c_init); - -static void __exit rc5t583_i2c_exit(void) -{ - i2c_del_driver(&rc5t583_i2c_driver); -} - -module_exit(rc5t583_i2c_exit); - -MODULE_AUTHOR("Laxman Dewangan "); -MODULE_DESCRIPTION("RICOH RC5T583 power management system device driver"); -MODULE_LICENSE("GPL v2"); -- cgit v1.2.1 From cf090914da11e067a6f0438651912929c8b038f2 Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Sun, 13 Jan 2019 13:36:39 -0500 Subject: mfd: sta2x11: Drop unused MODULE_ tags from non-modular code The Kconfig currently controlling compilation of this code is: drivers/mfd/Kconfig:config MFD_STA2X11 drivers/mfd/Kconfig: bool "STMicroelectronics STA2X11" ...meaning that it currently is not being built as a module by anyone. Lets remove the couple traces of modular infrastructure use, so that when reading the driver there is no doubt it is builtin-only. We delete the MODULE_LICENSE tag etc. since all that information is already contained at the top of the file in the comments. Also note that MODULE_DEVICE_TABLE is a no-op for non-modular code. We replace module.h with init.h and export.h ; the latter since the file does export some symbols. Signed-off-by: Paul Gortmaker Acked-by: Alessandro Rubini Acked-by: Davide Ciminaghi Acked-by: Linus Walleij Signed-off-by: Lee Jones --- drivers/mfd/sta2x11-mfd.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'drivers/mfd') diff --git a/drivers/mfd/sta2x11-mfd.c b/drivers/mfd/sta2x11-mfd.c index 3aeafa228baf..cab9aabcaa1f 100644 --- a/drivers/mfd/sta2x11-mfd.c +++ b/drivers/mfd/sta2x11-mfd.c @@ -1,4 +1,6 @@ /* + * STA2x11 mfd for GPIO, SCTL and APBREG + * * Copyright (c) 2009-2011 Wind River Systems, Inc. * Copyright (c) 2011 ST Microelectronics (Alessandro Rubini, Davide Ciminaghi) * @@ -18,7 +20,8 @@ */ #include -#include +#include +#include #include #include #include @@ -653,8 +656,3 @@ static int __init sta2x11_mfd_init(void) */ subsys_initcall(sta2x11_drivers_init); rootfs_initcall(sta2x11_mfd_init); - -MODULE_LICENSE("GPL v2"); -MODULE_AUTHOR("Wind River"); -MODULE_DESCRIPTION("STA2x11 mfd for GPIO, SCTL and APBREG"); -MODULE_DEVICE_TABLE(pci, sta2x11_mfd_tbl); -- cgit v1.2.1 From 1345da73f6d100568e1fa55376759688c74fcae5 Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Sun, 13 Jan 2019 13:36:40 -0500 Subject: mfd: syscon: Make it explicitly non-modular The Kconfig currently controlling compilation of this code is: drivers/mfd/Kconfig:config MFD_SYSCON drivers/mfd/Kconfig: bool "System Controller Register R/W Based on Regmap" ...meaning that it currently is not being built as a module by anyone. Lets remove the modular code that is essentially orphaned, so that when reading the driver there is no doubt it is builtin-only. Since module_init was not in use by this code, the init ordering remains unchanged with this commit. We also delete the MODULE_LICENSE tag etc. since all that information is already contained at the top of the file in the comments. Signed-off-by: Paul Gortmaker Acked-by: Linus Walleij Signed-off-by: Lee Jones --- drivers/mfd/syscon.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) (limited to 'drivers/mfd') diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c index b6d05cd934e6..0ecdffb3d967 100644 --- a/drivers/mfd/syscon.c +++ b/drivers/mfd/syscon.c @@ -15,7 +15,7 @@ #include #include #include -#include +#include #include #include #include @@ -272,13 +272,3 @@ static int __init syscon_init(void) return platform_driver_register(&syscon_driver); } postcore_initcall(syscon_init); - -static void __exit syscon_exit(void) -{ - platform_driver_unregister(&syscon_driver); -} -module_exit(syscon_exit); - -MODULE_AUTHOR("Dong Aisheng "); -MODULE_DESCRIPTION("System Control driver"); -MODULE_LICENSE("GPL v2"); -- cgit v1.2.1 From 26fce5e099d76651a871e738e858f18bc7829d84 Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Sun, 13 Jan 2019 13:36:41 -0500 Subject: mfd: tps65090: Make it explicitly non-modular The Kconfig currently controlling compilation of this code is: drivers/mfd/Kconfig:config MFD_TPS65090 drivers/mfd/Kconfig: bool "TI TPS65090 Power Management chips" ...meaning that it currently is not being built as a module by anyone. Lets remove the modular code that is essentially orphaned, so that when reading the driver there is no doubt it is builtin-only. We explicitly disallow a driver unbind, since that doesn't have a sensible use case anyway, and it allows us to drop the ".remove" code for non-modular drivers. Since module_init was not in use by this code, the init ordering remains unchanged with this commit. Also note that MODULE_DEVICE_TABLE is a no-op for non-modular code. We also delete the MODULE_LICENSE tag etc. since all that information was (or is now) contained at the top of the file in the comments. Signed-off-by: Paul Gortmaker Acked-by: Linus Walleij Signed-off-by: Lee Jones --- drivers/mfd/tps65090.c | 30 +++++------------------------- 1 file changed, 5 insertions(+), 25 deletions(-) (limited to 'drivers/mfd') diff --git a/drivers/mfd/tps65090.c b/drivers/mfd/tps65090.c index f13e4cd06e89..6968df4d7828 100644 --- a/drivers/mfd/tps65090.c +++ b/drivers/mfd/tps65090.c @@ -2,7 +2,9 @@ * Core driver for TI TPS65090 PMIC family * * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. - + * + * Author: Venu Byravarasu + * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, * version 2, as published by the Free Software Foundation. @@ -19,7 +21,7 @@ #include #include #include -#include +#include #include #include #include @@ -171,7 +173,6 @@ static const struct of_device_id tps65090_of_match[] = { { .compatible = "ti,tps65090",}, {}, }; -MODULE_DEVICE_TABLE(of, tps65090_of_match); #endif static int tps65090_i2c_probe(struct i2c_client *client, @@ -236,30 +237,19 @@ err_irq_exit: return ret; } -static int tps65090_i2c_remove(struct i2c_client *client) -{ - struct tps65090 *tps65090 = i2c_get_clientdata(client); - - mfd_remove_devices(tps65090->dev); - if (client->irq) - regmap_del_irq_chip(client->irq, tps65090->irq_data); - - return 0; -} static const struct i2c_device_id tps65090_id_table[] = { { "tps65090", 0 }, { }, }; -MODULE_DEVICE_TABLE(i2c, tps65090_id_table); static struct i2c_driver tps65090_driver = { .driver = { .name = "tps65090", + .suppress_bind_attrs = true, .of_match_table = of_match_ptr(tps65090_of_match), }, .probe = tps65090_i2c_probe, - .remove = tps65090_i2c_remove, .id_table = tps65090_id_table, }; @@ -268,13 +258,3 @@ static int __init tps65090_init(void) return i2c_add_driver(&tps65090_driver); } subsys_initcall(tps65090_init); - -static void __exit tps65090_exit(void) -{ - i2c_del_driver(&tps65090_driver); -} -module_exit(tps65090_exit); - -MODULE_DESCRIPTION("TPS65090 core driver"); -MODULE_AUTHOR("Venu Byravarasu "); -MODULE_LICENSE("GPL v2"); -- cgit v1.2.1 From a8799defb4afd64405a077f1aa98552d3e79169a Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Sun, 13 Jan 2019 13:36:42 -0500 Subject: mfd: tps65910: Make it explicitly non-modular The Kconfig currently controlling compilation of this code is: drivers/mfd/Kconfig:config MFD_TPS65910 drivers/mfd/Kconfig- bool "TI TPS65910 Power Management chip" ...meaning that it currently is not being built as a module by anyone. Lets remove the modular code that is essentially orphaned, so that when reading the driver there is no doubt it is builtin-only. Since module_init was not in use by this code, the init ordering remains unchanged with this commit. We don't replace module.h with init.h since the file already has that. We do delete an unused moduleparam.h include though. Also note that MODULE_DEVICE_TABLE is a no-op for non-modular code. We also delete the MODULE_LICENSE tag etc. since all that information was (or is now) contained at the top of the file in the comments. Signed-off-by: Paul Gortmaker Acked-by: Linus Walleij Acked-by: Tony Lindgren Signed-off-by: Lee Jones --- drivers/mfd/tps65910.c | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) (limited to 'drivers/mfd') diff --git a/drivers/mfd/tps65910.c b/drivers/mfd/tps65910.c index bf16cbe6fd88..aa3d472a10ff 100644 --- a/drivers/mfd/tps65910.c +++ b/drivers/mfd/tps65910.c @@ -1,5 +1,5 @@ /* - * tps65910.c -- TI TPS6591x + * tps65910.c -- TI TPS6591x chip family multi-function driver * * Copyright 2010 Texas Instruments Inc. * @@ -13,8 +13,6 @@ * */ -#include -#include #include #include #include @@ -374,7 +372,6 @@ static const struct of_device_id tps65910_of_match[] = { { .compatible = "ti,tps65911", .data = (void *)TPS65911}, { }, }; -MODULE_DEVICE_TABLE(of, tps65910_of_match); static struct tps65910_board *tps65910_parse_dt(struct i2c_client *client, unsigned long *chip_id) @@ -527,8 +524,6 @@ static const struct i2c_device_id tps65910_i2c_id[] = { { "tps65911", TPS65911 }, { } }; -MODULE_DEVICE_TABLE(i2c, tps65910_i2c_id); - static struct i2c_driver tps65910_i2c_driver = { .driver = { @@ -545,14 +540,3 @@ static int __init tps65910_i2c_init(void) } /* init early so consumer devices can complete system boot */ subsys_initcall(tps65910_i2c_init); - -static void __exit tps65910_i2c_exit(void) -{ - i2c_del_driver(&tps65910_i2c_driver); -} -module_exit(tps65910_i2c_exit); - -MODULE_AUTHOR("Graeme Gregory "); -MODULE_AUTHOR("Jorge Eduardo Candelaria "); -MODULE_DESCRIPTION("TPS6591x chip family multi-function driver"); -MODULE_LICENSE("GPL"); -- cgit v1.2.1 From 6b5e1877e487b5bd5814dfc4e56956906792029f Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Sun, 13 Jan 2019 13:36:43 -0500 Subject: mfd: tps80031: Make it explicitly non-modular The Kconfig currently controlling compilation of this code is: drivers/mfd/Kconfig:config MFD_TPS80031 drivers/mfd/Kconfig: bool "TI TPS80031/TPS80032 Power Management chips" ...meaning that it currently is not being built as a module by anyone. Lets remove the modular code that is essentially orphaned, so that when reading the driver there is no doubt it is builtin-only. We explicitly disallow a driver unbind, since that doesn't have a sensible use case anyway, and it allows us to drop the ".remove" code for non-modular drivers. Since module_init was not in use by this code, the init ordering remains unchanged with this commit. We don't replace module.h with init.h since the file already has that. Also note that MODULE_DEVICE_TABLE is a no-op for non-modular code. We also delete the MODULE_LICENSE tag etc. since all that information is already contained at the top of the file in the comments. Signed-off-by: Paul Gortmaker Acked-by: Linus Walleij Acked-by: Laxman Dewangan Signed-off-by: Lee Jones --- drivers/mfd/tps80031.c | 37 ++----------------------------------- 1 file changed, 2 insertions(+), 35 deletions(-) (limited to 'drivers/mfd') diff --git a/drivers/mfd/tps80031.c b/drivers/mfd/tps80031.c index 608c7f77830e..865257ade8ac 100644 --- a/drivers/mfd/tps80031.c +++ b/drivers/mfd/tps80031.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include #include @@ -516,40 +515,18 @@ fail_client_reg: return ret; } -static int tps80031_remove(struct i2c_client *client) -{ - struct tps80031 *tps80031 = i2c_get_clientdata(client); - int i; - - if (tps80031_power_off_dev == tps80031) { - tps80031_power_off_dev = NULL; - pm_power_off = NULL; - } - - mfd_remove_devices(tps80031->dev); - - regmap_del_irq_chip(client->irq, tps80031->irq_data); - - for (i = 0; i < TPS80031_NUM_SLAVES; i++) { - if (tps80031->clients[i] != client) - i2c_unregister_device(tps80031->clients[i]); - } - return 0; -} - static const struct i2c_device_id tps80031_id_table[] = { { "tps80031", TPS80031 }, { "tps80032", TPS80032 }, { } }; -MODULE_DEVICE_TABLE(i2c, tps80031_id_table); static struct i2c_driver tps80031_driver = { .driver = { - .name = "tps80031", + .name = "tps80031", + .suppress_bind_attrs = true, }, .probe = tps80031_probe, - .remove = tps80031_remove, .id_table = tps80031_id_table, }; @@ -558,13 +535,3 @@ static int __init tps80031_init(void) return i2c_add_driver(&tps80031_driver); } subsys_initcall(tps80031_init); - -static void __exit tps80031_exit(void) -{ - i2c_del_driver(&tps80031_driver); -} -module_exit(tps80031_exit); - -MODULE_AUTHOR("Laxman Dewangan "); -MODULE_DESCRIPTION("TPS80031 core driver"); -MODULE_LICENSE("GPL v2"); -- cgit v1.2.1 From e85c5f0a1b429d9de68bc6493526afb694908bdd Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Sun, 13 Jan 2019 13:36:44 -0500 Subject: mfd: wm831x-spi: Make it explicitly non-modular The Kconfig currently controlling compilation of this code is: drivers/mfd/Kconfig:config MFD_WM831X_SPI drivers/mfd/Kconfig: bool "Wolfson Microelectronics WM831x/2x PMICs with SPI" ...meaning that it currently is not being built as a module by anyone. Lets remove the modular code that is essentially orphaned, so that when reading the driver there is no doubt it is builtin-only. We explicitly disallow a driver unbind, since that doesn't have a sensible use case anyway, and it allows us to drop the ".remove" code for non-modular drivers. Since module_init was not in use by this code, the init ordering remains unchanged with this commit. Also note that MODULE_DEVICE_TABLE is a no-op for non-modular code. We also delete the MODULE_LICENSE tag etc. since all that information is already contained at the top of the file in the comments. Signed-off-by: Paul Gortmaker Acked-by: Linus Walleij Signed-off-by: Lee Jones --- drivers/mfd/wm831x-spi.c | 24 ++---------------------- 1 file changed, 2 insertions(+), 22 deletions(-) (limited to 'drivers/mfd') diff --git a/drivers/mfd/wm831x-spi.c b/drivers/mfd/wm831x-spi.c index 018ce652ae57..dd4dab419940 100644 --- a/drivers/mfd/wm831x-spi.c +++ b/drivers/mfd/wm831x-spi.c @@ -13,7 +13,7 @@ */ #include -#include +#include #include #include #include @@ -67,15 +67,6 @@ static int wm831x_spi_probe(struct spi_device *spi) return wm831x_device_init(wm831x, spi->irq); } -static int wm831x_spi_remove(struct spi_device *spi) -{ - struct wm831x *wm831x = spi_get_drvdata(spi); - - wm831x_device_exit(wm831x); - - return 0; -} - static int wm831x_spi_suspend(struct device *dev) { struct wm831x *wm831x = dev_get_drvdata(dev); @@ -108,17 +99,16 @@ static const struct spi_device_id wm831x_spi_ids[] = { { "wm8326", WM8326 }, { }, }; -MODULE_DEVICE_TABLE(spi, wm831x_spi_ids); static struct spi_driver wm831x_spi_driver = { .driver = { .name = "wm831x", .pm = &wm831x_spi_pm, .of_match_table = of_match_ptr(wm831x_of_match), + .suppress_bind_attrs = true, }, .id_table = wm831x_spi_ids, .probe = wm831x_spi_probe, - .remove = wm831x_spi_remove, }; static int __init wm831x_spi_init(void) @@ -132,13 +122,3 @@ static int __init wm831x_spi_init(void) return 0; } subsys_initcall(wm831x_spi_init); - -static void __exit wm831x_spi_exit(void) -{ - spi_unregister_driver(&wm831x_spi_driver); -} -module_exit(wm831x_spi_exit); - -MODULE_DESCRIPTION("SPI support for WM831x/2x AudioPlus PMICs"); -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mark Brown"); -- cgit v1.2.1 From af5db808a41f1d63ecc835024d6d3b169600f36d Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Sun, 13 Jan 2019 13:36:45 -0500 Subject: mfd: wm831x-i2c: Make it explicitly non-modular The Kconfig currently controlling compilation of this code is: drivers/mfd/Kconfig:config MFD_WM831X_I2C drivers/mfd/Kconfig: bool "Wolfson Microelectronics WM831x/2x PMICs with I2C" ...meaning that it currently is not being built as a module by anyone. Lets remove the modular code that is essentially orphaned, so that when reading the driver there is no doubt it is builtin-only. We explicitly disallow a driver unbind, since that doesn't have a sensible use case anyway, and it allows us to drop the ".remove" code for non-modular drivers. Since module_init was not in use by this code, the init ordering remains unchanged with this commit. Also note that MODULE_DEVICE_TABLE is a no-op for non-modular code. Signed-off-by: Paul Gortmaker Acked-by: Linus Walleij Acked-by: Charles Keepax Signed-off-by: Lee Jones --- drivers/mfd/wm831x-i2c.c | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) (limited to 'drivers/mfd') diff --git a/drivers/mfd/wm831x-i2c.c b/drivers/mfd/wm831x-i2c.c index 22f7054d1b28..0f3af42f7268 100644 --- a/drivers/mfd/wm831x-i2c.c +++ b/drivers/mfd/wm831x-i2c.c @@ -13,7 +13,7 @@ */ #include -#include +#include #include #include #include @@ -68,15 +68,6 @@ static int wm831x_i2c_probe(struct i2c_client *i2c, return wm831x_device_init(wm831x, i2c->irq); } -static int wm831x_i2c_remove(struct i2c_client *i2c) -{ - struct wm831x *wm831x = i2c_get_clientdata(i2c); - - wm831x_device_exit(wm831x); - - return 0; -} - static int wm831x_i2c_suspend(struct device *dev) { struct wm831x *wm831x = dev_get_drvdata(dev); @@ -103,7 +94,6 @@ static const struct i2c_device_id wm831x_i2c_id[] = { { "wm8326", WM8326 }, { } }; -MODULE_DEVICE_TABLE(i2c, wm831x_i2c_id); static const struct dev_pm_ops wm831x_pm_ops = { .suspend = wm831x_i2c_suspend, @@ -115,9 +105,9 @@ static struct i2c_driver wm831x_i2c_driver = { .name = "wm831x", .pm = &wm831x_pm_ops, .of_match_table = of_match_ptr(wm831x_of_match), + .suppress_bind_attrs = true, }, .probe = wm831x_i2c_probe, - .remove = wm831x_i2c_remove, .id_table = wm831x_i2c_id, }; @@ -132,9 +122,3 @@ static int __init wm831x_i2c_init(void) return ret; } subsys_initcall(wm831x_i2c_init); - -static void __exit wm831x_i2c_exit(void) -{ - i2c_del_driver(&wm831x_i2c_driver); -} -module_exit(wm831x_i2c_exit); -- cgit v1.2.1 From efb5a790dfc33b36bc64dd5a41ffc3ae5a709770 Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Sun, 13 Jan 2019 13:36:46 -0500 Subject: mfd: wm831x-core: Drop unused module infrastructure from non-modular code The Kconfig currently controlling compilation of this code is: drivers/mfd/Kconfig:config MFD_WM831X drivers/mfd/Kconfig: bool ...meaning that it currently is not being built as a module by anyone. Lets remove the couple traces of modular infrastructure use, so that when reading the driver there is no doubt it is builtin-only. We delete the MODULE_LICENSE tag etc. since all that information is already contained at the top of the file in the comments. Previous demodularizaion work has made wm831x_device_exit() no longer used, so it is also removed from the 831x core code. Signed-off-by: Paul Gortmaker Acked-by: Charles Keepax Signed-off-by: Lee Jones --- drivers/mfd/wm831x-core.c | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) (limited to 'drivers/mfd') diff --git a/drivers/mfd/wm831x-core.c b/drivers/mfd/wm831x-core.c index e70d35ef5c6d..25fbbaf39cb9 100644 --- a/drivers/mfd/wm831x-core.c +++ b/drivers/mfd/wm831x-core.c @@ -13,7 +13,8 @@ */ #include -#include +#include +#include #include #include #include @@ -1892,14 +1893,6 @@ err: return ret; } -void wm831x_device_exit(struct wm831x *wm831x) -{ - wm831x_otp_exit(wm831x); - mfd_remove_devices(wm831x->dev); - free_irq(wm831x_irq(wm831x, WM831X_IRQ_AUXADC_DATA), wm831x); - wm831x_irq_exit(wm831x); -} - int wm831x_device_suspend(struct wm831x *wm831x) { int reg, mask; @@ -1944,7 +1937,3 @@ void wm831x_device_shutdown(struct wm831x *wm831x) } } EXPORT_SYMBOL_GPL(wm831x_device_shutdown); - -MODULE_DESCRIPTION("Core support for the WM831X AudioPlus PMIC"); -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mark Brown"); -- cgit v1.2.1 From fc6430661a88c92c6b8391d09e1b3ae508b88c01 Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Sun, 13 Jan 2019 13:36:47 -0500 Subject: mfd: wm8350-i2c: Make it explicitly non-modular The Kconfig currently controlling compilation of this code is: drivers/mfd/Kconfig:config MFD_WM8350_I2C drivers/mfd/Kconfig: bool "Wolfson Microelectronics WM8350 with I2C" ...meaning that it currently is not being built as a module by anyone. Lets remove the modular code that is essentially orphaned, so that when reading the driver there is no doubt it is builtin-only. We explicitly disallow a driver unbind, since that doesn't have a sensible use case anyway, and it allows us to drop the ".remove" code for non-modular drivers. Since module_init was not in use by this code, the init ordering remains unchanged with this commit. We don't replace module.h with init.h since the file already has that. But we do delete an unused moduleparam.h Also note that MODULE_DEVICE_TABLE is a no-op for non-modular code. We also delete the MODULE_LICENSE tag etc. since all that information is already contained at the top of the file in the comments. Signed-off-by: Paul Gortmaker Acked-by: Linus Walleij Acked-by: Charles Keepax Signed-off-by: Lee Jones --- drivers/mfd/wm8350-i2c.c | 24 +----------------------- 1 file changed, 1 insertion(+), 23 deletions(-) (limited to 'drivers/mfd') diff --git a/drivers/mfd/wm8350-i2c.c b/drivers/mfd/wm8350-i2c.c index 9358f03b7938..b4194e068e1b 100644 --- a/drivers/mfd/wm8350-i2c.c +++ b/drivers/mfd/wm8350-i2c.c @@ -13,8 +13,6 @@ * */ -#include -#include #include #include #include @@ -48,30 +46,19 @@ static int wm8350_i2c_probe(struct i2c_client *i2c, return wm8350_device_init(wm8350, i2c->irq, pdata); } -static int wm8350_i2c_remove(struct i2c_client *i2c) -{ - struct wm8350 *wm8350 = i2c_get_clientdata(i2c); - - wm8350_device_exit(wm8350); - - return 0; -} - static const struct i2c_device_id wm8350_i2c_id[] = { { "wm8350", 0 }, { "wm8351", 0 }, { "wm8352", 0 }, { } }; -MODULE_DEVICE_TABLE(i2c, wm8350_i2c_id); - static struct i2c_driver wm8350_i2c_driver = { .driver = { .name = "wm8350", + .suppress_bind_attrs = true, }, .probe = wm8350_i2c_probe, - .remove = wm8350_i2c_remove, .id_table = wm8350_i2c_id, }; @@ -81,12 +68,3 @@ static int __init wm8350_i2c_init(void) } /* init early so consumer devices can complete system boot */ subsys_initcall(wm8350_i2c_init); - -static void __exit wm8350_i2c_exit(void) -{ - i2c_del_driver(&wm8350_i2c_driver); -} -module_exit(wm8350_i2c_exit); - -MODULE_DESCRIPTION("I2C support for the WM8350 AudioPlus PMIC"); -MODULE_LICENSE("GPL"); -- cgit v1.2.1 From 0db88688e1bb0180d6348742bdba8927cd0e5670 Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Sun, 13 Jan 2019 13:36:48 -0500 Subject: mfd: wm8350-core: Drop unused module infrastructure from non-modular code The Kconfig currently controlling compilation of this code is: drivers/mfd/Kconfig:config MFD_WM8350 drivers/mfd/Kconfig: bool ...meaning that it currently is not being built as a module by anyone. Lets remove the couple traces of modular infrastructure use, so that when reading the driver there is no doubt it is builtin-only. We delete the MODULE_LICENSE tag etc. since all that information is already contained at the top of the file in the comments. We replace module.h with init.h and export.h ; the latter since the file does export some symbols. Previous demodularizaion work has made wm8350_device_exit() no longer used, so it is also removed from the 8350 core code. Signed-off-by: Paul Gortmaker Acked-by: Charles Keepax Signed-off-by: Lee Jones --- drivers/mfd/wm8350-core.c | 30 ++---------------------------- 1 file changed, 2 insertions(+), 28 deletions(-) (limited to 'drivers/mfd') diff --git a/drivers/mfd/wm8350-core.c b/drivers/mfd/wm8350-core.c index 8a07c5634aee..9e1070f26b11 100644 --- a/drivers/mfd/wm8350-core.c +++ b/drivers/mfd/wm8350-core.c @@ -13,7 +13,8 @@ */ #include -#include +#include +#include #include #include #include @@ -442,30 +443,3 @@ err: return ret; } EXPORT_SYMBOL_GPL(wm8350_device_init); - -void wm8350_device_exit(struct wm8350 *wm8350) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(wm8350->pmic.led); i++) - platform_device_unregister(wm8350->pmic.led[i].pdev); - - for (i = 0; i < ARRAY_SIZE(wm8350->pmic.pdev); i++) - platform_device_unregister(wm8350->pmic.pdev[i]); - - platform_device_unregister(wm8350->wdt.pdev); - platform_device_unregister(wm8350->rtc.pdev); - platform_device_unregister(wm8350->power.pdev); - platform_device_unregister(wm8350->hwmon.pdev); - platform_device_unregister(wm8350->gpio.pdev); - platform_device_unregister(wm8350->codec.pdev); - - if (wm8350->irq_base) - free_irq(wm8350->irq_base + WM8350_IRQ_AUXADC_DATARDY, wm8350); - - wm8350_irq_exit(wm8350); -} -EXPORT_SYMBOL_GPL(wm8350_device_exit); - -MODULE_DESCRIPTION("WM8350 AudioPlus PMIC core driver"); -MODULE_LICENSE("GPL"); -- cgit v1.2.1 From b2b658752c71311f06b6efab5667e98b01b52b6b Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Sun, 13 Jan 2019 13:36:49 -0500 Subject: mfd: wm8400-core: Make it explicitly non-modular The Kconfig currently controlling compilation of this code is: drivers/mfd/Kconfig:config MFD_WM8400 drivers/mfd/Kconfig: bool "Wolfson Microelectronics WM8400" ...meaning that it currently is not being built as a module by anyone. Lets remove the modular code that is essentially orphaned, so that when reading the driver there is no doubt it is builtin-only. Since module_init was not in use by this code, the init ordering remains unchanged with this commit. A trivial function rename from wm8400_module_init to the name wm8400_driver_init is also done to reduce possible confusion. Also note that MODULE_DEVICE_TABLE is a no-op for non-modular code. We also delete the MODULE_LICENSE tag etc. since all that information is already contained at the top of the file in the comments. Signed-off-by: Paul Gortmaker Acked-by: Linus Walleij Acked-by: Charles Keepax Signed-off-by: Lee Jones --- drivers/mfd/wm8400-core.c | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) (limited to 'drivers/mfd') diff --git a/drivers/mfd/wm8400-core.c b/drivers/mfd/wm8400-core.c index 8a98a2fc74e1..79756c83f5f0 100644 --- a/drivers/mfd/wm8400-core.c +++ b/drivers/mfd/wm8400-core.c @@ -12,7 +12,7 @@ * */ -#include +#include #include #include #include @@ -150,7 +150,6 @@ static const struct i2c_device_id wm8400_i2c_id[] = { { "wm8400", 0 }, { } }; -MODULE_DEVICE_TABLE(i2c, wm8400_i2c_id); static struct i2c_driver wm8400_i2c_driver = { .driver = { @@ -161,7 +160,7 @@ static struct i2c_driver wm8400_i2c_driver = { }; #endif -static int __init wm8400_module_init(void) +static int __init wm8400_driver_init(void) { int ret = -ENODEV; @@ -173,15 +172,4 @@ static int __init wm8400_module_init(void) return ret; } -subsys_initcall(wm8400_module_init); - -static void __exit wm8400_module_exit(void) -{ -#if IS_ENABLED(CONFIG_I2C) - i2c_del_driver(&wm8400_i2c_driver); -#endif -} -module_exit(wm8400_module_exit); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mark Brown "); +subsys_initcall(wm8400_driver_init); -- cgit v1.2.1 From d57f72875eed3f26afaca176c0f425f209bc99d7 Mon Sep 17 00:00:00 2001 From: Christian Hohnstaedt Date: Mon, 14 Jan 2019 09:16:34 +0100 Subject: mfd: tps65218.c: Add input voltage options These options apply to all regulators in this chip. ti,strict-supply-voltage-supervision: Set STRICT flag in CONFIG1 ti,under-voltage-limit-microvolt: Select 2.75, 2.95, 3.25 or 3.35 V UVLO in CONFIG1 ti,under-voltage-hyst-microvolt: Select 200mV or 400mV UVLOHYS in CONFIG2 Signed-off-by: Christian Hohnstaedt Tested-by: Keerthy Reviewed-by: Keerthy Signed-off-by: Lee Jones --- drivers/mfd/tps65218.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) (limited to 'drivers/mfd') diff --git a/drivers/mfd/tps65218.c b/drivers/mfd/tps65218.c index 8bcdecf494d0..a62ea4cb8be7 100644 --- a/drivers/mfd/tps65218.c +++ b/drivers/mfd/tps65218.c @@ -211,6 +211,83 @@ static const struct of_device_id of_tps65218_match_table[] = { }; MODULE_DEVICE_TABLE(of, of_tps65218_match_table); +static int tps65218_voltage_set_strict(struct tps65218 *tps) +{ + u32 strict; + + if (of_property_read_u32(tps->dev->of_node, + "ti,strict-supply-voltage-supervision", + &strict)) + return 0; + + if (strict != 0 && strict != 1) { + dev_err(tps->dev, + "Invalid ti,strict-supply-voltage-supervision value\n"); + return -EINVAL; + } + + tps65218_update_bits(tps, TPS65218_REG_CONFIG1, + TPS65218_CONFIG1_STRICT, + strict ? TPS65218_CONFIG1_STRICT : 0, + TPS65218_PROTECT_L1); + return 0; +} + +static int tps65218_voltage_set_uv_hyst(struct tps65218 *tps) +{ + u32 hyst; + + if (of_property_read_u32(tps->dev->of_node, + "ti,under-voltage-hyst-microvolt", &hyst)) + return 0; + + if (hyst != 400000 && hyst != 200000) { + dev_err(tps->dev, + "Invalid ti,under-voltage-hyst-microvolt value\n"); + return -EINVAL; + } + + tps65218_update_bits(tps, TPS65218_REG_CONFIG2, + TPS65218_CONFIG2_UVLOHYS, + hyst == 400000 ? TPS65218_CONFIG2_UVLOHYS : 0, + TPS65218_PROTECT_L1); + return 0; +} + +static int tps65218_voltage_set_uvlo(struct tps65218 *tps) +{ + u32 uvlo; + int uvloval; + + if (of_property_read_u32(tps->dev->of_node, + "ti,under-voltage-limit-microvolt", &uvlo)) + return 0; + + switch (uvlo) { + case 2750000: + uvloval = TPS65218_CONFIG1_UVLO_2750000; + break; + case 2950000: + uvloval = TPS65218_CONFIG1_UVLO_2950000; + break; + case 3250000: + uvloval = TPS65218_CONFIG1_UVLO_3250000; + break; + case 3350000: + uvloval = TPS65218_CONFIG1_UVLO_3350000; + break; + default: + dev_err(tps->dev, + "Invalid ti,under-voltage-limit-microvolt value\n"); + return -EINVAL; + } + + tps65218_update_bits(tps, TPS65218_REG_CONFIG1, + TPS65218_CONFIG1_UVLO_MASK, uvloval, + TPS65218_PROTECT_L1); + return 0; +} + static int tps65218_probe(struct i2c_client *client, const struct i2c_device_id *ids) { @@ -249,6 +326,18 @@ static int tps65218_probe(struct i2c_client *client, tps->rev = chipid & TPS65218_CHIPID_REV_MASK; + ret = tps65218_voltage_set_strict(tps); + if (ret) + return ret; + + ret = tps65218_voltage_set_uvlo(tps); + if (ret) + return ret; + + ret = tps65218_voltage_set_uv_hyst(tps); + if (ret) + return ret; + ret = mfd_add_devices(tps->dev, PLATFORM_DEVID_AUTO, tps65218_cells, ARRAY_SIZE(tps65218_cells), NULL, 0, regmap_irq_get_domain(tps->irq_data)); -- cgit v1.2.1 From 09fdc98577120d4f47601c3127efde726a2300c6 Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Mon, 21 Jan 2019 16:11:28 +0200 Subject: mfd: Kconfig: Fix I2C_DESIGNWARE_PLATFORM dependencies INTEL_SOC_PMIC, INTEL_SOC_PMIC_CHTWC and MFD_TPS68470 select the I2C_DESIGNWARE_PLATFORM without its dependencies making it possible to see warning and build error like below: WARNING: unmet direct dependencies detected for I2C_DESIGNWARE_PLATFORM Depends on [n]: I2C [=y] && HAS_IOMEM [=y] && (ACPI [=y] && COMMON_CLK [=n] || !ACPI [=y]) Selected by [y]: - MFD_TPS68470 [=y] && HAS_IOMEM [=y] && ACPI [=y] && I2C [=y]=y /usr/bin/ld: drivers/i2c/busses/i2c-designware-platdrv.o: in function `dw_i2c_plat_resume': i2c-designware-platdrv.c:(.text+0x62): undefined reference to `i2c_dw_prepare_clk' /usr/bin/ld: drivers/i2c/busses/i2c-designware-platdrv.o: in function `dw_i2c_plat_suspend': i2c-designware-platdrv.c:(.text+0x9a): undefined reference to `i2c_dw_prepare_clk' /usr/bin/ld: drivers/i2c/busses/i2c-designware-platdrv.o: in function `dw_i2c_plat_probe': i2c-designware-platdrv.c:(.text+0x41c): undefined reference to `i2c_dw_prepare_clk' /usr/bin/ld: i2c-designware-platdrv.c:(.text+0x438): undefined reference to `i2c_dw_read_comp_param' /usr/bin/ld: i2c-designware-platdrv.c:(.text+0x545): undefined reference to `i2c_dw_probe' /usr/bin/ld: i2c-designware-platdrv.c:(.text+0x727): undefined reference to `i2c_dw_probe_slave' Fix this by making above options to depend on I2C_DESIGNWARE_PLATFORM being built-in. I2C_DESIGNWARE_PLATFORM is a visible symbol with dependencies so in general the select should be avoided. Fixes: acebcff9eda8 ("mfd: intel_soc_pmic: Select designware i2c-bus driver") Fixes: de85d79f4aab ("mfd: Add Cherry Trail Whiskey Cove PMIC driver") Fixes: 9bbf6a15ce19 ("mfd: Add support for TPS68470 device") Cc: Stable # v4.14+ Reported-by: Randy Dunlap Signed-off-by: Jarkko Nikula Acked-by: Randy Dunlap # build-tested Signed-off-by: Lee Jones --- drivers/mfd/Kconfig | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/mfd') diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 211da115d3f6..6e58221f5c28 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -518,10 +518,10 @@ config INTEL_SOC_PMIC bool "Support for Crystal Cove PMIC" depends on ACPI && HAS_IOMEM && I2C=y && GPIOLIB && COMMON_CLK depends on X86 || COMPILE_TEST + depends on I2C_DESIGNWARE_PLATFORM=y select MFD_CORE select REGMAP_I2C select REGMAP_IRQ - select I2C_DESIGNWARE_PLATFORM help Select this option to enable support for Crystal Cove PMIC on some Intel SoC systems. The PMIC provides ADC, GPIO, @@ -547,10 +547,10 @@ config INTEL_SOC_PMIC_CHTWC bool "Support for Intel Cherry Trail Whiskey Cove PMIC" depends on ACPI && HAS_IOMEM && I2C=y && COMMON_CLK depends on X86 || COMPILE_TEST + depends on I2C_DESIGNWARE_PLATFORM=y select MFD_CORE select REGMAP_I2C select REGMAP_IRQ - select I2C_DESIGNWARE_PLATFORM help Select this option to enable support for the Intel Cherry Trail Whiskey Cove PMIC found on some Intel Cherry Trail systems. @@ -1420,9 +1420,9 @@ config MFD_TPS65217 config MFD_TPS68470 bool "TI TPS68470 Power Management / LED chips" depends on ACPI && I2C=y + depends on I2C_DESIGNWARE_PLATFORM=y select MFD_CORE select REGMAP_I2C - select I2C_DESIGNWARE_PLATFORM help If you say yes here you get support for the TPS68470 series of Power Management / LED chips. -- cgit v1.2.1 From ae7b8eda27b33b1f688dfdebe4d46f690a8f9162 Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Tue, 22 Jan 2019 10:56:36 -0600 Subject: mfd: sm501: Fix potential NULL pointer dereference There is a potential NULL pointer dereference in case devm_kzalloc() fails and returns NULL. Fix this by adding a NULL check on *lookup* This bug was detected with the help of Coccinelle. Fixes: b2e63555592f ("i2c: gpio: Convert to use descriptors") Cc: stable@vger.kernel.org Signed-off-by: Gustavo A. R. Silva Signed-off-by: Lee Jones --- drivers/mfd/sm501.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/mfd') diff --git a/drivers/mfd/sm501.c b/drivers/mfd/sm501.c index a530972c5a7e..e0173bf4b0dc 100644 --- a/drivers/mfd/sm501.c +++ b/drivers/mfd/sm501.c @@ -1145,6 +1145,9 @@ static int sm501_register_gpio_i2c_instance(struct sm501_devdata *sm, lookup = devm_kzalloc(&pdev->dev, sizeof(*lookup) + 3 * sizeof(struct gpiod_lookup), GFP_KERNEL); + if (!lookup) + return -ENOMEM; + lookup->dev_id = "i2c-gpio"; if (iic->pin_sda < 32) lookup->table[0].chip_label = "SM501-LOW"; -- cgit v1.2.1 From 9f208eca4f2faa38def458f663ec142a0b6f451b Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Tue, 22 Jan 2019 10:58:20 -0600 Subject: mfd: sm501: Use struct_size() in devm_kzalloc() One of the more common cases of allocation size calculations is finding the size of a structure that has a zero-sized array at the end, along with memory for some number of elements for that array. For example: struct foo { int stuff; struct boo entry[]; }; instance = devm_kzalloc(dev, sizeof(struct foo) + count * sizeof(struct boo), GFP_KERNEL); Instead of leaving these open-coded and prone to type mistakes, we can now use the new struct_size() helper: instance = devm_kzalloc(dev, struct_size(instance, entry, count), GFP_KERNEL); This code was detected with the help of Coccinelle. Signed-off-by: Gustavo A. R. Silva Signed-off-by: Lee Jones --- drivers/mfd/sm501.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/mfd') diff --git a/drivers/mfd/sm501.c b/drivers/mfd/sm501.c index e0173bf4b0dc..d217debf382e 100644 --- a/drivers/mfd/sm501.c +++ b/drivers/mfd/sm501.c @@ -1142,8 +1142,7 @@ static int sm501_register_gpio_i2c_instance(struct sm501_devdata *sm, return -ENOMEM; /* Create a gpiod lookup using gpiochip-local offsets */ - lookup = devm_kzalloc(&pdev->dev, - sizeof(*lookup) + 3 * sizeof(struct gpiod_lookup), + lookup = devm_kzalloc(&pdev->dev, struct_size(lookup, table, 3), GFP_KERNEL); if (!lookup) return -ENOMEM; -- cgit v1.2.1 From 83761f9663a228f148ee318cc0531035cfa5654c Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 29 Jan 2019 12:25:53 +0100 Subject: mfd: sec-core: Return gracefully instead of BUG() if device cannot match Replace impossible BUG() in probe with a proper return. This can be triggered only in case of a clear bug (e.g. adding broken half-support for new S2MPSXX flavor) but BUG() is discouraged and the boot process can actually try to continue. Signed-off-by: Krzysztof Kozlowski Signed-off-by: Lee Jones --- drivers/mfd/sec-core.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/mfd') diff --git a/drivers/mfd/sec-core.c b/drivers/mfd/sec-core.c index e0835c9df7a1..00321011de0a 100644 --- a/drivers/mfd/sec-core.c +++ b/drivers/mfd/sec-core.c @@ -471,8 +471,9 @@ static int sec_pmic_probe(struct i2c_client *i2c, num_sec_devs = ARRAY_SIZE(s2mpu02_devs); break; default: - /* If this happens the probe function is problem */ - BUG(); + dev_err(&i2c->dev, "Unsupported device type (%lu)\n", + sec_pmic->device_type); + return -ENODEV; } ret = devm_mfd_add_devices(sec_pmic->dev, -1, sec_devs, num_sec_devs, NULL, 0, NULL); -- cgit v1.2.1 From 422dcafe477c7240d03c7b150704c45e0b17be57 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Wed, 30 Jan 2019 11:41:26 +0000 Subject: mfd: lochnagar: Add support for the Cirrus Logic Lochnagar Lochnagar is an evaluation and development board for Cirrus Logic Smart CODEC and Amp devices. It allows the connection of most Cirrus Logic devices on mini-cards, as well as allowing connection of various application processor systems to provide a full evaluation platform. This driver supports the board controller chip on the Lochnagar board. Audio system topology, clocking and power can all be controlled through the Lochnagar controller chip, allowing the device under test to be used in a variety of possible use cases. As the Lochnagar is a fairly complex device this MFD driver allows the drivers for the various features to be bound in. Initially clocking, regulator and pinctrl will be added as these are necessary to configure the system. But in time at least audio and voltage/current monitoring will also be added. Signed-off-by: Charles Keepax Signed-off-by: Lee Jones --- drivers/mfd/Kconfig | 8 + drivers/mfd/Makefile | 2 + drivers/mfd/lochnagar-i2c.c | 398 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 408 insertions(+) create mode 100644 drivers/mfd/lochnagar-i2c.c (limited to 'drivers/mfd') diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 6e58221f5c28..f38f8741c68e 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -1686,6 +1686,14 @@ config MFD_VX855 VIA VX855/VX875 south bridge. You will need to enable the vx855_spi and/or vx855_gpio drivers for this to do anything useful. +config MFD_LOCHNAGAR + bool "Cirrus Logic Lochnagar Audio Development Board" + select MFD_CORE + select REGMAP_I2C + depends on I2C=y && OF + help + Support for Cirrus Logic Lochnagar audio development board. + config MFD_ARIZONA select REGMAP select REGMAP_IRQ diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index a62fb0112d9f..a406fd3b8681 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -37,6 +37,8 @@ obj-$(CONFIG_MFD_T7L66XB) += t7l66xb.o tmio_core.o obj-$(CONFIG_MFD_TC6387XB) += tc6387xb.o tmio_core.o obj-$(CONFIG_MFD_TC6393XB) += tc6393xb.o tmio_core.o +obj-$(CONFIG_MFD_LOCHNAGAR) += lochnagar-i2c.o + obj-$(CONFIG_MFD_ARIZONA) += arizona-core.o obj-$(CONFIG_MFD_ARIZONA) += arizona-irq.o obj-$(CONFIG_MFD_ARIZONA_I2C) += arizona-i2c.o diff --git a/drivers/mfd/lochnagar-i2c.c b/drivers/mfd/lochnagar-i2c.c new file mode 100644 index 000000000000..3a65d9938902 --- /dev/null +++ b/drivers/mfd/lochnagar-i2c.c @@ -0,0 +1,398 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Lochnagar I2C bus interface + * + * Copyright (c) 2012-2018 Cirrus Logic, Inc. and + * Cirrus Logic International Semiconductor Ltd. + * + * Author: Charles Keepax + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#define LOCHNAGAR_BOOT_RETRIES 10 +#define LOCHNAGAR_BOOT_DELAY_MS 350 + +#define LOCHNAGAR_CONFIG_POLL_US 10000 + +static bool lochnagar1_readable_register(struct device *dev, unsigned int reg) +{ + switch (reg) { + case LOCHNAGAR_SOFTWARE_RESET: + case LOCHNAGAR_FIRMWARE_ID1...LOCHNAGAR_FIRMWARE_ID2: + case LOCHNAGAR1_CDC_AIF1_SEL...LOCHNAGAR1_CDC_AIF3_SEL: + case LOCHNAGAR1_CDC_MCLK1_SEL...LOCHNAGAR1_CDC_MCLK2_SEL: + case LOCHNAGAR1_CDC_AIF_CTRL1...LOCHNAGAR1_CDC_AIF_CTRL2: + case LOCHNAGAR1_EXT_AIF_CTRL: + case LOCHNAGAR1_DSP_AIF1_SEL...LOCHNAGAR1_DSP_AIF2_SEL: + case LOCHNAGAR1_DSP_CLKIN_SEL: + case LOCHNAGAR1_DSP_AIF: + case LOCHNAGAR1_GF_AIF1...LOCHNAGAR1_GF_AIF2: + case LOCHNAGAR1_PSIA_AIF: + case LOCHNAGAR1_PSIA1_SEL...LOCHNAGAR1_PSIA2_SEL: + case LOCHNAGAR1_SPDIF_AIF_SEL: + case LOCHNAGAR1_GF_AIF3_SEL...LOCHNAGAR1_GF_AIF4_SEL: + case LOCHNAGAR1_GF_CLKOUT1_SEL: + case LOCHNAGAR1_GF_AIF1_SEL...LOCHNAGAR1_GF_AIF2_SEL: + case LOCHNAGAR1_GF_GPIO2...LOCHNAGAR1_GF_GPIO7: + case LOCHNAGAR1_RST: + case LOCHNAGAR1_LED1...LOCHNAGAR1_LED2: + case LOCHNAGAR1_I2C_CTRL: + return true; + default: + return false; + } +} + +static const struct regmap_config lochnagar1_i2c_regmap = { + .reg_bits = 8, + .val_bits = 8, + .reg_format_endian = REGMAP_ENDIAN_BIG, + .val_format_endian = REGMAP_ENDIAN_BIG, + + .max_register = 0x50, + .readable_reg = lochnagar1_readable_register, + + .use_single_read = true, + .use_single_write = true, + + .cache_type = REGCACHE_RBTREE, +}; + +static const struct reg_sequence lochnagar1_patch[] = { + { 0x40, 0x0083 }, + { 0x47, 0x0018 }, + { 0x50, 0x0000 }, +}; + +static bool lochnagar2_readable_register(struct device *dev, unsigned int reg) +{ + switch (reg) { + case LOCHNAGAR_SOFTWARE_RESET: + case LOCHNAGAR_FIRMWARE_ID1...LOCHNAGAR_FIRMWARE_ID2: + case LOCHNAGAR2_CDC_AIF1_CTRL...LOCHNAGAR2_CDC_AIF3_CTRL: + case LOCHNAGAR2_DSP_AIF1_CTRL...LOCHNAGAR2_DSP_AIF2_CTRL: + case LOCHNAGAR2_PSIA1_CTRL...LOCHNAGAR2_PSIA2_CTRL: + case LOCHNAGAR2_GF_AIF3_CTRL...LOCHNAGAR2_GF_AIF4_CTRL: + case LOCHNAGAR2_GF_AIF1_CTRL...LOCHNAGAR2_GF_AIF2_CTRL: + case LOCHNAGAR2_SPDIF_AIF_CTRL: + case LOCHNAGAR2_USB_AIF1_CTRL...LOCHNAGAR2_USB_AIF2_CTRL: + case LOCHNAGAR2_ADAT_AIF_CTRL: + case LOCHNAGAR2_CDC_MCLK1_CTRL...LOCHNAGAR2_CDC_MCLK2_CTRL: + case LOCHNAGAR2_DSP_CLKIN_CTRL: + case LOCHNAGAR2_PSIA1_MCLK_CTRL...LOCHNAGAR2_PSIA2_MCLK_CTRL: + case LOCHNAGAR2_SPDIF_MCLK_CTRL: + case LOCHNAGAR2_GF_CLKOUT1_CTRL...LOCHNAGAR2_GF_CLKOUT2_CTRL: + case LOCHNAGAR2_ADAT_MCLK_CTRL: + case LOCHNAGAR2_SOUNDCARD_MCLK_CTRL: + case LOCHNAGAR2_GPIO_FPGA_GPIO1...LOCHNAGAR2_GPIO_FPGA_GPIO6: + case LOCHNAGAR2_GPIO_CDC_GPIO1...LOCHNAGAR2_GPIO_CDC_GPIO8: + case LOCHNAGAR2_GPIO_DSP_GPIO1...LOCHNAGAR2_GPIO_DSP_GPIO6: + case LOCHNAGAR2_GPIO_GF_GPIO2...LOCHNAGAR2_GPIO_GF_GPIO7: + case LOCHNAGAR2_GPIO_CDC_AIF1_BCLK...LOCHNAGAR2_GPIO_CDC_AIF3_TXDAT: + case LOCHNAGAR2_GPIO_DSP_AIF1_BCLK...LOCHNAGAR2_GPIO_DSP_AIF2_TXDAT: + case LOCHNAGAR2_GPIO_PSIA1_BCLK...LOCHNAGAR2_GPIO_PSIA2_TXDAT: + case LOCHNAGAR2_GPIO_GF_AIF3_BCLK...LOCHNAGAR2_GPIO_GF_AIF4_TXDAT: + case LOCHNAGAR2_GPIO_GF_AIF1_BCLK...LOCHNAGAR2_GPIO_GF_AIF2_TXDAT: + case LOCHNAGAR2_GPIO_DSP_UART1_RX...LOCHNAGAR2_GPIO_DSP_UART2_TX: + case LOCHNAGAR2_GPIO_GF_UART2_RX...LOCHNAGAR2_GPIO_GF_UART2_TX: + case LOCHNAGAR2_GPIO_USB_UART_RX: + case LOCHNAGAR2_GPIO_CDC_PDMCLK1...LOCHNAGAR2_GPIO_CDC_PDMDAT2: + case LOCHNAGAR2_GPIO_CDC_DMICCLK1...LOCHNAGAR2_GPIO_CDC_DMICDAT4: + case LOCHNAGAR2_GPIO_DSP_DMICCLK1...LOCHNAGAR2_GPIO_DSP_DMICDAT2: + case LOCHNAGAR2_GPIO_I2C2_SCL...LOCHNAGAR2_GPIO_I2C4_SDA: + case LOCHNAGAR2_GPIO_DSP_STANDBY: + case LOCHNAGAR2_GPIO_CDC_MCLK1...LOCHNAGAR2_GPIO_CDC_MCLK2: + case LOCHNAGAR2_GPIO_DSP_CLKIN: + case LOCHNAGAR2_GPIO_PSIA1_MCLK...LOCHNAGAR2_GPIO_PSIA2_MCLK: + case LOCHNAGAR2_GPIO_GF_GPIO1...LOCHNAGAR2_GPIO_GF_GPIO5: + case LOCHNAGAR2_GPIO_DSP_GPIO20: + case LOCHNAGAR2_GPIO_CHANNEL1...LOCHNAGAR2_GPIO_CHANNEL16: + case LOCHNAGAR2_MINICARD_RESETS: + case LOCHNAGAR2_ANALOGUE_PATH_CTRL1...LOCHNAGAR2_ANALOGUE_PATH_CTRL2: + case LOCHNAGAR2_COMMS_CTRL4: + case LOCHNAGAR2_SPDIF_CTRL: + case LOCHNAGAR2_IMON_CTRL1...LOCHNAGAR2_IMON_CTRL4: + case LOCHNAGAR2_IMON_DATA1...LOCHNAGAR2_IMON_DATA2: + case LOCHNAGAR2_POWER_CTRL: + case LOCHNAGAR2_MICVDD_CTRL1: + case LOCHNAGAR2_MICVDD_CTRL2: + case LOCHNAGAR2_VDDCORE_CDC_CTRL1: + case LOCHNAGAR2_VDDCORE_CDC_CTRL2: + case LOCHNAGAR2_SOUNDCARD_AIF_CTRL: + return true; + default: + return false; + } +} + +static bool lochnagar2_volatile_register(struct device *dev, unsigned int reg) +{ + switch (reg) { + case LOCHNAGAR2_GPIO_CHANNEL1...LOCHNAGAR2_GPIO_CHANNEL16: + case LOCHNAGAR2_ANALOGUE_PATH_CTRL1: + case LOCHNAGAR2_IMON_CTRL3...LOCHNAGAR2_IMON_CTRL4: + case LOCHNAGAR2_IMON_DATA1...LOCHNAGAR2_IMON_DATA2: + return true; + default: + return false; + } +} + +static const struct regmap_config lochnagar2_i2c_regmap = { + .reg_bits = 16, + .val_bits = 16, + .reg_format_endian = REGMAP_ENDIAN_BIG, + .val_format_endian = REGMAP_ENDIAN_BIG, + + .max_register = 0x1F1F, + .readable_reg = lochnagar2_readable_register, + .volatile_reg = lochnagar2_volatile_register, + + .cache_type = REGCACHE_RBTREE, +}; + +static const struct reg_sequence lochnagar2_patch[] = { + { 0x00EE, 0x0000 }, +}; + +struct lochnagar_config { + int id; + const char * const name; + enum lochnagar_type type; + const struct regmap_config *regmap; + const struct reg_sequence *patch; + int npatch; +}; + +static struct lochnagar_config lochnagar_configs[] = { + { + .id = 0x50, + .name = "lochnagar1", + .type = LOCHNAGAR1, + .regmap = &lochnagar1_i2c_regmap, + .patch = lochnagar1_patch, + .npatch = ARRAY_SIZE(lochnagar1_patch), + }, + { + .id = 0xCB58, + .name = "lochnagar2", + .type = LOCHNAGAR2, + .regmap = &lochnagar2_i2c_regmap, + .patch = lochnagar2_patch, + .npatch = ARRAY_SIZE(lochnagar2_patch), + }, +}; + +static const struct of_device_id lochnagar_of_match[] = { + { .compatible = "cirrus,lochnagar1", .data = &lochnagar_configs[0] }, + { .compatible = "cirrus,lochnagar2", .data = &lochnagar_configs[1] }, + {}, +}; + +static int lochnagar_wait_for_boot(struct regmap *regmap, unsigned int *id) +{ + int i, ret; + + for (i = 0; i < LOCHNAGAR_BOOT_RETRIES; ++i) { + msleep(LOCHNAGAR_BOOT_DELAY_MS); + + /* The reset register will return the device ID when read */ + ret = regmap_read(regmap, LOCHNAGAR_SOFTWARE_RESET, id); + if (!ret) + return ret; + } + + return -ETIMEDOUT; +} + +/** + * lochnagar_update_config - Synchronise the boards analogue configuration to + * the hardware. + * + * @lochnagar: A pointer to the primary core data structure. + * + * Return: Zero on success or an appropriate negative error code on failure. + */ +int lochnagar_update_config(struct lochnagar *lochnagar) +{ + struct regmap *regmap = lochnagar->regmap; + unsigned int done = LOCHNAGAR2_ANALOGUE_PATH_UPDATE_STS_MASK; + int timeout_ms = LOCHNAGAR_BOOT_DELAY_MS * LOCHNAGAR_BOOT_RETRIES; + unsigned int val = 0; + int ret; + + lockdep_assert_held(&lochnagar->analogue_config_lock); + + if (lochnagar->type != LOCHNAGAR2) + return 0; + + /* + * Toggle the ANALOGUE_PATH_UPDATE bit and wait for the device to + * acknowledge that any outstanding changes to the analogue + * configuration have been applied. + */ + ret = regmap_write(regmap, LOCHNAGAR2_ANALOGUE_PATH_CTRL1, 0); + if (ret < 0) + return ret; + + ret = regmap_write(regmap, LOCHNAGAR2_ANALOGUE_PATH_CTRL1, + LOCHNAGAR2_ANALOGUE_PATH_UPDATE_MASK); + if (ret < 0) + return ret; + + ret = regmap_read_poll_timeout(regmap, + LOCHNAGAR2_ANALOGUE_PATH_CTRL1, val, + (val & done), LOCHNAGAR_CONFIG_POLL_US, + timeout_ms * 1000); + if (ret < 0) + return ret; + + return 0; +} +EXPORT_SYMBOL_GPL(lochnagar_update_config); + +static int lochnagar_i2c_probe(struct i2c_client *i2c) +{ + struct device *dev = &i2c->dev; + const struct lochnagar_config *config = NULL; + const struct of_device_id *of_id; + struct lochnagar *lochnagar; + struct gpio_desc *reset, *present; + unsigned int val; + unsigned int firmwareid; + unsigned int devid, rev; + int ret; + + lochnagar = devm_kzalloc(dev, sizeof(*lochnagar), GFP_KERNEL); + if (!lochnagar) + return -ENOMEM; + + of_id = of_match_device(lochnagar_of_match, dev); + if (!of_id) + return -EINVAL; + + config = of_id->data; + + lochnagar->dev = dev; + mutex_init(&lochnagar->analogue_config_lock); + + dev_set_drvdata(dev, lochnagar); + + reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW); + if (IS_ERR(reset)) { + ret = PTR_ERR(reset); + dev_err(dev, "Failed to get reset GPIO: %d\n", ret); + return ret; + } + + present = devm_gpiod_get_optional(dev, "present", GPIOD_OUT_HIGH); + if (IS_ERR(present)) { + ret = PTR_ERR(present); + dev_err(dev, "Failed to get present GPIO: %d\n", ret); + return ret; + } + + /* Leave the Lochnagar in reset for a reasonable amount of time */ + msleep(20); + + /* Bring Lochnagar out of reset */ + gpiod_set_value_cansleep(reset, 1); + + /* Identify Lochnagar */ + lochnagar->type = config->type; + + lochnagar->regmap = devm_regmap_init_i2c(i2c, config->regmap); + if (IS_ERR(lochnagar->regmap)) { + ret = PTR_ERR(lochnagar->regmap); + dev_err(dev, "Failed to allocate register map: %d\n", ret); + return ret; + } + + /* Wait for Lochnagar to boot */ + ret = lochnagar_wait_for_boot(lochnagar->regmap, &val); + if (ret < 0) { + dev_err(dev, "Failed to read device ID: %d\n", ret); + return ret; + } + + devid = val & LOCHNAGAR_DEVICE_ID_MASK; + rev = val & LOCHNAGAR_REV_ID_MASK; + + if (devid != config->id) { + dev_err(dev, + "ID does not match %s (expected 0x%x got 0x%x)\n", + config->name, config->id, devid); + return -ENODEV; + } + + /* Identify firmware */ + ret = regmap_read(lochnagar->regmap, LOCHNAGAR_FIRMWARE_ID1, &val); + if (ret < 0) { + dev_err(dev, "Failed to read firmware id 1: %d\n", ret); + return ret; + } + + firmwareid = val; + + ret = regmap_read(lochnagar->regmap, LOCHNAGAR_FIRMWARE_ID2, &val); + if (ret < 0) { + dev_err(dev, "Failed to read firmware id 2: %d\n", ret); + return ret; + } + + firmwareid |= (val << config->regmap->val_bits); + + dev_info(dev, "Found %s (0x%x) revision %u firmware 0x%.6x\n", + config->name, devid, rev + 1, firmwareid); + + ret = regmap_register_patch(lochnagar->regmap, config->patch, + config->npatch); + if (ret < 0) { + dev_err(dev, "Failed to register patch: %d\n", ret); + return ret; + } + + ret = devm_of_platform_populate(dev); + if (ret < 0) { + dev_err(dev, "Failed to populate child nodes: %d\n", ret); + return ret; + } + + return ret; +} + +static struct i2c_driver lochnagar_i2c_driver = { + .driver = { + .name = "lochnagar", + .of_match_table = of_match_ptr(lochnagar_of_match), + .suppress_bind_attrs = true, + }, + .probe_new = lochnagar_i2c_probe, +}; + +static int __init lochnagar_i2c_init(void) +{ + int ret; + + ret = i2c_add_driver(&lochnagar_i2c_driver); + if (ret) + pr_err("Failed to register Lochnagar driver: %d\n", ret); + + return ret; +} +subsys_initcall(lochnagar_i2c_init); -- cgit v1.2.1 From 10cffde4ad47cef7e8ab10bbb7a1feb9dc284a7a Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 31 Jan 2019 12:32:12 +0800 Subject: mfd: at91-usart: Constify at91_usart_spi_subdev and at91_usart_serial_subdev They are never get changed, make them constant. While at it, fix indent as well. Signed-off-by: Axel Lin Signed-off-by: Lee Jones --- drivers/mfd/at91-usart.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers/mfd') diff --git a/drivers/mfd/at91-usart.c b/drivers/mfd/at91-usart.c index d20747f612c1..684d3a8db661 100644 --- a/drivers/mfd/at91-usart.c +++ b/drivers/mfd/at91-usart.c @@ -15,15 +15,15 @@ #include #include -static struct mfd_cell at91_usart_spi_subdev = { - .name = "at91_usart_spi", - .of_compatible = "microchip,at91sam9g45-usart-spi", - }; +static const struct mfd_cell at91_usart_spi_subdev = { + .name = "at91_usart_spi", + .of_compatible = "microchip,at91sam9g45-usart-spi", +}; -static struct mfd_cell at91_usart_serial_subdev = { - .name = "atmel_usart_serial", - .of_compatible = "atmel,at91rm9200-usart-serial", - }; +static const struct mfd_cell at91_usart_serial_subdev = { + .name = "atmel_usart_serial", + .of_compatible = "atmel,at91rm9200-usart-serial", +}; static int at91_usart_mode_probe(struct platform_device *pdev) { -- cgit v1.2.1 From c0056bfe48ab8dfe383c56bc75d1f03260dc9b2a Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 31 Jan 2019 12:32:13 +0800 Subject: mfd: at91-usart: No need to copy mfd_cell in probe Use pointer instead. Signed-off-by: Axel Lin Signed-off-by: Lee Jones --- drivers/mfd/at91-usart.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/mfd') diff --git a/drivers/mfd/at91-usart.c b/drivers/mfd/at91-usart.c index 684d3a8db661..6a8351a4588e 100644 --- a/drivers/mfd/at91-usart.c +++ b/drivers/mfd/at91-usart.c @@ -27,17 +27,17 @@ static const struct mfd_cell at91_usart_serial_subdev = { static int at91_usart_mode_probe(struct platform_device *pdev) { - struct mfd_cell cell; + const struct mfd_cell *cell; u32 opmode = AT91_USART_MODE_SERIAL; device_property_read_u32(&pdev->dev, "atmel,usart-mode", &opmode); switch (opmode) { case AT91_USART_MODE_SPI: - cell = at91_usart_spi_subdev; + cell = &at91_usart_spi_subdev; break; case AT91_USART_MODE_SERIAL: - cell = at91_usart_serial_subdev; + cell = &at91_usart_serial_subdev; break; default: dev_err(&pdev->dev, "atmel,usart-mode has an invalid value %u\n", @@ -45,7 +45,7 @@ static int at91_usart_mode_probe(struct platform_device *pdev) return -EINVAL; } - return devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_AUTO, &cell, 1, + return devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_AUTO, cell, 1, NULL, 0, NULL); } -- cgit v1.2.1 From 66265e719b4603ef9a1b8a6c876bcb542c021496 Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Wed, 6 Feb 2019 14:11:07 -0500 Subject: mfd: tps68470: Drop unused MODULE_DEVICE_TABLE The Kconfig currently controlling compilation of this code is: drivers/mfd/Kconfig:config MFD_TPS68470 drivers/mfd/Kconfig: bool "TI TPS68470 Power Management / LED chips" ...meaning that it currently is not being built as a module by anyone. Hence we remove the MODULE_DEVICE_TABLE since it is a no-op for non-modular code. There is no removal of here because there isn't one. Instead, it is relying on including that implicitly from an ACPI header. In cleaning up the ACPI instance of module.h (which also isn't strictly needed), then this mfd driver breaks when MODULE_DEVICE_TABLE becomes undefined here. The easiest dependency solution is to simply defer the ACPI cleanup until this change is present in mainline. Signed-off-by: Paul Gortmaker Signed-off-by: Lee Jones --- drivers/mfd/tps68470.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/mfd') diff --git a/drivers/mfd/tps68470.c b/drivers/mfd/tps68470.c index a5981a79b29a..4a4df4ffd18c 100644 --- a/drivers/mfd/tps68470.c +++ b/drivers/mfd/tps68470.c @@ -86,7 +86,6 @@ static const struct acpi_device_id tps68470_acpi_ids[] = { {"INT3472"}, {}, }; -MODULE_DEVICE_TABLE(acpi, tps68470_acpi_ids); static struct i2c_driver tps68470_driver = { .driver = { -- cgit v1.2.1 From c1778e5819a9784b5551cf8f7abd66571c1239e2 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Wed, 6 Feb 2019 18:39:59 +0100 Subject: mfd: cros_ec_dev: Return number of bytes read with CROS_EC_DEV_IOCRDMEM While ioctls normally return a negative error or 0 on success, this is not the case for CROS_EC_DEV_IOCXCMD in the cros_ec driver, which returns the number of bytes read instead. However, CROS_EC_DEV_IOCRDMEM in the same driver does not return the number of byte read on success. This is both inconsistent and problematic, since the amount of returned data can be dynamic. Have it return the number of data bytes for consistency. Signed-off-by: Guenter Roeck Signed-off-by: Enric Balletbo i Serra Reviewed-by: Benson Leung Signed-off-by: Lee Jones --- drivers/mfd/cros_ec_dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/mfd') diff --git a/drivers/mfd/cros_ec_dev.c b/drivers/mfd/cros_ec_dev.c index ed809fc97df8..d275deaecb12 100644 --- a/drivers/mfd/cros_ec_dev.c +++ b/drivers/mfd/cros_ec_dev.c @@ -224,7 +224,7 @@ static long ec_device_ioctl_readmem(struct cros_ec_dev *ec, void __user *arg) if (copy_to_user((void __user *)arg, &s_mem, sizeof(s_mem))) return -EFAULT; - return 0; + return num; } static long ec_device_ioctl(struct file *filp, unsigned int cmd, -- cgit v1.2.1 From 16b7a09bb6fdf5d83bd22fd930c7e3c1e4f32911 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Thu, 24 Jan 2019 20:03:28 +0200 Subject: mfd: intel-lpss: Move linux/pm.h to the local header We now using a common macro for PM operations in Intel LPSS driver, and, since that macro relies on the definition and macro from linux/pm.h header file, it's logical to include it directly in intel-lpss.h. Otherwise it's a bit fragile and requires a proper ordering of header inclusion in C files. Signed-off-by: Andy Shevchenko Acked-by: Mika Westerberg Signed-off-by: Lee Jones --- drivers/mfd/intel-lpss-acpi.c | 1 - drivers/mfd/intel-lpss-pci.c | 1 - drivers/mfd/intel-lpss.h | 2 ++ 3 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/mfd') diff --git a/drivers/mfd/intel-lpss-acpi.c b/drivers/mfd/intel-lpss-acpi.c index 7911b0a14a6d..6d9f03363ee7 100644 --- a/drivers/mfd/intel-lpss-acpi.c +++ b/drivers/mfd/intel-lpss-acpi.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/mfd/intel-lpss-pci.c b/drivers/mfd/intel-lpss-pci.c index 0e5282fc1467..cba2eb166650 100644 --- a/drivers/mfd/intel-lpss-pci.c +++ b/drivers/mfd/intel-lpss-pci.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include diff --git a/drivers/mfd/intel-lpss.h b/drivers/mfd/intel-lpss.h index 865bbeaaf00c..3a120fecd2dc 100644 --- a/drivers/mfd/intel-lpss.h +++ b/drivers/mfd/intel-lpss.h @@ -14,6 +14,8 @@ #ifndef __MFD_INTEL_LPSS_H #define __MFD_INTEL_LPSS_H +#include + struct device; struct resource; struct property_entry; -- cgit v1.2.1 From 2f17dd34ffed09823d6598903276b867bb238f95 Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Sat, 9 Feb 2019 00:06:22 +0100 Subject: mfd: tqmx86: IO controller with I2C, Wachdog and GPIO The QMX86 is a PLD present on some TQ-Systems ComExpress modules. It provides 1 or 2 I2C bus masters, 8 GPIOs and a watchdog timer. Add an MFD which will instantiate the individual drivers. Signed-off-by: Andrew Lunn Signed-off-by: Lee Jones --- drivers/mfd/Kconfig | 8 ++ drivers/mfd/Makefile | 1 + drivers/mfd/tqmx86.c | 281 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 290 insertions(+) create mode 100644 drivers/mfd/tqmx86.c (limited to 'drivers/mfd') diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index f38f8741c68e..18ee80389237 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -1677,6 +1677,14 @@ config MFD_TC6393XB help Support for Toshiba Mobile IO Controller TC6393XB +config MFD_TQMX86 + tristate "TQ-Systems IO controller TQMX86" + select MFD_CORE + help + Say yes here to enable support for various functions of the + TQ-Systems IO controller and watchdog device, found on their + ComExpress CPU modules. + config MFD_VX855 tristate "VIA VX855/VX875 integrated south bridge" depends on PCI diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index a406fd3b8681..61a078a2b8f5 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -36,6 +36,7 @@ obj-$(CONFIG_MFD_TC3589X) += tc3589x.o obj-$(CONFIG_MFD_T7L66XB) += t7l66xb.o tmio_core.o obj-$(CONFIG_MFD_TC6387XB) += tc6387xb.o tmio_core.o obj-$(CONFIG_MFD_TC6393XB) += tc6393xb.o tmio_core.o +obj-$(CONFIG_MFD_TQMX86) += tqmx86.o obj-$(CONFIG_MFD_LOCHNAGAR) += lochnagar-i2c.o diff --git a/drivers/mfd/tqmx86.c b/drivers/mfd/tqmx86.c new file mode 100644 index 000000000000..22d2f02d855c --- /dev/null +++ b/drivers/mfd/tqmx86.c @@ -0,0 +1,281 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * TQ-Systems PLD MFD core driver, based on vendor driver by + * Vadim V.Vlasov + * + * Copyright (c) 2015 TQ-Systems GmbH + * Copyright (c) 2019 Andrew Lunn + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define TQMX86_IOBASE 0x160 +#define TQMX86_IOSIZE 0x3f +#define TQMX86_IOBASE_I2C 0x1a0 +#define TQMX86_IOSIZE_I2C 0xa +#define TQMX86_IOBASE_WATCHDOG 0x18b +#define TQMX86_IOSIZE_WATCHDOG 0x2 +#define TQMX86_IOBASE_GPIO 0x18d +#define TQMX86_IOSIZE_GPIO 0x4 + +#define TQMX86_REG_BOARD_ID 0x20 +#define TQMX86_REG_BOARD_ID_E38M 1 +#define TQMX86_REG_BOARD_ID_50UC 2 +#define TQMX86_REG_BOARD_ID_E38C 3 +#define TQMX86_REG_BOARD_ID_60EB 4 +#define TQMX86_REG_BOARD_ID_E39M 5 +#define TQMX86_REG_BOARD_ID_E39C 6 +#define TQMX86_REG_BOARD_ID_E39x 7 +#define TQMX86_REG_BOARD_ID_70EB 8 +#define TQMX86_REG_BOARD_ID_80UC 9 +#define TQMX86_REG_BOARD_ID_90UC 10 +#define TQMX86_REG_BOARD_REV 0x21 +#define TQMX86_REG_IO_EXT_INT 0x26 +#define TQMX86_REG_IO_EXT_INT_NONE 0 +#define TQMX86_REG_IO_EXT_INT_7 1 +#define TQMX86_REG_IO_EXT_INT_9 2 +#define TQMX86_REG_IO_EXT_INT_12 3 +#define TQMX86_REG_IO_EXT_INT_MASK 0x3 +#define TQMX86_REG_IO_EXT_INT_GPIO_SHIFT 4 + +#define TQMX86_REG_I2C_DETECT 0x47 +#define TQMX86_REG_I2C_DETECT_SOFT 0xa5 +#define TQMX86_REG_I2C_INT_EN 0x49 + +static uint gpio_irq; +module_param(gpio_irq, uint, 0); +MODULE_PARM_DESC(gpio_irq, "GPIO IRQ number (7, 9, 12)"); + +static const struct resource tqmx_i2c_soft_resources[] = { + DEFINE_RES_IO(TQMX86_IOBASE_I2C, TQMX86_IOSIZE_I2C), +}; + +static const struct resource tqmx_watchdog_resources[] = { + DEFINE_RES_IO(TQMX86_IOBASE_WATCHDOG, TQMX86_IOSIZE_WATCHDOG), +}; + +/* + * The IRQ resource must be first, since it is updated with the + * configured IRQ in the probe function. + */ +static struct resource tqmx_gpio_resources[] = { + DEFINE_RES_IRQ(0), + DEFINE_RES_IO(TQMX86_IOBASE_GPIO, TQMX86_IOSIZE_GPIO), +}; + +static struct i2c_board_info tqmx86_i2c_devices[] = { + { + /* 4K EEPROM at 0x50 */ + I2C_BOARD_INFO("24c32", 0x50), + }, +}; + +static struct ocores_i2c_platform_data ocores_platfom_data = { + .num_devices = ARRAY_SIZE(tqmx86_i2c_devices), + .devices = tqmx86_i2c_devices, +}; + +static const struct mfd_cell tqmx86_i2c_soft_dev[] = { + { + .name = "ocores-i2c", + .platform_data = &ocores_platfom_data, + .pdata_size = sizeof(ocores_platfom_data), + .resources = tqmx_i2c_soft_resources, + .num_resources = ARRAY_SIZE(tqmx_i2c_soft_resources), + }, +}; + +static const struct mfd_cell tqmx86_devs[] = { + { + .name = "tqmx86-wdt", + .resources = tqmx_watchdog_resources, + .num_resources = ARRAY_SIZE(tqmx_watchdog_resources), + .ignore_resource_conflicts = true, + }, + { + .name = "tqmx86-gpio", + .resources = tqmx_gpio_resources, + .num_resources = ARRAY_SIZE(tqmx_gpio_resources), + .ignore_resource_conflicts = true, + }, +}; + +static const char *tqmx86_board_id_to_name(u8 board_id) +{ + switch (board_id) { + case TQMX86_REG_BOARD_ID_E38M: + return "TQMxE38M"; + case TQMX86_REG_BOARD_ID_50UC: + return "TQMx50UC"; + case TQMX86_REG_BOARD_ID_E38C: + return "TQMxE38C"; + case TQMX86_REG_BOARD_ID_60EB: + return "TQMx60EB"; + case TQMX86_REG_BOARD_ID_E39M: + return "TQMxE39M"; + case TQMX86_REG_BOARD_ID_E39C: + return "TQMxE39C"; + case TQMX86_REG_BOARD_ID_E39x: + return "TQMxE39x"; + case TQMX86_REG_BOARD_ID_70EB: + return "TQMx70EB"; + case TQMX86_REG_BOARD_ID_80UC: + return "TQMx80UC"; + case TQMX86_REG_BOARD_ID_90UC: + return "TQMx90UC"; + default: + return "Unknown"; + } +} + +static int tqmx86_board_id_to_clk_rate(u8 board_id) +{ + switch (board_id) { + case TQMX86_REG_BOARD_ID_50UC: + case TQMX86_REG_BOARD_ID_60EB: + case TQMX86_REG_BOARD_ID_70EB: + case TQMX86_REG_BOARD_ID_80UC: + case TQMX86_REG_BOARD_ID_90UC: + return 24000; + case TQMX86_REG_BOARD_ID_E39M: + case TQMX86_REG_BOARD_ID_E39C: + case TQMX86_REG_BOARD_ID_E39x: + return 25000; + case TQMX86_REG_BOARD_ID_E38M: + case TQMX86_REG_BOARD_ID_E38C: + return 33000; + default: + return 0; + } +} + +static int tqmx86_probe(struct platform_device *pdev) +{ + u8 board_id, rev, i2c_det, i2c_ien, io_ext_int_val; + struct device *dev = &pdev->dev; + u8 gpio_irq_cfg, readback; + const char *board_name; + void __iomem *io_base; + int err; + + switch (gpio_irq) { + case 0: + gpio_irq_cfg = TQMX86_REG_IO_EXT_INT_NONE; + break; + case 7: + gpio_irq_cfg = TQMX86_REG_IO_EXT_INT_7; + break; + case 9: + gpio_irq_cfg = TQMX86_REG_IO_EXT_INT_9; + break; + case 12: + gpio_irq_cfg = TQMX86_REG_IO_EXT_INT_12; + break; + default: + pr_err("tqmx86: Invalid GPIO IRQ (%d)\n", gpio_irq); + return -EINVAL; + } + + io_base = devm_ioport_map(dev, TQMX86_IOBASE, TQMX86_IOSIZE); + if (!io_base) + return -ENOMEM; + + board_id = ioread8(io_base + TQMX86_REG_BOARD_ID); + board_name = tqmx86_board_id_to_name(board_id); + rev = ioread8(io_base + TQMX86_REG_BOARD_REV); + + dev_info(dev, + "Found %s - Board ID %d, PCB Revision %d, PLD Revision %d\n", + board_name, board_id, rev >> 4, rev & 0xf); + + i2c_det = ioread8(io_base + TQMX86_REG_I2C_DETECT); + i2c_ien = ioread8(io_base + TQMX86_REG_I2C_INT_EN); + + if (gpio_irq_cfg) { + io_ext_int_val = + gpio_irq_cfg << TQMX86_REG_IO_EXT_INT_GPIO_SHIFT; + iowrite8(io_ext_int_val, io_base + TQMX86_REG_IO_EXT_INT); + readback = ioread8(io_base + TQMX86_REG_IO_EXT_INT); + if (readback != io_ext_int_val) { + dev_warn(dev, "GPIO interrupts not supported.\n"); + return -EINVAL; + } + + /* Assumes the IRQ resource is first. */ + tqmx_gpio_resources[0].start = gpio_irq; + } + + ocores_platfom_data.clock_khz = tqmx86_board_id_to_clk_rate(board_id); + + if (i2c_det == TQMX86_REG_I2C_DETECT_SOFT) { + err = devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE, + tqmx86_i2c_soft_dev, + ARRAY_SIZE(tqmx86_i2c_soft_dev), + NULL, 0, NULL); + if (err) + return err; + } + + return devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE, + tqmx86_devs, + ARRAY_SIZE(tqmx86_devs), + NULL, 0, NULL); +} + +static int tqmx86_create_platform_device(const struct dmi_system_id *id) +{ + struct platform_device *pdev; + int err; + + pdev = platform_device_alloc("tqmx86", -1); + if (!pdev) + return -ENOMEM; + + err = platform_device_add(pdev); + if (err) + platform_device_put(pdev); + + return err; +} + +static const struct dmi_system_id tqmx86_dmi_table[] __initconst = { + { + .ident = "TQMX86", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "TQ-Group"), + DMI_MATCH(DMI_PRODUCT_NAME, "TQMx"), + }, + .callback = tqmx86_create_platform_device, + }, + {} +}; +MODULE_DEVICE_TABLE(dmi, tqmx86_dmi_table); + +static struct platform_driver tqmx86_driver = { + .driver = { + .name = "tqmx86", + }, + .probe = tqmx86_probe, +}; + +static int __init tqmx86_init(void) +{ + if (!dmi_check_system(tqmx86_dmi_table)) + return -ENODEV; + + return platform_driver_register(&tqmx86_driver); +} + +module_init(tqmx86_init); + +MODULE_DESCRIPTION("TQx86 PLD Core Driver"); +MODULE_AUTHOR("Andrew Lunn "); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:tqmx86"); -- cgit v1.2.1 From 4720eb47529e456410470e6e2bed38d5d36cbb8a Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Mon, 11 Feb 2019 14:20:23 +0100 Subject: mfd: sec-core: Cleanup formatting to a consistent style Cleanup the formatting to have consistent style across the file (only white-space issues). No expected difference in code. Signed-off-by: Krzysztof Kozlowski Signed-off-by: Lee Jones --- drivers/mfd/sec-core.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'drivers/mfd') diff --git a/drivers/mfd/sec-core.c b/drivers/mfd/sec-core.c index 00321011de0a..521319086c81 100644 --- a/drivers/mfd/sec-core.c +++ b/drivers/mfd/sec-core.c @@ -114,7 +114,8 @@ static const struct mfd_cell s2mpu02_devs[] = { #ifdef CONFIG_OF static const struct of_device_id sec_dt_match[] = { - { .compatible = "samsung,s5m8767-pmic", + { + .compatible = "samsung,s5m8767-pmic", .data = (void *)S5M8767X, }, { .compatible = "samsung,s2mps11-pmic", @@ -309,8 +310,8 @@ static void sec_pmic_configure(struct sec_pmic_dev *sec_pmic) * the sub-modules need not instantiate another instance while parsing their * platform data. */ -static struct sec_platform_data *sec_pmic_i2c_parse_dt_pdata( - struct device *dev) +static struct sec_platform_data * +sec_pmic_i2c_parse_dt_pdata(struct device *dev) { struct sec_platform_data *pd; @@ -331,8 +332,8 @@ static struct sec_platform_data *sec_pmic_i2c_parse_dt_pdata( return pd; } #else -static struct sec_platform_data *sec_pmic_i2c_parse_dt_pdata( - struct device *dev) +static struct sec_platform_data * +sec_pmic_i2c_parse_dt_pdata(struct device *dev) { return NULL; } -- cgit v1.2.1 From d2d833e0bf2bad221a955626b942b38312630894 Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Mon, 11 Feb 2019 16:48:27 -0600 Subject: mfd: mxs-lradc: Mark expected switch fall-through MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In preparation to enabling -Wimplicit-fallthrough, mark switch cases where we are expecting to fall through. This patch fixes the following warning: drivers/mfd/mxs-lradc.c: In function ‘mxs_lradc_probe’: drivers/mfd/mxs-lradc.c:179:7: warning: this statement may fall through [-Wimplicit-fallthrough=] if (lradc->soc == IMX28_LRADC) { ^ drivers/mfd/mxs-lradc.c:185:3: note: here default: ^~~~~~~ Warning level 3 was used: -Wimplicit-fallthrough=3 Notice that, in this particular case, the code comment is modified in accordance with what GCC is expecting to find. This patch is part of the ongoing efforts to enable -Wimplicit-fallthrough. Signed-off-by: Gustavo A. R. Silva Signed-off-by: Lee Jones --- drivers/mfd/mxs-lradc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/mfd') diff --git a/drivers/mfd/mxs-lradc.c b/drivers/mfd/mxs-lradc.c index 98e732a7ae96..a09a8d06302b 100644 --- a/drivers/mfd/mxs-lradc.c +++ b/drivers/mfd/mxs-lradc.c @@ -181,7 +181,7 @@ static int mxs_lradc_probe(struct platform_device *pdev) MXS_LRADC_TOUCHSCREEN_5WIRE; break; } - /* fall through to an error message for i.MX23 */ + /* fall through - to an error message for i.MX23 */ default: dev_err(&pdev->dev, "Unsupported number of touchscreen wires (%d)\n" -- cgit v1.2.1