From: "Chai, Chong Yi" <chong.yi.c...@intel.com>

---
 features/soc/baytrail/baytrail.scc                 |   4 +
 ...trail-Serialize-GPIO-registers-access-wit.patch | 256 ++++++++++++++++
 ...trail-enable-platform-device-in-the-absen.patch | 339 +++++++++++++++++++++
 ...trail-setup-IOAPIC-interrupt-for-GPIO-clu.patch |  78 +++++
 ...trail-unmap-interrupt-when-free-the-gpio-.patch |  40 +++
 5 files changed, 717 insertions(+)
 create mode 100644 
features/soc/baytrail/pinctrl-baytrail-Serialize-GPIO-registers-access-wit.patch
 create mode 100644 
features/soc/baytrail/pinctrl-baytrail-enable-platform-device-in-the-absen.patch
 create mode 100644 
features/soc/baytrail/pinctrl-baytrail-setup-IOAPIC-interrupt-for-GPIO-clu.patch
 create mode 100644 
features/soc/baytrail/pinctrl-baytrail-unmap-interrupt-when-free-the-gpio-.patch

diff --git a/features/soc/baytrail/baytrail.scc 
b/features/soc/baytrail/baytrail.scc
index 57c4cd7..b61a2e7 100644
--- a/features/soc/baytrail/baytrail.scc
+++ b/features/soc/baytrail/baytrail.scc
@@ -68,3 +68,7 @@ patch hpet-Fix-checkpatch.pl-warnings.patch
 patch libata-add-curr_xfer_mode-attribute.patch
 patch libata-enable-atapi_an-by-default.patch
 patch libata-handle-HDIO_SET_DMA-HDIO_GET_DMA-ioctl.patch
+patch pinctrl-baytrail-unmap-interrupt-when-free-the-gpio-.patch
+patch pinctrl-baytrail-enable-platform-device-in-the-absen.patch
+patch pinctrl-baytrail-setup-IOAPIC-interrupt-for-GPIO-clu.patch
+patch pinctrl-baytrail-Serialize-GPIO-registers-access-wit.patch
diff --git 
a/features/soc/baytrail/pinctrl-baytrail-Serialize-GPIO-registers-access-wit.patch
 
