* [Xenomai] ipipe bug in gpio/irq for mx6
@ 2016-03-18 10:43 Johann Obermayr
2016-03-18 11:10 ` Gilles Chanteperdrix
0 siblings, 1 reply; 6+ messages in thread
From: Johann Obermayr @ 2016-03-18 10:43 UTC (permalink / raw)
To: xenomai
Hello,
in the the git branch ipipe-3.0-imx6q
in the file arch/arm/plat-mxc/gpio.c
there is follow function.
void __ipipe_mach_enable_irqdesc(struct ipipe_domain *ipd, unsigned irq)
{
struct irq_desc *desc = irq_to_desc(irq);
struct irq_data *idata = irq_desc_get_irq_data(desc);
struct irq_chip *chip = irq_data_get_irq_chip(idata);
if (chip == &gpio_irq_chip) {
/* It is a gpio. */
u32 gpio = irq_to_gpio(irq);
struct mxc_gpio_port *port = &mxc_gpio_ports[gpio / 32];
if (ipd != &ipipe_root) {
port->nonroot_gpios |= (1 << (gpio % 32));
if (port->nonroot_gpios == (1 << (gpio % 32))) {
__ipipe_irqbits[(port->irq / 32)]
&= ~(1 << (port->irq % 32));
set_irq_prio(port->irq, 1);
}
}
} else
set_irq_prio(irq, ipd != &ipipe_root);
}
But there is missing set_irq_prio for the port->irq_high.
to add
if (port->irq_high > 0)
set_irq_prio(port->irq_high, 1);
is not my problem.
my problem is, that i don't known if __ipipe_irqbits is handled correct.
regards
Johann
^ permalink raw reply [flat|nested] 6+ messages in thread* Re: [Xenomai] ipipe bug in gpio/irq for mx6 2016-03-18 10:43 [Xenomai] ipipe bug in gpio/irq for mx6 Johann Obermayr @ 2016-03-18 11:10 ` Gilles Chanteperdrix 2016-03-18 12:15 ` Johann Obermayr 0 siblings, 1 reply; 6+ messages in thread From: Gilles Chanteperdrix @ 2016-03-18 11:10 UTC (permalink / raw) To: Johann Obermayr; +Cc: xenomai On Fri, Mar 18, 2016 at 11:43:26AM +0100, Johann Obermayr wrote: > Hello, > > in the the git branch ipipe-3.0-imx6q This I-pipe patch is really old now. Any chance to use a current version of Xenomai? > in the file arch/arm/plat-mxc/gpio.c > > there is follow function. > > void __ipipe_mach_enable_irqdesc(struct ipipe_domain *ipd, unsigned irq) > { > struct irq_desc *desc = irq_to_desc(irq); > struct irq_data *idata = irq_desc_get_irq_data(desc); > struct irq_chip *chip = irq_data_get_irq_chip(idata); > > if (chip == &gpio_irq_chip) { > /* It is a gpio. */ > u32 gpio = irq_to_gpio(irq); > struct mxc_gpio_port *port = &mxc_gpio_ports[gpio / 32]; > > if (ipd != &ipipe_root) { > port->nonroot_gpios |= (1 << (gpio % 32)); > if (port->nonroot_gpios == (1 << (gpio % 32))) { > __ipipe_irqbits[(port->irq / 32)] > &= ~(1 << (port->irq % 32)); > set_irq_prio(port->irq, 1); > } > } > } else > set_irq_prio(irq, ipd != &ipipe_root); > } > > But there is missing set_irq_prio for the port->irq_high. > to add > if (port->irq_high > 0) > set_irq_prio(port->irq_high, 1); > is not my problem. > > my problem is, that i don't known if __ipipe_irqbits is handled > correct. Well, if you want to set port->irq_high, you have to clear the corresponding bit in __ipipe_irqbits, as is done for port->irq. -- Gilles. https://click-hack.org ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [Xenomai] ipipe bug in gpio/irq for mx6 2016-03-18 11:10 ` Gilles Chanteperdrix @ 2016-03-18 12:15 ` Johann Obermayr 2016-03-18 12:28 ` Gilles Chanteperdrix 0 siblings, 1 reply; 6+ messages in thread From: Johann Obermayr @ 2016-03-18 12:15 UTC (permalink / raw) To: xenomai Am 18.03.2016 um 12:10 schrieb Gilles Chanteperdrix: > On Fri, Mar 18, 2016 at 11:43:26AM +0100, Johann Obermayr wrote: >> Hello, >> >> in the the git branch ipipe-3.0-imx6q > This I-pipe patch is really old now. Any chance to use a current > version of Xenomai? Not now. but we have started to change to 3.10.x with newer xenomai >> in the file arch/arm/plat-mxc/gpio.c >> >> there is follow function. >> >> void __ipipe_mach_enable_irqdesc(struct ipipe_domain *ipd, unsigned irq) >> { >> struct irq_desc *desc = irq_to_desc(irq); >> struct irq_data *idata = irq_desc_get_irq_data(desc); >> struct irq_chip *chip = irq_data_get_irq_chip(idata); >> >> if (chip == &gpio_irq_chip) { >> /* It is a gpio. */ >> u32 gpio = irq_to_gpio(irq); >> struct mxc_gpio_port *port = &mxc_gpio_ports[gpio / 32]; >> >> if (ipd != &ipipe_root) { >> port->nonroot_gpios |= (1 << (gpio % 32)); >> if (port->nonroot_gpios == (1 << (gpio % 32))) { >> __ipipe_irqbits[(port->irq / 32)] >> &= ~(1 << (port->irq % 32)); >> set_irq_prio(port->irq, 1); >> } >> } >> } else >> set_irq_prio(irq, ipd != &ipipe_root); >> } >> >> But there is missing set_irq_prio for the port->irq_high. >> to add >> if (port->irq_high > 0) >> set_irq_prio(port->irq_high, 1); >> is not my problem. >> >> my problem is, that i don't known if __ipipe_irqbits is handled >> correct. > Well, if you want to set port->irq_high, you have to clear the > corresponding bit in __ipipe_irqbits, as is done for port->irq. > Thank you Gilles. i've also take a part from newer version. void __ipipe_mach_enable_irqdesc(struct ipipe_domain *ipd, unsigned irq) { struct irq_desc *desc = irq_to_desc(irq); struct irq_data *idata = irq_desc_get_irq_data(desc); struct irq_chip *chip = irq_data_get_irq_chip(idata); if (chip == &gpio_irq_chip) { /* It is a gpio. */ u32 gpio = irq_to_gpio(irq); struct mxc_gpio_port *port = &mxc_gpio_ports[gpio / 32]; if (ipd == &ipipe_root) { port->nonroot_gpios &= ~(1 << (gpio % 32)); if (port->nonroot_gpios == 0) { __ipipe_irqbits[(port->irq / 32)] &= ~(1 << (port->irq % 32)); __ipipe_irqbits[(port->irq_high / 32)] &= ~(1 << (port->irq_high % 32)); set_irq_prio(port->irq, 0); if (port->irq_high > 0) set_irq_prio(port->irq_high, 0); } } else { port->nonroot_gpios |= (1 << (gpio % 32)); if (port->nonroot_gpios == (1 << (gpio % 32))) { __ipipe_irqbits[(port->irq / 32)] &= ~(1 << (port->irq % 32)); __ipipe_irqbits[(port->irq_high / 32)] &= ~(1 << (port->irq_high % 32)); set_irq_prio(port->irq, 1); if (port->irq_high > 0) set_irq_prio(port->irq_high, 1); } } } else set_irq_prio(irq, ipd != &ipipe_root); } is this correct to clear the the bit in __ipipe_irqbits also for ipd == ipipe_root ? Regards Johann ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [Xenomai] ipipe bug in gpio/irq for mx6 2016-03-18 12:15 ` Johann Obermayr @ 2016-03-18 12:28 ` Gilles Chanteperdrix 2016-03-23 11:01 ` Johann Obermayr 0 siblings, 1 reply; 6+ messages in thread From: Gilles Chanteperdrix @ 2016-03-18 12:28 UTC (permalink / raw) To: Johann Obermayr; +Cc: xenomai On Fri, Mar 18, 2016 at 01:15:17PM +0100, Johann Obermayr wrote: > Am 18.03.2016 um 12:10 schrieb Gilles Chanteperdrix: > > On Fri, Mar 18, 2016 at 11:43:26AM +0100, Johann Obermayr wrote: > >> Hello, > >> > >> in the the git branch ipipe-3.0-imx6q > > This I-pipe patch is really old now. Any chance to use a current > > version of Xenomai? > Not now. but we have started to change to 3.10.x with newer xenomai > >> in the file arch/arm/plat-mxc/gpio.c > >> > >> there is follow function. > >> > >> void __ipipe_mach_enable_irqdesc(struct ipipe_domain *ipd, unsigned irq) > >> { > >> struct irq_desc *desc = irq_to_desc(irq); > >> struct irq_data *idata = irq_desc_get_irq_data(desc); > >> struct irq_chip *chip = irq_data_get_irq_chip(idata); > >> > >> if (chip == &gpio_irq_chip) { > >> /* It is a gpio. */ > >> u32 gpio = irq_to_gpio(irq); > >> struct mxc_gpio_port *port = &mxc_gpio_ports[gpio / 32]; > >> > >> if (ipd != &ipipe_root) { > >> port->nonroot_gpios |= (1 << (gpio % 32)); > >> if (port->nonroot_gpios == (1 << (gpio % 32))) { > >> __ipipe_irqbits[(port->irq / 32)] > >> &= ~(1 << (port->irq % 32)); > >> set_irq_prio(port->irq, 1); > >> } > >> } > >> } else > >> set_irq_prio(irq, ipd != &ipipe_root); > >> } > >> > >> But there is missing set_irq_prio for the port->irq_high. > >> to add > >> if (port->irq_high > 0) > >> set_irq_prio(port->irq_high, 1); > >> is not my problem. > >> > >> my problem is, that i don't known if __ipipe_irqbits is handled > >> correct. > > Well, if you want to set port->irq_high, you have to clear the > > corresponding bit in __ipipe_irqbits, as is done for port->irq. > > > Thank you Gilles. > > i've also take a part from newer version. > void __ipipe_mach_enable_irqdesc(struct ipipe_domain *ipd, unsigned irq) > { > struct irq_desc *desc = irq_to_desc(irq); > struct irq_data *idata = irq_desc_get_irq_data(desc); > struct irq_chip *chip = irq_data_get_irq_chip(idata); > > if (chip == &gpio_irq_chip) { > /* It is a gpio. */ > u32 gpio = irq_to_gpio(irq); > struct mxc_gpio_port *port = &mxc_gpio_ports[gpio / 32]; > > if (ipd == &ipipe_root) { > port->nonroot_gpios &= ~(1 << (gpio % 32)); > if (port->nonroot_gpios == 0) { > __ipipe_irqbits[(port->irq / 32)] &= ~(1 << (port->irq > % 32)); > __ipipe_irqbits[(port->irq_high / 32)] &= ~(1 << > (port->irq_high % 32)); > set_irq_prio(port->irq, 0); > if (port->irq_high > 0) > set_irq_prio(port->irq_high, 0); > } > } else { > port->nonroot_gpios |= (1 << (gpio % 32)); > if (port->nonroot_gpios == (1 << (gpio % 32))) { > __ipipe_irqbits[(port->irq / 32)] &= ~(1 << (port->irq > % 32)); > __ipipe_irqbits[(port->irq_high / 32)] &= ~(1 << > (port->irq_high % 32)); > set_irq_prio(port->irq, 1); > if (port->irq_high > 0) > set_irq_prio(port->irq_high, 1); > } > } > } else > set_irq_prio(irq, ipd != &ipipe_root); > } > > is this correct to clear the the bit in __ipipe_irqbits also for ipd == > ipipe_root ? It is useless, __ipipe_mach_enable_irqdesc for root irqs is called only once at boot time, when the bits are already cleared. -- Gilles. https://click-hack.org ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [Xenomai] ipipe bug in gpio/irq for mx6 2016-03-18 12:28 ` Gilles Chanteperdrix @ 2016-03-23 11:01 ` Johann Obermayr 2016-03-23 11:12 ` Gilles Chanteperdrix 0 siblings, 1 reply; 6+ messages in thread From: Johann Obermayr @ 2016-03-23 11:01 UTC (permalink / raw) To: xenomai Am 18.03.2016 um 13:28 schrieb Gilles Chanteperdrix: > On Fri, Mar 18, 2016 at 01:15:17PM +0100, Johann Obermayr wrote: >> Am 18.03.2016 um 12:10 schrieb Gilles Chanteperdrix: >>> On Fri, Mar 18, 2016 at 11:43:26AM +0100, Johann Obermayr wrote: >>>> Hello, >>>> >>>> in the the git branch ipipe-3.0-imx6q >>> This I-pipe patch is really old now. Any chance to use a current >>> version of Xenomai? >> Not now. but we have started to change to 3.10.x with newer xenomai >>>> in the file arch/arm/plat-mxc/gpio.c >>>> >>>> there is follow function. >>>> >>>> void __ipipe_mach_enable_irqdesc(struct ipipe_domain *ipd, unsigned irq) >>>> { >>>> struct irq_desc *desc = irq_to_desc(irq); >>>> struct irq_data *idata = irq_desc_get_irq_data(desc); >>>> struct irq_chip *chip = irq_data_get_irq_chip(idata); >>>> >>>> if (chip == &gpio_irq_chip) { >>>> /* It is a gpio. */ >>>> u32 gpio = irq_to_gpio(irq); >>>> struct mxc_gpio_port *port = &mxc_gpio_ports[gpio / 32]; >>>> >>>> if (ipd != &ipipe_root) { >>>> port->nonroot_gpios |= (1 << (gpio % 32)); >>>> if (port->nonroot_gpios == (1 << (gpio % 32))) { >>>> __ipipe_irqbits[(port->irq / 32)] >>>> &= ~(1 << (port->irq % 32)); >>>> set_irq_prio(port->irq, 1); >>>> } >>>> } >>>> } else >>>> set_irq_prio(irq, ipd != &ipipe_root); >>>> } >>>> >>>> But there is missing set_irq_prio for the port->irq_high. >>>> to add >>>> if (port->irq_high > 0) >>>> set_irq_prio(port->irq_high, 1); >>>> is not my problem. >>>> >>>> my problem is, that i don't known if __ipipe_irqbits is handled >>>> correct. >>> Well, if you want to set port->irq_high, you have to clear the >>> corresponding bit in __ipipe_irqbits, as is done for port->irq. >>> >> Thank you Gilles. >> >> i've also take a part from newer version. >> void __ipipe_mach_enable_irqdesc(struct ipipe_domain *ipd, unsigned irq) >> { >> struct irq_desc *desc = irq_to_desc(irq); >> struct irq_data *idata = irq_desc_get_irq_data(desc); >> struct irq_chip *chip = irq_data_get_irq_chip(idata); >> >> if (chip == &gpio_irq_chip) { >> /* It is a gpio. */ >> u32 gpio = irq_to_gpio(irq); >> struct mxc_gpio_port *port = &mxc_gpio_ports[gpio / 32]; >> >> if (ipd == &ipipe_root) { >> port->nonroot_gpios &= ~(1 << (gpio % 32)); >> if (port->nonroot_gpios == 0) { >> __ipipe_irqbits[(port->irq / 32)] &= ~(1 << (port->irq >> % 32)); >> __ipipe_irqbits[(port->irq_high / 32)] &= ~(1 << >> (port->irq_high % 32)); >> set_irq_prio(port->irq, 0); >> if (port->irq_high > 0) >> set_irq_prio(port->irq_high, 0); >> } >> } else { >> port->nonroot_gpios |= (1 << (gpio % 32)); >> if (port->nonroot_gpios == (1 << (gpio % 32))) { >> __ipipe_irqbits[(port->irq / 32)] &= ~(1 << (port->irq >> % 32)); >> __ipipe_irqbits[(port->irq_high / 32)] &= ~(1 << >> (port->irq_high % 32)); >> set_irq_prio(port->irq, 1); >> if (port->irq_high > 0) >> set_irq_prio(port->irq_high, 1); >> } >> } >> } else >> set_irq_prio(irq, ipd != &ipipe_root); >> } >> >> is this correct to clear the the bit in __ipipe_irqbits also for ipd == >> ipipe_root ? > It is useless, __ipipe_mach_enable_irqdesc for root irqs is called > only once at boot time, when the bits are already cleared. > Here are my patches for imx.6 gpio irq handling. also add patch for using edge select bit (irq raise/fall detection) on imx.6 Regards Johann -------------- next part -------------- >From b806dcf59ec3cf1abc18318cce090b78e396dec6 Mon Sep 17 00:00:00 2001 From: Johann Obermayr <johann.obermayr@sigmatek.at> Date: Fri, 18 Mar 2016 16:04:38 +0100 Subject: [PATCH] high irq for GPIO input not working. --- arch/arm/plat-mxc/gpio.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/arch/arm/plat-mxc/gpio.c b/arch/arm/plat-mxc/gpio.c index 87b643e..3f5925a 100755 --- a/arch/arm/plat-mxc/gpio.c +++ b/arch/arm/plat-mxc/gpio.c @@ -426,9 +426,12 @@ void __ipipe_mach_enable_irqdesc(struct ipipe_domain *ipd, unsigned irq) if (ipd != &ipipe_root) { port->nonroot_gpios |= (1 << (gpio % 32)); if (port->nonroot_gpios == (1 << (gpio % 32))) { - __ipipe_irqbits[(port->irq / 32)] - &= ~(1 << (port->irq % 32)); + __ipipe_irqbits[(port->irq / 32)] &= ~(1 << (port->irq % 32)); set_irq_prio(port->irq, 1); + if (port->irq_high > 0) { + __ipipe_irqbits[(port->irq_high / 32)] &= ~(1 << (port->irq_high % 32)); + set_irq_prio(port->irq_high, 1); + } } } } else @@ -450,8 +453,11 @@ void __ipipe_mach_disable_irqdesc(struct ipipe_domain *ipd, unsigned irq) port->nonroot_gpios &= ~(1 << (gpio % 32)); if (!port->nonroot_gpios) { set_irq_prio(port->irq, 0); - __ipipe_irqbits[(port->irq / 32)] - |= (1 << (port->irq % 32)); + __ipipe_irqbits[(port->irq / 32)] |= (1 << (port->irq % 32)); + if (port->irq_high > 0) { + set_irq_prio(port->irq_high, 0); + __ipipe_irqbits[(port->irq_high / 32)] |= (1 << (port->irq_high % 32)); + } } } } else if (ipd != &ipipe_root) -- 1.7.9.5 -------------- next part -------------- >From 962417f6870aec76188f391a708fc05d54f6d94c Mon Sep 17 00:00:00 2001 From: Johann Obermayr <johann.obermayr@sigmatek.at> Date: Mon, 21 Mar 2016 17:14:18 +0100 Subject: [PATCH] use edge select bit to activate raise/fall irq detection. --- arch/arm/plat-mxc/gpio.c | 51 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 36 insertions(+), 15 deletions(-) diff --git a/arch/arm/plat-mxc/gpio.c b/arch/arm/plat-mxc/gpio.c index 3f5925a..c1caa6b 100755 --- a/arch/arm/plat-mxc/gpio.c +++ b/arch/arm/plat-mxc/gpio.c @@ -31,6 +31,7 @@ static struct mxc_gpio_port *mxc_gpio_ports; static int gpio_table_size; +static int GPIO_EDGE_SEL = -1; #define cpu_is_mx1_mx2() (cpu_is_mx1() || cpu_is_mx2()) @@ -46,7 +47,7 @@ static int gpio_table_size; #define GPIO_INT_HIGH_LEV (cpu_is_mx1_mx2() ? 0x2 : 0x1) #define GPIO_INT_RISE_EDGE (cpu_is_mx1_mx2() ? 0x0 : 0x2) #define GPIO_INT_FALL_EDGE (cpu_is_mx1_mx2() ? 0x1 : 0x3) -#define GPIO_INT_NONE 0x4 +#define GPIO_INT_BOTH_EDGES 0x4 /* Note: This driver assumes 32 GPIOs are handled in one register */ @@ -93,8 +94,9 @@ static int gpio_set_irq_type(struct irq_data *d, u32 type) u32 bit, val; int edge; void __iomem *reg = port->base; + u32 gpio_idx = gpio & 31; - port->both_edges &= ~(1 << (gpio & 31)); + port->both_edges &= ~(1 << gpio_idx); switch (type) { case IRQ_TYPE_EDGE_RISING: edge = GPIO_INT_RISE_EDGE; @@ -103,15 +105,19 @@ static int gpio_set_irq_type(struct irq_data *d, u32 type) edge = GPIO_INT_FALL_EDGE; break; case IRQ_TYPE_EDGE_BOTH: - val = mxc_gpio_get(&port->chip, gpio & 31); - if (val) { - edge = GPIO_INT_LOW_LEV; - pr_debug("mxc: set GPIO %d to low trigger\n", gpio); + if (GPIO_EDGE_SEL >= 0) { + edge = GPIO_INT_BOTH_EDGES; } else { - edge = GPIO_INT_HIGH_LEV; - pr_debug("mxc: set GPIO %d to high trigger\n", gpio); + val = mxc_gpio_get(&port->chip, gpio_idx); + if (val) { + edge = GPIO_INT_LOW_LEV; + pr_debug("mxc: set GPIO %d to low trigger\n", gpio); + } else { + edge = GPIO_INT_HIGH_LEV; + pr_debug("mxc: set GPIO %d to high trigger\n", gpio); + } + port->both_edges |= (1 << gpio_idx); } - port->both_edges |= 1 << (gpio & 31); break; case IRQ_TYPE_LEVEL_LOW: edge = GPIO_INT_LOW_LEV; @@ -124,11 +130,22 @@ static int gpio_set_irq_type(struct irq_data *d, u32 type) } spin_lock_irqsave(&port->lock, flags); - reg += GPIO_ICR1 + ((gpio & 0x10) >> 2); /* lower or upper register */ - bit = gpio & 0xf; - val = __raw_readl(reg) & ~(0x3 << (bit << 1)); - __raw_writel(val | (edge << (bit << 1)), reg); - _clear_gpio_irqstatus(port, gpio & 0x1f); + if (GPIO_EDGE_SEL >= 0) { + void __iomem *regsel = port->base + GPIO_EDGE_SEL; + val = __raw_readl(regsel); + if (edge == GPIO_INT_BOTH_EDGES) + __raw_writel(val | (1 << gpio_idx), regsel); + else + __raw_writel(val & ~(1 << gpio_idx), regsel); + } + + if (edge != GPIO_INT_BOTH_EDGES) { + reg += GPIO_ICR1 + ((gpio & 0x10) >> 2); /* lower or upper register */ + bit = gpio & 0xf; + val = __raw_readl(reg) & ~(0x3 << (bit << 1)); + __raw_writel(val | (edge << (bit << 1)), reg); + } + _clear_gpio_irqstatus(port, gpio_idx); spin_unlock_irqrestore(&port->lock, flags); return 0; @@ -330,7 +347,7 @@ int mxc_gpio_init(struct mxc_gpio_port *port, int cnt) mxc_gpio_ports = port; gpio_table_size = cnt; - printk(KERN_INFO "MXC GPIO hardware\n"); + printk(KERN_INFO "MXC (%u) GPIO hardware\n", mxc_cpu_type); for (i = 0; i < cnt; i++) { /* disable the interrupt and clear the status */ @@ -381,6 +398,10 @@ int mxc_gpio_init(struct mxc_gpio_port *port, int cnt) irq_set_handler_data(port[0].irq, port); } + /* mx35 or newer support edge select */ + if (mxc_cpu_type >= MXC_CPU_MX35) + GPIO_EDGE_SEL = 0x1C; + return 0; } -- 1.7.9.5 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [Xenomai] ipipe bug in gpio/irq for mx6 2016-03-23 11:01 ` Johann Obermayr @ 2016-03-23 11:12 ` Gilles Chanteperdrix 0 siblings, 0 replies; 6+ messages in thread From: Gilles Chanteperdrix @ 2016-03-23 11:12 UTC (permalink / raw) To: Johann Obermayr; +Cc: xenomai On Wed, Mar 23, 2016 at 12:01:01PM +0100, Johann Obermayr wrote: > Am 18.03.2016 um 13:28 schrieb Gilles Chanteperdrix: > > On Fri, Mar 18, 2016 at 01:15:17PM +0100, Johann Obermayr wrote: > >> Am 18.03.2016 um 12:10 schrieb Gilles Chanteperdrix: > >>> On Fri, Mar 18, 2016 at 11:43:26AM +0100, Johann Obermayr wrote: > >>>> Hello, > >>>> > >>>> in the the git branch ipipe-3.0-imx6q > >>> This I-pipe patch is really old now. Any chance to use a current > >>> version of Xenomai? > >> Not now. but we have started to change to 3.10.x with newer xenomai > >>>> in the file arch/arm/plat-mxc/gpio.c > >>>> > >>>> there is follow function. > >>>> > >>>> void __ipipe_mach_enable_irqdesc(struct ipipe_domain *ipd, unsigned irq) > >>>> { > >>>> struct irq_desc *desc = irq_to_desc(irq); > >>>> struct irq_data *idata = irq_desc_get_irq_data(desc); > >>>> struct irq_chip *chip = irq_data_get_irq_chip(idata); > >>>> > >>>> if (chip == &gpio_irq_chip) { > >>>> /* It is a gpio. */ > >>>> u32 gpio = irq_to_gpio(irq); > >>>> struct mxc_gpio_port *port = &mxc_gpio_ports[gpio / 32]; > >>>> > >>>> if (ipd != &ipipe_root) { > >>>> port->nonroot_gpios |= (1 << (gpio % 32)); > >>>> if (port->nonroot_gpios == (1 << (gpio % 32))) { > >>>> __ipipe_irqbits[(port->irq / 32)] > >>>> &= ~(1 << (port->irq % 32)); > >>>> set_irq_prio(port->irq, 1); > >>>> } > >>>> } > >>>> } else > >>>> set_irq_prio(irq, ipd != &ipipe_root); > >>>> } > >>>> > >>>> But there is missing set_irq_prio for the port->irq_high. > >>>> to add > >>>> if (port->irq_high > 0) > >>>> set_irq_prio(port->irq_high, 1); > >>>> is not my problem. > >>>> > >>>> my problem is, that i don't known if __ipipe_irqbits is handled > >>>> correct. > >>> Well, if you want to set port->irq_high, you have to clear the > >>> corresponding bit in __ipipe_irqbits, as is done for port->irq. > >>> > >> Thank you Gilles. > >> > >> i've also take a part from newer version. > >> void __ipipe_mach_enable_irqdesc(struct ipipe_domain *ipd, unsigned irq) > >> { > >> struct irq_desc *desc = irq_to_desc(irq); > >> struct irq_data *idata = irq_desc_get_irq_data(desc); > >> struct irq_chip *chip = irq_data_get_irq_chip(idata); > >> > >> if (chip == &gpio_irq_chip) { > >> /* It is a gpio. */ > >> u32 gpio = irq_to_gpio(irq); > >> struct mxc_gpio_port *port = &mxc_gpio_ports[gpio / 32]; > >> > >> if (ipd == &ipipe_root) { > >> port->nonroot_gpios &= ~(1 << (gpio % 32)); > >> if (port->nonroot_gpios == 0) { > >> __ipipe_irqbits[(port->irq / 32)] &= ~(1 << (port->irq > >> % 32)); > >> __ipipe_irqbits[(port->irq_high / 32)] &= ~(1 << > >> (port->irq_high % 32)); > >> set_irq_prio(port->irq, 0); > >> if (port->irq_high > 0) > >> set_irq_prio(port->irq_high, 0); > >> } > >> } else { > >> port->nonroot_gpios |= (1 << (gpio % 32)); > >> if (port->nonroot_gpios == (1 << (gpio % 32))) { > >> __ipipe_irqbits[(port->irq / 32)] &= ~(1 << (port->irq > >> % 32)); > >> __ipipe_irqbits[(port->irq_high / 32)] &= ~(1 << > >> (port->irq_high % 32)); > >> set_irq_prio(port->irq, 1); > >> if (port->irq_high > 0) > >> set_irq_prio(port->irq_high, 1); > >> } > >> } > >> } else > >> set_irq_prio(irq, ipd != &ipipe_root); > >> } > >> > >> is this correct to clear the the bit in __ipipe_irqbits also for ipd == > >> ipipe_root ? > > It is useless, __ipipe_mach_enable_irqdesc for root irqs is called > > only once at boot time, when the bits are already cleared. > > > Here are my patches for imx.6 gpio irq handling. > also add patch for using edge select bit (irq raise/fall detection) on > imx.6 > > Regards > Johann > > -------------- next part -------------- > From b806dcf59ec3cf1abc18318cce090b78e396dec6 Mon Sep 17 00:00:00 2001 > From: Johann Obermayr <johann.obermayr@sigmatek.at> > Date: Fri, 18 Mar 2016 16:04:38 +0100 > Subject: [PATCH] high irq for GPIO input not working. > > --- > arch/arm/plat-mxc/gpio.c | 14 ++++++++++---- > 1 file changed, 10 insertions(+), 4 deletions(-) > > diff --git a/arch/arm/plat-mxc/gpio.c b/arch/arm/plat-mxc/gpio.c > index 87b643e..3f5925a 100755 > --- a/arch/arm/plat-mxc/gpio.c > +++ b/arch/arm/plat-mxc/gpio.c > @@ -426,9 +426,12 @@ void __ipipe_mach_enable_irqdesc(struct ipipe_domain *ipd, unsigned irq) > if (ipd != &ipipe_root) { > port->nonroot_gpios |= (1 << (gpio % 32)); > if (port->nonroot_gpios == (1 << (gpio % 32))) { > - __ipipe_irqbits[(port->irq / 32)] > - &= ~(1 << (port->irq % 32)); > + __ipipe_irqbits[(port->irq / 32)] &= ~(1 << (port->irq % 32)); > set_irq_prio(port->irq, 1); > + if (port->irq_high > 0) { > + __ipipe_irqbits[(port->irq_high / 32)] &= ~(1 << (port->irq_high % 32)); > + set_irq_prio(port->irq_high, 1); > + } > } > } > } else > @@ -450,8 +453,11 @@ void __ipipe_mach_disable_irqdesc(struct ipipe_domain *ipd, unsigned irq) > port->nonroot_gpios &= ~(1 << (gpio % 32)); > if (!port->nonroot_gpios) { > set_irq_prio(port->irq, 0); > - __ipipe_irqbits[(port->irq / 32)] > - |= (1 << (port->irq % 32)); > + __ipipe_irqbits[(port->irq / 32)] |= (1 << (port->irq % 32)); > + if (port->irq_high > 0) { > + set_irq_prio(port->irq_high, 0); > + __ipipe_irqbits[(port->irq_high / 32)] |= (1 << (port->irq_high % 32)); > + } > } > } > } else if (ipd != &ipipe_root) > -- > 1.7.9.5 I am fine with this patch. Will merge it in recent kernels if possible. > > -------------- next part -------------- > From 962417f6870aec76188f391a708fc05d54f6d94c Mon Sep 17 00:00:00 2001 > From: Johann Obermayr <johann.obermayr@sigmatek.at> > Date: Mon, 21 Mar 2016 17:14:18 +0100 > Subject: [PATCH] use edge select bit to activate raise/fall irq detection. > > --- > arch/arm/plat-mxc/gpio.c | 51 ++++++++++++++++++++++++++++++++-------------- > 1 file changed, 36 insertions(+), 15 deletions(-) > > diff --git a/arch/arm/plat-mxc/gpio.c b/arch/arm/plat-mxc/gpio.c > index 3f5925a..c1caa6b 100755 > --- a/arch/arm/plat-mxc/gpio.c > +++ b/arch/arm/plat-mxc/gpio.c > @@ -31,6 +31,7 @@ > > static struct mxc_gpio_port *mxc_gpio_ports; > static int gpio_table_size; > +static int GPIO_EDGE_SEL = -1; All capital names are reserved to macros. I am fine with this patch patch though I do not understand why it is needed, if Linux is able to detect both edges so should Xenomai with the same code. Also, if the patch is for the 3.0-imx6q branch, this branch has been abandoned a long time ago. The 3.0 kernel has been EOL for a long time now (last release dates back from october 2013). So, I do not plan to issue any new patches for this kernel. -- Gilles. https://click-hack.org ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2016-03-23 11:12 UTC | newest] Thread overview: 6+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2016-03-18 10:43 [Xenomai] ipipe bug in gpio/irq for mx6 Johann Obermayr 2016-03-18 11:10 ` Gilles Chanteperdrix 2016-03-18 12:15 ` Johann Obermayr 2016-03-18 12:28 ` Gilles Chanteperdrix 2016-03-23 11:01 ` Johann Obermayr 2016-03-23 11:12 ` Gilles Chanteperdrix
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.