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