cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
ykeastronaut
Visitor
Visitor
14,251 Views
Registered: ‎01-23-2015

GPIO issues with Linux version 3.17.0-xilinx

Jump to solution

Hi all.

 

I loaded the newest kernel 3.17.0-xilinx for the zynq 7010 board. When I tested  GPIO from /sys/class/gpio,It failed like this.

 

/tmp #  uname -a
Linux Zynq7000 3.17.0-xilinx #2 SMP PREEMPT Tue Jan 13 09:50:31 CST 2015 armv7l GNU/Linux

 

/tmp # cd /sys/class/gpio/


/sys/class/gpio # ls
export       gpiochip138      unexport

 

/sys/class/gpio # echo 1 > /sys/class/gpio/export
sh: write error: No such device

/sys/class/gpio #

         I checked kernel configuration items of GPIO in .Config file in the 3.17 kernel source. The GPIO related items were set well.

  • CONFIG_GPIO_SYSFS=y
  • CONFIG_SYSFS=y
  • CONFIG_GPIO_XILINX=y 

      When I use 3.12-xilinx kernel, every thing about gpio works well but It failed in 3.17 kernel.  I added the GPIO items below in the 3.17 device tree. But It didn`t work all the same when echo 11 <  /sys/class/gpio/export.

&gpio0 {
#gpio-cells = <2>;
clocks = <&clkc 42>;
compatible = "xlnx,zynq-gpio-1.0";
emio-gpio-width = <64>;
gpio-controller ;
gpio-mask-high = <0x0>;
gpio-mask-low = <0x5600>;
interrupt-parent = <&intc>;
interrupts = <0 20 4>;
reg = <0xe000a000 0x1000>;
};

    Is there anything wrong with my GPIO configuration? Thanks a lot.

0 Kudos
Reply
1 Solution

Accepted Solutions
norman_wong
Scholar
Scholar
22,356 Views
Registered: ‎05-28-2012

The dynamic allocation of GPIO numbers is a good idea but GPIO subsystem allocates from the top downwards. This will break a huge number of embedded systems that expects the old allocation from 0 upwards. It will be a issue with both kernel space and user space code. All the common userspace GPIO sysfs examples will now confuse and frustrate people.

Looks like there is a kernel space legacy mode for avoid breaking kernel code. Needs gpiolib-legacy.c to be compiled in. For now it appears to be compiled in with gpiolib.c. I suspect Legacy mode will be removed once all main line code is converted over to use the new GPIO system. The problem is that not everybody has their code checked into the main line.

No idea why the Linux kernel writers have strongly imposed this change. I'd expect this sort of thing from closed systems but Linux is open source. I can change it.

----drivers/gpio/gpio-zynq.c----
static int zynq_gpio_probe(struct platform_device *pdev)
{
  ...
  chip->base = 0; //<----- Using -1 results in a base of 138.
  ...
}

Perhaps Xilinx could change the gpio-zynq.c code to allow the base to be specified by the device tree.

 

View solution in original post

0 Kudos
Reply
22 Replies
achutha
Xilinx Employee
Xilinx Employee
14,239 Views
Registered: ‎07-01-2010
Can you share the dts file and mss file?
Can you re-check if the dts mapping for gpio is correct?

Also refer to the wiki page for details.
http://www.wiki.xilinx.com/Linux+GPIO+Driver

Regards,
Achutha
---------------------------------------------------------------------------------------------
Kindly note- Please mark the Answer as "Accept as solution" if information provided is helpful.

Give Kudos to a post which you think is helpful and reply oriented.
----------------------------------------------------------------------------------------
0 Kudos
Reply
linnj
Xilinx Employee
Xilinx Employee
14,216 Views
Registered: ‎09-10-2008

Hi,

 

Based on my testing there's nothing wrong that you did, the GPIOs seem to be moving around with regard to where they start. They now start at 138 instead of 1 like they used to.  I was able to use the GPIOs with my limited testing with these new numbers.

 

It would be nice if we could prevent this problem with the kernel as it is a pain.

 

Thanks

John

0 Kudos
Reply
ykeastronaut
Visitor
Visitor
14,198 Views
Registered: ‎01-23-2015

Hi  

 

Thanks for your help!  The attachment is our dts. GPIOs still can`t work (echo 11 < /sys/class/gpio/export) with or without the following GPIO-related configuration items in the dts.

&gpio0 {
#gpio-cells = <2>;
clocks = <&clkc 42>;
compatible = "xlnx,zynq-gpio-1.0";
emio-gpio-width = <64>;
gpio-controller ;
gpio-mask-high = <0x0>;
gpio-mask-low = <0x5600>;
interrupt-parent = <&intc>;
interrupts = <0 20 4>;
reg = <0xe000a000 0x1000>;
}; 

 

