Merge tag 'gpio-for-linus' of git://git.secretlab.ca/git/linux-2.6
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 28 Mar 2012 21:08:46 +0000 (14:08 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 28 Mar 2012 21:08:46 +0000 (14:08 -0700)
Pull GPIO changes for v3.4 from Grant Likely:
 "Primarily gpio device driver changes with some minor side effects
  under arch/arm and arch/x86.  Also includes a few core changes such as
  explicitly supporting (electrical) open source and open drain outputs
  and some help for parsing gpio devicetree properties."

Fix up context conflict due to Laxman Dewangan adding sleep control for
the tps65910 driver separately for gpio's and regulators.

* tag 'gpio-for-linus' of git://git.secretlab.ca/git/linux-2.6: (34 commits)
  gpio/ep93xx: Remove unused inline function and useless pr_err message
  gpio/sodaville: Mark broken due to core irqdomain migration
  gpio/omap: fix redundant decoding of gpio offset
  gpio/omap: fix incorrect update to context.irqenable1
  gpio/omap: fix incorrect context restore logic in omap_gpio_runtime_*
  gpio/omap: fix missing dataout context save in _set_gpio_dataout_reg
  gpio/omap: fix _set_gpio_irqenable implementation
  gpio/omap: fix trigger type to unsigned
  gpio/omap: fix wakeup_en register update in _set_gpio_wakeup()
  gpio: tegra: tegra_gpio_config shouldn't be __init
  gpio/davinci: fix enabling unbanked GPIO IRQs
  gpio/davinci: fix oops on unbanked gpio irq request
  gpio/omap: Fix section warning for omap_mpuio_alloc_gc()
  ARM: tegra: export tegra_gpio_{en,dis}able
  gpio/gpio-stmpe: Fix the value returned by _get_value routine
  Documentation/gpio.txt: Explain expected pinctrl interaction
  GPIO: LPC32xx: Add output reading to GPO P3
  GPIO: LPC32xx: Fix missing bit selection mask
  gpio/omap: fix wakeups on level-triggered GPIOs
  gpio/omap: Fix IRQ handling for SPARSE_IRQ
  ...

1  2 
drivers/gpio/Kconfig
drivers/gpio/Makefile
drivers/gpio/gpio-ep93xx.c
drivers/gpio/gpio-stmpe.c
drivers/gpio/gpio-tegra.c
include/linux/gpio.h
include/linux/mfd/tps65910.h

diff --combined drivers/gpio/Kconfig
index 0409cf35adda246f944c7173b219640aa23be3c6,dfea1d84655d968b9d93f6e85721b390d9e256c0..edadbdad31d04c2f228166afa8f1971f21573044
@@@ -190,17 -190,6 +190,17 @@@ config GPIO_VX85
          additional drivers must be enabled in order to use the
          functionality of the device.
  
 +config GPIO_GE_FPGA
 +      bool "GE FPGA based GPIO"
 +      depends on GE_FPGA
 +      help
 +        Support for common GPIO functionality provided on some GE Single Board
 +        Computers.
 +
 +        This driver provides basic support (configure as input or output, read
 +        and write pin state) for GPIO implemented in a number of GE single
 +        board computers.
 +
  comment "I2C GPIO expanders:"
  
  config GPIO_MAX7300
@@@ -236,6 -225,12 +236,12 @@@ config GPIO_MAX732X_IR
          Say yes here to enable the max732x to be used as an interrupt
          controller. It requires the driver to be built in the kernel.
  
+ config GPIO_MC9S08DZ60
+       bool "MX35 3DS BOARD MC9S08DZ60 GPIO functions"
+       depends on I2C && MACH_MX35_3DS
+       help
+         Select this to enable the MC9S08DZ60 GPIO driver
  config GPIO_PCA953X
        tristate "PCA953x, PCA955x, TCA64xx, and MAX7310 I/O ports"
        depends on I2C
@@@ -422,6 -417,14 +428,14 @@@ config GPIO_ML_IO
          Hub) which is for IVI(In-Vehicle Infotainment) use.
          This driver can access the IOH's GPIO device.
  
