diff options
author | Dirk Brandewie <dirk.brandewie@gmail.com> | 2011-10-29 05:57:23 -0400 |
---|---|---|
committer | Ben Dooks <ben-linux@fluff.org> | 2011-10-29 06:03:39 -0400 |
commit | 2373f6b9744d5373b886f3ce1a985193cca0a356 (patch) | |
tree | 1d3e76da9c3c0bdac1be935742210ebd5e77719d /drivers/i2c/busses/i2c-designware-core.c | |
parent | 4a423a8c8107b983007199c76c8327cd1747f092 (diff) |
i2c-designware: split of i2c-designware.c into core and bus specific parts
This patch splits i2c-designware.c into three pieces:
i2c-designware-core.c, contains the code that interacts directly
with the core.
i2c-designware-platdrv.c, contains the code specific to the
platform driver using the core.
i2c-designware-core.h contains the definitions and declareations
shared by i2c-designware-core.c and i2c-designware-platdrv.c.
This patch is the first in a set to allow multiple instances of the
designware I2C core in the system.
Signed-off-by: Dirk Brandewie <dirk.brandewie@gmail.com>
Signed-off-by: Ben Dooks <ben-linux@fluff.org>
Diffstat (limited to 'drivers/i2c/busses/i2c-designware-core.c')
-rw-r--r-- | drivers/i2c/busses/i2c-designware-core.c | 562 |
1 files changed, 562 insertions, 0 deletions
diff --git a/drivers/i2c/busses/i2c-designware-core.c b/drivers/i2c/busses/i2c-designware-core.c new file mode 100644 index 00000000000..38d5a6b22a8 --- /dev/null +++ b/drivers/i2c/busses/i2c-designware-core.c | |||
@@ -0,0 +1,562 @@ | |||
1 | /* | ||
2 | * Synopsys DesignWare I2C adapter driver (master only). | ||
3 | * | ||
4 | * Based on the TI DAVINCI I2C adapter driver. | ||
5 | * | ||
6 | * Copyright (C) 2006 Texas Instruments. | ||
7 | * Copyright (C) 2007 MontaVista Software Inc. | ||
8 | * Copyright (C) 2009 Provigent Ltd. | ||
9 | * | ||
10 | * ---------------------------------------------------------------------------- | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or modify | ||
13 | * it under the terms of the GNU General Public License as published by | ||
14 | * the Free Software Foundation; either version 2 of the License, or | ||
15 | * (at your option) any later version. | ||
16 | * | ||
17 | * This program is distributed in the hope that it will be useful, | ||
18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
20 | * GNU General Public License for more details. | ||
21 | * | ||
22 | * You should have received a copy of the GNU General Public License | ||
23 | * along with this program; if not, write to the Free Software | ||
24 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
25 | * ---------------------------------------------------------------------------- | ||
26 | * | ||
27 | */ | ||
28 | #include <linux/clk.h> | ||
29 | #include <linux/errno.h> | ||
30 | #include <linux/err.h> | ||
31 | #include <linux/i2c.h> | ||
32 | #include <linux/interrupt.h> | ||
33 | #include <linux/io.h> | ||
34 | #include <linux/delay.h> | ||
35 | #include "i2c-designware-core.h" | ||
36 | |||
37 | static char *abort_sources[] = { | ||
38 | [ABRT_7B_ADDR_NOACK] = | ||
39 | "slave address not acknowledged (7bit mode)", | ||
40 | [ABRT_10ADDR1_NOACK] = | ||
41 | "first address byte not acknowledged (10bit mode)", | ||
42 | [ABRT_10ADDR2_NOACK] = | ||
43 | "second address byte not acknowledged (10bit mode)", | ||
44 | [ABRT_TXDATA_NOACK] = | ||
45 | "data not acknowledged", | ||
46 | [ABRT_GCALL_NOACK] = | ||
47 | "no acknowledgement for a general call", | ||
48 | [ABRT_GCALL_READ] = | ||
49 | "read after general call", | ||
50 | [ABRT_SBYTE_ACKDET] = | ||
51 | "start byte acknowledged", | ||
52 | [ABRT_SBYTE_NORSTRT] = | ||
53 | "trying to send start byte when restart is disabled", | ||
54 | [ABRT_10B_RD_NORSTRT] = | ||
55 | "trying to read when restart is disabled (10bit mode)", | ||
56 | [ABRT_MASTER_DIS] = | ||
57 | "trying to use disabled adapter", | ||
58 | [ARB_LOST] = | ||
59 | "lost arbitration", | ||
60 | }; | ||
61 | |||
62 | u32 dw_readl(struct dw_i2c_dev *dev, int offset) | ||
63 | { | ||
64 | u32 value = readl(dev->base + offset); | ||
65 | |||
66 | if (dev->swab) | ||
67 | return swab32(value); | ||
68 | else | ||
69 | return value; | ||
70 | } | ||
71 | |||
72 | void dw_writel(struct dw_i2c_dev *dev, u32 b, int offset) | ||
73 | { | ||
74 | if (dev->swab) | ||
75 | b = swab32(b); | ||
76 | |||
77 | writel(b, dev->base + offset); | ||
78 | } | ||
79 | |||
80 | static u32 | ||
81 | i2c_dw_scl_hcnt(u32 ic_clk, u32 tSYMBOL, u32 tf, int cond, int offset) | ||
82 | { | ||
83 | /* | ||
84 | * DesignWare I2C core doesn't seem to have solid strategy to meet | ||
85 | * the tHD;STA timing spec. Configuring _HCNT based on tHIGH spec | ||
86 | * will result in violation of the tHD;STA spec. | ||
87 | */ | ||
88 | if (cond) | ||
89 | /* | ||
90 | * Conditional expression: | ||
91 | * | ||
92 | * IC_[FS]S_SCL_HCNT + (1+4+3) >= IC_CLK * tHIGH | ||
93 | * | ||
94 | * This is based on the DW manuals, and represents an ideal | ||
95 | * configuration. The resulting I2C bus speed will be | ||
96 | * faster than any of the others. | ||
97 | * | ||
98 | * If your hardware is free from tHD;STA issue, try this one. | ||
99 | */ | ||
100 | return (ic_clk * tSYMBOL + 5000) / 10000 - 8 + offset; | ||
101 | else | ||
102 | /* | ||
103 | * Conditional expression: | ||
104 | * | ||
105 | * IC_[FS]S_SCL_HCNT + 3 >= IC_CLK * (tHD;STA + tf) | ||
106 | * | ||
107 | * This is just experimental rule; the tHD;STA period turned | ||
108 | * out to be proportinal to (_HCNT + 3). With this setting, | ||
109 | * we could meet both tHIGH and tHD;STA timing specs. | ||
110 | * | ||
111 | * If unsure, you'd better to take this alternative. | ||
112 | * | ||
113 | * The reason why we need to take into account "tf" here, | ||
114 | * is the same as described in i2c_dw_scl_lcnt(). | ||
115 | */ | ||
116 | return (ic_clk * (tSYMBOL + tf) + 5000) / 10000 - 3 + offset; | ||
117 | } | ||
118 | |||
119 | static u32 i2c_dw_scl_lcnt(u32 ic_clk, u32 tLOW, u32 tf, int offset) | ||
120 | { | ||
121 | /* | ||
122 | * Conditional expression: | ||
123 | * | ||
124 | * IC_[FS]S_SCL_LCNT + 1 >= IC_CLK * (tLOW + tf) | ||
125 | * | ||
126 | * DW I2C core starts counting the SCL CNTs for the LOW period | ||
127 | * of the SCL clock (tLOW) as soon as it pulls the SCL line. | ||
128 | * In order to meet the tLOW timing spec, we need to take into | ||
129 | * account the fall time of SCL signal (tf). Default tf value | ||
130 | * should be 0.3 us, for safety. | ||
131 | */ | ||
132 | return ((ic_clk * (tLOW + tf) + 5000) / 10000) - 1 + offset; | ||
133 | } | ||
134 | |||
135 | /** | ||
136 | * i2c_dw_init() - initialize the designware i2c master hardware | ||
137 | * @dev: device private data | ||
138 | * | ||
139 | * This functions configures and enables the I2C master. | ||
140 | * This function is called during I2C init function, and in case of timeout at | ||
141 | * run time. | ||
142 | */ | ||
143 | int i2c_dw_init(struct dw_i2c_dev *dev) | ||
144 | { | ||
145 | u32 input_clock_khz = clk_get_rate(dev->clk) / 1000; | ||
146 | u32 ic_con, hcnt, lcnt; | ||
147 | u32 reg; | ||
148 | |||
149 | /* Configure register endianess access */ | ||
150 | reg = dw_readl(dev, DW_IC_COMP_TYPE); | ||
151 | if (reg == ___constant_swab32(DW_IC_COMP_TYPE_VALUE)) { | ||
152 | dev->swab = 1; | ||
153 | reg = DW_IC_COMP_TYPE_VALUE; | ||
154 | } | ||
155 | |||
156 | if (reg != DW_IC_COMP_TYPE_VALUE) { | ||
157 | dev_err(dev->dev, "Unknown Synopsys component type: " | ||
158 | "0x%08x\n", reg); | ||
159 | return -ENODEV; | ||
160 | } | ||
161 | |||
162 | /* Disable the adapter */ | ||
163 | dw_writel(dev, 0, DW_IC_ENABLE); | ||
164 | |||
165 | /* set standard and fast speed deviders for high/low periods */ | ||
166 | |||
167 | /* Standard-mode */ | ||
168 | hcnt = i2c_dw_scl_hcnt(input_clock_khz, | ||
169 | 40, /* tHD;STA = tHIGH = 4.0 us */ | ||
170 | 3, /* tf = 0.3 us */ | ||
171 | 0, /* 0: DW default, 1: Ideal */ | ||
172 | 0); /* No offset */ | ||
173 | lcnt = i2c_dw_scl_lcnt(input_clock_khz, | ||
174 | 47, /* tLOW = 4.7 us */ | ||
175 | 3, /* tf = 0.3 us */ | ||
176 | 0); /* No offset */ | ||
177 | dw_writel(dev, hcnt, DW_IC_SS_SCL_HCNT); | ||
178 | dw_writel(dev, lcnt, DW_IC_SS_SCL_LCNT); | ||
179 | dev_dbg(dev->dev, "Standard-mode HCNT:LCNT = %d:%d\n", hcnt, lcnt); | ||
180 | |||
181 | /* Fast-mode */ | ||
182 | hcnt = i2c_dw_scl_hcnt(input_clock_khz, | ||
183 | 6, /* tHD;STA = tHIGH = 0.6 us */ | ||
184 | 3, /* tf = 0.3 us */ | ||
185 | 0, /* 0: DW default, 1: Ideal */ | ||
186 | 0); /* No offset */ | ||
187 | lcnt = i2c_dw_scl_lcnt(input_clock_khz, | ||
188 | 13, /* tLOW = 1.3 us */ | ||
189 | 3, /* tf = 0.3 us */ | ||
190 | 0); /* No offset */ | ||
191 | dw_writel(dev, hcnt, DW_IC_FS_SCL_HCNT); | ||
192 | dw_writel(dev, lcnt, DW_IC_FS_SCL_LCNT); | ||
193 | dev_dbg(dev->dev, "Fast-mode HCNT:LCNT = %d:%d\n", hcnt, lcnt); | ||
194 | |||
195 | /* Configure Tx/Rx FIFO threshold levels */ | ||
196 | dw_writel(dev, dev->tx_fifo_depth - 1, DW_IC_TX_TL); | ||
197 | dw_writel(dev, 0, DW_IC_RX_TL); | ||
198 | |||
199 | /* configure the i2c master */ | ||
200 | ic_con = DW_IC_CON_MASTER | DW_IC_CON_SLAVE_DISABLE | | ||
201 | DW_IC_CON_RESTART_EN | DW_IC_CON_SPEED_FAST; | ||
202 | dw_writel(dev, ic_con, DW_IC_CON); | ||
203 | return 0; | ||
204 | } | ||
205 | |||
206 | /* | ||
207 | * Waiting for bus not busy | ||
208 | */ | ||
209 | static int i2c_dw_wait_bus_not_busy(struct dw_i2c_dev *dev) | ||
210 | { | ||
211 | int timeout = TIMEOUT; | ||
212 | |||
213 | while (dw_readl(dev, DW_IC_STATUS) & DW_IC_STATUS_ACTIVITY) { | ||
214 | if (timeout <= 0) { | ||
215 | dev_warn(dev->dev, "timeout waiting for bus ready\n"); | ||
216 | return -ETIMEDOUT; | ||
217 | } | ||
218 | timeout--; | ||
219 | mdelay(1); | ||
220 | } | ||
221 | |||
222 | return 0; | ||
223 | } | ||
224 | |||
225 | static void i2c_dw_xfer_init(struct dw_i2c_dev *dev) | ||
226 | { | ||
227 | struct i2c_msg *msgs = dev->msgs; | ||
228 | u32 ic_con; | ||
229 | |||
230 | /* Disable the adapter */ | ||
231 | dw_writel(dev, 0, DW_IC_ENABLE); | ||
232 | |||
233 | /* set the slave (target) address */ | ||
234 | dw_writel(dev, msgs[dev->msg_write_idx].addr, DW_IC_TAR); | ||
235 | |||
236 | /* if the slave address is ten bit address, enable 10BITADDR */ | ||
237 | ic_con = dw_readl(dev, DW_IC_CON); | ||
238 | if (msgs[dev->msg_write_idx].flags & I2C_M_TEN) | ||
239 | ic_con |= DW_IC_CON_10BITADDR_MASTER; | ||
240 | else | ||
241 | ic_con &= ~DW_IC_CON_10BITADDR_MASTER; | ||
242 | dw_writel(dev, ic_con, DW_IC_CON); | ||
243 | |||
244 | /* Enable the adapter */ | ||
245 | dw_writel(dev, 1, DW_IC_ENABLE); | ||
246 | |||
247 | /* Enable interrupts */ | ||
248 | dw_writel(dev, DW_IC_INTR_DEFAULT_MASK, DW_IC_INTR_MASK); | ||
249 | } | ||
250 | |||
251 | /* | ||
252 | * Initiate (and continue) low level master read/write transaction. | ||
253 | * This function is only called from i2c_dw_isr, and pumping i2c_msg | ||
254 | * messages into the tx buffer. Even if the size of i2c_msg data is | ||
255 | * longer than the size of the tx buffer, it handles everything. | ||
256 | */ | ||
257 | void | ||
258 | i2c_dw_xfer_msg(struct dw_i2c_dev *dev) | ||
259 | { | ||
260 | struct i2c_msg *msgs = dev->msgs; | ||
261 | u32 intr_mask; | ||
262 | int tx_limit, rx_limit; | ||
263 | u32 addr = msgs[dev->msg_write_idx].addr; | ||
264 | u32 buf_len = dev->tx_buf_len; | ||
265 | u8 *buf = dev->tx_buf; | ||
266 | |||
267 | intr_mask = DW_IC_INTR_DEFAULT_MASK; | ||
268 | |||
269 | for (; dev->msg_write_idx < dev->msgs_num; dev->msg_write_idx++) { | ||
270 | /* | ||
271 | * if target address has changed, we need to | ||
272 | * reprogram the target address in the i2c | ||
273 | * adapter when we are done with this transfer | ||
274 | */ | ||
275 | if (msgs[dev->msg_write_idx].addr != addr) { | ||
276 | dev_err(dev->dev, | ||
277 | "%s: invalid target address\n", __func__); | ||
278 | dev->msg_err = -EINVAL; | ||
279 | break; | ||
280 | } | ||
281 | |||
282 | if (msgs[dev->msg_write_idx].len == 0) { | ||
283 | dev_err(dev->dev, | ||
284 | "%s: invalid message length\n", __func__); | ||
285 | dev->msg_err = -EINVAL; | ||
286 | break; | ||
287 | } | ||
288 | |||
289 | if (!(dev->status & STATUS_WRITE_IN_PROGRESS)) { | ||
290 | /* new i2c_msg */ | ||
291 | buf = msgs[dev->msg_write_idx].buf; | ||
292 | buf_len = msgs[dev->msg_write_idx].len; | ||
293 | } | ||
294 | |||
295 | tx_limit = dev->tx_fifo_depth - dw_readl(dev, DW_IC_TXFLR); | ||
296 | rx_limit = dev->rx_fifo_depth - dw_readl(dev, DW_IC_RXFLR); | ||
297 | |||
298 | while (buf_len > 0 && tx_limit > 0 && rx_limit > 0) { | ||
299 | if (msgs[dev->msg_write_idx].flags & I2C_M_RD) { | ||
300 | dw_writel(dev, 0x100, DW_IC_DATA_CMD); | ||
301 | rx_limit--; | ||
302 | } else | ||
303 | dw_writel(dev, *buf++, DW_IC_DATA_CMD); | ||
304 | tx_limit--; buf_len--; | ||
305 | } | ||
306 | |||
307 | dev->tx_buf = buf; | ||
308 | dev->tx_buf_len = buf_len; | ||
309 | |||
310 | if (buf_len > 0) { | ||
311 | /* more bytes to be written */ | ||
312 | dev->status |= STATUS_WRITE_IN_PROGRESS; | ||
313 | break; | ||
314 | } else | ||
315 | dev->status &= ~STATUS_WRITE_IN_PROGRESS; | ||
316 | } | ||
317 | |||
318 | /* | ||
319 | * If i2c_msg index search is completed, we don't need TX_EMPTY | ||
320 | * interrupt any more. | ||
321 | */ | ||
322 | if (dev->msg_write_idx == dev->msgs_num) | ||
323 | intr_mask &= ~DW_IC_INTR_TX_EMPTY; | ||
324 | |||
325 | if (dev->msg_err) | ||
326 | intr_mask = 0; | ||
327 | |||
328 | dw_writel(dev, intr_mask, DW_IC_INTR_MASK); | ||
329 | } | ||
330 | |||
331 | static void | ||
332 | i2c_dw_read(struct dw_i2c_dev *dev) | ||
333 | { | ||
334 | struct i2c_msg *msgs = dev->msgs; | ||
335 | int rx_valid; | ||
336 | |||
337 | for (; dev->msg_read_idx < dev->msgs_num; dev->msg_read_idx++) { | ||
338 | u32 len; | ||
339 | u8 *buf; | ||
340 | |||
341 | if (!(msgs[dev->msg_read_idx].flags & I2C_M_RD)) | ||
342 | continue; | ||
343 | |||
344 | if (!(dev->status & STATUS_READ_IN_PROGRESS)) { | ||
345 | len = msgs[dev->msg_read_idx].len; | ||
346 | buf = msgs[dev->msg_read_idx].buf; | ||
347 | } else { | ||
348 | len = dev->rx_buf_len; | ||
349 | buf = dev->rx_buf; | ||
350 | } | ||
351 | |||
352 | rx_valid = dw_readl(dev, DW_IC_RXFLR); | ||
353 | |||
354 | for (; len > 0 && rx_valid > 0; len--, rx_valid--) | ||
355 | *buf++ = dw_readl(dev, DW_IC_DATA_CMD); | ||
356 | |||
357 | if (len > 0) { | ||
358 | dev->status |= STATUS_READ_IN_PROGRESS; | ||
359 | dev->rx_buf_len = len; | ||
360 | dev->rx_buf = buf; | ||
361 | return; | ||
362 | } else | ||
363 | dev->status &= ~STATUS_READ_IN_PROGRESS; | ||
364 | } | ||
365 | } | ||
366 | |||
367 | static int i2c_dw_handle_tx_abort(struct dw_i2c_dev *dev) | ||
368 | { | ||
369 | unsigned long abort_source = dev->abort_source; | ||
370 | int i; | ||
371 | |||
372 | if (abort_source & DW_IC_TX_ABRT_NOACK) { | ||
373 | for_each_set_bit(i, &abort_source, ARRAY_SIZE(abort_sources)) | ||
374 | dev_dbg(dev->dev, | ||
375 | "%s: %s\n", __func__, abort_sources[i]); | ||
376 | return -EREMOTEIO; | ||
377 | } | ||
378 | |||
379 | for_each_set_bit(i, &abort_source, ARRAY_SIZE(abort_sources)) | ||
380 | dev_err(dev->dev, "%s: %s\n", __func__, abort_sources[i]); | ||
381 | |||
382 | if (abort_source & DW_IC_TX_ARB_LOST) | ||
383 | return -EAGAIN; | ||
384 | else if (abort_source & DW_IC_TX_ABRT_GCALL_READ) | ||
385 | return -EINVAL; /* wrong msgs[] data */ | ||
386 | else | ||
387 | return -EIO; | ||
388 | } | ||
389 | |||
390 | /* | ||
391 | * Prepare controller for a transaction and call i2c_dw_xfer_msg | ||
392 | */ | ||
393 | int | ||
394 | i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) | ||
395 | { | ||
396 | struct dw_i2c_dev *dev = i2c_get_adapdata(adap); | ||
397 | int ret; | ||
398 | |||
399 | dev_dbg(dev->dev, "%s: msgs: %d\n", __func__, num); | ||
400 | |||
401 | mutex_lock(&dev->lock); | ||
402 | |||
403 | INIT_COMPLETION(dev->cmd_complete); | ||
404 | dev->msgs = msgs; | ||
405 | dev->msgs_num = num; | ||
406 | dev->cmd_err = 0; | ||
407 | dev->msg_write_idx = 0; | ||
408 | dev->msg_read_idx = 0; | ||
409 | dev->msg_err = 0; | ||
410 | dev->status = STATUS_IDLE; | ||
411 | dev->abort_source = 0; | ||
412 | |||
413 | ret = i2c_dw_wait_bus_not_busy(dev); | ||
414 | if (ret < 0) | ||
415 | goto done; | ||
416 | |||
417 | /* start the transfers */ | ||
418 | i2c_dw_xfer_init(dev); | ||
419 | |||
420 | /* wait for tx to complete */ | ||
421 | ret = wait_for_completion_interruptible_timeout(&dev->cmd_complete, HZ); | ||
422 | if (ret == 0) { | ||
423 | dev_err(dev->dev, "controller timed out\n"); | ||
424 | i2c_dw_init(dev); | ||
425 | ret = -ETIMEDOUT; | ||
426 | goto done; | ||
427 | } else if (ret < 0) | ||
428 | goto done; | ||
429 | |||
430 | if (dev->msg_err) { | ||
431 | ret = dev->msg_err; | ||
432 | goto done; | ||
433 | } | ||
434 | |||
435 | /* no error */ | ||
436 | if (likely(!dev->cmd_err)) { | ||
437 | /* Disable the adapter */ | ||
438 | dw_writel(dev, 0, DW_IC_ENABLE); | ||
439 | ret = num; | ||
440 | goto done; | ||
441 | } | ||
442 | |||
443 | /* We have an error */ | ||
444 | if (dev->cmd_err == DW_IC_ERR_TX_ABRT) { | ||
445 | ret = i2c_dw_handle_tx_abort(dev); | ||
446 | goto done; | ||
447 | } | ||
448 | ret = -EIO; | ||
449 | |||
450 | done: | ||
451 | mutex_unlock(&dev->lock); | ||
452 | |||
453 | return ret; | ||
454 | } | ||
455 | |||
456 | u32 i2c_dw_func(struct i2c_adapter *adap) | ||
457 | { | ||
458 | return I2C_FUNC_I2C | | ||
459 | I2C_FUNC_10BIT_ADDR | | ||
460 | I2C_FUNC_SMBUS_BYTE | | ||
461 | I2C_FUNC_SMBUS_BYTE_DATA | | ||
462 | I2C_FUNC_SMBUS_WORD_DATA | | ||
463 | I2C_FUNC_SMBUS_I2C_BLOCK; | ||
464 | } | ||
465 | |||
466 | static u32 i2c_dw_read_clear_intrbits(struct dw_i2c_dev *dev) | ||
467 | { | ||
468 | u32 stat; | ||
469 | |||
470 | /* | ||
471 | * The IC_INTR_STAT register just indicates "enabled" interrupts. | ||
472 | * Ths unmasked raw version of interrupt status bits are available | ||
473 | * in the IC_RAW_INTR_STAT register. | ||
474 | * | ||
475 | * That is, | ||
476 | * stat = dw_readl(IC_INTR_STAT); | ||
477 | * equals to, | ||
478 | * stat = dw_readl(IC_RAW_INTR_STAT) & dw_readl(IC_INTR_MASK); | ||
479 | * | ||
480 | * The raw version might be useful for debugging purposes. | ||
481 | */ | ||
482 | stat = dw_readl(dev, DW_IC_INTR_STAT); | ||
483 | |||
484 | /* | ||
485 | * Do not use the IC_CLR_INTR register to clear interrupts, or | ||
486 | * you'll miss some interrupts, triggered during the period from | ||
487 | * dw_readl(IC_INTR_STAT) to dw_readl(IC_CLR_INTR). | ||
488 | * | ||
489 | * Instead, use the separately-prepared IC_CLR_* registers. | ||
490 | */ | ||
491 | if (stat & DW_IC_INTR_RX_UNDER) | ||
492 | dw_readl(dev, DW_IC_CLR_RX_UNDER); | ||
493 | if (stat & DW_IC_INTR_RX_OVER) | ||
494 | dw_readl(dev, DW_IC_CLR_RX_OVER); | ||
495 | if (stat & DW_IC_INTR_TX_OVER) | ||
496 | dw_readl(dev, DW_IC_CLR_TX_OVER); | ||
497 | if (stat & DW_IC_INTR_RD_REQ) | ||
498 | dw_readl(dev, DW_IC_CLR_RD_REQ); | ||
499 | if (stat & DW_IC_INTR_TX_ABRT) { | ||
500 | /* | ||
501 | * The IC_TX_ABRT_SOURCE register is cleared whenever | ||
502 | * the IC_CLR_TX_ABRT is read. Preserve it beforehand. | ||
503 | */ | ||
504 | dev->abort_source = dw_readl(dev, DW_IC_TX_ABRT_SOURCE); | ||
505 | dw_readl(dev, DW_IC_CLR_TX_ABRT); | ||
506 | } | ||
507 | if (stat & DW_IC_INTR_RX_DONE) | ||
508 | dw_readl(dev, DW_IC_CLR_RX_DONE); | ||
509 | if (stat & DW_IC_INTR_ACTIVITY) | ||
510 | dw_readl(dev, DW_IC_CLR_ACTIVITY); | ||
511 | if (stat & DW_IC_INTR_STOP_DET) | ||
512 | dw_readl(dev, DW_IC_CLR_STOP_DET); | ||
513 | if (stat & DW_IC_INTR_START_DET) | ||
514 | dw_readl(dev, DW_IC_CLR_START_DET); | ||
515 | if (stat & DW_IC_INTR_GEN_CALL) | ||
516 | dw_readl(dev, DW_IC_CLR_GEN_CALL); | ||
517 | |||
518 | return stat; | ||
519 | } | ||
520 | |||
521 | /* | ||
522 | * Interrupt service routine. This gets called whenever an I2C interrupt | ||
523 | * occurs. | ||
524 | */ | ||
525 | irqreturn_t i2c_dw_isr(int this_irq, void *dev_id) | ||
526 | { | ||
527 | struct dw_i2c_dev *dev = dev_id; | ||
528 | u32 stat; | ||
529 | |||
530 | stat = i2c_dw_read_clear_intrbits(dev); | ||
531 | dev_dbg(dev->dev, "%s: stat=0x%x\n", __func__, stat); | ||
532 | |||
533 | if (stat & DW_IC_INTR_TX_ABRT) { | ||
534 | dev->cmd_err |= DW_IC_ERR_TX_ABRT; | ||
535 | dev->status = STATUS_IDLE; | ||
536 | |||
537 | /* | ||
538 | * Anytime TX_ABRT is set, the contents of the tx/rx | ||
539 | * buffers are flushed. Make sure to skip them. | ||
540 | */ | ||
541 | dw_writel(dev, 0, DW_IC_INTR_MASK); | ||
542 | goto tx_aborted; | ||
543 | } | ||
544 | |||
545 | if (stat & DW_IC_INTR_RX_FULL) | ||
546 | i2c_dw_read(dev); | ||
547 | |||
548 | if (stat & DW_IC_INTR_TX_EMPTY) | ||
549 | i2c_dw_xfer_msg(dev); | ||
550 | |||
551 | /* | ||
552 | * No need to modify or disable the interrupt mask here. | ||
553 | * i2c_dw_xfer_msg() will take care of it according to | ||
554 | * the current transmit status. | ||
555 | */ | ||
556 | |||
557 | tx_aborted: | ||
558 | if ((stat & (DW_IC_INTR_TX_ABRT | DW_IC_INTR_STOP_DET)) || dev->msg_err) | ||
559 | complete(&dev->cmd_complete); | ||
560 | |||
561 | return IRQ_HANDLED; | ||
562 | } | ||