diff options
Diffstat (limited to 'arch/arm/mach-orion5x')
-rw-r--r-- | arch/arm/mach-orion5x/common.h | 1 | ||||
-rw-r--r-- | arch/arm/mach-orion5x/pci.c | 36 |
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; | |||
40 | struct pci_sys_data; | 40 | struct pci_sys_data; |
41 | 41 | ||
42 | void orion5x_pcie_id(u32 *dev, u32 *rev); | 42 | void orion5x_pcie_id(u32 *dev, u32 *rev); |
43 | void orion5x_pci_set_cardbus_mode(void); | ||
43 | int orion5x_pci_sys_setup(int nr, struct pci_sys_data *sys); | 44 | int orion5x_pci_sys_setup(int nr, struct pci_sys_data *sys); |
44 | struct pci_bus *orion5x_pci_sys_scan_bus(int nr, struct pci_sys_data *sys); | 45 | struct pci_bus *orion5x_pci_sys_scan_bus(int nr, struct pci_sys_data *sys); |
45 | int orion5x_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin); | 46 | int 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 | */ |
267 | static DEFINE_SPINLOCK(orion5x_pci_lock); | 267 | static DEFINE_SPINLOCK(orion5x_pci_lock); |
268 | 268 | ||
269 | static int orion5x_pci_cardbus_mode; | ||
270 | |||
269 | static int orion5x_pci_local_bus_nr(void) | 271 | static 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 | ||
326 | static 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 | |||
324 | static int orion5x_pci_rd_conf(struct pci_bus *bus, u32 devfn, | 346 | static 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, | |||
340 | static int orion5x_pci_wr_conf(struct pci_bus *bus, u32 devfn, | 358 | static 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 | } |
525 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL, PCI_ANY_ID, rc_pci_fixup); | 542 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL, PCI_ANY_ID, rc_pci_fixup); |
526 | 543 | ||
544 | void __init orion5x_pci_set_cardbus_mode(void) | ||
545 | { | ||
546 | orion5x_pci_cardbus_mode = 1; | ||
547 | } | ||
548 | |||
527 | int __init orion5x_pci_sys_setup(int nr, struct pci_sys_data *sys) | 549 | int __init orion5x_pci_sys_setup(int nr, struct pci_sys_data *sys) |
528 | { | 550 | { |
529 | int ret = 0; | 551 | int ret = 0; |