提交 ed442b67 编写于 作者: R Russell King

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: NJochen Friedrich <jochen@scram.de>
Signed-off-by: NRussell King <rmk+kernel@arm.linux.org.uk>
上级 65b539bb
......@@ -116,14 +116,22 @@ static void ucb1x00_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
else
ucb->io_out &= ~(1 << offset);
ucb1x00_enable(ucb);
ucb1x00_reg_write(ucb, UCB_IO_DATA, ucb->io_out);
ucb1x00_disable(ucb);
spin_unlock_irqrestore(&ucb->io_lock, flags);
}
static int ucb1x00_gpio_get(struct gpio_chip *chip, unsigned offset)
{
struct ucb1x00 *ucb = container_of(chip, struct ucb1x00, gpio);
return ucb1x00_reg_read(ucb, UCB_IO_DATA) & (1 << offset);
unsigned val;
ucb1x00_enable(ucb);
val = ucb1x00_reg_read(ucb, UCB_IO_DATA);
ucb1x00_disable(ucb);
return val & (1 << offset);
}
static 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)
spin_lock_irqsave(&ucb->io_lock, flags);
ucb->io_dir &= ~(1 << offset);
ucb1x00_enable(ucb);
ucb1x00_reg_write(ucb, UCB_IO_DIR, ucb->io_dir);
ucb1x00_disable(ucb);
spin_unlock_irqrestore(&ucb->io_lock, flags);
return 0;
......@@ -153,6 +163,7 @@ static int ucb1x00_gpio_direction_output(struct gpio_chip *chip, unsigned offset
else
ucb->io_out &= ~mask;
ucb1x00_enable(ucb);
if (old != ucb->io_out)
ucb1x00_reg_write(ucb, UCB_IO_DATA, ucb->io_out);
......@@ -160,6 +171,7 @@ static int ucb1x00_gpio_direction_output(struct gpio_chip *chip, unsigned offset
ucb->io_dir |= mask;
ucb1x00_reg_write(ucb, UCB_IO_DIR, ucb->io_dir);
}
ucb1x00_disable(ucb);
spin_unlock_irqrestore(&ucb->io_lock, flags);
return 0;
......@@ -703,8 +715,10 @@ static int ucb1x00_resume(struct mcp *mcp)
struct ucb1x00 *ucb = mcp_get_drvdata(mcp);
struct ucb1x00_dev *dev;
ucb1x00_enable(ucb);
ucb1x00_reg_write(ucb, UCB_IO_DATA, ucb->io_out);
ucb1x00_reg_write(ucb, UCB_IO_DIR, ucb->io_dir);
ucb1x00_disable(ucb);
mutex_lock(&ucb1x00_mutex);
list_for_each_entry(dev, &ucb->devs, dev_node) {
if (dev->drv->resume)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册