Commit 420b54de25828c45f3fc1f12d52d9657f5e90a53

Authored by Matt Fleming
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_ */