| .. | .. |
|---|
| 64 | 64 | * @gc: GPIO chip |
|---|
| 65 | 65 | * @pctl: pointer to pinctrl_dev |
|---|
| 66 | 66 | * @pctldesc: pinctrl descriptor |
|---|
| 67 | | - * @irq_domain: pointer to irq domain |
|---|
| 68 | 67 | * @lock: lock to protect access to I/O registers |
|---|
| 69 | 68 | */ |
|---|
| 70 | 69 | struct nsp_gpio { |
|---|
| 71 | 70 | struct device *dev; |
|---|
| 72 | 71 | void __iomem *base; |
|---|
| 73 | 72 | void __iomem *io_ctrl; |
|---|
| 73 | + struct irq_chip irqchip; |
|---|
| 74 | 74 | struct gpio_chip gc; |
|---|
| 75 | 75 | struct pinctrl_dev *pctl; |
|---|
| 76 | 76 | struct pinctrl_desc pctldesc; |
|---|
| 77 | | - struct irq_domain *irq_domain; |
|---|
| 78 | 77 | raw_spinlock_t lock; |
|---|
| 79 | 78 | }; |
|---|
| 80 | 79 | |
|---|
| .. | .. |
|---|
| 136 | 135 | |
|---|
| 137 | 136 | static irqreturn_t nsp_gpio_irq_handler(int irq, void *data) |
|---|
| 138 | 137 | { |
|---|
| 139 | | - struct nsp_gpio *chip = (struct nsp_gpio *)data; |
|---|
| 140 | | - struct gpio_chip gc = chip->gc; |
|---|
| 138 | + struct gpio_chip *gc = (struct gpio_chip *)data; |
|---|
| 139 | + struct nsp_gpio *chip = gpiochip_get_data(gc); |
|---|
| 141 | 140 | int bit; |
|---|
| 142 | 141 | unsigned long int_bits = 0; |
|---|
| 143 | 142 | u32 int_status; |
|---|
| .. | .. |
|---|
| 155 | 154 | level &= readl(chip->base + NSP_GPIO_INT_MASK); |
|---|
| 156 | 155 | int_bits = level | event; |
|---|
| 157 | 156 | |
|---|
| 158 | | - for_each_set_bit(bit, &int_bits, gc.ngpio) { |
|---|
| 159 | | - /* |
|---|
| 160 | | - * Clear the interrupt before invoking the |
|---|
| 161 | | - * handler, so we do not leave any window |
|---|
| 162 | | - */ |
|---|
| 163 | | - writel(BIT(bit), chip->base + NSP_GPIO_EVENT); |
|---|
| 157 | + for_each_set_bit(bit, &int_bits, gc->ngpio) |
|---|
| 164 | 158 | generic_handle_irq( |
|---|
| 165 | | - irq_linear_revmap(chip->irq_domain, bit)); |
|---|
| 166 | | - } |
|---|
| 159 | + irq_linear_revmap(gc->irq.domain, bit)); |
|---|
| 167 | 160 | } |
|---|
| 168 | 161 | |
|---|
| 169 | 162 | return int_bits ? IRQ_HANDLED : IRQ_NONE; |
|---|
| .. | .. |
|---|
| 171 | 164 | |
|---|
| 172 | 165 | static void nsp_gpio_irq_ack(struct irq_data *d) |
|---|
| 173 | 166 | { |
|---|
| 174 | | - struct nsp_gpio *chip = irq_data_get_irq_chip_data(d); |
|---|
| 167 | + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
|---|
| 168 | + struct nsp_gpio *chip = gpiochip_get_data(gc); |
|---|
| 175 | 169 | unsigned gpio = d->hwirq; |
|---|
| 176 | 170 | u32 val = BIT(gpio); |
|---|
| 177 | 171 | u32 trigger_type; |
|---|
| 178 | 172 | |
|---|
| 179 | 173 | trigger_type = irq_get_trigger_type(d->irq); |
|---|
| 180 | 174 | if (trigger_type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)) |
|---|
| 181 | | - nsp_set_bit(chip, REG, NSP_GPIO_EVENT, gpio, val); |
|---|
| 175 | + writel(val, chip->base + NSP_GPIO_EVENT); |
|---|
| 182 | 176 | } |
|---|
| 183 | 177 | |
|---|
| 184 | 178 | /* |
|---|
| .. | .. |
|---|
| 189 | 183 | */ |
|---|
| 190 | 184 | static void nsp_gpio_irq_set_mask(struct irq_data *d, bool unmask) |
|---|
| 191 | 185 | { |
|---|
| 192 | | - struct nsp_gpio *chip = irq_data_get_irq_chip_data(d); |
|---|
| 186 | + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
|---|
| 187 | + struct nsp_gpio *chip = gpiochip_get_data(gc); |
|---|
| 193 | 188 | unsigned gpio = d->hwirq; |
|---|
| 194 | 189 | u32 trigger_type; |
|---|
| 195 | 190 | |
|---|
| .. | .. |
|---|
| 202 | 197 | |
|---|
| 203 | 198 | static void nsp_gpio_irq_mask(struct irq_data *d) |
|---|
| 204 | 199 | { |
|---|
| 205 | | - struct nsp_gpio *chip = irq_data_get_irq_chip_data(d); |
|---|
| 200 | + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
|---|
| 201 | + struct nsp_gpio *chip = gpiochip_get_data(gc); |
|---|
| 206 | 202 | unsigned long flags; |
|---|
| 207 | 203 | |
|---|
| 208 | 204 | raw_spin_lock_irqsave(&chip->lock, flags); |
|---|
| .. | .. |
|---|
| 212 | 208 | |
|---|
| 213 | 209 | static void nsp_gpio_irq_unmask(struct irq_data *d) |
|---|
| 214 | 210 | { |
|---|
| 215 | | - struct nsp_gpio *chip = irq_data_get_irq_chip_data(d); |
|---|
| 211 | + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
|---|
| 212 | + struct nsp_gpio *chip = gpiochip_get_data(gc); |
|---|
| 216 | 213 | unsigned long flags; |
|---|
| 217 | 214 | |
|---|
| 218 | 215 | raw_spin_lock_irqsave(&chip->lock, flags); |
|---|
| .. | .. |
|---|
| 222 | 219 | |
|---|
| 223 | 220 | static int nsp_gpio_irq_set_type(struct irq_data *d, unsigned int type) |
|---|
| 224 | 221 | { |
|---|
| 225 | | - struct nsp_gpio *chip = irq_data_get_irq_chip_data(d); |
|---|
| 222 | + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
|---|
| 223 | + struct nsp_gpio *chip = gpiochip_get_data(gc); |
|---|
| 226 | 224 | unsigned gpio = d->hwirq; |
|---|
| 227 | 225 | bool level_low; |
|---|
| 228 | 226 | bool falling; |
|---|
| .. | .. |
|---|
| 258 | 256 | |
|---|
| 259 | 257 | nsp_set_bit(chip, REG, NSP_GPIO_EVENT_INT_POLARITY, gpio, falling); |
|---|
| 260 | 258 | nsp_set_bit(chip, REG, NSP_GPIO_INT_POLARITY, gpio, level_low); |
|---|
| 259 | + |
|---|
| 260 | + if (type & IRQ_TYPE_EDGE_BOTH) |
|---|
| 261 | + irq_set_handler_locked(d, handle_edge_irq); |
|---|
| 262 | + else |
|---|
| 263 | + irq_set_handler_locked(d, handle_level_irq); |
|---|
| 264 | + |
|---|
| 261 | 265 | raw_spin_unlock_irqrestore(&chip->lock, flags); |
|---|
| 262 | 266 | |
|---|
| 263 | 267 | dev_dbg(chip->dev, "gpio:%u level_low:%s falling:%s\n", gpio, |
|---|
| 264 | 268 | level_low ? "true" : "false", falling ? "true" : "false"); |
|---|
| 265 | 269 | return 0; |
|---|
| 266 | 270 | } |
|---|
| 267 | | - |
|---|
| 268 | | -static struct irq_chip nsp_gpio_irq_chip = { |
|---|
| 269 | | - .name = "gpio-a", |
|---|
| 270 | | - .irq_enable = nsp_gpio_irq_unmask, |
|---|
| 271 | | - .irq_disable = nsp_gpio_irq_mask, |
|---|
| 272 | | - .irq_ack = nsp_gpio_irq_ack, |
|---|
| 273 | | - .irq_mask = nsp_gpio_irq_mask, |
|---|
| 274 | | - .irq_unmask = nsp_gpio_irq_unmask, |
|---|
| 275 | | - .irq_set_type = nsp_gpio_irq_set_type, |
|---|
| 276 | | -}; |
|---|
| 277 | 271 | |
|---|
| 278 | 272 | static int nsp_gpio_direction_input(struct gpio_chip *gc, unsigned gpio) |
|---|
| 279 | 273 | { |
|---|
| .. | .. |
|---|
| 303 | 297 | return 0; |
|---|
| 304 | 298 | } |
|---|
| 305 | 299 | |
|---|
| 300 | +static int nsp_gpio_get_direction(struct gpio_chip *gc, unsigned gpio) |
|---|
| 301 | +{ |
|---|
| 302 | + struct nsp_gpio *chip = gpiochip_get_data(gc); |
|---|
| 303 | + unsigned long flags; |
|---|
| 304 | + int val; |
|---|
| 305 | + |
|---|
| 306 | + raw_spin_lock_irqsave(&chip->lock, flags); |
|---|
| 307 | + val = nsp_get_bit(chip, REG, NSP_GPIO_OUT_EN, gpio); |
|---|
| 308 | + raw_spin_unlock_irqrestore(&chip->lock, flags); |
|---|
| 309 | + |
|---|
| 310 | + return !val; |
|---|
| 311 | +} |
|---|
| 312 | + |
|---|
| 306 | 313 | static void nsp_gpio_set(struct gpio_chip *gc, unsigned gpio, int val) |
|---|
| 307 | 314 | { |
|---|
| 308 | 315 | struct nsp_gpio *chip = gpiochip_get_data(gc); |
|---|
| .. | .. |
|---|
| 320 | 327 | struct nsp_gpio *chip = gpiochip_get_data(gc); |
|---|
| 321 | 328 | |
|---|
| 322 | 329 | return !!(readl(chip->base + NSP_GPIO_DATA_IN) & BIT(gpio)); |
|---|
| 323 | | -} |
|---|
| 324 | | - |
|---|
| 325 | | -static int nsp_gpio_to_irq(struct gpio_chip *gc, unsigned offset) |
|---|
| 326 | | -{ |
|---|
| 327 | | - struct nsp_gpio *chip = gpiochip_get_data(gc); |
|---|
| 328 | | - |
|---|
| 329 | | - return irq_linear_revmap(chip->irq_domain, offset); |
|---|
| 330 | 330 | } |
|---|
| 331 | 331 | |
|---|
| 332 | 332 | static int nsp_get_groups_count(struct pinctrl_dev *pctldev) |
|---|
| .. | .. |
|---|
| 613 | 613 | static int nsp_gpio_probe(struct platform_device *pdev) |
|---|
| 614 | 614 | { |
|---|
| 615 | 615 | struct device *dev = &pdev->dev; |
|---|
| 616 | | - struct resource *res; |
|---|
| 617 | 616 | struct nsp_gpio *chip; |
|---|
| 618 | 617 | struct gpio_chip *gc; |
|---|
| 619 | | - u32 val, count; |
|---|
| 618 | + u32 val; |
|---|
| 620 | 619 | int irq, ret; |
|---|
| 621 | 620 | |
|---|
| 622 | 621 | if (of_property_read_u32(pdev->dev.of_node, "ngpios", &val)) { |
|---|
| .. | .. |
|---|
| 631 | 630 | chip->dev = dev; |
|---|
| 632 | 631 | platform_set_drvdata(pdev, chip); |
|---|
| 633 | 632 | |
|---|
| 634 | | - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
|---|
| 635 | | - chip->base = devm_ioremap_resource(dev, res); |
|---|
| 633 | + chip->base = devm_platform_ioremap_resource(pdev, 0); |
|---|
| 636 | 634 | if (IS_ERR(chip->base)) { |
|---|
| 637 | 635 | dev_err(dev, "unable to map I/O memory\n"); |
|---|
| 638 | 636 | return PTR_ERR(chip->base); |
|---|
| 639 | 637 | } |
|---|
| 640 | 638 | |
|---|
| 641 | | - res = platform_get_resource(pdev, IORESOURCE_MEM, 1); |
|---|
| 642 | | - chip->io_ctrl = devm_ioremap_resource(dev, res); |
|---|
| 639 | + chip->io_ctrl = devm_platform_ioremap_resource(pdev, 1); |
|---|
| 643 | 640 | if (IS_ERR(chip->io_ctrl)) { |
|---|
| 644 | 641 | dev_err(dev, "unable to map I/O memory\n"); |
|---|
| 645 | 642 | return PTR_ERR(chip->io_ctrl); |
|---|
| .. | .. |
|---|
| 657 | 654 | gc->free = gpiochip_generic_free; |
|---|
| 658 | 655 | gc->direction_input = nsp_gpio_direction_input; |
|---|
| 659 | 656 | gc->direction_output = nsp_gpio_direction_output; |
|---|
| 657 | + gc->get_direction = nsp_gpio_get_direction; |
|---|
| 660 | 658 | gc->set = nsp_gpio_set; |
|---|
| 661 | 659 | gc->get = nsp_gpio_get; |
|---|
| 662 | | - gc->to_irq = nsp_gpio_to_irq; |
|---|
| 663 | 660 | |
|---|
| 664 | 661 | /* optional GPIO interrupt support */ |
|---|
| 665 | 662 | irq = platform_get_irq(pdev, 0); |
|---|
| 666 | 663 | if (irq > 0) { |
|---|
| 667 | | - /* Create irq domain so that each pin can be assigned an IRQ.*/ |
|---|
| 668 | | - chip->irq_domain = irq_domain_add_linear(gc->of_node, gc->ngpio, |
|---|
| 669 | | - &irq_domain_simple_ops, |
|---|
| 670 | | - chip); |
|---|
| 671 | | - if (!chip->irq_domain) { |
|---|
| 672 | | - dev_err(&pdev->dev, "Couldn't allocate IRQ domain\n"); |
|---|
| 673 | | - return -ENXIO; |
|---|
| 674 | | - } |
|---|
| 664 | + struct gpio_irq_chip *girq; |
|---|
| 665 | + struct irq_chip *irqc; |
|---|
| 675 | 666 | |
|---|
| 676 | | - /* Map each gpio to an IRQ and set the handler for gpiolib. */ |
|---|
| 677 | | - for (count = 0; count < gc->ngpio; count++) { |
|---|
| 678 | | - int irq = irq_create_mapping(chip->irq_domain, count); |
|---|
| 679 | | - |
|---|
| 680 | | - irq_set_chip_and_handler(irq, &nsp_gpio_irq_chip, |
|---|
| 681 | | - handle_simple_irq); |
|---|
| 682 | | - irq_set_chip_data(irq, chip); |
|---|
| 683 | | - } |
|---|
| 684 | | - |
|---|
| 685 | | - /* Install ISR for this GPIO controller. */ |
|---|
| 686 | | - ret = devm_request_irq(&pdev->dev, irq, nsp_gpio_irq_handler, |
|---|
| 687 | | - IRQF_SHARED, "gpio-a", chip); |
|---|
| 688 | | - if (ret) { |
|---|
| 689 | | - dev_err(&pdev->dev, "Unable to request IRQ%d: %d\n", |
|---|
| 690 | | - irq, ret); |
|---|
| 691 | | - goto err_rm_gpiochip; |
|---|
| 692 | | - } |
|---|
| 667 | + irqc = &chip->irqchip; |
|---|
| 668 | + irqc->name = "gpio-a"; |
|---|
| 669 | + irqc->irq_ack = nsp_gpio_irq_ack; |
|---|
| 670 | + irqc->irq_mask = nsp_gpio_irq_mask; |
|---|
| 671 | + irqc->irq_unmask = nsp_gpio_irq_unmask; |
|---|
| 672 | + irqc->irq_set_type = nsp_gpio_irq_set_type; |
|---|
| 693 | 673 | |
|---|
| 694 | 674 | val = readl(chip->base + NSP_CHIP_A_INT_MASK); |
|---|
| 695 | 675 | val = val | NSP_CHIP_A_GPIO_INT_BIT; |
|---|
| 696 | 676 | writel(val, (chip->base + NSP_CHIP_A_INT_MASK)); |
|---|
| 677 | + |
|---|
| 678 | + /* Install ISR for this GPIO controller. */ |
|---|
| 679 | + ret = devm_request_irq(dev, irq, nsp_gpio_irq_handler, |
|---|
| 680 | + IRQF_SHARED, "gpio-a", &chip->gc); |
|---|
| 681 | + if (ret) { |
|---|
| 682 | + dev_err(&pdev->dev, "Unable to request IRQ%d: %d\n", |
|---|
| 683 | + irq, ret); |
|---|
| 684 | + return ret; |
|---|
| 685 | + } |
|---|
| 686 | + |
|---|
| 687 | + girq = &chip->gc.irq; |
|---|
| 688 | + girq->chip = irqc; |
|---|
| 689 | + /* This will let us handle the parent IRQ in the driver */ |
|---|
| 690 | + girq->parent_handler = NULL; |
|---|
| 691 | + girq->num_parents = 0; |
|---|
| 692 | + girq->parents = NULL; |
|---|
| 693 | + girq->default_type = IRQ_TYPE_NONE; |
|---|
| 694 | + girq->handler = handle_bad_irq; |
|---|
| 697 | 695 | } |
|---|
| 698 | 696 | |
|---|
| 699 | | - ret = gpiochip_add_data(gc, chip); |
|---|
| 697 | + ret = devm_gpiochip_add_data(dev, gc, chip); |
|---|
| 700 | 698 | if (ret < 0) { |
|---|
| 701 | 699 | dev_err(dev, "unable to add GPIO chip\n"); |
|---|
| 702 | 700 | return ret; |
|---|
| .. | .. |
|---|
| 705 | 703 | ret = nsp_gpio_register_pinconf(chip); |
|---|
| 706 | 704 | if (ret) { |
|---|
| 707 | 705 | dev_err(dev, "unable to register pinconf\n"); |
|---|
| 708 | | - goto err_rm_gpiochip; |
|---|
| 706 | + return ret; |
|---|
| 709 | 707 | } |
|---|
| 710 | 708 | |
|---|
| 711 | 709 | return 0; |
|---|
| 712 | | - |
|---|
| 713 | | -err_rm_gpiochip: |
|---|
| 714 | | - gpiochip_remove(gc); |
|---|
| 715 | | - |
|---|
| 716 | | - return ret; |
|---|
| 717 | 710 | } |
|---|
| 718 | 711 | |
|---|
| 719 | 712 | static struct platform_driver nsp_gpio_driver = { |
|---|