Commit | Line | Data |
---|---|---|
9b8bf5bf | 1 | // SPDX-License-Identifier: GPL-2.0 |
04c17aa8 | 2 | /* |
f4574beb | 3 | * Copyright (C) 2011 LAPIS Semiconductor Co., Ltd. |
04c17aa8 | 4 | */ |
5c85418a | 5 | #include <linux/bits.h> |
5db1f873 | 6 | #include <linux/gpio/driver.h> |
38eb18a6 TM |
7 | #include <linux/interrupt.h> |
8 | #include <linux/irq.h> | |
3e1884f8 AS |
9 | #include <linux/kernel.h> |
10 | #include <linux/module.h> | |
11 | #include <linux/pci.h> | |
349b6c53 | 12 | #include <linux/slab.h> |
38eb18a6 TM |
13 | |
14 | #define PCH_EDGE_FALLING 0 | |
5c85418a AS |
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) | |
38eb18a6 TM |
20 | |
21 | #define PCH_IRQ_BASE 24 | |
04c17aa8 | 22 | |
04c17aa8 TM |
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; | |
e98bed7f TM |
35 | u32 reserved[3]; |
36 | u32 gpio_use_sel; | |
04c17aa8 TM |
37 | u32 reset; |
38 | }; | |
39 | ||
b65bb2c1 AS |
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 | ||
d4260e6d TM |
45 | enum pch_type_t { |
46 | INTEL_EG20T_PCH, | |
f4574beb TM |
47 | OKISEMI_ML7223m_IOH, /* LAPIS Semiconductor ML7223 IOH PCIe Bus-m */ |
48 | OKISEMI_ML7223n_IOH /* LAPIS Semiconductor ML7223 IOH PCIe Bus-n */ | |
d4260e6d TM |
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 | ||
04c17aa8 TM |
58 | /** |
59 | * struct pch_gpio_reg_data - The register store data. | |
38eb18a6 TM |
60 | * @ien_reg: To store contents of IEN register. |
61 | * @imask_reg: To store contents of IMASK register. | |
04c17aa8 TM |
62 | * @po_reg: To store contents of PO register. |
63 | * @pm_reg: To store contents of PM register. | |
e98bed7f TM |
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) | |
04c17aa8 TM |
68 | */ |
69 | struct pch_gpio_reg_data { | |
38eb18a6 TM |
70 | u32 ien_reg; |
71 | u32 imask_reg; | |
04c17aa8 TM |
72 | u32 po_reg; |
73 | u32 pm_reg; | |
e98bed7f TM |
74 | u32 im0_reg; |
75 | u32 im1_reg; | |
76 | u32 gpio_use_sel_reg; | |
04c17aa8 TM |
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. | |
38eb18a6 TM |
87 | * @lock: Used for register access protection |
88 | * @irq_base: Save base of IRQ number for interrupt | |
d4260e6d | 89 | * @ioh: IOH ID |
7cb6580c | 90 | * @spinlock: Used for register access protection |
04c17aa8 TM |
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; | |
38eb18a6 | 98 | int irq_base; |
d4260e6d | 99 | enum pch_type_t ioh; |
d568a681 | 100 | spinlock_t spinlock; |
04c17aa8 TM |
101 | }; |
102 | ||
0c106a23 | 103 | static void pch_gpio_set(struct gpio_chip *gpio, unsigned int nr, int val) |
04c17aa8 TM |
104 | { |
105 | u32 reg_val; | |
510f4871 | 106 | struct pch_gpio *chip = gpiochip_get_data(gpio); |
7cb6580c | 107 | unsigned long flags; |
04c17aa8 | 108 | |
7cb6580c | 109 | spin_lock_irqsave(&chip->spinlock, flags); |
04c17aa8 TM |
110 | reg_val = ioread32(&chip->reg->po); |
111 | if (val) | |
5c85418a | 112 | reg_val |= BIT(nr); |
04c17aa8 | 113 | else |
5c85418a | 114 | reg_val &= ~BIT(nr); |
04c17aa8 TM |
115 | |
116 | iowrite32(reg_val, &chip->reg->po); | |
7cb6580c | 117 | spin_unlock_irqrestore(&chip->spinlock, flags); |
04c17aa8 TM |
118 | } |
119 | ||
0c106a23 | 120 | static int pch_gpio_get(struct gpio_chip *gpio, unsigned int nr) |
04c17aa8 | 121 | { |
510f4871 | 122 | struct pch_gpio *chip = gpiochip_get_data(gpio); |
04c17aa8 | 123 | |
5c85418a | 124 | return !!(ioread32(&chip->reg->pi) & BIT(nr)); |
04c17aa8 TM |
125 | } |
126 | ||
0c106a23 | 127 | static int pch_gpio_direction_output(struct gpio_chip *gpio, unsigned int nr, |
04c17aa8 TM |
128 | int val) |
129 | { | |
510f4871 | 130 | struct pch_gpio *chip = gpiochip_get_data(gpio); |
04c17aa8 TM |
131 | u32 pm; |
132 | u32 reg_val; | |
7cb6580c | 133 | unsigned long flags; |
04c17aa8 | 134 | |
7cb6580c | 135 | spin_lock_irqsave(&chip->spinlock, flags); |
04c17aa8 TM |
136 | |
137 | reg_val = ioread32(&chip->reg->po); | |
138 | if (val) | |
5c85418a | 139 | reg_val |= BIT(nr); |
04c17aa8 | 140 | else |
5c85418a | 141 | reg_val &= ~BIT(nr); |
88aab934 | 142 | iowrite32(reg_val, &chip->reg->po); |
2ddf6cd6 | 143 | |
5c85418a AS |
144 | pm = ioread32(&chip->reg->pm); |
145 | pm &= BIT(gpio_pins[chip->ioh]) - 1; | |
146 | pm |= BIT(nr); | |
2ddf6cd6 DK |
147 | iowrite32(pm, &chip->reg->pm); |
148 | ||
7cb6580c | 149 | spin_unlock_irqrestore(&chip->spinlock, flags); |
04c17aa8 TM |
150 | |
151 | return 0; | |
152 | } | |
153 | ||
0c106a23 | 154 | static int pch_gpio_direction_input(struct gpio_chip *gpio, unsigned int nr) |
04c17aa8 | 155 | { |
510f4871 | 156 | struct pch_gpio *chip = gpiochip_get_data(gpio); |
04c17aa8 | 157 | u32 pm; |
7cb6580c | 158 | unsigned long flags; |
04c17aa8 | 159 | |
7cb6580c | 160 | spin_lock_irqsave(&chip->spinlock, flags); |
5c85418a AS |
161 | pm = ioread32(&chip->reg->pm); |
162 | pm &= BIT(gpio_pins[chip->ioh]) - 1; | |
163 | pm &= ~BIT(nr); | |
04c17aa8 | 164 | iowrite32(pm, &chip->reg->pm); |
7cb6580c | 165 | spin_unlock_irqrestore(&chip->spinlock, flags); |
04c17aa8 TM |
166 | |
167 | return 0; | |
168 | } | |
169 | ||
170 | /* | |
171 | * Save register configuration and disable interrupts. | |
172 | */ | |
226e6b86 | 173 | static void __maybe_unused pch_gpio_save_reg_conf(struct pch_gpio *chip) |
04c17aa8 | 174 | { |
38eb18a6 TM |
175 | chip->pch_gpio_reg.ien_reg = ioread32(&chip->reg->ien); |
176 | chip->pch_gpio_reg.imask_reg = ioread32(&chip->reg->imask); | |
04c17aa8 TM |
177 | chip->pch_gpio_reg.po_reg = ioread32(&chip->reg->po); |
178 | chip->pch_gpio_reg.pm_reg = ioread32(&chip->reg->pm); | |
e98bed7f TM |
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) | |
226e6b86 | 183 | chip->pch_gpio_reg.gpio_use_sel_reg = ioread32(&chip->reg->gpio_use_sel); |
04c17aa8 TM |
184 | } |
185 | ||
186 | /* | |
187 | * This function restores the register configuration of the GPIO device. | |
188 | */ | |
226e6b86 | 189 | static void __maybe_unused pch_gpio_restore_reg_conf(struct pch_gpio *chip) |
04c17aa8 | 190 | { |
38eb18a6 TM |
191 | iowrite32(chip->pch_gpio_reg.ien_reg, &chip->reg->ien); |
192 | iowrite32(chip->pch_gpio_reg.imask_reg, &chip->reg->imask); | |
04c17aa8 TM |
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); | |
e98bed7f TM |
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) | |
226e6b86 | 201 | iowrite32(chip->pch_gpio_reg.gpio_use_sel_reg, &chip->reg->gpio_use_sel); |
04c17aa8 TM |
202 | } |
203 | ||
0c106a23 | 204 | static int pch_gpio_to_irq(struct gpio_chip *gpio, unsigned int offset) |
38eb18a6 | 205 | { |
510f4871 | 206 | struct pch_gpio *chip = gpiochip_get_data(gpio); |
37ceab74 | 207 | |
38eb18a6 TM |
208 | return chip->irq_base + offset; |
209 | } | |
210 | ||
04c17aa8 TM |
211 | static void pch_gpio_setup(struct pch_gpio *chip) |
212 | { | |
213 | struct gpio_chip *gpio = &chip->gpio; | |
214 | ||
215 | gpio->label = dev_name(chip->dev); | |
58383c78 | 216 | gpio->parent = chip->dev; |
04c17aa8 TM |
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; | |
04c17aa8 | 222 | gpio->base = -1; |
d4260e6d | 223 | gpio->ngpio = gpio_pins[chip->ioh]; |
9fb1f39e | 224 | gpio->can_sleep = false; |
38eb18a6 TM |
225 | gpio->to_irq = pch_gpio_to_irq; |
226 | } | |
227 | ||
228 | static int pch_irq_type(struct irq_data *d, unsigned int type) | |
229 | { | |
38eb18a6 TM |
230 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); |
231 | struct pch_gpio *chip = gc->private; | |
df9541a6 TG |
232 | u32 im, im_pos, val; |
233 | u32 __iomem *im_reg; | |
234 | unsigned long flags; | |
235 | int ch, irq = d->irq; | |
38eb18a6 TM |
236 | |
237 | ch = irq - chip->irq_base; | |
368b8436 | 238 | if (irq < chip->irq_base + 8) { |
38eb18a6 | 239 | im_reg = &chip->reg->im0; |
368b8436 | 240 | im_pos = ch - 0; |
38eb18a6 TM |
241 | } else { |
242 | im_reg = &chip->reg->im1; | |
243 | im_pos = ch - 8; | |
244 | } | |
0511e116 | 245 | dev_dbg(chip->dev, "irq=%d type=%d ch=%d pos=%d\n", irq, type, ch, im_pos); |
38eb18a6 | 246 | |
38eb18a6 TM |
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; | |
38eb18a6 | 263 | default: |
368b8436 | 264 | return 0; |
38eb18a6 TM |
265 | } |
266 | ||
368b8436 AS |
267 | spin_lock_irqsave(&chip->spinlock, flags); |
268 | ||
38eb18a6 TM |
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 | ||
df9541a6 | 273 | /* And the handler */ |
5376b0b3 | 274 | if (type & IRQ_TYPE_LEVEL_MASK) |
2456d869 | 275 | irq_set_handler_locked(d, handle_level_irq); |
5376b0b3 | 276 | else if (type & IRQ_TYPE_EDGE_BOTH) |
2456d869 | 277 | irq_set_handler_locked(d, handle_edge_irq); |
38eb18a6 | 278 | |
38eb18a6 | 279 | spin_unlock_irqrestore(&chip->spinlock, flags); |
38eb18a6 TM |
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 | ||
5c85418a | 288 | iowrite32(BIT(d->irq - chip->irq_base), &chip->reg->imaskclr); |
38eb18a6 TM |
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 | ||
5c85418a | 296 | iowrite32(BIT(d->irq - chip->irq_base), &chip->reg->imask); |
38eb18a6 TM |
297 | } |
298 | ||
df9541a6 TG |
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 | ||
5c85418a | 304 | iowrite32(BIT(d->irq - chip->irq_base), &chip->reg->iclr); |
df9541a6 TG |
305 | } |
306 | ||
38eb18a6 TM |
307 | static irqreturn_t pch_gpio_handler(int irq, void *dev_id) |
308 | { | |
309 | struct pch_gpio *chip = dev_id; | |
9be93e1a | 310 | unsigned long reg_val = ioread32(&chip->reg->istatus); |
5a4245de | 311 | int i; |
38eb18a6 | 312 | |
532e762d | 313 | dev_vdbg(chip->dev, "irq=%d status=0x%lx\n", irq, reg_val); |
5a4245de AS |
314 | |
315 | reg_val &= BIT(gpio_pins[chip->ioh]) - 1; | |
532e762d | 316 | |
5a4245de | 317 | for_each_set_bit(i, ®_val, gpio_pins[chip->ioh]) |
9be93e1a | 318 | generic_handle_irq(chip->irq_base + i); |
5a4245de AS |
319 | |
320 | return IRQ_RETVAL(reg_val); | |
38eb18a6 TM |
321 | } |
322 | ||
09445a10 BG |
323 | static int pch_gpio_alloc_generic_chip(struct pch_gpio *chip, |
324 | unsigned int irq_start, | |
325 | unsigned int num) | |
38eb18a6 TM |
326 | { |
327 | struct irq_chip_generic *gc; | |
328 | struct irq_chip_type *ct; | |
e0fc5a1b | 329 | int rv; |
38eb18a6 | 330 | |
e0fc5a1b BG |
331 | gc = devm_irq_alloc_generic_chip(chip->dev, "pch_gpio", 1, irq_start, |
332 | chip->base, handle_simple_irq); | |
09445a10 BG |
333 | if (!gc) |
334 | return -ENOMEM; | |
335 | ||
38eb18a6 TM |
336 | gc->private = chip; |
337 | ct = gc->chip_types; | |
338 | ||
df9541a6 | 339 | ct->chip.irq_ack = pch_irq_ack; |
38eb18a6 TM |
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 | ||
e0fc5a1b BG |
344 | rv = devm_irq_setup_generic_chip(chip->dev, gc, IRQ_MSK(num), |
345 | IRQ_GC_INIT_MASK_CACHE, | |
346 | IRQ_NOREQUEST | IRQ_NOPROBE, 0); | |
09445a10 | 347 | |
e0fc5a1b | 348 | return rv; |
04c17aa8 TM |
349 | } |
350 | ||
3836309d | 351 | static int pch_gpio_probe(struct pci_dev *pdev, |
04c17aa8 TM |
352 | const struct pci_device_id *id) |
353 | { | |
2822b027 | 354 | struct device *dev = &pdev->dev; |
04c17aa8 TM |
355 | s32 ret; |
356 | struct pch_gpio *chip; | |
38eb18a6 | 357 | int irq_base; |
04c17aa8 | 358 | |
2822b027 | 359 | chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL); |
04c17aa8 TM |
360 | if (chip == NULL) |
361 | return -ENOMEM; | |
362 | ||
2822b027 | 363 | chip->dev = dev; |
6ad02b29 | 364 | ret = pcim_enable_device(pdev); |
d3bb436d AS |
365 | if (ret) |
366 | return dev_err_probe(dev, ret, "Failed to enable PCI device\n"); | |
04c17aa8 | 367 | |
5c85418a | 368 | ret = pcim_iomap_regions(pdev, BIT(1), KBUILD_MODNAME); |
d3bb436d AS |
369 | if (ret) |
370 | return dev_err_probe(dev, ret, "Failed to request and map PCI regions\n"); | |
04c17aa8 | 371 | |
6ad02b29 | 372 | chip->base = pcim_iomap_table(pdev)[1]; |
82b2cd4c | 373 | chip->ioh = id->driver_data; |
04c17aa8 TM |
374 | chip->reg = chip->base; |
375 | pci_set_drvdata(pdev, chip); | |
d166370a | 376 | spin_lock_init(&chip->spinlock); |
04c17aa8 | 377 | pch_gpio_setup(chip); |
a3bb44bc | 378 | |
2822b027 | 379 | ret = devm_gpiochip_add_data(dev, &chip->gpio, chip); |
d3bb436d AS |
380 | if (ret) |
381 | return dev_err_probe(dev, ret, "Failed to register GPIO\n"); | |
04c17aa8 | 382 | |
2822b027 | 383 | irq_base = devm_irq_alloc_descs(dev, -1, 0, |
f57f3e60 | 384 | gpio_pins[chip->ioh], NUMA_NO_NODE); |
38eb18a6 | 385 | if (irq_base < 0) { |
2822b027 | 386 | dev_warn(dev, "PCH gpio: Failed to get IRQ base num\n"); |
38eb18a6 | 387 | chip->irq_base = -1; |
6ad02b29 | 388 | return 0; |
38eb18a6 TM |
389 | } |
390 | chip->irq_base = irq_base; | |
391 | ||
df9541a6 | 392 | /* Mask all interrupts, but enable them */ |
5c85418a AS |
393 | iowrite32(BIT(gpio_pins[chip->ioh]) - 1, &chip->reg->imask); |
394 | iowrite32(BIT(gpio_pins[chip->ioh]) - 1, &chip->reg->ien); | |
df9541a6 | 395 | |
2822b027 | 396 | ret = devm_request_irq(dev, pdev->irq, pch_gpio_handler, |
f57f3e60 | 397 | IRQF_SHARED, KBUILD_MODNAME, chip); |
d3bb436d AS |
398 | if (ret) |
399 | return dev_err_probe(dev, ret, "Failed to request IRQ\n"); | |
38eb18a6 | 400 | |
6ad02b29 | 401 | return pch_gpio_alloc_generic_chip(chip, irq_base, gpio_pins[chip->ioh]); |
04c17aa8 TM |
402 | } |
403 | ||
226e6b86 | 404 | static int __maybe_unused pch_gpio_suspend(struct device *dev) |
04c17aa8 | 405 | { |
a7db2856 | 406 | struct pch_gpio *chip = dev_get_drvdata(dev); |
d568a681 | 407 | unsigned long flags; |
04c17aa8 | 408 | |
d568a681 | 409 | spin_lock_irqsave(&chip->spinlock, flags); |
04c17aa8 | 410 | pch_gpio_save_reg_conf(chip); |
d568a681 | 411 | spin_unlock_irqrestore(&chip->spinlock, flags); |
04c17aa8 | 412 | |
04c17aa8 TM |
413 | return 0; |
414 | } | |
415 | ||
226e6b86 | 416 | static int __maybe_unused pch_gpio_resume(struct device *dev) |
04c17aa8 | 417 | { |
a7db2856 | 418 | struct pch_gpio *chip = dev_get_drvdata(dev); |
d568a681 | 419 | unsigned long flags; |
04c17aa8 | 420 | |
d568a681 | 421 | spin_lock_irqsave(&chip->spinlock, flags); |
04c17aa8 TM |
422 | iowrite32(0x01, &chip->reg->reset); |
423 | iowrite32(0x00, &chip->reg->reset); | |
424 | pch_gpio_restore_reg_conf(chip); | |
d568a681 | 425 | spin_unlock_irqrestore(&chip->spinlock, flags); |
04c17aa8 TM |
426 | |
427 | return 0; | |
428 | } | |
226e6b86 AS |
429 | |
430 | static SIMPLE_DEV_PM_OPS(pch_gpio_pm_ops, pch_gpio_suspend, pch_gpio_resume); | |
04c17aa8 | 431 | |
14f4a883 | 432 | static const struct pci_device_id pch_gpio_pcidev_id[] = { |
b65bb2c1 AS |
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 | { } | |
04c17aa8 | 438 | }; |
19234cdd | 439 | MODULE_DEVICE_TABLE(pci, pch_gpio_pcidev_id); |
04c17aa8 TM |
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, | |
226e6b86 AS |
445 | .driver = { |
446 | .pm = &pch_gpio_pm_ops, | |
447 | }, | |
04c17aa8 TM |
448 | }; |
449 | ||
93baa65f | 450 | module_pci_driver(pch_gpio_driver); |
04c17aa8 TM |
451 | |
452 | MODULE_DESCRIPTION("PCH GPIO PCI Driver"); | |
9b8bf5bf | 453 | MODULE_LICENSE("GPL v2"); |