1/* langwell_gpio.c Moorestown platform Langwell chip GPIO driver 2 * Copyright (c) 2008 - 2009, Intel Corporation. 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 * This program is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU General Public License for more details. 12 * 13 * You should have received a copy of the GNU General Public License 14 * along with this program; if not, write to the Free Software 15 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 16 */ 17 18/* Supports: 19 * Moorestown platform Langwell chip. 20 * Medfield platform Penwell chip. 21 */ 22 23#include <linux/module.h> 24#include <linux/pci.h> 25#include <linux/kernel.h> 26#include <linux/delay.h> 27#include <linux/stddef.h> 28#include <linux/interrupt.h> 29#include <linux/init.h> 30#include <linux/irq.h> 31#include <linux/io.h> 32#include <linux/gpio.h> 33#include <linux/slab.h> 34 35/* 36 * Langwell chip has 64 pins and thus there are 2 32bit registers to control 37 * each feature, while Penwell chip has 96 pins for each block, and need 3 32bit 38 * registers to control them, so we only define the order here instead of a 39 * structure, to get a bit offset for a pin (use GPDR as an example): 40 * 41 * nreg = ngpio / 32; 42 * reg = offset / 32; 43 * bit = offset % 32; 44 * reg_addr = reg_base + GPDR * nreg * 4 + reg * 4; 45 * 46 * so the bit of reg_addr is to control pin offset's GPDR feature 47*/ 48 49enum GPIO_REG { 50 GPLR = 0, /* pin level read-only */ 51 GPDR, /* pin direction */ 52 GPSR, /* pin set */ 53 GPCR, /* pin clear */ 54 GRER, /* rising edge detect */ 55 GFER, /* falling edge detect */ 56 GEDR, /* edge detect result */ 57}; 58 59struct lnw_gpio { 60 struct gpio_chip chip; 61 void *reg_base; 62 spinlock_t lock; 63 unsigned irq_base; 64}; 65 66static void __iomem *gpio_reg(struct gpio_chip *chip, unsigned offset, 67 enum GPIO_REG reg_type) 68{ 69 struct lnw_gpio *lnw = container_of(chip, struct lnw_gpio, chip); 70 unsigned nreg = chip->ngpio / 32; 71 u8 reg = offset / 32; 72 void __iomem *ptr; 73 74 ptr = (void __iomem *)(lnw->reg_base + reg_type * nreg * 4 + reg * 4); 75 return ptr; 76} 77 78static int lnw_gpio_get(struct gpio_chip *chip, unsigned offset) 79{ 80 void __iomem *gplr = gpio_reg(chip, offset, GPLR); 81 82 return readl(gplr) & BIT(offset % 32); 83} 84 85static void lnw_gpio_set(struct gpio_chip *chip, unsigned offset, int value) 86{ 87 void __iomem *gpsr, *gpcr; 88 89 if (value) { 90 gpsr = gpio_reg(chip, offset, GPSR); 91 writel(BIT(offset % 32), gpsr); 92 } else { 93 gpcr = gpio_reg(chip, offset, GPCR); 94 writel(BIT(offset % 32), gpcr); 95 } 96} 97 98static int lnw_gpio_direction_input(struct gpio_chip *chip, unsigned offset) 99{ 100 struct lnw_gpio *lnw = container_of(chip, struct lnw_gpio, chip); 101 void __iomem *gpdr = gpio_reg(chip, offset, GPDR); 102 u32 value; 103 unsigned long flags; 104 105 spin_lock_irqsave(&lnw->lock, flags); 106 value = readl(gpdr); 107 value &= ~BIT(offset % 32); 108 writel(value, gpdr); 109 spin_unlock_irqrestore(&lnw->lock, flags); 110 return 0; 111} 112 113static int lnw_gpio_direction_output(struct gpio_chip *chip, 114 unsigned offset, int value) 115{ 116 struct lnw_gpio *lnw = container_of(chip, struct lnw_gpio, chip); 117 void __iomem *gpdr = gpio_reg(chip, offset, GPDR); 118 unsigned long flags; 119 120 lnw_gpio_set(chip, offset, value); 121 spin_lock_irqsave(&lnw->lock, flags); 122 value = readl(gpdr); 123 value |= BIT(offset % 32);; 124 writel(value, gpdr); 125 spin_unlock_irqrestore(&lnw->lock, flags); 126 return 0; 127} 128 129static int lnw_gpio_to_irq(struct gpio_chip *chip, unsigned offset) 130{ 131 struct lnw_gpio *lnw = container_of(chip, struct lnw_gpio, chip); 132 return lnw->irq_base + offset; 133} 134 135static int lnw_irq_type(unsigned irq, unsigned type) 136{ 137 struct lnw_gpio *lnw = get_irq_chip_data(irq); 138 u32 gpio = irq - lnw->irq_base; 139 unsigned long flags; 140 u32 value; 141 void __iomem *grer = gpio_reg(&lnw->chip, gpio, GRER); 142 void __iomem *gfer = gpio_reg(&lnw->chip, gpio, GFER); 143 144 if (gpio >= lnw->chip.ngpio) 145 return -EINVAL; 146 spin_lock_irqsave(&lnw->lock, flags); 147 if (type & IRQ_TYPE_EDGE_RISING) 148 value = readl(grer) | BIT(gpio % 32); 149 else 150 value = readl(grer) & (~BIT(gpio % 32)); 151 writel(value, grer); 152 153 if (type & IRQ_TYPE_EDGE_FALLING) 154 value = readl(gfer) | BIT(gpio % 32); 155 else 156 value = readl(gfer) & (~BIT(gpio % 32)); 157 writel(value, gfer); 158 spin_unlock_irqrestore(&lnw->lock, flags); 159 160 return 0; 161}; 162 163static void lnw_irq_unmask(unsigned irq) 164{ 165}; 166 167static void lnw_irq_mask(unsigned irq) 168{ 169}; 170 171static struct irq_chip lnw_irqchip = { 172 .name = "LNW-GPIO", 173 .mask = lnw_irq_mask, 174 .unmask = lnw_irq_unmask, 175 .set_type = lnw_irq_type, 176}; 177 178static DEFINE_PCI_DEVICE_TABLE(lnw_gpio_ids) = { /* pin number */ 179 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x080f), .driver_data = 64 }, 180 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x081f), .driver_data = 96 }, 181 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x081a), .driver_data = 96 }, 182 { 0, } 183}; 184MODULE_DEVICE_TABLE(pci, lnw_gpio_ids); 185 186static void lnw_irq_handler(unsigned irq, struct irq_desc *desc) 187{ 188 struct lnw_gpio *lnw = (struct lnw_gpio *)get_irq_data(irq); 189 u32 base, gpio; 190 void __iomem *gedr; 191 u32 gedr_v; 192 193 /* check GPIO controller to check which pin triggered the interrupt */ 194 for (base = 0; base < lnw->chip.ngpio; base += 32) { 195 gedr = gpio_reg(&lnw->chip, base, GEDR); 196 gedr_v = readl(gedr); 197 if (!gedr_v) 198 continue; 199 for (gpio = base; gpio < base + 32; gpio++) 200 if (gedr_v & BIT(gpio % 32)) { 201 pr_debug("pin %d triggered\n", gpio); 202 generic_handle_irq(lnw->irq_base + gpio); 203 } 204 /* clear the edge detect status bit */ 205 writel(gedr_v, gedr); 206 } 207 desc->chip->eoi(irq); 208} 209 210static int __devinit lnw_gpio_probe(struct pci_dev *pdev, 211 const struct pci_device_id *id) 212{ 213 void *base; 214 int i; 215 resource_size_t start, len; 216 struct lnw_gpio *lnw; 217 u32 irq_base; 218 u32 gpio_base; 219 int retval = 0; 220 221 retval = pci_enable_device(pdev); 222 if (retval) 223 goto done; 224 225 retval = pci_request_regions(pdev, "langwell_gpio"); 226 if (retval) { 227 dev_err(&pdev->dev, "error requesting resources\n"); 228 goto err2; 229 } 230 /* get the irq_base from bar1 */ 231 start = pci_resource_start(pdev, 1); 232 len = pci_resource_len(pdev, 1); 233 base = ioremap_nocache(start, len); 234 if (!base) { 235 dev_err(&pdev->dev, "error mapping bar1\n"); 236 goto err3; 237 } 238 irq_base = *(u32 *)base; 239 gpio_base = *((u32 *)base + 1); 240 /* release the IO mapping, since we already get the info from bar1 */ 241 iounmap(base); 242 /* get the register base from bar0 */ 243 start = pci_resource_start(pdev, 0); 244 len = pci_resource_len(pdev, 0); 245 base = ioremap_nocache(start, len); 246 if (!base) { 247 dev_err(&pdev->dev, "error mapping bar0\n"); 248 retval = -EFAULT; 249 goto err3; 250 } 251 252 lnw = kzalloc(sizeof(struct lnw_gpio), GFP_KERNEL); 253 if (!lnw) { 254 dev_err(&pdev->dev, "can't allocate langwell_gpio chip data\n"); 255 retval = -ENOMEM; 256 goto err4; 257 } 258 lnw->reg_base = base; 259 lnw->irq_base = irq_base; 260 lnw->chip.label = dev_name(&pdev->dev); 261 lnw->chip.direction_input = lnw_gpio_direction_input; 262 lnw->chip.direction_output = lnw_gpio_direction_output; 263 lnw->chip.get = lnw_gpio_get; 264 lnw->chip.set = lnw_gpio_set; 265 lnw->chip.to_irq = lnw_gpio_to_irq; 266 lnw->chip.base = gpio_base; 267 lnw->chip.ngpio = id->driver_data; 268 lnw->chip.can_sleep = 0; 269 pci_set_drvdata(pdev, lnw); 270 retval = gpiochip_add(&lnw->chip); 271 if (retval) { 272 dev_err(&pdev->dev, "langwell gpiochip_add error %d\n", retval); 273 goto err5; 274 } 275 set_irq_data(pdev->irq, lnw); 276 set_irq_chained_handler(pdev->irq, lnw_irq_handler); 277 for (i = 0; i < lnw->chip.ngpio; i++) { 278 set_irq_chip_and_handler_name(i + lnw->irq_base, &lnw_irqchip, 279 handle_simple_irq, "demux"); 280 set_irq_chip_data(i + lnw->irq_base, lnw); 281 } 282 283 spin_lock_init(&lnw->lock); 284 goto done; 285err5: 286 kfree(lnw); 287err4: 288 iounmap(base); 289err3: 290 pci_release_regions(pdev); 291err2: 292 pci_disable_device(pdev); 293done: 294 return retval; 295} 296 297static struct pci_driver lnw_gpio_driver = { 298 .name = "langwell_gpio", 299 .id_table = lnw_gpio_ids, 300 .probe = lnw_gpio_probe, 301}; 302 303static int __init lnw_gpio_init(void) 304{ 305 return pci_register_driver(&lnw_gpio_driver); 306} 307 308device_initcall(lnw_gpio_init); 309