[linux-yocto] [PATCH 02/11] pinctrl-broxton: enable platform device in the absent of ACPI enumeration

Yong, Jonathan jonathan.yong at intel.com
Mon Jun 27 18:28:17 PDT 2016


From: Tan Jui Nee <jui.nee.tan 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 Apollo Lake Pinctrl GPIO platform driver.

Signed-off-by: Tan Jui Nee <jui.nee.tan at intel.com>
Signed-off-by: Yong, Jonathan <jonathan.yong at intel.com>
---
 MAINTAINERS                             |   6 +
 drivers/pinctrl/intel/Kconfig           |  12 +-
 drivers/pinctrl/intel/Makefile          |   1 +
 drivers/pinctrl/intel/pinctrl-apl-dev.c | 201 ++++++++++++++++++++++++++++++++
 drivers/pinctrl/intel/pinctrl-broxton.c |  29 ++++-
 include/linux/pinctrl/pinctrl-apl.h     |  18 +++
 6 files changed, 262 insertions(+), 5 deletions(-)
 create mode 100644 drivers/pinctrl/intel/pinctrl-apl-dev.c
 create mode 100644 include/linux/pinctrl/pinctrl-apl.h

diff --git a/MAINTAINERS b/MAINTAINERS
index dcfa127..5e13b56 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2294,6 +2294,12 @@ L:	netdev at vger.kernel.org
 S:	Supported
 F:	drivers/net/ethernet/brocade/bna/
 
+BROXTON PLATFORM Pin Controller
+M:	Tan, Jui Nee <jui.nee.tan at intel.com>
+S:	Supported
+F:	drivers/pinctrl/intel/pinctrl-apl-dev.c
+F:	include/linux/pinctrl/pinctrl-apl.h
+
 BSG (block layer generic sg v4 driver)
 M:	FUJITA Tomonori <fujita.tomonori at lab.ntt.co.jp>
 L:	linux-scsi at vger.kernel.org
diff --git a/drivers/pinctrl/intel/Kconfig b/drivers/pinctrl/intel/Kconfig
index 4d2efad..bab8823 100644
--- a/drivers/pinctrl/intel/Kconfig
+++ b/drivers/pinctrl/intel/Kconfig
@@ -36,12 +36,22 @@ config PINCTRL_INTEL
 
 config PINCTRL_BROXTON
 	tristate "Intel Broxton pinctrl and GPIO driver"
-	depends on ACPI
 	select PINCTRL_INTEL
 	help
 	  Broxton pinctrl driver provides an interface that allows
 	  configuring of SoC pins and using them as GPIOs.
 
+config PINCTRL_APL_DEVICE
+	tristate "Intel Apollo Lake GPIO pin control Platform Device Emulation"
+	depends on PINCTRL_BROXTON
+	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 Apollo Lake GPIO pin control platform
+	  driver.
+
 config PINCTRL_SUNRISEPOINT
 	tristate "Intel Sunrisepoint pinctrl and GPIO driver"
 	depends on ACPI
diff --git a/drivers/pinctrl/intel/Makefile b/drivers/pinctrl/intel/Makefile
index 03bc68e..2df696b 100644
--- a/drivers/pinctrl/intel/Makefile
+++ b/drivers/pinctrl/intel/Makefile
@@ -4,4 +4,5 @@ obj-$(CONFIG_PINCTRL_BAYTRAIL)		+= pinctrl-baytrail.o
 obj-$(CONFIG_PINCTRL_CHERRYVIEW)	+= pinctrl-cherryview.o
 obj-$(CONFIG_PINCTRL_INTEL)		+= pinctrl-intel.o
 obj-$(CONFIG_PINCTRL_BROXTON)		+= pinctrl-broxton.o
+obj-$(CONFIG_PINCTRL_APL_DEVICE)	+= pinctrl-apl-dev.o
 obj-$(CONFIG_PINCTRL_SUNRISEPOINT)	+= pinctrl-sunrisepoint.o
