diff options
-rw-r--r-- | drivers/i2c/busses/i2c-amd-asf-plat.c | 17 |
1 files changed, 17 insertions, 0 deletions
diff --git a/drivers/i2c/busses/i2c-amd-asf-plat.c b/drivers/i2c/busses/i2c-amd-asf-plat.c index 408c4bf6979f..47e0c90341ae 100644 --- a/drivers/i2c/busses/i2c-amd-asf-plat.c +++ b/drivers/i2c/busses/i2c-amd-asf-plat.c @@ -48,6 +48,7 @@ struct amd_asf_dev { struct i2c_adapter adap; + void __iomem *eoi_base; struct i2c_client *target; struct delayed_work work_buf; struct sb800_mmio_cfg mmio_cfg; @@ -299,6 +300,7 @@ static int amd_asf_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct amd_asf_dev *asf_dev; + struct resource *eoi_addr; int ret, irq; asf_dev = devm_kzalloc(dev, sizeof(*asf_dev), GFP_KERNEL); @@ -310,6 +312,21 @@ static int amd_asf_probe(struct platform_device *pdev) if (!asf_dev->port_addr) return dev_err_probe(dev, -EINVAL, "missing IO resources\n"); + /* + * The resource obtained via ACPI might not belong to the ASF device address space. Instead, + * it could be within other IP blocks of the ASIC, which are crucial for generating + * subsequent interrupts. Therefore, we avoid using devm_platform_ioremap_resource() and + * use platform_get_resource() and devm_ioremap() separately to prevent any address space + * conflicts. + */ + eoi_addr = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!eoi_addr) + return dev_err_probe(dev, -EINVAL, "missing MEM resources\n"); + + asf_dev->eoi_base = devm_ioremap(dev, eoi_addr->start, resource_size(eoi_addr)); + if (!asf_dev->eoi_base) + return dev_err_probe(dev, -EBUSY, "failed mapping IO region\n"); + ret = devm_delayed_work_autocancel(dev, &asf_dev->work_buf, amd_asf_process_target); if (ret) return dev_err_probe(dev, ret, "failed to create work queue\n"); |