dm: gpio: MPC85XX GPIO platform data support
authorHamish Martin <hamish.martin@alliedtelesis.co.nz>
Mon, 13 Jun 2016 22:17:05 +0000 (10:17 +1200)
committerSimon Glass <sjg@chromium.org>
Mon, 11 Jul 2016 20:06:44 +0000 (14:06 -0600)
Define a platform data structure for the MPC85XX GPIO driver to allow
use of the driver without device tree. Users should define the GPIO
blocks for their platform like this:
  struct mpc85xx_gpio_plat gpio_blocks[] = {
         {
                 .addr = 0x130000,
                 .ngpios = 32,
         },
         {
                 .addr = 0x131000,
                 .ngpios = 32,
         },
  };

  U_BOOT_DEVICES(my_platform_gpios) = {
         { "gpio_mpc85xx", &gpio_blocks[0] },
         { "gpio_mpc85xx", &gpio_blocks[1] },
  };

This is intended to build upon the recent submission of the base
MPC85XX driver from Mario Six. We need to use that new driver
without dts support and this patch gives us that flexibility.
This has been tested on a Freescale T2080 CPU, although only the first
GPIO block.

Signed-off-by: Hamish Martin <hamish.martin@alliedtelesis.co.nz>
Reviewed-by: Mario Six <mario.six@gdsys.cc>
Tested-by: Mario Six <mario.six@gdsys.cc>
Acked-by: Simon Glass <sjg@chromium.org>
arch/powerpc/include/asm/arch-mpc85xx/gpio.h
drivers/gpio/mpc85xx_gpio.c

index 41b6677bba38836bc4a29381f0f193380f66266a..76faa22c8b437012ce9bbd72fde83e3c686e5736 100644 (file)
 #include <asm/mpc85xx_gpio.h>
 #endif
 
+struct mpc85xx_gpio_plat {
+       ulong addr;
+       unsigned long size;
+       uint ngpios;
+};
+
 #endif
index 04773e2b31c3074e322dff41debfb5bc63522f4f..3754a8215c3630db7c33cc50a13eff8959fa6b04 100644 (file)
@@ -163,23 +163,41 @@ static int mpc85xx_gpio_get_function(struct udevice *dev, unsigned gpio)
        return dir ? GPIOF_OUTPUT : GPIOF_INPUT;
 }
 
+#if CONFIG_IS_ENABLED(OF_CONTROL)
 static int mpc85xx_gpio_ofdata_to_platdata(struct udevice *dev) {
-       struct mpc85xx_gpio_data *data = dev_get_priv(dev);
+       struct mpc85xx_gpio_plat *plat = dev_get_platdata(dev);
        fdt_addr_t addr;
        fdt_size_t size;
 
        addr = fdtdec_get_addr_size_auto_noparent(gd->fdt_blob, dev->of_offset,
                                                  "reg", 0, &size);
 
-       data->addr = addr;
-       data->base = map_sysmem(CONFIG_SYS_IMMR + addr, size);
+       plat->addr = addr;
+       plat->size = size;
+       plat->ngpios = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
+                                                 "ngpios", 32);
 
-       if (!data->base)
+       return 0;
+}
+#endif
+
+static int mpc85xx_gpio_platdata_to_priv(struct udevice *dev)
+{
+       struct mpc85xx_gpio_data *priv = dev_get_priv(dev);
+       struct mpc85xx_gpio_plat *plat = dev_get_platdata(dev);
+       unsigned long size = plat->size;
+
+       if (size == 0)
+               size = 0x100;
+
+       priv->addr = plat->addr;
+       priv->base = map_sysmem(CONFIG_SYS_IMMR + plat->addr, size);
+
+       if (!priv->base)
                return -ENOMEM;
 
-       data->gpio_count = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
-                                         "ngpios", 32);
-       data->dat_shadow = 0;
+       priv->gpio_count = plat->ngpios;
+       priv->dat_shadow = 0;
 
        return 0;
 }
@@ -190,6 +208,8 @@ static int mpc85xx_gpio_probe(struct udevice *dev)
        struct mpc85xx_gpio_data *data = dev_get_priv(dev);
        char name[32], *str;
 
+       mpc85xx_gpio_platdata_to_priv(dev);
+
        snprintf(name, sizeof(name), "MPC@%lx_", data->addr);
        str = strdup(name);
 
@@ -221,8 +241,11 @@ U_BOOT_DRIVER(gpio_mpc85xx) = {
        .name   = "gpio_mpc85xx",
        .id     = UCLASS_GPIO,
        .ops    = &gpio_mpc85xx_ops,
+#if CONFIG_IS_ENABLED(OF_CONTROL)
        .ofdata_to_platdata = mpc85xx_gpio_ofdata_to_platdata,
+       .platdata_auto_alloc_size = sizeof(struct mpc85xx_gpio_plat),
        .of_match = mpc85xx_gpio_ids,
+#endif
        .probe  = mpc85xx_gpio_probe,
        .priv_auto_alloc_size = sizeof(struct mpc85xx_gpio_data),
 };