Re: [U-Boot] [PATCH 3/4] x86: gpio: add pinctrl support from the device tree

2015-04-24 Thread Gabriel Huau

On 04/23/2015 08:14 PM, Bin Meng wrote:

Hi Gabriel,

On Fri, Apr 24, 2015 at 12:16 AM, Gabriel Huau  wrote:

A set of properties has been defined for the device tree to select for
each pin the pull/func/default output configuration.

The offset for the PAD needs to be provided and if a GPIO needs to be
configured, his offset needs to be provided as well.

Here is an example:
pin_usb_host_en0@0 {
 gpio-offset = <0x80 8>;
 pad-offset = <0x260>;
 mode-gpio;
 output-value = <1>;
 direction = ;
};

Signed-off-by: Gabriel Huau 
---
  arch/x86/dts/minnowmax.dts|  21 +++
  arch/x86/include/asm/arch-baytrail/gpio.h |   1 +
  arch/x86/include/asm/gpio.h   |   1 +
  drivers/gpio/intel_ich6_gpio.c| 222 ++
  include/dt-bindings/gpio/gpio.h   |  20 +++
  5 files changed, 239 insertions(+), 26 deletions(-)

diff --git a/arch/x86/dts/minnowmax.dts b/arch/x86/dts/minnowmax.dts
index c73e421..3936e21 100644
--- a/arch/x86/dts/minnowmax.dts
+++ b/arch/x86/dts/minnowmax.dts
@@ -6,6 +6,8 @@

  /dts-v1/;

+#include 
+
  /include/ "skeleton.dtsi"
  /include/ "serial.dtsi"

@@ -21,6 +23,25 @@
 silent_console = <0>;
 };

+   pch_pinctrl {
+   compatible = "intel,ich6-pinctrl";

I guess the prefix 'ich6' is debatable.



I hesitated with 'x86' but I'm open to any suggestion.


+   pin_usb_host_en0@0 {
+   gpio-offset = <0x80 8>;
+   pad-offset = <0x260>;
+   mode-gpio;
+   output-value = <1>;
+   direction = ;
+   };
+
+   pin_usb_host_en1@0 {
+   gpio-offset = <0x80 9>;
+   pad-offset = <0x258>;
+   mode-gpio;
+   output-value = <1>;
+   direction = ;
+   };
+   };
+
 gpioa {
 compatible = "intel,ich6-gpio";
 u-boot,dm-pre-reloc;
diff --git a/arch/x86/include/asm/arch-baytrail/gpio.h 
b/arch/x86/include/asm/arch-baytrail/gpio.h
index 4e8987c..85a65a8 100644
--- a/arch/x86/include/asm/arch-baytrail/gpio.h
+++ b/arch/x86/include/asm/arch-baytrail/gpio.h
@@ -9,5 +9,6 @@

  /* Where in config space is the register that points to the GPIO registers? */
  #define PCI_CFG_GPIOBASE 0x48
+#define PCI_CFG_IOBASE   0x4c

  #endif /* _X86_ARCH_GPIO_H_ */
diff --git a/arch/x86/include/asm/gpio.h b/arch/x86/include/asm/gpio.h
index 1099427..ed85b08 100644
--- a/arch/x86/include/asm/gpio.h
+++ b/arch/x86/include/asm/gpio.h
@@ -147,6 +147,7 @@ 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/drivers/gpio/intel_ich6_gpio.c b/drivers/gpio/intel_ich6_gpio.c
index 7e679a0..a110d5b 100644
--- a/drivers/gpio/intel_ich6_gpio.c
+++ b/drivers/gpio/intel_ich6_gpio.c
@@ -44,21 +44,32 @@ struct ich6_bank_priv {
 uint16_t lvl;
  };

+#define GPIO_USESEL_OFFSET(x) (x)
+#define GPIO_IOSEL_OFFSET(x) (x + 4)
+#define GPIO_LVL_OFFSET(x) (x + 8)

+#define IOPAD_MODE_MASK0x7
+#define IOPAD_PULL_ASSIGN_MASK 0x3
+#define IOPAD_PULL_ASSIGN_SHIFT7
+#define IOPAD_PULL_STRENGTH_MASK   0x3
+#define IOPAD_PULL_STRENGTH_SHIFT  9
+
+static int __ich6_gpio_set_value(uint16_t base, unsigned offset, int value);
+static int __ich6_gpio_set_direction(uint16_t base, unsigned offset, int dir);
+static int __ich6_gpio_set_function(uint16_t base, unsigned offset, int func);
+
  /* TODO: Move this to device tree, or platform data */
  void ich_gpio_set_gpio_map(const struct pch_gpio_map *map)
  {
 gd->arch.gpio_map = map;
  }

-static int gpio_ich6_ofdata_to_platdata(struct udevice *dev)
+static int gpio_ich6_get_base(unsigned long base)
  {
-   struct ich6_bank_platdata *plat = dev_get_platdata(dev);
 pci_dev_t pci_dev;  /* handle for 0:1f:0 */
 u8 tmpbyte;
 u16 tmpword;
 u32 tmplong;
-   u16 gpiobase;
-   int offset;

 /* Where should it be? */
 pci_dev = PCI_BDF(0, 0x1f, 0);
@@ -123,9 +134,9 @@ static int gpio_ich6_ofdata_to_platdata(struct udevice *dev)
  * while on the Ivybridge the bit0 is used to indicate it is an
  * I/O space.
  */
-   tmplong = x86_pci_read_config32(pci_dev, PCI_CFG_GPIOBASE);
+   tmplong = x86_pci_read_config32(pci_dev, base);
 if (tmplong == 0x || tmplong == 0x) {
-   debug("%s: unexpected GPIOBASE value\n", __func__);
+   debug("%s: unexpected BASE value\n", __func__);
 return -ENODEV;
 }

@@ -135,7 +146,138 @@ static int gpio_ich6_ofdata_to_platdata(struct udevice 
*dev)
  * at the offset tha

Re: [U-Boot] [PATCH 3/4] x86: gpio: add pinctrl support from the device tree

2015-04-24 Thread Gabriel Huau

Hi Simon,

On 04/23/2015 08:35 PM, Simon Glass wrote:

Hi,

On 23 April 2015 at 10:16, Gabriel Huau  wrote:

A set of properties has been defined for the device tree to select for
each pin the pull/func/default output configuration.

The offset for the PAD needs to be provided and if a GPIO needs to be
configured, his offset needs to be provided as well.

Here is an example:
pin_usb_host_en0@0 {
 gpio-offset = <0x80 8>;
 pad-offset = <0x260>;
 mode-gpio;
 output-value = <1>;
 direction = ;
};

Signed-off-by: Gabriel Huau 
---
  arch/x86/dts/minnowmax.dts|  21 +++
  arch/x86/include/asm/arch-baytrail/gpio.h |   1 +
  arch/x86/include/asm/gpio.h   |   1 +
  drivers/gpio/intel_ich6_gpio.c| 222 ++
  include/dt-bindings/gpio/gpio.h   |  20 +++
  5 files changed, 239 insertions(+), 26 deletions(-)

diff --git a/arch/x86/dts/minnowmax.dts b/arch/x86/dts/minnowmax.dts
index c73e421..3936e21 100644
--- a/arch/x86/dts/minnowmax.dts
+++ b/arch/x86/dts/minnowmax.dts
@@ -6,6 +6,8 @@

  /dts-v1/;

+#include 
+
  /include/ "skeleton.dtsi"
  /include/ "serial.dtsi"

@@ -21,6 +23,25 @@
 silent_console = <0>;
 };

+   pch_pinctrl {
+   compatible = "intel,ich6-pinctrl";

Make sure you use tabs for indenting here.

You should create a binding file to describe your binding - in
doc/device-tree-bindings.


+   pin_usb_host_en0@0 {
+   gpio-offset = <0x80 8>;
+   pad-offset = <0x260>;
+   mode-gpio;
+   output-value = <1>;
+   direction = ;
+   };
+
+   pin_usb_host_en1@0 {
+   gpio-offset = <0x80 9>;
+   pad-offset = <0x258>;
+   mode-gpio;
+   output-value = <1>;
+   direction = ;
+   };
+   };
+
 gpioa {
 compatible = "intel,ich6-gpio";
 u-boot,dm-pre-reloc;
diff --git a/arch/x86/include/asm/arch-baytrail/gpio.h 
b/arch/x86/include/asm/arch-baytrail/gpio.h
index 4e8987c..85a65a8 100644
--- a/arch/x86/include/asm/arch-baytrail/gpio.h
+++ b/arch/x86/include/asm/arch-baytrail/gpio.h
@@ -9,5 +9,6 @@

  /* Where in config space is the register that points to the GPIO registers? */
  #define PCI_CFG_GPIOBASE 0x48
+#define PCI_CFG_IOBASE   0x4c

  #endif /* _X86_ARCH_GPIO_H_ */
diff --git a/arch/x86/include/asm/gpio.h b/arch/x86/include/asm/gpio.h
index 1099427..ed85b08 100644
--- a/arch/x86/include/asm/gpio.h
+++ b/arch/x86/include/asm/gpio.h
@@ -147,6 +147,7 @@ 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/drivers/gpio/intel_ich6_gpio.c b/drivers/gpio/intel_ich6_gpio.c
index 7e679a0..a110d5b 100644
--- a/drivers/gpio/intel_ich6_gpio.c
+++ b/drivers/gpio/intel_ich6_gpio.c
@@ -44,21 +44,32 @@ struct ich6_bank_priv {
 uint16_t lvl;
  };

+#define GPIO_USESEL_OFFSET(x) (x)
+#define GPIO_IOSEL_OFFSET(x) (x + 4)
+#define GPIO_LVL_OFFSET(x) (x + 8)

Comments on the above


+
+#define IOPAD_MODE_MASK0x7
+#define IOPAD_PULL_ASSIGN_MASK 0x3
+#define IOPAD_PULL_ASSIGN_SHIFT7

Can you make the mask value an actual valid mask, like:

  +#define IOPAD_PULL_ASSIGN_MASK (0x3 << IOPAD_PULL_ASSIGN_SHIFT)


+#define IOPAD_PULL_STRENGTH_MASK   0x3
+#define IOPAD_PULL_STRENGTH_SHIFT  9
+
+static int __ich6_gpio_set_value(uint16_t base, unsigned offset, int value);

Can you reorder the functions to avoid the need for these forward
declarations? Also only one underscore prefix please.


+static int __ich6_gpio_set_direction(uint16_t base, unsigned offset, int dir);
+static int __ich6_gpio_set_function(uint16_t base, unsigned offset, int func);
+
  /* TODO: Move this to device tree, or platform data */
  void ich_gpio_set_gpio_map(const struct pch_gpio_map *map)
  {
 gd->arch.gpio_map = map;
  }

-static int gpio_ich6_ofdata_to_platdata(struct udevice *dev)
+static int gpio_ich6_get_base(unsigned long base)
  {
-   struct ich6_bank_platdata *plat = dev_get_platdata(dev);
 pci_dev_t pci_dev;  /* handle for 0:1f:0 */
 u8 tmpbyte;
 u16 tmpword;
 u32 tmplong;
-   u16 gpiobase;
-   int offset;

 /* Where should it be? */
 pci_dev = PCI_BDF(0, 0x1f, 0);
@@ -123,9 +134,9 @@ static int gpio_ich6_ofdata_to_platdata(struct udevice *dev)
  * while on the Ivybridge the bit0 is used to indicate it is an
  * I/O space.
  */
-   tmplong = x86_pci_read_config32(pci_dev, PCI_CFG_GPIOBASE);

Can the base come from the device tree somewhere? E.g.

pch {
 gpio {
reg = ;

Re: [U-Boot] [PATCH 3/4] x86: gpio: add pinctrl support from the device tree

2015-04-24 Thread Simon Glass
Hi,

On 23 April 2015 at 10:16, Gabriel Huau  wrote:
> A set of properties has been defined for the device tree to select for
> each pin the pull/func/default output configuration.
>
> The offset for the PAD needs to be provided and if a GPIO needs to be
> configured, his offset needs to be provided as well.
>
> Here is an example:
> pin_usb_host_en0@0 {
> gpio-offset = <0x80 8>;
> pad-offset = <0x260>;
> mode-gpio;
> output-value = <1>;
> direction = ;
> };
>
> Signed-off-by: Gabriel Huau 
> ---
>  arch/x86/dts/minnowmax.dts|  21 +++
>  arch/x86/include/asm/arch-baytrail/gpio.h |   1 +
>  arch/x86/include/asm/gpio.h   |   1 +
>  drivers/gpio/intel_ich6_gpio.c| 222 
> ++
>  include/dt-bindings/gpio/gpio.h   |  20 +++
>  5 files changed, 239 insertions(+), 26 deletions(-)
>
> diff --git a/arch/x86/dts/minnowmax.dts b/arch/x86/dts/minnowmax.dts
> index c73e421..3936e21 100644
> --- a/arch/x86/dts/minnowmax.dts
> +++ b/arch/x86/dts/minnowmax.dts
> @@ -6,6 +6,8 @@
>
>  /dts-v1/;
>
> +#include 
> +
>  /include/ "skeleton.dtsi"
>  /include/ "serial.dtsi"
>
> @@ -21,6 +23,25 @@
> silent_console = <0>;
> };
>
> +   pch_pinctrl {
> +   compatible = "intel,ich6-pinctrl";

Make sure you use tabs for indenting here.

You should create a binding file to describe your binding - in
doc/device-tree-bindings.

> +   pin_usb_host_en0@0 {
> +   gpio-offset = <0x80 8>;
> +   pad-offset = <0x260>;
> +   mode-gpio;
> +   output-value = <1>;
> +   direction = ;
> +   };
> +
> +   pin_usb_host_en1@0 {
> +   gpio-offset = <0x80 9>;
> +   pad-offset = <0x258>;
> +   mode-gpio;
> +   output-value = <1>;
> +   direction = ;
> +   };
> +   };
> +
> gpioa {
> compatible = "intel,ich6-gpio";
> u-boot,dm-pre-reloc;
> diff --git a/arch/x86/include/asm/arch-baytrail/gpio.h 
> b/arch/x86/include/asm/arch-baytrail/gpio.h
> index 4e8987c..85a65a8 100644
> --- a/arch/x86/include/asm/arch-baytrail/gpio.h
> +++ b/arch/x86/include/asm/arch-baytrail/gpio.h
> @@ -9,5 +9,6 @@
>
>  /* Where in config space is the register that points to the GPIO registers? 
> */
>  #define PCI_CFG_GPIOBASE 0x48
> +#define PCI_CFG_IOBASE   0x4c
>
>  #endif /* _X86_ARCH_GPIO_H_ */
> diff --git a/arch/x86/include/asm/gpio.h b/arch/x86/include/asm/gpio.h
> index 1099427..ed85b08 100644
> --- a/arch/x86/include/asm/gpio.h
> +++ b/arch/x86/include/asm/gpio.h
> @@ -147,6 +147,7 @@ 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/drivers/gpio/intel_ich6_gpio.c b/drivers/gpio/intel_ich6_gpio.c
> index 7e679a0..a110d5b 100644
> --- a/drivers/gpio/intel_ich6_gpio.c
> +++ b/drivers/gpio/intel_ich6_gpio.c
> @@ -44,21 +44,32 @@ struct ich6_bank_priv {
> uint16_t lvl;
>  };
>
> +#define GPIO_USESEL_OFFSET(x) (x)
> +#define GPIO_IOSEL_OFFSET(x) (x + 4)
> +#define GPIO_LVL_OFFSET(x) (x + 8)

Comments on the above

> +
> +#define IOPAD_MODE_MASK0x7
> +#define IOPAD_PULL_ASSIGN_MASK 0x3
> +#define IOPAD_PULL_ASSIGN_SHIFT7

Can you make the mask value an actual valid mask, like:

 +#define IOPAD_PULL_ASSIGN_MASK (0x3 << IOPAD_PULL_ASSIGN_SHIFT)

> +#define IOPAD_PULL_STRENGTH_MASK   0x3
> +#define IOPAD_PULL_STRENGTH_SHIFT  9
> +
> +static int __ich6_gpio_set_value(uint16_t base, unsigned offset, int value);

Can you reorder the functions to avoid the need for these forward
declarations? Also only one underscore prefix please.

> +static int __ich6_gpio_set_direction(uint16_t base, unsigned offset, int 
> dir);
> +static int __ich6_gpio_set_function(uint16_t base, unsigned offset, int 
> func);
> +
>  /* TODO: Move this to device tree, or platform data */
>  void ich_gpio_set_gpio_map(const struct pch_gpio_map *map)
>  {
> gd->arch.gpio_map = map;
>  }
>
> -static int gpio_ich6_ofdata_to_platdata(struct udevice *dev)
> +static int gpio_ich6_get_base(unsigned long base)
>  {
> -   struct ich6_bank_platdata *plat = dev_get_platdata(dev);
> pci_dev_t pci_dev;  /* handle for 0:1f:0 */
> u8 tmpbyte;
> u16 tmpword;
> u32 tmplong;
> -   u16 gpiobase;
> -   int offset;
>
> /* Where should it be? */
> pci_dev = PCI_BDF(0, 0x1f, 0);
> @@ -123,9 +134,9 @@ static int gpio_ich6_ofdata_to_platdata(struct udevice 
> *dev)
>  * while on the Ivybridge the bit0 is used to indicate it is an
>  * I/O space.
>  */

Re: [U-Boot] [PATCH 3/4] x86: gpio: add pinctrl support from the device tree

2015-04-24 Thread Bin Meng
Hi Gabriel,

On Fri, Apr 24, 2015 at 12:16 AM, Gabriel Huau  wrote:
> A set of properties has been defined for the device tree to select for
> each pin the pull/func/default output configuration.
>
> The offset for the PAD needs to be provided and if a GPIO needs to be
> configured, his offset needs to be provided as well.
>
> Here is an example:
> pin_usb_host_en0@0 {
> gpio-offset = <0x80 8>;
> pad-offset = <0x260>;
> mode-gpio;
> output-value = <1>;
> direction = ;
> };
>
> Signed-off-by: Gabriel Huau 
> ---
>  arch/x86/dts/minnowmax.dts|  21 +++
>  arch/x86/include/asm/arch-baytrail/gpio.h |   1 +
>  arch/x86/include/asm/gpio.h   |   1 +
>  drivers/gpio/intel_ich6_gpio.c| 222 
> ++
>  include/dt-bindings/gpio/gpio.h   |  20 +++
>  5 files changed, 239 insertions(+), 26 deletions(-)
>
> diff --git a/arch/x86/dts/minnowmax.dts b/arch/x86/dts/minnowmax.dts
> index c73e421..3936e21 100644
> --- a/arch/x86/dts/minnowmax.dts
> +++ b/arch/x86/dts/minnowmax.dts
> @@ -6,6 +6,8 @@
>
>  /dts-v1/;
>
> +#include 
> +
>  /include/ "skeleton.dtsi"
>  /include/ "serial.dtsi"
>
> @@ -21,6 +23,25 @@
> silent_console = <0>;
> };
>
> +   pch_pinctrl {
> +   compatible = "intel,ich6-pinctrl";

I guess the prefix 'ich6' is debatable.

> +   pin_usb_host_en0@0 {
> +   gpio-offset = <0x80 8>;
> +   pad-offset = <0x260>;
> +   mode-gpio;
> +   output-value = <1>;
> +   direction = ;
> +   };
> +
> +   pin_usb_host_en1@0 {
> +   gpio-offset = <0x80 9>;
> +   pad-offset = <0x258>;
> +   mode-gpio;
> +   output-value = <1>;
> +   direction = ;
> +   };
> +   };
> +
> gpioa {
> compatible = "intel,ich6-gpio";
> u-boot,dm-pre-reloc;
> diff --git a/arch/x86/include/asm/arch-baytrail/gpio.h 
> b/arch/x86/include/asm/arch-baytrail/gpio.h
> index 4e8987c..85a65a8 100644
> --- a/arch/x86/include/asm/arch-baytrail/gpio.h
> +++ b/arch/x86/include/asm/arch-baytrail/gpio.h
> @@ -9,5 +9,6 @@
>
>  /* Where in config space is the register that points to the GPIO registers? 
> */
>  #define PCI_CFG_GPIOBASE 0x48
> +#define PCI_CFG_IOBASE   0x4c
>
>  #endif /* _X86_ARCH_GPIO_H_ */
> diff --git a/arch/x86/include/asm/gpio.h b/arch/x86/include/asm/gpio.h
> index 1099427..ed85b08 100644
> --- a/arch/x86/include/asm/gpio.h
> +++ b/arch/x86/include/asm/gpio.h
> @@ -147,6 +147,7 @@ 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/drivers/gpio/intel_ich6_gpio.c b/drivers/gpio/intel_ich6_gpio.c
> index 7e679a0..a110d5b 100644
> --- a/drivers/gpio/intel_ich6_gpio.c
> +++ b/drivers/gpio/intel_ich6_gpio.c
> @@ -44,21 +44,32 @@ struct ich6_bank_priv {
> uint16_t lvl;
>  };
>
> +#define GPIO_USESEL_OFFSET(x) (x)
> +#define GPIO_IOSEL_OFFSET(x) (x + 4)
> +#define GPIO_LVL_OFFSET(x) (x + 8)
>
> +#define IOPAD_MODE_MASK0x7
> +#define IOPAD_PULL_ASSIGN_MASK 0x3
> +#define IOPAD_PULL_ASSIGN_SHIFT7
> +#define IOPAD_PULL_STRENGTH_MASK   0x3
> +#define IOPAD_PULL_STRENGTH_SHIFT  9
> +
> +static int __ich6_gpio_set_value(uint16_t base, unsigned offset, int value);
> +static int __ich6_gpio_set_direction(uint16_t base, unsigned offset, int 
> dir);
> +static int __ich6_gpio_set_function(uint16_t base, unsigned offset, int 
> func);
> +
>  /* TODO: Move this to device tree, or platform data */
>  void ich_gpio_set_gpio_map(const struct pch_gpio_map *map)
>  {
> gd->arch.gpio_map = map;
>  }
>
> -static int gpio_ich6_ofdata_to_platdata(struct udevice *dev)
> +static int gpio_ich6_get_base(unsigned long base)
>  {
> -   struct ich6_bank_platdata *plat = dev_get_platdata(dev);
> pci_dev_t pci_dev;  /* handle for 0:1f:0 */
> u8 tmpbyte;
> u16 tmpword;
> u32 tmplong;
> -   u16 gpiobase;
> -   int offset;
>
> /* Where should it be? */
> pci_dev = PCI_BDF(0, 0x1f, 0);
> @@ -123,9 +134,9 @@ static int gpio_ich6_ofdata_to_platdata(struct udevice 
> *dev)
>  * while on the Ivybridge the bit0 is used to indicate it is an
>  * I/O space.
>  */
> -   tmplong = x86_pci_read_config32(pci_dev, PCI_CFG_GPIOBASE);
> +   tmplong = x86_pci_read_config32(pci_dev, base);
> if (tmplong == 0x || tmplong == 0x) {
> -   debug("%s: unexpected GPIOBASE value\n", __func__);
> +   debug("%s: unexpected BASE value\n", __func__);
> return -ENODE

[U-Boot] [PATCH 3/4] x86: gpio: add pinctrl support from the device tree

2015-04-23 Thread Gabriel Huau
A set of properties has been defined for the device tree to select for
each pin the pull/func/default output configuration.

The offset for the PAD needs to be provided and if a GPIO needs to be
configured, his offset needs to be provided as well.

Here is an example:
pin_usb_host_en0@0 {
gpio-offset = <0x80 8>;
pad-offset = <0x260>;
mode-gpio;
output-value = <1>;
direction = ;
};

Signed-off-by: Gabriel Huau 
---
 arch/x86/dts/minnowmax.dts|  21 +++
 arch/x86/include/asm/arch-baytrail/gpio.h |   1 +
 arch/x86/include/asm/gpio.h   |   1 +
 drivers/gpio/intel_ich6_gpio.c| 222 ++
 include/dt-bindings/gpio/gpio.h   |  20 +++
 5 files changed, 239 insertions(+), 26 deletions(-)

diff --git a/arch/x86/dts/minnowmax.dts b/arch/x86/dts/minnowmax.dts
index c73e421..3936e21 100644
--- a/arch/x86/dts/minnowmax.dts
+++ b/arch/x86/dts/minnowmax.dts
@@ -6,6 +6,8 @@
 
 /dts-v1/;
 
+#include 
+
 /include/ "skeleton.dtsi"
 /include/ "serial.dtsi"
 
@@ -21,6 +23,25 @@
silent_console = <0>;
};
 
+   pch_pinctrl {
+   compatible = "intel,ich6-pinctrl";
+   pin_usb_host_en0@0 {
+   gpio-offset = <0x80 8>;
+   pad-offset = <0x260>;
+   mode-gpio;
+   output-value = <1>;
+   direction = ;
+   };
+
+   pin_usb_host_en1@0 {
+   gpio-offset = <0x80 9>;
+   pad-offset = <0x258>;
+   mode-gpio;
+   output-value = <1>;
+   direction = ;
+   };
+   };
+
gpioa {
compatible = "intel,ich6-gpio";
u-boot,dm-pre-reloc;
diff --git a/arch/x86/include/asm/arch-baytrail/gpio.h 
b/arch/x86/include/asm/arch-baytrail/gpio.h
index 4e8987c..85a65a8 100644
--- a/arch/x86/include/asm/arch-baytrail/gpio.h
+++ b/arch/x86/include/asm/arch-baytrail/gpio.h
@@ -9,5 +9,6 @@
 
 /* Where in config space is the register that points to the GPIO registers? */
 #define PCI_CFG_GPIOBASE 0x48
+#define PCI_CFG_IOBASE   0x4c
 
 #endif /* _X86_ARCH_GPIO_H_ */
diff --git a/arch/x86/include/asm/gpio.h b/arch/x86/include/asm/gpio.h
index 1099427..ed85b08 100644
--- a/arch/x86/include/asm/gpio.h
+++ b/arch/x86/include/asm/gpio.h
@@ -147,6 +147,7 @@ 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/drivers/gpio/intel_ich6_gpio.c b/drivers/gpio/intel_ich6_gpio.c
index 7e679a0..a110d5b 100644
--- a/drivers/gpio/intel_ich6_gpio.c
+++ b/drivers/gpio/intel_ich6_gpio.c
@@ -44,21 +44,32 @@ struct ich6_bank_priv {
uint16_t lvl;
 };
 
+#define GPIO_USESEL_OFFSET(x) (x)
+#define GPIO_IOSEL_OFFSET(x) (x + 4)
+#define GPIO_LVL_OFFSET(x) (x + 8)
+
+#define IOPAD_MODE_MASK0x7
+#define IOPAD_PULL_ASSIGN_MASK 0x3
+#define IOPAD_PULL_ASSIGN_SHIFT7
+#define IOPAD_PULL_STRENGTH_MASK   0x3
+#define IOPAD_PULL_STRENGTH_SHIFT  9
+
+static int __ich6_gpio_set_value(uint16_t base, unsigned offset, int value);
+static int __ich6_gpio_set_direction(uint16_t base, unsigned offset, int dir);
+static int __ich6_gpio_set_function(uint16_t base, unsigned offset, int func);
+
 /* TODO: Move this to device tree, or platform data */
 void ich_gpio_set_gpio_map(const struct pch_gpio_map *map)
 {
gd->arch.gpio_map = map;
 }
 
-static int gpio_ich6_ofdata_to_platdata(struct udevice *dev)
+static int gpio_ich6_get_base(unsigned long base)
 {
-   struct ich6_bank_platdata *plat = dev_get_platdata(dev);
pci_dev_t pci_dev;  /* handle for 0:1f:0 */
u8 tmpbyte;
u16 tmpword;
u32 tmplong;
-   u16 gpiobase;
-   int offset;
 
/* Where should it be? */
pci_dev = PCI_BDF(0, 0x1f, 0);
@@ -123,9 +134,9 @@ static int gpio_ich6_ofdata_to_platdata(struct udevice *dev)
 * while on the Ivybridge the bit0 is used to indicate it is an
 * I/O space.
 */
-   tmplong = x86_pci_read_config32(pci_dev, PCI_CFG_GPIOBASE);
+   tmplong = x86_pci_read_config32(pci_dev, base);
if (tmplong == 0x || tmplong == 0x) {
-   debug("%s: unexpected GPIOBASE value\n", __func__);
+   debug("%s: unexpected BASE value\n", __func__);
return -ENODEV;
}
 
@@ -135,7 +146,138 @@ static int gpio_ich6_ofdata_to_platdata(struct udevice 
*dev)
 * at the offset that we just read. Bit 0 indicates that it's
 * an I/O address, not a memory address, so mask that off.
 */
-   gpiobase = tmplong & 0xfffe;
+   return tmplong & 0xfffc;
+}
+
+int gpio_ich6_pinctrl_init(void)
+{
+   int p