aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/platform/x86/intel_pmc_ipc.c398
1 files changed, 139 insertions, 259 deletions
diff --git a/drivers/platform/x86/intel_pmc_ipc.c b/drivers/platform/x86/intel_pmc_ipc.c
index e03fa31446ca..e36144c337cd 100644
--- a/drivers/platform/x86/intel_pmc_ipc.c
+++ b/drivers/platform/x86/intel_pmc_ipc.c
@@ -20,6 +20,7 @@
20#include <linux/errno.h> 20#include <linux/errno.h>
21#include <linux/init.h> 21#include <linux/init.h>
22#include <linux/device.h> 22#include <linux/device.h>
23#include <linux/mfd/core.h>
23#include <linux/pm.h> 24#include <linux/pm.h>
24#include <linux/pci.h> 25#include <linux/pci.h>
25#include <linux/platform_device.h> 26#include <linux/platform_device.h>
@@ -88,6 +89,7 @@
88#define PLAT_RESOURCE_ISP_IFACE_INDEX 5 89#define PLAT_RESOURCE_ISP_IFACE_INDEX 5
89#define PLAT_RESOURCE_GTD_DATA_INDEX 6 90#define PLAT_RESOURCE_GTD_DATA_INDEX 6
90#define PLAT_RESOURCE_GTD_IFACE_INDEX 7 91#define PLAT_RESOURCE_GTD_IFACE_INDEX 7
92#define PLAT_RESOURCE_MEM_MAX_INDEX 8
91#define PLAT_RESOURCE_ACPI_IO_INDEX 0 93#define PLAT_RESOURCE_ACPI_IO_INDEX 0
92 94
93/* 95/*
@@ -106,8 +108,6 @@
106#define TELEM_SSRAM_SIZE 240 108#define TELEM_SSRAM_SIZE 240
107#define TELEM_PMC_SSRAM_OFFSET 0x1B00 109#define TELEM_PMC_SSRAM_OFFSET 0x1B00
108#define TELEM_PUNIT_SSRAM_OFFSET 0x1A00 110#define TELEM_PUNIT_SSRAM_OFFSET 0x1A00
109#define TCO_PMC_OFFSET 0x8
110#define TCO_PMC_SIZE 0x4
111 111
112/* PMC register bit definitions */ 112/* PMC register bit definitions */
113 113
@@ -124,26 +124,10 @@ static struct intel_pmc_ipc_dev {
124 int cmd; 124 int cmd;
125 struct completion cmd_complete; 125 struct completion cmd_complete;
126 126
127 /* The following PMC BARs share the same ACPI device with the IPC */
128 resource_size_t acpi_io_base;
129 int acpi_io_size;
130 struct platform_device *tco_dev;
131
132 /* gcr */ 127 /* gcr */
133 void __iomem *gcr_mem_base; 128 void __iomem *gcr_mem_base;
134 bool has_gcr_regs; 129 bool has_gcr_regs;
135 spinlock_t gcr_lock; 130 spinlock_t gcr_lock;
136
137 /* punit */
138 struct platform_device *punit_dev;
139
140 /* Telemetry */
141 resource_size_t telem_pmc_ssram_base;
142 resource_size_t telem_punit_ssram_base;
143 int telem_pmc_ssram_size;
144 int telem_punit_ssram_size;
145 u8 telem_res_inval;
146 struct platform_device *telemetry_dev;
147} ipcdev; 131} ipcdev;
148 132
149static char *ipc_err_sources[] = { 133static char *ipc_err_sources[] = {
@@ -508,7 +492,7 @@ static int ipc_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
508 ret = devm_request_irq(&pdev->dev, pdev->irq, ioc, 0, "intel_pmc_ipc", 492 ret = devm_request_irq(&pdev->dev, pdev->irq, ioc, 0, "intel_pmc_ipc",
509 pmc); 493 pmc);
510 if (ret) { 494 if (ret) {
511 dev_err(&pdev->dev, "Failed to request irq\n"); 495 dev_err(&pdev->dev, "Failed to request IRQ\n");
512 return ret; 496 return ret;
513 } 497 }
514 498
@@ -593,44 +577,6 @@ static const struct attribute_group intel_ipc_group = {
593 .attrs = intel_ipc_attrs, 577 .attrs = intel_ipc_attrs,
594}; 578};
595 579
596static struct resource punit_res_array[] = {
597 /* Punit BIOS */
598 {
599 .flags = IORESOURCE_MEM,
600 },
601 {
602 .flags = IORESOURCE_MEM,
603 },
604 /* Punit ISP */
605 {
606 .flags = IORESOURCE_MEM,
607 },
608 {
609 .flags = IORESOURCE_MEM,
610 },
611 /* Punit GTD */
612 {
613 .flags = IORESOURCE_MEM,
614 },
615 {
616 .flags = IORESOURCE_MEM,
617 },
618};
619
620#define TCO_RESOURCE_ACPI_IO 0
621#define TCO_RESOURCE_SMI_EN_IO 1
622#define TCO_RESOURCE_GCR_MEM 2
623static struct resource tco_res[] = {
624 /* ACPI - TCO */
625 {
626 .flags = IORESOURCE_IO,
627 },
628 /* ACPI - SMI */
629 {
630 .flags = IORESOURCE_IO,
631 },
632};
633
634static struct itco_wdt_platform_data tco_info = { 580static struct itco_wdt_platform_data tco_info = {
635 .name = "Apollo Lake SoC", 581 .name = "Apollo Lake SoC",
636 .version = 5, 582 .version = 5,
@@ -638,234 +584,177 @@ static struct itco_wdt_platform_data tco_info = {
638 .update_no_reboot_bit = update_no_reboot_bit, 584 .update_no_reboot_bit = update_no_reboot_bit,
639}; 585};
640 586
641#define TELEMETRY_RESOURCE_PUNIT_SSRAM 0 587static int ipc_create_punit_device(struct platform_device *pdev)
642#define TELEMETRY_RESOURCE_PMC_SSRAM 1
643static struct resource telemetry_res[] = {
644 /*Telemetry*/
645 {
646 .flags = IORESOURCE_MEM,
647 },
648 {
649 .flags = IORESOURCE_MEM,
650 },
651};
652
653static int ipc_create_punit_device(void)
654{ 588{
655 struct platform_device *pdev; 589 struct resource punit_res[PLAT_RESOURCE_MEM_MAX_INDEX];
656 const struct platform_device_info pdevinfo = { 590 struct mfd_cell punit_cell;
657 .parent = ipcdev.dev, 591 struct resource *res;
658 .name = PUNIT_DEVICE_NAME, 592 int mindex, pindex = 0;
659 .id = -1, 593
660 .res = punit_res_array, 594 for (mindex = 0; mindex <= PLAT_RESOURCE_MEM_MAX_INDEX; mindex++) {
661 .num_res = ARRAY_SIZE(punit_res_array), 595
596 res = platform_get_resource(pdev, IORESOURCE_MEM, mindex);
597
598 switch (mindex) {
599 /* Get PUNIT resources */
600 case PLAT_RESOURCE_BIOS_DATA_INDEX:
601 case PLAT_RESOURCE_BIOS_IFACE_INDEX:
602 /* BIOS resources are required, so return error if not
603 * available
604 */
605 if (!res) {
606 dev_err(&pdev->dev,
607 "Failed to get PUNIT MEM resource %d\n",
608 pindex);
609 return -ENXIO;
610 }
611 case PLAT_RESOURCE_ISP_DATA_INDEX:
612 case PLAT_RESOURCE_ISP_IFACE_INDEX:
613 case PLAT_RESOURCE_GTD_DATA_INDEX:
614 case PLAT_RESOURCE_GTD_IFACE_INDEX:
615 /* if valid resource found, copy the resource to PUNIT
616 * resource
617 */
618 if (res)
619 memcpy(&punit_res[pindex], res, sizeof(*res));
620 punit_res[pindex].flags = IORESOURCE_MEM;
621 dev_dbg(&pdev->dev, "PUNIT memory res: %pR\n",
622 &punit_res[pindex]);
623 pindex++;
624 break;
662 }; 625 };
626 }
663 627
664 pdev = platform_device_register_full(&pdevinfo); 628 /* Create PUNIT IPC MFD cell */
665 if (IS_ERR(pdev)) 629 punit_cell.name = PUNIT_DEVICE_NAME;
666 return PTR_ERR(pdev); 630 punit_cell.num_resources = ARRAY_SIZE(punit_res);
667 631 punit_cell.resources = punit_res;
668 ipcdev.punit_dev = pdev; 632 punit_cell.ignore_resource_conflicts = 1;
669 633
670 return 0; 634 return devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_NONE,
635 &punit_cell, 1, NULL, 0, NULL);
671} 636}
672 637
673static int ipc_create_tco_device(void) 638static int ipc_create_wdt_device(struct platform_device *pdev)
674{ 639{
675 struct platform_device *pdev; 640 static struct resource wdt_ipc_res[2];
676 struct resource *res; 641 struct resource *res;
677 const struct platform_device_info pdevinfo = { 642 static struct mfd_cell wdt_cell;
678 .parent = ipcdev.dev,
679 .name = TCO_DEVICE_NAME,
680 .id = -1,
681 .res = tco_res,
682 .num_res = ARRAY_SIZE(tco_res),
683 .data = &tco_info,
684 .size_data = sizeof(tco_info),
685 };
686 643
687 res = tco_res + TCO_RESOURCE_ACPI_IO; 644 /* If we have ACPI based watchdog use that instead, othewise create
688 res->start = ipcdev.acpi_io_base + TCO_BASE_OFFSET; 645 * a MFD cell for iTCO watchdog
689 res->end = res->start + TCO_REGS_SIZE - 1; 646 */
647 if (acpi_has_watchdog())
648 return 0;
690 649
691 res = tco_res + TCO_RESOURCE_SMI_EN_IO; 650 /* Get iTCO watchdog resources */
692 res->start = ipcdev.acpi_io_base + SMI_EN_OFFSET; 651 res = platform_get_resource(pdev, IORESOURCE_IO,
693 res->end = res->start + SMI_EN_SIZE - 1; 652 PLAT_RESOURCE_ACPI_IO_INDEX);
653 if (!res) {
654 dev_err(&pdev->dev, "Failed to get WDT resource\n");
655 return -ENXIO;
656 }
694 657
695 pdev = platform_device_register_full(&pdevinfo); 658 wdt_ipc_res[0].start = res->start + TCO_BASE_OFFSET;
696 if (IS_ERR(pdev)) 659 wdt_ipc_res[0].end = res->start +
697 return PTR_ERR(pdev); 660 TCO_BASE_OFFSET + TCO_REGS_SIZE - 1;
661 wdt_ipc_res[0].flags = IORESOURCE_IO;
662 wdt_ipc_res[1].start = res->start + SMI_EN_OFFSET;
663 wdt_ipc_res[1].end = res->start +
664 SMI_EN_OFFSET + SMI_EN_SIZE - 1;
665 wdt_ipc_res[1].flags = IORESOURCE_IO;
698 666
699 ipcdev.tco_dev = pdev; 667 dev_dbg(&pdev->dev, "watchdog res 0: %pR\n", &wdt_ipc_res[0]);
668 dev_dbg(&pdev->dev, "watchdog res 1: %pR\n", &wdt_ipc_res[1]);
700 669
701 return 0; 670 wdt_cell.name = TCO_DEVICE_NAME;
671 wdt_cell.platform_data = &tco_info;
672 wdt_cell.pdata_size = sizeof(tco_info);
673 wdt_cell.num_resources = ARRAY_SIZE(wdt_ipc_res);
674 wdt_cell.resources = wdt_ipc_res;
675 wdt_cell.ignore_resource_conflicts = 1;
676
677 return devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_NONE,
678 &wdt_cell, 1, NULL, 0, NULL);
702} 679}
703 680
704static int ipc_create_telemetry_device(void) 681static int ipc_create_telemetry_device(struct platform_device *pdev)
705{ 682{
706 struct platform_device *pdev; 683 struct resource telemetry_ipc_res[2];
684 struct mfd_cell telemetry_cell;
707 struct resource *res; 685 struct resource *res;
708 const struct platform_device_info pdevinfo = {
709 .parent = ipcdev.dev,
710 .name = TELEMETRY_DEVICE_NAME,
711 .id = -1,
712 .res = telemetry_res,
713 .num_res = ARRAY_SIZE(telemetry_res),
714 };
715 686
716 res = telemetry_res + TELEMETRY_RESOURCE_PUNIT_SSRAM; 687 /* Get telemetry resources */
717 res->start = ipcdev.telem_punit_ssram_base; 688 res = platform_get_resource(pdev, IORESOURCE_MEM,
718 res->end = res->start + ipcdev.telem_punit_ssram_size - 1; 689 PLAT_RESOURCE_TELEM_SSRAM_INDEX);
690 if (!res) {
691 dev_err(&pdev->dev, "Failed to get telemetry resource\n");
692 return -ENXIO;
693 }
719 694
720 res = telemetry_res + TELEMETRY_RESOURCE_PMC_SSRAM; 695 telemetry_ipc_res[0].start = res->start + TELEM_PUNIT_SSRAM_OFFSET;
721 res->start = ipcdev.telem_pmc_ssram_base; 696 telemetry_ipc_res[0].end = res->start +
722 res->end = res->start + ipcdev.telem_pmc_ssram_size - 1; 697 TELEM_PUNIT_SSRAM_OFFSET + TELEM_SSRAM_SIZE - 1;
698 telemetry_ipc_res[0].flags = IORESOURCE_MEM;
699 telemetry_ipc_res[1].start = res->start + TELEM_PMC_SSRAM_OFFSET;
700 telemetry_ipc_res[1].end = res->start +
701 TELEM_PMC_SSRAM_OFFSET + TELEM_SSRAM_SIZE - 1;
702 telemetry_ipc_res[1].flags = IORESOURCE_MEM;
723 703
724 pdev = platform_device_register_full(&pdevinfo); 704 dev_dbg(&pdev->dev, "Telemetry res 0: %pR\n", &telemetry_ipc_res[0]);
725 if (IS_ERR(pdev)) 705 dev_dbg(&pdev->dev, "Telemetry res 1: %pR\n", &telemetry_ipc_res[1]);
726 return PTR_ERR(pdev);
727 706
728 ipcdev.telemetry_dev = pdev; 707 telemetry_cell.name = TELEMETRY_DEVICE_NAME;
708 telemetry_cell.num_resources = ARRAY_SIZE(telemetry_ipc_res);
709 telemetry_cell.resources = telemetry_ipc_res;
710 telemetry_cell.ignore_resource_conflicts = 1;
729 711
730 return 0; 712 return devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_NONE,
713 &telemetry_cell, 1, NULL, 0, NULL);
731} 714}
732 715
733static int ipc_create_pmc_devices(void) 716static int ipc_create_pmc_devices(struct platform_device *pdev)
734{ 717{
735 int ret; 718 int ret;
736 719
737 /* If we have ACPI based watchdog use that instead */ 720 ret = ipc_create_punit_device(pdev);
738 if (!acpi_has_watchdog()) { 721 if (ret < 0)
739 ret = ipc_create_tco_device(); 722 return ret;
740 if (ret) {
741 dev_err(ipcdev.dev, "Failed to add tco platform device\n");
742 return ret;
743 }
744 }
745 723
746 ret = ipc_create_punit_device(); 724 ret = ipc_create_wdt_device(pdev);
747 if (ret) { 725 if (ret < 0)
748 dev_err(ipcdev.dev, "Failed to add punit platform device\n"); 726 return ret;
749 platform_device_unregister(ipcdev.tco_dev);
750 }
751 727
752 if (!ipcdev.telem_res_inval) { 728 ret = ipc_create_telemetry_device(pdev);
753 ret = ipc_create_telemetry_device(); 729 if (ret < 0)
754 if (ret) 730 return ret;
755 dev_warn(ipcdev.dev,
756 "Failed to add telemetry platform device\n");
757 }
758 731
759 return ret; 732 return 0;
760} 733}
761 734
762static int ipc_plat_get_res(struct platform_device *pdev) 735static int ipc_plat_get_res(struct platform_device *pdev)
763{ 736{
764 struct resource *res, *punit_res; 737 struct resource *res;
765 void __iomem *addr; 738 void __iomem *addr;
766 int size;
767
768 res = platform_get_resource(pdev, IORESOURCE_IO,
769 PLAT_RESOURCE_ACPI_IO_INDEX);
770 if (!res) {
771 dev_err(&pdev->dev, "Failed to get io resource\n");
772 return -ENXIO;
773 }
774 size = resource_size(res);
775 ipcdev.acpi_io_base = res->start;
776 ipcdev.acpi_io_size = size;
777 dev_info(&pdev->dev, "io res: %pR\n", res);
778
779 punit_res = punit_res_array;
780 /* This is index 0 to cover BIOS data register */
781 res = platform_get_resource(pdev, IORESOURCE_MEM,
782 PLAT_RESOURCE_BIOS_DATA_INDEX);
783 if (!res) {
784 dev_err(&pdev->dev, "Failed to get res of punit BIOS data\n");
785 return -ENXIO;
786 }
787 *punit_res = *res;
788 dev_info(&pdev->dev, "punit BIOS data res: %pR\n", res);
789
790 /* This is index 1 to cover BIOS interface register */
791 res = platform_get_resource(pdev, IORESOURCE_MEM,
792 PLAT_RESOURCE_BIOS_IFACE_INDEX);
793 if (!res) {
794 dev_err(&pdev->dev, "Failed to get res of punit BIOS iface\n");
795 return -ENXIO;
796 }
797 *++punit_res = *res;
798 dev_info(&pdev->dev, "punit BIOS interface res: %pR\n", res);
799
800 /* This is index 2 to cover ISP data register, optional */
801 res = platform_get_resource(pdev, IORESOURCE_MEM,
802 PLAT_RESOURCE_ISP_DATA_INDEX);
803 ++punit_res;
804 if (res) {
805 *punit_res = *res;
806 dev_info(&pdev->dev, "punit ISP data res: %pR\n", res);
807 }
808
809 /* This is index 3 to cover ISP interface register, optional */
810 res = platform_get_resource(pdev, IORESOURCE_MEM,
811 PLAT_RESOURCE_ISP_IFACE_INDEX);
812 ++punit_res;
813 if (res) {
814 *punit_res = *res;
815 dev_info(&pdev->dev, "punit ISP interface res: %pR\n", res);
816 }
817
818 /* This is index 4 to cover GTD data register, optional */
819 res = platform_get_resource(pdev, IORESOURCE_MEM,
820 PLAT_RESOURCE_GTD_DATA_INDEX);
821 ++punit_res;
822 if (res) {
823 *punit_res = *res;
824 dev_info(&pdev->dev, "punit GTD data res: %pR\n", res);
825 }
826
827 /* This is index 5 to cover GTD interface register, optional */
828 res = platform_get_resource(pdev, IORESOURCE_MEM,
829 PLAT_RESOURCE_GTD_IFACE_INDEX);
830 ++punit_res;
831 if (res) {
832 *punit_res = *res;
833 dev_info(&pdev->dev, "punit GTD interface res: %pR\n", res);
834 }
835 739
740 /* Get IPC resources */
836 res = platform_get_resource(pdev, IORESOURCE_MEM, 741 res = platform_get_resource(pdev, IORESOURCE_MEM,
837 PLAT_RESOURCE_IPC_INDEX); 742 PLAT_RESOURCE_IPC_INDEX);
838 if (!res) { 743 if (!res) {
839 dev_err(&pdev->dev, "Failed to get ipc resource\n"); 744 dev_err(&pdev->dev, "Failed to get IPC resources\n");
840 return -ENXIO; 745 return -ENXIO;
841 } 746 }
842 size = PLAT_RESOURCE_IPC_SIZE + PLAT_RESOURCE_GCR_SIZE; 747
843 res->end = res->start + size - 1; 748 res->end = res->start +
749 PLAT_RESOURCE_IPC_SIZE + PLAT_RESOURCE_GCR_SIZE - 1;
844 750
845 addr = devm_ioremap_resource(&pdev->dev, res); 751 addr = devm_ioremap_resource(&pdev->dev, res);
846 if (IS_ERR(addr)) 752 if (IS_ERR(addr))
847 return PTR_ERR(addr); 753 return PTR_ERR(addr);
848 754
849 ipcdev.ipc_base = addr; 755 ipcdev.ipc_base = addr;
850
851 ipcdev.gcr_mem_base = addr + PLAT_RESOURCE_GCR_OFFSET; 756 ipcdev.gcr_mem_base = addr + PLAT_RESOURCE_GCR_OFFSET;
852 dev_info(&pdev->dev, "ipc res: %pR\n", res); 757 dev_dbg(&pdev->dev, "PMC IPC resource %pR\n", res);
853
854 ipcdev.telem_res_inval = 0;
855 res = platform_get_resource(pdev, IORESOURCE_MEM,
856 PLAT_RESOURCE_TELEM_SSRAM_INDEX);
857 if (!res) {
858 dev_err(&pdev->dev, "Failed to get telemetry ssram resource\n");
859 ipcdev.telem_res_inval = 1;
860 } else {
861 ipcdev.telem_punit_ssram_base = res->start +
862 TELEM_PUNIT_SSRAM_OFFSET;
863 ipcdev.telem_punit_ssram_size = TELEM_SSRAM_SIZE;
864 ipcdev.telem_pmc_ssram_base = res->start +
865 TELEM_PMC_SSRAM_OFFSET;
866 ipcdev.telem_pmc_ssram_size = TELEM_SSRAM_SIZE;
867 dev_info(&pdev->dev, "telemetry ssram res: %pR\n", res);
868 }
869 758
870 return 0; 759 return 0;
871} 760}
@@ -911,7 +800,7 @@ static int ipc_plat_probe(struct platform_device *pdev)
911 800
912 ipcdev.irq = platform_get_irq(pdev, 0); 801 ipcdev.irq = platform_get_irq(pdev, 0);
913 if (ipcdev.irq < 0) { 802 if (ipcdev.irq < 0) {
914 dev_err(&pdev->dev, "Failed to get irq\n"); 803 dev_err(&pdev->dev, "Failed to get IRQ\n");
915 return -EINVAL; 804 return -EINVAL;
916 } 805 }
917 806
@@ -921,47 +810,38 @@ static int ipc_plat_probe(struct platform_device *pdev)
921 return ret; 810 return ret;
922 } 811 }
923 812
924 ret = ipc_create_pmc_devices(); 813 ret = ipc_create_pmc_devices(pdev);
925 if (ret) { 814 if (ret) {
926 dev_err(&pdev->dev, "Failed to create pmc devices\n"); 815 dev_err(&pdev->dev, "Failed to create PMC devices\n");
927 return ret; 816 return ret;
928 } 817 }
929 818
930 if (devm_request_irq(&pdev->dev, ipcdev.irq, ioc, IRQF_NO_SUSPEND, 819 ret = devm_request_irq(&pdev->dev, ipcdev.irq, ioc, IRQF_NO_SUSPEND,
931 "intel_pmc_ipc", &ipcdev)) { 820 "intel_pmc_ipc", &ipcdev);
932 dev_err(&pdev->dev, "Failed to request irq\n"); 821 if (ret) {
933 ret = -EBUSY; 822 dev_err(&pdev->dev, "Failed to request IRQ\n");
934 goto err_irq; 823 return ret;
935 } 824 }
936 825
937 ret = sysfs_create_group(&pdev->dev.kobj, &intel_ipc_group); 826 ret = sysfs_create_group(&pdev->dev.kobj, &intel_ipc_group);
938 if (ret) { 827 if (ret) {
939 dev_err(&pdev->dev, "Failed to create sysfs group %d\n", 828 dev_err(&pdev->dev, "Failed to create sysfs group %d\n",
940 ret); 829 ret);
941 goto err_sys; 830 devm_free_irq(&pdev->dev, ipcdev.irq, &ipcdev);
831 return ret;
942 } 832 }
943 833
944 ipcdev.has_gcr_regs = true; 834 ipcdev.has_gcr_regs = true;
945 835
946 return 0; 836 return 0;
947err_sys:
948 devm_free_irq(&pdev->dev, ipcdev.irq, &ipcdev);
949err_irq:
950 platform_device_unregister(ipcdev.tco_dev);
951 platform_device_unregister(ipcdev.punit_dev);
952 platform_device_unregister(ipcdev.telemetry_dev);
953
954 return ret;
955} 837}
956 838
957static int ipc_plat_remove(struct platform_device *pdev) 839static int ipc_plat_remove(struct platform_device *pdev)
958{ 840{
959 sysfs_remove_group(&pdev->dev.kobj, &intel_ipc_group); 841 sysfs_remove_group(&pdev->dev.kobj, &intel_ipc_group);
960 devm_free_irq(&pdev->dev, ipcdev.irq, &ipcdev); 842 devm_free_irq(&pdev->dev, ipcdev.irq, &ipcdev);
961 platform_device_unregister(ipcdev.tco_dev);
962 platform_device_unregister(ipcdev.punit_dev);
963 platform_device_unregister(ipcdev.telemetry_dev);
964 ipcdev.dev = NULL; 843 ipcdev.dev = NULL;
844
965 return 0; 845 return 0;
966} 846}
967 847
@@ -980,12 +860,12 @@ static int __init intel_pmc_ipc_init(void)
980 860
981 ret = platform_driver_register(&ipc_plat_driver); 861 ret = platform_driver_register(&ipc_plat_driver);
982 if (ret) { 862 if (ret) {
983 pr_err("Failed to register PMC ipc platform driver\n"); 863 pr_err("Failed to register PMC IPC platform driver\n");
984 return ret; 864 return ret;
985 } 865 }
986 ret = pci_register_driver(&ipc_pci_driver); 866 ret = pci_register_driver(&ipc_pci_driver);
987 if (ret) { 867 if (ret) {
988 pr_err("Failed to register PMC ipc pci driver\n"); 868 pr_err("Failed to register PMC IPC PCI driver\n");
989 platform_driver_unregister(&ipc_plat_driver); 869 platform_driver_unregister(&ipc_plat_driver);
990 return ret; 870 return ret;
991 } 871 }