1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * Copyright (C) 2011 LAPIS Semiconductor Co., Ltd. |
4 | */ |
5 | #include <linux/bits.h> |
6 | #include <linux/gpio/driver.h> |
7 | #include <linux/interrupt.h> |
8 | #include <linux/irq.h> |
9 | #include <linux/kernel.h> |
10 | #include <linux/module.h> |
11 | #include <linux/pci.h> |
12 | #include <linux/slab.h> |
13 | |
14 | #define PCH_EDGE_FALLING 0 |
15 | #define PCH_EDGE_RISING 1 |
16 | #define PCH_LEVEL_L 2 |
17 | #define PCH_LEVEL_H 3 |
18 | #define PCH_EDGE_BOTH 4 |
19 | #define PCH_IM_MASK GENMASK(2, 0) |
20 | |
21 | #define PCH_IRQ_BASE 24 |
22 | |
23 | struct pch_regs { |
24 | u32 ien; |
25 | u32 istatus; |
26 | u32 idisp; |
27 | u32 iclr; |
28 | u32 imask; |
29 | u32 imaskclr; |
30 | u32 po; |
31 | u32 pi; |
32 | u32 pm; |
33 | u32 im0; |
34 | u32 im1; |
35 | u32 reserved[3]; |
36 | u32 gpio_use_sel; |
37 | u32 reset; |
38 | }; |
39 | |
40 | #define PCI_DEVICE_ID_INTEL_EG20T_PCH 0x8803 |
41 | #define PCI_DEVICE_ID_ROHM_ML7223m_IOH 0x8014 |
42 | #define PCI_DEVICE_ID_ROHM_ML7223n_IOH 0x8043 |
43 | #define PCI_DEVICE_ID_ROHM_EG20T_PCH 0x8803 |
44 | |
45 | enum pch_type_t { |
46 | INTEL_EG20T_PCH, |
47 | OKISEMI_ML7223m_IOH, /* LAPIS Semiconductor ML7223 IOH PCIe Bus-m */ |
48 | OKISEMI_ML7223n_IOH /* LAPIS Semiconductor ML7223 IOH PCIe Bus-n */ |
49 | }; |
50 | |
51 | /* Specifies number of GPIO PINS */ |
52 | static int gpio_pins[] = { |
53 | [INTEL_EG20T_PCH] = 12, |
54 | [OKISEMI_ML7223m_IOH] = 8, |
55 | [OKISEMI_ML7223n_IOH] = 8, |
56 | }; |
57 | |
58 | /** |
59 | * struct pch_gpio_reg_data - The register store data. |
60 | * @ien_reg: To store contents of IEN register. |
61 | * @imask_reg: To store contents of IMASK register. |
62 | * @po_reg: To store contents of PO register. |
63 | * @pm_reg: To store contents of PM register. |
64 | * @im0_reg: To store contents of IM0 register. |
65 | * @im1_reg: To store contents of IM1 register. |
66 | * @gpio_use_sel_reg : To store contents of GPIO_USE_SEL register. |
67 | * (Only ML7223 Bus-n) |
68 | */ |
69 | struct pch_gpio_reg_data { |
70 | u32 ien_reg; |
71 | u32 imask_reg; |
72 | u32 po_reg; |
73 | u32 pm_reg; |
74 | u32 im0_reg; |
75 | u32 im1_reg; |
76 | u32 gpio_use_sel_reg; |
77 | }; |
78 | |
79 | /** |
80 | * struct pch_gpio - GPIO private data structure. |
81 | * @base: PCI base address of Memory mapped I/O register. |
82 | * @reg: Memory mapped PCH GPIO register list. |
83 | * @dev: Pointer to device structure. |
84 | * @gpio: Data for GPIO infrastructure. |
85 | * @pch_gpio_reg: Memory mapped Register data is saved here |
86 | * when suspend. |
87 | * @lock: Used for register access protection |
88 | * @irq_base: Save base of IRQ number for interrupt |
89 | * @ioh: IOH ID |
90 | * @spinlock: Used for register access protection |
91 | */ |
92 | struct pch_gpio { |
93 | void __iomem *base; |
94 | struct pch_regs __iomem *reg; |
95 | struct device *dev; |
96 | struct gpio_chip gpio; |
97 | struct pch_gpio_reg_data pch_gpio_reg; |
98 | int irq_base; |
99 | enum pch_type_t ioh; |
100 | spinlock_t spinlock; |
101 | }; |
102 | |
103 | static void pch_gpio_set(struct gpio_chip *gpio, unsigned int nr, int val) |
104 | { |
105 | u32 reg_val; |
106 | struct pch_gpio *chip = gpiochip_get_data(gc: gpio); |
107 | unsigned long flags; |
108 | |
109 | spin_lock_irqsave(&chip->spinlock, flags); |
110 | reg_val = ioread32(&chip->reg->po); |
111 | if (val) |
112 | reg_val |= BIT(nr); |
113 | else |
114 | reg_val &= ~BIT(nr); |
115 | |
116 | iowrite32(reg_val, &chip->reg->po); |
117 | spin_unlock_irqrestore(lock: &chip->spinlock, flags); |
118 | } |
119 | |
120 | static int pch_gpio_get(struct gpio_chip *gpio, unsigned int nr) |
121 | { |
122 | struct pch_gpio *chip = gpiochip_get_data(gc: gpio); |
123 | |
124 | return !!(ioread32(&chip->reg->pi) & BIT(nr)); |
125 | } |
126 | |
127 | static int pch_gpio_direction_output(struct gpio_chip *gpio, unsigned int nr, |
128 | int val) |
129 | { |
130 | struct pch_gpio *chip = gpiochip_get_data(gc: gpio); |
131 | u32 pm; |
132 | u32 reg_val; |
133 | unsigned long flags; |
134 | |
135 | spin_lock_irqsave(&chip->spinlock, flags); |
136 | |
137 | reg_val = ioread32(&chip->reg->po); |
138 | if (val) |
139 | reg_val |= BIT(nr); |
140 | else |
141 | reg_val &= ~BIT(nr); |
142 | iowrite32(reg_val, &chip->reg->po); |
143 | |
144 | pm = ioread32(&chip->reg->pm); |
145 | pm &= BIT(gpio_pins[chip->ioh]) - 1; |
146 | pm |= BIT(nr); |
147 | iowrite32(pm, &chip->reg->pm); |
148 | |
149 | spin_unlock_irqrestore(lock: &chip->spinlock, flags); |
150 | |
151 | return 0; |
152 | } |
153 | |
154 | static int pch_gpio_direction_input(struct gpio_chip *gpio, unsigned int nr) |
155 | { |
156 | struct pch_gpio *chip = gpiochip_get_data(gc: gpio); |
157 | u32 pm; |
158 | unsigned long flags; |
159 | |
160 | spin_lock_irqsave(&chip->spinlock, flags); |
161 | pm = ioread32(&chip->reg->pm); |
162 | pm &= BIT(gpio_pins[chip->ioh]) - 1; |
163 | pm &= ~BIT(nr); |
164 | iowrite32(pm, &chip->reg->pm); |
165 | spin_unlock_irqrestore(lock: &chip->spinlock, flags); |
166 | |
167 | return 0; |
168 | } |
169 | |
170 | /* |
171 | * Save register configuration and disable interrupts. |
172 | */ |
173 | static void __maybe_unused pch_gpio_save_reg_conf(struct pch_gpio *chip) |
174 | { |
175 | chip->pch_gpio_reg.ien_reg = ioread32(&chip->reg->ien); |
176 | chip->pch_gpio_reg.imask_reg = ioread32(&chip->reg->imask); |
177 | chip->pch_gpio_reg.po_reg = ioread32(&chip->reg->po); |
178 | chip->pch_gpio_reg.pm_reg = ioread32(&chip->reg->pm); |
179 | chip->pch_gpio_reg.im0_reg = ioread32(&chip->reg->im0); |
180 | if (chip->ioh == INTEL_EG20T_PCH) |
181 | chip->pch_gpio_reg.im1_reg = ioread32(&chip->reg->im1); |
182 | if (chip->ioh == OKISEMI_ML7223n_IOH) |
183 | chip->pch_gpio_reg.gpio_use_sel_reg = ioread32(&chip->reg->gpio_use_sel); |
184 | } |
185 | |
186 | /* |
187 | * This function restores the register configuration of the GPIO device. |
188 | */ |
189 | static void __maybe_unused pch_gpio_restore_reg_conf(struct pch_gpio *chip) |
190 | { |
191 | iowrite32(chip->pch_gpio_reg.ien_reg, &chip->reg->ien); |
192 | iowrite32(chip->pch_gpio_reg.imask_reg, &chip->reg->imask); |
193 | /* to store contents of PO register */ |
194 | iowrite32(chip->pch_gpio_reg.po_reg, &chip->reg->po); |
195 | /* to store contents of PM register */ |
196 | iowrite32(chip->pch_gpio_reg.pm_reg, &chip->reg->pm); |
197 | iowrite32(chip->pch_gpio_reg.im0_reg, &chip->reg->im0); |
198 | if (chip->ioh == INTEL_EG20T_PCH) |
199 | iowrite32(chip->pch_gpio_reg.im1_reg, &chip->reg->im1); |
200 | if (chip->ioh == OKISEMI_ML7223n_IOH) |
201 | iowrite32(chip->pch_gpio_reg.gpio_use_sel_reg, &chip->reg->gpio_use_sel); |
202 | } |
203 | |
204 | static int pch_gpio_to_irq(struct gpio_chip *gpio, unsigned int offset) |
205 | { |
206 | struct pch_gpio *chip = gpiochip_get_data(gc: gpio); |
207 | |
208 | return chip->irq_base + offset; |
209 | } |
210 | |
211 | static void pch_gpio_setup(struct pch_gpio *chip) |
212 | { |
213 | struct gpio_chip *gpio = &chip->gpio; |
214 | |
215 | gpio->label = dev_name(dev: chip->dev); |
216 | gpio->parent = chip->dev; |
217 | gpio->owner = THIS_MODULE; |
218 | gpio->direction_input = pch_gpio_direction_input; |
219 | gpio->get = pch_gpio_get; |
220 | gpio->direction_output = pch_gpio_direction_output; |
221 | gpio->set = pch_gpio_set; |
222 | gpio->base = -1; |
223 | gpio->ngpio = gpio_pins[chip->ioh]; |
224 | gpio->can_sleep = false; |
225 | gpio->to_irq = pch_gpio_to_irq; |
226 | } |
227 | |
228 | static int pch_irq_type(struct irq_data *d, unsigned int type) |
229 | { |
230 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); |
231 | struct pch_gpio *chip = gc->private; |
232 | u32 im, im_pos, val; |
233 | u32 __iomem *im_reg; |
234 | unsigned long flags; |
235 | int ch, irq = d->irq; |
236 | |
237 | ch = irq - chip->irq_base; |
238 | if (irq < chip->irq_base + 8) { |
239 | im_reg = &chip->reg->im0; |
240 | im_pos = ch - 0; |
241 | } else { |
242 | im_reg = &chip->reg->im1; |
243 | im_pos = ch - 8; |
244 | } |
245 | dev_dbg(chip->dev, "irq=%d type=%d ch=%d pos=%d\n" , irq, type, ch, im_pos); |
246 | |
247 | switch (type) { |
248 | case IRQ_TYPE_EDGE_RISING: |
249 | val = PCH_EDGE_RISING; |
250 | break; |
251 | case IRQ_TYPE_EDGE_FALLING: |
252 | val = PCH_EDGE_FALLING; |
253 | break; |
254 | case IRQ_TYPE_EDGE_BOTH: |
255 | val = PCH_EDGE_BOTH; |
256 | break; |
257 | case IRQ_TYPE_LEVEL_HIGH: |
258 | val = PCH_LEVEL_H; |
259 | break; |
260 | case IRQ_TYPE_LEVEL_LOW: |
261 | val = PCH_LEVEL_L; |
262 | break; |
263 | default: |
264 | return 0; |
265 | } |
266 | |
267 | spin_lock_irqsave(&chip->spinlock, flags); |
268 | |
269 | /* Set interrupt mode */ |
270 | im = ioread32(im_reg) & ~(PCH_IM_MASK << (im_pos * 4)); |
271 | iowrite32(im | (val << (im_pos * 4)), im_reg); |
272 | |
273 | /* And the handler */ |
274 | if (type & IRQ_TYPE_LEVEL_MASK) |
275 | irq_set_handler_locked(data: d, handler: handle_level_irq); |
276 | else if (type & IRQ_TYPE_EDGE_BOTH) |
277 | irq_set_handler_locked(data: d, handler: handle_edge_irq); |
278 | |
279 | spin_unlock_irqrestore(lock: &chip->spinlock, flags); |
280 | return 0; |
281 | } |
282 | |
283 | static void pch_irq_unmask(struct irq_data *d) |
284 | { |
285 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); |
286 | struct pch_gpio *chip = gc->private; |
287 | |
288 | iowrite32(BIT(d->irq - chip->irq_base), &chip->reg->imaskclr); |
289 | } |
290 | |
291 | static void pch_irq_mask(struct irq_data *d) |
292 | { |
293 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); |
294 | struct pch_gpio *chip = gc->private; |
295 | |
296 | iowrite32(BIT(d->irq - chip->irq_base), &chip->reg->imask); |
297 | } |
298 | |
299 | static void pch_irq_ack(struct irq_data *d) |
300 | { |
301 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); |
302 | struct pch_gpio *chip = gc->private; |
303 | |
304 | iowrite32(BIT(d->irq - chip->irq_base), &chip->reg->iclr); |
305 | } |
306 | |
307 | static irqreturn_t pch_gpio_handler(int irq, void *dev_id) |
308 | { |
309 | struct pch_gpio *chip = dev_id; |
310 | unsigned long reg_val = ioread32(&chip->reg->istatus); |
311 | int i; |
312 | |
313 | dev_vdbg(chip->dev, "irq=%d status=0x%lx\n" , irq, reg_val); |
314 | |
315 | reg_val &= BIT(gpio_pins[chip->ioh]) - 1; |
316 | |
317 | for_each_set_bit(i, ®_val, gpio_pins[chip->ioh]) |
318 | generic_handle_irq(irq: chip->irq_base + i); |
319 | |
320 | return IRQ_RETVAL(reg_val); |
321 | } |
322 | |
323 | static int pch_gpio_alloc_generic_chip(struct pch_gpio *chip, |
324 | unsigned int irq_start, |
325 | unsigned int num) |
326 | { |
327 | struct irq_chip_generic *gc; |
328 | struct irq_chip_type *ct; |
329 | int rv; |
330 | |
331 | gc = devm_irq_alloc_generic_chip(dev: chip->dev, name: "pch_gpio" , num_ct: 1, irq_base: irq_start, |
332 | reg_base: chip->base, handler: handle_simple_irq); |
333 | if (!gc) |
334 | return -ENOMEM; |
335 | |
336 | gc->private = chip; |
337 | ct = gc->chip_types; |
338 | |
339 | ct->chip.irq_ack = pch_irq_ack; |
340 | ct->chip.irq_mask = pch_irq_mask; |
341 | ct->chip.irq_unmask = pch_irq_unmask; |
342 | ct->chip.irq_set_type = pch_irq_type; |
343 | |
344 | rv = devm_irq_setup_generic_chip(dev: chip->dev, gc, IRQ_MSK(num), |
345 | flags: IRQ_GC_INIT_MASK_CACHE, |
346 | clr: IRQ_NOREQUEST | IRQ_NOPROBE, set: 0); |
347 | |
348 | return rv; |
349 | } |
350 | |
351 | static int pch_gpio_probe(struct pci_dev *pdev, |
352 | const struct pci_device_id *id) |
353 | { |
354 | struct device *dev = &pdev->dev; |
355 | s32 ret; |
356 | struct pch_gpio *chip; |
357 | int irq_base; |
358 | |
359 | chip = devm_kzalloc(dev, size: sizeof(*chip), GFP_KERNEL); |
360 | if (chip == NULL) |
361 | return -ENOMEM; |
362 | |
363 | chip->dev = dev; |
364 | ret = pcim_enable_device(pdev); |
365 | if (ret) |
366 | return dev_err_probe(dev, err: ret, fmt: "Failed to enable PCI device\n" ); |
367 | |
368 | ret = pcim_iomap_regions(pdev, BIT(1), KBUILD_MODNAME); |
369 | if (ret) |
370 | return dev_err_probe(dev, err: ret, fmt: "Failed to request and map PCI regions\n" ); |
371 | |
372 | chip->base = pcim_iomap_table(pdev)[1]; |
373 | chip->ioh = id->driver_data; |
374 | chip->reg = chip->base; |
375 | pci_set_drvdata(pdev, data: chip); |
376 | spin_lock_init(&chip->spinlock); |
377 | pch_gpio_setup(chip); |
378 | |
379 | ret = devm_gpiochip_add_data(dev, &chip->gpio, chip); |
380 | if (ret) |
381 | return dev_err_probe(dev, err: ret, fmt: "Failed to register GPIO\n" ); |
382 | |
383 | irq_base = devm_irq_alloc_descs(dev, -1, 0, |
384 | gpio_pins[chip->ioh], NUMA_NO_NODE); |
385 | if (irq_base < 0) { |
386 | dev_warn(dev, "PCH gpio: Failed to get IRQ base num\n" ); |
387 | chip->irq_base = -1; |
388 | return 0; |
389 | } |
390 | chip->irq_base = irq_base; |
391 | |
392 | /* Mask all interrupts, but enable them */ |
393 | iowrite32(BIT(gpio_pins[chip->ioh]) - 1, &chip->reg->imask); |
394 | iowrite32(BIT(gpio_pins[chip->ioh]) - 1, &chip->reg->ien); |
395 | |
396 | ret = devm_request_irq(dev, irq: pdev->irq, handler: pch_gpio_handler, |
397 | IRQF_SHARED, KBUILD_MODNAME, dev_id: chip); |
398 | if (ret) |
399 | return dev_err_probe(dev, err: ret, fmt: "Failed to request IRQ\n" ); |
400 | |
401 | return pch_gpio_alloc_generic_chip(chip, irq_start: irq_base, num: gpio_pins[chip->ioh]); |
402 | } |
403 | |
404 | static int __maybe_unused pch_gpio_suspend(struct device *dev) |
405 | { |
406 | struct pch_gpio *chip = dev_get_drvdata(dev); |
407 | unsigned long flags; |
408 | |
409 | spin_lock_irqsave(&chip->spinlock, flags); |
410 | pch_gpio_save_reg_conf(chip); |
411 | spin_unlock_irqrestore(lock: &chip->spinlock, flags); |
412 | |
413 | return 0; |
414 | } |
415 | |
416 | static int __maybe_unused pch_gpio_resume(struct device *dev) |
417 | { |
418 | struct pch_gpio *chip = dev_get_drvdata(dev); |
419 | unsigned long flags; |
420 | |
421 | spin_lock_irqsave(&chip->spinlock, flags); |
422 | iowrite32(0x01, &chip->reg->reset); |
423 | iowrite32(0x00, &chip->reg->reset); |
424 | pch_gpio_restore_reg_conf(chip); |
425 | spin_unlock_irqrestore(lock: &chip->spinlock, flags); |
426 | |
427 | return 0; |
428 | } |
429 | |
430 | static SIMPLE_DEV_PM_OPS(pch_gpio_pm_ops, pch_gpio_suspend, pch_gpio_resume); |
431 | |
432 | static const struct pci_device_id pch_gpio_pcidev_id[] = { |
433 | { PCI_DEVICE_DATA(INTEL, EG20T_PCH, INTEL_EG20T_PCH) }, |
434 | { PCI_DEVICE_DATA(ROHM, ML7223m_IOH, OKISEMI_ML7223m_IOH) }, |
435 | { PCI_DEVICE_DATA(ROHM, ML7223n_IOH, OKISEMI_ML7223n_IOH) }, |
436 | { PCI_DEVICE_DATA(ROHM, EG20T_PCH, INTEL_EG20T_PCH) }, |
437 | { } |
438 | }; |
439 | MODULE_DEVICE_TABLE(pci, pch_gpio_pcidev_id); |
440 | |
441 | static struct pci_driver pch_gpio_driver = { |
442 | .name = "pch_gpio" , |
443 | .id_table = pch_gpio_pcidev_id, |
444 | .probe = pch_gpio_probe, |
445 | .driver = { |
446 | .pm = &pch_gpio_pm_ops, |
447 | }, |
448 | }; |
449 | |
450 | module_pci_driver(pch_gpio_driver); |
451 | |
452 | MODULE_DESCRIPTION("PCH GPIO PCI Driver" ); |
453 | MODULE_LICENSE("GPL v2" ); |
454 | |