[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