[Xenomai] [PATCH] Add zynq-7000 rtdm gpio driver.

2017-12-03 Thread Greg Gallagher
From: Greg Gallagher 

---
 For the zynq platform (and possibly others in the future) we need to modify 
 gpio-core to request gpio pins before using them. The open() function will 
 now request a gpio and fail if it's already reserved. This should make 
 the pin request transparent to the user. The ability to request and release 
 pins is also available in an ioctrl message.  Tested on Microzed Zynq-7010 
 platform and the raspberry pi 2 board.

---
 include/rtdm/uapi/gpio.h|  2 +
 kernel/drivers/gpio/Kconfig |  8 
 kernel/drivers/gpio/Makefile|  1 +
 kernel/drivers/gpio/gpio-core.c | 87 +++--
 kernel/drivers/gpio/gpio-zynq7000.c | 40 +
 5 files changed, 116 insertions(+), 22 deletions(-)
 create mode 100644 kernel/drivers/gpio/gpio-zynq7000.c

diff --git a/include/rtdm/uapi/gpio.h b/include/rtdm/uapi/gpio.h
index f846f48..b745f15 100644
--- a/include/rtdm/uapi/gpio.h
+++ b/include/rtdm/uapi/gpio.h
@@ -22,6 +22,8 @@
 #define GPIO_RTIOC_DIR_IN  _IO(RTDM_CLASS_GPIO, 1)
 #define GPIO_RTIOC_IRQEN   _IOW(RTDM_CLASS_GPIO, 2, int) /* GPIO 
trigger */
 #define GPIO_RTIOC_IRQDIS  _IO(RTDM_CLASS_GPIO, 3)
+#define GPIO_RTIOC_REQS_IO(RTDM_CLASS_GPIO, 4)
+#define GPIO_RTIOC_RELS_IO(RTDM_CLASS_GPIO, 5)
 
 #define GPIO_TRIGGER_NONE  0x0 /* unspecified */
 #define GPIO_TRIGGER_EDGE_RISING   0x1
diff --git a/kernel/drivers/gpio/Kconfig b/kernel/drivers/gpio/Kconfig
index 869392f..81fc442 100644
--- a/kernel/drivers/gpio/Kconfig
+++ b/kernel/drivers/gpio/Kconfig
@@ -33,6 +33,14 @@ config XENO_DRIVERS_GPIO_SUN8I_H3
Suitable for the GPIO controller available from Allwinner's H3
SoC, as found on the NanoPI boards.
 
+config XENO_DRIVERS_GPIO_ZYNQ7000
+   depends on ARCH_ZYNQ
+   bool "Support for Zynq7000 GPIOs"
+   help
+
+   Enables support for the GPIO controller available from
+   Xilinx's Zynq7000 SoC.
+
 config XENO_DRIVERS_GPIO_DEBUG
bool "Enable GPIO core debugging features"
 
diff --git a/kernel/drivers/gpio/Makefile b/kernel/drivers/gpio/Makefile
index 35ca52c..7f28403 100644
--- a/kernel/drivers/gpio/Makefile
+++ b/kernel/drivers/gpio/Makefile
@@ -8,3 +8,4 @@ xeno_gpio-y := gpio-core.o
 xeno_gpio-$(CONFIG_XENO_DRIVERS_GPIO_BCM2835) += gpio-bcm2835.o
 xeno_gpio-$(CONFIG_XENO_DRIVERS_GPIO_MXC) += gpio-mxc.o
 xeno_gpio-$(CONFIG_XENO_DRIVERS_GPIO_SUN8I_H3) += gpio-sun8i-h3.o
