Skip to content

Commit

Permalink
PCI: faraday: Convert IRQ masking to raw PCI config accessors
Browse files Browse the repository at this point in the history
Current ftpci100 driver host bridge controller driver requires struct
pci_bus to be created in order to mask and clear IRQs using standard PCI
bus config accessors.

This struct pci_bus dependency is fictitious and burdens the driver with
unneeded constraints (eg to use separate APIs to create and scan the root
bus).

Add PCI raw config space accessors to PCIe ftpci100 driver and remove the
fictitious struct pci_bus dependency.

Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
[bhelgaas: folded in raw PCI read accessor from
http://lkml.kernel.org/r/20170621162651.25315-1-linus.walleij@linaro.org
The clock piece of the above posting goes with the separate "Add clock
handling" patch.]
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
  • Loading branch information
Lorenzo Pieralisi authored and Bjorn Helgaas committed Jun 28, 2017
1 parent 022adcf commit f1e8bd2
Showing 1 changed file with 48 additions and 33 deletions.
81 changes: 48 additions & 33 deletions drivers/pci/host/pci-ftpci100.c
Original file line number Diff line number Diff line change
Expand Up @@ -178,12 +178,11 @@ static int faraday_res_to_memcfg(resource_size_t mem_base,
return 0;
}

static int faraday_pci_read_config(struct pci_bus *bus, unsigned int fn,
int config, int size, u32 *value)
static int faraday_raw_pci_read_config(struct faraday_pci *p, int bus_number,
unsigned int fn, int config, int size,
u32 *value)
{
struct faraday_pci *p = bus->sysdata;

writel(PCI_CONF_BUS(bus->number) |
writel(PCI_CONF_BUS(bus_number) |
PCI_CONF_DEVICE(PCI_SLOT(fn)) |
PCI_CONF_FUNCTION(PCI_FUNC(fn)) |
PCI_CONF_WHERE(config) |
Expand All @@ -197,24 +196,28 @@ static int faraday_pci_read_config(struct pci_bus *bus, unsigned int fn,
else if (size == 2)
*value = (*value >> (8 * (config & 3))) & 0xFFFF;

return PCIBIOS_SUCCESSFUL;
}

static int faraday_pci_read_config(struct pci_bus *bus, unsigned int fn,
int config, int size, u32 *value)
{
struct faraday_pci *p = bus->sysdata;

dev_dbg(&bus->dev,
"[read] slt: %.2d, fnc: %d, cnf: 0x%.2X, val (%d bytes): 0x%.8X\n",
PCI_SLOT(fn), PCI_FUNC(fn), config, size, *value);

return PCIBIOS_SUCCESSFUL;
return faraday_raw_pci_read_config(p, bus->number, fn, config, size, value);
}

static int faraday_pci_write_config(struct pci_bus *bus, unsigned int fn,
int config, int size, u32 value)
static int faraday_raw_pci_write_config(struct faraday_pci *p, int bus_number,
unsigned int fn, int config, int size,
u32 value)
{
struct faraday_pci *p = bus->sysdata;
int ret = PCIBIOS_SUCCESSFUL;

dev_dbg(&bus->dev,
"[write] slt: %.2d, fnc: %d, cnf: 0x%.2X, val (%d bytes): 0x%.8X\n",
PCI_SLOT(fn), PCI_FUNC(fn), config, size, value);

writel(PCI_CONF_BUS(bus->number) |
writel(PCI_CONF_BUS(bus_number) |
PCI_CONF_DEVICE(PCI_SLOT(fn)) |
PCI_CONF_FUNCTION(PCI_FUNC(fn)) |
PCI_CONF_WHERE(config) |
Expand All @@ -238,6 +241,19 @@ static int faraday_pci_write_config(struct pci_bus *bus, unsigned int fn,
return ret;
}

static int faraday_pci_write_config(struct pci_bus *bus, unsigned int fn,
int config, int size, u32 value)
{
struct faraday_pci *p = bus->sysdata;

dev_dbg(&bus->dev,
"[write] slt: %.2d, fnc: %d, cnf: 0x%.2X, val (%d bytes): 0x%.8X\n",
PCI_SLOT(fn), PCI_FUNC(fn), config, size, value);

return faraday_raw_pci_write_config(p, bus->number, fn, config, size,
value);
}

static struct pci_ops faraday_pci_ops = {
.read = faraday_pci_read_config,
.write = faraday_pci_write_config,
Expand All @@ -248,32 +264,32 @@ static void faraday_pci_ack_irq(struct irq_data *d)
struct faraday_pci *p = irq_data_get_irq_chip_data(d);
unsigned int reg;

faraday_pci_read_config(p->bus, 0, FARADAY_PCI_CTRL2, 4, &reg);
faraday_raw_pci_read_config(p, 0, 0, FARADAY_PCI_CTRL2, 4, &reg);
reg &= ~(0xF << PCI_CTRL2_INTSTS_SHIFT);
reg |= BIT(irqd_to_hwirq(d) + PCI_CTRL2_INTSTS_SHIFT);
faraday_pci_write_config(p->bus, 0, FARADAY_PCI_CTRL2, 4, reg);
faraday_raw_pci_write_config(p, 0, 0, FARADAY_PCI_CTRL2, 4, reg);
}

static void faraday_pci_mask_irq(struct irq_data *d)
{
struct faraday_pci *p = irq_data_get_irq_chip_data(d);
unsigned int reg;

faraday_pci_read_config(p->bus, 0, FARADAY_PCI_CTRL2, 4, &reg);
faraday_raw_pci_read_config(p, 0, 0, FARADAY_PCI_CTRL2, 4, &reg);
reg &= ~((0xF << PCI_CTRL2_INTSTS_SHIFT)
| BIT(irqd_to_hwirq(d) + PCI_CTRL2_INTMASK_SHIFT));
faraday_pci_write_config(p->bus, 0, FARADAY_PCI_CTRL2, 4, reg);
faraday_raw_pci_write_config(p, 0, 0, FARADAY_PCI_CTRL2, 4, reg);
}

static void faraday_pci_unmask_irq(struct irq_data *d)
{
struct faraday_pci *p = irq_data_get_irq_chip_data(d);
unsigned int reg;

faraday_pci_read_config(p->bus, 0, FARADAY_PCI_CTRL2, 4, &reg);
faraday_raw_pci_read_config(p, 0, 0, FARADAY_PCI_CTRL2, 4, &reg);
reg &= ~(0xF << PCI_CTRL2_INTSTS_SHIFT);
reg |= BIT(irqd_to_hwirq(d) + PCI_CTRL2_INTMASK_SHIFT);
faraday_pci_write_config(p->bus, 0, FARADAY_PCI_CTRL2, 4, reg);
faraday_raw_pci_write_config(p, 0, 0, FARADAY_PCI_CTRL2, 4, reg);
}

static void faraday_pci_irq_handler(struct irq_desc *desc)
Expand All @@ -282,7 +298,7 @@ static void faraday_pci_irq_handler(struct irq_desc *desc)
struct irq_chip *irqchip = irq_desc_get_chip(desc);
unsigned int irq_stat, reg, i;

faraday_pci_read_config(p->bus, 0, FARADAY_PCI_CTRL2, 4, &reg);
faraday_raw_pci_read_config(p, 0, 0, FARADAY_PCI_CTRL2, 4, &reg);
irq_stat = reg >> PCI_CTRL2_INTSTS_SHIFT;

chained_irq_enter(irqchip, desc);
Expand Down Expand Up @@ -403,8 +419,8 @@ static int faraday_pci_parse_map_dma_ranges(struct faraday_pci *p,
dev_info(dev, "DMA MEM%d BASE: 0x%016llx -> 0x%016llx config %08x\n",
i + 1, range.pci_addr, end, val);
if (i <= 2) {
faraday_pci_write_config(p->bus, 0, confreg[i],
4, val);
faraday_raw_pci_write_config(p, 0, 0, confreg[i],
4, val);
} else {
dev_err(dev, "ignore extraneous dma-range %d\n", i);
break;
Expand Down Expand Up @@ -496,17 +512,8 @@ static int faraday_pci_probe(struct platform_device *pdev)
val |= PCI_COMMAND_MEMORY;
val |= PCI_COMMAND_MASTER;
writel(val, p->base + PCI_CTRL);

list_splice_init(&res, &host->windows);
ret = pci_register_host_bridge(host);
if (ret) {
dev_err(dev, "failed to register host: %d\n", ret);
return ret;
}
p->bus = host->bus;

/* Mask and clear all interrupts */
faraday_pci_write_config(p->bus, 0, FARADAY_PCI_CTRL2 + 2, 2, 0xF000);
faraday_raw_pci_write_config(p, 0, 0, FARADAY_PCI_CTRL2 + 2, 2, 0xF000);
if (variant->cascaded_irq) {
ret = faraday_pci_setup_cascaded_irq(p);
if (ret) {
Expand All @@ -519,6 +526,14 @@ static int faraday_pci_probe(struct platform_device *pdev)
if (ret)
return ret;

list_splice_init(&res, &host->windows);
ret = pci_register_host_bridge(host);
if (ret) {
dev_err(dev, "failed to register host: %d\n", ret);
return ret;
}
p->bus = host->bus;

pci_scan_child_bus(p->bus);
pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
pci_bus_assign_resources(p->bus);
Expand Down

0 comments on commit f1e8bd2

Please sign in to comment.