Subject: SSP read with kernel thread (one more patch)
To: None <port-hpcarm@netbsd.org>
From: Emmanuel Dreyfus <manu@netbsd.org>
List: port-hpcarm
Date: 09/11/2002 00:03:09
The following patch introduces two kernel threads to take care of reading data
from the SSP. What's cool is that we don't waste CPU when we have to wait: we
sleep instead.

The interupt overhead shown by top drops to nearly zero, but I'm still not very
satisfied with the way the system dehaves when I'm dragging a window in
windowmaker (solid dragging enabled). But maybe it's just that the machine does
not have enough horsepower to cope? 

I think the kernel thread for the touchpanel is probably worth it, since my last
patch produced a lot of interrupt overhead, and this one nearly nothing. On the
other hand, I wonder what to do with the keyboard kernel thread. We don't win
that much with it, as far as I can tell.

Could you people give it a try and give me your opinion? 

Index: j720ssp.c
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/hpcarm/dev/j720ssp.c,v
retrieving revision 1.8
diff -r1.8 j720ssp.c
80d79
< #include <sys/callout.h>
83a83
> #include <sys/kthread.h>
118d117
<       struct callout sc_tptimeout;
119a119,121
> 
>       struct proc *sc_tp_kthread;
>       struct proc *sc_kbd_kthread;
125,126c127
< void j720tpsoft(void *);
< void j720tp_timeout(void *);
---
> int j720tppoll(void *);
133a135,138
> void j720ssp_create_kthread(void *);
> void j720ssp_tp_kthread(void *);
> void j720ssp_kbd_kthread(void *);
> 
224c229
<       sc->sc_kbdsi = softintr_establish(IPL_SOFTCLOCK, j720kbdsoft, sc);
---
>       kthread_create(j720ssp_create_kthread, sc);
281d285
<       callout_init(&sc->sc_tptimeout);
284d287
<       sc->sc_tpsi = softintr_establish(IPL_SOFTCLOCK, j720tpsoft, sc);
302a306,347
> void
> j720ssp_create_kthread(arg)
>       void *arg;
> {
>       struct j720ssp_softc *sc = arg;
> 
>       if (kthread_create1(j720ssp_kbd_kthread, sc, 
>           &sc->sc_kbd_kthread, "j720ssp_kbd")) 
>               panic("j720ssp_create_kthread (j720ssp_kbd_kthread)");
> 
>       if (kthread_create1(j720ssp_tp_kthread, sc, 
>           &sc->sc_tp_kthread, "j720ssp_tp")) 
>               panic("j720ssp_create_kthread (j720ssp_tp_kthread)");
> }
> 
> void
> j720ssp_tp_kthread(arg)
>       void *arg;
> {
>       struct j720ssp_softc *sc = arg;
>       int dontcare;
> 
>       while (1) {
>               tsleep(&sc->sc_tp_kthread, PRIBIO, "j720ssp_tp", 0);
>               while (j720tppoll(sc)) 
>                       (void)tsleep(&dontcare, PRIBIO, "j720ssp_tp", hz / 25);
>       }
> }
> 
> void
> j720ssp_kbd_kthread(arg)
>       void *arg;
> {
>       struct j720ssp_softc *sc = arg;
> 
>       while (1) {
>               tsleep(&sc->sc_kbd_kthread, PRIBIO, "j720ssp_kbd", 0);
>               j720kbdsoft(sc);
>       }
> }
> 
> 
364,373c409,410
<       /*
<        * Schedule a soft interrupt to process at lower priority,
<        * as reading keycodes takes time.
<        *
<        * Interrupts are generated every 25-33ms as long as there
<        * are unprocessed key events.  So it is not a good idea to
<        * use callout to call j720kbdsoft after some delay in hope
<        * of reducing interrupts.
<        */
<       softintr_schedule(sc->sc_kbdsi);
---
>       /* Here we should disable kbd interrupt */
>       wakeup(&sc->sc_kbd_kthread);
385c422,423
<       softintr_schedule(sc->sc_tpsi);
---
>       j720tp_disable(sc);
>       wakeup(&sc->sc_tp_kthread);
414a453,454
>       /* If we managed to disable it, re-enable it now */
>       /* j720kbd_enable(sc, 1); */
468,469c508,509
< void
< j720tpsoft(void *arg)
---
> int
> j720tppoll(void *arg)
473a514,524
>       /* 
>        * If touch panel is not touched anymore, 
>        * stop polling and re-enable interrupt 
>        */
>       if (bus_space_read_4(sc->sc_iot, 
>           sc->sc_gpioh, SAGPIO_PLR) & (1 << 9)) {
>               wsmouse_input(sc->sc_wsmousedev, 0, 0, 0, 0, 0);
>               j720tp_enable(sc);
>               return 0;
>       }
> 
499c550
<       printf("j720tpsoft: %d %d %d  %d %d %d\n", buf[0], buf[1], buf[2],
---
>       printf("j720tppoll: %d %d %d  %d %d %d\n", buf[0], buf[1], buf[2],
508,510c559
<       callout_reset(&sc->sc_tptimeout, hz / 10, j720tp_timeout, sc);
< 
<       return;
---
>       return 1;
520,526c569
<       printf("j720tpsoft: error %x\n", data);
< }
< 
< void
< j720tp_timeout(void *arg)
< {
<       struct j720ssp_softc *sc = arg;
---
>       printf("j720tppoll: error %x\n", data);
528,538c571
< #if 0
<       /* XXX I don't this this is necessary (untested) */
<       if (bus_space_read_4(sc->sc_iot, sc->sc_gpioh, SAGPIO_PLR) &
<           (1 << 9)) {
<               /* Touchpad is still pressed */
<               callout_reset(&sc->sc_tptimeout, hz / 10, j720tp_timeout, sc);
<               return;
<       }
< #endif
< 
<       wsmouse_input(sc->sc_wsmousedev, 0, 0, 0, 0, 0);
---
>       return 0;
673a707
>       int dontcare;
686c720
<               delay(5000);
---
>               tsleep(&dontcare, PRIBIO, "j720ssp_readwrite", 1);
692c726
<       delay(5000);
---
>       tsleep(&dontcare, PRIBIO, "j720ssp_readwrite", 1);


-- 
Emmanuel Dreyfus.
NetBSD, parceque je le vaux bien.
manu@netbsd.org