Skip to content

Commit

Permalink
pinctrl: sirf: enable GPIO pullup/down configuration from dts
Browse files Browse the repository at this point in the history
commit 7bec207 remove sirfsoc_gpio_set_pull function,
this patches takes the feature back by adding sirf,pullups and
sirf,pulldowns prop in dts, and the driver will set the GPIO
pull according to the dts.

Cc: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Barry Song <Baohua.Song@csr.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
  • Loading branch information
21cnbao authored and linusw committed Dec 26, 2012
1 parent 408f181 commit fc2b04e
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 0 deletions.
3 changes: 3 additions & 0 deletions Documentation/devicetree/bindings/pinctrl/pinctrl-sirf.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ Required properties:
- interrupts : Interrupts used by every GPIO group
- gpio-controller : Indicates this device is a GPIO controller
- interrupt-controller : Marks the device node as an interrupt controller
Optional properties:
- sirf,pullups : if n-th bit of m-th bank is set, set a pullup on GPIO-n of bank m
- sirf,pulldowns : if n-th bit of m-th bank is set, set a pulldown on GPIO-n of bank m

Please refer to pinctrl-bindings.txt in this directory for details of the common
pinctrl bindings used by client devices.
Expand Down
48 changes: 48 additions & 0 deletions drivers/pinctrl/pinctrl-sirf.c
Original file line number Diff line number Diff line change
Expand Up @@ -1663,6 +1663,44 @@ const struct irq_domain_ops sirfsoc_gpio_irq_simple_ops = {
.xlate = irq_domain_xlate_twocell,
};

static void sirfsoc_gpio_set_pullup(const u32 *pullups)
{
int i, n;
const unsigned long *p = (const unsigned long *)pullups;

for (i = 0; i < SIRFSOC_GPIO_NO_OF_BANKS; i++) {
n = find_first_bit(p + i, BITS_PER_LONG);
while (n < BITS_PER_LONG) {
u32 offset = SIRFSOC_GPIO_CTRL(i, n);
u32 val = readl(sgpio_bank[i].chip.regs + offset);
val |= SIRFSOC_GPIO_CTL_PULL_MASK;
val |= SIRFSOC_GPIO_CTL_PULL_HIGH;
writel(val, sgpio_bank[i].chip.regs + offset);

n = find_next_bit(p + i, BITS_PER_LONG, n + 1);
}
}
}

static void sirfsoc_gpio_set_pulldown(const u32 *pulldowns)
{
int i, n;
const unsigned long *p = (const unsigned long *)pulldowns;

for (i = 0; i < SIRFSOC_GPIO_NO_OF_BANKS; i++) {
n = find_first_bit(p + i, BITS_PER_LONG);
while (n < BITS_PER_LONG) {
u32 offset = SIRFSOC_GPIO_CTRL(i, n);
u32 val = readl(sgpio_bank[i].chip.regs + offset);
val |= SIRFSOC_GPIO_CTL_PULL_MASK;
val &= ~SIRFSOC_GPIO_CTL_PULL_HIGH;
writel(val, sgpio_bank[i].chip.regs + offset);

n = find_next_bit(p + i, BITS_PER_LONG, n + 1);
}
}
}

static int __devinit sirfsoc_gpio_probe(struct device_node *np)
{
int i, err = 0;
Expand All @@ -1671,6 +1709,8 @@ static int __devinit sirfsoc_gpio_probe(struct device_node *np)
struct platform_device *pdev;
bool is_marco = false;

u32 pullups[SIRFSOC_GPIO_NO_OF_BANKS], pulldowns[SIRFSOC_GPIO_NO_OF_BANKS];

pdev = of_find_device_by_node(np);
if (!pdev)
return -ENODEV;
Expand Down Expand Up @@ -1726,6 +1766,14 @@ static int __devinit sirfsoc_gpio_probe(struct device_node *np)
irq_set_handler_data(bank->parent_irq, bank);
}

if (!of_property_read_u32_array(np, "sirf,pullups", pullups,
SIRFSOC_GPIO_NO_OF_BANKS))
sirfsoc_gpio_set_pullup(pullups);

if (!of_property_read_u32_array(np, "sirf,pulldowns", pulldowns,
SIRFSOC_GPIO_NO_OF_BANKS))
sirfsoc_gpio_set_pulldown(pulldowns);

return 0;

out:
Expand Down

0 comments on commit fc2b04e

Please sign in to comment.