diff --git a/drivers/pinctrl/intel/pinctrl-apl-dev.c b/drivers/pinctrl/intel/pinctrl-apl-dev.c
new file mode 100644
index 0000000..226ec6a
--- /dev/null
+++ b/drivers/pinctrl/intel/pinctrl-apl-dev.c
@@ -0,0 +1,201 @@
+/*
+ * pinctrl-apl-dev.c: APL pinctrl GPIO Platform Device
+ *
+ * (C) Copyright 2015 Intel Corporation
+ * Author: Kean Ho, Chew (kean.ho.chew at intel.com)
+ * Modified: Tan, Jui Nee (jui.nee.tan 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-apl.h>
+
+/* PCI Memory Base Access */
+#define PCI_DEVICE_ID_INTEL_APL_PCU	0x5A92
+#define NO_REGISTER_SETTINGS	(BIT(0) | BIT(1) | BIT(2))
+
+/* Offsets */
+#define NORTH_OFFSET		0xC5
+#define NORTHWEST_OFFSET		0xC4
+#define WEST_OFFSET		0xC7
+#define SOUTHWEST_OFFSET		0xC0
+
+#define NORTH_END		(90 * 0x8)
+#define NORTHWEST_END		(77 * 0x8)
+#define WEST_END		(47 * 0x8)
+#define SOUTHWEST_END		(43 * 0x8)
+
+static struct apl_pinctrl_port apl_gpio_north_platform_data = {
+	.unique_id = "1",
+};
+
+static struct resource apl_gpio_north_resources[] = {
+	{
+		.start	= 0x0,
+		.end	= 0x0,
+		.flags	= IORESOURCE_MEM,
+		.name	= "io-memory",
+	},
+	{
+		.start	= 14,
+		.end	= 14,
+		.flags	= IORESOURCE_IRQ,
+		.name	= "irq",
+	}
+};
+
+static struct apl_pinctrl_port apl_gpio_northwest_platform_data = {
+	.unique_id = "2",
+};
+
+static struct resource apl_gpio_northwest_resources[] = {
+	{
+		.start	= 0x0,
+		.end	= 0x0,
+		.flags	= IORESOURCE_MEM,
+		.name	= "io-memory",
+	},
+	{
+		.start	= 14,
+		.end	= 14,
+		.flags	= IORESOURCE_IRQ,
+		.name	= "irq",
+	}
+};
+
+static struct apl_pinctrl_port apl_gpio_west_platform_data = {
+	.unique_id = "3",
+};
+
+static struct resource apl_gpio_west_resources[] = {
+	{
+		.start	= 0x0,
+		.end	= 0x0,
+		.flags	= IORESOURCE_MEM,
+		.name	= "io-memory",
+	},
+	{
+		.start	= 14,
+		.end	= 14,
+		.flags	= IORESOURCE_IRQ,
+		.name	= "irq",
+	}
+};
+
+static struct apl_pinctrl_port apl_gpio_southwest_platform_data = {
+	.unique_id = "4",
+};
+
+static struct resource apl_gpio_southwest_resources[] = {
+	{
+		.start	= 0x0,
+		.end	= 0x0,
+		.flags	= IORESOURCE_MEM,
+		.name	= "io-memory",
+	},
+	{
+		.start	= 14,
+		.end	= 14,
+		.flags	= IORESOURCE_IRQ,
+		.name	= "irq",
+	}
+};
+
+static struct platform_device apl_gpio_north_device = {
+	.name			= "apl_gpio",
+	.id			= 0,
+	.num_resources		= ARRAY_SIZE(apl_gpio_north_resources),
+	.resource		= apl_gpio_north_resources,
+	.dev			= {
+		.platform_data	= &apl_gpio_north_platform_data,
+	}
+};
+
+static struct platform_device apl_gpio_northwest_device = {
+	.name			= "apl_gpio",
+	.id			= 1,
+	.num_resources		= ARRAY_SIZE(apl_gpio_northwest_resources),
+	.resource		= apl_gpio_northwest_resources,
+	.dev			= {
+		.platform_data	= &apl_gpio_northwest_platform_data,
+	}
+};
+
+static struct platform_device apl_gpio_west_device = {
+	.name			= "apl_gpio",
+	.id			= 2,
+	.num_resources		= ARRAY_SIZE(apl_gpio_west_resources),
+	.resource		= apl_gpio_west_resources,
+	.dev			= {
+		.platform_data	= &apl_gpio_west_platform_data,
+	}
+};
+
+static struct platform_device apl_gpio_southwest_device = {
+	.name			= "apl_gpio",
+	.id			= 3,
+	.num_resources		= ARRAY_SIZE(apl_gpio_southwest_resources),
+	.resource		= apl_gpio_southwest_resources,
+	.dev			= {
+		.platform_data	= &apl_gpio_southwest_platform_data,
+	}
+};
+
+static struct platform_device *devices[] __initdata = {
+	&apl_gpio_north_device,
+	&apl_gpio_northwest_device,
+	&apl_gpio_west_device,
+	&apl_gpio_southwest_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_APL_PCU,
+				NULL);
+
+	if (pci_dev == NULL)
+		return -EFAULT;
+
+	pci_read_config_dword(pci_dev, 0x10, &io_base_add);
+	io_base_add &= ~NO_REGISTER_SETTINGS;
+	apl_gpio_north_resources[0].start =
+		io_base_add + (NORTH_OFFSET << 16);
+	apl_gpio_north_resources[0].end =
+		io_base_add + (NORTH_OFFSET << 16) + NORTH_END;
+	apl_gpio_northwest_resources[0].start =
+		io_base_add + (NORTHWEST_OFFSET << 16);
+	apl_gpio_northwest_resources[0].end =
+		io_base_add + (NORTHWEST_OFFSET << 16) + NORTHWEST_END;
+	apl_gpio_west_resources[0].start =
+		io_base_add + (WEST_OFFSET << 16);
+	apl_gpio_west_resources[0].end =
+		io_base_add + (WEST_OFFSET << 16) + WEST_END;
+	apl_gpio_southwest_resources[0].start =
+		io_base_add + (SOUTHWEST_OFFSET << 16);
+	apl_gpio_southwest_resources[0].end =
+		io_base_add + (SOUTHWEST_OFFSET << 16) + SOUTHWEST_END;
+	return 0;
+};
+rootfs_initcall(get_pci_memory_init);
+
+static int __init apl_gpio_device_init(void)
+{
+	return platform_add_devices(devices, ARRAY_SIZE(devices));
+};
+device_initcall(apl_gpio_device_init);
diff --git a/drivers/pinctrl/intel/pinctrl-broxton.c b/drivers/pinctrl/intel/pinctrl-broxton.c
index 5979d38..27855a5 100644
--- a/drivers/pinctrl/intel/pinctrl-broxton.c
+++ b/drivers/pinctrl/intel/pinctrl-broxton.c
@@ -14,6 +14,7 @@
 #include <linux/platform_device.h>
 #include <linux/pm.h>
 #include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinctrl-apl.h>
 
 #include "pinctrl-intel.h"
 
