|
@@ -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) |
|
|
@@ -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) |
|
|
@@ -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,
|
|
@@ -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);
|
|
|
unsigned int reg;
|
|
|
|
|
|
- faraday_pci_read_config(p->bus, 0, FARADAY_PCI_CTRL2, 4, ®);
|
|
|
+ faraday_raw_pci_read_config(p, 0, 0, FARADAY_PCI_CTRL2, 4, ®);
|
|
|
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)
|
|
@@ -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);
|
|
|
unsigned int reg;
|
|
|
|
|
|
- faraday_pci_read_config(p->bus, 0, FARADAY_PCI_CTRL2, 4, ®);
|
|
|
+ faraday_raw_pci_read_config(p, 0, 0, FARADAY_PCI_CTRL2, 4, ®);
|
|
|
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)
|
|
@@ -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);
|
|
|
unsigned int reg;
|
|
|
|
|
|
- faraday_pci_read_config(p->bus, 0, FARADAY_PCI_CTRL2, 4, ®);
|
|
|
+ faraday_raw_pci_read_config(p, 0, 0, FARADAY_PCI_CTRL2, 4, ®);
|
|
|
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)
|
|
@@ -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, ®);
|
|
|
+ faraday_raw_pci_read_config(p, 0, 0, FARADAY_PCI_CTRL2, 4, ®);
|
|
|
irq_stat = reg >> PCI_CTRL2_INTSTS_SHIFT;
|
|
|
|
|
|
chained_irq_enter(irqchip, desc);
|
|
@@ -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;
|
|
@@ -432,7 +448,7 @@ static int faraday_pci_probe(struct platform_device *pdev)
|
|
|
u32 val;
|
|
|
LIST_HEAD(res);
|
|
|
|
|
|
- host = pci_alloc_host_bridge(sizeof(*p));
|
|
|
+ host = devm_pci_alloc_host_bridge(dev, sizeof(*p));
|
|
|
if (!host)
|
|
|
return -ENOMEM;
|
|
|
|
|
@@ -440,6 +456,8 @@ static int faraday_pci_probe(struct platform_device *pdev)
|
|
|
host->ops = &faraday_pci_ops;
|
|
|
host->busnr = 0;
|
|
|
host->msi = NULL;
|
|
|
+ host->map_irq = of_irq_parse_and_map_pci;
|
|
|
+ host->swizzle_irq = pci_common_swizzle;
|
|
|
p = pci_host_bridge_priv(host);
|
|
|
host->sysdata = p;
|
|
|
p->dev = dev;
|
|
@@ -496,17 +514,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) {
|
|
@@ -519,8 +528,14 @@ static int faraday_pci_probe(struct platform_device *pdev)
|
|
|
if (ret)
|
|
|
return ret;
|
|
|
|
|
|
- pci_scan_child_bus(p->bus);
|
|
|
- pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
|
|
|
+ list_splice_init(&res, &host->windows);
|
|
|
+ ret = pci_scan_root_bus_bridge(host);
|
|
|
+ if (ret) {
|
|
|
+ dev_err(dev, "failed to scan host: %d\n", ret);
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+ p->bus = host->bus;
|
|
|
+
|
|
|
pci_bus_assign_resources(p->bus);
|
|
|
pci_bus_add_devices(p->bus);
|
|
|
pci_free_resource_list(&res);
|