aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/platform/x86/intel_pmc_ipc.c
diff options
context:
space:
mode:
authorKuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>2017-04-09 18:00:20 -0400
committerAndy Shevchenko <andriy.shevchenko@linux.intel.com>2017-04-28 14:51:28 -0400
commit9d855d468dc655d10be6cb52e36aa0bbfa6f515d (patch)
tree2eae0c6d7165c0e28c1c33f0f36a18ea4cee1661 /drivers/platform/x86/intel_pmc_ipc.c
parent140c91b26ebc48d80c6ac3ef06953b17d7fb3785 (diff)
platform/x86: intel_pmc_ipc: Fix iTCO_wdt GCS memory mapping failure
iTCO_wdt driver need access to PMC_CFG GCR register to modify the noreboot setting. Currently, this is done by passing PMC_CFG reg address as memory resource to watchdog driver and allowing it directly modify the PMC_CFG register. But currently PMC driver also has requirement to memory map the entire GCR register space in this driver. This causes mem request failure in watchdog driver. So this patch fixes this issue by adding API to update noreboot flag and passes them to watchdog driver via platform data. Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Diffstat (limited to 'drivers/platform/x86/intel_pmc_ipc.c')
-rw-r--r--drivers/platform/x86/intel_pmc_ipc.c29
1 files changed, 17 insertions, 12 deletions
diff --git a/drivers/platform/x86/intel_pmc_ipc.c b/drivers/platform/x86/intel_pmc_ipc.c
index a0c773b3910e..0a39b0f17bbe 100644
--- a/drivers/platform/x86/intel_pmc_ipc.c
+++ b/drivers/platform/x86/intel_pmc_ipc.c
@@ -112,6 +112,13 @@
112#define TCO_PMC_OFFSET 0x8 112#define TCO_PMC_OFFSET 0x8
113#define TCO_PMC_SIZE 0x4 113#define TCO_PMC_SIZE 0x4
114 114
115/* PMC register bit definitions */
116
117/* PMC_CFG_REG bit masks */
118#define PMC_CFG_NO_REBOOT_MASK (1 << 4)
119#define PMC_CFG_NO_REBOOT_EN (1 << 4)
120#define PMC_CFG_NO_REBOOT_DIS (0 << 4)
121
115static struct intel_pmc_ipc_dev { 122static struct intel_pmc_ipc_dev {
116 struct device *dev; 123 struct device *dev;
117 void __iomem *ipc_base; 124 void __iomem *ipc_base;
@@ -126,8 +133,6 @@ static struct intel_pmc_ipc_dev {
126 struct platform_device *tco_dev; 133 struct platform_device *tco_dev;
127 134
128 /* gcr */ 135 /* gcr */
129 resource_size_t gcr_base;
130 int gcr_size;
131 void __iomem *gcr_mem_base; 136 void __iomem *gcr_mem_base;
132 bool has_gcr_regs; 137 bool has_gcr_regs;
133 138
@@ -313,6 +318,14 @@ gcr_ipc_unlock:
313} 318}
314EXPORT_SYMBOL_GPL(intel_pmc_gcr_update); 319EXPORT_SYMBOL_GPL(intel_pmc_gcr_update);
315 320
321static int update_no_reboot_bit(void *priv, bool set)
322{
323 u32 value = set ? PMC_CFG_NO_REBOOT_EN : PMC_CFG_NO_REBOOT_DIS;
324
325 return intel_pmc_gcr_update(PMC_GCR_PMC_CFG_REG,
326 PMC_CFG_NO_REBOOT_MASK, value);
327}
328
316static int intel_pmc_ipc_check_status(void) 329static int intel_pmc_ipc_check_status(void)
317{ 330{
318 int status; 331 int status;
@@ -630,15 +643,13 @@ static struct resource tco_res[] = {
630 { 643 {
631 .flags = IORESOURCE_IO, 644 .flags = IORESOURCE_IO,
632 }, 645 },
633 /* GCS */
634 {
635 .flags = IORESOURCE_MEM,
636 },
637}; 646};
638 647
639static struct itco_wdt_platform_data tco_info = { 648static struct itco_wdt_platform_data tco_info = {
640 .name = "Apollo Lake SoC", 649 .name = "Apollo Lake SoC",
641 .version = 5, 650 .version = 5,
651 .no_reboot_priv = &ipcdev,
652 .update_no_reboot_bit = update_no_reboot_bit,
642}; 653};
643 654
644#define TELEMETRY_RESOURCE_PUNIT_SSRAM 0 655#define TELEMETRY_RESOURCE_PUNIT_SSRAM 0
@@ -695,10 +706,6 @@ static int ipc_create_tco_device(void)
695 res->start = ipcdev.acpi_io_base + SMI_EN_OFFSET; 706 res->start = ipcdev.acpi_io_base + SMI_EN_OFFSET;
696 res->end = res->start + SMI_EN_SIZE - 1; 707 res->end = res->start + SMI_EN_SIZE - 1;
697 708
698 res = tco_res + TCO_RESOURCE_GCR_MEM;
699 res->start = ipcdev.gcr_base + TCO_PMC_OFFSET;
700 res->end = res->start + TCO_PMC_SIZE - 1;
701
702 pdev = platform_device_register_full(&pdevinfo); 709 pdev = platform_device_register_full(&pdevinfo);
703 if (IS_ERR(pdev)) 710 if (IS_ERR(pdev))
704 return PTR_ERR(pdev); 711 return PTR_ERR(pdev);
@@ -860,9 +867,7 @@ static int ipc_plat_get_res(struct platform_device *pdev)
860 } 867 }
861 ipcdev.ipc_base = addr; 868 ipcdev.ipc_base = addr;
862 869
863 ipcdev.gcr_base = res->start + PLAT_RESOURCE_GCR_OFFSET;
864 ipcdev.gcr_mem_base = addr + PLAT_RESOURCE_GCR_OFFSET; 870 ipcdev.gcr_mem_base = addr + PLAT_RESOURCE_GCR_OFFSET;
865 ipcdev.gcr_size = PLAT_RESOURCE_GCR_SIZE;
866 dev_info(&pdev->dev, "ipc res: %pR\n", res); 871 dev_info(&pdev->dev, "ipc res: %pR\n", res);
867 872
868 ipcdev.telem_res_inval = 0; 873 ipcdev.telem_res_inval = 0;