Re: GPIO subsystem and interrupts -- no way to do rising & falling edge on same pin?
Jason Thorpe <[email protected]> Tue, 15 May 2018 17:22:26 -0400
| Newsgroups | gmane.os.netbsd.devel.embedded |
|---|---|
| Message-ID | <[email protected]> |
> On May 15, 2018, at 7:17 AM, Jason Thorpe <[email protected]> wrote: >=20 > I=E2=80=99ve done this =E2=80=94 I=E2=80=99m going to be posting some = more on this as soon as I=E2=80=99ve tested it (and had Brad Spencer = verify that the PPS driver he submitted still works correctly with the = new way). Ok, well, testing is still pending, but I figured I=E2=80=99m stuck on a = plane and have some time so might as well post about what the new = interface looks like. The following have been added to gpio_chipset_tag_t: void * (*gp_intr_establish)(void *, int, int, int, int (*)(void *), void *); void (*gp_intr_disestablish)(void *, void *); bool (*gp_intr_str)(void *, int, int, char *, size_t); A back-end would initialize them with pointers to functions such as = these: static void * bcmgpio_gpio_intr_establish(void *vsc, int pin, int ipl, int irqmode, int (*func)(void *), void *arg); static void bcmgpio_gpio_intr_disestablish(void *vsc, void *ih); static bool bcmgpio_gpio_intrstr(void *vsc, int pin, int irqmode, char *buf, size_t = buflen); The gpio_pin structure no longer has pin_callback or pin_callback_arg = fields. The following fields have been added (filled in by the = back-end). int pin_intrcaps; /* interrupt = capabilities */ gpio_pin_ctl_intr() has been removed, as has gpio_intr() and = gpio_pin_irqen(). Instead, we have: void * gpio_intr_establish(void *, struct gpio_pinmap *, int, int, int, int (*)(void *), void *); void gpio_intr_disestablish(void *, void *); bool gpio_intr_str(void *, struct gpio_pinmap *, int, int, char *, size_t); Interrupts will be dispatched by the back-end GPIO controller driver, as = they are with FDT-registered interrupts. This allows the GPIO code to = support level-triggered interrupts, among other things. A new gpio_pin_intrcaps() has been added, which is like gpio_pin_caps(), = but it returns the interrupt capabilities instead. gpio_pin_get_conf() and gpio_pin_set_conf() have been added; = gpio_pin_set_conf() is like gpio_pin_ctl(), but it checks the requested = mode against the capabilities of the pin. gpio_pin_get_conf() returns = the currently set mode. There is also a new gpio_pin_irqmode_issupported(), which, in addition = to checking against pin capabilities, checks for non-sensical interrupt = mode combinations. The old GPIO pin mode flags GPIO_PIN_EVENTS, GPIO_PIN_LEVEL, and = GPIO_PIN_FALLING have been removed and are now available for recycling. There are new, separate GPIO interrupt flags: /* GPIO interrupt flags */ #define GPIO_INTR_POS_EDGE 0x00000001 /* interrupt on rising = edge */ #define GPIO_INTR_NEG_EDGE 0x00000002 /* interrupt on falling = edge */ #define GPIO_INTR_DOUBLE_EDGE 0x00000004 /* interrupt on both = edges */ #define GPIO_INTR_HIGH_LEVEL 0x00000008 /* interrupt on high = level */ #define GPIO_INTR_LOW_LEVEL 0x00000010 /* interrupt on low = level */ #define GPIO_INTR_MPSAFE 0x80000000 /* MP-safe handling */ These are expressive enough to describe the capabilities of modern GPIO = controllers, and the modes (EDGE and LEVEL bits) are generally treated = as mutually exclusive, although if you request a POS_EDGE and a NEG_EDGE = interrupt together, the code will internally map that to DOUBLE_EDGE = before checking for that capability on the pin. This doesn=E2=80=99t change any of the API for userland at all; none of = the interrupt bits were useful to userland before, and nothing in the = tree used them at all. Here=E2=80=99s a link to the GPIO infrastructure diffs, with the bcm2835 = back-end changes to support both FDT and GPIO interrupt interfaces. = https://www.dropbox.com/s/zlmi8ang9gje6ld/gpio-diffs-20180515.txt Tip o=E2=80=99 the hat to Brad Spencer for his initial work on = supporting GPIO interrupts on Raspberry Pi. Once the infrastructure = changes are in, I intend to integrate his =E2=80=9Cgpioiorq=E2=80=9D = sample driver, =E2=80=9Cgpiopps=E2=80=9D NTP PPS driver, and = =E2=80=9Cgpiorng=E2=80=9D radioactive-decay random number generator = driver (all modified to work with the new GPIO interrupt = infrastructure). At some future juncture, it would be awfully nice if the FDT and the = GPIO interrupt interfaces were fully harmonized. But for now, this is a = big improvement and will support stuff like Brad=E2=80=99s nifty = hardware hacks (you guys should really read his web pages - good stuff!) = as well as my silly little clock project. Feedback appreciated. Thx. -- thorpej (Gosh, it=E2=80=99s fun to be properly hacking on NetBSD again=E2=80=A6= )