diff --git a/drivers/mfd/lpc_ich.c b/drivers/mfd/lpc_ich.c index 58da6c95c46253a9d6680cdc216f5d1c240a78d6..8b21d0f629c85ea32c0b08cfd3fdcb3f56242b8f 100644 --- a/drivers/mfd/lpc_ich.c +++ b/drivers/mfd/lpc_ich.c @@ -131,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; + 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 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] = { @@ -168,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", @@ -199,6 +217,15 @@ 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, +}; + static struct mfd_cell lpc_ich_spi_cell = { .name = "intel-spi", .num_resources = ARRAY_SIZE(intel_spi_res), @@ -618,6 +645,7 @@ 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_GLK] = { @@ -1156,30 +1184,32 @@ static int lpc_ich_init_wdt(struct pci_dev *dev) 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 +1362,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/include/linux/mfd/lpc_ich.h b/include/linux/mfd/lpc_ich.h index 83621e0ccf330d61f414d97761f28068ebbab3ef..1fbda1f8967db41ba3bacd331e5d18dfa8ebca3c 100644 --- a/include/linux/mfd/lpc_ich.h +++ b/include/linux/mfd/lpc_ich.h @@ -26,11 +26,14 @@ enum lpc_gpio_versions { AVOTON_GPIO, }; +struct lpc_ich_gpio_info; + struct lpc_ich_info { char name[32]; unsigned int iTCO_version; enum lpc_gpio_versions gpio_version; enum intel_spi_type spi_type; + const struct lpc_ich_gpio_info *gpio_info; u8 use_gpio; };