.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * Copyright (C) 2014-2017 Broadcom |
---|
3 | | - * |
---|
4 | | - * This program is free software; you can redistribute it and/or |
---|
5 | | - * modify it under the terms of the GNU General Public License as |
---|
6 | | - * published by the Free Software Foundation version 2. |
---|
7 | | - * |
---|
8 | | - * This program is distributed "as is" WITHOUT ANY WARRANTY of any |
---|
9 | | - * kind, whether express or implied; without even the implied warranty |
---|
10 | | - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
11 | | - * GNU General Public License for more details. |
---|
12 | 4 | */ |
---|
13 | 5 | |
---|
14 | 6 | /* |
---|
.. | .. |
---|
114 | 106 | |
---|
115 | 107 | raw_spinlock_t lock; |
---|
116 | 108 | |
---|
| 109 | + struct irq_chip irqchip; |
---|
117 | 110 | struct gpio_chip gc; |
---|
118 | 111 | unsigned num_banks; |
---|
119 | 112 | |
---|
.. | .. |
---|
138 | 131 | * iproc_set_bit - set or clear one bit (corresponding to the GPIO pin) in a |
---|
139 | 132 | * Iproc GPIO register |
---|
140 | 133 | * |
---|
141 | | - * @iproc_gpio: Iproc GPIO device |
---|
| 134 | + * @chip: Iproc GPIO device |
---|
142 | 135 | * @reg: register offset |
---|
143 | 136 | * @gpio: GPIO pin |
---|
144 | 137 | * @set: set or clear |
---|
.. | .. |
---|
293 | 286 | iproc_set_bit(chip, IPROC_GPIO_INT_DE_OFFSET, gpio, dual_edge); |
---|
294 | 287 | iproc_set_bit(chip, IPROC_GPIO_INT_EDGE_OFFSET, gpio, |
---|
295 | 288 | rising_or_high); |
---|
| 289 | + |
---|
| 290 | + if (type & IRQ_TYPE_EDGE_BOTH) |
---|
| 291 | + irq_set_handler_locked(d, handle_edge_irq); |
---|
| 292 | + else |
---|
| 293 | + irq_set_handler_locked(d, handle_level_irq); |
---|
| 294 | + |
---|
296 | 295 | raw_spin_unlock_irqrestore(&chip->lock, flags); |
---|
297 | 296 | |
---|
298 | 297 | dev_dbg(chip->dev, |
---|
.. | .. |
---|
301 | 300 | |
---|
302 | 301 | return 0; |
---|
303 | 302 | } |
---|
304 | | - |
---|
305 | | -static struct irq_chip iproc_gpio_irq_chip = { |
---|
306 | | - .name = "bcm-iproc-gpio", |
---|
307 | | - .irq_ack = iproc_gpio_irq_ack, |
---|
308 | | - .irq_mask = iproc_gpio_irq_mask, |
---|
309 | | - .irq_unmask = iproc_gpio_irq_unmask, |
---|
310 | | - .irq_set_type = iproc_gpio_irq_set_type, |
---|
311 | | -}; |
---|
312 | 303 | |
---|
313 | 304 | /* |
---|
314 | 305 | * Request the Iproc IOMUX pinmux controller to mux individual pins to GPIO |
---|
.. | .. |
---|
364 | 355 | dev_dbg(chip->dev, "gpio:%u set output, value:%d\n", gpio, val); |
---|
365 | 356 | |
---|
366 | 357 | return 0; |
---|
| 358 | +} |
---|
| 359 | + |
---|
| 360 | +static int iproc_gpio_get_direction(struct gpio_chip *gc, unsigned int gpio) |
---|
| 361 | +{ |
---|
| 362 | + struct iproc_gpio *chip = gpiochip_get_data(gc); |
---|
| 363 | + unsigned int offset = IPROC_GPIO_REG(gpio, IPROC_GPIO_OUT_EN_OFFSET); |
---|
| 364 | + unsigned int shift = IPROC_GPIO_SHIFT(gpio); |
---|
| 365 | + |
---|
| 366 | + if (readl(chip->base + offset) & BIT(shift)) |
---|
| 367 | + return GPIO_LINE_DIRECTION_OUT; |
---|
| 368 | + |
---|
| 369 | + return GPIO_LINE_DIRECTION_IN; |
---|
367 | 370 | } |
---|
368 | 371 | |
---|
369 | 372 | static void iproc_gpio_set(struct gpio_chip *gc, unsigned gpio, int val) |
---|
.. | .. |
---|
801 | 804 | chip->dev = dev; |
---|
802 | 805 | platform_set_drvdata(pdev, chip); |
---|
803 | 806 | |
---|
804 | | - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
---|
805 | | - chip->base = devm_ioremap_resource(dev, res); |
---|
| 807 | + chip->base = devm_platform_ioremap_resource(pdev, 0); |
---|
806 | 808 | if (IS_ERR(chip->base)) { |
---|
807 | 809 | dev_err(dev, "unable to map I/O memory\n"); |
---|
808 | 810 | return PTR_ERR(chip->base); |
---|
.. | .. |
---|
842 | 844 | gc->free = iproc_gpio_free; |
---|
843 | 845 | gc->direction_input = iproc_gpio_direction_input; |
---|
844 | 846 | gc->direction_output = iproc_gpio_direction_output; |
---|
| 847 | + gc->get_direction = iproc_gpio_get_direction; |
---|
845 | 848 | gc->set = iproc_gpio_set; |
---|
846 | 849 | gc->get = iproc_gpio_get; |
---|
847 | 850 | |
---|
848 | 851 | chip->pinmux_is_supported = of_property_read_bool(dev->of_node, |
---|
849 | 852 | "gpio-ranges"); |
---|
| 853 | + |
---|
| 854 | + /* optional GPIO interrupt support */ |
---|
| 855 | + irq = platform_get_irq_optional(pdev, 0); |
---|
| 856 | + if (irq > 0) { |
---|
| 857 | + struct irq_chip *irqc; |
---|
| 858 | + struct gpio_irq_chip *girq; |
---|
| 859 | + |
---|
| 860 | + irqc = &chip->irqchip; |
---|
| 861 | + irqc->name = dev_name(dev); |
---|
| 862 | + irqc->irq_ack = iproc_gpio_irq_ack; |
---|
| 863 | + irqc->irq_mask = iproc_gpio_irq_mask; |
---|
| 864 | + irqc->irq_unmask = iproc_gpio_irq_unmask; |
---|
| 865 | + irqc->irq_set_type = iproc_gpio_irq_set_type; |
---|
| 866 | + irqc->irq_enable = iproc_gpio_irq_unmask; |
---|
| 867 | + irqc->irq_disable = iproc_gpio_irq_mask; |
---|
| 868 | + |
---|
| 869 | + girq = &gc->irq; |
---|
| 870 | + girq->chip = irqc; |
---|
| 871 | + girq->parent_handler = iproc_gpio_irq_handler; |
---|
| 872 | + girq->num_parents = 1; |
---|
| 873 | + girq->parents = devm_kcalloc(dev, 1, |
---|
| 874 | + sizeof(*girq->parents), |
---|
| 875 | + GFP_KERNEL); |
---|
| 876 | + if (!girq->parents) |
---|
| 877 | + return -ENOMEM; |
---|
| 878 | + girq->parents[0] = irq; |
---|
| 879 | + girq->default_type = IRQ_TYPE_NONE; |
---|
| 880 | + girq->handler = handle_bad_irq; |
---|
| 881 | + } |
---|
850 | 882 | |
---|
851 | 883 | ret = gpiochip_add_data(gc, chip); |
---|
852 | 884 | if (ret < 0) { |
---|
.. | .. |
---|
870 | 902 | goto err_rm_gpiochip; |
---|
871 | 903 | } |
---|
872 | 904 | } |
---|
873 | | - } |
---|
874 | | - |
---|
875 | | - /* optional GPIO interrupt support */ |
---|
876 | | - irq = platform_get_irq(pdev, 0); |
---|
877 | | - if (irq) { |
---|
878 | | - ret = gpiochip_irqchip_add(gc, &iproc_gpio_irq_chip, 0, |
---|
879 | | - handle_simple_irq, IRQ_TYPE_NONE); |
---|
880 | | - if (ret) { |
---|
881 | | - dev_err(dev, "no GPIO irqchip\n"); |
---|
882 | | - goto err_rm_gpiochip; |
---|
883 | | - } |
---|
884 | | - |
---|
885 | | - gpiochip_set_chained_irqchip(gc, &iproc_gpio_irq_chip, irq, |
---|
886 | | - iproc_gpio_irq_handler); |
---|
887 | 905 | } |
---|
888 | 906 | |
---|
889 | 907 | return 0; |
---|