From mboxrd@z Thu Jan 1 00:00:00 1970 From: Michal Simek Date: Mon, 29 Apr 2013 10:56:28 +0200 Subject: [U-Boot] [RFC PATCH] gpio: Add support for microblaze xilinx GPIO In-Reply-To: References: <0a7e4804d681b0a73f0d40a37c326420e888b9ea.1366792065.git.michal.simek@xilinx.com> Message-ID: <517E35BC.2040000@monstr.eu> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de On 04/27/2013 05:45 PM, Simon Glass wrote: > Hi Michal, > > On Wed, Apr 24, 2013 at 1:27 AM, Michal Simek 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 >> --- >> 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 >> +/* 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 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 = ; > }; > gpb: gpio-b { > compatible = "xilinx,gpio-controller"; > reg = ; > }; > }; > > 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: