diff options
Diffstat (limited to 'arch/mips/pci')
-rw-r--r-- | arch/mips/pci/Makefile | 1 | ||||
-rw-r--r-- | arch/mips/pci/fixup-ath79.c | 21 | ||||
-rw-r--r-- | arch/mips/pci/ops-bridge.c | 68 | ||||
-rw-r--r-- | arch/mips/pci/pci-ip27.c | 49 |
4 files changed, 61 insertions, 78 deletions
diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile index 8185a2bfaf09..c4f976593061 100644 --- a/arch/mips/pci/Makefile +++ b/arch/mips/pci/Makefile @@ -29,6 +29,7 @@ obj-$(CONFIG_MIPS_PCI_VIRTIO) += pci-virtio-guest.o # # These are still pretty much in the old state, watch, go blind. # +obj-$(CONFIG_ATH79) += fixup-ath79.o obj-$(CONFIG_LASAT) += pci-lasat.o obj-$(CONFIG_MIPS_COBALT) += fixup-cobalt.o obj-$(CONFIG_LEMOTE_FULOONG2E) += fixup-fuloong2e.o ops-loongson2.o diff --git a/arch/mips/pci/fixup-ath79.c b/arch/mips/pci/fixup-ath79.c new file mode 100644 index 000000000000..9e651a4af05e --- /dev/null +++ b/arch/mips/pci/fixup-ath79.c @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2018 John Crispin <john@phrozen.org> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + +#include <linux/pci.h> +//#include <linux/of_irq.h> +#include <linux/of_pci.h> + +int pcibios_plat_dev_init(struct pci_dev *dev) +{ + return PCIBIOS_SUCCESSFUL; +} + +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +{ + return of_irq_parse_and_map_pci(dev, slot, pin); +} diff --git a/arch/mips/pci/ops-bridge.c b/arch/mips/pci/ops-bridge.c index a1d2c4ae0d1b..df95b0da08f2 100644 --- a/arch/mips/pci/ops-bridge.c +++ b/arch/mips/pci/ops-bridge.c @@ -44,7 +44,7 @@ static int pci_conf0_read_config(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 * value) { struct bridge_controller *bc = BRIDGE_CONTROLLER(bus); - bridge_t *bridge = bc->base; + struct bridge_regs *bridge = bc->base; int slot = PCI_SLOT(devfn); int fn = PCI_FUNC(devfn); volatile void *addr; @@ -56,11 +56,11 @@ static int pci_conf0_read_config(struct pci_bus *bus, unsigned int devfn, return PCIBIOS_DEVICE_NOT_FOUND; /* - * IOC3 is fucking fucked beyond belief ... Don't even give the + * IOC3 is broken beyond belief ... Don't even give the * generic PCI code a chance to look at it for real ... */ if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16))) - goto oh_my_gawd; + goto is_ioc3; addr = &bridge->b_type0_cfg_dev[slot].f[fn].c[where ^ (4 - size)]; @@ -73,21 +73,16 @@ static int pci_conf0_read_config(struct pci_bus *bus, unsigned int devfn, return res ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL; -oh_my_gawd: +is_ioc3: /* - * IOC3 is fucking fucked beyond belief ... Don't even give the - * generic PCI code a chance to look at the wrong register. + * IOC3 special handling */ if ((where >= 0x14 && where < 0x40) || (where >= 0x48)) { *value = emulate_ioc3_cfg(where, size); return PCIBIOS_SUCCESSFUL; } - /* - * IOC3 is fucking fucked beyond belief ... Don't try to access - * anything but 32-bit words ... - */ addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2]; if (get_dbe(cf, (u32 *) addr)) @@ -104,7 +99,7 @@ static int pci_conf1_read_config(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 * value) { struct bridge_controller *bc = BRIDGE_CONTROLLER(bus); - bridge_t *bridge = bc->base; + struct bridge_regs *bridge = bc->base; int busno = bus->number; int slot = PCI_SLOT(devfn); int fn = PCI_FUNC(devfn); @@ -112,19 +107,19 @@ static int pci_conf1_read_config(struct pci_bus *bus, unsigned int devfn, u32 cf, shift, mask; int res; - bridge->b_pci_cfg = (busno << 16) | (slot << 11); + bridge_write(bc, b_pci_cfg, (busno << 16) | (slot << 11)); addr = &bridge->b_type1_cfg.c[(fn << 8) | PCI_VENDOR_ID]; if (get_dbe(cf, (u32 *) addr)) return PCIBIOS_DEVICE_NOT_FOUND; /* - * IOC3 is fucking fucked beyond belief ... Don't even give the + * IOC3 is broken beyond belief ... Don't even give the * generic PCI code a chance to look at it for real ... */ if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16))) - goto oh_my_gawd; + goto is_ioc3; - bridge->b_pci_cfg = (busno << 16) | (slot << 11); + bridge_write(bc, b_pci_cfg, (busno << 16) | (slot << 11)); addr = &bridge->b_type1_cfg.c[(fn << 8) | (where ^ (4 - size))]; if (size == 1) @@ -136,22 +131,17 @@ static int pci_conf1_read_config(struct pci_bus *bus, unsigned int devfn, return res ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL; -oh_my_gawd: +is_ioc3: /* - * IOC3 is fucking fucked beyond belief ... Don't even give the - * generic PCI code a chance to look at the wrong register. + * IOC3 special handling */ if ((where >= 0x14 && where < 0x40) || (where >= 0x48)) { *value = emulate_ioc3_cfg(where, size); return PCIBIOS_SUCCESSFUL; } - /* - * IOC3 is fucking fucked beyond belief ... Don't try to access - * anything but 32-bit words ... - */ - bridge->b_pci_cfg = (busno << 16) | (slot << 11); + bridge_write(bc, b_pci_cfg, (busno << 16) | (slot << 11)); addr = &bridge->b_type1_cfg.c[(fn << 8) | where]; if (get_dbe(cf, (u32 *) addr)) @@ -177,7 +167,7 @@ static int pci_conf0_write_config(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value) { struct bridge_controller *bc = BRIDGE_CONTROLLER(bus); - bridge_t *bridge = bc->base; + struct bridge_regs *bridge = bc->base; int slot = PCI_SLOT(devfn); int fn = PCI_FUNC(devfn); volatile void *addr; @@ -189,11 +179,11 @@ static int pci_conf0_write_config(struct pci_bus *bus, unsigned int devfn, return PCIBIOS_DEVICE_NOT_FOUND; /* - * IOC3 is fucking fucked beyond belief ... Don't even give the + * IOC3 is broken beyond belief ... Don't even give the * generic PCI code a chance to look at it for real ... */ if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16))) - goto oh_my_gawd; + goto is_ioc3; addr = &bridge->b_type0_cfg_dev[slot].f[fn].c[where ^ (4 - size)]; @@ -210,19 +200,14 @@ static int pci_conf0_write_config(struct pci_bus *bus, unsigned int devfn, return PCIBIOS_SUCCESSFUL; -oh_my_gawd: +is_ioc3: /* - * IOC3 is fucking fucked beyond belief ... Don't even give the - * generic PCI code a chance to touch the wrong register. + * IOC3 special handling */ if ((where >= 0x14 && where < 0x40) || (where >= 0x48)) return PCIBIOS_SUCCESSFUL; - /* - * IOC3 is fucking fucked beyond belief ... Don't try to access - * anything but 32-bit words ... - */ addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2]; if (get_dbe(cf, (u32 *) addr)) @@ -243,7 +228,7 @@ static int pci_conf1_write_config(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value) { struct bridge_controller *bc = BRIDGE_CONTROLLER(bus); - bridge_t *bridge = bc->base; + struct bridge_regs *bridge = bc->base; int slot = PCI_SLOT(devfn); int fn = PCI_FUNC(devfn); int busno = bus->number; @@ -251,17 +236,17 @@ static int pci_conf1_write_config(struct pci_bus *bus, unsigned int devfn, u32 cf, shift, mask, smask; int res; - bridge->b_pci_cfg = (busno << 16) | (slot << 11); + bridge_write(bc, b_pci_cfg, (busno << 16) | (slot << 11)); addr = &bridge->b_type1_cfg.c[(fn << 8) | PCI_VENDOR_ID]; if (get_dbe(cf, (u32 *) addr)) return PCIBIOS_DEVICE_NOT_FOUND; /* - * IOC3 is fucking fucked beyond belief ... Don't even give the + * IOC3 is broken beyond belief ... Don't even give the * generic PCI code a chance to look at it for real ... */ if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16))) - goto oh_my_gawd; + goto is_ioc3; addr = &bridge->b_type1_cfg.c[(fn << 8) | (where ^ (4 - size))]; @@ -278,19 +263,14 @@ static int pci_conf1_write_config(struct pci_bus *bus, unsigned int devfn, return PCIBIOS_SUCCESSFUL; -oh_my_gawd: +is_ioc3: /* - * IOC3 is fucking fucked beyond belief ... Don't even give the - * generic PCI code a chance to touch the wrong register. + * IOC3 special handling */ if ((where >= 0x14 && where < 0x40) || (where >= 0x48)) return PCIBIOS_SUCCESSFUL; - /* - * IOC3 is fucking fucked beyond belief ... Don't try to access - * anything but 32-bit words ... - */ addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2]; if (get_dbe(cf, (u32 *) addr)) diff --git a/arch/mips/pci/pci-ip27.c b/arch/mips/pci/pci-ip27.c index c94a66070a60..3c177b4d0609 100644 --- a/arch/mips/pci/pci-ip27.c +++ b/arch/mips/pci/pci-ip27.c @@ -24,22 +24,11 @@ #define MAX_PCI_BUSSES 40 /* - * Max #PCI devices (like scsi controllers) we handle on a bus. - */ -#define MAX_DEVICES_PER_PCIBUS 8 - -/* * XXX: No kmalloc available when we do our crosstalk scan, * we should try to move it later in the boot process. */ static struct bridge_controller bridges[MAX_PCI_BUSSES]; -/* - * Translate from irq to software PCI bus number and PCI slot. - */ -struct bridge_controller *irq_to_bridge[MAX_PCI_BUSSES * MAX_DEVICES_PER_PCIBUS]; -int irq_to_slot[MAX_PCI_BUSSES * MAX_DEVICES_PER_PCIBUS]; - extern struct pci_ops bridge_pci_ops; int bridge_probe(nasid_t nasid, int widget_id, int masterwid) @@ -47,7 +36,6 @@ int bridge_probe(nasid_t nasid, int widget_id, int masterwid) unsigned long offset = NODE_OFFSET(nasid); struct bridge_controller *bc; static int num_bridges = 0; - bridge_t *bridge; int slot; pci_set_flags(PCI_PROBE_ONLY); @@ -78,7 +66,6 @@ int bridge_probe(nasid_t nasid, int widget_id, int masterwid) bc->io.end = ~0UL; bc->io.flags = IORESOURCE_IO; - bc->irq_cpu = smp_processor_id(); bc->widget_id = widget_id; bc->nasid = nasid; @@ -87,45 +74,43 @@ int bridge_probe(nasid_t nasid, int widget_id, int masterwid) /* * point to this bridge */ - bridge = (bridge_t *) RAW_NODE_SWIN_BASE(nasid, widget_id); + bc->base = (struct bridge_regs *)RAW_NODE_SWIN_BASE(nasid, widget_id); /* * Clear all pending interrupts. */ - bridge->b_int_rst_stat = BRIDGE_IRR_ALL_CLR; + bridge_write(bc, b_int_rst_stat, BRIDGE_IRR_ALL_CLR); /* * Until otherwise set up, assume all interrupts are from slot 0 */ - bridge->b_int_device = 0x0; + bridge_write(bc, b_int_device, 0x0); /* * swap pio's to pci mem and io space (big windows) */ - bridge->b_wid_control |= BRIDGE_CTRL_IO_SWAP | - BRIDGE_CTRL_MEM_SWAP; + bridge_set(bc, b_wid_control, BRIDGE_CTRL_IO_SWAP | + BRIDGE_CTRL_MEM_SWAP); #ifdef CONFIG_PAGE_SIZE_4KB - bridge->b_wid_control &= ~BRIDGE_CTRL_PAGE_SIZE; + bridge_clr(bc, b_wid_control, BRIDGE_CTRL_PAGE_SIZE); #else /* 16kB or larger */ - bridge->b_wid_control |= BRIDGE_CTRL_PAGE_SIZE; + bridge_set(bc, b_wid_control, BRIDGE_CTRL_PAGE_SIZE); #endif /* * Hmm... IRIX sets additional bits in the address which * are documented as reserved in the bridge docs. */ - bridge->b_wid_int_upper = 0x8000 | (masterwid << 16); - bridge->b_wid_int_lower = 0x01800090; /* PI_INT_PEND_MOD off*/ - bridge->b_dir_map = (masterwid << 20); /* DMA */ - bridge->b_int_enable = 0; + bridge_write(bc, b_wid_int_upper, 0x8000 | (masterwid << 16)); + bridge_write(bc, b_wid_int_lower, 0x01800090); /* PI_INT_PEND_MOD off*/ + bridge_write(bc, b_dir_map, (masterwid << 20)); /* DMA */ + bridge_write(bc, b_int_enable, 0); for (slot = 0; slot < 8; slot ++) { - bridge->b_device[slot].reg |= BRIDGE_DEV_SWAP_DIR; + bridge_set(bc, b_device[slot].reg, BRIDGE_DEV_SWAP_DIR); bc->pci_int[slot] = -1; } - bridge->b_wid_tflush; /* wait until Bridge PIO complete */ - - bc->base = bridge; + bridge_read(bc, b_wid_tflush); /* wait until Bridge PIO complete */ register_pci_controller(&bc->pc); @@ -168,16 +153,12 @@ int pcibios_plat_dev_init(struct pci_dev *dev) irq = bc->pci_int[slot]; if (irq == -1) { - irq = request_bridge_irq(bc); + irq = request_bridge_irq(bc, slot); if (irq < 0) return irq; bc->pci_int[slot] = irq; } - - irq_to_bridge[irq] = bc; - irq_to_slot[irq] = slot; - dev->irq = irq; return 0; @@ -206,7 +187,7 @@ phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t dma_addr) static inline void pci_disable_swapping(struct pci_dev *dev) { struct bridge_controller *bc = BRIDGE_CONTROLLER(dev->bus); - bridge_t *bridge = bc->base; + struct bridge_regs *bridge = bc->base; int slot = PCI_SLOT(dev->devfn); /* Turn off byte swapping */ |