1 /* 2 * Copyright (C) 2008, 2009 Provigent Ltd. 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License version 2 as 6 * published by the Free Software Foundation. 7 * 8 * Driver for the ARM PrimeCell(tm) General Purpose Input/Output (PL061) 9 * 10 * Data sheet: ARM DDI 0190B, September 2000 11 */ 12 #include <linux/spinlock.h> 13 #include <linux/errno.h> 14 #include <linux/module.h> 15 #include <linux/io.h> 16 #include <linux/ioport.h> 17 #include <linux/irq.h> 18 #include <linux/bitops.h> 19 #include <linux/workqueue.h> 20 #include <linux/gpio.h> 21 #include <linux/device.h> 22 #include <linux/amba/bus.h> 23 #include <linux/amba/pl061.h> 24 #include <linux/slab.h> 25 #include <linux/pm.h> 26 #include <asm/mach/irq.h> 27 28 #define GPIODIR 0x400 29 #define GPIOIS 0x404 30 #define GPIOIBE 0x408 31 #define GPIOIEV 0x40C 32 #define GPIOIE 0x410 33 #define GPIORIS 0x414 34 #define GPIOMIS 0x418 35 #define GPIOIC 0x41C 36 37 #define PL061_GPIO_NR 8 38 39 #ifdef CONFIG_PM 40 struct pl061_context_save_regs { 41 u8 gpio_data; 42 u8 gpio_dir; 43 u8 gpio_is; 44 u8 gpio_ibe; 45 u8 gpio_iev; 46 u8 gpio_ie; 47 }; 48 #endif 49 50 struct pl061_gpio { 51 /* Each of the two spinlocks protects a different set of hardware 52 * regiters and data structurs. This decouples the code of the IRQ from 53 * the GPIO code. This also makes the case of a GPIO routine call from 54 * the IRQ code simpler. 55 */ 56 spinlock_t lock; /* GPIO registers */ 57 58 void __iomem *base; 59 int irq_base; 60 struct irq_chip_generic *irq_gc; 61 struct gpio_chip gc; 62 63 #ifdef CONFIG_PM 64 struct pl061_context_save_regs csave_regs; 65 #endif 66 }; 67 68 static int pl061_direction_input(struct gpio_chip *gc, unsigned offset) 69 { 70 struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc); 71 unsigned long flags; 72 unsigned char gpiodir; 73 74 if (offset >= gc->ngpio) 75 return -EINVAL; 76 77 spin_lock_irqsave(&chip->lock, flags); 78 gpiodir = readb(chip->base + GPIODIR); 79 gpiodir &= ~(1 << offset); 80 writeb(gpiodir, chip->base + GPIODIR); 81 spin_unlock_irqrestore(&chip->lock, flags); 82 83 return 0; 84 } 85 86 static int pl061_direction_output(struct gpio_chip *gc, unsigned offset, 87 int value) 88 { 89 struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc); 90 unsigned long flags; 91 unsigned char gpiodir; 92 93 if (offset >= gc->ngpio) 94 return -EINVAL; 95 96 spin_lock_irqsave(&chip->lock, flags); 97 writeb(!!value << offset, chip->base + (1 << (offset + 2))); 98 gpiodir = readb(chip->base + GPIODIR); 99 gpiodir |= 1 << offset; 100 writeb(gpiodir, chip->base + GPIODIR); 101 102 /* 103 * gpio value is set again, because pl061 doesn't allow to set value of 104 * a gpio pin before configuring it in OUT mode. 105 */ 106 writeb(!!value << offset, chip->base + (1 << (offset + 2))); 107 spin_unlock_irqrestore(&chip->lock, flags); 108 109 return 0; 110 } 111 112 static int pl061_get_value(struct gpio_chip *gc, unsigned offset) 113 { 114 struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc); 115 116 return !!readb(chip->base + (1 << (offset + 2))); 117 } 118 119 static void pl061_set_value(struct gpio_chip *gc, unsigned offset, int value) 120 { 121 struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc); 122 123 writeb(!!value << offset, chip->base + (1 << (offset + 2))); 124 } 125 126 static int pl061_to_irq(struct gpio_chip *gc, unsigned offset) 127 { 128 struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc); 129 130 if (chip->irq_base <= 0) 131 return -EINVAL; 132 133 return chip->irq_base + offset; 134 } 135 136 static int pl061_irq_type(struct irq_data *d, unsigned trigger) 137 { 138 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); 139 struct pl061_gpio *chip = gc->private; 140 int offset = d->irq - chip->irq_base; 141 unsigned long flags; 142 u8 gpiois, gpioibe, gpioiev; 143 144 if (offset < 0 || offset >= PL061_GPIO_NR) 145 return -EINVAL; 146 147 raw_spin_lock_irqsave(&gc->lock, flags); 148 149 gpioiev = readb(chip->base + GPIOIEV); 150 151 gpiois = readb(chip->base + GPIOIS); 152 if (trigger & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) { 153 gpiois |= 1 << offset; 154 if (trigger & IRQ_TYPE_LEVEL_HIGH) 155 gpioiev |= 1 << offset; 156 else 157 gpioiev &= ~(1 << offset); 158 } else 159 gpiois &= ~(1 << offset); 160 writeb(gpiois, chip->base + GPIOIS); 161 162 gpioibe = readb(chip->base + GPIOIBE); 163 if ((trigger & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH) 164 gpioibe |= 1 << offset; 165 else { 166 gpioibe &= ~(1 << offset); 167 if (trigger & IRQ_TYPE_EDGE_RISING) 168 gpioiev |= 1 << offset; 169 else if (trigger & IRQ_TYPE_EDGE_FALLING) 170 gpioiev &= ~(1 << offset); 171 } 172 writeb(gpioibe, chip->base + GPIOIBE); 173 174 writeb(gpioiev, chip->base + GPIOIEV); 175 176 raw_spin_unlock_irqrestore(&gc->lock, flags); 177 178 return 0; 179 } 180 181 static void pl061_irq_handler(unsigned irq, struct irq_desc *desc) 182 { 183 unsigned long pending; 184 int offset; 185 struct pl061_gpio *chip = irq_desc_get_handler_data(desc); 186 struct irq_chip *irqchip = irq_desc_get_chip(desc); 187 188 chained_irq_enter(irqchip, desc); 189 190 pending = readb(chip->base + GPIOMIS); 191 writeb(pending, chip->base + GPIOIC); 192 if (pending) { 193 for_each_set_bit(offset, &pending, PL061_GPIO_NR) 194 generic_handle_irq(pl061_to_irq(&chip->gc, offset)); 195 } 196 197 chained_irq_exit(irqchip, desc); 198 } 199 200 static void __init pl061_init_gc(struct pl061_gpio *chip, int irq_base) 201 { 202 struct irq_chip_type *ct; 203 204 chip->irq_gc = irq_alloc_generic_chip("gpio-pl061", 1, irq_base, 205 chip->base, handle_simple_irq); 206 chip->irq_gc->private = chip; 207 208 ct = chip->irq_gc->chip_types; 209 ct->chip.irq_mask = irq_gc_mask_clr_bit; 210 ct->chip.irq_unmask = irq_gc_mask_set_bit; 211 ct->chip.irq_set_type = pl061_irq_type; 212 ct->chip.irq_set_wake = irq_gc_set_wake; 213 ct->regs.mask = GPIOIE; 214 215 irq_setup_generic_chip(chip->irq_gc, IRQ_MSK(PL061_GPIO_NR), 216 IRQ_GC_INIT_NESTED_LOCK, IRQ_NOREQUEST, 0); 217 } 218 219 static int pl061_probe(struct amba_device *dev, const struct amba_id *id) 220 { 221 struct pl061_platform_data *pdata; 222 struct pl061_gpio *chip; 223 int ret, irq, i; 224 225 chip = kzalloc(sizeof(*chip), GFP_KERNEL); 226 if (chip == NULL) 227 return -ENOMEM; 228 229 pdata = dev->dev.platform_data; 230 if (pdata) { 231 chip->gc.base = pdata->gpio_base; 232 chip->irq_base = pdata->irq_base; 233 } else if (dev->dev.of_node) { 234 chip->gc.base = -1; 235 chip->irq_base = 0; 236 } else { 237 ret = -ENODEV; 238 goto free_mem; 239 } 240 241 if (!request_mem_region(dev->res.start, 242 resource_size(&dev->res), "pl061")) { 243 ret = -EBUSY; 244 goto free_mem; 245 } 246 247 chip->base = ioremap(dev->res.start, resource_size(&dev->res)); 248 if (chip->base == NULL) { 249 ret = -ENOMEM; 250 goto release_region; 251 } 252 253 spin_lock_init(&chip->lock); 254 255 chip->gc.direction_input = pl061_direction_input; 256 chip->gc.direction_output = pl061_direction_output; 257 chip->gc.get = pl061_get_value; 258 chip->gc.set = pl061_set_value; 259 chip->gc.to_irq = pl061_to_irq; 260 chip->gc.ngpio = PL061_GPIO_NR; 261 chip->gc.label = dev_name(&dev->dev); 262 chip->gc.dev = &dev->dev; 263 chip->gc.owner = THIS_MODULE; 264 265 ret = gpiochip_add(&chip->gc); 266 if (ret) 267 goto iounmap; 268 269 /* 270 * irq_chip support 271 */ 272 273 if (chip->irq_base <= 0) 274 return 0; 275 276 pl061_init_gc(chip, chip->irq_base); 277 278 writeb(0, chip->base + GPIOIE); /* disable irqs */ 279 irq = dev->irq[0]; 280 if (irq < 0) { 281 ret = -ENODEV; 282 goto iounmap; 283 } 284 irq_set_chained_handler(irq, pl061_irq_handler); 285 irq_set_handler_data(irq, chip); 286 287 for (i = 0; i < PL061_GPIO_NR; i++) { 288 if (pdata) { 289 if (pdata->directions & (1 << i)) 290 pl061_direction_output(&chip->gc, i, 291 pdata->values & (1 << i)); 292 else 293 pl061_direction_input(&chip->gc, i); 294 } 295 } 296 297 amba_set_drvdata(dev, chip); 298 299 return 0; 300 301 iounmap: 302 iounmap(chip->base); 303 release_region: 304 release_mem_region(dev->res.start, resource_size(&dev->res)); 305 free_mem: 306 kfree(chip); 307 308 return ret; 309 } 310 311 #ifdef CONFIG_PM 312 static int pl061_suspend(struct device *dev) 313 { 314 struct pl061_gpio *chip = dev_get_drvdata(dev); 315 int offset; 316 317 chip->csave_regs.gpio_data = 0; 318 chip->csave_regs.gpio_dir = readb(chip->base + GPIODIR); 319 chip->csave_regs.gpio_is = readb(chip->base + GPIOIS); 320 chip->csave_regs.gpio_ibe = readb(chip->base + GPIOIBE); 321 chip->csave_regs.gpio_iev = readb(chip->base + GPIOIEV); 322 chip->csave_regs.gpio_ie = readb(chip->base + GPIOIE); 323 324 for (offset = 0; offset < PL061_GPIO_NR; offset++) { 325 if (chip->csave_regs.gpio_dir & (1 << offset)) 326 chip->csave_regs.gpio_data |= 327 pl061_get_value(&chip->gc, offset) << offset; 328 } 329 330 return 0; 331 } 332 333 static int pl061_resume(struct device *dev) 334 { 335 struct pl061_gpio *chip = dev_get_drvdata(dev); 336 int offset; 337 338 for (offset = 0; offset < PL061_GPIO_NR; offset++) { 339 if (chip->csave_regs.gpio_dir & (1 << offset)) 340 pl061_direction_output(&chip->gc, offset, 341 chip->csave_regs.gpio_data & 342 (1 << offset)); 343 else 344 pl061_direction_input(&chip->gc, offset); 345 } 346 347 writeb(chip->csave_regs.gpio_is, chip->base + GPIOIS); 348 writeb(chip->csave_regs.gpio_ibe, chip->base + GPIOIBE); 349 writeb(chip->csave_regs.gpio_iev, chip->base + GPIOIEV); 350 writeb(chip->csave_regs.gpio_ie, chip->base + GPIOIE); 351 352 return 0; 353 } 354 355 static const struct dev_pm_ops pl061_dev_pm_ops = { 356 .suspend = pl061_suspend, 357 .resume = pl061_resume, 358 .freeze = pl061_suspend, 359 .restore = pl061_resume, 360 }; 361 #endif 362 363 static struct amba_id pl061_ids[] = { 364 { 365 .id = 0x00041061, 366 .mask = 0x000fffff, 367 }, 368 { 0, 0 }, 369 }; 370 371 MODULE_DEVICE_TABLE(amba, pl061_ids); 372 373 static struct amba_driver pl061_gpio_driver = { 374 .drv = { 375 .name = "pl061_gpio", 376 #ifdef CONFIG_PM 377 .pm = &pl061_dev_pm_ops, 378 #endif 379 }, 380 .id_table = pl061_ids, 381 .probe = pl061_probe, 382 }; 383 384 static int __init pl061_gpio_init(void) 385 { 386 return amba_driver_register(&pl061_gpio_driver); 387 } 388 subsys_initcall(pl061_gpio_init); 389 390 MODULE_AUTHOR("Baruch Siach <baruch@tkos.co.il>"); 391 MODULE_DESCRIPTION("PL061 GPIO driver"); 392 MODULE_LICENSE("GPL"); 393