Blame view
drivers/gpio/gpio-mxc.c
12.3 KB
07bd1a6cc MXC arch: Add gpi... |
1 2 3 4 5 |
/* * MXC GPIO support. (c) 2008 Daniel Mack <daniel@caiaq.de> * Copyright 2008 Juergen Beisert, kernel@pengutronix.de * * Based on code from Freescale, |
e24798e63 mx5: Add registra... |
6 |
* Copyright (C) 2004-2010 Freescale Semiconductor, Inc. All Rights Reserved. |
07bd1a6cc MXC arch: Add gpi... |
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
* * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include <linux/init.h> |
a3484ffd2 ARM: imx: Add wak... |
23 |
#include <linux/interrupt.h> |
07bd1a6cc MXC arch: Add gpi... |
24 25 26 |
#include <linux/io.h> #include <linux/irq.h> #include <linux/gpio.h> |
b78d8e59a gpio/mxc: Change ... |
27 28 |
#include <linux/platform_device.h> #include <linux/slab.h> |
2ce420da3 gpio/mxc: convert... |
29 |
#include <linux/basic_mmio_gpio.h> |
8937cb602 gpio/mxc: add dev... |
30 31 |
#include <linux/of.h> #include <linux/of_device.h> |
bb207ef1e drivers/gpio: Fix... |
32 |
#include <linux/module.h> |
07bd1a6cc MXC arch: Add gpi... |
33 |
#include <asm-generic/bug.h> |
0e44b6ecc gpio/mxc: add cha... |
34 |
#include <asm/mach/irq.h> |
07bd1a6cc MXC arch: Add gpi... |
35 |
|
a43956122 gpio/mxc: move ir... |
36 |
#define irq_to_gpio(irq) ((irq) - MXC_GPIO_IRQ_START) |
e7fc6ae74 gpio/mxc: get rid... |
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
enum mxc_gpio_hwtype { IMX1_GPIO, /* runs on i.mx1 */ IMX21_GPIO, /* runs on i.mx21 and i.mx27 */ IMX31_GPIO, /* runs on all other i.mx */ }; /* device type dependent stuff */ struct mxc_gpio_hwdata { unsigned dr_reg; unsigned gdir_reg; unsigned psr_reg; unsigned icr1_reg; unsigned icr2_reg; unsigned imr_reg; unsigned isr_reg; unsigned low_level; unsigned high_level; unsigned rise_edge; unsigned fall_edge; }; |
b78d8e59a gpio/mxc: Change ... |
57 58 59 60 61 62 |
struct mxc_gpio_port { struct list_head node; void __iomem *base; int irq; int irq_high; int virtual_irq_start; |
2ce420da3 gpio/mxc: convert... |
63 |
struct bgpio_chip bgc; |
b78d8e59a gpio/mxc: Change ... |
64 |
u32 both_edges; |
b78d8e59a gpio/mxc: Change ... |
65 |
}; |
e7fc6ae74 gpio/mxc: get rid... |
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 |
static struct mxc_gpio_hwdata imx1_imx21_gpio_hwdata = { .dr_reg = 0x1c, .gdir_reg = 0x00, .psr_reg = 0x24, .icr1_reg = 0x28, .icr2_reg = 0x2c, .imr_reg = 0x30, .isr_reg = 0x34, .low_level = 0x03, .high_level = 0x02, .rise_edge = 0x00, .fall_edge = 0x01, }; static struct mxc_gpio_hwdata imx31_gpio_hwdata = { .dr_reg = 0x00, .gdir_reg = 0x04, .psr_reg = 0x08, .icr1_reg = 0x0c, .icr2_reg = 0x10, .imr_reg = 0x14, .isr_reg = 0x18, .low_level = 0x00, .high_level = 0x01, .rise_edge = 0x02, .fall_edge = 0x03, }; static enum mxc_gpio_hwtype mxc_gpio_hwtype; static struct mxc_gpio_hwdata *mxc_gpio_hwdata; #define GPIO_DR (mxc_gpio_hwdata->dr_reg) #define GPIO_GDIR (mxc_gpio_hwdata->gdir_reg) #define GPIO_PSR (mxc_gpio_hwdata->psr_reg) #define GPIO_ICR1 (mxc_gpio_hwdata->icr1_reg) #define GPIO_ICR2 (mxc_gpio_hwdata->icr2_reg) #define GPIO_IMR (mxc_gpio_hwdata->imr_reg) #define GPIO_ISR (mxc_gpio_hwdata->isr_reg) #define GPIO_INT_LOW_LEV (mxc_gpio_hwdata->low_level) #define GPIO_INT_HIGH_LEV (mxc_gpio_hwdata->high_level) #define GPIO_INT_RISE_EDGE (mxc_gpio_hwdata->rise_edge) #define GPIO_INT_FALL_EDGE (mxc_gpio_hwdata->fall_edge) #define GPIO_INT_NONE 0x4 static struct platform_device_id mxc_gpio_devtype[] = { { .name = "imx1-gpio", .driver_data = IMX1_GPIO, }, { .name = "imx21-gpio", .driver_data = IMX21_GPIO, }, { .name = "imx31-gpio", .driver_data = IMX31_GPIO, }, { /* sentinel */ } }; |
8937cb602 gpio/mxc: add dev... |
125 126 127 128 129 130 |
static const struct of_device_id mxc_gpio_dt_ids[] = { { .compatible = "fsl,imx1-gpio", .data = &mxc_gpio_devtype[IMX1_GPIO], }, { .compatible = "fsl,imx21-gpio", .data = &mxc_gpio_devtype[IMX21_GPIO], }, { .compatible = "fsl,imx31-gpio", .data = &mxc_gpio_devtype[IMX31_GPIO], }, { /* sentinel */ } }; |
b78d8e59a gpio/mxc: Change ... |
131 132 133 134 135 136 |
/* * MX2 has one interrupt *for all* gpio ports. The list is used * to save the references to all ports, so that mx2_gpio_irq_handler * can walk through all interrupt status registers. */ static LIST_HEAD(mxc_gpio_ports); |
07bd1a6cc MXC arch: Add gpi... |
137 138 |
/* Note: This driver assumes 32 GPIOs are handled in one register */ |
4d93579f6 ARM: plat-mxc: ir... |
139 |
static int gpio_set_irq_type(struct irq_data *d, u32 type) |
07bd1a6cc MXC arch: Add gpi... |
140 |
{ |
4d93579f6 ARM: plat-mxc: ir... |
141 |
u32 gpio = irq_to_gpio(d->irq); |
e4ea93336 gpio/mxc: convert... |
142 143 |
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); struct mxc_gpio_port *port = gc->private; |
07bd1a6cc MXC arch: Add gpi... |
144 145 146 |
u32 bit, val; int edge; void __iomem *reg = port->base; |
910862ec0 mxc: emulate GPIO... |
147 |
port->both_edges &= ~(1 << (gpio & 31)); |
07bd1a6cc MXC arch: Add gpi... |
148 |
switch (type) { |
6cab48602 [ARM] 5179/1: Rep... |
149 |
case IRQ_TYPE_EDGE_RISING: |
07bd1a6cc MXC arch: Add gpi... |
150 151 |
edge = GPIO_INT_RISE_EDGE; break; |
6cab48602 [ARM] 5179/1: Rep... |
152 |
case IRQ_TYPE_EDGE_FALLING: |
07bd1a6cc MXC arch: Add gpi... |
153 154 |
edge = GPIO_INT_FALL_EDGE; break; |
910862ec0 mxc: emulate GPIO... |
155 |
case IRQ_TYPE_EDGE_BOTH: |
5523f86be gpio/mxc: fix a b... |
156 |
val = gpio_get_value(gpio); |
910862ec0 mxc: emulate GPIO... |
157 158 159 160 161 162 163 164 165 166 167 |
if (val) { edge = GPIO_INT_LOW_LEV; pr_debug("mxc: set GPIO %d to low trigger ", gpio); } else { edge = GPIO_INT_HIGH_LEV; pr_debug("mxc: set GPIO %d to high trigger ", gpio); } port->both_edges |= 1 << (gpio & 31); break; |
6cab48602 [ARM] 5179/1: Rep... |
168 |
case IRQ_TYPE_LEVEL_LOW: |
07bd1a6cc MXC arch: Add gpi... |
169 170 |
edge = GPIO_INT_LOW_LEV; break; |
6cab48602 [ARM] 5179/1: Rep... |
171 |
case IRQ_TYPE_LEVEL_HIGH: |
07bd1a6cc MXC arch: Add gpi... |
172 173 |
edge = GPIO_INT_HIGH_LEV; break; |
910862ec0 mxc: emulate GPIO... |
174 |
default: |
07bd1a6cc MXC arch: Add gpi... |
175 176 177 178 179 |
return -EINVAL; } reg += GPIO_ICR1 + ((gpio & 0x10) >> 2); /* lower or upper register */ bit = gpio & 0xf; |
b78d8e59a gpio/mxc: Change ... |
180 181 |
val = readl(reg) & ~(0x3 << (bit << 1)); writel(val | (edge << (bit << 1)), reg); |
e4ea93336 gpio/mxc: convert... |
182 |
writel(1 << (gpio & 0x1f), port->base + GPIO_ISR); |
07bd1a6cc MXC arch: Add gpi... |
183 184 185 |
return 0; } |
910862ec0 mxc: emulate GPIO... |
186 187 188 189 190 191 192 193 |
static void mxc_flip_edge(struct mxc_gpio_port *port, u32 gpio) { void __iomem *reg = port->base; u32 bit, val; int edge; reg += GPIO_ICR1 + ((gpio & 0x10) >> 2); /* lower or upper register */ bit = gpio & 0xf; |
b78d8e59a gpio/mxc: Change ... |
194 |
val = readl(reg); |
910862ec0 mxc: emulate GPIO... |
195 196 |
edge = (val >> (bit << 1)) & 3; val &= ~(0x3 << (bit << 1)); |
3d40f7fef arm/imx/gpio: GPI... |
197 |
if (edge == GPIO_INT_HIGH_LEV) { |
910862ec0 mxc: emulate GPIO... |
198 199 200 |
edge = GPIO_INT_LOW_LEV; pr_debug("mxc: switch GPIO %d to low trigger ", gpio); |
3d40f7fef arm/imx/gpio: GPI... |
201 |
} else if (edge == GPIO_INT_LOW_LEV) { |
910862ec0 mxc: emulate GPIO... |
202 203 204 |
edge = GPIO_INT_HIGH_LEV; pr_debug("mxc: switch GPIO %d to high trigger ", gpio); |
3d40f7fef arm/imx/gpio: GPI... |
205 |
} else { |
910862ec0 mxc: emulate GPIO... |
206 207 208 209 210 |
pr_err("mxc: invalid configuration for GPIO %d: %x ", gpio, edge); return; } |
b78d8e59a gpio/mxc: Change ... |
211 |
writel(val | (edge << (bit << 1)), reg); |
910862ec0 mxc: emulate GPIO... |
212 |
} |
3621f188b arm/imx/gpio: use... |
213 |
/* handle 32 interrupts in one status register */ |
07bd1a6cc MXC arch: Add gpi... |
214 215 |
static void mxc_gpio_irq_handler(struct mxc_gpio_port *port, u32 irq_stat) { |
3621f188b arm/imx/gpio: use... |
216 |
u32 gpio_irq_no_base = port->virtual_irq_start; |
07bd1a6cc MXC arch: Add gpi... |
217 |
|
3621f188b arm/imx/gpio: use... |
218 219 |
while (irq_stat != 0) { int irqoffset = fls(irq_stat) - 1; |
07bd1a6cc MXC arch: Add gpi... |
220 |
|
3621f188b arm/imx/gpio: use... |
221 222 |
if (port->both_edges & (1 << irqoffset)) mxc_flip_edge(port, irqoffset); |
910862ec0 mxc: emulate GPIO... |
223 |
|
3621f188b arm/imx/gpio: use... |
224 |
generic_handle_irq(gpio_irq_no_base + irqoffset); |
910862ec0 mxc: emulate GPIO... |
225 |
|
3621f188b arm/imx/gpio: use... |
226 |
irq_stat &= ~(1 << irqoffset); |
07bd1a6cc MXC arch: Add gpi... |
227 228 |
} } |
cfca8b539 patch-mxc-add-ARC... |
229 |
/* MX1 and MX3 has one interrupt *per* gpio port */ |
07bd1a6cc MXC arch: Add gpi... |
230 231 232 |
static void mx3_gpio_irq_handler(u32 irq, struct irq_desc *desc) { u32 irq_stat; |
6845664a6 arm: Cleanup the ... |
233 |
struct mxc_gpio_port *port = irq_get_handler_data(irq); |
0e44b6ecc gpio/mxc: add cha... |
234 235 236 |
struct irq_chip *chip = irq_get_chip(irq); chained_irq_enter(chip, desc); |
07bd1a6cc MXC arch: Add gpi... |
237 |
|
b78d8e59a gpio/mxc: Change ... |
238 |
irq_stat = readl(port->base + GPIO_ISR) & readl(port->base + GPIO_IMR); |
e2c97e7fd MXC: remove BUG_O... |
239 |
|
07bd1a6cc MXC arch: Add gpi... |
240 |
mxc_gpio_irq_handler(port, irq_stat); |
0e44b6ecc gpio/mxc: add cha... |
241 242 |
chained_irq_exit(chip, desc); |
07bd1a6cc MXC arch: Add gpi... |
243 |
} |
07bd1a6cc MXC arch: Add gpi... |
244 |
|
07bd1a6cc MXC arch: Add gpi... |
245 246 247 |
/* MX2 has one interrupt *for all* gpio ports */ static void mx2_gpio_irq_handler(u32 irq, struct irq_desc *desc) { |
07bd1a6cc MXC arch: Add gpi... |
248 |
u32 irq_msk, irq_stat; |
b78d8e59a gpio/mxc: Change ... |
249 |
struct mxc_gpio_port *port; |
07bd1a6cc MXC arch: Add gpi... |
250 251 |
/* walk through all interrupt status registers */ |
b78d8e59a gpio/mxc: Change ... |
252 253 |
list_for_each_entry(port, &mxc_gpio_ports, node) { irq_msk = readl(port->base + GPIO_IMR); |
07bd1a6cc MXC arch: Add gpi... |
254 255 |
if (!irq_msk) continue; |
b78d8e59a gpio/mxc: Change ... |
256 |
irq_stat = readl(port->base + GPIO_ISR) & irq_msk; |
07bd1a6cc MXC arch: Add gpi... |
257 |
if (irq_stat) |
b78d8e59a gpio/mxc: Change ... |
258 |
mxc_gpio_irq_handler(port, irq_stat); |
07bd1a6cc MXC arch: Add gpi... |
259 260 |
} } |
07bd1a6cc MXC arch: Add gpi... |
261 |
|
a3484ffd2 ARM: imx: Add wak... |
262 263 264 265 266 267 268 269 270 |
/* * Set interrupt number "irq" in the GPIO as a wake-up source. * While system is running, all registered GPIO interrupts need to have * wake-up enabled. When system is suspended, only selected GPIO interrupts * need to have wake-up enabled. * @param irq interrupt source number * @param enable enable as wake-up if equal to non-zero * @return This function returns 0 on success. */ |
4d93579f6 ARM: plat-mxc: ir... |
271 |
static int gpio_set_wake_irq(struct irq_data *d, u32 enable) |
a3484ffd2 ARM: imx: Add wak... |
272 |
{ |
4d93579f6 ARM: plat-mxc: ir... |
273 |
u32 gpio = irq_to_gpio(d->irq); |
a3484ffd2 ARM: imx: Add wak... |
274 |
u32 gpio_idx = gpio & 0x1F; |
e4ea93336 gpio/mxc: convert... |
275 276 |
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); struct mxc_gpio_port *port = gc->private; |
a3484ffd2 ARM: imx: Add wak... |
277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 |
if (enable) { if (port->irq_high && (gpio_idx >= 16)) enable_irq_wake(port->irq_high); else enable_irq_wake(port->irq); } else { if (port->irq_high && (gpio_idx >= 16)) disable_irq_wake(port->irq_high); else disable_irq_wake(port->irq); } return 0; } |
e4ea93336 gpio/mxc: convert... |
292 293 294 295 296 297 298 299 300 301 |
static void __init mxc_gpio_init_gc(struct mxc_gpio_port *port) { struct irq_chip_generic *gc; struct irq_chip_type *ct; gc = irq_alloc_generic_chip("gpio-mxc", 1, port->virtual_irq_start, port->base, handle_level_irq); gc->private = port; ct = gc->chip_types; |
591567a5e gpio/mxc/mxs: fix... |
302 |
ct->chip.irq_ack = irq_gc_ack_set_bit; |
e4ea93336 gpio/mxc: convert... |
303 304 305 |
ct->chip.irq_mask = irq_gc_mask_clr_bit; ct->chip.irq_unmask = irq_gc_mask_set_bit; ct->chip.irq_set_type = gpio_set_irq_type; |
591567a5e gpio/mxc/mxs: fix... |
306 |
ct->chip.irq_set_wake = gpio_set_wake_irq; |
e4ea93336 gpio/mxc: convert... |
307 308 309 310 311 312 |
ct->regs.ack = GPIO_ISR; ct->regs.mask = GPIO_IMR; irq_setup_generic_chip(gc, IRQ_MSK(32), IRQ_GC_INIT_NESTED_LOCK, IRQ_NOREQUEST, 0); } |
b5eee2fde ARM: mxc: Add mis... |
313 |
|
e7fc6ae74 gpio/mxc: get rid... |
314 315 |
static void __devinit mxc_gpio_get_hw(struct platform_device *pdev) { |
8937cb602 gpio/mxc: add dev... |
316 317 318 319 320 321 322 |
const struct of_device_id *of_id = of_match_device(mxc_gpio_dt_ids, &pdev->dev); enum mxc_gpio_hwtype hwtype; if (of_id) pdev->id_entry = of_id->data; hwtype = pdev->id_entry->driver_data; |
e7fc6ae74 gpio/mxc: get rid... |
323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 |
if (mxc_gpio_hwtype) { /* * The driver works with a reasonable presupposition, * that is all gpio ports must be the same type when * running on one soc. */ BUG_ON(mxc_gpio_hwtype != hwtype); return; } if (hwtype == IMX31_GPIO) mxc_gpio_hwdata = &imx31_gpio_hwdata; else mxc_gpio_hwdata = &imx1_imx21_gpio_hwdata; mxc_gpio_hwtype = hwtype; } |
09ad8039d gpio/mxc: add .to... |
341 342 343 344 345 346 347 348 |
static int mxc_gpio_to_irq(struct gpio_chip *gc, unsigned offset) { struct bgpio_chip *bgc = to_bgpio_chip(gc); struct mxc_gpio_port *port = container_of(bgc, struct mxc_gpio_port, bgc); return port->virtual_irq_start + offset; } |
b78d8e59a gpio/mxc: Change ... |
349 |
static int __devinit mxc_gpio_probe(struct platform_device *pdev) |
07bd1a6cc MXC arch: Add gpi... |
350 |
{ |
8937cb602 gpio/mxc: add dev... |
351 |
struct device_node *np = pdev->dev.of_node; |
b78d8e59a gpio/mxc: Change ... |
352 353 |
struct mxc_gpio_port *port; struct resource *iores; |
e4ea93336 gpio/mxc: convert... |
354 |
int err; |
b78d8e59a gpio/mxc: Change ... |
355 |
|
e7fc6ae74 gpio/mxc: get rid... |
356 |
mxc_gpio_get_hw(pdev); |
b78d8e59a gpio/mxc: Change ... |
357 358 359 |
port = kzalloc(sizeof(struct mxc_gpio_port), GFP_KERNEL); if (!port) return -ENOMEM; |
07bd1a6cc MXC arch: Add gpi... |
360 |
|
b78d8e59a gpio/mxc: Change ... |
361 362 363 364 365 |
iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!iores) { err = -ENODEV; goto out_kfree; } |
14cb0deb6 arm/imx/gpio: add... |
366 |
|
b78d8e59a gpio/mxc: Change ... |
367 368 369 370 371 |
if (!request_mem_region(iores->start, resource_size(iores), pdev->name)) { err = -EBUSY; goto out_kfree; } |
07bd1a6cc MXC arch: Add gpi... |
372 |
|
b78d8e59a gpio/mxc: Change ... |
373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 |
port->base = ioremap(iores->start, resource_size(iores)); if (!port->base) { err = -ENOMEM; goto out_release_mem; } port->irq_high = platform_get_irq(pdev, 1); port->irq = platform_get_irq(pdev, 0); if (port->irq < 0) { err = -EINVAL; goto out_iounmap; } /* disable the interrupt and clear the status */ writel(0, port->base + GPIO_IMR); writel(~0, port->base + GPIO_ISR); |
e7fc6ae74 gpio/mxc: get rid... |
389 |
if (mxc_gpio_hwtype == IMX21_GPIO) { |
8afaada2d mxc gpio: CONFIG_... |
390 |
/* setup one handler for all GPIO interrupts */ |
b78d8e59a gpio/mxc: Change ... |
391 392 393 394 395 396 397 398 399 400 401 402 403 |
if (pdev->id == 0) irq_set_chained_handler(port->irq, mx2_gpio_irq_handler); } else { /* setup one handler for each entry */ irq_set_chained_handler(port->irq, mx3_gpio_irq_handler); irq_set_handler_data(port->irq, port); if (port->irq_high > 0) { /* setup handler for GPIO 16 to 31 */ irq_set_chained_handler(port->irq_high, mx3_gpio_irq_handler); irq_set_handler_data(port->irq_high, port); } |
07bd1a6cc MXC arch: Add gpi... |
404 |
} |
2ce420da3 gpio/mxc: convert... |
405 406 407 408 409 410 |
err = bgpio_init(&port->bgc, &pdev->dev, 4, port->base + GPIO_PSR, port->base + GPIO_DR, NULL, port->base + GPIO_GDIR, NULL, false); if (err) goto out_iounmap; |
b78d8e59a gpio/mxc: Change ... |
411 |
|
09ad8039d gpio/mxc: add .to... |
412 |
port->bgc.gc.to_irq = mxc_gpio_to_irq; |
2ce420da3 gpio/mxc: convert... |
413 |
port->bgc.gc.base = pdev->id * 32; |
fb1492186 gpio/mxc: add mis... |
414 415 |
port->bgc.dir = port->bgc.read_reg(port->bgc.reg_dir); port->bgc.data = port->bgc.read_reg(port->bgc.reg_set); |
b78d8e59a gpio/mxc: Change ... |
416 |
|
2ce420da3 gpio/mxc: convert... |
417 |
err = gpiochip_add(&port->bgc.gc); |
b78d8e59a gpio/mxc: Change ... |
418 |
if (err) |
2ce420da3 gpio/mxc: convert... |
419 |
goto out_bgpio_remove; |
b78d8e59a gpio/mxc: Change ... |
420 |
|
8937cb602 gpio/mxc: add dev... |
421 422 423 424 425 426 427 428 429 |
/* * In dt case, we use gpio number range dynamically * allocated by gpio core. */ port->virtual_irq_start = MXC_GPIO_IRQ_START + (np ? port->bgc.gc.base : pdev->id * 32); /* gpio-mxc can be a generic irq chip */ mxc_gpio_init_gc(port); |
b78d8e59a gpio/mxc: Change ... |
430 |
list_add_tail(&port->node, &mxc_gpio_ports); |
07bd1a6cc MXC arch: Add gpi... |
431 |
return 0; |
b78d8e59a gpio/mxc: Change ... |
432 |
|
2ce420da3 gpio/mxc: convert... |
433 434 |
out_bgpio_remove: bgpio_remove(&port->bgc); |
b78d8e59a gpio/mxc: Change ... |
435 436 437 438 439 440 441 442 443 |
out_iounmap: iounmap(port->base); out_release_mem: release_mem_region(iores->start, resource_size(iores)); out_kfree: kfree(port); dev_info(&pdev->dev, "%s failed with errno %d ", __func__, err); return err; |
07bd1a6cc MXC arch: Add gpi... |
444 |
} |
b78d8e59a gpio/mxc: Change ... |
445 446 447 448 449 |
static struct platform_driver mxc_gpio_driver = { .driver = { .name = "gpio-mxc", .owner = THIS_MODULE, |
8937cb602 gpio/mxc: add dev... |
450 |
.of_match_table = mxc_gpio_dt_ids, |
b78d8e59a gpio/mxc: Change ... |
451 452 |
}, .probe = mxc_gpio_probe, |
e7fc6ae74 gpio/mxc: get rid... |
453 |
.id_table = mxc_gpio_devtype, |
b78d8e59a gpio/mxc: Change ... |
454 455 456 457 458 459 460 461 462 463 464 465 466 |
}; static int __init gpio_mxc_init(void) { return platform_driver_register(&mxc_gpio_driver); } postcore_initcall(gpio_mxc_init); MODULE_AUTHOR("Freescale Semiconductor, " "Daniel Mack <danielncaiaq.de>, " "Juergen Beisert <kernel@pengutronix.de>"); MODULE_DESCRIPTION("Freescale MXC GPIO"); MODULE_LICENSE("GPL"); |