HP Jornada 6xx PCMCIA driver

Dominik Brodowski linux at dominikbrodowski.net
Sun Nov 18 13:03:37 EST 2007


Hi,

On Fri, Nov 16, 2007 at 12:36:52AM +0100, Kristoffer Ericson wrote:
> Im in the process of both bugtracking and rewriting the hp6xx pcmcia
> driver. It stopped working approx 2.6.17/2.6.18 but was in bad shape
> before then so it sure needs a rewrite. Need to fix the bug first though.
> 
> Anyhow. When inserting a card I get unexpected IRQ at vector blabla. Im not
> surprised by this but more in how its suppose to be done.
> Please note that my issues are mainly related to IRQ, so thats why Im not
> adding major code examples.
> 
> HP Jornada 6xx has an hd64461 chipset (arch/sh/cchips/hd6446x/hd64461.c)
> where we have IRQ 36 that symbolizes 16 devices.
> We use an demuxer to mask out where the interrupt is actually coming from
> and then passes it to the correct interrupt handler.
> 
> Now PCMCIA has IRQ 78 (demuxed from IRQ 36) usually. Since we want to
> divide what comes from the slot and pcmcia_card we create a software
> demuxer. IRQ 78 -> demuxer (if PCMCIA then IRQ=79 otherwise cardstatus
> IRQ=78).

Actually, why do you bother? The PCMCIA subsystem is capable of working with
shared IRQs...

> static void hd64461_enable_irq(unsigned int irq)
> {
> 	hd64461_enable_int(irq);
> }
> 
> static void hd64461_disable_irq(unsigned int irq)
> {
> 	hd64461_disable_int(irq);
> }
> 
> static unsigned int hd64461_startup_irq(unsigned int irq)
> {
> 	hd64461_enable_irq(irq);
> 	return 0;
> }
> 
> static void hd64461_shutdown_irq(unsigned int irq)
> {
> 	hd64461_disable_irq(irq);
> }
> 
> static void hd64461_mask_and_ack_irq(unsigned int irq)
> {
> 	hd64461_disable_irq(irq);
> }
> 
> static void hd64461_end_irq(unsigned int irq)
> {
> 	hd64461_enable_irq(irq);
> }

Since these functions seem to be (at least almost) the same, could you unify
this?

> static int hd64461_pcmcia_irq_demux(int irq, void *dev)
> {
> 	hd64461_socket_t *sp = (hd64461_socket_t *) dev;
> 	unsigned char cscr;
> 	unsigned cscr_reg = HD64461_PCC0CSCR;
> 
> 	/* irq should be 78 here */
> 	printk(KERN_INFO "hd64461_pcmcia_irq_demux(irq= %d)\n", irq);
> 
> 	/* If interrupt was due to pcmcia interrupt, then change it to 81 */

81? I thought 79

> int hd64461_init_socket(int sock, int irq, int io_irq, unsigned long mem_base,unsigned long io_offset)
> {
> 	sp->irq = irq;
...
> 	sp->socket.pci_irq = io_irq;
...
> 	if ((request_irq(irq, hd64461_interrupt, IRQF_DISABLED, "hd64461_ss-irq", sp)) < 0) {

I think this should be io_irq here -- the "socket" IRQ which is demuxed to 79
is io_irq; and the "card" one stays at 78. (Better use these terms than
"pcmcia" interrupt -- which is ambiguous).

> 		printk(KERN_INFO "hd64461_init: request for irq %d: failed\n", sp->irq);
> 		return -1;
> 	}
> 	
> 	/* setup io_irq chip data and move it through demux */
> 	set_irq_chip(io_irq, &hd64461_ss_irq_chip);
> 	hd64461_register_irq_demux(sp->irq, hd64461_pcmcia_irq_demux,sp);

Regarding the demux', see my comment above.

> 	/* HD64461_IRQ_PCC0 = 64 + 14 = 78         */
> 	/* HD64461_IRQ_PCC0 + 3 = 64 + 14 + 1 = 79 */
	                    + 1

Hope this helps a bit,

	Dominik



More information about the linux-pcmcia mailing list