--- zzzz-none-000/linux-3.10.107/drivers/pinctrl/spear/pinctrl-plgpio.c 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/drivers/pinctrl/spear/pinctrl-plgpio.c 2021-02-04 17:41:59.000000000 +0000 @@ -11,12 +11,11 @@ #include #include -#include +#include #include -#include -#include -#include #include +#include +#include #include #include #include @@ -54,7 +53,6 @@ * * lock: lock for guarding gpio registers * base: base address of plgpio block - * irq_base: irq number of plgpio0 * chip: gpio framework specific chip information structure * p2o: function ptr for pin to offset conversion. This is required only for * machines where mapping b/w pin and offset is not 1-to-1. @@ -68,8 +66,6 @@ spinlock_t lock; void __iomem *base; struct clk *clk; - unsigned irq_base; - struct irq_domain *irq_domain; struct gpio_chip chip; int (*p2o)(int pin); /* pin_to_offset */ int (*o2p)(int offset); /* offset_to_pin */ @@ -280,21 +276,12 @@ pinctrl_free_gpio(gpio); } -static int plgpio_to_irq(struct gpio_chip *chip, unsigned offset) -{ - struct plgpio *plgpio = container_of(chip, struct plgpio, chip); - - if (IS_ERR_VALUE(plgpio->irq_base)) - return -EINVAL; - - return irq_find_mapping(plgpio->irq_domain, offset); -} - /* PLGPIO IRQ */ static void plgpio_irq_disable(struct irq_data *d) { - struct plgpio *plgpio = irq_data_get_irq_chip_data(d); - int offset = d->irq - plgpio->irq_base; + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct plgpio *plgpio = container_of(gc, struct plgpio, chip); + int offset = d->hwirq; unsigned long flags; /* get correct offset for "offset" pin */ @@ -311,8 +298,9 @@ static void plgpio_irq_enable(struct irq_data *d) { - struct plgpio *plgpio = irq_data_get_irq_chip_data(d); - int offset = d->irq - plgpio->irq_base; + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct plgpio *plgpio = container_of(gc, struct plgpio, chip); + int offset = d->hwirq; unsigned long flags; /* get correct offset for "offset" pin */ @@ -329,8 +317,9 @@ static int plgpio_irq_set_type(struct irq_data *d, unsigned trigger) { - struct plgpio *plgpio = irq_data_get_irq_chip_data(d); - int offset = d->irq - plgpio->irq_base; + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct plgpio *plgpio = container_of(gc, struct plgpio, chip); + int offset = d->hwirq; void __iomem *reg_off; unsigned int supported_type = 0, val; @@ -367,9 +356,10 @@ .irq_set_type = plgpio_irq_set_type, }; -static void plgpio_irq_handler(unsigned irq, struct irq_desc *desc) +static void plgpio_irq_handler(struct irq_desc *desc) { - struct plgpio *plgpio = irq_get_handler_data(irq); + struct gpio_chip *gc = irq_desc_get_handler_data(desc); + struct plgpio *plgpio = container_of(gc, struct plgpio, chip); struct irq_chip *irqchip = irq_desc_get_chip(desc); int regs_count, count, pin, offset, i = 0; unsigned long pending; @@ -410,7 +400,8 @@ /* get correct irq line number */ pin = i * MAX_GPIO_PER_REG + pin; - generic_handle_irq(plgpio_to_irq(&plgpio->chip, pin)); + generic_handle_irq( + irq_find_mapping(gc->irqdomain, pin)); } } chained_irq_exit(irqchip, desc); @@ -441,7 +432,7 @@ return offset; } -int spear310_o2p(int offset) +static int spear310_o2p(int offset) { if (offset <= 3) return 101 - offset; @@ -523,16 +514,9 @@ } static int plgpio_probe(struct platform_device *pdev) { - struct device_node *np = pdev->dev.of_node; struct plgpio *plgpio; struct resource *res; - int ret, irq, i; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(&pdev->dev, "invalid IORESOURCE_MEM\n"); - return -EBUSY; - } + int ret, irq; plgpio = devm_kzalloc(&pdev->dev, sizeof(*plgpio), GFP_KERNEL); if (!plgpio) { @@ -540,6 +524,7 @@ return -ENOMEM; } + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); plgpio->base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(plgpio->base)) return PTR_ERR(plgpio->base); @@ -568,7 +553,6 @@ platform_set_drvdata(pdev, plgpio); spin_lock_init(&plgpio->lock); - plgpio->irq_base = -1; plgpio->chip.base = -1; plgpio->chip.request = plgpio_request; plgpio->chip.free = plgpio_free; @@ -576,10 +560,10 @@ plgpio->chip.direction_output = plgpio_direction_output; plgpio->chip.get = plgpio_get_value; plgpio->chip.set = plgpio_set_value; - plgpio->chip.to_irq = plgpio_to_irq; plgpio->chip.label = dev_name(&pdev->dev); plgpio->chip.dev = &pdev->dev; plgpio->chip.owner = THIS_MODULE; + plgpio->chip.of_node = pdev->dev.of_node; if (!IS_ERR(plgpio->clk)) { ret = clk_prepare(plgpio->clk); @@ -597,43 +581,32 @@ irq = platform_get_irq(pdev, 0); if (irq < 0) { - dev_info(&pdev->dev, "irqs not supported\n"); - return 0; - } - - plgpio->irq_base = irq_alloc_descs(-1, 0, plgpio->chip.ngpio, 0); - if (IS_ERR_VALUE(plgpio->irq_base)) { - /* we would not support irq for gpio */ - dev_warn(&pdev->dev, "couldn't allocate irq base\n"); + dev_info(&pdev->dev, "PLGPIO registered without IRQs\n"); return 0; } - plgpio->irq_domain = irq_domain_add_legacy(np, plgpio->chip.ngpio, - plgpio->irq_base, 0, &irq_domain_simple_ops, NULL); - if (WARN_ON(!plgpio->irq_domain)) { - dev_err(&pdev->dev, "irq domain init failed\n"); - irq_free_descs(plgpio->irq_base, plgpio->chip.ngpio); - ret = -ENXIO; + ret = gpiochip_irqchip_add(&plgpio->chip, + &plgpio_irqchip, + 0, + handle_simple_irq, + IRQ_TYPE_NONE); + if (ret) { + dev_err(&pdev->dev, "failed to add irqchip to gpiochip\n"); goto remove_gpiochip; } - irq_set_chained_handler(irq, plgpio_irq_handler); - for (i = 0; i < plgpio->chip.ngpio; i++) { - irq_set_chip_and_handler(i + plgpio->irq_base, &plgpio_irqchip, - handle_simple_irq); - set_irq_flags(i + plgpio->irq_base, IRQF_VALID); - irq_set_chip_data(i + plgpio->irq_base, plgpio); - } + gpiochip_set_chained_irqchip(&plgpio->chip, + &plgpio_irqchip, + irq, + plgpio_irq_handler); - irq_set_handler_data(irq, plgpio); dev_info(&pdev->dev, "PLGPIO registered with IRQs\n"); return 0; remove_gpiochip: dev_info(&pdev->dev, "Remove gpiochip\n"); - if (gpiochip_remove(&plgpio->chip)) - dev_err(&pdev->dev, "unable to remove gpiochip\n"); + gpiochip_remove(&plgpio->chip); unprepare_clk: if (!IS_ERR(plgpio->clk)) clk_unprepare(plgpio->clk); @@ -737,10 +710,9 @@ static struct platform_driver plgpio_driver = { .probe = plgpio_probe, .driver = { - .owner = THIS_MODULE, .name = "spear-plgpio", .pm = &plgpio_dev_pm_ops, - .of_match_table = of_match_ptr(plgpio_of_match), + .of_match_table = plgpio_of_match, }, }; @@ -751,5 +723,5 @@ subsys_initcall(plgpio_init); MODULE_AUTHOR("Viresh Kumar "); -MODULE_DESCRIPTION("ST Microlectronics SPEAr PLGPIO driver"); +MODULE_DESCRIPTION("STMicroelectronics SPEAr PLGPIO driver"); MODULE_LICENSE("GPL");