LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
* [PATCH 1/3] gpiolib: Add ability to get GPIO pin direction
@ 2011-01-06 19:54 Peter Tyser
  2011-01-06 19:54 ` [PATCH 2/3] gpio: pca953x: Implement get_direction() hook Peter Tyser
                   ` (2 more replies)
  0 siblings, 3 replies; 26+ messages in thread
From: Peter Tyser @ 2011-01-06 19:54 UTC (permalink / raw)
  To: linux-kernel
  Cc: Peter Tyser, Alek Du, Samuel Ortiz, David Brownell, Eric Miao,
	Uwe Kleine-K?nig, Mark Brown, Joe Perches

Add a new get_direction() function to the gpio_chip structure.  This is
useful so that the direction of a pin can be determined when its
exported.  Previously, the direction defaulted to 'in' regardless of the
actual configuration of the GPIO pin which resulted in the 'direction'
sysfs file often being incorrect.

If a GPIO driver implements get_direction(), it is called in
gpio_request() to set the initial direction of the pin accurately.

Cc: Alek Du <alek.du@intel.com>
Cc: Samuel Ortiz <sameo@linux.intel.com>
Cc: David Brownell <dbrownell@users.sourceforge.net>
Cc: Eric Miao <eric.y.miao@gmail.com>
Cc: Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>
Cc: Mark Brown <broonie@opensource.wolfsonmicro.com>
Cc: Joe Perches <joe@perches.com>
Signed-off-by: Peter Tyser <ptyser@xes-inc.com>
---
 drivers/gpio/gpiolib.c     |   15 ++++++++-------
 include/asm-generic/gpio.h |    4 ++++
 2 files changed, 12 insertions(+), 7 deletions(-)

diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 649550e..0a360d8 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -1062,13 +1062,6 @@ int gpiochip_add(struct gpio_chip *chip)
 	if (status == 0) {
 		for (id = base; id < base + chip->ngpio; id++) {
 			gpio_desc[id].chip = chip;
-
-			/* REVISIT:  most hardware initializes GPIOs as
-			 * inputs (often with pullups enabled) so power
-			 * usage is minimized.  Linux code should set the
-			 * gpio direction first thing; but until it does,
-			 * we may expose the wrong direction in sysfs.
-			 */
 			gpio_desc[id].flags = !chip->direction_input
 				? (1 << FLAG_IS_OUT)
 				: 0;
@@ -1215,6 +1208,14 @@ int gpio_request(unsigned gpio, const char *label)
 		}
 	}
 
+	if (chip->get_direction) {
+		/* chip->get_direction may sleep */
+		spin_unlock_irqrestore(&gpio_lock, flags);
+		if (chip->get_direction(chip, gpio - chip->base) > 0)
+			set_bit(FLAG_IS_OUT, &desc->flags);
+		spin_lock_irqsave(&gpio_lock, flags);
+	}
+
 done:
 	if (status)
 		pr_debug("gpio_request: gpio-%d (%s) status %d\n",
diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h
index ff5c660..7d55cf7 100644
--- a/include/asm-generic/gpio.h
+++ b/include/asm-generic/gpio.h
@@ -57,6 +57,8 @@ struct device_node;
  * @direction_input: configures signal "offset" as input, or returns error
  * @get: returns value for signal "offset"; for output signals this
  *	returns either the value actually sensed, or zero
+ * @get_direction: optional hook to determine if a GPIO signal is configured
+ *	as an input (0) or output (1).
  * @direction_output: configures signal "offset" as output, or returns error
  * @set: assigns output value for signal "offset"
  * @to_irq: optional hook supporting non-static gpio_to_irq() mappings;
@@ -101,6 +103,8 @@ struct gpio_chip {
 						unsigned offset);
 	int			(*get)(struct gpio_chip *chip,
 						unsigned offset);
+	int			(*get_direction)(struct gpio_chip *chip,
+						unsigned offset);
 	int			(*direction_output)(struct gpio_chip *chip,
 						unsigned offset, int value);
 	int			(*set_debounce)(struct gpio_chip *chip,
-- 
1.7.0.4


^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH 2/3] gpio: pca953x: Implement get_direction() hook
  2011-01-06 19:54 [PATCH 1/3] gpiolib: Add ability to get GPIO pin direction Peter Tyser
@ 2011-01-06 19:54 ` Peter Tyser
  2011-01-06 23:16   ` David Brownell
  2011-01-06 19:54 ` [PATCH 3/3] gpio: Add support for Intel ICHx/3100/Series[56] GPIO Peter Tyser
  2011-02-14 15:48 ` [PATCH 1/3] gpiolib: Add ability to get GPIO pin direction Peter Tyser
  2 siblings, 1 reply; 26+ messages in thread
From: Peter Tyser @ 2011-01-06 19:54 UTC (permalink / raw)
  To: linux-kernel
  Cc: Peter Tyser, Alek Du, Samuel Ortiz, David Brownell, Eric Miao,
	Uwe Kleine-K?nig, Mark Brown, Joe Perches

Adding the get_direction() function allows the accurate GPIO pin
direction data to be shown in sysfs.  Previously, the direction was
was always initialized to 'input', even if the pin was configured as an
output.

Cc: Alek Du <alek.du@intel.com>
Cc: Samuel Ortiz <sameo@linux.intel.com>
Cc: David Brownell <dbrownell@users.sourceforge.net>
Cc: Eric Miao <eric.y.miao@gmail.com>
Cc: Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>
Cc: Mark Brown <broonie@opensource.wolfsonmicro.com>
Cc: Joe Perches <joe@perches.com>
Signed-off-by: Peter Tyser <ptyser@xes-inc.com>
---
 drivers/gpio/pca953x.c |   11 +++++++++++
 1 files changed, 11 insertions(+), 0 deletions(-)

diff --git a/drivers/gpio/pca953x.c b/drivers/gpio/pca953x.c
index 5018666..d291028 100644
--- a/drivers/gpio/pca953x.c
+++ b/drivers/gpio/pca953x.c
@@ -159,6 +159,16 @@ static int pca953x_gpio_direction_output(struct gpio_chip *gc,
 	return 0;
 }
 
+static int pca953x_gpio_get_direction(struct gpio_chip *gc, unsigned off)
+{
+	struct pca953x_chip *chip;
+
+	chip = container_of(gc, struct pca953x_chip, gpio_chip);
+
+	/* return 0 if IO pin is input, 1 if its an output */
+	return chip->reg_direction & (1u << off) ? 0 : 1;
+}
+
 static int pca953x_gpio_get_value(struct gpio_chip *gc, unsigned off)
 {
 	struct pca953x_chip *chip;
@@ -207,6 +217,7 @@ static void pca953x_setup_gpio(struct pca953x_chip *chip, int gpios)
 
 	gc->direction_input  = pca953x_gpio_direction_input;
 	gc->direction_output = pca953x_gpio_direction_output;
+	gc->get_direction = pca953x_gpio_get_direction;
 	gc->get = pca953x_gpio_get_value;
 	gc->set = pca953x_gpio_set_value;
 	gc->can_sleep = 1;
-- 
1.7.0.4


^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH 3/3] gpio: Add support for Intel ICHx/3100/Series[56] GPIO
  2011-01-06 19:54 [PATCH 1/3] gpiolib: Add ability to get GPIO pin direction Peter Tyser
  2011-01-06 19:54 ` [PATCH 2/3] gpio: pca953x: Implement get_direction() hook Peter Tyser
@ 2011-01-06 19:54 ` Peter Tyser
  2011-01-06 23:12   ` David Brownell
  2011-02-14 15:48 ` [PATCH 1/3] gpiolib: Add ability to get GPIO pin direction Peter Tyser
  2 siblings, 1 reply; 26+ messages in thread
From: Peter Tyser @ 2011-01-06 19:54 UTC (permalink / raw)
  To: linux-kernel
  Cc: Peter Tyser, Alek Du, Samuel Ortiz, David Brownell, Eric Miao,
	Uwe Kleine-K?nig, Mark Brown, Joe Perches

This driver works on many Intel chipsets, including the ICH6, ICH7,
ICH8, ICH9, ICH10, 3100, Series 5/3400 (Ibex Peak), Series 6/C200
(Cougar Point).

Additional Intel chipsets should be easily supported if needed, eg the
ICH1-5, EP80579, etc.

Tested on a QM57 (Ibex Peak) and 3100.

Cc: Alek Du <alek.du@intel.com>
Cc: Samuel Ortiz <sameo@linux.intel.com>
Cc: David Brownell <dbrownell@users.sourceforge.net>
Cc: Eric Miao <eric.y.miao@gmail.com>
Cc: Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>
Cc: Mark Brown <broonie@opensource.wolfsonmicro.com>
Cc: Joe Perches <joe@perches.com>
Signed-off-by: Peter Tyser <ptyser@xes-inc.com>
---
 MAINTAINERS              |    5 +
 drivers/gpio/Kconfig     |   11 +
 drivers/gpio/Makefile    |    1 +
 drivers/gpio/ichx_gpio.c |  551 ++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 568 insertions(+), 0 deletions(-)
 create mode 100644 drivers/gpio/ichx_gpio.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 71e40f9..95df3b9 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2946,6 +2946,11 @@ W:	http://www.developer.ibm.com/welcome/netfinity/serveraid.html
 S:	Supported
 F:	drivers/scsi/ips.*
 
+ICHX GPIO DRIVER
+M:	Peter Tyser <ptyser@xes-inc.com>
+S:	Maintained
+F:	drivers/gpio/ichx_gpio.c
+
 IDE SUBSYSTEM
 M:	"David S. Miller" <davem@davemloft.net>
 L:	linux-ide@vger.kernel.org
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 3143ac7..aa5f540 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -319,6 +319,17 @@ config GPIO_BT8XX
 
 	  If unsure, say N.
 
+config GPIO_ICHX
+	tristate "Intel ICHx GPIO"
+	depends on PCI && GPIOLIB && X86
+	help
+	  Say yes here to support the GPIO functionality of a number of Intel
+	  ICH-based chipsets.  Currently supported devices: ICH6, ICH7, ICH8
+	  ICH9, ICH10, Series 5/3400 (ie Ibex Peak), Series 6/C200 (eg
+	  Cougar Point), and 3100.
+
+	  If unsure, say N.
+
 config GPIO_LANGWELL
 	bool "Intel Langwell/Penwell GPIO support"
 	depends on PCI
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index bdf3dde..d02cf70 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_GPIOLIB)		+= gpiolib.o
 obj-$(CONFIG_GPIO_ADP5520)	+= adp5520-gpio.o
 obj-$(CONFIG_GPIO_ADP5588)	+= adp5588-gpio.o
 obj-$(CONFIG_GPIO_BASIC_MMIO)	+= basic_mmio_gpio.o
