Instead of having x86-pinctrl work separately from ich6-gpio have it
work underneath ich6-gpio. This removes redundant configuration and will
allow the addition of shared bank settings in future commits.

Signed-off-by: George McCollister <george.mccollis...@gmail.com>
---
 arch/x86/dts/minnowmax.dts                         |  96 +++++++++---------
 arch/x86/include/asm/gpio.h                        |   1 -
 board/intel/minnowmax/minnowmax.c                  |   9 +-
 doc/device-tree-bindings/gpio/intel,ich6-gpio.txt  |  14 +++
 .../gpio/intel,x86-pinctrl.txt                     |  17 ++--
 drivers/gpio/intel_ich6_gpio.c                     | 107 ++++++++-------------
 6 files changed, 118 insertions(+), 126 deletions(-)
 create mode 100644 doc/device-tree-bindings/gpio/intel,ich6-gpio.txt

diff --git a/arch/x86/dts/minnowmax.dts b/arch/x86/dts/minnowmax.dts
index e917f0f..79ac26d 100644
--- a/arch/x86/dts/minnowmax.dts
+++ b/arch/x86/dts/minnowmax.dts
@@ -26,54 +26,6 @@
                silent_console = <0>;
        };
 
-       pch_pinctrl {
-               compatible = "intel,x86-pinctrl";
-               io-base = <0x4c>;
-
-               /* GPIO E0 */
-               soc_gpio_s5_0@0 {
-                       gpio-offset = <0x80 0>;
-                       pad-offset = <0x1d0>;
-                       mode-gpio;
-                       output-value = <0>;
-                       direction = <PIN_OUTPUT>;
-               };
-
-               /* GPIO E1 */
-               soc_gpio_s5_1@0 {
-                       gpio-offset = <0x80 1>;
-                       pad-offset = <0x210>;
-                       mode-gpio;
-                       output-value = <0>;
-                       direction = <PIN_OUTPUT>;
-               };
-
-               /* GPIO E2 */
-               soc_gpio_s5_2@0 {
-                       gpio-offset = <0x80 2>;
-                       pad-offset = <0x1e0>;
-                       mode-gpio;
-                       output-value = <0>;
-                       direction = <PIN_OUTPUT>;
-               };
-
-               pin_usb_host_en0@0 {
-                       gpio-offset = <0x80 8>;
-                       pad-offset = <0x260>;
-                       mode-gpio;
-                       output-value = <1>;
-                       direction = <PIN_OUTPUT>;
-               };
-
-               pin_usb_host_en1@0 {
-                       gpio-offset = <0x80 9>;
-                       pad-offset = <0x250>;
-                       mode-gpio;
-                       output-value = <1>;
-                       direction = <PIN_OUTPUT>;
-               };
-       };
-
        gpioa {
                compatible = "intel,ich6-gpio";
                u-boot,dm-pre-reloc;
@@ -107,6 +59,54 @@
                u-boot,dm-pre-reloc;
                reg = <0x80 0x20>;
                bank-name = "E";
+
+               pch_pinctrl@0 {
+                       compatible = "intel,x86-pinctrl";
+                       io-base = <0x4c>;
+
+                       /* GPIO E0 */
+                       soc_gpio_s5_0@0 {
+                               gpio-offset = <0>;
+                               pad-offset = <0x1d0>;
+                               mode-gpio;
+                               output-value = <0>;
+                               direction = <PIN_OUTPUT>;
+                       };
+
+                       /* GPIO E1 */
+                       soc_gpio_s5_1@0 {
+                               gpio-offset = <1>;
+                               pad-offset = <0x210>;
+                               mode-gpio;
+                               output-value = <0>;
+                               direction = <PIN_OUTPUT>;
+                       };
+
+                       /* GPIO E2 */
+                       soc_gpio_s5_2@0 {
+                               gpio-offset = <2>;
+                               pad-offset = <0x1e0>;
+                               mode-gpio;
+                               output-value = <0>;
+                               direction = <PIN_OUTPUT>;
+                       };
+
+                       pin_usb_host_en0@0 {
+                               gpio-offset = <8>;
+                               pad-offset = <0x260>;
+                               mode-gpio;
+                               output-value = <1>;
+                               direction = <PIN_OUTPUT>;
+                       };
+
+                       pin_usb_host_en1@0 {
+                               gpio-offset = <9>;
+                               pad-offset = <0x250>;
+                               mode-gpio;
+                               output-value = <1>;
+                               direction = <PIN_OUTPUT>;
+                       };
+               };
        };
 
        gpiof {
diff --git a/arch/x86/include/asm/gpio.h b/arch/x86/include/asm/gpio.h
index ed85b08..1099427 100644
--- a/arch/x86/include/asm/gpio.h
+++ b/arch/x86/include/asm/gpio.h
@@ -147,7 +147,6 @@ struct pch_gpio_map {
        } set3;
 };
 
