1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * GPIO interface for Intel Sodaville SoCs. 4 * 5 * Copyright (c) 2010, 2011 Intel Corporation 6 * 7 * Author: Hans J. Koch <hjk@linutronix.de> 8 */ 9 10 #include <linux/errno.h> 11 #include <linux/gpio/driver.h> 12 #include <linux/gpio/generic.h> 13 #include <linux/init.h> 14 #include <linux/interrupt.h> 15 #include <linux/io.h> 16 #include <linux/irq.h> 17 #include <linux/kernel.h> 18 #include <linux/of_irq.h> 19 #include <linux/pci.h> 20 #include <linux/platform_device.h> 21 22 #define DRV_NAME "sdv_gpio" 23 #define SDV_NUM_PUB_GPIOS 12 24 #define PCI_DEVICE_ID_SDV_GPIO 0x2e67 25 #define GPIO_BAR 0 26 27 #define GPOUTR 0x00 28 #define GPOER 0x04 29 #define GPINR 0x08 30 31 #define GPSTR 0x0c 32 #define GPIT1R0 0x10 33 #define GPIO_INT 0x14 34 #define GPIT1R1 0x18 35 36 #define GPMUXCTL 0x1c 37 38 struct sdv_gpio_chip_data { 39 int irq_base; 40 void __iomem *gpio_pub_base; 41 struct irq_domain *id; 42 struct irq_chip_generic *gc; 43 struct gpio_generic_chip gen_gc; 44 }; 45 46 static int sdv_gpio_pub_set_type(struct irq_data *d, unsigned int type) 47 { 48 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); 49 struct sdv_gpio_chip_data *sd = gc->private; 50 void __iomem *type_reg; 51 u32 reg; 52 53 if (d->hwirq < 8) 54 type_reg = sd->gpio_pub_base + GPIT1R0; 55 else 56 type_reg = sd->gpio_pub_base + GPIT1R1; 57 58 reg = readl(type_reg); 59 60 switch (type) { 61 case IRQ_TYPE_LEVEL_HIGH: 62 reg &= ~BIT(4 * (d->hwirq % 8)); 63 break; 64 65 case IRQ_TYPE_LEVEL_LOW: 66 reg |= BIT(4 * (d->hwirq % 8)); 67 break; 68 69 default: 70 return -EINVAL; 71 } 72 73 writel(reg, type_reg); 74 return 0; 75 } 76 77 static irqreturn_t sdv_gpio_pub_irq_handler(int irq, void *data) 78 { 79 struct sdv_gpio_chip_data *sd = data; 80 unsigned long irq_stat = readl(sd->gpio_pub_base + GPSTR); 81 int irq_bit; 82 83 irq_stat &= readl(sd->gpio_pub_base + GPIO_INT); 84 if (!irq_stat) 85 return IRQ_NONE; 86 87 for_each_set_bit(irq_bit, &irq_stat, 32) 88 generic_handle_domain_irq(sd->id, irq_bit); 89 90 return IRQ_HANDLED; 91 } 92 93 static int sdv_xlate(struct irq_domain *h, struct device_node *node, 94 const u32 *intspec, u32 intsize, irq_hw_number_t *out_hwirq, 95 u32 *out_type) 96 { 97 u32 line, type; 98 99 if (node != irq_domain_get_of_node(h)) 100 return -EINVAL; 101 102 if (intsize < 2) 103 return -EINVAL; 104 105 line = *intspec; 106 *out_hwirq = line; 107 108 intspec++; 109 type = *intspec; 110 111 switch (type) { 112 case IRQ_TYPE_LEVEL_LOW: 113 case IRQ_TYPE_LEVEL_HIGH: 114 *out_type = type; 115 break; 116 default: 117 return -EINVAL; 118 } 119 return 0; 120 } 121 122 static const struct irq_domain_ops irq_domain_sdv_ops = { 123 .xlate = sdv_xlate, 124 }; 125 126 static int sdv_register_irqsupport(struct sdv_gpio_chip_data *sd, 127 struct pci_dev *pdev) 128 { 129 struct irq_chip_type *ct; 130 int ret; 131 132 sd->irq_base = devm_irq_alloc_descs(&pdev->dev, -1, 0, 133 SDV_NUM_PUB_GPIOS, -1); 134 if (sd->irq_base < 0) 135 return sd->irq_base; 136 137 /* mask + ACK all interrupt sources */ 138 writel(0, sd->gpio_pub_base + GPIO_INT); 139 writel((1 << 11) - 1, sd->gpio_pub_base + GPSTR); 140 141 ret = devm_request_irq(&pdev->dev, pdev->irq, 142 sdv_gpio_pub_irq_handler, IRQF_SHARED, 143 "sdv_gpio", sd); 144 if (ret) 145 return ret; 146 147 /* 148 * This gpio irq controller latches level irqs. Testing shows that if 149 * we unmask & ACK the IRQ before the source of the interrupt is gone 150 * then the interrupt is active again. 151 */ 152 sd->gc = devm_irq_alloc_generic_chip(&pdev->dev, "sdv-gpio", 1, 153 sd->irq_base, 154 sd->gpio_pub_base, 155 handle_fasteoi_irq); 156 if (!sd->gc) 157 return -ENOMEM; 158 159 sd->gc->private = sd; 160 ct = sd->gc->chip_types; 161 ct->type = IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW; 162 ct->regs.eoi = GPSTR; 163 ct->regs.mask = GPIO_INT; 164 ct->chip.irq_mask = irq_gc_mask_clr_bit; 165 ct->chip.irq_unmask = irq_gc_mask_set_bit; 166 ct->chip.irq_eoi = irq_gc_eoi; 167 ct->chip.irq_set_type = sdv_gpio_pub_set_type; 168 169 irq_setup_generic_chip(sd->gc, IRQ_MSK(SDV_NUM_PUB_GPIOS), 170 IRQ_GC_INIT_MASK_CACHE, IRQ_NOREQUEST, 171 IRQ_LEVEL | IRQ_NOPROBE); 172 173 sd->id = irq_domain_create_legacy(dev_fwnode(&pdev->dev), SDV_NUM_PUB_GPIOS, sd->irq_base, 174 0, &irq_domain_sdv_ops, sd); 175 if (!sd->id) 176 return -ENODEV; 177 178 return 0; 179 } 180 181 static int sdv_gpio_probe(struct pci_dev *pdev, 182 const struct pci_device_id *pci_id) 183 { 184 struct gpio_generic_chip_config config; 185 struct sdv_gpio_chip_data *sd; 186 int ret; 187 u32 mux_val; 188 189 sd = devm_kzalloc(&pdev->dev, sizeof(*sd), GFP_KERNEL); 190 if (!sd) 191 return -ENOMEM; 192 193 ret = pcim_enable_device(pdev); 194 if (ret) { 195 dev_err(&pdev->dev, "can't enable device.\n"); 196 return ret; 197 } 198 199 ret = pcim_iomap_regions(pdev, 1 << GPIO_BAR, DRV_NAME); 200 if (ret) { 201 dev_err(&pdev->dev, "can't alloc PCI BAR #%d\n", GPIO_BAR); 202 return ret; 203 } 204 205 sd->gpio_pub_base = pcim_iomap_table(pdev)[GPIO_BAR]; 206 207 ret = of_property_read_u32(pdev->dev.of_node, "intel,muxctl", &mux_val); 208 if (!ret) 209 writel(mux_val, sd->gpio_pub_base + GPMUXCTL); 210 211 config = (struct gpio_generic_chip_config) { 212 .dev = &pdev->dev, 213 .sz = 4, 214 .dat = sd->gpio_pub_base + GPINR, 215 .set = sd->gpio_pub_base + GPOUTR, 216 .dirout = sd->gpio_pub_base + GPOER, 217 }; 218 219 ret = gpio_generic_chip_init(&sd->gen_gc, &config); 220 if (ret) 221 return ret; 222 223 sd->gen_gc.gc.ngpio = SDV_NUM_PUB_GPIOS; 224 225 ret = devm_gpiochip_add_data(&pdev->dev, &sd->gen_gc.gc, sd); 226 if (ret < 0) { 227 dev_err(&pdev->dev, "gpiochip_add() failed.\n"); 228 return ret; 229 } 230 231 ret = sdv_register_irqsupport(sd, pdev); 232 if (ret) 233 return ret; 234 235 pci_set_drvdata(pdev, sd); 236 dev_info(&pdev->dev, "Sodaville GPIO driver registered.\n"); 237 return 0; 238 } 239 240 static const struct pci_device_id sdv_gpio_pci_ids[] = { 241 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_SDV_GPIO) }, 242 { 0, }, 243 }; 244 245 static struct pci_driver sdv_gpio_driver = { 246 .driver = { 247 .suppress_bind_attrs = true, 248 }, 249 .name = DRV_NAME, 250 .id_table = sdv_gpio_pci_ids, 251 .probe = sdv_gpio_probe, 252 }; 253 builtin_pci_driver(sdv_gpio_driver); 254