@@ -997,8 +998,12 @@ static const struct intel_pinctrl_soc_data *apl_pinctrl_soc_data[] = {
 };
 
 static const struct acpi_device_id bxt_pinctrl_acpi_match[] = {
-	{ "INT3452", (kernel_ulong_t)apl_pinctrl_soc_data },
-	{ "INT34D1", (kernel_ulong_t)bxt_pinctrl_soc_data },
+#ifdef CONFIG_PINCTRL_APL_DEVICE
+	"apl_gpio", (kernel_ulong_t)apl_pinctrl_soc_data,
+#else
+	"INT3452", (kernel_ulong_t)apl_pinctrl_soc_data,
+	"INT34D1", (kernel_ulong_t)bxt_pinctrl_soc_data,
+#endif
 	{ }
 };
 MODULE_DEVICE_TABLE(acpi, bxt_pinctrl_acpi_match);
@@ -1008,21 +1013,34 @@ static int bxt_pinctrl_probe(struct platform_device *pdev)
 	const struct intel_pinctrl_soc_data *soc_data = NULL;
 	const struct intel_pinctrl_soc_data **soc_table;
 	const struct acpi_device_id *id;
-	struct acpi_device *adev;
 	int i;
+#ifdef CONFIG_PINCTRL_APL_DEVICE
+	struct device *dev = &pdev->dev;
+	struct apl_pinctrl_port *platform_data = dev->platform_data;
+
+	id = bxt_pinctrl_acpi_match;
+	if (strcmp(pdev->name, id->id))
+		return -ENODEV;
+#else
+	struct acpi_device *adev;
 
 	adev = ACPI_COMPANION(&pdev->dev);
 	if (!adev)
 		return -ENODEV;
 
 	id = acpi_match_device(bxt_pinctrl_acpi_match, &pdev->dev);
+#endif
 	if (!id)
 		return -ENODEV;
 
 	soc_table = (const struct intel_pinctrl_soc_data **)id->driver_data;
 
 	for (i = 0; soc_table[i]; i++) {
+#ifdef CONFIG_PINCTRL_APL_DEVICE
+		if (!strcmp(platform_data->unique_id, soc_table[i]->uid)) {
+#else
 		if (!strcmp(adev->pnp.unique_id, soc_table[i]->uid)) {
+#endif
 			soc_data = soc_table[i];
 			break;
 		}
@@ -1043,9 +1061,12 @@ static struct platform_driver bxt_pinctrl_driver = {
 	.probe = bxt_pinctrl_probe,
 	.remove = intel_pinctrl_remove,
 	.driver = {
-		.name = "broxton-pinctrl",
+		.name = "apl_gpio",
+		.owner  = THIS_MODULE,
+#ifndef CONFIG_PINCTRL_APL_DEVICE
 		.acpi_match_table = bxt_pinctrl_acpi_match,
 		.pm = &bxt_pinctrl_pm_ops,
+#endif
 	},
 };
 
diff --git a/include/linux/pinctrl/pinctrl-apl.h b/include/linux/pinctrl/pinctrl-apl.h
new file mode 100644
index 0000000..d414255
--- /dev/null
+++ b/include/linux/pinctrl/pinctrl-apl.h
@@ -0,0 +1,18 @@
+/*
+ * pinctrl-apl.h: Apollo Lake GPIO pinctrl header file
+ *
+ * Copyright (C) 2015 Intel Corporation
+ * Author: Chew, Kean Ho <kean.ho.chew at intel.com>
+ * Modified: Tan, Jui Nee <jui.nee.tan 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_APL_DEVICE
+struct apl_pinctrl_port {
+	char *unique_id;
+};
+#endif
+
-- 
2.7.3



More information about the linux-yocto mailing list