[linux-yocto] [[PATCH 1/1] pinctrl: baytrail: unmap interrupt when free the gpio pin
chong.yi.chai at intel.com
chong.yi.chai at intel.com
Wed Mar 30 20:16:57 PDT 2016
From: "Chai, Chong Yi" <chong.yi.chai at 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.mohamad at 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.tan at intel.com>
+Signed-off-by: Petallo, MauriceX R <mauricex.r.petallo at intel.com>
+Signed-off-by: Wan Ahmad Zainie <wan.ahmad.zainie.wan.mohamad at 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.chew at 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.chew at intel.com>
+Signed-off-by: Chew, Chiau Ee <chiau.ee.chew at intel.com>
+Signed-off-by: Sreeju Selvaraj <sreeju.armughanx.selvaraj at intel.com>
+Signed-off-by: Maurice Petallo <mauricex.r.petallo at 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.chew at 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.chew at 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.chew at 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.chew at intel.com>
+Signed-off-by: Chew, Chiau Ee <chiau.ee.chew at intel.com>
+Signed-off-by: Sreeju Selvaraj <sreeju.armughanx.selvaraj at intel.com>
+Signed-off-by: Maurice Petallo <mauricex.r.petallo at 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.chew at 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.chew at intel.com>
+Signed-off-by: Chew, Chiau Ee <chiau.ee.chew at intel.com>
+Signed-off-by: Sreeju Selvaraj <sreeju.armughanx.selvaraj at intel.com>
+Signed-off-by: Maurice Petallo <mauricex.r.petallo at 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
More information about the linux-yocto
mailing list