diff options
Diffstat (limited to 'drivers/i2c/busses/i2c-pnx.c')
-rw-r--r-- | drivers/i2c/busses/i2c-pnx.c | 296 |
1 files changed, 155 insertions, 141 deletions
diff --git a/drivers/i2c/busses/i2c-pnx.c b/drivers/i2c/busses/i2c-pnx.c index 5d1c2603a130..9532dee6b580 100644 --- a/drivers/i2c/busses/i2c-pnx.c +++ b/drivers/i2c/busses/i2c-pnx.c | |||
@@ -20,15 +20,15 @@ | |||
20 | #include <linux/platform_device.h> | 20 | #include <linux/platform_device.h> |
21 | #include <linux/i2c-pnx.h> | 21 | #include <linux/i2c-pnx.h> |
22 | #include <linux/io.h> | 22 | #include <linux/io.h> |
23 | #include <linux/err.h> | ||
24 | #include <linux/clk.h> | ||
25 | |||
23 | #include <mach/hardware.h> | 26 | #include <mach/hardware.h> |
24 | #include <mach/i2c.h> | 27 | #include <mach/i2c.h> |
25 | #include <asm/irq.h> | ||
26 | #include <asm/uaccess.h> | ||
27 | 28 | ||
28 | #define I2C_PNX_TIMEOUT 10 /* msec */ | 29 | #define I2C_PNX_TIMEOUT 10 /* msec */ |
29 | #define I2C_PNX_SPEED_KHZ 100 | 30 | #define I2C_PNX_SPEED_KHZ 100 |
30 | #define I2C_PNX_REGION_SIZE 0x100 | 31 | #define I2C_PNX_REGION_SIZE 0x100 |
31 | #define PNX_DEFAULT_FREQ 13 /* MHz */ | ||
32 | 32 | ||
33 | static inline int wait_timeout(long timeout, struct i2c_pnx_algo_data *data) | 33 | static inline int wait_timeout(long timeout, struct i2c_pnx_algo_data *data) |
34 | { | 34 | { |
@@ -50,22 +50,21 @@ static inline int wait_reset(long timeout, struct i2c_pnx_algo_data *data) | |||
50 | return (timeout <= 0); | 50 | return (timeout <= 0); |
51 | } | 51 | } |
52 | 52 | ||
53 | static inline void i2c_pnx_arm_timer(struct i2c_adapter *adap) | 53 | static inline void i2c_pnx_arm_timer(struct i2c_pnx_algo_data *alg_data) |
54 | { | 54 | { |
55 | struct i2c_pnx_algo_data *data = adap->algo_data; | 55 | struct timer_list *timer = &alg_data->mif.timer; |
56 | struct timer_list *timer = &data->mif.timer; | 56 | unsigned long expires = msecs_to_jiffies(I2C_PNX_TIMEOUT); |
57 | int expires = I2C_PNX_TIMEOUT / (1000 / HZ); | ||
58 | 57 | ||
59 | if (expires <= 1) | 58 | if (expires <= 1) |
60 | expires = 2; | 59 | expires = 2; |
61 | 60 | ||
62 | del_timer_sync(timer); | 61 | del_timer_sync(timer); |
63 | 62 | ||
64 | dev_dbg(&adap->dev, "Timer armed at %lu plus %u jiffies.\n", | 63 | dev_dbg(&alg_data->adapter.dev, "Timer armed at %lu plus %lu jiffies.\n", |
65 | jiffies, expires); | 64 | jiffies, expires); |
66 | 65 | ||
67 | timer->expires = jiffies + expires; | 66 | timer->expires = jiffies + expires; |
68 | timer->data = (unsigned long)adap; | 67 | timer->data = (unsigned long)&alg_data; |
69 | 68 | ||
70 | add_timer(timer); | 69 | add_timer(timer); |
71 | } | 70 | } |
@@ -77,34 +76,34 @@ static inline void i2c_pnx_arm_timer(struct i2c_adapter *adap) | |||
77 | * | 76 | * |
78 | * Generate a START signal in the desired mode. | 77 | * Generate a START signal in the desired mode. |
79 | */ | 78 | */ |
80 | static int i2c_pnx_start(unsigned char slave_addr, struct i2c_adapter *adap) | 79 | static int i2c_pnx_start(unsigned char slave_addr, |
80 | struct i2c_pnx_algo_data *alg_data) | ||
81 | { | 81 | { |
82 | struct i2c_pnx_algo_data *alg_data = adap->algo_data; | 82 | dev_dbg(&alg_data->adapter.dev, "%s(): addr 0x%x mode %d\n", __func__, |
83 | |||
84 | dev_dbg(&adap->dev, "%s(): addr 0x%x mode %d\n", __func__, | ||
85 | slave_addr, alg_data->mif.mode); | 83 | slave_addr, alg_data->mif.mode); |
86 | 84 | ||
87 | /* Check for 7 bit slave addresses only */ | 85 | /* Check for 7 bit slave addresses only */ |
88 | if (slave_addr & ~0x7f) { | 86 | if (slave_addr & ~0x7f) { |
89 | dev_err(&adap->dev, "%s: Invalid slave address %x. " | 87 | dev_err(&alg_data->adapter.dev, |
90 | "Only 7-bit addresses are supported\n", | 88 | "%s: Invalid slave address %x. Only 7-bit addresses are supported\n", |
91 | adap->name, slave_addr); | 89 | alg_data->adapter.name, slave_addr); |
92 | return -EINVAL; | 90 | return -EINVAL; |
93 | } | 91 | } |
94 | 92 | ||
95 | /* First, make sure bus is idle */ | 93 | /* First, make sure bus is idle */ |
96 | if (wait_timeout(I2C_PNX_TIMEOUT, alg_data)) { | 94 | if (wait_timeout(I2C_PNX_TIMEOUT, alg_data)) { |
97 | /* Somebody else is monopolizing the bus */ | 95 | /* Somebody else is monopolizing the bus */ |
98 | dev_err(&adap->dev, "%s: Bus busy. Slave addr = %02x, " | 96 | dev_err(&alg_data->adapter.dev, |
99 | "cntrl = %x, stat = %x\n", | 97 | "%s: Bus busy. Slave addr = %02x, cntrl = %x, stat = %x\n", |
100 | adap->name, slave_addr, | 98 | alg_data->adapter.name, slave_addr, |
101 | ioread32(I2C_REG_CTL(alg_data)), | 99 | ioread32(I2C_REG_CTL(alg_data)), |
102 | ioread32(I2C_REG_STS(alg_data))); | 100 | ioread32(I2C_REG_STS(alg_data))); |
103 | return -EBUSY; | 101 | return -EBUSY; |
104 | } else if (ioread32(I2C_REG_STS(alg_data)) & mstatus_afi) { | 102 | } else if (ioread32(I2C_REG_STS(alg_data)) & mstatus_afi) { |
105 | /* Sorry, we lost the bus */ | 103 | /* Sorry, we lost the bus */ |
106 | dev_err(&adap->dev, "%s: Arbitration failure. " | 104 | dev_err(&alg_data->adapter.dev, |
107 | "Slave addr = %02x\n", adap->name, slave_addr); | 105 | "%s: Arbitration failure. Slave addr = %02x\n", |
106 | alg_data->adapter.name, slave_addr); | ||
108 | return -EIO; | 107 | return -EIO; |
109 | } | 108 | } |
110 | 109 | ||
@@ -115,14 +114,14 @@ static int i2c_pnx_start(unsigned char slave_addr, struct i2c_adapter *adap) | |||
115 | iowrite32(ioread32(I2C_REG_STS(alg_data)) | mstatus_tdi | mstatus_afi, | 114 | iowrite32(ioread32(I2C_REG_STS(alg_data)) | mstatus_tdi | mstatus_afi, |
116 | I2C_REG_STS(alg_data)); | 115 | I2C_REG_STS(alg_data)); |
117 | 116 | ||
118 | dev_dbg(&adap->dev, "%s(): sending %#x\n", __func__, | 117 | dev_dbg(&alg_data->adapter.dev, "%s(): sending %#x\n", __func__, |
119 | (slave_addr << 1) | start_bit | alg_data->mif.mode); | 118 | (slave_addr << 1) | start_bit | alg_data->mif.mode); |
120 | 119 | ||
121 | /* Write the slave address, START bit and R/W bit */ | 120 | /* Write the slave address, START bit and R/W bit */ |
122 | iowrite32((slave_addr << 1) | start_bit | alg_data->mif.mode, | 121 | iowrite32((slave_addr << 1) | start_bit | alg_data->mif.mode, |
123 | I2C_REG_TX(alg_data)); | 122 | I2C_REG_TX(alg_data)); |
124 | 123 | ||
125 | dev_dbg(&adap->dev, "%s(): exit\n", __func__); | 124 | dev_dbg(&alg_data->adapter.dev, "%s(): exit\n", __func__); |
126 | 125 | ||
127 | return 0; | 126 | return 0; |
128 | } | 127 | } |
@@ -133,13 +132,12 @@ static int i2c_pnx_start(unsigned char slave_addr, struct i2c_adapter *adap) | |||
133 | * | 132 | * |
134 | * Generate a STOP signal to terminate the master transaction. | 133 | * Generate a STOP signal to terminate the master transaction. |
135 | */ | 134 | */ |
136 | static void i2c_pnx_stop(struct i2c_adapter *adap) | 135 | static void i2c_pnx_stop(struct i2c_pnx_algo_data *alg_data) |
137 | { | 136 | { |
138 | struct i2c_pnx_algo_data *alg_data = adap->algo_data; | ||
139 | /* Only 1 msec max timeout due to interrupt context */ | 137 | /* Only 1 msec max timeout due to interrupt context */ |
140 | long timeout = 1000; | 138 | long timeout = 1000; |
141 | 139 | ||
142 | dev_dbg(&adap->dev, "%s(): entering: stat = %04x.\n", | 140 | dev_dbg(&alg_data->adapter.dev, "%s(): entering: stat = %04x.\n", |
143 | __func__, ioread32(I2C_REG_STS(alg_data))); | 141 | __func__, ioread32(I2C_REG_STS(alg_data))); |
144 | 142 | ||
145 | /* Write a STOP bit to TX FIFO */ | 143 | /* Write a STOP bit to TX FIFO */ |
@@ -153,7 +151,7 @@ static void i2c_pnx_stop(struct i2c_adapter *adap) | |||
153 | timeout--; | 151 | timeout--; |
154 | } | 152 | } |
155 | 153 | ||
156 | dev_dbg(&adap->dev, "%s(): exiting: stat = %04x.\n", | 154 | dev_dbg(&alg_data->adapter.dev, "%s(): exiting: stat = %04x.\n", |
157 | __func__, ioread32(I2C_REG_STS(alg_data))); | 155 | __func__, ioread32(I2C_REG_STS(alg_data))); |
158 | } | 156 | } |
159 | 157 | ||
@@ -163,36 +161,29 @@ static void i2c_pnx_stop(struct i2c_adapter *adap) | |||
163 | * | 161 | * |
164 | * Sends one byte of data to the slave | 162 | * Sends one byte of data to the slave |
165 | */ | 163 | */ |
166 | static int i2c_pnx_master_xmit(struct i2c_adapter *adap) | 164 | static int i2c_pnx_master_xmit(struct i2c_pnx_algo_data *alg_data) |
167 | { | 165 | { |
168 | struct i2c_pnx_algo_data *alg_data = adap->algo_data; | ||
169 | u32 val; | 166 | u32 val; |
170 | 167 | ||
171 | dev_dbg(&adap->dev, "%s(): entering: stat = %04x.\n", | 168 | dev_dbg(&alg_data->adapter.dev, "%s(): entering: stat = %04x.\n", |
172 | __func__, ioread32(I2C_REG_STS(alg_data))); | 169 | __func__, ioread32(I2C_REG_STS(alg_data))); |
173 | 170 | ||
174 | if (alg_data->mif.len > 0) { | 171 | if (alg_data->mif.len > 0) { |
175 | /* We still have something to talk about... */ | 172 | /* We still have something to talk about... */ |
176 | val = *alg_data->mif.buf++; | 173 | val = *alg_data->mif.buf++; |
177 | 174 | ||
178 | if (alg_data->mif.len == 1) { | ||
179 | val |= stop_bit; | ||
180 | if (!alg_data->last) | ||
181 | val |= start_bit; | ||
182 | } | ||
183 | |||
184 | alg_data->mif.len--; | 175 | alg_data->mif.len--; |
185 | iowrite32(val, I2C_REG_TX(alg_data)); | 176 | iowrite32(val, I2C_REG_TX(alg_data)); |
186 | 177 | ||
187 | dev_dbg(&adap->dev, "%s(): xmit %#x [%d]\n", __func__, | 178 | dev_dbg(&alg_data->adapter.dev, "%s(): xmit %#x [%d]\n", |
188 | val, alg_data->mif.len + 1); | 179 | __func__, val, alg_data->mif.len + 1); |
189 | 180 | ||
190 | if (alg_data->mif.len == 0) { | 181 | if (alg_data->mif.len == 0) { |
191 | if (alg_data->last) { | 182 | if (alg_data->last) { |
192 | /* Wait until the STOP is seen. */ | 183 | /* Wait until the STOP is seen. */ |
193 | if (wait_timeout(I2C_PNX_TIMEOUT, alg_data)) | 184 | if (wait_timeout(I2C_PNX_TIMEOUT, alg_data)) |
194 | dev_err(&adap->dev, "The bus is still " | 185 | dev_err(&alg_data->adapter.dev, |
195 | "active after timeout\n"); | 186 | "The bus is still active after timeout\n"); |
196 | } | 187 | } |
197 | /* Disable master interrupts */ | 188 | /* Disable master interrupts */ |
198 | iowrite32(ioread32(I2C_REG_CTL(alg_data)) & | 189 | iowrite32(ioread32(I2C_REG_CTL(alg_data)) & |
@@ -201,14 +192,15 @@ static int i2c_pnx_master_xmit(struct i2c_adapter *adap) | |||
201 | 192 | ||
202 | del_timer_sync(&alg_data->mif.timer); | 193 | del_timer_sync(&alg_data->mif.timer); |
203 | 194 | ||
204 | dev_dbg(&adap->dev, "%s(): Waking up xfer routine.\n", | 195 | dev_dbg(&alg_data->adapter.dev, |
196 | "%s(): Waking up xfer routine.\n", | ||
205 | __func__); | 197 | __func__); |
206 | 198 | ||
207 | complete(&alg_data->mif.complete); | 199 | complete(&alg_data->mif.complete); |
208 | } | 200 | } |
209 | } else if (alg_data->mif.len == 0) { | 201 | } else if (alg_data->mif.len == 0) { |
210 | /* zero-sized transfer */ | 202 | /* zero-sized transfer */ |
211 | i2c_pnx_stop(adap); | 203 | i2c_pnx_stop(alg_data); |
212 | 204 | ||
213 | /* Disable master interrupts. */ | 205 | /* Disable master interrupts. */ |
214 | iowrite32(ioread32(I2C_REG_CTL(alg_data)) & | 206 | iowrite32(ioread32(I2C_REG_CTL(alg_data)) & |
@@ -217,13 +209,14 @@ static int i2c_pnx_master_xmit(struct i2c_adapter *adap) | |||
217 | 209 | ||
218 | /* Stop timer. */ | 210 | /* Stop timer. */ |
219 | del_timer_sync(&alg_data->mif.timer); | 211 | del_timer_sync(&alg_data->mif.timer); |
220 | dev_dbg(&adap->dev, "%s(): Waking up xfer routine after " | 212 | dev_dbg(&alg_data->adapter.dev, |
221 | "zero-xfer.\n", __func__); | 213 | "%s(): Waking up xfer routine after zero-xfer.\n", |
214 | __func__); | ||
222 | 215 | ||
223 | complete(&alg_data->mif.complete); | 216 | complete(&alg_data->mif.complete); |
224 | } | 217 | } |
225 | 218 | ||
226 | dev_dbg(&adap->dev, "%s(): exiting: stat = %04x.\n", | 219 | dev_dbg(&alg_data->adapter.dev, "%s(): exiting: stat = %04x.\n", |
227 | __func__, ioread32(I2C_REG_STS(alg_data))); | 220 | __func__, ioread32(I2C_REG_STS(alg_data))); |
228 | 221 | ||
229 | return 0; | 222 | return 0; |
@@ -235,28 +228,23 @@ static int i2c_pnx_master_xmit(struct i2c_adapter *adap) | |||
235 | * | 228 | * |
236 | * Reads one byte data from the slave | 229 | * Reads one byte data from the slave |
237 | */ | 230 | */ |
238 | static int i2c_pnx_master_rcv(struct i2c_adapter *adap) | 231 | static int i2c_pnx_master_rcv(struct i2c_pnx_algo_data *alg_data) |
239 | { | 232 | { |
240 | struct i2c_pnx_algo_data *alg_data = adap->algo_data; | ||
241 | unsigned int val = 0; | 233 | unsigned int val = 0; |
242 | u32 ctl = 0; | 234 | u32 ctl = 0; |
243 | 235 | ||
244 | dev_dbg(&adap->dev, "%s(): entering: stat = %04x.\n", | 236 | dev_dbg(&alg_data->adapter.dev, "%s(): entering: stat = %04x.\n", |
245 | __func__, ioread32(I2C_REG_STS(alg_data))); | 237 | __func__, ioread32(I2C_REG_STS(alg_data))); |
246 | 238 | ||
247 | /* Check, whether there is already data, | 239 | /* Check, whether there is already data, |
248 | * or we didn't 'ask' for it yet. | 240 | * or we didn't 'ask' for it yet. |
249 | */ | 241 | */ |
250 | if (ioread32(I2C_REG_STS(alg_data)) & mstatus_rfe) { | 242 | if (ioread32(I2C_REG_STS(alg_data)) & mstatus_rfe) { |
251 | dev_dbg(&adap->dev, "%s(): Write dummy data to fill " | 243 | dev_dbg(&alg_data->adapter.dev, |
252 | "Rx-fifo...\n", __func__); | 244 | "%s(): Write dummy data to fill Rx-fifo...\n", |
245 | __func__); | ||
253 | 246 | ||
254 | if (alg_data->mif.len == 1) { | 247 | if (alg_data->mif.len == 1) { |
255 | /* Last byte, do not acknowledge next rcv. */ | ||
256 | val |= stop_bit; | ||
257 | if (!alg_data->last) | ||
258 | val |= start_bit; | ||
259 | |||
260 | /* | 248 | /* |
261 | * Enable interrupt RFDAIE (data in Rx fifo), | 249 | * Enable interrupt RFDAIE (data in Rx fifo), |
262 | * and disable DRMIE (need data for Tx) | 250 | * and disable DRMIE (need data for Tx) |
@@ -281,16 +269,16 @@ static int i2c_pnx_master_rcv(struct i2c_adapter *adap) | |||
281 | if (alg_data->mif.len > 0) { | 269 | if (alg_data->mif.len > 0) { |
282 | val = ioread32(I2C_REG_RX(alg_data)); | 270 | val = ioread32(I2C_REG_RX(alg_data)); |
283 | *alg_data->mif.buf++ = (u8) (val & 0xff); | 271 | *alg_data->mif.buf++ = (u8) (val & 0xff); |
284 | dev_dbg(&adap->dev, "%s(): rcv 0x%x [%d]\n", __func__, val, | 272 | dev_dbg(&alg_data->adapter.dev, "%s(): rcv 0x%x [%d]\n", |
285 | alg_data->mif.len); | 273 | __func__, val, alg_data->mif.len); |
286 | 274 | ||
287 | alg_data->mif.len--; | 275 | alg_data->mif.len--; |
288 | if (alg_data->mif.len == 0) { | 276 | if (alg_data->mif.len == 0) { |
289 | if (alg_data->last) | 277 | if (alg_data->last) |
290 | /* Wait until the STOP is seen. */ | 278 | /* Wait until the STOP is seen. */ |
291 | if (wait_timeout(I2C_PNX_TIMEOUT, alg_data)) | 279 | if (wait_timeout(I2C_PNX_TIMEOUT, alg_data)) |
292 | dev_err(&adap->dev, "The bus is still " | 280 | dev_err(&alg_data->adapter.dev, |
293 | "active after timeout\n"); | 281 | "The bus is still active after timeout\n"); |
294 | 282 | ||
295 | /* Disable master interrupts */ | 283 | /* Disable master interrupts */ |
296 | ctl = ioread32(I2C_REG_CTL(alg_data)); | 284 | ctl = ioread32(I2C_REG_CTL(alg_data)); |
@@ -304,7 +292,7 @@ static int i2c_pnx_master_rcv(struct i2c_adapter *adap) | |||
304 | } | 292 | } |
305 | } | 293 | } |
306 | 294 | ||
307 | dev_dbg(&adap->dev, "%s(): exiting: stat = %04x.\n", | 295 | dev_dbg(&alg_data->adapter.dev, "%s(): exiting: stat = %04x.\n", |
308 | __func__, ioread32(I2C_REG_STS(alg_data))); | 296 | __func__, ioread32(I2C_REG_STS(alg_data))); |
309 | 297 | ||
310 | return 0; | 298 | return 0; |
@@ -312,11 +300,11 @@ static int i2c_pnx_master_rcv(struct i2c_adapter *adap) | |||
312 | 300 | ||
313 | static irqreturn_t i2c_pnx_interrupt(int irq, void *dev_id) | 301 | static irqreturn_t i2c_pnx_interrupt(int irq, void *dev_id) |
314 | { | 302 | { |
303 | struct i2c_pnx_algo_data *alg_data = dev_id; | ||
315 | u32 stat, ctl; | 304 | u32 stat, ctl; |
316 | struct i2c_adapter *adap = dev_id; | ||
317 | struct i2c_pnx_algo_data *alg_data = adap->algo_data; | ||
318 | 305 | ||
319 | dev_dbg(&adap->dev, "%s(): mstat = %x mctrl = %x, mode = %d\n", | 306 | dev_dbg(&alg_data->adapter.dev, |
307 | "%s(): mstat = %x mctrl = %x, mode = %d\n", | ||
320 | __func__, | 308 | __func__, |
321 | ioread32(I2C_REG_STS(alg_data)), | 309 | ioread32(I2C_REG_STS(alg_data)), |
322 | ioread32(I2C_REG_CTL(alg_data)), | 310 | ioread32(I2C_REG_CTL(alg_data)), |
@@ -339,10 +327,10 @@ static irqreturn_t i2c_pnx_interrupt(int irq, void *dev_id) | |||
339 | complete(&alg_data->mif.complete); | 327 | complete(&alg_data->mif.complete); |
340 | } else if (stat & mstatus_nai) { | 328 | } else if (stat & mstatus_nai) { |
341 | /* Slave did not acknowledge, generate a STOP */ | 329 | /* Slave did not acknowledge, generate a STOP */ |
342 | dev_dbg(&adap->dev, "%s(): " | 330 | dev_dbg(&alg_data->adapter.dev, |
343 | "Slave did not acknowledge, generating a STOP.\n", | 331 | "%s(): Slave did not acknowledge, generating a STOP.\n", |
344 | __func__); | 332 | __func__); |
345 | i2c_pnx_stop(adap); | 333 | i2c_pnx_stop(alg_data); |
346 | 334 | ||
347 | /* Disable master interrupts. */ | 335 | /* Disable master interrupts. */ |
348 | ctl = ioread32(I2C_REG_CTL(alg_data)); | 336 | ctl = ioread32(I2C_REG_CTL(alg_data)); |
@@ -368,9 +356,9 @@ static irqreturn_t i2c_pnx_interrupt(int irq, void *dev_id) | |||
368 | */ | 356 | */ |
369 | if ((stat & mstatus_drmi) || !(stat & mstatus_rfe)) { | 357 | if ((stat & mstatus_drmi) || !(stat & mstatus_rfe)) { |
370 | if (alg_data->mif.mode == I2C_SMBUS_WRITE) { | 358 | if (alg_data->mif.mode == I2C_SMBUS_WRITE) { |
371 | i2c_pnx_master_xmit(adap); | 359 | i2c_pnx_master_xmit(alg_data); |
372 | } else if (alg_data->mif.mode == I2C_SMBUS_READ) { | 360 | } else if (alg_data->mif.mode == I2C_SMBUS_READ) { |
373 | i2c_pnx_master_rcv(adap); | 361 | i2c_pnx_master_rcv(alg_data); |
374 | } | 362 | } |
375 | } | 363 | } |
376 | } | 364 | } |
@@ -379,7 +367,8 @@ static irqreturn_t i2c_pnx_interrupt(int irq, void *dev_id) | |||
379 | stat = ioread32(I2C_REG_STS(alg_data)); | 367 | stat = ioread32(I2C_REG_STS(alg_data)); |
380 | iowrite32(stat | mstatus_tdi | mstatus_afi, I2C_REG_STS(alg_data)); | 368 | iowrite32(stat | mstatus_tdi | mstatus_afi, I2C_REG_STS(alg_data)); |
381 | 369 | ||
382 | dev_dbg(&adap->dev, "%s(): exiting, stat = %x ctrl = %x.\n", | 370 | dev_dbg(&alg_data->adapter.dev, |
371 | "%s(): exiting, stat = %x ctrl = %x.\n", | ||
383 | __func__, ioread32(I2C_REG_STS(alg_data)), | 372 | __func__, ioread32(I2C_REG_STS(alg_data)), |
384 | ioread32(I2C_REG_CTL(alg_data))); | 373 | ioread32(I2C_REG_CTL(alg_data))); |
385 | 374 | ||
@@ -388,14 +377,13 @@ static irqreturn_t i2c_pnx_interrupt(int irq, void *dev_id) | |||
388 | 377 | ||
389 | static void i2c_pnx_timeout(unsigned long data) | 378 | static void i2c_pnx_timeout(unsigned long data) |
390 | { | 379 | { |
391 | struct i2c_adapter *adap = (struct i2c_adapter *)data; | 380 | struct i2c_pnx_algo_data *alg_data = (struct i2c_pnx_algo_data *)data; |
392 | struct i2c_pnx_algo_data *alg_data = adap->algo_data; | ||
393 | u32 ctl; | 381 | u32 ctl; |
394 | 382 | ||
395 | dev_err(&adap->dev, "Master timed out. stat = %04x, cntrl = %04x. " | 383 | dev_err(&alg_data->adapter.dev, |
396 | "Resetting master...\n", | 384 | "Master timed out. stat = %04x, cntrl = %04x. Resetting master...\n", |
397 | ioread32(I2C_REG_STS(alg_data)), | 385 | ioread32(I2C_REG_STS(alg_data)), |
398 | ioread32(I2C_REG_CTL(alg_data))); | 386 | ioread32(I2C_REG_CTL(alg_data))); |
399 | 387 | ||
400 | /* Reset master and disable interrupts */ | 388 | /* Reset master and disable interrupts */ |
401 | ctl = ioread32(I2C_REG_CTL(alg_data)); | 389 | ctl = ioread32(I2C_REG_CTL(alg_data)); |
@@ -409,15 +397,14 @@ static void i2c_pnx_timeout(unsigned long data) | |||
409 | complete(&alg_data->mif.complete); | 397 | complete(&alg_data->mif.complete); |
410 | } | 398 | } |
411 | 399 | ||
412 | static inline void bus_reset_if_active(struct i2c_adapter *adap) | 400 | static inline void bus_reset_if_active(struct i2c_pnx_algo_data *alg_data) |
413 | { | 401 | { |
414 | struct i2c_pnx_algo_data *alg_data = adap->algo_data; | ||
415 | u32 stat; | 402 | u32 stat; |
416 | 403 | ||
417 | if ((stat = ioread32(I2C_REG_STS(alg_data))) & mstatus_active) { | 404 | if ((stat = ioread32(I2C_REG_STS(alg_data))) & mstatus_active) { |
418 | dev_err(&adap->dev, | 405 | dev_err(&alg_data->adapter.dev, |
419 | "%s: Bus is still active after xfer. Reset it...\n", | 406 | "%s: Bus is still active after xfer. Reset it...\n", |
420 | adap->name); | 407 | alg_data->adapter.name); |
421 | iowrite32(ioread32(I2C_REG_CTL(alg_data)) | mcntrl_reset, | 408 | iowrite32(ioread32(I2C_REG_CTL(alg_data)) | mcntrl_reset, |
422 | I2C_REG_CTL(alg_data)); | 409 | I2C_REG_CTL(alg_data)); |
423 | wait_reset(I2C_PNX_TIMEOUT, alg_data); | 410 | wait_reset(I2C_PNX_TIMEOUT, alg_data); |
@@ -451,10 +438,11 @@ i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) | |||
451 | struct i2c_pnx_algo_data *alg_data = adap->algo_data; | 438 | struct i2c_pnx_algo_data *alg_data = adap->algo_data; |
452 | u32 stat = ioread32(I2C_REG_STS(alg_data)); | 439 | u32 stat = ioread32(I2C_REG_STS(alg_data)); |
453 | 440 | ||
454 | dev_dbg(&adap->dev, "%s(): entering: %d messages, stat = %04x.\n", | 441 | dev_dbg(&alg_data->adapter.dev, |
442 | "%s(): entering: %d messages, stat = %04x.\n", | ||
455 | __func__, num, ioread32(I2C_REG_STS(alg_data))); | 443 | __func__, num, ioread32(I2C_REG_STS(alg_data))); |
456 | 444 | ||
457 | bus_reset_if_active(adap); | 445 | bus_reset_if_active(alg_data); |
458 | 446 | ||
459 | /* Process transactions in a loop. */ | 447 | /* Process transactions in a loop. */ |
460 | for (i = 0; rc >= 0 && i < num; i++) { | 448 | for (i = 0; rc >= 0 && i < num; i++) { |
@@ -464,9 +452,9 @@ i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) | |||
464 | addr = pmsg->addr; | 452 | addr = pmsg->addr; |
465 | 453 | ||
466 | if (pmsg->flags & I2C_M_TEN) { | 454 | if (pmsg->flags & I2C_M_TEN) { |
467 | dev_err(&adap->dev, | 455 | dev_err(&alg_data->adapter.dev, |
468 | "%s: 10 bits addr not supported!\n", | 456 | "%s: 10 bits addr not supported!\n", |
469 | adap->name); | 457 | alg_data->adapter.name); |
470 | rc = -EINVAL; | 458 | rc = -EINVAL; |
471 | break; | 459 | break; |
472 | } | 460 | } |
@@ -478,11 +466,10 @@ i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) | |||
478 | alg_data->mif.ret = 0; | 466 | alg_data->mif.ret = 0; |
479 | alg_data->last = (i == num - 1); | 467 | alg_data->last = (i == num - 1); |
480 | 468 | ||
481 | dev_dbg(&adap->dev, "%s(): mode %d, %d bytes\n", __func__, | 469 | dev_dbg(&alg_data->adapter.dev, "%s(): mode %d, %d bytes\n", |
482 | alg_data->mif.mode, | 470 | __func__, alg_data->mif.mode, alg_data->mif.len); |
483 | alg_data->mif.len); | ||
484 | 471 | ||
485 | i2c_pnx_arm_timer(adap); | 472 | i2c_pnx_arm_timer(alg_data); |
486 | 473 | ||
487 | /* initialize the completion var */ | 474 | /* initialize the completion var */ |
488 | init_completion(&alg_data->mif.complete); | 475 | init_completion(&alg_data->mif.complete); |
@@ -493,7 +480,7 @@ i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) | |||
493 | I2C_REG_CTL(alg_data)); | 480 | I2C_REG_CTL(alg_data)); |
494 | 481 | ||
495 | /* Put start-code and slave-address on the bus. */ | 482 | /* Put start-code and slave-address on the bus. */ |
496 | rc = i2c_pnx_start(addr, adap); | 483 | rc = i2c_pnx_start(addr, alg_data); |
497 | if (rc < 0) | 484 | if (rc < 0) |
498 | break; | 485 | break; |
499 | 486 | ||
@@ -502,31 +489,32 @@ i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) | |||
502 | 489 | ||
503 | if (!(rc = alg_data->mif.ret)) | 490 | if (!(rc = alg_data->mif.ret)) |
504 | completed++; | 491 | completed++; |
505 | dev_dbg(&adap->dev, "%s(): Complete, return code = %d.\n", | 492 | dev_dbg(&alg_data->adapter.dev, |
493 | "%s(): Complete, return code = %d.\n", | ||
506 | __func__, rc); | 494 | __func__, rc); |
507 | 495 | ||
508 | /* Clear TDI and AFI bits in case they are set. */ | 496 | /* Clear TDI and AFI bits in case they are set. */ |
509 | if ((stat = ioread32(I2C_REG_STS(alg_data))) & mstatus_tdi) { | 497 | if ((stat = ioread32(I2C_REG_STS(alg_data))) & mstatus_tdi) { |
510 | dev_dbg(&adap->dev, | 498 | dev_dbg(&alg_data->adapter.dev, |
511 | "%s: TDI still set... clearing now.\n", | 499 | "%s: TDI still set... clearing now.\n", |
512 | adap->name); | 500 | alg_data->adapter.name); |
513 | iowrite32(stat, I2C_REG_STS(alg_data)); | 501 | iowrite32(stat, I2C_REG_STS(alg_data)); |
514 | } | 502 | } |
515 | if ((stat = ioread32(I2C_REG_STS(alg_data))) & mstatus_afi) { | 503 | if ((stat = ioread32(I2C_REG_STS(alg_data))) & mstatus_afi) { |
516 | dev_dbg(&adap->dev, | 504 | dev_dbg(&alg_data->adapter.dev, |
517 | "%s: AFI still set... clearing now.\n", | 505 | "%s: AFI still set... clearing now.\n", |
518 | adap->name); | 506 | alg_data->adapter.name); |
519 | iowrite32(stat, I2C_REG_STS(alg_data)); | 507 | iowrite32(stat, I2C_REG_STS(alg_data)); |
520 | } | 508 | } |
521 | } | 509 | } |
522 | 510 | ||
523 | bus_reset_if_active(adap); | 511 | bus_reset_if_active(alg_data); |
524 | 512 | ||
525 | /* Cleanup to be sure... */ | 513 | /* Cleanup to be sure... */ |
526 | alg_data->mif.buf = NULL; | 514 | alg_data->mif.buf = NULL; |
527 | alg_data->mif.len = 0; | 515 | alg_data->mif.len = 0; |
528 | 516 | ||
529 | dev_dbg(&adap->dev, "%s(): exiting, stat = %x\n", | 517 | dev_dbg(&alg_data->adapter.dev, "%s(): exiting, stat = %x\n", |
530 | __func__, ioread32(I2C_REG_STS(alg_data))); | 518 | __func__, ioread32(I2C_REG_STS(alg_data))); |
531 | 519 | ||
532 | if (completed != num) | 520 | if (completed != num) |
@@ -545,69 +533,92 @@ static struct i2c_algorithm pnx_algorithm = { | |||
545 | .functionality = i2c_pnx_func, | 533 | .functionality = i2c_pnx_func, |
546 | }; | 534 | }; |
547 | 535 | ||
536 | #ifdef CONFIG_PM | ||
548 | static int i2c_pnx_controller_suspend(struct platform_device *pdev, | 537 | static int i2c_pnx_controller_suspend(struct platform_device *pdev, |
549 | pm_message_t state) | 538 | pm_message_t state) |
550 | { | 539 | { |
551 | struct i2c_pnx_data *i2c_pnx = platform_get_drvdata(pdev); | 540 | struct i2c_pnx_algo_data *alg_data = platform_get_drvdata(pdev); |
552 | return i2c_pnx->suspend(pdev, state); | 541 | |
542 | /* FIXME: shouldn't this be clk_disable? */ | ||
543 | clk_enable(alg_data->clk); | ||
544 | |||
545 | return 0; | ||
553 | } | 546 | } |
554 | 547 | ||
555 | static int i2c_pnx_controller_resume(struct platform_device *pdev) | 548 | static int i2c_pnx_controller_resume(struct platform_device *pdev) |
556 | { | 549 | { |
557 | struct i2c_pnx_data *i2c_pnx = platform_get_drvdata(pdev); | 550 | struct i2c_pnx_algo_data *alg_data = platform_get_drvdata(pdev); |
558 | return i2c_pnx->resume(pdev); | 551 | |
552 | return clk_enable(alg_data->clk); | ||
559 | } | 553 | } |
554 | #else | ||
555 | #define i2c_pnx_controller_suspend NULL | ||
556 | #define i2c_pnx_controller_resume NULL | ||
557 | #endif | ||
560 | 558 | ||
561 | static int __devinit i2c_pnx_probe(struct platform_device *pdev) | 559 | static int __devinit i2c_pnx_probe(struct platform_device *pdev) |
562 | { | 560 | { |
563 | unsigned long tmp; | 561 | unsigned long tmp; |
564 | int ret = 0; | 562 | int ret = 0; |
565 | struct i2c_pnx_algo_data *alg_data; | 563 | struct i2c_pnx_algo_data *alg_data; |
566 | int freq_mhz; | 564 | unsigned long freq; |
567 | struct i2c_pnx_data *i2c_pnx = pdev->dev.platform_data; | 565 | struct i2c_pnx_data *i2c_pnx = pdev->dev.platform_data; |
568 | 566 | ||
569 | if (!i2c_pnx || !i2c_pnx->adapter) { | 567 | if (!i2c_pnx || !i2c_pnx->name) { |
570 | dev_err(&pdev->dev, "%s: no platform data supplied\n", | 568 | dev_err(&pdev->dev, "%s: no platform data supplied\n", |
571 | __func__); | 569 | __func__); |
572 | ret = -EINVAL; | 570 | ret = -EINVAL; |
573 | goto out; | 571 | goto out; |
574 | } | 572 | } |
575 | 573 | ||
576 | platform_set_drvdata(pdev, i2c_pnx); | 574 | alg_data = kzalloc(sizeof(*alg_data), GFP_KERNEL); |
577 | 575 | if (!alg_data) { | |
578 | if (i2c_pnx->calculate_input_freq) | 576 | ret = -ENOMEM; |
579 | freq_mhz = i2c_pnx->calculate_input_freq(pdev); | 577 | goto err_kzalloc; |
580 | else { | ||
581 | freq_mhz = PNX_DEFAULT_FREQ; | ||
582 | dev_info(&pdev->dev, "Setting bus frequency to default value: " | ||
583 | "%d MHz\n", freq_mhz); | ||
584 | } | 578 | } |
585 | 579 | ||
586 | i2c_pnx->adapter->algo = &pnx_algorithm; | 580 | platform_set_drvdata(pdev, alg_data); |
581 | |||
582 | strlcpy(alg_data->adapter.name, i2c_pnx->name, | ||
583 | sizeof(alg_data->adapter.name)); | ||
584 | alg_data->adapter.dev.parent = &pdev->dev; | ||
585 | alg_data->adapter.algo = &pnx_algorithm; | ||
586 | alg_data->adapter.algo_data = alg_data; | ||
587 | alg_data->adapter.nr = pdev->id; | ||
588 | alg_data->i2c_pnx = i2c_pnx; | ||
589 | |||
590 | alg_data->clk = clk_get(&pdev->dev, NULL); | ||
591 | if (IS_ERR(alg_data->clk)) { | ||
592 | ret = PTR_ERR(alg_data->clk); | ||
593 | goto out_drvdata; | ||
594 | } | ||
587 | 595 | ||
588 | alg_data = i2c_pnx->adapter->algo_data; | ||
589 | init_timer(&alg_data->mif.timer); | 596 | init_timer(&alg_data->mif.timer); |
590 | alg_data->mif.timer.function = i2c_pnx_timeout; | 597 | alg_data->mif.timer.function = i2c_pnx_timeout; |
591 | alg_data->mif.timer.data = (unsigned long)i2c_pnx->adapter; | 598 | alg_data->mif.timer.data = (unsigned long)alg_data; |
592 | 599 | ||
593 | /* Register I/O resource */ | 600 | /* Register I/O resource */ |
594 | if (!request_mem_region(alg_data->base, I2C_PNX_REGION_SIZE, | 601 | if (!request_mem_region(i2c_pnx->base, I2C_PNX_REGION_SIZE, |
595 | pdev->name)) { | 602 | pdev->name)) { |
596 | dev_err(&pdev->dev, | 603 | dev_err(&pdev->dev, |
597 | "I/O region 0x%08x for I2C already in use.\n", | 604 | "I/O region 0x%08x for I2C already in use.\n", |
598 | alg_data->base); | 605 | i2c_pnx->base); |
599 | ret = -ENODEV; | 606 | ret = -ENODEV; |
600 | goto out_drvdata; | 607 | goto out_clkget; |
601 | } | 608 | } |
602 | 609 | ||
603 | if (!(alg_data->ioaddr = | 610 | alg_data->ioaddr = ioremap(i2c_pnx->base, I2C_PNX_REGION_SIZE); |
604 | (u32)ioremap(alg_data->base, I2C_PNX_REGION_SIZE))) { | 611 | if (!alg_data->ioaddr) { |
605 | dev_err(&pdev->dev, "Couldn't ioremap I2C I/O region\n"); | 612 | dev_err(&pdev->dev, "Couldn't ioremap I2C I/O region\n"); |
606 | ret = -ENOMEM; | 613 | ret = -ENOMEM; |
607 | goto out_release; | 614 | goto out_release; |
608 | } | 615 | } |
609 | 616 | ||
610 | i2c_pnx->set_clock_run(pdev); | 617 | ret = clk_enable(alg_data->clk); |
618 | if (ret) | ||
619 | goto out_unmap; | ||
620 | |||
621 | freq = clk_get_rate(alg_data->clk); | ||
611 | 622 | ||
612 | /* | 623 | /* |
613 | * Clock Divisor High This value is the number of system clocks | 624 | * Clock Divisor High This value is the number of system clocks |
@@ -620,45 +631,47 @@ static int __devinit i2c_pnx_probe(struct platform_device *pdev) | |||
620 | * the deglitching filter length. | 631 | * the deglitching filter length. |
621 | */ | 632 | */ |
622 | 633 | ||
623 | tmp = ((freq_mhz * 1000) / I2C_PNX_SPEED_KHZ) / 2 - 2; | 634 | tmp = ((freq / 1000) / I2C_PNX_SPEED_KHZ) / 2 - 2; |
624 | iowrite32(tmp, I2C_REG_CKH(alg_data)); | 635 | iowrite32(tmp, I2C_REG_CKH(alg_data)); |
625 | iowrite32(tmp, I2C_REG_CKL(alg_data)); | 636 | iowrite32(tmp, I2C_REG_CKL(alg_data)); |
626 | 637 | ||
627 | iowrite32(mcntrl_reset, I2C_REG_CTL(alg_data)); | 638 | iowrite32(mcntrl_reset, I2C_REG_CTL(alg_data)); |
628 | if (wait_reset(I2C_PNX_TIMEOUT, alg_data)) { | 639 | if (wait_reset(I2C_PNX_TIMEOUT, alg_data)) { |
629 | ret = -ENODEV; | 640 | ret = -ENODEV; |
630 | goto out_unmap; | 641 | goto out_clock; |
631 | } | 642 | } |
632 | init_completion(&alg_data->mif.complete); | 643 | init_completion(&alg_data->mif.complete); |
633 | 644 | ||
634 | ret = request_irq(alg_data->irq, i2c_pnx_interrupt, | 645 | ret = request_irq(i2c_pnx->irq, i2c_pnx_interrupt, |
635 | 0, pdev->name, i2c_pnx->adapter); | 646 | 0, pdev->name, alg_data); |
636 | if (ret) | 647 | if (ret) |
637 | goto out_clock; | 648 | goto out_clock; |
638 | 649 | ||
639 | /* Register this adapter with the I2C subsystem */ | 650 | /* Register this adapter with the I2C subsystem */ |
640 | i2c_pnx->adapter->dev.parent = &pdev->dev; | 651 | ret = i2c_add_numbered_adapter(&alg_data->adapter); |
641 | i2c_pnx->adapter->nr = pdev->id; | ||
642 | ret = i2c_add_numbered_adapter(i2c_pnx->adapter); | ||
643 | if (ret < 0) { | 652 | if (ret < 0) { |
644 | dev_err(&pdev->dev, "I2C: Failed to add bus\n"); | 653 | dev_err(&pdev->dev, "I2C: Failed to add bus\n"); |
645 | goto out_irq; | 654 | goto out_irq; |
646 | } | 655 | } |
647 | 656 | ||
648 | dev_dbg(&pdev->dev, "%s: Master at %#8x, irq %d.\n", | 657 | dev_dbg(&pdev->dev, "%s: Master at %#8x, irq %d.\n", |
649 | i2c_pnx->adapter->name, alg_data->base, alg_data->irq); | 658 | alg_data->adapter.name, i2c_pnx->base, i2c_pnx->irq); |
650 | 659 | ||
651 | return 0; | 660 | return 0; |
652 | 661 | ||
653 | out_irq: | 662 | out_irq: |
654 | free_irq(alg_data->irq, i2c_pnx->adapter); | 663 | free_irq(i2c_pnx->irq, alg_data); |
655 | out_clock: | 664 | out_clock: |
656 | i2c_pnx->set_clock_stop(pdev); | 665 | clk_disable(alg_data->clk); |
657 | out_unmap: | 666 | out_unmap: |
658 | iounmap((void *)alg_data->ioaddr); | 667 | iounmap(alg_data->ioaddr); |
659 | out_release: | 668 | out_release: |
660 | release_mem_region(alg_data->base, I2C_PNX_REGION_SIZE); | 669 | release_mem_region(i2c_pnx->base, I2C_PNX_REGION_SIZE); |
670 | out_clkget: | ||
671 | clk_put(alg_data->clk); | ||
661 | out_drvdata: | 672 | out_drvdata: |
673 | kfree(alg_data); | ||
674 | err_kzalloc: | ||
662 | platform_set_drvdata(pdev, NULL); | 675 | platform_set_drvdata(pdev, NULL); |
663 | out: | 676 | out: |
664 | return ret; | 677 | return ret; |
@@ -666,15 +679,16 @@ out: | |||
666 | 679 | ||
667 | static int __devexit i2c_pnx_remove(struct platform_device *pdev) | 680 | static int __devexit i2c_pnx_remove(struct platform_device *pdev) |
668 | { | 681 | { |
669 | struct i2c_pnx_data *i2c_pnx = platform_get_drvdata(pdev); | 682 | struct i2c_pnx_algo_data *alg_data = platform_get_drvdata(pdev); |
670 | struct i2c_adapter *adap = i2c_pnx->adapter; | 683 | struct i2c_pnx_data *i2c_pnx = alg_data->i2c_pnx; |
671 | struct i2c_pnx_algo_data *alg_data = adap->algo_data; | 684 | |
672 | 685 | free_irq(i2c_pnx->irq, alg_data); | |
673 | free_irq(alg_data->irq, i2c_pnx->adapter); | 686 | i2c_del_adapter(&alg_data->adapter); |
674 | i2c_del_adapter(adap); | 687 | clk_disable(alg_data->clk); |
675 | i2c_pnx->set_clock_stop(pdev); | 688 | iounmap(alg_data->ioaddr); |
676 | iounmap((void *)alg_data->ioaddr); | 689 | release_mem_region(i2c_pnx->base, I2C_PNX_REGION_SIZE); |
677 | release_mem_region(alg_data->base, I2C_PNX_REGION_SIZE); | 690 | clk_put(alg_data->clk); |
691 | kfree(alg_data); | ||
678 | platform_set_drvdata(pdev, NULL); | 692 | platform_set_drvdata(pdev, NULL); |
679 | 693 | ||
680 | return 0; | 694 | return 0; |