-int gpio_ich6_pinctrl_init(void);
 void setup_pch_gpios(u16 gpiobase, const struct pch_gpio_map *gpio);
 void ich_gpio_set_gpio_map(const struct pch_gpio_map *map);
 
diff --git a/board/intel/minnowmax/minnowmax.c 
b/board/intel/minnowmax/minnowmax.c
index 44e5bf4..ae06cc4 100644
--- a/board/intel/minnowmax/minnowmax.c
+++ b/board/intel/minnowmax/minnowmax.c
@@ -5,12 +5,17 @@
  */
 
 #include <common.h>
+#include <dm.h>
 #include <asm/gpio.h>
 
 int arch_early_init_r(void)
 {
-       /* do the pin-muxing */
-       gpio_ich6_pinctrl_init();
+       struct udevice *dev;
+
+       /* Force initialization of gpio so initial states are set correctly. */
+       for (uclass_first_device(UCLASS_GPIO, &dev);
+            dev;
+            uclass_next_device(&dev));
 
        return 0;
 }
diff --git a/doc/device-tree-bindings/gpio/intel,ich6-gpio.txt 
b/doc/device-tree-bindings/gpio/intel,ich6-gpio.txt
new file mode 100644
index 0000000..23345b2
--- /dev/null
+++ b/doc/device-tree-bindings/gpio/intel,ich6-gpio.txt
@@ -0,0 +1,14 @@
+Intel x86 GPIO controller
+
+Each GPIO bank node can have the following properties:
+- compatible          - (required) must be set to "intel,x86-pinctrl"
+- reg                 - (required) GPIO offset and length.
+- bank-name           - (required) Name of the bank.
+
+Example:
+gpioa {
+       compatible = "intel,ich6-gpio";
+       u-boot,dm-pre-reloc;
+       reg = <0 0x20>;
+       bank-name = "A";
+};
diff --git a/doc/device-tree-bindings/gpio/intel,x86-pinctrl.txt 
b/doc/device-tree-bindings/gpio/intel,x86-pinctrl.txt
index 45ab1af..eb9c8da 100644
--- a/doc/device-tree-bindings/gpio/intel,x86-pinctrl.txt
+++ b/doc/device-tree-bindings/gpio/intel,x86-pinctrl.txt
@@ -1,7 +1,7 @@
-Intel x86 PINCTRL/GPIO controller
+Intel x86 PINCTRL
 
-Pin-muxing on x86 can be described with a node for the PINCTRL master
-node and a set of child nodes for each pin on the SoC.
+Pin-muxing on x86 can be described under each GPIO bank with a node for the
+PINCTRL master node and a set of child nodes for each pin on the SoC.
 
 The PINCTRL master node requires the following properties:
 - compatible : "intel,x86-pinctrl"
@@ -9,13 +9,12 @@ The PINCTRL master node requires the following properties:
 Pin nodes must be children of the pinctrl master node and can
 contain the following properties:
 - pad-offset        - (required) offset in the IOBASE for the pin to 
configured.
-- gpio-offset       - (required) offset in the GPIOBASE for the pin to 
configured and
-                                       also the bit shift in this register.
-- mode-gpio                    - (optional) standalone property to force the 
pin into GPIO mode.
-- mode-func                    - (optional) function number to assign to the 
pin. if 'mode-gpio'
+- gpio-offset       - (required) bit shift in the GPIO register.
+- mode-gpio         - (optional) standalone property to force the pin into 
GPIO mode.
+- mode-func         - (optional) function number to assign to the pin. if 
'mode-gpio'
                                        is set, this property will be ignored.
 in case of 'mode-gpio' property set:
-- output-value         - (optional) this set the default output value of the 
GPIO.
+- output-value      - (optional) this set the default output value of the GPIO.
 - direction         - (optional) this set the direction of the gpio.
 - pull-str          - (optional) this set the pull strength of the pin.
 - pull-assign       - (optional) this set the pull assignement (up/down) of 
