From 3abee4579484c554961bb0af92a77adc0ebd791d Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Mon, 14 Sep 2020 23:43:29 +0200 Subject: mfd: Add simple regmap based I2C driver There are I2C devices which contain several different functions but doesn't require any special access functions. For these kind of drivers an I2C regmap should be enough. Create an I2C driver which creates an I2C regmap and enumerates its children. If a device wants to use this as its MFD core driver, it has to add an individual compatible string. It may provide its own regmap configuration. Subdevices can use dev_get_regmap() on the parent to get their regmap instance. Signed-off-by: Michael Walle Signed-off-by: Lee Jones --- drivers/mfd/Kconfig | 12 ++++++++++ drivers/mfd/Makefile | 1 + drivers/mfd/simple-mfd-i2c.c | 56 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 69 insertions(+) create mode 100644 drivers/mfd/simple-mfd-i2c.c (limited to 'drivers/mfd') diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 33df0837ab41..6e1a38944d28 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -1162,6 +1162,18 @@ config MFD_SI476X_CORE To compile this driver as a module, choose M here: the module will be called si476x-core. +config MFD_SIMPLE_MFD_I2C + tristate + depends on I2C + select REGMAP_I2C + help + This driver creates a single register map with the intention for it + to be shared by all sub-devices. + + Once the register map has been successfully initialised, any + sub-devices represented by child nodes in Device Tree will be + subsequently registered. + config MFD_SM501 tristate "Silicon Motion SM501" depends on HAS_DMA diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index a60e5f835283..78d24a3e7c9e 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -264,3 +264,4 @@ obj-$(CONFIG_MFD_STMFX) += stmfx.o obj-$(CONFIG_MFD_KHADAS_MCU) += khadas-mcu.o obj-$(CONFIG_SGI_MFD_IOC3) += ioc3.o +obj-$(CONFIG_MFD_SIMPLE_MFD_I2C) += simple-mfd-i2c.o diff --git a/drivers/mfd/simple-mfd-i2c.c b/drivers/mfd/simple-mfd-i2c.c new file mode 100644 index 000000000000..28e96a246be1 --- /dev/null +++ b/drivers/mfd/simple-mfd-i2c.c @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Simple MFD - I2C + * + * This driver creates a single register map with the intention for it to be + * shared by all sub-devices. Children can use their parent's device structure + * (dev.parent) in order to reference it. + * + * Once the register map has been successfully initialised, any sub-devices + * represented by child nodes in Device Tree will be subsequently registered. + */ + +#include +#include +#include +#include +#include + +static const struct regmap_config simple_regmap_config = { + .reg_bits = 8, + .val_bits = 8, +}; + +static int simple_mfd_i2c_probe(struct i2c_client *i2c) +{ + const struct regmap_config *config; + struct regmap *regmap; + + config = device_get_match_data(&i2c->dev); + if (!config) + config = &simple_regmap_config; + + regmap = devm_regmap_init_i2c(i2c, config); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + return devm_of_platform_populate(&i2c->dev); +} + +static const struct of_device_id simple_mfd_i2c_of_match[] = { + {} +}; +MODULE_DEVICE_TABLE(of, simple_mfd_i2c_of_match); + +static struct i2c_driver simple_mfd_i2c_driver = { + .probe_new = simple_mfd_i2c_probe, + .driver = { + .name = "simple-mfd-i2c", + .of_match_table = simple_mfd_i2c_of_match, + }, +}; +module_i2c_driver(simple_mfd_i2c_driver); + +MODULE_AUTHOR("Michael Walle "); +MODULE_DESCRIPTION("Simple MFD - I2C driver"); +MODULE_LICENSE("GPL v2"); -- cgit v1.2.3 From a538ad229bbee4f8c68204c75b2e1ae43db875d6 Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Mon, 14 Sep 2020 23:43:31 +0200 Subject: mfd: simple-mfd-i2c: Add sl28cpld support Add the core support for the board management controller found on the SMARC-sAL28 board. Also add a virtual symbol which pulls in the simple-mfd-i2c driver and provide a common symbol on which the subdevice drivers can depend on. At the moment, this controller is used on the Kontron SMARC-sAL28 board. Signed-off-by: Michael Walle Signed-off-by: Lee Jones --- drivers/mfd/Kconfig | 10 ++++++++++ drivers/mfd/simple-mfd-i2c.c | 1 + 2 files changed, 11 insertions(+) (limited to 'drivers/mfd') diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 6e1a38944d28..ed90eb5bdc83 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -1174,6 +1174,16 @@ config MFD_SIMPLE_MFD_I2C sub-devices represented by child nodes in Device Tree will be subsequently registered. +config MFD_SL28CPLD + tristate "Kontron sl28cpld Board Management Controller" + select MFD_SIMPLE_MFD_I2C + help + Say yes here to enable support for the Kontron sl28cpld board + management controller. + + It can be found on the following boards: + * SMARC-sAL28 + config MFD_SM501 tristate "Silicon Motion SM501" depends on HAS_DMA diff --git a/drivers/mfd/simple-mfd-i2c.c b/drivers/mfd/simple-mfd-i2c.c index 28e96a246be1..87f684cff9a1 100644 --- a/drivers/mfd/simple-mfd-i2c.c +++ b/drivers/mfd/simple-mfd-i2c.c @@ -38,6 +38,7 @@ static int simple_mfd_i2c_probe(struct i2c_client *i2c) } static const struct of_device_id simple_mfd_i2c_of_match[] = { + { .compatible = "kontron,sl28cpld" }, {} }; MODULE_DEVICE_TABLE(of, simple_mfd_i2c_of_match); -- cgit v1.2.3 From 31c53962d65fb813eded2332b0fff60ffaaf2368 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 12 Aug 2020 14:29:03 +0200 Subject: mfd: Kconfig: Fix typo of 'individual' individul -> individual Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Lee Jones --- drivers/mfd/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/mfd') diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index ed90eb5bdc83..4b918fdcc7c7 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -493,7 +493,7 @@ config MFD_HI6421_PMIC Add support for HiSilicon Hi6421 PMIC. Hi6421 includes multi- functions, such as regulators, RTC, codec, Coulomb counter, etc. This driver includes core APIs _only_. You have to select - individul components like voltage regulators under corresponding + individual components like voltage regulators under corresponding menus in order to enable them. We communicate with the Hi6421 via memory-mapped I/O. -- cgit v1.2.3 From d1264a075ed65d6b174a4742e69186125e66fd27 Mon Sep 17 00:00:00 2001 From: Andreas Kemnade Date: Sat, 15 Aug 2020 18:56:10 +0200 Subject: mfd: rn5t618: Add a power supply subdevice The RN5T618 and RC5T619 both have a charger and a fuel gauge, so add a subdevice for it. According to drivers in the wild, things should be at least similar, but since it is not tested, add it only to the RC5T619. Signed-off-by: Andreas Kemnade Signed-off-by: Lee Jones --- drivers/mfd/rn5t618.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/mfd') diff --git a/drivers/mfd/rn5t618.c b/drivers/mfd/rn5t618.c index e25407ed3ad4..dc452df1f1bf 100644 --- a/drivers/mfd/rn5t618.c +++ b/drivers/mfd/rn5t618.c @@ -25,6 +25,7 @@ static const struct mfd_cell rn5t618_cells[] = { static const struct mfd_cell rc5t619_cells[] = { { .name = "rn5t618-adc" }, + { .name = "rn5t618-power" }, { .name = "rn5t618-regulator" }, { .name = "rc5t619-rtc" }, { .name = "rn5t618-wdt" }, -- cgit v1.2.3 From e26ea09b6e0995cb65760e44042e26d3e40452a7 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 28 Aug 2020 09:37:04 +0100 Subject: mfd: khadas-mcu: Fix randconfig 'unused-const-variable' warning When testing with !OF, the build system reports: >> drivers/mfd/khadas-mcu.c:125:34: warning: unused variable 'khadas_mcu_of_match' [-Wunused-const-variable] static const struct of_device_id khadas_mcu_of_match[] = { ^ Reported-by: kernel test robot Acked-by: Neil Armstrong Signed-off-by: Lee Jones --- drivers/mfd/khadas-mcu.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/mfd') diff --git a/drivers/mfd/khadas-mcu.c b/drivers/mfd/khadas-mcu.c index 44d5bb462dab..f3d418810693 100644 --- a/drivers/mfd/khadas-mcu.c +++ b/drivers/mfd/khadas-mcu.c @@ -122,11 +122,13 @@ static int khadas_mcu_probe(struct i2c_client *client, return 0; } +#ifdef CONFIG_OF static const struct of_device_id khadas_mcu_of_match[] = { { .compatible = "khadas,mcu", }, {}, }; MODULE_DEVICE_TABLE(of, khadas_mcu_of_match); +#endif static struct i2c_driver khadas_mcu_driver = { .driver = { -- cgit v1.2.3 From ede6b2d1dfc0d6a7b0b3161a2e911d464e28e0ad Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Fri, 10 Jul 2020 01:12:28 +0200 Subject: mfd: ene-kb3930: Add driver for ENE KB3930 Embedded Controller This driver provides access to the EC RAM of said embedded controller attached to the I2C bus as well as optionally supporting its slightly weird power-off/restart protocol. A particular implementation of the EC firmware can be identified by a model byte. If this driver identifies the Dell Ariel platform, it registers the appropriate cells. Signed-off-by: Lubomir Rintel Signed-off-by: Lee Jones --- drivers/mfd/Kconfig | 11 +++ drivers/mfd/Makefile | 1 + drivers/mfd/ene-kb3930.c | 212 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 224 insertions(+) create mode 100644 drivers/mfd/ene-kb3930.c (limited to 'drivers/mfd') diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 4b918fdcc7c7..e1d3bf77b245 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -398,6 +398,17 @@ config MFD_DLN2 etc. must be enabled in order to use the functionality of the device. +config MFD_ENE_KB3930 + tristate "ENE KB3930 Embedded Controller support" + depends on I2C + depends on MACH_MMP3_DT || COMPILE_TEST + select MFD_CORE + help + This adds support for the power-off functionality and access to + the registers that control LEDS and USB port power on ENE KB3930 + Embedded Controller. To use the LED functionality LEDS_ARIEL must + be enabled. + config MFD_EXYNOS_LPASS tristate "Samsung Exynos SoC Low Power Audio Subsystem" depends on ARCH_EXYNOS || COMPILE_TEST diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index 78d24a3e7c9e..e6c7520ed129 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -14,6 +14,7 @@ obj-$(CONFIG_ARCH_BCM2835) += bcm2835-pm.o obj-$(CONFIG_MFD_BCM590XX) += bcm590xx.o obj-$(CONFIG_MFD_BD9571MWV) += bd9571mwv.o obj-$(CONFIG_MFD_CROS_EC_DEV) += cros_ec_dev.o +obj-$(CONFIG_MFD_ENE_KB3930) += ene-kb3930.o obj-$(CONFIG_MFD_EXYNOS_LPASS) += exynos-lpass.o obj-$(CONFIG_MFD_GATEWORKS_GSC) += gateworks-gsc.o diff --git a/drivers/mfd/ene-kb3930.c b/drivers/mfd/ene-kb3930.c new file mode 100644 index 000000000000..1c32ff586816 --- /dev/null +++ b/drivers/mfd/ene-kb3930.c @@ -0,0 +1,212 @@ +// SPDX-License-Identifier: BSD-2-Clause OR GPL-2.0-or-later +/* + * ENE KB3930 Embedded Controller Driver + * + * Copyright (C) 2020 Lubomir Rintel + */ + +#include +#include +#include +#include +#include +#include +#include + +/* I2C registers that are multiplexing access to the EC RAM. */ +enum { + EC_DATA_IN = 0x00, + EC_RAM_OUT = 0x80, + EC_RAM_IN = 0x81, +}; + +/* EC RAM registers. */ +enum { + EC_MODEL = 0x30, + EC_VERSION_MAJ = 0x31, + EC_VERSION_MIN = 0x32, +}; + +struct kb3930 { + struct i2c_client *client; + struct regmap *ram_regmap; + struct gpio_descs *off_gpios; +}; + +struct kb3930 *kb3930_power_off; + +#define EC_GPIO_WAVE 0 +#define EC_GPIO_OFF_MODE 1 + +#define EC_OFF_MODE_REBOOT 0 +#define EC_OFF_MODE_POWER 1 + +static void kb3930_off(struct kb3930 *ddata, int off_mode) +{ + gpiod_direction_output(ddata->off_gpios->desc[EC_GPIO_OFF_MODE], + off_mode); + + /* + * This creates a 10 Hz wave on EC_GPIO_WAVE that signals a + * shutdown request to the EC. Once the EC detects it, it will + * proceed to turn the power off or reset the board depending on + * the value of EC_GPIO_OFF_MODE. + */ + while (1) { + mdelay(50); + gpiod_direction_output(ddata->off_gpios->desc[EC_GPIO_WAVE], 0); + mdelay(50); + gpiod_direction_output(ddata->off_gpios->desc[EC_GPIO_WAVE], 1); + } +} + +static int kb3930_restart(struct notifier_block *this, + unsigned long mode, void *cmd) +{ + kb3930_off(kb3930_power_off, EC_OFF_MODE_REBOOT); + return NOTIFY_DONE; +} + +static void kb3930_pm_power_off(void) +{ + kb3930_off(kb3930_power_off, EC_OFF_MODE_POWER); +} + +static struct notifier_block kb3930_restart_nb = { + .notifier_call = kb3930_restart, +}; + +static const struct mfd_cell ariel_ec_cells[] = { + { .name = "dell-wyse-ariel-led", }, + { .name = "dell-wyse-ariel-power", }, +}; + +static int kb3930_ec_ram_reg_write(void *context, unsigned int reg, + unsigned int val) +{ + struct kb3930 *ddata = context; + + return i2c_smbus_write_word_data(ddata->client, EC_RAM_OUT, + (val << 8) | reg); +} + +static int kb3930_ec_ram_reg_read(void *context, unsigned int reg, + unsigned int *val) +{ + struct kb3930 *ddata = context; + int ret; + + ret = i2c_smbus_write_word_data(ddata->client, EC_RAM_IN, reg); + if (ret < 0) + return ret; + + ret = i2c_smbus_read_word_data(ddata->client, EC_DATA_IN); + if (ret < 0) + return ret; + + *val = ret >> 8; + return 0; +} + +static const struct regmap_config kb3930_ram_regmap_config = { + .name = "ec_ram", + .reg_bits = 8, + .val_bits = 8, + .reg_stride = 1, + .max_register = 0xff, + .reg_write = kb3930_ec_ram_reg_write, + .reg_read = kb3930_ec_ram_reg_read, + .fast_io = false, +}; + +static int kb3930_probe(struct i2c_client *client) +{ + struct device *dev = &client->dev; + struct device_node *np = dev->of_node; + struct kb3930 *ddata; + unsigned int model; + int ret; + + ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL); + if (!ddata) + return -ENOMEM; + + kb3930_power_off = ddata; + ddata->client = client; + i2c_set_clientdata(client, ddata); + + ddata->ram_regmap = devm_regmap_init(dev, NULL, ddata, + &kb3930_ram_regmap_config); + if (IS_ERR(ddata->ram_regmap)) + return PTR_ERR(ddata->ram_regmap); + + ret = regmap_read(ddata->ram_regmap, EC_MODEL, &model); + if (ret < 0) + return ret; + + /* Currently we only support the cells present on Dell Ariel model. */ + if (model != 'J') { + dev_err(dev, "unknown board model: %02x\n", model); + return -ENODEV; + } + + ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_AUTO, + ariel_ec_cells, + ARRAY_SIZE(ariel_ec_cells), + NULL, 0, NULL); + if (ret) + return ret; + + if (of_property_read_bool(np, "system-power-controller")) { + ddata->off_gpios = + devm_gpiod_get_array_optional(dev, "off", GPIOD_IN); + if (IS_ERR(ddata->off_gpios)) + return PTR_ERR(ddata->off_gpios); + if (ddata->off_gpios->ndescs < 2) { + dev_err(dev, "invalid off-gpios property\n"); + return -EINVAL; + } + } + + if (ddata->off_gpios) { + register_restart_handler(&kb3930_restart_nb); + if (!pm_power_off) + pm_power_off = kb3930_pm_power_off; + } + + return 0; +} + +static int kb3930_remove(struct i2c_client *client) +{ + struct kb3930 *ddata = i2c_get_clientdata(client); + + if (ddata->off_gpios) { + if (pm_power_off == kb3930_pm_power_off) + pm_power_off = NULL; + unregister_restart_handler(&kb3930_restart_nb); + } + kb3930_power_off = NULL; + + return 0; +} + +static const struct of_device_id kb3930_dt_ids[] = { + { .compatible = "ene,kb3930" }, + { } +}; +MODULE_DEVICE_TABLE(of, kb3930_dt_ids); + +static struct i2c_driver kb3930_driver = { + .probe_new = kb3930_probe, + .remove = kb3930_remove, + .driver = { + .name = "ene-kb3930", + .of_match_table = of_match_ptr(kb3930_dt_ids), + }, +}; +module_i2c_driver(kb3930_driver); + +MODULE_AUTHOR("Lubomir Rintel "); +MODULE_DESCRIPTION("ENE KB3930 Embedded Controller Driver"); +MODULE_LICENSE("Dual BSD/GPL"); -- cgit v1.2.3 From f104563fe08047b18cd3c96b41de0bc9c16739c7 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Wed, 26 Aug 2020 16:49:33 +0200 Subject: mfd: madera: Simplify with dev_err_probe() Common pattern of handling deferred probe can be simplified with dev_err_probe(). Less code and also it prints the error value. Signed-off-by: Krzysztof Kozlowski Acked-by: Charles Keepax Signed-off-by: Lee Jones --- drivers/mfd/madera-core.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) (limited to 'drivers/mfd') diff --git a/drivers/mfd/madera-core.c b/drivers/mfd/madera-core.c index 8a8d733fdce5..4ed6ad8ce002 100644 --- a/drivers/mfd/madera-core.c +++ b/drivers/mfd/madera-core.c @@ -369,19 +369,14 @@ EXPORT_SYMBOL_GPL(madera_of_match); static int madera_get_reset_gpio(struct madera *madera) { struct gpio_desc *reset; - int ret; if (madera->pdata.reset) return 0; reset = devm_gpiod_get_optional(madera->dev, "reset", GPIOD_OUT_LOW); - if (IS_ERR(reset)) { - ret = PTR_ERR(reset); - if (ret != -EPROBE_DEFER) - dev_err(madera->dev, "Failed to request /RESET: %d\n", - ret); - return ret; - } + if (IS_ERR(reset)) + return dev_err_probe(madera->dev, PTR_ERR(reset), + "Failed to request /RESET"); /* * A hard reset is needed for full reset of the chip. We allow running -- cgit v1.2.3 From 41c9c06c491a92e186e41ff64163fa74f08e15e6 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Wed, 26 Aug 2020 16:49:34 +0200 Subject: mfd: stmfx: Simplify with dev_err_probe() Common pattern of handling deferred probe can be simplified with dev_err_probe(). Less code and also it prints the error value. Signed-off-by: Krzysztof Kozlowski Signed-off-by: Lee Jones --- drivers/mfd/stmfx.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'drivers/mfd') diff --git a/drivers/mfd/stmfx.c b/drivers/mfd/stmfx.c index 711979afd90a..5e680bfdf5c9 100644 --- a/drivers/mfd/stmfx.c +++ b/drivers/mfd/stmfx.c @@ -331,11 +331,9 @@ static int stmfx_chip_init(struct i2c_client *client) ret = PTR_ERR_OR_ZERO(stmfx->vdd); if (ret == -ENODEV) { stmfx->vdd = NULL; - } else if (ret == -EPROBE_DEFER) { - return ret; - } else if (ret) { - dev_err(&client->dev, "Failed to get VDD regulator: %d\n", ret); - return ret; + } else { + return dev_err_probe(&client->dev, ret, + "Failed to get VDD regulator\n"); } if (stmfx->vdd) { -- cgit v1.2.3 From 0f1b1b899521e3380a01f9f88a1bcb6163b7ee9f Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Wed, 26 Aug 2020 16:49:35 +0200 Subject: mfd: wcd934x: Simplify with dev_err_probe() Common pattern of handling deferred probe can be simplified with dev_err_probe(). Less code and also it prints the error value. Signed-off-by: Krzysztof Kozlowski Signed-off-by: Lee Jones --- drivers/mfd/wcd934x.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'drivers/mfd') diff --git a/drivers/mfd/wcd934x.c b/drivers/mfd/wcd934x.c index da910302d51a..c274d733b656 100644 --- a/drivers/mfd/wcd934x.c +++ b/drivers/mfd/wcd934x.c @@ -219,12 +219,9 @@ static int wcd934x_slim_probe(struct slim_device *sdev) return -ENOMEM; ddata->irq = of_irq_get(np, 0); - if (ddata->irq < 0) { - if (ddata->irq != -EPROBE_DEFER) - dev_err(ddata->dev, "Failed to get IRQ: err = %d\n", - ddata->irq); - return ddata->irq; - } + if (ddata->irq < 0) + return dev_err_probe(ddata->dev, ddata->irq, + "Failed to get IRQ\n"); reset_gpio = of_get_named_gpio(np, "reset-gpios", 0); if (reset_gpio < 0) { -- cgit v1.2.3 From b6d213fb0b503683c0c6d33d80c85babd36bf0fc Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Wed, 26 Aug 2020 22:21:49 +0200 Subject: mfd: dm355evm_msp: Convert LEDs to GPIO descriptor table This converts the DaVinci DM355EVM LEDs to use GPIO descriptor look-ups. Cc: Sekhar Nori Cc: Bartosz Golaszewski Signed-off-by: Linus Walleij Signed-off-by: Lee Jones --- drivers/mfd/dm355evm_msp.c | 76 ++++++++++++++++++++++++++++++---------------- 1 file changed, 50 insertions(+), 26 deletions(-) (limited to 'drivers/mfd') diff --git a/drivers/mfd/dm355evm_msp.c b/drivers/mfd/dm355evm_msp.c index 151c36ce7343..54fb6cbd2aa0 100644 --- a/drivers/mfd/dm355evm_msp.c +++ b/drivers/mfd/dm355evm_msp.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -116,6 +117,54 @@ static const u8 msp_gpios[] = { MSP_GPIO(4, SDMMC), MSP_GPIO(3, SDMMC), /* mmc1 WP, nCD */ }; +static struct gpio_led evm_leds[] = { + { .name = "dm355evm::ds14", + .default_trigger = "heartbeat", }, + { .name = "dm355evm::ds15", + .default_trigger = "mmc0", }, + { .name = "dm355evm::ds16", + /* could also be a CE-ATA drive */ + .default_trigger = "mmc1", }, + { .name = "dm355evm::ds17", + .default_trigger = "nand-disk", }, + { .name = "dm355evm::ds18", }, + { .name = "dm355evm::ds19", }, + { .name = "dm355evm::ds20", }, + { .name = "dm355evm::ds21", }, +}; + +static struct gpio_led_platform_data evm_led_data = { + .num_leds = ARRAY_SIZE(evm_leds), + .leds = evm_leds, +}; + +static struct gpiod_lookup_table evm_leds_gpio_table = { + .dev_id = "leds-gpio", + .table = { + /* + * These GPIOs are on the dm355evm_msp + * GPIO chip at index 0..7 + */ + GPIO_LOOKUP_IDX("dm355evm_msp", 0, NULL, + 0, GPIO_ACTIVE_LOW), + GPIO_LOOKUP_IDX("dm355evm_msp", 1, NULL, + 1, GPIO_ACTIVE_LOW), + GPIO_LOOKUP_IDX("dm355evm_msp", 2, NULL, + 2, GPIO_ACTIVE_LOW), + GPIO_LOOKUP_IDX("dm355evm_msp", 3, NULL, + 3, GPIO_ACTIVE_LOW), + GPIO_LOOKUP_IDX("dm355evm_msp", 4, NULL, + 4, GPIO_ACTIVE_LOW), + GPIO_LOOKUP_IDX("dm355evm_msp", 5, NULL, + 5, GPIO_ACTIVE_LOW), + GPIO_LOOKUP_IDX("dm355evm_msp", 6, NULL, + 6, GPIO_ACTIVE_LOW), + GPIO_LOOKUP_IDX("dm355evm_msp", 7, NULL, + 7, GPIO_ACTIVE_LOW), + { }, + }, +}; + #define MSP_GPIO_REG(offset) (msp_gpios[(offset)] >> 3) #define MSP_GPIO_MASK(offset) BIT(msp_gpios[(offset)] & 0x07) @@ -260,32 +309,7 @@ static int add_children(struct i2c_client *client) /* LED output */ if (msp_has_leds()) { -#define GPIO_LED(l) .name = l, .active_low = true - static struct gpio_led evm_leds[] = { - { GPIO_LED("dm355evm::ds14"), - .default_trigger = "heartbeat", }, - { GPIO_LED("dm355evm::ds15"), - .default_trigger = "mmc0", }, - { GPIO_LED("dm355evm::ds16"), - /* could also be a CE-ATA drive */ - .default_trigger = "mmc1", }, - { GPIO_LED("dm355evm::ds17"), - .default_trigger = "nand-disk", }, - { GPIO_LED("dm355evm::ds18"), }, - { GPIO_LED("dm355evm::ds19"), }, - { GPIO_LED("dm355evm::ds20"), }, - { GPIO_LED("dm355evm::ds21"), }, - }; -#undef GPIO_LED - - struct gpio_led_platform_data evm_led_data = { - .num_leds = ARRAY_SIZE(evm_leds), - .leds = evm_leds, - }; - - for (i = 0; i < ARRAY_SIZE(evm_leds); i++) - evm_leds[i].gpio = i + dm355evm_msp_gpio.base; - + gpiod_add_lookup_table(&evm_leds_gpio_table); /* NOTE: these are the only fully programmable LEDs * on the board, since GPIO-61/ds22 (and many signals * going to DC7) must be used for AEMIF address lines -- cgit v1.2.3 From 5f039fa742b6d8b4bbb7eb1a91c0dd251f03712d Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 21 Aug 2020 17:25:09 +0300 Subject: mfd: intel-lpss: Add device IDs for UART ports for Lakefield Add PCI IDs for Lakefield to the list of supported UARTs. Cc: Jarkko Nikula Cc: Mika Westerberg Cc: "Ravi V. Shankar" Signed-off-by: Ricardo Neri Signed-off-by: Andy Shevchenko Signed-off-by: Lee Jones --- drivers/mfd/intel-lpss-pci.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/mfd') diff --git a/drivers/mfd/intel-lpss-pci.c b/drivers/mfd/intel-lpss-pci.c index 9a58032f818a..2d7c588ef1ed 100644 --- a/drivers/mfd/intel-lpss-pci.c +++ b/drivers/mfd/intel-lpss-pci.c @@ -293,6 +293,10 @@ static const struct pci_device_id intel_lpss_pci_ids[] = { { PCI_VDEVICE(INTEL, 0x5ac4), (kernel_ulong_t)&bxt_info }, { PCI_VDEVICE(INTEL, 0x5ac6), (kernel_ulong_t)&bxt_info }, { PCI_VDEVICE(INTEL, 0x5aee), (kernel_ulong_t)&bxt_uart_info }, + /* LKF */ + { PCI_VDEVICE(INTEL, 0x98a8), (kernel_ulong_t)&bxt_uart_info }, + { PCI_VDEVICE(INTEL, 0x98a9), (kernel_ulong_t)&bxt_uart_info }, + { PCI_VDEVICE(INTEL, 0x98c7), (kernel_ulong_t)&bxt_uart_info }, /* SPT-LP */ { PCI_VDEVICE(INTEL, 0x9d27), (kernel_ulong_t)&spt_uart_info }, { PCI_VDEVICE(INTEL, 0x9d28), (kernel_ulong_t)&spt_uart_info }, -- cgit v1.2.3 From a75bfc824a2d33f57ebdc003bfe6b7a9e11e9cb9 Mon Sep 17 00:00:00 2001 From: Baolin Wang Date: Tue, 18 Aug 2020 11:41:58 +0800 Subject: mfd: sprd: Add wakeup capability for PMIC IRQ When changing to use suspend-to-idle to save power, the PMIC irq can not wakeup the system due to lack of wakeup capability, which will cause the sub-irqs (such as power key) of the PMIC can not wake up the system. Thus we can add the wakeup capability for PMIC irq to solve this issue, as well as removing the IRQF_NO_SUSPEND flag to allow PMIC irq to be a wakeup source. Reported-by: Chunyan Zhang Signed-off-by: Baolin Wang Tested-by: Chunyan Zhang Signed-off-by: Lee Jones --- drivers/mfd/sprd-sc27xx-spi.c | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) (limited to 'drivers/mfd') diff --git a/drivers/mfd/sprd-sc27xx-spi.c b/drivers/mfd/sprd-sc27xx-spi.c index f8a8b918c60d..6b7956604a0f 100644 --- a/drivers/mfd/sprd-sc27xx-spi.c +++ b/drivers/mfd/sprd-sc27xx-spi.c @@ -189,7 +189,7 @@ static int sprd_pmic_probe(struct spi_device *spi) ddata->irqs[i].mask = BIT(i); ret = devm_regmap_add_irq_chip(&spi->dev, ddata->regmap, ddata->irq, - IRQF_ONESHOT | IRQF_NO_SUSPEND, 0, + IRQF_ONESHOT, 0, &ddata->irq_chip, &ddata->irq_data); if (ret) { dev_err(&spi->dev, "Failed to add PMIC irq chip %d\n", ret); @@ -202,9 +202,34 @@ static int sprd_pmic_probe(struct spi_device *spi) return ret; } + device_init_wakeup(&spi->dev, true); return 0; } +#ifdef CONFIG_PM_SLEEP +static int sprd_pmic_suspend(struct device *dev) +{ + struct sprd_pmic *ddata = dev_get_drvdata(dev); + + if (device_may_wakeup(dev)) + enable_irq_wake(ddata->irq); + + return 0; +} + +static int sprd_pmic_resume(struct device *dev) +{ + struct sprd_pmic *ddata = dev_get_drvdata(dev); + + if (device_may_wakeup(dev)) + disable_irq_wake(ddata->irq); + + return 0; +} +#endif + +static SIMPLE_DEV_PM_OPS(sprd_pmic_pm_ops, sprd_pmic_suspend, sprd_pmic_resume); + static const struct of_device_id sprd_pmic_match[] = { { .compatible = "sprd,sc2731", .data = &sc2731_data }, {}, @@ -215,6 +240,7 @@ static struct spi_driver sprd_pmic_driver = { .driver = { .name = "sc27xx-pmic", .of_match_table = sprd_pmic_match, + .pm = &sprd_pmic_pm_ops, }, .probe = sprd_pmic_probe, }; -- cgit v1.2.3 From 529a1101212a785c5df92c314b0e718287150c3b Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Thu, 3 Sep 2020 17:02:37 +0100 Subject: mfd: syscon: Don't free allocated name for regmap_config The name allocated for the regmap_config structure is freed pretty early, right after the registration of the MMIO region. Unfortunately, that doesn't follow the life cycle that debugfs expects, as it can access the name field long after the free has occurred. Move the free on the error path, and keep it forever otherwise. Fixes: e15d7f2b81d2 ("mfd: syscon: Use a unique name with regmap_config") Signed-off-by: Marc Zyngier Signed-off-by: Lee Jones --- drivers/mfd/syscon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/mfd') diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c index 75859e492984..7a660411c562 100644 --- a/drivers/mfd/syscon.c +++ b/drivers/mfd/syscon.c @@ -108,7 +108,6 @@ static struct syscon *of_syscon_register(struct device_node *np, bool check_clk) syscon_config.max_register = resource_size(&res) - reg_io_width; regmap = regmap_init_mmio(NULL, base, &syscon_config); - kfree(syscon_config.name); if (IS_ERR(regmap)) { pr_err("regmap init failed\n"); ret = PTR_ERR(regmap); @@ -145,6 +144,7 @@ err_clk: regmap_exit(regmap); err_regmap: iounmap(base); + kfree(syscon_config.name); err_map: kfree(syscon); return ERR_PTR(ret); -- cgit v1.2.3 From 8ce24f8967df2836b4557a23e74dc4bb098249f1 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 11 Sep 2020 14:33:26 +0300 Subject: mfd: sm501: Fix leaks in probe() This code should clean up if sm501_init_dev() fails. Fixes: b6d6454fdb66 ("[PATCH] mfd: SM501 core driver") Signed-off-by: Dan Carpenter Signed-off-by: Lee Jones --- drivers/mfd/sm501.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers/mfd') diff --git a/drivers/mfd/sm501.c b/drivers/mfd/sm501.c index ccd62b963952..6d2f4a0a901d 100644 --- a/drivers/mfd/sm501.c +++ b/drivers/mfd/sm501.c @@ -1415,8 +1415,14 @@ static int sm501_plat_probe(struct platform_device *dev) goto err_claim; } - return sm501_init_dev(sm); + ret = sm501_init_dev(sm); + if (ret) + goto err_unmap; + + return 0; + err_unmap: + iounmap(sm->regs); err_claim: release_mem_region(sm->io_res->start, 0x100); err_res: -- cgit v1.2.3 From d38eac299151e4715c3b22e0253126440fa513b4 Mon Sep 17 00:00:00 2001 From: YueHaibing Date: Mon, 14 Sep 2020 22:25:18 +0800 Subject: mfd: mt6360: Remove unused include This file does not make use of it. Reported-by: Hulk Robot Signed-off-by: YueHaibing Signed-off-by: Lee Jones --- drivers/mfd/mt6360-core.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/mfd') diff --git a/drivers/mfd/mt6360-core.c b/drivers/mfd/mt6360-core.c index e9cacc27d980..4661c1b29a72 100644 --- a/drivers/mfd/mt6360-core.c +++ b/drivers/mfd/mt6360-core.c @@ -13,7 +13,6 @@ #include #include #include -#include #include -- cgit v1.2.3 From 4b6ec08fd21ee3179cbfccf3605ad13d9f38b623 Mon Sep 17 00:00:00 2001 From: Luca Ceresoli Date: Wed, 2 Sep 2020 16:22:59 +0200 Subject: mfd: lp87565: Add LP87524-Q1 variant Add support for the LP87524B/J/P-Q1 Four 4-MHz Buck Converter. This is a variant of the LP87565 having 4 single-phase outputs and up to 10 A of total output current. Signed-off-by: Luca Ceresoli Signed-off-by: Lee Jones --- drivers/mfd/lp87565.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/mfd') diff --git a/drivers/mfd/lp87565.c b/drivers/mfd/lp87565.c index 2268be9113f1..9c21483d9653 100644 --- a/drivers/mfd/lp87565.c +++ b/drivers/mfd/lp87565.c @@ -26,6 +26,10 @@ static const struct mfd_cell lp87565_cells[] = { static const struct of_device_id of_lp87565_match_table[] = { { .compatible = "ti,lp87565", }, + { + .compatible = "ti,lp87524-q1", + .data = (void *)LP87565_DEVICE_TYPE_LP87524_Q1, + }, { .compatible = "ti,lp87565-q1", .data = (void *)LP87565_DEVICE_TYPE_LP87565_Q1, -- cgit v1.2.3 From 876611c493b10cbb59e0e2143d3e744d0442de63 Mon Sep 17 00:00:00 2001 From: Xu Yilun Date: Tue, 15 Sep 2020 11:44:21 +0800 Subject: mfd: intel-m10-bmc: Add Intel MAX 10 BMC chip support for Intel FPGA PAC This patch implements the basic functions of the BMC chip for some Intel FPGA PCIe Acceleration Cards (PAC). The BMC is implemented using the Intel MAX 10 CPLD. This BMC chip is connected to the FPGA by a SPI bus. To provide direct register access from the FPGA, the "SPI slave to Avalon Master Bridge" (spi-avmm) IP is integrated in the chip. It converts encoded streams of bytes from the host to the internal register read/write on the Avalon bus. So This driver uses the regmap-spi-avmm for register accessing. Signed-off-by: Xu Yilun Signed-off-by: Wu Hao Signed-off-by: Matthew Gerlach Signed-off-by: Russ Weight Reviewed-by: Tom Rix Signed-off-by: Lee Jones --- drivers/mfd/Kconfig | 13 ++++ drivers/mfd/Makefile | 1 + drivers/mfd/intel-m10-bmc.c | 164 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 178 insertions(+) create mode 100644 drivers/mfd/intel-m10-bmc.c (limited to 'drivers/mfd') diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index e1d3bf77b245..2ba269429e25 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -2151,5 +2151,18 @@ config SGI_MFD_IOC3 If you have an SGI Origin, Octane, or a PCI IOC3 card, then say Y. Otherwise say N. +config MFD_INTEL_M10_BMC + tristate "Intel MAX 10 Board Management Controller" + depends on SPI_MASTER + select REGMAP_SPI_AVMM + select MFD_CORE + help + Support for the Intel MAX 10 board management controller using the + SPI interface. + + This driver provides common support for accessing the device, + additional drivers must be enabled in order to use the functionality + of the device. + endmenu endif diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index e6c7520ed129..1780019d2474 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -266,3 +266,4 @@ obj-$(CONFIG_MFD_KHADAS_MCU) += khadas-mcu.o obj-$(CONFIG_SGI_MFD_IOC3) += ioc3.o obj-$(CONFIG_MFD_SIMPLE_MFD_I2C) += simple-mfd-i2c.o +obj-$(CONFIG_MFD_INTEL_M10_BMC) += intel-m10-bmc.o diff --git a/drivers/mfd/intel-m10-bmc.c b/drivers/mfd/intel-m10-bmc.c new file mode 100644 index 000000000000..b84579b7b4f0 --- /dev/null +++ b/drivers/mfd/intel-m10-bmc.c @@ -0,0 +1,164 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Intel MAX 10 Board Management Controller chip + * + * Copyright (C) 2018-2020 Intel Corporation. All rights reserved. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +enum m10bmc_type { + M10_N3000, +}; + +static struct mfd_cell m10bmc_pacn3000_subdevs[] = { + { .name = "n3000bmc-hwmon" }, + { .name = "n3000bmc-retimer" }, + { .name = "n3000bmc-secure" }, +}; + +static struct regmap_config intel_m10bmc_regmap_config = { + .reg_bits = 32, + .val_bits = 32, + .reg_stride = 4, + .max_register = M10BMC_MEM_END, +}; + +static ssize_t bmc_version_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct intel_m10bmc *ddata = dev_get_drvdata(dev); + unsigned int val; + int ret; + + ret = m10bmc_sys_read(ddata, M10BMC_BUILD_VER, &val); + if (ret) + return ret; + + return sprintf(buf, "0x%x\n", val); +} +static DEVICE_ATTR_RO(bmc_version); + +static ssize_t bmcfw_version_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct intel_m10bmc *ddata = dev_get_drvdata(dev); + unsigned int val; + int ret; + + ret = m10bmc_sys_read(ddata, NIOS2_FW_VERSION, &val); + if (ret) + return ret; + + return sprintf(buf, "0x%x\n", val); +} +static DEVICE_ATTR_RO(bmcfw_version); + +static struct attribute *m10bmc_attrs[] = { + &dev_attr_bmc_version.attr, + &dev_attr_bmcfw_version.attr, + NULL, +}; +ATTRIBUTE_GROUPS(m10bmc); + +static int check_m10bmc_version(struct intel_m10bmc *ddata) +{ + unsigned int v; + int ret; + + /* + * This check is to filter out the very old legacy BMC versions, + * M10BMC_LEGACY_SYS_BASE is the offset to this old block of mmio + * registers. In the old BMC chips, the BMC version info is stored + * in this old version register (M10BMC_LEGACY_SYS_BASE + + * M10BMC_BUILD_VER), so its read out value would have not been + * LEGACY_INVALID (0xffffffff). But in new BMC chips that the + * driver supports, the value of this register should be + * LEGACY_INVALID. + */ + ret = m10bmc_raw_read(ddata, + M10BMC_LEGACY_SYS_BASE + M10BMC_BUILD_VER, &v); + if (ret) + return -ENODEV; + + if (v != M10BMC_VER_LEGACY_INVALID) { + dev_err(ddata->dev, "bad version M10BMC detected\n"); + return -ENODEV; + } + + return 0; +} + +static int intel_m10_bmc_spi_probe(struct spi_device *spi) +{ + const struct spi_device_id *id = spi_get_device_id(spi); + struct device *dev = &spi->dev; + struct mfd_cell *cells; + struct intel_m10bmc *ddata; + int ret, n_cell; + + ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL); + if (!ddata) + return -ENOMEM; + + ddata->dev = dev; + + ddata->regmap = + devm_regmap_init_spi_avmm(spi, &intel_m10bmc_regmap_config); + if (IS_ERR(ddata->regmap)) { + ret = PTR_ERR(ddata->regmap); + dev_err(dev, "Failed to allocate regmap: %d\n", ret); + return ret; + } + + spi_set_drvdata(spi, ddata); + + ret = check_m10bmc_version(ddata); + if (ret) { + dev_err(dev, "Failed to identify m10bmc hardware\n"); + return ret; + } + + switch (id->driver_data) { + case M10_N3000: + cells = m10bmc_pacn3000_subdevs; + n_cell = ARRAY_SIZE(m10bmc_pacn3000_subdevs); + break; + default: + return -ENODEV; + } + + ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_AUTO, cells, n_cell, + NULL, 0, NULL); + if (ret) + dev_err(dev, "Failed to register sub-devices: %d\n", ret); + + return ret; +} + +static const struct spi_device_id m10bmc_spi_id[] = { + { "m10-n3000", M10_N3000 }, + { } +}; +MODULE_DEVICE_TABLE(spi, m10bmc_spi_id); + +static struct spi_driver intel_m10bmc_spi_driver = { + .driver = { + .name = "intel-m10-bmc", + .dev_groups = m10bmc_groups, + }, + .probe = intel_m10_bmc_spi_probe, + .id_table = m10bmc_spi_id, +}; +module_spi_driver(intel_m10bmc_spi_driver); + +MODULE_DESCRIPTION("Intel MAX 10 BMC Device Driver"); +MODULE_AUTHOR("Intel Corporation"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("spi:intel-m10-bmc"); -- cgit v1.2.3 From e8299c7313af857254bc4304bc37482e9b952481 Mon Sep 17 00:00:00 2001 From: Michael Brunner Date: Thu, 20 Aug 2020 15:39:14 +0000 Subject: mfd: Add ACPI support to Kontron PLD driver Recent Kontron COMe modules identify the PLD device using the hardware id KEM0001 in the ACPI table. This patch adds support for probing the device using the HID and also retrieving the resources. As this is not available for all products, the DMI based detection still needs to be around for older systems. It is executed if no matching ACPI HID is found during registering the platform driver or no specific device id is forced. If a device is detected using ACPI and no resource information is available, the default io resource is used. Forcing a device id with the force_device_id parameter and therefore manually generating a platform device takes precedence over ACPI during probing. Signed-off-by: Michael Brunner Signed-off-by: Lee Jones --- drivers/mfd/kempld-core.c | 115 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 109 insertions(+), 6 deletions(-) (limited to 'drivers/mfd') diff --git a/drivers/mfd/kempld-core.c b/drivers/mfd/kempld-core.c index 52bec01149e5..1dfe556df038 100644 --- a/drivers/mfd/kempld-core.c +++ b/drivers/mfd/kempld-core.c @@ -13,6 +13,7 @@ #include #include #include +#include #define MAX_ID_LEN 4 static char force_device_id[MAX_ID_LEN + 1] = ""; @@ -124,6 +125,7 @@ static const struct kempld_platform_data kempld_platform_data_generic = { }; static struct platform_device *kempld_pdev; +static bool kempld_acpi_mode; static int kempld_create_platform_device(const struct dmi_system_id *id) { @@ -426,13 +428,93 @@ static int kempld_detect_device(struct kempld_device_data *pld) return ret; } +#ifdef CONFIG_ACPI +static int kempld_get_acpi_data(struct platform_device *pdev) +{ + struct list_head resource_list; + struct resource *resources; + struct resource_entry *rentry; + struct device *dev = &pdev->dev; + struct acpi_device *acpi_dev = ACPI_COMPANION(dev); + const struct kempld_platform_data *pdata; + int ret; + int count; + + pdata = acpi_device_get_match_data(dev); + ret = platform_device_add_data(pdev, pdata, + sizeof(struct kempld_platform_data)); + if (ret) + return ret; + + INIT_LIST_HEAD(&resource_list); + ret = acpi_dev_get_resources(acpi_dev, &resource_list, NULL, NULL); + if (ret < 0) + goto out; + + count = ret; + + if (count == 0) { + ret = platform_device_add_resources(pdev, pdata->ioresource, 1); + goto out; + } + + resources = devm_kcalloc(&acpi_dev->dev, count, sizeof(*resources), + GFP_KERNEL); + if (!resources) { + ret = -ENOMEM; + goto out; + } + + count = 0; + list_for_each_entry(rentry, &resource_list, node) { + memcpy(&resources[count], rentry->res, + sizeof(*resources)); + count++; + } + ret = platform_device_add_resources(pdev, resources, count); + +out: + acpi_dev_free_resource_list(&resource_list); + + return ret; +} +#else +static int kempld_get_acpi_data(struct platform_device *pdev) +{ + return -ENODEV; +} +#endif /* CONFIG_ACPI */ + static int kempld_probe(struct platform_device *pdev) { - const struct kempld_platform_data *pdata = - dev_get_platdata(&pdev->dev); + const struct kempld_platform_data *pdata; struct device *dev = &pdev->dev; struct kempld_device_data *pld; struct resource *ioport; + int ret; + + if (kempld_pdev == NULL) { + /* + * No kempld_pdev device has been registered in kempld_init, + * so we seem to be probing an ACPI platform device. + */ + ret = kempld_get_acpi_data(pdev); + if (ret) + return ret; + + kempld_acpi_mode = true; + } else if (kempld_pdev != pdev) { + /* + * The platform device we are probing is not the one we + * registered in kempld_init using the DMI table, so this one + * comes from ACPI. + * As we can only probe one - abort here and use the DMI + * based one instead. + */ + dev_notice(dev, "platform device exists - not using ACPI\n"); + return -ENODEV; + } + pdata = dev_get_platdata(dev); pld = devm_kzalloc(dev, sizeof(*pld), GFP_KERNEL); if (!pld) @@ -471,9 +553,17 @@ static int kempld_remove(struct platform_device *pdev) return 0; } +static const struct acpi_device_id kempld_acpi_table[] = { + { "KEM0001", (kernel_ulong_t)&kempld_platform_data_generic }, + {} +}; +MODULE_DEVICE_TABLE(acpi, kempld_acpi_table); + static struct platform_driver kempld_driver = { .driver = { .name = "kempld", + .acpi_match_table = ACPI_PTR(kempld_acpi_table), + .probe_type = PROBE_FORCE_SYNCHRONOUS, }, .probe = kempld_probe, .remove = kempld_remove, @@ -792,6 +882,7 @@ MODULE_DEVICE_TABLE(dmi, kempld_dmi_table); static int __init kempld_init(void) { const struct dmi_system_id *id; + int ret; if (force_device_id[0]) { for (id = kempld_dmi_table; @@ -801,12 +892,24 @@ static int __init kempld_init(void) break; if (id->matches[0].slot == DMI_NONE) return -ENODEV; - } else { - if (!dmi_check_system(kempld_dmi_table)) - return -ENODEV; } - return platform_driver_register(&kempld_driver); + ret = platform_driver_register(&kempld_driver); + if (ret) + return ret; + + /* + * With synchronous probing the device should already be probed now. + * If no device id is forced and also no ACPI definition for the + * device was found, scan DMI table as fallback. + * + * If drivers_autoprobing is disabled and the device is found here, + * only that device can be bound manually later. + */ + if (!kempld_pdev && !kempld_acpi_mode) + dmi_check_system(kempld_dmi_table); + + return 0; } static void __exit kempld_exit(void) -- cgit v1.2.3 From 1586d3a964c9b273ca982b750f757fbedcb57afb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Beh=C3=BAn?= Date: Thu, 17 Sep 2020 21:31:40 +0200 Subject: mfd: asic3: Build if COMPILE_TEST=y MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Build this driver on another platforms if COMPILE_TEST=y. Another drivers may depend on this, for example leds-asic3. Signed-off-by: Marek BehĂșn Signed-off-by: Lee Jones --- drivers/mfd/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/mfd') diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 2ba269429e25..bdf8cb962027 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -290,7 +290,8 @@ config MFD_CS47L92 config MFD_ASIC3 bool "Compaq ASIC3" - depends on GPIOLIB && ARM + depends on GPIOLIB + depends on ARM || COMPILE_TEST select MFD_CORE help This driver supports the ASIC3 multifunction chip found on many -- cgit v1.2.3 From 328162a8824cfefe4f891200bc77c0bf3e7fe5ff Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 2 Oct 2020 07:53:36 +0100 Subject: mfd: sl28cpld: Depend on I2C Fixes the following randconfig build error: ld: drivers/mfd/simple-mfd-i2c.o: in function `simple_mfd_i2c_probe': simple-mfd-i2c.c:(.text+0x48): undefined reference to `__devm_regmap_init_i2c' ld: drivers/mfd/simple-mfd-i2c.o: in function `simple_mfd_i2c_driver_init': simple-mfd-i2c.c:(.init.text+0x14): undefined reference to `i2c_register_driver' ld: drivers/mfd/simple-mfd-i2c.o: in function `simple_mfd_i2c_driver_exit': simple-mfd-i2c.c:(.exit.text+0xd): undefined reference to `i2c_del_driver' Reported-by: Randy Dunlap Tested-by: Randy Dunlap # build-tested Acked-by: Randy Dunlap Signed-off-by: Lee Jones --- drivers/mfd/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/mfd') diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index bdf8cb962027..8b99a13669bf 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -1188,6 +1188,7 @@ config MFD_SIMPLE_MFD_I2C config MFD_SL28CPLD tristate "Kontron sl28cpld Board Management Controller" + depends on I2C select MFD_SIMPLE_MFD_I2C help Say yes here to enable support for the Kontron sl28cpld board -- cgit v1.2.3 From 6d81dc3c79d46b66b29712eb1ac5ad2cbe4231d2 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 2 Oct 2020 07:56:18 +0100 Subject: mfd: kempld-core: Fix unused variable 'kempld_acpi_table' when !ACPI drivers/mfd/kempld-core.c:556:36: warning: unused variable 'kempld_acpi_table' [-Wunused-const-variable] Signed-off-by: Lee Jones --- drivers/mfd/kempld-core.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/mfd') diff --git a/drivers/mfd/kempld-core.c b/drivers/mfd/kempld-core.c index 1dfe556df038..2c9295953c11 100644 --- a/drivers/mfd/kempld-core.c +++ b/drivers/mfd/kempld-core.c @@ -553,11 +553,13 @@ static int kempld_remove(struct platform_device *pdev) return 0; } +#ifdef CONFIG_ACPI static const struct acpi_device_id kempld_acpi_table[] = { { "KEM0001", (kernel_ulong_t)&kempld_platform_data_generic }, {} }; MODULE_DEVICE_TABLE(acpi, kempld_acpi_table); +#endif static struct platform_driver kempld_driver = { .driver = { -- cgit v1.2.3