ssb: Fix pcicore cardbus mode

This fixes the pcicore driver to not die a horrible
crash death when inserting a cardbus card.

Signed-off-by: Michael Buesch <mb@bu3sch.de>
Signed-off-by: John W. Linville <linville@tuxdriver.com>

authored by Michael Buesch and committed by John W. Linville 7cb44615 53521d8c

+39 -2
+26 -2
drivers/ssb/driver_pcicore.c
··· 11 #include <linux/ssb/ssb.h> 12 #include <linux/pci.h> 13 #include <linux/delay.h> 14 15 #include "ssb_private.h" 16 ··· 26 void pcicore_write32(struct ssb_pcicore *pc, u16 offset, u32 value) 27 { 28 ssb_write32(pc->dev, offset, value); 29 } 30 31 /************************************************** ··· 130 u32 addr = 0; 131 u32 tmp; 132 133 - if (unlikely(pc->cardbusmode && dev > 1)) 134 goto out; 135 if (bus == 0) { 136 /* Type 0 transaction */ 137 if (unlikely(dev >= SSB_PCI_SLOT_MAX)) ··· 333 pcicore_write32(pc, SSB_PCICORE_ARBCTL, val); 334 udelay(1); /* Assertion time demanded by the PCI standard */ 335 336 - /*TODO cardbus mode */ 337 338 /* 64MB I/O window */ 339 pcicore_write32(pc, SSB_PCICORE_SBTOPCI0,
··· 11 #include <linux/ssb/ssb.h> 12 #include <linux/pci.h> 13 #include <linux/delay.h> 14 + #include <linux/ssb/ssb_embedded.h> 15 16 #include "ssb_private.h" 17 ··· 25 void pcicore_write32(struct ssb_pcicore *pc, u16 offset, u32 value) 26 { 27 ssb_write32(pc->dev, offset, value); 28 + } 29 + 30 + static inline 31 + u16 pcicore_read16(struct ssb_pcicore *pc, u16 offset) 32 + { 33 + return ssb_read16(pc->dev, offset); 34 + } 35 + 36 + static inline 37 + void pcicore_write16(struct ssb_pcicore *pc, u16 offset, u16 value) 38 + { 39 + ssb_write16(pc->dev, offset, value); 40 } 41 42 /************************************************** ··· 117 u32 addr = 0; 118 u32 tmp; 119 120 + /* We do only have one cardbus device behind the bridge. */ 121 + if (pc->cardbusmode && (dev >= 1)) 122 goto out; 123 + 124 if (bus == 0) { 125 /* Type 0 transaction */ 126 if (unlikely(dev >= SSB_PCI_SLOT_MAX)) ··· 318 pcicore_write32(pc, SSB_PCICORE_ARBCTL, val); 319 udelay(1); /* Assertion time demanded by the PCI standard */ 320 321 + if (pc->dev->bus->has_cardbus_slot) { 322 + ssb_dprintk(KERN_INFO PFX "CardBus slot detected\n"); 323 + pc->cardbusmode = 1; 324 + /* GPIO 1 resets the bridge */ 325 + ssb_gpio_out(pc->dev->bus, 1, 1); 326 + ssb_gpio_outen(pc->dev->bus, 1, 1); 327 + pcicore_write16(pc, SSB_PCICORE_SPROM(0), 328 + pcicore_read16(pc, SSB_PCICORE_SPROM(0)) 329 + | 0x0400); 330 + } 331 332 /* 64MB I/O window */ 333 pcicore_write32(pc, SSB_PCICORE_SBTOPCI0,
+1
drivers/ssb/main.c
··· 557 goto out; 558 memcpy(&bus->boardinfo, &iv.boardinfo, sizeof(iv.boardinfo)); 559 memcpy(&bus->sprom, &iv.sprom, sizeof(iv.sprom)); 560 out: 561 return err; 562 }
··· 557 goto out; 558 memcpy(&bus->boardinfo, &iv.boardinfo, sizeof(iv.boardinfo)); 559 memcpy(&bus->sprom, &iv.sprom, sizeof(iv.sprom)); 560 + bus->has_cardbus_slot = iv.has_cardbus_slot; 561 out: 562 return err; 563 }
+7
include/linux/ssb/ssb.h
··· 282 struct ssb_boardinfo boardinfo; 283 /* Contents of the SPROM. */ 284 struct ssb_sprom sprom; 285 286 #ifdef CONFIG_SSB_EMBEDDED 287 /* Lock for GPIO register access. */ ··· 301 302 /* The initialization-invariants. */ 303 struct ssb_init_invariants { 304 struct ssb_boardinfo boardinfo; 305 struct ssb_sprom sprom; 306 }; 307 /* Type of function to fetch the invariants. */ 308 typedef int (*ssb_invariants_func_t)(struct ssb_bus *bus,
··· 282 struct ssb_boardinfo boardinfo; 283 /* Contents of the SPROM. */ 284 struct ssb_sprom sprom; 285 + /* If the board has a cardbus slot, this is set to true. */ 286 + bool has_cardbus_slot; 287 288 #ifdef CONFIG_SSB_EMBEDDED 289 /* Lock for GPIO register access. */ ··· 299 300 /* The initialization-invariants. */ 301 struct ssb_init_invariants { 302 + /* Versioning information about the PCB. */ 303 struct ssb_boardinfo boardinfo; 304 + /* The SPROM information. That's either stored in an 305 + * EEPROM or NVRAM on the board. */ 306 struct ssb_sprom sprom; 307 + /* If the board has a cardbus slot, this is set to true. */ 308 + bool has_cardbus_slot; 309 }; 310 /* Type of function to fetch the invariants. */ 311 typedef int (*ssb_invariants_func_t)(struct ssb_bus *bus,
+5
include/linux/ssb/ssb_driver_pci.h
··· 51 #define SSB_PCICORE_SBTOPCI1_MASK 0xFC000000 52 #define SSB_PCICORE_SBTOPCI2 0x0108 /* Backplane to PCI translation 2 (sbtopci2) */ 53 #define SSB_PCICORE_SBTOPCI2_MASK 0xC0000000 54 55 /* SBtoPCIx */ 56 #define SSB_PCICORE_SBTOPCI_MEM 0x00000000
··· 51 #define SSB_PCICORE_SBTOPCI1_MASK 0xFC000000 52 #define SSB_PCICORE_SBTOPCI2 0x0108 /* Backplane to PCI translation 2 (sbtopci2) */ 53 #define SSB_PCICORE_SBTOPCI2_MASK 0xC0000000 54 + #define SSB_PCICORE_PCICFG0 0x0400 /* PCI config space 0 (rev >= 8) */ 55 + #define SSB_PCICORE_PCICFG1 0x0500 /* PCI config space 1 (rev >= 8) */ 56 + #define SSB_PCICORE_PCICFG2 0x0600 /* PCI config space 2 (rev >= 8) */ 57 + #define SSB_PCICORE_PCICFG3 0x0700 /* PCI config space 3 (rev >= 8) */ 58 + #define SSB_PCICORE_SPROM(wordoffset) (0x0800 + ((wordoffset) * 2)) /* SPROM shadow area (72 bytes) */ 59 60 /* SBtoPCIx */ 61 #define SSB_PCICORE_SBTOPCI_MEM 0x00000000