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/list.h> 16 #include <linux/io.h> 17 #include <linux/ioport.h> 18 #include <linux/irq.h> 19 #include <linux/bitops.h> 20 #include <linux/workqueue.h> 21 #include <linux/gpio.h> 22 #include <linux/device.h> 23 #include <linux/amba/bus.h> 24 #include <linux/amba/pl061.h> 25 #include <linux/slab.h> 26 27 #define GPIODIR 0x400 28 #define GPIOIS 0x404 29 #define GPIOIBE 0x408 30 #define GPIOIEV 0x40C 31 #define GPIOIE 0x410 32 #define GPIORIS 0x414 33 #define GPIOMIS 0x418 34 #define GPIOIC 0x41C 35 36 #define PL061_GPIO_NR 8 37 38 struct pl061_gpio { 39 /* We use a list of pl061_gpio structs for each trigger IRQ in the main 40 * interrupts controller of the system. We need this to support systems 41 * in which more that one PL061s are connected to the same IRQ. The ISR 42 * interates through this list to find the source of the interrupt. 43 */ 44 struct list_head list; 45 46 /* Each of the two spinlocks protects a different set of hardware 47 * regiters and data structurs. This decouples the code of the IRQ from 48 * the GPIO code. This also makes the case of a GPIO routine call from 49 * the IRQ code simpler. 50 */ 51 spinlock_t lock; /* GPIO registers */ 52 spinlock_t irq_lock; /* IRQ registers */ 53 54 void __iomem *base; 55 unsigned irq_base; 56 struct gpio_chip gc; 57 }; 58 59 static int pl061_direction_input(struct gpio_chip *gc, unsigned offset) 60 { 61 struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc); 62 unsigned long flags; 63 unsigned char gpiodir; 64 65 if (offset >= gc->ngpio) 66 return -EINVAL; 67 68 spin_lock_irqsave(&chip->lock, flags); 69 gpiodir = readb(chip->base + GPIODIR); 70 gpiodir &= ~(1 << offset); 71 writeb(gpiodir, chip->base + GPIODIR); 72 spin_unlock_irqrestore(&chip->lock, flags); 73 74 return 0; 75 } 76 77 static int pl061_direction_output(struct gpio_chip *gc, unsigned offset, 78 int value) 79 { 80 struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc); 81 unsigned long flags; 82 unsigned char gpiodir; 83 84 if (offset >= gc->ngpio) 85 return -EINVAL; 86 87 spin_lock_irqsave(&chip->lock, flags); 88 writeb(!!value << offset, chip->base + (1 << (offset + 2))); 89 gpiodir = readb(chip->base + GPIODIR); 90 gpiodir |= 1 << offset; 91 writeb(gpiodir, chip->base + GPIODIR); 92 93 /* 94 * gpio value is set again, because pl061 doesn't allow to set value of 95 * a gpio pin before configuring it in OUT mode. 96 */ 97 writeb(!!value << offset, chip->base + (1 << (offset + 2))); 98 spin_unlock_irqrestore(&chip->lock, flags); 99 100 return 0; 101 } 102 103 static int pl061_get_value(struct gpio_chip *gc, unsigned offset) 104 { 105 struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc); 106 107 return !!readb(chip->base + (1 << (offset + 2))); 108 } 109 110 static void pl061_set_value(struct gpio_chip *gc, unsigned offset, int value) 111 { 112 struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc); 113 114 writeb(!!value << offset, chip->base + (1 << (offset + 2))); 115 } 116 117 static int pl061_to_irq(struct gpio_chip *gc, unsigned offset) 118 { 119 struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc); 120 121 if (chip->irq_base == (unsigned) -1) 122 return -EINVAL; 123 124 return chip->irq_base + offset; 125 } 126 127 /* 128 * PL061 GPIO IRQ 129 */ 130 static void pl061_irq_disable(struct irq_data *d) 131 { 132 struct pl061_gpio *chip = irq_data_get_irq_chip_data(d); 133 int offset = d->irq - chip->irq_base; 134 unsigned long flags; 135 u8 gpioie; 136 137 spin_lock_irqsave(&chip->irq_lock, flags); 138 gpioie = readb(chip->base + GPIOIE); 139 gpioie &= ~(1 << offset); 140 writeb(gpioie, chip->base + GPIOIE); 141 spin_unlock_irqrestore(&chip->irq_lock, flags); 142 } 143 144 static void pl061_irq_enable(struct irq_data *d) 145 { 146 struct pl061_gpio *chip = irq_data_get_irq_chip_data(d); 147 int offset = d->irq - chip->irq_base; 148 unsigned long flags; 149 u8 gpioie; 150 151 spin_lock_irqsave(&chip->irq_lock, flags); 152 gpioie = readb(chip->base + GPIOIE); 153 gpioie |= 1 << offset; 154 writeb(gpioie, chip->base + GPIOIE); 155 spin_unlock_irqrestore(&chip->irq_lock, flags); 156 } 157 158 static int pl061_irq_type(struct irq_data *d, unsigned trigger) 159 { 160 struct pl061_gpio *chip = irq_data_get_irq_chip_data(d); 161 int offset = d->irq - chip->irq_base; 162 unsigned long flags; 163 u8 gpiois, gpioibe, gpioiev; 164 165 if (offset < 0 || offset >= PL061_GPIO_NR) 166 return -EINVAL; 167 168 spin_lock_irqsave(&chip->irq_lock, flags); 169 170 gpioiev = readb(chip->base + GPIOIEV); 171 172 gpiois = readb(chip->base + GPIOIS); 173 if (trigger & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) { 174 gpiois |= 1 << offset; 175 if (trigger & IRQ_TYPE_LEVEL_HIGH) 176 gpioiev |= 1 << offset; 177 else 178 gpioiev &= ~(1 << offset); 179 } else 180 gpiois &= ~(1 << offset); 181 writeb(gpiois, chip->base + GPIOIS); 182 183 gpioibe = readb(chip->base + GPIOIBE); 184 if ((trigger & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH) 185 gpioibe |= 1 << offset; 186 else { 187 gpioibe &= ~(1 << offset); 188 if (trigger & IRQ_TYPE_EDGE_RISING) 189 gpioiev |= 1 << offset; 190 else if (trigger & IRQ_TYPE_EDGE_FALLING) 191 gpioiev &= ~(1 << offset); 192 } 193 writeb(gpioibe, chip->base + GPIOIBE); 194 195 writeb(gpioiev, chip->base + GPIOIEV); 196 197 spin_unlock_irqrestore(&chip->irq_lock, flags); 198 199 return 0; 200 } 201 202 static struct irq_chip pl061_irqchip = { 203 .name = "GPIO", 204 .irq_enable = pl061_irq_enable, 205 .irq_disable = pl061_irq_disable, 206 .irq_set_type = pl061_irq_type, 207 }; 208 209 static void pl061_irq_handler(unsigned irq, struct irq_desc *desc) 210 { 211 struct list_head *chip_list = irq_get_handler_data(irq); 212 struct list_head *ptr; 213 struct pl061_gpio *chip; 214 215 desc->irq_data.chip->irq_ack(&desc->irq_data); 216 list_for_each(ptr, chip_list) { 217 unsigned long pending; 218 int offset; 219 220 chip = list_entry(ptr, struct pl061_gpio, list); 221 pending = readb(chip->base + GPIOMIS); 222 writeb(pending, chip->base + GPIOIC); 223 224 if (pending == 0) 225 continue; 226 227 for_each_set_bit(offset, &pending, PL061_GPIO_NR) 228 generic_handle_irq(pl061_to_irq(&chip->gc, offset)); 229 } 230 desc->irq_data.chip->irq_unmask(&desc->irq_data); 231 } 232 233 static int pl061_probe(struct amba_device *dev, const struct amba_id *id) 234 { 235 struct pl061_platform_data *pdata; 236 struct pl061_gpio *chip; 237 struct list_head *chip_list; 238 int ret, irq, i; 239 static DECLARE_BITMAP(init_irq, NR_IRQS); 240 241 pdata = dev->dev.platform_data; 242 if (pdata == NULL) 243 return -ENODEV; 244 245 chip = kzalloc(sizeof(*chip), GFP_KERNEL); 246 if (chip == NULL) 247 return -ENOMEM; 248 249 if (!request_mem_region(dev->res.start, 250 resource_size(&dev->res), "pl061")) { 251 ret = -EBUSY; 252 goto free_mem; 253 } 254 255 chip->base = ioremap(dev->res.start, resource_size(&dev->res)); 256 if (chip->base == NULL) { 257 ret = -ENOMEM; 258 goto release_region; 259 } 260 261 spin_lock_init(&chip->lock); 262 spin_lock_init(&chip->irq_lock); 263 INIT_LIST_HEAD(&chip->list); 264 265 chip->gc.direction_input = pl061_direction_input; 266 chip->gc.direction_output = pl061_direction_output; 267 chip->gc.get = pl061_get_value; 268 chip->gc.set = pl061_set_value; 269 chip->gc.to_irq = pl061_to_irq; 270 chip->gc.base = pdata->gpio_base; 271 chip->gc.ngpio = PL061_GPIO_NR; 272 chip->gc.label = dev_name(&dev->dev); 273 chip->gc.dev = &dev->dev; 274 chip->gc.owner = THIS_MODULE; 275 276 chip->irq_base = pdata->irq_base; 277 278 ret = gpiochip_add(&chip->gc); 279 if (ret) 280 goto iounmap; 281 282 /* 283 * irq_chip support 284 */ 285 286 if (chip->irq_base == (unsigned) -1) 287 return 0; 288 289 writeb(0, chip->base + GPIOIE); /* disable irqs */ 290 irq = dev->irq[0]; 291 if (irq < 0) { 292 ret = -ENODEV; 293 goto iounmap; 294 } 295 irq_set_chained_handler(irq, pl061_irq_handler); 296 if (!test_and_set_bit(irq, init_irq)) { /* list initialized? */ 297 chip_list = kmalloc(sizeof(*chip_list), GFP_KERNEL); 298 if (chip_list == NULL) { 299 clear_bit(irq, init_irq); 300 ret = -ENOMEM; 301 goto iounmap; 302 } 303 INIT_LIST_HEAD(chip_list); 304 irq_set_handler_data(irq, chip_list); 305 } else 306 chip_list = irq_get_handler_data(irq); 307 list_add(&chip->list, chip_list); 308 309 for (i = 0; i < PL061_GPIO_NR; i++) { 310 if (pdata->directions & (1 << i)) 311 pl061_direction_output(&chip->gc, i, 312 pdata->values & (1 << i)); 313 else 314 pl061_direction_input(&chip->gc, i); 315 316 irq_set_chip_and_handler(i + chip->irq_base, &pl061_irqchip, 317 handle_simple_irq); 318 set_irq_flags(i+chip->irq_base, IRQF_VALID); 319 irq_set_chip_data(i + chip->irq_base, chip); 320 } 321 322 return 0; 323 324 iounmap: 325 iounmap(chip->base); 326 release_region: 327 release_mem_region(dev->res.start, resource_size(&dev->res)); 328 free_mem: 329 kfree(chip); 330 331 return ret; 332 } 333 334 static struct amba_id pl061_ids[] = { 335 { 336 .id = 0x00041061, 337 .mask = 0x000fffff, 338 }, 339 { 0, 0 }, 340 }; 341 342 static struct amba_driver pl061_gpio_driver = { 343 .drv = { 344 .name = "pl061_gpio", 345 }, 346 .id_table = pl061_ids, 347 .probe = pl061_probe, 348 }; 349 350 static int __init pl061_gpio_init(void) 351 { 352 return amba_driver_register(&pl061_gpio_driver); 353 } 354 subsys_initcall(pl061_gpio_init); 355 356 MODULE_AUTHOR("Baruch Siach <baruch@tkos.co.il>"); 357 MODULE_DESCRIPTION("PL061 GPIO driver"); 358 MODULE_LICENSE("GPL"); 359