diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-07-29 22:39:22 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-07-29 22:39:22 -0400 |
| commit | 658874f05d040ca96eb5ba9b1c30ce0ff287d762 (patch) | |
| tree | a62069f861d3c587b8165ad2aecca4c97dced215 /drivers/i2c | |
| parent | 91a5698d1f253d30f53f0c58d2504eaec481b854 (diff) | |
| parent | cd086d3aa6f7f7bf4d4e1f9fa09af0f0b6bb99ec (diff) | |
Merge branch 'i2c-fixes-rc4' of git://aeryn.fluff.org.uk/bjdooks/linux
* 'i2c-fixes-rc4' of git://aeryn.fluff.org.uk/bjdooks/linux:
i2c-omap: OMAP3430 Silicon Errata 1.153
i2c-omap: In case of a NACK|ARDY|AL return from the ISR
i2c-omap: Bug in reading the RXSTAT/TXSTAT values from the I2C_BUFFSTAT register
i2c-sh_mobile: change module_init() to subsys_initcall()
i2c: strncpy does not null terminate string
i2c-s3c2410: s3c24xx_i2c_init: don't clobber IICLC value
Diffstat (limited to 'drivers/i2c')
| -rw-r--r-- | drivers/i2c/busses/i2c-omap.c | 42 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-s3c2410.c | 5 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-sh_mobile.c | 2 |
3 files changed, 35 insertions, 14 deletions
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index fdd83277c8a8..d258b02aef44 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c | |||
| @@ -672,9 +672,10 @@ omap_i2c_isr(int this_irq, void *dev_id) | |||
| 672 | break; | 672 | break; |
| 673 | } | 673 | } |
| 674 | 674 | ||
| 675 | err = 0; | ||
| 676 | complete: | ||
| 675 | omap_i2c_write_reg(dev, OMAP_I2C_STAT_REG, stat); | 677 | omap_i2c_write_reg(dev, OMAP_I2C_STAT_REG, stat); |
| 676 | 678 | ||
| 677 | err = 0; | ||
| 678 | if (stat & OMAP_I2C_STAT_NACK) { | 679 | if (stat & OMAP_I2C_STAT_NACK) { |
| 679 | err |= OMAP_I2C_STAT_NACK; | 680 | err |= OMAP_I2C_STAT_NACK; |
| 680 | omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, | 681 | omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, |
| @@ -685,16 +686,19 @@ omap_i2c_isr(int this_irq, void *dev_id) | |||
| 685 | err |= OMAP_I2C_STAT_AL; | 686 | err |= OMAP_I2C_STAT_AL; |
| 686 | } | 687 | } |
| 687 | if (stat & (OMAP_I2C_STAT_ARDY | OMAP_I2C_STAT_NACK | | 688 | if (stat & (OMAP_I2C_STAT_ARDY | OMAP_I2C_STAT_NACK | |
| 688 | OMAP_I2C_STAT_AL)) | 689 | OMAP_I2C_STAT_AL)) { |
| 689 | omap_i2c_complete_cmd(dev, err); | 690 | omap_i2c_complete_cmd(dev, err); |
| 691 | return IRQ_HANDLED; | ||
| 692 | } | ||
| 690 | if (stat & (OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR)) { | 693 | if (stat & (OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR)) { |
| 691 | u8 num_bytes = 1; | 694 | u8 num_bytes = 1; |
| 692 | if (dev->fifo_size) { | 695 | if (dev->fifo_size) { |
| 693 | if (stat & OMAP_I2C_STAT_RRDY) | 696 | if (stat & OMAP_I2C_STAT_RRDY) |
| 694 | num_bytes = dev->fifo_size; | 697 | num_bytes = dev->fifo_size; |
| 695 | else | 698 | else /* read RXSTAT on RDR interrupt */ |
| 696 | num_bytes = omap_i2c_read_reg(dev, | 699 | num_bytes = (omap_i2c_read_reg(dev, |
| 697 | OMAP_I2C_BUFSTAT_REG); | 700 | OMAP_I2C_BUFSTAT_REG) |
| 701 | >> 8) & 0x3F; | ||
| 698 | } | 702 | } |
| 699 | while (num_bytes) { | 703 | while (num_bytes) { |
| 700 | num_bytes--; | 704 | num_bytes--; |
| @@ -731,9 +735,10 @@ omap_i2c_isr(int this_irq, void *dev_id) | |||
| 731 | if (dev->fifo_size) { | 735 | if (dev->fifo_size) { |
| 732 | if (stat & OMAP_I2C_STAT_XRDY) | 736 | if (stat & OMAP_I2C_STAT_XRDY) |
| 733 | num_bytes = dev->fifo_size; | 737 | num_bytes = dev->fifo_size; |
| 734 | else | 738 | else /* read TXSTAT on XDR interrupt */ |
| 735 | num_bytes = omap_i2c_read_reg(dev, | 739 | num_bytes = omap_i2c_read_reg(dev, |
| 736 | OMAP_I2C_BUFSTAT_REG); | 740 | OMAP_I2C_BUFSTAT_REG) |
| 741 | & 0x3F; | ||
| 737 | } | 742 | } |
| 738 | while (num_bytes) { | 743 | while (num_bytes) { |
| 739 | num_bytes--; | 744 | num_bytes--; |
| @@ -760,6 +765,27 @@ omap_i2c_isr(int this_irq, void *dev_id) | |||
| 760 | "data to send\n"); | 765 | "data to send\n"); |
| 761 | break; | 766 | break; |
| 762 | } | 767 | } |
| 768 | |||
| 769 | /* | ||
| 770 | * OMAP3430 Errata 1.153: When an XRDY/XDR | ||
| 771 | * is hit, wait for XUDF before writing data | ||
| 772 | * to DATA_REG. Otherwise some data bytes can | ||
| 773 | * be lost while transferring them from the | ||
| 774 | * memory to the I2C interface. | ||
| 775 | */ | ||
| 776 | |||
| 777 | if (cpu_is_omap34xx()) { | ||
| 778 | while (!(stat & OMAP_I2C_STAT_XUDF)) { | ||
| 779 | if (stat & (OMAP_I2C_STAT_NACK | OMAP_I2C_STAT_AL)) { | ||
| 780 | omap_i2c_ack_stat(dev, stat & (OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR)); | ||
| 781 | err |= OMAP_I2C_STAT_XUDF; | ||
| 782 | goto complete; | ||
| 783 | } | ||
| 784 | cpu_relax(); | ||
| 785 | stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG); | ||
| 786 | } | ||
| 787 | } | ||
| 788 | |||
| 763 | omap_i2c_write_reg(dev, OMAP_I2C_DATA_REG, w); | 789 | omap_i2c_write_reg(dev, OMAP_I2C_DATA_REG, w); |
| 764 | } | 790 | } |
| 765 | omap_i2c_ack_stat(dev, | 791 | omap_i2c_ack_stat(dev, |
| @@ -879,7 +905,7 @@ omap_i2c_probe(struct platform_device *pdev) | |||
| 879 | i2c_set_adapdata(adap, dev); | 905 | i2c_set_adapdata(adap, dev); |
| 880 | adap->owner = THIS_MODULE; | 906 | adap->owner = THIS_MODULE; |
| 881 | adap->class = I2C_CLASS_HWMON; | 907 | adap->class = I2C_CLASS_HWMON; |
| 882 | strncpy(adap->name, "OMAP I2C adapter", sizeof(adap->name)); | 908 | strlcpy(adap->name, "OMAP I2C adapter", sizeof(adap->name)); |
| 883 | adap->algo = &omap_i2c_algo; | 909 | adap->algo = &omap_i2c_algo; |
| 884 | adap->dev.parent = &pdev->dev; | 910 | adap->dev.parent = &pdev->dev; |
| 885 | 911 | ||
diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c index 8f42a4536cdf..20bb0ceb027b 100644 --- a/drivers/i2c/busses/i2c-s3c2410.c +++ b/drivers/i2c/busses/i2c-s3c2410.c | |||
| @@ -763,11 +763,6 @@ static int s3c24xx_i2c_init(struct s3c24xx_i2c *i2c) | |||
| 763 | dev_info(i2c->dev, "bus frequency set to %d KHz\n", freq); | 763 | dev_info(i2c->dev, "bus frequency set to %d KHz\n", freq); |
| 764 | dev_dbg(i2c->dev, "S3C2410_IICCON=0x%02lx\n", iicon); | 764 | dev_dbg(i2c->dev, "S3C2410_IICCON=0x%02lx\n", iicon); |
| 765 | 765 | ||
| 766 | /* check for s3c2440 i2c controller */ | ||
| 767 | |||
| 768 | if (s3c24xx_i2c_is2440(i2c)) | ||
| 769 | writel(0x0, i2c->regs + S3C2440_IICLC); | ||
| 770 | |||
| 771 | return 0; | 766 | return 0; |
| 772 | } | 767 | } |
| 773 | 768 | ||
diff --git a/drivers/i2c/busses/i2c-sh_mobile.c b/drivers/i2c/busses/i2c-sh_mobile.c index 4f3d99cd1692..820487d0d5c7 100644 --- a/drivers/i2c/busses/i2c-sh_mobile.c +++ b/drivers/i2c/busses/i2c-sh_mobile.c | |||
| @@ -637,7 +637,7 @@ static void __exit sh_mobile_i2c_adap_exit(void) | |||
| 637 | platform_driver_unregister(&sh_mobile_i2c_driver); | 637 | platform_driver_unregister(&sh_mobile_i2c_driver); |
| 638 | } | 638 | } |
| 639 | 639 | ||
| 640 | module_init(sh_mobile_i2c_adap_init); | 640 | subsys_initcall(sh_mobile_i2c_adap_init); |
| 641 | module_exit(sh_mobile_i2c_adap_exit); | 641 | module_exit(sh_mobile_i2c_adap_exit); |
| 642 | 642 | ||
| 643 | MODULE_DESCRIPTION("SuperH Mobile I2C Bus Controller driver"); | 643 | MODULE_DESCRIPTION("SuperH Mobile I2C Bus Controller driver"); |
