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