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 | |
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
-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"); |