Skip to content

Commit af6c7e1

Browse files
committed
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 8cc7fb4 ("intel_pmc_ipc: update acpi resource structure for Punit") that also fixes a symptoms described in the commit 6cc8cbb ("platform/x86: intel_punit_ipc: Fix resource ioremap warning") that is going to be reverted afterwards. Reported-by: Junxiao Chang <[email protected]> Signed-off-by: Andy Shevchenko <[email protected]> Cc: Qipeng Zha <[email protected]> Cc: Kuppuswamy Sathyanarayanan <[email protected]> Reviewed-by: Kuppuswamy Sathyanarayanan <[email protected]>
1 parent 9eac0d7 commit af6c7e1

File tree

1 file changed

+11
-13
lines changed

1 file changed

+11
-13
lines changed

drivers/platform/x86/intel_pmc_ipc.c

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ static struct intel_pmc_ipc_dev {
131131

132132
/* punit */
133133
struct platform_device *punit_dev;
134+
unsigned int punit_res_count;
134135

135136
/* Telemetry */
136137
resource_size_t telem_pmc_ssram_base;
@@ -682,7 +683,7 @@ static int ipc_create_punit_device(void)
682683
.name = PUNIT_DEVICE_NAME,
683684
.id = -1,
684685
.res = punit_res_array,
685-
.num_res = ARRAY_SIZE(punit_res_array),
686+
.num_res = ipcdev.punit_res_count,
686687
};
687688

688689
pdev = platform_device_register_full(&pdevinfo);
@@ -789,7 +790,7 @@ static int ipc_create_pmc_devices(void)
789790

790791
static int ipc_plat_get_res(struct platform_device *pdev)
791792
{
792-
struct resource *res, *punit_res;
793+
struct resource *res, *punit_res = punit_res_array;
793794
void __iomem *addr;
794795
int size;
795796

@@ -804,15 +805,16 @@ static int ipc_plat_get_res(struct platform_device *pdev)
804805
ipcdev.acpi_io_size = size;
805806
dev_info(&pdev->dev, "io res: %pR\n", res);
806807

807-
punit_res = punit_res_array;
808+
ipcdev.punit_res_count = 0;
809+
808810
/* This is index 0 to cover BIOS data register */
809811
res = platform_get_resource(pdev, IORESOURCE_MEM,
810812
PLAT_RESOURCE_BIOS_DATA_INDEX);
811813
if (!res) {
812814
dev_err(&pdev->dev, "Failed to get res of punit BIOS data\n");
813815
return -ENXIO;
814816
}
815-
*punit_res = *res;
817+
punit_res[ipcdev.punit_res_count++] = *res;
816818
dev_info(&pdev->dev, "punit BIOS data res: %pR\n", res);
817819

818820
/* This is index 1 to cover BIOS interface register */
@@ -822,42 +824,38 @@ static int ipc_plat_get_res(struct platform_device *pdev)
822824
dev_err(&pdev->dev, "Failed to get res of punit BIOS iface\n");
823825
return -ENXIO;
824826
}
825-
*++punit_res = *res;
827+
punit_res[ipcdev.punit_res_count++] = *res;
826828
dev_info(&pdev->dev, "punit BIOS interface res: %pR\n", res);
827829

828830
/* This is index 2 to cover ISP data register, optional */
829831
res = platform_get_resource(pdev, IORESOURCE_MEM,
830832
PLAT_RESOURCE_ISP_DATA_INDEX);
831-
++punit_res;
832833
if (res) {
833-
*punit_res = *res;
834+
punit_res[ipcdev.punit_res_count++] = *res;
834835
dev_info(&pdev->dev, "punit ISP data res: %pR\n", res);
835836
}
836837

837838
/* This is index 3 to cover ISP interface register, optional */
838839
res = platform_get_resource(pdev, IORESOURCE_MEM,
839840
PLAT_RESOURCE_ISP_IFACE_INDEX);
840-
++punit_res;
841841
if (res) {
842-
*punit_res = *res;
842+
punit_res[ipcdev.punit_res_count++] = *res;
843843
dev_info(&pdev->dev, "punit ISP interface res: %pR\n", res);
844844
}
845845

846846
/* This is index 4 to cover GTD data register, optional */
847847
res = platform_get_resource(pdev, IORESOURCE_MEM,
848848
PLAT_RESOURCE_GTD_DATA_INDEX);
849-
++punit_res;
850849
if (res) {
851-
*punit_res = *res;
850+
punit_res[ipcdev.punit_res_count++] = *res;
852851
dev_info(&pdev->dev, "punit GTD data res: %pR\n", res);
853852
}
854853

855854
/* This is index 5 to cover GTD interface register, optional */
856855
res = platform_get_resource(pdev, IORESOURCE_MEM,
857856
PLAT_RESOURCE_GTD_IFACE_INDEX);
858-
++punit_res;
859857
if (res) {
860-
*punit_res = *res;
858+
punit_res[ipcdev.punit_res_count++] = *res;
861859
dev_info(&pdev->dev, "punit GTD interface res: %pR\n", res);
862860
}
863861

0 commit comments

Comments
 (0)