[linux-yocto] [PATCHv2 5/6] pinctrl-baytrail: enable platform device in the absent of ACPI enumeration
rebecca.swee.fun.chang at intel.com
rebecca.swee.fun.chang at intel.com
Fri Aug 29 02:29:54 PDT 2014
From: "Chew, Kean Ho" <kean.ho.chew at intel.com>
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.
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>
---
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 6585b37..f3b850a 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -60,7 +60,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
@@ -68,7 +68,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 80f5239..66efd3d 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -17,6 +17,7 @@ obj-$(CONFIG_PINCTRL_AB8505) += pinctrl-ab8505.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_IMX) += pinctrl-imx.o
obj-$(CONFIG_PINCTRL_IMX35) += pinctrl-imx35.o
obj-$(CONFIG_PINCTRL_IMX51) += pinctrl-imx51.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 5dee6d7..7a313f1 100644
--- a/drivers/pinctrl/pinctrl-baytrail.c
+++ b/drivers/pinctrl/pinctrl-baytrail.c
@@ -35,6 +35,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
@@ -453,15 +454,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");
@@ -469,7 +474,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;
@@ -549,11 +558,13 @@ 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 },
{ }
};
MODULE_DEVICE_TABLE(acpi, byt_gpio_acpi_match);
+#endif
static int byt_gpio_remove(struct platform_device *pdev)
{
@@ -574,8 +585,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.9.1
More information about the linux-yocto
mailing list