diff options
author | Matt Fleming <matt.fleming@intel.com> | 2015-08-06 08:46:24 -0400 |
---|---|---|
committer | Lee Jones <lee.jones@linaro.org> | 2015-08-11 10:03:21 -0400 |
commit | 420b54de25828c45f3fc1f12d52d9657f5e90a53 (patch) | |
tree | 4a7b05b69ebabf2ef477cb39f29b9f747246b80e /drivers/mfd/lpc_ich.c | |
parent | bc0195aad0daa2ad5b0d76cce22b167bc3435590 (diff) |
mfd: watchdog: iTCO_wdt: Expose watchdog properties using platform data
Intel Sunrisepoint (Skylake PCH) has the iTCO watchdog accessible across
the SMBus, unlike previous generations of PCH/ICH where it was on the
LPC bus. Because it's on the SMBus, it doesn't make sense to pass around
a 'struct lpc_ich_info', and leaking the type of bus into the iTCO
watchdog driver is kind of backwards anyway.
This change introduces a new 'struct itco_wdt_platform_data' for use
inside the iTCO watchdog driver and by the upcoming Intel Sunrisepoint
code, which neatly avoids having to include lpc_ich headers in the i801
i2c driver.
This change is overdue because lpc_ich_info has already found its way
into other TCO watchdog users, notably the intel_pmc_ipc driver where
the watchdog actually isn't on the LPC bus as far as I can see.
A simple translation layer is provided for converting from the existing
'struct lpc_ich_info' inside the lpc_ich mfd driver.
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
Acked-by: Darren Hart <dvhart@linux.intel.com> [drivers/x86 refactoring]
Reviewed-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
Diffstat (limited to 'drivers/mfd/lpc_ich.c')
-rw-r--r-- | drivers/mfd/lpc_ich.c | 32 |
1 files changed, 29 insertions, 3 deletions
diff --git a/drivers/mfd/lpc_ich.c b/drivers/mfd/lpc_ich.c index 8de34398abc0..c5a9a08b5dfb 100644 --- a/drivers/mfd/lpc_ich.c +++ b/drivers/mfd/lpc_ich.c | |||
@@ -66,6 +66,7 @@ | |||
66 | #include <linux/pci.h> | 66 | #include <linux/pci.h> |
67 | #include <linux/mfd/core.h> | 67 | #include <linux/mfd/core.h> |
68 | #include <linux/mfd/lpc_ich.h> | 68 | #include <linux/mfd/lpc_ich.h> |
69 | #include <linux/platform_data/itco_wdt.h> | ||
69 | 70 | ||
70 | #define ACPIBASE 0x40 | 71 | #define ACPIBASE 0x40 |
71 | #define ACPIBASE_GPE_OFF 0x28 | 72 | #define ACPIBASE_GPE_OFF 0x28 |
@@ -835,9 +836,31 @@ static void lpc_ich_enable_pmc_space(struct pci_dev *dev) | |||
835 | priv->actrl_pbase_save = reg_save; | 836 | priv->actrl_pbase_save = reg_save; |
836 | } | 837 | } |
837 | 838 | ||
838 | static void lpc_ich_finalize_cell(struct pci_dev *dev, struct mfd_cell *cell) | 839 | static int lpc_ich_finalize_wdt_cell(struct pci_dev *dev) |
839 | { | 840 | { |
841 | struct itco_wdt_platform_data *pdata; | ||
840 | struct lpc_ich_priv *priv = pci_get_drvdata(dev); | 842 | struct lpc_ich_priv *priv = pci_get_drvdata(dev); |
843 | struct lpc_ich_info *info; | ||
844 | struct mfd_cell *cell = &lpc_ich_cells[LPC_WDT]; | ||
845 | |||
846 | pdata = devm_kzalloc(&dev->dev, sizeof(*pdata), GFP_KERNEL); | ||
847 | if (!pdata) | ||
848 | return -ENOMEM; | ||
849 | |||
850 | info = &lpc_chipset_info[priv->chipset]; | ||
851 | |||
852 | pdata->version = info->iTCO_version; | ||
853 | strlcpy(pdata->name, info->name, sizeof(pdata->name)); | ||
854 | |||
855 | cell->platform_data = pdata; | ||
856 | cell->pdata_size = sizeof(*pdata); | ||
857 | return 0; | ||
858 | } | ||
859 | |||
860 | static void lpc_ich_finalize_gpio_cell(struct pci_dev *dev) | ||
861 | { | ||
862 | struct lpc_ich_priv *priv = pci_get_drvdata(dev); | ||
863 | struct mfd_cell *cell = &lpc_ich_cells[LPC_GPIO]; | ||
841 | 864 | ||
842 | cell->platform_data = &lpc_chipset_info[priv->chipset]; | 865 | cell->platform_data = &lpc_chipset_info[priv->chipset]; |
843 | cell->pdata_size = sizeof(struct lpc_ich_info); | 866 | cell->pdata_size = sizeof(struct lpc_ich_info); |
@@ -933,7 +956,7 @@ gpe0_done: | |||
933 | lpc_chipset_info[priv->chipset].use_gpio = ret; | 956 | lpc_chipset_info[priv->chipset].use_gpio = ret; |
934 | lpc_ich_enable_gpio_space(dev); | 957 | lpc_ich_enable_gpio_space(dev); |
935 | 958 | ||
936 | lpc_ich_finalize_cell(dev, &lpc_ich_cells[LPC_GPIO]); | 959 | lpc_ich_finalize_gpio_cell(dev); |
937 | ret = mfd_add_devices(&dev->dev, PLATFORM_DEVID_AUTO, | 960 | ret = mfd_add_devices(&dev->dev, PLATFORM_DEVID_AUTO, |
938 | &lpc_ich_cells[LPC_GPIO], 1, NULL, 0, NULL); | 961 | &lpc_ich_cells[LPC_GPIO], 1, NULL, 0, NULL); |
939 | 962 | ||
@@ -1007,7 +1030,10 @@ static int lpc_ich_init_wdt(struct pci_dev *dev) | |||
1007 | res->end = base_addr + ACPIBASE_PMC_END; | 1030 | res->end = base_addr + ACPIBASE_PMC_END; |
1008 | } | 1031 | } |
1009 | 1032 | ||
1010 | lpc_ich_finalize_cell(dev, &lpc_ich_cells[LPC_WDT]); | 1033 | ret = lpc_ich_finalize_wdt_cell(dev); |
1034 | if (ret) | ||
1035 | goto wdt_done; | ||
1036 | |||
1011 | ret = mfd_add_devices(&dev->dev, PLATFORM_DEVID_AUTO, | 1037 | ret = mfd_add_devices(&dev->dev, PLATFORM_DEVID_AUTO, |
1012 | &lpc_ich_cells[LPC_WDT], 1, NULL, 0, NULL); | 1038 | &lpc_ich_cells[LPC_WDT], 1, NULL, 0, NULL); |
1013 | 1039 | ||