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/irqchip/chained_irq.h> 19#include <linux/bitops.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/pinctrl/consumer.h> 26#include <linux/pm.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 40struct 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 50struct pl061_gpio { 51 spinlock_t lock; 52 53 void __iomem *base; 54 struct gpio_chip gc; 55 bool uses_pinctrl; 56 57#ifdef CONFIG_PM 58 struct pl061_context_save_regs csave_regs; 59#endif 60}; 61 62static int pl061_gpio_request(struct gpio_chip *gc, unsigned offset) 63{ 64 /* 65 * Map back to global GPIO space and request muxing, the direction 66 * parameter does not matter for this controller. 67 */ 68 struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc); 69 int gpio = gc->base + offset; 70 71 if (chip->uses_pinctrl) 72 return pinctrl_request_gpio(gpio); 73 return 0; 74} 75 76static void pl061_gpio_free(struct gpio_chip *gc, unsigned offset) 77{ 78 struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc); 79 int gpio = gc->base + offset; 80 81 if (chip->uses_pinctrl) 82 pinctrl_free_gpio(gpio); 83} 84 85static int pl061_direction_input(struct gpio_chip *gc, unsigned offset) 86{ 87 struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc); 88 unsigned long flags; 89 unsigned char gpiodir; 90 91 if (offset >= gc->ngpio) 92 return -EINVAL; 93 94 spin_lock_irqsave(&chip->lock, flags); 95 gpiodir = readb(chip->base + GPIODIR); 96 gpiodir &= ~(BIT(offset)); 97 writeb(gpiodir, chip->base + GPIODIR); 98 spin_unlock_irqrestore(&chip->lock, flags); 99 100 return 0; 101} 102 103static int pl061_direction_output(struct gpio_chip *gc, unsigned offset, 104 int value) 105{ 106 struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc); 107 unsigned long flags; 108 unsigned char gpiodir; 109 110 if (offset >= gc->ngpio) 111 return -EINVAL; 112 113 spin_lock_irqsave(&chip->lock, flags); 114 writeb(!!value << offset, chip->base + (BIT(offset + 2))); 115 gpiodir = readb(chip->base + GPIODIR); 116 gpiodir |= BIT(offset); 117 writeb(gpiodir, chip->base + GPIODIR); 118 119 /* 120 * gpio value is set again, because pl061 doesn't allow to set value of 121 * a gpio pin before configuring it in OUT mode. 122 */ 123 writeb(!!value << offset, chip->base + (BIT(offset + 2))); 124 spin_unlock_irqrestore(&chip->lock, flags); 125 126 return 0; 127} 128 129static int pl061_get_value(struct gpio_chip *gc, unsigned offset) 130{ 131 struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc); 132 133 return !!readb(chip->base + (BIT(offset + 2))); 134} 135 136static void pl061_set_value(struct gpio_chip *gc, unsigned offset, int value) 137{ 138 struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc); 139 140 writeb(!!value << offset, chip->base + (BIT(offset + 2))); 141} 142 143static int pl061_irq_type(struct irq_data *d, unsigned trigger) 144{ 145 struct gpio_chip *gc = irq_data_get_irq_chip_data(d); 146 struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc); 147 int offset = irqd_to_hwirq(d); 148 unsigned long flags; 149 u8 gpiois, gpioibe, gpioiev; 150 u8 bit = BIT(offset); 151 152 if (offset < 0 || offset >= PL061_GPIO_NR) 153 return -EINVAL; 154 155 spin_lock_irqsave(&chip->lock, flags); 156 157 gpioiev = readb(chip->base + GPIOIEV); 158 gpiois = readb(chip->base + GPIOIS); 159 gpioibe = readb(chip->base + GPIOIBE); 160 161 if (trigger & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) { 162 gpiois |= bit; 163 if (trigger & IRQ_TYPE_LEVEL_HIGH) 164 gpioiev |= bit; 165 else 166 gpioiev &= ~bit; 167 } else 168 gpiois &= ~bit; 169 170 if ((trigger & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH) 171 /* Setting this makes GPIOEV be ignored */ 172 gpioibe |= bit; 173 else { 174 gpioibe &= ~bit; 175 if (trigger & IRQ_TYPE_EDGE_RISING) 176 gpioiev |= bit; 177 else if (trigger & IRQ_TYPE_EDGE_FALLING) 178 gpioiev &= ~bit; 179 } 180 181 writeb(gpiois, chip->base + GPIOIS); 182 writeb(gpioibe, chip->base + GPIOIBE); 183 writeb(gpioiev, chip->base + GPIOIEV); 184 185 spin_unlock_irqrestore(&chip->lock, flags); 186 187 return 0; 188} 189 190static void pl061_irq_handler(unsigned irq, struct irq_desc *desc) 191{ 192 unsigned long pending; 193 int offset; 194 struct gpio_chip *gc = irq_desc_get_handler_data(desc); 195 struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc); 196 struct irq_chip *irqchip = irq_desc_get_chip(desc); 197 198 chained_irq_enter(irqchip, desc); 199 200 pending = readb(chip->base + GPIOMIS); 201 writeb(pending, chip->base + GPIOIC); 202 if (pending) { 203 for_each_set_bit(offset, &pending, PL061_GPIO_NR) 204 generic_handle_irq(irq_find_mapping(gc->irqdomain, 205 offset)); 206 } 207 208 chained_irq_exit(irqchip, desc); 209} 210 211static void pl061_irq_mask(struct irq_data *d) 212{ 213 struct gpio_chip *gc = irq_data_get_irq_chip_data(d); 214 struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc); 215 u8 mask = BIT(irqd_to_hwirq(d) % PL061_GPIO_NR); 216 u8 gpioie; 217 218 spin_lock(&chip->lock); 219 gpioie = readb(chip->base + GPIOIE) & ~mask; 220 writeb(gpioie, chip->base + GPIOIE); 221 spin_unlock(&chip->lock); 222} 223 224static void pl061_irq_unmask(struct irq_data *d) 225{ 226 struct gpio_chip *gc = irq_data_get_irq_chip_data(d); 227 struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc); 228 u8 mask = BIT(irqd_to_hwirq(d) % PL061_GPIO_NR); 229 u8 gpioie; 230 231 spin_lock(&chip->lock); 232 gpioie = readb(chip->base + GPIOIE) | mask; 233 writeb(gpioie, chip->base + GPIOIE); 234 spin_unlock(&chip->lock); 235} 236 237static struct irq_chip pl061_irqchip = { 238 .name = "pl061", 239 .irq_mask = pl061_irq_mask, 240 .irq_unmask = pl061_irq_unmask, 241 .irq_set_type = pl061_irq_type, 242}; 243 244static int pl061_probe(struct amba_device *adev, const struct amba_id *id) 245{ 246 struct device *dev = &adev->dev; 247 struct pl061_platform_data *pdata = dev_get_platdata(dev); 248 struct pl061_gpio *chip; 249 int ret, irq, i, irq_base; 250 251 chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL); 252 if (chip == NULL) 253 return -ENOMEM; 254 255 if (pdata) { 256 chip->gc.base = pdata->gpio_base; 257 irq_base = pdata->irq_base; 258 if (irq_base <= 0) { 259 dev_err(&adev->dev, "invalid IRQ base in pdata\n"); 260 return -ENODEV; 261 } 262 } else { 263 chip->gc.base = -1; 264 irq_base = 0; 265 } 266 267 chip->base = devm_ioremap_resource(dev, &adev->res); 268 if (IS_ERR(chip->base)) 269 return PTR_ERR(chip->base); 270 271 spin_lock_init(&chip->lock); 272 if (of_property_read_bool(dev->of_node, "gpio-ranges")) 273 chip->uses_pinctrl = true; 274 275 chip->gc.request = pl061_gpio_request; 276 chip->gc.free = pl061_gpio_free; 277 chip->gc.direction_input = pl061_direction_input; 278 chip->gc.direction_output = pl061_direction_output; 279 chip->gc.get = pl061_get_value; 280 chip->gc.set = pl061_set_value; 281 chip->gc.ngpio = PL061_GPIO_NR; 282 chip->gc.label = dev_name(dev); 283 chip->gc.dev = dev; 284 chip->gc.owner = THIS_MODULE; 285 286 ret = gpiochip_add(&chip->gc); 287 if (ret) 288 return ret; 289 290 /* 291 * irq_chip support 292 */ 293 writeb(0, chip->base + GPIOIE); /* disable irqs */ 294 irq = adev->irq[0]; 295 if (irq < 0) { 296 dev_err(&adev->dev, "invalid IRQ\n"); 297 return -ENODEV; 298 } 299 300 ret = gpiochip_irqchip_add(&chip->gc, &pl061_irqchip, 301 irq_base, handle_simple_irq, 302 IRQ_TYPE_NONE); 303 if (ret) { 304 dev_info(&adev->dev, "could not add irqchip\n"); 305 return ret; 306 } 307 gpiochip_set_chained_irqchip(&chip->gc, &pl061_irqchip, 308 irq, pl061_irq_handler); 309 310 for (i = 0; i < PL061_GPIO_NR; i++) { 311 if (pdata) { 312 if (pdata->directions & (BIT(i))) 313 pl061_direction_output(&chip->gc, i, 314 pdata->values & (BIT(i))); 315 else 316 pl061_direction_input(&chip->gc, i); 317 } 318 } 319 320 amba_set_drvdata(adev, chip); 321 dev_info(&adev->dev, "PL061 GPIO chip @%pa registered\n", 322 &adev->res.start); 323 324 return 0; 325} 326 327#ifdef CONFIG_PM 328static int pl061_suspend(struct device *dev) 329{ 330 struct pl061_gpio *chip = dev_get_drvdata(dev); 331 int offset; 332 333 chip->csave_regs.gpio_data = 0; 334 chip->csave_regs.gpio_dir = readb(chip->base + GPIODIR); 335 chip->csave_regs.gpio_is = readb(chip->base + GPIOIS); 336 chip->csave_regs.gpio_ibe = readb(chip->base + GPIOIBE); 337 chip->csave_regs.gpio_iev = readb(chip->base + GPIOIEV); 338 chip->csave_regs.gpio_ie = readb(chip->base + GPIOIE); 339 340 for (offset = 0; offset < PL061_GPIO_NR; offset++) { 341 if (chip->csave_regs.gpio_dir & (BIT(offset))) 342 chip->csave_regs.gpio_data |= 343 pl061_get_value(&chip->gc, offset) << offset; 344 } 345 346 return 0; 347} 348 349static int pl061_resume(struct device *dev) 350{ 351 struct pl061_gpio *chip = dev_get_drvdata(dev); 352 int offset; 353 354 for (offset = 0; offset < PL061_GPIO_NR; offset++) { 355 if (chip->csave_regs.gpio_dir & (BIT(offset))) 356 pl061_direction_output(&chip->gc, offset, 357 chip->csave_regs.gpio_data & 358 (BIT(offset))); 359 else 360 pl061_direction_input(&chip->gc, offset); 361 } 362 363 writeb(chip->csave_regs.gpio_is, chip->base + GPIOIS); 364 writeb(chip->csave_regs.gpio_ibe, chip->base + GPIOIBE); 365 writeb(chip->csave_regs.gpio_iev, chip->base + GPIOIEV); 366 writeb(chip->csave_regs.gpio_ie, chip->base + GPIOIE); 367 368 return 0; 369} 370 371static const struct dev_pm_ops pl061_dev_pm_ops = { 372 .suspend = pl061_suspend, 373 .resume = pl061_resume, 374 .freeze = pl061_suspend, 375 .restore = pl061_resume, 376}; 377#endif 378 379static struct amba_id pl061_ids[] = { 380 { 381 .id = 0x00041061, 382 .mask = 0x000fffff, 383 }, 384 { 0, 0 }, 385}; 386 387MODULE_DEVICE_TABLE(amba, pl061_ids); 388 389static struct amba_driver pl061_gpio_driver = { 390 .drv = { 391 .name = "pl061_gpio", 392#ifdef CONFIG_PM 393 .pm = &pl061_dev_pm_ops, 394#endif 395 }, 396 .id_table = pl061_ids, 397 .probe = pl061_probe, 398}; 399 400static int __init pl061_gpio_init(void) 401{ 402 return amba_driver_register(&pl061_gpio_driver); 403} 404module_init(pl061_gpio_init); 405 406MODULE_AUTHOR("Baruch Siach <baruch@tkos.co.il>"); 407MODULE_DESCRIPTION("PL061 GPIO driver"); 408MODULE_LICENSE("GPL"); 409