Commit 420b54de25828c45f3fc1f12d52d9657f5e90a53
Committed by
Lee Jones
1 parent
bc0195aad0
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>
Showing 5 changed files with 57 additions and 20 deletions Side-by-side Diff
drivers/mfd/lpc_ich.c
... | ... | @@ -66,6 +66,7 @@ |
66 | 66 | #include <linux/pci.h> |
67 | 67 | #include <linux/mfd/core.h> |
68 | 68 | #include <linux/mfd/lpc_ich.h> |
69 | +#include <linux/platform_data/itco_wdt.h> | |
69 | 70 | |
70 | 71 | #define ACPIBASE 0x40 |
71 | 72 | #define ACPIBASE_GPE_OFF 0x28 |
72 | 73 | |
73 | 74 | |
74 | 75 | |
... | ... | @@ -835,10 +836,32 @@ |
835 | 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 | 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]; | |
841 | 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]; | |
864 | + | |
842 | 865 | cell->platform_data = &lpc_chipset_info[priv->chipset]; |
843 | 866 | cell->pdata_size = sizeof(struct lpc_ich_info); |
844 | 867 | } |
... | ... | @@ -933,7 +956,7 @@ |
933 | 956 | lpc_chipset_info[priv->chipset].use_gpio = ret; |
934 | 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 | 960 | ret = mfd_add_devices(&dev->dev, PLATFORM_DEVID_AUTO, |
938 | 961 | &lpc_ich_cells[LPC_GPIO], 1, NULL, 0, NULL); |
939 | 962 | |
... | ... | @@ -1007,7 +1030,10 @@ |
1007 | 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 | 1037 | ret = mfd_add_devices(&dev->dev, PLATFORM_DEVID_AUTO, |
1012 | 1038 | &lpc_ich_cells[LPC_WDT], 1, NULL, 0, NULL); |
1013 | 1039 |
drivers/platform/x86/intel_pmc_ipc.c
... | ... | @@ -33,7 +33,7 @@ |
33 | 33 | #include <linux/suspend.h> |
34 | 34 | #include <linux/acpi.h> |
35 | 35 | #include <asm/intel_pmc_ipc.h> |
36 | -#include <linux/mfd/lpc_ich.h> | |
36 | +#include <linux/platform_data/itco_wdt.h> | |
37 | 37 | |
38 | 38 | /* |
39 | 39 | * IPC registers |
40 | 40 | |
... | ... | @@ -460,9 +460,9 @@ |
460 | 460 | }, |
461 | 461 | }; |
462 | 462 | |
463 | -static struct lpc_ich_info tco_info = { | |
463 | +static struct itco_wdt_platform_data tco_info = { | |
464 | 464 | .name = "Apollo Lake SoC", |
465 | - .iTCO_version = 3, | |
465 | + .version = 3, | |
466 | 466 | }; |
467 | 467 | |
468 | 468 | static int ipc_create_punit_device(void) |
... | ... | @@ -539,8 +539,7 @@ |
539 | 539 | goto err; |
540 | 540 | } |
541 | 541 | |
542 | - ret = platform_device_add_data(pdev, &tco_info, | |
543 | - sizeof(struct lpc_ich_info)); | |
542 | + ret = platform_device_add_data(pdev, &tco_info, sizeof(tco_info)); | |
544 | 543 | if (ret) { |
545 | 544 | dev_err(ipcdev.dev, "Failed to add tco platform data\n"); |
546 | 545 | goto err; |
drivers/watchdog/iTCO_wdt.c
... | ... | @@ -66,8 +66,7 @@ |
66 | 66 | #include <linux/spinlock.h> /* For spin_lock/spin_unlock/... */ |
67 | 67 | #include <linux/uaccess.h> /* For copy_to_user/put_user/... */ |
68 | 68 | #include <linux/io.h> /* For inb/outb/... */ |
69 | -#include <linux/mfd/core.h> | |
70 | -#include <linux/mfd/lpc_ich.h> | |
69 | +#include <linux/platform_data/itco_wdt.h> | |
71 | 70 | |
72 | 71 | #include "iTCO_vendor.h" |
73 | 72 | |
74 | 73 | |
... | ... | @@ -418,9 +417,9 @@ |
418 | 417 | { |
419 | 418 | int ret = -ENODEV; |
420 | 419 | unsigned long val32; |
421 | - struct lpc_ich_info *ich_info = dev_get_platdata(&dev->dev); | |
420 | + struct itco_wdt_platform_data *pdata = dev_get_platdata(&dev->dev); | |
422 | 421 | |
423 | - if (!ich_info) | |
422 | + if (!pdata) | |
424 | 423 | goto out; |
425 | 424 | |
426 | 425 | spin_lock_init(&iTCO_wdt_private.io_lock); |
... | ... | @@ -435,7 +434,7 @@ |
435 | 434 | if (!iTCO_wdt_private.smi_res) |
436 | 435 | goto out; |
437 | 436 | |
438 | - iTCO_wdt_private.iTCO_version = ich_info->iTCO_version; | |
437 | + iTCO_wdt_private.iTCO_version = pdata->version; | |
439 | 438 | iTCO_wdt_private.dev = dev; |
440 | 439 | iTCO_wdt_private.pdev = to_pci_dev(dev->dev.parent); |
441 | 440 | |
... | ... | @@ -501,7 +500,7 @@ |
501 | 500 | } |
502 | 501 | |
503 | 502 | pr_info("Found a %s TCO device (Version=%d, TCOBASE=0x%04llx)\n", |
504 | - ich_info->name, ich_info->iTCO_version, (u64)TCOBASE); | |
503 | + pdata->name, pdata->version, (u64)TCOBASE); | |
505 | 504 | |
506 | 505 | /* Clear out the (probably old) status */ |
507 | 506 | if (iTCO_wdt_private.iTCO_version == 3) { |
include/linux/mfd/lpc_ich.h
... | ... | @@ -20,12 +20,6 @@ |
20 | 20 | #ifndef LPC_ICH_H |
21 | 21 | #define LPC_ICH_H |
22 | 22 | |
23 | -/* Watchdog resources */ | |
24 | -#define ICH_RES_IO_TCO 0 | |
25 | -#define ICH_RES_IO_SMI 1 | |
26 | -#define ICH_RES_MEM_OFF 2 | |
27 | -#define ICH_RES_MEM_GCS_PMC 0 | |
28 | - | |
29 | 23 | /* GPIO resources */ |
30 | 24 | #define ICH_RES_GPIO 0 |
31 | 25 | #define ICH_RES_GPE0 1 |
include/linux/platform_data/itco_wdt.h
1 | +/* | |
2 | + * Platform data for the Intel TCO Watchdog | |
3 | + */ | |
4 | + | |
5 | +#ifndef _ITCO_WDT_H_ | |
6 | +#define _ITCO_WDT_H_ | |
7 | + | |
8 | +/* Watchdog resources */ | |
9 | +#define ICH_RES_IO_TCO 0 | |
10 | +#define ICH_RES_IO_SMI 1 | |
11 | +#define ICH_RES_MEM_OFF 2 | |
12 | +#define ICH_RES_MEM_GCS_PMC 0 | |
13 | + | |
14 | +struct itco_wdt_platform_data { | |
15 | + char name[32]; | |
16 | + unsigned int version; | |
17 | +}; | |
18 | + | |
19 | +#endif /* _ITCO_WDT_H_ */ |