diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-09-05 11:49:48 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-09-05 11:49:48 -0700 |
commit | 70b8e9eb3b50d8bded63f808b09c4844ef63c3b8 (patch) | |
tree | 42b5b22becc9e9542923be3bc78525e0d9f5c67c /drivers/gpio/gpio-tegra.c | |
parent | d16605c9128a498f9b8575b5c43be95c45dbcfab (diff) | |
parent | 02b6bddb0b0a4e27fad6623d82579f2a1e35d3d3 (diff) |
Merge tag 'gpio-v4.14-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio
Pull GPIO updates from Linus Walleij:
"This is the bulk of the GPIO changes for the v4.14 cycle.
Not so much changes this time, phew. David Daney and Bartosz
Golaszewski did all the really interesting work in infrastructure
improvement across GPIO and IRQ core, hats off for them and to tglx
and Marc Z for general help with these patch sets.
Core changes:
- Allow the GPIO irqchip to allocate IRQs dynamically. This is an
important change on systems where only a restricted number of IRQs,
lesser than the number of GPIO lines, can be utilized. Now we can
allocate these on a first-come-first-served basis instead of
hogging up valuable IRQ lines.
- Serious fix-up of the kerneldoc documentation and inclusion into
the kerneldoc builds.
- Pulled in the IRQ simulator from the IRQ core tree and use this in
the GPIO mockup driver for exhaustive testing of interrupt
abilities.
New drivers:
- New driver for ThunderX and OCTEON-TX. This is especially
interesting as it picks up improvements from the IRQ core that
allow us to handle fasteoi ACKs upwards in a hierarchy when there
are IRQ flag latches on several levels in a hierarchy. Very
interesting work here.
- New subdriver for Renesas R-Car r8a7745 (RZ/G1E).
Misc:
- Several fixes and improvements for Xilinx Zynq GPIO.
- Support an enablement GPIO for the 74x164 GPIO.
- Switch a bunch of chips to use devres to allocate irq descriptors.
- A bunch of constification fixes"
* tag 'gpio-v4.14-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio: (63 commits)
gpio: mockup: remove unused variable gc
gpio: pl061: constify amba_id
Revert "gpiolib: request the gpio before querying its direction"
gpio: twl6040: remove unneeded forward declaration
gpio: zevio: make gpio_chip const
gpio: add gpio_add_lookup_tables() to add several tables at once
gpio: rcar: Add r8a7745 (RZ/G1E) support
gpio: brcmstb: check return value of gpiochip_irqchip_add()
MAINTAINERS: Add entry for THUNDERX GPIO Driver.
gpio: Add gpio driver support for ThunderX and OCTEON-TX
gpio: mockup: use irq_sim
gpio: mxs: use devres for irq generic chip
gpio: mxc: use devres for irq generic chip
gpio: pch: use devres for irq generic chip
gpio: ml-ioh: use devres for irq generic chip
gpio: sta2x11: use devres for irq generic chip
gpio: sta2x11: disallow unbinding the driver
gpio: mxs: disallow unbinding the driver
gpio: mxc: disallow unbinding the driver
gpio: aspeed: Remove reference to clock name in debounce warning message
...
Diffstat (limited to 'drivers/gpio/gpio-tegra.c')
-rw-r--r-- | drivers/gpio/gpio-tegra.c | 129 |
1 files changed, 61 insertions, 68 deletions
diff --git a/drivers/gpio/gpio-tegra.c b/drivers/gpio/gpio-tegra.c index 506c6a67c5fc..fbaf974277df 100644 --- a/drivers/gpio/gpio-tegra.c +++ b/drivers/gpio/gpio-tegra.c @@ -67,8 +67,8 @@ struct tegra_gpio_info; struct tegra_gpio_bank { - int bank; - int irq; + unsigned int bank; + unsigned int irq; spinlock_t lvl_lock[4]; spinlock_t dbc_lock[4]; /* Lock for updating debounce count register */ #ifdef CONFIG_PM_SLEEP @@ -112,13 +112,14 @@ static inline u32 tegra_gpio_readl(struct tegra_gpio_info *tgi, u32 reg) return __raw_readl(tgi->regs + reg); } -static int tegra_gpio_compose(int bank, int port, int bit) +static unsigned int tegra_gpio_compose(unsigned int bank, unsigned int port, + unsigned int bit) { return (bank << 5) | ((port & 0x3) << 3) | (bit & 0x7); } static void tegra_gpio_mask_write(struct tegra_gpio_info *tgi, u32 reg, - int gpio, int value) + unsigned int gpio, u32 value) { u32 val; @@ -128,22 +129,22 @@ static void tegra_gpio_mask_write(struct tegra_gpio_info *tgi, u32 reg, tegra_gpio_writel(tgi, val, reg); } -static void tegra_gpio_enable(struct tegra_gpio_info *tgi, int gpio) +static void tegra_gpio_enable(struct tegra_gpio_info *tgi, unsigned int gpio) { tegra_gpio_mask_write(tgi, GPIO_MSK_CNF(tgi, gpio), gpio, 1); } -static void tegra_gpio_disable(struct tegra_gpio_info *tgi, int gpio) +static void tegra_gpio_disable(struct tegra_gpio_info *tgi, unsigned int gpio) { tegra_gpio_mask_write(tgi, GPIO_MSK_CNF(tgi, gpio), gpio, 0); } -static int tegra_gpio_request(struct gpio_chip *chip, unsigned offset) +static int tegra_gpio_request(struct gpio_chip *chip, unsigned int offset) { return pinctrl_request_gpio(offset); } -static void tegra_gpio_free(struct gpio_chip *chip, unsigned offset) +static void tegra_gpio_free(struct gpio_chip *chip, unsigned int offset) { struct tegra_gpio_info *tgi = gpiochip_get_data(chip); @@ -151,17 +152,18 @@ static void tegra_gpio_free(struct gpio_chip *chip, unsigned offset) tegra_gpio_disable(tgi, offset); } -static void tegra_gpio_set(struct gpio_chip *chip, unsigned offset, int value) +static void tegra_gpio_set(struct gpio_chip *chip, unsigned int offset, + int value) { struct tegra_gpio_info *tgi = gpiochip_get_data(chip); tegra_gpio_mask_write(tgi, GPIO_MSK_OUT(tgi, offset), offset, value); } -static int tegra_gpio_get(struct gpio_chip *chip, unsigned offset) +static int tegra_gpio_get(struct gpio_chip *chip, unsigned int offset) { struct tegra_gpio_info *tgi = gpiochip_get_data(chip); - int bval = BIT(GPIO_BIT(offset)); + unsigned int bval = BIT(GPIO_BIT(offset)); /* If gpio is in output mode then read from the out value */ if (tegra_gpio_readl(tgi, GPIO_OE(tgi, offset)) & bval) @@ -170,7 +172,8 @@ static int tegra_gpio_get(struct gpio_chip *chip, unsigned offset) return !!(tegra_gpio_readl(tgi, GPIO_IN(tgi, offset)) & bval); } -static int tegra_gpio_direction_input(struct gpio_chip *chip, unsigned offset) +static int tegra_gpio_direction_input(struct gpio_chip *chip, + unsigned int offset) { struct tegra_gpio_info *tgi = gpiochip_get_data(chip); @@ -179,8 +182,9 @@ static int tegra_gpio_direction_input(struct gpio_chip *chip, unsigned offset) return 0; } -static int tegra_gpio_direction_output(struct gpio_chip *chip, unsigned offset, - int value) +static int tegra_gpio_direction_output(struct gpio_chip *chip, + unsigned int offset, + int value) { struct tegra_gpio_info *tgi = gpiochip_get_data(chip); @@ -190,7 +194,8 @@ static int tegra_gpio_direction_output(struct gpio_chip *chip, unsigned offset, return 0; } -static int tegra_gpio_get_direction(struct gpio_chip *chip, unsigned offset) +static int tegra_gpio_get_direction(struct gpio_chip *chip, + unsigned int offset) { struct tegra_gpio_info *tgi = gpiochip_get_data(chip); u32 pin_mask = BIT(GPIO_BIT(offset)); @@ -212,7 +217,7 @@ static int tegra_gpio_set_debounce(struct gpio_chip *chip, unsigned int offset, struct tegra_gpio_bank *bank = &tgi->bank_info[GPIO_BANK(offset)]; unsigned int debounce_ms = DIV_ROUND_UP(debounce, 1000); unsigned long flags; - int port; + unsigned int port; if (!debounce_ms) { tegra_gpio_mask_write(tgi, GPIO_MSK_DBC_EN(tgi, offset), @@ -250,7 +255,7 @@ static int tegra_gpio_set_config(struct gpio_chip *chip, unsigned int offset, return tegra_gpio_set_debounce(chip, offset, debounce); } -static int tegra_gpio_to_irq(struct gpio_chip *chip, unsigned offset) +static int tegra_gpio_to_irq(struct gpio_chip *chip, unsigned int offset) { struct tegra_gpio_info *tgi = gpiochip_get_data(chip); @@ -261,7 +266,7 @@ static void tegra_gpio_irq_ack(struct irq_data *d) { struct tegra_gpio_bank *bank = irq_data_get_irq_chip_data(d); struct tegra_gpio_info *tgi = bank->tgi; - int gpio = d->hwirq; + unsigned int gpio = d->hwirq; tegra_gpio_writel(tgi, 1 << GPIO_BIT(gpio), GPIO_INT_CLR(tgi, gpio)); } @@ -270,7 +275,7 @@ static void tegra_gpio_irq_mask(struct irq_data *d) { struct tegra_gpio_bank *bank = irq_data_get_irq_chip_data(d); struct tegra_gpio_info *tgi = bank->tgi; - int gpio = d->hwirq; + unsigned int gpio = d->hwirq; tegra_gpio_mask_write(tgi, GPIO_MSK_INT_ENB(tgi, gpio), gpio, 0); } @@ -279,20 +284,18 @@ static void tegra_gpio_irq_unmask(struct irq_data *d) { struct tegra_gpio_bank *bank = irq_data_get_irq_chip_data(d); struct tegra_gpio_info *tgi = bank->tgi; - int gpio = d->hwirq; + unsigned int gpio = d->hwirq; tegra_gpio_mask_write(tgi, GPIO_MSK_INT_ENB(tgi, gpio), gpio, 1); } static int tegra_gpio_irq_set_type(struct irq_data *d, unsigned int type) { - int gpio = d->hwirq; + unsigned int gpio = d->hwirq, port = GPIO_PORT(gpio), lvl_type; struct tegra_gpio_bank *bank = irq_data_get_irq_chip_data(d); struct tegra_gpio_info *tgi = bank->tgi; - int port = GPIO_PORT(gpio); - int lvl_type; - int val; unsigned long flags; + u32 val; int ret; switch (type & IRQ_TYPE_SENSE_MASK) { @@ -323,7 +326,7 @@ static int tegra_gpio_irq_set_type(struct irq_data *d, unsigned int type) ret = gpiochip_lock_as_irq(&tgi->gc, gpio); if (ret) { dev_err(tgi->dev, - "unable to lock Tegra GPIO %d as IRQ\n", gpio); + "unable to lock Tegra GPIO %u as IRQ\n", gpio); return ret; } @@ -351,17 +354,15 @@ static void tegra_gpio_irq_shutdown(struct irq_data *d) { struct tegra_gpio_bank *bank = irq_data_get_irq_chip_data(d); struct tegra_gpio_info *tgi = bank->tgi; - int gpio = d->hwirq; + unsigned int gpio = d->hwirq; gpiochip_unlock_as_irq(&tgi->gc, gpio); } static void tegra_gpio_irq_handler(struct irq_desc *desc) { - int port; - int pin; + unsigned int port, pin, gpio; bool unmasked = false; - int gpio; u32 lvl; unsigned long sta; struct irq_chip *chip = irq_desc_get_chip(desc); @@ -389,7 +390,8 @@ static void tegra_gpio_irq_handler(struct irq_desc *desc) chained_irq_exit(chip, desc); } - generic_handle_irq(gpio_to_irq(gpio + pin)); + generic_handle_irq(irq_find_mapping(tgi->irq_domain, + gpio + pin)); } } @@ -404,8 +406,7 @@ static int tegra_gpio_resume(struct device *dev) struct platform_device *pdev = to_platform_device(dev); struct tegra_gpio_info *tgi = platform_get_drvdata(pdev); unsigned long flags; - int b; - int p; + unsigned int b, p; local_irq_save(flags); @@ -413,7 +414,8 @@ static int tegra_gpio_resume(struct device *dev) struct tegra_gpio_bank *bank = &tgi->bank_info[b]; for (p = 0; p < ARRAY_SIZE(bank->oe); p++) { - unsigned int gpio = (b<<5) | (p<<3); + unsigned int gpio = (b << 5) | (p << 3); + tegra_gpio_writel(tgi, bank->cnf[p], GPIO_CNF(tgi, gpio)); @@ -444,15 +446,15 @@ static int tegra_gpio_suspend(struct device *dev) struct platform_device *pdev = to_platform_device(dev); struct tegra_gpio_info *tgi = platform_get_drvdata(pdev); unsigned long flags; - int b; - int p; + unsigned int b, p; local_irq_save(flags); for (b = 0; b < tgi->bank_count; b++) { struct tegra_gpio_bank *bank = &tgi->bank_info[b]; for (p = 0; p < ARRAY_SIZE(bank->oe); p++) { - unsigned int gpio = (b<<5) | (p<<3); + unsigned int gpio = (b << 5) | (p << 3); + bank->cnf[p] = tegra_gpio_readl(tgi, GPIO_CNF(tgi, gpio)); bank->out[p] = tegra_gpio_readl(tgi, @@ -483,7 +485,7 @@ static int tegra_gpio_suspend(struct device *dev) static int tegra_gpio_irq_set_wake(struct irq_data *d, unsigned int enable) { struct tegra_gpio_bank *bank = irq_data_get_irq_chip_data(d); - int gpio = d->hwirq; + unsigned int gpio = d->hwirq; u32 port, bit, mask; port = GPIO_PORT(gpio); @@ -507,14 +509,14 @@ static int tegra_gpio_irq_set_wake(struct irq_data *d, unsigned int enable) static int dbg_gpio_show(struct seq_file *s, void *unused) { struct tegra_gpio_info *tgi = s->private; - int i; - int j; + unsigned int i, j; for (i = 0; i < tgi->bank_count; i++) { for (j = 0; j < 4; j++) { - int gpio = tegra_gpio_compose(i, j, 0); + unsigned int gpio = tegra_gpio_compose(i, j, 0); + seq_printf(s, - "%d:%d %02x %02x %02x %02x %02x %02x %06x\n", + "%u:%u %02x %02x %02x %02x %02x %02x %06x\n", i, j, tegra_gpio_readl(tgi, GPIO_CNF(tgi, gpio)), tegra_gpio_readl(tgi, GPIO_OE(tgi, gpio)), @@ -542,7 +544,7 @@ static const struct file_operations debug_fops = { static void tegra_gpio_debuginit(struct tegra_gpio_info *tgi) { - (void) debugfs_create_file("tegra_gpio", S_IRUGO, + (void) debugfs_create_file("tegra_gpio", 0444, NULL, tgi, &debug_fops); } @@ -566,35 +568,25 @@ static struct lock_class_key gpio_lock_class; static int tegra_gpio_probe(struct platform_device *pdev) { - const struct tegra_gpio_soc_config *config; struct tegra_gpio_info *tgi; struct resource *res; struct tegra_gpio_bank *bank; + unsigned int gpio, i, j; int ret; - int gpio; - int i; - int j; - - config = of_device_get_match_data(&pdev->dev); - if (!config) { - dev_err(&pdev->dev, "Error: No device match found\n"); - return -ENODEV; - } tgi = devm_kzalloc(&pdev->dev, sizeof(*tgi), GFP_KERNEL); if (!tgi) return -ENODEV; - tgi->soc = config; + tgi->soc = of_device_get_match_data(&pdev->dev); tgi->dev = &pdev->dev; - for (;;) { - res = platform_get_resource(pdev, IORESOURCE_IRQ, - tgi->bank_count); - if (!res) - break; - tgi->bank_count++; - } + ret = platform_irq_count(pdev); + if (ret < 0) + return ret; + + tgi->bank_count = ret; + if (!tgi->bank_count) { dev_err(&pdev->dev, "Missing IRQ resource\n"); return -ENODEV; @@ -626,13 +618,13 @@ static int tegra_gpio_probe(struct platform_device *pdev) platform_set_drvdata(pdev, tgi); - if (config->debounce_supported) + if (tgi->soc->debounce_supported) tgi->gc.set_config = tegra_gpio_set_config; - tgi->bank_info = devm_kzalloc(&pdev->dev, tgi->bank_count * + tgi->bank_info = devm_kcalloc(&pdev->dev, tgi->bank_count, sizeof(*tgi->bank_info), GFP_KERNEL); if (!tgi->bank_info) - return -ENODEV; + return -ENOMEM; tgi->irq_domain = irq_domain_add_linear(pdev->dev.of_node, tgi->gc.ngpio, @@ -641,15 +633,15 @@ static int tegra_gpio_probe(struct platform_device *pdev) return -ENODEV; for (i = 0; i < tgi->bank_count; i++) { - res = platform_get_resource(pdev, IORESOURCE_IRQ, i); - if (!res) { - dev_err(&pdev->dev, "Missing IRQ resource\n"); - return -ENODEV; + ret = platform_get_irq(pdev, i); + if (ret < 0) { + dev_err(&pdev->dev, "Missing IRQ resource: %d\n", ret); + return ret; } bank = &tgi->bank_info[i]; bank->bank = i; - bank->irq = res->start; + bank->irq = ret; bank->tgi = tgi; } @@ -661,6 +653,7 @@ static int tegra_gpio_probe(struct platform_device *pdev) for (i = 0; i < tgi->bank_count; i++) { for (j = 0; j < 4; j++) { int gpio = tegra_gpio_compose(i, j, 0); + tegra_gpio_writel(tgi, 0x00, GPIO_INT_ENB(tgi, gpio)); } } |