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