diff options
Diffstat (limited to 'drivers/i2c')
-rw-r--r-- | drivers/i2c/busses/i2c-mv64xxx.c | 193 |
1 files changed, 182 insertions, 11 deletions
diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c index 9cc361d19941..2404c4e0f35c 100644 --- a/drivers/i2c/busses/i2c-mv64xxx.c +++ b/drivers/i2c/busses/i2c-mv64xxx.c | |||
@@ -55,6 +55,32 @@ | |||
55 | #define MV64XXX_I2C_STATUS_MAST_RD_ADDR_2_NO_ACK 0xe8 | 55 | #define MV64XXX_I2C_STATUS_MAST_RD_ADDR_2_NO_ACK 0xe8 |
56 | #define MV64XXX_I2C_STATUS_NO_STATUS 0xf8 | 56 | #define MV64XXX_I2C_STATUS_NO_STATUS 0xf8 |
57 | 57 | ||
58 | /* Register defines (I2C bridge) */ | ||
59 | #define MV64XXX_I2C_REG_TX_DATA_LO 0xc0 | ||
60 | #define MV64XXX_I2C_REG_TX_DATA_HI 0xc4 | ||
61 | #define MV64XXX_I2C_REG_RX_DATA_LO 0xc8 | ||
62 | #define MV64XXX_I2C_REG_RX_DATA_HI 0xcc | ||
63 | #define MV64XXX_I2C_REG_BRIDGE_CONTROL 0xd0 | ||
64 | #define MV64XXX_I2C_REG_BRIDGE_STATUS 0xd4 | ||
65 | #define MV64XXX_I2C_REG_BRIDGE_INTR_CAUSE 0xd8 | ||
66 | #define MV64XXX_I2C_REG_BRIDGE_INTR_MASK 0xdC | ||
67 | #define MV64XXX_I2C_REG_BRIDGE_TIMING 0xe0 | ||
68 | |||
69 | /* Bridge Control values */ | ||
70 | #define MV64XXX_I2C_BRIDGE_CONTROL_WR 0x00000001 | ||
71 | #define MV64XXX_I2C_BRIDGE_CONTROL_RD 0x00000002 | ||
72 | #define MV64XXX_I2C_BRIDGE_CONTROL_ADDR_SHIFT 2 | ||
73 | #define MV64XXX_I2C_BRIDGE_CONTROL_ADDR_EXT 0x00001000 | ||
74 | #define MV64XXX_I2C_BRIDGE_CONTROL_TX_SIZE_SHIFT 13 | ||
75 | #define MV64XXX_I2C_BRIDGE_CONTROL_RX_SIZE_SHIFT 16 | ||
76 | #define MV64XXX_I2C_BRIDGE_CONTROL_ENABLE 0x00080000 | ||
77 | |||
78 | /* Bridge Status values */ | ||
79 | #define MV64XXX_I2C_BRIDGE_STATUS_ERROR 0x00000001 | ||
80 | #define MV64XXX_I2C_STATUS_OFFLOAD_ERROR 0xf0000001 | ||
81 | #define MV64XXX_I2C_STATUS_OFFLOAD_OK 0xf0000000 | ||
82 | |||
83 | |||
58 | /* Driver states */ | 84 | /* Driver states */ |
59 | enum { | 85 | enum { |
60 | MV64XXX_I2C_STATE_INVALID, | 86 | MV64XXX_I2C_STATE_INVALID, |
@@ -71,14 +97,17 @@ enum { | |||
71 | enum { | 97 | enum { |
72 | MV64XXX_I2C_ACTION_INVALID, | 98 | MV64XXX_I2C_ACTION_INVALID, |
73 | MV64XXX_I2C_ACTION_CONTINUE, | 99 | MV64XXX_I2C_ACTION_CONTINUE, |
100 | MV64XXX_I2C_ACTION_OFFLOAD_SEND_START, | ||
74 | MV64XXX_I2C_ACTION_SEND_START, | 101 | MV64XXX_I2C_ACTION_SEND_START, |
75 | MV64XXX_I2C_ACTION_SEND_RESTART, | 102 | MV64XXX_I2C_ACTION_SEND_RESTART, |
103 | MV64XXX_I2C_ACTION_OFFLOAD_RESTART, | ||
76 | MV64XXX_I2C_ACTION_SEND_ADDR_1, | 104 | MV64XXX_I2C_ACTION_SEND_ADDR_1, |
77 | MV64XXX_I2C_ACTION_SEND_ADDR_2, | 105 | MV64XXX_I2C_ACTION_SEND_ADDR_2, |
78 | MV64XXX_I2C_ACTION_SEND_DATA, | 106 | MV64XXX_I2C_ACTION_SEND_DATA, |
79 | MV64XXX_I2C_ACTION_RCV_DATA, | 107 | MV64XXX_I2C_ACTION_RCV_DATA, |
80 | MV64XXX_I2C_ACTION_RCV_DATA_STOP, | 108 | MV64XXX_I2C_ACTION_RCV_DATA_STOP, |
81 | MV64XXX_I2C_ACTION_SEND_STOP, | 109 | MV64XXX_I2C_ACTION_SEND_STOP, |
110 | MV64XXX_I2C_ACTION_OFFLOAD_SEND_STOP, | ||
82 | }; | 111 | }; |
83 | 112 | ||
84 | struct mv64xxx_i2c_regs { | 113 | struct mv64xxx_i2c_regs { |
@@ -117,6 +146,7 @@ struct mv64xxx_i2c_data { | |||
117 | spinlock_t lock; | 146 | spinlock_t lock; |
118 | struct i2c_msg *msg; | 147 | struct i2c_msg *msg; |
119 | struct i2c_adapter adapter; | 148 | struct i2c_adapter adapter; |
149 | bool offload_enabled; | ||
120 | }; | 150 | }; |
121 | 151 | ||
122 | static struct mv64xxx_i2c_regs mv64xxx_i2c_regs_mv64xxx = { | 152 | static struct mv64xxx_i2c_regs mv64xxx_i2c_regs_mv64xxx = { |
@@ -165,6 +195,77 @@ mv64xxx_i2c_prepare_for_io(struct mv64xxx_i2c_data *drv_data, | |||
165 | } | 195 | } |
166 | } | 196 | } |
167 | 197 | ||
198 | static int mv64xxx_i2c_offload_msg(struct mv64xxx_i2c_data *drv_data) | ||
199 | { | ||
200 | unsigned long data_reg_hi = 0; | ||
201 | unsigned long data_reg_lo = 0; | ||
202 | unsigned long ctrl_reg; | ||
203 | struct i2c_msg *msg = drv_data->msgs; | ||
204 | |||
205 | drv_data->msg = msg; | ||
206 | drv_data->byte_posn = 0; | ||
207 | drv_data->bytes_left = msg->len; | ||
208 | drv_data->aborting = 0; | ||
209 | drv_data->rc = 0; | ||
210 | /* Only regular transactions can be offloaded */ | ||
211 | if ((msg->flags & ~(I2C_M_TEN | I2C_M_RD)) != 0) | ||
212 | return -EINVAL; | ||
213 | |||
214 | /* Only 1-8 byte transfers can be offloaded */ | ||
215 | if (msg->len < 1 || msg->len > 8) | ||
216 | return -EINVAL; | ||
217 | |||
218 | /* Build transaction */ | ||
219 | ctrl_reg = MV64XXX_I2C_BRIDGE_CONTROL_ENABLE | | ||
220 | (msg->addr << MV64XXX_I2C_BRIDGE_CONTROL_ADDR_SHIFT); | ||
221 | |||
222 | if ((msg->flags & I2C_M_TEN) != 0) | ||
223 | ctrl_reg |= MV64XXX_I2C_BRIDGE_CONTROL_ADDR_EXT; | ||
224 | |||
225 | if ((msg->flags & I2C_M_RD) == 0) { | ||
226 | u8 local_buf[8] = { 0 }; | ||
227 | |||
228 | memcpy(local_buf, msg->buf, msg->len); | ||
229 | data_reg_lo = cpu_to_le32(*((u32 *)local_buf)); | ||
230 | data_reg_hi = cpu_to_le32(*((u32 *)(local_buf+4))); | ||
231 | |||
232 | ctrl_reg |= MV64XXX_I2C_BRIDGE_CONTROL_WR | | ||
233 | (msg->len - 1) << MV64XXX_I2C_BRIDGE_CONTROL_TX_SIZE_SHIFT; | ||
234 | |||
235 | writel_relaxed(data_reg_lo, | ||
236 | drv_data->reg_base + MV64XXX_I2C_REG_TX_DATA_LO); | ||
237 | writel_relaxed(data_reg_hi, | ||
238 | drv_data->reg_base + MV64XXX_I2C_REG_TX_DATA_HI); | ||
239 | |||
240 | } else { | ||
241 | ctrl_reg |= MV64XXX_I2C_BRIDGE_CONTROL_RD | | ||
242 | (msg->len - 1) << MV64XXX_I2C_BRIDGE_CONTROL_RX_SIZE_SHIFT; | ||
243 | } | ||
244 | |||
245 | /* Execute transaction */ | ||
246 | writel(ctrl_reg, drv_data->reg_base + MV64XXX_I2C_REG_BRIDGE_CONTROL); | ||
247 | |||
248 | return 0; | ||
249 | } | ||
250 | |||
251 | static void | ||
252 | mv64xxx_i2c_update_offload_data(struct mv64xxx_i2c_data *drv_data) | ||
253 | { | ||
254 | struct i2c_msg *msg = drv_data->msg; | ||
255 | |||
256 | if (msg->flags & I2C_M_RD) { | ||
257 | u32 data_reg_lo = readl(drv_data->reg_base + | ||
258 | MV64XXX_I2C_REG_RX_DATA_LO); | ||
259 | u32 data_reg_hi = readl(drv_data->reg_base + | ||
260 | MV64XXX_I2C_REG_RX_DATA_HI); | ||
261 | u8 local_buf[8] = { 0 }; | ||
262 | |||
263 | *((u32 *)local_buf) = le32_to_cpu(data_reg_lo); | ||
264 | *((u32 *)(local_buf+4)) = le32_to_cpu(data_reg_hi); | ||
265 | memcpy(msg->buf, local_buf, msg->len); | ||
266 | } | ||
267 | |||
268 | } | ||
168 | /* | 269 | /* |
169 | ***************************************************************************** | 270 | ***************************************************************************** |
170 | * | 271 | * |
@@ -177,6 +278,15 @@ mv64xxx_i2c_prepare_for_io(struct mv64xxx_i2c_data *drv_data, | |||
177 | static void | 278 | static void |
178 | mv64xxx_i2c_hw_init(struct mv64xxx_i2c_data *drv_data) | 279 | mv64xxx_i2c_hw_init(struct mv64xxx_i2c_data *drv_data) |
179 | { | 280 | { |
281 | if (drv_data->offload_enabled) { | ||
282 | writel(0, drv_data->reg_base + MV64XXX_I2C_REG_BRIDGE_CONTROL); | ||
283 | writel(0, drv_data->reg_base + MV64XXX_I2C_REG_BRIDGE_TIMING); | ||
284 | writel(0, drv_data->reg_base + | ||
285 | MV64XXX_I2C_REG_BRIDGE_INTR_CAUSE); | ||
286 | writel(0, drv_data->reg_base + | ||
287 | MV64XXX_I2C_REG_BRIDGE_INTR_MASK); | ||
288 | } | ||
289 | |||
180 | writel(0, drv_data->reg_base + drv_data->reg_offsets.soft_reset); | 290 | writel(0, drv_data->reg_base + drv_data->reg_offsets.soft_reset); |
181 | writel(MV64XXX_I2C_BAUD_DIV_M(drv_data->freq_m) | MV64XXX_I2C_BAUD_DIV_N(drv_data->freq_n), | 291 | writel(MV64XXX_I2C_BAUD_DIV_M(drv_data->freq_m) | MV64XXX_I2C_BAUD_DIV_N(drv_data->freq_n), |
182 | drv_data->reg_base + drv_data->reg_offsets.clock); | 292 | drv_data->reg_base + drv_data->reg_offsets.clock); |
@@ -283,6 +393,16 @@ mv64xxx_i2c_fsm(struct mv64xxx_i2c_data *drv_data, u32 status) | |||
283 | drv_data->rc = -ENXIO; | 393 | drv_data->rc = -ENXIO; |
284 | break; | 394 | break; |
285 | 395 | ||
396 | case MV64XXX_I2C_STATUS_OFFLOAD_OK: | ||
397 | if (drv_data->send_stop || drv_data->aborting) { | ||
398 | drv_data->action = MV64XXX_I2C_ACTION_OFFLOAD_SEND_STOP; | ||
399 | drv_data->state = MV64XXX_I2C_STATE_IDLE; | ||
400 | } else { | ||
401 | drv_data->action = MV64XXX_I2C_ACTION_OFFLOAD_RESTART; | ||
402 | drv_data->state = MV64XXX_I2C_STATE_WAITING_FOR_RESTART; | ||
403 | } | ||
404 | break; | ||
405 | |||
286 | default: | 406 | default: |
287 | dev_err(&drv_data->adapter.dev, | 407 | dev_err(&drv_data->adapter.dev, |
288 | "mv64xxx_i2c_fsm: Ctlr Error -- state: 0x%x, " | 408 | "mv64xxx_i2c_fsm: Ctlr Error -- state: 0x%x, " |
@@ -299,20 +419,27 @@ static void | |||
299 | mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data) | 419 | mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data) |
300 | { | 420 | { |
301 | switch(drv_data->action) { | 421 | switch(drv_data->action) { |
422 | case MV64XXX_I2C_ACTION_OFFLOAD_RESTART: | ||
423 | mv64xxx_i2c_update_offload_data(drv_data); | ||
424 | writel(0, drv_data->reg_base + MV64XXX_I2C_REG_BRIDGE_CONTROL); | ||
425 | writel(0, drv_data->reg_base + | ||
426 | MV64XXX_I2C_REG_BRIDGE_INTR_CAUSE); | ||
427 | /* FALLTHRU */ | ||
302 | case MV64XXX_I2C_ACTION_SEND_RESTART: | 428 | case MV64XXX_I2C_ACTION_SEND_RESTART: |
303 | /* We should only get here if we have further messages */ | 429 | /* We should only get here if we have further messages */ |
304 | BUG_ON(drv_data->num_msgs == 0); | 430 | BUG_ON(drv_data->num_msgs == 0); |
305 | 431 | ||
306 | drv_data->cntl_bits |= MV64XXX_I2C_REG_CONTROL_START; | ||
307 | writel(drv_data->cntl_bits, | ||
308 | drv_data->reg_base + drv_data->reg_offsets.control); | ||
309 | |||
310 | drv_data->msgs++; | 432 | drv_data->msgs++; |
311 | drv_data->num_msgs--; | 433 | drv_data->num_msgs--; |
434 | if (!(drv_data->offload_enabled && | ||
435 | mv64xxx_i2c_offload_msg(drv_data))) { | ||
436 | drv_data->cntl_bits |= MV64XXX_I2C_REG_CONTROL_START; | ||
437 | writel(drv_data->cntl_bits, | ||
438 | drv_data->reg_base + drv_data->reg_offsets.control); | ||
312 | 439 | ||
313 | /* Setup for the next message */ | 440 | /* Setup for the next message */ |
314 | mv64xxx_i2c_prepare_for_io(drv_data, drv_data->msgs); | 441 | mv64xxx_i2c_prepare_for_io(drv_data, drv_data->msgs); |
315 | 442 | } | |
316 | /* | 443 | /* |
317 | * We're never at the start of the message here, and by this | 444 | * 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. | 445 | * time it's already too late to do any protocol mangling. |
@@ -326,6 +453,12 @@ mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data) | |||
326 | drv_data->reg_base + drv_data->reg_offsets.control); | 453 | drv_data->reg_base + drv_data->reg_offsets.control); |
327 | break; | 454 | break; |
328 | 455 | ||
456 | case MV64XXX_I2C_ACTION_OFFLOAD_SEND_START: | ||
457 | if (!mv64xxx_i2c_offload_msg(drv_data)) | ||
458 | break; | ||
459 | else | ||
460 | drv_data->action = MV64XXX_I2C_ACTION_SEND_START; | ||
461 | /* FALLTHRU */ | ||
329 | case MV64XXX_I2C_ACTION_SEND_START: | 462 | case MV64XXX_I2C_ACTION_SEND_START: |
330 | writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_START, | 463 | writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_START, |
331 | drv_data->reg_base + drv_data->reg_offsets.control); | 464 | drv_data->reg_base + drv_data->reg_offsets.control); |
@@ -375,6 +508,7 @@ mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data) | |||
375 | "mv64xxx_i2c_do_action: Invalid action: %d\n", | 508 | "mv64xxx_i2c_do_action: Invalid action: %d\n", |
376 | drv_data->action); | 509 | drv_data->action); |
377 | drv_data->rc = -EIO; | 510 | drv_data->rc = -EIO; |
511 | |||
378 | /* FALLTHRU */ | 512 | /* FALLTHRU */ |
379 | case MV64XXX_I2C_ACTION_SEND_STOP: | 513 | case MV64XXX_I2C_ACTION_SEND_STOP: |
380 | drv_data->cntl_bits &= ~MV64XXX_I2C_REG_CONTROL_INTEN; | 514 | drv_data->cntl_bits &= ~MV64XXX_I2C_REG_CONTROL_INTEN; |
@@ -383,6 +517,15 @@ mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data) | |||
383 | drv_data->block = 0; | 517 | drv_data->block = 0; |
384 | wake_up(&drv_data->waitq); | 518 | wake_up(&drv_data->waitq); |
385 | break; | 519 | break; |
520 | |||
521 | case MV64XXX_I2C_ACTION_OFFLOAD_SEND_STOP: | ||
522 | mv64xxx_i2c_update_offload_data(drv_data); | ||
523 | writel(0, drv_data->reg_base + MV64XXX_I2C_REG_BRIDGE_CONTROL); | ||
524 | writel(0, drv_data->reg_base + | ||
525 | MV64XXX_I2C_REG_BRIDGE_INTR_CAUSE); | ||
526 | drv_data->block = 0; | ||
527 | wake_up(&drv_data->waitq); | ||
528 | break; | ||
386 | } | 529 | } |
387 | } | 530 | } |
388 | 531 | ||
@@ -395,6 +538,21 @@ mv64xxx_i2c_intr(int irq, void *dev_id) | |||
395 | irqreturn_t rc = IRQ_NONE; | 538 | irqreturn_t rc = IRQ_NONE; |
396 | 539 | ||
397 | spin_lock_irqsave(&drv_data->lock, flags); | 540 | spin_lock_irqsave(&drv_data->lock, flags); |
541 | |||
542 | if (drv_data->offload_enabled) { | ||
543 | while (readl(drv_data->reg_base + | ||
544 | MV64XXX_I2C_REG_BRIDGE_INTR_CAUSE)) { | ||
545 | int reg_status = readl(drv_data->reg_base + | ||
546 | MV64XXX_I2C_REG_BRIDGE_STATUS); | ||
547 | if (reg_status & MV64XXX_I2C_BRIDGE_STATUS_ERROR) | ||
548 | status = MV64XXX_I2C_STATUS_OFFLOAD_ERROR; | ||
549 | else | ||
550 | status = MV64XXX_I2C_STATUS_OFFLOAD_OK; | ||
551 | mv64xxx_i2c_fsm(drv_data, status); | ||
552 | mv64xxx_i2c_do_action(drv_data); | ||
553 | rc = IRQ_HANDLED; | ||
554 | } | ||
555 | } | ||
398 | while (readl(drv_data->reg_base + drv_data->reg_offsets.control) & | 556 | while (readl(drv_data->reg_base + drv_data->reg_offsets.control) & |
399 | MV64XXX_I2C_REG_CONTROL_IFLG) { | 557 | MV64XXX_I2C_REG_CONTROL_IFLG) { |
400 | status = readl(drv_data->reg_base + drv_data->reg_offsets.status); | 558 | status = readl(drv_data->reg_base + drv_data->reg_offsets.status); |
@@ -459,11 +617,15 @@ mv64xxx_i2c_execute_msg(struct mv64xxx_i2c_data *drv_data, struct i2c_msg *msg, | |||
459 | unsigned long flags; | 617 | unsigned long flags; |
460 | 618 | ||
461 | spin_lock_irqsave(&drv_data->lock, flags); | 619 | spin_lock_irqsave(&drv_data->lock, flags); |
462 | mv64xxx_i2c_prepare_for_io(drv_data, msg); | 620 | if (drv_data->offload_enabled) { |
463 | 621 | drv_data->action = MV64XXX_I2C_ACTION_OFFLOAD_SEND_START; | |
464 | drv_data->action = MV64XXX_I2C_ACTION_SEND_START; | 622 | drv_data->state = MV64XXX_I2C_STATE_WAITING_FOR_START_COND; |
465 | drv_data->state = MV64XXX_I2C_STATE_WAITING_FOR_START_COND; | 623 | } else { |
624 | mv64xxx_i2c_prepare_for_io(drv_data, msg); | ||
466 | 625 | ||
626 | drv_data->action = MV64XXX_I2C_ACTION_SEND_START; | ||
627 | drv_data->state = MV64XXX_I2C_STATE_WAITING_FOR_START_COND; | ||
628 | } | ||
467 | drv_data->send_stop = is_last; | 629 | drv_data->send_stop = is_last; |
468 | drv_data->block = 1; | 630 | drv_data->block = 1; |
469 | mv64xxx_i2c_do_action(drv_data); | 631 | mv64xxx_i2c_do_action(drv_data); |
@@ -521,6 +683,7 @@ static const struct i2c_algorithm mv64xxx_i2c_algo = { | |||
521 | static const struct of_device_id mv64xxx_i2c_of_match_table[] = { | 683 | static const struct of_device_id mv64xxx_i2c_of_match_table[] = { |
522 | { .compatible = "allwinner,sun4i-i2c", .data = &mv64xxx_i2c_regs_sun4i}, | 684 | { .compatible = "allwinner,sun4i-i2c", .data = &mv64xxx_i2c_regs_sun4i}, |
523 | { .compatible = "marvell,mv64xxx-i2c", .data = &mv64xxx_i2c_regs_mv64xxx}, | 685 | { .compatible = "marvell,mv64xxx-i2c", .data = &mv64xxx_i2c_regs_mv64xxx}, |
686 | { .compatible = "marvell,mv78230-i2c", .data = &mv64xxx_i2c_regs_mv64xxx}, | ||
524 | {} | 687 | {} |
525 | }; | 688 | }; |
526 | MODULE_DEVICE_TABLE(of, mv64xxx_i2c_of_match_table); | 689 | MODULE_DEVICE_TABLE(of, mv64xxx_i2c_of_match_table); |
@@ -601,6 +764,13 @@ mv64xxx_of_config(struct mv64xxx_i2c_data *drv_data, | |||
601 | 764 | ||
602 | memcpy(&drv_data->reg_offsets, device->data, sizeof(drv_data->reg_offsets)); | 765 | memcpy(&drv_data->reg_offsets, device->data, sizeof(drv_data->reg_offsets)); |
603 | 766 | ||
767 | /* | ||
768 | * For controllers embedded in new SoCs activate the | ||
769 | * Transaction Generator support. | ||
770 | */ | ||
771 | if (of_device_is_compatible(np, "marvell,mv78230-i2c")) | ||
772 | drv_data->offload_enabled = true; | ||
773 | |||
604 | out: | 774 | out: |
605 | return rc; | 775 | return rc; |
606 | #endif | 776 | #endif |
@@ -654,6 +824,7 @@ mv64xxx_i2c_probe(struct platform_device *pd) | |||
654 | drv_data->freq_n = pdata->freq_n; | 824 | drv_data->freq_n = pdata->freq_n; |
655 | drv_data->irq = platform_get_irq(pd, 0); | 825 | drv_data->irq = platform_get_irq(pd, 0); |
656 | drv_data->adapter.timeout = msecs_to_jiffies(pdata->timeout); | 826 | drv_data->adapter.timeout = msecs_to_jiffies(pdata->timeout); |
827 | drv_data->offload_enabled = false; | ||
657 | memcpy(&drv_data->reg_offsets, &mv64xxx_i2c_regs_mv64xxx, sizeof(drv_data->reg_offsets)); | 828 | memcpy(&drv_data->reg_offsets, &mv64xxx_i2c_regs_mv64xxx, sizeof(drv_data->reg_offsets)); |
658 | } else if (pd->dev.of_node) { | 829 | } else if (pd->dev.of_node) { |
659 | rc = mv64xxx_of_config(drv_data, &pd->dev); | 830 | rc = mv64xxx_of_config(drv_data, &pd->dev); |