diff options
author | Magnus Damm <damm@opensource.se> | 2010-08-02 03:16:37 -0400 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2010-08-04 03:10:34 -0400 |
commit | 82b20d8bae03406e954d8b7d0f6f734967088b17 (patch) | |
tree | 6d7d83c59d52930a59a2315cc423a94e997327ca /drivers/i2c | |
parent | 32dfab3ced3a3d2bb0ac2ed6fd7ac395edf02e88 (diff) |
i2c: i2c-sh_mobile irq rollback fix
Update the i2c-sh_mobile driver to properly free
interrupts. The function sh_mobile_i2c_hook_irqs()
is fixed so module both unload and load are working
as expected.
Signed-off-by: Magnus Damm <damm@opensource.se>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'drivers/i2c')
-rw-r--r-- | drivers/i2c/busses/i2c-sh_mobile.c | 23 |
1 files changed, 13 insertions, 10 deletions
diff --git a/drivers/i2c/busses/i2c-sh_mobile.c b/drivers/i2c/busses/i2c-sh_mobile.c index ffb405d7c6f2..97b84b80d0ff 100644 --- a/drivers/i2c/busses/i2c-sh_mobile.c +++ b/drivers/i2c/busses/i2c-sh_mobile.c | |||
@@ -497,15 +497,17 @@ static int sh_mobile_i2c_hook_irqs(struct platform_device *dev, int hook) | |||
497 | { | 497 | { |
498 | struct resource *res; | 498 | struct resource *res; |
499 | int ret = -ENXIO; | 499 | int ret = -ENXIO; |
500 | int q, m; | 500 | int n, k = 0; |
501 | int k = 0; | ||
502 | int n = 0; | ||
503 | 501 | ||
504 | while ((res = platform_get_resource(dev, IORESOURCE_IRQ, k))) { | 502 | while ((res = platform_get_resource(dev, IORESOURCE_IRQ, k))) { |
505 | for (n = res->start; hook && n <= res->end; n++) { | 503 | for (n = res->start; hook && n <= res->end; n++) { |
506 | if (request_irq(n, sh_mobile_i2c_isr, IRQF_DISABLED, | 504 | if (request_irq(n, sh_mobile_i2c_isr, IRQF_DISABLED, |
507 | dev_name(&dev->dev), dev)) | 505 | dev_name(&dev->dev), dev)) { |
506 | for (n--; n >= res->start; n--) | ||
507 | free_irq(n, dev); | ||
508 | |||
508 | goto rollback; | 509 | goto rollback; |
510 | } | ||
509 | } | 511 | } |
510 | k++; | 512 | k++; |
511 | } | 513 | } |
@@ -513,16 +515,17 @@ static int sh_mobile_i2c_hook_irqs(struct platform_device *dev, int hook) | |||
513 | if (hook) | 515 | if (hook) |
514 | return k > 0 ? 0 : -ENOENT; | 516 | return k > 0 ? 0 : -ENOENT; |
515 | 517 | ||
516 | k--; | ||
517 | ret = 0; | 518 | ret = 0; |
518 | 519 | ||
519 | rollback: | 520 | rollback: |
520 | for (q = k; k >= 0; k--) { | 521 | k--; |
521 | for (m = n; m >= res->start; m--) | 522 | |
522 | free_irq(m, dev); | 523 | while (k >= 0) { |
524 | res = platform_get_resource(dev, IORESOURCE_IRQ, k); | ||
525 | for (n = res->start; n <= res->end; n++) | ||
526 | free_irq(n, dev); | ||
523 | 527 | ||
524 | res = platform_get_resource(dev, IORESOURCE_IRQ, k - 1); | 528 | k--; |
525 | m = res->end; | ||
526 | } | 529 | } |
527 | 530 | ||
528 | return ret; | 531 | return ret; |