Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

i2c: pnx: add device tree support

This patch adds device tree support to the pnx-i2c driver by using platform
resources for memory region and irq and removing dependency on mach includes.

The following platforms are affected:

* PNX
* LPC31xx (WIP)
* LPC32xx

The patch is based on a patch by Jon Smirl, working on lpc31xx integration

Signed-off-by: Roland Stigge <stigge@antcom.de>
Signed-off-by: Wolfram Sang <w.sang@pengutronix.de>

authored by

Roland Stigge and committed by
Wolfram Sang
a092de11 973c5ed4

+84 -16
+36
Documentation/devicetree/bindings/i2c/pnx.txt
··· 1 + * NXP PNX I2C Controller 2 + 3 + Required properties: 4 + 5 + - reg: Offset and length of the register set for the device 6 + - compatible: should be "nxp,pnx-i2c" 7 + - interrupts: configure one interrupt line 8 + - #address-cells: always 1 (for i2c addresses) 9 + - #size-cells: always 0 10 + - interrupt-parent: the phandle for the interrupt controller that 11 + services interrupts for this device. 12 + 13 + Optional properties: 14 + 15 + - clock-frequency: desired I2C bus clock frequency in Hz, Default: 100000 Hz 16 + 17 + Examples: 18 + 19 + i2c1: i2c@400a0000 { 20 + compatible = "nxp,pnx-i2c"; 21 + reg = <0x400a0000 0x100>; 22 + interrupt-parent = <&mic>; 23 + interrupts = <51 0>; 24 + #address-cells = <1>; 25 + #size-cells = <0>; 26 + }; 27 + 28 + i2c2: i2c@400a8000 { 29 + compatible = "nxp,pnx-i2c"; 30 + reg = <0x400a8000 0x100>; 31 + interrupt-parent = <&mic>; 32 + interrupts = <50 0>; 33 + #address-cells = <1>; 34 + #size-cells = <0>; 35 + clock-frequency = <100000>; 36 + };
+47 -16
drivers/i2c/busses/i2c-pnx.c
··· 23 23 #include <linux/err.h> 24 24 #include <linux/clk.h> 25 25 #include <linux/slab.h> 26 + #include <linux/of_i2c.h> 26 27 27 - #define I2C_PNX_TIMEOUT 10 /* msec */ 28 - #define I2C_PNX_SPEED_KHZ 100 29 - #define I2C_PNX_REGION_SIZE 0x100 28 + #define I2C_PNX_TIMEOUT_DEFAULT 10 /* msec */ 29 + #define I2C_PNX_SPEED_KHZ_DEFAULT 100 30 + #define I2C_PNX_REGION_SIZE 0x100 30 31 31 32 enum { 32 33 mstatus_tdi = 0x00000001, ··· 75 74 #define I2C_REG_TXS(a) ((a)->ioaddr + 0x28) /* Tx slave FIFO (RO) */ 76 75 #define I2C_REG_STFL(a) ((a)->ioaddr + 0x2c) /* Tx slave FIFO level (RO) */ 77 76 78 - static inline int wait_timeout(long timeout, struct i2c_pnx_algo_data *data) 77 + static inline int wait_timeout(struct i2c_pnx_algo_data *data) 79 78 { 79 + long timeout = data->timeout; 80 80 while (timeout > 0 && 81 81 (ioread32(I2C_REG_STS(data)) & mstatus_active)) { 82 82 mdelay(1); ··· 86 84 return (timeout <= 0); 87 85 } 88 86 89 - static inline int wait_reset(long timeout, struct i2c_pnx_algo_data *data) 87 + static inline int wait_reset(struct i2c_pnx_algo_data *data) 90 88 { 89 + long timeout = data->timeout; 91 90 while (timeout > 0 && 92 91 (ioread32(I2C_REG_CTL(data)) & mcntrl_reset)) { 93 92 mdelay(1); ··· 100 97 static inline void i2c_pnx_arm_timer(struct i2c_pnx_algo_data *alg_data) 101 98 { 102 99 struct timer_list *timer = &alg_data->mif.timer; 103 - unsigned long expires = msecs_to_jiffies(I2C_PNX_TIMEOUT); 100 + unsigned long expires = msecs_to_jiffies(alg_data->timeout); 104 101 105 102 if (expires <= 1) 106 103 expires = 2; ··· 138 135 } 139 136 140 137 /* First, make sure bus is idle */ 141 - if (wait_timeout(I2C_PNX_TIMEOUT, alg_data)) { 138 + if (wait_timeout(alg_data)) { 142 139 /* Somebody else is monopolizing the bus */ 143 140 dev_err(&alg_data->adapter.dev, 144 141 "%s: Bus busy. Slave addr = %02x, cntrl = %x, stat = %x\n", ··· 231 228 if (alg_data->mif.len == 0) { 232 229 if (alg_data->last) { 233 230 /* Wait until the STOP is seen. */ 234 - if (wait_timeout(I2C_PNX_TIMEOUT, alg_data)) 231 + if (wait_timeout(alg_data)) 235 232 dev_err(&alg_data->adapter.dev, 236 233 "The bus is still active after timeout\n"); 237 234 } ··· 329 326 if (alg_data->mif.len == 0) { 330 327 if (alg_data->last) 331 328 /* Wait until the STOP is seen. */ 332 - if (wait_timeout(I2C_PNX_TIMEOUT, alg_data)) 329 + if (wait_timeout(alg_data)) 333 330 dev_err(&alg_data->adapter.dev, 334 331 "The bus is still active after timeout\n"); 335 332 ··· 445 442 446 443 ctl |= mcntrl_reset; 447 444 iowrite32(ctl, I2C_REG_CTL(alg_data)); 448 - wait_reset(I2C_PNX_TIMEOUT, alg_data); 445 + wait_reset(alg_data); 449 446 alg_data->mif.ret = -EIO; 450 447 complete(&alg_data->mif.complete); 451 448 } ··· 460 457 alg_data->adapter.name); 461 458 iowrite32(ioread32(I2C_REG_CTL(alg_data)) | mcntrl_reset, 462 459 I2C_REG_CTL(alg_data)); 463 - wait_reset(I2C_PNX_TIMEOUT, alg_data); 460 + wait_reset(alg_data); 464 461 } else if (!(stat & mstatus_rfe) || !(stat & mstatus_tfe)) { 465 462 /* If there is data in the fifo's after transfer, 466 463 * flush fifo's by reset. 467 464 */ 468 465 iowrite32(ioread32(I2C_REG_CTL(alg_data)) | mcntrl_reset, 469 466 I2C_REG_CTL(alg_data)); 470 - wait_reset(I2C_PNX_TIMEOUT, alg_data); 467 + wait_reset(alg_data); 471 468 } else if (stat & mstatus_nai) { 472 469 iowrite32(ioread32(I2C_REG_CTL(alg_data)) | mcntrl_reset, 473 470 I2C_REG_CTL(alg_data)); 474 - wait_reset(I2C_PNX_TIMEOUT, alg_data); 471 + wait_reset(alg_data); 475 472 } 476 473 } 477 474 ··· 615 612 struct i2c_pnx_algo_data *alg_data; 616 613 unsigned long freq; 617 614 struct resource *res; 615 + u32 speed = I2C_PNX_SPEED_KHZ_DEFAULT * 1000; 618 616 619 617 alg_data = kzalloc(sizeof(*alg_data), GFP_KERNEL); 620 618 if (!alg_data) { ··· 630 626 alg_data->adapter.algo_data = alg_data; 631 627 alg_data->adapter.nr = pdev->id; 632 628 629 + alg_data->timeout = I2C_PNX_TIMEOUT_DEFAULT; 630 + #ifdef CONFIG_OF 631 + alg_data->adapter.dev.of_node = of_node_get(pdev->dev.of_node); 632 + if (pdev->dev.of_node) { 633 + of_property_read_u32(pdev->dev.of_node, "clock-frequency", 634 + &speed); 635 + /* 636 + * At this point, it is planned to add an OF timeout property. 637 + * As soon as there is a consensus about how to call and handle 638 + * this, sth. like the following can be put here: 639 + * 640 + * of_property_read_u32(pdev->dev.of_node, "timeout", 641 + * &alg_data->timeout); 642 + */ 643 + } 644 + #endif 633 645 alg_data->clk = clk_get(&pdev->dev, NULL); 634 646 if (IS_ERR(alg_data->clk)) { 635 647 ret = PTR_ERR(alg_data->clk); ··· 671 651 dev_err(&pdev->dev, 672 652 "I/O region 0x%08x for I2C already in use.\n", 673 653 res->start); 674 - ret = -ENODEV; 654 + ret = -ENOMEM; 675 655 goto out_clkget; 676 656 } 677 657 ··· 700 680 * the deglitching filter length. 701 681 */ 702 682 703 - tmp = ((freq / 1000) / I2C_PNX_SPEED_KHZ) / 2 - 2; 683 + tmp = (freq / speed) / 2 - 2; 704 684 if (tmp > 0x3FF) 705 685 tmp = 0x3FF; 706 686 iowrite32(tmp, I2C_REG_CKH(alg_data)); 707 687 iowrite32(tmp, I2C_REG_CKL(alg_data)); 708 688 709 689 iowrite32(mcntrl_reset, I2C_REG_CTL(alg_data)); 710 - if (wait_reset(I2C_PNX_TIMEOUT, alg_data)) { 690 + if (wait_reset(alg_data)) { 711 691 ret = -ENODEV; 712 692 goto out_clock; 713 693 } ··· 729 709 dev_err(&pdev->dev, "I2C: Failed to add bus\n"); 730 710 goto out_irq; 731 711 } 712 + 713 + of_i2c_register_devices(&alg_data->adapter); 732 714 733 715 dev_dbg(&pdev->dev, "%s: Master at %#8x, irq %d.\n", 734 716 alg_data->adapter.name, res->start, alg_data->irq); ··· 770 748 return 0; 771 749 } 772 750 751 + #ifdef CONFIG_OF 752 + static const struct of_device_id i2c_pnx_of_match[] = { 753 + { .compatible = "nxp,pnx-i2c" }, 754 + { }, 755 + }; 756 + MODULE_DEVICE_TABLE(of, i2c_pnx_of_match); 757 + #endif 758 + 773 759 static struct platform_driver i2c_pnx_driver = { 774 760 .driver = { 775 761 .name = "pnx-i2c", 776 762 .owner = THIS_MODULE, 763 + .of_match_table = of_match_ptr(i2c_pnx_of_match), 777 764 }, 778 765 .probe = i2c_pnx_probe, 779 766 .remove = __devexit_p(i2c_pnx_remove),
+1
include/linux/i2c-pnx.h
··· 32 32 struct i2c_adapter adapter; 33 33 phys_addr_t base; 34 34 int irq; 35 + u32 timeout; 35 36 }; 36 37 37 38 #endif /* __I2C_PNX_H__ */