diff options
Diffstat (limited to 'drivers/i2c/busses/i2c-pnx.c')
-rw-r--r-- | drivers/i2c/busses/i2c-pnx.c | 285 |
1 files changed, 155 insertions, 130 deletions
diff --git a/drivers/i2c/busses/i2c-pnx.c b/drivers/i2c/busses/i2c-pnx.c index 5d1c2603a130..2b0bd0b042d6 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,12 +161,11 @@ 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) { |
@@ -184,15 +181,15 @@ static int i2c_pnx_master_xmit(struct i2c_adapter *adap) | |||
184 | alg_data->mif.len--; | 181 | alg_data->mif.len--; |
185 | iowrite32(val, I2C_REG_TX(alg_data)); | 182 | iowrite32(val, I2C_REG_TX(alg_data)); |
186 | 183 | ||
187 | dev_dbg(&adap->dev, "%s(): xmit %#x [%d]\n", __func__, | 184 | dev_dbg(&alg_data->adapter.dev, "%s(): xmit %#x [%d]\n", |
188 | val, alg_data->mif.len + 1); | 185 | __func__, val, alg_data->mif.len + 1); |
189 | 186 | ||
190 | if (alg_data->mif.len == 0) { | 187 | if (alg_data->mif.len == 0) { |
191 | if (alg_data->last) { | 188 | if (alg_data->last) { |
192 | /* Wait until the STOP is seen. */ | 189 | /* Wait until the STOP is seen. */ |
193 | if (wait_timeout(I2C_PNX_TIMEOUT, alg_data)) | 190 | if (wait_timeout(I2C_PNX_TIMEOUT, alg_data)) |
194 | dev_err(&adap->dev, "The bus is still " | 191 | dev_err(&alg_data->adapter.dev, |
195 | "active after timeout\n"); | 192 | "The bus is still active after timeout\n"); |
196 | } | 193 | } |
197 | /* Disable master interrupts */ | 194 | /* Disable master interrupts */ |
198 | iowrite32(ioread32(I2C_REG_CTL(alg_data)) & | 195 | iowrite32(ioread32(I2C_REG_CTL(alg_data)) & |
@@ -201,14 +198,15 @@ static int i2c_pnx_master_xmit(struct i2c_adapter *adap) | |||
201 | 198 | ||
202 | del_timer_sync(&alg_data->mif.timer); | 199 | del_timer_sync(&alg_data->mif.timer); |
203 | 200 | ||
204 | dev_dbg(&adap->dev, "%s(): Waking up xfer routine.\n", | 201 | dev_dbg(&alg_data->adapter.dev, |
202 | "%s(): Waking up xfer routine.\n", | ||
205 | __func__); | 203 | __func__); |
206 | 204 | ||
207 | complete(&alg_data->mif.complete); | 205 | complete(&alg_data->mif.complete); |
208 | } | 206 | } |
209 | } else if (alg_data->mif.len == 0) { | 207 | } else if (alg_data->mif.len == 0) { |
210 | /* zero-sized transfer */ | 208 | /* zero-sized transfer */ |
211 | i2c_pnx_stop(adap); | 209 | i2c_pnx_stop(alg_data); |
212 | 210 | ||
213 | /* Disable master interrupts. */ | 211 | /* Disable master interrupts. */ |
214 | iowrite32(ioread32(I2C_REG_CTL(alg_data)) & | 212 | iowrite32(ioread32(I2C_REG_CTL(alg_data)) & |
@@ -217,13 +215,14 @@ static int i2c_pnx_master_xmit(struct i2c_adapter *adap) | |||
217 | 215 | ||
218 | /* Stop timer. */ | 216 | /* Stop timer. */ |
219 | del_timer_sync(&alg_data->mif.timer); | 217 | del_timer_sync(&alg_data->mif.timer); |
220 | dev_dbg(&adap->dev, "%s(): Waking up xfer routine after " | 218 | dev_dbg(&alg_data->adapter.dev, |
221 | "zero-xfer.\n", __func__); | 219 | "%s(): Waking up xfer routine after zero-xfer.\n", |
220 | __func__); | ||
222 | 221 | ||
223 | complete(&alg_data->mif.complete); | 222 | complete(&alg_data->mif.complete); |
224 | } | 223 | } |
225 | 224 | ||
226 | dev_dbg(&adap->dev, "%s(): exiting: stat = %04x.\n", | 225 | dev_dbg(&alg_data->adapter.dev, "%s(): exiting: stat = %04x.\n", |
227 | __func__, ioread32(I2C_REG_STS(alg_data))); | 226 | __func__, ioread32(I2C_REG_STS(alg_data))); |
228 | 227 | ||
229 | return 0; | 228 | return 0; |
@@ -235,21 +234,21 @@ static int i2c_pnx_master_xmit(struct i2c_adapter *adap) | |||
235 | * | 234 | * |
236 | * Reads one byte data from the slave | 235 | * Reads one byte data from the slave |
237 | */ | 236 | */ |
238 | static int i2c_pnx_master_rcv(struct i2c_adapter *adap) | 237 | static int i2c_pnx_master_rcv(struct i2c_pnx_algo_data *alg_data) |
239 | { | 238 | { |
240 | struct i2c_pnx_algo_data *alg_data = adap->algo_data; | ||
241 | unsigned int val = 0; | 239 | unsigned int val = 0; |
242 | u32 ctl = 0; | 240 | u32 ctl = 0; |
243 | 241 | ||
244 | dev_dbg(&adap->dev, "%s(): entering: stat = %04x.\n", | 242 | dev_dbg(&alg_data->adapter.dev, "%s(): entering: stat = %04x.\n", |
245 | __func__, ioread32(I2C_REG_STS(alg_data))); | 243 | __func__, ioread32(I2C_REG_STS(alg_data))); |
246 | 244 | ||
247 | /* Check, whether there is already data, | 245 | /* Check, whether there is already data, |
248 | * or we didn't 'ask' for it yet. | 246 | * or we didn't 'ask' for it yet. |
249 | */ | 247 | */ |
250 | if (ioread32(I2C_REG_STS(alg_data)) & mstatus_rfe) { | 248 | if (ioread32(I2C_REG_STS(alg_data)) & mstatus_rfe) { |
251 | dev_dbg(&adap->dev, "%s(): Write dummy data to fill " | 249 | dev_dbg(&alg_data->adapter.dev, |
252 | "Rx-fifo...\n", __func__); | 250 | "%s(): Write dummy data to fill Rx-fifo...\n", |
251 | __func__); | ||
253 | 252 | ||
254 | if (alg_data->mif.len == 1) { | 253 | if (alg_data->mif.len == 1) { |
255 | /* Last byte, do not acknowledge next rcv. */ | 254 | /* Last byte, do not acknowledge next rcv. */ |
@@ -281,16 +280,16 @@ static int i2c_pnx_master_rcv(struct i2c_adapter *adap) | |||
281 | if (alg_data->mif.len > 0) { | 280 | if (alg_data->mif.len > 0) { |
282 | val = ioread32(I2C_REG_RX(alg_data)); | 281 | val = ioread32(I2C_REG_RX(alg_data)); |
283 | *alg_data->mif.buf++ = (u8) (val & 0xff); | 282 | *alg_data->mif.buf++ = (u8) (val & 0xff); |
284 | dev_dbg(&adap->dev, "%s(): rcv 0x%x [%d]\n", __func__, val, | 283 | dev_dbg(&alg_data->adapter.dev, "%s(): rcv 0x%x [%d]\n", |
285 | alg_data->mif.len); | 284 | __func__, val, alg_data->mif.len); |
286 | 285 | ||
287 | alg_data->mif.len--; | 286 | alg_data->mif.len--; |
288 | if (alg_data->mif.len == 0) { | 287 | if (alg_data->mif.len == 0) { |
289 | if (alg_data->last) | 288 | if (alg_data->last) |
290 | /* Wait until the STOP is seen. */ | 289 | /* Wait until the STOP is seen. */ |
291 | if (wait_timeout(I2C_PNX_TIMEOUT, alg_data)) | 290 | if (wait_timeout(I2C_PNX_TIMEOUT, alg_data)) |
292 | dev_err(&adap->dev, "The bus is still " | 291 | dev_err(&alg_data->adapter.dev, |
293 | "active after timeout\n"); | 292 | "The bus is still active after timeout\n"); |
294 | 293 | ||
295 | /* Disable master interrupts */ | 294 | /* Disable master interrupts */ |
296 | ctl = ioread32(I2C_REG_CTL(alg_data)); | 295 | ctl = ioread32(I2C_REG_CTL(alg_data)); |
@@ -304,7 +303,7 @@ static int i2c_pnx_master_rcv(struct i2c_adapter *adap) | |||
304 | } | 303 | } |
305 | } | 304 | } |
306 | 305 | ||
307 | dev_dbg(&adap->dev, "%s(): exiting: stat = %04x.\n", | 306 | dev_dbg(&alg_data->adapter.dev, "%s(): exiting: stat = %04x.\n", |
308 | __func__, ioread32(I2C_REG_STS(alg_data))); | 307 | __func__, ioread32(I2C_REG_STS(alg_data))); |
309 | 308 | ||
310 | return 0; | 309 | return 0; |
@@ -312,11 +311,11 @@ static int i2c_pnx_master_rcv(struct i2c_adapter *adap) | |||
312 | 311 | ||
313 | static irqreturn_t i2c_pnx_interrupt(int irq, void *dev_id) | 312 | static irqreturn_t i2c_pnx_interrupt(int irq, void *dev_id) |
314 | { | 313 | { |
314 | struct i2c_pnx_algo_data *alg_data = dev_id; | ||
315 | u32 stat, ctl; | 315 | u32 stat, ctl; |
316 | struct i2c_adapter *adap = dev_id; | ||
317 | struct i2c_pnx_algo_data *alg_data = adap->algo_data; | ||
318 | 316 | ||
319 | dev_dbg(&adap->dev, "%s(): mstat = %x mctrl = %x, mode = %d\n", | 317 | dev_dbg(&alg_data->adapter.dev, |
318 | "%s(): mstat = %x mctrl = %x, mode = %d\n", | ||
320 | __func__, | 319 | __func__, |
321 | ioread32(I2C_REG_STS(alg_data)), | 320 | ioread32(I2C_REG_STS(alg_data)), |
322 | ioread32(I2C_REG_CTL(alg_data)), | 321 | ioread32(I2C_REG_CTL(alg_data)), |
@@ -339,10 +338,10 @@ static irqreturn_t i2c_pnx_interrupt(int irq, void *dev_id) | |||
339 | complete(&alg_data->mif.complete); | 338 | complete(&alg_data->mif.complete); |
340 | } else if (stat & mstatus_nai) { | 339 | } else if (stat & mstatus_nai) { |
341 | /* Slave did not acknowledge, generate a STOP */ | 340 | /* Slave did not acknowledge, generate a STOP */ |
342 | dev_dbg(&adap->dev, "%s(): " | 341 | dev_dbg(&alg_data->adapter.dev, |
343 | "Slave did not acknowledge, generating a STOP.\n", | 342 | "%s(): Slave did not acknowledge, generating a STOP.\n", |
344 | __func__); | 343 | __func__); |
345 | i2c_pnx_stop(adap); | 344 | i2c_pnx_stop(alg_data); |
346 | 345 | ||
347 | /* Disable master interrupts. */ | 346 | /* Disable master interrupts. */ |
348 | ctl = ioread32(I2C_REG_CTL(alg_data)); | 347 | ctl = ioread32(I2C_REG_CTL(alg_data)); |
@@ -368,9 +367,9 @@ static irqreturn_t i2c_pnx_interrupt(int irq, void *dev_id) | |||
368 | */ | 367 | */ |
369 | if ((stat & mstatus_drmi) || !(stat & mstatus_rfe)) { | 368 | if ((stat & mstatus_drmi) || !(stat & mstatus_rfe)) { |
370 | if (alg_data->mif.mode == I2C_SMBUS_WRITE) { | 369 | if (alg_data->mif.mode == I2C_SMBUS_WRITE) { |
371 | i2c_pnx_master_xmit(adap); | 370 | i2c_pnx_master_xmit(alg_data); |
372 | } else if (alg_data->mif.mode == I2C_SMBUS_READ) { | 371 | } else if (alg_data->mif.mode == I2C_SMBUS_READ) { |
373 | i2c_pnx_master_rcv(adap); | 372 | i2c_pnx_master_rcv(alg_data); |
374 | } | 373 | } |
375 | } | 374 | } |
376 | } | 375 | } |
@@ -379,7 +378,8 @@ static irqreturn_t i2c_pnx_interrupt(int irq, void *dev_id) | |||
379 | stat = ioread32(I2C_REG_STS(alg_data)); | 378 | stat = ioread32(I2C_REG_STS(alg_data)); |
380 | iowrite32(stat | mstatus_tdi | mstatus_afi, I2C_REG_STS(alg_data)); | 379 | iowrite32(stat | mstatus_tdi | mstatus_afi, I2C_REG_STS(alg_data)); |
381 | 380 | ||
382 | dev_dbg(&adap->dev, "%s(): exiting, stat = %x ctrl = %x.\n", | 381 | dev_dbg(&alg_data->adapter.dev, |
382 | "%s(): exiting, stat = %x ctrl = %x.\n", | ||
383 | __func__, ioread32(I2C_REG_STS(alg_data)), | 383 | __func__, ioread32(I2C_REG_STS(alg_data)), |
384 | ioread32(I2C_REG_CTL(alg_data))); | 384 | ioread32(I2C_REG_CTL(alg_data))); |
385 | 385 | ||
@@ -388,14 +388,13 @@ static irqreturn_t i2c_pnx_interrupt(int irq, void *dev_id) | |||
388 | 388 | ||
389 | static void i2c_pnx_timeout(unsigned long data) | 389 | static void i2c_pnx_timeout(unsigned long data) |
390 | { | 390 | { |
391 | struct i2c_adapter *adap = (struct i2c_adapter *)data; | 391 | 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; | 392 | u32 ctl; |
394 | 393 | ||
395 | dev_err(&adap->dev, "Master timed out. stat = %04x, cntrl = %04x. " | 394 | dev_err(&alg_data->adapter.dev, |
396 | "Resetting master...\n", | 395 | "Master timed out. stat = %04x, cntrl = %04x. Resetting master...\n", |
397 | ioread32(I2C_REG_STS(alg_data)), | 396 | ioread32(I2C_REG_STS(alg_data)), |
398 | ioread32(I2C_REG_CTL(alg_data))); | 397 | ioread32(I2C_REG_CTL(alg_data))); |
399 | 398 | ||
400 | /* Reset master and disable interrupts */ | 399 | /* Reset master and disable interrupts */ |
401 | ctl = ioread32(I2C_REG_CTL(alg_data)); | 400 | ctl = ioread32(I2C_REG_CTL(alg_data)); |
@@ -409,15 +408,14 @@ static void i2c_pnx_timeout(unsigned long data) | |||
409 | complete(&alg_data->mif.complete); | 408 | complete(&alg_data->mif.complete); |
410 | } | 409 | } |
411 | 410 | ||
412 | static inline void bus_reset_if_active(struct i2c_adapter *adap) | 411 | static inline void bus_reset_if_active(struct i2c_pnx_algo_data *alg_data) |
413 | { | 412 | { |
414 | struct i2c_pnx_algo_data *alg_data = adap->algo_data; | ||
415 | u32 stat; | 413 | u32 stat; |
416 | 414 | ||
417 | if ((stat = ioread32(I2C_REG_STS(alg_data))) & mstatus_active) { | 415 | if ((stat = ioread32(I2C_REG_STS(alg_data))) & mstatus_active) { |
418 | dev_err(&adap->dev, | 416 | dev_err(&alg_data->adapter.dev, |
419 | "%s: Bus is still active after xfer. Reset it...\n", | 417 | "%s: Bus is still active after xfer. Reset it...\n", |
420 | adap->name); | 418 | alg_data->adapter.name); |
421 | iowrite32(ioread32(I2C_REG_CTL(alg_data)) | mcntrl_reset, | 419 | iowrite32(ioread32(I2C_REG_CTL(alg_data)) | mcntrl_reset, |
422 | I2C_REG_CTL(alg_data)); | 420 | I2C_REG_CTL(alg_data)); |
423 | wait_reset(I2C_PNX_TIMEOUT, alg_data); | 421 | wait_reset(I2C_PNX_TIMEOUT, alg_data); |
@@ -451,10 +449,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; | 449 | struct i2c_pnx_algo_data *alg_data = adap->algo_data; |
452 | u32 stat = ioread32(I2C_REG_STS(alg_data)); | 450 | u32 stat = ioread32(I2C_REG_STS(alg_data)); |
453 | 451 | ||
454 | dev_dbg(&adap->dev, "%s(): entering: %d messages, stat = %04x.\n", | 452 | dev_dbg(&alg_data->adapter.dev, |
453 | "%s(): entering: %d messages, stat = %04x.\n", | ||
455 | __func__, num, ioread32(I2C_REG_STS(alg_data))); | 454 | __func__, num, ioread32(I2C_REG_STS(alg_data))); |
456 | 455 | ||
457 | bus_reset_if_active(adap); | 456 | bus_reset_if_active(alg_data); |
458 | 457 | ||
459 | /* Process transactions in a loop. */ | 458 | /* Process transactions in a loop. */ |
460 | for (i = 0; rc >= 0 && i < num; i++) { | 459 | for (i = 0; rc >= 0 && i < num; i++) { |
@@ -464,9 +463,9 @@ i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) | |||
464 | addr = pmsg->addr; | 463 | addr = pmsg->addr; |
465 | 464 | ||
466 | if (pmsg->flags & I2C_M_TEN) { | 465 | if (pmsg->flags & I2C_M_TEN) { |
467 | dev_err(&adap->dev, | 466 | dev_err(&alg_data->adapter.dev, |
468 | "%s: 10 bits addr not supported!\n", | 467 | "%s: 10 bits addr not supported!\n", |
469 | adap->name); | 468 | alg_data->adapter.name); |
470 | rc = -EINVAL; | 469 | rc = -EINVAL; |
471 | break; | 470 | break; |
472 | } | 471 | } |
@@ -478,11 +477,10 @@ i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) | |||
478 | alg_data->mif.ret = 0; | 477 | alg_data->mif.ret = 0; |
479 | alg_data->last = (i == num - 1); | 478 | alg_data->last = (i == num - 1); |
480 | 479 | ||
481 | dev_dbg(&adap->dev, "%s(): mode %d, %d bytes\n", __func__, | 480 | dev_dbg(&alg_data->adapter.dev, "%s(): mode %d, %d bytes\n", |
482 | alg_data->mif.mode, | 481 | __func__, alg_data->mif.mode, alg_data->mif.len); |
483 | alg_data->mif.len); | ||
484 | 482 | ||
485 | i2c_pnx_arm_timer(adap); | 483 | i2c_pnx_arm_timer(alg_data); |
486 | 484 | ||
487 | /* initialize the completion var */ | 485 | /* initialize the completion var */ |
488 | init_completion(&alg_data->mif.complete); | 486 | init_completion(&alg_data->mif.complete); |
@@ -493,7 +491,7 @@ i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) | |||
493 | I2C_REG_CTL(alg_data)); | 491 | I2C_REG_CTL(alg_data)); |
494 | 492 | ||
495 | /* Put start-code and slave-address on the bus. */ | 493 | /* Put start-code and slave-address on the bus. */ |
496 | rc = i2c_pnx_start(addr, adap); | 494 | rc = i2c_pnx_start(addr, alg_data); |
497 | if (rc < 0) | 495 | if (rc < 0) |
498 | break; | 496 | break; |
499 | 497 | ||
@@ -502,31 +500,32 @@ i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) | |||
502 | 500 | ||
503 | if (!(rc = alg_data->mif.ret)) | 501 | if (!(rc = alg_data->mif.ret)) |
504 | completed++; | 502 | completed++; |
505 | dev_dbg(&adap->dev, "%s(): Complete, return code = %d.\n", | 503 | dev_dbg(&alg_data->adapter.dev, |
504 | "%s(): Complete, return code = %d.\n", | ||
506 | __func__, rc); | 505 | __func__, rc); |
507 | 506 | ||
508 | /* Clear TDI and AFI bits in case they are set. */ | 507 | /* Clear TDI and AFI bits in case they are set. */ |
509 | if ((stat = ioread32(I2C_REG_STS(alg_data))) & mstatus_tdi) { | 508 | if ((stat = ioread32(I2C_REG_STS(alg_data))) & mstatus_tdi) { |
510 | dev_dbg(&adap->dev, | 509 | dev_dbg(&alg_data->adapter.dev, |
511 | "%s: TDI still set... clearing now.\n", | 510 | "%s: TDI still set... clearing now.\n", |
512 | adap->name); | 511 | alg_data->adapter.name); |
513 | iowrite32(stat, I2C_REG_STS(alg_data)); | 512 | iowrite32(stat, I2C_REG_STS(alg_data)); |
514 | } | 513 | } |
515 | if ((stat = ioread32(I2C_REG_STS(alg_data))) & mstatus_afi) { | 514 | if ((stat = ioread32(I2C_REG_STS(alg_data))) & mstatus_afi) { |
516 | dev_dbg(&adap->dev, | 515 | dev_dbg(&alg_data->adapter.dev, |
517 | "%s: AFI still set... clearing now.\n", | 516 | "%s: AFI still set... clearing now.\n", |
518 | adap->name); | 517 | alg_data->adapter.name); |
519 | iowrite32(stat, I2C_REG_STS(alg_data)); | 518 | iowrite32(stat, I2C_REG_STS(alg_data)); |
520 | } | 519 | } |
521 | } | 520 | } |
522 | 521 | ||
523 | bus_reset_if_active(adap); | 522 | bus_reset_if_active(alg_data); |
524 | 523 | ||
525 | /* Cleanup to be sure... */ | 524 | /* Cleanup to be sure... */ |
526 | alg_data->mif.buf = NULL; | 525 | alg_data->mif.buf = NULL; |
527 | alg_data->mif.len = 0; | 526 | alg_data->mif.len = 0; |
528 | 527 | ||
529 | dev_dbg(&adap->dev, "%s(): exiting, stat = %x\n", | 528 | dev_dbg(&alg_data->adapter.dev, "%s(): exiting, stat = %x\n", |
530 | __func__, ioread32(I2C_REG_STS(alg_data))); | 529 | __func__, ioread32(I2C_REG_STS(alg_data))); |
531 | 530 | ||
532 | if (completed != num) | 531 | if (completed != num) |
@@ -545,69 +544,92 @@ static struct i2c_algorithm pnx_algorithm = { | |||
545 | .functionality = i2c_pnx_func, | 544 | .functionality = i2c_pnx_func, |
546 | }; | 545 | }; |
547 | 546 | ||
547 | #ifdef CONFIG_PM | ||
548 | static int i2c_pnx_controller_suspend(struct platform_device *pdev, | 548 | static int i2c_pnx_controller_suspend(struct platform_device *pdev, |
549 | pm_message_t state) | 549 | pm_message_t state) |
550 | { | 550 | { |
551 | struct i2c_pnx_data *i2c_pnx = platform_get_drvdata(pdev); | 551 | struct i2c_pnx_algo_data *alg_data = platform_get_drvdata(pdev); |
552 | return i2c_pnx->suspend(pdev, state); | 552 | |
553 | /* FIXME: shouldn't this be clk_disable? */ | ||
554 | clk_enable(alg_data->clk); | ||
555 | |||
556 | return 0; | ||
553 | } | 557 | } |
554 | 558 | ||
555 | static int i2c_pnx_controller_resume(struct platform_device *pdev) | 559 | static int i2c_pnx_controller_resume(struct platform_device *pdev) |
556 | { | 560 | { |
557 | struct i2c_pnx_data *i2c_pnx = platform_get_drvdata(pdev); | 561 | struct i2c_pnx_algo_data *alg_data = platform_get_drvdata(pdev); |
558 | return i2c_pnx->resume(pdev); | 562 | |
563 | return clk_enable(alg_data->clk); | ||
559 | } | 564 | } |
565 | #else | ||
566 | #define i2c_pnx_controller_suspend NULL | ||
567 | #define i2c_pnx_controller_resume NULL | ||
568 | #endif | ||
560 | 569 | ||
561 | static int __devinit i2c_pnx_probe(struct platform_device *pdev) | 570 | static int __devinit i2c_pnx_probe(struct platform_device *pdev) |
562 | { | 571 | { |
563 | unsigned long tmp; | 572 | unsigned long tmp; |
564 | int ret = 0; | 573 | int ret = 0; |
565 | struct i2c_pnx_algo_data *alg_data; | 574 | struct i2c_pnx_algo_data *alg_data; |
566 | int freq_mhz; | 575 | unsigned long freq; |
567 | struct i2c_pnx_data *i2c_pnx = pdev->dev.platform_data; | 576 | struct i2c_pnx_data *i2c_pnx = pdev->dev.platform_data; |
568 | 577 | ||
569 | if (!i2c_pnx || !i2c_pnx->adapter) { | 578 | if (!i2c_pnx || !i2c_pnx->name) { |
570 | dev_err(&pdev->dev, "%s: no platform data supplied\n", | 579 | dev_err(&pdev->dev, "%s: no platform data supplied\n", |
571 | __func__); | 580 | __func__); |
572 | ret = -EINVAL; | 581 | ret = -EINVAL; |
573 | goto out; | 582 | goto out; |
574 | } | 583 | } |
575 | 584 | ||
576 | platform_set_drvdata(pdev, i2c_pnx); | 585 | alg_data = kzalloc(sizeof(*alg_data), GFP_KERNEL); |
577 | 586 | if (!alg_data) { | |
578 | if (i2c_pnx->calculate_input_freq) | 587 | ret = -ENOMEM; |
579 | freq_mhz = i2c_pnx->calculate_input_freq(pdev); | 588 | 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 | } | 589 | } |
585 | 590 | ||
586 | i2c_pnx->adapter->algo = &pnx_algorithm; | 591 | platform_set_drvdata(pdev, alg_data); |
592 | |||
593 | strlcpy(alg_data->adapter.name, i2c_pnx->name, | ||
594 | sizeof(alg_data->adapter.name)); | ||
595 | alg_data->adapter.dev.parent = &pdev->dev; | ||
596 | alg_data->adapter.algo = &pnx_algorithm; | ||
597 | alg_data->adapter.algo_data = alg_data; | ||
598 | alg_data->adapter.nr = pdev->id; | ||
599 | alg_data->i2c_pnx = i2c_pnx; | ||
600 | |||
601 | alg_data->clk = clk_get(&pdev->dev, NULL); | ||
602 | if (IS_ERR(alg_data->clk)) { | ||
603 | ret = PTR_ERR(alg_data->clk); | ||
604 | goto out_drvdata; | ||
605 | } | ||
587 | 606 | ||
588 | alg_data = i2c_pnx->adapter->algo_data; | ||
589 | init_timer(&alg_data->mif.timer); | 607 | init_timer(&alg_data->mif.timer); |
590 | alg_data->mif.timer.function = i2c_pnx_timeout; | 608 | alg_data->mif.timer.function = i2c_pnx_timeout; |
591 | alg_data->mif.timer.data = (unsigned long)i2c_pnx->adapter; | 609 | alg_data->mif.timer.data = (unsigned long)alg_data; |
592 | 610 | ||
593 | /* Register I/O resource */ | 611 | /* Register I/O resource */ |
594 | if (!request_mem_region(alg_data->base, I2C_PNX_REGION_SIZE, | 612 | if (!request_mem_region(i2c_pnx->base, I2C_PNX_REGION_SIZE, |
595 | pdev->name)) { | 613 | pdev->name)) { |
596 | dev_err(&pdev->dev, | 614 | dev_err(&pdev->dev, |
597 | "I/O region 0x%08x for I2C already in use.\n", | 615 | "I/O region 0x%08x for I2C already in use.\n", |
598 | alg_data->base); | 616 | i2c_pnx->base); |
599 | ret = -ENODEV; | 617 | ret = -ENODEV; |
600 | goto out_drvdata; | 618 | goto out_clkget; |
601 | } | 619 | } |
602 | 620 | ||
603 | if (!(alg_data->ioaddr = | 621 | alg_data->ioaddr = ioremap(i2c_pnx->base, I2C_PNX_REGION_SIZE); |
604 | (u32)ioremap(alg_data->base, I2C_PNX_REGION_SIZE))) { | 622 | if (!alg_data->ioaddr) { |
605 | dev_err(&pdev->dev, "Couldn't ioremap I2C I/O region\n"); | 623 | dev_err(&pdev->dev, "Couldn't ioremap I2C I/O region\n"); |
606 | ret = -ENOMEM; | 624 | ret = -ENOMEM; |
607 | goto out_release; | 625 | goto out_release; |
608 | } | 626 | } |
609 | 627 | ||
610 | i2c_pnx->set_clock_run(pdev); | 628 | ret = clk_enable(alg_data->clk); |
629 | if (ret) | ||
630 | goto out_unmap; | ||
631 | |||
632 | freq = clk_get_rate(alg_data->clk); | ||
611 | 633 | ||
612 | /* | 634 | /* |
613 | * Clock Divisor High This value is the number of system clocks | 635 | * Clock Divisor High This value is the number of system clocks |
@@ -620,45 +642,47 @@ static int __devinit i2c_pnx_probe(struct platform_device *pdev) | |||
620 | * the deglitching filter length. | 642 | * the deglitching filter length. |
621 | */ | 643 | */ |
622 | 644 | ||
623 | tmp = ((freq_mhz * 1000) / I2C_PNX_SPEED_KHZ) / 2 - 2; | 645 | tmp = ((freq / 1000) / I2C_PNX_SPEED_KHZ) / 2 - 2; |
624 | iowrite32(tmp, I2C_REG_CKH(alg_data)); | 646 | iowrite32(tmp, I2C_REG_CKH(alg_data)); |
625 | iowrite32(tmp, I2C_REG_CKL(alg_data)); | 647 | iowrite32(tmp, I2C_REG_CKL(alg_data)); |
626 | 648 | ||
627 | iowrite32(mcntrl_reset, I2C_REG_CTL(alg_data)); | 649 | iowrite32(mcntrl_reset, I2C_REG_CTL(alg_data)); |
628 | if (wait_reset(I2C_PNX_TIMEOUT, alg_data)) { | 650 | if (wait_reset(I2C_PNX_TIMEOUT, alg_data)) { |
629 | ret = -ENODEV; | 651 | ret = -ENODEV; |
630 | goto out_unmap; | 652 | goto out_clock; |
631 | } | 653 | } |
632 | init_completion(&alg_data->mif.complete); | 654 | init_completion(&alg_data->mif.complete); |
633 | 655 | ||
634 | ret = request_irq(alg_data->irq, i2c_pnx_interrupt, | 656 | ret = request_irq(i2c_pnx->irq, i2c_pnx_interrupt, |
635 | 0, pdev->name, i2c_pnx->adapter); | 657 | 0, pdev->name, alg_data); |
636 | if (ret) | 658 | if (ret) |
637 | goto out_clock; | 659 | goto out_clock; |
638 | 660 | ||
639 | /* Register this adapter with the I2C subsystem */ | 661 | /* Register this adapter with the I2C subsystem */ |
640 | i2c_pnx->adapter->dev.parent = &pdev->dev; | 662 | 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) { | 663 | if (ret < 0) { |
644 | dev_err(&pdev->dev, "I2C: Failed to add bus\n"); | 664 | dev_err(&pdev->dev, "I2C: Failed to add bus\n"); |
645 | goto out_irq; | 665 | goto out_irq; |
646 | } | 666 | } |
647 | 667 | ||
648 | dev_dbg(&pdev->dev, "%s: Master at %#8x, irq %d.\n", | 668 | dev_dbg(&pdev->dev, "%s: Master at %#8x, irq %d.\n", |
649 | i2c_pnx->adapter->name, alg_data->base, alg_data->irq); | 669 | alg_data->adapter.name, i2c_pnx->base, i2c_pnx->irq); |
650 | 670 | ||
651 | return 0; | 671 | return 0; |
652 | 672 | ||
653 | out_irq: | 673 | out_irq: |
654 | free_irq(alg_data->irq, i2c_pnx->adapter); | 674 | free_irq(i2c_pnx->irq, alg_data); |
655 | out_clock: | 675 | out_clock: |
656 | i2c_pnx->set_clock_stop(pdev); | 676 | clk_disable(alg_data->clk); |
657 | out_unmap: | 677 | out_unmap: |
658 | iounmap((void *)alg_data->ioaddr); | 678 | iounmap(alg_data->ioaddr); |
659 | out_release: | 679 | out_release: |
660 | release_mem_region(alg_data->base, I2C_PNX_REGION_SIZE); | 680 | release_mem_region(i2c_pnx->base, I2C_PNX_REGION_SIZE); |
681 | out_clkget: | ||
682 | clk_put(alg_data->clk); | ||
661 | out_drvdata: | 683 | out_drvdata: |
684 | kfree(alg_data); | ||
685 | err_kzalloc: | ||
662 | platform_set_drvdata(pdev, NULL); | 686 | platform_set_drvdata(pdev, NULL); |
663 | out: | 687 | out: |
664 | return ret; | 688 | return ret; |
@@ -666,15 +690,16 @@ out: | |||
666 | 690 | ||
667 | static int __devexit i2c_pnx_remove(struct platform_device *pdev) | 691 | static int __devexit i2c_pnx_remove(struct platform_device *pdev) |
668 | { | 692 | { |
669 | struct i2c_pnx_data *i2c_pnx = platform_get_drvdata(pdev); | 693 | struct i2c_pnx_algo_data *alg_data = platform_get_drvdata(pdev); |
670 | struct i2c_adapter *adap = i2c_pnx->adapter; | 694 | struct i2c_pnx_data *i2c_pnx = alg_data->i2c_pnx; |
671 | struct i2c_pnx_algo_data *alg_data = adap->algo_data; | 695 | |
672 | 696 | free_irq(i2c_pnx->irq, alg_data); | |
673 | free_irq(alg_data->irq, i2c_pnx->adapter); | 697 | i2c_del_adapter(&alg_data->adapter); |
674 | i2c_del_adapter(adap); | 698 | clk_disable(alg_data->clk); |
675 | i2c_pnx->set_clock_stop(pdev); | 699 | iounmap(alg_data->ioaddr); |
676 | iounmap((void *)alg_data->ioaddr); | 700 | release_mem_region(i2c_pnx->base, I2C_PNX_REGION_SIZE); |
677 | release_mem_region(alg_data->base, I2C_PNX_REGION_SIZE); | 701 | clk_put(alg_data->clk); |
702 | kfree(alg_data); | ||
678 | platform_set_drvdata(pdev, NULL); | 703 | platform_set_drvdata(pdev, NULL); |
679 | 704 | ||
680 | return 0; | 705 | return 0; |