+ config GPIO_SODAVILLE
+       bool "Intel Sodaville GPIO support"
+       depends on X86 && PCI && OF && BROKEN
+       select GPIO_GENERIC
+       select GENERIC_IRQ_CHIP
+       help
+         Say Y here to support Intel Sodaville GPIO.
  config GPIO_TIMBERDALE
        bool "Support for timberdale GPIO IP"
        depends on MFD_TIMBERDALE && HAS_IOMEM
diff --combined drivers/gpio/Makefile
index 9a8fb54ae462df9b48b40e4e12c6eb22dcf31e97,593bdcd1976e834d8d73cfd91fb576301bb604bd..007f54bd0081203dcf04ec775254b6b72c8d422f
@@@ -16,7 -16,6 +16,7 @@@ obj-$(CONFIG_GPIO_CS5535)     += gpio-cs553
  obj-$(CONFIG_GPIO_DA9052)     += gpio-da9052.o
  obj-$(CONFIG_ARCH_DAVINCI)    += gpio-davinci.o
  obj-$(CONFIG_GPIO_EP93XX)     += gpio-ep93xx.o
 +obj-$(CONFIG_GPIO_GE_FPGA)    += gpio-ge.o
  obj-$(CONFIG_GPIO_IT8761E)    += gpio-it8761e.o
  obj-$(CONFIG_GPIO_JANZ_TTL)   += gpio-janz-ttl.o
  obj-$(CONFIG_ARCH_KS8695)     += gpio-ks8695.o
@@@ -27,6 -26,7 +27,7 @@@ obj-$(CONFIG_GPIO_MAX7300)    += gpio-max7
  obj-$(CONFIG_GPIO_MAX7301)    += gpio-max7301.o
  obj-$(CONFIG_GPIO_MAX732X)    += gpio-max732x.o
  obj-$(CONFIG_GPIO_MC33880)    += gpio-mc33880.o
+ obj-$(CONFIG_GPIO_MC9S08DZ60) += gpio-mc9s08dz60.o
  obj-$(CONFIG_GPIO_MCP23S08)   += gpio-mcp23s08.o
  obj-$(CONFIG_GPIO_ML_IOH)     += gpio-ml-ioh.o
  obj-$(CONFIG_GPIO_MPC5200)    += gpio-mpc5200.o
@@@ -46,6 -46,7 +47,7 @@@ obj-$(CONFIG_GPIO_RDC321X)    += gpio-rdc3
  obj-$(CONFIG_PLAT_SAMSUNG)    += gpio-samsung.o
  obj-$(CONFIG_ARCH_SA1100)     += gpio-sa1100.o
  obj-$(CONFIG_GPIO_SCH)                += gpio-sch.o
+ obj-$(CONFIG_GPIO_SODAVILLE)  += gpio-sodaville.o
  obj-$(CONFIG_GPIO_STMPE)      += gpio-stmpe.o
  obj-$(CONFIG_GPIO_SX150X)     += gpio-sx150x.o
  obj-$(CONFIG_GPIO_TC3589X)    += gpio-tc3589x.o
index 4ca5642e9776108b5ba873be4faa0dd37e3c08ac,6a89683fdc91e0c0e4008a25572e80503521985f..776b772523e5039f81440d412397aaabac49c544
@@@ -12,8 -12,6 +12,6 @@@
   *  published by the Free Software Foundation.
   */
  
- #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  #include <linux/init.h>
  #include <linux/module.h>
  #include <linux/platform_device.h>
@@@ -65,11 -63,6 +63,6 @@@ static void ep93xx_gpio_update_int_para
                EP93XX_GPIO_REG(int_en_register_offset[port]));
  }
  
