linux/drivers/gpio/gpio-xgs-iproc.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Copyright (C) 2017 Broadcom
   4 */
   5
   6#include <linux/gpio/driver.h>
   7#include <linux/init.h>
   8#include <linux/interrupt.h>
   9#include <linux/io.h>
  10#include <linux/irq.h>
  11#include <linux/kernel.h>
  12#include <linux/module.h>
  13#include <linux/platform_device.h>
  14#include <linux/spinlock.h>
  15
  16#define IPROC_CCA_INT_F_GPIOINT         BIT(0)
  17#define IPROC_CCA_INT_STS               0x20
  18#define IPROC_CCA_INT_MASK              0x24
  19
  20#define IPROC_GPIO_CCA_DIN              0x0
  21#define IPROC_GPIO_CCA_DOUT             0x4
  22#define IPROC_GPIO_CCA_OUT_EN           0x8
  23#define IPROC_GPIO_CCA_INT_LEVEL        0x10
  24#define IPROC_GPIO_CCA_INT_LEVEL_MASK   0x14
  25#define IPROC_GPIO_CCA_INT_EVENT        0x18
  26#define IPROC_GPIO_CCA_INT_EVENT_MASK   0x1C
  27#define IPROC_GPIO_CCA_INT_EDGE         0x24
  28
  29struct iproc_gpio_chip {
  30        struct irq_chip irqchip;
  31        struct gpio_chip gc;
  32        spinlock_t lock;
  33        struct device *dev;
  34        void __iomem *base;
  35        void __iomem *intr;
  36};
  37
  38static inline struct iproc_gpio_chip *
  39to_iproc_gpio(struct gpio_chip *gc)
  40{
  41        return container_of(gc, struct iproc_gpio_chip, gc);
  42}
  43
  44static void iproc_gpio_irq_ack(struct irq_data *d)
  45{
  46        struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
  47        struct iproc_gpio_chip *chip = to_iproc_gpio(gc);
  48        int pin = d->hwirq;
  49        unsigned long flags;
  50        u32 irq = d->irq;
  51        u32 irq_type, event_status = 0;
  52
  53        spin_lock_irqsave(&chip->lock, flags);
  54        irq_type = irq_get_trigger_type(irq);
  55        if (irq_type & IRQ_TYPE_EDGE_BOTH) {
  56                event_status |= BIT(pin);
  57                writel_relaxed(event_status,
  58                               chip->base + IPROC_GPIO_CCA_INT_EVENT);
  59        }
  60        spin_unlock_irqrestore(&chip->lock, flags);
  61}
  62
  63static void iproc_gpio_irq_unmask(struct irq_data *d)
  64{
  65        struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
  66        struct iproc_gpio_chip *chip = to_iproc_gpio(gc);
  67        int pin = d->hwirq;
  68        unsigned long flags;
  69        u32 irq = d->irq;
  70        u32 int_mask, irq_type, event_mask;
  71
  72        spin_lock_irqsave(&chip->lock, flags);
  73        irq_type = irq_get_trigger_type(irq);
  74        event_mask = readl_relaxed(chip->base + IPROC_GPIO_CCA_INT_EVENT_MASK);
  75        int_mask = readl_relaxed(chip->base + IPROC_GPIO_CCA_INT_LEVEL_MASK);
  76
  77        if (irq_type & IRQ_TYPE_EDGE_BOTH) {
  78                event_mask |= 1 << pin;
  79                writel_relaxed(event_mask,
  80                               chip->base + IPROC_GPIO_CCA_INT_EVENT_MASK);
  81        } else {
  82                int_mask |= 1 << pin;
  83                writel_relaxed(int_mask,
  84                               chip->base + IPROC_GPIO_CCA_INT_LEVEL_MASK);
  85        }
  86        spin_unlock_irqrestore(&chip->lock, flags);
  87}
  88
  89static void iproc_gpio_irq_mask(struct irq_data *d)
  90{
  91        struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
  92        struct iproc_gpio_chip *chip = to_iproc_gpio(gc);
  93        int pin = d->hwirq;
  94        unsigned long flags;
  95        u32 irq = d->irq;
  96        u32 irq_type, int_mask, event_mask;
  97
  98        spin_lock_irqsave(&chip->lock, flags);
  99        irq_type = irq_get_trigger_type(irq);
 100        event_mask = readl_relaxed(chip->base + IPROC_GPIO_CCA_INT_EVENT_MASK);
 101        int_mask = readl_relaxed(chip->base + IPROC_GPIO_CCA_INT_LEVEL_MASK);
 102
 103        if (irq_type & IRQ_TYPE_EDGE_BOTH) {
 104                event_mask &= ~BIT(pin);
 105                writel_relaxed(event_mask,
 106                               chip->base + IPROC_GPIO_CCA_INT_EVENT_MASK);
 107        } else {
 108                int_mask &= ~BIT(pin);
 109                writel_relaxed(int_mask,
 110                               chip->base + IPROC_GPIO_CCA_INT_LEVEL_MASK);
 111        }
 112        spin_unlock_irqrestore(&chip->lock, flags);
 113}
 114
 115static int iproc_gpio_irq_set_type(struct irq_data *d, u32 type)
 116{
 117        struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
 118        struct iproc_gpio_chip *chip = to_iproc_gpio(gc);
 119        int pin = d->hwirq;
 120        unsigned long flags;
 121        u32 irq = d->irq;
 122        u32 event_pol, int_pol;
 123        int ret = 0;
 124
 125        spin_lock_irqsave(&chip->lock, flags);
 126        switch (type & IRQ_TYPE_SENSE_MASK) {
 127        case IRQ_TYPE_EDGE_RISING:
 128                event_pol = readl_relaxed(chip->base + IPROC_GPIO_CCA_INT_EDGE);
 129                event_pol &= ~BIT(pin);
 130                writel_relaxed(event_pol, chip->base + IPROC_GPIO_CCA_INT_EDGE);
 131                break;
 132        case IRQ_TYPE_EDGE_FALLING:
 133                event_pol = readl_relaxed(chip->base + IPROC_GPIO_CCA_INT_EDGE);
 134                event_pol |= BIT(pin);
 135                writel_relaxed(event_pol, chip->base + IPROC_GPIO_CCA_INT_EDGE);
 136                break;
 137        case IRQ_TYPE_LEVEL_HIGH:
 138                int_pol = readl_relaxed(chip->base + IPROC_GPIO_CCA_INT_LEVEL);
 139                int_pol &= ~BIT(pin);
 140                writel_relaxed(int_pol, chip->base + IPROC_GPIO_CCA_INT_LEVEL);
 141                break;
 142        case IRQ_TYPE_LEVEL_LOW:
 143                int_pol = readl_relaxed(chip->base + IPROC_GPIO_CCA_INT_LEVEL);
 144                int_pol |= BIT(pin);
 145                writel_relaxed(int_pol, chip->base + IPROC_GPIO_CCA_INT_LEVEL);
 146                break;
 147        default:
 148                /* should not come here */
 149                ret = -EINVAL;
 150                goto out_unlock;
 151        }
 152
 153        if (type & IRQ_TYPE_LEVEL_MASK)
 154                irq_set_handler_locked(irq_get_irq_data(irq), handle_level_irq);
 155        else if (type & IRQ_TYPE_EDGE_BOTH)
 156                irq_set_handler_locked(irq_get_irq_data(irq), handle_edge_irq);
 157
 158out_unlock:
 159        spin_unlock_irqrestore(&chip->lock, flags);
 160
 161        return ret;
 162}
 163
 164static irqreturn_t iproc_gpio_irq_handler(int irq, void *data)
 165{
 166        struct gpio_chip *gc = (struct gpio_chip *)data;
 167        struct iproc_gpio_chip *chip = to_iproc_gpio(gc);
 168        int bit;
 169        unsigned long int_bits = 0;
 170        u32 int_status;
 171
 172        /* go through the entire GPIOs and handle all interrupts */
 173        int_status = readl_relaxed(chip->intr + IPROC_CCA_INT_STS);
 174        if (int_status & IPROC_CCA_INT_F_GPIOINT) {
 175                u32 event, level;
 176
 177                /* Get level and edge interrupts */
 178                event =
 179                    readl_relaxed(chip->base + IPROC_GPIO_CCA_INT_EVENT_MASK);
 180                event &= readl_relaxed(chip->base + IPROC_GPIO_CCA_INT_EVENT);
 181                level = readl_relaxed(chip->base + IPROC_GPIO_CCA_DIN);
 182                level ^= readl_relaxed(chip->base + IPROC_GPIO_CCA_INT_LEVEL);
 183                level &=
 184                    readl_relaxed(chip->base + IPROC_GPIO_CCA_INT_LEVEL_MASK);
 185                int_bits = level | event;
 186
 187                for_each_set_bit(bit, &int_bits, gc->ngpio)
 188                        generic_handle_domain_irq(gc->irq.domain, bit);
 189        }
 190
 191        return int_bits ? IRQ_HANDLED : IRQ_NONE;
 192}
 193
 194static int iproc_gpio_probe(struct platform_device *pdev)
 195{
 196        struct device *dev = &pdev->dev;
 197        struct device_node *dn = pdev->dev.of_node;
 198        struct iproc_gpio_chip *chip;
 199        u32 num_gpios;
 200        int irq, ret;
 201
 202        chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
 203        if (!chip)
 204                return -ENOMEM;
 205
 206        chip->dev = dev;
 207        platform_set_drvdata(pdev, chip);
 208        spin_lock_init(&chip->lock);
 209
 210        chip->base = devm_platform_ioremap_resource(pdev, 0);
 211        if (IS_ERR(chip->base))
 212                return PTR_ERR(chip->base);
 213
 214        ret = bgpio_init(&chip->gc, dev, 4,
 215                         chip->base + IPROC_GPIO_CCA_DIN,
 216                         chip->base + IPROC_GPIO_CCA_DOUT,
 217                         NULL,
 218                         chip->base + IPROC_GPIO_CCA_OUT_EN,
 219                         NULL,
 220                         0);
 221        if (ret) {
 222                dev_err(dev, "unable to init GPIO chip\n");
 223                return ret;
 224        }
 225
 226        chip->gc.label = dev_name(dev);
 227        if (!of_property_read_u32(dn, "ngpios", &num_gpios))
 228                chip->gc.ngpio = num_gpios;
 229
 230        irq = platform_get_irq(pdev, 0);
 231        if (irq > 0) {
 232                struct gpio_irq_chip *girq;
 233                struct irq_chip *irqc;
 234                u32 val;
 235
 236                irqc = &chip->irqchip;
 237                irqc->name = dev_name(dev);
 238                irqc->irq_ack = iproc_gpio_irq_ack;
 239                irqc->irq_mask = iproc_gpio_irq_mask;
 240                irqc->irq_unmask = iproc_gpio_irq_unmask;
 241                irqc->irq_set_type = iproc_gpio_irq_set_type;
 242
 243                chip->intr = devm_platform_ioremap_resource(pdev, 1);
 244                if (IS_ERR(chip->intr))
 245                        return PTR_ERR(chip->intr);
 246
 247                /* Enable GPIO interrupts for CCA GPIO */
 248                val = readl_relaxed(chip->intr + IPROC_CCA_INT_MASK);
 249                val |= IPROC_CCA_INT_F_GPIOINT;
 250                writel_relaxed(val, chip->intr + IPROC_CCA_INT_MASK);
 251
 252                /*
 253                 * Directly request the irq here instead of passing
 254                 * a flow-handler because the irq is shared.
 255                 */
 256                ret = devm_request_irq(dev, irq, iproc_gpio_irq_handler,
 257                                       IRQF_SHARED, chip->gc.label, &chip->gc);
 258                if (ret) {
 259                        dev_err(dev, "Fail to request IRQ%d: %d\n", irq, ret);
 260                        return ret;
 261                }
 262
 263                girq = &chip->gc.irq;
 264                girq->chip = irqc;
 265                /* This will let us handle the parent IRQ in the driver */
 266                girq->parent_handler = NULL;
 267                girq->num_parents = 0;
 268                girq->parents = NULL;
 269                girq->default_type = IRQ_TYPE_NONE;
 270                girq->handler = handle_simple_irq;
 271        }
 272
 273        ret = devm_gpiochip_add_data(dev, &chip->gc, chip);
 274        if (ret) {
 275                dev_err(dev, "unable to add GPIO chip\n");
 276                return ret;
 277        }
 278
 279        return 0;
 280}
 281
 282static int iproc_gpio_remove(struct platform_device *pdev)
 283{
 284        struct iproc_gpio_chip *chip;
 285
 286        chip = platform_get_drvdata(pdev);
 287        if (!chip)
 288                return -ENODEV;
 289
 290        if (chip->intr) {
 291                u32 val;
 292
 293                val = readl_relaxed(chip->intr + IPROC_CCA_INT_MASK);
 294                val &= ~IPROC_CCA_INT_F_GPIOINT;
 295                writel_relaxed(val, chip->intr + IPROC_CCA_INT_MASK);
 296        }
 297
 298        return 0;
 299}
 300
 301static const struct of_device_id bcm_iproc_gpio_of_match[] = {
 302        { .compatible = "brcm,iproc-gpio-cca" },
 303        {}
 304};
 305MODULE_DEVICE_TABLE(of, bcm_iproc_gpio_of_match);
 306
 307static struct platform_driver bcm_iproc_gpio_driver = {
 308        .driver = {
 309                .name = "iproc-xgs-gpio",
 310                .of_match_table = bcm_iproc_gpio_of_match,
 311        },
 312        .probe = iproc_gpio_probe,
 313        .remove = iproc_gpio_remove,
 314};
 315
 316module_platform_driver(bcm_iproc_gpio_driver);
 317
 318MODULE_DESCRIPTION("XGS IPROC GPIO driver");
 319MODULE_LICENSE("GPL v2");
 320