+xeno_gpio-$(CONFIG_XENO_DRIVERS_GPIO_ZYNQ7000) += gpio-zynq7000.o
diff --git a/kernel/drivers/gpio/gpio-core.c b/kernel/drivers/gpio/gpio-core.c
index 55594f6..40e6993 100644
--- a/kernel/drivers/gpio/gpio-core.c
+++ b/kernel/drivers/gpio/gpio-core.c
@@ -36,7 +36,8 @@ struct rtdm_gpio_pin {
 struct rtdm_gpio_chan {
int requested : 1,
has_direction : 1,
-   is_output : 1 ;
+   is_output : 1,
+is_interrupt : 1;
 };
 
 static int gpio_pin_interrupt(rtdm_irq_t *irqh)
@@ -60,12 +61,16 @@ static int request_gpio_irq(unsigned int gpio, struct 
rtdm_gpio_pin *pin,
if (trigger & ~GPIO_TRIGGER_MASK)
return -EINVAL;
 
-   ret = gpio_request(gpio, pin->name);
-   if (ret) {
-   if (ret != -EPROBE_DEFER)
-   printk(XENO_ERR "cannot request GPIO%d\n", gpio);
-   return ret;
-   }
+if (!chan->requested) {
+ret = gpio_request(gpio, pin->name);
+   if (ret) {
+if (ret != -EPROBE_DEFER)
+printk(XENO_ERR 
+   "can not request GPIO%d\n", gpio);
+   return ret;
+}
+   chan->requested = true;
+}
 
ret = gpio_direction_input(gpio);
if (ret) {
@@ -99,13 +104,14 @@ static int request_gpio_irq(unsigned int gpio, struct 
rtdm_gpio_pin *pin,
goto fail;
}
 
-   chan->requested = true;
 
rtdm_irq_enable(>irqh);
+chan->is_interrupt = true;
 
return 0;
 fail:
gpio_free(gpio);
+chan->requested = false;
 
return ret;
 }
@@ -116,6 +122,7 @@ static void release_gpio_irq(unsigned int gpio, struct 
rtdm_gpio_pin *pin,
rtdm_irq_free(>irqh);
gpio_free(gpio);
chan->requested = false;
+chan->is_interrupt = false;
 }
 
 static int gpio_pin_ioctl_nrt(struct rtdm_fd *fd,
@@ -134,32 +141,47 @@ static int gpio_pin_ioctl_nrt(struct rtdm_fd *fd,
ret = rtdm_safe_copy_from_user(fd, , arg, sizeof(val));
if (ret)
return ret;
-   ret = gpio_direction_output(gpio, val);
-   if (ret == 0) {
-   chan->has_direction = true;
-   chan->is_output = true;
-   }
-   break;
+ret = 

[Xenomai] [PATCH] Split rtdm_fd_enter up, move the functionality where we store the fd until after the open() call succeeds. Calls where open() fail a fd is left in the tree even after the cleanup cod

2017-12-03 Thread Greg Gallagher
---
 include/cobalt/kernel/rtdm/fd.h |  2 ++
 kernel/cobalt/posix/mqueue.c|  7 ++-
 kernel/cobalt/posix/timerfd.c   |  4 
 kernel/cobalt/rtdm/core.c   | 12 +---
 kernel/cobalt/rtdm/fd.c | 24 
 5 files changed, 37 insertions(+), 12 deletions(-)

diff --git a/include/cobalt/kernel/rtdm/fd.h b/include/cobalt/kernel/rtdm/fd.h
index 086b04b..e504c0c 100644
--- a/include/cobalt/kernel/rtdm/fd.h
+++ b/include/cobalt/kernel/rtdm/fd.h
@@ -345,6 +345,8 @@ static inline int rtdm_fd_is_compat(const struct rtdm_fd 
*fd)
 int rtdm_fd_enter(struct rtdm_fd *rtdm_fd, int ufd,
  unsigned int magic, struct rtdm_fd_ops *ops);
 
+int rtdm_fd_register(struct rtdm_fd *fd, int ufd);
+
 struct rtdm_fd *rtdm_fd_get(int ufd, unsigned int magic);
 
 int rtdm_fd_lock(struct rtdm_fd *fd);
diff --git a/kernel/cobalt/posix/mqueue.c b/kernel/cobalt/posix/mqueue.c
index 6357d22..859e12e 100644
--- a/kernel/cobalt/posix/mqueue.c
+++ b/kernel/cobalt/posix/mqueue.c
@@ -267,6 +267,7 @@ static struct rtdm_fd_ops mqd_ops = {
 static inline int mqd_create(struct cobalt_mq *mq, unsigned long flags, int 
ufd)
 {
struct cobalt_mqd *mqd;
+   int ret;
 
if (cobalt_ppd_get(0) == _kernel_ppd)
return -EPERM;
@@ -278,7 +279,11 @@ static inline int mqd_create(struct cobalt_mq *mq, 
unsigned long flags, int ufd)
mqd->fd.oflags = flags;
mqd->mq = mq;
 
-   return rtdm_fd_enter(>fd, ufd, COBALT_MQD_MAGIC, _ops);
+   ret = rtdm_fd_enter(>fd, ufd, COBALT_MQD_MAGIC, _ops);
+   if (ret < 0)
+   return ret;
+
+   return rtdm_fd_register(>fd, ufd);
 }
 
 static int mq_open(int uqd, const char *name, int oflags,
diff --git a/kernel/cobalt/posix/timerfd.c b/kernel/cobalt/posix/timerfd.c
index 51e7605..217e68a 100644
--- a/kernel/cobalt/posix/timerfd.c
+++ b/kernel/cobalt/posix/timerfd.c
@@ -202,6 +202,10 @@ COBALT_SYSCALL(timerfd_create, lostage, (int clockid, int 
flags))
if (ret < 0)
goto fail;
 
+   ret = rtdm_fd_register(>fd, ufd);
+   if (ret < 0)
+   goto fail;
+
return ufd;
 fail:
xnselect_destroy(>read_select);
diff --git a/kernel/cobalt/rtdm/core.c b/kernel/cobalt/rtdm/core.c
index 05f273f..01d9caf 100644
--- a/kernel/cobalt/rtdm/core.c
+++ b/kernel/cobalt/rtdm/core.c
@@ -174,7 +174,7 @@ int __rtdm_dev_open(const char *path, int oflag)
 
context->fd.minor = dev->minor;
context->fd.oflags = oflag;
-
+   
trace_cobalt_fd_open(current, >fd, ufd, oflag);
 
if (dev->ops.open) {
@@ -185,9 +185,12 @@ int __rtdm_dev_open(const char *path, int oflag)
goto fail_open;
}
 
-   fd_install(ufd, filp);
-
trace_cobalt_fd_created(>fd, ufd);
+   ret = rtdm_fd_register(>fd, ufd);
+   if (ret < 0)
+   goto fail_open;
+
+   fd_install(ufd, filp);
 
return ufd;
 
@@ -238,6 +241,9 @@ int __rtdm_dev_socket(int protocol_family, int socket_type,
}
 
trace_cobalt_fd_created(>fd, ufd);
+   ret = rtdm_fd_register(>fd, ufd);
+   if (ret < 0)
+   goto fail_socket;
 
return ufd;
 
diff --git a/kernel/cobalt/rtdm/fd.c b/kernel/cobalt/rtdm/fd.c
index ffcd3aa..e355526 100644
--- a/kernel/cobalt/rtdm/fd.c
+++ b/kernel/cobalt/rtdm/fd.c
@@ -145,20 +145,13 @@ static inline void set_compat_bit(struct rtdm_fd *fd)
 int rtdm_fd_enter(struct rtdm_fd *fd, int ufd, unsigned int magic,
  struct rtdm_fd_ops *ops)
 {
-   struct rtdm_fd_index *idx;
struct cobalt_ppd *ppd;
-   spl_t s;
-   int ret;
-
+   
secondary_mode_only();
 
if (magic == 0)
return -EINVAL;
 
-   idx = kmalloc(sizeof(*idx), GFP_KERNEL);
-   if (idx == NULL)
-   return -ENOMEM;
-
assign_default_dual_handlers(ops->ioctl);
assign_default_dual_handlers(ops->read);
assign_default_dual_handlers(ops->write);
@@ -175,6 +168,21 @@ int rtdm_fd_enter(struct rtdm_fd *fd, int ufd, unsigned 
int magic,
fd->refs = 1;
set_compat_bit(fd);
 
+   return 0;
+}
+
+int rtdm_fd_register(struct rtdm_fd *fd, int ufd)
+{
+   struct rtdm_fd_index *idx;
+   struct cobalt_ppd *ppd;
+   spl_t s;
+   int ret = 0;
+
+   ppd = cobalt_ppd_get(0);
+   idx = kmalloc(sizeof(*idx), GFP_KERNEL);
+   if (idx == NULL)
+   return -ENOMEM;
+
idx->fd = fd;
 
xnlock_get_irqsave(_lock, s);
-- 
2.7.4


___
Xenomai mailing list
Xenomai@xenomai.org
https://xenomai.org/mailman/listinfo/xenomai