From 102a0743326a03cd1a1202ceda21e175b7d3575c Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Tue, 20 Feb 2024 01:20:52 +0000 Subject: [PATCH] add new system file --- kernel/drivers/gpio/gpio-davinci.c | 94 +++++++++++++++++++++++----------------------- 1 files changed, 47 insertions(+), 47 deletions(-) diff --git a/kernel/drivers/gpio/gpio-davinci.c b/kernel/drivers/gpio/gpio-davinci.c index abb332d..80597e9 100644 --- a/kernel/drivers/gpio/gpio-davinci.c +++ b/kernel/drivers/gpio/gpio-davinci.c @@ -1,14 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * TI DaVinci GPIO Support * * Copyright (c) 2006-2007 David Brownell * Copyright (c) 2007, MontaVista Software, Inc. <source@mvista.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. */ + #include <linux/gpio/driver.h> #include <linux/errno.h> #include <linux/kernel.h> @@ -24,6 +21,12 @@ #include <linux/platform_device.h> #include <linux/platform_data/gpio-davinci.h> #include <linux/irqchip/chained_irq.h> +#include <linux/spinlock.h> + +#include <asm-generic/gpio.h> + +#define MAX_REGS_BANKS 5 +#define MAX_INT_PER_BANK 32 struct davinci_gpio_regs { u32 dir; @@ -41,10 +44,30 @@ typedef struct irq_chip *(*gpio_get_irq_chip_cb_t)(unsigned int irq); #define BINTEN 0x8 /* GPIO Interrupt Per-Bank Enable Register */ -#define MAX_LABEL_SIZE 20 static void __iomem *gpio_base; static unsigned int offset_array[5] = {0x10, 0x38, 0x60, 0x88, 0xb0}; + +struct davinci_gpio_irq_data { + void __iomem *regs; + struct davinci_gpio_controller *chip; + int bank_num; +}; + +struct davinci_gpio_controller { + struct gpio_chip chip; + struct irq_domain *irq_domain; + /* Serialize access to GPIO registers */ + spinlock_t lock; + void __iomem *regs[MAX_REGS_BANKS]; + int gpio_unbanked; + int irqs[MAX_INT_PER_BANK]; +}; + +static inline u32 __gpio_mask(unsigned gpio) +{ + return 1 << (gpio % 32); +} static inline struct davinci_gpio_regs __iomem *irq2regs(struct irq_data *d) { @@ -166,14 +189,11 @@ static int davinci_gpio_probe(struct platform_device *pdev) { - static int ctrl_num, bank_base; - int gpio, bank, i, ret = 0; + int bank, i, ret = 0; unsigned int ngpio, nbank, nirq; struct davinci_gpio_controller *chips; struct davinci_gpio_platform_data *pdata; struct device *dev = &pdev->dev; - struct resource *res; - char label[MAX_LABEL_SIZE]; pdata = davinci_gpio_get_pdata(pdev); if (!pdata) { @@ -207,32 +227,21 @@ else nirq = DIV_ROUND_UP(ngpio, 16); - nbank = DIV_ROUND_UP(ngpio, 32); - chips = devm_kcalloc(dev, - nbank, sizeof(struct davinci_gpio_controller), - GFP_KERNEL); + chips = devm_kzalloc(dev, sizeof(*chips), GFP_KERNEL); if (!chips) return -ENOMEM; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - gpio_base = devm_ioremap_resource(dev, res); + gpio_base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(gpio_base)) return PTR_ERR(gpio_base); for (i = 0; i < nirq; i++) { chips->irqs[i] = platform_get_irq(pdev, i); - if (chips->irqs[i] < 0) { - if (chips->irqs[i] != -EPROBE_DEFER) - dev_info(dev, "IRQ not populated, err = %d\n", - chips->irqs[i]); - return chips->irqs[i]; - } + if (chips->irqs[i] < 0) + return dev_err_probe(dev, chips->irqs[i], "IRQ not populated\n"); } - snprintf(label, MAX_LABEL_SIZE, "davinci_gpio.%d", ctrl_num++); - chips->chip.label = devm_kstrdup(dev, label, GFP_KERNEL); - if (!chips->chip.label) - return -ENOMEM; + chips->chip.label = dev_name(dev); chips->chip.direction_input = davinci_direction_in; chips->chip.get = davinci_gpio_get; @@ -240,41 +249,31 @@ chips->chip.set = davinci_gpio_set; chips->chip.ngpio = ngpio; - chips->chip.base = bank_base; + chips->chip.base = pdata->no_auto_base ? pdata->base : -1; #ifdef CONFIG_OF_GPIO chips->chip.of_gpio_n_cells = 2; chips->chip.parent = dev; chips->chip.of_node = dev->of_node; - - if (of_property_read_bool(dev->of_node, "gpio-ranges")) { - chips->chip.request = gpiochip_generic_request; - chips->chip.free = gpiochip_generic_free; - } + chips->chip.request = gpiochip_generic_request; + chips->chip.free = gpiochip_generic_free; #endif spin_lock_init(&chips->lock); - bank_base += ngpio; - for (gpio = 0, bank = 0; gpio < ngpio; gpio += 32, bank++) + nbank = DIV_ROUND_UP(ngpio, 32); + for (bank = 0; bank < nbank; bank++) chips->regs[bank] = gpio_base + offset_array[bank]; ret = devm_gpiochip_add_data(dev, &chips->chip, chips); if (ret) - goto err; + return ret; platform_set_drvdata(pdev, chips); ret = davinci_gpio_irq_setup(pdev); if (ret) - goto err; + return ret; return 0; - -err: - /* Revert the static variable increments */ - ctrl_num--; - bank_base -= ngpio; - - return ret; } /*--------------------------------------------------------------------------*/ @@ -292,7 +291,7 @@ static void gpio_irq_disable(struct irq_data *d) { struct davinci_gpio_regs __iomem *g = irq2regs(d); - u32 mask = (u32) irq_data_get_irq_handler_data(d); + uintptr_t mask = (uintptr_t)irq_data_get_irq_handler_data(d); writel_relaxed(mask, &g->clr_falling); writel_relaxed(mask, &g->clr_rising); @@ -301,7 +300,7 @@ static void gpio_irq_enable(struct irq_data *d) { struct davinci_gpio_regs __iomem *g = irq2regs(d); - u32 mask = (u32) irq_data_get_irq_handler_data(d); + uintptr_t mask = (uintptr_t)irq_data_get_irq_handler_data(d); unsigned status = irqd_get_trigger_type(d); status &= IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING; @@ -327,7 +326,7 @@ .irq_enable = gpio_irq_enable, .irq_disable = gpio_irq_disable, .irq_set_type = gpio_irq_type, - .flags = IRQCHIP_SET_TYPE_MASKED, + .flags = IRQCHIP_SET_TYPE_MASKED | IRQCHIP_SKIP_SET_WAKE, }; static void gpio_irq_handler(struct irq_desc *desc) @@ -442,7 +441,7 @@ "davinci_gpio"); irq_set_irq_type(irq, IRQ_TYPE_NONE); irq_set_chip_data(irq, (__force void *)g); - irq_set_handler_data(irq, (void *)__gpio_mask(hw)); + irq_set_handler_data(irq, (void *)(uintptr_t)__gpio_mask(hw)); return 0; } @@ -627,6 +626,7 @@ static const struct of_device_id davinci_gpio_ids[] = { { .compatible = "ti,keystone-gpio", keystone_gpio_get_irq_chip}, + { .compatible = "ti,am654-gpio", keystone_gpio_get_irq_chip}, { .compatible = "ti,dm6441-gpio", davinci_gpio_get_irq_chip}, { /* sentinel */ }, }; -- Gitblit v1.6.2