Skip to content

Commit

Permalink
of/device: Merge of_platform_bus_probe()
Browse files Browse the repository at this point in the history
Merge common code between PowerPC and microblaze.  This patch merges
the code that scans the tree and registers devices.  The functions
merged are of_platform_bus_probe(), of_platform_bus_create(), and
of_platform_device_create().

This patch also move the of_default_bus_ids[] table out of a Microblaze
header file and makes it non-static.  The device ids table isn't merged
because powerpc and microblaze use different default data.

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
CC: Michal Simek <monstr@monstr.eu>
CC: Grant Likely <grant.likely@secretlab.ca>
CC: Benjamin Herrenschmidt <benh@kernel.crashing.org>
CC: Stephen Rothwell <sfr@canb.auug.org.au>
CC: microblaze-uclinux@itee.uq.edu.au
CC: linuxppc-dev@ozlabs.org
  • Loading branch information
Grant Likely committed Jul 5, 2010
1 parent 34a1c1e commit 5fd200f
Show file tree
Hide file tree
Showing 6 changed files with 179 additions and 297 deletions.
33 changes: 0 additions & 33 deletions arch/microblaze/include/asm/of_platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,39 +14,6 @@
/* This is just here during the transition */
#include <linux/of_platform.h>

/*
* The list of OF IDs below is used for matching bus types in the
* system whose devices are to be exposed as of_platform_devices.
*
* This is the default list valid for most platforms. This file provides
* functions who can take an explicit list if necessary though
*
* The search is always performed recursively looking for children of
* the provided device_node and recursively if such a children matches
* a bus type in the list
*/

static const struct of_device_id of_default_bus_ids[] = {
{ .type = "soc", },
{ .compatible = "soc", },
{ .type = "plb5", },
{ .type = "plb4", },
{ .type = "opb", },
{ .type = "simple", },
{},
};

/* Platform devices and busses creation */
extern struct of_device *of_platform_device_create(struct device_node *np,
const char *bus_id,
struct device *parent);
/* pseudo "matches" value to not do deep probe */
#define OF_NO_DEEP_PROBE ((struct of_device_id *)-1)

extern int of_platform_bus_probe(struct device_node *root,
const struct of_device_id *matches,
struct device *parent);

extern struct of_device *of_find_device_by_phandle(phandle ph);

extern void of_instantiate_rtc(void);
Expand Down
141 changes: 18 additions & 123 deletions arch/microblaze/kernel/of_platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,132 +37,27 @@ static int __init of_bus_driver_init(void)
}
postcore_initcall(of_bus_driver_init);

struct of_device *of_platform_device_create(struct device_node *np,
const char *bus_id,
struct device *parent)
{
struct of_device *dev;

dev = of_device_alloc(np, bus_id, parent);
if (!dev)
return NULL;

dev->archdata.dma_mask = 0xffffffffUL;
dev->dev.bus = &of_platform_bus_type;

/* We do not fill the DMA ops for platform devices by default.
* This is currently the responsibility of the platform code
* to do such, possibly using a device notifier
*/

if (of_device_register(dev) != 0) {
of_device_free(dev);
return NULL;
}

return dev;
}
EXPORT_SYMBOL(of_platform_device_create);

/**
* of_platform_bus_create - Create an OF device for a bus node and all its
* children. Optionally recursively instanciate matching busses.
* @bus: device node of the bus to instanciate
* @matches: match table, NULL to use the default, OF_NO_DEEP_PROBE to
* disallow recursive creation of child busses
*/
static int of_platform_bus_create(const struct device_node *bus,
const struct of_device_id *matches,
struct device *parent)
{
struct device_node *child;
struct of_device *dev;
int rc = 0;

for_each_child_of_node(bus, child) {
pr_debug(" create child: %s\n", child->full_name);
dev = of_platform_device_create(child, NULL, parent);
if (dev == NULL)
rc = -ENOMEM;
else if (!of_match_node(matches, child))
continue;
if (rc == 0) {
pr_debug(" and sub busses\n");
rc = of_platform_bus_create(child, matches, &dev->dev);
}
if (rc) {
of_node_put(child);
break;
}
}
return rc;
}


/**
* of_platform_bus_probe - Probe the device-tree for platform busses
* @root: parent of the first level to probe or NULL for the root of the tree
* @matches: match table, NULL to use the default
* @parent: parent to hook devices from, NULL for toplevel
/*
* The list of OF IDs below is used for matching bus types in the
* system whose devices are to be exposed as of_platform_devices.
*
* Note that children of the provided root are not instanciated as devices
* unless the specified root itself matches the bus list and is not NULL.
* This is the default list valid for most platforms. This file provides
* functions who can take an explicit list if necessary though
*
* The search is always performed recursively looking for children of
* the provided device_node and recursively if such a children matches
* a bus type in the list
*/