As 

 

0 Kudos
Reply
ykeastronaut
Visitor
Visitor
14,197 Views
Registered: ‎01-23-2015
Thanks.

You are right Linnj. Now GPIOs start at 138 instead of 0 as they used to. How could we change to restore the original start number?
0 Kudos
Reply
sorenb
Xilinx Employee
Xilinx Employee
14,186 Views
Registered: ‎03-13-2012

Apparently there is not much one can do about it other than rewriting the whole userspace interface for GPIOs: https://lkml.org/lkml/2014/7/7/390

0 Kudos
Reply
norman_wong
Scholar
Scholar
14,175 Views
Registered: ‎05-28-2012

I think that behaviour crept in in 2014.4/3.7 with a commit by Harini Katakam on Jul 10, 2014. That commit changed the GPIO base from a static value of 0 to a dynamic one offset. That eventually calculates out to 138.

----drivers/gpio/gpio-zynq.c----
static int zynq_gpio_probe(struct platform_device *pdev)
{
  ...
  chip->base = -1; //<----- was 0 in 2014.2/3.14 and 2014.3/3.15, -1 means find a base for me.
  chip->ngpio = ZYNQ_GPIO_NR_GPIOS;
  ...
  ret = gpiochip_add(chip);
  ...
}

----include/asm-generic/gpio.h
#define ARCH_NR_GPIOS    256

----drivers/gpio/gpio-zynq.c
#define ZYNQ_GPIO_BANK0_NGPIO 32
#define ZYNQ_GPIO_BANK1_NGPIO 22
#define ZYNQ_GPIO_BANK2_NGPIO 32
#define ZYNQ_GPIO_BANK3_NGPIO 32
#define ZYNQ_GPIO_NR_GPIOS (ZYNQ_GPIO_BANK0_NGPIO + \
  ZYNQ_GPIO_BANK1_NGPIO + \
  ZYNQ_GPIO_BANK2_NGPIO + \
  ZYNQ_GPIO_BANK3_NGPIO) //<----------- ZYNQ_GPIO_NR_GPIOS = 118

----/drivers/gpio/gpiolib.c
int gpiochip_add(struct gpio_chip *chip)
{
  ...
  int base = chip->base;
  ...
  if (base < 0) {
    base = gpiochip_find_base(chip->ngpio);
  ...
}

----/drivers/gpio/gpiolib.c
static int gpiochip_find_base(int ngpio)
{
  struct gpio_chip *chip;
  int base = ARCH_NR_GPIOS - ngpio; <--------- 256-118 = 138
  ...
}

 

Tags (1)
0 Kudos
Reply
sorenb
Xilinx Employee
Xilinx Employee
14,169 Views
Registered: ‎03-13-2012

It didn't really "creep in". That change was requested and is how the GPIO subsystem works (https://lkml.org/lkml/2014/3/28/455 )

0 Kudos
Reply
norman_wong
Scholar
Scholar
22,357 Views
Registered: ‎05-28-2012

The dynamic allocation of GPIO numbers is a good idea but GPIO subsystem allocates from the top downwards. This will break a huge number of embedded systems that expects the old allocation from 0 upwards. It will be a issue with both kernel space and user space code. All the common userspace GPIO sysfs examples will now confuse and frustrate people.

Looks like there is a kernel space legacy mode for avoid breaking kernel code. Needs gpiolib-legacy.c to be compiled in. For now it appears to be compiled in with gpiolib.c. I suspect Legacy mode will be removed once all main line code is converted over to use the new GPIO system. The problem is that not everybody has their code checked into the main line.

No idea why the Linux kernel writers have strongly imposed this change. I'd expect this sort of thing from closed systems but Linux is open source. I can change it.

----drivers/gpio/gpio-zynq.c----
static int zynq_gpio_probe(struct platform_device *pdev)
{
  ...
  chip->base = 0; //<----- Using -1 results in a base of 138.
  ...
}

Perhaps Xilinx could change the gpio-zynq.c code to allow the base to be specified by the device tree.

 

View solution in original post

0 Kudos
Reply
sorenb
Xilinx Employee
Xilinx Employee
14,151 Views
Registered: ‎03-13-2012

The driver is upstream. And as you can see, upstream requires usage of dynamic allocation of the GPIO numbers.

The DT property you suggest would describe SW and not the HW. I.e. such a property would never be accepted upstream.

0 Kudos
Reply
ykeastronaut
Visitor
Visitor
11,230 Views
Registered: ‎01-23-2015

 

 

0 Kudos
Reply
norman_wong
Scholar
Scholar
11,229 Views
Registered: ‎05-28-2012

Some discussion about a bottom up GPIO number allocation here:

http://www.spinics.net/lists/linux-gpio/msg02945.html
Add find GPIO base in increasing order

I think that the top down allocation is for temporary plug'n'play GPIO peripherals. Implied is that one permanent GPIO peripheral is reserved a base of 0. With the Zynq, the on chip GPIO controller could be considered permanent. Unlikely that the Zynq GPIO controller could ever be considered plug'n'play. Lot of other GPIO drivers still retain a base of 0.

 

I've got no irons in this fire. My project has frozen the kernel version at 2014.3. As long as Vivado doesn't force an upgrade, it will stay at that version.

0 Kudos
Reply
tnjames
Observer
Observer
11,124 Views
Registered: ‎07-08-2013

We too have been caught out by this change, noting that using the latest kernel code from https://github.com/Xilinx/linux-xlnx there is now space for 1024 GPIO defined so first GPIO is now gpio906!  We initially tried forcing the first GPIO to be GPIO 0 as in post 8 and although this seemed to work as far as getting /sys/class/gpio/gpiochip0 back everything seemed to go catastrophically wrong as soon as the first interrupt came in; a new interrupt source appeared in /proc/interrupts with the interrupt count in free-fall.

 

Having given up trying to fix the index of the first GPIO we tried instead to simply modify the ARCH_NR_GPIO value using the following patch to limit the number of system GPIO to 118 so the first interrupt ends up back at 0.  Touchwood this seems to work, with GPIO starting at zero and with interrupts working.

 

--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1501,7 +1501,7 @@
 # selected platforms.
 config ARCH_NR_GPIO
 	int
-	default 1024 if ARCH_SHMOBILE || ARCH_TEGRA || ARCH_ZYNQ
+	default 1024 if ARCH_SHMOBILE || ARCH_TEGRA
 	default 512 if ARCH_EXYNOS || ARCH_KEYSTONE || SOC_OMAP5 || \
 		SOC_DRA7XX || ARCH_S3C24XX || ARCH_S3C64XX || ARCH_S5PV210
 	default 416 if ARCH_SUNXI
@@ -1509,6 +1509,7 @@
 	default 352 if ARCH_VT8500
 	default 288 if ARCH_ROCKCHIP
 	default 264 if MACH_H4700
+	default 118 if ARCH_ZYNQ
 	default 0
 	help
 	  Maximum number of GPIOs in the system.
@@ -1708,7 +1709,7 @@
 source "mm/Kconfig"
 

 

We will probably end up trying to update our applications to find the GPIO base at runtime by looking for /sys/class/gpio/gpiochipXXX but the patch above hopefully provides a 'quick fix'.

 

0 Kudos
Reply
linnj
Xilinx Employee
Xilinx Employee
11,122 Views
Registered: ‎09-10-2008
Xilinx is making this change to the Xilinx tree also so it should be back to normal on the next release.
0 Kudos
Reply
sorenb
Xilinx Employee
Xilinx Employee
11,112 Views
Registered: ‎03-13-2012

That change would break GPIO expanders.

0 Kudos
Reply
linnj
Xilinx Employee
Xilinx Employee
11,108 Views
Registered: ‎09-10-2008

Hi Soren,

 

Ah I didn't notice the 2nd line, I was only thinking of the 1st line in the change.

 

http://lists.infradead.org/pipermail/linux-arm-kernel/2015-January/316449.html

 

Thanks

John

0 Kudos
Reply
linnj
Xilinx Employee
Xilinx Employee
11,107 Views
Registered: ‎09-10-2008
I guess I need glasses as that was removing the line :( that I was thinking was being added.

Sorry for adding confusion.
0 Kudos
Reply
tnjames
Observer
Observer
11,094 Views
Registered: ‎07-08-2013

I agree, our patch only works if you are only using the PS's MIO and EMIO GPIO and I shared it as a quick/temporary workaround (that didn't result in a runaway interrupt condition) rather than a serious long-term change.

0 Kudos
Reply
justinlh
Explorer
Explorer
9,504 Views
Registered: ‎02-18-2014

All this being said, how do we go about identifying where the gpio range is? I appear to be struggling finding exactly which gpio to associate with my gpio 15 im accustom to using.

 

I've tried the 138 + 15 pin, which returns that it doesn't exist. But i found a range in the 837+ pin range that allows me to create sys/class/gpio/gpioXXX paths? More clarity would be helpful.

0 Kudos
Reply
norman_wong
Scholar
Scholar
9,450 Views
Registered: ‎05-28-2012

1) Calc with older kernel limits
 ARCH_NR_GPIOS = 256
 ZYNQ_GPIO_NR_GPIOS = 118
 base = ARCH_NR_GPIOS - ZYNQ_GPIO_NR_GPIOS = 256 - 118 = 138

2) Calc with newer kernel limits
 ARCH_NR_GPIOS = 1024
 ZYNQ_GPIO_NR_GPIOS = 118
 base = ARCH_NR_GPIOS - ZYNQ_GPIO_NR_GPIOS = 1024 - 118 = 906

3) Reverse calc with your observed numbers.
 base = 837
 ARCH_NR_GPIOS = 1024
 allocated = ARCH_NR_GPIOS - base = 1024 - 837 = 187
The number of MIOS and EMIOS is always
 ZYNQ_GPIO_NR_GPIOS = 118
That suggests 187 - 118 = 69 other GPIOs. Do you have a GPIO expander or GPIOs in PL?

Try looking at the files for each GPIO contoller
 /sys/class/gpio/gpiochipN/base
 /sys/class/gpio/gpiochipN/label
 /sys/class/gpio/gpiochipN/ngpio

0 Kudos
Reply
justinlh
Explorer
Explorer
7,211 Views
Registered: ‎02-18-2014

Yes we have other GPIO's in the Pl logic as well. Those however im just using mmap which has worked great so far. The only reason so far im attempting to use the kernel gpio driver (/sys/class/gpio) interface is because im attempting to accesses my PS Gpio's.

 

So in your example at step 3, would that make the following make sense?

 

base = 837

ARCH_NR_GPIOS =1024

other GPIO's = 69 (this number would change as we add or subtract pl gpios)

 

gpio 15 = base + other gpios(my offset)+ 15(my index)??

gpio 15 = 837 + 69 + 15 = 921??

 

 

Now with regards to your GPIO controllers that your specifing. When i bootup i get several gpio controllers following the format you describe, how do i determine which one correlats to the gpios i care about with regards to this?

 

The controllers i get are:

gpiochip829

gpiochip853

gpiochip883

gpiochip906

 

 

Thanks for the help

0 Kudos
Reply
justinlh
Explorer
Explorer
7,208 Views
Registered: ‎02-18-2014

I went ahead and added that above offset to my code... and it worked the first try. Thanks for the help!

 

Any idea where our base value of 837 came from? it seems different then the norm.

0 Kudos
Reply
norman_wong
Scholar
Scholar
7,172 Views
Registered: ‎05-28-2012

Some guesses from doing a reverse calc from info in your last post. The GPIO controllers will allocated GPIOS ranges from top down in the order that they are started.

ARCH_NR_GPIOS = 1024
ZYNQ_GPIO_NR_GPIOS = 118
base = ARCH_NR_GPIOS - ZYNQ_GPIO_NR_GPIOS = 1024 - 118 = 906
Should results in these file contents.
/sys/class/gpio/gpiochip906/base = 906
/sys/class/gpio/gpiochip906/label = "Something Xilinxy I would hope"
/sys/class/gpio/gpiochip906/ngpio = 118

ARCH_NR_GPIOS = 906
CHIP_A_NR_GPIOS = 23
base = ARCH_NR_GPIOS - CHIP_A_NR_GPIOS = 906- 23 = 883
Should results in these file contents.
/sys/class/gpio/gpiochip883/base = 883
/sys/class/gpio/gpiochip883/label = ?
/sys/class/gpio/gpiochip883/ngpio = 23

ARCH_NR_GPIOS = 883
CHIP_B_NR_GPIOS = 30
base = ARCH_NR_GPIOS - CHIP_B_NR_GPIOS = 883- 30 = 853
Should results in these file contents.
/sys/class/gpio/gpiochip853/base = 853
/sys/class/gpio/gpiochip853/label = ?
/sys/class/gpio/gpiochip853/ngpio = 30

ARCH_NR_GPIOS = 853
CHIP_C_NR_GPIOS = 24
base = ARCH_NR_GPIOS - CHIP_C_NR_GPIOS = 853- 24 = 829
Should results in these file contents.
/sys/class/gpio/gpiochip829/base = 829
/sys/class/gpio/gpiochip829/label = ?
/sys/class/gpio/gpiochip829/ngpio = 24

So GPIO 921 would be in the range of the first controller. The offset would then be 921-906 or GPIO 15 within that controller.

GPIO 837 would be GPIO 8 (837-829) in the last controller. You should be able to export down to GPIO 829. Perhaps the first 8 GPIOs on the last controller have already been allocated by a driver.

 

In theory, a GPIO sysfs user space library could be written to search the gpiochip libraries for the desired "label" file and read the appropriate "base" file for the base + offset calc. Avoids hard-coding the base number. Would have been so much easier if they did not mess with it in the first place.

 

0 Kudos
Reply