Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

PCI: hisi: Avoid invalid address space conversions

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>

+22 -10
+22 -10
drivers/pci/controller/dwc/pcie-hisi.c
··· 18 18 19 19 #if defined(CONFIG_PCI_HISI) || (defined(CONFIG_ACPI) && defined(CONFIG_PCI_QUIRKS)) 20 20 21 + struct hisi_pcie { 22 + void __iomem *reg_base; 23 + }; 24 + 21 25 static int hisi_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where, 22 26 int size, u32 *val) 23 27 { ··· 62 58 int where) 63 59 { 64 60 struct pci_config_window *cfg = bus->sysdata; 65 - void __iomem *reg_base = cfg->priv; 61 + struct hisi_pcie *pcie = cfg->priv; 66 62 67 63 if (bus->number == cfg->busr.start) 68 - return reg_base + where; 64 + return pcie->reg_base + where; 69 65 else 70 66 return pci_ecam_map_bus(bus, devfn, where); 71 67 } ··· 75 71 static int hisi_pcie_init(struct pci_config_window *cfg) 76 72 { 77 73 struct device *dev = cfg->parent; 74 + struct hisi_pcie *pcie; 78 75 struct acpi_device *adev = to_acpi_device(dev); 79 76 struct acpi_pci_root *root = acpi_driver_data(adev); 80 77 struct resource *res; 81 - void __iomem *reg_base; 82 78 int ret; 79 + 80 + pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL); 81 + if (!pcie) 82 + return -ENOMEM; 83 83 84 84 /* 85 85 * Retrieve RC base and size from a HISI0081 device with _UID ··· 99 91 return -ENOMEM; 100 92 } 101 93 102 - reg_base = devm_pci_remap_cfgspace(dev, res->start, resource_size(res)); 103 - if (!reg_base) 94 + pcie->reg_base = devm_pci_remap_cfgspace(dev, res->start, resource_size(res)); 95 + if (!pcie->reg_base) 104 96 return -ENOMEM; 105 97 106 - cfg->priv = reg_base; 98 + cfg->priv = pcie; 107 99 return 0; 108 100 } 109 101 ··· 123 115 static int hisi_pcie_platform_init(struct pci_config_window *cfg) 124 116 { 125 117 struct device *dev = cfg->parent; 118 + struct hisi_pcie *pcie; 126 119 struct platform_device *pdev = to_platform_device(dev); 127 120 struct resource *res; 128 - void __iomem *reg_base; 121 + 122 + pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL); 123 + if (!pcie) 124 + return -ENOMEM; 129 125 130 126 res = platform_get_resource(pdev, IORESOURCE_MEM, 1); 131 127 if (!res) { ··· 137 125 return -EINVAL; 138 126 } 139 127 140 - reg_base = devm_pci_remap_cfgspace(dev, res->start, resource_size(res)); 141 - if (!reg_base) 128 + pcie->reg_base = devm_pci_remap_cfgspace(dev, res->start, resource_size(res)); 129 + if (!pcie->reg_base) 142 130 return -ENOMEM; 143 131 144 - cfg->priv = reg_base; 132 + cfg->priv = pcie; 145 133 return 0; 146 134 } 147 135