aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/platform/x86/intel_pmc_ipc.c
diff options
context:
space:
mode:
authorSouvik Kumar Chakravarty <souvik.k.chakravarty@intel.com>2016-01-12 05:32:54 -0500
committerDarren Hart <dvhart@linux.intel.com>2016-01-19 20:35:51 -0500
commit48c1917088ba00af25a0afc13de7403d6a80b06d (patch)
tree3d31fb78d937618b04decc5d28fc6c162f7251e6 /drivers/platform/x86/intel_pmc_ipc.c
parent9d16b482b059d784137881f3ec4bb121c5a2e6ee (diff)
platform:x86: Add Intel telemetry platform device
Telemetry Device is created by the pmc_ipc driver. Resources are populated according SSRAM region as indicated by the BIOS tables. Signed-off-by: Souvik Kumar Chakravarty <souvik.k.chakravarty@intel.com> Signed-off-by: Darren Hart <dvhart@linux.intel.com>
Diffstat (limited to 'drivers/platform/x86/intel_pmc_ipc.c')
-rw-r--r--drivers/platform/x86/intel_pmc_ipc.c96
1 files changed, 96 insertions, 0 deletions
diff --git a/drivers/platform/x86/intel_pmc_ipc.c b/drivers/platform/x86/intel_pmc_ipc.c
index ca69135dc2dc..092519e37de6 100644
--- a/drivers/platform/x86/intel_pmc_ipc.c
+++ b/drivers/platform/x86/intel_pmc_ipc.c
@@ -70,6 +70,7 @@
70#define PLAT_RESOURCE_GCR_SIZE 0x1000 70#define PLAT_RESOURCE_GCR_SIZE 0x1000
71#define PLAT_RESOURCE_BIOS_DATA_INDEX 1 71#define PLAT_RESOURCE_BIOS_DATA_INDEX 1
72#define PLAT_RESOURCE_BIOS_IFACE_INDEX 2 72#define PLAT_RESOURCE_BIOS_IFACE_INDEX 2
73#define PLAT_RESOURCE_TELEM_SSRAM_INDEX 3
73#define PLAT_RESOURCE_ISP_DATA_INDEX 4 74#define PLAT_RESOURCE_ISP_DATA_INDEX 4
74#define PLAT_RESOURCE_ISP_IFACE_INDEX 5 75#define PLAT_RESOURCE_ISP_IFACE_INDEX 5
75#define PLAT_RESOURCE_GTD_DATA_INDEX 6 76#define PLAT_RESOURCE_GTD_DATA_INDEX 6
@@ -88,6 +89,10 @@
88#define TCO_BASE_OFFSET 0x60 89#define TCO_BASE_OFFSET 0x60
89#define TCO_REGS_SIZE 16 90#define TCO_REGS_SIZE 16
90#define PUNIT_DEVICE_NAME "intel_punit_ipc" 91#define PUNIT_DEVICE_NAME "intel_punit_ipc"
92#define TELEMETRY_DEVICE_NAME "intel_telemetry"
93#define TELEM_SSRAM_SIZE 240
94#define TELEM_PMC_SSRAM_OFFSET 0x1B00
95#define TELEM_PUNIT_SSRAM_OFFSET 0x1A00
91 96
92static const int iTCO_version = 3; 97static const int iTCO_version = 3;
93 98
@@ -110,6 +115,14 @@ static struct intel_pmc_ipc_dev {
110 115
111 /* punit */ 116 /* punit */
112 struct platform_device *punit_dev; 117 struct platform_device *punit_dev;
118
119 /* Telemetry */
120 resource_size_t telem_pmc_ssram_base;
121 resource_size_t telem_punit_ssram_base;
122 int telem_pmc_ssram_size;
123 int telem_punit_ssram_size;
124 u8 telem_res_inval;
125 struct platform_device *telemetry_dev;
113} ipcdev; 126} ipcdev;
114 127
115static char *ipc_err_sources[] = { 128static char *ipc_err_sources[] = {
@@ -491,6 +504,18 @@ static struct itco_wdt_platform_data tco_info = {
491 .version = 3, 504 .version = 3,
492}; 505};
493 506
507#define TELEMETRY_RESOURCE_PUNIT_SSRAM 0
508#define TELEMETRY_RESOURCE_PMC_SSRAM 1
509static struct resource telemetry_res[] = {
510 /*Telemetry*/
511 {
512 .flags = IORESOURCE_MEM,
513 },
514 {
515 .flags = IORESOURCE_MEM,
516 },
517};
518
494static int ipc_create_punit_device(void) 519static int ipc_create_punit_device(void)
495{ 520{
496 struct platform_device *pdev; 521 struct platform_device *pdev;
@@ -574,6 +599,51 @@ err:
574 return ret; 599 return ret;
575} 600}
576 601
602static int ipc_create_telemetry_device(void)
603{
604 struct platform_device *pdev;
605 struct resource *res;
606 int ret;
607
608 pdev = platform_device_alloc(TELEMETRY_DEVICE_NAME, -1);
609 if (!pdev) {
610 dev_err(ipcdev.dev,
611 "Failed to allocate telemetry platform device\n");
612 return -ENOMEM;
613 }
614
615 pdev->dev.parent = ipcdev.dev;
616
617 res = telemetry_res + TELEMETRY_RESOURCE_PUNIT_SSRAM;
618 res->start = ipcdev.telem_punit_ssram_base;
619 res->end = res->start + ipcdev.telem_punit_ssram_size - 1;
620
621 res = telemetry_res + TELEMETRY_RESOURCE_PMC_SSRAM;
622 res->start = ipcdev.telem_pmc_ssram_base;
623 res->end = res->start + ipcdev.telem_pmc_ssram_size - 1;
624
625 ret = platform_device_add_resources(pdev, telemetry_res,
626 ARRAY_SIZE(telemetry_res));
627 if (ret) {
628 dev_err(ipcdev.dev,
629 "Failed to add telemetry platform resources\n");
630 goto err;
631 }
632
633 ret = platform_device_add(pdev);
634 if (ret) {
635 dev_err(ipcdev.dev,
636 "Failed to add telemetry platform device\n");
637 goto err;
638 }
639 ipcdev.telemetry_dev = pdev;
640
641 return 0;
642err:
643 platform_device_put(pdev);
644 return ret;
645}
646
577static int ipc_create_pmc_devices(void) 647static int ipc_create_pmc_devices(void)
578{ 648{
579 int ret; 649 int ret;
@@ -588,6 +658,14 @@ static int ipc_create_pmc_devices(void)
588 dev_err(ipcdev.dev, "Failed to add punit platform device\n"); 658 dev_err(ipcdev.dev, "Failed to add punit platform device\n");
589 platform_device_unregister(ipcdev.tco_dev); 659 platform_device_unregister(ipcdev.tco_dev);
590 } 660 }
661
662 if (!ipcdev.telem_res_inval) {
663 ret = ipc_create_telemetry_device();
664 if (ret)
665 dev_warn(ipcdev.dev,
666 "Failed to add telemetry platform device\n");
667 }
668
591 return ret; 669 return ret;
592} 670}
593 671
@@ -692,6 +770,22 @@ static int ipc_plat_get_res(struct platform_device *pdev)
692 ipcdev.gcr_size = PLAT_RESOURCE_GCR_SIZE; 770 ipcdev.gcr_size = PLAT_RESOURCE_GCR_SIZE;
693 dev_info(&pdev->dev, "ipc res: %pR\n", res); 771 dev_info(&pdev->dev, "ipc res: %pR\n", res);
694 772
773 ipcdev.telem_res_inval = 0;
774 res = platform_get_resource(pdev, IORESOURCE_MEM,
775 PLAT_RESOURCE_TELEM_SSRAM_INDEX);
776 if (!res) {
777 dev_err(&pdev->dev, "Failed to get telemetry ssram resource\n");
778 ipcdev.telem_res_inval = 1;
779 } else {
780 ipcdev.telem_punit_ssram_base = res->start +
781 TELEM_PUNIT_SSRAM_OFFSET;
782 ipcdev.telem_punit_ssram_size = TELEM_SSRAM_SIZE;
783 ipcdev.telem_pmc_ssram_base = res->start +
784 TELEM_PMC_SSRAM_OFFSET;
785 ipcdev.telem_pmc_ssram_size = TELEM_SSRAM_SIZE;
786 dev_info(&pdev->dev, "telemetry ssram res: %pR\n", res);
787 }
788
695 return 0; 789 return 0;
696} 790}
697 791
@@ -749,6 +843,7 @@ err_sys:
749err_irq: 843err_irq:
750 platform_device_unregister(ipcdev.tco_dev); 844 platform_device_unregister(ipcdev.tco_dev);
751 platform_device_unregister(ipcdev.punit_dev); 845 platform_device_unregister(ipcdev.punit_dev);
846 platform_device_unregister(ipcdev.telemetry_dev);
752err_device: 847err_device:
753 iounmap(ipcdev.ipc_base); 848 iounmap(ipcdev.ipc_base);
754 res = platform_get_resource(pdev, IORESOURCE_MEM, 849 res = platform_get_resource(pdev, IORESOURCE_MEM,
@@ -766,6 +861,7 @@ static int ipc_plat_remove(struct platform_device *pdev)
766 free_irq(ipcdev.irq, &ipcdev); 861 free_irq(ipcdev.irq, &ipcdev);
767 platform_device_unregister(ipcdev.tco_dev); 862 platform_device_unregister(ipcdev.tco_dev);
768 platform_device_unregister(ipcdev.punit_dev); 863 platform_device_unregister(ipcdev.punit_dev);
864 platform_device_unregister(ipcdev.telemetry_dev);
769 iounmap(ipcdev.ipc_base); 865 iounmap(ipcdev.ipc_base);
770 res = platform_get_resource(pdev, IORESOURCE_MEM, 866 res = platform_get_resource(pdev, IORESOURCE_MEM,
771 PLAT_RESOURCE_IPC_INDEX); 867 PLAT_RESOURCE_IPC_INDEX);