On 04/27/2013 05:45 PM, Simon Glass wrote: > Hi Michal, > > On Wed, Apr 24, 2013 at 1:27 AM, Michal Simek <michal.si...@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.si...@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
signature.asc
Description: OpenPGP digital signature
_______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot