1 /* 2 * GPIO interface for Intel Sodaville SoCs. 3 * 4 * Copyright (c) 2010, 2011 Intel Corporation 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License 2 as published 8 * by the Free Software Foundation. 9 * 10 */ 11 12 #include <linux/errno.h> 13 #include <linux/gpio.h> 14 #include <linux/init.h> 15 #include <linux/io.h> 16 #include <linux/irq.h> 17 #include <linux/interrupt.h> 18 #include <linux/kernel.h> 19 #include <linux/module.h> 20 #include <linux/pci.h> 21 #include <linux/platform_device.h> 22 #include <linux/of_irq.h> 23 #include <linux/basic_mmio_gpio.h> 24 25 #define DRV_NAME "sdv_gpio" 26 #define SDV_NUM_PUB_GPIOS 12 27 #define PCI_DEVICE_ID_SDV_GPIO 0x2e67 28 #define GPIO_BAR 0 29 30 #define GPOUTR 0x00 31 #define GPOER 0x04 32 #define GPINR 0x08 33 34 #define GPSTR 0x0c 35 #define GPIT1R0 0x10 36 #define GPIO_INT 0x14 37 #define GPIT1R1 0x18 38 39 #define GPMUXCTL 0x1c 40 41 struct sdv_gpio_chip_data { 42 int irq_base; 43 void __iomem *gpio_pub_base; 44 struct irq_domain id; 45 struct irq_chip_generic *gc; 46 struct bgpio_chip bgpio; 47 }; 48 49 static int sdv_gpio_pub_set_type(struct irq_data *d, unsigned int type) 50 { 51 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); 52 struct sdv_gpio_chip_data *sd = gc->private; 53 void __iomem *type_reg; 54 u32 irq_offs = d->irq - sd->irq_base; 55 u32 reg; 56 57 if (irq_offs < 8) 58 type_reg = sd->gpio_pub_base + GPIT1R0; 59 else 60 type_reg = sd->gpio_pub_base + GPIT1R1; 61 62 reg = readl(type_reg); 63 64 switch (type) { 65 case IRQ_TYPE_LEVEL_HIGH: 66 reg &= ~BIT(4 * (irq_offs % 8)); 67 break; 68 69 case IRQ_TYPE_LEVEL_LOW: 70 reg |= BIT(4 * (irq_offs % 8)); 71 break; 72 73 default: 74 return -EINVAL; 75 } 76 77 writel(reg, type_reg); 78 return 0; 79 } 80 81 static irqreturn_t sdv_gpio_pub_irq_handler(int irq, void *data) 82 { 83 struct sdv_gpio_chip_data *sd = data; 84 u32 irq_stat = readl(sd->gpio_pub_base + GPSTR); 85 86 irq_stat &= readl(sd->gpio_pub_base + GPIO_INT); 87 if (!irq_stat) 88 return IRQ_NONE; 89 90 while (irq_stat) { 91 u32 irq_bit = __fls(irq_stat); 92 93 irq_stat &= ~BIT(irq_bit); 94 generic_handle_irq(sd->irq_base + irq_bit); 95 } 96 97 return IRQ_HANDLED; 98 } 99 100 static int sdv_xlate(struct irq_domain *h, struct device_node *node, 101 const u32 *intspec, u32 intsize, irq_hw_number_t *out_hwirq, 102 u32 *out_type) 103 { 104 u32 line, type; 105 106 if (node != h->of_node) 107 return -EINVAL; 108 109 if (intsize < 2) 110 return -EINVAL; 111 112 line = *intspec; 113 *out_hwirq = line; 114 115 intspec++; 116 type = *intspec; 117 118 switch (type) { 119 case IRQ_TYPE_LEVEL_LOW: 120 case IRQ_TYPE_LEVEL_HIGH: 121 *out_type = type; 122 break; 123 default: 124 return -EINVAL; 125 } 126 return 0; 127 } 128 129 static struct irq_domain_ops irq_domain_sdv_ops = { 130 .dt_translate = sdv_xlate, 131 }; 132 133 static __devinit int sdv_register_irqsupport(struct sdv_gpio_chip_data *sd, 134 struct pci_dev *pdev) 135 { 136 struct irq_chip_type *ct; 137 int ret; 138 139 sd->irq_base = irq_alloc_descs(-1, 0, SDV_NUM_PUB_GPIOS, -1); 140 if (sd->irq_base < 0) 141 return sd->irq_base; 142 143 /* mask + ACK all interrupt sources */ 144 writel(0, sd->gpio_pub_base + GPIO_INT); 145 writel((1 << 11) - 1, sd->gpio_pub_base + GPSTR); 146 147 ret = request_irq(pdev->irq, sdv_gpio_pub_irq_handler, IRQF_SHARED, 148 "sdv_gpio", sd); 149 if (ret) 150 goto out_free_desc; 151 152 sd->id.irq_base = sd->irq_base; 153 sd->id.of_node = of_node_get(pdev->dev.of_node); 154 sd->id.ops = &irq_domain_sdv_ops; 155 156 /* 157 * This gpio irq controller latches level irqs. Testing shows that if 158 * we unmask & ACK the IRQ before the source of the interrupt is gone 159 * then the interrupt is active again. 160 */ 161 sd->gc = irq_alloc_generic_chip("sdv-gpio", 1, sd->irq_base, 162 sd->gpio_pub_base, handle_fasteoi_irq); 163 if (!sd->gc) { 164 ret = -ENOMEM; 165 goto out_free_irq; 166 } 167 168 sd->gc->private = sd; 169 ct = sd->gc->chip_types; 170 ct->type = IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW; 171 ct->regs.eoi = GPSTR; 172 ct->regs.mask = GPIO_INT; 173 ct->chip.irq_mask = irq_gc_mask_clr_bit; 174 ct->chip.irq_unmask = irq_gc_mask_set_bit; 175 ct->chip.irq_eoi = irq_gc_eoi; 176 ct->chip.irq_set_type = sdv_gpio_pub_set_type; 177 178 irq_setup_generic_chip(sd->gc, IRQ_MSK(SDV_NUM_PUB_GPIOS), 179 IRQ_GC_INIT_MASK_CACHE, IRQ_NOREQUEST, 180 IRQ_LEVEL | IRQ_NOPROBE); 181 182 irq_domain_add(&sd->id); 183 return 0; 184 out_free_irq: 185 free_irq(pdev->irq, sd); 186 out_free_desc: 187 irq_free_descs(sd->irq_base, SDV_NUM_PUB_GPIOS); 188 return ret; 189 } 190 191 static int __devinit sdv_gpio_probe(struct pci_dev *pdev, 192 const struct pci_device_id *pci_id) 193 { 194 struct sdv_gpio_chip_data *sd; 195 unsigned long addr; 196 const void *prop; 197 int len; 198 int ret; 199 u32 mux_val; 200 201 sd = kzalloc(sizeof(struct sdv_gpio_chip_data), GFP_KERNEL); 202 if (!sd) 203 return -ENOMEM; 204 ret = pci_enable_device(pdev); 205 if (ret) { 206 dev_err(&pdev->dev, "can't enable device.\n"); 207 goto done; 208 } 209 210 ret = pci_request_region(pdev, GPIO_BAR, DRV_NAME); 211 if (ret) { 212 dev_err(&pdev->dev, "can't alloc PCI BAR #%d\n", GPIO_BAR); 213 goto disable_pci; 214 } 215 216 addr = pci_resource_start(pdev, GPIO_BAR); 217 if (!addr) 218 goto release_reg; 219 sd->gpio_pub_base = ioremap(addr, pci_resource_len(pdev, GPIO_BAR)); 220 221 prop = of_get_property(pdev->dev.of_node, "intel,muxctl", &len); 222 if (prop && len == 4) { 223 mux_val = of_read_number(prop, 1); 224 writel(mux_val, sd->gpio_pub_base + GPMUXCTL); 225 } 226 227 ret = bgpio_init(&sd->bgpio, &pdev->dev, 4, 228 sd->gpio_pub_base + GPINR, sd->gpio_pub_base + GPOUTR, 229 NULL, sd->gpio_pub_base + GPOER, NULL, false); 230 if (ret) 231 goto unmap; 232 sd->bgpio.gc.ngpio = SDV_NUM_PUB_GPIOS; 233 234 ret = gpiochip_add(&sd->bgpio.gc); 235 if (ret < 0) { 236 dev_err(&pdev->dev, "gpiochip_add() failed.\n"); 237 goto unmap; 238 } 239 240 ret = sdv_register_irqsupport(sd, pdev); 241 if (ret) 242 goto unmap; 243 244 pci_set_drvdata(pdev, sd); 245 dev_info(&pdev->dev, "Sodaville GPIO driver registered.\n"); 246 return 0; 247 248 unmap: 249 iounmap(sd->gpio_pub_base); 250 release_reg: 251 pci_release_region(pdev, GPIO_BAR); 252 disable_pci: 253 pci_disable_device(pdev); 254 done: 255 kfree(sd); 256 return ret; 257 } 258 259 static void sdv_gpio_remove(struct pci_dev *pdev) 260 { 261 struct sdv_gpio_chip_data *sd = pci_get_drvdata(pdev); 262 263 irq_domain_del(&sd->id); 264 free_irq(pdev->irq, sd); 265 irq_free_descs(sd->irq_base, SDV_NUM_PUB_GPIOS); 266 267 if (gpiochip_remove(&sd->bgpio.gc)) 268 dev_err(&pdev->dev, "gpiochip_remove() failed.\n"); 269 270 pci_release_region(pdev, GPIO_BAR); 271 iounmap(sd->gpio_pub_base); 272 pci_disable_device(pdev); 273 kfree(sd); 274 } 275 276 static struct pci_device_id sdv_gpio_pci_ids[] __devinitdata = { 277 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_SDV_GPIO) }, 278 { 0, }, 279 }; 280 281 static struct pci_driver sdv_gpio_driver = { 282 .name = DRV_NAME, 283 .id_table = sdv_gpio_pci_ids, 284 .probe = sdv_gpio_probe, 285 .remove = sdv_gpio_remove, 286 }; 287 288 static int __init sdv_gpio_init(void) 289 { 290 return pci_register_driver(&sdv_gpio_driver); 291 } 292 module_init(sdv_gpio_init); 293 294 static void __exit sdv_gpio_exit(void) 295 { 296 pci_unregister_driver(&sdv_gpio_driver); 297 } 298 module_exit(sdv_gpio_exit); 299 300 MODULE_AUTHOR("Hans J. Koch <hjk@linutronix.de>"); 301 MODULE_DESCRIPTION("GPIO interface for Intel Sodaville SoCs"); 302 MODULE_LICENSE("GPL v2"); 303