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
sdv_gpio_pub_set_type(struct irq_data * d,unsigned int type)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
sdv_gpio_pub_irq_handler(int irq,void * data)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
sdv_xlate(struct irq_domain * h,struct device_node * node,const u32 * intspec,u32 intsize,irq_hw_number_t * out_hwirq,u32 * out_type)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
sdv_register_irqsupport(struct sdv_gpio_chip_data * sd,struct pci_dev * pdev)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
sdv_gpio_probe(struct pci_dev * pdev,const struct pci_device_id * pci_id)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