1 --- a/drivers/ssb/main.c
2 +++ b/drivers/ssb/main.c
3 @@ -1192,10 +1192,10 @@ void ssb_device_enable(struct ssb_device
5 EXPORT_SYMBOL(ssb_device_enable);
7 -/* Wait for a bit in a register to get set or unset.
8 +/* Wait for bitmask in a register to get set or cleared.
9 * timeout is in units of ten-microseconds */
10 -static int ssb_wait_bit(struct ssb_device *dev, u16 reg, u32 bitmask,
11 - int timeout, int set)
12 +static int ssb_wait_bits(struct ssb_device *dev, u16 reg, u32 bitmask,
13 + int timeout, int set)
17 @@ -1203,7 +1203,7 @@ static int ssb_wait_bit(struct ssb_devic
18 for (i = 0; i < timeout; i++) {
19 val = ssb_read32(dev, reg);
22 + if ((val & bitmask) == bitmask)
26 @@ -1220,20 +1220,38 @@ static int ssb_wait_bit(struct ssb_devic
28 void ssb_device_disable(struct ssb_device *dev, u32 core_specific_flags)
33 if (ssb_read32(dev, SSB_TMSLOW) & SSB_TMSLOW_RESET)
36 reject = ssb_tmslow_reject_bitmask(dev);
37 - ssb_write32(dev, SSB_TMSLOW, reject | SSB_TMSLOW_CLOCK);
38 - ssb_wait_bit(dev, SSB_TMSLOW, reject, 1000, 1);
39 - ssb_wait_bit(dev, SSB_TMSHIGH, SSB_TMSHIGH_BUSY, 1000, 0);
40 - ssb_write32(dev, SSB_TMSLOW,
41 - SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK |
42 - reject | SSB_TMSLOW_RESET |
43 - core_specific_flags);
44 - ssb_flush_tmslow(dev);
46 + if (ssb_read32(dev, SSB_TMSLOW) & SSB_TMSLOW_CLOCK) {
47 + ssb_write32(dev, SSB_TMSLOW, reject | SSB_TMSLOW_CLOCK);
48 + ssb_wait_bits(dev, SSB_TMSLOW, reject, 1000, 1);
49 + ssb_wait_bits(dev, SSB_TMSHIGH, SSB_TMSHIGH_BUSY, 1000, 0);
51 + if (ssb_read32(dev, SSB_IDLOW) & SSB_IDLOW_INITIATOR) {
52 + val = ssb_read32(dev, SSB_IMSTATE);
53 + val |= SSB_IMSTATE_REJECT;
54 + ssb_write32(dev, SSB_IMSTATE, val);
55 + ssb_wait_bits(dev, SSB_IMSTATE, SSB_IMSTATE_BUSY, 1000,
59 + ssb_write32(dev, SSB_TMSLOW,
60 + SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK |
61 + reject | SSB_TMSLOW_RESET |
62 + core_specific_flags);
63 + ssb_flush_tmslow(dev);
65 + if (ssb_read32(dev, SSB_IDLOW) & SSB_IDLOW_INITIATOR) {
66 + val = ssb_read32(dev, SSB_IMSTATE);
67 + val &= ~SSB_IMSTATE_REJECT;
68 + ssb_write32(dev, SSB_IMSTATE, val);
72 ssb_write32(dev, SSB_TMSLOW,
73 reject | SSB_TMSLOW_RESET |
74 --- a/drivers/ssb/pci.c
75 +++ b/drivers/ssb/pci.c
76 @@ -468,10 +468,14 @@ static void sprom_extract_r45(struct ssb
77 SPEX(country_code, SSB_SPROM4_CCODE, 0xFFFF, 0);
78 SPEX(boardflags_lo, SSB_SPROM4_BFLLO, 0xFFFF, 0);
79 SPEX(boardflags_hi, SSB_SPROM4_BFLHI, 0xFFFF, 0);
80 + SPEX(boardflags2_lo, SSB_SPROM4_BFL2LO, 0xFFFF, 0);
81 + SPEX(boardflags2_hi, SSB_SPROM4_BFL2HI, 0xFFFF, 0);
83 SPEX(country_code, SSB_SPROM5_CCODE, 0xFFFF, 0);
84 SPEX(boardflags_lo, SSB_SPROM5_BFLLO, 0xFFFF, 0);
85 SPEX(boardflags_hi, SSB_SPROM5_BFLHI, 0xFFFF, 0);
86 + SPEX(boardflags2_lo, SSB_SPROM5_BFL2LO, 0xFFFF, 0);
87 + SPEX(boardflags2_hi, SSB_SPROM5_BFL2HI, 0xFFFF, 0);
89 SPEX(ant_available_a, SSB_SPROM4_ANTAVAIL, SSB_SPROM4_ANTAVAIL_A,
90 SSB_SPROM4_ANTAVAIL_A_SHIFT);
91 @@ -641,7 +645,7 @@ static int sprom_extract(struct ssb_bus
94 ssb_printk(KERN_WARNING PFX "Unsupported SPROM"
95 - " revision %d detected. Will extract"
96 + " revision %d detected. Will extract"
97 " v1\n", out->revision);
99 sprom_extract_r123(out, in);
100 --- a/include/linux/ssb/ssb_regs.h
101 +++ b/include/linux/ssb/ssb_regs.h
103 #define SSB_IMSTATE_AP_RSV 0x00000030 /* Reserved */
104 #define SSB_IMSTATE_IBE 0x00020000 /* In Band Error */
105 #define SSB_IMSTATE_TO 0x00040000 /* Timeout */
106 +#define SSB_IMSTATE_BUSY 0x01800000 /* Busy (Backplane rev >= 2.3 only) */
107 +#define SSB_IMSTATE_REJECT 0x02000000 /* Reject (Backplane rev >= 2.3 only) */
108 #define SSB_INTVEC 0x0F94 /* SB Interrupt Mask */
109 #define SSB_INTVEC_PCI 0x00000001 /* Enable interrupts for PCI */
110 #define SSB_INTVEC_ENET0 0x00000002 /* Enable interrupts for enet 0 */
112 #define SSB_TMSLOW_RESET 0x00000001 /* Reset */
113 #define SSB_TMSLOW_REJECT_22 0x00000002 /* Reject (Backplane rev 2.2) */
114 #define SSB_TMSLOW_REJECT_23 0x00000004 /* Reject (Backplane rev 2.3) */
115 -#define SSB_TMSLOW_PHYCLK 0x00000010 /* MAC PHY Clock Control Enable */
116 #define SSB_TMSLOW_CLOCK 0x00010000 /* Clock Enable */
117 #define SSB_TMSLOW_FGC 0x00020000 /* Force Gated Clocks On */
118 #define SSB_TMSLOW_PE 0x40000000 /* Power Management Enable */
120 /* SPROM Revision 4 */
121 #define SSB_SPROM4_BFLLO 0x0044 /* Boardflags (low 16 bits) */
122 #define SSB_SPROM4_BFLHI 0x0046 /* Board Flags Hi */
123 +#define SSB_SPROM4_BFL2LO 0x0048 /* Board flags 2 (low 16 bits) */
124 +#define SSB_SPROM4_BFL2HI 0x004A /* Board flags 2 Hi */
125 #define SSB_SPROM4_IL0MAC 0x004C /* 6 byte MAC address for a/b/g/n */
126 #define SSB_SPROM4_CCODE 0x0052 /* Country Code (2 bytes) */
127 #define SSB_SPROM4_GPIOA 0x0056 /* Gen. Purpose IO # 0 and 1 */
129 #define SSB_SPROM5_CCODE 0x0044 /* Country Code (2 bytes) */
130 #define SSB_SPROM5_BFLLO 0x004A /* Boardflags (low 16 bits) */
131 #define SSB_SPROM5_BFLHI 0x004C /* Board Flags Hi */
132 +#define SSB_SPROM5_BFL2LO 0x004E /* Board flags 2 (low 16 bits) */
133 +#define SSB_SPROM5_BFL2HI 0x0050 /* Board flags 2 Hi */
134 #define SSB_SPROM5_IL0MAC 0x0052 /* 6 byte MAC address for a/b/g/n */
135 #define SSB_SPROM5_GPIOA 0x0076 /* Gen. Purpose IO # 0 and 1 */
136 #define SSB_SPROM5_GPIOA_P0 0x00FF /* Pin 0 */