int of_platform_bus_probe(struct device_node *root,
const struct of_device_id *matches,
struct device *parent)
{
struct device_node *child;
struct of_device *dev;
int rc = 0;

if (matches == NULL)
matches = of_default_bus_ids;
if (matches == OF_NO_DEEP_PROBE)
return -EINVAL;
if (root == NULL)
root = of_find_node_by_path("/");
else
of_node_get(root);

pr_debug("of_platform_bus_probe()\n");
pr_debug(" starting at: %s\n", root->full_name);

/* Do a self check of bus type, if there's a match, create
* children
*/
if (of_match_node(matches, root)) {
pr_debug(" root match, create all sub devices\n");
dev = of_platform_device_create(root, NULL, parent);
if (dev == NULL) {
rc = -ENOMEM;
goto bail;
}
pr_debug(" create all sub busses\n");
rc = of_platform_bus_create(root, matches, &dev->dev);
goto bail;
}
for_each_child_of_node(root, child) {
if (!of_match_node(matches, child))
continue;

pr_debug(" match: %s\n", child->full_name);
dev = of_platform_device_create(child, NULL, parent);
if (dev == NULL)
rc = -ENOMEM;
else
rc = of_platform_bus_create(child, matches, &dev->dev);
if (rc) {
of_node_put(child);
break;
}
}
bail:
of_node_put(root);
return rc;
}
EXPORT_SYMBOL(of_platform_bus_probe);
const struct of_device_id of_default_bus_ids[] = {
{ .type = "soc", },
{ .compatible = "soc", },
{ .type = "plb5", },
{ .type = "plb4", },
{ .type = "opb", },
{ .type = "simple", },
{},
};

static int of_dev_node_match(struct device *dev, void *data)
{
Expand Down
11 changes: 0 additions & 11 deletions arch/powerpc/include/asm/of_platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,6 @@
*
*/

/* Platform devices and busses creation */
extern struct of_device *of_platform_device_create(struct device_node *np,
const char *bus_id,
struct device *parent);
/* pseudo "matches" value to not do deep probe */
#define OF_NO_DEEP_PROBE ((struct of_device_id *)-1)

extern int of_platform_bus_probe(struct device_node *root,
const struct of_device_id *matches,
struct device *parent);

extern struct of_device *of_find_device_by_phandle(phandle ph);

extern void of_instantiate_rtc(void);
Expand Down
131 changes: 1 addition & 130 deletions arch/powerpc/kernel/of_platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
* a bus type in the list
*/

static const struct of_device_id of_default_bus_ids[] = {
const struct of_device_id of_default_bus_ids[] = {
{ .type = "soc", },
{ .compatible = "soc", },
{ .type = "spider", },
Expand All @@ -64,135 +64,6 @@ static int __init of_bus_driver_init(void)

postcore_initcall(of_bus_driver_init);

struct of_device* of_platform_device_create(struct device_node *np,
const char *bus_id,
struct device *parent)
{
struct of_device *dev;

dev = of_device_alloc(np, bus_id, parent);
if (!dev)
return NULL;

dev->archdata.dma_mask = 0xffffffffUL;
dev->dev.coherent_dma_mask = DMA_BIT_MASK(32);

dev->dev.bus = &of_platform_bus_type;

/* We do not fill the DMA ops for platform devices by default.
* This is currently the responsibility of the platform code
* to do such, possibly using a device notifier
*/

if (of_device_register(dev) != 0) {
of_device_free(dev);
return NULL;
}

return dev;
}
EXPORT_SYMBOL(of_platform_device_create);



/**
* of_platform_bus_create - Create an OF device for a bus node and all its
* children. Optionally recursively instanciate matching busses.
* @bus: device node of the bus to instanciate
* @matches: match table, NULL to use the default, OF_NO_DEEP_PROBE to
* disallow recursive creation of child busses
*/
static int of_platform_bus_create(const struct device_node *bus,
const struct of_device_id *matches,
struct device *parent)
{
struct device_node *child;
struct of_device *dev;
int rc = 0;

for_each_child_of_node(bus, child) {
pr_debug(" create child: %s\n", child->full_name);
dev = of_platform_device_create(child, NULL, parent);
if (dev == NULL)
rc = -ENOMEM;
else if (!of_match_node(matches, child))
continue;
if (rc == 0) {
pr_debug(" and sub busses\n");
rc = of_platform_bus_create(child, matches, &dev->dev);
} if (rc) {
of_node_put(child);
break;
}
}
return rc;
}

/**
* of_platform_bus_probe - Probe the device-tree for platform busses
* @root: parent of the first level to probe or NULL for the root of the tree
* @matches: match table, NULL to use the default
* @parent: parent to hook devices from, NULL for toplevel
*
* Note that children of the provided root are not instanciated as devices
* unless the specified root itself matches the bus list and is not NULL.
*/

int of_platform_bus_probe(struct device_node *root,
const struct of_device_id *matches,
struct device *parent)
{
struct device_node *child;
struct of_device *dev;
int rc = 0;

if (matches == NULL)
matches = of_default_bus_ids;
if (matches == OF_NO_DEEP_PROBE)
return -EINVAL;
if (root == NULL)
root = of_find_node_by_path("/");
else
of_node_get(root);

pr_debug("of_platform_bus_probe()\n");
pr_debug(" starting at: %s\n", root->full_name);

/* Do a self check of bus type, if there's a match, create
* children
*/
if (of_match_node(matches, root)) {
pr_debug(" root match, create all sub devices\n");
dev = of_platform_device_create(root, NULL, parent);
if (dev == NULL) {
rc = -ENOMEM;
goto bail;
}
pr_debug(" create all sub busses\n");
rc = of_platform_bus_create(root, matches, &dev->dev);
goto bail;
}
for_each_child_of_node(root, child) {
if (!of_match_node(matches, child))
continue;

pr_debug(" match: %s\n", child->full_name);
dev = of_platform_device_create(child, NULL, parent);
if (dev == NULL)
rc = -ENOMEM;
else
rc = of_platform_bus_create(child, matches, &dev->dev);
if (rc) {
of_node_put(child);
break;
}
}
bail:
of_node_put(root);
return rc;
}
EXPORT_SYMBOL(of_platform_bus_probe);

static int of_dev_node_match(struct device *dev, void *data)
{
return to_of_device(dev)->dev.of_node == data;
Expand Down
Loading

0 comments on commit 5fd200f

Please sign in to comment.