the pin.
@@ -23,7 +22,7 @@ in case of 'mode-gpio' property set:
 Example:
 
 pin_usb_host_en0@0 {
-    gpio-offset = <0x80 8>;
+    gpio-offset = <8>;
     pad-offset = <0x260>;
     mode-gpio;
     output-value = <1>;
diff --git a/drivers/gpio/intel_ich6_gpio.c b/drivers/gpio/intel_ich6_gpio.c
index 67bf0a2..18420f3 100644
--- a/drivers/gpio/intel_ich6_gpio.c
+++ b/drivers/gpio/intel_ich6_gpio.c
@@ -41,15 +41,11 @@ DECLARE_GLOBAL_DATA_PTR;
 
 struct ich6_bank_priv {
        /* These are I/O addresses */
-       uint16_t use_sel;
-       uint16_t io_sel;
-       uint16_t lvl;
+       u16 use_sel;
+       u16 io_sel;
+       u16 lvl;
 };
 
-#define GPIO_USESEL_OFFSET(x)  (x)
-#define GPIO_IOSEL_OFFSET(x)   (x + 4)
-#define GPIO_LVL_OFFSET(x)     (x + 8)
-
 #define IOPAD_MODE_MASK                                0x7
 #define IOPAD_PULL_ASSIGN_SHIFT                7
 #define IOPAD_PULL_ASSIGN_MASK         (0x3 << IOPAD_PULL_ASSIGN_SHIFT)
@@ -147,92 +143,90 @@ static int gpio_ich6_get_base(unsigned long base)
        return tmplong & 1 ? tmplong & ~3 : tmplong & ~15;
 }
 
-static int _ich6_gpio_set_value(uint16_t base, unsigned offset, int value)
+
+static int ich6_gpio_set_value(struct udevice *dev, unsigned offset,
+                              int value)
 {
+       struct ich6_bank_priv *bank = dev_get_priv(dev);
        u32 val;
 
-       val = inl(base);
+       val = inl(bank->lvl);
        if (value)
                val |= (1UL << offset);
        else
                val &= ~(1UL << offset);
-       outl(val, base);
+       outl(val, bank->lvl);
 
        return 0;
 }
 
-static int _ich6_gpio_set_function(uint16_t base, unsigned offset, int func)
+static int ich6_gpio_set_function(struct udevice *dev, unsigned offset,
+                                 int func)
 {
+       struct ich6_bank_priv *bank = dev_get_priv(dev);
        u32 val;
 
        if (func) {
-               val = inl(base);
+               val = inl(bank->use_sel);
                val |= (1UL << offset);
-               outl(val, base);
+               outl(val, bank->use_sel);
        } else {
-               val = inl(base);
+               val = inl(bank->use_sel);
                val &= ~(1UL << offset);
-               outl(val, base);
+               outl(val, bank->use_sel);
        }
 
        return 0;
 }
 
-static int _ich6_gpio_set_direction(uint16_t base, unsigned offset, int dir)
+static int ich6_gpio_set_direction(struct udevice *dev, unsigned offset,
+                                  int dir)
 {
+       struct ich6_bank_priv *bank = dev_get_priv(dev);
        u32 val;
 
        if (!dir) {
-               val = inl(base);
+               val = inl(bank->io_sel);
                val |= (1UL << offset);
-               outl(val, base);
+               outl(val, bank->io_sel);
        } else {
-               val = inl(base);
+               val = inl(bank->io_sel);
                val &= ~(1UL << offset);
-               outl(val, base);
+               outl(val, bank->io_sel);
        }
 
        return 0;
 }
 