- static inline void ep93xx_gpio_int_mask(unsigned line)
- {
-       gpio_int_unmasked[line >> 3] &= ~(1 << (line & 7));
- }
  static void ep93xx_gpio_int_debounce(unsigned int irq, bool enable)
  {
        int line = irq_to_gpio(irq);
@@@ -212,7 -205,6 +205,6 @@@ static int ep93xx_gpio_irq_type(struct 
                handler = handle_edge_irq;
                break;
        default:
-               pr_err("failed to set irq type %d for gpio %d\n", type, gpio);
                return -EINVAL;
        }
  
@@@ -378,6 -370,13 +370,6 @@@ static int __devinit ep93xx_gpio_probe(
        }
        ep93xx_gpio->mmio_base = mmio;
  
 -      /* Default all ports to GPIO */
 -      ep93xx_devcfg_set_bits(EP93XX_SYSCON_DEVCFG_KEYS |
 -                             EP93XX_SYSCON_DEVCFG_GONK |
 -                             EP93XX_SYSCON_DEVCFG_EONIDE |
 -                             EP93XX_SYSCON_DEVCFG_GONIDE |
 -                             EP93XX_SYSCON_DEVCFG_HONIDE);
 -
        for (i = 0; i < ARRAY_SIZE(ep93xx_gpio_banks); i++) {
                struct bgpio_chip *bgc = &ep93xx_gpio->bgc[i];
                struct ep93xx_gpio_bank *bank = &ep93xx_gpio_banks[i];
index 094c5c4fd7f2ad05cd11060b504e9f4ad8e3ffd1,8abf4e9e23009f7decd5d3fe107fd8d1307b2111..dce34727bbf8774895e471ca32b6a025842c99ee
@@@ -54,7 -54,7 +54,7 @@@ static int stmpe_gpio_get(struct gpio_c
        if (ret < 0)
                return ret;
  
-       return ret & mask;
+       return !!(ret & mask);
  }
  
  static void stmpe_gpio_set(struct gpio_chip *chip, unsigned offset, int val)
@@@ -307,11 -307,13 +307,11 @@@ static int __devinit stmpe_gpio_probe(s
        struct stmpe_gpio_platform_data *pdata;
        struct stmpe_gpio *stmpe_gpio;
        int ret;
 -      int irq;
 +      int irq = 0;
  
        pdata = stmpe->pdata->gpio;
  
        irq = platform_get_irq(pdev, 0);
 -      if (irq < 0)
 -              return irq;
  
        stmpe_gpio = kzalloc(sizeof(struct stmpe_gpio), GFP_KERNEL);
        if (!stmpe_gpio)
        stmpe_gpio->chip.dev = &pdev->dev;
        stmpe_gpio->chip.base = pdata ? pdata->gpio_base : -1;
  
 -      stmpe_gpio->irq_base = stmpe->irq_base + STMPE_INT_GPIO(0);
 +      if (irq >= 0)
 +              stmpe_gpio->irq_base = stmpe->irq_base + STMPE_INT_GPIO(0);
 +      else
 +              dev_info(&pdev->dev,
 +                      "device configured in no-irq mode; "
 +                      "irqs are not available\n");
  
        ret = stmpe_enable(stmpe, STMPE_BLOCK_GPIO);
        if (ret)
                goto out_free;
  
 -      ret = stmpe_gpio_irq_init(stmpe_gpio);
 -      if (ret)
 -              goto out_disable;
 +      if (irq >= 0) {
 +              ret = stmpe_gpio_irq_init(stmpe_gpio);
 +              if (ret)
 +                      goto out_disable;
  
 -      ret = request_threaded_irq(irq, NULL, stmpe_gpio_irq, IRQF_ONESHOT,
 -                                 "stmpe-gpio", stmpe_gpio);
 -      if (ret) {
 -              dev_err(&pdev->dev, "unable to get irq: %d\n", ret);
 -              goto out_removeirq;
 +              ret = request_threaded_irq(irq, NULL, stmpe_gpio_irq,
 +                              IRQF_ONESHOT, "stmpe-gpio", stmpe_gpio);
 +              if (ret) {
 +                      dev_err(&pdev->dev, "unable to get irq: %d\n", ret);
 +                      goto out_removeirq;
 +              }
        }
  
        ret = gpiochip_add(&stmpe_gpio->chip);
        return 0;
  
  out_freeirq:
 -      free_irq(irq, stmpe_gpio);
 +      if (irq >= 0)
 +              free_irq(irq, stmpe_gpio);
  out_removeirq:
 -      stmpe_gpio_irq_remove(stmpe_gpio);
 +      if (irq >= 0)
 +              stmpe_gpio_irq_remove(stmpe_gpio);
  out_disable:
        stmpe_disable(stmpe, STMPE_BLOCK_GPIO);
  out_free:
@@@ -398,10 -391,8 +398,10 @@@ static int __devexit stmpe_gpio_remove(
  
        stmpe_disable(stmpe, STMPE_BLOCK_GPIO);
  
 -      free_irq(irq, stmpe_gpio);
 -      stmpe_gpio_irq_remove(stmpe_gpio);
 +      if (irq >= 0) {
 +              free_irq(irq, stmpe_gpio);
 +              stmpe_gpio_irq_remove(stmpe_gpio);
 +      }
        platform_set_drvdata(pdev, NULL);
        kfree(stmpe_gpio);
  
index 6f17671260e17b94d8176befe18e6706eb228832,ceb1fd081b857cbad5b9bfd4f71aa3ec078968c4..32de6707e3c456a19750e33dd21923bde2fcd41e
@@@ -25,7 -25,6 +25,7 @@@
  #include <linux/of.h>
  #include <linux/platform_device.h>
  #include <linux/module.h>
 +#include <linux/irqdomain.h>
  
  #include <asm/mach/irq.h>
  
@@@ -75,10 -74,9 +75,10 @@@ struct tegra_gpio_bank 
  #endif
  };
  
 -
 +static struct irq_domain *irq_domain;
  static void __iomem *regs;
 -static struct tegra_gpio_bank tegra_gpio_banks[7];
 +static u32 tegra_gpio_bank_count;
 +static struct tegra_gpio_bank *tegra_gpio_banks;
  
  static inline void tegra_gpio_writel(u32 val, u32 reg)
  {
@@@ -109,11 -107,13 +109,13 @@@ void tegra_gpio_enable(int gpio
  {
        tegra_gpio_mask_write(GPIO_MSK_CNF(gpio), gpio, 1);
  }
+ EXPORT_SYMBOL_GPL(tegra_gpio_enable);
  
  void tegra_gpio_disable(int gpio)
  {
        tegra_gpio_mask_write(GPIO_MSK_CNF(gpio), gpio, 0);
  }
+ EXPORT_SYMBOL_GPL(tegra_gpio_disable);
  
  static void tegra_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
  {
@@@ -141,7 -141,7 +143,7 @@@ static int tegra_gpio_direction_output(
  
  static int tegra_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
  {
 -      return TEGRA_GPIO_TO_IRQ(offset);
 +      return irq_find_mapping(irq_domain, offset);
  }
  
  static struct gpio_chip tegra_gpio_chip = {
  
  static void tegra_gpio_irq_ack(struct irq_data *d)
  {
 -      int gpio = d->irq - INT_GPIO_BASE;
 +      int gpio = d->hwirq;
  
        tegra_gpio_writel(1 << GPIO_BIT(gpio), GPIO_INT_CLR(gpio));
  }
  
  static void tegra_gpio_irq_mask(struct irq_data *d)
  {
 -      int gpio = d->irq - INT_GPIO_BASE;
 +      int gpio = d->hwirq;
  
        tegra_gpio_mask_write(GPIO_MSK_INT_ENB(gpio), gpio, 0);
  }
  
  static void tegra_gpio_irq_unmask(struct irq_data *d)
  {
 -      int gpio = d->irq - INT_GPIO_BASE;
 +      int gpio = d->hwirq;
  
        tegra_gpio_mask_write(GPIO_MSK_INT_ENB(gpio), gpio, 1);
  }
  
  static int tegra_gpio_irq_set_type(struct irq_data *d, unsigned int type)
  {
 -      int gpio = d->irq - INT_GPIO_BASE;
 +      int gpio = d->hwirq;
        struct tegra_gpio_bank *bank = irq_data_get_irq_chip_data(d);
        int port = GPIO_PORT(gpio);
        int lvl_type;
@@@ -275,7 -275,7 +277,7 @@@ void tegra_gpio_resume(void
  
        local_irq_save(flags);
  
 -      for (b = 0; b < ARRAY_SIZE(tegra_gpio_banks); b++) {
 +      for (b = 0; b < tegra_gpio_bank_count; b++) {
                struct tegra_gpio_bank *bank = &tegra_gpio_banks[b];
  
                for (p = 0; p < ARRAY_SIZE(bank->oe); p++) {
@@@ -298,7 -298,7 +300,7 @@@ void tegra_gpio_suspend(void
        int p;
  
        local_irq_save(flags);
 -      for (b = 0; b < ARRAY_SIZE(tegra_gpio_banks); b++) {
 +      for (b = 0; b < tegra_gpio_bank_count; b++) {
                struct tegra_gpio_bank *bank = &tegra_gpio_banks[b];
  
                for (p = 0; p < ARRAY_SIZE(bank->oe); p++) {
@@@ -339,44 -339,13 +341,44 @@@ static struct lock_class_key gpio_lock_
  
  static int __devinit tegra_gpio_probe(struct platform_device *pdev)
  {
 +      int irq_base;
        struct resource *res;
        struct tegra_gpio_bank *bank;
        int gpio;
        int i;
        int j;
  
 -      for (i = 0; i < ARRAY_SIZE(tegra_gpio_banks); i++) {
 +      for (;;) {
 +              res = platform_get_resource(pdev, IORESOURCE_IRQ, tegra_gpio_bank_count);
 +              if (!res)
 +                      break;
 +              tegra_gpio_bank_count++;
 +      }
 +      if (!tegra_gpio_bank_count) {
 +              dev_err(&pdev->dev, "Missing IRQ resource\n");
 +              return -ENODEV;
 +      }
 +
 +      tegra_gpio_chip.ngpio = tegra_gpio_bank_count * 32;
 +
 +      tegra_gpio_banks = devm_kzalloc(&pdev->dev,
 +                      tegra_gpio_bank_count * sizeof(*tegra_gpio_banks),
 +                      GFP_KERNEL);
 +      if (!tegra_gpio_banks) {
 +              dev_err(&pdev->dev, "Couldn't allocate bank structure\n");
 +              return -ENODEV;
 +      }
 +
 +      irq_base = irq_alloc_descs(-1, 0, tegra_gpio_chip.ngpio, 0);
 +      if (irq_base < 0) {
 +              dev_err(&pdev->dev, "Couldn't allocate IRQ numbers\n");
 +              return -ENODEV;
 +      }
 +      irq_domain = irq_domain_add_legacy(pdev->dev.of_node,
 +                                         tegra_gpio_chip.ngpio, irq_base, 0,
 +                                         &irq_domain_simple_ops, NULL);
 +
 +      for (i = 0; i < tegra_gpio_bank_count; i++) {
                res = platform_get_resource(pdev, IORESOURCE_IRQ, i);
                if (!res) {
                        dev_err(&pdev->dev, "Missing IRQ resource\n");
  
        gpiochip_add(&tegra_gpio_chip);
  
 -      for (gpio = 0; gpio < TEGRA_NR_GPIOS; gpio++) {
 -              int irq = TEGRA_GPIO_TO_IRQ(gpio);
 +      for (gpio = 0; gpio < tegra_gpio_chip.ngpio; gpio++) {
 +              int irq = irq_find_mapping(irq_domain, gpio);
                /* No validity check; all Tegra GPIOs are valid IRQs */
  
                bank = &tegra_gpio_banks[GPIO_BANK(gpio)];
                set_irq_flags(irq, IRQF_VALID);
        }
  
 -      for (i = 0; i < ARRAY_SIZE(tegra_gpio_banks); i++) {
 +      for (i = 0; i < tegra_gpio_bank_count; i++) {
                bank = &tegra_gpio_banks[i];
  
                irq_set_chained_handler(bank->irq, tegra_gpio_irq_handler);
@@@ -459,7 -428,7 +461,7 @@@ static int __init tegra_gpio_init(void
  }
  postcore_initcall(tegra_gpio_init);
  
- void __init tegra_gpio_config(struct tegra_gpio_table *table, int num)
+ void tegra_gpio_config(struct tegra_gpio_table *table, int num)
  {
        int i;
  
diff --combined include/linux/gpio.h
index ed5a46707ad0d0cd229e36920aa510b4d79fb279,67851bbd3a42dfdb3fca7ab34d136bc6c839b0ca..6155ecf192b0466f02ea616b5b8d8ef9fd5fc2f5
  #define GPIOF_OUT_INIT_LOW    (GPIOF_DIR_OUT | GPIOF_INIT_LOW)
  #define GPIOF_OUT_INIT_HIGH   (GPIOF_DIR_OUT | GPIOF_INIT_HIGH)
  
+ /* Gpio pin is open drain */
+ #define GPIOF_OPEN_DRAIN      (1 << 2)
+ /* Gpio pin is open source */
+ #define GPIOF_OPEN_SOURCE     (1 << 3)
  /**
   * struct gpio - a structure describing a GPIO with configuration
   * @gpio:     the GPIO number
@@@ -34,7 -40,6 +40,7 @@@ struct gpio 
  #include <linux/kernel.h>
  #include <linux/types.h>
  #include <linux/errno.h>
 +#include <linux/bug.h>
  
  struct device;
  struct gpio_chip;
index e34886397f902e722ac7ff98bf411f890141a224,9071902bd22208566da31953eb5151779a51811b..1c6c2860d1a60a6350ff46e7d45321ed8be95a80
@@@ -17,8 -17,6 +17,8 @@@
  #ifndef __LINUX_MFD_TPS65910_H
  #define __LINUX_MFD_TPS65910_H
  
 +#include <linux/gpio.h>
 +
  /* TPS chip id list */
  #define TPS65910                      0
  #define TPS65911                      1
  
  
  /*Register GPIO  (0x80) register.RegisterDescription */
+ #define GPIO_SLEEP_MASK                         0x80
+ #define GPIO_SLEEP_SHIFT                        7
  #define GPIO_DEB_MASK                           0x10
  #define GPIO_DEB_SHIFT                          4
  #define GPIO_PUEN_MASK                          0x08
  #define TPS65910_GPIO_STS                             BIT(1)
  #define TPS65910_GPIO_SET                             BIT(0)
  
+ /* Max number of TPS65910/11 GPIOs */
+ #define TPS65910_NUM_GPIO                             6
+ #define TPS65911_NUM_GPIO                             9
+ #define TPS6591X_MAX_NUM_GPIO                         9
  /* Regulator Index Definitions */
  #define TPS65910_REG_VRTC                             0
  #define TPS65910_REG_VIO                              1
  /* Max number of TPS65910/11 regulators */
  #define TPS65910_NUM_REGS                             13
  
 +/* External sleep controls through EN1/EN2/EN3/SLEEP inputs */
 +#define TPS65910_SLEEP_CONTROL_EXT_INPUT_EN1          0x1
 +#define TPS65910_SLEEP_CONTROL_EXT_INPUT_EN2          0x2
 +#define TPS65910_SLEEP_CONTROL_EXT_INPUT_EN3          0x4
 +#define TPS65911_SLEEP_CONTROL_EXT_INPUT_SLEEP                0x8
 +
  /**
   * struct tps65910_board
   * Board platform data may be used to initialize regulators.
@@@ -787,7 -786,7 +794,8 @@@ struct tps65910_board 
        int irq_base;
        int vmbch_threshold;
        int vmbch2_threshold;
+       bool en_gpio_sleep[TPS6591X_MAX_NUM_GPIO];
 +      unsigned long regulator_ext_sleep_control[TPS65910_NUM_REGS];
        struct regulator_init_data *tps65910_pmic_init_data[TPS65910_NUM_REGS];
  };
  
  struct tps65910 {
        struct device *dev;
        struct i2c_client *i2c_client;
 +      struct regmap *regmap;
        struct mutex io_mutex;
        unsigned int id;
        int (*read)(struct tps65910 *tps65910, u8 reg, int size, void *dest);