[PATCH v1 1/1] gpiolib/grgpio: Add support for newer grgpio features
Jan.Sommer at dlr.de
Jan.Sommer at dlr.de
Wed Aug 25 08:13:39 UTC 2021
Does anyone have any objections to this?
See also https://lists.rtems.org/pipermail/devel/2021-July/068086.html for the cover letter.
Best regards,
Jan
> -----Original Message-----
> From: Sommer, Jan
> Sent: Thursday, July 1, 2021 5:44 PM
> To: devel at rtems.org
> Cc: software at gaisler.com; Sommer, Jan <Jan.Sommer at dlr.de>
> Subject: [PATCH v1 1/1] gpiolib/grgpio: Add support for newer grgpio
> features
>
> - Use proper typedef for isr (avoid warning in user application)
> - Use set input enable register together with pin direction
> - Support irqgen == 1 mode if present in capabilities register
> ---
> bsps/include/grlib/gpiolib.h | 7 +++++--
> bsps/include/grlib/grlib.h | 4 +++-
> bsps/shared/grlib/drvmgr/ambapp_bus.c | 5 +----
> bsps/shared/grlib/gpio/gpiolib.c | 2 +-
> bsps/shared/grlib/gpio/grgpio.c | 22 ++++++++++++++++------
> 5 files changed, 26 insertions(+), 14 deletions(-)
>
> diff --git a/bsps/include/grlib/gpiolib.h b/bsps/include/grlib/gpiolib.h index
> f82d4fa2c2..37ac140862 100644
> --- a/bsps/include/grlib/gpiolib.h
> +++ b/bsps/include/grlib/gpiolib.h
> @@ -28,6 +28,9 @@ struct gpiolib_config { #define GPIOLIB_IRQ_POL_LOW
> 0 #define GPIOLIB_IRQ_POL_HIGH 1
>
> +/* Interrupt Service Routine (ISR) */
> +typedef void (*gpiolib_isr)(void *arg);
> +
> /* Libarary initialize function must be called befor any other */ extern int
> gpiolib_initialize(void);
>
> @@ -54,7 +57,7 @@ extern int gpiolib_irq_disable(void *handle); extern int
> gpiolib_irq_mask(void *handle); extern int gpiolib_irq_unmask(void
> *handle); extern int gpiolib_irq_force(void *handle); -extern int
> gpiolib_irq_register(void *handle, void *func, void *arg);
> +extern int gpiolib_irq_register(void *handle, gpiolib_isr func, void
> +*arg);
>
> /*** Driver Interface ***/
>
> @@ -66,7 +69,7 @@ struct gpiolib_drv_ops {
> int (*config)(void *handle, struct gpiolib_config *cfg);
> int (*get)(void *handle, int *val);
> int (*irq_opts)(void *handle, unsigned int options);
> - int (*irq_register)(void *handle, void *func, void *arg);
> + int (*irq_register)(void *handle, gpiolib_isr func, void
> *arg);
> int (*open)(void *handle);
> int (*set)(void *handle, int dir, int outval);
> int (*show)(void *handle);
> diff --git a/bsps/include/grlib/grlib.h b/bsps/include/grlib/grlib.h index
> 49d9999807..4aa3e9df4a 100644
> --- a/bsps/include/grlib/grlib.h
> +++ b/bsps/include/grlib/grlib.h
> @@ -17,6 +17,7 @@
> #define __GRLIB_H__
>
> #include <stdbool.h>
> +#include <bsp/utility.h>
>
> #ifdef __cplusplus
> extern "C" {
> @@ -125,6 +126,7 @@ struct grgpio_regs {
> volatile unsigned int iedge; /* 0x14 Interrupt edge register */
> volatile unsigned int bypass; /* 0x18 Bypass register */
> volatile unsigned int cap; /* 0x1C Capability register */
> +#define GRGPIO_CAP_IRQGEN(reg) BSP_FLD32GET(reg, 8, 12)
> volatile unsigned int irqmap[4]; /* 0x20 - 0x2C Interrupt map registers */
> volatile unsigned int res_30; /* 0x30 Reserved */
> volatile unsigned int res_34; /* 0x34 Reserved */
> @@ -132,7 +134,7 @@ struct grgpio_regs {
> volatile unsigned int res_3C; /* 0x3C Reserved */
> volatile unsigned int iavail; /* 0x40 Interrupt available register */
> volatile unsigned int iflag; /* 0x44 Interrupt flag register */
> - volatile unsigned int res_48; /* 0x48 Reserved */
> + volatile unsigned int input_en; /* 0x48 Input enable (if present) */
> volatile unsigned int pulse; /* 0x4C Pulse register */
> volatile unsigned int res_50; /* 0x50 Reserved */
> volatile unsigned int output_or; /* 0x54 I/O port output register, logical-OR
> */
> diff --git a/bsps/shared/grlib/drvmgr/ambapp_bus.c
> b/bsps/shared/grlib/drvmgr/ambapp_bus.c
> index 3c38fc16e0..0aed29224c 100644
> --- a/bsps/shared/grlib/drvmgr/ambapp_bus.c
> +++ b/bsps/shared/grlib/drvmgr/ambapp_bus.c
> @@ -521,11 +521,8 @@ static int ambapp_dev_fixup(struct drvmgr_dev
> *dev, struct amba_dev_info *pnp)
> for(core = 0; core < subcores; core++)
> drvmgr_dev_register(devs_to_register[core]);
> return 1;
> - } else if ( (pnp->info.device == GAISLER_GPIO) &&
> - (pnp->info.vendor == VENDOR_GAISLER) ) {
> - /* PIO[N] is connected to IRQ[N]. */
> - pnp->info.irq = 0;
> }
> +
> return 0;
> }
>
> diff --git a/bsps/shared/grlib/gpio/gpiolib.c
> b/bsps/shared/grlib/gpio/gpiolib.c
> index cf0038c5bb..0cb76402cc 100644
> --- a/bsps/shared/grlib/gpio/gpiolib.c
> +++ b/bsps/shared/grlib/gpio/gpiolib.c
> @@ -201,7 +201,7 @@ int gpiolib_get(void *handle, int *inval) }
>
> /*** IRQ Functions ***/
> -int gpiolib_irq_register(void *handle, void *func, void *arg)
> +int gpiolib_irq_register(void *handle, gpiolib_isr func, void *arg)
> {
> struct gpiolib_port *port = handle;
>
> diff --git a/bsps/shared/grlib/gpio/grgpio.c b/bsps/shared/grlib/gpio/grgpio.c
> index 05504ef020..5bce5f530a 100644
> --- a/bsps/shared/grlib/gpio/grgpio.c
> +++ b/bsps/shared/grlib/gpio/grgpio.c
> @@ -229,6 +229,7 @@ static int grgpio_grpiolib_irq_opts(void *handle,
> unsigned int options) {
> struct grgpio_priv *priv;
> int portnr;
> + int irq;
> drvmgr_isr isr;
> void *arg;
>
> @@ -244,33 +245,41 @@ static int grgpio_grpiolib_irq_opts(void *handle,
> unsigned int options)
> isr = priv->isrs[portnr].isr;
> arg = priv->isrs[portnr].arg;
>
> + /* For irqgen == 1, irq == pirq, i.e. no offset */
> + irq = 0;
> + if (GRGPIO_CAP_IRQGEN(priv->regs->cap) == 0) {
> + /* For irqgen == 0, irq == pirq + portnr */
> + irq += portnr;
> + }
> + /* FIXME: irqgen > 1 currently not supported */
> +
> if ( options & GPIOLIB_IRQ_DISABLE ) {
> /* Disable interrupt at interrupt controller */
> - if ( drvmgr_interrupt_unregister(priv->dev, portnr, isr, arg) ) {
> + if ( drvmgr_interrupt_unregister(priv->dev, irq, isr, arg) ) {
> return -1;
> }
> }
> if ( options & GPIOLIB_IRQ_CLEAR ) {
> /* Clear interrupt at interrupt controller */
> - if ( drvmgr_interrupt_clear(priv->dev, portnr) ) {
> + if ( drvmgr_interrupt_clear(priv->dev, irq) ) {
> return -1;
> }
> }
> if ( options & GPIOLIB_IRQ_ENABLE ) {
> /* Enable interrupt at interrupt controller */
> - if ( drvmgr_interrupt_register(priv->dev, portnr, "grgpio", isr,
> arg) ) {
> + if ( drvmgr_interrupt_register(priv->dev, irq, "grgpio", isr,
> arg) )
> +{
> return -1;
> }
> }
> if ( options & GPIOLIB_IRQ_MASK ) {
> /* Mask (disable) interrupt at interrupt controller */
> - if ( drvmgr_interrupt_mask(priv->dev, portnr) ) {
> + if ( drvmgr_interrupt_mask(priv->dev, irq) ) {
> return -1;
> }
> }
> if ( options & GPIOLIB_IRQ_UNMASK ) {
> /* Unmask (enable) interrupt at interrupt controller */
> - if ( drvmgr_interrupt_unmask(priv->dev, portnr) ) {
> + if ( drvmgr_interrupt_unmask(priv->dev, irq) ) {
> return -1;
> }
> }
> @@ -278,7 +287,7 @@ static int grgpio_grpiolib_irq_opts(void *handle,
> unsigned int options)
> return 0;
> }
>
> -static int grgpio_grpiolib_irq_register(void *handle, void *func, void *arg)
> +static int grgpio_grpiolib_irq_register(void *handle, gpiolib_isr func,
> +void *arg)
> {
> struct grgpio_priv *priv;
> int portnr;
> @@ -313,6 +322,7 @@ static int grgpio_grpiolib_set(void *handle, int dir, int
> outval)
> /* Set Direction and Output */
> mask = 1<<portnr;
> priv->regs->dir = (priv->regs->dir & ~mask) | (dir ? mask : 0);
> + priv->regs->input_en = (priv->regs->input_en & ~mask) | (dir ? 0 :
> +mask);
> priv->regs->output = (priv->regs->output & ~mask) | (outval ? mask :
> 0);
>
> return 0;
> --
> 2.17.1
More information about the devel
mailing list