-static int _gpio_ich6_pinctrl_cfg_pin(s32 gpiobase, s32 iobase, int pin_node)
+static int _gpio_ich6_pinctrl_cfg_pin(struct udevice *dev, s32 iobase,
+               int pin_node)
 {
-       u32 gpio_offset[2];
+       int gpio_offset;
        int pad_offset;
        int val;
-       int ret;
        const void *prop;
 
        /*
         * GPIO node is not mandatory, so we only do the
         * pinmuxing if the node exist.
         */
-       ret = fdtdec_get_int_array(gd->fdt_blob, pin_node, "gpio-offset",
-                            gpio_offset, 2);
-       if (!ret) {
+       gpio_offset = fdtdec_get_int(gd->fdt_blob, pin_node, "gpio-offset", -1);
+       if (gpio_offset != -1) {
                /* Do we want to force the GPIO mode? */
                prop = fdt_getprop(gd->fdt_blob, pin_node, "mode-gpio",
                                      NULL);
                if (prop)
-                       _ich6_gpio_set_function(GPIO_USESEL_OFFSET
-                                               (gpiobase) +
-                                               gpio_offset[0],
-                                               gpio_offset[1], 1);
+                       ich6_gpio_set_function(dev, gpio_offset, 1);
 
                val =
                    fdtdec_get_int(gd->fdt_blob, pin_node, "direction", -1);
                if (val != -1)
-                       _ich6_gpio_set_direction(GPIO_IOSEL_OFFSET
-                                                (gpiobase) +
-                                                gpio_offset[0],
-                                                gpio_offset[1], val);
+                       ich6_gpio_set_direction(dev, gpio_offset, val);
 
                val =
                    fdtdec_get_int(gd->fdt_blob, pin_node, "output-value", -1);
                if (val != -1)
-                       _ich6_gpio_set_value(GPIO_LVL_OFFSET(gpiobase)
-                                            + gpio_offset[0],
-                                            gpio_offset[1], val);
+                       ich6_gpio_set_value(dev, gpio_offset, val);
        }
 
        /* if iobase is present, let's configure the pad */
@@ -286,30 +280,19 @@ static int _gpio_ich6_pinctrl_cfg_pin(s32 gpiobase, s32 
iobase, int pin_node)
        return 0;
 }
 
-int gpio_ich6_pinctrl_init(void)
+static int gpio_ich6_pinctrl_init(struct udevice *dev)
 {
        int pin_node;
        int node;
        int ret;
-       int gpiobase;
        int iobase_offset;
        int iobase = -1;
-
-       /*
-        * Get the memory/io base address to configure every pins.
-        * IOBASE is used to configure the mode/pads
-        * GPIOBASE is used to configure the direction and default value
-        */
-       gpiobase = gpio_ich6_get_base(PCI_CFG_GPIOBASE);
-       if (gpiobase < 0) {
-               debug("%s: invalid GPIOBASE address (%08x)\n", __func__,
-                     gpiobase);
-               return -EINVAL;
-       }
+       int depth = 0;
 
        /* This is not an error to not have a pinctrl node */
        node =
-           fdtdec_next_compatible(gd->fdt_blob, 0, COMPAT_INTEL_X86_PINCTRL);
+           fdtdec_next_compatible_subnode(gd->fdt_blob, dev->of_offset,
+                           COMPAT_INTEL_X86_PINCTRL, &depth);
        if (node <= 0) {
                debug("%s: no pinctrl node\n", __func__);
                return 0;
@@ -335,7 +318,7 @@ int gpio_ich6_pinctrl_init(void)
             pin_node > 0;
             pin_node = fdt_next_subnode(gd->fdt_blob, pin_node)) {
                /* Configure the pin */
-               ret = _gpio_ich6_pinctrl_cfg_pin(gpiobase, iobase, pin_node);
+               ret = _gpio_ich6_pinctrl_cfg_pin(dev, iobase, pin_node);
                if (ret != 0) {
                        debug("%s: invalid configuration for the pin %d\n",
                              __func__, pin_node);
@@ -382,6 +365,8 @@ static int ich6_gpio_probe(struct udevice *dev)
        bank->io_sel = plat->base_addr + 4;
        bank->lvl = plat->base_addr + 8;
 
+       gpio_ich6_pinctrl_init(dev);
+
        return 0;
 }
 
@@ -408,22 +393,19 @@ static int ich6_gpio_request(struct udevice *dev, 
unsigned offset,
 
 static int ich6_gpio_direction_input(struct udevice *dev, unsigned offset)
 {
-       struct ich6_bank_priv *bank = dev_get_priv(dev);
-
-       return _ich6_gpio_set_direction(bank->io_sel, offset, 0);
+       return ich6_gpio_set_direction(dev, offset, 0);
 }
 
 static int ich6_gpio_direction_output(struct udevice *dev, unsigned offset,
                                       int value)
 {
        int ret;
-       struct ich6_bank_priv *bank = dev_get_priv(dev);
 
-       ret = _ich6_gpio_set_direction(bank->io_sel, offset, 1);
+       ret = ich6_gpio_set_direction(dev, offset, 1);
        if (ret)
                return ret;
 
-       return _ich6_gpio_set_value(bank->lvl, offset, value);
+       return ich6_gpio_set_value(dev, offset, value);
 }
 
 static int ich6_gpio_get_value(struct udevice *dev, unsigned offset)
@@ -437,13 +419,6 @@ static int ich6_gpio_get_value(struct udevice *dev, 
unsigned offset)
        return r;
 }
 
-static int ich6_gpio_set_value(struct udevice *dev, unsigned offset,
-                              int value)
-{
-       struct ich6_bank_priv *bank = dev_get_priv(dev);
-       return _ich6_gpio_set_value(bank->lvl, offset, value);
-}
-
 static int ich6_gpio_get_function(struct udevice *dev, unsigned offset)
 {
        struct ich6_bank_priv *bank = dev_get_priv(dev);
-- 
2.5.0

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to