aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/platform/x86/intel_pmc_ipc.c
diff options
context:
space:
mode:
authorAndy Shevchenko <andriy.shevchenko@linux.intel.com>2019-04-09 07:25:14 -0400
committerAndy Shevchenko <andriy.shevchenko@linux.intel.com>2019-05-06 10:54:04 -0400
commitaf6c7e1ffcb6db6c1265295fa1b20fc27a0753f2 (patch)
tree52efbc3de02810f82758727a4044733a98128981 /drivers/platform/x86/intel_pmc_ipc.c
parent9eac0d75f132608159eb649ceadfc4e53b2a1686 (diff)
platform/x86: intel_pmc_ipc: Don't map non-used optional resources
The intel_pmc_ipc driver has a placeholder for all possible resources that may have been provided by ACPI. Since there are few optional ones, the driver still uses them and binds to wrong ranges in resource tree: # grep intel_punit_ipc /proc/iomem 00000000-00000000 : intel_punit_ipc 00000000-00000000 : intel_punit_ipc 00000000-00000000 : intel_punit_ipc 00000000-00000000 : intel_punit_ipc This leads to issues with resource management during inserting and removing modules, such as intel_pmc_ipc itself, which can't be inserted anymore after first removal. Count the actual resources provided and supply only them to the child device. This is a real fix of the commit 8cc7fb4a6523 ("intel_pmc_ipc: update acpi resource structure for Punit") that also fixes a symptoms described in the commit 6cc8cbbc8868 ("platform/x86: intel_punit_ipc: Fix resource ioremap warning") that is going to be reverted afterwards. Reported-by: Junxiao Chang <junxiao.chang@intel.com> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Cc: Qipeng Zha <qipeng.zha@intel.com> Cc: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com> Reviewed-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
Diffstat (limited to 'drivers/platform/x86/intel_pmc_ipc.c')
-rw-r--r--drivers/platform/x86/intel_pmc_ipc.c24
1 files changed, 11 insertions, 13 deletions
diff --git a/drivers/platform/x86/intel_pmc_ipc.c b/drivers/platform/x86/intel_pmc_ipc.c
index 9007aa717586..55037ff258f8 100644
--- a/drivers/platform/x86/intel_pmc_ipc.c
+++ b/drivers/platform/x86/intel_pmc_ipc.c
@@ -131,6 +131,7 @@ static struct intel_pmc_ipc_dev {
131 131
132 /* punit */ 132 /* punit */
133 struct platform_device *punit_dev; 133 struct platform_device *punit_dev;
134 unsigned int punit_res_count;
134 135
135 /* Telemetry */ 136 /* Telemetry */
136 resource_size_t telem_pmc_ssram_base; 137 resource_size_t telem_pmc_ssram_base;
@@ -682,7 +683,7 @@ static int ipc_create_punit_device(void)
682 .name = PUNIT_DEVICE_NAME, 683 .name = PUNIT_DEVICE_NAME,
683 .id = -1, 684 .id = -1,
684 .res = punit_res_array, 685 .res = punit_res_array,
685 .num_res = ARRAY_SIZE(punit_res_array), 686 .num_res = ipcdev.punit_res_count,
686 }; 687 };
687 688
688 pdev = platform_device_register_full(&pdevinfo); 689 pdev = platform_device_register_full(&pdevinfo);
@@ -789,7 +790,7 @@ static int ipc_create_pmc_devices(void)
789 790
790static int ipc_plat_get_res(struct platform_device *pdev) 791static int ipc_plat_get_res(struct platform_device *pdev)
791{ 792{
792 struct resource *res, *punit_res; 793 struct resource *res, *punit_res = punit_res_array;
793 void __iomem *addr; 794 void __iomem *addr;
794 int size; 795 int size;
795 796
@@ -804,7 +805,8 @@ static int ipc_plat_get_res(struct platform_device *pdev)
804 ipcdev.acpi_io_size = size; 805 ipcdev.acpi_io_size = size;
805 dev_info(&pdev->dev, "io res: %pR\n", res); 806 dev_info(&pdev->dev, "io res: %pR\n", res);
806 807
807 punit_res = punit_res_array; 808 ipcdev.punit_res_count = 0;
809
808 /* This is index 0 to cover BIOS data register */ 810 /* This is index 0 to cover BIOS data register */
809 res = platform_get_resource(pdev, IORESOURCE_MEM, 811 res = platform_get_resource(pdev, IORESOURCE_MEM,
810 PLAT_RESOURCE_BIOS_DATA_INDEX); 812 PLAT_RESOURCE_BIOS_DATA_INDEX);
@@ -812,7 +814,7 @@ static int ipc_plat_get_res(struct platform_device *pdev)
812 dev_err(&pdev->dev, "Failed to get res of punit BIOS data\n"); 814 dev_err(&pdev->dev, "Failed to get res of punit BIOS data\n");
813 return -ENXIO; 815 return -ENXIO;
814 } 816 }
815 *punit_res = *res; 817 punit_res[ipcdev.punit_res_count++] = *res;
816 dev_info(&pdev->dev, "punit BIOS data res: %pR\n", res); 818 dev_info(&pdev->dev, "punit BIOS data res: %pR\n", res);
817 819
818 /* This is index 1 to cover BIOS interface register */ 820 /* This is index 1 to cover BIOS interface register */
@@ -822,42 +824,38 @@ static int ipc_plat_get_res(struct platform_device *pdev)
822 dev_err(&pdev->dev, "Failed to get res of punit BIOS iface\n"); 824 dev_err(&pdev->dev, "Failed to get res of punit BIOS iface\n");
823 return -ENXIO; 825 return -ENXIO;
824 } 826 }
825 *++punit_res = *res; 827 punit_res[ipcdev.punit_res_count++] = *res;
826 dev_info(&pdev->dev, "punit BIOS interface res: %pR\n", res); 828 dev_info(&pdev->dev, "punit BIOS interface res: %pR\n", res);
827 829
828 /* This is index 2 to cover ISP data register, optional */ 830 /* This is index 2 to cover ISP data register, optional */
829 res = platform_get_resource(pdev, IORESOURCE_MEM, 831 res = platform_get_resource(pdev, IORESOURCE_MEM,
830 PLAT_RESOURCE_ISP_DATA_INDEX); 832 PLAT_RESOURCE_ISP_DATA_INDEX);
831 ++punit_res;
832 if (res) { 833 if (res) {
833 *punit_res = *res; 834 punit_res[ipcdev.punit_res_count++] = *res;
834 dev_info(&pdev->dev, "punit ISP data res: %pR\n", res); 835 dev_info(&pdev->dev, "punit ISP data res: %pR\n", res);
835 } 836 }
836 837
837 /* This is index 3 to cover ISP interface register, optional */ 838 /* This is index 3 to cover ISP interface register, optional */
838 res = platform_get_resource(pdev, IORESOURCE_MEM, 839 res = platform_get_resource(pdev, IORESOURCE_MEM,
839 PLAT_RESOURCE_ISP_IFACE_INDEX); 840 PLAT_RESOURCE_ISP_IFACE_INDEX);
840 ++punit_res;
841 if (res) { 841 if (res) {
842 *punit_res = *res; 842 punit_res[ipcdev.punit_res_count++] = *res;
843 dev_info(&pdev->dev, "punit ISP interface res: %pR\n", res); 843 dev_info(&pdev->dev, "punit ISP interface res: %pR\n", res);
844 } 844 }
845 845
846 /* This is index 4 to cover GTD data register, optional */ 846 /* This is index 4 to cover GTD data register, optional */
847 res = platform_get_resource(pdev, IORESOURCE_MEM, 847 res = platform_get_resource(pdev, IORESOURCE_MEM,
848 PLAT_RESOURCE_GTD_DATA_INDEX); 848 PLAT_RESOURCE_GTD_DATA_INDEX);
849 ++punit_res;
850 if (res) { 849 if (res) {
851 *punit_res = *res; 850 punit_res[ipcdev.punit_res_count++] = *res;
852 dev_info(&pdev->dev, "punit GTD data res: %pR\n", res); 851 dev_info(&pdev->dev, "punit GTD data res: %pR\n", res);
853 } 852 }
854 853
855 /* This is index 5 to cover GTD interface register, optional */ 854 /* This is index 5 to cover GTD interface register, optional */
856 res = platform_get_resource(pdev, IORESOURCE_MEM, 855 res = platform_get_resource(pdev, IORESOURCE_MEM,
857 PLAT_RESOURCE_GTD_IFACE_INDEX); 856 PLAT_RESOURCE_GTD_IFACE_INDEX);
858 ++punit_res;
859 if (res) { 857 if (res) {
860 *punit_res = *res; 858 punit_res[ipcdev.punit_res_count++] = *res;
861 dev_info(&pdev->dev, "punit GTD interface res: %pR\n", res); 859 dev_info(&pdev->dev, "punit GTD interface res: %pR\n", res);
862 } 860 }
863 861