Skip to content

Commit

Permalink
PCI: hisi: Avoid invalid address space conversions
Browse files Browse the repository at this point in the history
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/[email protected]
Signed-off-by: Bjorn Helgaas <[email protected]>
Cc: Zhou Wang <[email protected]>
  • Loading branch information
bjorn-helgaas committed Jan 3, 2022
1 parent dacee58 commit 088c840
Showing 1 changed file with 22 additions and 10 deletions.
32 changes: 22 additions & 10 deletions drivers/pci/controller/dwc/pcie-hisi.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@

#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)
{
Expand Down Expand Up @@ -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);
}
Expand All @@ -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.
Expand All @@ -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;
}

Expand All @@ -115,21 +123,25 @@ 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) {
dev_err(dev, "missing \"reg[1]\"property\n");
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;
}

Expand Down

0 comments on commit 088c840

Please sign in to comment.