diff options
| -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; |
