aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRussell King <rmk@dyn-67.arm.linux.org.uk>2007-05-10 11:46:13 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2007-05-11 12:18:55 -0400
commitc7b87f3d5037a35b5c7bb916ffc826be3fcb208d (patch)
tree57fb9d7bb21965fa0d78b26043cf459ce51a9668
parent129a84de2347002f09721cda3155ccfd19fade40 (diff)
[ARM] ecard: add helper function for setting ecard irq ops
Rather than having every driver fiddle about setting its private IRQ operations and data, provide a helper function to contain this functionality in one place. Arrange to remove the driver-private IRQ operations and data when the device is removed from the driver, and remove the driver private code to do this. This fixes potential problems caused by drivers forgetting to remove these hooks. Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r--arch/arm/kernel/ecard.c16
-rw-r--r--drivers/ata/pata_icside.c13
-rw-r--r--drivers/ide/arm/icside.c9
-rw-r--r--drivers/net/arm/etherh.c4
-rw-r--r--drivers/scsi/arm/cumana_2.c4
-rw-r--r--drivers/scsi/arm/eesox.c4
-rw-r--r--drivers/scsi/arm/powertec.c4
-rw-r--r--include/asm-arm/ecard.h4
8 files changed, 33 insertions, 25 deletions
diff --git a/arch/arm/kernel/ecard.c b/arch/arm/kernel/ecard.c
index bdbd7da99286..65f1398723a4 100644
--- a/arch/arm/kernel/ecard.c
+++ b/arch/arm/kernel/ecard.c
@@ -958,6 +958,14 @@ void ecard_release_resources(struct expansion_card *ec)
958} 958}
959EXPORT_SYMBOL(ecard_release_resources); 959EXPORT_SYMBOL(ecard_release_resources);
960 960
961void ecard_setirq(struct expansion_card *ec, const struct expansion_card_ops *ops, void *irq_data)
962{
963 ec->irq_data = irq_data;
964 barrier();
965 ec->ops = ops;
966}
967EXPORT_SYMBOL(ecard_setirq);
968
961/* 969/*
962 * Probe for an expansion card. 970 * Probe for an expansion card.
963 * 971 *
@@ -1133,6 +1141,14 @@ static int ecard_drv_remove(struct device *dev)
1133 drv->remove(ec); 1141 drv->remove(ec);
1134 ecard_release(ec); 1142 ecard_release(ec);
1135 1143
1144 /*
1145 * Restore the default operations. We ensure that the
1146 * ops are set before we change the data.
1147 */
1148 ec->ops = &ecard_default_ops;
1149 barrier();
1150 ec->irq_data = NULL;
1151
1136 return 0; 1152 return 0;
1137} 1153}
1138 1154
diff --git a/drivers/ata/pata_icside.c b/drivers/ata/pata_icside.c
index dbc8ee2adcf0..d7621a39ed09 100644
--- a/drivers/ata/pata_icside.c
+++ b/drivers/ata/pata_icside.c
@@ -434,8 +434,8 @@ pata_icside_register_v5(struct ata_probe_ent *ae, struct expansion_card *ec)
434 434
435 ec->irqaddr = base + ICS_ARCIN_V5_INTRSTAT; 435 ec->irqaddr = base + ICS_ARCIN_V5_INTRSTAT;
436 ec->irqmask = 1; 436 ec->irqmask = 1;
437 ec->irq_data = state; 437
438 ec->ops = &pata_icside_ops_arcin_v5; 438 ecard_setirq(ec, &pata_icside_ops_arcin_v5, state);
439 439
440 /* 440 /*
441 * Be on the safe side - disable interrupts 441 * Be on the safe side - disable interrupts
@@ -480,8 +480,7 @@ pata_icside_register_v6(struct ata_probe_ent *ae, struct expansion_card *ec)
480 480
481 writeb(sel, ioc_base); 481 writeb(sel, ioc_base);
482 482
483 ec->irq_data = state; 483 ecard_setirq(ec, &pata_icside_ops_arcin_v6, state);
484 ec->ops = &pata_icside_ops_arcin_v6;
485 484
486 state->irq_port = easi_base; 485 state->irq_port = easi_base;
487 state->ioc_base = ioc_base; 486 state->ioc_base = ioc_base;
@@ -609,8 +608,7 @@ static void pata_icside_shutdown(struct expansion_card *ec)
609 * this register via that region. 608 * this register via that region.
610 */ 609 */
611 local_irq_save(flags); 610 local_irq_save(flags);
612 if (ec->ops) 611 ec->ops->irqdisable(ec, ec->irq);
613 ec->ops->irqdisable(ec, ec->irq);
614 local_irq_restore(flags); 612 local_irq_restore(flags);
615 613
616 /* 614 /*
@@ -638,9 +636,6 @@ static void __devexit pata_icside_remove(struct expansion_card *ec)
638 * don't NULL out the drvdata - devres/libata wants it 636 * don't NULL out the drvdata - devres/libata wants it
639 * to free the ata_host structure. 637 * to free the ata_host structure.
640 */ 638 */
641 ec->ops = NULL;
642 ec->irq_data = NULL;
643
644 if (state->dma != NO_DMA) 639 if (state->dma != NO_DMA)
645 free_dma(state->dma); 640 free_dma(state->dma);
646 if (state->ioc_base) 641 if (state->ioc_base)
diff --git a/drivers/ide/arm/icside.c b/drivers/ide/arm/icside.c
index 1fe0457243db..69c949ea93e3 100644
--- a/drivers/ide/arm/icside.c
+++ b/drivers/ide/arm/icside.c
@@ -574,8 +574,8 @@ icside_register_v5(struct icside_state *state, struct expansion_card *ec)
574 574
575 ec->irqaddr = base + ICS_ARCIN_V5_INTRSTAT; 575 ec->irqaddr = base + ICS_ARCIN_V5_INTRSTAT;
576 ec->irqmask = 1; 576 ec->irqmask = 1;
577 ec->irq_data = state; 577
578 ec->ops = &icside_ops_arcin_v5; 578 ecard_setirq(ec, &icside_ops_arcin_v5, state);
579 579
580 /* 580 /*
581 * Be on the safe side - disable interrupts 581 * Be on the safe side - disable interrupts
@@ -630,8 +630,7 @@ icside_register_v6(struct icside_state *state, struct expansion_card *ec)
630 630
631 writeb(sel, ioc_base); 631 writeb(sel, ioc_base);
632 632
633 ec->irq_data = state; 633 ecard_setirq(ec, &icside_ops_arcin_v6, state);
634 ec->ops = &icside_ops_arcin_v6;
635 634
636 state->irq_port = easi_base; 635 state->irq_port = easi_base;
637 state->ioc_base = ioc_base; 636 state->ioc_base = ioc_base;
@@ -793,8 +792,6 @@ static void __devexit icside_remove(struct expansion_card *ec)
793 } 792 }
794 793
795 ecard_set_drvdata(ec, NULL); 794 ecard_set_drvdata(ec, NULL);
796 ec->ops = NULL;
797 ec->irq_data = NULL;
798 795
799 if (state->ioc_base) 796 if (state->ioc_base)
800 iounmap(state->ioc_base); 797 iounmap(state->ioc_base);
diff --git a/drivers/net/arm/etherh.c b/drivers/net/arm/etherh.c
index 61f574aa3a99..387f1e3a4e84 100644
--- a/drivers/net/arm/etherh.c
+++ b/drivers/net/arm/etherh.c
@@ -710,8 +710,7 @@ etherh_probe(struct expansion_card *ec, const struct ecard_id *id)
710 * IRQ and control port handling - only for non-NIC slot cards. 710 * IRQ and control port handling - only for non-NIC slot cards.
711 */ 711 */
712 if (ec->slot_no != 8) { 712 if (ec->slot_no != 8) {
713 ec->ops = &etherh_ops; 713 ecard_setirq(ec, &etherh_ops, eh);
714 ec->irq_data = eh;
715 } else { 714 } else {
716 /* 715 /*
717 * If we're in the NIC slot, make sure the IRQ is enabled 716 * If we're in the NIC slot, make sure the IRQ is enabled
@@ -778,7 +777,6 @@ static void __devexit etherh_remove(struct expansion_card *ec)
778 ecard_set_drvdata(ec, NULL); 777 ecard_set_drvdata(ec, NULL);
779 778
780 unregister_netdev(dev); 779 unregister_netdev(dev);
781 ec->ops = NULL;
782 780
783 if (eh->ioc_fast) 781 if (eh->ioc_fast)
784 iounmap(eh->ioc_fast); 782 iounmap(eh->ioc_fast);
diff --git a/drivers/scsi/arm/cumana_2.c b/drivers/scsi/arm/cumana_2.c
index 82add77ad131..f51aa3446bc7 100644
--- a/drivers/scsi/arm/cumana_2.c
+++ b/drivers/scsi/arm/cumana_2.c
@@ -450,8 +450,8 @@ cumanascsi2_probe(struct expansion_card *ec, const struct ecard_id *id)
450 450
451 ec->irqaddr = info->base + CUMANASCSI2_STATUS; 451 ec->irqaddr = info->base + CUMANASCSI2_STATUS;
452 ec->irqmask = STATUS_INT; 452 ec->irqmask = STATUS_INT;
453 ec->irq_data = info; 453
454 ec->ops = &cumanascsi_2_ops; 454 ecard_setirq(ec, &cumanascsi_2_ops, info);
455 455
456 ret = fas216_init(host); 456 ret = fas216_init(host);
457 if (ret) 457 if (ret)
diff --git a/drivers/scsi/arm/eesox.c b/drivers/scsi/arm/eesox.c
index ed06a8c19ad6..cc5d513aa99a 100644
--- a/drivers/scsi/arm/eesox.c
+++ b/drivers/scsi/arm/eesox.c
@@ -569,8 +569,8 @@ eesoxscsi_probe(struct expansion_card *ec, const struct ecard_id *id)
569 569
570 ec->irqaddr = base + EESOX_DMASTAT; 570 ec->irqaddr = base + EESOX_DMASTAT;
571 ec->irqmask = EESOX_STAT_INTR; 571 ec->irqmask = EESOX_STAT_INTR;
572 ec->irq_data = info; 572
573 ec->ops = &eesoxscsi_ops; 573 ecard_setirq(ec, &eesoxscsi_ops, info);
574 574
575 device_create_file(&ec->dev, &dev_attr_bus_term); 575 device_create_file(&ec->dev, &dev_attr_bus_term);
576 576
diff --git a/drivers/scsi/arm/powertec.c b/drivers/scsi/arm/powertec.c
index 159047a34997..3cbd525b58c5 100644
--- a/drivers/scsi/arm/powertec.c
+++ b/drivers/scsi/arm/powertec.c
@@ -361,8 +361,8 @@ powertecscsi_probe(struct expansion_card *ec, const struct ecard_id *id)
361 361
362 ec->irqaddr = base + POWERTEC_INTR_STATUS; 362 ec->irqaddr = base + POWERTEC_INTR_STATUS;
363 ec->irqmask = POWERTEC_INTR_BIT; 363 ec->irqmask = POWERTEC_INTR_BIT;
364 ec->irq_data = info; 364
365 ec->ops = &powertecscsi_ops; 365 ecard_setirq(ec, &powertecscsi_ops, info);
366 366
367 device_create_file(&ec->dev, &dev_attr_bus_term); 367 device_create_file(&ec->dev, &dev_attr_bus_term);
368 368
diff --git a/include/asm-arm/ecard.h b/include/asm-arm/ecard.h
index 3a6d3eb27622..8f1000eac91f 100644
--- a/include/asm-arm/ecard.h
+++ b/include/asm-arm/ecard.h
@@ -121,7 +121,7 @@ struct in_ecid { /* Packed card ID information */
121typedef struct expansion_card ecard_t; 121typedef struct expansion_card ecard_t;
122typedef unsigned long *loader_t; 122typedef unsigned long *loader_t;
123 123
124typedef struct { /* Card handler routines */ 124typedef struct expansion_card_ops { /* Card handler routines */
125 void (*irqenable)(ecard_t *ec, int irqnr); 125 void (*irqenable)(ecard_t *ec, int irqnr);
126 void (*irqdisable)(ecard_t *ec, int irqnr); 126 void (*irqdisable)(ecard_t *ec, int irqnr);
127 int (*irqpending)(ecard_t *ec); 127 int (*irqpending)(ecard_t *ec);
@@ -179,6 +179,8 @@ struct expansion_card {
179 u64 dma_mask; 179 u64 dma_mask;
180}; 180};
181 181
182void ecard_setirq(struct expansion_card *ec, const struct expansion_card_ops *ops, void *irq_data);
183
182struct in_chunk_dir { 184struct in_chunk_dir {
183 unsigned int start_offset; 185 unsigned int start_offset;
184 union { 186 union {