Skip to content

Commit

Permalink
[ARM] ecard: add helper function for setting ecard irq ops
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Russell King authored and Russell King committed May 11, 2007
1 parent 129a84d commit c7b87f3
Show file tree
Hide file tree
Showing 8 changed files with 33 additions and 25 deletions.
16 changes: 16 additions & 0 deletions arch/arm/kernel/ecard.c
Original file line number Diff line number Diff line change
Expand Up @@ -958,6 +958,14 @@ void ecard_release_resources(struct expansion_card *ec)
}
EXPORT_SYMBOL(ecard_release_resources);

void ecard_setirq(struct expansion_card *ec, const struct expansion_card_ops *ops, void *irq_data)
{
ec->irq_data = irq_data;
barrier();
ec->ops = ops;
}
EXPORT_SYMBOL(ecard_setirq);

/*
* Probe for an expansion card.
*
Expand Down Expand Up @@ -1133,6 +1141,14 @@ static int ecard_drv_remove(struct device *dev)
drv->remove(ec);
ecard_release(ec);

/*
* Restore the default operations. We ensure that the
* ops are set before we change the data.
*/
ec->ops = &ecard_default_ops;
barrier();
ec->irq_data = NULL;

return 0;
}

Expand Down
13 changes: 4 additions & 9 deletions drivers/ata/pata_icside.c
Original file line number Diff line number Diff line change
Expand Up @@ -434,8 +434,8 @@ pata_icside_register_v5(struct ata_probe_ent *ae, struct expansion_card *ec)

ec->irqaddr = base + ICS_ARCIN_V5_INTRSTAT;
ec->irqmask = 1;
ec->irq_data = state;
ec->ops = &pata_icside_ops_arcin_v5;

ecard_setirq(ec, &pata_icside_ops_arcin_v5, state);

/*
* Be on the safe side - disable interrupts
Expand Down Expand Up @@ -480,8 +480,7 @@ pata_icside_register_v6(struct ata_probe_ent *ae, struct expansion_card *ec)

writeb(sel, ioc_base);

ec->irq_data = state;
ec->ops = &pata_icside_ops_arcin_v6;
ecard_setirq(ec, &pata_icside_ops_arcin_v6, state);

state->irq_port = easi_base;
state->ioc_base = ioc_base;
Expand Down Expand Up @@ -609,8 +608,7 @@ static void pata_icside_shutdown(struct expansion_card *ec)
* this register via that region.
*/
local_irq_save(flags);
if (ec->ops)
ec->ops->irqdisable(ec, ec->irq);
ec->ops->irqdisable(ec, ec->irq);
local_irq_restore(flags);

/*
Expand Down Expand Up @@ -638,9 +636,6 @@ static void __devexit pata_icside_remove(struct expansion_card *ec)
* don't NULL out the drvdata - devres/libata wants it
* to free the ata_host structure.
*/
ec->ops = NULL;
ec->irq_data = NULL;

if (state->dma != NO_DMA)
free_dma(state->dma);
if (state->ioc_base)
Expand Down
9 changes: 3 additions & 6 deletions drivers/ide/arm/icside.c
Original file line number Diff line number Diff line change
Expand Up @@ -574,8 +574,8 @@ icside_register_v5(struct icside_state *state, struct expansion_card *ec)

ec->irqaddr = base + ICS_ARCIN_V5_INTRSTAT;
ec->irqmask = 1;
ec->irq_data = state;
ec->ops = &icside_ops_arcin_v5;

ecard_setirq(ec, &icside_ops_arcin_v5, state);

/*
* Be on the safe side - disable interrupts
Expand Down Expand Up @@ -630,8 +630,7 @@ icside_register_v6(struct icside_state *state, struct expansion_card *ec)

writeb(sel, ioc_base);

ec->irq_data = state;
ec->ops = &icside_ops_arcin_v6;
ecard_setirq(ec, &icside_ops_arcin_v6, state);

state->irq_port = easi_base;
state->ioc_base = ioc_base;
Expand Down Expand Up @@ -793,8 +792,6 @@ static void __devexit icside_remove(struct expansion_card *ec)
}

ecard_set_drvdata(ec, NULL);
ec->ops = NULL;
ec->irq_data = NULL;

if (state->ioc_base)
iounmap(state->ioc_base);
Expand Down
4 changes: 1 addition & 3 deletions drivers/net/arm/etherh.c
Original file line number Diff line number Diff line change
Expand Up @@ -710,8 +710,7 @@ etherh_probe(struct expansion_card *ec, const struct ecard_id *id)
* IRQ and control port handling - only for non-NIC slot cards.
*/
if (ec->slot_no != 8) {
ec->ops = &etherh_ops;
ec->irq_data = eh;
ecard_setirq(ec, &etherh_ops, eh);
} else {
/*
* If we're in the NIC slot, make sure the IRQ is enabled
Expand Down Expand Up @@ -778,7 +777,6 @@ static void __devexit etherh_remove(struct expansion_card *ec)
ecard_set_drvdata(ec, NULL);

unregister_netdev(dev);
ec->ops = NULL;

if (eh->ioc_fast)
iounmap(eh->ioc_fast);
Expand Down
4 changes: 2 additions & 2 deletions drivers/scsi/arm/cumana_2.c
Original file line number Diff line number Diff line change
Expand Up @@ -450,8 +450,8 @@ cumanascsi2_probe(struct expansion_card *ec, const struct ecard_id *id)

ec->irqaddr = info->base + CUMANASCSI2_STATUS;
ec->irqmask = STATUS_INT;
ec->irq_data = info;
ec->ops = &cumanascsi_2_ops;

ecard_setirq(ec, &cumanascsi_2_ops, info);

ret = fas216_init(host);
if (ret)
Expand Down
4 changes: 2 additions & 2 deletions drivers/scsi/arm/eesox.c
Original file line number Diff line number Diff line change
Expand Up @@ -569,8 +569,8 @@ eesoxscsi_probe(struct expansion_card *ec, const struct ecard_id *id)

ec->irqaddr = base + EESOX_DMASTAT;
ec->irqmask = EESOX_STAT_INTR;
ec->irq_data = info;
ec->ops = &eesoxscsi_ops;

ecard_setirq(ec, &eesoxscsi_ops, info);

device_create_file(&ec->dev, &dev_attr_bus_term);

Expand Down
4 changes: 2 additions & 2 deletions drivers/scsi/arm/powertec.c
Original file line number Diff line number Diff line change
Expand Up @@ -361,8 +361,8 @@ powertecscsi_probe(struct expansion_card *ec, const struct ecard_id *id)

ec->irqaddr = base + POWERTEC_INTR_STATUS;
ec->irqmask = POWERTEC_INTR_BIT;
ec->irq_data = info;
ec->ops = &powertecscsi_ops;

ecard_setirq(ec, &powertecscsi_ops, info);

device_create_file(&ec->dev, &dev_attr_bus_term);

Expand Down
4 changes: 3 additions & 1 deletion include/asm-arm/ecard.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ struct in_ecid { /* Packed card ID information */
typedef struct expansion_card ecard_t;
typedef unsigned long *loader_t;

typedef struct { /* Card handler routines */
typedef struct expansion_card_ops { /* Card handler routines */
void (*irqenable)(ecard_t *ec, int irqnr);
void (*irqdisable)(ecard_t *ec, int irqnr);
int (*irqpending)(ecard_t *ec);
Expand Down Expand Up @@ -179,6 +179,8 @@ struct expansion_card {
u64 dma_mask;
};

void ecard_setirq(struct expansion_card *ec, const struct expansion_card_ops *ops, void *irq_data);

struct in_chunk_dir {
unsigned int start_offset;
union {
Expand Down

0 comments on commit c7b87f3

Please sign in to comment.