aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-orion5x
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-orion5x')
-rw-r--r--arch/arm/mach-orion5x/common.h1
-rw-r--r--arch/arm/mach-orion5x/pci.c36
2 files changed, 30 insertions, 7 deletions
diff --git a/arch/arm/mach-orion5x/common.h b/arch/arm/mach-orion5x/common.h
index 97db8d88f3db..f72cf0e77544 100644
--- a/arch/arm/mach-orion5x/common.h
+++ b/arch/arm/mach-orion5x/common.h
@@ -40,6 +40,7 @@ struct pci_bus;
40struct pci_sys_data; 40struct pci_sys_data;
41 41
42void orion5x_pcie_id(u32 *dev, u32 *rev); 42void orion5x_pcie_id(u32 *dev, u32 *rev);
43void orion5x_pci_set_cardbus_mode(void);
43int orion5x_pci_sys_setup(int nr, struct pci_sys_data *sys); 44int orion5x_pci_sys_setup(int nr, struct pci_sys_data *sys);
44struct pci_bus *orion5x_pci_sys_scan_bus(int nr, struct pci_sys_data *sys); 45struct pci_bus *orion5x_pci_sys_scan_bus(int nr, struct pci_sys_data *sys);
45int orion5x_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin); 46int orion5x_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin);
diff --git a/arch/arm/mach-orion5x/pci.c b/arch/arm/mach-orion5x/pci.c
index 025ef63b1ddb..256a4f680935 100644
--- a/arch/arm/mach-orion5x/pci.c
+++ b/arch/arm/mach-orion5x/pci.c
@@ -266,6 +266,8 @@ static int __init pcie_setup(struct pci_sys_data *sys)
266 */ 266 */
267static DEFINE_SPINLOCK(orion5x_pci_lock); 267static DEFINE_SPINLOCK(orion5x_pci_lock);
268 268
269static int orion5x_pci_cardbus_mode;
270
269static int orion5x_pci_local_bus_nr(void) 271static int orion5x_pci_local_bus_nr(void)
270{ 272{
271 u32 conf = readl(PCI_P2P_CONF); 273 u32 conf = readl(PCI_P2P_CONF);
@@ -321,14 +323,30 @@ static int orion5x_pci_hw_wr_conf(int bus, int dev, u32 func,
321 return ret; 323 return ret;
322} 324}
323 325
326static int orion5x_pci_valid_config(int bus, u32 devfn)
327{
328 if (bus == orion5x_pci_local_bus_nr()) {
329 /*
330 * Don't go out for local device
331 */
332 if (PCI_SLOT(devfn) == 0 && PCI_FUNC(devfn) != 0)
333 return 0;
334
335 /*
336 * When the PCI signals are directly connected to a
337 * Cardbus slot, ignore all but device IDs 0 and 1.
338 */
339 if (orion5x_pci_cardbus_mode && PCI_SLOT(devfn) > 1)
340 return 0;
341 }
342
343 return 1;
344}
345
324static int orion5x_pci_rd_conf(struct pci_bus *bus, u32 devfn, 346static int orion5x_pci_rd_conf(struct pci_bus *bus, u32 devfn,
325 int where, int size, u32 *val) 347 int where, int size, u32 *val)
326{ 348{
327 /* 349 if (!orion5x_pci_valid_config(bus->number, devfn)) {
328 * Don't go out for local device
329 */
330 if (bus->number == orion5x_pci_local_bus_nr() &&
331 PCI_SLOT(devfn) == 0 && PCI_FUNC(devfn) != 0) {
332 *val = 0xffffffff; 350 *val = 0xffffffff;
333 return PCIBIOS_DEVICE_NOT_FOUND; 351 return PCIBIOS_DEVICE_NOT_FOUND;
334 } 352 }
@@ -340,8 +358,7 @@ static int orion5x_pci_rd_conf(struct pci_bus *bus, u32 devfn,
340static int orion5x_pci_wr_conf(struct pci_bus *bus, u32 devfn, 358static int orion5x_pci_wr_conf(struct pci_bus *bus, u32 devfn,
341 int where, int size, u32 val) 359 int where, int size, u32 val)
342{ 360{
343 if (bus->number == orion5x_pci_local_bus_nr() && 361 if (!orion5x_pci_valid_config(bus->number, devfn))
344 PCI_SLOT(devfn) == 0 && PCI_FUNC(devfn) != 0)
345 return PCIBIOS_DEVICE_NOT_FOUND; 362 return PCIBIOS_DEVICE_NOT_FOUND;
346 363
347 return orion5x_pci_hw_wr_conf(bus->number, PCI_SLOT(devfn), 364 return orion5x_pci_hw_wr_conf(bus->number, PCI_SLOT(devfn),
@@ -524,6 +541,11 @@ static void __devinit rc_pci_fixup(struct pci_dev *dev)
524} 541}
525DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL, PCI_ANY_ID, rc_pci_fixup); 542DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL, PCI_ANY_ID, rc_pci_fixup);
526 543
544void __init orion5x_pci_set_cardbus_mode(void)
545{
546 orion5x_pci_cardbus_mode = 1;
547}
548
527int __init orion5x_pci_sys_setup(int nr, struct pci_sys_data *sys) 549int __init orion5x_pci_sys_setup(int nr, struct pci_sys_data *sys)
528{ 550{
529 int ret = 0; 551 int ret = 0;