Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/sfr/ofcons
* 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/sfr/ofcons: Create drivers/of/platform.c Create linux/of_platorm.h [SPARC/64] Rename some functions like PowerPC Begin consolidation of of_device.h Begin to consolidate of_device.c Consolidate of_find_node_by routines Consolidate of_get_next_child Consolidate of_get_parent Consolidate of_find_property Consolidate of_device_is_compatible Start split out of common open firmware code Split out common parts of prom.h
This commit is contained in:
commit
2cb7e71422
33 changed files with 846 additions and 1483 deletions
|
@ -92,6 +92,9 @@ config ARCH_MAY_HAVE_PC_FDC
|
|||
config PPC_OF
|
||||
def_bool y
|
||||
|
||||
config OF
|
||||
def_bool y
|
||||
|
||||
config PPC_UDBG_16550
|
||||
bool
|
||||
default n
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include <linux/string.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
|
@ -8,118 +9,6 @@
|
|||
#include <asm/errno.h>
|
||||
#include <asm/of_device.h>
|
||||
|
||||
/**
|
||||
* of_match_node - Tell if an device_node has a matching of_match structure
|
||||
* @ids: array of of device match structures to search in
|
||||
* @node: the of device structure to match against
|
||||
*
|
||||
* Low level utility function used by device matching.
|
||||
*/
|
||||
const struct of_device_id *of_match_node(const struct of_device_id *matches,
|
||||
const struct device_node *node)
|
||||
{
|
||||
while (matches->name[0] || matches->type[0] || matches->compatible[0]) {
|
||||
int match = 1;
|
||||
if (matches->name[0])
|
||||
match &= node->name
|
||||
&& !strcmp(matches->name, node->name);
|
||||
if (matches->type[0])
|
||||
match &= node->type
|
||||
&& !strcmp(matches->type, node->type);
|
||||
if (matches->compatible[0])
|
||||
match &= of_device_is_compatible(node,
|
||||
matches->compatible);
|
||||
if (match)
|
||||
return matches;
|
||||
matches++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* of_match_device - Tell if an of_device structure has a matching
|
||||
* of_match structure
|
||||
* @ids: array of of device match structures to search in
|
||||
* @dev: the of device structure to match against
|
||||
*
|
||||
* Used by a driver to check whether an of_device present in the
|
||||
* system is in its list of supported devices.
|
||||
*/
|
||||
const struct of_device_id *of_match_device(const struct of_device_id *matches,
|
||||
const struct of_device *dev)
|
||||
{
|
||||
if (!dev->node)
|
||||
return NULL;
|
||||
return of_match_node(matches, dev->node);
|
||||
}
|
||||
|
||||
struct of_device *of_dev_get(struct of_device *dev)
|
||||
{
|
||||
struct device *tmp;
|
||||
|
||||
if (!dev)
|
||||
return NULL;
|
||||
tmp = get_device(&dev->dev);
|
||||
if (tmp)
|
||||
return to_of_device(tmp);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void of_dev_put(struct of_device *dev)
|
||||
{
|
||||
if (dev)
|
||||
put_device(&dev->dev);
|
||||
}
|
||||
|
||||
static ssize_t dev_show_devspec(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct of_device *ofdev;
|
||||
|
||||
ofdev = to_of_device(dev);
|
||||
return sprintf(buf, "%s", ofdev->node->full_name);
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(devspec, S_IRUGO, dev_show_devspec, NULL);
|
||||
|
||||
/**
|
||||
* of_release_dev - free an of device structure when all users of it are finished.
|
||||
* @dev: device that's been disconnected
|
||||
*
|
||||
* Will be called only by the device core when all users of this of device are
|
||||
* done.
|
||||
*/
|
||||
void of_release_dev(struct device *dev)
|
||||
{
|
||||
struct of_device *ofdev;
|
||||
|
||||
ofdev = to_of_device(dev);
|
||||
of_node_put(ofdev->node);
|
||||
kfree(ofdev);
|
||||
}
|
||||
|
||||
int of_device_register(struct of_device *ofdev)
|
||||
{
|
||||
int rc;
|
||||
|
||||
BUG_ON(ofdev->node == NULL);
|
||||
|
||||
rc = device_register(&ofdev->dev);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
return device_create_file(&ofdev->dev, &dev_attr_devspec);
|
||||
}
|
||||
|
||||
void of_device_unregister(struct of_device *ofdev)
|
||||
{
|
||||
device_remove_file(&ofdev->dev, &dev_attr_devspec);
|
||||
|
||||
device_unregister(&ofdev->dev);
|
||||
}
|
||||
|
||||
|
||||
ssize_t of_device_get_modalias(struct of_device *ofdev,
|
||||
char *str, ssize_t len)
|
||||
{
|
||||
|
@ -229,14 +118,5 @@ int of_device_uevent(struct device *dev,
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
EXPORT_SYMBOL(of_match_node);
|
||||
EXPORT_SYMBOL(of_match_device);
|
||||
EXPORT_SYMBOL(of_device_register);
|
||||
EXPORT_SYMBOL(of_device_unregister);
|
||||
EXPORT_SYMBOL(of_dev_get);
|
||||
EXPORT_SYMBOL(of_dev_put);
|
||||
EXPORT_SYMBOL(of_release_dev);
|
||||
EXPORT_SYMBOL(of_device_uevent);
|
||||
EXPORT_SYMBOL(of_device_get_modalias);
|
||||
|
|
|
@ -55,94 +55,14 @@ static struct of_device_id of_default_bus_ids[] = {
|
|||
|
||||
static atomic_t bus_no_reg_magic;
|
||||
|
||||
/*
|
||||
*
|
||||
* OF platform device type definition & base infrastructure
|
||||
*
|
||||
*/
|
||||
|
||||
static int of_platform_bus_match(struct device *dev, struct device_driver *drv)
|
||||
{
|
||||
struct of_device * of_dev = to_of_device(dev);
|
||||
struct of_platform_driver * of_drv = to_of_platform_driver(drv);
|
||||
const struct of_device_id * matches = of_drv->match_table;
|
||||
|
||||
if (!matches)
|
||||
return 0;
|
||||
|
||||
return of_match_device(matches, of_dev) != NULL;
|
||||
}
|
||||
|
||||
static int of_platform_device_probe(struct device *dev)
|
||||
{
|
||||
int error = -ENODEV;
|
||||
struct of_platform_driver *drv;
|
||||
struct of_device *of_dev;
|
||||
const struct of_device_id *match;
|
||||
|
||||
drv = to_of_platform_driver(dev->driver);
|
||||
of_dev = to_of_device(dev);
|
||||
|
||||
if (!drv->probe)
|
||||
return error;
|
||||
|
||||
of_dev_get(of_dev);
|
||||
|
||||
match = of_match_device(drv->match_table, of_dev);
|
||||
if (match)
|
||||
error = drv->probe(of_dev, match);
|
||||
if (error)
|
||||
of_dev_put(of_dev);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
static int of_platform_device_remove(struct device *dev)
|
||||
{
|
||||
struct of_device * of_dev = to_of_device(dev);
|
||||
struct of_platform_driver * drv = to_of_platform_driver(dev->driver);
|
||||
|
||||
if (dev->driver && drv->remove)
|
||||
drv->remove(of_dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int of_platform_device_suspend(struct device *dev, pm_message_t state)
|
||||
{
|
||||
struct of_device * of_dev = to_of_device(dev);
|
||||
struct of_platform_driver * drv = to_of_platform_driver(dev->driver);
|
||||
int error = 0;
|
||||
|
||||
if (dev->driver && drv->suspend)
|
||||
error = drv->suspend(of_dev, state);
|
||||
return error;
|
||||
}
|
||||
|
||||
static int of_platform_device_resume(struct device * dev)
|
||||
{
|
||||
struct of_device * of_dev = to_of_device(dev);
|
||||
struct of_platform_driver * drv = to_of_platform_driver(dev->driver);
|
||||
int error = 0;
|
||||
|
||||
if (dev->driver && drv->resume)
|
||||
error = drv->resume(of_dev);
|
||||
return error;
|
||||
}
|
||||
|
||||
struct bus_type of_platform_bus_type = {
|
||||
.name = "of_platform",
|
||||
.match = of_platform_bus_match,
|
||||
.uevent = of_device_uevent,
|
||||
.probe = of_platform_device_probe,
|
||||
.remove = of_platform_device_remove,
|
||||
.suspend = of_platform_device_suspend,
|
||||
.resume = of_platform_device_resume,
|
||||
};
|
||||
EXPORT_SYMBOL(of_platform_bus_type);
|
||||
|
||||
static int __init of_bus_driver_init(void)
|
||||
{
|
||||
return bus_register(&of_platform_bus_type);
|
||||
return of_bus_type_init(&of_platform_bus_type, "of_platform");
|
||||
}
|
||||
|
||||
postcore_initcall(of_bus_driver_init);
|
||||
|
|
|
@ -78,12 +78,9 @@ static struct boot_param_header *initial_boot_params __initdata;
|
|||
struct boot_param_header *initial_boot_params;
|
||||
#endif
|
||||
|
||||
static struct device_node *allnodes = NULL;
|
||||
extern struct device_node *allnodes; /* temporary while merging */
|
||||
|
||||
/* use when traversing tree through the allnext, child, sibling,
|
||||
* or parent members of struct device_node.
|
||||
*/
|
||||
static DEFINE_RWLOCK(devtree_lock);
|
||||
extern rwlock_t devtree_lock; /* temporary while merging */
|
||||
|
||||
/* export that to outside world */
|
||||
struct device_node *of_chosen;
|
||||
|
@ -1056,60 +1053,6 @@ void __init early_init_devtree(void *params)
|
|||
DBG(" <- early_init_devtree()\n");
|
||||
}
|
||||
|
||||
int of_n_addr_cells(struct device_node* np)
|
||||
{
|
||||
const int *ip;
|
||||
do {
|
||||
if (np->parent)
|
||||
np = np->parent;
|
||||
ip = of_get_property(np, "#address-cells", NULL);
|
||||
if (ip != NULL)
|
||||
return *ip;
|
||||
} while (np->parent);
|
||||
/* No #address-cells property for the root node, default to 1 */
|
||||
return 1;
|
||||
}
|
||||
EXPORT_SYMBOL(of_n_addr_cells);
|
||||
|
||||
int of_n_size_cells(struct device_node* np)
|
||||
{
|
||||
const int* ip;
|
||||
do {
|
||||
if (np->parent)
|
||||
np = np->parent;
|
||||
ip = of_get_property(np, "#size-cells", NULL);
|
||||
if (ip != NULL)
|
||||
return *ip;
|
||||
} while (np->parent);
|
||||
/* No #size-cells property for the root node, default to 1 */
|
||||
return 1;
|
||||
}
|
||||
EXPORT_SYMBOL(of_n_size_cells);
|
||||
|
||||
/** Checks if the given "compat" string matches one of the strings in
|
||||
* the device's "compatible" property
|
||||
*/
|
||||
int of_device_is_compatible(const struct device_node *device,
|
||||
const char *compat)
|
||||
{
|
||||
const char* cp;
|
||||
int cplen, l;
|
||||
|
||||
cp = of_get_property(device, "compatible", &cplen);
|
||||
if (cp == NULL)
|
||||
return 0;
|
||||
while (cplen > 0) {
|
||||
if (strncasecmp(cp, compat, strlen(compat)) == 0)
|
||||
return 1;
|
||||
l = strlen(cp) + 1;
|
||||
cp += l;
|
||||
cplen -= l;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(of_device_is_compatible);
|
||||
|
||||
|
||||
/**
|
||||
* Indicates whether the root node has a given value in its
|
||||
|
@ -1140,119 +1083,6 @@ EXPORT_SYMBOL(machine_is_compatible);
|
|||
*
|
||||
*******/
|
||||
|
||||
/**
|
||||
* of_find_node_by_name - Find a node by its "name" property
|
||||
* @from: 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
|
||||
* @name: The name string to match against
|
||||
*
|
||||
* Returns a node pointer with refcount incremented, use
|
||||
* of_node_put() on it when done.
|
||||
*/
|
||||
struct device_node *of_find_node_by_name(struct device_node *from,
|
||||
const char *name)
|
||||
{
|
||||
struct device_node *np;
|
||||
|
||||
read_lock(&devtree_lock);
|
||||
np = from ? from->allnext : allnodes;
|
||||
for (; np != NULL; np = np->allnext)
|
||||
if (np->name != NULL && strcasecmp(np->name, name) == 0
|
||||
&& of_node_get(np))
|
||||
break;
|
||||
of_node_put(from);
|
||||
read_unlock(&devtree_lock);
|
||||
return np;
|
||||
}
|
||||
EXPORT_SYMBOL(of_find_node_by_name);
|
||||
|
||||
/**
|
||||
* of_find_node_by_type - Find a node by its "device_type" property
|
||||
* @from: The node to start searching from, or NULL to start searching
|
||||
* the entire device tree. 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 from for you.
|
||||
* @type: The type string to match against
|
||||
*
|
||||
* Returns a node pointer with refcount incremented, use
|
||||
* of_node_put() on it when done.
|
||||
*/
|
||||
struct device_node *of_find_node_by_type(struct device_node *from,
|
||||
const char *type)
|
||||
{
|
||||
struct device_node *np;
|
||||
|
||||
read_lock(&devtree_lock);
|
||||
np = from ? from->allnext : allnodes;
|
||||
for (; np != 0; np = np->allnext)
|
||||
if (np->type != 0 && strcasecmp(np->type, type) == 0
|
||||
&& of_node_get(np))
|
||||
break;
|
||||
of_node_put(from);
|
||||
read_unlock(&devtree_lock);
|
||||
return np;
|
||||
}
|
||||
EXPORT_SYMBOL(of_find_node_by_type);
|
||||
|
||||
/**
|
||||
* of_find_compatible_node - Find a node based on type and one of the
|
||||
* tokens in its "compatible" property
|
||||
* @from: 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 refcount incremented, use
|
||||
* of_node_put() on it when done.
|
||||
*/
|
||||
struct device_node *of_find_compatible_node(struct device_node *from,
|
||||
const char *type, const char *compatible)
|
||||
{
|
||||
struct device_node *np;
|
||||
|
||||
read_lock(&devtree_lock);
|
||||
np = from ? from->allnext : allnodes;
|
||||
for (; np != 0; np = np->allnext) {
|
||||
if (type != NULL
|
||||
&& !(np->type != 0 && strcasecmp(np->type, type) == 0))
|
||||
continue;
|
||||
if (of_device_is_compatible(np, compatible) && of_node_get(np))
|
||||
break;
|
||||
}
|
||||
of_node_put(from);
|
||||
read_unlock(&devtree_lock);
|
||||
return np;
|
||||
}
|
||||
EXPORT_SYMBOL(of_find_compatible_node);
|
||||
|
||||
/**
|
||||
* of_find_node_by_path - Find a node matching a full OF path
|
||||
* @path: The full path to match
|
||||
*
|
||||
* Returns a node pointer with refcount incremented, use
|
||||
* of_node_put() on it when done.
|
||||
*/
|
||||
struct device_node *of_find_node_by_path(const char *path)
|
||||
{
|
||||
struct device_node *np = allnodes;
|
||||
|
||||
read_lock(&devtree_lock);
|
||||
for (; np != 0; np = np->allnext) {
|
||||
if (np->full_name != 0 && strcasecmp(np->full_name, path) == 0
|
||||
&& of_node_get(np))
|
||||
break;
|
||||
}
|
||||
read_unlock(&devtree_lock);
|
||||
return np;
|
||||
}
|
||||
EXPORT_SYMBOL(of_find_node_by_path);
|
||||
|
||||
/**
|
||||
* of_find_node_by_phandle - Find a node given a phandle
|
||||
* @handle: phandle of the node to find
|
||||
|
@ -1297,51 +1127,6 @@ struct device_node *of_find_all_nodes(struct device_node *prev)
|
|||
}
|
||||
EXPORT_SYMBOL(of_find_all_nodes);
|
||||
|
||||
/**
|
||||
* of_get_parent - Get a node's parent if any
|
||||
* @node: Node to get parent
|
||||
*
|
||||
* Returns a node pointer with refcount incremented, use
|
||||
* of_node_put() on it when done.
|
||||
*/
|
||||
struct device_node *of_get_parent(const struct device_node *node)
|
||||
{
|
||||
struct device_node *np;
|
||||
|
||||
if (!node)
|
||||
return NULL;
|
||||
|
||||
read_lock(&devtree_lock);
|
||||
np = of_node_get(node->parent);
|
||||
read_unlock(&devtree_lock);
|
||||
return np;
|
||||
}
|
||||
EXPORT_SYMBOL(of_get_parent);
|
||||
|
||||
/**
|
||||
* of_get_next_child - Iterate a node childs
|
||||
* @node: parent node
|
||||
* @prev: previous child of the parent node, or NULL to get first
|
||||
*
|
||||
* Returns a node pointer with refcount incremented, use
|
||||
* of_node_put() on it when done.
|
||||
*/
|
||||
struct device_node *of_get_next_child(const struct device_node *node,
|
||||
struct device_node *prev)
|
||||
{
|
||||
struct device_node *next;
|
||||
|
||||
read_lock(&devtree_lock);
|
||||
next = prev ? prev->sibling : node->child;
|
||||
for (; next != 0; next = next->sibling)
|
||||
if (of_node_get(next))
|
||||
break;
|
||||
of_node_put(prev);
|
||||
read_unlock(&devtree_lock);
|
||||
return next;
|
||||
}
|
||||
EXPORT_SYMBOL(of_get_next_child);
|
||||
|
||||
/**
|
||||
* of_node_get - Increment refcount of a node
|
||||
* @node: Node to inc refcount, NULL is supported to
|
||||
|
@ -1543,37 +1328,6 @@ static int __init prom_reconfig_setup(void)
|
|||
__initcall(prom_reconfig_setup);
|
||||
#endif
|
||||
|
||||
struct property *of_find_property(const struct device_node *np,
|
||||
const char *name,
|
||||
int *lenp)
|
||||
{
|
||||
struct property *pp;
|
||||
|
||||
read_lock(&devtree_lock);
|
||||
for (pp = np->properties; pp != 0; pp = pp->next)
|
||||
if (strcmp(pp->name, name) == 0) {
|
||||
if (lenp != 0)
|
||||
*lenp = pp->length;
|
||||
break;
|
||||
}
|
||||
read_unlock(&devtree_lock);
|
||||
|
||||
return pp;
|
||||
}
|
||||
EXPORT_SYMBOL(of_find_property);
|
||||
|
||||
/*
|
||||
* Find a property with a given name for a given node
|
||||
* and return the value.
|
||||
*/
|
||||
const void *of_get_property(const struct device_node *np, const char *name,
|
||||
int *lenp)
|
||||
{
|
||||
struct property *pp = of_find_property(np,name,lenp);
|
||||
return pp ? pp->value : NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(of_get_property);
|
||||
|
||||
/*
|
||||
* Add a property to a node
|
||||
*/
|
||||
|
|
|
@ -24,6 +24,9 @@ config GENERIC_ISA_DMA
|
|||
config ARCH_NO_VIRT_TO_BUS
|
||||
def_bool y
|
||||
|
||||
config OF
|
||||
def_bool y
|
||||
|
||||
source "init/Kconfig"
|
||||
|
||||
menu "General machine setup"
|
||||
|
|
|
@ -1,132 +1,13 @@
|
|||
#include <linux/string.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <asm/errno.h>
|
||||
#include <asm/of_device.h>
|
||||
|
||||
/**
|
||||
* of_match_device - Tell if an of_device structure has a matching
|
||||
* of_match structure
|
||||
* @ids: array of of device match structures to search in
|
||||
* @dev: the of device structure to match against
|
||||
*
|
||||
* Used by a driver to check whether an of_device present in the
|
||||
* system is in its list of supported devices.
|
||||
*/
|
||||
const struct of_device_id *of_match_device(const struct of_device_id *matches,
|
||||
const struct of_device *dev)
|
||||
{
|
||||
if (!dev->node)
|
||||
return NULL;
|
||||
while (matches->name[0] || matches->type[0] || matches->compatible[0]) {
|
||||
int match = 1;
|
||||
if (matches->name[0])
|
||||
match &= dev->node->name
|
||||
&& !strcmp(matches->name, dev->node->name);
|
||||
if (matches->type[0])
|
||||
match &= dev->node->type
|
||||
&& !strcmp(matches->type, dev->node->type);
|
||||
if (matches->compatible[0])
|
||||
match &= of_device_is_compatible(dev->node,
|
||||
matches->compatible);
|
||||
if (match)
|
||||
return matches;
|
||||
matches++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int of_platform_bus_match(struct device *dev, struct device_driver *drv)
|
||||
{
|
||||
struct of_device * of_dev = to_of_device(dev);
|
||||
struct of_platform_driver * of_drv = to_of_platform_driver(drv);
|
||||
const struct of_device_id * matches = of_drv->match_table;
|
||||
|
||||
if (!matches)
|
||||
return 0;
|
||||
|
||||
return of_match_device(matches, of_dev) != NULL;
|
||||
}
|
||||
|
||||
struct of_device *of_dev_get(struct of_device *dev)
|
||||
{
|
||||
struct device *tmp;
|
||||
|
||||
if (!dev)
|
||||
return NULL;
|
||||
tmp = get_device(&dev->dev);
|
||||
if (tmp)
|
||||
return to_of_device(tmp);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void of_dev_put(struct of_device *dev)
|
||||
{
|
||||
if (dev)
|
||||
put_device(&dev->dev);
|
||||
}
|
||||
|
||||
|
||||
static int of_device_probe(struct device *dev)
|
||||
{
|
||||
int error = -ENODEV;
|
||||
struct of_platform_driver *drv;
|
||||
struct of_device *of_dev;
|
||||
const struct of_device_id *match;
|
||||
|
||||
drv = to_of_platform_driver(dev->driver);
|
||||
of_dev = to_of_device(dev);
|
||||
|
||||
if (!drv->probe)
|
||||
return error;
|
||||
|
||||
of_dev_get(of_dev);
|
||||
|
||||
match = of_match_device(drv->match_table, of_dev);
|
||||
if (match)
|
||||
error = drv->probe(of_dev, match);
|
||||
if (error)
|
||||
of_dev_put(of_dev);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
static int of_device_remove(struct device *dev)
|
||||
{
|
||||
struct of_device * of_dev = to_of_device(dev);
|
||||
struct of_platform_driver * drv = to_of_platform_driver(dev->driver);
|
||||
|
||||
if (dev->driver && drv->remove)
|
||||
drv->remove(of_dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int of_device_suspend(struct device *dev, pm_message_t state)
|
||||
{
|
||||
struct of_device * of_dev = to_of_device(dev);
|
||||
struct of_platform_driver * drv = to_of_platform_driver(dev->driver);
|
||||
int error = 0;
|
||||
|
||||
if (dev->driver && drv->suspend)
|
||||
error = drv->suspend(of_dev, state);
|
||||
return error;
|
||||
}
|
||||
|
||||
static int of_device_resume(struct device * dev)
|
||||
{
|
||||
struct of_device * of_dev = to_of_device(dev);
|
||||
struct of_platform_driver * drv = to_of_platform_driver(dev->driver);
|
||||
int error = 0;
|
||||
|
||||
if (dev->driver && drv->resume)
|
||||
error = drv->resume(of_dev);
|
||||
return error;
|
||||
}
|
||||
#include <linux/errno.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of_platform.h>
|
||||
|
||||
static int node_match(struct device *dev, void *data)
|
||||
{
|
||||
|
@ -138,7 +19,7 @@ static int node_match(struct device *dev, void *data)
|
|||
|
||||
struct of_device *of_find_device_by_node(struct device_node *dp)
|
||||
{
|
||||
struct device *dev = bus_find_device(&of_bus_type, NULL,
|
||||
struct device *dev = bus_find_device(&of_platform_bus_type, NULL,
|
||||
dp, node_match);
|
||||
|
||||
if (dev)
|
||||
|
@ -149,38 +30,17 @@ struct of_device *of_find_device_by_node(struct device_node *dp)
|
|||
EXPORT_SYMBOL(of_find_device_by_node);
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
struct bus_type ebus_bus_type = {
|
||||
.name = "ebus",
|
||||
.match = of_platform_bus_match,
|
||||
.probe = of_device_probe,
|
||||
.remove = of_device_remove,
|
||||
.suspend = of_device_suspend,
|
||||
.resume = of_device_resume,
|
||||
};
|
||||
struct bus_type ebus_bus_type;
|
||||
EXPORT_SYMBOL(ebus_bus_type);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SBUS
|
||||
struct bus_type sbus_bus_type = {
|
||||
.name = "sbus",
|
||||
.match = of_platform_bus_match,
|
||||
.probe = of_device_probe,
|
||||
.remove = of_device_remove,
|
||||
.suspend = of_device_suspend,
|
||||
.resume = of_device_resume,
|
||||
};
|
||||
struct bus_type sbus_bus_type;
|
||||
EXPORT_SYMBOL(sbus_bus_type);
|
||||
#endif
|
||||
|
||||
struct bus_type of_bus_type = {
|
||||
.name = "of",
|
||||
.match = of_platform_bus_match,
|
||||
.probe = of_device_probe,
|
||||
.remove = of_device_remove,
|
||||
.suspend = of_device_suspend,
|
||||
.resume = of_device_resume,
|
||||
};
|
||||
EXPORT_SYMBOL(of_bus_type);
|
||||
struct bus_type of_platform_bus_type;
|
||||
EXPORT_SYMBOL(of_platform_bus_type);
|
||||
|
||||
static inline u64 of_read_addr(const u32 *cell, int size)
|
||||
{
|
||||
|
@ -646,7 +506,7 @@ static struct of_device * __init scan_one_device(struct device_node *dp,
|
|||
build_device_resources(op, parent);
|
||||
|
||||
op->dev.parent = parent;
|
||||
op->dev.bus = &of_bus_type;
|
||||
op->dev.bus = &of_platform_bus_type;
|
||||
if (!parent)
|
||||
strcpy(op->dev.bus_id, "root");
|
||||
else
|
||||
|
@ -690,14 +550,14 @@ static int __init of_bus_driver_init(void)
|
|||
{
|
||||
int err;
|
||||
|
||||
err = bus_register(&of_bus_type);
|
||||
err = of_bus_type_init(&of_platform_bus_type, "of");
|
||||
#ifdef CONFIG_PCI
|
||||
if (!err)
|
||||
err = bus_register(&ebus_bus_type);
|
||||
err = of_bus_type_init(&ebus_bus_type, "ebus");
|
||||
#endif
|
||||
#ifdef CONFIG_SBUS
|
||||
if (!err)
|
||||
err = bus_register(&sbus_bus_type);
|
||||
err = of_bus_type_init(&sbus_bus_type, "sbus");
|
||||
#endif
|
||||
|
||||
if (!err)
|
||||
|
@ -735,56 +595,6 @@ void of_unregister_driver(struct of_platform_driver *drv)
|
|||
driver_unregister(&drv->driver);
|
||||
}
|
||||
|
||||
|
||||
static ssize_t dev_show_devspec(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct of_device *ofdev;
|
||||
|
||||
ofdev = to_of_device(dev);
|
||||
return sprintf(buf, "%s", ofdev->node->full_name);
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(devspec, S_IRUGO, dev_show_devspec, NULL);
|
||||
|
||||
/**
|
||||
* of_release_dev - free an of device structure when all users of it are finished.
|
||||
* @dev: device that's been disconnected
|
||||
*
|
||||
* Will be called only by the device core when all users of this of device are
|
||||
* done.
|
||||
*/
|
||||
void of_release_dev(struct device *dev)
|
||||
{
|
||||
struct of_device *ofdev;
|
||||
|
||||
ofdev = to_of_device(dev);
|
||||
|
||||
kfree(ofdev);
|
||||
}
|
||||
|
||||
int of_device_register(struct of_device *ofdev)
|
||||
{
|
||||
int rc;
|
||||
|
||||
BUG_ON(ofdev->node == NULL);
|
||||
|
||||
rc = device_register(&ofdev->dev);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = device_create_file(&ofdev->dev, &dev_attr_devspec);
|
||||
if (rc)
|
||||
device_unregister(&ofdev->dev);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void of_device_unregister(struct of_device *ofdev)
|
||||
{
|
||||
device_remove_file(&ofdev->dev, &dev_attr_devspec);
|
||||
device_unregister(&ofdev->dev);
|
||||
}
|
||||
|
||||
struct of_device* of_platform_device_create(struct device_node *np,
|
||||
const char *bus_id,
|
||||
struct device *parent,
|
||||
|
@ -810,12 +620,6 @@ struct of_device* of_platform_device_create(struct device_node *np,
|
|||
return dev;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(of_match_device);
|
||||
EXPORT_SYMBOL(of_register_driver);
|
||||
EXPORT_SYMBOL(of_unregister_driver);
|
||||
EXPORT_SYMBOL(of_device_register);
|
||||
EXPORT_SYMBOL(of_device_unregister);
|
||||
EXPORT_SYMBOL(of_dev_get);
|
||||
EXPORT_SYMBOL(of_dev_put);
|
||||
EXPORT_SYMBOL(of_platform_device_create);
|
||||
EXPORT_SYMBOL(of_release_dev);
|
||||
|
|
|
@ -25,73 +25,9 @@
|
|||
#include <asm/prom.h>
|
||||
#include <asm/oplib.h>
|
||||
|
||||
static struct device_node *allnodes;
|
||||
extern struct device_node *allnodes; /* temporary while merging */
|
||||
|
||||
/* use when traversing tree through the allnext, child, sibling,
|
||||
* or parent members of struct device_node.
|
||||
*/
|
||||
static DEFINE_RWLOCK(devtree_lock);
|
||||
|
||||
int of_device_is_compatible(const struct device_node *device,
|
||||
const char *compat)
|
||||
{
|
||||
const char* cp;
|
||||
int cplen, l;
|
||||
|
||||
cp = of_get_property(device, "compatible", &cplen);
|
||||
if (cp == NULL)
|
||||
return 0;
|
||||
while (cplen > 0) {
|
||||
if (strncmp(cp, compat, strlen(compat)) == 0)
|
||||
return 1;
|
||||
l = strlen(cp) + 1;
|
||||
cp += l;
|
||||
cplen -= l;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(of_device_is_compatible);
|
||||
|
||||
struct device_node *of_get_parent(const struct device_node *node)
|
||||
{
|
||||
struct device_node *np;
|
||||
|
||||
if (!node)
|
||||
return NULL;
|
||||
|
||||
np = node->parent;
|
||||
|
||||
return np;
|
||||
}
|
||||
EXPORT_SYMBOL(of_get_parent);
|
||||
|
||||
struct device_node *of_get_next_child(const struct device_node *node,
|
||||
struct device_node *prev)
|
||||
{
|
||||
struct device_node *next;
|
||||
|
||||
next = prev ? prev->sibling : node->child;
|
||||
for (; next != 0; next = next->sibling) {
|
||||
break;
|
||||
}
|
||||
|
||||
return next;
|
||||
}
|
||||
EXPORT_SYMBOL(of_get_next_child);
|
||||
|
||||
struct device_node *of_find_node_by_path(const char *path)
|
||||
{
|
||||
struct device_node *np = allnodes;
|
||||
|
||||
for (; np != 0; np = np->allnext) {
|
||||
if (np->full_name != 0 && strcmp(np->full_name, path) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
return np;
|
||||
}
|
||||
EXPORT_SYMBOL(of_find_node_by_path);
|
||||
extern rwlock_t devtree_lock; /* temporary while merging */
|
||||
|
||||
struct device_node *of_find_node_by_phandle(phandle handle)
|
||||
{
|
||||
|
@ -105,81 +41,6 @@ struct device_node *of_find_node_by_phandle(phandle handle)
|
|||
}
|
||||
EXPORT_SYMBOL(of_find_node_by_phandle);
|
||||
|
||||
struct device_node *of_find_node_by_name(struct device_node *from,
|
||||
const char *name)
|
||||
{
|
||||
struct device_node *np;
|
||||
|
||||
np = from ? from->allnext : allnodes;
|
||||
for (; np != NULL; np = np->allnext)
|
||||
if (np->name != NULL && strcmp(np->name, name) == 0)
|
||||
break;
|
||||
|
||||
return np;
|
||||
}
|
||||
EXPORT_SYMBOL(of_find_node_by_name);
|
||||
|
||||
struct device_node *of_find_node_by_type(struct device_node *from,
|
||||
const char *type)
|
||||
{
|
||||
struct device_node *np;
|
||||
|
||||
np = from ? from->allnext : allnodes;
|
||||
for (; np != 0; np = np->allnext)
|
||||
if (np->type != 0 && strcmp(np->type, type) == 0)
|
||||
break;
|
||||
|
||||
return np;
|
||||
}
|
||||
EXPORT_SYMBOL(of_find_node_by_type);
|
||||
|
||||
struct device_node *of_find_compatible_node(struct device_node *from,
|
||||
const char *type, const char *compatible)
|
||||
{
|
||||
struct device_node *np;
|
||||
|
||||
np = from ? from->allnext : allnodes;
|
||||
for (; np != 0; np = np->allnext) {
|
||||
if (type != NULL
|
||||
&& !(np->type != 0 && strcmp(np->type, type) == 0))
|
||||
continue;
|
||||
if (of_device_is_compatible(np, compatible))
|
||||
break;
|
||||
}
|
||||
|
||||
return np;
|
||||
}
|
||||
EXPORT_SYMBOL(of_find_compatible_node);
|
||||
|
||||
struct property *of_find_property(const struct device_node *np,
|
||||
const char *name,
|
||||
int *lenp)
|
||||
{
|
||||
struct property *pp;
|
||||
|
||||
for (pp = np->properties; pp != 0; pp = pp->next) {
|
||||
if (strcasecmp(pp->name, name) == 0) {
|
||||
if (lenp != 0)
|
||||
*lenp = pp->length;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return pp;
|
||||
}
|
||||
EXPORT_SYMBOL(of_find_property);
|
||||
|
||||
/*
|
||||
* Find a property with a given name for a given node
|
||||
* and return the value.
|
||||
*/
|
||||
const void *of_get_property(const struct device_node *np, const char *name,
|
||||
int *lenp)
|
||||
{
|
||||
struct property *pp = of_find_property(np,name,lenp);
|
||||
return pp ? pp->value : NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(of_get_property);
|
||||
|
||||
int of_getintprop_default(struct device_node *np, const char *name, int def)
|
||||
{
|
||||
struct property *prop;
|
||||
|
@ -193,36 +54,6 @@ int of_getintprop_default(struct device_node *np, const char *name, int def)
|
|||
}
|
||||
EXPORT_SYMBOL(of_getintprop_default);
|
||||
|
||||
int of_n_addr_cells(struct device_node *np)
|
||||
{
|
||||
const int* ip;
|
||||
do {
|
||||
if (np->parent)
|
||||
np = np->parent;
|
||||
ip = of_get_property(np, "#address-cells", NULL);
|
||||
if (ip != NULL)
|
||||
return *ip;
|
||||
} while (np->parent);
|
||||
/* No #address-cells property for the root node, default to 2 */
|
||||
return 2;
|
||||
}
|
||||
EXPORT_SYMBOL(of_n_addr_cells);
|
||||
|
||||
int of_n_size_cells(struct device_node *np)
|
||||
{
|
||||
const int* ip;
|
||||
do {
|
||||
if (np->parent)
|
||||
np = np->parent;
|
||||
ip = of_get_property(np, "#size-cells", NULL);
|
||||
if (ip != NULL)
|
||||
return *ip;
|
||||
} while (np->parent);
|
||||
/* No #size-cells property for the root node, default to 1 */
|
||||
return 1;
|
||||
}
|
||||
EXPORT_SYMBOL(of_n_size_cells);
|
||||
|
||||
int of_set_property(struct device_node *dp, const char *name, void *val, int len)
|
||||
{
|
||||
struct property **prevp;
|
||||
|
|
|
@ -354,7 +354,7 @@ static struct of_platform_driver clock_driver = {
|
|||
/* Probe for the mostek real time clock chip. */
|
||||
static int __init clock_init(void)
|
||||
{
|
||||
return of_register_driver(&clock_driver, &of_bus_type);
|
||||
return of_register_driver(&clock_driver, &of_platform_bus_type);
|
||||
}
|
||||
|
||||
/* Must be after subsys_initcall() so that busses are probed. Must
|
||||
|
|
|
@ -65,6 +65,9 @@ config AUDIT_ARCH
|
|||
config ARCH_NO_VIRT_TO_BUS
|
||||
def_bool y
|
||||
|
||||
config OF
|
||||
def_bool y
|
||||
|
||||
choice
|
||||
prompt "Kernel page size"
|
||||
default SPARC64_PAGE_SIZE_8KB
|
||||
|
|
|
@ -155,7 +155,7 @@ static struct of_platform_driver auxio_driver = {
|
|||
|
||||
static int __init auxio_init(void)
|
||||
{
|
||||
return of_register_driver(&auxio_driver, &of_bus_type);
|
||||
return of_register_driver(&auxio_driver, &of_platform_bus_type);
|
||||
}
|
||||
|
||||
/* Must be after subsys_initcall() so that busses are probed. Must
|
||||
|
|
|
@ -1,132 +1,13 @@
|
|||
#include <linux/string.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <asm/errno.h>
|
||||
#include <asm/of_device.h>
|
||||
|
||||
/**
|
||||
* of_match_device - Tell if an of_device structure has a matching
|
||||
* of_match structure
|
||||
* @ids: array of of device match structures to search in
|
||||
* @dev: the of device structure to match against
|
||||
*
|
||||
* Used by a driver to check whether an of_device present in the
|
||||
* system is in its list of supported devices.
|
||||
*/
|
||||
const struct of_device_id *of_match_device(const struct of_device_id *matches,
|
||||
const struct of_device *dev)
|
||||
{
|
||||
if (!dev->node)
|
||||
return NULL;
|
||||
while (matches->name[0] || matches->type[0] || matches->compatible[0]) {
|
||||
int match = 1;
|
||||
if (matches->name[0])
|
||||
match &= dev->node->name
|
||||
&& !strcmp(matches->name, dev->node->name);
|
||||
if (matches->type[0])
|
||||
match &= dev->node->type
|
||||
&& !strcmp(matches->type, dev->node->type);
|
||||
if (matches->compatible[0])
|
||||
match &= of_device_is_compatible(dev->node,
|
||||
matches->compatible);
|
||||
if (match)
|
||||
return matches;
|
||||
matches++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int of_platform_bus_match(struct device *dev, struct device_driver *drv)
|
||||
{
|
||||
struct of_device * of_dev = to_of_device(dev);
|
||||
struct of_platform_driver * of_drv = to_of_platform_driver(drv);
|
||||
const struct of_device_id * matches = of_drv->match_table;
|
||||
|
||||
if (!matches)
|
||||
return 0;
|
||||
|
||||
return of_match_device(matches, of_dev) != NULL;
|
||||
}
|
||||
|
||||
struct of_device *of_dev_get(struct of_device *dev)
|
||||
{
|
||||
struct device *tmp;
|
||||
|
||||
if (!dev)
|
||||
return NULL;
|
||||
tmp = get_device(&dev->dev);
|
||||
if (tmp)
|
||||
return to_of_device(tmp);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void of_dev_put(struct of_device *dev)
|
||||
{
|
||||
if (dev)
|
||||
put_device(&dev->dev);
|
||||
}
|
||||
|
||||
|
||||
static int of_device_probe(struct device *dev)
|
||||
{
|
||||
int error = -ENODEV;
|
||||
struct of_platform_driver *drv;
|
||||
struct of_device *of_dev;
|
||||
const struct of_device_id *match;
|
||||
|
||||
drv = to_of_platform_driver(dev->driver);
|
||||
of_dev = to_of_device(dev);
|
||||
|
||||
if (!drv->probe)
|
||||
return error;
|
||||
|
||||
of_dev_get(of_dev);
|
||||
|
||||
match = of_match_device(drv->match_table, of_dev);
|
||||
if (match)
|
||||
error = drv->probe(of_dev, match);
|
||||
if (error)
|
||||
of_dev_put(of_dev);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
static int of_device_remove(struct device *dev)
|
||||
{
|
||||
struct of_device * of_dev = to_of_device(dev);
|
||||
struct of_platform_driver * drv = to_of_platform_driver(dev->driver);
|
||||
|
||||
if (dev->driver && drv->remove)
|
||||
drv->remove(of_dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int of_device_suspend(struct device *dev, pm_message_t state)
|
||||
{
|
||||
struct of_device * of_dev = to_of_device(dev);
|
||||
struct of_platform_driver * drv = to_of_platform_driver(dev->driver);
|
||||
int error = 0;
|
||||
|
||||
if (dev->driver && drv->suspend)
|
||||
error = drv->suspend(of_dev, state);
|
||||
return error;
|
||||
}
|
||||
|
||||
static int of_device_resume(struct device * dev)
|
||||
{
|
||||
struct of_device * of_dev = to_of_device(dev);
|
||||
struct of_platform_driver * drv = to_of_platform_driver(dev->driver);
|
||||
int error = 0;
|
||||
|
||||
if (dev->driver && drv->resume)
|
||||
error = drv->resume(of_dev);
|
||||
return error;
|
||||
}
|
||||
#include <linux/errno.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of_platform.h>
|
||||
|
||||
void __iomem *of_ioremap(struct resource *res, unsigned long offset, unsigned long size, char *name)
|
||||
{
|
||||
|
@ -163,7 +44,7 @@ static int node_match(struct device *dev, void *data)
|
|||
|
||||
struct of_device *of_find_device_by_node(struct device_node *dp)
|
||||
{
|
||||
struct device *dev = bus_find_device(&of_bus_type, NULL,
|
||||
struct device *dev = bus_find_device(&of_platform_bus_type, NULL,
|
||||
dp, node_match);
|
||||
|
||||
if (dev)
|
||||
|
@ -174,48 +55,20 @@ struct of_device *of_find_device_by_node(struct device_node *dp)
|
|||
EXPORT_SYMBOL(of_find_device_by_node);
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
struct bus_type isa_bus_type = {
|
||||
.name = "isa",
|
||||
.match = of_platform_bus_match,
|
||||
.probe = of_device_probe,
|
||||
.remove = of_device_remove,
|
||||
.suspend = of_device_suspend,
|
||||
.resume = of_device_resume,
|
||||
};
|
||||
struct bus_type isa_bus_type;
|
||||
EXPORT_SYMBOL(isa_bus_type);
|
||||
|
||||
struct bus_type ebus_bus_type = {
|
||||
.name = "ebus",
|
||||
.match = of_platform_bus_match,
|
||||
.probe = of_device_probe,
|
||||
.remove = of_device_remove,
|
||||
.suspend = of_device_suspend,
|
||||
.resume = of_device_resume,
|
||||
};
|
||||
struct bus_type ebus_bus_type;
|
||||
EXPORT_SYMBOL(ebus_bus_type);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SBUS
|
||||
struct bus_type sbus_bus_type = {
|
||||
.name = "sbus",
|
||||
.match = of_platform_bus_match,
|
||||
.probe = of_device_probe,
|
||||
.remove = of_device_remove,
|
||||
.suspend = of_device_suspend,
|
||||
.resume = of_device_resume,
|
||||
};
|
||||
struct bus_type sbus_bus_type;
|
||||
EXPORT_SYMBOL(sbus_bus_type);
|
||||
#endif
|
||||
|
||||
struct bus_type of_bus_type = {
|
||||
.name = "of",
|
||||
.match = of_platform_bus_match,
|
||||
.probe = of_device_probe,
|
||||
.remove = of_device_remove,
|
||||
.suspend = of_device_suspend,
|
||||
.resume = of_device_resume,
|
||||
};
|
||||
EXPORT_SYMBOL(of_bus_type);
|
||||
struct bus_type of_platform_bus_type;
|
||||
EXPORT_SYMBOL(of_platform_bus_type);
|
||||
|
||||
static inline u64 of_read_addr(const u32 *cell, int size)
|
||||
{
|
||||
|
@ -933,7 +786,7 @@ static struct of_device * __init scan_one_device(struct device_node *dp,
|
|||
op->irqs[i] = build_one_device_irq(op, parent, op->irqs[i]);
|
||||
|
||||
op->dev.parent = parent;
|
||||
op->dev.bus = &of_bus_type;
|
||||
op->dev.bus = &of_platform_bus_type;
|
||||
if (!parent)
|
||||
strcpy(op->dev.bus_id, "root");
|
||||
else
|
||||
|
@ -977,16 +830,16 @@ static int __init of_bus_driver_init(void)
|
|||
{
|
||||
int err;
|
||||
|
||||
err = bus_register(&of_bus_type);
|
||||
err = of_bus_type_init(&of_platform_bus_type, "of");
|
||||
#ifdef CONFIG_PCI
|
||||
if (!err)
|
||||
err = bus_register(&isa_bus_type);
|
||||
err = of_bus_type_init(&isa_bus_type, "isa");
|
||||
if (!err)
|
||||
err = bus_register(&ebus_bus_type);
|
||||
err = of_bus_type_init(&ebus_bus_type, "ebus");
|
||||
#endif
|
||||
#ifdef CONFIG_SBUS
|
||||
if (!err)
|
||||
err = bus_register(&sbus_bus_type);
|
||||
err = of_bus_type_init(&sbus_bus_type, "sbus");
|
||||
#endif
|
||||
|
||||
if (!err)
|
||||
|
@ -1020,61 +873,13 @@ int of_register_driver(struct of_platform_driver *drv, struct bus_type *bus)
|
|||
/* register with core */
|
||||
return driver_register(&drv->driver);
|
||||
}
|
||||
EXPORT_SYMBOL(of_register_driver);
|
||||
|
||||
void of_unregister_driver(struct of_platform_driver *drv)
|
||||
{
|
||||
driver_unregister(&drv->driver);
|
||||
}
|
||||
|
||||
|
||||
static ssize_t dev_show_devspec(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct of_device *ofdev;
|
||||
|
||||
ofdev = to_of_device(dev);
|
||||
return sprintf(buf, "%s", ofdev->node->full_name);
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(devspec, S_IRUGO, dev_show_devspec, NULL);
|
||||
|
||||
/**
|
||||
* of_release_dev - free an of device structure when all users of it are finished.
|
||||
* @dev: device that's been disconnected
|
||||
*
|
||||
* Will be called only by the device core when all users of this of device are
|
||||
* done.
|
||||
*/
|
||||
void of_release_dev(struct device *dev)
|
||||
{
|
||||
struct of_device *ofdev;
|
||||
|
||||
ofdev = to_of_device(dev);
|
||||
|
||||
kfree(ofdev);
|
||||
}
|
||||
|
||||
int of_device_register(struct of_device *ofdev)
|
||||
{
|
||||
int rc;
|
||||
|
||||
BUG_ON(ofdev->node == NULL);
|
||||
|
||||
rc = device_register(&ofdev->dev);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = device_create_file(&ofdev->dev, &dev_attr_devspec);
|
||||
if (rc)
|
||||
device_unregister(&ofdev->dev);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void of_device_unregister(struct of_device *ofdev)
|
||||
{
|
||||
device_remove_file(&ofdev->dev, &dev_attr_devspec);
|
||||
device_unregister(&ofdev->dev);
|
||||
}
|
||||
EXPORT_SYMBOL(of_unregister_driver);
|
||||
|
||||
struct of_device* of_platform_device_create(struct device_node *np,
|
||||
const char *bus_id,
|
||||
|
@ -1100,13 +905,4 @@ struct of_device* of_platform_device_create(struct device_node *np,
|
|||
|
||||
return dev;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(of_match_device);
|
||||
EXPORT_SYMBOL(of_register_driver);
|
||||
EXPORT_SYMBOL(of_unregister_driver);
|
||||
EXPORT_SYMBOL(of_device_register);
|
||||
EXPORT_SYMBOL(of_device_unregister);
|
||||
EXPORT_SYMBOL(of_dev_get);
|
||||
EXPORT_SYMBOL(of_dev_put);
|
||||
EXPORT_SYMBOL(of_platform_device_create);
|
||||
EXPORT_SYMBOL(of_release_dev);
|
||||
|
|
|
@ -112,6 +112,6 @@ static struct of_platform_driver power_driver = {
|
|||
|
||||
void __init power_init(void)
|
||||
{
|
||||
of_register_driver(&power_driver, &of_bus_type);
|
||||
of_register_driver(&power_driver, &of_platform_bus_type);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -30,73 +30,9 @@
|
|||
#include <asm/upa.h>
|
||||
#include <asm/smp.h>
|
||||
|
||||
static struct device_node *allnodes;
|
||||
extern struct device_node *allnodes; /* temporary while merging */
|
||||
|
||||
/* use when traversing tree through the allnext, child, sibling,
|
||||
* or parent members of struct device_node.
|
||||
*/
|
||||
static DEFINE_RWLOCK(devtree_lock);
|
||||
|
||||
int of_device_is_compatible(const struct device_node *device,
|
||||
const char *compat)
|
||||
{
|
||||
const char* cp;
|
||||
int cplen, l;
|
||||
|
||||
cp = of_get_property(device, "compatible", &cplen);
|
||||
if (cp == NULL)
|
||||
return 0;
|
||||
while (cplen > 0) {
|
||||
if (strncmp(cp, compat, strlen(compat)) == 0)
|
||||
return 1;
|
||||
l = strlen(cp) + 1;
|
||||
cp += l;
|
||||
cplen -= l;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(of_device_is_compatible);
|
||||
|
||||
struct device_node *of_get_parent(const struct device_node *node)
|
||||
{
|
||||
struct device_node *np;
|
||||
|
||||
if (!node)
|
||||
return NULL;
|
||||
|
||||
np = node->parent;
|
||||
|
||||
return np;
|
||||
}
|
||||
EXPORT_SYMBOL(of_get_parent);
|
||||
|
||||
struct device_node *of_get_next_child(const struct device_node *node,
|
||||
struct device_node *prev)
|
||||
{
|
||||
struct device_node *next;
|
||||
|
||||
next = prev ? prev->sibling : node->child;
|
||||
for (; next != 0; next = next->sibling) {
|
||||
break;
|
||||
}
|
||||
|
||||
return next;
|
||||
}
|
||||
EXPORT_SYMBOL(of_get_next_child);
|
||||
|
||||
struct device_node *of_find_node_by_path(const char *path)
|
||||
{
|
||||
struct device_node *np = allnodes;
|
||||
|
||||
for (; np != 0; np = np->allnext) {
|
||||
if (np->full_name != 0 && strcmp(np->full_name, path) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
return np;
|
||||
}
|
||||
EXPORT_SYMBOL(of_find_node_by_path);
|
||||
extern rwlock_t devtree_lock; /* temporary while merging */
|
||||
|
||||
struct device_node *of_find_node_by_phandle(phandle handle)
|
||||
{
|
||||
|
@ -110,81 +46,6 @@ struct device_node *of_find_node_by_phandle(phandle handle)
|
|||
}
|
||||
EXPORT_SYMBOL(of_find_node_by_phandle);
|
||||
|
||||
struct device_node *of_find_node_by_name(struct device_node *from,
|
||||
const char *name)
|
||||
{
|
||||
struct device_node *np;
|
||||
|
||||
np = from ? from->allnext : allnodes;
|
||||
for (; np != NULL; np = np->allnext)
|
||||
if (np->name != NULL && strcmp(np->name, name) == 0)
|
||||
break;
|
||||
|
||||
return np;
|
||||
}
|
||||
EXPORT_SYMBOL(of_find_node_by_name);
|
||||
|
||||
struct device_node *of_find_node_by_type(struct device_node *from,
|
||||
const char *type)
|
||||
{
|
||||
struct device_node *np;
|
||||
|
||||
np = from ? from->allnext : allnodes;
|
||||
for (; np != 0; np = np->allnext)
|
||||
if (np->type != 0 && strcmp(np->type, type) == 0)
|
||||
break;
|
||||
|
||||
return np;
|
||||
}
|
||||
EXPORT_SYMBOL(of_find_node_by_type);
|
||||
|
||||
struct device_node *of_find_compatible_node(struct device_node *from,
|
||||
const char *type, const char *compatible)
|
||||
{
|
||||
struct device_node *np;
|
||||
|
||||
np = from ? from->allnext : allnodes;
|
||||
for (; np != 0; np = np->allnext) {
|
||||
if (type != NULL
|
||||
&& !(np->type != 0 && strcmp(np->type, type) == 0))
|
||||
continue;
|
||||
if (of_device_is_compatible(np, compatible))
|
||||
break;
|
||||
}
|
||||
|
||||
return np;
|
||||
}
|
||||
EXPORT_SYMBOL(of_find_compatible_node);
|
||||
|
||||
struct property *of_find_property(const struct device_node *np,
|
||||
const char *name,
|
||||
int *lenp)
|
||||
{
|
||||
struct property *pp;
|
||||
|
||||
for (pp = np->properties; pp != 0; pp = pp->next) {
|
||||
if (strcasecmp(pp->name, name) == 0) {
|
||||
if (lenp != 0)
|
||||
*lenp = pp->length;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return pp;
|
||||
}
|
||||
EXPORT_SYMBOL(of_find_property);
|
||||
|
||||
/*
|
||||
* Find a property with a given name for a given node
|
||||
* and return the value.
|
||||
*/
|
||||
const void *of_get_property(const struct device_node *np, const char *name,
|
||||
int *lenp)
|
||||
{
|
||||
struct property *pp = of_find_property(np,name,lenp);
|
||||
return pp ? pp->value : NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(of_get_property);
|
||||
|
||||
int of_getintprop_default(struct device_node *np, const char *name, int def)
|
||||
{
|
||||
struct property *prop;
|
||||
|
@ -198,36 +59,6 @@ int of_getintprop_default(struct device_node *np, const char *name, int def)
|
|||
}
|
||||
EXPORT_SYMBOL(of_getintprop_default);
|
||||
|
||||
int of_n_addr_cells(struct device_node *np)
|
||||
{
|
||||
const int* ip;
|
||||
do {
|
||||
if (np->parent)
|
||||
np = np->parent;
|
||||
ip = of_get_property(np, "#address-cells", NULL);
|
||||
if (ip != NULL)
|
||||
return *ip;
|
||||
} while (np->parent);
|
||||
/* No #address-cells property for the root node, default to 2 */
|
||||
return 2;
|
||||
}
|
||||
EXPORT_SYMBOL(of_n_addr_cells);
|
||||
|
||||
int of_n_size_cells(struct device_node *np)
|
||||
{
|
||||
const int* ip;
|
||||
do {
|
||||
if (np->parent)
|
||||
np = np->parent;
|
||||
ip = of_get_property(np, "#size-cells", NULL);
|
||||
if (ip != NULL)
|
||||
return *ip;
|
||||
} while (np->parent);
|
||||
/* No #size-cells property for the root node, default to 1 */
|
||||
return 1;
|
||||
}
|
||||
EXPORT_SYMBOL(of_n_size_cells);
|
||||
|
||||
int of_set_property(struct device_node *dp, const char *name, void *val, int len)
|
||||
{
|
||||
struct property **prevp;
|
||||
|
|
|
@ -835,7 +835,7 @@ static int __init clock_init(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
return of_register_driver(&clock_driver, &of_bus_type);
|
||||
return of_register_driver(&clock_driver, &of_platform_bus_type);
|
||||
}
|
||||
|
||||
/* Must be after subsys_initcall() so that busses are probed. Must
|
||||
|
|
|
@ -8,6 +8,8 @@ source "drivers/connector/Kconfig"
|
|||
|
||||
source "drivers/mtd/Kconfig"
|
||||
|
||||
source "drivers/of/Kconfig"
|
||||
|
||||
source "drivers/parport/Kconfig"
|
||||
|
||||
source "drivers/pnp/Kconfig"
|
||||
|
|
|
@ -86,3 +86,4 @@ obj-$(CONFIG_GENERIC_TIME) += clocksource/
|
|||
obj-$(CONFIG_DMA_ENGINE) += dma/
|
||||
obj-$(CONFIG_HID) += hid/
|
||||
obj-$(CONFIG_PPC_PS3) += ps3/
|
||||
obj-$(CONFIG_OF) += of/
|
||||
|
|
3
drivers/of/Kconfig
Normal file
3
drivers/of/Kconfig
Normal file
|
@ -0,0 +1,3 @@
|
|||
config OF_DEVICE
|
||||
def_bool y
|
||||
depends on OF && (SPARC || PPC_OF)
|
2
drivers/of/Makefile
Normal file
2
drivers/of/Makefile
Normal file
|
@ -0,0 +1,2 @@
|
|||
obj-y = base.o
|
||||
obj-$(CONFIG_OF_DEVICE) += device.o platform.o
|
275
drivers/of/base.c
Normal file
275
drivers/of/base.c
Normal file
|
@ -0,0 +1,275 @@
|
|||
/*
|
||||
* Procedures for creating, accessing and interpreting the device tree.
|
||||
*
|
||||
* Paul Mackerras August 1996.
|
||||
* Copyright (C) 1996-2005 Paul Mackerras.
|
||||
*
|
||||
* Adapted for 64bit PowerPC by Dave Engebretsen and Peter Bergner.
|
||||
* {engebret|bergner}@us.ibm.com
|
||||
*
|
||||
* Adapted for sparc and sparc64 by David S. Miller davem@davemloft.net
|
||||
*
|
||||
* Reconsolidated from arch/x/kernel/prom.c by Stephen Rothwell.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/spinlock.h>
|
||||
|
||||
struct device_node *allnodes;
|
||||
|
||||
/* use when traversing tree through the allnext, child, sibling,
|
||||
* or parent members of struct device_node.
|
||||
*/
|
||||
DEFINE_RWLOCK(devtree_lock);
|
||||
|
||||
int of_n_addr_cells(struct device_node *np)
|
||||
{
|
||||
const int *ip;
|
||||
|
||||
do {
|
||||
if (np->parent)
|
||||
np = np->parent;
|
||||
ip = of_get_property(np, "#address-cells", NULL);
|
||||
if (ip)
|
||||
return *ip;
|
||||
} while (np->parent);
|
||||
/* No #address-cells property for the root node */
|
||||
return OF_ROOT_NODE_ADDR_CELLS_DEFAULT;
|
||||
}
|
||||
EXPORT_SYMBOL(of_n_addr_cells);
|
||||
|
||||
int of_n_size_cells(struct device_node *np)
|
||||
{
|
||||
const int *ip;
|
||||
|
||||
do {
|
||||
if (np->parent)
|
||||
np = np->parent;
|
||||
ip = of_get_property(np, "#size-cells", NULL);
|
||||
if (ip)
|
||||
return *ip;
|
||||
} while (np->parent);
|
||||
/* No #size-cells property for the root node */
|
||||
return OF_ROOT_NODE_SIZE_CELLS_DEFAULT;
|
||||
}
|
||||
EXPORT_SYMBOL(of_n_size_cells);
|
||||
|
||||
struct property *of_find_property(const struct device_node *np,
|
||||
const char *name,
|
||||
int *lenp)
|
||||
{
|
||||
struct property *pp;
|
||||
|
||||
read_lock(&devtree_lock);
|
||||
for (pp = np->properties; pp != 0; pp = pp->next) {
|
||||
if (of_prop_cmp(pp->name, name) == 0) {
|
||||
if (lenp != 0)
|
||||
*lenp = pp->length;
|
||||
break;
|
||||
}
|
||||
}
|
||||
read_unlock(&devtree_lock);
|
||||
|
||||
return pp;
|
||||
}
|
||||
EXPORT_SYMBOL(of_find_property);
|
||||
|
||||
/*
|
||||
* Find a property with a given name for a given node
|
||||
* and return the value.
|
||||
*/
|
||||
const void *of_get_property(const struct device_node *np, const char *name,
|
||||
int *lenp)
|
||||
{
|
||||
struct property *pp = of_find_property(np, name, lenp);
|
||||
|
||||
return pp ? pp->value : NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(of_get_property);
|
||||
|
||||
/** Checks if the given "compat" string matches one of the strings in
|
||||
* the device's "compatible" property
|
||||
*/
|
||||
int of_device_is_compatible(const struct device_node *device,
|
||||
const char *compat)
|
||||
{
|
||||
const char* cp;
|
||||
int cplen, l;
|
||||
|
||||
cp = of_get_property(device, "compatible", &cplen);
|
||||
if (cp == NULL)
|
||||
return 0;
|
||||
while (cplen > 0) {
|
||||
if (of_compat_cmp(cp, compat, strlen(compat)) == 0)
|
||||
return 1;
|
||||
l = strlen(cp) + 1;
|
||||
cp += l;
|
||||
cplen -= l;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(of_device_is_compatible);
|
||||
|
||||
/**
|
||||
* of_get_parent - Get a node's parent if any
|
||||
* @node: Node to get parent
|
||||
*
|
||||
* Returns a node pointer with refcount incremented, use
|
||||
* of_node_put() on it when done.
|
||||
*/
|
||||
struct device_node *of_get_parent(const struct device_node *node)
|
||||
{
|
||||
struct device_node *np;
|
||||
|
||||
if (!node)
|
||||
return NULL;
|
||||
|
||||
read_lock(&devtree_lock);
|
||||
np = of_node_get(node->parent);
|
||||
read_unlock(&devtree_lock);
|
||||
return np;
|
||||
}
|
||||
EXPORT_SYMBOL(of_get_parent);
|
||||
|
||||
/**
|
||||
* of_get_next_child - Iterate a node childs
|
||||
* @node: parent node
|
||||
* @prev: previous child of the parent node, or NULL to get first
|
||||
*
|
||||
* Returns a node pointer with refcount incremented, use
|
||||
* of_node_put() on it when done.
|
||||
*/
|
||||
struct device_node *of_get_next_child(const struct device_node *node,
|
||||
struct device_node *prev)
|
||||
{
|
||||
struct device_node *next;
|
||||
|
||||
read_lock(&devtree_lock);
|
||||
next = prev ? prev->sibling : node->child;
|
||||
for (; next; next = next->sibling)
|
||||
if (of_node_get(next))
|
||||
break;
|
||||
of_node_put(prev);
|
||||
read_unlock(&devtree_lock);
|
||||
return next;
|
||||
}
|
||||
EXPORT_SYMBOL(of_get_next_child);
|
||||
|
||||
/**
|
||||
* of_find_node_by_path - Find a node matching a full OF path
|
||||
* @path: The full path to match
|
||||
*
|
||||
* Returns a node pointer with refcount incremented, use
|
||||
* of_node_put() on it when done.
|
||||
*/
|
||||
struct device_node *of_find_node_by_path(const char *path)
|
||||
{
|
||||
struct device_node *np = allnodes;
|
||||
|
||||
read_lock(&devtree_lock);
|
||||
for (; np; np = np->allnext) {
|
||||
if (np->full_name && (of_node_cmp(np->full_name, path) == 0)
|
||||
&& of_node_get(np))
|
||||
break;
|
||||
}
|
||||
read_unlock(&devtree_lock);
|
||||
return np;
|
||||
}
|
||||
EXPORT_SYMBOL(of_find_node_by_path);
|
||||
|
||||
/**
|
||||
* of_find_node_by_name - Find a node by its "name" property
|
||||
* @from: 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
|
||||
* @name: The name string to match against
|
||||
*
|
||||
* Returns a node pointer with refcount incremented, use
|
||||
* of_node_put() on it when done.
|
||||
*/
|
||||
struct device_node *of_find_node_by_name(struct device_node *from,
|
||||
const char *name)
|
||||
{
|
||||
struct device_node *np;
|
||||
|
||||
read_lock(&devtree_lock);
|
||||
np = from ? from->allnext : allnodes;
|
||||
for (; np; np = np->allnext)
|
||||
if (np->name && (of_node_cmp(np->name, name) == 0)
|
||||
&& of_node_get(np))
|
||||
break;
|
||||
of_node_put(from);
|
||||
read_unlock(&devtree_lock);
|
||||
return np;
|
||||
}
|
||||
EXPORT_SYMBOL(of_find_node_by_name);
|
||||
|
||||
/**
|
||||
* of_find_node_by_type - Find a node by its "device_type" property
|
||||
* @from: The node to start searching from, or NULL to start searching
|
||||
* the entire device tree. 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 from for you.
|
||||
* @type: The type string to match against
|
||||
*
|
||||
* Returns a node pointer with refcount incremented, use
|
||||
* of_node_put() on it when done.
|
||||
*/
|
||||
struct device_node *of_find_node_by_type(struct device_node *from,
|
||||
const char *type)
|
||||
{
|
||||
struct device_node *np;
|
||||
|
||||
read_lock(&devtree_lock);
|
||||
np = from ? from->allnext : allnodes;
|
||||
for (; np; np = np->allnext)
|
||||
if (np->type && (of_node_cmp(np->type, type) == 0)
|
||||
&& of_node_get(np))
|
||||
break;
|
||||
of_node_put(from);
|
||||
read_unlock(&devtree_lock);
|
||||
return np;
|
||||
}
|
||||
EXPORT_SYMBOL(of_find_node_by_type);
|
||||
|
||||
/**
|
||||
* of_find_compatible_node - Find a node based on type and one of the
|
||||
* tokens in its "compatible" property
|
||||
* @from: 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 refcount incremented, use
|
||||
* of_node_put() on it when done.
|
||||
*/
|
||||
struct device_node *of_find_compatible_node(struct device_node *from,
|
||||
const char *type, const char *compatible)
|
||||
{
|
||||
struct device_node *np;
|
||||
|
||||
read_lock(&devtree_lock);
|
||||
np = from ? from->allnext : allnodes;
|
||||
for (; np; np = np->allnext) {
|
||||
if (type
|
||||
&& !(np->type && (of_node_cmp(np->type, type) == 0)))
|
||||
continue;
|
||||
if (of_device_is_compatible(np, compatible) && of_node_get(np))
|
||||
break;
|
||||
}
|
||||
of_node_put(from);
|
||||
read_unlock(&devtree_lock);
|
||||
return np;
|
||||
}
|
||||
EXPORT_SYMBOL(of_find_compatible_node);
|
131
drivers/of/device.c
Normal file
131
drivers/of/device.c
Normal file
|
@ -0,0 +1,131 @@
|
|||
#include <linux/string.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <asm/errno.h>
|
||||
|
||||
/**
|
||||
* of_match_node - Tell if an device_node has a matching of_match structure
|
||||
* @ids: array of of device match structures to search in
|
||||
* @node: the of device structure to match against
|
||||
*
|
||||
* Low level utility function used by device matching.
|
||||
*/
|
||||
const struct of_device_id *of_match_node(const struct of_device_id *matches,
|
||||
const struct device_node *node)
|
||||
{
|
||||
while (matches->name[0] || matches->type[0] || matches->compatible[0]) {
|
||||
int match = 1;
|
||||
if (matches->name[0])
|
||||
match &= node->name
|
||||
&& !strcmp(matches->name, node->name);
|
||||
if (matches->type[0])
|
||||
match &= node->type
|
||||
&& !strcmp(matches->type, node->type);
|
||||
if (matches->compatible[0])
|
||||
match &= of_device_is_compatible(node,
|
||||
matches->compatible);
|
||||
if (match)
|
||||
return matches;
|
||||
matches++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(of_match_node);
|
||||
|
||||
/**
|
||||
* of_match_device - Tell if an of_device structure has a matching
|
||||
* of_match structure
|
||||
* @ids: array of of device match structures to search in
|
||||
* @dev: the of device structure to match against
|
||||
*
|
||||
* Used by a driver to check whether an of_device present in the
|
||||
* system is in its list of supported devices.
|
||||
*/
|
||||
const struct of_device_id *of_match_device(const struct of_device_id *matches,
|
||||
const struct of_device *dev)
|
||||
{
|
||||
if (!dev->node)
|
||||
return NULL;
|
||||
return of_match_node(matches, dev->node);
|
||||
}
|
||||
EXPORT_SYMBOL(of_match_device);
|
||||
|
||||
struct of_device *of_dev_get(struct of_device *dev)
|
||||
{
|
||||
struct device *tmp;
|
||||
|
||||
if (!dev)
|
||||
return NULL;
|
||||
tmp = get_device(&dev->dev);
|
||||
if (tmp)
|
||||
return to_of_device(tmp);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(of_dev_get);
|
||||
|
||||
void of_dev_put(struct of_device *dev)
|
||||
{
|
||||
if (dev)
|
||||
put_device(&dev->dev);
|
||||
}
|
||||
EXPORT_SYMBOL(of_dev_put);
|
||||
|
||||
static ssize_t dev_show_devspec(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct of_device *ofdev;
|
||||
|
||||
ofdev = to_of_device(dev);
|
||||
return sprintf(buf, "%s", ofdev->node->full_name);
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(devspec, S_IRUGO, dev_show_devspec, NULL);
|
||||
|
||||
/**
|
||||
* of_release_dev - free an of device structure when all users of it are finished.
|
||||
* @dev: device that's been disconnected
|
||||
*
|
||||
* Will be called only by the device core when all users of this of device are
|
||||
* done.
|
||||
*/
|
||||
void of_release_dev(struct device *dev)
|
||||
{
|
||||
struct of_device *ofdev;
|
||||
|
||||
ofdev = to_of_device(dev);
|
||||
of_node_put(ofdev->node);
|
||||
kfree(ofdev);
|
||||
}
|
||||
EXPORT_SYMBOL(of_release_dev);
|
||||
|
||||
int of_device_register(struct of_device *ofdev)
|
||||
{
|
||||
int rc;
|
||||
|
||||
BUG_ON(ofdev->node == NULL);
|
||||
|
||||
rc = device_register(&ofdev->dev);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = device_create_file(&ofdev->dev, &dev_attr_devspec);
|
||||
if (rc)
|
||||
device_unregister(&ofdev->dev);
|
||||
|
||||
return rc;
|
||||
}
|
||||
EXPORT_SYMBOL(of_device_register);
|
||||
|
||||
void of_device_unregister(struct of_device *ofdev)
|
||||
{
|
||||
device_remove_file(&ofdev->dev, &dev_attr_devspec);
|
||||
device_unregister(&ofdev->dev);
|
||||
}
|
||||
EXPORT_SYMBOL(of_device_unregister);
|
96
drivers/of/platform.c
Normal file
96
drivers/of/platform.c
Normal file
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
* Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp.
|
||||
* <benh@kernel.crashing.org>
|
||||
* and Arnd Bergmann, IBM Corp.
|
||||
* Merged from powerpc/kernel/of_platform.c and
|
||||
* sparc{,64}/kernel/of_device.c by Stephen Rothwell
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
#include <linux/errno.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of_platform.h>
|
||||
|
||||
static int of_platform_bus_match(struct device *dev, struct device_driver *drv)
|
||||
{
|
||||
struct of_device *of_dev = to_of_device(dev);
|
||||
struct of_platform_driver *of_drv = to_of_platform_driver(drv);
|
||||
const struct of_device_id *matches = of_drv->match_table;
|
||||
|
||||
if (!matches)
|
||||
return 0;
|
||||
|
||||
return of_match_device(matches, of_dev) != NULL;
|
||||
}
|
||||
|
||||
static int of_platform_device_probe(struct device *dev)
|
||||
{
|
||||
int error = -ENODEV;
|
||||
struct of_platform_driver *drv;
|
||||
struct of_device *of_dev;
|
||||
const struct of_device_id *match;
|
||||
|
||||
drv = to_of_platform_driver(dev->driver);
|
||||
of_dev = to_of_device(dev);
|
||||
|
||||
if (!drv->probe)
|
||||
return error;
|
||||
|
||||
of_dev_get(of_dev);
|
||||
|
||||
match = of_match_device(drv->match_table, of_dev);
|
||||
if (match)
|
||||
error = drv->probe(of_dev, match);
|
||||
if (error)
|
||||
of_dev_put(of_dev);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
static int of_platform_device_remove(struct device *dev)
|
||||
{
|
||||
struct of_device *of_dev = to_of_device(dev);
|
||||
struct of_platform_driver *drv = to_of_platform_driver(dev->driver);
|
||||
|
||||
if (dev->driver && drv->remove)
|
||||
drv->remove(of_dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int of_platform_device_suspend(struct device *dev, pm_message_t state)
|
||||
{
|
||||
struct of_device *of_dev = to_of_device(dev);
|
||||
struct of_platform_driver *drv = to_of_platform_driver(dev->driver);
|
||||
int error = 0;
|
||||
|
||||
if (dev->driver && drv->suspend)
|
||||
error = drv->suspend(of_dev, state);
|
||||
return error;
|
||||
}
|
||||
|
||||
static int of_platform_device_resume(struct device * dev)
|
||||
{
|
||||
struct of_device *of_dev = to_of_device(dev);
|
||||
struct of_platform_driver *drv = to_of_platform_driver(dev->driver);
|
||||
int error = 0;
|
||||
|
||||
if (dev->driver && drv->resume)
|
||||
error = drv->resume(of_dev);
|
||||
return error;
|
||||
}
|
||||
|
||||
int of_bus_type_init(struct bus_type *bus, const char *name)
|
||||
{
|
||||
bus->name = name;
|
||||
bus->match = of_platform_bus_match;
|
||||
bus->probe = of_platform_device_probe;
|
||||
bus->remove = of_platform_device_remove;
|
||||
bus->suspend = of_platform_device_suspend;
|
||||
bus->resume = of_platform_device_resume;
|
||||
return bus_register(bus);
|
||||
}
|
|
@ -3,14 +3,12 @@
|
|||
#ifdef __KERNEL__
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <asm/prom.h>
|
||||
|
||||
#include <linux/of.h>
|
||||
|
||||
/*
|
||||
* The of_device is a kind of "base class" that is a superset of
|
||||
* struct device for use by devices attached to an OF node and
|
||||
* probed using OF properties
|
||||
* probed using OF properties.
|
||||
*/
|
||||
struct of_device
|
||||
{
|
||||
|
@ -18,24 +16,14 @@ struct of_device
|
|||
u64 dma_mask; /* DMA mask */
|
||||
struct device dev; /* Generic device interface */
|
||||
};
|
||||
#define to_of_device(d) container_of(d, struct of_device, dev)
|
||||
|
||||
extern const struct of_device_id *of_match_node(
|
||||
const struct of_device_id *matches, const struct device_node *node);
|
||||
extern const struct of_device_id *of_match_device(
|
||||
const struct of_device_id *matches, const struct of_device *dev);
|
||||
|
||||
extern struct of_device *of_dev_get(struct of_device *dev);
|
||||
extern void of_dev_put(struct of_device *dev);
|
||||
|
||||
extern int of_device_register(struct of_device *ofdev);
|
||||
extern void of_device_unregister(struct of_device *ofdev);
|
||||
extern void of_release_dev(struct device *dev);
|
||||
|
||||
extern ssize_t of_device_get_modalias(struct of_device *ofdev,
|
||||
char *str, ssize_t len);
|
||||
extern int of_device_uevent(struct device *dev,
|
||||
char **envp, int num_envp, char *buffer, int buffer_size);
|
||||
|
||||
/* This is just here during the transition */
|
||||
#include <linux/of_device.h>
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
#endif /* _ASM_POWERPC_OF_DEVICE_H */
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#ifndef _ASM_POWERPC_OF_PLATFORM_H
|
||||
#define _ASM_POWERPC_OF_PLATFORM_H
|
||||
/*
|
||||
* Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp.
|
||||
* <benh@kernel.crashing.org>
|
||||
|
@ -9,37 +11,8 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include <asm/of_device.h>
|
||||
|
||||
/*
|
||||
* The of_platform_bus_type is a bus type used by drivers that do not
|
||||
* attach to a macio or similar bus but still use OF probing
|
||||
* mechanism
|
||||
*/
|
||||
extern struct bus_type of_platform_bus_type;
|
||||
|
||||
/*
|
||||
* An of_platform_driver driver is attached to a basic of_device on
|
||||
* the "platform bus" (of_platform_bus_type)
|
||||
*/
|
||||
struct of_platform_driver
|
||||
{
|
||||
char *name;
|
||||
struct of_device_id *match_table;
|
||||
struct module *owner;
|
||||
|
||||
int (*probe)(struct of_device* dev,
|
||||
const struct of_device_id *match);
|
||||
int (*remove)(struct of_device* dev);
|
||||
|
||||
int (*suspend)(struct of_device* dev, pm_message_t state);
|
||||
int (*resume)(struct of_device* dev);
|
||||
int (*shutdown)(struct of_device* dev);
|
||||
|
||||
struct device_driver driver;
|
||||
};
|
||||
#define to_of_platform_driver(drv) \
|
||||
container_of(drv,struct of_platform_driver, driver)
|
||||
/* This is just here during the transition */
|
||||
#include <linux/of_platform.h>
|
||||
|
||||
/* Platform drivers register/unregister */
|
||||
extern int of_register_platform_driver(struct of_platform_driver *drv);
|
||||
|
@ -56,5 +29,6 @@ extern int of_platform_bus_probe(struct device_node *root,
|
|||
struct of_device_id *matches,
|
||||
struct device *parent);
|
||||
|
||||
extern struct of_device *of_find_device_by_node(struct device_node *np);
|
||||
extern struct of_device *of_find_device_by_phandle(phandle ph);
|
||||
|
||||
#endif /* _ASM_POWERPC_OF_PLATFORM_H */
|
||||
|
|
|
@ -21,6 +21,13 @@
|
|||
#include <asm/irq.h>
|
||||
#include <asm/atomic.h>
|
||||
|
||||
#define OF_ROOT_NODE_ADDR_CELLS_DEFAULT 1
|
||||
#define OF_ROOT_NODE_SIZE_CELLS_DEFAULT 1
|
||||
|
||||
#define of_compat_cmp(s1, s2, l) strncasecmp((s1), (s2), (l))
|
||||
#define of_prop_cmp(s1, s2) strcmp((s1), (s2))
|
||||
#define of_node_cmp(s1, s2) strcasecmp((s1), (s2))
|
||||
|
||||
/* Definitions used by the flattened device tree */
|
||||
#define OF_DT_HEADER 0xd00dfeed /* marker */
|
||||
#define OF_DT_BEGIN_NODE 0x1 /* Start of node, full name */
|
||||
|
@ -97,10 +104,6 @@ struct device_node {
|
|||
|
||||
extern struct device_node *of_chosen;
|
||||
|
||||
/* flag descriptions */
|
||||
#define OF_DYNAMIC 1 /* node and properties were allocated via kmalloc */
|
||||
#define OF_DETACHED 2 /* node has been detached from the device tree */
|
||||
|
||||
static inline int of_node_check_flag(struct device_node *n, unsigned long flag)
|
||||
{
|
||||
return test_bit(flag, &n->_flags);
|
||||
|
@ -120,31 +123,7 @@ static inline void set_node_proc_entry(struct device_node *dn, struct proc_dir_e
|
|||
}
|
||||
|
||||
|
||||
/* New style node lookup */
|
||||
extern struct device_node *of_find_node_by_name(struct device_node *from,
|
||||
const char *name);
|
||||
#define for_each_node_by_name(dn, name) \
|
||||
for (dn = of_find_node_by_name(NULL, name); dn; \
|
||||
dn = of_find_node_by_name(dn, name))
|
||||
extern struct device_node *of_find_node_by_type(struct device_node *from,
|
||||
const char *type);
|
||||
#define for_each_node_by_type(dn, type) \
|
||||
for (dn = of_find_node_by_type(NULL, type); dn; \
|
||||
dn = of_find_node_by_type(dn, type))
|
||||
extern struct device_node *of_find_compatible_node(struct device_node *from,
|
||||
const char *type, const char *compat);
|
||||
#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))
|
||||
extern struct device_node *of_find_node_by_path(const char *path);
|
||||
extern struct device_node *of_find_node_by_phandle(phandle handle);
|
||||
extern struct device_node *of_find_all_nodes(struct device_node *prev);
|
||||
extern struct device_node *of_get_parent(const struct device_node *node);
|
||||
extern struct device_node *of_get_next_child(const struct device_node *node,
|
||||
struct device_node *prev);
|
||||
extern struct property *of_find_property(const struct device_node *np,
|
||||
const char *name,
|
||||
int *lenp);
|
||||
extern struct device_node *of_node_get(struct device_node *node);
|
||||
extern void of_node_put(struct device_node *node);
|
||||
|
||||
|
@ -166,17 +145,9 @@ extern void of_detach_node(const struct device_node *);
|
|||
extern void finish_device_tree(void);
|
||||
extern void unflatten_device_tree(void);
|
||||
extern void early_init_devtree(void *);
|
||||
extern int of_device_is_compatible(const struct device_node *device,
|
||||
const char *);
|
||||
#define device_is_compatible(d, c) of_device_is_compatible((d), (c))
|
||||
extern int machine_is_compatible(const char *compat);
|
||||
extern const void *of_get_property(const struct device_node *node,
|
||||
const char *name,
|
||||
int *lenp);
|
||||
#define get_property(a, b, c) of_get_property((a), (b), (c))
|
||||
extern void print_properties(struct device_node *node);
|
||||
extern int of_n_addr_cells(struct device_node* np);
|
||||
extern int of_n_size_cells(struct device_node* np);
|
||||
extern int prom_n_intr_cells(struct device_node* np);
|
||||
extern void prom_get_irq_senses(unsigned char *senses, int off, int max);
|
||||
extern int prom_add_property(struct device_node* np, struct property* prop);
|
||||
|
@ -230,7 +201,6 @@ static inline unsigned long of_read_ulong(const u32 *cell, int size)
|
|||
|
||||
/* Translate an OF address block into a CPU physical address
|
||||
*/
|
||||
#define OF_BAD_ADDR ((u64)-1)
|
||||
extern u64 of_translate_address(struct device_node *np, const u32 *addr);
|
||||
|
||||
/* Extract an address from a device, returns the region size and
|
||||
|
@ -357,5 +327,11 @@ extern int of_irq_to_resource(struct device_node *dev, int index,
|
|||
*/
|
||||
extern void __iomem *of_iomap(struct device_node *device, int index);
|
||||
|
||||
/*
|
||||
* NB: This is here while we transition from using asm/prom.h
|
||||
* to linux/of.h
|
||||
*/
|
||||
#include <linux/of.h>
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
#endif /* _POWERPC_PROM_H */
|
||||
|
|
|
@ -3,13 +3,9 @@
|
|||
#ifdef __KERNEL__
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <asm/openprom.h>
|
||||
#include <asm/prom.h>
|
||||
|
||||
extern struct bus_type ebus_bus_type;
|
||||
extern struct bus_type sbus_bus_type;
|
||||
extern struct bus_type of_bus_type;
|
||||
|
||||
/*
|
||||
* The of_device is a kind of "base class" that is a superset of
|
||||
|
@ -30,50 +26,13 @@ struct of_device
|
|||
int portid;
|
||||
int clock_freq;
|
||||
};
|
||||
#define to_of_device(d) container_of(d, struct of_device, dev)
|
||||
|
||||
extern void __iomem *of_ioremap(struct resource *res, unsigned long offset, unsigned long size, char *name);
|
||||
extern void of_iounmap(struct resource *res, void __iomem *base, unsigned long size);
|
||||
|
||||
extern struct of_device *of_find_device_by_node(struct device_node *);
|
||||
|
||||
extern const struct of_device_id *of_match_device(
|
||||
const struct of_device_id *matches, const struct of_device *dev);
|
||||
|
||||
extern struct of_device *of_dev_get(struct of_device *dev);
|
||||
extern void of_dev_put(struct of_device *dev);
|
||||
|
||||
/*
|
||||
* An of_platform_driver driver is attached to a basic of_device on
|
||||
* the ISA, EBUS, and SBUS busses on sparc64.
|
||||
*/
|
||||
struct of_platform_driver
|
||||
{
|
||||
char *name;
|
||||
struct of_device_id *match_table;
|
||||
struct module *owner;
|
||||
|
||||
int (*probe)(struct of_device* dev, const struct of_device_id *match);
|
||||
int (*remove)(struct of_device* dev);
|
||||
|
||||
int (*suspend)(struct of_device* dev, pm_message_t state);
|
||||
int (*resume)(struct of_device* dev);
|
||||
int (*shutdown)(struct of_device* dev);
|
||||
|
||||
struct device_driver driver;
|
||||
};
|
||||
#define to_of_platform_driver(drv) container_of(drv,struct of_platform_driver, driver)
|
||||
|
||||
extern int of_register_driver(struct of_platform_driver *drv,
|
||||
struct bus_type *bus);
|
||||
extern void of_unregister_driver(struct of_platform_driver *drv);
|
||||
extern int of_device_register(struct of_device *ofdev);
|
||||
extern void of_device_unregister(struct of_device *ofdev);
|
||||
extern struct of_device *of_platform_device_create(struct device_node *np,
|
||||
const char *bus_id,
|
||||
struct device *parent,
|
||||
struct bus_type *bus);
|
||||
extern void of_release_dev(struct device *dev);
|
||||
/* These are just here during the transition */
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of_platform.h>
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
#endif /* _ASM_SPARC_OF_DEVICE_H */
|
||||
|
|
32
include/asm-sparc/of_platform.h
Normal file
32
include/asm-sparc/of_platform.h
Normal file
|
@ -0,0 +1,32 @@
|
|||
#ifndef _ASM_SPARC_OF_PLATFORM_H
|
||||
#define _ASM_SPARC_OF_PLATFORM_H
|
||||
/*
|
||||
* Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp.
|
||||
* <benh@kernel.crashing.org>
|
||||
* Modified for Sparc by merging parts of asm-sparc/of_device.h
|
||||
* by Stephen Rothwell
|
||||
*
|
||||
* 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 is just here during the transition */
|
||||
#include <linux/of_platform.h>
|
||||
|
||||
extern struct bus_type ebus_bus_type;
|
||||
extern struct bus_type sbus_bus_type;
|
||||
extern struct bus_type of_platform_bus_type;
|
||||
#define of_bus_type of_platform_bus_type /* for compatibility */
|
||||
|
||||
extern int of_register_driver(struct of_platform_driver *drv,
|
||||
struct bus_type *bus);
|
||||
extern void of_unregister_driver(struct of_platform_driver *drv);
|
||||
extern struct of_device *of_platform_device_create(struct device_node *np,
|
||||
const char *bus_id,
|
||||
struct device *parent,
|
||||
struct bus_type *bus);
|
||||
|
||||
#endif /* _ASM_SPARC_OF_PLATFORM_H */
|
|
@ -2,7 +2,6 @@
|
|||
#define _SPARC_PROM_H
|
||||
#ifdef __KERNEL__
|
||||
|
||||
|
||||
/*
|
||||
* Definitions for talking to the Open Firmware PROM on
|
||||
* Power Macintosh computers.
|
||||
|
@ -17,11 +16,17 @@
|
|||
* as published by the Free Software Foundation; either version
|
||||
* 2 of the License, or (at your option) any later version.
|
||||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <asm/atomic.h>
|
||||
|
||||
#define OF_ROOT_NODE_ADDR_CELLS_DEFAULT 2
|
||||
#define OF_ROOT_NODE_SIZE_CELLS_DEFAULT 1
|
||||
|
||||
#define of_compat_cmp(s1, s2, l) strncmp((s1), (s2), (l))
|
||||
#define of_prop_cmp(s1, s2) strcasecmp((s1), (s2))
|
||||
#define of_node_cmp(s1, s2) strcmp((s1), (s2))
|
||||
|
||||
typedef u32 phandle;
|
||||
typedef u32 ihandle;
|
||||
|
||||
|
@ -55,53 +60,30 @@ struct device_node {
|
|||
unsigned int unique_id;
|
||||
};
|
||||
|
||||
/* flag descriptions */
|
||||
#define OF_DYNAMIC 1 /* node and properties were allocated via kmalloc */
|
||||
|
||||
#define OF_IS_DYNAMIC(x) test_bit(OF_DYNAMIC, &x->_flags)
|
||||
#define OF_MARK_DYNAMIC(x) set_bit(OF_DYNAMIC, &x->_flags)
|
||||
|
||||
#define OF_BAD_ADDR ((u64)-1)
|
||||
|
||||
static inline void set_node_proc_entry(struct device_node *dn, struct proc_dir_entry *de)
|
||||
{
|
||||
dn->pde = de;
|
||||
}
|
||||
|
||||
extern struct device_node *of_find_node_by_name(struct device_node *from,
|
||||
const char *name);
|
||||
#define for_each_node_by_name(dn, name) \
|
||||
for (dn = of_find_node_by_name(NULL, name); dn; \
|
||||
dn = of_find_node_by_name(dn, name))
|
||||
extern struct device_node *of_find_node_by_type(struct device_node *from,
|
||||
const char *type);
|
||||
#define for_each_node_by_type(dn, type) \
|
||||
for (dn = of_find_node_by_type(NULL, type); dn; \
|
||||
dn = of_find_node_by_type(dn, type))
|
||||
extern struct device_node *of_find_compatible_node(struct device_node *from,
|
||||
const char *type, const char *compat);
|
||||
extern struct device_node *of_find_node_by_path(const char *path);
|
||||
extern struct device_node *of_find_node_by_phandle(phandle handle);
|
||||
extern struct device_node *of_get_parent(const struct device_node *node);
|
||||
extern struct device_node *of_get_next_child(const struct device_node *node,
|
||||
struct device_node *prev);
|
||||
extern struct property *of_find_property(const struct device_node *np,
|
||||
const char *name,
|
||||
int *lenp);
|
||||
extern int of_device_is_compatible(const struct device_node *device,
|
||||
const char *);
|
||||
extern const void *of_get_property(const struct device_node *node,
|
||||
const char *name,
|
||||
int *lenp);
|
||||
#define get_property(node,name,lenp) of_get_property(node,name,lenp)
|
||||
extern int of_set_property(struct device_node *node, const char *name, void *val, int len);
|
||||
extern int of_getintprop_default(struct device_node *np,
|
||||
const char *name,
|
||||
int def);
|
||||
extern int of_n_addr_cells(struct device_node *np);
|
||||
extern int of_n_size_cells(struct device_node *np);
|
||||
|
||||
extern void prom_build_devicetree(void);
|
||||
|
||||
/* Dummy ref counting routines - to be implemented later */
|
||||
static inline struct device_node *of_node_get(struct device_node *node)
|
||||
{
|
||||
return node;
|
||||
}
|
||||
static inline void of_node_put(struct device_node *node)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* NB: This is here while we transition from using asm/prom.h
|
||||
* to linux/of.h
|
||||
*/
|
||||
#include <linux/of.h>
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
#endif /* _SPARC_PROM_H */
|
||||
|
|
|
@ -3,14 +3,9 @@
|
|||
#ifdef __KERNEL__
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <asm/openprom.h>
|
||||
#include <asm/prom.h>
|
||||
|
||||
extern struct bus_type isa_bus_type;
|
||||
extern struct bus_type ebus_bus_type;
|
||||
extern struct bus_type sbus_bus_type;
|
||||
extern struct bus_type of_bus_type;
|
||||
|
||||
/*
|
||||
* The of_device is a kind of "base class" that is a superset of
|
||||
|
@ -31,50 +26,13 @@ struct of_device
|
|||
int portid;
|
||||
int clock_freq;
|
||||
};
|
||||
#define to_of_device(d) container_of(d, struct of_device, dev)
|
||||
|
||||
extern void __iomem *of_ioremap(struct resource *res, unsigned long offset, unsigned long size, char *name);
|
||||
extern void of_iounmap(struct resource *res, void __iomem *base, unsigned long size);
|
||||
|
||||
extern struct of_device *of_find_device_by_node(struct device_node *);
|
||||
|
||||
extern const struct of_device_id *of_match_device(
|
||||
const struct of_device_id *matches, const struct of_device *dev);
|
||||
|
||||
extern struct of_device *of_dev_get(struct of_device *dev);
|
||||
extern void of_dev_put(struct of_device *dev);
|
||||
|
||||
/*
|
||||
* An of_platform_driver driver is attached to a basic of_device on
|
||||
* the ISA, EBUS, and SBUS busses on sparc64.
|
||||
*/
|
||||
struct of_platform_driver
|
||||
{
|
||||
char *name;
|
||||
struct of_device_id *match_table;
|
||||
struct module *owner;
|
||||
|
||||
int (*probe)(struct of_device* dev, const struct of_device_id *match);
|
||||
int (*remove)(struct of_device* dev);
|
||||
|
||||
int (*suspend)(struct of_device* dev, pm_message_t state);
|
||||
int (*resume)(struct of_device* dev);
|
||||
int (*shutdown)(struct of_device* dev);
|
||||
|
||||
struct device_driver driver;
|
||||
};
|
||||
#define to_of_platform_driver(drv) container_of(drv,struct of_platform_driver, driver)
|
||||
|
||||
extern int of_register_driver(struct of_platform_driver *drv,
|
||||
struct bus_type *bus);
|
||||
extern void of_unregister_driver(struct of_platform_driver *drv);
|
||||
extern int of_device_register(struct of_device *ofdev);
|
||||
extern void of_device_unregister(struct of_device *ofdev);
|
||||
extern struct of_device *of_platform_device_create(struct device_node *np,
|
||||
const char *bus_id,
|
||||
struct device *parent,
|
||||
struct bus_type *bus);
|
||||
extern void of_release_dev(struct device *dev);
|
||||
/* These are just here during the transition */
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of_platform.h>
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
#endif /* _ASM_SPARC64_OF_DEVICE_H */
|
||||
|
|
33
include/asm-sparc64/of_platform.h
Normal file
33
include/asm-sparc64/of_platform.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
#ifndef _ASM_SPARC64_OF_PLATFORM_H
|
||||
#define _ASM_SPARC64_OF_PLATFORM_H
|
||||
/*
|
||||
* Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp.
|
||||
* <benh@kernel.crashing.org>
|
||||
* Modified for Sparc by merging parts of asm-sparc/of_device.h
|
||||
* by Stephen Rothwell
|
||||
*
|
||||
* 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 is just here during the transition */
|
||||
#include <linux/of_platform.h>
|
||||
|
||||
extern struct bus_type isa_bus_type;
|
||||
extern struct bus_type ebus_bus_type;
|
||||
extern struct bus_type sbus_bus_type;
|
||||
extern struct bus_type of_platform_bus_type;
|
||||
#define of_bus_type of_platform_bus_type /* for compatibility */
|
||||
|
||||
extern int of_register_driver(struct of_platform_driver *drv,
|
||||
struct bus_type *bus);
|
||||
extern void of_unregister_driver(struct of_platform_driver *drv);
|
||||
extern struct of_device *of_platform_device_create(struct device_node *np,
|
||||
const char *bus_id,
|
||||
struct device *parent,
|
||||
struct bus_type *bus);
|
||||
|
||||
#endif /* _ASM_SPARC64_OF_PLATFORM_H */
|
|
@ -2,7 +2,6 @@
|
|||
#define _SPARC64_PROM_H
|
||||
#ifdef __KERNEL__
|
||||
|
||||
|
||||
/*
|
||||
* Definitions for talking to the Open Firmware PROM on
|
||||
* Power Macintosh computers.
|
||||
|
@ -17,11 +16,17 @@
|
|||
* as published by the Free Software Foundation; either version
|
||||
* 2 of the License, or (at your option) any later version.
|
||||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <asm/atomic.h>
|
||||
|
||||
#define OF_ROOT_NODE_ADDR_CELLS_DEFAULT 2
|
||||
#define OF_ROOT_NODE_SIZE_CELLS_DEFAULT 1
|
||||
|
||||
#define of_compat_cmp(s1, s2, l) strncmp((s1), (s2), (l))
|
||||
#define of_prop_cmp(s1, s2) strcasecmp((s1), (s2))
|
||||
#define of_node_cmp(s1, s2) strcmp((s1), (s2))
|
||||
|
||||
typedef u32 phandle;
|
||||
typedef u32 ihandle;
|
||||
|
||||
|
@ -63,54 +68,31 @@ struct of_irq_controller {
|
|||
void *data;
|
||||
};
|
||||
|
||||
/* flag descriptions */
|
||||
#define OF_DYNAMIC 1 /* node and properties were allocated via kmalloc */
|
||||
|
||||
#define OF_IS_DYNAMIC(x) test_bit(OF_DYNAMIC, &x->_flags)
|
||||
#define OF_MARK_DYNAMIC(x) set_bit(OF_DYNAMIC, &x->_flags)
|
||||
|
||||
#define OF_BAD_ADDR ((u64)-1)
|
||||
|
||||
static inline void set_node_proc_entry(struct device_node *dn, struct proc_dir_entry *de)
|
||||
{
|
||||
dn->pde = de;
|
||||
}
|
||||
|
||||
extern struct device_node *of_find_node_by_name(struct device_node *from,
|
||||
const char *name);
|
||||
#define for_each_node_by_name(dn, name) \
|
||||
for (dn = of_find_node_by_name(NULL, name); dn; \
|
||||
dn = of_find_node_by_name(dn, name))
|
||||
extern struct device_node *of_find_node_by_type(struct device_node *from,
|
||||
const char *type);
|
||||
#define for_each_node_by_type(dn, type) \
|
||||
for (dn = of_find_node_by_type(NULL, type); dn; \
|
||||
dn = of_find_node_by_type(dn, type))
|
||||
extern struct device_node *of_find_compatible_node(struct device_node *from,
|
||||
const char *type, const char *compat);
|
||||
extern struct device_node *of_find_node_by_path(const char *path);
|
||||
extern struct device_node *of_find_node_by_phandle(phandle handle);
|
||||
extern struct device_node *of_find_node_by_cpuid(int cpuid);
|
||||
extern struct device_node *of_get_parent(const struct device_node *node);
|
||||
extern struct device_node *of_get_next_child(const struct device_node *node,
|
||||
struct device_node *prev);
|
||||
extern struct property *of_find_property(const struct device_node *np,
|
||||
const char *name,
|
||||
int *lenp);
|
||||
extern int of_device_is_compatible(const struct device_node *device,
|
||||
const char *);
|
||||
extern const void *of_get_property(const struct device_node *node,
|
||||
const char *name,
|
||||
int *lenp);
|
||||
#define get_property(node,name,lenp) of_get_property(node,name,lenp)
|
||||
extern int of_set_property(struct device_node *node, const char *name, void *val, int len);
|
||||
extern int of_getintprop_default(struct device_node *np,
|
||||
const char *name,
|
||||
int def);
|
||||
extern int of_n_addr_cells(struct device_node *np);
|
||||
extern int of_n_size_cells(struct device_node *np);
|
||||
|
||||
extern void prom_build_devicetree(void);
|
||||
|
||||
/* Dummy ref counting routines - to be implemented later */
|
||||
static inline struct device_node *of_node_get(struct device_node *node)
|
||||
{
|
||||
return node;
|
||||
}
|
||||
static inline void of_node_put(struct device_node *node)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* NB: This is here while we transition from using asm/prom.h
|
||||
* to linux/of.h
|
||||
*/
|
||||
#include <linux/of.h>
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
#endif /* _SPARC64_PROM_H */
|
||||
|
|
61
include/linux/of.h
Normal file
61
include/linux/of.h
Normal file
|
@ -0,0 +1,61 @@
|
|||
#ifndef _LINUX_OF_H
|
||||
#define _LINUX_OF_H
|
||||
/*
|
||||
* Definitions for talking to the Open Firmware PROM on
|
||||
* Power Macintosh and other computers.
|
||||
*
|
||||
* Copyright (C) 1996-2005 Paul Mackerras.
|
||||
*
|
||||
* Updates for PPC64 by Peter Bergner & David Engebretsen, IBM Corp.
|
||||
* Updates for SPARC64 by David S. Miller
|
||||
* Derived from PowerPC and Sparc prom.h files by Stephen Rothwell, IBM Corp.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#include <linux/types.h>
|
||||
|
||||
#include <asm/bitops.h>
|
||||
#include <asm/prom.h>
|
||||
|
||||
/* flag descriptions */
|
||||
#define OF_DYNAMIC 1 /* node and properties were allocated via kmalloc */
|
||||
#define OF_DETACHED 2 /* node has been detached from the device tree */
|
||||
|
||||
#define OF_BAD_ADDR ((u64)-1)
|
||||
|
||||
extern struct device_node *of_find_node_by_name(struct device_node *from,
|
||||
const char *name);
|
||||
#define for_each_node_by_name(dn, name) \
|
||||
for (dn = of_find_node_by_name(NULL, name); dn; \
|
||||
dn = of_find_node_by_name(dn, name))
|
||||
extern struct device_node *of_find_node_by_type(struct device_node *from,
|
||||
const char *type);
|
||||
#define for_each_node_by_type(dn, type) \
|
||||
for (dn = of_find_node_by_type(NULL, type); dn; \
|
||||
dn = of_find_node_by_type(dn, type))
|
||||
extern struct device_node *of_find_compatible_node(struct device_node *from,
|
||||
const char *type, const char *compat);
|
||||
#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))
|
||||
extern struct device_node *of_find_node_by_path(const char *path);
|
||||
extern struct device_node *of_find_node_by_phandle(phandle handle);
|
||||
extern struct device_node *of_get_parent(const struct device_node *node);
|
||||
extern struct device_node *of_get_next_child(const struct device_node *node,
|
||||
struct device_node *prev);
|
||||
extern struct property *of_find_property(const struct device_node *np,
|
||||
const char *name,
|
||||
int *lenp);
|
||||
extern int of_device_is_compatible(const struct device_node *device,
|
||||
const char *);
|
||||
extern const void *of_get_property(const struct device_node *node,
|
||||
const char *name,
|
||||
int *lenp);
|
||||
#define get_property(a, b, c) of_get_property((a), (b), (c))
|
||||
extern int of_n_addr_cells(struct device_node *np);
|
||||
extern int of_n_size_cells(struct device_node *np);
|
||||
|
||||
#endif /* _LINUX_OF_H */
|
26
include/linux/of_device.h
Normal file
26
include/linux/of_device.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
#ifndef _LINUX_OF_DEVICE_H
|
||||
#define _LINUX_OF_DEVICE_H
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
|
||||
#include <asm/of_device.h>
|
||||
|
||||
#define to_of_device(d) container_of(d, struct of_device, dev)
|
||||
|
||||
extern const struct of_device_id *of_match_node(
|
||||
const struct of_device_id *matches, const struct device_node *node);
|
||||
extern const struct of_device_id *of_match_device(
|
||||
const struct of_device_id *matches, const struct of_device *dev);
|
||||
|
||||
extern struct of_device *of_dev_get(struct of_device *dev);
|
||||
extern void of_dev_put(struct of_device *dev);
|
||||
|
||||
extern int of_device_register(struct of_device *ofdev);
|
||||
extern void of_device_unregister(struct of_device *ofdev);
|
||||
extern void of_release_dev(struct device *dev);
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
#endif /* _LINUX_OF_DEVICE_H */
|
57
include/linux/of_platform.h
Normal file
57
include/linux/of_platform.h
Normal file
|
@ -0,0 +1,57 @@
|
|||
#ifndef _LINUX_OF_PLATFORM_H
|
||||
#define _LINUX_OF_PLATFORM_H
|
||||
/*
|
||||
* Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp.
|
||||
* <benh@kernel.crashing.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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/of_device.h>
|
||||
|
||||
/*
|
||||
* The of_platform_bus_type is a bus type used by drivers that do not
|
||||
* attach to a macio or similar bus but still use OF probing
|
||||
* mechanism
|
||||
*/
|
||||
extern struct bus_type of_platform_bus_type;
|
||||
|
||||
/*
|
||||
* An of_platform_driver driver is attached to a basic of_device on
|
||||
* the "platform bus" (of_platform_bus_type) (or ISA, EBUS and SBUS
|
||||
* busses on sparc).
|
||||
*/
|
||||
struct of_platform_driver
|
||||
{
|
||||
char *name;
|
||||
struct of_device_id *match_table;
|
||||
struct module *owner;
|
||||
|
||||
int (*probe)(struct of_device* dev,
|
||||
const struct of_device_id *match);
|
||||
int (*remove)(struct of_device* dev);
|
||||
|
||||
int (*suspend)(struct of_device* dev, pm_message_t state);
|
||||
int (*resume)(struct of_device* dev);
|
||||
int (*shutdown)(struct of_device* dev);
|
||||
|
||||
struct device_driver driver;
|
||||
};
|
||||
#define to_of_platform_driver(drv) \
|
||||
container_of(drv,struct of_platform_driver, driver)
|
||||
|
||||
#include <asm/of_platform.h>
|
||||
|
||||
extern struct of_device *of_find_device_by_node(struct device_node *np);
|
||||
|
||||
extern int of_bus_type_init(struct bus_type *bus, const char *name);
|
||||
|
||||
#endif /* _LINUX_OF_PLATFORM_H */
|
Loading…
Reference in a new issue