From 2a5dccdb00d85a6ad6111d7a2b13f9f4fae35838 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Thu, 21 Mar 2013 17:34:08 +0100 Subject: [PATCH 135/137] PCI: MIPS: adds rt3883 pci support Add support for the pcie found on the rt3883 SoC. Signed-off-by: John Crispin --- arch/mips/pci/Makefile | 1 + arch/mips/pci/pci-rt3883.c | 640 ++++++++++++++++++++++++++++++++++++++++++++ arch/mips/ralink/Kconfig | 1 + 3 files changed, 642 insertions(+) create mode 100644 arch/mips/pci/pci-rt3883.c --- a/arch/mips/pci/Makefile +++ b/arch/mips/pci/Makefile @@ -43,6 +43,7 @@ obj-$(CONFIG_SNI_RM) += fixup-sni.o ops obj-$(CONFIG_LANTIQ) += fixup-lantiq.o obj-$(CONFIG_PCI_LANTIQ) += pci-lantiq.o ops-lantiq.o obj-$(CONFIG_SOC_RT2880) += pci-rt2880.o +obj-$(CONFIG_SOC_RT3883) += pci-rt3883.o obj-$(CONFIG_TANBAC_TB0219) += fixup-tb0219.o obj-$(CONFIG_TANBAC_TB0226) += fixup-tb0226.o obj-$(CONFIG_TANBAC_TB0287) += fixup-tb0287.o --- /dev/null +++ b/arch/mips/pci/pci-rt3883.c @@ -0,0 +1,640 @@ +/* + * Ralink RT3662/RT3883 SoC PCI support + * + * Copyright (C) 2011-2013 Gabor Juhos + * + * Parts of this file are based on Ralink's 2.6.21 BSP + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define RT3883_MEMORY_BASE 0x00000000 +#define RT3883_MEMORY_SIZE 0x02000000 + +#define RT3883_PCI_REG_PCICFG 0x00 +#define RT3883_PCICFG_P2P_BR_DEVNUM_M 0xf +#define RT3883_PCICFG_P2P_BR_DEVNUM_S 16 +#define RT3883_PCICFG_PCIRST BIT(1) +#define RT3883_PCI_REG_PCIRAW 0x04 +#define RT3883_PCI_REG_PCIINT 0x08 +#define RT3883_PCI_REG_PCIENA 0x0c + +#define RT3883_PCI_REG_CFGADDR 0x20 +#define RT3883_PCI_REG_CFGDATA 0x24 +#define RT3883_PCI_REG_MEMBASE 0x28 +#define RT3883_PCI_REG_IOBASE 0x2c +#define RT3883_PCI_REG_ARBCTL 0x80 + +#define RT3883_PCI_REG_BASE(_x) (0x1000 + (_x) * 0x1000) +#define RT3883_PCI_REG_BAR0SETUP(_x) (RT3883_PCI_REG_BASE((_x)) + 0x10) +#define RT3883_PCI_REG_IMBASEBAR0(_x) (RT3883_PCI_REG_BASE((_x)) + 0x18) +#define RT3883_PCI_REG_ID(_x) (RT3883_PCI_REG_BASE((_x)) + 0x30) +#define RT3883_PCI_REG_CLASS(_x) (RT3883_PCI_REG_BASE((_x)) + 0x34) +#define RT3883_PCI_REG_SUBID(_x) (RT3883_PCI_REG_BASE((_x)) + 0x38) +#define RT3883_PCI_REG_STATUS(_x) (RT3883_PCI_REG_BASE((_x)) + 0x50) + +#define RT3883_PCI_MODE_NONE 0 +#define RT3883_PCI_MODE_PCI BIT(0) +#define RT3883_PCI_MODE_PCIE BIT(1) +#define RT3883_PCI_MODE_BOTH (RT3883_PCI_MODE_PCI | RT3883_PCI_MODE_PCIE) + +#define RT3883_PCI_IRQ_COUNT 32 + +#define RT3883_P2P_BR_DEVNUM 1 + +struct rt3883_pci_controller { + void __iomem *base; + spinlock_t lock; + + struct irq_domain *irq_domain; + + struct pci_controller pci_controller; + struct resource io_res; + struct resource mem_res; + + bool pcie_ready; + unsigned char p2p_devnum; +}; + +static inline struct rt3883_pci_controller * +pci_bus_to_rt3883_controller(struct pci_bus *bus) +{ + struct pci_controller *hose; + + hose = (struct pci_controller *) bus->sysdata; + return container_of(hose, struct rt3883_pci_controller, pci_controller); +} + +static inline u32 rt3883_pci_r32(struct rt3883_pci_controller *rpc, + unsigned reg) +{ + return ioread32(rpc->base + reg); +} + +static inline void rt3883_pci_w32(struct rt3883_pci_controller *rpc, + u32 val, unsigned reg) +{ + iowrite32(val, rpc->base + reg); +} + +static inline u32 rt3883_pci_get_cfgaddr(unsigned int bus, unsigned int slot, + unsigned int func, unsigned int where) +{ + return ((bus << 16) | (slot << 11) | (func << 8) | (where & 0xfc) | + 0x80000000); +} + +static u32 rt3883_pci_read_cfg32(struct rt3883_pci_controller *rpc, + unsigned bus, unsigned slot, + unsigned func, unsigned reg) +{ + unsigned long flags; + u32 address; + u32 ret; + + address = rt3883_pci_get_cfgaddr(bus, slot, func, reg); + + spin_lock_irqsave(&rpc->lock, flags); + rt3883_pci_w32(rpc, address, RT3883_PCI_REG_CFGADDR); + ret = rt3883_pci_r32(rpc, RT3883_PCI_REG_CFGDATA); + spin_unlock_irqrestore(&rpc->lock, flags); + + return ret; +} + +static void rt3883_pci_write_cfg32(struct rt3883_pci_controller *rpc, + unsigned bus, unsigned slot, + unsigned func, unsigned reg, u32 val) +{ + unsigned long flags; + u32 address; + + address = rt3883_pci_get_cfgaddr(bus, slot, func, reg); + + spin_lock_irqsave(&rpc->lock, flags); + rt3883_pci_w32(rpc, address, RT3883_PCI_REG_CFGADDR); + rt3883_pci_w32(rpc, val, RT3883_PCI_REG_CFGDATA); + spin_unlock_irqrestore(&rpc->lock, flags); +} + +static void rt3883_pci_irq_handler(unsigned int irq, struct irq_desc *desc) +{ + struct rt3883_pci_controller *rpc; + u32 pending; + + rpc = irq_get_handler_data(irq); + + pending = rt3883_pci_r32(rpc, RT3883_PCI_REG_PCIINT) & + rt3883_pci_r32(rpc, RT3883_PCI_REG_PCIENA); + + if (!pending) { + spurious_interrupt(); + return; + } + + while (pending) { + unsigned bit = __ffs(pending); + + irq = irq_find_mapping(rpc->irq_domain, bit); + generic_handle_irq(irq); + + pending &= ~BIT(bit); + } +} + +static void rt3883_pci_irq_unmask(struct irq_data *d) +{ + struct rt3883_pci_controller *rpc; + u32 t; + + rpc = irq_data_get_irq_chip_data(d); + + t = rt3883_pci_r32(rpc, RT3883_PCI_REG_PCIENA); + rt3883_pci_w32(rpc, t | BIT(d->hwirq), RT3883_PCI_REG_PCIENA); + /* flush write */ + rt3883_pci_r32(rpc, RT3883_PCI_REG_PCIENA); +} + +static void rt3883_pci_irq_mask(struct irq_data *d) +{ + struct rt3883_pci_controller *rpc; + u32 t; + + rpc = irq_data_get_irq_chip_data(d); + + t = rt3883_pci_r32(rpc, RT3883_PCI_REG_PCIENA); + rt3883_pci_w32(rpc, t & ~BIT(d->hwirq), RT3883_PCI_REG_PCIENA); + /* flush write */ + rt3883_pci_r32(rpc, RT3883_PCI_REG_PCIENA); +} + +static struct irq_chip rt3883_pci_irq_chip = { + .name = "RT3883 PCI", + .irq_mask = rt3883_pci_irq_mask, + .irq_unmask = rt3883_pci_irq_unmask, + .irq_mask_ack = rt3883_pci_irq_mask, +}; + +static int rt3883_pci_irq_map(struct irq_domain *d, unsigned int irq, + irq_hw_number_t hw) +{ + irq_set_chip_and_handler(irq, &rt3883_pci_irq_chip, handle_level_irq); + irq_set_chip_data(irq, d->host_data); + + return 0; +} + +static const struct irq_domain_ops rt3883_pci_irq_domain_ops = { + .map = rt3883_pci_irq_map, + .xlate = irq_domain_xlate_onecell, +}; + +static int rt3883_pci_irq_init(struct device *dev, + struct rt3883_pci_controller *rpc) +{ + struct device_node *np = dev->of_node; + struct device_node *intc_np; + int irq; + int err; + + intc_np = of_get_child_by_name(np, "interrupt-controller"); + if (!intc_np) { + dev_err(dev, "no %s child node found", "interrupt-controller"); + return -ENODEV; + } + + irq = irq_of_parse_and_map(intc_np, 0); + if (irq == 0) { + dev_err(dev, "%s has no IRQ", of_node_full_name(intc_np)); + err = -EINVAL; + goto err_put_intc; + } + + /* disable all interrupts */ + rt3883_pci_w32(rpc, 0, RT3883_PCI_REG_PCIENA); + + rpc->irq_domain = + irq_domain_add_linear(intc_np, RT3883_PCI_IRQ_COUNT, + &rt3883_pci_irq_domain_ops, + rpc); + if (!rpc->irq_domain) { + dev_err(dev, "unable to add IRQ domain\n"); + err = -ENODEV; + goto err_put_intc; + } + + irq_set_handler_data(irq, rpc); + irq_set_chained_handler(irq, rt3883_pci_irq_handler); + + return 0; + +err_put_intc: + of_node_put(intc_np); + return err; +} + +static int rt3883_pci_config_read(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 *val) +{ + struct rt3883_pci_controller *rpc; + unsigned long flags; + u32 address; + u32 data; + + rpc = pci_bus_to_rt3883_controller(bus); + + if (!rpc->pcie_ready && bus->number == 1) + return PCIBIOS_DEVICE_NOT_FOUND; + + address = rt3883_pci_get_cfgaddr(bus->number, PCI_SLOT(devfn), + PCI_FUNC(devfn), where); + + spin_lock_irqsave(&rpc->lock, flags); + rt3883_pci_w32(rpc, address, RT3883_PCI_REG_CFGADDR); + data = rt3883_pci_r32(rpc, RT3883_PCI_REG_CFGDATA); + spin_unlock_irqrestore(&rpc->lock, flags); + + switch (size) { + case 1: + *val = (data >> ((where & 3) << 3)) & 0xff; + break; + case 2: + *val = (data >> ((where & 3) << 3)) & 0xffff; + break; + case 4: + *val = data; + break; + } + + return PCIBIOS_SUCCESSFUL; +} + +static int rt3883_pci_config_write(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 val) +{ + struct rt3883_pci_controller *rpc; + unsigned long flags; + u32 address; + u32 data; + + rpc = pci_bus_to_rt3883_controller(bus); + + if (!rpc->pcie_ready && bus->number == 1) + return PCIBIOS_DEVICE_NOT_FOUND; + + address = rt3883_pci_get_cfgaddr(bus->number, PCI_SLOT(devfn), + PCI_FUNC(devfn), where); + + spin_lock_irqsave(&rpc->lock, flags); + rt3883_pci_w32(rpc, address, RT3883_PCI_REG_CFGADDR); + data = rt3883_pci_r32(rpc, RT3883_PCI_REG_CFGDATA); + + switch (size) { + case 1: + data = (data & ~(0xff << ((where & 3) << 3))) | + (val << ((where & 3) << 3)); + break; + case 2: + data = (data & ~(0xffff << ((where & 3) << 3))) | + (val << ((where & 3) << 3)); + break; + case 4: + data = val; + break; + } + + rt3883_pci_w32(rpc, data, RT3883_PCI_REG_CFGDATA); + spin_unlock_irqrestore(&rpc->lock, flags); + + return PCIBIOS_SUCCESSFUL; +} + +static struct pci_ops rt3883_pci_ops = { + .read = rt3883_pci_config_read, + .write = rt3883_pci_config_write, +}; + +static void rt3883_pci_preinit(struct rt3883_pci_controller *rpc, unsigned mode) +{ + u32 syscfg1; + u32 rstctrl; + u32 clkcfg1; + u32 t; + + rstctrl = rt_sysc_r32(RT3883_SYSC_REG_RSTCTRL); + syscfg1 = rt_sysc_r32(RT3883_SYSC_REG_SYSCFG1); + clkcfg1 = rt_sysc_r32(RT3883_SYSC_REG_CLKCFG1); + + if (mode & RT3883_PCI_MODE_PCIE) { + rstctrl |= RT3883_RSTCTRL_PCIE; + rt_sysc_w32(rstctrl, RT3883_SYSC_REG_RSTCTRL); + + /* setup PCI PAD drive mode */ + syscfg1 &= ~(0x30); + syscfg1 |= (2 << 4); + rt_sysc_w32(syscfg1, RT3883_SYSC_REG_SYSCFG1); + + t = rt_sysc_r32(RT3883_SYSC_REG_PCIE_CLK_GEN0); + t &= ~BIT(31); + rt_sysc_w32(t, RT3883_SYSC_REG_PCIE_CLK_GEN0); + + t = rt_sysc_r32(RT3883_SYSC_REG_PCIE_CLK_GEN1); + t &= 0x80ffffff; + rt_sysc_w32(t, RT3883_SYSC_REG_PCIE_CLK_GEN1); + + t = rt_sysc_r32(RT3883_SYSC_REG_PCIE_CLK_GEN1); + t |= 0xa << 24; + rt_sysc_w32(t, RT3883_SYSC_REG_PCIE_CLK_GEN1); + + t = rt_sysc_r32(RT3883_SYSC_REG_PCIE_CLK_GEN0); + t |= BIT(31); + rt_sysc_w32(t, RT3883_SYSC_REG_PCIE_CLK_GEN0); + + msleep(50); + + rstctrl &= ~RT3883_RSTCTRL_PCIE; + rt_sysc_w32(rstctrl, RT3883_SYSC_REG_RSTCTRL); + } + + syscfg1 |= (RT3883_SYSCFG1_PCIE_RC_MODE | RT3883_SYSCFG1_PCI_HOST_MODE); + + clkcfg1 &= ~(RT3883_CLKCFG1_PCI_CLK_EN | RT3883_CLKCFG1_PCIE_CLK_EN); + + if (mode & RT3883_PCI_MODE_PCI) { + clkcfg1 |= RT3883_CLKCFG1_PCI_CLK_EN; + rstctrl &= ~RT3883_RSTCTRL_PCI; + } + + if (mode & RT3883_PCI_MODE_PCIE) { + clkcfg1 |= RT3883_CLKCFG1_PCIE_CLK_EN; + rstctrl &= ~RT3883_RSTCTRL_PCIE; + } + + rt_sysc_w32(syscfg1, RT3883_SYSC_REG_SYSCFG1); + rt_sysc_w32(rstctrl, RT3883_SYSC_REG_RSTCTRL); + rt_sysc_w32(clkcfg1, RT3883_SYSC_REG_CLKCFG1); + + msleep(500); + + /* + * setup the device number of the P2P bridge + * and de-assert the reset line + */ + t = (RT3883_P2P_BR_DEVNUM << RT3883_PCICFG_P2P_BR_DEVNUM_S); + rt3883_pci_w32(rpc, t, RT3883_PCI_REG_PCICFG); + + /* flush write */ + rt3883_pci_r32(rpc, RT3883_PCI_REG_PCICFG); + msleep(500); + + if (mode & RT3883_PCI_MODE_PCIE) { + msleep(500); + + t = rt3883_pci_r32(rpc, RT3883_PCI_REG_STATUS(1)); + + rpc->pcie_ready = t & BIT(0); + + if (!rpc->pcie_ready) { + /* reset the PCIe block */ + t = rt_sysc_r32(RT3883_SYSC_REG_RSTCTRL); + t |= RT3883_RSTCTRL_PCIE; + rt_sysc_w32(t, RT3883_SYSC_REG_RSTCTRL); + t &= ~RT3883_RSTCTRL_PCIE; + rt_sysc_w32(t, RT3883_SYSC_REG_RSTCTRL); + + /* turn off PCIe clock */ + t = rt_sysc_r32(RT3883_SYSC_REG_CLKCFG1); + t &= ~RT3883_CLKCFG1_PCIE_CLK_EN; + rt_sysc_w32(t, RT3883_SYSC_REG_CLKCFG1); + + t = rt_sysc_r32(RT3883_SYSC_REG_PCIE_CLK_GEN0); + t &= ~0xf000c080; + rt_sysc_w32(t, RT3883_SYSC_REG_PCIE_CLK_GEN0); + } + } + + /* enable PCI arbiter */ + rt3883_pci_w32(rpc, 0x79, RT3883_PCI_REG_ARBCTL); +} + +static inline void +rt3883_dump_pci_config(struct rt3883_pci_controller *rpc, + int bus, int slot) +{ + int i; + + for (i = 0; i < 16; i++) { + u32 val; + + val = rt3883_pci_read_cfg32(rpc, bus, slot, 0, i << 2); + pr_info("pci %02x:%02x.0 0x%02x = %08x\n", + bus, slot, i << 2, val); + } +} + +static int rt3883_pci_probe(struct platform_device *pdev) +{ + struct rt3883_pci_controller *rpc; + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + struct resource *res; + struct device_node *child; + u32 val; + int err; + int mode; + + rpc = devm_kzalloc(dev, sizeof(*rpc), GFP_KERNEL); + if (!rpc) + return -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -EINVAL; + + rpc->base = devm_ioremap_resource(dev, res); + if (IS_ERR(rpc->base)) + return PTR_ERR(rpc->base); + + rpc->pci_controller.of_node = of_get_child_by_name(np, "host-bridge"); + if (!rpc->pci_controller.of_node) { + dev_err(dev, "no %s child node found", "host-bridge"); + return -ENODEV; + } + + mode = RT3883_PCI_MODE_NONE; + for_each_child_of_node(rpc->pci_controller.of_node, child) { + u32 slot; + + if (!of_device_is_available(child)) + continue; + + if (of_property_read_u32(child, "ralink,pci-slot", + &slot)) { + dev_err(dev, "no '%s' property found for %s\n", + "ralink,pci-slot", + of_node_full_name(child)); + continue; + } + + switch (slot) { + case 1: + mode |= RT3883_PCI_MODE_PCIE; + break; + + case 17: + case 18: + mode |= RT3883_PCI_MODE_PCI; + break; + } + } + + if (mode == RT3883_PCI_MODE_NONE) { + dev_err(dev, "unable to determine PCI mode\n"); + err = -EINVAL; + goto err_put_hb_node; + } + + dev_info(dev, "mode:%s%s\n", + (mode & RT3883_PCI_MODE_PCI) ? " PCI" : "", + (mode & RT3883_PCI_MODE_PCIE) ? " PCIe" : ""); + + rt3883_pci_preinit(rpc, mode); + + rpc->pci_controller.pci_ops = &rt3883_pci_ops; + rpc->pci_controller.io_resource = &rpc->io_res; + rpc->pci_controller.mem_resource = &rpc->mem_res; + + /* Load PCI I/O and memory resources from DT */ + pci_load_of_ranges(&rpc->pci_controller, + rpc->pci_controller.of_node); + + rt3883_pci_w32(rpc, rpc->mem_res.start, RT3883_PCI_REG_MEMBASE); + rt3883_pci_w32(rpc, rpc->io_res.start, RT3883_PCI_REG_IOBASE); + + ioport_resource.start = rpc->io_res.start; + ioport_resource.end = rpc->io_res.end; + + /* PCI */ + rt3883_pci_w32(rpc, 0x03ff0000, RT3883_PCI_REG_BAR0SETUP(0)); + rt3883_pci_w32(rpc, RT3883_MEMORY_BASE, RT3883_PCI_REG_IMBASEBAR0(0)); + rt3883_pci_w32(rpc, 0x08021814, RT3883_PCI_REG_ID(0)); + rt3883_pci_w32(rpc, 0x00800001, RT3883_PCI_REG_CLASS(0)); + rt3883_pci_w32(rpc, 0x28801814, RT3883_PCI_REG_SUBID(0)); + + /* PCIe */ + rt3883_pci_w32(rpc, 0x03ff0000, RT3883_PCI_REG_BAR0SETUP(1)); + rt3883_pci_w32(rpc, RT3883_MEMORY_BASE, RT3883_PCI_REG_IMBASEBAR0(1)); + rt3883_pci_w32(rpc, 0x08021814, RT3883_PCI_REG_ID(1)); + rt3883_pci_w32(rpc, 0x06040001, RT3883_PCI_REG_CLASS(1)); + rt3883_pci_w32(rpc, 0x28801814, RT3883_PCI_REG_SUBID(1)); + + err = rt3883_pci_irq_init(dev, rpc); + if (err) + goto err_put_hb_node; + + /* PCIe */ + val = rt3883_pci_read_cfg32(rpc, 0, 0x01, 0, PCI_COMMAND); + val |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; + rt3883_pci_write_cfg32(rpc, 0, 0x01, 0, PCI_COMMAND, val); + + /* PCI */ + val = rt3883_pci_read_cfg32(rpc, 0, 0x00, 0, PCI_COMMAND); + val |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; + rt3883_pci_write_cfg32(rpc, 0, 0x00, 0, PCI_COMMAND, val); + + if (mode == RT3883_PCI_MODE_PCIE) { + rt3883_pci_w32(rpc, 0x03ff0001, RT3883_PCI_REG_BAR0SETUP(0)); + rt3883_pci_w32(rpc, 0x03ff0001, RT3883_PCI_REG_BAR0SETUP(1)); + + rt3883_pci_write_cfg32(rpc, 0, RT3883_P2P_BR_DEVNUM, 0, + PCI_BASE_ADDRESS_0, + RT3883_MEMORY_BASE); + /* flush write */ + rt3883_pci_read_cfg32(rpc, 0, RT3883_P2P_BR_DEVNUM, 0, + PCI_BASE_ADDRESS_0); + } else { + rt3883_pci_write_cfg32(rpc, 0, RT3883_P2P_BR_DEVNUM, 0, + PCI_IO_BASE, 0x00000101); + } + + register_pci_controller(&rpc->pci_controller); + + return 0; + +err_put_hb_node: + of_node_put(rpc->pci_controller.of_node); + return err; +} + +int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +{ + struct rt3883_pci_controller *rpc; + struct of_irq dev_irq; + int err; + int irq; + + rpc = pci_bus_to_rt3883_controller(dev->bus); + err = of_irq_map_pci(dev, &dev_irq); + if (err) { + pr_err("pci %s: unable to get irq map, err=%d\n", + pci_name((struct pci_dev *) dev), err); + return 0; + } + + irq = irq_create_of_mapping(dev_irq.controller, + dev_irq.specifier, + dev_irq.size); + + if (irq == 0) + pr_crit("pci %s: no irq found for pin %u\n", + pci_name((struct pci_dev *) dev), pin); + else + pr_info("pci %s: using irq %d for pin %u\n", + pci_name((struct pci_dev *) dev), irq, pin); + + return irq; +} + +int pcibios_plat_dev_init(struct pci_dev *dev) +{ + return 0; +} + +static const struct of_device_id rt3883_pci_ids[] = { + { .compatible = "ralink,rt3883-pci" }, + {}, +}; +MODULE_DEVICE_TABLE(of, rt3883_pci_ids); + +static struct platform_driver rt3883_pci_driver = { + .probe = rt3883_pci_probe, + .driver = { + .name = "rt3883-pci", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(rt3883_pci_ids), + }, +}; + +static int __init rt3883_pci_init(void) +{ + return platform_driver_register(&rt3883_pci_driver); +} + +postcore_initcall(rt3883_pci_init); --- a/arch/mips/ralink/Kconfig +++ b/arch/mips/ralink/Kconfig @@ -20,6 +20,7 @@ choice bool "RT3883" select USB_ARCH_HAS_OHCI select USB_ARCH_HAS_EHCI + select HW_HAS_PCI config SOC_MT7620 bool "MT7620"