From: Al Stone al.stone@linaro.org
These patches are purely experimental; they just barely compile and they do not run just yet. The reason for posting them is really just to stir some discussion and see if this is a truly crazy idea or if it has some potential for easing the ACPI transition.
These patches introduce GUFI: the Grand Unified Firmware Interface. Okay, yes, it is a silly name. I didn't spend a lot of time on it. What I'm most interested in is the idea and whether it is worth pursuing further, and whether or not there are better ways to do this if it does make sense.
The idea is very simple: introduce a shim layer that looks like a merge of some sort between ACPI and FDT functionality in the kernel. In that shim layer, make it possible for a driver to make a single call to a function, and with that call, retrieve configuration information stored in either ACPI tables or a DT. Further, allow the kernel to specify which has priority -- i.e., search through ACPI tables, and then through FDT if data is not found, or vice versa -- or which is exclusive, either ACPI or FDT only.
Why would I do this? As a kernel developer, this allows me to make changes in the direction of either FDT or ACPI as quickly or as slowly as I want to. Most of my config can be in FDT and I can then piecemeal convert to ACPI as I figure out ASL and/or any driver changes that may be needed. Secondly, if I do this well, the changes to convert from FDT to ACPI *should* be very small; from ACPI to FDT may be much more difficult but over time that can likely be improved as well. Third, in the really, really long term, maybe someone comes up with yet another hardware configuration description format that is so cool it provides sharks with laser beams on their heads and *everyone* wants to convert to it. With this layer in place, perhaps we can smooth even that transition by abstracting out the config info that's needed and the API to retrieve it.
So, what do you think?
Al Stone (5): ACPI: GUFI: add kernel config options for GUFI ACPI: GUFI: add build commands for drivers/gufi ACPI: GUFI: add in early prototype code for some GUFI functions ACPI: GUFI: add in simple test driver placeholders ACPI: GUFI: start modifying the vexpress-sysreg driver to use the GUFI
arch/arm64/Kconfig | 6 - drivers/Kconfig | 2 + drivers/Makefile | 1 + drivers/acpi/acpi_platform.c | 1 + drivers/gufi/Kconfig | 54 ++++++++ drivers/gufi/Makefile | 11 ++ drivers/gufi/gufi.c | 309 ++++++++++++++++++++++++++++++++++++++++++ drivers/gufi/gufi_acpi_test.c | 84 ++++++++++++ drivers/gufi/gufi_of_test.c | 83 ++++++++++++ drivers/mfd/vexpress-sysreg.c | 14 +- include/linux/gufi.h | 83 ++++++++++++ 11 files changed, 636 insertions(+), 12 deletions(-) create mode 100644 drivers/gufi/Kconfig create mode 100644 drivers/gufi/Makefile create mode 100644 drivers/gufi/gufi.c create mode 100644 drivers/gufi/gufi_acpi_test.c create mode 100644 drivers/gufi/gufi_of_test.c create mode 100644 include/linux/gufi.h
From: Al Stone al.stone@linaro.org
Introduce the kernel config options to enable the Grand Unified Firmware Interface (GUFI). Give the user the option of using only ACPI, only DT, or searching both with either ACPI or DT being searched first.
Signed-off-by: Al Stone al.stone@linaro.org --- arch/arm64/Kconfig | 6 ------ drivers/Kconfig | 2 ++ drivers/gufi/Kconfig | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 6 deletions(-) create mode 100644 drivers/gufi/Kconfig
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 3bbda50..9c34098 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -331,12 +331,6 @@ endmenu
source "drivers/firmware/Kconfig"
-menu "Power management and ACPI options" - -source "drivers/acpi/Kconfig" - -endmenu - source "fs/Kconfig"
source "arch/arm64/kvm/Kconfig" diff --git a/drivers/Kconfig b/drivers/Kconfig index 73a4f88..d2e7f3c 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -10,6 +10,8 @@ source "drivers/mtd/Kconfig"
source "drivers/of/Kconfig"
+source "drivers/gufi/Kconfig" + source "drivers/parport/Kconfig"
source "drivers/pnp/Kconfig" diff --git a/drivers/gufi/Kconfig b/drivers/gufi/Kconfig new file mode 100644 index 0000000..d6a1197 --- /dev/null +++ b/drivers/gufi/Kconfig @@ -0,0 +1,54 @@ +config GUFI + def_bool y + +menu "Grand Unified Firmware Interface support" + depends on GUFI + +choice + prompt "Fetching configuration info" + default GUFI_ACPI_FIRST + +config GUFI_ACPI_ONLY + bool "ONLY search ACPI tables" + depends on ACPI + help + This option forces GUFI to search for device configuration + information in the ACPI tables and methods only, ignoring + any Device Tree content. + +config GUFI_DT_ONLY + bool "ONLY search Device Tree" + depends on OF + help + This option forces GUFI to search for device configuration + information in the Device Tree only, ignoring any ACPI content. + +config GUFI_ACPI_FIRST + bool "Always search ACPI tables first" + depends on ACPI + help + This option forces GUFI to search for device configuration + information in the ACPI tables and methods first and should + that fail, look in a Device Tree, if it is enabled. + +config GUFI_DT_FIRST + bool "Always search Device Tree first" + depends on OF + help + This option forces GUFI to search for device configuration + information in the Device Tree and should that fail, look in + the ACPI tables and methods, if it is enabled. + +endchoice + +config GUFI_TEST_DRIVER + bool "Enable a null driver that can be used to test GUFI" + depends on GUFI && (ACPI || OF) + help + This option adds a small device driver that can be used to + test out features of GUFI. It's not really needed unless + you're either developing some part of GUFI or you wish to + verify that the right configuration information is being + retrieved from firmware tables. + +endmenu # GUFI
From: Al Stone al.stone@linaro.org
Add in the Makefiles needed for building the GUFI.
Signed-off-by: Al Stone al.stone@linaro.org --- drivers/Makefile | 1 + drivers/gufi/Makefile | 11 +++++++++++ 2 files changed, 12 insertions(+) create mode 100644 drivers/gufi/Makefile
diff --git a/drivers/Makefile b/drivers/Makefile index 214e82c..dca26df 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -127,6 +127,7 @@ obj-$(CONFIG_DCA) += dca/ obj-$(CONFIG_HID) += hid/ obj-$(CONFIG_PPC_PS3) += ps3/ obj-$(CONFIG_OF) += of/ +obj-$(CONFIG_GUFI) += gufi/ obj-$(CONFIG_SSB) += ssb/ obj-$(CONFIG_BCMA) += bcma/ obj-$(CONFIG_VHOST_RING) += vhost/ diff --git a/drivers/gufi/Makefile b/drivers/gufi/Makefile new file mode 100644 index 0000000..2daf40b --- /dev/null +++ b/drivers/gufi/Makefile @@ -0,0 +1,11 @@ +# +# Makefile for the Grand Unified Firmware Interface +# + +CFLAGS_gufi_of_test.o := -DDEBUG +CFLAGS_gufi_acpi_test.o := -DDEBUG + +obj-$(CONFIG_GUFI) = gufi.o + +obj-$(CONFIG_GUFI_TEST_DRIVER) += gufi_of_test.o +obj-$(CONFIG_GUFI_TEST_DRIVER) += gufi_acpi_test.o
From: Al Stone al.stone@linaro.org
This patch introduces the basic structure and content for just a couple of example GUFI functions. Each function is designed so that one can continue to use FDT and with minimal change, convert to using functions that will retrieve configuration data from either DT or ACPI, whichever has info available. In essence, these functions act as a translation layer.
Signed-off-by: Al Stone al.stone@linaro.org --- drivers/gufi/gufi.c | 309 +++++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/gufi.h | 83 ++++++++++++++ 2 files changed, 392 insertions(+) create mode 100644 drivers/gufi/gufi.c create mode 100644 include/linux/gufi.h
diff --git a/drivers/gufi/gufi.c b/drivers/gufi/gufi.c new file mode 100644 index 0000000..3fda2b1 --- /dev/null +++ b/drivers/gufi/gufi.c @@ -0,0 +1,309 @@ +/* + * Grand Unified Firmware Interface + * + * Copyright (C) 2013 Al Stone al.stone@linaro.org + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +#ifdef CONFIG_GUFI + +#include <linux/gufi.h> +#include <linux/of_address.h> + +enum search_preference { + SEARCH_ACPI_ONLY = 0, + SEARCH_DT_ONLY, + SEARCH_ACPI_FIRST, + SEARCH_DT_FIRST +}; + +#if IS_ENABLED(CONFIG_GUFI_ACPI_ONLY) +#define DEFAULT_PREFERENCE SEARCH_ACPI_ONLY +#elif IS_ENABLED(CONFIG_GUFI_DT_ONLY +#define DEFAULT_PREFERENCE SEARCH_DT_ONLY +#elif IS_ENABLED(CONFIG_GUFI_ACPI_FIRST +#define DEFAULT_PREFERENCE SEARCH_ACPI_FIRST +#elif IS_ENABLED(CONFIG_GUFI_DT_FIRST +#define DEFAULT_PREFERENCE SEARCH_DT_FIRST +#else +#define DEFAULT_PREFERENCE SEARCH_ACPI_FIRST +#endif + +static enum search_preference search_first = DEFAULT_PREFERENCE; + +static LIST_HEAD(__gdn_list); + +/* + * This macro may be a bit long, but the idea is to simplify the code + * for most of the other functions defined since each function will need + * to employ the same logic. Without this macro, each function would also + * have to duplicate code (one instance for each switch) which could make + * it harder to maintain over time (e.g., correcting the second switch + * but inadvertently missing the first one). Or, should some new format + * other than ACPI or Device Tree be defined, adding might be simpler + * with this approach. + * + * s => the enum search_preference variable being used to track which + * searches have been done + * sacpi => expression to use for ACPI functionality + * sdt => expression to use for DT functionality + * + */ +#define run_in_order(s, sacpi, sdt) \ + switch (s) { \ + case SEARCH_ACPI_ONLY: \ + sacpi; \ + break; \ + ;; \ + case SEARCH_DT_ONLY: \ + sdt; \ + break; \ + ;; \ + case SEARCH_ACPI_FIRST: \ + sacpi; \ + break; \ + ;; \ + case SEARCH_DT_FIRST: \ + sdt; \ + break; \ + ;; \ + default: \ + pr_err("%s: internal error (1)", __func__); \ + } \ + if (s >= SEARCH_ACPI_FIRST) { \ + s++; \ + s = s > SEARCH_DT_FIRST ? SEARCH_ACPI_FIRST : s; \ + switch (s) { \ + case SEARCH_ACPI_ONLY: \ + case SEARCH_DT_ONLY: \ + break; \ + ;; \ + case SEARCH_ACPI_FIRST: \ + sacpi; \ + break; \ + ;; \ + case SEARCH_DT_FIRST: \ + sdt; \ + break; \ + ;; \ + default: \ + pr_err("%s: internal error (2)", __func__); \ + } \ + } + + + +/* Reference counting routines */ + +/** + * gufi_node_get - Increment the reference count for a node + * @gdn: Node that needs the reference count incremented; NULL + * is handled for caller safety. + * + * NOTE: ACPI does not do reference counting. + * + * Returns the node incremented. + */ +struct gufi_device_node *gufi_node_get(struct gufi_device_node *gdn) +{ + if (gdn) { + if (gdn->dn) + of_node_get(gdn->dn); + kref_get(&gdn->kref); + } + return gdn; +} +EXPORT_SYMBOL(gufi_node_get); + +/** + * gufi_node_release - Release node resources for re-use + * @kref: kref element of the node being released + * + * Used as a destructor by gufi_node_put(). This is mostly a + * placeholder for now. + * + */ +static void gufi_node_release(struct kref *kref) +{ + struct gufi_device_node *gdn; + + gdn = container_of(kref, struct gufi_device_node, kref); + + kfree(gdn); +} + +/** + * gufi_node_put - Decrement the reference count for a node + * @gdn: Node that needs the reference count decremented; NULL + * is handled for caller safety. + * + * NOTE: ACPI does not do reference counting. + * + */ +void gufi_node_put(struct gufi_device_node *gdn) +{ + if (gdn) { + if (gdn->dn) + of_node_put(gdn->dn); + kref_put(&gdn->kref, gufi_node_release); + } +} +EXPORT_SYMBOL(gufi_node_put); + + +/* Search for nodes in interesting ways */ + +/** + * __gufi_look_for_node - All gufi_device_nodes a kept in a list. + * Given either a device_node or acpi_device_id + * (or both), search the list for a matching + * node. If there is no node, make one and + * add it to the list. + * @dn: struct device_node to look for + * @id: struct acpi_device_id to look for + * + * Returns a pointer to the node found, if any, or creates a new node + * and returns the address to it. + */ +static struct gufi_device_node *__gufi_look_for_node(struct device_node *dn, + struct acpi_device_id *id) +{ + struct gufi_device_node *pos; + struct gufi_device_node *node = NULL; + + list_for_each_entry(pos, &__gdn_list, entry) { + if (pos->dn == dn && pos->id == id) { + node = pos; + break; + } + } + + if (!node) { + node = kzalloc(sizeof(struct gufi_device_node), GFP_KERNEL); + if (node) { + node->dn = dn; + node->id = id; + list_add_tail(&node->entry, &__gdn_list); + } + } + return node; +} + +/** + * __gufi_find_acpi_compatible - Emulate the DT of_find_compatible_node + * using ACPI + * @gdn: The node to start searching from or NULL, the node + * you pass will not be searched, only the next one + * will; typically, you pass what the previous call + * returned. of_node_put() will be called on it + * @type: The type string to match "device_type" or NULL to ignore + * @compatible: The string to match to one of the tokens in the device + * "compatible" list. + * + * Return an acpi_device_id pointer. + */ +static struct acpi_device_id *__gufi_find_acpi_compatible( + struct gufi_device_node *gdn, + const char *type, + const char *compatible) +{ + struct acpi_device_id *id = NULL; + + /* + * TODO: traverse the namespace looking for a device with the right + * keys; the values of the keys are irrelevant here. Will need to + * invoke the _PRP method to retrieve all key-value pairs. + */ + return id; +} + +/** + * gufi_find_compatible_node - Find a node based on type and one of the + * tokens in its "compatible" property, or + * by a token returned from a _DSM or _PRP + * method + * @gdn: The node to start searching from or NULL, the node + * you pass will not be searched, only the next one + * will; typically, you pass what the previous call + * returned. of_node_put() will be called on it + * @type: The type string to match "device_type" or NULL to ignore + * @compatible: The string to match to one of the tokens in the device + * "compatible" list. + * + * Returns a node pointer with reference count incremented; use + * gufi_node_put() on it when done. + */ +struct gufi_device_node *gufi_find_compatible_node( + struct gufi_device_node *gdn, + const char *type, + const char *compatible) +{ + enum search_preference search = search_first; + struct device_node *dn = NULL; + struct acpi_device_id *id = NULL; + struct gufi_device_node *node; + + run_in_order(search, + dn = of_find_compatible_node(gdn->dn, type, compatible), + id = __gufi_find_acpi_compatible(gdn, type, compatible) + ); + node = __gufi_look_for_node(dn, id); + gufi_node_put(node); + return node; +} + + +/* Addressing routines */ + +/** + * __gufi_acpi_iomap - Maps the memory mapped IO for a given device_node + * @gdn: the device whose io range will be mapped + * + * Returns a pointer to the mapped memory + */ +void __iomem *__gufi_acpi_iomap(struct gufi_device_node *gdn) +{ + /* + * TODO: do I actually have to do an ioremap() here or has + * this already been taken care of? + */ + return NULL; +} + +/** + * gufi_iomap - Maps the memory mapped IO for a given device_node + * @gdn: the device whose io range will be mapped + * @index: index of the io range + * + * Returns a pointer to the mapped memory + */ +void __iomem *gufi_iomap(struct gufi_device_node *gdn, int index) +{ + enum search_preference search = search_first; + void __iomem *ptr; + + run_in_order(search, + ptr = of_iomap(gdn->dn, index), + ptr = __gufi_acpi_iomap(gdn) + ); + return ptr; +} + +#endif /* CONFIG_GUFI */ diff --git a/include/linux/gufi.h b/include/linux/gufi.h new file mode 100644 index 0000000..1ad0955 --- /dev/null +++ b/include/linux/gufi.h @@ -0,0 +1,83 @@ +/* + * gufi.h - Grand Unified Firmware Interface + * + * Copyright (C) 2013 Al Stone al.stone@linaro.org + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +#ifndef _LINUX_GUFI_H +#define _LINUX_GUFI_H + +#ifdef CONFIG_GUFI + +#include <linux/acpi.h> +#include <linux/errno.h> +#include <linux/kref.h> +#include <linux/list.h> +#include <linux/of.h> +#include <linux/types.h> + +struct gufi_device_node { + struct device_node *dn; + struct acpi_device_id *id; + struct kref kref; + struct list_head entry; +}; + +/* Reference counting routines */ +extern struct gufi_device_node *gufi_node_get(struct gufi_device_node *gdn); +extern void gufi_node_put(struct gufi_device_node *gdn); + +/* Search for nodes in interesting ways */ +extern struct gufi_device_node *gufi_find_compatible_node( + struct gufi_device_node *gdn, + const char *type, + const char *compatible); + +/* Addressing routines */ +extern void __iomem *gufi_iomap(struct gufi_device_node *gdn, int index); + +#else /* CONFIG_GUFI */ + +/* Reference counting routines */ +struct gufi_device_node *gufi_node_get(struct gufi_device_node *gdn) +{ + return NULL; +} +void gufi_node_put(struct gufi_device_node *gdn) { return; } + +/* Search for nodes in interesting ways */ +struct gufi_device_node *gufi_find_compatible_node( + struct gufi_device_node *gdn, + const char *type, + const char *compatible) +{ + return NULL; +} + +/* Addressing routines */ +void __iomem *gufi_iomap(struct gufi_device_node *gdn, int index) +{ + return NULL; +} + +#endif /* CONFIG_GUFI */ + +#endif /*_LINUX_GUFI_H */
From: Al Stone al.stone@linaro.org
This patch adds in some essentially null drivers (for now) as placeholders. The intent is to eventually provide a sysfs interface that would allow the kernel developer to interact with GUFI and test out the various aspects of the interface.
Signed-off-by: Al Stone al.stone@linaro.org --- drivers/acpi/acpi_platform.c | 1 + drivers/gufi/gufi_acpi_test.c | 84 +++++++++++++++++++++++++++++++++++++++++++ drivers/gufi/gufi_of_test.c | 83 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 168 insertions(+) create mode 100644 drivers/gufi/gufi_acpi_test.c create mode 100644 drivers/gufi/gufi_of_test.c
diff --git a/drivers/acpi/acpi_platform.c b/drivers/acpi/acpi_platform.c index 1359eda..dd83d5d 100644 --- a/drivers/acpi/acpi_platform.c +++ b/drivers/acpi/acpi_platform.c @@ -36,6 +36,7 @@ static const struct acpi_device_id acpi_platform_device_ids[] = { { "LNRO0007" }, /* armv8 pmu */ { "LNRO0009" }, /* vexpress-sysreg */ { "LNRO000A" }, /* uart-pl011 */ + { "LNRO000B" }, /* gufi-acpi-test */
{ } }; diff --git a/drivers/gufi/gufi_acpi_test.c b/drivers/gufi/gufi_acpi_test.c new file mode 100644 index 0000000..3536520 --- /dev/null +++ b/drivers/gufi/gufi_acpi_test.c @@ -0,0 +1,84 @@ +/* + * Grand Unified Firmware Interface -- test driver + * + * Copyright (C) 2013 Al Stone al.stone@linaro.org + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +#ifdef CONFIG_GUFI + +#ifdef CONFIG_ACPI + +#include <linux/gufi.h> +#include <linux/module.h> +#include <linux/acpi.h> +#include <linux/platform_device.h> + +/* Platform Device */ + +static int gufi_acpi_probe(struct platform_device *pdev) +{ + pr_debug("entering gufi_acpi_probe\n"); + return -EINVAL; +} + +static int gufi_acpi_remove(struct platform_device *pdev) +{ + return -EINVAL; +} + +/* Platform Driver */ + +static struct acpi_device_id gufi_acpi_match[] = { + { "LNRO000B", }, + { } +}; +MODULE_DEVICE_TABLE(gufi, gufi_acpi_match); + +static struct platform_driver gufi_acpi_driver = { + .probe = gufi_acpi_probe, + .remove = gufi_acpi_remove, + .driver = { + .name = "gufi-acpi-test", + .owner = THIS_MODULE, + .acpi_match_table = gufi_acpi_match, + }, +}; + +static int __init gufi_acpi_init(void) +{ + return platform_driver_register(&gufi_acpi_driver); +} + +static void __init gufi_acpi_exit(void) +{ + platform_driver_unregister(&gufi_acpi_driver); +} + +module_init(gufi_acpi_init); +module_exit(gufi_acpi_exit); + +MODULE_AUTHOR("Al Stone al.stone@linaro.org"); +MODULE_DESCRIPTION("DT Test Driver for the Grand Unified Firmware Interface"); +MODULE_LICENSE("GPL"); + +#endif /* CONFIG_OF */ + +#endif /* CONFIG_GUFI */ diff --git a/drivers/gufi/gufi_of_test.c b/drivers/gufi/gufi_of_test.c new file mode 100644 index 0000000..60ebc71 --- /dev/null +++ b/drivers/gufi/gufi_of_test.c @@ -0,0 +1,83 @@ +/* + * Grand Unified Firmware Interface -- test driver + * + * Copyright (C) 2013 Al Stone al.stone@linaro.org + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +#ifdef CONFIG_GUFI + +#ifdef CONFIG_OF + +#include <linux/gufi.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/platform_device.h> + +/* Platform Device */ + +static int gufi_of_probe(struct platform_device *pdev) +{ + return -EINVAL; +} + +static int gufi_of_remove(struct platform_device *pdev) +{ + return -EINVAL; +} + +/* Platform Driver */ + +static struct of_device_id gufi_of_match[] = { + { .compatible = "gufi,of", }, + { } +}; +MODULE_DEVICE_TABLE(gufi, gufi_of_match); + +static struct platform_driver gufi_of_driver = { + .probe = gufi_of_probe, + .remove = gufi_of_remove, + .driver = { + .name = "gufi-of-test", + .owner = THIS_MODULE, + .of_match_table = gufi_of_match, + }, +}; + +static int __init gufi_of_init(void) +{ + return platform_driver_register(&gufi_of_driver); +} + +static void __init gufi_of_exit(void) +{ + platform_driver_unregister(&gufi_of_driver); +} + +module_init(gufi_of_init); +module_exit(gufi_of_exit); + +MODULE_AUTHOR("Al Stone al.stone@linaro.org"); +MODULE_DESCRIPTION("DT Test Driver for the Grand Unified Firmware Interface"); +MODULE_LICENSE("GPL"); + +#endif /* CONFIG_OF */ + +#endif /* CONFIG_GUFI */
From: Al Stone al.stone@linaro.org
As a way to test out the concepts and implementation, start converting the existing vexpress-sysreg driver so that it uses the GUFI. The intent is to (a) act as a test for the idea, and (b) be very clear on how extensive (or not) the changes actually are. The goal is to make it so the changes can be done almost entirely with a sed script.
Signed-off-by: Al Stone al.stone@linaro.org --- drivers/mfd/vexpress-sysreg.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/drivers/mfd/vexpress-sysreg.c b/drivers/mfd/vexpress-sysreg.c index 31f60ff..3e7e4d3 100644 --- a/drivers/mfd/vexpress-sysreg.c +++ b/drivers/mfd/vexpress-sysreg.c @@ -15,14 +15,13 @@ #include <linux/gpio.h> #include <linux/io.h> #include <linux/leds.h> -#include <linux/of_address.h> +#include <linux/gufi.h> #include <linux/platform_device.h> #include <linux/regulator/driver.h> #include <linux/slab.h> #include <linux/stat.h> #include <linux/timer.h> #include <linux/vexpress.h> -#include <linux/acpi.h>
#define SYS_ID 0x000 #define SYS_SW 0x004 @@ -118,9 +117,11 @@ void __iomem *vexpress_get_24mhz_clock_base(void) static void vexpress_sysreg_find_prop(struct device_node *node, const char *name, u32 *val) { + /* BOZO: should be gufi_node_get(node); */ of_node_get(node); while (node) { if (of_property_read_u32(node, name, val) == 0) { + /* BOZO: should be gufi_node_put(node); */ of_node_put(node); return; } @@ -339,15 +340,16 @@ void __init vexpress_sysreg_early_init(void __iomem *base)
void __init vexpress_sysreg_of_early_init(void) { - struct device_node *node; + struct gufi_device_node *node;
if (vexpress_sysreg_base) return;
- node = of_find_compatible_node(NULL, NULL, "arm,vexpress-sysreg"); + node = gufi_find_compatible_node(NULL, NULL, "arm,vexpress-sysreg"); if (node) { - vexpress_sysreg_base = of_iomap(node, 0); - vexpress_sysreg_setup(node); + vexpress_sysreg_base = gufi_iomap(node, 0); + /* BOZO: was vexpress_sysreg_setup(node); */ + vexpress_sysreg_setup(node->dn); } }
W dniu 12/10/13 01:13, al.stone@linaro.org pisze:
From: Al Stone al.stone@linaro.org
These patches are purely experimental; they just barely compile and they do not run just yet. The reason for posting them is really just to stir some discussion and see if this is a truly crazy idea or if it has some potential for easing the ACPI transition.
These patches introduce GUFI: the Grand Unified Firmware Interface. Okay, yes, it is a silly name. I didn't spend a lot of time on it. What I'm most interested in is the idea and whether it is worth pursuing further, and whether or not there are better ways to do this if it does make sense.
The idea is very simple: introduce a shim layer that looks like a merge of some sort between ACPI and FDT functionality in the kernel. In that shim layer, make it possible for a driver to make a single call to a function, and with that call, retrieve configuration information stored in either ACPI tables or a DT. Further, allow the kernel to specify which has priority -- i.e., search through ACPI tables, and then through FDT if data is not found, or vice versa -- or which is exclusive, either ACPI or FDT only.
Why would I do this? As a kernel developer, this allows me to make changes in the direction of either FDT or ACPI as quickly or as slowly as I want to. Most of my config can be in FDT and I can then piecemeal convert to ACPI as I figure out ASL and/or any driver changes that may be needed. Secondly, if I do this well, the changes to convert from FDT to ACPI *should* be very small; from ACPI to FDT may be much more difficult but over time that can likely be improved as well. Third, in the really, really long term, maybe someone comes up with yet another hardware configuration description format that is so cool it provides sharks with laser beams on their heads and *everyone* wants to convert to it. With this layer in place, perhaps we can smooth even that transition by abstracting out the config info that's needed and the API to retrieve it.
So, what do you think?
Hi Al,
Sorry you had to wait so long.
Here is my 2 cents on this: 1. The goal is really noble :) 2. AFAIU, that should be generic API for driver binding, which is hardware configuration independent. But, I can see OF and ACPI specific arguments in GUFI's API. Image how hard would it be to add next h/w description (with laser and turbo on his back :) ).
In my opinion, we could treat GUFI layer like socket with many protocols supported. First step would be to register h/w configuration description handlers to GUFI's list and then use generic GUFI's API in drivers which suppose to dispatch appropriate handler:
struct gufi_protocol of_protoc { .find_node = of_find_compatible_node, .... };
gufi_register_prot(struct gufi_protocol prot) { add_prot_to_gufi_list(prot); ... }
gufi_find_compatible_node(struct gufi_device_node *node) { struct gufi_protocol prot;
/* h/w config description handler dispatch */ prot = find_prot_for_node_from_gufi_list(node); /* Call h/w configuration specific handler */ prot.find_node(args...); }
My two concerns: 1. Can we find GUFI's API generic enough to satisfy possible h/w description. 2. Will it be upstreamed with only two h/w configuration description - OF and ACPI.
Tomasz
Al Stone (5): ACPI: GUFI: add kernel config options for GUFI ACPI: GUFI: add build commands for drivers/gufi ACPI: GUFI: add in early prototype code for some GUFI functions ACPI: GUFI: add in simple test driver placeholders ACPI: GUFI: start modifying the vexpress-sysreg driver to use the GUFI
arch/arm64/Kconfig | 6 - drivers/Kconfig | 2 + drivers/Makefile | 1 + drivers/acpi/acpi_platform.c | 1 + drivers/gufi/Kconfig | 54 ++++++++ drivers/gufi/Makefile | 11 ++ drivers/gufi/gufi.c | 309 ++++++++++++++++++++++++++++++++++++++++++ drivers/gufi/gufi_acpi_test.c | 84 ++++++++++++ drivers/gufi/gufi_of_test.c | 83 ++++++++++++ drivers/mfd/vexpress-sysreg.c | 14 +- include/linux/gufi.h | 83 ++++++++++++ 11 files changed, 636 insertions(+), 12 deletions(-) create mode 100644 drivers/gufi/Kconfig create mode 100644 drivers/gufi/Makefile create mode 100644 drivers/gufi/gufi.c create mode 100644 drivers/gufi/gufi_acpi_test.c create mode 100644 drivers/gufi/gufi_of_test.c create mode 100644 include/linux/gufi.h
On Tue, Jan 14, 2014 at 12:03:04PM +0100, Tomasz Nowicki wrote:
W dniu 12/10/13 01:13, al.stone@linaro.org pisze:
From: Al Stone al.stone@linaro.org
These patches are purely experimental; they just barely compile and they do not run just yet. The reason for posting them is really just to stir some discussion and see if this is a truly crazy idea or if it has some potential for easing the ACPI transition.
These patches introduce GUFI: the Grand Unified Firmware Interface. Okay, yes, it is a silly name. I didn't spend a lot of time on it. What I'm most interested in is the idea and whether it is worth pursuing further, and whether or not there are better ways to do this if it does make sense.
The idea is very simple: introduce a shim layer that looks like a merge of some sort between ACPI and FDT functionality in the kernel. In that shim layer, make it possible for a driver to make a single call to a function, and with that call, retrieve configuration information stored in either ACPI tables or a DT. Further, allow the kernel to specify which has priority -- i.e., search through ACPI tables, and then through FDT if data is not found, or vice versa -- or which is exclusive, either ACPI or FDT only.
Why would I do this? As a kernel developer, this allows me to make changes in the direction of either FDT or ACPI as quickly or as slowly as I want to. Most of my config can be in FDT and I can then piecemeal convert to ACPI as I figure out ASL and/or any driver changes that may be needed. Secondly, if I do this well, the changes to convert from FDT to ACPI *should* be very small; from ACPI to FDT may be much more difficult but over time that can likely be improved as well. Third, in the really, really long term, maybe someone comes up with yet another hardware configuration description format that is so cool it provides sharks with laser beams on their heads and *everyone* wants to convert to it. With this layer in place, perhaps we can smooth even that transition by abstracting out the config info that's needed and the API to retrieve it.
So, what do you think?
Hi Al,
Sorry you had to wait so long.
Here is my 2 cents on this:
- The goal is really noble :)
- AFAIU, that should be generic API for driver binding, which is
hardware configuration independent. But, I can see OF and ACPI specific arguments in GUFI's API. Image how hard would it be to add next h/w description (with laser and turbo on his back :) ).
Hi Tomasz,
you reminded me to look at the patch, I think you are correct about the API, I think it should take dev/pdev arguments only. All the of/acpi stuff should be actually hidden so if your trying to get a config string all the finding correct node/ACPI ASL bit should be invisible.
This may actually be impossible in the non trivial case as it requires ACPI and DT bindings to be pretty identical which is already not going to happen with _PRP method + ACPI native support. I especially expect values hidden in sub-nodes to break.
Graeme
In my opinion, we could treat GUFI layer like socket with many protocols supported. First step would be to register h/w configuration description handlers to GUFI's list and then use generic GUFI's API in drivers which suppose to dispatch appropriate handler:
struct gufi_protocol of_protoc { .find_node = of_find_compatible_node, .... };
gufi_register_prot(struct gufi_protocol prot) { add_prot_to_gufi_list(prot); ... }
gufi_find_compatible_node(struct gufi_device_node *node) { struct gufi_protocol prot;
/* h/w config description handler dispatch */ prot = find_prot_for_node_from_gufi_list(node); /* Call h/w configuration specific handler */ prot.find_node(args...); }
My two concerns:
- Can we find GUFI's API generic enough to satisfy possible h/w
description. 2. Will it be upstreamed with only two h/w configuration description
- OF and ACPI.
Tomasz
Al Stone (5): ACPI: GUFI: add kernel config options for GUFI ACPI: GUFI: add build commands for drivers/gufi ACPI: GUFI: add in early prototype code for some GUFI functions ACPI: GUFI: add in simple test driver placeholders ACPI: GUFI: start modifying the vexpress-sysreg driver to use the GUFI
arch/arm64/Kconfig | 6 - drivers/Kconfig | 2 + drivers/Makefile | 1 + drivers/acpi/acpi_platform.c | 1 + drivers/gufi/Kconfig | 54 ++++++++ drivers/gufi/Makefile | 11 ++ drivers/gufi/gufi.c | 309 ++++++++++++++++++++++++++++++++++++++++++ drivers/gufi/gufi_acpi_test.c | 84 ++++++++++++ drivers/gufi/gufi_of_test.c | 83 ++++++++++++ drivers/mfd/vexpress-sysreg.c | 14 +- include/linux/gufi.h | 83 ++++++++++++ 11 files changed, 636 insertions(+), 12 deletions(-) create mode 100644 drivers/gufi/Kconfig create mode 100644 drivers/gufi/Makefile create mode 100644 drivers/gufi/gufi.c create mode 100644 drivers/gufi/gufi_acpi_test.c create mode 100644 drivers/gufi/gufi_of_test.c create mode 100644 include/linux/gufi.h
Linaro-acpi mailing list Linaro-acpi@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-acpi
W dniu 01/14/14 15:52, Graeme Gregory pisze:
On Tue, Jan 14, 2014 at 12:03:04PM +0100, Tomasz Nowicki wrote:
W dniu 12/10/13 01:13, al.stone@linaro.org pisze:
From: Al Stone al.stone@linaro.org
These patches are purely experimental; they just barely compile and they do not run just yet. The reason for posting them is really just to stir some discussion and see if this is a truly crazy idea or if it has some potential for easing the ACPI transition.
These patches introduce GUFI: the Grand Unified Firmware Interface. Okay, yes, it is a silly name. I didn't spend a lot of time on it. What I'm most interested in is the idea and whether it is worth pursuing further, and whether or not there are better ways to do this if it does make sense.
The idea is very simple: introduce a shim layer that looks like a merge of some sort between ACPI and FDT functionality in the kernel. In that shim layer, make it possible for a driver to make a single call to a function, and with that call, retrieve configuration information stored in either ACPI tables or a DT. Further, allow the kernel to specify which has priority -- i.e., search through ACPI tables, and then through FDT if data is not found, or vice versa -- or which is exclusive, either ACPI or FDT only.
Why would I do this? As a kernel developer, this allows me to make changes in the direction of either FDT or ACPI as quickly or as slowly as I want to. Most of my config can be in FDT and I can then piecemeal convert to ACPI as I figure out ASL and/or any driver changes that may be needed. Secondly, if I do this well, the changes to convert from FDT to ACPI *should* be very small; from ACPI to FDT may be much more difficult but over time that can likely be improved as well. Third, in the really, really long term, maybe someone comes up with yet another hardware configuration description format that is so cool it provides sharks with laser beams on their heads and *everyone* wants to convert to it. With this layer in place, perhaps we can smooth even that transition by abstracting out the config info that's needed and the API to retrieve it.
So, what do you think?
Hi Al,
Sorry you had to wait so long.
Here is my 2 cents on this:
- The goal is really noble :)
- AFAIU, that should be generic API for driver binding, which is
hardware configuration independent. But, I can see OF and ACPI specific arguments in GUFI's API. Image how hard would it be to add next h/w description (with laser and turbo on his back :) ).
Hi Tomasz,
you reminded me to look at the patch, I think you are correct about the API, I think it should take dev/pdev arguments only. All the of/acpi stuff should be actually hidden so if your trying to get a config string all the finding correct node/ACPI ASL bit should be invisible.
This may actually be impossible in the non trivial case as it requires ACPI and DT bindings to be pretty identical which is already not going to happen with _PRP method + ACPI native support. I especially expect values hidden in sub-nodes to break.
Right, that was one of my concerns.
Tomasz
Graeme
In my opinion, we could treat GUFI layer like socket with many protocols supported. First step would be to register h/w configuration description handlers to GUFI's list and then use generic GUFI's API in drivers which suppose to dispatch appropriate handler:
struct gufi_protocol of_protoc { .find_node = of_find_compatible_node, .... };
gufi_register_prot(struct gufi_protocol prot) { add_prot_to_gufi_list(prot); ... }
gufi_find_compatible_node(struct gufi_device_node *node) { struct gufi_protocol prot;
/* h/w config description handler dispatch */ prot = find_prot_for_node_from_gufi_list(node); /* Call h/w configuration specific handler */ prot.find_node(args...); }
My two concerns:
- Can we find GUFI's API generic enough to satisfy possible h/w
description. 2. Will it be upstreamed with only two h/w configuration description
- OF and ACPI.
Tomasz
Al Stone (5): ACPI: GUFI: add kernel config options for GUFI ACPI: GUFI: add build commands for drivers/gufi ACPI: GUFI: add in early prototype code for some GUFI functions ACPI: GUFI: add in simple test driver placeholders ACPI: GUFI: start modifying the vexpress-sysreg driver to use the GUFI
arch/arm64/Kconfig | 6 - drivers/Kconfig | 2 + drivers/Makefile | 1 + drivers/acpi/acpi_platform.c | 1 + drivers/gufi/Kconfig | 54 ++++++++ drivers/gufi/Makefile | 11 ++ drivers/gufi/gufi.c | 309 ++++++++++++++++++++++++++++++++++++++++++ drivers/gufi/gufi_acpi_test.c | 84 ++++++++++++ drivers/gufi/gufi_of_test.c | 83 ++++++++++++ drivers/mfd/vexpress-sysreg.c | 14 +- include/linux/gufi.h | 83 ++++++++++++ 11 files changed, 636 insertions(+), 12 deletions(-) create mode 100644 drivers/gufi/Kconfig create mode 100644 drivers/gufi/Makefile create mode 100644 drivers/gufi/gufi.c create mode 100644 drivers/gufi/gufi_acpi_test.c create mode 100644 drivers/gufi/gufi_of_test.c create mode 100644 include/linux/gufi.h
Linaro-acpi mailing list Linaro-acpi@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-acpi
On Tue, Jan 14, 2014 at 03:59:37PM +0100, Tomasz Nowicki wrote:
W dniu 01/14/14 15:52, Graeme Gregory pisze:
On Tue, Jan 14, 2014 at 12:03:04PM +0100, Tomasz Nowicki wrote:
W dniu 12/10/13 01:13, al.stone@linaro.org pisze:
From: Al Stone al.stone@linaro.org
These patches are purely experimental; they just barely compile and they do not run just yet. The reason for posting them is really just to stir some discussion and see if this is a truly crazy idea or if it has some potential for easing the ACPI transition.
These patches introduce GUFI: the Grand Unified Firmware Interface. Okay, yes, it is a silly name. I didn't spend a lot of time on it. What I'm most interested in is the idea and whether it is worth pursuing further, and whether or not there are better ways to do this if it does make sense.
The idea is very simple: introduce a shim layer that looks like a merge of some sort between ACPI and FDT functionality in the kernel. In that shim layer, make it possible for a driver to make a single call to a function, and with that call, retrieve configuration information stored in either ACPI tables or a DT. Further, allow the kernel to specify which has priority -- i.e., search through ACPI tables, and then through FDT if data is not found, or vice versa -- or which is exclusive, either ACPI or FDT only.
Why would I do this? As a kernel developer, this allows me to make changes in the direction of either FDT or ACPI as quickly or as slowly as I want to. Most of my config can be in FDT and I can then piecemeal convert to ACPI as I figure out ASL and/or any driver changes that may be needed. Secondly, if I do this well, the changes to convert from FDT to ACPI *should* be very small; from ACPI to FDT may be much more difficult but over time that can likely be improved as well. Third, in the really, really long term, maybe someone comes up with yet another hardware configuration description format that is so cool it provides sharks with laser beams on their heads and *everyone* wants to convert to it. With this layer in place, perhaps we can smooth even that transition by abstracting out the config info that's needed and the API to retrieve it.
So, what do you think?
Hi Al,
Sorry you had to wait so long.
Here is my 2 cents on this:
- The goal is really noble :)
- AFAIU, that should be generic API for driver binding, which is
hardware configuration independent. But, I can see OF and ACPI specific arguments in GUFI's API. Image how hard would it be to add next h/w description (with laser and turbo on his back :) ).
Hi Tomasz,
you reminded me to look at the patch, I think you are correct about the API, I think it should take dev/pdev arguments only. All the of/acpi stuff should be actually hidden so if your trying to get a config string all the finding correct node/ACPI ASL bit should be invisible.
This may actually be impossible in the non trivial case as it requires ACPI and DT bindings to be pretty identical which is already not going to happen with _PRP method + ACPI native support. I especially expect values hidden in sub-nodes to break.
Right, that was one of my concerns.
Another thought occurs to me is yet again we are suffering from a lack of information about armv8 server architecture.
This interface is assuming the same IP blocks will be used for server and mobile type devices. If this is not true then the drivers will be different for each platform and big machine drivers can be ACPI and little machine drivers DT without any collision.
We are only hitting this issue at the moment because there is only one armv8 model and it doesn't really represent either expected platform.
Graeme
Tomasz
Graeme
In my opinion, we could treat GUFI layer like socket with many protocols supported. First step would be to register h/w configuration description handlers to GUFI's list and then use generic GUFI's API in drivers which suppose to dispatch appropriate handler:
struct gufi_protocol of_protoc { .find_node = of_find_compatible_node, .... };
gufi_register_prot(struct gufi_protocol prot) { add_prot_to_gufi_list(prot); ... }
gufi_find_compatible_node(struct gufi_device_node *node) { struct gufi_protocol prot;
/* h/w config description handler dispatch */ prot = find_prot_for_node_from_gufi_list(node); /* Call h/w configuration specific handler */ prot.find_node(args...); }
My two concerns:
- Can we find GUFI's API generic enough to satisfy possible h/w
description. 2. Will it be upstreamed with only two h/w configuration description
- OF and ACPI.
Tomasz
Al Stone (5): ACPI: GUFI: add kernel config options for GUFI ACPI: GUFI: add build commands for drivers/gufi ACPI: GUFI: add in early prototype code for some GUFI functions ACPI: GUFI: add in simple test driver placeholders ACPI: GUFI: start modifying the vexpress-sysreg driver to use the GUFI
arch/arm64/Kconfig | 6 - drivers/Kconfig | 2 + drivers/Makefile | 1 + drivers/acpi/acpi_platform.c | 1 + drivers/gufi/Kconfig | 54 ++++++++ drivers/gufi/Makefile | 11 ++ drivers/gufi/gufi.c | 309 ++++++++++++++++++++++++++++++++++++++++++ drivers/gufi/gufi_acpi_test.c | 84 ++++++++++++ drivers/gufi/gufi_of_test.c | 83 ++++++++++++ drivers/mfd/vexpress-sysreg.c | 14 +- include/linux/gufi.h | 83 ++++++++++++ 11 files changed, 636 insertions(+), 12 deletions(-) create mode 100644 drivers/gufi/Kconfig create mode 100644 drivers/gufi/Makefile create mode 100644 drivers/gufi/gufi.c create mode 100644 drivers/gufi/gufi_acpi_test.c create mode 100644 drivers/gufi/gufi_of_test.c create mode 100644 include/linux/gufi.h
Linaro-acpi mailing list Linaro-acpi@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-acpi
On 01/14/2014 08:20 AM, Graeme Gregory wrote:
On Tue, Jan 14, 2014 at 03:59:37PM +0100, Tomasz Nowicki wrote:
W dniu 01/14/14 15:52, Graeme Gregory pisze:
On Tue, Jan 14, 2014 at 12:03:04PM +0100, Tomasz Nowicki wrote:
W dniu 12/10/13 01:13, al.stone@linaro.org pisze:
From: Al Stone al.stone@linaro.org
These patches are purely experimental; they just barely compile and they do not run just yet. The reason for posting them is really just to stir some discussion and see if this is a truly crazy idea or if it has some potential for easing the ACPI transition.
These patches introduce GUFI: the Grand Unified Firmware Interface. Okay, yes, it is a silly name. I didn't spend a lot of time on it. What I'm most interested in is the idea and whether it is worth pursuing further, and whether or not there are better ways to do this if it does make sense.
The idea is very simple: introduce a shim layer that looks like a merge of some sort between ACPI and FDT functionality in the kernel. In that shim layer, make it possible for a driver to make a single call to a function, and with that call, retrieve configuration information stored in either ACPI tables or a DT. Further, allow the kernel to specify which has priority -- i.e., search through ACPI tables, and then through FDT if data is not found, or vice versa -- or which is exclusive, either ACPI or FDT only.
Why would I do this? As a kernel developer, this allows me to make changes in the direction of either FDT or ACPI as quickly or as slowly as I want to. Most of my config can be in FDT and I can then piecemeal convert to ACPI as I figure out ASL and/or any driver changes that may be needed. Secondly, if I do this well, the changes to convert from FDT to ACPI *should* be very small; from ACPI to FDT may be much more difficult but over time that can likely be improved as well. Third, in the really, really long term, maybe someone comes up with yet another hardware configuration description format that is so cool it provides sharks with laser beams on their heads and *everyone* wants to convert to it. With this layer in place, perhaps we can smooth even that transition by abstracting out the config info that's needed and the API to retrieve it.
So, what do you think?
Hi Al,
Sorry you had to wait so long.
Here is my 2 cents on this:
- The goal is really noble :)
- AFAIU, that should be generic API for driver binding, which is
hardware configuration independent. But, I can see OF and ACPI specific arguments in GUFI's API. Image how hard would it be to add next h/w description (with laser and turbo on his back :) ).
Hi Tomasz,
you reminded me to look at the patch, I think you are correct about the API, I think it should take dev/pdev arguments only. All the of/acpi stuff should be actually hidden so if your trying to get a config string all the finding correct node/ACPI ASL bit should be invisible.
This may actually be impossible in the non trivial case as it requires ACPI and DT bindings to be pretty identical which is already not going to happen with _PRP method + ACPI native support. I especially expect values hidden in sub-nodes to break.
Right, that was one of my concerns.
Another thought occurs to me is yet again we are suffering from a lack of information about armv8 server architecture.
This interface is assuming the same IP blocks will be used for server and mobile type devices. If this is not true then the drivers will be different for each platform and big machine drivers can be ACPI and little machine drivers DT without any collision.
We are only hitting this issue at the moment because there is only one armv8 model and it doesn't really represent either expected platform.
Graeme
Tomasz
Graeme
In my opinion, we could treat GUFI layer like socket with many protocols supported. First step would be to register h/w configuration description handlers to GUFI's list and then use generic GUFI's API in drivers which suppose to dispatch appropriate handler:
struct gufi_protocol of_protoc { .find_node = of_find_compatible_node, .... };
gufi_register_prot(struct gufi_protocol prot) { add_prot_to_gufi_list(prot); ... }
gufi_find_compatible_node(struct gufi_device_node *node) { struct gufi_protocol prot;
/* h/w config description handler dispatch */ prot = find_prot_for_node_from_gufi_list(node); /* Call h/w configuration specific handler */ prot.find_node(args...); }
My two concerns:
- Can we find GUFI's API generic enough to satisfy possible h/w
description. 2. Will it be upstreamed with only two h/w configuration description
- OF and ACPI.
Tomasz
Al Stone (5): ACPI: GUFI: add kernel config options for GUFI ACPI: GUFI: add build commands for drivers/gufi ACPI: GUFI: add in early prototype code for some GUFI functions ACPI: GUFI: add in simple test driver placeholders ACPI: GUFI: start modifying the vexpress-sysreg driver to use the GUFI
arch/arm64/Kconfig | 6 - drivers/Kconfig | 2 + drivers/Makefile | 1 + drivers/acpi/acpi_platform.c | 1 + drivers/gufi/Kconfig | 54 ++++++++ drivers/gufi/Makefile | 11 ++ drivers/gufi/gufi.c | 309 ++++++++++++++++++++++++++++++++++++++++++ drivers/gufi/gufi_acpi_test.c | 84 ++++++++++++ drivers/gufi/gufi_of_test.c | 83 ++++++++++++ drivers/mfd/vexpress-sysreg.c | 14 +- include/linux/gufi.h | 83 ++++++++++++ 11 files changed, 636 insertions(+), 12 deletions(-) create mode 100644 drivers/gufi/Kconfig create mode 100644 drivers/gufi/Makefile create mode 100644 drivers/gufi/gufi.c create mode 100644 drivers/gufi/gufi_acpi_test.c create mode 100644 drivers/gufi/gufi_of_test.c create mode 100644 include/linux/gufi.h
Linaro-acpi mailing list Linaro-acpi@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-acpi
For those following along at home, the prototype code is stashed here:
https://github.com/ahs3/leg-kernel/tree/gufi
That's the branch as posted in this RFC. I've started playing with the protocol idea and some early code for that is here:
https://github.com/ahs3/leg-kernel/tree/gufi2
It looks promising.
On 01/14/2014 07:59 AM, Tomasz Nowicki wrote:
W dniu 01/14/14 15:52, Graeme Gregory pisze:
On Tue, Jan 14, 2014 at 12:03:04PM +0100, Tomasz Nowicki wrote:
W dniu 12/10/13 01:13, al.stone@linaro.org pisze:
From: Al Stone al.stone@linaro.org
These patches are purely experimental; they just barely compile and they do not run just yet. The reason for posting them is really just to stir some discussion and see if this is a truly crazy idea or if it has some potential for easing the ACPI transition.
These patches introduce GUFI: the Grand Unified Firmware Interface. Okay, yes, it is a silly name. I didn't spend a lot of time on it. What I'm most interested in is the idea and whether it is worth pursuing further, and whether or not there are better ways to do this if it does make sense.
The idea is very simple: introduce a shim layer that looks like a merge of some sort between ACPI and FDT functionality in the kernel. In that shim layer, make it possible for a driver to make a single call to a function, and with that call, retrieve configuration information stored in either ACPI tables or a DT. Further, allow the kernel to specify which has priority -- i.e., search through ACPI tables, and then through FDT if data is not found, or vice versa -- or which is exclusive, either ACPI or FDT only.
Why would I do this? As a kernel developer, this allows me to make changes in the direction of either FDT or ACPI as quickly or as slowly as I want to. Most of my config can be in FDT and I can then piecemeal convert to ACPI as I figure out ASL and/or any driver changes that may be needed. Secondly, if I do this well, the changes to convert from FDT to ACPI *should* be very small; from ACPI to FDT may be much more difficult but over time that can likely be improved as well. Third, in the really, really long term, maybe someone comes up with yet another hardware configuration description format that is so cool it provides sharks with laser beams on their heads and *everyone* wants to convert to it. With this layer in place, perhaps we can smooth even that transition by abstracting out the config info that's needed and the API to retrieve it.
So, what do you think?
Hi Al,
Sorry you had to wait so long.
Here is my 2 cents on this:
- The goal is really noble :)
- AFAIU, that should be generic API for driver binding, which is
hardware configuration independent. But, I can see OF and ACPI specific arguments in GUFI's API. Image how hard would it be to add next h/w description (with laser and turbo on his back :) ).
Hi Tomasz,
you reminded me to look at the patch, I think you are correct about the API, I think it should take dev/pdev arguments only. All the of/acpi stuff should be actually hidden so if your trying to get a config string all the finding correct node/ACPI ASL bit should be invisible.
This may actually be impossible in the non trivial case as it requires ACPI and DT bindings to be pretty identical which is already not going to happen with _PRP method + ACPI native support. I especially expect values hidden in sub-nodes to break.
Right, that was one of my concerns.
Tomasz
Graeme
In my opinion, we could treat GUFI layer like socket with many protocols supported. First step would be to register h/w configuration description handlers to GUFI's list and then use generic GUFI's API in drivers which suppose to dispatch appropriate handler:
struct gufi_protocol of_protoc { .find_node = of_find_compatible_node, .... };
gufi_register_prot(struct gufi_protocol prot) { add_prot_to_gufi_list(prot); ... }
gufi_find_compatible_node(struct gufi_device_node *node) { struct gufi_protocol prot;
/* h/w config description handler dispatch */ prot = find_prot_for_node_from_gufi_list(node); /* Call h/w configuration specific handler */ prot.find_node(args...);
}
My two concerns:
- Can we find GUFI's API generic enough to satisfy possible h/w
description. 2. Will it be upstreamed with only two h/w configuration description
- OF and ACPI.
Tomasz
I had thought about structuring this the way Tomasz suggested; in fact, I would still prefer to do that -- it seems the right way to handle it.
And I agree with Graeme that it may be hard to do -- the APIs are so very different in so many odd ways.
That difficulty is partly why this prototype looks like it does. But, I was also trying to see if I could make this work by not changing any code in the driver itself. Or, if that was not possible, make the API so that you could just do "sed 's/of_*/gufi_*/g'" on the source and it would be mostly done. That is, ideally, absolute minimal changes in order to enable ACPI. If we go to a combined/abstracted API (the more elegant solution, truth be told), every driver would eventually need to change should GUFI become the default, and that's a lot of work.
The other thing I was thinking about at the time was the idea of having some way to support development or transition. For example, just like we have been doing, suppose I have a DT-based driver I am converting to ACPI. If GUFI could allow me to intermix the two while I'm making the changes -- i.e., get some info from DT, some from ACPI -- then I can do incremental changes. If we use the protocol idea, that may still be possible, but I'd have to think that through some more.
That being said, perhaps these things should not be requirements; patches are always welcome :), and I'm definitely going to step back and play with the idea of the protocol method more seriously just to see what happens.
Oh, the other concern I have is I would like to avoid creating an API just to have an API. The chances of getting that upstream I assume are nil. Features like those mentioned above would help keep that from happening.
BTW, thanks for all the comments -- that's exactly the sort of feedback I was hoping to get.
Al Stone (5): ACPI: GUFI: add kernel config options for GUFI ACPI: GUFI: add build commands for drivers/gufi ACPI: GUFI: add in early prototype code for some GUFI functions ACPI: GUFI: add in simple test driver placeholders ACPI: GUFI: start modifying the vexpress-sysreg driver to use the GUFI
arch/arm64/Kconfig | 6 - drivers/Kconfig | 2 + drivers/Makefile | 1 + drivers/acpi/acpi_platform.c | 1 + drivers/gufi/Kconfig | 54 ++++++++ drivers/gufi/Makefile | 11 ++ drivers/gufi/gufi.c | 309 ++++++++++++++++++++++++++++++++++++++++++ drivers/gufi/gufi_acpi_test.c | 84 ++++++++++++ drivers/gufi/gufi_of_test.c | 83 ++++++++++++ drivers/mfd/vexpress-sysreg.c | 14 +- include/linux/gufi.h | 83 ++++++++++++ 11 files changed, 636 insertions(+), 12 deletions(-) create mode 100644 drivers/gufi/Kconfig create mode 100644 drivers/gufi/Makefile create mode 100644 drivers/gufi/gufi.c create mode 100644 drivers/gufi/gufi_acpi_test.c create mode 100644 drivers/gufi/gufi_of_test.c create mode 100644 include/linux/gufi.h
Linaro-acpi mailing list Linaro-acpi@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-acpi
On Mon, 9 Dec 2013 17:13:06 -0700, al.stone@linaro.org wrote:
From: Al Stone al.stone@linaro.org
These patches are purely experimental; they just barely compile and they do not run just yet. The reason for posting them is really just to stir some discussion and see if this is a truly crazy idea or if it has some potential for easing the ACPI transition.
These patches introduce GUFI: the Grand Unified Firmware Interface. Okay, yes, it is a silly name. I didn't spend a lot of time on it. What I'm most interested in is the idea and whether it is worth pursuing further, and whether or not there are better ways to do this if it does make sense.
The idea is very simple: introduce a shim layer that looks like a merge of some sort between ACPI and FDT functionality in the kernel. In that shim layer, make it possible for a driver to make a single call to a function, and with that call, retrieve configuration information stored in either ACPI tables or a DT. Further, allow the kernel to specify which has priority -- i.e., search through ACPI tables, and then through FDT if data is not found, or vice versa -- or which is exclusive, either ACPI or FDT only.
Hi Al,
Thanks for kicking this off.
So.... as I said in our chat this morning, I fully support having some of the decode logic behind an API that works for both FDT and ACPI... but this isn't it. :-)
I think the approach that you're taking here is too ambitious. Trying to unify both the DT and ACPI into a single tree, and then having access to data anywhere within that tree feels like far too much abstraction and I think it will become very fragile.
I would like instead to restrict the shared API to only decoding properties from either a single node, or a single node and it's children. By making it relative to a single node, you don't need to recreate the entire tree structure just to create a unified concept of a GUFI node.
I do understand the problem of what gets passed in then? acpi_device or device_node? Instead of trying to do that, I think it would be reasonable for the API to pass in the struct device pointer instead. The main user of this feature is going to be device drivers anyway, so by passing in the struct device, the API can choose whichever one is populated.
At the same time, I would really like to explore a decode descripter type of interface, where all of the desired properties are listed in a structure and the API takes care of error checking on each property. That would be a marked improvement on what we have to do right now for parsing data properties.
g.
Why would I do this? As a kernel developer, this allows me to make changes in the direction of either FDT or ACPI as quickly or as slowly as I want to. Most of my config can be in FDT and I can then piecemeal convert to ACPI as I figure out ASL and/or any driver changes that may be needed. Secondly, if I do this well, the changes to convert from FDT to ACPI *should* be very small; from ACPI to FDT may be much more difficult but over time that can likely be improved as well. Third, in the really, really long term, maybe someone comes up with yet another hardware configuration description format that is so cool it provides sharks with laser beams on their heads and *everyone* wants to convert to it. With this layer in place, perhaps we can smooth even that transition by abstracting out the config info that's needed and the API to retrieve it.
So, what do you think?
Al Stone (5): ACPI: GUFI: add kernel config options for GUFI ACPI: GUFI: add build commands for drivers/gufi ACPI: GUFI: add in early prototype code for some GUFI functions ACPI: GUFI: add in simple test driver placeholders ACPI: GUFI: start modifying the vexpress-sysreg driver to use the GUFI
arch/arm64/Kconfig | 6 - drivers/Kconfig | 2 + drivers/Makefile | 1 + drivers/acpi/acpi_platform.c | 1 + drivers/gufi/Kconfig | 54 ++++++++ drivers/gufi/Makefile | 11 ++ drivers/gufi/gufi.c | 309 ++++++++++++++++++++++++++++++++++++++++++ drivers/gufi/gufi_acpi_test.c | 84 ++++++++++++ drivers/gufi/gufi_of_test.c | 83 ++++++++++++ drivers/mfd/vexpress-sysreg.c | 14 +- include/linux/gufi.h | 83 ++++++++++++ 11 files changed, 636 insertions(+), 12 deletions(-) create mode 100644 drivers/gufi/Kconfig create mode 100644 drivers/gufi/Makefile create mode 100644 drivers/gufi/gufi.c create mode 100644 drivers/gufi/gufi_acpi_test.c create mode 100644 drivers/gufi/gufi_of_test.c create mode 100644 include/linux/gufi.h
-- 1.8.3.1
Linaro-acpi mailing list Linaro-acpi@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-acpi
On Saturday 29 March 2014 01:53:19 Grant Likely wrote:
I do understand the problem of what gets passed in then? acpi_device or device_node? Instead of trying to do that, I think it would be reasonable for the API to pass in the struct device pointer instead. The main user of this feature is going to be device drivers anyway, so by passing in the struct device, the API can choose whichever one is populated.
I agree. It might actually be useful to provide an extension to platform_device_register_full() to allow adding named properties to traditional platform devices, so the interface should at least be able to handle that if we get there. However, we also try to get away from traditional platform devices for most users, it would only be relevant for drivers that are shared with platforms or architectures that we don't plan to convert to DT anyway.
At the same time, I would really like to explore a decode descripter type of interface, where all of the desired properties are listed in a structure and the API takes care of error checking on each property. That would be a marked improvement on what we have to do right now for parsing data properties.
I had started working on something in November, see http://lists.infradead.org/pipermail/linux-arm-kernel/2013-November/209031.h...
Al also wanted to take a closer look at whether he can get it to actually work, as I haven't done any work on it since the original post.
Arnd