PCI: hisi: Avoid invalid address space conversions
authorBjorn Helgaas <bhelgaas@google.com>
Thu, 23 Dec 2021 21:37:48 +0000 (15:37 -0600)
committerBjorn Helgaas <bhelgaas@google.com>
Mon, 3 Jan 2022 21:05:28 +0000 (15:05 -0600)
The sparse checker complains about converting pointers between address
spaces.  The pci_config_window.priv pointer is a generic void *, but
hisi_pcie_map_bus() needs a void __iomem *.

This isn't a problem in other drivers because they store the __iomem
pointer in a driver struct.  Add a trivial struct hisi_pcie to avoid the
warning.

The sparse warning looks like this:

  $ make C=2 drivers/pci/controller/
  drivers/pci/controller/dwc/pcie-hisi.c:61:37: warning: incorrect type in initializer (different address spaces)
  drivers/pci/controller/dwc/pcie-hisi.c:61:37:    expected void [noderef] __iomem *reg_base
  drivers/pci/controller/dwc/pcie-hisi.c:61:37:    got void *priv

Link: https://lore.kernel.org/r/20211223213749.1314142-2-helgaas@kernel.org
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Cc: Zhou Wang <wangzhou1@hisilicon.com>
drivers/pci/controller/dwc/pcie-hisi.c

index 8fc5960faf286ee3c5afb5373247ba80ab25882e..8904b5b85ee589576afcb6c81bb4bd39ff960c15 100644 (file)
 
 #if defined(CONFIG_PCI_HISI) || (defined(CONFIG_ACPI) && defined(CONFIG_PCI_QUIRKS))
 
+struct hisi_pcie {
+       void __iomem    *reg_base;
+};
+
 static int hisi_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
                             int size, u32 *val)
 {
@@ -58,10 +62,10 @@ static void __iomem *hisi_pcie_map_bus(struct pci_bus *bus, unsigned int devfn,
                                       int where)
 {
        struct pci_config_window *cfg = bus->sysdata;
-       void __iomem *reg_base = cfg->priv;
+       struct hisi_pcie *pcie = cfg->priv;
 
        if (bus->number == cfg->busr.start)
-               return reg_base + where;
+               return pcie->reg_base + where;
        else
                return pci_ecam_map_bus(bus, devfn, where);
 }
@@ -71,12 +75,16 @@ static void __iomem *hisi_pcie_map_bus(struct pci_bus *bus, unsigned int devfn,
 static int hisi_pcie_init(struct pci_config_window *cfg)
 {
        struct device *dev = cfg->parent;
+       struct hisi_pcie *pcie;
        struct acpi_device *adev = to_acpi_device(dev);
        struct acpi_pci_root *root = acpi_driver_data(adev);
        struct resource *res;
-       void __iomem *reg_base;
        int ret;
 
+       pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
+       if (!pcie)
+               return -ENOMEM;
+
        /*
         * Retrieve RC base and size from a HISI0081 device with _UID
         * matching our segment.
@@ -91,11 +99,11 @@ static int hisi_pcie_init(struct pci_config_window *cfg)
                return -ENOMEM;
        }
 
-       reg_base = devm_pci_remap_cfgspace(dev, res->start, resource_size(res));
-       if (!reg_base)
+       pcie->reg_base = devm_pci_remap_cfgspace(dev, res->start, resource_size(res));
+       if (!pcie->reg_base)
                return -ENOMEM;
 
-       cfg->priv = reg_base;
+       cfg->priv = pcie;
        return 0;
 }
 
@@ -115,9 +123,13 @@ const struct pci_ecam_ops hisi_pcie_ops = {
 static int hisi_pcie_platform_init(struct pci_config_window *cfg)
 {
        struct device *dev = cfg->parent;
+       struct hisi_pcie *pcie;
        struct platform_device *pdev = to_platform_device(dev);
        struct resource *res;
-       void __iomem *reg_base;
+
+       pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
+       if (!pcie)
+               return -ENOMEM;
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
        if (!res) {
@@ -125,11 +137,11 @@ static int hisi_pcie_platform_init(struct pci_config_window *cfg)
                return -EINVAL;
        }
 
-       reg_base = devm_pci_remap_cfgspace(dev, res->start, resource_size(res));
-       if (!reg_base)
+       pcie->reg_base = devm_pci_remap_cfgspace(dev, res->start, resource_size(res));
+       if (!pcie->reg_base)
                return -ENOMEM;
 
-       cfg->priv = reg_base;
+       cfg->priv = pcie;
        return 0;
 }