2018-04-24 17:33:00

by Bartosz Golaszewski

[permalink] [raw]
Subject: [PATCH 00/11] platform: device tree support for early platform drivers

From: Bartosz Golaszewski <[email protected]>

Device tree based systems often use OF_DECLARE() macros for devices
that need to be initialized early in the boot process such as clocks,
timers etc. However platform devices are more desirable.

This series aims at introducing support for early platform drivers for
OF-based systems.

The idea is to have a special compatible fallback string: "earlydev"
that similarily to "syscon" would be added to device nodes that need
early probing. We then need to call of_early_platform_populate() early
in the boot process to actually probe the registered devices.

I am aware that this new compatible does not strictly correspond with
the "hardware description only" rule of DT, but we already have many
functionalities that break this rule: syscon, gpio hogs etc.

The first user of this new functionality will be the DaVinci platform
for which we want to probe the pll, psc and timer drivers early in the
boot sequence but keep them implemented as platform drivers.

In the future, if this series gets accepted, this could become and
alternative to TIMER_OF_DECLARE, CLK_OF_DECLARE etc. and could lead
to deprecating of those macros in favor of early platform drivers.

Bartosz Golaszewski (11):
platform: early: provide early_platform_add_device()
platform: provide early_platform_driver_register_probe_all()
platform: make support for early platform devices conditional
of: platform: use pdev as name for vars of type struct platform_device
platform: use a dedicated list_head for early devices
of: provide for_each_compatible_child_node()
dt-bindings: add bindings for early devices
of: platform: provide of_early_platform_populate()
platform: provide early_platform_driver()
of: platform: provide of_early_platform_probe()
misc: implement a dummy early platform driver

Documentation/devicetree/bindings/early.txt | 7 +
arch/sh/Kconfig | 1 +
drivers/base/Kconfig | 4 +
drivers/base/platform.c | 26 ++--
drivers/misc/Kconfig | 8 ++
drivers/misc/Makefile | 1 +
drivers/misc/dummy-early.c | 40 ++++++
drivers/of/device.c | 14 +-
drivers/of/platform.c | 143 +++++++++++++++-----
include/linux/device.h | 4 +
include/linux/of.h | 3 +
include/linux/of_device.h | 5 +
include/linux/of_platform.h | 19 +++
include/linux/platform_device.h | 52 +++++++
14 files changed, 279 insertions(+), 48 deletions(-)
create mode 100644 Documentation/devicetree/bindings/early.txt
create mode 100644 drivers/misc/dummy-early.c

--
2.17.0



2018-04-24 17:33:08

by Bartosz Golaszewski

[permalink] [raw]
Subject: [PATCH 03/11] platform: make support for early platform devices conditional

From: Bartosz Golaszewski <[email protected]>

We want to add support for device tree based early platform devices.

In order not to introduce additional bloat for all users when we extend
struct device to accomodate early platform DT support, let's make the
current machine code support conditional.

The only current user of the early platform infrastructure is SuperH so
make it select the appropriate Kconfig option.

Signed-off-by: Bartosz Golaszewski <[email protected]>
---
arch/sh/Kconfig | 1 +
drivers/base/Kconfig | 4 ++++
drivers/base/platform.c | 3 +++
include/linux/platform_device.h | 32 ++++++++++++++++++++++++++++++++
4 files changed, 40 insertions(+)

diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index 97fe29316476..1b2c0b2ce402 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -50,6 +50,7 @@ config SUPERH
select HAVE_ARCH_AUDITSYSCALL
select HAVE_FUTEX_CMPXCHG if FUTEX
select HAVE_NMI
+ select EARLY_PLATFORM_DEVICES
help
The SuperH is a RISC processor targeted for use in embedded systems
and consumer electronics; it was also used in the Sega Dreamcast
diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig
index 29b0eb452b3a..37de5e1d6217 100644
--- a/drivers/base/Kconfig
+++ b/drivers/base/Kconfig
@@ -205,6 +205,10 @@ config DEBUG_TEST_DRIVER_REMOVE
unusable. You should say N here unless you are explicitly looking to
test this functionality.

+config EARLY_PLATFORM_DEVICES
+ bool
+ default n
+
source "drivers/base/test/Kconfig"

config SYS_HYPERVISOR
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 8075ddc70a17..af440d703f0b 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -1186,6 +1186,8 @@ u64 dma_get_required_mask(struct device *dev)
EXPORT_SYMBOL_GPL(dma_get_required_mask);
#endif

+#ifdef CONFIG_EARLY_PLATFORM_DEVICES
+
static __initdata LIST_HEAD(early_platform_driver_list);
static __initdata LIST_HEAD(early_platform_device_list);

@@ -1471,3 +1473,4 @@ void __init early_platform_cleanup(void)
}
}

+#endif /* CONFIG_EARLY_PLATFORM_DEVICES */
diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h
index a06b194ba30b..514ada776004 100644
--- a/include/linux/platform_device.h
+++ b/include/linux/platform_device.h
@@ -297,6 +297,8 @@ struct early_platform_driver {
#define EARLY_PLATFORM_ID_UNSET -2
#define EARLY_PLATFORM_ID_ERROR -3

+#ifdef CONFIG_EARLY_PLATFORM_DEVICES
+
extern int early_platform_driver_register(struct early_platform_driver *epdrv,
char *buf);
extern void early_platform_add_devices(struct platform_device **devs, int num);
@@ -350,6 +352,36 @@ static inline char *early_platform_driver_setup_func(void) \
}
#endif /* MODULE */

+#else /* CONFIG_EARLY_PLATFORM_DEVICES */
+static inline int
+early_platform_driver_register(struct early_platform_driver *epdrv, char *buf)
+{
+ return -ENOSYS;
+}
+static inline void
+early_platform_add_devices(struct platform_device **devs, int num) {}
+static inline void early_platform_add_device(struct platform_device *pdev) {}
+static inline int is_early_platform_device(struct platform_device *pdev)
+{
+ return -ENOSYS;
+}
+static inline void early_platform_driver_register_all(char *class_str) {}
+static inline int early_platform_driver_probe(char *class_str,
+ int nr_probe, int user_only)
+{
+ return -ENOSYS;
+}
+static inline int early_platform_driver_register_probe_all(char *class_str,
+ int nr_probe,
+ int user_only)
+{
+ return -ENOSYS;
+}
+static inline void early_platform_cleanup(void) {}
+#define early_platform_init(class_string, platdrv)
+#define early_platform_init_buffer(class_string, platdrv, buf, bufsiz)
+#endif /* CONFIG_EARLY_PLATFORM_DEVICES */
+
#ifdef CONFIG_SUSPEND
extern int platform_pm_suspend(struct device *dev);
extern int platform_pm_resume(struct device *dev);
--
2.17.0


2018-04-24 17:33:08

by Bartosz Golaszewski

[permalink] [raw]
Subject: [PATCH 04/11] of: platform: use pdev as name for vars of type struct platform_device

From: Bartosz Golaszewski <[email protected]>

It's a good convention to name struct device local variables 'dev'
and reserve 'pdev' for struct platform_device. Otherwise the code
sometimes becomes confusing to read. Rename all such instances in
of/platform.c

Signed-off-by: Bartosz Golaszewski <[email protected]>
---
drivers/of/platform.c | 50 +++++++++++++++++++++----------------------
1 file changed, 25 insertions(+), 25 deletions(-)

diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index c00d81dfac0b..60342209fbd8 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -109,12 +109,12 @@ struct platform_device *of_device_alloc(struct device_node *np,
const char *bus_id,
struct device *parent)
{
- struct platform_device *dev;
+ struct platform_device *pdev;
int rc, i, num_reg = 0, num_irq;
struct resource *res, temp_res;

- dev = platform_device_alloc("", PLATFORM_DEVID_NONE);
- if (!dev)
+ pdev = platform_device_alloc("", PLATFORM_DEVID_NONE);
+ if (!pdev)
return NULL;

/* count the io and irq resources */
@@ -126,12 +126,12 @@ struct platform_device *of_device_alloc(struct device_node *np,
if (num_irq || num_reg) {
res = kzalloc(sizeof(*res) * (num_irq + num_reg), GFP_KERNEL);
if (!res) {
- platform_device_put(dev);
+ platform_device_put(pdev);
return NULL;
}

- dev->num_resources = num_reg + num_irq;
- dev->resource = res;
+ pdev->num_resources = num_reg + num_irq;
+ pdev->resource = res;
for (i = 0; i < num_reg; i++, res++) {
rc = of_address_to_resource(np, i, res);
WARN_ON(rc);
@@ -141,16 +141,16 @@ struct platform_device *of_device_alloc(struct device_node *np,
np->name);
}

- dev->dev.of_node = of_node_get(np);
- dev->dev.fwnode = &np->fwnode;
- dev->dev.parent = parent ? : &platform_bus;
+ pdev->dev.of_node = of_node_get(np);
+ pdev->dev.fwnode = &np->fwnode;
+ pdev->dev.parent = parent ? : &platform_bus;

if (bus_id)
- dev_set_name(&dev->dev, "%s", bus_id);
+ dev_set_name(&pdev->dev, "%s", bus_id);
else
- of_device_make_bus_id(&dev->dev);
+ of_device_make_bus_id(&pdev->dev);

- return dev;
+ return pdev;
}
EXPORT_SYMBOL(of_device_alloc);

@@ -170,26 +170,26 @@ static struct platform_device *of_platform_device_create_pdata(
void *platform_data,
struct device *parent)
{
- struct platform_device *dev;
+ struct platform_device *pdev;

if (!of_device_is_available(np) ||
of_node_test_and_set_flag(np, OF_POPULATED))
return NULL;

- dev = of_device_alloc(np, bus_id, parent);
- if (!dev)
+ pdev = of_device_alloc(np, bus_id, parent);
+ if (!pdev)
goto err_clear_flag;

- dev->dev.bus = &platform_bus_type;
- dev->dev.platform_data = platform_data;
- of_msi_configure(&dev->dev, dev->dev.of_node);
+ pdev->dev.bus = &platform_bus_type;
+ pdev->dev.platform_data = platform_data;
+ of_msi_configure(&pdev->dev, pdev->dev.of_node);

- if (of_device_add(dev) != 0) {
- platform_device_put(dev);
+ if (of_device_add(pdev) != 0) {
+ platform_device_put(pdev);
goto err_clear_flag;
}

- return dev;
+ return pdev;

err_clear_flag:
of_node_clear_flag(np, OF_POPULATED);
@@ -344,7 +344,7 @@ static int of_platform_bus_create(struct device_node *bus,
{
const struct of_dev_auxdata *auxdata;
struct device_node *child;
- struct platform_device *dev;
+ struct platform_device *pdev;
const char *bus_id = NULL;
void *platform_data = NULL;
int rc = 0;
@@ -377,13 +377,13 @@ static int of_platform_bus_create(struct device_node *bus,
return 0;
}

- dev = of_platform_device_create_pdata(bus, bus_id, platform_data, parent);
- if (!dev || !of_match_node(matches, bus))
+ pdev = of_platform_device_create_pdata(bus, bus_id, platform_data, parent);
+ if (!pdev || !of_match_node(matches, bus))
return 0;

for_each_child_of_node(bus, child) {
pr_debug(" create child: %pOF\n", child);
- rc = of_platform_bus_create(child, matches, lookup, &dev->dev, strict);
+ rc = of_platform_bus_create(child, matches, lookup, &pdev->dev, strict);
if (rc) {
of_node_put(child);
break;
--
2.17.0


2018-04-24 17:33:19

by Bartosz Golaszewski

[permalink] [raw]
Subject: [PATCH 11/11] misc: implement a dummy early platform driver

From: Bartosz Golaszewski <[email protected]>

Implement a very simple early platform driver. Its purpose is to show
how such drivers can be registered and to emit a message when probed.

It can be then added to the device tree or machine code to verify that
the early platform devices work as expected.

Signed-off-by: Bartosz Golaszewski <[email protected]>
---
drivers/misc/Kconfig | 8 ++++++++
drivers/misc/Makefile | 1 +
drivers/misc/dummy-early.c | 40 ++++++++++++++++++++++++++++++++++++++
3 files changed, 49 insertions(+)
create mode 100644 drivers/misc/dummy-early.c

diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 5d713008749b..bf9b9b355f81 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -91,6 +91,14 @@ config DUMMY_IRQ
The sole purpose of this module is to help with debugging of systems on
which spurious IRQs would happen on disabled IRQ vector.

+config DUMMY_EARLY
+ bool "Dummy early platform driver"
+ select EARLY_PLATFORM_DEVICES
+ default n
+ help
+ This module's only function is to register itself with the early
+ platform device framework and be probed early in the boot process.
+
config IBM_ASM
tristate "Device driver for IBM RSA service processor"
depends on X86 && PCI && INPUT
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 20be70c3f118..84ad0225eb14 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_INTEL_MID_PTI) += pti.o
obj-$(CONFIG_ATMEL_SSC) += atmel-ssc.o
obj-$(CONFIG_ATMEL_TCLIB) += atmel_tclib.o
obj-$(CONFIG_DUMMY_IRQ) += dummy-irq.o
+obj-$(CONFIG_DUMMY_EARLY) += dummy-early.o
obj-$(CONFIG_ICS932S401) += ics932s401.o
obj-$(CONFIG_LKDTM) += lkdtm/
obj-$(CONFIG_TIFM_CORE) += tifm_core.o
diff --git a/drivers/misc/dummy-early.c b/drivers/misc/dummy-early.c
new file mode 100644
index 000000000000..b1d555d72ffb
--- /dev/null
+++ b/drivers/misc/dummy-early.c
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2018 Texas Instruments
+ *
+ * Author:
+ * Bartosz Golaszewski <[email protected]>
+ *
+ * Dummy testing driver whose only purpose is to be registered and probed
+ * using the early platform device mechanism.
+ */
+
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+
+static int dummy_early_probe(struct platform_device *pdev)
+{
+ dev_notice(&pdev->dev, "dummy-early driver probed!\n");
+
+ return 0;
+}
+
+static const struct of_device_id dummy_early_of_match[] = {
+ { .compatible = "none,dummy-early", },
+ { },
+};
+
+static struct platform_driver dummy_early_driver = {
+ .probe = dummy_early_probe,
+ .driver = {
+ .name = "dummy-early",
+ .of_match_table = dummy_early_of_match,
+ },
+};
+early_platform_driver(dummy_early_driver);
+
+MODULE_AUTHOR("Bartosz Golaszewski <[email protected]>");
+MODULE_DESCRIPTION("Dummy early platform device driver");
+MODULE_LICENSE("GPL v2");
--
2.17.0


2018-04-24 17:33:51

by Bartosz Golaszewski

[permalink] [raw]
Subject: [PATCH 10/11] of: platform: provide of_early_platform_probe()

From: Bartosz Golaszewski <[email protected]>

Implement a function that must be called from machine code early in
the bo process in order to probe all registered early devices.

Signed-off-by: Bartosz Golaszewski <[email protected]>
---
drivers/of/platform.c | 12 ++++++++++++
include/linux/of_platform.h | 2 ++
2 files changed, 14 insertions(+)

diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index 4b55e568fe77..525a466b03d1 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -541,6 +541,18 @@ int of_early_platform_populate(struct device_node *root,
return rc;
}
EXPORT_SYMBOL_GPL(of_early_platform_populate);
+
+/**
+ * of_early_platform_probe() - Probe all registered early platform devices.
+ *
+ * Returns 0 on success, a negative error code on failure.
+ */
+int of_early_platform_probe(void)
+{
+ return early_platform_driver_register_probe_all(
+ EARLY_PLATFORM_DEFAULT_CLASS, INT_MAX, 0);
+}
+EXPORT_SYMBOL_GPL(of_early_platform_probe);
#endif /* CONFIG_EARLY_PLATFORM_DEVICES */

int of_platform_default_populate(struct device_node *root,
diff --git a/include/linux/of_platform.h b/include/linux/of_platform.h
index 2bf1013a3e89..caa08e3bf3b7 100644
--- a/include/linux/of_platform.h
+++ b/include/linux/of_platform.h
@@ -81,6 +81,7 @@ extern int of_early_platform_populate(struct device_node *root,
const struct of_device_id *matches,
const struct of_dev_auxdata *lookup,
struct device *parent);
+extern int of_early_platform_probe(void);
#else /* CONFIG_EARLY_PLATFORM_DEVICES */
static inline int
of_early_platform_populate(struct device_node *root,
@@ -90,6 +91,7 @@ of_early_platform_populate(struct device_node *root,
{
return -ENOSYS;
}
+static inline void int of_early_platform_probe(void) {}
#endif /* CONFIG_EARLY_PLATFORM_DEVICES */

extern int of_platform_default_populate(struct device_node *root,
--
2.17.0


2018-04-24 17:34:23

by Bartosz Golaszewski

[permalink] [raw]
Subject: [PATCH 08/11] of: platform: provide of_early_platform_populate()

From: Bartosz Golaszewski <[email protected]>

Implement a variant of of_platform_populate() which scans child nodes
of the root device node for the "earlydev" compatible fallback and
registers the corresponding platform devices as early platform devices.

Signed-off-by: Bartosz Golaszewski <[email protected]>
---
drivers/of/device.c | 14 +++++-
drivers/of/platform.c | 89 +++++++++++++++++++++++++++++++------
include/linux/of_device.h | 5 +++
include/linux/of_platform.h | 17 +++++++
4 files changed, 110 insertions(+), 15 deletions(-)

diff --git a/drivers/of/device.c b/drivers/of/device.c
index 064c818105bd..cef13538d539 100644
--- a/drivers/of/device.c
+++ b/drivers/of/device.c
@@ -53,7 +53,7 @@ void of_dev_put(struct platform_device *dev)
}
EXPORT_SYMBOL(of_dev_put);

-int of_device_add(struct platform_device *ofdev)
+static void of_device_add_prepare(struct platform_device *ofdev)
{
BUG_ON(ofdev->dev.of_node == NULL);

@@ -68,10 +68,22 @@ int of_device_add(struct platform_device *ofdev)
* device is on the same node as the parent.
*/
set_dev_node(&ofdev->dev, of_node_to_nid(ofdev->dev.of_node));
+}

+int of_device_add(struct platform_device *ofdev)
+{
+ of_device_add_prepare(ofdev);
return device_add(&ofdev->dev);
}

+#ifdef CONFIG_EARLY_PLATFORM_DEVICES
+void of_device_add_early(struct platform_device *ofdev)
+{
+ of_device_add_prepare(ofdev);
+ early_platform_add_device(ofdev);
+}
+#endif /* CONFIG_EARLY_PLATFORM_DEVICES */
+
/**
* of_dma_configure - Setup DMA configuration
* @dev: Device to apply DMA configuration
diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index 60342209fbd8..4b55e568fe77 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -160,6 +160,7 @@ EXPORT_SYMBOL(of_device_alloc);
* @bus_id: name to assign device
* @platform_data: pointer to populate platform_data pointer with
* @parent: Linux device model parent device.
+ * @early: create as an early platform device
*
* Returns pointer to created platform device, or NULL if a device was not
* registered. Unavailable devices will not get registered.
@@ -168,9 +169,11 @@ static struct platform_device *of_platform_device_create_pdata(
struct device_node *np,
const char *bus_id,
void *platform_data,
- struct device *parent)
+ struct device *parent,
+ bool early)
{
struct platform_device *pdev;
+ int rc;

if (!of_device_is_available(np) ||
of_node_test_and_set_flag(np, OF_POPULATED))
@@ -184,9 +187,14 @@ static struct platform_device *of_platform_device_create_pdata(
pdev->dev.platform_data = platform_data;
of_msi_configure(&pdev->dev, pdev->dev.of_node);

- if (of_device_add(pdev) != 0) {
- platform_device_put(pdev);
- goto err_clear_flag;
+ if (unlikely(early)) {
+ of_device_add_early(pdev);
+ } else {
+ rc = of_device_add(pdev);
+ if (rc) {
+ platform_device_put(pdev);
+ goto err_clear_flag;
+ }
}

return pdev;
@@ -209,7 +217,7 @@ struct platform_device *of_platform_device_create(struct device_node *np,
const char *bus_id,
struct device *parent)
{
- return of_platform_device_create_pdata(np, bus_id, NULL, parent);
+ return of_platform_device_create_pdata(np, bus_id, NULL, parent, false);
}
EXPORT_SYMBOL(of_platform_device_create);

@@ -333,6 +341,7 @@ static const struct of_dev_auxdata *of_dev_lookup(const struct of_dev_auxdata *l
* @lookup: auxdata table for matching id and platform_data with device nodes
* @parent: parent for new device, or NULL for top level.
* @strict: require compatible property
+ * @early: register sub-devices as early platform devices
*
* Creates a platform_device for the provided device_node, and optionally
* recursively create devices for all the child nodes.
@@ -340,7 +349,8 @@ static const struct of_dev_auxdata *of_dev_lookup(const struct of_dev_auxdata *l
static int of_platform_bus_create(struct device_node *bus,
const struct of_device_id *matches,
const struct of_dev_auxdata *lookup,
- struct device *parent, bool strict)
+ struct device *parent,
+ bool strict, bool early)
{
const struct of_dev_auxdata *auxdata;
struct device_node *child;
@@ -377,13 +387,15 @@ static int of_platform_bus_create(struct device_node *bus,
return 0;
}

- pdev = of_platform_device_create_pdata(bus, bus_id, platform_data, parent);
+ pdev = of_platform_device_create_pdata(bus, bus_id,
+ platform_data, parent, early);
if (!pdev || !of_match_node(matches, bus))
return 0;

for_each_child_of_node(bus, child) {
pr_debug(" create child: %pOF\n", child);
- rc = of_platform_bus_create(child, matches, lookup, &pdev->dev, strict);
+ rc = of_platform_bus_create(child, matches, lookup,
+ &pdev->dev, strict, early);
if (rc) {
of_node_put(child);
break;
@@ -418,11 +430,13 @@ int of_platform_bus_probe(struct device_node *root,

/* Do a self check of bus type, if there's a match, create children */
if (of_match_node(matches, root)) {
- rc = of_platform_bus_create(root, matches, NULL, parent, false);
+ rc = of_platform_bus_create(root, matches, NULL,
+ parent, false, false);
} else for_each_child_of_node(root, child) {
if (!of_match_node(matches, child))
continue;
- rc = of_platform_bus_create(child, matches, NULL, parent, false);
+ rc = of_platform_bus_create(child, matches, NULL,
+ parent, false, false);
if (rc) {
of_node_put(child);
break;
@@ -454,9 +468,9 @@ EXPORT_SYMBOL(of_platform_bus_probe);
* Returns 0 on success, < 0 on failure.
*/
int of_platform_populate(struct device_node *root,
- const struct of_device_id *matches,
- const struct of_dev_auxdata *lookup,
- struct device *parent)
+ const struct of_device_id *matches,
+ const struct of_dev_auxdata *lookup,
+ struct device *parent)
{
struct device_node *child;
int rc = 0;
@@ -469,7 +483,8 @@ int of_platform_populate(struct device_node *root,
pr_debug(" starting at: %pOF\n", root);

for_each_child_of_node(root, child) {
- rc = of_platform_bus_create(child, matches, lookup, parent, true);
+ rc = of_platform_bus_create(child, matches, lookup,
+ parent, false, false);
if (rc) {
of_node_put(child);
break;
@@ -482,6 +497,52 @@ int of_platform_populate(struct device_node *root,
}
EXPORT_SYMBOL_GPL(of_platform_populate);

+/**
+ * of_early_platform_populate() - Populate platform_devices from device tree
+ * data early in the boot process
+ * @root: parent of the first level to probe or NULL for the root of the tree
+ * @matches: match table, NULL to use the default
+ * @lookup: auxdata table for matching id and platform_data with device nodes
+ * @parent: parent to hook devices from, NULL for toplevel
+ *
+ * Virtually the same as of_platform_populate() except that it adds devices
+ * as early platform devices.
+ *
+ * Returns 0 on success, < 0 on failure.
+ */
+#ifdef CONFIG_EARLY_PLATFORM_DEVICES
+int of_early_platform_populate(struct device_node *root,
+ const struct of_device_id *matches,
+ const struct of_dev_auxdata *lookup,
+ struct device *parent)
+{
+ struct device_node *child;
+ int rc = 0;
+
+ root = root ? of_node_get(root) : of_find_node_by_path("/");
+ if (!root)
+ return -EINVAL;
+
+ pr_debug("%s()\n", __func__);
+ pr_debug(" starting at: %pOF\n", root);
+
+ for_each_compatible_child_node(child, NULL,
+ EARLY_PLATFORM_DEFAULT_CLASS, root) {
+ rc = of_platform_bus_create(child, matches, lookup,
+ parent, false, true);
+ if (rc) {
+ of_node_put(child);
+ break;
+ }
+ }
+ of_node_set_flag(root, OF_POPULATED_BUS);
+
+ of_node_put(root);
+ return rc;
+}
+EXPORT_SYMBOL_GPL(of_early_platform_populate);
+#endif /* CONFIG_EARLY_PLATFORM_DEVICES */
+
int of_platform_default_populate(struct device_node *root,
const struct of_dev_auxdata *lookup,
struct device *parent)
diff --git a/include/linux/of_device.h b/include/linux/of_device.h
index 8da5a1b31ece..8a59a054a434 100644
--- a/include/linux/of_device.h
+++ b/include/linux/of_device.h
@@ -30,6 +30,11 @@ extern struct platform_device *of_dev_get(struct platform_device *dev);
extern void of_dev_put(struct platform_device *dev);

extern int of_device_add(struct platform_device *pdev);
+#ifdef CONFIG_EARLY_PLATFORM_DEVICES
+extern void of_device_add_early(struct platform_device *pdev);
+#else /* CONFIG_EARLY_PLATFORM_DEVICES */
+static inline void of_device_add_early(struct platform_device *pdev) {}
+#endif /* CONFIG_EARLY_PLATFORM_DEVICES */
extern int of_device_register(struct platform_device *ofdev);
extern void of_device_unregister(struct platform_device *ofdev);

diff --git a/include/linux/of_platform.h b/include/linux/of_platform.h
index 84a966623e78..2bf1013a3e89 100644
--- a/include/linux/of_platform.h
+++ b/include/linux/of_platform.h
@@ -75,6 +75,23 @@ extern int of_platform_populate(struct device_node *root,
const struct of_device_id *matches,
const struct of_dev_auxdata *lookup,
struct device *parent);
+
+#ifdef CONFIG_EARLY_PLATFORM_DEVICES
+extern int of_early_platform_populate(struct device_node *root,
+ const struct of_device_id *matches,
+ const struct of_dev_auxdata *lookup,
+ struct device *parent);
+#else /* CONFIG_EARLY_PLATFORM_DEVICES */
+static inline int
+of_early_platform_populate(struct device_node *root,
+ const struct of_device_id *matches,
+ const struct of_dev_auxdata *lookup,
+ struct device *parent)
+{
+ return -ENOSYS;
+}
+#endif /* CONFIG_EARLY_PLATFORM_DEVICES */
+
extern int of_platform_default_populate(struct device_node *root,
const struct of_dev_auxdata *lookup,
struct device *parent);
--
2.17.0


2018-04-24 17:35:15

by Bartosz Golaszewski

[permalink] [raw]
Subject: [PATCH 07/11] dt-bindings: add bindings for early devices

From: Bartosz Golaszewski <[email protected]>

Add a simple document describing the "earlydev" compatible fallback.

Signed-off-by: Bartosz Golaszewski <[email protected]>
---
Documentation/devicetree/bindings/early.txt | 7 +++++++
1 file changed, 7 insertions(+)
create mode 100644 Documentation/devicetree/bindings/early.txt

diff --git a/Documentation/devicetree/bindings/early.txt b/Documentation/devicetree/bindings/early.txt
new file mode 100644
index 000000000000..51cbd8630255
--- /dev/null
+++ b/Documentation/devicetree/bindings/early.txt
@@ -0,0 +1,7 @@
+* Early device driver
+
+Certain devices must be initialized early in the boot process. An early
+device node represents such a system component.
+
+Required properties:
+- compatible: Must contain the following fallback: "earlydev"
--
2.17.0


2018-04-24 17:35:36

by Bartosz Golaszewski

[permalink] [raw]
Subject: [PATCH 02/11] platform: provide early_platform_driver_register_probe_all()

From: Bartosz Golaszewski <[email protected]>

All users of early_platform_driver_register_all() subsequently call
early_platform_driver_probe(). Provide a helper that calls both
functions.

Signed-off-by: Bartosz Golaszewski <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
include/linux/platform_device.h | 9 +++++++++
1 file changed, 9 insertions(+)

diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h
index 80942ed0f728..a06b194ba30b 100644
--- a/include/linux/platform_device.h
+++ b/include/linux/platform_device.h
@@ -314,6 +314,15 @@ static inline int is_early_platform_device(struct platform_device *pdev)
extern void early_platform_driver_register_all(char *class_str);
extern int early_platform_driver_probe(char *class_str,
int nr_probe, int user_only);
+
+static inline int early_platform_driver_register_probe_all(char *class_str,
+ int nr_probe,
+ int user_only)
+{
+ early_platform_driver_register_all(class_str);
+ return early_platform_driver_probe(class_str, nr_probe, user_only);
+}
+
extern void early_platform_cleanup(void);

#define early_platform_init(class_string, platdrv) \
--
2.17.0


2018-04-24 17:35:43

by Bartosz Golaszewski

[permalink] [raw]
Subject: [PATCH 09/11] platform: provide early_platform_driver()

From: Bartosz Golaszewski <[email protected]>

Implement a macro similar to module_platform_driver() which allows to
register early platform drivers with the default early class.

Signed-off-by: Bartosz Golaszewski <[email protected]>
---
include/linux/platform_device.h | 6 ++++++
1 file changed, 6 insertions(+)

diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h
index 514ada776004..b565a1237fa6 100644
--- a/include/linux/platform_device.h
+++ b/include/linux/platform_device.h
@@ -297,6 +297,8 @@ struct early_platform_driver {
#define EARLY_PLATFORM_ID_UNSET -2
#define EARLY_PLATFORM_ID_ERROR -3

+#define EARLY_PLATFORM_DEFAULT_CLASS "earlydev"
+
#ifdef CONFIG_EARLY_PLATFORM_DEVICES

extern int early_platform_driver_register(struct early_platform_driver *epdrv,
@@ -352,6 +354,9 @@ static inline char *early_platform_driver_setup_func(void) \
}
#endif /* MODULE */

+#define early_platform_driver(__platdrv) \
+ early_platform_init(EARLY_PLATFORM_DEFAULT_CLASS, &(__platdrv))
+
#else /* CONFIG_EARLY_PLATFORM_DEVICES */
static inline int
early_platform_driver_register(struct early_platform_driver *epdrv, char *buf)
@@ -380,6 +385,7 @@ static inline int early_platform_driver_register_probe_all(char *class_str,
static inline void early_platform_cleanup(void) {}
#define early_platform_init(class_string, platdrv)
#define early_platform_init_buffer(class_string, platdrv, buf, bufsiz)
+#define early_platform_driver(__platdrv)
#endif /* CONFIG_EARLY_PLATFORM_DEVICES */

#ifdef CONFIG_SUSPEND
--
2.17.0


2018-04-24 17:36:03

by Bartosz Golaszewski

[permalink] [raw]
Subject: [PATCH 06/11] of: provide for_each_compatible_child_node()

From: Bartosz Golaszewski <[email protected]>

Add a variant of for_each_compatible_node() allowing to only iterate
over all compatible nodes that are children of the specified root node.

Signed-off-by: Bartosz Golaszewski <[email protected]>
---
include/linux/of.h | 3 +++
1 file changed, 3 insertions(+)

diff --git a/include/linux/of.h b/include/linux/of.h
index 4d25e4f952d9..15e0dbf7a602 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -1170,6 +1170,9 @@ static inline int of_property_read_s32(const struct device_node *np,
#define for_each_compatible_node(dn, type, compatible) \
for (dn = of_find_compatible_node(NULL, type, compatible); dn; \
dn = of_find_compatible_node(dn, type, compatible))
+#define for_each_compatible_child_node(dn, type, compatible, root) \
+ for (dn = of_find_compatible_node(root, type, compatible); dn; \
+ dn = of_find_compatible_node(dn, type, compatible))
#define for_each_matching_node(dn, matches) \
for (dn = of_find_matching_node(NULL, matches); dn; \
dn = of_find_matching_node(dn, matches))
--
2.17.0


2018-04-24 17:36:08

by Bartosz Golaszewski

[permalink] [raw]
Subject: [PATCH 05/11] platform: use a dedicated list_head for early devices

From: Bartosz Golaszewski <[email protected]>

The current implementation of early platform device support uses the
devres list head in struct device. This causes problems when adding
support for device tree based early devices. Use a dedicated list_head
which is included in struct device conditionally in order to avoid
adding bloat for all architectures.

Signed-off-by: Bartosz Golaszewski <[email protected]>
---
drivers/base/platform.c | 23 +++++++++++------------
include/linux/device.h | 4 ++++
2 files changed, 15 insertions(+), 12 deletions(-)

diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index af440d703f0b..90526acdcb84 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -1264,12 +1264,10 @@ void __init early_platform_add_devices(struct platform_device **devs, int num)
for (i = 0; i < num; i++) {
dev = &devs[i]->dev;

- if (!dev->devres_head.next) {
- pm_runtime_early_init(dev);
- INIT_LIST_HEAD(&dev->devres_head);
- list_add_tail(&dev->devres_head,
- &early_platform_device_list);
- }
+ pm_runtime_early_init(dev);
+ INIT_LIST_HEAD(&dev->early_dev_head);
+ list_add_tail(&dev->early_dev_head,
+ &early_platform_device_list);
}
}

@@ -1310,7 +1308,7 @@ early_platform_match(struct early_platform_driver *epdrv, int id)
{
struct platform_device *pd;

- list_for_each_entry(pd, &early_platform_device_list, dev.devres_head)
+ list_for_each_entry(pd, &early_platform_device_list, dev.early_dev_head)
if (platform_match(&pd->dev, &epdrv->pdrv->driver))
if (pd->id == id)
return pd;
@@ -1328,7 +1326,7 @@ static int __init early_platform_left(struct early_platform_driver *epdrv,
{
struct platform_device *pd;

- list_for_each_entry(pd, &early_platform_device_list, dev.devres_head)
+ list_for_each_entry(pd, &early_platform_device_list, dev.early_dev_head)
if (platform_match(&pd->dev, &epdrv->pdrv->driver))
if (pd->id >= id)
return 1;
@@ -1465,11 +1463,12 @@ void __init early_platform_cleanup(void)
{
struct platform_device *pd, *pd2;

- /* clean up the devres list used to chain devices */
+ /* clean up the list used to chain devices */
list_for_each_entry_safe(pd, pd2, &early_platform_device_list,
- dev.devres_head) {
- list_del(&pd->dev.devres_head);
- memset(&pd->dev.devres_head, 0, sizeof(pd->dev.devres_head));
+ dev.early_dev_head) {
+ list_del(&pd->dev.early_dev_head);
+ memset(&pd->dev.early_dev_head, 0,
+ sizeof(pd->dev.early_dev_head));
}
}

diff --git a/include/linux/device.h b/include/linux/device.h
index 0059b99e1f25..4fadba0f9a35 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -979,6 +979,10 @@ struct device {
spinlock_t devres_lock;
struct list_head devres_head;

+#ifdef CONFIG_EARLY_PLATFORM_DEVICES
+ struct list_head early_dev_head;
+#endif
+
struct klist_node knode_class;
struct class *class;
const struct attribute_group **groups; /* optional groups */
--
2.17.0


2018-04-24 17:36:31

by Bartosz Golaszewski

[permalink] [raw]
Subject: [PATCH 01/11] platform: early: provide early_platform_add_device()

From: Bartosz Golaszewski <[email protected]>

Currently we only have early_platform_add_devices() which takes struct
platform_device ** as argument, requiring the users to have an
intermediate array of platform_device pointers even if we're only
adding a single device. Provide a helper for adding a single device at
a time.

Signed-off-by: Bartosz Golaszewski <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
include/linux/platform_device.h | 5 +++++
1 file changed, 5 insertions(+)

diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h
index 49f634d96118..80942ed0f728 100644
--- a/include/linux/platform_device.h
+++ b/include/linux/platform_device.h
@@ -301,6 +301,11 @@ extern int early_platform_driver_register(struct early_platform_driver *epdrv,
char *buf);
extern void early_platform_add_devices(struct platform_device **devs, int num);

+static inline void early_platform_add_device(struct platform_device *pdev)
+{
+ early_platform_add_devices(&pdev, 1);
+}
+
static inline int is_early_platform_device(struct platform_device *pdev)
{
return !pdev->dev.driver;
--
2.17.0


2018-04-24 18:14:08

by Rich Felker

[permalink] [raw]
Subject: Re: [PATCH 00/11] platform: device tree support for early platform drivers

On Tue, Apr 24, 2018 at 07:30:40PM +0200, Bartosz Golaszewski wrote:
> From: Bartosz Golaszewski <[email protected]>
>
> Device tree based systems often use OF_DECLARE() macros for devices
> that need to be initialized early in the boot process such as clocks,
> timers etc. However platform devices are more desirable.
>
> This series aims at introducing support for early platform drivers for
> OF-based systems.
>
> The idea is to have a special compatible fallback string: "earlydev"
> that similarily to "syscon" would be added to device nodes that need
> early probing. We then need to call of_early_platform_populate() early
> in the boot process to actually probe the registered devices.

This makes no sense to me. It's not the device tree that should
contain the knowledge that these need to be registered/probed early in
the boot. That need is a property of the operating system/device
drivers, and so the *drivers* should be the ones that contain the
knowledge.

> I am aware that this new compatible does not strictly correspond with
> the "hardware description only" rule of DT, but we already have many
> functionalities that break this rule: syscon, gpio hogs etc.
>
> The first user of this new functionality will be the DaVinci platform
> for which we want to probe the pll, psc and timer drivers early in the
> boot sequence but keep them implemented as platform drivers.
>
> In the future, if this series gets accepted, this could become and
> alternative to TIMER_OF_DECLARE, CLK_OF_DECLARE etc. and could lead
> to deprecating of those macros in favor of early platform drivers.

This seems completely unacceptable, in that it would render new
kernels unable to boot on existing device trees (which may be
hard-coded in rom on existing devices).

Rich

2018-04-24 18:21:49

by Rich Felker

[permalink] [raw]
Subject: Re: [PATCH 00/11] platform: device tree support for early platform drivers

On Tue, Apr 24, 2018 at 06:55:45PM +0100, Mark Rutland wrote:
> Hi bartosz,
>
> On Tue, Apr 24, 2018 at 07:30:40PM +0200, Bartosz Golaszewski wrote:
> > From: Bartosz Golaszewski <[email protected]>
> >
> > Device tree based systems often use OF_DECLARE() macros for devices
> > that need to be initialized early in the boot process such as clocks,
> > timers etc. However platform devices are more desirable.
> >
> > This series aims at introducing support for early platform drivers for
> > OF-based systems.
> >
> > The idea is to have a special compatible fallback string: "earlydev"
> > that similarily to "syscon" would be added to device nodes that need
> > early probing. We then need to call of_early_platform_populate() early
> > in the boot process to actually probe the registered devices.
> >
> > I am aware that this new compatible does not strictly correspond with
> > the "hardware description only" rule of DT, but we already have many
> > functionalities that break this rule: syscon, gpio hogs etc.
>
> I don't think we need the "earlydev" string at all, and can still keep
> the rest of this infrastrcuture if it is helpful.
>
> So while I'm certainly oppposed to the "earlydev" string, I think that
> the infrastrcuture could be useful.

Yes. I think this agrees with my objection -- I'm not opposed to the
infrastructure in the kernel, but to semantically-wrong and
backwards-incompatible changes to the device tree contract.

> > The first user of this new functionality will be the DaVinci platform
> > for which we want to probe the pll, psc and timer drivers early in the
> > boot sequence but keep them implemented as platform drivers.
>
> Can we have early_paltform_driver() take a reference to the driver's
> of_match_table, and put that in a special section?
>
> Then instead of looking for "earlydev", we look for any compatible
> string in that section. No magic string required in the DT, and we can
> always mess around with probe ordering in future.

Yes, this is pretty much exactly the change I had in mind.

Rich

2018-04-24 19:33:31

by Randy Dunlap

[permalink] [raw]
Subject: Re: [PATCH 03/11] platform: make support for early platform devices conditional

On 04/24/2018 10:30 AM, Bartosz Golaszewski wrote:
> From: Bartosz Golaszewski <[email protected]>
>
> Signed-off-by: Bartosz Golaszewski <[email protected]>
> ---
> arch/sh/Kconfig | 1 +
> drivers/base/Kconfig | 4 ++++
> drivers/base/platform.c | 3 +++
> include/linux/platform_device.h | 32 ++++++++++++++++++++++++++++++++
> 4 files changed, 40 insertions(+)

> index 29b0eb452b3a..37de5e1d6217 100644
> --- a/drivers/base/Kconfig
> +++ b/drivers/base/Kconfig
> @@ -205,6 +205,10 @@ config DEBUG_TEST_DRIVER_REMOVE
> unusable. You should say N here unless you are explicitly looking to
> test this functionality.
>
> +config EARLY_PLATFORM_DEVICES
> + bool
> + default n

The default value is already 'n', so we usually ask people to omit that
value. OTOH, you could combine those 2 lines into:

def_bool n


> +
> source "drivers/base/test/Kconfig"
>
> config SYS_HYPERVISOR


--
~Randy

2018-04-24 19:41:52

by Rob Herring

[permalink] [raw]
Subject: Re: [PATCH 00/11] platform: device tree support for early platform drivers

On Tue, Apr 24, 2018 at 12:30 PM, Bartosz Golaszewski <[email protected]> wrote:
> From: Bartosz Golaszewski <[email protected]>
>
> Device tree based systems often use OF_DECLARE() macros for devices
> that need to be initialized early in the boot process such as clocks,
> timers etc. However platform devices are more desirable.

Yes, platform devices would be more desirable, but ...
>
> This series aims at introducing support for early platform drivers for
> OF-based systems.

... the whole early_platform_device infrastructure is not really a
platform_device. Rather it kind of looks like one and I guess gets
converted over during boot.

This is not the first attempt to add DT support to early platform
devices[1]. I think the same objections still apply. It has been
pretty much only an SH thing (which as an arch, I'm told is pretty
much unmaintained and broken).

> The idea is to have a special compatible fallback string: "earlydev"
> that similarily to "syscon" would be added to device nodes that need
> early probing. We then need to call of_early_platform_populate() early
> in the boot process to actually probe the registered devices.

Others have sufficiently explained why this won't fly for DT, so I
don't have more to add.

Rob

[1] http://lists.infradead.org/pipermail/linux-arm-kernel/2011-June/054529.html

2018-04-25 09:35:36

by Bartosz Golaszewski

[permalink] [raw]
Subject: Re: [PATCH 00/11] platform: device tree support for early platform drivers

2018-04-24 19:57 GMT+02:00 Rich Felker <[email protected]>:
> On Tue, Apr 24, 2018 at 07:30:40PM +0200, Bartosz Golaszewski wrote:
>> From: Bartosz Golaszewski <[email protected]>
>>
>> Device tree based systems often use OF_DECLARE() macros for devices
>> that need to be initialized early in the boot process such as clocks,
>> timers etc. However platform devices are more desirable.
>>
>> This series aims at introducing support for early platform drivers for
>> OF-based systems.
>>
>> The idea is to have a special compatible fallback string: "earlydev"
>> that similarily to "syscon" would be added to device nodes that need
>> early probing. We then need to call of_early_platform_populate() early
>> in the boot process to actually probe the registered devices.
>
> This makes no sense to me. It's not the device tree that should
> contain the knowledge that these need to be registered/probed early in
> the boot. That need is a property of the operating system/device
> drivers, and so the *drivers* should be the ones that contain the
> knowledge.
>
>> I am aware that this new compatible does not strictly correspond with
>> the "hardware description only" rule of DT, but we already have many
>> functionalities that break this rule: syscon, gpio hogs etc.
>>
>> The first user of this new functionality will be the DaVinci platform
>> for which we want to probe the pll, psc and timer drivers early in the
>> boot sequence but keep them implemented as platform drivers.
>>
>> In the future, if this series gets accepted, this could become and
>> alternative to TIMER_OF_DECLARE, CLK_OF_DECLARE etc. and could lead
>> to deprecating of those macros in favor of early platform drivers.
>
> This seems completely unacceptable, in that it would render new
> kernels unable to boot on existing device trees (which may be
> hard-coded in rom on existing devices).
>

Just ot make it clear: by deprecating I meant not accepting any new
users, not blindly replacing the current ones.

Thanks,
Bart

2018-04-25 14:22:20

by Rich Felker

[permalink] [raw]
Subject: Re: [PATCH 03/11] platform: make support for early platform devices conditional

On Tue, Apr 24, 2018 at 07:30:43PM +0200, Bartosz Golaszewski wrote:
> From: Bartosz Golaszewski <[email protected]>
>
> We want to add support for device tree based early platform devices.
>
> In order not to introduce additional bloat for all users when we extend
> struct device to accomodate early platform DT support, let's make the
> current machine code support conditional.
>
> The only current user of the early platform infrastructure is SuperH so
> make it select the appropriate Kconfig option.
>
> Signed-off-by: Bartosz Golaszewski <[email protected]>
> ---
> arch/sh/Kconfig | 1 +
> drivers/base/Kconfig | 4 ++++
> drivers/base/platform.c | 3 +++
> include/linux/platform_device.h | 32 ++++++++++++++++++++++++++++++++
> 4 files changed, 40 insertions(+)
>
> diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
> index 97fe29316476..1b2c0b2ce402 100644
> --- a/arch/sh/Kconfig
> +++ b/arch/sh/Kconfig
> @@ -50,6 +50,7 @@ config SUPERH
> select HAVE_ARCH_AUDITSYSCALL
> select HAVE_FUTEX_CMPXCHG if FUTEX
> select HAVE_NMI
> + select EARLY_PLATFORM_DEVICES
> help
> The SuperH is a RISC processor targeted for use in embedded systems
> and consumer electronics; it was also used in the Sega Dreamcast

If SH is the only user and only intended user for this, don't add it.
None of the devices using legacy board files full of platform device
declarations are using device tree yet, and when we do convert them
they should use device tree correctly, not with hacks designed around
OS behavior rather than abstract hardware declaration.

Rich

2018-04-26 03:48:02

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH 10/11] of: platform: provide of_early_platform_probe()

Hi Bartosz,

I love your patch! Yet something to improve:

[auto build test ERROR on linus/master]
[also build test ERROR on v4.17-rc2]
[cannot apply to next-20180424]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url: https://github.com/0day-ci/linux/commits/Bartosz-Golaszewski/platform-device-tree-support-for-early-platform-drivers/20180426-003135
config: i386-randconfig-x015-201816 (attached as .config)
compiler: gcc-7 (Debian 7.3.0-16) 7.3.0
reproduce:
# save the attached .config to linux build tree
make ARCH=i386

All errors (new ones prefixed by >>):

In file included from arch/x86/kernel/devicetree.c:12:0:
>> include/linux/of_platform.h:94:20: error: two or more data types in declaration specifiers
static inline void int of_early_platform_probe(void) {}
^~~

vim +94 include/linux/of_platform.h

63
64 /* Platform devices and busses creation */
65 extern struct platform_device *of_platform_device_create(struct device_node *np,
66 const char *bus_id,
67 struct device *parent);
68
69 extern int of_platform_device_destroy(struct device *dev, void *data);
70 extern int of_platform_bus_probe(struct device_node *root,
71 const struct of_device_id *matches,
72 struct device *parent);
73 #ifdef CONFIG_OF_ADDRESS
74 extern int of_platform_populate(struct device_node *root,
75 const struct of_device_id *matches,
76 const struct of_dev_auxdata *lookup,
77 struct device *parent);
78
79 #ifdef CONFIG_EARLY_PLATFORM_DEVICES
80 extern int of_early_platform_populate(struct device_node *root,
81 const struct of_device_id *matches,
82 const struct of_dev_auxdata *lookup,
83 struct device *parent);
84 extern int of_early_platform_probe(void);
85 #else /* CONFIG_EARLY_PLATFORM_DEVICES */
86 static inline int
87 of_early_platform_populate(struct device_node *root,
88 const struct of_device_id *matches,
89 const struct of_dev_auxdata *lookup,
90 struct device *parent)
91 {
92 return -ENOSYS;
93 }
> 94 static inline void int of_early_platform_probe(void) {}
95 #endif /* CONFIG_EARLY_PLATFORM_DEVICES */
96

---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation


Attachments:
(No filename) (2.52 kB)
.config.gz (24.39 kB)
Download all attachments

2018-04-26 04:30:02

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH 05/11] platform: use a dedicated list_head for early devices

Hi Bartosz,

I love your patch! Perhaps something to improve:

[auto build test WARNING on linus/master]
[also build test WARNING on v4.17-rc2]
[cannot apply to next-20180424]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url: https://github.com/0day-ci/linux/commits/Bartosz-Golaszewski/platform-device-tree-support-for-early-platform-drivers/20180426-003135
reproduce: make htmldocs

All warnings (new ones prefixed by >>):

include/net/mac80211.h:2083: warning: bad line: >
include/net/mac80211.h:2083: warning: bad line: >
include/net/mac80211.h:2083: warning: bad line: >
include/net/mac80211.h:2083: warning: bad line: >
include/net/mac80211.h:2083: warning: bad line: >
include/net/mac80211.h:2083: warning: bad line: >
include/net/mac80211.h:2083: warning: bad line: >
include/net/mac80211.h:2083: warning: bad line: >
include/net/mac80211.h:2083: warning: bad line: >
include/net/mac80211.h:2083: warning: bad line: >
include/net/mac80211.h:2083: warning: bad line: >
include/net/mac80211.h:2083: warning: bad line: >
include/net/mac80211.h:2083: warning: bad line: >
include/net/mac80211.h:2083: warning: bad line: >
include/net/mac80211.h:2083: warning: bad line: >
include/net/mac80211.h:2083: warning: bad line: >
include/net/mac80211.h:2083: warning: bad line: >
include/net/mac80211.h:2083: warning: bad line: >
include/net/mac80211.h:2083: warning: bad line: >
include/net/mac80211.h:2083: warning: bad line: >
include/net/mac80211.h:2083: warning: bad line: >
include/net/mac80211.h:2083: warning: bad line: >
include/net/mac80211.h:2083: warning: bad line: >
include/net/mac80211.h:2083: warning: bad line: >
include/net/mac80211.h:2083: warning: bad line: >
include/net/mac80211.h:2083: warning: bad line: >
include/net/mac80211.h:2083: warning: bad line: >
include/net/mac80211.h:2083: warning: bad line: >
include/net/mac80211.h:2083: warning: bad line: >
include/net/mac80211.h:2083: warning: bad line: >
include/net/mac80211.h:2083: warning: bad line: >
include/net/mac80211.h:2083: warning: bad line: >
include/net/mac80211.h:2083: warning: bad line: >
include/net/mac80211.h:2083: warning: bad line: >
include/net/mac80211.h:2083: warning: bad line: >
include/net/mac80211.h:2083: warning: bad line: >
include/net/mac80211.h:2083: warning: bad line: >
include/net/mac80211.h:2083: warning: bad line: >
include/net/mac80211.h:2083: warning: bad line: >
include/net/mac80211.h:2083: warning: bad line: >
include/net/mac80211.h:2083: warning: bad line: >
include/net/mac80211.h:2083: warning: bad line: >
include/net/mac80211.h:2083: warning: bad line: >
include/net/mac80211.h:2083: warning: bad line: >
include/net/mac80211.h:2083: warning: bad line: >
include/net/mac80211.h:2083: warning: bad line: >
include/net/mac80211.h:2083: warning: bad line: >
include/net/mac80211.h:2083: warning: bad line: >
include/net/mac80211.h:2083: warning: bad line: >
include/net/mac80211.h:2083: warning: bad line: >
include/net/mac80211.h:2083: warning: bad line: >
include/net/mac80211.h:2083: warning: bad line: >
include/net/mac80211.h:2083: warning: bad line: >
include/net/mac80211.h:2083: warning: bad line: >
include/net/mac80211.h:2083: warning: bad line: >
include/net/mac80211.h:2083: warning: bad line: >
include/net/mac80211.h:2083: warning: bad line: >
net/mac80211/sta_info.h:586: warning: Function parameter or member 'rx_stats_avg' not described in 'sta_info'
net/mac80211/sta_info.h:586: warning: Function parameter or member 'rx_stats_avg.signal' not described in 'sta_info'
net/mac80211/sta_info.h:586: warning: Function parameter or member 'rx_stats_avg.chain_signal' not described in 'sta_info'
net/mac80211/sta_info.h:586: warning: Function parameter or member 'status_stats.filtered' not described in 'sta_info'
net/mac80211/sta_info.h:586: warning: Function parameter or member 'status_stats.retry_failed' not described in 'sta_info'
net/mac80211/sta_info.h:586: warning: Function parameter or member 'status_stats.retry_count' not described in 'sta_info'
net/mac80211/sta_info.h:586: warning: Function parameter or member 'status_stats.lost_packets' not described in 'sta_info'
net/mac80211/sta_info.h:586: warning: Function parameter or member 'status_stats.last_tdls_pkt_time' not described in 'sta_info'
net/mac80211/sta_info.h:586: warning: Function parameter or member 'status_stats.msdu_retries' not described in 'sta_info'
net/mac80211/sta_info.h:586: warning: Function parameter or member 'status_stats.msdu_failed' not described in 'sta_info'
net/mac80211/sta_info.h:586: warning: Function parameter or member 'status_stats.last_ack' not described in 'sta_info'
net/mac80211/sta_info.h:586: warning: Function parameter or member 'status_stats.last_ack_signal' not described in 'sta_info'
net/mac80211/sta_info.h:586: warning: Function parameter or member 'status_stats.ack_signal_filled' not described in 'sta_info'
net/mac80211/sta_info.h:586: warning: Function parameter or member 'tx_stats.packets' not described in 'sta_info'
net/mac80211/sta_info.h:586: warning: Function parameter or member 'tx_stats.bytes' not described in 'sta_info'
net/mac80211/sta_info.h:586: warning: Function parameter or member 'tx_stats.last_rate' not described in 'sta_info'
net/mac80211/sta_info.h:586: warning: Function parameter or member 'tx_stats.msdu' not described in 'sta_info'
kernel/sched/fair.c:3731: warning: Function parameter or member 'flags' not described in 'attach_entity_load_avg'
include/linux/dma-buf.h:307: warning: Function parameter or member 'cb_excl.cb' not described in 'dma_buf'
include/linux/dma-buf.h:307: warning: Function parameter or member 'cb_excl.poll' not described in 'dma_buf'
include/linux/dma-buf.h:307: warning: Function parameter or member 'cb_excl.active' not described in 'dma_buf'
include/linux/dma-buf.h:307: warning: Function parameter or member 'cb_shared.cb' not described in 'dma_buf'
include/linux/dma-buf.h:307: warning: Function parameter or member 'cb_shared.poll' not described in 'dma_buf'
include/linux/dma-buf.h:307: warning: Function parameter or member 'cb_shared.active' not described in 'dma_buf'
include/linux/dma-fence-array.h:54: warning: Function parameter or member 'work' not described in 'dma_fence_array'
Error: Cannot open file drivers/base/firmware_class.c
WARNING: kernel-doc 'scripts/kernel-doc -rst -enable-lineno -function request_firmware drivers/base/firmware_class.c' failed with return code 1
Error: Cannot open file drivers/base/firmware_class.c
WARNING: kernel-doc 'scripts/kernel-doc -rst -enable-lineno -function request_firmware_direct drivers/base/firmware_class.c' failed with return code 1
Error: Cannot open file drivers/base/firmware_class.c
WARNING: kernel-doc 'scripts/kernel-doc -rst -enable-lineno -function request_firmware_into_buf drivers/base/firmware_class.c' failed with return code 1
Error: Cannot open file drivers/base/firmware_class.c
WARNING: kernel-doc 'scripts/kernel-doc -rst -enable-lineno -function request_firmware_nowait drivers/base/firmware_class.c' failed with return code 1
Error: Cannot open file drivers/base/firmware_class.c
WARNING: kernel-doc 'scripts/kernel-doc -rst -enable-lineno -function firmware_request_cache drivers/base/firmware_class.c' failed with return code 1
include/linux/gpio/driver.h:142: warning: Function parameter or member 'request_key' not described in 'gpio_irq_chip'
include/linux/iio/iio.h:270: warning: Function parameter or member 'scan_type.sign' not described in 'iio_chan_spec'
include/linux/iio/iio.h:270: warning: Function parameter or member 'scan_type.realbits' not described in 'iio_chan_spec'
include/linux/iio/iio.h:270: warning: Function parameter or member 'scan_type.storagebits' not described in 'iio_chan_spec'
include/linux/iio/iio.h:270: warning: Function parameter or member 'scan_type.shift' not described in 'iio_chan_spec'
include/linux/iio/iio.h:270: warning: Function parameter or member 'scan_type.repeat' not described in 'iio_chan_spec'
include/linux/iio/iio.h:270: warning: Function parameter or member 'scan_type.endianness' not described in 'iio_chan_spec'
include/linux/iio/hw-consumer.h:1: warning: no structured comments found
>> include/linux/device.h:998: warning: Function parameter or member 'early_dev_head' not described in 'device'
Error: Cannot open file drivers/base/firmware_class.c
Error: Cannot open file drivers/base/firmware_class.c
WARNING: kernel-doc 'scripts/kernel-doc -rst -enable-lineno -export drivers/base/firmware_class.c' failed with return code 2
include/linux/input/sparse-keymap.h:46: warning: Function parameter or member 'sw' not described in 'key_entry'
include/linux/mtd/rawnand.h:752: warning: Function parameter or member 'timings.sdr' not described in 'nand_data_interface'
include/linux/mtd/rawnand.h:817: warning: Function parameter or member 'buf' not described in 'nand_op_data_instr'
include/linux/mtd/rawnand.h:817: warning: Function parameter or member 'buf.in' not described in 'nand_op_data_instr'
include/linux/mtd/rawnand.h:817: warning: Function parameter or member 'buf.out' not described in 'nand_op_data_instr'
include/linux/mtd/rawnand.h:863: warning: Function parameter or member 'ctx' not described in 'nand_op_instr'
include/linux/mtd/rawnand.h:863: warning: Function parameter or member 'ctx.cmd' not described in 'nand_op_instr'
include/linux/mtd/rawnand.h:863: warning: Function parameter or member 'ctx.addr' not described in 'nand_op_instr'
include/linux/mtd/rawnand.h:863: warning: Function parameter or member 'ctx.data' not described in 'nand_op_instr'
include/linux/mtd/rawnand.h:863: warning: Function parameter or member 'ctx.waitrdy' not described in 'nand_op_instr'
include/linux/mtd/rawnand.h:1010: warning: Function parameter or member 'ctx' not described in 'nand_op_parser_pattern_elem'
include/linux/mtd/rawnand.h:1010: warning: Function parameter or member 'ctx.addr' not described in 'nand_op_parser_pattern_elem'
include/linux/mtd/rawnand.h:1010: warning: Function parameter or member 'ctx.data' not described in 'nand_op_parser_pattern_elem'
include/linux/mtd/rawnand.h:1313: warning: Function parameter or member 'manufacturer.desc' not described in 'nand_chip'
include/linux/mtd/rawnand.h:1313: warning: Function parameter or member 'manufacturer.priv' not described in 'nand_chip'
include/linux/regulator/driver.h:222: warning: Function parameter or member 'resume_early' not described in 'regulator_ops'
drivers/regulator/core.c:4306: warning: Excess function parameter 'state' description in 'regulator_suspend_late'
arch/s390/include/asm/cio.h:245: warning: Function parameter or member 'esw.esw0' not described in 'irb'
arch/s390/include/asm/cio.h:245: warning: Function parameter or member 'esw.esw1' not described in 'irb'
arch/s390/include/asm/cio.h:245: warning: Function parameter or member 'esw.esw2' not described in 'irb'
arch/s390/include/asm/cio.h:245: warning: Function parameter or member 'esw.esw3' not described in 'irb'
arch/s390/include/asm/cio.h:245: warning: Function parameter or member 'esw.eadm' not described in 'irb'
drivers/usb/typec/mux.c:186: warning: Function parameter or member 'mux' not described in 'typec_mux_unregister'
drivers/usb/typec/mux.c:186: warning: Excess function parameter 'sw' description in 'typec_mux_unregister'

vim +998 include/linux/device.h

^1da177e Linus Torvalds 2005-04-16 @998

:::::: The code at line 998 was first introduced by commit
:::::: 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 Linux-2.6.12-rc2

:::::: TO: Linus Torvalds <[email protected]>
:::::: CC: Linus Torvalds <[email protected]>

---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation


Attachments:
(No filename) (12.03 kB)
.config.gz (6.20 kB)
Download all attachments