b/features/soc/baytrail/pinctrl-baytrail-Serialize-GPIO-registers-access-wit.patch
new file mode 100644
index 0000000..f4bca99
--- /dev/null
+++ 
b/features/soc/baytrail/pinctrl-baytrail-Serialize-GPIO-registers-access-wit.patch
@@ -0,0 +1,256 @@
+From 0a5d87717424225324dc7afcc79c305a6b87ac23 Mon Sep 17 00:00:00 2001
+From: Wan Ahmad Zainie <wan.ahmad.zainie.wan.moha...@intel.com>
+Date: Mon, 18 May 2015 12:49:57 +0800
+Subject: [PATCH 097/164] pinctrl-baytrail: Serialize GPIO registers access
+ with global spinlock
+
+When multiple drivers access the GPIO registers concurrently, it
+may result in unpredictable system behaviour, that is, write
+instructions may be dropped. As to fix this issue, add global
+lock for all reads and writes to serialize GPIO accessing.
+
+Referring to Errata: VLI63, VLT61
+Errata Web-link:
+https://cdiext.intel.com/cdi/edesign-infodesk/EDCDownloader.aspx?id=539130
+
+Version 3:
+- This is a forward ported version of the patch from byt_3.10.61_ltsi_dev
+  0d31cde pinctrl-baytrail: Serialize GPIO registers access with global 
spinlock
+
+Version 2:
+- This is a forward ported version of the patch from vlv_1.0.1_dev:
+  4b900f5 gpio-byt: Serialize GPIO registers access with global spinlock
+- Removed remaining instances of vg->lock
+
+Signed-off-by: Tan, Jui Nee <jui.nee....@intel.com>
+Signed-off-by: Petallo, MauriceX R <mauricex.r.peta...@intel.com>
+Signed-off-by: Wan Ahmad Zainie <wan.ahmad.zainie.wan.moha...@intel.com>
+---
+ drivers/pinctrl/pinctrl-baytrail.c |   57 +++++++++++++++++++++++++-----------
+ 1 files changed, 40 insertions(+), 17 deletions(-)
+
+diff --git a/drivers/pinctrl/pinctrl-baytrail.c 
b/drivers/pinctrl/pinctrl-baytrail.c
+index a2ebed6..0818dbd 100644
+--- a/drivers/pinctrl/pinctrl-baytrail.c
++++ b/drivers/pinctrl/pinctrl-baytrail.c
+@@ -125,11 +125,12 @@ static struct pinctrl_gpio_range byt_ranges[] = {
+       },
+ };
+ 
++static DEFINE_SPINLOCK(byt_reg_access_lock);
++
+ struct byt_gpio {
+       struct gpio_chip                chip;
+       struct irq_domain               *domain;
+       struct platform_device          *pdev;
+-      spinlock_t                      lock;
+       void __iomem                    *reg_base;
+       struct pinctrl_gpio_range       *range;
+ };
+@@ -171,14 +172,18 @@ static int byt_gpio_request(struct gpio_chip *chip, 
unsigned offset) 
+       void __iomem *reg = byt_gpio_reg(chip, offset, BYT_CONF0_REG);
+       u32 value;
+       bool special;
++      unsigned long flags;
+ 
+       /*
+        * In most cases, func pin mux 000 means GPIO function.
+        * But, some pins may have func pin mux 001 represents
+        * GPIO function. Only allow user to export pin with
+        * func pin mux preset as GPIO function by BIOS/FW.
+        */
++      spin_lock_irqsave(&byt_reg_access_lock, flags);
+       value = readl(reg) & BYT_PIN_MUX;
++      spin_unlock_irqrestore(&byt_reg_access_lock, flags);
++
+       special = is_special_pin(vg, offset);
+       if ((special && value != 1) || (!special && value)) {
+               dev_err(&vg->pdev->dev,
+@@ -197,11 +202,17 @@ static void byt_gpio_free(struct gpio_chip *chip, 
unsigned offset)
+       void __iomem *reg = byt_gpio_reg(&vg->chip, offset, BYT_CONF0_REG);
+       u32 value;
+       unsigned int virq;
++      unsigned long flags;
++
++      spin_lock_irqsave(&byt_reg_access_lock, flags);
+ 
+       /* clear interrupt triggering */
+       value = readl(reg);
+       value &= ~(BYT_TRIG_POS | BYT_TRIG_NEG | BYT_TRIG_LVL);
+       writel(value, reg);
++
++      spin_unlock_irqrestore(&byt_reg_access_lock, flags);
++
+       virq = irq_find_mapping(vg->domain, offset);
+       irq_dispose_mapping(virq);
+ 
+@@ -219,7 +230,8 @@ static int byt_irq_type(struct irq_data *d, unsigned type)
+       if (offset >= vg->chip.ngpio)
+               return -EINVAL;
+ 
+-      spin_lock_irqsave(&vg->lock, flags);
++      spin_lock_irqsave(&byt_reg_access_lock, flags);
++
+       value = readl(reg);
+ 
+       /* For level trigges the BYT_TRIG_POS and BYT_TRIG_NEG bits
+@@ -244,7 +256,7 @@ static int byt_irq_type(struct irq_data *d, unsigned type)
+       }
+       writel(value, reg);
+ 
+-      spin_unlock_irqrestore(&vg->lock, flags);
++      spin_unlock_irqrestore(&byt_reg_access_lock, flags);
+ 
+       return 0;
+ }
+@@ -252,17 +264,23 @@ static int byt_irq_type(struct irq_data *d, unsigned 
type)
+ static int byt_gpio_get(struct gpio_chip *chip, unsigned offset)
+ {
+       void __iomem *reg = byt_gpio_reg(chip, offset, BYT_VAL_REG);
+-      return readl(reg) & BYT_LEVEL;
++      u32 value;
++      unsigned long flags;
++
++      spin_lock_irqsave(&byt_reg_access_lock, flags);
++      value = readl(reg) & BYT_LEVEL;
++      spin_unlock_irqrestore(&byt_reg_access_lock, flags);
++
++      return value;
+ }
+ 
+ static void byt_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+ {
+-      struct byt_gpio *vg = to_byt_gpio(chip);
+       void __iomem *reg = byt_gpio_reg(chip, offset, BYT_VAL_REG);
+       unsigned long flags;
+       u32 old_val;
+ 
+-      spin_lock_irqsave(&vg->lock, flags);
++      spin_lock_irqsave(&byt_reg_access_lock, flags);
+ 
+       old_val = readl(reg);
+ 
+@@ -271,23 +289,22 @@ static void byt_gpio_set(struct gpio_chip *chip, 
unsigned offset, int value)
+       else
+               writel(old_val & ~BYT_LEVEL, reg);
+ 
+-      spin_unlock_irqrestore(&vg->lock, flags);
++      spin_unlock_irqrestore(&byt_reg_access_lock, flags);
+ }
+ 
+ static int byt_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+ {
+-      struct byt_gpio *vg = to_byt_gpio(chip);
+       void __iomem *reg = byt_gpio_reg(chip, offset, BYT_VAL_REG);
+       unsigned long flags;
+       u32 value;
+ 
+-      spin_lock_irqsave(&vg->lock, flags);
++      spin_lock_irqsave(&byt_reg_access_lock, flags);
+ 
+       value = readl(reg) | BYT_DIR_MASK;
+       value &= ~BYT_INPUT_EN;         /* active low */
+       writel(value, reg);
+ 
+-      spin_unlock_irqrestore(&vg->lock, flags);
++      spin_unlock_irqrestore(&byt_reg_access_lock, flags);
+ 
+       return 0;
+ }
+@@ -295,12 +312,11 @@ static int byt_gpio_direction_input(struct gpio_chip 
*chip, unsigned offset)
+ static int byt_gpio_direction_output(struct gpio_chip *chip,
+                                    unsigned gpio, int value)
+ {
+-      struct byt_gpio *vg = to_byt_gpio(chip);
+       void __iomem *reg = byt_gpio_reg(chip, gpio, BYT_VAL_REG);
+       unsigned long flags;
+       u32 reg_val;
+ 
+-      spin_lock_irqsave(&vg->lock, flags);
++      spin_lock_irqsave(&byt_reg_access_lock, flags);
+ 
+       reg_val = readl(reg) | BYT_DIR_MASK;
+       reg_val &= ~(BYT_OUTPUT_EN | BYT_INPUT_EN);
+@@ -310,7 +326,7 @@ static int byt_gpio_direction_output(struct gpio_chip 
*chip,
+       else
+               writel(reg_val & ~BYT_LEVEL, reg);
+ 
+-      spin_unlock_irqrestore(&vg->lock, flags);
++      spin_unlock_irqrestore(&byt_reg_access_lock, flags);
+ 
+       return 0;
+ }
+@@ -322,7 +338,7 @@ static void byt_gpio_dbg_show(struct seq_file *s, struct 
gpio_chip *chip)
+       unsigned long flags;
+       u32 conf0, val, offs;
+ 
+-      spin_lock_irqsave(&vg->lock, flags);
++      spin_lock_irqsave(&byt_reg_access_lock, flags);
+ 
+       for (i = 0; i < vg->chip.ngpio; i++) {
+               const char *label;
+@@ -347,7 +363,8 @@ static void byt_gpio_dbg_show(struct seq_file *s, struct 
gpio_chip *chip)
+                          conf0 & BYT_TRIG_POS ? " rise" : "",
+                          conf0 & BYT_TRIG_LVL ? " level" : "");
+       }
+-      spin_unlock_irqrestore(&vg->lock, flags);
++
++      spin_unlock_irqrestore(&byt_reg_access_lock, flags);
+ }
+ 
+ static int byt_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
+@@ -366,12 +419,15 @@ static void byt_gpio_irq_handler(unsigned irq, struct 
irq_desc *desc)
+       u32 pending;
+       unsigned virq;
+       int looplimit = 0;
++      unsigned long flags;
+ 
+       /* check from GPIO controller which pin triggered the interrupt */
+       for (base = 0; base < vg->chip.ngpio; base += 32) {
+ 
+               reg = byt_gpio_reg(&vg->chip, base, BYT_INT_STAT_REG);
+ 
++              spin_lock_irqsave(&byt_reg_access_lock, flags);
++
+               while ((pending = readl(reg))) {
+                       pin = __ffs(pending);
+                       mask = BIT(pin);
+@@ -339,6 +419,8 @@ static void byt_gpio_irq_handler(unsigned irq, struct 
irq_desc *desc)
+                               break;
+                       }
+               }
++
++              spin_unlock_irqrestore(&byt_reg_access_lock, flags);
+       }
+       chip->irq_eoi(data);
+ }
+@@ -444,14 +466,17 @@ static void byt_gpio_irq_init_hw(struct byt_gpio *vg)
+ {
+       void __iomem *reg;
+       u32 base, value;
++      unsigned long flags;
+ 
+       /* clear interrupt status trigger registers */
+       for (base = 0; base < vg->chip.ngpio; base += 32) {
+               reg = byt_gpio_reg(&vg->chip, base, BYT_INT_STAT_REG);
++              spin_lock_irqsave(&byt_reg_access_lock, flags);
+               writel(0xffffffff, reg);
+               /* make sure trigger bits are cleared, if not then a pin
+                  might be misconfigured in bios */
+               value = readl(reg);
++              spin_unlock_irqrestore(&byt_reg_access_lock, flags);
+               if (value)
+                       dev_err(&vg->pdev->dev,
+                               "GPIO interrupt error, pins misconfigured\n");
+@@ -553,8 +578,6 @@ static int byt_gpio_probe(struct platform_device *pdev)
+       if (IS_ERR(vg->reg_base))
+               return PTR_ERR(vg->reg_base);
+ 
+-      spin_lock_init(&vg->lock);
+-
+       gc = &vg->chip;
+       gc->label = dev_name(&pdev->dev);
+       gc->owner = THIS_MODULE;
+-- 
+1.7.7.6
+
diff --git 
a/features/soc/baytrail/pinctrl-baytrail-enable-platform-device-in-the-absen.patch
 
b/features/soc/baytrail/pinctrl-baytrail-enable-platform-device-in-the-absen.patch
new file mode 100644
index 0000000..2974a62
--- /dev/null
+++ 
b/features/soc/baytrail/pinctrl-baytrail-enable-platform-device-in-the-absen.patch
@@ -0,0 +1,339 @@
+From 0bfd2d51551e63d0d3238491f377fa86021880d6 Mon Sep 17 00:00:00 2001
+From: "Chew, Kean Ho" <kean.ho.c...@intel.com>
+Date: Wed, 12 Feb 2014 06:14:33 -0500
+Subject: [PATCH 016/164] pinctrl-baytrail: enable platform device in the
+ absent of ACPI enumeration
+
+This is to cater the need for non-ACPI system whereby
+a platform device has to be created in order to bind
+with the BYT Pinctrl GPIO platform driver.
+
+Conflicts:
+       drivers/pinctrl/Makefile
+
+Signed-off-by: Chew, Kean Ho <kean.ho.c...@intel.com>
+Signed-off-by: Chew, Chiau Ee <chiau.ee.c...@intel.com>
+Signed-off-by: Sreeju Selvaraj <sreeju.armughanx.selva...@intel.com>
+Signed-off-by: Maurice Petallo <mauricex.r.peta...@intel.com>
+---
+ drivers/pinctrl/Kconfig                |   19 ++++-
+ drivers/pinctrl/Makefile               |    1 +
+ drivers/pinctrl/pinctrl-baytrail-dev.c |  159 ++++++++++++++++++++++++++++++++
+ drivers/pinctrl/pinctrl-baytrail.c     |   19 +++-
+ include/linux/pinctrl/pinctrl-byt.h    |   16 +++
+ 5 files changed, 209 insertions(+), 5 deletions(-)
+ create mode 100644 drivers/pinctrl/pinctrl-baytrail-dev.c
+ create mode 100644 include/linux/pinctrl/pinctrl-byt.h
+
+diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
+index 1e4e693..d0ce157 100644
+--- a/drivers/pinctrl/Kconfig
++++ b/drivers/pinctrl/Kconfig
+@@ -89,7 +89,7 @@ config PINCTRL_AT91
+ 
+ config PINCTRL_BAYTRAIL
+       bool "Intel Baytrail GPIO pin control"
+-      depends on GPIOLIB && ACPI && X86
++      depends on GPIOLIB && X86
+       select IRQ_DOMAIN
+       help
+         driver for memory mapped GPIO functionality on Intel Baytrail
+@@ -97,7 +97,22 @@ config PINCTRL_BAYTRAIL
+         Most pins are usually muxed to some other functionality by firmware,
+         so only a small amount is available for gpio use.
+ 
+-        Requires ACPI device enumeration code to set up a platform device.
++        For ACPI platform, it would require ACPI device enumeration code
++        to set up a platform device. Else, say yes to PINCTRL_BAYTRAIL_DEVICE
++        as well to set up platform device in the absent of ACPI enumeration
++        code.
++
++config PINCTRL_BAYTRAIL_DEVICE
++      bool "Intel Baytrail GPIO pin control Platform Device Emulation"
++      depends on PINCTRL_BAYTRAIL
++      help
++        This driver is to set up platform device in the absent of ACPI
++        enumeration.
++
++        Say yes for non-ACPI platform. This will enable the platform devices
++        to be created and bind with the BayTrail GPIO pin control platform
++        driver.
++
+ 
+ config PINCTRL_BCM2835
+       bool
+diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
+index 4b83588..29b5ed1 100644
+--- a/drivers/pinctrl/Makefile
++++ b/drivers/pinctrl/Makefile
+@@ -21,6 +21,7 @@ obj-$(CONFIG_PINCTRL_BF60x)  += pinctrl-adi2-bf60x.o
+ obj-$(CONFIG_PINCTRL_AT91)    += pinctrl-at91.o
+ obj-$(CONFIG_PINCTRL_BCM2835) += pinctrl-bcm2835.o
+ obj-$(CONFIG_PINCTRL_BAYTRAIL)        += pinctrl-baytrail.o
++obj-$(CONFIG_PINCTRL_BAYTRAIL_DEVICE) += pinctrl-baytrail-dev.o
+ obj-$(CONFIG_PINCTRL_CAPRI)   += pinctrl-capri.o
+ obj-$(CONFIG_PINCTRL_IMX)     += pinctrl-imx.o
+ obj-$(CONFIG_PINCTRL_IMX1_CORE)       += pinctrl-imx1-core.o
+diff --git a/drivers/pinctrl/pinctrl-baytrail-dev.c 
b/drivers/pinctrl/pinctrl-baytrail-dev.c
+new file mode 100644
+index 0000000..6754753
+--- /dev/null
++++ b/drivers/pinctrl/pinctrl-baytrail-dev.c
+@@ -0,0 +1,159 @@
++/*
++ * pinctrl-baytrail-dev.c: BayTrail pinctrl GPIO Platform Device
++ *
++ * (C) Copyright 2013 Intel Corporation
++ * Author: Kean Ho, Chew (kean.ho.c...@intel.com)
++ *
++ * 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; version 2
++ * of the License.
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/types.h>
++#include <linux/bitops.h>
++#include <linux/interrupt.h>
++#include <linux/platform_device.h>
++#include <linux/seq_file.h>
++#include <linux/pci.h>
++#include <linux/pinctrl/pinctrl-byt.h>
++
++/* PCI Memory Base Access */
++#define PCI_DEVICE_ID_INTEL_BYT_PCU   0x0f1c
++#define NO_REGISTER_SETTINGS  (BIT(0) | BIT(1) | BIT(2))
++
++/* Offsets */
++#define SCORE_OFFSET          0x0
++#define NCORE_OFFSET          0x1000
++#define SUS_OFFSET            0x2000
++#define SCORE_END             0x72C
++#define NCORE_END             0x970
++#define SUS_END                       0x98C
++
++static struct byt_pinctrl_port byt_gpio_score_platform_data = {
++      .unique_id = "1",
++};
++
++static struct resource byt_gpio_score_resources[] = {
++      {
++              .start  = 0x0,
++              .end    = 0x0,
++              .flags  = IORESOURCE_MEM,
++              .name   = "io-memory",
++      },
++      {
++              .start  = 49,
++              .end    = 49,
++              .flags  = IORESOURCE_IRQ,
++              .name   = "irq",
++      }
++};
++
++static struct byt_pinctrl_port byt_gpio_ncore_platform_data = {
++      .unique_id = "2",
++};
++
++static struct resource byt_gpio_ncore_resources[] = {
++      {
++              .start  = 0x0,
++              .end    = 0x0,
++              .flags  = IORESOURCE_MEM,
++              .name   = "io-memory",
++      },
++      {
++              .start  = 48,
++              .end    = 48,
++              .flags  = IORESOURCE_IRQ,
++              .name   = "irq",
++      }
++};
++
++static struct byt_pinctrl_port byt_gpio_sus_platform_data = {
++      .unique_id = "3",
++};
++
++static struct resource byt_gpio_sus_resources[] = {
++      {
++              .start  = 0x0,
++              .end    = 0x0,
++              .flags  = IORESOURCE_MEM,
++              .name   = "io-memory",
++      },
++      {
++              .start  = 50,
++              .end    = 50,
++              .flags  = IORESOURCE_IRQ,
++              .name   = "irq",
++      }
++};
++
++static struct platform_device byt_gpio_score_device = {
++      .name                   = "byt_gpio",
++      .id                     = 0,
++      .num_resources          = ARRAY_SIZE(byt_gpio_score_resources),
++      .resource               = byt_gpio_score_resources,
++      .dev                    = {
++              .platform_data  = &byt_gpio_score_platform_data,
++      }
++};
++
++static struct platform_device byt_gpio_ncore_device = {
++      .name                   = "byt_gpio",
++      .id                     = 1,
++      .num_resources          = ARRAY_SIZE(byt_gpio_ncore_resources),
++      .resource               = byt_gpio_ncore_resources,
++      .dev                    = {
++              .platform_data  = &byt_gpio_ncore_platform_data,
++      }
++};
++
++static struct platform_device byt_gpio_sus_device = {
++      .name                   = "byt_gpio",
++      .id                     = 2,
++      .num_resources          = ARRAY_SIZE(byt_gpio_sus_resources),
++      .resource               = byt_gpio_sus_resources,
++      .dev                    = {
++              .platform_data  = &byt_gpio_sus_platform_data,
++      }
++};
++
++static struct platform_device *devices[] __initdata = {
++      &byt_gpio_score_device,
++      &byt_gpio_ncore_device,
++      &byt_gpio_sus_device,
++};
++
++static int __init get_pci_memory_init(void)
++{
++      u32 io_base_add;
++      struct pci_dev *pci_dev;
++      pci_dev = pci_get_device(PCI_VENDOR_ID_INTEL,
++                              PCI_DEVICE_ID_INTEL_BYT_PCU,
++                              NULL);
++
++      if (pci_dev == NULL) {
++              return -EFAULT;
++      };
++      pci_read_config_dword(pci_dev, 0x4c, &io_base_add);
++      io_base_add &= ~NO_REGISTER_SETTINGS;
++      byt_gpio_score_resources[0].start = io_base_add + SCORE_OFFSET;
++      byt_gpio_score_resources[0].end =
++                              io_base_add + SCORE_OFFSET + SCORE_END;
++      byt_gpio_ncore_resources[0].start = io_base_add + NCORE_OFFSET;
++      byt_gpio_ncore_resources[0].end =
++                              io_base_add + NCORE_OFFSET + NCORE_END;
++      byt_gpio_sus_resources[0].start = io_base_add + SUS_OFFSET;
++      byt_gpio_sus_resources[0].end = io_base_add + SUS_OFFSET + SUS_END;
++      return 0;
++};
++rootfs_initcall(get_pci_memory_init);
++
++
++static int __init byt_gpio_device_init(void)
++{
++      return platform_add_devices(devices, ARRAY_SIZE(devices));
++};
++device_initcall(byt_gpio_device_init);
+diff --git a/drivers/pinctrl/pinctrl-baytrail.c 
b/drivers/pinctrl/pinctrl-baytrail.c
+index 5e230c8..599cbcf 100644
+--- a/drivers/pinctrl/pinctrl-baytrail.c
++++ b/drivers/pinctrl/pinctrl-baytrail.c
+@@ -34,6 +34,7 @@
+ #include <linux/io.h>
+ #include <linux/pm_runtime.h>
+ #include <linux/pinctrl/pinctrl.h>
++#include <linux/pinctrl/pinctrl-byt.h>
+ 
+ /* memory mapped register offsets */
+ #define BYT_CONF0_REG         0x000
+@@ -480,15 +481,19 @@ static int byt_gpio_probe(struct platform_device *pdev)
+       struct gpio_chip *gc;
+       struct resource *mem_rc, *irq_rc;
+       struct device *dev = &pdev->dev;
+-      struct acpi_device *acpi_dev;
+       struct pinctrl_gpio_range *range;
+-      acpi_handle handle = ACPI_HANDLE(dev);
+       unsigned hwirq;
+       int ret;
+ 
++#ifdef CONFIG_PINCTRL_BAYTRAIL_DEVICE
++      struct byt_pinctrl_port *platform_data = dev->platform_data;
++#else
++      struct acpi_device *acpi_dev;
++      acpi_handle handle = ACPI_HANDLE(dev);
++
+       if (acpi_bus_get_device(handle, &acpi_dev))
+               return -ENODEV;
+-
++#endif
+       vg = devm_kzalloc(dev, sizeof(struct byt_gpio), GFP_KERNEL);
+       if (!vg) {
+               dev_err(&pdev->dev, "can't allocate byt_gpio chip data\n");
+@@ -490,7 +495,11 @@ static int byt_gpio_probe(struct platform_device *pdev)
+       }
+ 
+       for (range = byt_ranges; range->name; range++) {
++#ifdef CONFIG_PINCTRL_BAYTRAIL_DEVICE
++              if (!strcmp(platform_data->unique_id, range->name)) {
++#else
+               if (!strcmp(acpi_dev->pnp.unique_id, range->name)) {
++#endif
+                       vg->chip.ngpio = range->npins;
+                       vg->range = range;
+                       break;
+@@ -573,12 +582,14 @@ static const struct dev_pm_ops byt_gpio_pm_ops = {
+       .runtime_resume = byt_gpio_runtime_resume,
+ };
+ 
++#ifndef CONFIG_PINCTRL_BAYTRAIL_DEVICE
+ static const struct acpi_device_id byt_gpio_acpi_match[] = {
+       { "INT33B2", 0 },
+       { "INT33FC", 0 },
+       { }
+ };
+ MODULE_DEVICE_TABLE(acpi, byt_gpio_acpi_match);
++#endif
+ 
+ static int byt_gpio_remove(struct platform_device *pdev)
+ {
+@@ -599,8 +610,10 @@ static struct platform_driver byt_gpio_driver = {
+       .driver         = {
+               .name   = "byt_gpio",
+               .owner  = THIS_MODULE,
++#ifndef CONFIG_PINCTRL_BAYTRAIL_DEVICE
+               .pm     = &byt_gpio_pm_ops,
+               .acpi_match_table = ACPI_PTR(byt_gpio_acpi_match),
++#endif
+       },
+ };
+ 
+diff --git a/include/linux/pinctrl/pinctrl-byt.h 
b/include/linux/pinctrl/pinctrl-byt.h
+new file mode 100644
+index 0000000..95db4b9
+--- /dev/null
++++ b/include/linux/pinctrl/pinctrl-byt.h
+@@ -0,0 +1,16 @@
++/*
++ * pinctrl-byt.h: BayTrail GPIO pinctrl header file
++ *
++ * Copyright (C) 2013 Intel Corporation
++ * Author: Chew, Kean Ho <kean.ho.c...@intel.com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation.
++ */
++
++#ifdef CONFIG_PINCTRL_BAYTRAIL_DEVICE
++struct byt_pinctrl_port {
++      char *unique_id;
++};
++#endif
+-- 
+1.7.7.6
+
diff --git 
a/features/soc/baytrail/pinctrl-baytrail-setup-IOAPIC-interrupt-for-GPIO-clu.patch
 
b/features/soc/baytrail/pinctrl-baytrail-setup-IOAPIC-interrupt-for-GPIO-clu.patch
new file mode 100644
index 0000000..c4de301
--- /dev/null
+++ 
b/features/soc/baytrail/pinctrl-baytrail-setup-IOAPIC-interrupt-for-GPIO-clu.patch
@@ -0,0 +1,78 @@
+From 0a933c448bbf42b1d0407eb81a68ad3b163f6599 Mon Sep 17 00:00:00 2001
+From: "Chew, Kean Ho" <kean.ho.c...@intel.com>
+Date: Tue, 11 Feb 2014 11:25:45 -0500
+Subject: [PATCH 017/164] pinctrl-baytrail: setup IOAPIC interrupt for GPIO
+ clusters on non-ACPI system
+
+BayTrail GPIO NORTH, SOUTH and SUS clusters use IRQ48,
+49 and 50 respectively. On non-ACPI system, we need
+to setup IOAPIC RTE for device that use interrupt
+beyond IRQ23.
+
+Conflicts:
+       drivers/pinctrl/pinctrl-baytrail.c
+
+Signed-off-by: Chew, Kean Ho <kean.ho.c...@intel.com>
+Signed-off-by: Chew, Chiau Ee <chiau.ee.c...@intel.com>
+Signed-off-by: Sreeju Selvaraj <sreeju.armughanx.selva...@intel.com>
+Signed-off-by: Maurice Petallo <mauricex.r.peta...@intel.com>
+---
+ drivers/pinctrl/pinctrl-baytrail.c |   35 +++++++++++++++++++++++++++++++++++
+ 1 files changed, 35 insertions(+), 0 deletions(-)
+
+diff --git a/drivers/pinctrl/pinctrl-baytrail.c 
b/drivers/pinctrl/pinctrl-baytrail.c
+index 599cbcf..a2ebed6 100644
+--- a/drivers/pinctrl/pinctrl-baytrail.c
++++ b/drivers/pinctrl/pinctrl-baytrail.c
+@@ -475,6 +475,36 @@ static const struct irq_domain_ops byt_gpio_irq_ops = {
+       .map = byt_gpio_irq_map,
+ };
+ 
++#ifdef CONFIG_PINCTRL_BAYTRAIL_DEVICE
++static int byt_gpio_irq_enable(unsigned hwirq, struct platform_device *pdev)
++{
++      struct io_apic_irq_attr irq_attr;
++      struct device *dev = &pdev->dev;
++      /*
++       *  Since PCI BIOS is not able to provide IRQ mapping to
++       *  IRQ24 and onward, we need register to ioapic directly
++       *  and hardcode pci->irq= hwirq
++       */
++      irq_attr.ioapic = mp_find_ioapic(hwirq);
++      if (irq_attr.ioapic < 0) {
++              dev_err(&pdev->dev,
++                      "Unable to locate IOAPIC for IRQ=%d\n", hwirq);
++              return irq_attr.ioapic;
++      }
++      irq_attr.ioapic_pin = hwirq;
++      irq_attr.trigger = 1;   /* level */
++      irq_attr.polarity = 1;  /* active low */
++      io_apic_set_pci_routing(dev, hwirq, &irq_attr);
++      return 0;
++
++}
++#else
++static int byt_gpio_irq_enable(unsigned hwirq, struct platform_device *pdev)
++{
++      return 0;
++}
++#endif
++
+ static int byt_gpio_probe(struct platform_device *pdev)
+ {
+       struct byt_gpio *vg;
+@@ -550,6 +580,11 @@ static int byt_gpio_probe(struct platform_device *pdev)
+       if (irq_rc && irq_rc->start) {
+               hwirq = irq_rc->start;
+               gc->to_irq = byt_gpio_to_irq;
++              ret = byt_gpio_irq_enable(hwirq, pdev);
++              if (ret) {
++                      dev_err(&pdev->dev, "failed to add GPIO to APIC\n");
++                      return ret;
++              }
+ 
+               vg->domain = irq_domain_add_linear(NULL, gc->ngpio,
+                                                  &byt_gpio_irq_ops, vg);
+-- 
+1.7.7.6
+
diff --git 
a/features/soc/baytrail/pinctrl-baytrail-unmap-interrupt-when-free-the-gpio-.patch
 
b/features/soc/baytrail/pinctrl-baytrail-unmap-interrupt-when-free-the-gpio-.patch
new file mode 100644
index 0000000..840f07e
--- /dev/null
+++ 
b/features/soc/baytrail/pinctrl-baytrail-unmap-interrupt-when-free-the-gpio-.patch
@@ -0,0 +1,40 @@
+From 1d22c7e44b1e8b743622178b02ec1beb3f0bdadf Mon Sep 17 00:00:00 2001
+From: "Chew, Kean Ho" <kean.ho.c...@intel.com>
+Date: Wed, 12 Feb 2014 04:20:41 -0500
+Subject: [PATCH 015/164] pinctrl-baytrail: unmap interrupt when free the gpio
+ pin
+
+In to_irq() callback, we create the hwirq to linux irq
+mapping for the requested GPIO pin. Hence, we unamp
+the mapping when the gpio pin is being released.
+
+Signed-off-by: Chew, Kean Ho <kean.ho.c...@intel.com>
+Signed-off-by: Chew, Chiau Ee <chiau.ee.c...@intel.com>
+Signed-off-by: Sreeju Selvaraj <sreeju.armughanx.selva...@intel.com>
+Signed-off-by: Maurice Petallo <mauricex.r.peta...@intel.com>
+---
+ drivers/pinctrl/pinctrl-baytrail.c |    3 +++
+ 1 files changed, 3 insertions(+), 0 deletions(-)
+
+diff --git a/drivers/pinctrl/pinctrl-baytrail.c 
b/drivers/pinctrl/pinctrl-baytrail.c
+index f6ebaa7..5e230c8 100644
+--- a/drivers/pinctrl/pinctrl-baytrail.c
++++ b/drivers/pinctrl/pinctrl-baytrail.c
+@@ -195,11 +195,14 @@ static void byt_gpio_free(struct gpio_chip *chip, 
unsigned offset)
+       struct byt_gpio *vg = to_byt_gpio(chip);
+       void __iomem *reg = byt_gpio_reg(&vg->chip, offset, BYT_CONF0_REG);
+       u32 value;
++      unsigned int virq;
+ 
+       /* clear interrupt triggering */
+       value = readl(reg);
+       value &= ~(BYT_TRIG_POS | BYT_TRIG_NEG | BYT_TRIG_LVL);
+       writel(value, reg);
++      virq = irq_find_mapping(vg->domain, offset);
++      irq_dispose_mapping(virq);
+ 
+       pm_runtime_put(&vg->pdev->dev);
+ }
+-- 
+1.7.7.6
+
-- 
1.9.1

-- 
_______________________________________________
linux-yocto mailing list
linux-yocto@yoctoproject.org
https://lists.yoctoproject.org/listinfo/linux-yocto

Reply via email to