summaryrefslogtreecommitdiff
path: root/drivers/pinctrl/pinctrl-sirf.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pinctrl/pinctrl-sirf.c')
-rw-r--r--drivers/pinctrl/pinctrl-sirf.c48
1 files changed, 48 insertions, 0 deletions
diff --git a/drivers/pinctrl/pinctrl-sirf.c b/drivers/pinctrl/pinctrl-sirf.c
index a4f0c5e..30e1a38 100644
--- a/drivers/pinctrl/pinctrl-sirf.c
+++ b/drivers/pinctrl/pinctrl-sirf.c
@@ -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;
@@ -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;
@@ -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: