aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorH Hartley Sweeten <hsweeten@visionengravers.com>2010-03-21 23:09:20 -0400
committerEric Miao <eric.y.miao@gmail.com>2010-03-22 00:03:09 -0400
commitc8c3dcb9df8025ed48f8b14bf4b8a77801d88758 (patch)
tree42a62d5218a6edb26efa8a21eabfe5973dcb03ae /arch
parent1b0d76cb9d5a65567230097a2512046f09f30523 (diff)
[ARM] locomo: fix unpaired spin_lock_irqsave
The function locomo_m62332_senddata sends a three byte i2c message to a M62332 DAC. This entire function is guarded with a spin_lock_irqsave at the start of the function and a spin_unlock_irqrestore at the end. As each byte is transferred, the i2c ACK from the DAC is checked. Currently, if the ACK is missing the function simply returns without the unlock. It also leaves the i2c bus in an invalid state since the last byte transferred did not have a "stop" condition and leave the bus idle. Fix this by adding an exit path using goto. Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Eric Miao <eric.y.miao@gmail.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/common/locomo.c6
1 files changed, 3 insertions, 3 deletions
diff --git a/arch/arm/common/locomo.c b/arch/arm/common/locomo.c
index 4f9ccf60aac2..9dff07c80ddb 100644
--- a/arch/arm/common/locomo.c
+++ b/arch/arm/common/locomo.c
@@ -707,7 +707,7 @@ void locomo_m62332_senddata(struct locomo_dev *ldev, unsigned int dac_data, int
707 udelay(DAC_SCL_HIGH_HOLD_TIME); /* 4.7 usec */ 707 udelay(DAC_SCL_HIGH_HOLD_TIME); /* 4.7 usec */
708 if (locomo_readl(mapbase + LOCOMO_DAC) & LOCOMO_DAC_SDAOEB) { /* High is error */ 708 if (locomo_readl(mapbase + LOCOMO_DAC) & LOCOMO_DAC_SDAOEB) { /* High is error */
709 printk(KERN_WARNING "locomo: m62332_senddata Error 1\n"); 709 printk(KERN_WARNING "locomo: m62332_senddata Error 1\n");
710 return; 710 goto out;
711 } 711 }
712 712
713 /* Send Sub address (LSB is channel select) */ 713 /* Send Sub address (LSB is channel select) */
@@ -735,7 +735,7 @@ void locomo_m62332_senddata(struct locomo_dev *ldev, unsigned int dac_data, int
735 udelay(DAC_SCL_HIGH_HOLD_TIME); /* 4.7 usec */ 735 udelay(DAC_SCL_HIGH_HOLD_TIME); /* 4.7 usec */
736 if (locomo_readl(mapbase + LOCOMO_DAC) & LOCOMO_DAC_SDAOEB) { /* High is error */ 736 if (locomo_readl(mapbase + LOCOMO_DAC) & LOCOMO_DAC_SDAOEB) { /* High is error */
737 printk(KERN_WARNING "locomo: m62332_senddata Error 2\n"); 737 printk(KERN_WARNING "locomo: m62332_senddata Error 2\n");
738 return; 738 goto out;
739 } 739 }
740 740
741 /* Send DAC data */ 741 /* Send DAC data */
@@ -760,9 +760,9 @@ void locomo_m62332_senddata(struct locomo_dev *ldev, unsigned int dac_data, int
760 udelay(DAC_SCL_HIGH_HOLD_TIME); /* 4.7 usec */ 760 udelay(DAC_SCL_HIGH_HOLD_TIME); /* 4.7 usec */
761 if (locomo_readl(mapbase + LOCOMO_DAC) & LOCOMO_DAC_SDAOEB) { /* High is error */ 761 if (locomo_readl(mapbase + LOCOMO_DAC) & LOCOMO_DAC_SDAOEB) { /* High is error */
762 printk(KERN_WARNING "locomo: m62332_senddata Error 3\n"); 762 printk(KERN_WARNING "locomo: m62332_senddata Error 3\n");
763 return;
764 } 763 }
765 764
765out:
766 /* stop */ 766 /* stop */
767 r = locomo_readl(mapbase + LOCOMO_DAC); 767 r = locomo_readl(mapbase + LOCOMO_DAC);
768 r &= ~(LOCOMO_DAC_SCLOEB); 768 r &= ~(LOCOMO_DAC_SCLOEB);