+obj-$(CONFIG_GPIO_ICHX)		+= ichx_gpio.o
 obj-$(CONFIG_GPIO_LANGWELL)	+= langwell_gpio.o
 obj-$(CONFIG_GPIO_MAX730X)	+= max730x.o
 obj-$(CONFIG_GPIO_MAX7300)	+= max7300.o
diff --git a/drivers/gpio/ichx_gpio.c b/drivers/gpio/ichx_gpio.c
new file mode 100644
index 0000000..63d27b5
--- /dev/null
+++ b/drivers/gpio/ichx_gpio.c
@@ -0,0 +1,551 @@
+/*
+ * Intel ICH6-10, Series 5 and 6 GPIO driver
+ *
+ * Copyright (C) 2010 Extreme Engineering Solutions.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+
+#define DRV_NAME "ichx_gpio"
+
+/* PCI config register offsets into LPC I/F - D31:F0 */
+#define PCI_ICHX_ACPI_BAR	0x40
+#define PCI_ICHX_GPIO_BAR	0x48
+#define PCI_ICHX_GPIO_CTRL	0x4C
+
+/*
+ * GPIO register offsets in GPIO I/O space.
+ * Each chunk of 32 GPIOs is manipulated via its own USE_SELx, IO_SELx, and
+ * LVLx registers.  Logic in the read/write functions takes a register and
+ * an absolute bit number and determines the proper register offset and bit
+ * number in that register.  For example, to read the value of GPIO bit 50
+ * the code would access offset ichx_regs[2(=GPIO_LVL)][1(=50/32)],
+ * bit 18 (50%32).
+ */
+enum GPIO_REG {
+	GPIO_USE_SEL = 0,
+	GPIO_IO_SEL,
+	GPIO_LVL,
+};
+static const u8 ichx_regs[3][3] = {
+	{0x00, 0x30, 0x40},	/* USE_SEL[1-3] offsets */
+	{0x04, 0x34, 0x44},	/* IO_SEL[1-3] offsets */
+	{0x0c, 0x38, 0x48},	/* LVL[1-3] offsets */
+};
+
+#define ICHX_GPIO_WRITE(val, reg)	outl(val, (reg) + ichx_priv.gpio_base)
+#define ICHX_GPIO_READ(reg)		inl((reg) + ichx_priv.gpio_base)
+#define ICHX_PM_WRITE(val, reg)		outl(val, (reg) + ichx_priv.pm_base)
+#define ICHX_PM_READ(reg)		inl((reg) + ichx_priv.pm_base)
+
+/* Convenient wrapper to make our PCI ID table */
+#define ICHX_GPIO_PCI_DEVICE(dev, data) \
+	.vendor = PCI_VENDOR_ID_INTEL,	\
+	.device = dev,			\
+	.subvendor = PCI_ANY_ID,	\
+	.subdevice = PCI_ANY_ID,	\
+	.class = 0,			\
+	.class_mask = 0,		\
+	.driver_data = (ulong)data
+
+struct ichx_desc {
+	/* Max GPIO pins the chipset can have */
+	uint ngpio;
+
+	/* The offset of GPE0_STS in the PM IO region, 0 if unneeded */
+	uint gpe0_sts_ofs;
+
+	/* USE_SEL is bogus on some chipsets, eg 3100 */
+	u32 use_sel_ignore[3];
+
+	/* Some chipsets have quirks, let these use their own request/get */
+	int (*request)(struct gpio_chip *chip, unsigned offset);
+	int (*get)(struct gpio_chip *chip, unsigned offset);
+};
+
+static struct {
+	spinlock_t lock;
+	struct platform_device *dev;
+	struct pci_dev *pdev;
+	struct gpio_chip chip;
+	unsigned long gpio_base;/* GPIO IO base */
+	unsigned long pm_base;	/* Power Mangagment IO base */
+	struct ichx_desc *desc;	/* Pointer to chipset-specific description */
+	u32 orig_gpio_ctrl;	/* Orig CTRL value, used to restore on exit */
+} ichx_priv;
+
+static struct platform_device *ichx_gpio_platform_device;
+
+static int modparam_gpiobase = -1 /* dynamic */;
+module_param_named(gpiobase, modparam_gpiobase, int, 0444);
+MODULE_PARM_DESC(gpiobase, "The GPIO number base. -1 means dynamic, "
+			   "which is the default.");
+
+static int ichx_write_bit(int reg, unsigned nr, int val, int verify)
+{
+	unsigned long flags;
+	u32 data;
+	int reg_nr = nr / 32;
+	int bit = nr & 0x1f;
+	int ret = 0;
+
+	spin_lock_irqsave(&ichx_priv.lock, flags);
+
+	data = ICHX_GPIO_READ(ichx_regs[reg][reg_nr]);
+	data = (data & ~(1 << bit)) | (val << bit);
+	ICHX_GPIO_WRITE(data, ichx_regs[reg][reg_nr]);
+	if (verify && (data != ICHX_GPIO_READ(ichx_regs[reg][reg_nr])))
+		ret = -EPERM;
+
+	spin_unlock_irqrestore(&ichx_priv.lock, flags);
+
+	return ret;
+}
+
+static int ichx_read_bit(int reg, unsigned nr)
+{
+	unsigned long flags;
+	u32 data;
+	int reg_nr = nr / 32;
+	int bit = nr & 0x1f;
+
+	spin_lock_irqsave(&ichx_priv.lock, flags);
+
+	data = ICHX_GPIO_READ(ichx_regs[reg][reg_nr]);
+
+	spin_unlock_irqrestore(&ichx_priv.lock, flags);
+
+	return data & (1 << bit) ? 1 : 0;
+}
+
+static int ichx_gpio_direction_input(struct gpio_chip *gpio, unsigned nr)
+{
+	/*
+	 * Try setting pin as an input and verify it worked since many pins
+	 * are output-only.
+	 */
+	if (ichx_write_bit(GPIO_IO_SEL, nr, 1, 1))
+		return -EINVAL;
+
+	return 0;
+}
+
+static int ichx_gpio_direction_output(struct gpio_chip *gpio, unsigned nr,
+					int val)
+{
+	/* Set GPIO output value. */
+	ichx_write_bit(GPIO_LVL, nr, val, 0);
+
+	/*
+	 * Try setting pin as an output and verify it worked since many pins
+	 * are input-only.
+	 */
+	if (ichx_write_bit(GPIO_IO_SEL, nr, 0, 1))
+		return -EINVAL;
+
+	return 0;
+}
+
+static int ichx_gpio_get_direction(struct gpio_chip *chip, unsigned nr)
+{
+	/* Return 0 if IO pin is input, 1 if its an output */
+	return !ichx_read_bit(GPIO_IO_SEL, nr);
+}
+
+static int ichx_gpio_get(struct gpio_chip *chip, unsigned nr)
+{
+	return ichx_read_bit(GPIO_LVL, nr);
+}
+
+static int ich6_gpio_get(struct gpio_chip *chip, unsigned nr)
+{
+	unsigned long flags;
+	u32 data;
+
+	/*
+	 * GPI 0 - 15 need to be read from the power management registers on
+	 * a ICH6/3100 bridge.
+	 */
+	if (nr < 16) {
+		spin_lock_irqsave(&ichx_priv.lock, flags);
+
+		/* GPI 0 - 15 are latched, write 1 to clear*/
+		ICHX_PM_WRITE(1 << (16 + nr), ichx_priv.desc->gpe0_sts_ofs);
+
+		data = ICHX_PM_READ(ichx_priv.desc->gpe0_sts_ofs);
+
+		spin_unlock_irqrestore(&ichx_priv.lock, flags);
+
+		return (data >> 16) & (1 << nr) ? 1 : 0;
+	} else {
+		return ichx_gpio_get(chip, nr);
+	}
+}
+
+static int ichx_gpio_request(struct gpio_chip *chip, unsigned nr)
+{
+	/*
+	 * Note we assume the BIOS properly set a bridge's USE value.  Some
+	 * chips (eg Intel 3100) have bogus USE values though, so first see if
+	 * the chipset's USE value can be trusted for this specific bit.
+	 * If it can't be trusted, assume that the pin can be used as a GPIO.
+	 */
+	if (ichx_priv.desc->use_sel_ignore[nr / 32] & (1 << (nr & 0x1f)))
+		return 1;
+
+	return ichx_read_bit(GPIO_USE_SEL, nr) ? 0 : -ENODEV;
+}
+
+static int ich6_gpio_request(struct gpio_chip *chip, unsigned nr)
+{
+	/*
+	 * Fixups for bits 16 and 17 are necessary on the Intel ICH6/3100
+	 * brdige as they are controlled by USE register bits 0 and 1.  See
+	 * "Table 704 GPIO_USE_SEL1 register" in the i3100 datasheet for
+	 * additional info.
+	 */
+	if ((nr == 16) || (nr == 17))
+		nr -= 16;
+
+	return ichx_gpio_request(chip, nr);
+}
+
+static void ichx_gpio_set(struct gpio_chip *chip, unsigned nr, int val)
+{
+	ichx_write_bit(GPIO_LVL, nr, val, 0);
+}
+
+static void __devinit ichx_gpiolib_setup(struct gpio_chip *chip)
+{
+	chip->owner = THIS_MODULE;
+	chip->label = DRV_NAME;
+
+	/* Allow chip-specific overrides of request()/get() */
+	chip->request = ichx_priv.desc->request ?
+		ichx_priv.desc->request : ichx_gpio_request;
+	chip->get = ichx_priv.desc->get ?
+		ichx_priv.desc->get : ichx_gpio_get;
+
+	chip->set = ichx_gpio_set;
+	chip->get_direction = ichx_gpio_get_direction;
+	chip->direction_input = ichx_gpio_direction_input;
+	chip->direction_output = ichx_gpio_direction_output;
+	chip->base = modparam_gpiobase;
+	chip->ngpio = ichx_priv.desc->ngpio;
+	chip->can_sleep = 0;
+	chip->dbg_show = NULL;
+}
+
+static int __devinit ichx_gpio_init(struct pci_dev *pdev,
+				const struct pci_device_id *ent,
+				struct platform_device *dev)
+{
+	int err;
+
+	ichx_priv.pdev = pdev;
+	ichx_priv.dev = dev;
+	ichx_priv.desc = (struct ichx_desc *)ent->driver_data;
+
+	/* Determine I/O address of GPIO registers */
+	pci_read_config_dword(pdev, PCI_ICHX_GPIO_BAR,
+			      (u32 *)&ichx_priv.gpio_base);
+	ichx_priv.gpio_base &= PCI_BASE_ADDRESS_IO_MASK;
+	if (!ichx_priv.gpio_base) {
+		printk(KERN_ERR "%s: GPIO BAR not enumerated\n", DRV_NAME);
+		return -ENODEV;
+	}
+
+	/*
+	 * If necessary, determine the I/O address of ACPI/power management
+	 * registers which are needed to read the the GPE0 register for GPI pins
+	 * 0 - 15 on some chipsets.
+	 */
+	if (ichx_priv.desc->gpe0_sts_ofs) {
+		pci_read_config_dword(pdev, PCI_ICHX_ACPI_BAR,
+				      (u32 *)&ichx_priv.pm_base);
+		ichx_priv.pm_base &= PCI_BASE_ADDRESS_IO_MASK;
+		if (!ichx_priv.pm_base)
+			printk(KERN_WARNING "%s: ACPI BAR not enumerated, "
+			       "GPI 0 - 15 unusable\n", DRV_NAME);
+	}
+
+	/* Enable GPIO */
+	pci_read_config_dword(pdev, PCI_ICHX_GPIO_CTRL,
+			&ichx_priv.orig_gpio_ctrl);
+	pci_write_config_dword(pdev, PCI_ICHX_GPIO_CTRL,
+			ichx_priv.orig_gpio_ctrl | 0x10);
+
+	/*
+	 * Reserve GPIO I/O region. The power management region is used by other
+	 * drivers thus shouldn't be reserved.  The GPIO I/O region is 64
+	 * bytes for older chipsets with <= 64 GPIO, 128 bytes for newer
+	 * chipsets with > 64 GPIO.
+	 */
+	if (!devm_request_region(&dev->dev, ichx_priv.gpio_base,
+			ichx_priv.desc->ngpio > 64 ? 128 : 64,
+			"ichxgpio")) {
+		printk(KERN_ERR "%s: Can't request iomem (0x%lx)\n",
+		       DRV_NAME, ichx_priv.gpio_base);
+		return -EBUSY;
+	}
+
+	ichx_gpiolib_setup(&ichx_priv.chip);
+
+	err = gpiochip_add(&ichx_priv.chip);
+	if (err) {
+		printk(KERN_ERR "%s: Failed to register GPIOs\n", DRV_NAME);
+		return err;
+	}
+
+	printk(KERN_INFO "%s: GPIO from %d to %d on %s\n", DRV_NAME,
+	       ichx_priv.chip.base,
+	       ichx_priv.chip.base + ichx_priv.chip.ngpio - 1,
+	       dev_name(&pdev->dev));
+
+	return 0;
+}
+
+/* ICH6-based, 631xesb-based */
+static struct ichx_desc ich6_desc = {
+	/* Bridges using the ICH6 controller need fixups for GPIO 0 - 17 */
+	.request = ich6_gpio_request,
+	.get = ich6_gpio_get,
+
+	/* GPIO 0-15 are read in the GPE0_STS PM register */
+	.gpe0_sts_ofs = 0x28,
+
+	.ngpio = 50,
+};
+
+/* Intel 3100 */
+static struct ichx_desc i3100_desc = {
+	/*
+	 * Bits 16,17, 20 of USE_SEL and bit 16 of USE_SEL2 always read 0 on
+	 * the Intel 3100.  See "Table 712. GPIO Summary Table" of 3100
+	 * Datasheet for more info.
+	 */
+	.use_sel_ignore = {0x00130000, 0x00010000, 0x0},
+
+	/* The 3100 needs fixups for GPIO 0 - 17 */
+	.request = ich6_gpio_request,
+	.get = ich6_gpio_get,
+
+	/* GPIO 0-15 are read in the GPE0_STS PM register */
+	.gpe0_sts_ofs = 0x28,
+
+	.ngpio = 50,
+};
+
+/* ICH7 and ICH8-based */
+static struct ichx_desc ich7_desc = {
+	.ngpio = 50,
+};
+
+/* ICH9-based */
+static struct ichx_desc ich9_desc = {
+	.ngpio = 61,
+};
+
+/* ICH10-based - Consumer/corporate versions have different amount of GPIO */
+static struct ichx_desc ich10_cons_desc = {
+	.ngpio = 51,
+};
+static struct ichx_desc ich10_corp_desc = {
+	.ngpio = 72,
+};
+
+/* Intel 5 series, 6 series, 3400 series, and C200 series */
+static struct ichx_desc intel5_desc = {
+	.ngpio = 76,
+};
+
+/*
+ * Note that we don't register a PCI driver since the PCI device has additional
+ * functionality that is used by other drivers, eg iTCO_wdt.  We use the table
+ * to probe for matching devices, then use a platform driver.
+ *
+ * Also note that some additional, old chipsets should in theory be supported
+ * by this driver (eg 82801XX chips), but they are left out due to the fact
+ * that they complicate the driver and there likely isn't much of a demand
+ * since a driver doesn't already exist for the 10+ years the chipsets have
+ * existed for.
+ */
+static DEFINE_PCI_DEVICE_TABLE(ichx_pci_tbl) = {
+	{ ICHX_GPIO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH6_0, &ich6_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH6_1, &ich6_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH6_2, &ich6_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH7_0, &ich7_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH7_1, &ich7_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH7_30, &ich7_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH7_31, &ich7_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH8_0, &ich7_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH8_1, &ich7_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH8_2, &ich7_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH8_3, &ich7_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH8_4, &ich7_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH9_1, &ich9_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH9_2, &ich9_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH9_4, &ich9_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH9_5, &ich9_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH9_7, &ich9_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH9_8, &ich9_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH10_0, &ich10_corp_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH10_3, &ich10_corp_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH10_1, &ich10_cons_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH10_2, &ich10_cons_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ESB2_0, &i3100_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(0x2671, &ich6_desc) }, /* 631Xesb series */
+	{ ICHX_GPIO_PCI_DEVICE(0x2672, &ich6_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(0x2673, &ich6_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(0x2674, &ich6_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(0x2675, &ich6_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(0x2676, &ich6_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(0x2677, &ich6_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(0x2678, &ich6_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(0x2679, &ich6_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(0x267a, &ich6_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(0x267b, &ich6_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(0x267c, &ich6_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(0x267d, &ich6_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(0x267e, &ich6_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(0x267f, &ich6_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(0x3b00, &intel5_desc) }, /* 5 series */
+	{ ICHX_GPIO_PCI_DEVICE(0x3b01, &intel5_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(0x3b02, &intel5_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(0x3b03, &intel5_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(0x3b04, &intel5_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(0x3b05, &intel5_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(0x3b06, &intel5_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(0x3b07, &intel5_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(0x3b08, &intel5_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(0x3b09, &intel5_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(0x3b0a, &intel5_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(0x3b0b, &intel5_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(0x3b0c, &intel5_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(0x3b0d, &intel5_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(0x3b0e, &intel5_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(0x3b0f, &intel5_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(0x1c41, &intel5_desc) }, /* 6 Series */
+	{ ICHX_GPIO_PCI_DEVICE(0x1c42, &intel5_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(0x1c43, &intel5_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(0x1c44, &intel5_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(0x1c45, &intel5_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(0x1c46, &intel5_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(0x1c47, &intel5_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(0x1c48, &intel5_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(0x1c49, &intel5_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(0x1c4a, &intel5_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(0x1c4b, &intel5_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(0x1c4c, &intel5_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(0x1c4d, &intel5_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(0x1c4e, &intel5_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(0x1c4f, &intel5_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(0x1c50, &intel5_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(0x1c51, &intel5_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(0x1c52, &intel5_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(0x1c53, &intel5_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(0x1c54, &intel5_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(0x1c55, &intel5_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(0x1c56, &intel5_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(0x1c57, &intel5_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(0x1c58, &intel5_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(0x1c59, &intel5_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(0x1c5a, &intel5_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(0x1c5b, &intel5_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(0x1c5c, &intel5_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(0x1c5d, &intel5_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(0x1c5e, &intel5_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(0x1c5f, &intel5_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(0x3b12, &intel5_desc) }, /* 3400 series */
+	{ ICHX_GPIO_PCI_DEVICE(0x3b14, &intel5_desc) },
+	{ ICHX_GPIO_PCI_DEVICE(0x3b16, &intel5_desc) },
+	{ 0, },
+};
+MODULE_DEVICE_TABLE(pci, ichx_pci_tbl);
+
+static int __devinit ichx_gpio_probe(struct platform_device *dev)
+{
+	struct pci_dev *pdev = NULL;
+	const struct pci_device_id *ent;
+
+	spin_lock_init(&ichx_priv.lock);
+
+	for_each_pci_dev(pdev) {
+		ent = pci_match_id(ichx_pci_tbl, pdev);
+		if (ent)
+			return ichx_gpio_init(pdev, ent, dev);
+	}
+
+	return -ENODEV;
+}
+
+static int __devexit ichx_gpio_remove(struct platform_device *dev)
+{
+	int ret = gpiochip_remove(&ichx_priv.chip);
+
+	/* Restore original GPIO control register value */
+	pci_write_config_dword(ichx_priv.pdev, PCI_ICHX_GPIO_CTRL,
+			ichx_priv.orig_gpio_ctrl);
+
+	return ret;
+}
+
+static struct platform_driver ichx_gpio_driver = {
+	.driver		= {
+		.owner	= THIS_MODULE,
+		.name	= DRV_NAME,
+	},
+	.probe		= ichx_gpio_probe,
+	.remove		= __devexit_p(ichx_gpio_remove),
+};
+
+static int __devinit ichx_gpio_init_module(void)
+{
+	int err = platform_driver_register(&ichx_gpio_driver);
+	if (err)
+		return err;
+
+	ichx_gpio_platform_device =
+		platform_device_register_simple(DRV_NAME, -1, NULL, 0);
+
+	if (IS_ERR(ichx_gpio_platform_device)) {
+		err = PTR_ERR(ichx_gpio_platform_device);
+		goto unreg_platform_driver;
+	}
+
+	return 0;
+
+unreg_platform_driver:
+	platform_driver_unregister(&ichx_gpio_driver);
+	return err;
+}
+
+static void __devexit ichx_gpio_exit_module(void)
+{
+	platform_device_unregister(ichx_gpio_platform_device);
+	platform_driver_unregister(&ichx_gpio_driver);
+}
+
+module_init(ichx_gpio_init_module);
+module_exit(ichx_gpio_exit_module);
+
+MODULE_AUTHOR("Peter Tyser <ptyser@xes-inc.com>");
+MODULE_DESCRIPTION("Intel ICHx series bridge GPIO driver");
+MODULE_LICENSE("GPL");
-- 
1.7.0.4


^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 3/3] gpio: Add support for Intel ICHx/3100/Series[56] GPIO
  2011-01-06 19:54 ` [PATCH 3/3] gpio: Add support for Intel ICHx/3100/Series[56] GPIO Peter Tyser
@ 2011-01-06 23:12   ` David Brownell
  0 siblings, 0 replies; 26+ messages in thread
From: David Brownell @ 2011-01-06 23:12 UTC (permalink / raw)
  To: linux-kernel, Peter Tyser
  Cc: Peter Tyser, Alek Du, Samuel Ortiz, David Brownell, Eric Miao,
	Uwe Kleine-K?nig, Mark Brown, Joe Perches


Interesting.  I had an ICH8 (plus) driver at
some point, but held back doing anything with it
because of the ACPI interactions needed on most
relevant hardware, for wakeups and other issues.
Regardless, I'm glad to see someone pick up on
the fact that these are just GPIOs, and that Linux
should be able to work with them

- Dave


^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 2/3] gpio: pca953x: Implement get_direction() hook
  2011-01-06 19:54 ` [PATCH 2/3] gpio: pca953x: Implement get_direction() hook Peter Tyser
@ 2011-01-06 23:16   ` David Brownell
  0 siblings, 0 replies; 26+ messages in thread
From: David Brownell @ 2011-01-06 23:16 UTC (permalink / raw)
  To: linux-kernel, Peter Tyser
  Cc: Peter Tyser, Alek Du, Samuel Ortiz, David Brownell, Eric Miao,
	Uwe Kleine-K?nig, Mark Brown, Joe Perches



--- On Thu, 1/6/11, Peter Tyser <ptyser@xes-inc.com> wrote:

> Subject: [PATCH 2/3] gpio: pca953x: Implement get_direction() hook


Ack   This can affect initialization too ISTR.


^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 1/3] gpiolib: Add ability to get GPIO pin direction
  2011-01-06 19:54 [PATCH 1/3] gpiolib: Add ability to get GPIO pin direction Peter Tyser
  2011-01-06 19:54 ` [PATCH 2/3] gpio: pca953x: Implement get_direction() hook Peter Tyser
  2011-01-06 19:54 ` [PATCH 3/3] gpio: Add support for Intel ICHx/3100/Series[56] GPIO Peter Tyser
@ 2011-02-14 15:48 ` Peter Tyser
  2011-02-14 16:02   ` Grant Likely
  2011-02-14 17:08   ` Alan Cox
  2 siblings, 2 replies; 26+ messages in thread
From: Peter Tyser @ 2011-02-14 15:48 UTC (permalink / raw)
  To: linux-kernel
  Cc: Alek Du, Samuel Ortiz, David Brownell, Eric Miao,
	Uwe Kleine-K?nig, Mark Brown, Joe Perches, grant.likely

On Thu, 2011-01-06 at 13:54 -0600, Peter Tyser wrote:
> Add a new get_direction() function to the gpio_chip structure.  This is
> useful so that the direction of a pin can be determined when its
> exported.  Previously, the direction defaulted to 'in' regardless of the
> actual configuration of the GPIO pin which resulted in the 'direction'
> sysfs file often being incorrect.
> 
> If a GPIO driver implements get_direction(), it is called in
> gpio_request() to set the initial direction of the pin accurately.

I see Grant was just added as a GPIO maintainer, so added him on CC.

Anything gating getting these 3 patches being picked up?

Thanks,
Peter


^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 1/3] gpiolib: Add ability to get GPIO pin direction
  2011-02-14 15:48 ` [PATCH 1/3] gpiolib: Add ability to get GPIO pin direction Peter Tyser
@ 2011-02-14 16:02   ` Grant Likely
  2011-02-14 19:14     ` Grant Likely
  2011-02-14 17:08   ` Alan Cox
  1 sibling, 1 reply; 26+ messages in thread
From: Grant Likely @ 2011-02-14 16:02 UTC (permalink / raw)
  To: Peter Tyser
  Cc: linux-kernel, Alek Du, Samuel Ortiz, David Brownell, Eric Miao,
	Uwe Kleine-K?nig, Mark Brown, Joe Perches

On Mon, Feb 14, 2011 at 8:48 AM, Peter Tyser <ptyser@xes-inc.com> wrote:
> On Thu, 2011-01-06 at 13:54 -0600, Peter Tyser wrote:
>> Add a new get_direction() function to the gpio_chip structure.  This is
>> useful so that the direction of a pin can be determined when its
>> exported.  Previously, the direction defaulted to 'in' regardless of the
>> actual configuration of the GPIO pin which resulted in the 'direction'
>> sysfs file often being incorrect.
>>
>> If a GPIO driver implements get_direction(), it is called in
>> gpio_request() to set the initial direction of the pin accurately.
>
> I see Grant was just added as a GPIO maintainer, so added him on CC.
>
> Anything gating getting these 3 patches being picked up?

I'll take a look at them later today.

g.

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 1/3] gpiolib: Add ability to get GPIO pin direction
  2011-02-14 15:48 ` [PATCH 1/3] gpiolib: Add ability to get GPIO pin direction Peter Tyser
  2011-02-14 16:02   ` Grant Likely
@ 2011-02-14 17:08   ` Alan Cox
  2011-02-14 17:26     ` Grant Likely
  1 sibling, 1 reply; 26+ messages in thread
From: Alan Cox @ 2011-02-14 17:08 UTC (permalink / raw)
  To: Peter Tyser
  Cc: linux-kernel, Alek Du, Samuel Ortiz, David Brownell, Eric Miao,
	Uwe Kleine-K?nig, Mark Brown, Joe Perches, grant.likely

> > If a GPIO driver implements get_direction(), it is called in
> > gpio_request() to set the initial direction of the pin accurately.
> 
> I see Grant was just added as a GPIO maintainer, so added him on CC.
> 
> Anything gating getting these 3 patches being picked up?

We need four states for a gpio pin direction though. A pin can be

- input
- output
- unknown (hardware lacks get functionality and it has not been set by
  software yet)
- alt_func (pin is in use for some other purpose)

(and being able to set them alt_func was proposed a while ago and I think
wants revisiting judging by the number of platforms which use gpio, and
in their own arch code are privately handling alt_func stuff)

Alan

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 1/3] gpiolib: Add ability to get GPIO pin direction
  2011-02-14 17:08   ` Alan Cox
@ 2011-02-14 17:26     ` Grant Likely
  2011-02-14 17:39       ` Mark Brown
                         ` (2 more replies)
  0 siblings, 3 replies; 26+ messages in thread
From: Grant Likely @ 2011-02-14 17:26 UTC (permalink / raw)
  To: Alan Cox
  Cc: Peter Tyser, linux-kernel, Alek Du, Samuel Ortiz, David Brownell,
	Eric Miao, Uwe Kleine-K?nig, Mark Brown, Joe Perches

On Mon, Feb 14, 2011 at 10:08 AM, Alan Cox <alan@lxorguk.ukuu.org.uk> wrote:
>> > If a GPIO driver implements get_direction(), it is called in
>> > gpio_request() to set the initial direction of the pin accurately.
>>
>> I see Grant was just added as a GPIO maintainer, so added him on CC.
>>
>> Anything gating getting these 3 patches being picked up?
>
> We need four states for a gpio pin direction though. A pin can be
>
> - input
> - output

There are actually multiple output modes that a specific gpio
controller could implement, but the gpio api only has a boolean
understanding of output.  I don't know if it is really worthwhile to
try and encode all the possible configurations in this API.

> - unknown (hardware lacks get functionality and it has not been set by
>  software yet)
> - alt_func (pin is in use for some other purpose)

What is the use-case for alt_func?  From the point of view of a GPIO
driver, I don't think it cares if the pin has been dedicated to
something else.  It can twiddle all it wants, but if the pin is routed
to something else then it won't have any external effects (pin mux is
often a separate logic block from the gpio controller).  Also with
GPIOs, the engineers fiddling with them *really* needs to know what
the gpios are routed to.  It is highly unlikely to have any kind of
automatic configuration of gpios; ie. if it isn't wired as a gpio,
then don't go twiddling it.

>
> (and being able to set them alt_func was proposed a while ago and I think
> wants revisiting judging by the number of platforms which use gpio, and
> in their own arch code are privately handling alt_func stuff)

Fair enough; convince me on alt_func.  What is the use case that I'm missing?

g.

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 1/3] gpiolib: Add ability to get GPIO pin direction
  2011-02-14 17:26     ` Grant Likely
@ 2011-02-14 17:39       ` Mark Brown
  2011-02-14 17:45       ` Peter Tyser
  2011-02-14 19:35       ` Alan Cox
  2 siblings, 0 replies; 26+ messages in thread
From: Mark Brown @ 2011-02-14 17:39 UTC (permalink / raw)
  To: Grant Likely
  Cc: Alan Cox, Peter Tyser, linux-kernel, Alek Du, Samuel Ortiz,
	David Brownell, Eric Miao, Uwe Kleine-K?nig, Joe Perches

On Mon, Feb 14, 2011 at 10:26:18AM -0700, Grant Likely wrote:
> On Mon, Feb 14, 2011 at 10:08 AM, Alan Cox <alan@lxorguk.ukuu.org.uk> wrote:

> > - input
> > - output

> There are actually multiple output modes that a specific gpio
> controller could implement, but the gpio api only has a boolean
> understanding of output.  I don't know if it is really worthwhile to
> try and encode all the possible configurations in this API.

Ditto for inputs, and of course there's all the pad configuration stuff.

> > - alt_func (pin is in use for some other purpose)

> What is the use-case for alt_func?  From the point of view of a GPIO
> driver, I don't think it cares if the pin has been dedicated to
> something else.  It can twiddle all it wants, but if the pin is routed
> to something else then it won't have any external effects (pin mux is
> often a separate logic block from the gpio controller).  Also with

Not always entirely true, some of the controllers I've worked with have
input and output both as alternate functions among the others there so
selecting input or output mode will tend to force the mode but...

> GPIOs, the engineers fiddling with them *really* needs to know what
> the gpios are routed to.  It is highly unlikely to have any kind of
> automatic configuration of gpios; ie. if it isn't wired as a gpio,
> then don't go twiddling it.

...it doesn't make much difference for the reasons you mention.

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 1/3] gpiolib: Add ability to get GPIO pin direction
  2011-02-14 17:26     ` Grant Likely
  2011-02-14 17:39       ` Mark Brown
@ 2011-02-14 17:45       ` Peter Tyser
  2011-02-14 18:04         ` Grant Likely
  2011-02-14 19:35       ` Alan Cox
  2 siblings, 1 reply; 26+ messages in thread
From: Peter Tyser @ 2011-02-14 17:45 UTC (permalink / raw)
  To: Grant Likely
  Cc: Alan Cox, linux-kernel, Alek Du, Samuel Ortiz, David Brownell,
	Eric Miao, Uwe Kleine-K?nig, Mark Brown, Joe Perches

> > We need four states for a gpio pin direction though. A pin can be
> >
> > - input
> > - output
> 
> There are actually multiple output modes that a specific gpio
> controller could implement, but the gpio api only has a boolean
> understanding of output.  I don't know if it is really worthwhile to
> try and encode all the possible configurations in this API.
> 
> > - unknown (hardware lacks get functionality and it has not been set by
> >  software yet)

I'm not sure how we could handle unknown directions in a better way.  We
really should know the direction by this point for most (all?) GPIO
chips.  I'd think the proper fix would be to make sure we can detect a
direction for all chips - either by reading hardware bits or by having
the platform code let us know (eg pdata->n_latch in pcf857x.c).  If you
have a suggestion about how unknown pins should be used, I can look into
it and submit a follow up patch.

> > - alt_func (pin is in use for some other purpose)
> 
> What is the use-case for alt_func?  From the point of view of a GPIO
> driver, I don't think it cares if the pin has been dedicated to
> something else.  It can twiddle all it wants, but if the pin is routed
> to something else then it won't have any external effects (pin mux is
> often a separate logic block from the gpio controller).  Also with
> GPIOs, the engineers fiddling with them *really* needs to know what
> the gpios are routed to.  It is highly unlikely to have any kind of
> automatic configuration of gpios; ie. if it isn't wired as a gpio,
> then don't go twiddling it.

Additionally, for this case I thought the low level GPIO driver should
implement a request() function to prevent a non-GPIO pin from being used
in the first place.  Eg like chip_gpio_request() in cs5535-gpio.c, or
ichx_gpio_request() in patch 3 of this series.

> > (and being able to set them alt_func was proposed a while ago and I think
> > wants revisiting judging by the number of platforms which use gpio, and
> > in their own arch code are privately handling alt_func stuff)
> 
> Fair enough; convince me on alt_func.  What is the use case that I'm missing?

Peter


^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 1/3] gpiolib: Add ability to get GPIO pin direction
  2011-02-14 17:45       ` Peter Tyser
@ 2011-02-14 18:04         ` Grant Likely
  2011-02-14 18:46           ` Peter Tyser
  0 siblings, 1 reply; 26+ messages in thread
From: Grant Likely @ 2011-02-14 18:04 UTC (permalink / raw)
  To: Peter Tyser
  Cc: Alan Cox, linux-kernel, Alek Du, Samuel Ortiz, David Brownell,
	Eric Miao, Uwe Kleine-K?nig, Mark Brown, Joe Perches

On Mon, Feb 14, 2011 at 10:45 AM, Peter Tyser <ptyser@xes-inc.com> wrote:
>> > We need four states for a gpio pin direction though. A pin can be
>> >
>> > - input
>> > - output
>>
>> There are actually multiple output modes that a specific gpio
>> controller could implement, but the gpio api only has a boolean
>> understanding of output.  I don't know if it is really worthwhile to
>> try and encode all the possible configurations in this API.
>>
>> > - unknown (hardware lacks get functionality and it has not been set by
>> >  software yet)
>
> I'm not sure how we could handle unknown directions in a better way.  We
> really should know the direction by this point for most (all?) GPIO
> chips.  I'd think the proper fix would be to make sure we can detect a
> direction for all chips - either by reading hardware bits or by having
> the platform code let us know (eg pdata->n_latch in pcf857x.c).  If you
> have a suggestion about how unknown pins should be used, I can look into
> it and submit a follow up patch.

Does it really matter?  Sure it's *nice* to have the current status
information if the driver can easily get it, but it probably isn't
critical.  Any user of the pin should be putting the pin in the mode
it needs regardless of the initial state.

>
>> > - alt_func (pin is in use for some other purpose)
>>
>> What is the use-case for alt_func?  From the point of view of a GPIO
>> driver, I don't think it cares if the pin has been dedicated to
>> something else.  It can twiddle all it wants, but if the pin is routed
>> to something else then it won't have any external effects (pin mux is
>> often a separate logic block from the gpio controller).  Also with
>> GPIOs, the engineers fiddling with them *really* needs to know what
>> the gpios are routed to.  It is highly unlikely to have any kind of
>> automatic configuration of gpios; ie. if it isn't wired as a gpio,
>> then don't go twiddling it.
>
> Additionally, for this case I thought the low level GPIO driver should
> implement a request() function to prevent a non-GPIO pin from being used
> in the first place.  Eg like chip_gpio_request() in cs5535-gpio.c, or
> ichx_gpio_request() in patch 3 of this series.

Yes, *if* a driver has the knowledge that a pin is unusable, then it
should not allow the pin to be requested.

g.

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 1/3] gpiolib: Add ability to get GPIO pin direction
  2011-02-14 18:04         ` Grant Likely
@ 2011-02-14 18:46           ` Peter Tyser
  0 siblings, 0 replies; 26+ messages in thread
From: Peter Tyser @ 2011-02-14 18:46 UTC (permalink / raw)
  To: Grant Likely
  Cc: Alan Cox, linux-kernel, Alek Du, Samuel Ortiz, David Brownell,
	Eric Miao, Uwe Kleine-K?nig, Mark Brown, Joe Perches

On Mon, 2011-02-14 at 11:04 -0700, Grant Likely wrote:
> On Mon, Feb 14, 2011 at 10:45 AM, Peter Tyser <ptyser@xes-inc.com> wrote:
> >> > We need four states for a gpio pin direction though. A pin can be
> >> >
> >> > - input
> >> > - output
> >>
> >> There are actually multiple output modes that a specific gpio
> >> controller could implement, but the gpio api only has a boolean
> >> understanding of output.  I don't know if it is really worthwhile to
> >> try and encode all the possible configurations in this API.
> >>
> >> > - unknown (hardware lacks get functionality and it has not been set by
> >> >  software yet)
> >
> > I'm not sure how we could handle unknown directions in a better way.  We
> > really should know the direction by this point for most (all?) GPIO
> > chips.  I'd think the proper fix would be to make sure we can detect a
> > direction for all chips - either by reading hardware bits or by having
> > the platform code let us know (eg pdata->n_latch in pcf857x.c).  If you
> > have a suggestion about how unknown pins should be used, I can look into
> > it and submit a follow up patch.
> 
> Does it really matter?  Sure it's *nice* to have the current status
> information if the driver can easily get it, but it probably isn't
> critical.  Any user of the pin should be putting the pin in the mode
> it needs regardless of the initial state.

I don't think it matters too much since I haven't encountered a driver
where you can't determine a pin direction yet.  But if it were
impossible to determine a direction, it would throw people off.  They'd
have to know that the pin direction couldn't be trusted initially, which
is a big leap (this is the bug I'm trying to fix with this patch).  Eg
if someone sees a pin direction as "input" via sysfs, what are the odds
that they'll run "echo input > direction" just to make sure...

Anyway, I don't think its a critical issue either since its a corner
case with an easy workaround.  If we did want to add support for
allowing a direction of "unknown", it could be in a follow up patch
since its technically a bigger issue than this patch.

Peter


^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 1/3] gpiolib: Add ability to get GPIO pin direction
  2011-02-14 16:02   ` Grant Likely
@ 2011-02-14 19:14     ` Grant Likely
  2011-02-14 20:01       ` Peter Tyser
  0 siblings, 1 reply; 26+ messages in thread
From: Grant Likely @ 2011-02-14 19:14 UTC (permalink / raw)
  To: Peter Tyser
  Cc: linux-kernel, Alek Du, Samuel Ortiz, David Brownell, Eric Miao,
	Uwe Kleine-K?nig, Mark Brown, Joe Perches

On Mon, Feb 14, 2011 at 09:02:02AM -0700, Grant Likely wrote:
> On Mon, Feb 14, 2011 at 8:48 AM, Peter Tyser <ptyser@xes-inc.com> wrote:
> > On Thu, 2011-01-06 at 13:54 -0600, Peter Tyser wrote:
> >> Add a new get_direction() function to the gpio_chip structure.  This is
> >> useful so that the direction of a pin can be determined when its
> >> exported.  Previously, the direction defaulted to 'in' regardless of the
> >> actual configuration of the GPIO pin which resulted in the 'direction'
> >> sysfs file often being incorrect.
> >>
> >> If a GPIO driver implements get_direction(), it is called in
> >> gpio_request() to set the initial direction of the pin accurately.
> >
> > I see Grant was just added as a GPIO maintainer, so added him on CC.
> >
> > Anything gating getting these 3 patches being picked up?
> 
> I'll take a look at them later today.

What are the other two patches?  I only see this one.  Can you repost?

g.

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 1/3] gpiolib: Add ability to get GPIO pin direction
  2011-02-14 17:26     ` Grant Likely
  2011-02-14 17:39       ` Mark Brown
  2011-02-14 17:45       ` Peter Tyser
@ 2011-02-14 19:35       ` Alan Cox
  2011-02-14 23:35         ` Peter Tyser
  2011-03-06  7:49         ` Grant Likely
  2 siblings, 2 replies; 26+ messages in thread
From: Alan Cox @ 2011-02-14 19:35 UTC (permalink / raw)
  To: Grant Likely
  Cc: Peter Tyser, linux-kernel, Alek Du, Samuel Ortiz, David Brownell,
	Eric Miao, Uwe Kleine-K?nig, Mark Brown, Joe Perches

> What is the use-case for alt_func?  From the point of view of a GPIO
> driver, I don't think it cares if the pin has been dedicated to

Currently it doesn't.

However the moment it starts setting input and output itself on requests
then it does because it may kick the pin out of alt_func mode when you
merely want to request it so you know which pin to stick into alt_func
mode, or to find a mapping. The current situation is an "ignorance is
bliss" one, but making it smarter backfires. We have the same problem
with unknown state - if I have a set of pins some of whose state is known
at boot time then I can't now provide a get_direction interface because
of the lack of states. At the very least we need input/output/godknows
where the latter means the gpio_request code keeps its nose out.

	reconfigure_resource();
	see_if_we_own_it()

is simply the wrong order for a resource.


The second problem is that in many cases you need to call gpio_request to
know you have the pin yourself before you can set the direction. That
means forcing the direction in gpio_request is daft - you force an
undefined value that cannot yet safely be set in all cases.

At the moment the lack of alt_func also has some strange effects and you
end up with code like

foo_firmware_update()
{
	/* Reserve the line for alt_func use for the moment */
	gpio_request(GPIO_FOO, "blah");
	random_gpio_driver_specific_altfunc_foo();
	do stuff();
	random_gpio_driver_specific_altfunc_foo();
	gpio_free(GPIO_FOO);

	/* Now available again for its normal GPIO use */
}


and that means you can't generalise dynamic access to a shared GPIO pin
without extra hardcoded knowledge.

In the case of a fixed pin its easy as you can either a) not register it
or b) just gpio_request it at boot and whack it in arch code, but if you
want to go beyond that it gets interesting.

Alan

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 1/3] gpiolib: Add ability to get GPIO pin direction
  2011-02-14 19:14     ` Grant Likely
@ 2011-02-14 20:01       ` Peter Tyser
  0 siblings, 0 replies; 26+ messages in thread
From: Peter Tyser @ 2011-02-14 20:01 UTC (permalink / raw)
  To: Grant Likely
  Cc: linux-kernel, Alek Du, Samuel Ortiz, David Brownell, Eric Miao,
	Uwe Kleine-K?nig, Mark Brown, Joe Perches

On Mon, 2011-02-14 at 12:14 -0700, Grant Likely wrote:
> On Mon, Feb 14, 2011 at 09:02:02AM -0700, Grant Likely wrote:
> > On Mon, Feb 14, 2011 at 8:48 AM, Peter Tyser <ptyser@xes-inc.com> wrote:
> > > On Thu, 2011-01-06 at 13:54 -0600, Peter Tyser wrote:
> > >> Add a new get_direction() function to the gpio_chip structure.  This is
> > >> useful so that the direction of a pin can be determined when its
> > >> exported.  Previously, the direction defaulted to 'in' regardless of the
> > >> actual configuration of the GPIO pin which resulted in the 'direction'
> > >> sysfs file often being incorrect.
> > >>
> > >> If a GPIO driver implements get_direction(), it is called in
> > >> gpio_request() to set the initial direction of the pin accurately.
> > >
> > > I see Grant was just added as a GPIO maintainer, so added him on CC.
> > >
> > > Anything gating getting these 3 patches being picked up?
> > 
> > I'll take a look at them later today.
> 
> What are the other two patches?  I only see this one.  Can you repost?

I just resent the 3 patches to you off-list.  They can also be found at:
https://patchwork.kernel.org/patch/460411/
https://patchwork.kernel.org/patch/460321/
https://patchwork.kernel.org/patch/460331/

Peter


^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 1/3] gpiolib: Add ability to get GPIO pin direction
  2011-02-14 19:35       ` Alan Cox
@ 2011-02-14 23:35         ` Peter Tyser
  2011-02-15 11:42           ` Alan Cox
  2011-02-15 23:55           ` Mark Brown
  2011-03-06  7:49         ` Grant Likely
  1 sibling, 2 replies; 26+ messages in thread
From: Peter Tyser @ 2011-02-14 23:35 UTC (permalink / raw)
  To: Alan Cox
  Cc: Grant Likely, linux-kernel, Alek Du, Samuel Ortiz,
	David Brownell, Eric Miao, Uwe Kleine-K?nig, Mark Brown,
	Joe Perches

On Mon, 2011-02-14 at 19:35 +0000, Alan Cox wrote:
> > What is the use-case for alt_func?  From the point of view of a GPIO
> > driver, I don't think it cares if the pin has been dedicated to
> 
> Currently it doesn't.
> 
> However the moment it starts setting input and output itself on requests
> then it does because it may kick the pin out of alt_func mode when you
> merely want to request it so you know which pin to stick into alt_func
> mode, or to find a mapping. The current situation is an "ignorance is
> bliss" one, but making it smarter backfires. We have the same problem
> with unknown state - if I have a set of pins some of whose state is known
> at boot time then I can't now provide a get_direction interface because
> of the lack of states. At the very least we need input/output/godknows
> where the latter means the gpio_request code keeps its nose out.
> 
> 	reconfigure_resource();
> 	see_if_we_own_it()
> 
> is simply the wrong order for a resource.

It looks like most drivers that implement a chip-specific request()
function do check if the gpio pin is available for use prior to
reconfiguring it.  If a pin is reserved for an alt_func, the request
fails and the pin is not touched.  Seems like adding a well coded
chip-specific request() function to drivers where necessary would
resolve your concern about reconfiguring pins before checking ownership?

> The second problem is that in many cases you need to call gpio_request to
> know you have the pin yourself before you can set the direction. That
> means forcing the direction in gpio_request is daft - you force an
> undefined value that cannot yet safely be set in all cases.

My understanding is that gpio_request() doesn't generally force a
direction, it just sets up the pin for use, or checks to make sure the
pin could be used.  Most chip's don't have their own request() function
and thus don't touch hardware at all.  For those that do have their own
request() function, they don't appear to force a value in many cases.

Also, in most cases I'd think that the BIOS/U-Boot/firmware should have
configured the GPIO pins appropriately, which Linux should inherit in
general.  Linux currently inherits GPIO states that were set in firmware
when a GPIO is requested, but it doesn't properly report those values
via sysfs - that's the only bug I'm trying to fix.

> At the moment the lack of alt_func also has some strange effects and you
> end up with code like
> 
> foo_firmware_update()
> {
> 	/* Reserve the line for alt_func use for the moment */
> 	gpio_request(GPIO_FOO, "blah");
> 	random_gpio_driver_specific_altfunc_foo();
> 	do stuff();
> 	random_gpio_driver_specific_altfunc_foo();
> 	gpio_free(GPIO_FOO);
> 
> 	/* Now available again for its normal GPIO use */
> }
> 
> 
> and that means you can't generalise dynamic access to a shared GPIO pin
> without extra hardcoded knowledge.

Are there many cases where people need to swap a pin from GPIO to alt
functionality, and back again in Linux?  I have never seen them used
like that; generally they are either wired up to an alt_func device (I2C
pins, serial pins, etc), or as a GPIO - not both dynamically.  If some
hardware does need to do that, isn't it very chipset/board specific?  I
guess I'm just not really grasping the big advantage of the alt_func
feature, or how it'd be implemented as common code.  It looks like there
was a thread about it back in 2009 that didn't go anywhere:
http://thread.gmane.org/gmane.linux.kernel/851818

The current GPIO implementation has worked well for my usage scenarios,
so you may have to be blunt with me as far as what your looking for:)

Thanks,
Peter 


^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 1/3] gpiolib: Add ability to get GPIO pin direction
  2011-02-14 23:35         ` Peter Tyser
@ 2011-02-15 11:42           ` Alan Cox
  2011-02-15 17:05             ` Peter Tyser
  2011-02-15 23:55           ` Mark Brown
  1 sibling, 1 reply; 26+ messages in thread
From: Alan Cox @ 2011-02-15 11:42 UTC (permalink / raw)
  To: Peter Tyser
  Cc: Grant Likely, linux-kernel, Alek Du, Samuel Ortiz,
	David Brownell, Eric Miao, Uwe Kleine-K?nig, Mark Brown,
	Joe Perches

> fails and the pin is not touched.  Seems like adding a well coded
> chip-specific request() function to drivers where necessary would
> resolve your concern about reconfiguring pins before checking ownership?

That seems sensible and it keeps the knowledge out of gpiolib.

> Also, in most cases I'd think that the BIOS/U-Boot/firmware should have
> configured the GPIO pins appropriately, which Linux should inherit in
> general.  Linux currently inherits GPIO states that were set in firmware
> when a GPIO is requested, but it doesn't properly report those values
> via sysfs - that's the only bug I'm trying to fix.

Yes - however you can't fix it unless you are prepared to admit that the
gpio has multiple states. At minimum you need to be able to report

	input/output/unknown/unavailable

if you want to generalise it. Otherwise you don't solve the problem
because you are asking a question that driver cannot answer correctly.

> Are there many cases where people need to swap a pin from GPIO to alt
> functionality, and back again in Linux?  I have never seen them used
> like that

Well I'm not surprised - you can't currently do it that way. The code
doesn't support it, instead such things are buried in arch code and
driver specific goo. I question whether it should be buried away like
that.

That's really about Grant's why do we need it comment rather than about
your bits. From the point of view of direction reporting (which I'm fully
in favour of) the only problem that matters is the fact a pin has a
minimum of four states to report. From that point of view  "unavailable"
is probably a better way to report it than alt_func as it covers all the
other "unavailable" cases that may exist and haven't yet been thought of.

Alan

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 1/3] gpiolib: Add ability to get GPIO pin direction
  2011-02-15 11:42           ` Alan Cox
@ 2011-02-15 17:05             ` Peter Tyser
  2011-02-15 17:19               ` Alan Cox
  2011-03-06  7:53               ` Grant Likely
  0 siblings, 2 replies; 26+ messages in thread
From: Peter Tyser @ 2011-02-15 17:05 UTC (permalink / raw)
  To: Alan Cox
  Cc: Grant Likely, linux-kernel, Alek Du, Samuel Ortiz,
	David Brownell, Eric Miao, Uwe Kleine-K?nig, Mark Brown,
	Joe Perches

> > Also, in most cases I'd think that the BIOS/U-Boot/firmware should have
> > configured the GPIO pins appropriately, which Linux should inherit in
> > general.  Linux currently inherits GPIO states that were set in firmware
> > when a GPIO is requested, but it doesn't properly report those values
> > via sysfs - that's the only bug I'm trying to fix.
> 
> Yes - however you can't fix it unless you are prepared to admit that the
> gpio has multiple states. At minimum you need to be able to report
> 
> 	input/output/unknown/unavailable
> 
> if you want to generalise it. Otherwise you don't solve the problem
> because you are asking a question that driver cannot answer correctly.

As far as the "unknown" state, I can update the patch to have the logic:
+       if (chip->get_direction) {
+               /* chip->get_direction may sleep */
+               spin_unlock_irqrestore(&gpio_lock, flags);
+               if (chip->get_direction(chip, gpio - chip->base) > 0)
+                       set_bit(FLAG_IS_OUT, &desc->flags);
+               spin_lock_irqsave(&gpio_lock, flags);
+       } else {
+               set_bit(FLAG_IS_UNKNOWN, &desc->flags);
+       }

This would have the side effect of having nearly all GPIO drivers
default to an "unknown" direction until they implement the new
get_direction() function, which I think is an improvement over the
current system where they are all unconditionally shown as "input",
often incorrectly.  Are you OK with this Grant?


For the "unavailable" state, I didn't think it would be necessary.  As
is, if someone calls gpio_request() on an invalid or alt_use pin, they
shouldn't get access to the GPIO, which makes the "unavailable value
moot since they couldn't access the GPIO in the first place.

Changing the logic to allow "unavailable" GPIO pins to be
requested/exported would require larger changes to the code, and
wouldn't provide much benefit without additional changes (eg an alt_func
feature).  So I'd vote to not add support for "unavailable" pins in this
patch and rather wait until someone has a specific use for it, and add
it then.

Peter


^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 1/3] gpiolib: Add ability to get GPIO pin direction
  2011-02-15 17:05             ` Peter Tyser
@ 2011-02-15 17:19               ` Alan Cox
  2011-02-15 17:49                 ` Peter Tyser
  2011-03-06  7:53               ` Grant Likely
  1 sibling, 1 reply; 26+ messages in thread
From: Alan Cox @ 2011-02-15 17:19 UTC (permalink / raw)
  To: Peter Tyser
  Cc: Grant Likely, linux-kernel, Alek Du, Samuel Ortiz,
	David Brownell, Eric Miao, Uwe Kleine-K?nig, Mark Brown,
	Joe Perches

> +       if (chip->get_direction) {
> +               /* chip->get_direction may sleep */
> +               spin_unlock_irqrestore(&gpio_lock, flags);
> +               if (chip->get_direction(chip, gpio - chip->base) > 0)
> +                       set_bit(FLAG_IS_OUT, &desc->flags);
> +               spin_lock_irqsave(&gpio_lock, flags);
> +       } else {
> +               set_bit(FLAG_IS_UNKNOWN, &desc->flags);
> +       }
> 
> This would have the side effect of having nearly all GPIO drivers
> default to an "unknown" direction until they implement the new
> get_direction() function, which I think is an improvement over the

This doesn't solve anything. If the hardware supports alt_func state then
it now can't implement get_direction, so that's useless.
 
> For the "unavailable" state, I didn't think it would be necessary.  As
> is, if someone calls gpio_request() on an invalid or alt_use pin, they
> shouldn't get access to the GPIO, which makes the "unavailable value
> moot since they couldn't access the GPIO in the first place.

In a word 'sysfs'

We need FLAG_IS_UNKNOWN (or saner would be FLAG_IS_IN to go with
FLAG_IS_OUT) to make the sysfs code report properly (and some other spots
fixing to make it work right)

If you add FLAG_IS_UNKNOWN then the other change you need is in

gpio_direction_show() which needs to also check the UNKNOWN bit and
report appropriately. That would fix that problem and at least allow the
reporting side of GPIO in use for something else to be handled as a
platform thing even though it can't be handled properly.

The combination of RESERVED & EXPORTED is also busted but is actually
sensible - that I gues should report reserved and fail the set operations.



^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 1/3] gpiolib: Add ability to get GPIO pin direction
  2011-02-15 17:19               ` Alan Cox
@ 2011-02-15 17:49                 ` Peter Tyser
  2011-02-15 19:41                   ` Alan Cox
  2011-02-17  8:06                   ` Uwe Kleine-König
  0 siblings, 2 replies; 26+ messages in thread
From: Peter Tyser @ 2011-02-15 17:49 UTC (permalink / raw)
  To: Alan Cox
  Cc: Grant Likely, linux-kernel, Alek Du, Samuel Ortiz,
	David Brownell, Eric Miao, Uwe Kleine-K?nig, Mark Brown,
	Joe Perches

On Tue, 2011-02-15 at 17:19 +0000, Alan Cox wrote:
> > +       if (chip->get_direction) {
> > +               /* chip->get_direction may sleep */
> > +               spin_unlock_irqrestore(&gpio_lock, flags);
> > +               if (chip->get_direction(chip, gpio - chip->base) > 0)
> > +                       set_bit(FLAG_IS_OUT, &desc->flags);
> > +               spin_lock_irqsave(&gpio_lock, flags);
> > +       } else {
> > +               set_bit(FLAG_IS_UNKNOWN, &desc->flags);
> > +       }
> > 
> > This would have the side effect of having nearly all GPIO drivers
> > default to an "unknown" direction until they implement the new
> > get_direction() function, which I think is an improvement over the
> 
> This doesn't solve anything. If the hardware supports alt_func state then
> it now can't implement get_direction, so that's useless.

I don't follow.  If a pin is configured for some alternate function,
then requesting it for GPIO should fail, thus it doesn't matter if it
implements get_direction()?  Since we can't easily toggle back and forth
between GPIO and alt_func, I'd think we shouldn't be able to request
alt_func pins for GPIO - they should be off-limits to the GPIO subsystem
altogether.

My understanding is that currently if some platform wants to toggle pins
back and forth between alt_func and GPIO, it needs to handle that logic
itself.  If platform code is handling that toggling, I'd think the GPIO
code should not touch pins configured as alt_func.  If the platform is
no longer using them as alt_func, then it should poke the appropriate
registers to make them not alt_func so that they can then be used by the
GPIO subsystem.

Maybe we disagree on the above point, which is adding to the confusion?

> > For the "unavailable" state, I didn't think it would be necessary.  As
> > is, if someone calls gpio_request() on an invalid or alt_use pin, they
> > shouldn't get access to the GPIO, which makes the "unavailable value
> > moot since they couldn't access the GPIO in the first place.
> 
> In a word 'sysfs'
> 
> We need FLAG_IS_UNKNOWN (or saner would be FLAG_IS_IN to go with
> FLAG_IS_OUT) to make the sysfs code report properly (and some other spots
> fixing to make it work right)

Agreed.

> If you add FLAG_IS_UNKNOWN then the other change you need is in
> 
> gpio_direction_show() which needs to also check the UNKNOWN bit and
> report appropriately.

Agreed.

> That would fix that problem and at least allow the
> reporting side of GPIO in use for something else to be handled as a
> platform thing even though it can't be handled properly.

I don't follow.  I don't think I'm grasping what you want for alt_func
pins in the short term.  Do you want them to be exported to the GPIO
sysfs filesystem and shown as "unavailable"?  If so, what advantage does
that have over not allowing them to be exported/reserved in the first
place?

Peter





^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 1/3] gpiolib: Add ability to get GPIO pin direction
  2011-02-15 17:49                 ` Peter Tyser
@ 2011-02-15 19:41                   ` Alan Cox
  2011-02-17  8:06                   ` Uwe Kleine-König
  1 sibling, 0 replies; 26+ messages in thread
From: Alan Cox @ 2011-02-15 19:41 UTC (permalink / raw)
  To: Peter Tyser
  Cc: Grant Likely, linux-kernel, Alek Du, Samuel Ortiz,
	David Brownell, Eric Miao, Uwe Kleine-K?nig, Mark Brown,
	Joe Perches

> My understanding is that currently if some platform wants to toggle pins
> back and forth between alt_func and GPIO, it needs to handle that logic
> itself.  If platform code is handling that toggling, I'd think the GPIO

Yes - which is broken as you can't abstract it to the drivers which is
the whole point of GPIO. Anyway put that bit aside - for the get method
it's not actually important since we need an unknown state anyway and
alt_func is unknown or similar.

> > That would fix that problem and at least allow the
> > reporting side of GPIO in use for something else to be handled as a
> > platform thing even though it can't be handled properly.
> 
> I don't follow.  I don't think I'm grasping what you want for alt_func
> pins in the short term.  Do you want them to be exported to the GPIO
> sysfs filesystem and shown as "unavailable"?  If so, what advantage does
> that have over not allowing them to be exported/reserved in the first
> place?

You can see what state they are in. Otherwise you have to clone the GPIO
sysfs to expose private platform specific magic to indicate that.

Anyway first step is to allow 'Unknown' to be reported by a get_direction
method. The direction of a pin in some magic platform owned state is
defacto 'unknown'.

Not having a get_direction method doesn't help as we don't support
changing the methods on the fly (which is horrid for locking and best
kept that way) so we need a way to return input/output/beats me

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 1/3] gpiolib: Add ability to get GPIO pin direction
  2011-02-14 23:35         ` Peter Tyser
  2011-02-15 11:42           ` Alan Cox
@ 2011-02-15 23:55           ` Mark Brown
  1 sibling, 0 replies; 26+ messages in thread
From: Mark Brown @ 2011-02-15 23:55 UTC (permalink / raw)
  To: Peter Tyser
  Cc: Alan Cox, Grant Likely, linux-kernel, Alek Du, Samuel Ortiz,
	David Brownell, Eric Miao, Uwe Kleine-K?nig, Joe Perches

On Mon, Feb 14, 2011 at 05:35:02PM -0600, Peter Tyser wrote:

> Also, in most cases I'd think that the BIOS/U-Boot/firmware should have
> configured the GPIO pins appropriately, which Linux should inherit in
> general.  Linux currently inherits GPIO states that were set in firmware
> when a GPIO is requested, but it doesn't properly report those values
> via sysfs - that's the only bug I'm trying to fix.

That's one model for these things but it's *far* from universal.
Another model which is at least as common is that the bootloader does
the minimum possible to transfer control to Linux which then does the
actual configuration for the system.

> Are there many cases where people need to swap a pin from GPIO to alt
> functionality, and back again in Linux?  I have never seen them used
> like that; generally they are either wired up to an alt_func device (I2C
> pins, serial pins, etc), or as a GPIO - not both dynamically.  If some
> hardware does need to do that, isn't it very chipset/board specific?  I

No, it's very rare.  One example we have in the kernel is the PXA27x
AC'97 driver - the controller doesn't generate one of the resets
correctly so the driver puts the signals into GPIO mode and manually
generates the reset on the bus for the CODEC when it needs to do so.

> guess I'm just not really grasping the big advantage of the alt_func
> feature, or how it'd be implemented as common code.  It looks like there
> was a thread about it back in 2009 that didn't go anywhere:
> http://thread.gmane.org/gmane.linux.kernel/851818

I tend to agree; I strongly expect that any alternate function code
would just wind up feeding at best device specific if not system
specific constants through and give us no more generality than we have
now.

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 1/3] gpiolib: Add ability to get GPIO pin direction
  2011-02-15 17:49                 ` Peter Tyser
  2011-02-15 19:41                   ` Alan Cox
@ 2011-02-17  8:06                   ` Uwe Kleine-König
  1 sibling, 0 replies; 26+ messages in thread
From: Uwe Kleine-König @ 2011-02-17  8:06 UTC (permalink / raw)
  To: Peter Tyser
  Cc: Alan Cox, Grant Likely, linux-kernel, Alek Du, Samuel Ortiz,
	David Brownell, Eric Miao, Mark Brown, Joe Perches

On Tue, Feb 15, 2011 at 11:49:11AM -0600, Peter Tyser wrote:
> On Tue, 2011-02-15 at 17:19 +0000, Alan Cox wrote:
> > > +       if (chip->get_direction) {
> > > +               /* chip->get_direction may sleep */
> > > +               spin_unlock_irqrestore(&gpio_lock, flags);
> > > +               if (chip->get_direction(chip, gpio - chip->base) > 0)
> > > +                       set_bit(FLAG_IS_OUT, &desc->flags);
> > > +               spin_lock_irqsave(&gpio_lock, flags);
> > > +       } else {
> > > +               set_bit(FLAG_IS_UNKNOWN, &desc->flags);
> > > +       }
> > > 
> > > This would have the side effect of having nearly all GPIO drivers
> > > default to an "unknown" direction until they implement the new
> > > get_direction() function, which I think is an improvement over the
> > 
> > This doesn't solve anything. If the hardware supports alt_func state then
> > it now can't implement get_direction, so that's useless.
> 
> I don't follow.  If a pin is configured for some alternate function,
> then requesting it for GPIO should fail, thus it doesn't matter if it
> implements get_direction()?  Since we can't easily toggle back and forth
> between GPIO and alt_func, I'd think we shouldn't be able to request
> alt_func pins for GPIO - they should be off-limits to the GPIO subsystem
> altogether.
hmm, I'm not sure.  Letting gpio_request fail looks good from the POV of
an uninformed driver.  But for some platform code, it seems more natural
to do:

	gpio_request(mygpio);
	myplatform_iomux_setup(pad_for_altfunc);
	do_something_special();
	/*
	 * the controler is unable to reset some component, so use
	 * bitbanging for that
	 */
	myplatform_iomux_setup(pad_for_gpio);
	gpio_direction_output(mygpio, 0);
	usleep(100);
	myplatform_iomux_setup(pad_for_altfunc);
	...

instead of only being able to gpio_request after
myplatform_iomux_setup(pad_for_gpio). (And so in theory take that risk
that another process grabs the gpio between mux-for-gpio and
gpio_request.) So if you ask me, it's gpio_direction_{in,out}put that
should fail, not gpio_request.  But I'm not that sure about it to
already know now to keep this opinion until after this discussion is
over.

> My understanding is that currently if some platform wants to toggle pins
> back and forth between alt_func and GPIO, it needs to handle that logic
> itself.  If platform code is handling that toggling, I'd think the GPIO
> code should not touch pins configured as alt_func.  If the platform is
> no longer using them as alt_func, then it should poke the appropriate
> registers to make them not alt_func so that they can then be used by the
> GPIO subsystem.
.. or at least make the usage via the gpio subsystem fail using it.
OTOH on arm/plat-mxc (at least the newer chips) there is no easy mapping
between pads and gpios.  So currently we do:  gpio_request and
gpio_direction_{in,out}put yield 0, but it depends on the pin muxing if
the gpio is "visible" anywhere.  I don't like that much, but I agree
that it's not worth to setup a huge table to map gpios to pads and back
just to return -ESOMETHING in the gpio functions.
 
Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-König            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 1/3] gpiolib: Add ability to get GPIO pin direction
  2011-02-14 19:35       ` Alan Cox
  2011-02-14 23:35         ` Peter Tyser
@ 2011-03-06  7:49         ` Grant Likely
  1 sibling, 0 replies; 26+ messages in thread
From: Grant Likely @ 2011-03-06  7:49 UTC (permalink / raw)
  To: Alan Cox
  Cc: Peter Tyser, linux-kernel, Alek Du, Samuel Ortiz, David Brownell,
	Eric Miao, Uwe Kleine-K?nig, Mark Brown, Joe Perches

On Mon, Feb 14, 2011 at 07:35:02PM +0000, Alan Cox wrote:
> > What is the use-case for alt_func?  From the point of view of a GPIO
> > driver, I don't think it cares if the pin has been dedicated to
> 
> Currently it doesn't.
> 
> However the moment it starts setting input and output itself on requests
> then it does because it may kick the pin out of alt_func mode when you
> merely want to request it so you know which pin to stick into alt_func
> mode, or to find a mapping. The current situation is an "ignorance is
> bliss" one, but making it smarter backfires. We have the same problem
> with unknown state - if I have a set of pins some of whose state is known
> at boot time then I can't now provide a get_direction interface because
> of the lack of states. At the very least we need input/output/godknows
> where the latter means the gpio_request code keeps its nose out.

Not quite; the gpio api is only about discrete gpios.  If a particular
pin is dedicated to another non-gpio purpose, then from the POV of the
gpio api, the pin is disconnected from the outside world and any
twiddling of it just won't do anything.  If an alt_func has any driver
behaviour impact, then it needs to be handled internal to the driver.

> 
> 	reconfigure_resource();
> 	see_if_we_own_it()
> 
> is simply the wrong order for a resource.

Yes, this is broken.  gpio_request() should not change the state of
the resource.  I don't see anything in gpiolib that currently does
this.

> The second problem is that in many cases you need to call gpio_request to
> know you have the pin yourself before you can set the direction. That
> means forcing the direction in gpio_request is daft - you force an
> undefined value that cannot yet safely be set in all cases.
> 
> At the moment the lack of alt_func also has some strange effects and you
> end up with code like
> 
> foo_firmware_update()
> {
> 	/* Reserve the line for alt_func use for the moment */
> 	gpio_request(GPIO_FOO, "blah");
> 	random_gpio_driver_specific_altfunc_foo();
> 	do stuff();
> 	random_gpio_driver_specific_altfunc_foo();
> 	gpio_free(GPIO_FOO);
> 
> 	/* Now available again for its normal GPIO use */
> }
> 
> 
> and that means you can't generalise dynamic access to a shared GPIO pin
> without extra hardcoded knowledge.

I don't follow the argument.  Of course you have to do weird hardcoded
things when a gpio pin has to be shared between multiple purposes, but
that is also a weird corner case that won't fit any kind of common
pattern.  I don't see the above code snippet as a problem.

g.

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 1/3] gpiolib: Add ability to get GPIO pin direction
  2011-02-15 17:05             ` Peter Tyser
  2011-02-15 17:19               ` Alan Cox
@ 2011-03-06  7:53               ` Grant Likely
  1 sibling, 0 replies; 26+ messages in thread
From: Grant Likely @ 2011-03-06  7:53 UTC (permalink / raw)
  To: Peter Tyser
  Cc: Alan Cox, linux-kernel, Alek Du, Samuel Ortiz, David Brownell,
	Eric Miao, Uwe Kleine-K?nig, Mark Brown, Joe Perches

On Tue, Feb 15, 2011 at 11:05:48AM -0600, Peter Tyser wrote:
> > > Also, in most cases I'd think that the BIOS/U-Boot/firmware should have
> > > configured the GPIO pins appropriately, which Linux should inherit in
> > > general.  Linux currently inherits GPIO states that were set in firmware
> > > when a GPIO is requested, but it doesn't properly report those values
> > > via sysfs - that's the only bug I'm trying to fix.
> > 
> > Yes - however you can't fix it unless you are prepared to admit that the
> > gpio has multiple states. At minimum you need to be able to report
> > 
> > 	input/output/unknown/unavailable
> > 
> > if you want to generalise it. Otherwise you don't solve the problem
> > because you are asking a question that driver cannot answer correctly.
> 
> As far as the "unknown" state, I can update the patch to have the logic:
> +       if (chip->get_direction) {
> +               /* chip->get_direction may sleep */
> +               spin_unlock_irqrestore(&gpio_lock, flags);
> +               if (chip->get_direction(chip, gpio - chip->base) > 0)
> +                       set_bit(FLAG_IS_OUT, &desc->flags);
> +               spin_lock_irqsave(&gpio_lock, flags);
> +       } else {
> +               set_bit(FLAG_IS_UNKNOWN, &desc->flags);
> +       }
> 
> This would have the side effect of having nearly all GPIO drivers
> default to an "unknown" direction until they implement the new
> get_direction() function, which I think is an improvement over the
> current system where they are all unconditionally shown as "input",
> often incorrectly.  Are you OK with this Grant?

Not really, no.  Defaulting to "input" may be incorrect, but it is
always safe, it it should only be a minor inconvenience to human users
of the sysfs interface.  Actual usage of a gpio pin must always be to
explicitly set the direction before using a pin.


> Changing the logic to allow "unavailable" GPIO pins to be
> requested/exported would require larger changes to the code, and
> wouldn't provide much benefit without additional changes (eg an alt_func
> feature).  So I'd vote to not add support for "unavailable" pins in this
> patch and rather wait until someone has a specific use for it, and add
> it then.

Agreed.

g.

^ permalink raw reply	[flat|nested] 26+ messages in thread

end of thread, other threads:[~2011-03-06  7:53 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-01-06 19:54 [PATCH 1/3] gpiolib: Add ability to get GPIO pin direction Peter Tyser
2011-01-06 19:54 ` [PATCH 2/3] gpio: pca953x: Implement get_direction() hook Peter Tyser
2011-01-06 23:16   ` David Brownell
2011-01-06 19:54 ` [PATCH 3/3] gpio: Add support for Intel ICHx/3100/Series[56] GPIO Peter Tyser
2011-01-06 23:12   ` David Brownell
2011-02-14 15:48 ` [PATCH 1/3] gpiolib: Add ability to get GPIO pin direction Peter Tyser
2011-02-14 16:02   ` Grant Likely
2011-02-14 19:14     ` Grant Likely
2011-02-14 20:01       ` Peter Tyser
2011-02-14 17:08   ` Alan Cox
2011-02-14 17:26     ` Grant Likely
2011-02-14 17:39       ` Mark Brown
2011-02-14 17:45       ` Peter Tyser
2011-02-14 18:04         ` Grant Likely
2011-02-14 18:46           ` Peter Tyser
2011-02-14 19:35       ` Alan Cox
2011-02-14 23:35         ` Peter Tyser
2011-02-15 11:42           ` Alan Cox
2011-02-15 17:05             ` Peter Tyser
2011-02-15 17:19               ` Alan Cox
2011-02-15 17:49                 ` Peter Tyser
2011-02-15 19:41                   ` Alan Cox
2011-02-17  8:06                   ` Uwe Kleine-König
2011-03-06  7:53               ` Grant Likely
2011-02-15 23:55           ` Mark Brown
2011-03-06  7:49         ` Grant Likely

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).