diff options
Diffstat (limited to '')
41 files changed, 338 insertions, 299 deletions
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 90ce58fd62..68d71b4b55 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -1483,6 +1483,7 @@ config MFD_SYSCON config MFD_TI_AM335X_TSCADC tristate "TI ADC / Touch Screen chip support" + depends on ARCH_OMAP2PLUS || ARCH_K3 || COMPILE_TEST select MFD_CORE select REGMAP select REGMAP_MMIO diff --git a/drivers/mfd/arizona-i2c.c b/drivers/mfd/arizona-i2c.c index 9b7183ffc9..10e76fc8f1 100644 --- a/drivers/mfd/arizona-i2c.c +++ b/drivers/mfd/arizona-i2c.c @@ -22,19 +22,12 @@ static int arizona_i2c_probe(struct i2c_client *i2c) { - const struct i2c_device_id *id = i2c_client_get_device_id(i2c); - const void *match_data; struct arizona *arizona; const struct regmap_config *regmap_config = NULL; - unsigned long type = 0; + unsigned long type; int ret; - match_data = device_get_match_data(&i2c->dev); - if (match_data) - type = (unsigned long)match_data; - else if (id) - type = id->driver_data; - + type = (uintptr_t)i2c_get_match_data(i2c); switch (type) { case WM5102: if (IS_ENABLED(CONFIG_MFD_WM5102)) diff --git a/drivers/mfd/atmel-hlcdc.c b/drivers/mfd/atmel-hlcdc.c index 20de7f49a8..4c4e35d404 100644 --- a/drivers/mfd/atmel-hlcdc.c +++ b/drivers/mfd/atmel-hlcdc.c @@ -139,6 +139,7 @@ static const struct of_device_id atmel_hlcdc_match[] = { { .compatible = "atmel,sama5d3-hlcdc" }, { .compatible = "atmel,sama5d4-hlcdc" }, { .compatible = "microchip,sam9x60-hlcdc" }, + { .compatible = "microchip,sam9x75-xlcdc" }, { /* sentinel */ }, }; MODULE_DEVICE_TABLE(of, atmel_hlcdc_match); diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c index 87603eeaa2..deaa969bab 100644 --- a/drivers/mfd/axp20x.c +++ b/drivers/mfd/axp20x.c @@ -22,7 +22,8 @@ #include <linux/mfd/axp20x.h> #include <linux/mfd/core.h> #include <linux/module.h> -#include <linux/of_device.h> +#include <linux/of.h> +#include <linux/property.h> #include <linux/reboot.h> #include <linux/regmap.h> #include <linux/regulator/consumer.h> @@ -1131,25 +1132,10 @@ static int axp20x_power_off(struct sys_off_data *data) int axp20x_match_device(struct axp20x_dev *axp20x) { struct device *dev = axp20x->dev; - const struct acpi_device_id *acpi_id; - const struct of_device_id *of_id; - - if (dev->of_node) { - of_id = of_match_device(dev->driver->of_match_table, dev); - if (!of_id) { - dev_err(dev, "Unable to match OF ID\n"); - return -ENODEV; - } - axp20x->variant = (long)of_id->data; - } else { - acpi_id = acpi_match_device(dev->driver->acpi_match_table, dev); - if (!acpi_id || !acpi_id->driver_data) { - dev_err(dev, "Unable to match ACPI ID and data\n"); - return -ENODEV; - } - axp20x->variant = (long)acpi_id->driver_data; - } + const struct mfd_cell *cells_no_irq = NULL; + int nr_cells_no_irq = 0; + axp20x->variant = (long)device_get_match_data(dev); switch (axp20x->variant) { case AXP152_ID: axp20x->nr_cells = ARRAY_SIZE(axp152_cells); @@ -1207,14 +1193,15 @@ int axp20x_match_device(struct axp20x_dev *axp20x) * if there is no interrupt line. */ if (of_property_read_bool(axp20x->dev->of_node, - "x-powers,self-working-mode") && - axp20x->irq > 0) { + "x-powers,self-working-mode")) { axp20x->nr_cells = ARRAY_SIZE(axp806_self_working_cells); axp20x->cells = axp806_self_working_cells; } else { axp20x->nr_cells = ARRAY_SIZE(axp806_cells); axp20x->cells = axp806_cells; } + nr_cells_no_irq = ARRAY_SIZE(axp806_cells); + cells_no_irq = axp806_cells; axp20x->regmap_cfg = &axp806_regmap_config; axp20x->regmap_irq_chip = &axp806_regmap_irq_chip; break; @@ -1238,24 +1225,8 @@ int axp20x_match_device(struct axp20x_dev *axp20x) axp20x->regmap_irq_chip = &axp803_regmap_irq_chip; break; case AXP15060_ID: - /* - * Don't register the power key part if there is no interrupt - * line. - * - * Since most use cases of AXP PMICs are Allwinner SOCs, board - * designers follow Allwinner's reference design and connects - * IRQ line to SOC, there's no need for those variants to deal - * with cases that IRQ isn't connected. However, AXP15660 is - * used by some other vendors' SOCs that didn't connect IRQ - * line, we need to deal with this case. - */ - if (axp20x->irq > 0) { - axp20x->nr_cells = ARRAY_SIZE(axp15060_cells); - axp20x->cells = axp15060_cells; - } else { - axp20x->nr_cells = ARRAY_SIZE(axp_regulator_only_cells); - axp20x->cells = axp_regulator_only_cells; - } + axp20x->nr_cells = ARRAY_SIZE(axp15060_cells); + axp20x->cells = axp15060_cells; axp20x->regmap_cfg = &axp15060_regmap_config; axp20x->regmap_irq_chip = &axp15060_regmap_irq_chip; break; @@ -1263,6 +1234,23 @@ int axp20x_match_device(struct axp20x_dev *axp20x) dev_err(dev, "unsupported AXP20X ID %lu\n", axp20x->variant); return -EINVAL; } + + /* + * Use an alternative cell array when no interrupt line is connected, + * since IRQs are required by some drivers. + * The default is the safe "regulator-only", as this works fine without + * an interrupt specified. + */ + if (axp20x->irq <= 0) { + if (cells_no_irq) { + axp20x->nr_cells = nr_cells_no_irq; + axp20x->cells = cells_no_irq; + } else { + axp20x->nr_cells = ARRAY_SIZE(axp_regulator_only_cells); + axp20x->cells = axp_regulator_only_cells; + } + } + dev_info(dev, "AXP20x variant %s found\n", axp20x_model_names[axp20x->variant]); diff --git a/drivers/mfd/db8500-prcmu.c b/drivers/mfd/db8500-prcmu.c index 27a881da4d..5b3e355e78 100644 --- a/drivers/mfd/db8500-prcmu.c +++ b/drivers/mfd/db8500-prcmu.c @@ -2639,9 +2639,9 @@ static void dbx500_fw_version_init(struct device_node *np) fw_info.version.api_version = (version >> 8) & 0xFF; fw_info.version.func_version = (version >> 16) & 0xFF; fw_info.version.errata = (version >> 24) & 0xFF; - strncpy(fw_info.version.project_name, + strscpy(fw_info.version.project_name, fw_project_name(fw_info.version.project), - PRCMU_FW_PROJECT_NAME_LEN); + sizeof(fw_info.version.project_name)); fw_info.valid = true; pr_info("PRCMU firmware: %s(%d), version %d.%d.%d\n", fw_info.version.project_name, diff --git a/drivers/mfd/hi6421-pmic-core.c b/drivers/mfd/hi6421-pmic-core.c index a6a890537a..5af24a4383 100644 --- a/drivers/mfd/hi6421-pmic-core.c +++ b/drivers/mfd/hi6421-pmic-core.c @@ -15,8 +15,9 @@ #include <linux/mfd/core.h> #include <linux/mfd/hi6421-pmic.h> #include <linux/module.h> -#include <linux/of_device.h> +#include <linux/of.h> #include <linux/platform_device.h> +#include <linux/property.h> #include <linux/regmap.h> static const struct mfd_cell hi6421_devs[] = { @@ -50,16 +51,12 @@ MODULE_DEVICE_TABLE(of, of_hi6421_pmic_match); static int hi6421_pmic_probe(struct platform_device *pdev) { struct hi6421_pmic *pmic; - const struct of_device_id *id; const struct mfd_cell *subdevs; enum hi6421_type type; void __iomem *base; int n_subdevs, ret; - id = of_match_device(of_hi6421_pmic_match, &pdev->dev); - if (!id) - return -EINVAL; - type = (uintptr_t)id->data; + type = (uintptr_t)device_get_match_data(&pdev->dev); pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL); if (!pmic) diff --git a/drivers/mfd/iqs62x.c b/drivers/mfd/iqs62x.c index e03b4d38fb..1b46559056 100644 --- a/drivers/mfd/iqs62x.c +++ b/drivers/mfd/iqs62x.c @@ -96,7 +96,7 @@ struct iqs62x_fw_blk { u8 addr; u8 mask; u8 len; - u8 data[]; + u8 data[] __counted_by(len); }; struct iqs62x_info { diff --git a/drivers/mfd/lochnagar-i2c.c b/drivers/mfd/lochnagar-i2c.c index 59092f839d..0b76fcccd0 100644 --- a/drivers/mfd/lochnagar-i2c.c +++ b/drivers/mfd/lochnagar-i2c.c @@ -15,8 +15,8 @@ #include <linux/i2c.h> #include <linux/lockdep.h> #include <linux/mfd/core.h> +#include <linux/mod_devicetable.h> #include <linux/mutex.h> -#include <linux/of.h> #include <linux/of_platform.h> #include <linux/regmap.h> @@ -270,7 +270,6 @@ 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; @@ -282,11 +281,7 @@ static int lochnagar_i2c_probe(struct i2c_client *i2c) if (!lochnagar) return -ENOMEM; - of_id = of_match_device(lochnagar_of_match, dev); - if (!of_id) - return -EINVAL; - - config = of_id->data; + config = i2c_get_match_data(i2c); lochnagar->dev = dev; mutex_init(&lochnagar->analogue_config_lock); diff --git a/drivers/mfd/lp87565.c b/drivers/mfd/lp87565.c index 1b7f834991..08c62ddfb4 100644 --- a/drivers/mfd/lp87565.c +++ b/drivers/mfd/lp87565.c @@ -6,10 +6,11 @@ */ #include <linux/gpio/consumer.h> +#include <linux/i2c.h> #include <linux/interrupt.h> #include <linux/mfd/core.h> +#include <linux/mod_devicetable.h> #include <linux/module.h> -#include <linux/of_device.h> #include <linux/regmap.h> #include <linux/mfd/lp87565.h> @@ -46,7 +47,6 @@ MODULE_DEVICE_TABLE(of, of_lp87565_match_table); static int lp87565_probe(struct i2c_client *client) { struct lp87565 *lp87565; - const struct of_device_id *of_id; int ret; unsigned int otpid; @@ -89,10 +89,7 @@ static int lp87565_probe(struct i2c_client *client) } lp87565->rev = otpid & LP87565_OTP_REV_OTP_ID; - - of_id = of_match_device(of_lp87565_match_table, &client->dev); - if (of_id) - lp87565->dev_type = (uintptr_t)of_id->data; + lp87565->dev_type = (uintptr_t)i2c_get_match_data(client); i2c_set_clientdata(client, lp87565); diff --git a/drivers/mfd/lpc_ich.c b/drivers/mfd/lpc_ich.c index 7b1c597b68..73a0e7f9bd 100644 --- a/drivers/mfd/lpc_ich.c +++ b/drivers/mfd/lpc_ich.c @@ -85,19 +85,6 @@ #define wdt_mem_res(i) wdt_res(ICH_RES_MEM_OFF, i) #define wdt_res(b, i) (&wdt_ich_res[(b) + (i)]) -struct lpc_ich_priv { - int chipset; - - int abase; /* ACPI base */ - int actrl_pbase; /* ACPI control or PMC base */ - int gbase; /* GPIO base */ - int gctrl; /* GPIO control */ - - int abase_save; /* Cached ACPI base value */ - int actrl_pbase_save; /* Cached ACPI control or PMC base value */ - int gctrl_save; /* Cached GPIO control value */ -}; - static struct resource wdt_ich_res[] = { /* ACPI - TCO */ { @@ -144,22 +131,33 @@ static struct mfd_cell lpc_ich_gpio_cell = { .ignore_resource_conflicts = true, }; +#define INTEL_GPIO_RESOURCE_SIZE 0x1000 + +struct lpc_ich_gpio_info { + const char *hid; + const struct mfd_cell *devices; + size_t nr_devices; + struct resource **resources; + size_t nr_resources; + const resource_size_t *offsets; +}; + #define APL_GPIO_NORTH 0 #define APL_GPIO_NORTHWEST 1 #define APL_GPIO_WEST 2 #define APL_GPIO_SOUTHWEST 3 + #define APL_GPIO_NR_DEVICES 4 +#define APL_GPIO_NR_RESOURCES 4 /* Offset data for Apollo Lake GPIO controllers */ -static resource_size_t apl_gpio_offsets[APL_GPIO_NR_DEVICES] = { +static const resource_size_t apl_gpio_offsets[APL_GPIO_NR_RESOURCES] = { [APL_GPIO_NORTH] = 0xc50000, [APL_GPIO_NORTHWEST] = 0xc40000, [APL_GPIO_WEST] = 0xc70000, [APL_GPIO_SOUTHWEST] = 0xc00000, }; -#define APL_GPIO_RESOURCE_SIZE 0x1000 - #define APL_GPIO_IRQ 14 static struct resource apl_gpio_resources[APL_GPIO_NR_DEVICES][2] = { @@ -181,6 +179,13 @@ static struct resource apl_gpio_resources[APL_GPIO_NR_DEVICES][2] = { }, }; +static struct resource *apl_gpio_mem_resources[APL_GPIO_NR_RESOURCES] = { + [APL_GPIO_NORTH] = &apl_gpio_resources[APL_GPIO_NORTH][0], + [APL_GPIO_NORTHWEST] = &apl_gpio_resources[APL_GPIO_NORTHWEST][0], + [APL_GPIO_WEST] = &apl_gpio_resources[APL_GPIO_WEST][0], + [APL_GPIO_SOUTHWEST] = &apl_gpio_resources[APL_GPIO_SOUTHWEST][0], +}; + static const struct mfd_cell apl_gpio_devices[APL_GPIO_NR_DEVICES] = { [APL_GPIO_NORTH] = { .name = "apollolake-pinctrl", @@ -212,6 +217,58 @@ static const struct mfd_cell apl_gpio_devices[APL_GPIO_NR_DEVICES] = { }, }; +static const struct lpc_ich_gpio_info apl_gpio_info = { + .hid = "INT3452", + .devices = apl_gpio_devices, + .nr_devices = ARRAY_SIZE(apl_gpio_devices), + .resources = apl_gpio_mem_resources, + .nr_resources = ARRAY_SIZE(apl_gpio_mem_resources), + .offsets = apl_gpio_offsets, +}; + +#define DNV_GPIO_NORTH 0 +#define DNV_GPIO_SOUTH 1 + +#define DNV_GPIO_NR_DEVICES 1 +#define DNV_GPIO_NR_RESOURCES 2 + +/* Offset data for Denverton GPIO controllers */ +static const resource_size_t dnv_gpio_offsets[DNV_GPIO_NR_RESOURCES] = { + [DNV_GPIO_NORTH] = 0xc20000, + [DNV_GPIO_SOUTH] = 0xc50000, +}; + +#define DNV_GPIO_IRQ 14 + +static struct resource dnv_gpio_resources[DNV_GPIO_NR_RESOURCES + 1] = { + [DNV_GPIO_NORTH] = DEFINE_RES_MEM(0, 0), + [DNV_GPIO_SOUTH] = DEFINE_RES_MEM(0, 0), + DEFINE_RES_IRQ(DNV_GPIO_IRQ), +}; + +static struct resource *dnv_gpio_mem_resources[DNV_GPIO_NR_RESOURCES] = { + [DNV_GPIO_NORTH] = &dnv_gpio_resources[DNV_GPIO_NORTH], + [DNV_GPIO_SOUTH] = &dnv_gpio_resources[DNV_GPIO_SOUTH], +}; + +static const struct mfd_cell dnv_gpio_devices[DNV_GPIO_NR_DEVICES] = { + { + .name = "denverton-pinctrl", + .num_resources = ARRAY_SIZE(dnv_gpio_resources), + .resources = dnv_gpio_resources, + .ignore_resource_conflicts = true, + }, +}; + +static const struct lpc_ich_gpio_info dnv_gpio_info = { + .hid = "INTC3000", + .devices = dnv_gpio_devices, + .nr_devices = ARRAY_SIZE(dnv_gpio_devices), + .resources = dnv_gpio_mem_resources, + .nr_resources = ARRAY_SIZE(dnv_gpio_mem_resources), + .offsets = dnv_gpio_offsets, +}; + static struct mfd_cell lpc_ich_spi_cell = { .name = "intel-spi", .num_resources = ARRAY_SIZE(intel_spi_res), @@ -289,10 +346,24 @@ enum lpc_chipsets { LPC_LEWISBURG, /* Lewisburg */ LPC_9S, /* 9 Series */ LPC_APL, /* Apollo Lake SoC */ + LPC_DNV, /* Denverton SoC */ LPC_GLK, /* Gemini Lake SoC */ LPC_COUGARMOUNTAIN,/* Cougar Mountain SoC*/ }; +struct lpc_ich_priv { + enum lpc_chipsets chipset; + + int abase; /* ACPI base */ + int actrl_pbase; /* ACPI control or PMC base */ + int gbase; /* GPIO base */ + int gctrl; /* GPIO control */ + + int abase_save; /* Cached ACPI base value */ + int actrl_pbase_save; /* Cached ACPI control or PMC base value */ + int gctrl_save; /* Cached GPIO control value */ +}; + static struct lpc_ich_info lpc_chipset_info[] = { [LPC_ICH] = { .name = "ICH", @@ -618,8 +689,13 @@ static struct lpc_ich_info lpc_chipset_info[] = { [LPC_APL] = { .name = "Apollo Lake SoC", .iTCO_version = 5, + .gpio_info = &apl_gpio_info, .spi_type = INTEL_SPI_BXT, }, + [LPC_DNV] = { + .name = "Denverton SoC", + .gpio_info = &dnv_gpio_info, + }, [LPC_GLK] = { .name = "Gemini Lake SoC", .spi_type = INTEL_SPI_BXT, @@ -638,6 +714,7 @@ static struct lpc_ich_info lpc_chipset_info[] = { */ static const struct pci_device_id lpc_ich_ids[] = { { PCI_VDEVICE(INTEL, 0x0f1c), LPC_BAYTRAIL}, + { PCI_VDEVICE(INTEL, 0x19dc), LPC_DNV}, { PCI_VDEVICE(INTEL, 0x1c41), LPC_CPT}, { PCI_VDEVICE(INTEL, 0x1c42), LPC_CPTD}, { PCI_VDEVICE(INTEL, 0x1c43), LPC_CPTM}, @@ -1156,30 +1233,32 @@ wdt_done: static int lpc_ich_init_pinctrl(struct pci_dev *dev) { + struct lpc_ich_priv *priv = pci_get_drvdata(dev); + const struct lpc_ich_gpio_info *info = lpc_chipset_info[priv->chipset].gpio_info; struct resource base; unsigned int i; int ret; /* Check, if GPIO has been exported as an ACPI device */ - if (acpi_dev_present("INT3452", NULL, -1)) + if (acpi_dev_present(info->hid, NULL, -1)) return -EEXIST; ret = p2sb_bar(dev->bus, 0, &base); if (ret) return ret; - for (i = 0; i < ARRAY_SIZE(apl_gpio_devices); i++) { - struct resource *mem = &apl_gpio_resources[i][0]; - resource_size_t offset = apl_gpio_offsets[i]; + for (i = 0; i < info->nr_resources; i++) { + struct resource *mem = info->resources[i]; + resource_size_t offset = info->offsets[i]; /* Fill MEM resource */ mem->start = base.start + offset; - mem->end = base.start + offset + APL_GPIO_RESOURCE_SIZE - 1; + mem->end = base.start + offset + INTEL_GPIO_RESOURCE_SIZE - 1; mem->flags = base.flags; } - return mfd_add_devices(&dev->dev, 0, apl_gpio_devices, - ARRAY_SIZE(apl_gpio_devices), NULL, 0, NULL); + return mfd_add_devices(&dev->dev, 0, info->devices, info->nr_devices, + NULL, 0, NULL); } static bool lpc_ich_byt_set_writeable(void __iomem *base, void *data) @@ -1332,7 +1411,7 @@ static int lpc_ich_probe(struct pci_dev *dev, cell_added = true; } - if (priv->chipset == LPC_APL) { + if (lpc_chipset_info[priv->chipset].gpio_info) { ret = lpc_ich_init_pinctrl(dev); if (!ret) cell_added = true; diff --git a/drivers/mfd/madera-i2c.c b/drivers/mfd/madera-i2c.c index a404ea26bc..0986e4a99f 100644 --- a/drivers/mfd/madera-i2c.c +++ b/drivers/mfd/madera-i2c.c @@ -18,21 +18,14 @@ static int madera_i2c_probe(struct i2c_client *i2c) { - const struct i2c_device_id *id = i2c_client_get_device_id(i2c); struct madera *madera; const struct regmap_config *regmap_16bit_config = NULL; const struct regmap_config *regmap_32bit_config = NULL; - const void *of_data; unsigned long type; const char *name; int ret; - of_data = of_device_get_match_data(&i2c->dev); - if (of_data) - type = (unsigned long)of_data; - else - type = id->driver_data; - + type = (uintptr_t)i2c_get_match_data(i2c); switch (type) { case CS47L15: if (IS_ENABLED(CONFIG_MFD_CS47L15)) { diff --git a/drivers/mfd/max14577.c b/drivers/mfd/max14577.c index 1f4f500259..8f7472c760 100644 --- a/drivers/mfd/max14577.c +++ b/drivers/mfd/max14577.c @@ -9,9 +9,10 @@ // This driver is based on max8997.c #include <linux/err.h> +#include <linux/i2c.h> +#include <linux/mod_devicetable.h> #include <linux/module.h> #include <linux/interrupt.h> -#include <linux/of_device.h> #include <linux/mfd/core.h> #include <linux/mfd/max14577.h> #include <linux/mfd/max14577-private.h> @@ -357,7 +358,6 @@ static void max77836_remove(struct max14577 *max14577) static int max14577_i2c_probe(struct i2c_client *i2c) { - const struct i2c_device_id *id = i2c_client_get_device_id(i2c); struct max14577 *max14577; struct max14577_platform_data *pdata = dev_get_platdata(&i2c->dev); struct device_node *np = i2c->dev.of_node; @@ -397,15 +397,7 @@ static int max14577_i2c_probe(struct i2c_client *i2c) return ret; } - if (np) { - const struct of_device_id *of_id; - - of_id = of_match_device(max14577_dt_match, &i2c->dev); - if (of_id) - max14577->dev_type = (uintptr_t)of_id->data; - } else { - max14577->dev_type = id->driver_data; - } + max14577->dev_type = (enum maxim_device_type)i2c_get_match_data(i2c); max14577_print_dev_type(max14577); diff --git a/drivers/mfd/max77541.c b/drivers/mfd/max77541.c index 10c2e274b4..d77c31c86e 100644 --- a/drivers/mfd/max77541.c +++ b/drivers/mfd/max77541.c @@ -162,7 +162,6 @@ static int max77541_pmic_setup(struct device *dev) static int max77541_probe(struct i2c_client *client) { - const struct i2c_device_id *id = i2c_client_get_device_id(client); struct device *dev = &client->dev; struct max77541 *max77541; @@ -173,10 +172,7 @@ static int max77541_probe(struct i2c_client *client) i2c_set_clientdata(client, max77541); max77541->i2c = client; - max77541->id = (uintptr_t)device_get_match_data(dev); - if (!max77541->id) - max77541->id = (enum max7754x_ids)id->driver_data; - + max77541->id = (uintptr_t)i2c_get_match_data(client); if (!max77541->id) return -EINVAL; diff --git a/drivers/mfd/max77620.c b/drivers/mfd/max77620.c index e63e8e47d9..74ef3f6d57 100644 --- a/drivers/mfd/max77620.c +++ b/drivers/mfd/max77620.c @@ -172,7 +172,7 @@ static const struct regmap_config max77620_regmap_config = { .reg_bits = 8, .val_bits = 8, .max_register = MAX77620_REG_DVSSD4 + 1, - .cache_type = REGCACHE_RBTREE, + .cache_type = REGCACHE_MAPLE, .rd_table = &max77620_readable_table, .wr_table = &max77620_writable_table, .volatile_table = &max77620_volatile_table, @@ -184,7 +184,7 @@ static const struct regmap_config max20024_regmap_config = { .reg_bits = 8, .val_bits = 8, .max_register = MAX20024_REG_MAX_ADD + 1, - .cache_type = REGCACHE_RBTREE, + .cache_type = REGCACHE_MAPLE, .rd_table = &max20024_readable_table, .wr_table = &max77620_writable_table, .volatile_table = &max77620_volatile_table, @@ -213,7 +213,7 @@ static const struct regmap_config max77663_regmap_config = { .reg_bits = 8, .val_bits = 8, .max_register = MAX77620_REG_CID5 + 1, - .cache_type = REGCACHE_RBTREE, + .cache_type = REGCACHE_MAPLE, .rd_table = &max77663_readable_table, .wr_table = &max77663_writable_table, .volatile_table = &max77620_volatile_table, diff --git a/drivers/mfd/max77686.c b/drivers/mfd/max77686.c index 91c286c457..0118a444a6 100644 --- a/drivers/mfd/max77686.c +++ b/drivers/mfd/max77686.c @@ -108,7 +108,7 @@ static const struct regmap_config max77802_regmap_config = { .precious_reg = max77802_is_precious_reg, .volatile_reg = max77802_is_volatile_reg, .name = "max77802-pmic", - .cache_type = REGCACHE_RBTREE, + .cache_type = REGCACHE_MAPLE, }; static const struct regmap_irq max77686_irqs[] = { diff --git a/drivers/mfd/max8907.c b/drivers/mfd/max8907.c index 8bbe7979db..accf426234 100644 --- a/drivers/mfd/max8907.c +++ b/drivers/mfd/max8907.c @@ -63,7 +63,7 @@ static const struct regmap_config max8907_regmap_gen_config = { .precious_reg = max8907_gen_is_precious_reg, .writeable_reg = max8907_gen_is_writeable_reg, .max_register = MAX8907_REG_LDO20VOUT, - .cache_type = REGCACHE_RBTREE, + .cache_type = REGCACHE_MAPLE, }; static bool max8907_rtc_is_volatile_reg(struct device *dev, unsigned int reg) @@ -108,7 +108,7 @@ static const struct regmap_config max8907_regmap_rtc_config = { .precious_reg = max8907_rtc_is_precious_reg, .writeable_reg = max8907_rtc_is_writeable_reg, .max_register = MAX8907_REG_MPL_CNTL, - .cache_type = REGCACHE_RBTREE, + .cache_type = REGCACHE_MAPLE, }; static const struct regmap_irq max8907_chg_irqs[] = { diff --git a/drivers/mfd/max8997.c b/drivers/mfd/max8997.c index 110bef71f2..ffe96b4036 100644 --- a/drivers/mfd/max8997.c +++ b/drivers/mfd/max8997.c @@ -142,18 +142,8 @@ static struct max8997_platform_data *max8997_i2c_parse_dt_pdata( return pd; } -static inline unsigned long max8997_i2c_get_driver_data(struct i2c_client *i2c, - const struct i2c_device_id *id) -{ - if (i2c->dev.of_node) - return (unsigned long)of_device_get_match_data(&i2c->dev); - - return id->driver_data; -} - static int max8997_i2c_probe(struct i2c_client *i2c) { - const struct i2c_device_id *id = i2c_client_get_device_id(i2c); struct max8997_dev *max8997; struct max8997_platform_data *pdata = dev_get_platdata(&i2c->dev); int ret = 0; @@ -166,7 +156,7 @@ static int max8997_i2c_probe(struct i2c_client *i2c) i2c_set_clientdata(i2c, max8997); max8997->dev = &i2c->dev; max8997->i2c = i2c; - max8997->type = max8997_i2c_get_driver_data(i2c, id); + max8997->type = (uintptr_t)i2c_get_match_data(i2c); max8997->irq = i2c->irq; if (IS_ENABLED(CONFIG_OF) && max8997->dev->of_node) { diff --git a/drivers/mfd/max8998.c b/drivers/mfd/max8998.c index 4cc426a6c7..6ba27171da 100644 --- a/drivers/mfd/max8998.c +++ b/drivers/mfd/max8998.c @@ -152,18 +152,8 @@ static struct max8998_platform_data *max8998_i2c_parse_dt_pdata( return pd; } -static inline unsigned long max8998_i2c_get_driver_data(struct i2c_client *i2c, - const struct i2c_device_id *id) -{ - if (i2c->dev.of_node) - return (unsigned long)of_device_get_match_data(&i2c->dev); - - return id->driver_data; -} - static int max8998_i2c_probe(struct i2c_client *i2c) { - const struct i2c_device_id *id = i2c_client_get_device_id(i2c); struct max8998_platform_data *pdata = dev_get_platdata(&i2c->dev); struct max8998_dev *max8998; int ret = 0; @@ -183,7 +173,7 @@ static int max8998_i2c_probe(struct i2c_client *i2c) max8998->dev = &i2c->dev; max8998->i2c = i2c; max8998->irq = i2c->irq; - max8998->type = max8998_i2c_get_driver_data(i2c, id); + max8998->type = (uintptr_t)i2c_get_match_data(i2c); max8998->pdata = pdata; if (pdata) { max8998->ono = pdata->ono; diff --git a/drivers/mfd/mc13xxx-spi.c b/drivers/mfd/mc13xxx-spi.c index f70d79aa5a..c973e2579b 100644 --- a/drivers/mfd/mc13xxx-spi.c +++ b/drivers/mfd/mc13xxx-spi.c @@ -8,13 +8,12 @@ */ #include <linux/slab.h> +#include <linux/mod_devicetable.h> #include <linux/module.h> #include <linux/platform_device.h> #include <linux/interrupt.h> #include <linux/mfd/core.h> #include <linux/mfd/mc13xxx.h> -#include <linux/of.h> -#include <linux/of_device.h> #include <linux/err.h> #include <linux/spi/spi.h> @@ -151,16 +150,7 @@ static int mc13xxx_spi_probe(struct spi_device *spi) return ret; } - if (spi->dev.of_node) { - const struct of_device_id *of_id = - of_match_device(mc13xxx_dt_ids, &spi->dev); - - mc13xxx->variant = of_id->data; - } else { - const struct spi_device_id *id_entry = spi_get_device_id(spi); - - mc13xxx->variant = (void *)id_entry->driver_data; - } + mc13xxx->variant = spi_get_device_match_data(spi); return mc13xxx_common_init(&spi->dev); } diff --git a/drivers/mfd/motorola-cpcap.c b/drivers/mfd/motorola-cpcap.c index a19691ba8d..d8243b956f 100644 --- a/drivers/mfd/motorola-cpcap.c +++ b/drivers/mfd/motorola-cpcap.c @@ -11,7 +11,7 @@ #include <linux/irq.h> #include <linux/kernel.h> #include <linux/module.h> -#include <linux/of_device.h> +#include <linux/mod_devicetable.h> #include <linux/regmap.h> #include <linux/sysfs.h> @@ -290,14 +290,9 @@ static const struct mfd_cell cpcap_mfd_devices[] = { static int cpcap_probe(struct spi_device *spi) { - const struct of_device_id *match; struct cpcap_ddata *cpcap; int ret; - match = of_match_device(cpcap_of_match, &spi->dev); - if (!match) - return -ENODEV; - cpcap = devm_kzalloc(&spi->dev, sizeof(*cpcap), GFP_KERNEL); if (!cpcap) return -ENOMEM; diff --git a/drivers/mfd/mxs-lradc.c b/drivers/mfd/mxs-lradc.c index 21f3033d6e..ec1b356562 100644 --- a/drivers/mfd/mxs-lradc.c +++ b/drivers/mfd/mxs-lradc.c @@ -16,8 +16,8 @@ #include <linux/mfd/mxs-lradc.h> #include <linux/module.h> #include <linux/of.h> -#include <linux/of_device.h> #include <linux/platform_device.h> +#include <linux/property.h> #include <linux/slab.h> #define ADC_CELL 0 @@ -125,7 +125,6 @@ MODULE_DEVICE_TABLE(of, mxs_lradc_dt_ids); static int mxs_lradc_probe(struct platform_device *pdev) { - const struct of_device_id *of_id; struct device *dev = &pdev->dev; struct device_node *node = dev->of_node; struct mxs_lradc *lradc; @@ -138,11 +137,7 @@ static int mxs_lradc_probe(struct platform_device *pdev) if (!lradc) return -ENOMEM; - of_id = of_match_device(mxs_lradc_dt_ids, &pdev->dev); - if (!of_id) - return -EINVAL; - - lradc->soc = (uintptr_t)of_id->data; + lradc->soc = (enum mxs_lradc_id)device_get_match_data(&pdev->dev); lradc->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(lradc->clk)) { diff --git a/drivers/mfd/palmas.c b/drivers/mfd/palmas.c index 6e562bab62..7fc886f4f8 100644 --- a/drivers/mfd/palmas.c +++ b/drivers/mfd/palmas.c @@ -296,7 +296,7 @@ static const struct regmap_irq palmas_irqs[] = { }, }; -static struct regmap_irq_chip palmas_irq_chip = { +static const struct regmap_irq_chip palmas_irq_chip = { .name = "palmas", .irqs = palmas_irqs, .num_irqs = ARRAY_SIZE(palmas_irqs), @@ -309,7 +309,7 @@ static struct regmap_irq_chip palmas_irq_chip = { PALMAS_INT1_MASK), }; -static struct regmap_irq_chip tps65917_irq_chip = { +static const struct regmap_irq_chip tps65917_irq_chip = { .name = "tps65917", .irqs = tps65917_irqs, .num_irqs = ARRAY_SIZE(tps65917_irqs), @@ -463,51 +463,29 @@ static void palmas_power_off(void) __func__, ret); } -static unsigned int palmas_features = PALMAS_PMIC_FEATURE_SMPS10_BOOST; -static unsigned int tps659038_features; - struct palmas_driver_data { - unsigned int *features; - struct regmap_irq_chip *irq_chip; + unsigned int features; + const struct regmap_irq_chip *irq_chip; }; -static struct palmas_driver_data palmas_data = { - .features = &palmas_features, +static const struct palmas_driver_data palmas_data = { + .features = PALMAS_PMIC_FEATURE_SMPS10_BOOST, .irq_chip = &palmas_irq_chip, }; -static struct palmas_driver_data tps659038_data = { - .features = &tps659038_features, +static const struct palmas_driver_data tps659038_data = { .irq_chip = &palmas_irq_chip, }; -static struct palmas_driver_data tps65917_data = { - .features = &tps659038_features, +static const struct palmas_driver_data tps65917_data = { .irq_chip = &tps65917_irq_chip, }; -static const struct of_device_id of_palmas_match_tbl[] = { - { - .compatible = "ti,palmas", - .data = &palmas_data, - }, - { - .compatible = "ti,tps659038", - .data = &tps659038_data, - }, - { - .compatible = "ti,tps65917", - .data = &tps65917_data, - }, - { }, -}; -MODULE_DEVICE_TABLE(of, of_palmas_match_tbl); - static int palmas_i2c_probe(struct i2c_client *i2c) { struct palmas *palmas; struct palmas_platform_data *pdata; - struct palmas_driver_data *driver_data; + const struct palmas_driver_data *driver_data; struct device_node *node = i2c->dev.of_node; int ret = 0, i; unsigned int reg, addr; @@ -535,8 +513,8 @@ static int palmas_i2c_probe(struct i2c_client *i2c) palmas->dev = &i2c->dev; palmas->irq = i2c->irq; - driver_data = (struct palmas_driver_data *) device_get_match_data(&i2c->dev); - palmas->features = *driver_data->features; + driver_data = i2c_get_match_data(i2c); + palmas->features = driver_data->features; for (i = 0; i < PALMAS_NUM_CLIENTS; i++) { if (i == 0) @@ -712,11 +690,19 @@ static void palmas_i2c_remove(struct i2c_client *i2c) } } +static const struct of_device_id of_palmas_match_tbl[] = { + { .compatible = "ti,palmas", .data = &palmas_data }, + { .compatible = "ti,tps659038", .data = &tps659038_data }, + { .compatible = "ti,tps65917", .data = &tps65917_data }, + { } +}; +MODULE_DEVICE_TABLE(of, of_palmas_match_tbl); + static const struct i2c_device_id palmas_i2c_id[] = { - { "palmas", }, - { "twl6035", }, - { "twl6037", }, - { "tps65913", }, + { "palmas", (kernel_ulong_t)&palmas_data }, + { "twl6035", (kernel_ulong_t)&palmas_data }, + { "twl6037", (kernel_ulong_t)&palmas_data }, + { "tps65913", (kernel_ulong_t)&palmas_data }, { /* end */ } }; MODULE_DEVICE_TABLE(i2c, palmas_i2c_id); diff --git a/drivers/mfd/qcom-spmi-pmic.c b/drivers/mfd/qcom-spmi-pmic.c index 8e449cff5c..4549fa9f7d 100644 --- a/drivers/mfd/qcom-spmi-pmic.c +++ b/drivers/mfd/qcom-spmi-pmic.c @@ -8,10 +8,12 @@ #include <linux/gfp.h> #include <linux/kernel.h> #include <linux/module.h> +#include <linux/of.h> +#include <linux/of_device.h> +#include <linux/of_platform.h> #include <linux/spmi.h> #include <linux/types.h> #include <linux/regmap.h> -#include <linux/of_platform.h> #include <soc/qcom/qcom-spmi-pmic.h> #define PMIC_REV2 0x101 @@ -114,7 +116,7 @@ static struct spmi_device *qcom_pmic_get_base_usid(struct spmi_device *sdev, str } if (pmic_addr == function_parent_usid - (ctx->num_usids - 1)) { - sdev = spmi_device_from_of(child); + sdev = spmi_find_device_by_of_node(child); if (!sdev) { /* * If the base USID for this PMIC hasn't been @@ -241,7 +243,7 @@ const struct qcom_spmi_pmic *qcom_pmic_get(struct device *dev) return &spmi->pmic; } -EXPORT_SYMBOL(qcom_pmic_get); +EXPORT_SYMBOL_GPL(qcom_pmic_get); static const struct regmap_config spmi_regmap_config = { .reg_bits = 16, @@ -264,7 +266,7 @@ static int pmic_spmi_probe(struct spmi_device *sdev) if (!ctx) return -ENOMEM; - ctx->num_usids = (uintptr_t)of_device_get_match_data(&sdev->dev); + ctx->num_usids = (uintptr_t)device_get_match_data(&sdev->dev); /* Only the first slave id for a PMIC contains this information */ if (sdev->usid % ctx->num_usids == 0) { diff --git a/drivers/mfd/qcom_rpm.c b/drivers/mfd/qcom_rpm.c index 0866113228..27446f43e3 100644 --- a/drivers/mfd/qcom_rpm.c +++ b/drivers/mfd/qcom_rpm.c @@ -7,6 +7,8 @@ #include <linux/module.h> #include <linux/platform_device.h> +#include <linux/property.h> +#include <linux/of.h> #include <linux/of_platform.h> #include <linux/io.h> #include <linux/interrupt.h> @@ -528,7 +530,6 @@ static irqreturn_t qcom_rpm_wakeup_interrupt(int irq, void *dev) static int qcom_rpm_probe(struct platform_device *pdev) { - const struct of_device_id *match; struct device_node *syscon_np; struct qcom_rpm *rpm; u32 fw_version[3]; @@ -570,10 +571,9 @@ static int qcom_rpm_probe(struct platform_device *pdev) if (irq_wakeup < 0) return irq_wakeup; - match = of_match_device(qcom_rpm_of_match, &pdev->dev); - if (!match) + rpm->data = device_get_match_data(&pdev->dev); + if (!rpm->data) return -ENODEV; - rpm->data = match->data; rpm->status_regs = devm_platform_get_and_ioremap_resource(pdev, 0, NULL); if (IS_ERR(rpm->status_regs)) diff --git a/drivers/mfd/rk8xx-core.c b/drivers/mfd/rk8xx-core.c index a577f950c6..b1ffc3b9e2 100644 --- a/drivers/mfd/rk8xx-core.c +++ b/drivers/mfd/rk8xx-core.c @@ -517,6 +517,10 @@ static int rk808_power_off(struct sys_off_data *data) reg = RK805_DEV_CTRL_REG; bit = DEV_OFF; break; + case RK806_ID: + reg = RK806_SYS_CFG3; + bit = DEV_OFF; + break; case RK808_ID: reg = RK808_DEVCTRL_REG, bit = DEV_OFF_RST; @@ -677,7 +681,8 @@ int rk8xx_probe(struct device *dev, int variant, unsigned int irq, struct regmap if (ret) return dev_err_probe(dev, ret, "failed to add MFD devices\n"); - if (device_property_read_bool(dev, "rockchip,system-power-controller")) { + if (device_property_read_bool(dev, "rockchip,system-power-controller") || + device_property_read_bool(dev, "system-power-controller")) { ret = devm_register_sys_off_handler(dev, SYS_OFF_MODE_POWER_OFF_PREPARE, SYS_OFF_PRIO_HIGH, &rk808_power_off, rk808); diff --git a/drivers/mfd/rk8xx-i2c.c b/drivers/mfd/rk8xx-i2c.c index 1a98feea97..75b5cf09d5 100644 --- a/drivers/mfd/rk8xx-i2c.c +++ b/drivers/mfd/rk8xx-i2c.c @@ -80,7 +80,7 @@ static const struct regmap_config rk818_regmap_config = { .reg_bits = 8, .val_bits = 8, .max_register = RK818_USB_CTRL_REG, - .cache_type = REGCACHE_RBTREE, + .cache_type = REGCACHE_MAPLE, .volatile_reg = rk808_is_volatile_reg, }; @@ -88,7 +88,7 @@ static const struct regmap_config rk805_regmap_config = { .reg_bits = 8, .val_bits = 8, .max_register = RK805_OFF_SOURCE_REG, - .cache_type = REGCACHE_RBTREE, + .cache_type = REGCACHE_MAPLE, .volatile_reg = rk808_is_volatile_reg, }; @@ -96,7 +96,7 @@ static const struct regmap_config rk808_regmap_config = { .reg_bits = 8, .val_bits = 8, .max_register = RK808_IO_POL_REG, - .cache_type = REGCACHE_RBTREE, + .cache_type = REGCACHE_MAPLE, .volatile_reg = rk808_is_volatile_reg, }; diff --git a/drivers/mfd/rn5t618.c b/drivers/mfd/rn5t618.c index 0fe616b2db..7336e6d8a0 100644 --- a/drivers/mfd/rn5t618.c +++ b/drivers/mfd/rn5t618.c @@ -13,7 +13,7 @@ #include <linux/mfd/core.h> #include <linux/mfd/rn5t618.h> #include <linux/module.h> -#include <linux/of_device.h> +#include <linux/of.h> #include <linux/platform_device.h> #include <linux/reboot.h> #include <linux/regmap.h> @@ -179,22 +179,15 @@ MODULE_DEVICE_TABLE(of, rn5t618_of_match); static int rn5t618_i2c_probe(struct i2c_client *i2c) { - const struct of_device_id *of_id; struct rn5t618 *priv; int ret; - of_id = of_match_device(rn5t618_of_match, &i2c->dev); - if (!of_id) { - dev_err(&i2c->dev, "Failed to find matching DT ID\n"); - return -EINVAL; - } - priv = devm_kzalloc(&i2c->dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; i2c_set_clientdata(i2c, priv); - priv->variant = (long)of_id->data; + priv->variant = (long)i2c_get_match_data(i2c); priv->irq = i2c->irq; priv->dev = &i2c->dev; diff --git a/drivers/mfd/stm32-timers.c b/drivers/mfd/stm32-timers.c index 732a28db80..a656a1c186 100644 --- a/drivers/mfd/stm32-timers.c +++ b/drivers/mfd/stm32-timers.c @@ -215,6 +215,48 @@ static void stm32_timers_dma_remove(struct device *dev, dma_release_channel(ddata->dma.chans[i]); } +static const char * const stm32_timers_irq_name[STM32_TIMERS_MAX_IRQS] = { + "brk", "up", "trg-com", "cc" +}; + +static int stm32_timers_irq_probe(struct platform_device *pdev, + struct stm32_timers *ddata) +{ + int i, ret; + + /* + * STM32 Timer may have either: + * - a unique global interrupt line + * - four dedicated interrupt lines that may be handled separately. + * Optionally get them here, to be used by child devices. + */ + ret = platform_get_irq_byname_optional(pdev, "global"); + if (ret < 0 && ret != -ENXIO) { + return ret; + } else if (ret != -ENXIO) { + ddata->irq[STM32_TIMERS_IRQ_GLOBAL_BRK] = ret; + ddata->nr_irqs = 1; + return 0; + } + + for (i = 0; i < STM32_TIMERS_MAX_IRQS; i++) { + ret = platform_get_irq_byname_optional(pdev, stm32_timers_irq_name[i]); + if (ret < 0 && ret != -ENXIO) { + return ret; + } else if (ret != -ENXIO) { + ddata->irq[i] = ret; + ddata->nr_irqs++; + } + } + + if (ddata->nr_irqs && ddata->nr_irqs != STM32_TIMERS_MAX_IRQS) { + dev_err(&pdev->dev, "Invalid number of IRQs %d\n", ddata->nr_irqs); + return -EINVAL; + } + + return 0; +} + static int stm32_timers_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -245,6 +287,10 @@ static int stm32_timers_probe(struct platform_device *pdev) stm32_timers_get_arr_size(ddata); + ret = stm32_timers_irq_probe(pdev, ddata); + if (ret) + return ret; + ret = stm32_timers_dma_probe(dev, ddata); if (ret) { stm32_timers_dma_remove(dev, ddata); diff --git a/drivers/mfd/tps65086.c b/drivers/mfd/tps65086.c index 9bb7d7d8dc..152179ee11 100644 --- a/drivers/mfd/tps65086.c +++ b/drivers/mfd/tps65086.c @@ -34,7 +34,7 @@ static const struct regmap_access_table tps65086_volatile_table = { static const struct regmap_config tps65086_regmap_config = { .reg_bits = 8, .val_bits = 8, - .cache_type = REGCACHE_RBTREE, + .cache_type = REGCACHE_MAPLE, .volatile_table = &tps65086_volatile_table, }; diff --git a/drivers/mfd/tps65090.c b/drivers/mfd/tps65090.c index 9245e11219..b764badaa6 100644 --- a/drivers/mfd/tps65090.c +++ b/drivers/mfd/tps65090.c @@ -151,7 +151,7 @@ static const struct regmap_config tps65090_regmap_config = { .val_bits = 8, .max_register = TPS65090_MAX_REG, .num_reg_defaults_raw = TPS65090_NUM_REGS, - .cache_type = REGCACHE_RBTREE, + .cache_type = REGCACHE_MAPLE, .volatile_reg = is_volatile_reg, }; diff --git a/drivers/mfd/tps65218.c b/drivers/mfd/tps65218.c index 11e4e52b56..427a2b97f1 100644 --- a/drivers/mfd/tps65218.c +++ b/drivers/mfd/tps65218.c @@ -127,7 +127,7 @@ static const struct regmap_access_table tps65218_volatile_table = { static const struct regmap_config tps65218_regmap_config = { .reg_bits = 8, .val_bits = 8, - .cache_type = REGCACHE_RBTREE, + .cache_type = REGCACHE_MAPLE, .volatile_table = &tps65218_volatile_table, }; diff --git a/drivers/mfd/tps6586x.c b/drivers/mfd/tps6586x.c index 55675ceedc..03c65bbf21 100644 --- a/drivers/mfd/tps6586x.c +++ b/drivers/mfd/tps6586x.c @@ -22,6 +22,7 @@ #include <linux/err.h> #include <linux/i2c.h> #include <linux/platform_device.h> +#include <linux/reboot.h> #include <linux/regmap.h> #include <linux/of.h> @@ -29,6 +30,7 @@ #include <linux/mfd/tps6586x.h> #define TPS6586X_SUPPLYENE 0x14 +#define SOFT_RST_BIT BIT(0) #define EXITSLREQ_BIT BIT(1) #define SLEEP_MODE_BIT BIT(3) @@ -454,16 +456,37 @@ static const struct regmap_config tps6586x_regmap_config = { .val_bits = 8, .max_register = TPS6586X_MAX_REGISTER, .volatile_reg = is_volatile_reg, - .cache_type = REGCACHE_RBTREE, + .cache_type = REGCACHE_MAPLE, }; -static struct device *tps6586x_dev; -static void tps6586x_power_off(void) +static int tps6586x_power_off_handler(struct sys_off_data *data) { - if (tps6586x_clr_bits(tps6586x_dev, TPS6586X_SUPPLYENE, EXITSLREQ_BIT)) - return; + int ret; + + /* Put the PMIC into sleep state. This takes at least 20ms. */ + ret = tps6586x_clr_bits(data->dev, TPS6586X_SUPPLYENE, EXITSLREQ_BIT); + if (ret) + return notifier_from_errno(ret); + + ret = tps6586x_set_bits(data->dev, TPS6586X_SUPPLYENE, SLEEP_MODE_BIT); + if (ret) + return notifier_from_errno(ret); + + mdelay(50); + return notifier_from_errno(-ETIME); +} + +static int tps6586x_restart_handler(struct sys_off_data *data) +{ + int ret; + + /* Put the PMIC into hard reboot state. This takes at least 20ms. */ + ret = tps6586x_set_bits(data->dev, TPS6586X_SUPPLYENE, SOFT_RST_BIT); + if (ret) + return notifier_from_errno(ret); - tps6586x_set_bits(tps6586x_dev, TPS6586X_SUPPLYENE, SLEEP_MODE_BIT); + mdelay(50); + return notifier_from_errno(-ETIME); } static void tps6586x_print_version(struct i2c_client *client, int version) @@ -559,9 +582,20 @@ static int tps6586x_i2c_probe(struct i2c_client *client) goto err_add_devs; } - if (pdata->pm_off && !pm_power_off) { - tps6586x_dev = &client->dev; - pm_power_off = tps6586x_power_off; + if (pdata->pm_off) { + ret = devm_register_power_off_handler(&client->dev, &tps6586x_power_off_handler, + NULL); + if (ret) { + dev_err(&client->dev, "register power off handler failed: %d\n", ret); + goto err_add_devs; + } + + ret = devm_register_restart_handler(&client->dev, &tps6586x_restart_handler, + NULL); + if (ret) { + dev_err(&client->dev, "register restart handler failed: %d\n", ret); + goto err_add_devs; + } } return 0; diff --git a/drivers/mfd/tps65910.c b/drivers/mfd/tps65910.c index 41408df171..8fb0384d5a 100644 --- a/drivers/mfd/tps65910.c +++ b/drivers/mfd/tps65910.c @@ -19,7 +19,7 @@ #include <linux/regmap.h> #include <linux/mfd/tps65910.h> #include <linux/of.h> -#include <linux/of_device.h> +#include <linux/property.h> static const struct resource rtc_resources[] = { { @@ -281,7 +281,7 @@ static const struct regmap_config tps65910_regmap_config = { .val_bits = 8, .volatile_reg = is_volatile_reg, .max_register = TPS65910_MAX_REGISTER - 1, - .cache_type = REGCACHE_RBTREE, + .cache_type = REGCACHE_MAPLE, }; static int tps65910_ck32k_init(struct tps65910 *tps65910, @@ -374,16 +374,9 @@ static struct tps65910_board *tps65910_parse_dt(struct i2c_client *client, struct device_node *np = client->dev.of_node; struct tps65910_board *board_info; unsigned int prop; - const struct of_device_id *match; int ret; - match = of_match_device(tps65910_of_match, &client->dev); - if (!match) { - dev_err(&client->dev, "Failed to find matching dt id\n"); - return NULL; - } - - *chip_id = (unsigned long)match->data; + *chip_id = (unsigned long)device_get_match_data(&client->dev); board_info = devm_kzalloc(&client->dev, sizeof(*board_info), GFP_KERNEL); diff --git a/drivers/mfd/tps65912-core.c b/drivers/mfd/tps65912-core.c index 7d994b8a59..2305ea6036 100644 --- a/drivers/mfd/tps65912-core.c +++ b/drivers/mfd/tps65912-core.c @@ -81,7 +81,7 @@ static const struct regmap_access_table tps65912_volatile_table = { const struct regmap_config tps65912_regmap_config = { .reg_bits = 8, .val_bits = 8, - .cache_type = REGCACHE_RBTREE, + .cache_type = REGCACHE_MAPLE, .volatile_table = &tps65912_volatile_table, }; EXPORT_SYMBOL_GPL(tps65912_regmap_config); diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c index ce01a87f8d..6e384a79e3 100644 --- a/drivers/mfd/twl-core.c +++ b/drivers/mfd/twl-core.c @@ -31,6 +31,8 @@ #include <linux/regulator/machine.h> #include <linux/i2c.h> + +#include <linux/mfd/core.h> #include <linux/mfd/twl.h> /* Register descriptions for audio */ @@ -312,7 +314,7 @@ static const struct regmap_config twl4030_regmap_config[4] = { .reg_defaults = twl4030_49_defaults, .num_reg_defaults = ARRAY_SIZE(twl4030_49_defaults), - .cache_type = REGCACHE_RBTREE, + .cache_type = REGCACHE_MAPLE, }, { /* Address 0x4a */ @@ -690,6 +692,10 @@ static struct of_dev_auxdata twl_auxdata_lookup[] = { { /* sentinel */ }, }; +static const struct mfd_cell twl6032_cells[] = { + { .name = "twl6032-clk" }, +}; + /* NOTE: This driver only handles a single twl4030/tps659x0 chip */ static int twl_probe(struct i2c_client *client) @@ -836,6 +842,16 @@ twl_probe(struct i2c_client *client) TWL4030_DCDC_GLOBAL_CFG); } + if (id->driver_data == (TWL6030_CLASS | TWL6032_SUBCLASS)) { + status = devm_mfd_add_devices(&client->dev, + PLATFORM_DEVID_NONE, + twl6032_cells, + ARRAY_SIZE(twl6032_cells), + NULL, 0, NULL); + if (status < 0) + goto free; + } + status = of_platform_populate(node, NULL, twl_auxdata_lookup, &client->dev); diff --git a/drivers/mfd/twl4030-power.c b/drivers/mfd/twl4030-power.c index e35b0f788c..1595e9c761 100644 --- a/drivers/mfd/twl4030-power.c +++ b/drivers/mfd/twl4030-power.c @@ -27,8 +27,8 @@ #include <linux/pm.h> #include <linux/mfd/twl.h> #include <linux/platform_device.h> +#include <linux/property.h> #include <linux/of.h> -#include <linux/of_device.h> #include <asm/mach-types.h> @@ -883,7 +883,6 @@ static int twl4030_power_probe(struct platform_device *pdev) { const struct twl4030_power_data *pdata = dev_get_platdata(&pdev->dev); struct device_node *node = pdev->dev.of_node; - const struct of_device_id *match; int err = 0; int err2 = 0; u8 val; @@ -904,10 +903,8 @@ static int twl4030_power_probe(struct platform_device *pdev) return err; } - match = of_match_device(of_match_ptr(twl4030_power_of_match), - &pdev->dev); - if (match && match->data) - pdata = match->data; + if (node) + pdata = device_get_match_data(&pdev->dev); if (pdata) { err = twl4030_power_configure_scripts(pdata); diff --git a/drivers/mfd/twl6030-irq.c b/drivers/mfd/twl6030-irq.c index 3c03681c12..f9fce8408c 100644 --- a/drivers/mfd/twl6030-irq.c +++ b/drivers/mfd/twl6030-irq.c @@ -24,10 +24,10 @@ #include <linux/kthread.h> #include <linux/mfd/twl.h> #include <linux/platform_device.h> +#include <linux/property.h> #include <linux/suspend.h> #include <linux/of.h> #include <linux/irqdomain.h> -#include <linux/of_device.h> #include "twl-core.h" @@ -368,10 +368,10 @@ int twl6030_init_irq(struct device *dev, int irq_num) int nr_irqs; int status; u8 mask[3]; - const struct of_device_id *of_id; + const int *irq_tbl; - of_id = of_match_device(twl6030_of_match, dev); - if (!of_id || !of_id->data) { + irq_tbl = device_get_match_data(dev); + if (!irq_tbl) { dev_err(dev, "Unknown TWL device model\n"); return -EINVAL; } @@ -409,7 +409,7 @@ int twl6030_init_irq(struct device *dev, int irq_num) twl6030_irq->pm_nb.notifier_call = twl6030_irq_pm_notifier; atomic_set(&twl6030_irq->wakeirqs, 0); - twl6030_irq->irq_mapping_tbl = of_id->data; + twl6030_irq->irq_mapping_tbl = irq_tbl; twl6030_irq->irq_domain = irq_domain_add_linear(node, nr_irqs, diff --git a/drivers/mfd/wcd934x.c b/drivers/mfd/wcd934x.c index 6b942d5270..7b9873b72c 100644 --- a/drivers/mfd/wcd934x.c +++ b/drivers/mfd/wcd934x.c @@ -112,7 +112,7 @@ static const struct regmap_range_cfg wcd934x_ranges[] = { static struct regmap_config wcd934x_regmap_config = { .reg_bits = 16, .val_bits = 8, - .cache_type = REGCACHE_RBTREE, + .cache_type = REGCACHE_MAPLE, .max_register = 0xffff, .can_multi_write = true, .ranges = wcd934x_ranges, diff --git a/drivers/mfd/wm831x-i2c.c b/drivers/mfd/wm831x-i2c.c index 694ddbbf03..9bee007f9c 100644 --- a/drivers/mfd/wm831x-i2c.c +++ b/drivers/mfd/wm831x-i2c.c @@ -15,7 +15,6 @@ #include <linux/slab.h> #include <linux/err.h> #include <linux/of.h> -#include <linux/of_device.h> #include <linux/regmap.h> #include <linux/mfd/wm831x/core.h> @@ -23,22 +22,15 @@ static int wm831x_i2c_probe(struct i2c_client *i2c) { - const struct i2c_device_id *id = i2c_client_get_device_id(i2c); struct wm831x_pdata *pdata = dev_get_platdata(&i2c->dev); - const struct of_device_id *of_id; struct wm831x *wm831x; enum wm831x_parent type; int ret; - if (i2c->dev.of_node) { - of_id = of_match_device(wm831x_of_match, &i2c->dev); - if (!of_id) { - dev_err(&i2c->dev, "Failed to match device\n"); - return -ENODEV; - } - type = (uintptr_t)of_id->data; - } else { - type = (enum wm831x_parent)id->driver_data; + type = (uintptr_t)i2c_get_match_data(i2c); + if (!type) { + dev_err(&i2c->dev, "Failed to match device\n"); + return -ENODEV; } wm831x = devm_kzalloc(&i2c->dev, sizeof(struct wm831x), GFP_KERNEL); diff --git a/drivers/mfd/wm831x-spi.c b/drivers/mfd/wm831x-spi.c index 76be7ef5c9..54c8726791 100644 --- a/drivers/mfd/wm831x-spi.c +++ b/drivers/mfd/wm831x-spi.c @@ -10,7 +10,6 @@ #include <linux/kernel.h> #include <linux/init.h> #include <linux/of.h> -#include <linux/of_device.h> #include <linux/pm.h> #include <linux/spi/spi.h> #include <linux/regmap.h> @@ -21,21 +20,14 @@ static int wm831x_spi_probe(struct spi_device *spi) { struct wm831x_pdata *pdata = dev_get_platdata(&spi->dev); - const struct spi_device_id *id = spi_get_device_id(spi); - const struct of_device_id *of_id; struct wm831x *wm831x; enum wm831x_parent type; int ret; - if (spi->dev.of_node) { - of_id = of_match_device(wm831x_of_match, &spi->dev); - if (!of_id) { - dev_err(&spi->dev, "Failed to match device\n"); - return -ENODEV; - } - type = (uintptr_t)of_id->data; - } else { - type = (enum wm831x_parent)id->driver_data; + type = (uintptr_t)spi_get_device_match_data(spi); + if (!type) { + dev_err(&spi->dev, "Failed to match device\n"); + return -ENODEV; } wm831x = devm_kzalloc(&spi->dev, sizeof(struct wm831x), GFP_KERNEL); diff --git a/drivers/mfd/wm8994-core.c b/drivers/mfd/wm8994-core.c index aba7af6881..d5ac066f9d 100644 --- a/drivers/mfd/wm8994-core.c +++ b/drivers/mfd/wm8994-core.c @@ -15,7 +15,6 @@ #include <linux/delay.h> #include <linux/mfd/core.h> #include <linux/of.h> -#include <linux/of_device.h> #include <linux/pm_runtime.h> #include <linux/regmap.h> #include <linux/regulator/consumer.h> @@ -612,8 +611,6 @@ MODULE_DEVICE_TABLE(of, wm8994_of_match); static int wm8994_i2c_probe(struct i2c_client *i2c) { - const struct i2c_device_id *id = i2c_client_get_device_id(i2c); - const struct of_device_id *of_id; struct wm8994 *wm8994; int ret; @@ -625,13 +622,7 @@ static int wm8994_i2c_probe(struct i2c_client *i2c) wm8994->dev = &i2c->dev; wm8994->irq = i2c->irq; - if (i2c->dev.of_node) { - of_id = of_match_device(wm8994_of_match, &i2c->dev); - if (of_id) - wm8994->type = (uintptr_t)of_id->data; - } else { - wm8994->type = id->driver_data; - } + wm8994->type = (enum wm8994_type)i2c_get_match_data(i2c); wm8994->regmap = devm_regmap_init_i2c(i2c, &wm8994_base_regmap_config); if (IS_ERR(wm8994->regmap)) { |