aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd/ucb1x00-core.c
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2012-01-21 13:13:20 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2012-02-18 18:15:38 -0500
commited442b6798eb39eda3bcea92ef9403280b603818 (patch)
tree4e9d701e751169e5eda8ef7ee985c29b55f16d9e /drivers/mfd/ucb1x00-core.c
parent65b539bb900f64b9a3f9b761bf0f735dc84e6b70 (diff)
MFD: ucb1x00-core: add missing ucb1x00_enable()/ucb1x00_disable()
ucb1x00_enable() and ucb1x00_disable() are used for power saving on the SIB interface, allowing the host supplied clock to be disabled when not required. We require drivers which access the ucb1x00 to ensure that they have enabled the clock prior to accessing the device, and they should disable it once they're done. As we don't expect gpiolib users to be aware of this detail, we must make these calls in the gpiolib interfaces. Add them. Also add them to the resume method, which needs to re-establish the GPIO pin settings. Acked-by: Jochen Friedrich <jochen@scram.de> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'drivers/mfd/ucb1x00-core.c')
-rw-r--r--drivers/mfd/ucb1x00-core.c16
1 files changed, 15 insertions, 1 deletions
diff --git a/drivers/mfd/ucb1x00-core.c b/drivers/mfd/ucb1x00-core.c
index 162496de1b3..9f8ea52f0ca 100644
--- a/drivers/mfd/ucb1x00-core.c
+++ b/drivers/mfd/ucb1x00-core.c
@@ -116,14 +116,22 @@ static void ucb1x00_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
116 else 116 else
117 ucb->io_out &= ~(1 << offset); 117 ucb->io_out &= ~(1 << offset);
118 118
119 ucb1x00_enable(ucb);
119 ucb1x00_reg_write(ucb, UCB_IO_DATA, ucb->io_out); 120 ucb1x00_reg_write(ucb, UCB_IO_DATA, ucb->io_out);
121 ucb1x00_disable(ucb);
120 spin_unlock_irqrestore(&ucb->io_lock, flags); 122 spin_unlock_irqrestore(&ucb->io_lock, flags);
121} 123}
122 124
123static int ucb1x00_gpio_get(struct gpio_chip *chip, unsigned offset) 125static int ucb1x00_gpio_get(struct gpio_chip *chip, unsigned offset)
124{ 126{
125 struct ucb1x00 *ucb = container_of(chip, struct ucb1x00, gpio); 127 struct ucb1x00 *ucb = container_of(chip, struct ucb1x00, gpio);
126 return ucb1x00_reg_read(ucb, UCB_IO_DATA) & (1 << offset); 128 unsigned val;
129
130 ucb1x00_enable(ucb);
131 val = ucb1x00_reg_read(ucb, UCB_IO_DATA);
132 ucb1x00_disable(ucb);
133
134 return val & (1 << offset);
127} 135}
128 136
129static int ucb1x00_gpio_direction_input(struct gpio_chip *chip, unsigned offset) 137static int ucb1x00_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
@@ -133,7 +141,9 @@ static int ucb1x00_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
133 141
134 spin_lock_irqsave(&ucb->io_lock, flags); 142 spin_lock_irqsave(&ucb->io_lock, flags);
135 ucb->io_dir &= ~(1 << offset); 143 ucb->io_dir &= ~(1 << offset);
144 ucb1x00_enable(ucb);
136 ucb1x00_reg_write(ucb, UCB_IO_DIR, ucb->io_dir); 145 ucb1x00_reg_write(ucb, UCB_IO_DIR, ucb->io_dir);
146 ucb1x00_disable(ucb);
137 spin_unlock_irqrestore(&ucb->io_lock, flags); 147 spin_unlock_irqrestore(&ucb->io_lock, flags);
138 148
139 return 0; 149 return 0;
@@ -153,6 +163,7 @@ static int ucb1x00_gpio_direction_output(struct gpio_chip *chip, unsigned offset
153 else 163 else
154 ucb->io_out &= ~mask; 164 ucb->io_out &= ~mask;
155 165
166 ucb1x00_enable(ucb);
156 if (old != ucb->io_out) 167 if (old != ucb->io_out)
157 ucb1x00_reg_write(ucb, UCB_IO_DATA, ucb->io_out); 168 ucb1x00_reg_write(ucb, UCB_IO_DATA, ucb->io_out);
158 169
@@ -160,6 +171,7 @@ static int ucb1x00_gpio_direction_output(struct gpio_chip *chip, unsigned offset
160 ucb->io_dir |= mask; 171 ucb->io_dir |= mask;
161 ucb1x00_reg_write(ucb, UCB_IO_DIR, ucb->io_dir); 172 ucb1x00_reg_write(ucb, UCB_IO_DIR, ucb->io_dir);
162 } 173 }
174 ucb1x00_disable(ucb);
163 spin_unlock_irqrestore(&ucb->io_lock, flags); 175 spin_unlock_irqrestore(&ucb->io_lock, flags);
164 176
165 return 0; 177 return 0;
@@ -703,8 +715,10 @@ static int ucb1x00_resume(struct mcp *mcp)
703 struct ucb1x00 *ucb = mcp_get_drvdata(mcp); 715 struct ucb1x00 *ucb = mcp_get_drvdata(mcp);
704 struct ucb1x00_dev *dev; 716 struct ucb1x00_dev *dev;
705 717
718 ucb1x00_enable(ucb);
706 ucb1x00_reg_write(ucb, UCB_IO_DATA, ucb->io_out); 719 ucb1x00_reg_write(ucb, UCB_IO_DATA, ucb->io_out);
707 ucb1x00_reg_write(ucb, UCB_IO_DIR, ucb->io_dir); 720 ucb1x00_reg_write(ucb, UCB_IO_DIR, ucb->io_dir);
721 ucb1x00_disable(ucb);
708 mutex_lock(&ucb1x00_mutex); 722 mutex_lock(&ucb1x00_mutex);
709 list_for_each_entry(dev, &ucb->devs, dev_node) { 723 list_for_each_entry(dev, &ucb->devs, dev_node) {
710 if (dev->drv->resume) 724 if (dev->drv->resume)