326 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Copyright (C) 2017 Broadcom4 */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/seq_file.h>15#include <linux/spinlock.h>16 17#define IPROC_CCA_INT_F_GPIOINT BIT(0)18#define IPROC_CCA_INT_STS 0x2019#define IPROC_CCA_INT_MASK 0x2420 21#define IPROC_GPIO_CCA_DIN 0x022#define IPROC_GPIO_CCA_DOUT 0x423#define IPROC_GPIO_CCA_OUT_EN 0x824#define IPROC_GPIO_CCA_INT_LEVEL 0x1025#define IPROC_GPIO_CCA_INT_LEVEL_MASK 0x1426#define IPROC_GPIO_CCA_INT_EVENT 0x1827#define IPROC_GPIO_CCA_INT_EVENT_MASK 0x1C28#define IPROC_GPIO_CCA_INT_EDGE 0x2429 30struct iproc_gpio_chip {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 gpiochip_enable_irq(gc, pin);73 spin_lock_irqsave(&chip->lock, flags);74 irq_type = irq_get_trigger_type(irq);75 event_mask = readl_relaxed(chip->base + IPROC_GPIO_CCA_INT_EVENT_MASK);76 int_mask = readl_relaxed(chip->base + IPROC_GPIO_CCA_INT_LEVEL_MASK);77 78 if (irq_type & IRQ_TYPE_EDGE_BOTH) {79 event_mask |= 1 << pin;80 writel_relaxed(event_mask,81 chip->base + IPROC_GPIO_CCA_INT_EVENT_MASK);82 } else {83 int_mask |= 1 << pin;84 writel_relaxed(int_mask,85 chip->base + IPROC_GPIO_CCA_INT_LEVEL_MASK);86 }87 spin_unlock_irqrestore(&chip->lock, flags);88}89 90static void iproc_gpio_irq_mask(struct irq_data *d)91{92 struct gpio_chip *gc = irq_data_get_irq_chip_data(d);93 struct iproc_gpio_chip *chip = to_iproc_gpio(gc);94 int pin = d->hwirq;95 unsigned long flags;96 u32 irq = d->irq;97 u32 irq_type, int_mask, event_mask;98 99 spin_lock_irqsave(&chip->lock, flags);100 irq_type = irq_get_trigger_type(irq);101 event_mask = readl_relaxed(chip->base + IPROC_GPIO_CCA_INT_EVENT_MASK);102 int_mask = readl_relaxed(chip->base + IPROC_GPIO_CCA_INT_LEVEL_MASK);103 104 if (irq_type & IRQ_TYPE_EDGE_BOTH) {105 event_mask &= ~BIT(pin);106 writel_relaxed(event_mask,107 chip->base + IPROC_GPIO_CCA_INT_EVENT_MASK);108 } else {109 int_mask &= ~BIT(pin);110 writel_relaxed(int_mask,111 chip->base + IPROC_GPIO_CCA_INT_LEVEL_MASK);112 }113 spin_unlock_irqrestore(&chip->lock, flags);114 gpiochip_disable_irq(gc, pin);115}116 117static int iproc_gpio_irq_set_type(struct irq_data *d, u32 type)118{119 struct gpio_chip *gc = irq_data_get_irq_chip_data(d);120 struct iproc_gpio_chip *chip = to_iproc_gpio(gc);121 int pin = d->hwirq;122 unsigned long flags;123 u32 irq = d->irq;124 u32 event_pol, int_pol;125 int ret = 0;126 127 spin_lock_irqsave(&chip->lock, flags);128 switch (type & IRQ_TYPE_SENSE_MASK) {129 case IRQ_TYPE_EDGE_RISING:130 event_pol = readl_relaxed(chip->base + IPROC_GPIO_CCA_INT_EDGE);131 event_pol &= ~BIT(pin);132 writel_relaxed(event_pol, chip->base + IPROC_GPIO_CCA_INT_EDGE);133 break;134 case IRQ_TYPE_EDGE_FALLING:135 event_pol = readl_relaxed(chip->base + IPROC_GPIO_CCA_INT_EDGE);136 event_pol |= BIT(pin);137 writel_relaxed(event_pol, chip->base + IPROC_GPIO_CCA_INT_EDGE);138 break;139 case IRQ_TYPE_LEVEL_HIGH:140 int_pol = readl_relaxed(chip->base + IPROC_GPIO_CCA_INT_LEVEL);141 int_pol &= ~BIT(pin);142 writel_relaxed(int_pol, chip->base + IPROC_GPIO_CCA_INT_LEVEL);143 break;144 case IRQ_TYPE_LEVEL_LOW:145 int_pol = readl_relaxed(chip->base + IPROC_GPIO_CCA_INT_LEVEL);146 int_pol |= BIT(pin);147 writel_relaxed(int_pol, chip->base + IPROC_GPIO_CCA_INT_LEVEL);148 break;149 default:150 /* should not come here */151 ret = -EINVAL;152 goto out_unlock;153 }154 155 if (type & IRQ_TYPE_LEVEL_MASK)156 irq_set_handler_locked(irq_get_irq_data(irq), handle_level_irq);157 else if (type & IRQ_TYPE_EDGE_BOTH)158 irq_set_handler_locked(irq_get_irq_data(irq), handle_edge_irq);159 160out_unlock:161 spin_unlock_irqrestore(&chip->lock, flags);162 163 return ret;164}165 166static irqreturn_t iproc_gpio_irq_handler(int irq, void *data)167{168 struct gpio_chip *gc = (struct gpio_chip *)data;169 struct iproc_gpio_chip *chip = to_iproc_gpio(gc);170 int bit;171 unsigned long int_bits = 0;172 u32 int_status;173 174 /* go through the entire GPIOs and handle all interrupts */175 int_status = readl_relaxed(chip->intr + IPROC_CCA_INT_STS);176 if (int_status & IPROC_CCA_INT_F_GPIOINT) {177 u32 event, level;178 179 /* Get level and edge interrupts */180 event =181 readl_relaxed(chip->base + IPROC_GPIO_CCA_INT_EVENT_MASK);182 event &= readl_relaxed(chip->base + IPROC_GPIO_CCA_INT_EVENT);183 level = readl_relaxed(chip->base + IPROC_GPIO_CCA_DIN);184 level ^= readl_relaxed(chip->base + IPROC_GPIO_CCA_INT_LEVEL);185 level &=186 readl_relaxed(chip->base + IPROC_GPIO_CCA_INT_LEVEL_MASK);187 int_bits = level | event;188 189 for_each_set_bit(bit, &int_bits, gc->ngpio)190 generic_handle_domain_irq(gc->irq.domain, bit);191 }192 193 return int_bits ? IRQ_HANDLED : IRQ_NONE;194}195 196static void iproc_gpio_irq_print_chip(struct irq_data *d, struct seq_file *p)197{198 struct gpio_chip *gc = irq_data_get_irq_chip_data(d);199 struct iproc_gpio_chip *chip = to_iproc_gpio(gc);200 201 seq_printf(p, dev_name(chip->dev));202}203 204static const struct irq_chip iproc_gpio_irq_chip = {205 .irq_ack = iproc_gpio_irq_ack,206 .irq_mask = iproc_gpio_irq_mask,207 .irq_unmask = iproc_gpio_irq_unmask,208 .irq_set_type = iproc_gpio_irq_set_type,209 .irq_print_chip = iproc_gpio_irq_print_chip,210 .flags = IRQCHIP_IMMUTABLE,211 GPIOCHIP_IRQ_RESOURCE_HELPERS,212};213 214static int iproc_gpio_probe(struct platform_device *pdev)215{216 struct device *dev = &pdev->dev;217 struct device_node *dn = pdev->dev.of_node;218 struct iproc_gpio_chip *chip;219 u32 num_gpios;220 int irq, ret;221 222 chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);223 if (!chip)224 return -ENOMEM;225 226 chip->dev = dev;227 platform_set_drvdata(pdev, chip);228 spin_lock_init(&chip->lock);229 230 chip->base = devm_platform_ioremap_resource(pdev, 0);231 if (IS_ERR(chip->base))232 return PTR_ERR(chip->base);233 234 ret = bgpio_init(&chip->gc, dev, 4,235 chip->base + IPROC_GPIO_CCA_DIN,236 chip->base + IPROC_GPIO_CCA_DOUT,237 NULL,238 chip->base + IPROC_GPIO_CCA_OUT_EN,239 NULL,240 0);241 if (ret) {242 dev_err(dev, "unable to init GPIO chip\n");243 return ret;244 }245 246 chip->gc.label = dev_name(dev);247 if (!of_property_read_u32(dn, "ngpios", &num_gpios))248 chip->gc.ngpio = num_gpios;249 250 irq = platform_get_irq(pdev, 0);251 if (irq > 0) {252 struct gpio_irq_chip *girq;253 u32 val;254 255 chip->intr = devm_platform_ioremap_resource(pdev, 1);256 if (IS_ERR(chip->intr))257 return PTR_ERR(chip->intr);258 259 /* Enable GPIO interrupts for CCA GPIO */260 val = readl_relaxed(chip->intr + IPROC_CCA_INT_MASK);261 val |= IPROC_CCA_INT_F_GPIOINT;262 writel_relaxed(val, chip->intr + IPROC_CCA_INT_MASK);263 264 /*265 * Directly request the irq here instead of passing266 * a flow-handler because the irq is shared.267 */268 ret = devm_request_irq(dev, irq, iproc_gpio_irq_handler,269 IRQF_SHARED, chip->gc.label, &chip->gc);270 if (ret) {271 dev_err(dev, "Fail to request IRQ%d: %d\n", irq, ret);272 return ret;273 }274 275 girq = &chip->gc.irq;276 gpio_irq_chip_set_chip(girq, &iproc_gpio_irq_chip);277 /* This will let us handle the parent IRQ in the driver */278 girq->parent_handler = NULL;279 girq->num_parents = 0;280 girq->parents = NULL;281 girq->default_type = IRQ_TYPE_NONE;282 girq->handler = handle_simple_irq;283 }284 285 ret = devm_gpiochip_add_data(dev, &chip->gc, chip);286 if (ret) {287 dev_err(dev, "unable to add GPIO chip\n");288 return ret;289 }290 291 return 0;292}293 294static void iproc_gpio_remove(struct platform_device *pdev)295{296 struct iproc_gpio_chip *chip = platform_get_drvdata(pdev);297 298 if (chip->intr) {299 u32 val;300 301 val = readl_relaxed(chip->intr + IPROC_CCA_INT_MASK);302 val &= ~IPROC_CCA_INT_F_GPIOINT;303 writel_relaxed(val, chip->intr + IPROC_CCA_INT_MASK);304 }305}306 307static const struct of_device_id bcm_iproc_gpio_of_match[] = {308 { .compatible = "brcm,iproc-gpio-cca" },309 {}310};311MODULE_DEVICE_TABLE(of, bcm_iproc_gpio_of_match);312 313static struct platform_driver bcm_iproc_gpio_driver = {314 .driver = {315 .name = "iproc-xgs-gpio",316 .of_match_table = bcm_iproc_gpio_of_match,317 },318 .probe = iproc_gpio_probe,319 .remove_new = iproc_gpio_remove,320};321 322module_platform_driver(bcm_iproc_gpio_driver);323 324MODULE_DESCRIPTION("XGS IPROC GPIO driver");325MODULE_LICENSE("GPL v2");326