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