Hi
Is there anyone familiar with gpio-imx-rpmsg.c driver, { .compatible = "fsl,imx-rpmsg-gpio" }? Perhaps not, since it is demonstrated only with i.MX7ULP, forums search doesn't give a lot of hits.
Is that driver supposed to work with libgpiod? I'm using kernel 5.4.x. gpioget shell command works, gpioset command works as well , gpiomon doesn't work:
# gpiomon gpiochip8 16
gpiomon: error waiting for events: No such device
As well sysfs doesn't list "edge" file here
# echo 272 > /sys/class/gpio/export
# ls /sys/class/gpio/gpio272
active_low device power suppliers value
consumers direction subsystem uevent
"edge" is present with i.MX7D native GPIO driver:
# echo 176 > /sys/class/gpio/export
root@rcserv:~# ls /sys/class/gpio/gpio176
active_low device edge subsystem uevent
consumers direction power suppliers value
Thanks
Edward
Solved! Go to Solution.
Hi Igor,
Indeed it doesn't matter, libgpiod or sysfs+poll(). RPMSG GPIO interrupts are documented ... but not implemented.
gpio-imx-rpmsg.c\gpio\drivers - linux-imx - i.MX Linux kernel (codeaurora.org)
Here's RPMSG callback with TBD:
static int gpio_rpmsg_cb(struct rpmsg_device *rpdev,
void *data, int len, void *priv, u32 src)
{
struct gpio_rpmsg_data *msg = (struct gpio_rpmsg_data *)data;
if (msg->header.type == GPIO_RPMSG_REPLY) {
gpio_rpmsg.reply_msg = msg;
complete(&gpio_rpmsg.cmd_complete);
} else if (msg->header.type == GPIO_RPMSG_NOTIFY) {
gpio_rpmsg.notify_msg = msg;
/* TBD for interrupt handler */
} else
dev_err(&gpio_rpmsg.rpdev->dev, "wrong command type!\n");
return 0;
}
Replacing TBD with generic_handle_irq() with right arguments make interrupts working. Both libgpiod and sysfs.
Perhaps complete version of driver is lost somewhere? It's of course good to write documentation first and then implement according to documentation. But, hm, I'd prefer both complete and working :-). As I understand iMX7ULP EVK doesn't use RPMSG GPIO interrupts, buttons are used by RPMSG keyboard driver.
Regards
Edward
Hi Igor,
Indeed it doesn't matter, libgpiod or sysfs+poll(). RPMSG GPIO interrupts are documented ... but not implemented.
gpio-imx-rpmsg.c\gpio\drivers - linux-imx - i.MX Linux kernel (codeaurora.org)
Here's RPMSG callback with TBD:
static int gpio_rpmsg_cb(struct rpmsg_device *rpdev,
void *data, int len, void *priv, u32 src)
{
struct gpio_rpmsg_data *msg = (struct gpio_rpmsg_data *)data;
if (msg->header.type == GPIO_RPMSG_REPLY) {
gpio_rpmsg.reply_msg = msg;
complete(&gpio_rpmsg.cmd_complete);
} else if (msg->header.type == GPIO_RPMSG_NOTIFY) {
gpio_rpmsg.notify_msg = msg;
/* TBD for interrupt handler */
} else
dev_err(&gpio_rpmsg.rpdev->dev, "wrong command type!\n");
return 0;
}
Replacing TBD with generic_handle_irq() with right arguments make interrupts working. Both libgpiod and sysfs.
Perhaps complete version of driver is lost somewhere? It's of course good to write documentation first and then implement according to documentation. But, hm, I'd prefer both complete and working :-). As I understand iMX7ULP EVK doesn't use RPMSG GPIO interrupts, buttons are used by RPMSG keyboard driver.
Regards
Edward
to_irq is missing in the driver. With copy paste from other driver gpiomon seems waiting, proper RPMSG request seems being sent along with launch of gpiomon. Need to fix M4 part to make both parts working:
diff --git a/drivers/gpio/gpio-imx-rpmsg.c b/drivers/gpio/gpio-imx-rpmsg.c
index 418455f..4abbabb 100644
--- a/drivers/gpio/gpio-imx-rpmsg.c
+++ b/drivers/gpio/gpio-imx-rpmsg.c
@@ -310,6 +310,13 @@ static void imx_rpmsg_mask_irq(struct irq_data *d)
/* No need to implement the callback */
}
+static int imx_rpmsg_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
+{
+ struct imx_rpmsg_gpio_port *port = gpiochip_get_data(gc);
+
+ return irq_find_mapping(port->domain, offset);
+}
+
static struct irq_chip imx_rpmsg_irq_chip = {
.irq_mask = imx_rpmsg_mask_irq,
.irq_unmask = imx_rpmsg_unmask_irq,
@@ -337,6 +344,7 @@ static int imx_rpmsg_gpio_probe(struct platform_device *pdev)
gc = &port->gc;
gc->of_node = np;
gc->parent = dev;
+ gc->to_irq = imx_rpmsg_gpio_to_irq;
gc->label = "imx-rpmsg-gpio";
gc->ngpio = IMX_RPMSG_GPIO_PER_PORT;
gc->base = of_alias_get_id(np, "gpio") * IMX_RPMSG_GPIO_PER_PORT;
Edit: as well "edge" file is present using GPIO sysfs.
Edward
Hi Edward
thanks for sharing patch, you are right by default gpio-imx-rpmsg driver is not supposed to work with libgpiod.
Best regards
igor
Hi, @nxf77080
that patch above was only to fix missing interrupt `edge` file. See attached whole driver source file after additional mods. Interrupts and IO seem working well. Would be nice to get rid of static gpio_rpmsg struct, I've no time for it
Regards,
Edward
As a NXP employee you should know much better than me where to get examples for corresponding Cortex-M code. It was quite hard to get answer: get MCUXpresso SDK for i.MX7ULP.
Regards
Edward
Yep, have the SDK. Thought maybe you had made mods to the M4 side.
Thanks
Of course I had to shave tons of codes unsuitable for i.MX7D code, I can't share it.
GPIO interrupts already are implemented in SDK. Cortex-M GPIO interrupt handler includes SRTM_IoService_NotifyInputEvent() call. This call is used to signal GPIO interrupt over RPMSG. This works well with edge sensitive interrupts. Level sensitive interrupts should limit reporting rate, else RPMSG queue may overflow. It should be implemented on Cortex-M.
Edward
Thanks. I figured some rate limiting would have to be employed on the M4 side for level sensitive interrupts.
Best Regards,
Rob