Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fc2b04e7 authored by Barry Song's avatar Barry Song Committed by Linus Walleij
Browse files

pinctrl: sirf: enable GPIO pullup/down configuration from dts



commit 7bec2074 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: default avatarBarry Song <Baohua.Song@csr.com>
Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
parent 408f181e
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -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.
+48 −0
Original line number Diff line number Diff line
@@ -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: