Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c7b87f3d authored by Russell King's avatar Russell King Committed by Russell King
Browse files

[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: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent 129a84de
Loading
Loading
Loading
Loading
+16 −0
Original line number Diff line number Diff line
@@ -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.
 *
@@ -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;
}

+4 −9
Original line number Diff line number Diff line
@@ -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
@@ -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;
@@ -609,7 +608,6 @@ 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);
	local_irq_restore(flags);

@@ -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)
+3 −6
Original line number Diff line number Diff line
@@ -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
@@ -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;
@@ -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);
+1 −3
Original line number Diff line number Diff line
@@ -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
@@ -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);
+2 −2
Original line number Diff line number Diff line
@@ -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)
Loading