aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c/busses/i2c-mv64xxx.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/i2c/busses/i2c-mv64xxx.c')
-rw-r--r--drivers/i2c/busses/i2c-mv64xxx.c321
1 files changed, 161 insertions, 160 deletions
diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c
index 1a3abd6a0bfc..b1f42bf40963 100644
--- a/drivers/i2c/busses/i2c-mv64xxx.c
+++ b/drivers/i2c/busses/i2c-mv64xxx.c
@@ -19,19 +19,15 @@
19#include <linux/platform_device.h> 19#include <linux/platform_device.h>
20#include <linux/io.h> 20#include <linux/io.h>
21#include <linux/of.h> 21#include <linux/of.h>
22#include <linux/of_device.h>
22#include <linux/of_irq.h> 23#include <linux/of_irq.h>
23#include <linux/of_i2c.h> 24#include <linux/of_i2c.h>
24#include <linux/clk.h> 25#include <linux/clk.h>
25#include <linux/err.h> 26#include <linux/err.h>
26 27
27/* Register defines */ 28#define MV64XXX_I2C_ADDR_ADDR(val) ((val & 0x7f) << 1)
28#define MV64XXX_I2C_REG_SLAVE_ADDR 0x00 29#define MV64XXX_I2C_BAUD_DIV_N(val) (val & 0x7)
29#define MV64XXX_I2C_REG_DATA 0x04 30#define MV64XXX_I2C_BAUD_DIV_M(val) ((val & 0xf) << 3)
30#define MV64XXX_I2C_REG_CONTROL 0x08
31#define MV64XXX_I2C_REG_STATUS 0x0c
32#define MV64XXX_I2C_REG_BAUD 0x0c
33#define MV64XXX_I2C_REG_EXT_SLAVE_ADDR 0x10
34#define MV64XXX_I2C_REG_SOFT_RESET 0x1c
35 31
36#define MV64XXX_I2C_REG_CONTROL_ACK 0x00000004 32#define MV64XXX_I2C_REG_CONTROL_ACK 0x00000004
37#define MV64XXX_I2C_REG_CONTROL_IFLG 0x00000008 33#define MV64XXX_I2C_REG_CONTROL_IFLG 0x00000008
@@ -85,15 +81,26 @@ enum {
85 MV64XXX_I2C_ACTION_SEND_STOP, 81 MV64XXX_I2C_ACTION_SEND_STOP,
86}; 82};
87 83
84struct mv64xxx_i2c_regs {
85 u8 addr;
86 u8 ext_addr;
87 u8 data;
88 u8 control;
89 u8 status;
90 u8 clock;
91 u8 soft_reset;
92};
93
88struct mv64xxx_i2c_data { 94struct mv64xxx_i2c_data {
95 struct i2c_msg *msgs;
96 int num_msgs;
89 int irq; 97 int irq;
90 u32 state; 98 u32 state;
91 u32 action; 99 u32 action;
92 u32 aborting; 100 u32 aborting;
93 u32 cntl_bits; 101 u32 cntl_bits;
94 void __iomem *reg_base; 102 void __iomem *reg_base;
95 u32 reg_base_p; 103 struct mv64xxx_i2c_regs reg_offsets;
96 u32 reg_size;
97 u32 addr1; 104 u32 addr1;
98 u32 addr2; 105 u32 addr2;
99 u32 bytes_left; 106 u32 bytes_left;
@@ -112,6 +119,52 @@ struct mv64xxx_i2c_data {
112 struct i2c_adapter adapter; 119 struct i2c_adapter adapter;
113}; 120};
114 121
122static struct mv64xxx_i2c_regs mv64xxx_i2c_regs_mv64xxx = {
123 .addr = 0x00,
124 .ext_addr = 0x10,
125 .data = 0x04,
126 .control = 0x08,
127 .status = 0x0c,
128 .clock = 0x0c,
129 .soft_reset = 0x1c,
130};
131
132static struct mv64xxx_i2c_regs mv64xxx_i2c_regs_sun4i = {
133 .addr = 0x00,
134 .ext_addr = 0x04,
135 .data = 0x08,
136 .control = 0x0c,
137 .status = 0x10,
138 .clock = 0x14,
139 .soft_reset = 0x18,
140};
141
142static void
143mv64xxx_i2c_prepare_for_io(struct mv64xxx_i2c_data *drv_data,
144 struct i2c_msg *msg)
145{
146 u32 dir = 0;
147
148 drv_data->msg = msg;
149 drv_data->byte_posn = 0;
150 drv_data->bytes_left = msg->len;
151 drv_data->aborting = 0;
152 drv_data->rc = 0;
153 drv_data->cntl_bits = MV64XXX_I2C_REG_CONTROL_ACK |
154 MV64XXX_I2C_REG_CONTROL_INTEN | MV64XXX_I2C_REG_CONTROL_TWSIEN;
155
156 if (msg->flags & I2C_M_RD)
157 dir = 1;
158
159 if (msg->flags & I2C_M_TEN) {
160 drv_data->addr1 = 0xf0 | (((u32)msg->addr & 0x300) >> 7) | dir;
161 drv_data->addr2 = (u32)msg->addr & 0xff;
162 } else {
163 drv_data->addr1 = MV64XXX_I2C_ADDR_ADDR((u32)msg->addr) | dir;
164 drv_data->addr2 = 0;
165 }
166}
167
115/* 168/*
116 ***************************************************************************** 169 *****************************************************************************
117 * 170 *
@@ -124,13 +177,13 @@ struct mv64xxx_i2c_data {
124static void 177static void
125mv64xxx_i2c_hw_init(struct mv64xxx_i2c_data *drv_data) 178mv64xxx_i2c_hw_init(struct mv64xxx_i2c_data *drv_data)
126{ 179{
127 writel(0, drv_data->reg_base + MV64XXX_I2C_REG_SOFT_RESET); 180 writel(0, drv_data->reg_base + drv_data->reg_offsets.soft_reset);
128 writel((((drv_data->freq_m & 0xf) << 3) | (drv_data->freq_n & 0x7)), 181 writel(MV64XXX_I2C_BAUD_DIV_M(drv_data->freq_m) | MV64XXX_I2C_BAUD_DIV_N(drv_data->freq_n),
129 drv_data->reg_base + MV64XXX_I2C_REG_BAUD); 182 drv_data->reg_base + drv_data->reg_offsets.clock);
130 writel(0, drv_data->reg_base + MV64XXX_I2C_REG_SLAVE_ADDR); 183 writel(0, drv_data->reg_base + drv_data->reg_offsets.addr);
131 writel(0, drv_data->reg_base + MV64XXX_I2C_REG_EXT_SLAVE_ADDR); 184 writel(0, drv_data->reg_base + drv_data->reg_offsets.ext_addr);
132 writel(MV64XXX_I2C_REG_CONTROL_TWSIEN | MV64XXX_I2C_REG_CONTROL_STOP, 185 writel(MV64XXX_I2C_REG_CONTROL_TWSIEN | MV64XXX_I2C_REG_CONTROL_STOP,
133 drv_data->reg_base + MV64XXX_I2C_REG_CONTROL); 186 drv_data->reg_base + drv_data->reg_offsets.control);
134 drv_data->state = MV64XXX_I2C_STATE_IDLE; 187 drv_data->state = MV64XXX_I2C_STATE_IDLE;
135} 188}
136 189
@@ -170,7 +223,7 @@ mv64xxx_i2c_fsm(struct mv64xxx_i2c_data *drv_data, u32 status)
170 if ((drv_data->bytes_left == 0) 223 if ((drv_data->bytes_left == 0)
171 || (drv_data->aborting 224 || (drv_data->aborting
172 && (drv_data->byte_posn != 0))) { 225 && (drv_data->byte_posn != 0))) {
173 if (drv_data->send_stop) { 226 if (drv_data->send_stop || drv_data->aborting) {
174 drv_data->action = MV64XXX_I2C_ACTION_SEND_STOP; 227 drv_data->action = MV64XXX_I2C_ACTION_SEND_STOP;
175 drv_data->state = MV64XXX_I2C_STATE_IDLE; 228 drv_data->state = MV64XXX_I2C_STATE_IDLE;
176 } else { 229 } else {
@@ -227,7 +280,7 @@ mv64xxx_i2c_fsm(struct mv64xxx_i2c_data *drv_data, u32 status)
227 /* Doesn't seem to be a device at other end */ 280 /* Doesn't seem to be a device at other end */
228 drv_data->action = MV64XXX_I2C_ACTION_SEND_STOP; 281 drv_data->action = MV64XXX_I2C_ACTION_SEND_STOP;
229 drv_data->state = MV64XXX_I2C_STATE_IDLE; 282 drv_data->state = MV64XXX_I2C_STATE_IDLE;
230 drv_data->rc = -ENODEV; 283 drv_data->rc = -ENXIO;
231 break; 284 break;
232 285
233 default: 286 default:
@@ -247,58 +300,71 @@ mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data)
247{ 300{
248 switch(drv_data->action) { 301 switch(drv_data->action) {
249 case MV64XXX_I2C_ACTION_SEND_RESTART: 302 case MV64XXX_I2C_ACTION_SEND_RESTART:
303 /* We should only get here if we have further messages */
304 BUG_ON(drv_data->num_msgs == 0);
305
250 drv_data->cntl_bits |= MV64XXX_I2C_REG_CONTROL_START; 306 drv_data->cntl_bits |= MV64XXX_I2C_REG_CONTROL_START;
251 drv_data->cntl_bits &= ~MV64XXX_I2C_REG_CONTROL_INTEN;
252 writel(drv_data->cntl_bits, 307 writel(drv_data->cntl_bits,
253 drv_data->reg_base + MV64XXX_I2C_REG_CONTROL); 308 drv_data->reg_base + drv_data->reg_offsets.control);
254 drv_data->block = 0; 309
255 wake_up(&drv_data->waitq); 310 drv_data->msgs++;
311 drv_data->num_msgs--;
312
313 /* Setup for the next message */
314 mv64xxx_i2c_prepare_for_io(drv_data, drv_data->msgs);
315
316 /*
317 * We're never at the start of the message here, and by this
318 * time it's already too late to do any protocol mangling.
319 * Thankfully, do not advertise support for that feature.
320 */
321 drv_data->send_stop = drv_data->num_msgs == 1;
256 break; 322 break;
257 323
258 case MV64XXX_I2C_ACTION_CONTINUE: 324 case MV64XXX_I2C_ACTION_CONTINUE:
259 writel(drv_data->cntl_bits, 325 writel(drv_data->cntl_bits,
260 drv_data->reg_base + MV64XXX_I2C_REG_CONTROL); 326 drv_data->reg_base + drv_data->reg_offsets.control);
261 break; 327 break;
262 328
263 case MV64XXX_I2C_ACTION_SEND_START: 329 case MV64XXX_I2C_ACTION_SEND_START:
264 writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_START, 330 writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_START,
265 drv_data->reg_base + MV64XXX_I2C_REG_CONTROL); 331 drv_data->reg_base + drv_data->reg_offsets.control);
266 break; 332 break;
267 333
268 case MV64XXX_I2C_ACTION_SEND_ADDR_1: 334 case MV64XXX_I2C_ACTION_SEND_ADDR_1:
269 writel(drv_data->addr1, 335 writel(drv_data->addr1,
270 drv_data->reg_base + MV64XXX_I2C_REG_DATA); 336 drv_data->reg_base + drv_data->reg_offsets.data);
271 writel(drv_data->cntl_bits, 337 writel(drv_data->cntl_bits,
272 drv_data->reg_base + MV64XXX_I2C_REG_CONTROL); 338 drv_data->reg_base + drv_data->reg_offsets.control);
273 break; 339 break;
274 340
275 case MV64XXX_I2C_ACTION_SEND_ADDR_2: 341 case MV64XXX_I2C_ACTION_SEND_ADDR_2:
276 writel(drv_data->addr2, 342 writel(drv_data->addr2,
277 drv_data->reg_base + MV64XXX_I2C_REG_DATA); 343 drv_data->reg_base + drv_data->reg_offsets.data);
278 writel(drv_data->cntl_bits, 344 writel(drv_data->cntl_bits,
279 drv_data->reg_base + MV64XXX_I2C_REG_CONTROL); 345 drv_data->reg_base + drv_data->reg_offsets.control);
280 break; 346 break;
281 347
282 case MV64XXX_I2C_ACTION_SEND_DATA: 348 case MV64XXX_I2C_ACTION_SEND_DATA:
283 writel(drv_data->msg->buf[drv_data->byte_posn++], 349 writel(drv_data->msg->buf[drv_data->byte_posn++],
284 drv_data->reg_base + MV64XXX_I2C_REG_DATA); 350 drv_data->reg_base + drv_data->reg_offsets.data);
285 writel(drv_data->cntl_bits, 351 writel(drv_data->cntl_bits,
286 drv_data->reg_base + MV64XXX_I2C_REG_CONTROL); 352 drv_data->reg_base + drv_data->reg_offsets.control);
287 break; 353 break;
288 354
289 case MV64XXX_I2C_ACTION_RCV_DATA: 355 case MV64XXX_I2C_ACTION_RCV_DATA:
290 drv_data->msg->buf[drv_data->byte_posn++] = 356 drv_data->msg->buf[drv_data->byte_posn++] =
291 readl(drv_data->reg_base + MV64XXX_I2C_REG_DATA); 357 readl(drv_data->reg_base + drv_data->reg_offsets.data);
292 writel(drv_data->cntl_bits, 358 writel(drv_data->cntl_bits,
293 drv_data->reg_base + MV64XXX_I2C_REG_CONTROL); 359 drv_data->reg_base + drv_data->reg_offsets.control);
294 break; 360 break;
295 361
296 case MV64XXX_I2C_ACTION_RCV_DATA_STOP: 362 case MV64XXX_I2C_ACTION_RCV_DATA_STOP:
297 drv_data->msg->buf[drv_data->byte_posn++] = 363 drv_data->msg->buf[drv_data->byte_posn++] =
298 readl(drv_data->reg_base + MV64XXX_I2C_REG_DATA); 364 readl(drv_data->reg_base + drv_data->reg_offsets.data);
299 drv_data->cntl_bits &= ~MV64XXX_I2C_REG_CONTROL_INTEN; 365 drv_data->cntl_bits &= ~MV64XXX_I2C_REG_CONTROL_INTEN;
300 writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_STOP, 366 writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_STOP,
301 drv_data->reg_base + MV64XXX_I2C_REG_CONTROL); 367 drv_data->reg_base + drv_data->reg_offsets.control);
302 drv_data->block = 0; 368 drv_data->block = 0;
303 wake_up(&drv_data->waitq); 369 wake_up(&drv_data->waitq);
304 break; 370 break;
@@ -313,7 +379,7 @@ mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data)
313 case MV64XXX_I2C_ACTION_SEND_STOP: 379 case MV64XXX_I2C_ACTION_SEND_STOP:
314 drv_data->cntl_bits &= ~MV64XXX_I2C_REG_CONTROL_INTEN; 380 drv_data->cntl_bits &= ~MV64XXX_I2C_REG_CONTROL_INTEN;
315 writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_STOP, 381 writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_STOP,
316 drv_data->reg_base + MV64XXX_I2C_REG_CONTROL); 382 drv_data->reg_base + drv_data->reg_offsets.control);
317 drv_data->block = 0; 383 drv_data->block = 0;
318 wake_up(&drv_data->waitq); 384 wake_up(&drv_data->waitq);
319 break; 385 break;
@@ -329,9 +395,9 @@ mv64xxx_i2c_intr(int irq, void *dev_id)
329 irqreturn_t rc = IRQ_NONE; 395 irqreturn_t rc = IRQ_NONE;
330 396
331 spin_lock_irqsave(&drv_data->lock, flags); 397 spin_lock_irqsave(&drv_data->lock, flags);
332 while (readl(drv_data->reg_base + MV64XXX_I2C_REG_CONTROL) & 398 while (readl(drv_data->reg_base + drv_data->reg_offsets.control) &
333 MV64XXX_I2C_REG_CONTROL_IFLG) { 399 MV64XXX_I2C_REG_CONTROL_IFLG) {
334 status = readl(drv_data->reg_base + MV64XXX_I2C_REG_STATUS); 400 status = readl(drv_data->reg_base + drv_data->reg_offsets.status);
335 mv64xxx_i2c_fsm(drv_data, status); 401 mv64xxx_i2c_fsm(drv_data, status);
336 mv64xxx_i2c_do_action(drv_data); 402 mv64xxx_i2c_do_action(drv_data);
337 rc = IRQ_HANDLED; 403 rc = IRQ_HANDLED;
@@ -349,32 +415,6 @@ mv64xxx_i2c_intr(int irq, void *dev_id)
349 ***************************************************************************** 415 *****************************************************************************
350 */ 416 */
351static void 417static void
352mv64xxx_i2c_prepare_for_io(struct mv64xxx_i2c_data *drv_data,
353 struct i2c_msg *msg)
354{
355 u32 dir = 0;
356
357 drv_data->msg = msg;
358 drv_data->byte_posn = 0;
359 drv_data->bytes_left = msg->len;
360 drv_data->aborting = 0;
361 drv_data->rc = 0;
362 drv_data->cntl_bits = MV64XXX_I2C_REG_CONTROL_ACK |
363 MV64XXX_I2C_REG_CONTROL_INTEN | MV64XXX_I2C_REG_CONTROL_TWSIEN;
364
365 if (msg->flags & I2C_M_RD)
366 dir = 1;
367
368 if (msg->flags & I2C_M_TEN) {
369 drv_data->addr1 = 0xf0 | (((u32)msg->addr & 0x300) >> 7) | dir;
370 drv_data->addr2 = (u32)msg->addr & 0xff;
371 } else {
372 drv_data->addr1 = ((u32)msg->addr & 0x7f) << 1 | dir;
373 drv_data->addr2 = 0;
374 }
375}
376
377static void
378mv64xxx_i2c_wait_for_completion(struct mv64xxx_i2c_data *drv_data) 418mv64xxx_i2c_wait_for_completion(struct mv64xxx_i2c_data *drv_data)
379{ 419{
380 long time_left; 420 long time_left;
@@ -414,36 +454,15 @@ mv64xxx_i2c_wait_for_completion(struct mv64xxx_i2c_data *drv_data)
414 454
415static int 455static int
416mv64xxx_i2c_execute_msg(struct mv64xxx_i2c_data *drv_data, struct i2c_msg *msg, 456mv64xxx_i2c_execute_msg(struct mv64xxx_i2c_data *drv_data, struct i2c_msg *msg,
417 int is_first, int is_last) 457 int is_last)
418{ 458{
419 unsigned long flags; 459 unsigned long flags;
420 460
421 spin_lock_irqsave(&drv_data->lock, flags); 461 spin_lock_irqsave(&drv_data->lock, flags);
422 mv64xxx_i2c_prepare_for_io(drv_data, msg); 462 mv64xxx_i2c_prepare_for_io(drv_data, msg);
423 463
424 if (unlikely(msg->flags & I2C_M_NOSTART)) { /* Skip start/addr phases */ 464 drv_data->action = MV64XXX_I2C_ACTION_SEND_START;
425 if (drv_data->msg->flags & I2C_M_RD) { 465 drv_data->state = MV64XXX_I2C_STATE_WAITING_FOR_START_COND;
426 /* No action to do, wait for slave to send a byte */
427 drv_data->action = MV64XXX_I2C_ACTION_CONTINUE;
428 drv_data->state =
429 MV64XXX_I2C_STATE_WAITING_FOR_SLAVE_DATA;
430 } else {
431 drv_data->action = MV64XXX_I2C_ACTION_SEND_DATA;
432 drv_data->state =
433 MV64XXX_I2C_STATE_WAITING_FOR_SLAVE_ACK;
434 drv_data->bytes_left--;
435 }
436 } else {
437 if (is_first) {
438 drv_data->action = MV64XXX_I2C_ACTION_SEND_START;
439 drv_data->state =
440 MV64XXX_I2C_STATE_WAITING_FOR_START_COND;
441 } else {
442 drv_data->action = MV64XXX_I2C_ACTION_SEND_ADDR_1;
443 drv_data->state =
444 MV64XXX_I2C_STATE_WAITING_FOR_ADDR_1_ACK;
445 }
446 }
447 466
448 drv_data->send_stop = is_last; 467 drv_data->send_stop = is_last;
449 drv_data->block = 1; 468 drv_data->block = 1;
@@ -471,16 +490,20 @@ static int
471mv64xxx_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) 490mv64xxx_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
472{ 491{
473 struct mv64xxx_i2c_data *drv_data = i2c_get_adapdata(adap); 492 struct mv64xxx_i2c_data *drv_data = i2c_get_adapdata(adap);
474 int i, rc; 493 int rc, ret = num;
475 494
476 for (i = 0; i < num; i++) { 495 BUG_ON(drv_data->msgs != NULL);
477 rc = mv64xxx_i2c_execute_msg(drv_data, &msgs[i], 496 drv_data->msgs = msgs;
478 i == 0, i + 1 == num); 497 drv_data->num_msgs = num;
479 if (rc < 0) 498
480 return rc; 499 rc = mv64xxx_i2c_execute_msg(drv_data, &msgs[0], num == 1);
481 } 500 if (rc < 0)
501 ret = rc;
502
503 drv_data->num_msgs = 0;
504 drv_data->msgs = NULL;
482 505
483 return num; 506 return ret;
484} 507}
485 508
486static const struct i2c_algorithm mv64xxx_i2c_algo = { 509static const struct i2c_algorithm mv64xxx_i2c_algo = {
@@ -495,39 +518,12 @@ static const struct i2c_algorithm mv64xxx_i2c_algo = {
495 * 518 *
496 ***************************************************************************** 519 *****************************************************************************
497 */ 520 */
498static int 521static const struct of_device_id mv64xxx_i2c_of_match_table[] = {
499mv64xxx_i2c_map_regs(struct platform_device *pd, 522 { .compatible = "allwinner,sun4i-i2c", .data = &mv64xxx_i2c_regs_sun4i},
500 struct mv64xxx_i2c_data *drv_data) 523 { .compatible = "marvell,mv64xxx-i2c", .data = &mv64xxx_i2c_regs_mv64xxx},
501{ 524 {}
502 int size; 525};
503 struct resource *r = platform_get_resource(pd, IORESOURCE_MEM, 0); 526MODULE_DEVICE_TABLE(of, mv64xxx_i2c_of_match_table);
504
505 if (!r)
506 return -ENODEV;
507
508 size = resource_size(r);
509
510 if (!request_mem_region(r->start, size, drv_data->adapter.name))
511 return -EBUSY;
512
513 drv_data->reg_base = ioremap(r->start, size);
514 drv_data->reg_base_p = r->start;
515 drv_data->reg_size = size;
516
517 return 0;
518}
519
520static void
521mv64xxx_i2c_unmap_regs(struct mv64xxx_i2c_data *drv_data)
522{
523 if (drv_data->reg_base) {
524 iounmap(drv_data->reg_base);
525 release_mem_region(drv_data->reg_base_p, drv_data->reg_size);
526 }
527
528 drv_data->reg_base = NULL;
529 drv_data->reg_base_p = 0;
530}
531 527
532#ifdef CONFIG_OF 528#ifdef CONFIG_OF
533static int 529static int
@@ -562,8 +558,10 @@ mv64xxx_find_baud_factors(const u32 req_freq, const u32 tclk, u32 *best_n,
562 558
563static int 559static int
564mv64xxx_of_config(struct mv64xxx_i2c_data *drv_data, 560mv64xxx_of_config(struct mv64xxx_i2c_data *drv_data,
565 struct device_node *np) 561 struct device *dev)
566{ 562{
563 const struct of_device_id *device;
564 struct device_node *np = dev->of_node;
567 u32 bus_freq, tclk; 565 u32 bus_freq, tclk;
568 int rc = 0; 566 int rc = 0;
569 567
@@ -580,7 +578,11 @@ mv64xxx_of_config(struct mv64xxx_i2c_data *drv_data,
580 goto out; 578 goto out;
581 } 579 }
582 tclk = clk_get_rate(drv_data->clk); 580 tclk = clk_get_rate(drv_data->clk);
583 of_property_read_u32(np, "clock-frequency", &bus_freq); 581
582 rc = of_property_read_u32(np, "clock-frequency", &bus_freq);
583 if (rc)
584 bus_freq = 100000; /* 100kHz by default */
585
584 if (!mv64xxx_find_baud_factors(bus_freq, tclk, 586 if (!mv64xxx_find_baud_factors(bus_freq, tclk,
585 &drv_data->freq_n, &drv_data->freq_m)) { 587 &drv_data->freq_n, &drv_data->freq_m)) {
586 rc = -EINVAL; 588 rc = -EINVAL;
@@ -592,6 +594,13 @@ mv64xxx_of_config(struct mv64xxx_i2c_data *drv_data,
592 * So hard code the value to 1 second. 594 * So hard code the value to 1 second.
593 */ 595 */
594 drv_data->adapter.timeout = HZ; 596 drv_data->adapter.timeout = HZ;
597
598 device = of_match_device(mv64xxx_i2c_of_match_table, dev);
599 if (!device)
600 return -ENODEV;
601
602 memcpy(&drv_data->reg_offsets, device->data, sizeof(drv_data->reg_offsets));
603
595out: 604out:
596 return rc; 605 return rc;
597#endif 606#endif
@@ -599,7 +608,7 @@ out:
599#else /* CONFIG_OF */ 608#else /* CONFIG_OF */
600static int 609static int
601mv64xxx_of_config(struct mv64xxx_i2c_data *drv_data, 610mv64xxx_of_config(struct mv64xxx_i2c_data *drv_data,
602 struct device_node *np) 611 struct device *dev)
603{ 612{
604 return -ENODEV; 613 return -ENODEV;
605} 614}
@@ -610,19 +619,21 @@ mv64xxx_i2c_probe(struct platform_device *pd)
610{ 619{
611 struct mv64xxx_i2c_data *drv_data; 620 struct mv64xxx_i2c_data *drv_data;
612 struct mv64xxx_i2c_pdata *pdata = pd->dev.platform_data; 621 struct mv64xxx_i2c_pdata *pdata = pd->dev.platform_data;
622 struct resource *r;
613 int rc; 623 int rc;
614 624
615 if ((!pdata && !pd->dev.of_node)) 625 if ((!pdata && !pd->dev.of_node))
616 return -ENODEV; 626 return -ENODEV;
617 627
618 drv_data = kzalloc(sizeof(struct mv64xxx_i2c_data), GFP_KERNEL); 628 drv_data = devm_kzalloc(&pd->dev, sizeof(struct mv64xxx_i2c_data),
629 GFP_KERNEL);
619 if (!drv_data) 630 if (!drv_data)
620 return -ENOMEM; 631 return -ENOMEM;
621 632
622 if (mv64xxx_i2c_map_regs(pd, drv_data)) { 633 r = platform_get_resource(pd, IORESOURCE_MEM, 0);
623 rc = -ENODEV; 634 drv_data->reg_base = devm_ioremap_resource(&pd->dev, r);
624 goto exit_kfree; 635 if (IS_ERR(drv_data->reg_base))
625 } 636 return PTR_ERR(drv_data->reg_base);
626 637
627 strlcpy(drv_data->adapter.name, MV64XXX_I2C_CTLR_NAME " adapter", 638 strlcpy(drv_data->adapter.name, MV64XXX_I2C_CTLR_NAME " adapter",
628 sizeof(drv_data->adapter.name)); 639 sizeof(drv_data->adapter.name));
@@ -632,7 +643,7 @@ mv64xxx_i2c_probe(struct platform_device *pd)
632 643
633#if defined(CONFIG_HAVE_CLK) 644#if defined(CONFIG_HAVE_CLK)
634 /* Not all platforms have a clk */ 645 /* Not all platforms have a clk */
635 drv_data->clk = clk_get(&pd->dev, NULL); 646 drv_data->clk = devm_clk_get(&pd->dev, NULL);
636 if (!IS_ERR(drv_data->clk)) { 647 if (!IS_ERR(drv_data->clk)) {
637 clk_prepare(drv_data->clk); 648 clk_prepare(drv_data->clk);
638 clk_enable(drv_data->clk); 649 clk_enable(drv_data->clk);
@@ -643,14 +654,15 @@ mv64xxx_i2c_probe(struct platform_device *pd)
643 drv_data->freq_n = pdata->freq_n; 654 drv_data->freq_n = pdata->freq_n;
644 drv_data->irq = platform_get_irq(pd, 0); 655 drv_data->irq = platform_get_irq(pd, 0);
645 drv_data->adapter.timeout = msecs_to_jiffies(pdata->timeout); 656 drv_data->adapter.timeout = msecs_to_jiffies(pdata->timeout);
657 memcpy(&drv_data->reg_offsets, &mv64xxx_i2c_regs_mv64xxx, sizeof(drv_data->reg_offsets));
646 } else if (pd->dev.of_node) { 658 } else if (pd->dev.of_node) {
647 rc = mv64xxx_of_config(drv_data, pd->dev.of_node); 659 rc = mv64xxx_of_config(drv_data, &pd->dev);
648 if (rc) 660 if (rc)
649 goto exit_unmap_regs; 661 goto exit_clk;
650 } 662 }
651 if (drv_data->irq < 0) { 663 if (drv_data->irq < 0) {
652 rc = -ENXIO; 664 rc = -ENXIO;
653 goto exit_unmap_regs; 665 goto exit_clk;
654 } 666 }
655 667
656 drv_data->adapter.dev.parent = &pd->dev; 668 drv_data->adapter.dev.parent = &pd->dev;
@@ -664,13 +676,13 @@ mv64xxx_i2c_probe(struct platform_device *pd)
664 676
665 mv64xxx_i2c_hw_init(drv_data); 677 mv64xxx_i2c_hw_init(drv_data);
666 678
667 if (request_irq(drv_data->irq, mv64xxx_i2c_intr, 0, 679 rc = request_irq(drv_data->irq, mv64xxx_i2c_intr, 0,
668 MV64XXX_I2C_CTLR_NAME, drv_data)) { 680 MV64XXX_I2C_CTLR_NAME, drv_data);
681 if (rc) {
669 dev_err(&drv_data->adapter.dev, 682 dev_err(&drv_data->adapter.dev,
670 "mv64xxx: Can't register intr handler irq: %d\n", 683 "mv64xxx: Can't register intr handler irq%d: %d\n",
671 drv_data->irq); 684 drv_data->irq, rc);
672 rc = -EINVAL; 685 goto exit_clk;
673 goto exit_unmap_regs;
674 } else if ((rc = i2c_add_numbered_adapter(&drv_data->adapter)) != 0) { 686 } else if ((rc = i2c_add_numbered_adapter(&drv_data->adapter)) != 0) {
675 dev_err(&drv_data->adapter.dev, 687 dev_err(&drv_data->adapter.dev,
676 "mv64xxx: Can't add i2c adapter, rc: %d\n", -rc); 688 "mv64xxx: Can't add i2c adapter, rc: %d\n", -rc);
@@ -681,9 +693,9 @@ mv64xxx_i2c_probe(struct platform_device *pd)
681 693
682 return 0; 694 return 0;
683 695
684 exit_free_irq: 696exit_free_irq:
685 free_irq(drv_data->irq, drv_data); 697 free_irq(drv_data->irq, drv_data);
686 exit_unmap_regs: 698exit_clk:
687#if defined(CONFIG_HAVE_CLK) 699#if defined(CONFIG_HAVE_CLK)
688 /* Not all platforms have a clk */ 700 /* Not all platforms have a clk */
689 if (!IS_ERR(drv_data->clk)) { 701 if (!IS_ERR(drv_data->clk)) {
@@ -691,9 +703,6 @@ mv64xxx_i2c_probe(struct platform_device *pd)
691 clk_unprepare(drv_data->clk); 703 clk_unprepare(drv_data->clk);
692 } 704 }
693#endif 705#endif
694 mv64xxx_i2c_unmap_regs(drv_data);
695 exit_kfree:
696 kfree(drv_data);
697 return rc; 706 return rc;
698} 707}
699 708
@@ -704,7 +713,6 @@ mv64xxx_i2c_remove(struct platform_device *dev)
704 713
705 i2c_del_adapter(&drv_data->adapter); 714 i2c_del_adapter(&drv_data->adapter);
706 free_irq(drv_data->irq, drv_data); 715 free_irq(drv_data->irq, drv_data);
707 mv64xxx_i2c_unmap_regs(drv_data);
708#if defined(CONFIG_HAVE_CLK) 716#if defined(CONFIG_HAVE_CLK)
709 /* Not all platforms have a clk */ 717 /* Not all platforms have a clk */
710 if (!IS_ERR(drv_data->clk)) { 718 if (!IS_ERR(drv_data->clk)) {
@@ -712,17 +720,10 @@ mv64xxx_i2c_remove(struct platform_device *dev)
712 clk_unprepare(drv_data->clk); 720 clk_unprepare(drv_data->clk);
713 } 721 }
714#endif 722#endif
715 kfree(drv_data);
716 723
717 return 0; 724 return 0;
718} 725}
719 726
720static const struct of_device_id mv64xxx_i2c_of_match_table[] = {
721 { .compatible = "marvell,mv64xxx-i2c", },
722 {}
723};
724MODULE_DEVICE_TABLE(of, mv64xxx_i2c_of_match_table);
725
726static struct platform_driver mv64xxx_i2c_driver = { 727static struct platform_driver mv64xxx_i2c_driver = {
727 .probe = mv64xxx_i2c_probe, 728 .probe = mv64xxx_i2c_probe,
728 .remove = mv64xxx_i2c_remove, 729 .remove = mv64xxx_i2c_remove,