Commit f1e8bd21 authored by Lorenzo Pieralisi's avatar Lorenzo Pieralisi Committed by Bjorn Helgaas

PCI: faraday: Convert IRQ masking to raw PCI config accessors

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: default avatarLorenzo 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: default avatarBjorn Helgaas <bhelgaas@google.com>
Acked-by: default avatarLinus Walleij <linus.walleij@linaro.org>
parent 022adcfc
...@@ -178,12 +178,11 @@ static int faraday_res_to_memcfg(resource_size_t mem_base, ...@@ -178,12 +178,11 @@ static int faraday_res_to_memcfg(resource_size_t mem_base,
return 0; return 0;
} }
static int faraday_pci_read_config(struct pci_bus *bus, unsigned int fn, static int faraday_raw_pci_read_config(struct faraday_pci *p, int bus_number,
int config, int size, u32 *value) 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_DEVICE(PCI_SLOT(fn)) |
PCI_CONF_FUNCTION(PCI_FUNC(fn)) | PCI_CONF_FUNCTION(PCI_FUNC(fn)) |
PCI_CONF_WHERE(config) | PCI_CONF_WHERE(config) |
...@@ -197,24 +196,28 @@ static int faraday_pci_read_config(struct pci_bus *bus, unsigned int fn, ...@@ -197,24 +196,28 @@ static int faraday_pci_read_config(struct pci_bus *bus, unsigned int fn,
else if (size == 2) else if (size == 2)
*value = (*value >> (8 * (config & 3))) & 0xFFFF; *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, dev_dbg(&bus->dev,
"[read] slt: %.2d, fnc: %d, cnf: 0x%.2X, val (%d bytes): 0x%.8X\n", "[read] slt: %.2d, fnc: %d, cnf: 0x%.2X, val (%d bytes): 0x%.8X\n",
PCI_SLOT(fn), PCI_FUNC(fn), config, size, *value); 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, static int faraday_raw_pci_write_config(struct faraday_pci *p, int bus_number,
int config, int size, u32 value) unsigned int fn, int config, int size,
u32 value)
{ {
struct faraday_pci *p = bus->sysdata;
int ret = PCIBIOS_SUCCESSFUL; int ret = PCIBIOS_SUCCESSFUL;
dev_dbg(&bus->dev, writel(PCI_CONF_BUS(bus_number) |
"[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) |
PCI_CONF_DEVICE(PCI_SLOT(fn)) | PCI_CONF_DEVICE(PCI_SLOT(fn)) |
PCI_CONF_FUNCTION(PCI_FUNC(fn)) | PCI_CONF_FUNCTION(PCI_FUNC(fn)) |
PCI_CONF_WHERE(config) | PCI_CONF_WHERE(config) |
...@@ -238,6 +241,19 @@ static int faraday_pci_write_config(struct pci_bus *bus, unsigned int fn, ...@@ -238,6 +241,19 @@ static int faraday_pci_write_config(struct pci_bus *bus, unsigned int fn,
return ret; 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 = { static struct pci_ops faraday_pci_ops = {
.read = faraday_pci_read_config, .read = faraday_pci_read_config,
.write = faraday_pci_write_config, .write = faraday_pci_write_config,
...@@ -248,10 +264,10 @@ static void faraday_pci_ack_irq(struct irq_data *d) ...@@ -248,10 +264,10 @@ static void faraday_pci_ack_irq(struct irq_data *d)
struct faraday_pci *p = irq_data_get_irq_chip_data(d); struct faraday_pci *p = irq_data_get_irq_chip_data(d);
unsigned int reg; 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 &= ~(0xF << PCI_CTRL2_INTSTS_SHIFT);
reg |= BIT(irqd_to_hwirq(d) + 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) static void faraday_pci_mask_irq(struct irq_data *d)
...@@ -259,10 +275,10 @@ static void faraday_pci_mask_irq(struct irq_data *d) ...@@ -259,10 +275,10 @@ static void faraday_pci_mask_irq(struct irq_data *d)
struct faraday_pci *p = irq_data_get_irq_chip_data(d); struct faraday_pci *p = irq_data_get_irq_chip_data(d);
unsigned int reg; 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 &= ~((0xF << PCI_CTRL2_INTSTS_SHIFT)
| BIT(irqd_to_hwirq(d) + PCI_CTRL2_INTMASK_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) static void faraday_pci_unmask_irq(struct irq_data *d)
...@@ -270,10 +286,10 @@ static void faraday_pci_unmask_irq(struct irq_data *d) ...@@ -270,10 +286,10 @@ static void faraday_pci_unmask_irq(struct irq_data *d)
struct faraday_pci *p = irq_data_get_irq_chip_data(d); struct faraday_pci *p = irq_data_get_irq_chip_data(d);
unsigned int reg; 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 &= ~(0xF << PCI_CTRL2_INTSTS_SHIFT);
reg |= BIT(irqd_to_hwirq(d) + PCI_CTRL2_INTMASK_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) static void faraday_pci_irq_handler(struct irq_desc *desc)
...@@ -282,7 +298,7 @@ static void faraday_pci_irq_handler(struct irq_desc *desc) ...@@ -282,7 +298,7 @@ static void faraday_pci_irq_handler(struct irq_desc *desc)
struct irq_chip *irqchip = irq_desc_get_chip(desc); struct irq_chip *irqchip = irq_desc_get_chip(desc);
unsigned int irq_stat, reg, i; 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; irq_stat = reg >> PCI_CTRL2_INTSTS_SHIFT;
chained_irq_enter(irqchip, desc); chained_irq_enter(irqchip, desc);
...@@ -403,8 +419,8 @@ static int faraday_pci_parse_map_dma_ranges(struct faraday_pci *p, ...@@ -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", dev_info(dev, "DMA MEM%d BASE: 0x%016llx -> 0x%016llx config %08x\n",
i + 1, range.pci_addr, end, val); i + 1, range.pci_addr, end, val);
if (i <= 2) { if (i <= 2) {
faraday_pci_write_config(p->bus, 0, confreg[i], faraday_raw_pci_write_config(p, 0, 0, confreg[i],
4, val); 4, val);
} else { } else {
dev_err(dev, "ignore extraneous dma-range %d\n", i); dev_err(dev, "ignore extraneous dma-range %d\n", i);
break; break;
...@@ -496,17 +512,8 @@ static int faraday_pci_probe(struct platform_device *pdev) ...@@ -496,17 +512,8 @@ static int faraday_pci_probe(struct platform_device *pdev)
val |= PCI_COMMAND_MEMORY; val |= PCI_COMMAND_MEMORY;
val |= PCI_COMMAND_MASTER; val |= PCI_COMMAND_MASTER;
writel(val, p->base + PCI_CTRL); 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 */ /* 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) { if (variant->cascaded_irq) {
ret = faraday_pci_setup_cascaded_irq(p); ret = faraday_pci_setup_cascaded_irq(p);
if (ret) { if (ret) {
...@@ -519,6 +526,14 @@ static int faraday_pci_probe(struct platform_device *pdev) ...@@ -519,6 +526,14 @@ static int faraday_pci_probe(struct platform_device *pdev)
if (ret) if (ret)
return 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_scan_child_bus(p->bus);
pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci); pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
pci_bus_assign_resources(p->bus); pci_bus_assign_resources(p->bus);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment