[U-Boot] [RFC PATCH] gpio: Add support for microblaze xilinx GPIO

Michal Simek monstr at monstr.eu
Mon Apr 29 10:56:28 CEST 2013


On 04/27/2013 05:45 PM, Simon Glass wrote:
> Hi Michal,
> 
> On Wed, Apr 24, 2013 at 1:27 AM, Michal Simek <michal.simek at xilinx.com> wrote:
>> Microblaze uses gpio which is connected to the system reset.
>> Currently gpio subsystem wasn't used for it.
>>
>> Add gpio driver and change Microblaze reset logic to be done
>> via gpio subsystem.
>>
>> There are various configurations which Microblaze can have
>> that's why gpio_alloc/gpio_alloc_dual(for dual channel)
>> function has been introduced and gpio can be allocated
>> dynamically.
>>
>> Adding several gpios IP is also possible and supported.
>>
>> For listing gpio configuration please use "gpio status" command
>>
>> Signed-off-by: Michal Simek <michal.simek at xilinx.com>
>> ---
>>  arch/microblaze/include/asm/gpio.h                 |  50 +---
>>  .../xilinx/microblaze-generic/microblaze-generic.c |  17 +-
>>  drivers/gpio/Makefile                              |   1 +
>>  drivers/gpio/xilinx_gpio.c                         | 323 +++++++++++++++++++++
>>  include/configs/microblaze-generic.h               |   3 +-
>>  5 files changed, 353 insertions(+), 41 deletions(-)
>>  create mode 100644 drivers/gpio/xilinx_gpio.c
>>
>> diff --git a/arch/microblaze/include/asm/gpio.h b/arch/microblaze/include/asm/gpio.h
>> index 883f4d4..69df8c5 100644
>> --- a/arch/microblaze/include/asm/gpio.h
>> +++ b/arch/microblaze/include/asm/gpio.h
>> @@ -1,41 +1,21 @@
>>  #ifndef _ASM_MICROBLAZE_GPIO_H_
>>  #define _ASM_MICROBLAZE_GPIO_H_
>>
>> -#include <asm/io.h>
>> +/* Allocation functions */
>> +extern int gpio_alloc_dual(u32 baseaddr, const char *name, u32 gpio_no0,
>> +                          u32 gpio_no1);
>> +extern int gpio_alloc(u32 baseaddr, const char *name, u32 gpio_no);
>> +
>> +/* Standard functions */
>> +extern int gpio_request(unsigned gpio, const char *label);
>> +extern int gpio_free(unsigned gpio);
>> +extern int gpio_direction_input(unsigned gpio);
>> +extern int gpio_direction_output(unsigned gpio, int value);
>> +extern int gpio_get_value(unsigned gpio);
>> +extern int gpio_set_value(unsigned gpio, int value);
>> +extern int gpio_is_valid(int number);
> 
> You should just be able to include <asm-generic/gpio.h> for these.

Thanks for pointing to this.

>> +/* Get gpio pin name if used/setup */
>> +static char *get_name(unsigned gpio)
>> +{
>> +       u32 gpio_priv;
>> +       debug("%s\n", __func__);
>> +
>> +       struct xilinx_gpio_priv *priv = gpio_get_controller(gpio);
> 
> It looks like gpio_get_controller() can return NULL, but you use it anyway?


yep. I have fixed that return path if gpio_get_controller returns NULL.


>> +
>> +int gpio_alloc(u32 baseaddr, const char *name, u32 gpio_no)
>> +{
>> +       struct xilinx_gpio_priv *priv;
>> +
>> +       priv = calloc(1, sizeof(struct xilinx_gpio_priv));
>> +
>> +       /* Setup gpio name */
>> +       if (name != NULL) {
>> +               strncpy(priv->name, name, GPIO_NAME_SIZE);
>> +               priv->name[GPIO_NAME_SIZE - 1] = '\0';
>> +       }
>> +       priv->regs = (struct gpio_regs *)baseaddr;
>> +
>> +       priv->gpio_min = xilinx_gpio_max;
>> +       xilinx_gpio_max = priv->gpio_min + gpio_no;
>> +       priv->gpio_max = xilinx_gpio_max - 1;
>> +
>> +       priv->gpio_name = calloc(gpio_no, sizeof(struct gpio_names));
>> +
>> +       INIT_LIST_HEAD(&priv->list);
>> +       list_add_tail(&priv->list, &gpio_list);
>> +
>> +       printf("%s: Add %s (%d-%d)\n", __func__, name,
>> +              priv->gpio_min, priv->gpio_max);
>> +
>> +       /* Return the first gpio allocated for this device */
>> +       return priv->gpio_min;
>> +}
> 
> In terms of allocation, is this function intended to tell the GPIO
> driver that there are new GPIOs available?

yep. That was my intention. Just call it from board file to tell
there are new gpios.


> For device tree the GPIO banks can be split into individual nodes each
> with the same compatible string. Then during device init you can build
> a table of available GPIOs. Each bank gets a phandle so that it can be
> used elsewhere. For example you might do:
> 
> gpio-controllers {
>    gpa: gpio-a {
>       compatible = "xilinx,gpio-controller";
>       reg = <some_address  size>;
>    };
>    gpb: gpio-b {
>       compatible = "xilinx,gpio-controller";
>       reg = <some_address  size>;
>    };
> };
> 
> example-peripheral {
>    gpios = <&gpa 5 ...>, <&gpb 6 ...>;
> };
> 
> The exact binding of GPIOs is up to you - use the same one as Linux if
> you have one there.

yep. I have designed these functions based on device-tree description
and to be able to use it for binding.

In general while loop over dts with compatible string to call this gpio_alloc
or gpio_alloc_dual based on properties.

Thanks,
Michal



-- 
Michal Simek, Ing. (M.Eng), OpenPGP -> KeyID: FE3D1F91
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel - Microblaze cpu - http://www.monstr.eu/fdt/
Maintainer of Linux kernel - Xilinx Zynq ARM architecture
Microblaze U-BOOT custodian and responsible for u-boot arm zynq platform


-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 263 bytes
Desc: OpenPGP digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20130429/69cf2006/attachment.pgp>


More information about the U-Boot mailing list