1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Copyright (C) 2013 Altera Corporation 4 * Based on gpio-mpc8xxx.c 5 */ 6 7 #include <linux/bitops.h> 8 #include <linux/device.h> 9 #include <linux/err.h> 10 #include <linux/io.h> 11 #include <linux/irq.h> 12 #include <linux/mod_devicetable.h> 13 #include <linux/module.h> 14 #include <linux/platform_device.h> 15 #include <linux/property.h> 16 #include <linux/spinlock.h> 17 #include <linux/types.h> 18 19 #include <linux/gpio/driver.h> 20 #include <linux/gpio/generic.h> 21 22 #define ALTERA_GPIO_MAX_NGPIO 32 23 #define ALTERA_GPIO_DATA 0x0 24 #define ALTERA_GPIO_DIR 0x4 25 #define ALTERA_GPIO_IRQ_MASK 0x8 26 #define ALTERA_GPIO_EDGE_CAP 0xc 27 28 /** 29 * struct altera_gpio_chip 30 * @chip : Generic GPIO chip structure. 31 * @regs : memory mapped IO address for the controller registers. 32 * @gpio_lock : synchronization lock so that new irq/set/get requests 33 * will be blocked until the current one completes. 34 * @interrupt_trigger : specifies the hardware configured IRQ trigger type 35 * (rising, falling, both, high) 36 */ 37 struct altera_gpio_chip { 38 struct gpio_generic_chip chip; 39 void __iomem *regs; 40 raw_spinlock_t gpio_lock; 41 int interrupt_trigger; 42 }; 43 44 static void altera_gpio_irq_unmask(struct irq_data *d) 45 { 46 struct gpio_chip *gc = irq_data_get_irq_chip_data(d); 47 struct altera_gpio_chip *altera_gc = gpiochip_get_data(gc); 48 unsigned long flags; 49 u32 intmask; 50 51 gpiochip_enable_irq(gc, irqd_to_hwirq(d)); 52 53 raw_spin_lock_irqsave(&altera_gc->gpio_lock, flags); 54 intmask = readl(altera_gc->regs + ALTERA_GPIO_IRQ_MASK); 55 /* Set ALTERA_GPIO_IRQ_MASK bit to unmask */ 56 intmask |= BIT(irqd_to_hwirq(d)); 57 writel(intmask, altera_gc->regs + ALTERA_GPIO_IRQ_MASK); 58 raw_spin_unlock_irqrestore(&altera_gc->gpio_lock, flags); 59 } 60 61 static void altera_gpio_irq_mask(struct irq_data *d) 62 { 63 struct gpio_chip *gc = irq_data_get_irq_chip_data(d); 64 struct altera_gpio_chip *altera_gc = gpiochip_get_data(gc); 65 unsigned long flags; 66 u32 intmask; 67 68 raw_spin_lock_irqsave(&altera_gc->gpio_lock, flags); 69 intmask = readl(altera_gc->regs + ALTERA_GPIO_IRQ_MASK); 70 /* Clear ALTERA_GPIO_IRQ_MASK bit to mask */ 71 intmask &= ~BIT(irqd_to_hwirq(d)); 72 writel(intmask, altera_gc->regs + ALTERA_GPIO_IRQ_MASK); 73 raw_spin_unlock_irqrestore(&altera_gc->gpio_lock, flags); 74 75 gpiochip_disable_irq(gc, irqd_to_hwirq(d)); 76 } 77 78 /* 79 * This controller's IRQ type is synthesized in hardware, so this function 80 * just checks if the requested set_type matches the synthesized IRQ type 81 */ 82 static int altera_gpio_irq_set_type(struct irq_data *d, 83 unsigned int type) 84 { 85 struct gpio_chip *gc = irq_data_get_irq_chip_data(d); 86 struct altera_gpio_chip *altera_gc = gpiochip_get_data(gc); 87 88 if (type == IRQ_TYPE_NONE) { 89 irq_set_handler_locked(d, handle_bad_irq); 90 return 0; 91 } 92 if (type == altera_gc->interrupt_trigger) { 93 if (type == IRQ_TYPE_LEVEL_HIGH) 94 irq_set_handler_locked(d, handle_level_irq); 95 else 96 irq_set_handler_locked(d, handle_simple_irq); 97 return 0; 98 } 99 irq_set_handler_locked(d, handle_bad_irq); 100 return -EINVAL; 101 } 102 103 static unsigned int altera_gpio_irq_startup(struct irq_data *d) 104 { 105 altera_gpio_irq_unmask(d); 106 107 return 0; 108 } 109 110 static void altera_gpio_irq_edge_handler(struct irq_desc *desc) 111 { 112 struct gpio_chip *gc = irq_desc_get_handler_data(desc); 113 struct altera_gpio_chip *altera_gc = gpiochip_get_data(gc); 114 struct irq_domain *irqdomain = gc->irq.domain; 115 struct irq_chip *chip; 116 unsigned long status; 117 int i; 118 119 chip = irq_desc_get_chip(desc); 120 121 chained_irq_enter(chip, desc); 122 123 while ((status = 124 (readl(altera_gc->regs + ALTERA_GPIO_EDGE_CAP) & 125 readl(altera_gc->regs + ALTERA_GPIO_IRQ_MASK)))) { 126 writel(status, altera_gc->regs + ALTERA_GPIO_EDGE_CAP); 127 for_each_set_bit(i, &status, gc->ngpio) 128 generic_handle_domain_irq(irqdomain, i); 129 } 130 131 chained_irq_exit(chip, desc); 132 } 133 134 static void altera_gpio_irq_leveL_high_handler(struct irq_desc *desc) 135 { 136 struct gpio_chip *gc = irq_desc_get_handler_data(desc); 137 struct altera_gpio_chip *altera_gc = gpiochip_get_data(gc); 138 struct irq_domain *irqdomain = gc->irq.domain; 139 struct irq_chip *chip; 140 unsigned long status; 141 int i; 142 143 chip = irq_desc_get_chip(desc); 144 145 chained_irq_enter(chip, desc); 146 147 status = readl(altera_gc->regs + ALTERA_GPIO_DATA); 148 status &= readl(altera_gc->regs + ALTERA_GPIO_IRQ_MASK); 149 150 for_each_set_bit(i, &status, gc->ngpio) 151 generic_handle_domain_irq(irqdomain, i); 152 153 chained_irq_exit(chip, desc); 154 } 155 156 static const struct irq_chip altera_gpio_irq_chip = { 157 .name = "altera-gpio", 158 .irq_mask = altera_gpio_irq_mask, 159 .irq_unmask = altera_gpio_irq_unmask, 160 .irq_set_type = altera_gpio_irq_set_type, 161 .irq_startup = altera_gpio_irq_startup, 162 .irq_shutdown = altera_gpio_irq_mask, 163 .flags = IRQCHIP_IMMUTABLE, 164 GPIOCHIP_IRQ_RESOURCE_HELPERS, 165 }; 166 167 static int altera_gpio_probe(struct platform_device *pdev) 168 { 169 struct gpio_generic_chip_config config; 170 struct device *dev = &pdev->dev; 171 int reg, ret; 172 struct altera_gpio_chip *altera_gc; 173 struct gpio_generic_chip *chip; 174 struct gpio_chip *gc; 175 struct gpio_irq_chip *girq; 176 int mapped_irq; 177 178 altera_gc = devm_kzalloc(&pdev->dev, sizeof(*altera_gc), GFP_KERNEL); 179 if (!altera_gc) 180 return -ENOMEM; 181 182 raw_spin_lock_init(&altera_gc->gpio_lock); 183 184 altera_gc->regs = devm_platform_ioremap_resource(pdev, 0); 185 if (IS_ERR(altera_gc->regs)) 186 return dev_err_probe(dev, PTR_ERR(altera_gc->regs), 187 "failed to ioremap memory resource\n"); 188 189 chip = &altera_gc->chip; 190 191 config = (struct gpio_generic_chip_config) { 192 .dev = dev, 193 .sz = 4, 194 .dat = altera_gc->regs + ALTERA_GPIO_DATA, 195 .set = altera_gc->regs + ALTERA_GPIO_DATA, 196 .dirout = altera_gc->regs + ALTERA_GPIO_DIR, 197 }; 198 199 ret = gpio_generic_chip_init(chip, &config); 200 if (ret) 201 return dev_err_probe(dev, ret, "unable to init generic GPIO\n"); 202 203 gc = &chip->gc; 204 205 if (device_property_read_u32(dev, "altr,ngpio", ®)) 206 /* By default assume maximum ngpio */ 207 gc->ngpio = ALTERA_GPIO_MAX_NGPIO; 208 else 209 gc->ngpio = reg; 210 211 if (gc->ngpio > ALTERA_GPIO_MAX_NGPIO) { 212 dev_warn(&pdev->dev, 213 "ngpio is greater than %d, defaulting to %d\n", 214 ALTERA_GPIO_MAX_NGPIO, ALTERA_GPIO_MAX_NGPIO); 215 gc->ngpio = ALTERA_GPIO_MAX_NGPIO; 216 } 217 218 gc->base = -1; 219 gc->label = devm_kasprintf(dev, GFP_KERNEL, "%pfw", dev_fwnode(dev)); 220 if (!gc->label) 221 return -ENOMEM; 222 223 mapped_irq = platform_get_irq_optional(pdev, 0); 224 if (mapped_irq < 0) 225 goto skip_irq; 226 227 if (device_property_read_u32(dev, "altr,interrupt-type", ®)) { 228 dev_err(&pdev->dev, 229 "altr,interrupt-type value not set in device tree\n"); 230 return -EINVAL; 231 } 232 altera_gc->interrupt_trigger = reg; 233 234 girq = &gc->irq; 235 gpio_irq_chip_set_chip(girq, &altera_gpio_irq_chip); 236 237 if (altera_gc->interrupt_trigger == IRQ_TYPE_LEVEL_HIGH) 238 girq->parent_handler = altera_gpio_irq_leveL_high_handler; 239 else 240 girq->parent_handler = altera_gpio_irq_edge_handler; 241 girq->num_parents = 1; 242 girq->parents = devm_kcalloc(&pdev->dev, 1, sizeof(*girq->parents), 243 GFP_KERNEL); 244 if (!girq->parents) 245 return -ENOMEM; 246 girq->default_type = IRQ_TYPE_NONE; 247 girq->handler = handle_bad_irq; 248 girq->parents[0] = mapped_irq; 249 250 skip_irq: 251 ret = devm_gpiochip_add_data(dev, gc, altera_gc); 252 if (ret) { 253 dev_err(&pdev->dev, "Failed adding memory mapped gpiochip\n"); 254 return ret; 255 } 256 257 return 0; 258 } 259 260 static const struct of_device_id altera_gpio_of_match[] = { 261 { .compatible = "altr,pio-1.0", }, 262 {}, 263 }; 264 MODULE_DEVICE_TABLE(of, altera_gpio_of_match); 265 266 static struct platform_driver altera_gpio_driver = { 267 .driver = { 268 .name = "altera_gpio", 269 .of_match_table = altera_gpio_of_match, 270 }, 271 .probe = altera_gpio_probe, 272 }; 273 274 static int __init altera_gpio_init(void) 275 { 276 return platform_driver_register(&altera_gpio_driver); 277 } 278 subsys_initcall(altera_gpio_init); 279 280 static void __exit altera_gpio_exit(void) 281 { 282 platform_driver_unregister(&altera_gpio_driver); 283 } 284 module_exit(altera_gpio_exit); 285 286 MODULE_AUTHOR("Tien Hock Loh <thloh@altera.com>"); 287 MODULE_DESCRIPTION("Altera GPIO driver"); 288 MODULE_LICENSE("GPL"); 289