1 /* 2 * GPIO interface for Intel Sodaville SoCs. 3 * 4 * Copyright (c) 2010, 2011 Intel Corporation 5 * 6 * Author: Hans J. Koch <hjk@linutronix.de> 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License 2 as published 10 * by the Free Software Foundation. 11 * 12 */ 13 14 #include <linux/errno.h> 15 #include <linux/init.h> 16 #include <linux/io.h> 17 #include <linux/irq.h> 18 #include <linux/interrupt.h> 19 #include <linux/kernel.h> 20 #include <linux/pci.h> 21 #include <linux/platform_device.h> 22 #include <linux/of_irq.h> 23 #include <linux/gpio/driver.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 gpio_chip chip; 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 reg; 55 56 if (d->hwirq < 8) 57 type_reg = sd->gpio_pub_base + GPIT1R0; 58 else 59 type_reg = sd->gpio_pub_base + GPIT1R1; 60 61 reg = readl(type_reg); 62 63 switch (type) { 64 case IRQ_TYPE_LEVEL_HIGH: 65 reg &= ~BIT(4 * (d->hwirq % 8)); 66 break; 67 68 case IRQ_TYPE_LEVEL_LOW: 69 reg |= BIT(4 * (d->hwirq % 8)); 70 break; 71 72 default: 73 return -EINVAL; 74 } 75 76 writel(reg, type_reg); 77 return 0; 78 } 79 80 static irqreturn_t sdv_gpio_pub_irq_handler(int irq, void *data) 81 { 82 struct sdv_gpio_chip_data *sd = data; 83 u32 irq_stat = readl(sd->gpio_pub_base + GPSTR); 84 85 irq_stat &= readl(sd->gpio_pub_base + GPIO_INT); 86 if (!irq_stat) 87 return IRQ_NONE; 88 89 while (irq_stat) { 90 u32 irq_bit = __fls(irq_stat); 91 92 irq_stat &= ~BIT(irq_bit); 93 generic_handle_irq(irq_find_mapping(sd->id, irq_bit)); 94 } 95 96 return IRQ_HANDLED; 97 } 98 99 static int sdv_xlate(struct irq_domain *h, struct device_node *node, 100 const u32 *intspec, u32 intsize, irq_hw_number_t *out_hwirq, 101 u32 *out_type) 102 { 103 u32 line, type; 104 105 if (node != irq_domain_get_of_node(h)) 106 return -EINVAL; 107 108 if (intsize < 2) 109 return -EINVAL; 110 111 line = *intspec; 112 *out_hwirq = line; 113 114 intspec++; 115 type = *intspec; 116 117 switch (type) { 118 case IRQ_TYPE_LEVEL_LOW: 119 case IRQ_TYPE_LEVEL_HIGH: 120 *out_type = type; 121 break; 122 default: 123 return -EINVAL; 124 } 125 return 0; 126 } 127 128 static const struct irq_domain_ops irq_domain_sdv_ops = { 129 .xlate = sdv_xlate, 130 }; 131 132 static int sdv_register_irqsupport(struct sdv_gpio_chip_data *sd, 133 struct pci_dev *pdev) 134 { 135 struct irq_chip_type *ct; 136 int ret; 137 138 sd->irq_base = devm_irq_alloc_descs(&pdev->dev, -1, 0, 139 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 = devm_request_irq(&pdev->dev, pdev->irq, 148 sdv_gpio_pub_irq_handler, IRQF_SHARED, 149 "sdv_gpio", sd); 150 if (ret) 151 return ret; 152 153 /* 154 * This gpio irq controller latches level irqs. Testing shows that if 155 * we unmask & ACK the IRQ before the source of the interrupt is gone 156 * then the interrupt is active again. 157 */ 158 sd->gc = irq_alloc_generic_chip("sdv-gpio", 1, sd->irq_base, 159 sd->gpio_pub_base, handle_fasteoi_irq); 160 if (!sd->gc) 161 return -ENOMEM; 162 163 sd->gc->private = sd; 164 ct = sd->gc->chip_types; 165 ct->type = IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW; 166 ct->regs.eoi = GPSTR; 167 ct->regs.mask = GPIO_INT; 168 ct->chip.irq_mask = irq_gc_mask_clr_bit; 169 ct->chip.irq_unmask = irq_gc_mask_set_bit; 170 ct->chip.irq_eoi = irq_gc_eoi; 171 ct->chip.irq_set_type = sdv_gpio_pub_set_type; 172 173 irq_setup_generic_chip(sd->gc, IRQ_MSK(SDV_NUM_PUB_GPIOS), 174 IRQ_GC_INIT_MASK_CACHE, IRQ_NOREQUEST, 175 IRQ_LEVEL | IRQ_NOPROBE); 176 177 sd->id = irq_domain_add_legacy(pdev->dev.of_node, SDV_NUM_PUB_GPIOS, 178 sd->irq_base, 0, &irq_domain_sdv_ops, sd); 179 if (!sd->id) 180 return -ENODEV; 181 182 return 0; 183 } 184 185 static int sdv_gpio_probe(struct pci_dev *pdev, 186 const struct pci_device_id *pci_id) 187 { 188 struct sdv_gpio_chip_data *sd; 189 unsigned long addr; 190 const void *prop; 191 int len; 192 int ret; 193 u32 mux_val; 194 195 sd = kzalloc(sizeof(struct sdv_gpio_chip_data), GFP_KERNEL); 196 if (!sd) 197 return -ENOMEM; 198 ret = pci_enable_device(pdev); 199 if (ret) { 200 dev_err(&pdev->dev, "can't enable device.\n"); 201 goto done; 202 } 203 204 ret = pci_request_region(pdev, GPIO_BAR, DRV_NAME); 205 if (ret) { 206 dev_err(&pdev->dev, "can't alloc PCI BAR #%d\n", GPIO_BAR); 207 goto disable_pci; 208 } 209 210 addr = pci_resource_start(pdev, GPIO_BAR); 211 if (!addr) { 212 ret = -ENODEV; 213 goto release_reg; 214 } 215 sd->gpio_pub_base = ioremap(addr, pci_resource_len(pdev, GPIO_BAR)); 216 217 prop = of_get_property(pdev->dev.of_node, "intel,muxctl", &len); 218 if (prop && len == 4) { 219 mux_val = of_read_number(prop, 1); 220 writel(mux_val, sd->gpio_pub_base + GPMUXCTL); 221 } 222 223 ret = bgpio_init(&sd->chip, &pdev->dev, 4, 224 sd->gpio_pub_base + GPINR, sd->gpio_pub_base + GPOUTR, 225 NULL, sd->gpio_pub_base + GPOER, NULL, 0); 226 if (ret) 227 goto unmap; 228 sd->chip.ngpio = SDV_NUM_PUB_GPIOS; 229 230 ret = gpiochip_add_data(&sd->chip, sd); 231 if (ret < 0) { 232 dev_err(&pdev->dev, "gpiochip_add() failed.\n"); 233 goto unmap; 234 } 235 236 ret = sdv_register_irqsupport(sd, pdev); 237 if (ret) 238 goto unmap; 239 240 pci_set_drvdata(pdev, sd); 241 dev_info(&pdev->dev, "Sodaville GPIO driver registered.\n"); 242 return 0; 243 244 unmap: 245 iounmap(sd->gpio_pub_base); 246 release_reg: 247 pci_release_region(pdev, GPIO_BAR); 248 disable_pci: 249 pci_disable_device(pdev); 250 done: 251 kfree(sd); 252 return ret; 253 } 254 255 static const struct pci_device_id sdv_gpio_pci_ids[] = { 256 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_SDV_GPIO) }, 257 { 0, }, 258 }; 259 260 static struct pci_driver sdv_gpio_driver = { 261 .driver = { 262 .suppress_bind_attrs = true, 263 }, 264 .name = DRV_NAME, 265 .id_table = sdv_gpio_pci_ids, 266 .probe = sdv_gpio_probe, 267 }; 268 builtin_pci_driver(sdv_gpio_driver); 269