mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-11-25 10:00:53 +07:00
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
@ -92,6 +92,9 @@ config ARCH_MAY_HAVE_PC_FDC
|
|||||||
config PPC_OF
|
config PPC_OF
|
||||||
def_bool y
|
def_bool y
|
||||||
|
|
||||||
|
config OF
|
||||||
|
def_bool y
|
||||||
|
|
||||||
config PPC_UDBG_16550
|
config PPC_UDBG_16550
|
||||||
bool
|
bool
|
||||||
default n
|
default n
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include <linux/string.h>
|
#include <linux/string.h>
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/of.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/mod_devicetable.h>
|
#include <linux/mod_devicetable.h>
|
||||||
@ -8,118 +9,6 @@
|
|||||||
#include <asm/errno.h>
|
#include <asm/errno.h>
|
||||||
#include <asm/of_device.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,
|
ssize_t of_device_get_modalias(struct of_device *ofdev,
|
||||||
char *str, ssize_t len)
|
char *str, ssize_t len)
|
||||||
{
|
{
|
||||||
@ -229,14 +118,5 @@ int of_device_uevent(struct device *dev,
|
|||||||
|
|
||||||
return 0;
|
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_uevent);
|
||||||
EXPORT_SYMBOL(of_device_get_modalias);
|
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;
|
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 = {
|
struct bus_type of_platform_bus_type = {
|
||||||
.name = "of_platform",
|
|
||||||
.match = of_platform_bus_match,
|
|
||||||
.uevent = of_device_uevent,
|
.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);
|
EXPORT_SYMBOL(of_platform_bus_type);
|
||||||
|
|
||||||
static int __init of_bus_driver_init(void)
|
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);
|
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;
|
struct boot_param_header *initial_boot_params;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static struct device_node *allnodes = NULL;
|
extern struct device_node *allnodes; /* temporary while merging */
|
||||||
|
|
||||||
/* use when traversing tree through the allnext, child, sibling,
|
extern rwlock_t devtree_lock; /* temporary while merging */
|
||||||
* or parent members of struct device_node.
|
|
||||||
*/
|
|
||||||
static DEFINE_RWLOCK(devtree_lock);
|
|
||||||
|
|
||||||
/* export that to outside world */
|
/* export that to outside world */
|
||||||
struct device_node *of_chosen;
|
struct device_node *of_chosen;
|
||||||
@ -1056,60 +1053,6 @@ void __init early_init_devtree(void *params)
|
|||||||
DBG(" <- early_init_devtree()\n");
|
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
|
* 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
|
* of_find_node_by_phandle - Find a node given a phandle
|
||||||
* @handle: phandle of the node to find
|
* @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);
|
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
|
* of_node_get - Increment refcount of a node
|
||||||
* @node: Node to inc refcount, NULL is supported to
|
* @node: Node to inc refcount, NULL is supported to
|
||||||
@ -1543,37 +1328,6 @@ static int __init prom_reconfig_setup(void)
|
|||||||
__initcall(prom_reconfig_setup);
|
__initcall(prom_reconfig_setup);
|
||||||
#endif
|
#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
|
* Add a property to a node
|
||||||
*/
|
*/
|
||||||
|
@ -24,6 +24,9 @@ config GENERIC_ISA_DMA
|
|||||||
config ARCH_NO_VIRT_TO_BUS
|
config ARCH_NO_VIRT_TO_BUS
|
||||||
def_bool y
|
def_bool y
|
||||||
|
|
||||||
|
config OF
|
||||||
|
def_bool y
|
||||||
|
|
||||||
source "init/Kconfig"
|
source "init/Kconfig"
|
||||||
|
|
||||||
menu "General machine setup"
|
menu "General machine setup"
|
||||||
|
@ -1,132 +1,13 @@
|
|||||||
#include <linux/string.h>
|
#include <linux/string.h>
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/of.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/mod_devicetable.h>
|
#include <linux/mod_devicetable.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
|
#include <linux/errno.h>
|
||||||
#include <asm/errno.h>
|
#include <linux/of_device.h>
|
||||||
#include <asm/of_device.h>
|
#include <linux/of_platform.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;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int node_match(struct device *dev, void *data)
|
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 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);
|
dp, node_match);
|
||||||
|
|
||||||
if (dev)
|
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);
|
EXPORT_SYMBOL(of_find_device_by_node);
|
||||||
|
|
||||||
#ifdef CONFIG_PCI
|
#ifdef CONFIG_PCI
|
||||||
struct bus_type ebus_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,
|
|
||||||
};
|
|
||||||
EXPORT_SYMBOL(ebus_bus_type);
|
EXPORT_SYMBOL(ebus_bus_type);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_SBUS
|
#ifdef CONFIG_SBUS
|
||||||
struct bus_type sbus_bus_type = {
|
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,
|
|
||||||
};
|
|
||||||
EXPORT_SYMBOL(sbus_bus_type);
|
EXPORT_SYMBOL(sbus_bus_type);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct bus_type of_bus_type = {
|
struct bus_type of_platform_bus_type;
|
||||||
.name = "of",
|
EXPORT_SYMBOL(of_platform_bus_type);
|
||||||
.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);
|
|
||||||
|
|
||||||
static inline u64 of_read_addr(const u32 *cell, int size)
|
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);
|
build_device_resources(op, parent);
|
||||||
|
|
||||||
op->dev.parent = parent;
|
op->dev.parent = parent;
|
||||||
op->dev.bus = &of_bus_type;
|
op->dev.bus = &of_platform_bus_type;
|
||||||
if (!parent)
|
if (!parent)
|
||||||
strcpy(op->dev.bus_id, "root");
|
strcpy(op->dev.bus_id, "root");
|
||||||
else
|
else
|
||||||
@ -690,14 +550,14 @@ static int __init of_bus_driver_init(void)
|
|||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
err = bus_register(&of_bus_type);
|
err = of_bus_type_init(&of_platform_bus_type, "of");
|
||||||
#ifdef CONFIG_PCI
|
#ifdef CONFIG_PCI
|
||||||
if (!err)
|
if (!err)
|
||||||
err = bus_register(&ebus_bus_type);
|
err = of_bus_type_init(&ebus_bus_type, "ebus");
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_SBUS
|
#ifdef CONFIG_SBUS
|
||||||
if (!err)
|
if (!err)
|
||||||
err = bus_register(&sbus_bus_type);
|
err = of_bus_type_init(&sbus_bus_type, "sbus");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!err)
|
if (!err)
|
||||||
@ -735,56 +595,6 @@ void of_unregister_driver(struct of_platform_driver *drv)
|
|||||||
driver_unregister(&drv->driver);
|
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,
|
struct of_device* of_platform_device_create(struct device_node *np,
|
||||||
const char *bus_id,
|
const char *bus_id,
|
||||||
struct device *parent,
|
struct device *parent,
|
||||||
@ -810,12 +620,6 @@ struct of_device* of_platform_device_create(struct device_node *np,
|
|||||||
return dev;
|
return dev;
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT_SYMBOL(of_match_device);
|
|
||||||
EXPORT_SYMBOL(of_register_driver);
|
EXPORT_SYMBOL(of_register_driver);
|
||||||
EXPORT_SYMBOL(of_unregister_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_platform_device_create);
|
||||||
EXPORT_SYMBOL(of_release_dev);
|
|
||||||
|
@ -25,73 +25,9 @@
|
|||||||
#include <asm/prom.h>
|
#include <asm/prom.h>
|
||||||
#include <asm/oplib.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,
|
extern rwlock_t devtree_lock; /* temporary while merging */
|
||||||
* 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);
|
|
||||||
|
|
||||||
struct device_node *of_find_node_by_phandle(phandle handle)
|
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);
|
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)
|
int of_getintprop_default(struct device_node *np, const char *name, int def)
|
||||||
{
|
{
|
||||||
struct property *prop;
|
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);
|
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)
|
int of_set_property(struct device_node *dp, const char *name, void *val, int len)
|
||||||
{
|
{
|
||||||
struct property **prevp;
|
struct property **prevp;
|
||||||
|
@ -354,7 +354,7 @@ static struct of_platform_driver clock_driver = {
|
|||||||
/* Probe for the mostek real time clock chip. */
|
/* Probe for the mostek real time clock chip. */
|
||||||
static int __init clock_init(void)
|
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
|
/* Must be after subsys_initcall() so that busses are probed. Must
|
||||||
|
@ -65,6 +65,9 @@ config AUDIT_ARCH
|
|||||||
config ARCH_NO_VIRT_TO_BUS
|
config ARCH_NO_VIRT_TO_BUS
|
||||||
def_bool y
|
def_bool y
|
||||||
|
|
||||||
|
config OF
|
||||||
|
def_bool y
|
||||||
|
|
||||||
choice
|
choice
|
||||||
prompt "Kernel page size"
|
prompt "Kernel page size"
|
||||||
default SPARC64_PAGE_SIZE_8KB
|
default SPARC64_PAGE_SIZE_8KB
|
||||||
|
@ -155,7 +155,7 @@ static struct of_platform_driver auxio_driver = {
|
|||||||
|
|
||||||
static int __init auxio_init(void)
|
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
|
/* Must be after subsys_initcall() so that busses are probed. Must
|
||||||
|
@ -1,132 +1,13 @@
|
|||||||
#include <linux/string.h>
|
#include <linux/string.h>
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/of.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/mod_devicetable.h>
|
#include <linux/mod_devicetable.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
|
#include <linux/errno.h>
|
||||||
#include <asm/errno.h>
|
#include <linux/of_device.h>
|
||||||
#include <asm/of_device.h>
|
#include <linux/of_platform.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;
|
|
||||||
}
|
|
||||||
|
|
||||||
void __iomem *of_ioremap(struct resource *res, unsigned long offset, unsigned long size, char *name)
|
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 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);
|
dp, node_match);
|
||||||
|
|
||||||
if (dev)
|
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);
|
EXPORT_SYMBOL(of_find_device_by_node);
|
||||||
|
|
||||||
#ifdef CONFIG_PCI
|
#ifdef CONFIG_PCI
|
||||||
struct bus_type isa_bus_type = {
|
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,
|
|
||||||
};
|
|
||||||
EXPORT_SYMBOL(isa_bus_type);
|
EXPORT_SYMBOL(isa_bus_type);
|
||||||
|
|
||||||
struct bus_type ebus_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,
|
|
||||||
};
|
|
||||||
EXPORT_SYMBOL(ebus_bus_type);
|
EXPORT_SYMBOL(ebus_bus_type);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_SBUS
|
#ifdef CONFIG_SBUS
|
||||||
struct bus_type sbus_bus_type = {
|
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,
|
|
||||||
};
|
|
||||||
EXPORT_SYMBOL(sbus_bus_type);
|
EXPORT_SYMBOL(sbus_bus_type);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct bus_type of_bus_type = {
|
struct bus_type of_platform_bus_type;
|
||||||
.name = "of",
|
EXPORT_SYMBOL(of_platform_bus_type);
|
||||||
.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);
|
|
||||||
|
|
||||||
static inline u64 of_read_addr(const u32 *cell, int size)
|
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->irqs[i] = build_one_device_irq(op, parent, op->irqs[i]);
|
||||||
|
|
||||||
op->dev.parent = parent;
|
op->dev.parent = parent;
|
||||||
op->dev.bus = &of_bus_type;
|
op->dev.bus = &of_platform_bus_type;
|
||||||
if (!parent)
|
if (!parent)
|
||||||
strcpy(op->dev.bus_id, "root");
|
strcpy(op->dev.bus_id, "root");
|
||||||
else
|
else
|
||||||
@ -977,16 +830,16 @@ static int __init of_bus_driver_init(void)
|
|||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
err = bus_register(&of_bus_type);
|
err = of_bus_type_init(&of_platform_bus_type, "of");
|
||||||
#ifdef CONFIG_PCI
|
#ifdef CONFIG_PCI
|
||||||
if (!err)
|
if (!err)
|
||||||
err = bus_register(&isa_bus_type);
|
err = of_bus_type_init(&isa_bus_type, "isa");
|
||||||
if (!err)
|
if (!err)
|
||||||
err = bus_register(&ebus_bus_type);
|
err = of_bus_type_init(&ebus_bus_type, "ebus");
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_SBUS
|
#ifdef CONFIG_SBUS
|
||||||
if (!err)
|
if (!err)
|
||||||
err = bus_register(&sbus_bus_type);
|
err = of_bus_type_init(&sbus_bus_type, "sbus");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!err)
|
if (!err)
|
||||||
@ -1020,61 +873,13 @@ int of_register_driver(struct of_platform_driver *drv, struct bus_type *bus)
|
|||||||
/* register with core */
|
/* register with core */
|
||||||
return driver_register(&drv->driver);
|
return driver_register(&drv->driver);
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(of_register_driver);
|
||||||
|
|
||||||
void of_unregister_driver(struct of_platform_driver *drv)
|
void of_unregister_driver(struct of_platform_driver *drv)
|
||||||
{
|
{
|
||||||
driver_unregister(&drv->driver);
|
driver_unregister(&drv->driver);
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(of_unregister_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,
|
struct of_device* of_platform_device_create(struct device_node *np,
|
||||||
const char *bus_id,
|
const char *bus_id,
|
||||||
@ -1100,13 +905,4 @@ struct of_device* of_platform_device_create(struct device_node *np,
|
|||||||
|
|
||||||
return dev;
|
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_platform_device_create);
|
||||||
EXPORT_SYMBOL(of_release_dev);
|
|
||||||
|
@ -112,6 +112,6 @@ static struct of_platform_driver power_driver = {
|
|||||||
|
|
||||||
void __init power_init(void)
|
void __init power_init(void)
|
||||||
{
|
{
|
||||||
of_register_driver(&power_driver, &of_bus_type);
|
of_register_driver(&power_driver, &of_platform_bus_type);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -30,73 +30,9 @@
|
|||||||
#include <asm/upa.h>
|
#include <asm/upa.h>
|
||||||
#include <asm/smp.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,
|
extern rwlock_t devtree_lock; /* temporary while merging */
|
||||||
* 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);
|
|
||||||
|
|
||||||
struct device_node *of_find_node_by_phandle(phandle handle)
|
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);
|
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)
|
int of_getintprop_default(struct device_node *np, const char *name, int def)
|
||||||
{
|
{
|
||||||
struct property *prop;
|
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);
|
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)
|
int of_set_property(struct device_node *dp, const char *name, void *val, int len)
|
||||||
{
|
{
|
||||||
struct property **prevp;
|
struct property **prevp;
|
||||||
|
@ -835,7 +835,7 @@ static int __init clock_init(void)
|
|||||||
return 0;
|
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
|
/* 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/mtd/Kconfig"
|
||||||
|
|
||||||
|
source "drivers/of/Kconfig"
|
||||||
|
|
||||||
source "drivers/parport/Kconfig"
|
source "drivers/parport/Kconfig"
|
||||||
|
|
||||||
source "drivers/pnp/Kconfig"
|
source "drivers/pnp/Kconfig"
|
||||||
|
@ -86,3 +86,4 @@ obj-$(CONFIG_GENERIC_TIME) += clocksource/
|
|||||||
obj-$(CONFIG_DMA_ENGINE) += dma/
|
obj-$(CONFIG_DMA_ENGINE) += dma/
|
||||||
obj-$(CONFIG_HID) += hid/
|
obj-$(CONFIG_HID) += hid/
|
||||||
obj-$(CONFIG_PPC_PS3) += ps3/
|
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__
|
#ifdef __KERNEL__
|
||||||
|
|
||||||
#include <linux/device.h>
|
#include <linux/device.h>
|
||||||
#include <linux/mod_devicetable.h>
|
#include <linux/of.h>
|
||||||
#include <asm/prom.h>
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The of_device is a kind of "base class" that is a superset of
|
* 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
|
* struct device for use by devices attached to an OF node and
|
||||||
* probed using OF properties
|
* probed using OF properties.
|
||||||
*/
|
*/
|
||||||
struct of_device
|
struct of_device
|
||||||
{
|
{
|
||||||
@ -18,24 +16,14 @@ struct of_device
|
|||||||
u64 dma_mask; /* DMA mask */
|
u64 dma_mask; /* DMA mask */
|
||||||
struct device dev; /* Generic device interface */
|
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,
|
extern ssize_t of_device_get_modalias(struct of_device *ofdev,
|
||||||
char *str, ssize_t len);
|
char *str, ssize_t len);
|
||||||
extern int of_device_uevent(struct device *dev,
|
extern int of_device_uevent(struct device *dev,
|
||||||
char **envp, int num_envp, char *buffer, int buffer_size);
|
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 /* __KERNEL__ */
|
||||||
#endif /* _ASM_POWERPC_OF_DEVICE_H */
|
#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.
|
* Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp.
|
||||||
* <benh@kernel.crashing.org>
|
* <benh@kernel.crashing.org>
|
||||||
@ -9,37 +11,8 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <asm/of_device.h>
|
/* This is just here during the transition */
|
||||||
|
#include <linux/of_platform.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)
|
|
||||||
|
|
||||||
/* Platform drivers register/unregister */
|
/* Platform drivers register/unregister */
|
||||||
extern int of_register_platform_driver(struct of_platform_driver *drv);
|
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 of_device_id *matches,
|
||||||
struct device *parent);
|
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);
|
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/irq.h>
|
||||||
#include <asm/atomic.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 */
|
/* Definitions used by the flattened device tree */
|
||||||
#define OF_DT_HEADER 0xd00dfeed /* marker */
|
#define OF_DT_HEADER 0xd00dfeed /* marker */
|
||||||
#define OF_DT_BEGIN_NODE 0x1 /* Start of node, full name */
|
#define OF_DT_BEGIN_NODE 0x1 /* Start of node, full name */
|
||||||
@ -97,10 +104,6 @@ struct device_node {
|
|||||||
|
|
||||||
extern struct device_node *of_chosen;
|
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)
|
static inline int of_node_check_flag(struct device_node *n, unsigned long flag)
|
||||||
{
|
{
|
||||||
return test_bit(flag, &n->_flags);
|
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_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 struct device_node *of_node_get(struct device_node *node);
|
||||||
extern void of_node_put(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 finish_device_tree(void);
|
||||||
extern void unflatten_device_tree(void);
|
extern void unflatten_device_tree(void);
|
||||||
extern void early_init_devtree(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))
|
#define device_is_compatible(d, c) of_device_is_compatible((d), (c))
|
||||||
extern int machine_is_compatible(const char *compat);
|
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 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 int prom_n_intr_cells(struct device_node* np);
|
||||||
extern void prom_get_irq_senses(unsigned char *senses, int off, int max);
|
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);
|
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
|
/* 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);
|
extern u64 of_translate_address(struct device_node *np, const u32 *addr);
|
||||||
|
|
||||||
/* Extract an address from a device, returns the region size and
|
/* 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);
|
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 /* __KERNEL__ */
|
||||||
#endif /* _POWERPC_PROM_H */
|
#endif /* _POWERPC_PROM_H */
|
||||||
|
@ -3,13 +3,9 @@
|
|||||||
#ifdef __KERNEL__
|
#ifdef __KERNEL__
|
||||||
|
|
||||||
#include <linux/device.h>
|
#include <linux/device.h>
|
||||||
|
#include <linux/of.h>
|
||||||
#include <linux/mod_devicetable.h>
|
#include <linux/mod_devicetable.h>
|
||||||
#include <asm/openprom.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
|
* The of_device is a kind of "base class" that is a superset of
|
||||||
@ -30,50 +26,13 @@ struct of_device
|
|||||||
int portid;
|
int portid;
|
||||||
int clock_freq;
|
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 __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 void of_iounmap(struct resource *res, void __iomem *base, unsigned long size);
|
||||||
|
|
||||||
extern struct of_device *of_find_device_by_node(struct device_node *);
|
/* These are just here during the transition */
|
||||||
|
#include <linux/of_device.h>
|
||||||
extern const struct of_device_id *of_match_device(
|
#include <linux/of_platform.h>
|
||||||
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);
|
|
||||||
|
|
||||||
#endif /* __KERNEL__ */
|
#endif /* __KERNEL__ */
|
||||||
#endif /* _ASM_SPARC_OF_DEVICE_H */
|
#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
|
#define _SPARC_PROM_H
|
||||||
#ifdef __KERNEL__
|
#ifdef __KERNEL__
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Definitions for talking to the Open Firmware PROM on
|
* Definitions for talking to the Open Firmware PROM on
|
||||||
* Power Macintosh computers.
|
* Power Macintosh computers.
|
||||||
@ -17,11 +16,17 @@
|
|||||||
* as published by the Free Software Foundation; either version
|
* as published by the Free Software Foundation; either version
|
||||||
* 2 of the License, or (at your option) any later version.
|
* 2 of the License, or (at your option) any later version.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <linux/proc_fs.h>
|
#include <linux/proc_fs.h>
|
||||||
#include <asm/atomic.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 phandle;
|
||||||
typedef u32 ihandle;
|
typedef u32 ihandle;
|
||||||
|
|
||||||
@ -55,53 +60,30 @@ struct device_node {
|
|||||||
unsigned int unique_id;
|
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_IS_DYNAMIC(x) test_bit(OF_DYNAMIC, &x->_flags)
|
||||||
#define OF_MARK_DYNAMIC(x) set_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_set_property(struct device_node *node, const char *name, void *val, int len);
|
||||||
extern int of_getintprop_default(struct device_node *np,
|
extern int of_getintprop_default(struct device_node *np,
|
||||||
const char *name,
|
const char *name,
|
||||||
int def);
|
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);
|
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 /* __KERNEL__ */
|
||||||
#endif /* _SPARC_PROM_H */
|
#endif /* _SPARC_PROM_H */
|
||||||
|
@ -3,14 +3,9 @@
|
|||||||
#ifdef __KERNEL__
|
#ifdef __KERNEL__
|
||||||
|
|
||||||
#include <linux/device.h>
|
#include <linux/device.h>
|
||||||
|
#include <linux/of.h>
|
||||||
#include <linux/mod_devicetable.h>
|
#include <linux/mod_devicetable.h>
|
||||||
#include <asm/openprom.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
|
* The of_device is a kind of "base class" that is a superset of
|
||||||
@ -31,50 +26,13 @@ struct of_device
|
|||||||
int portid;
|
int portid;
|
||||||
int clock_freq;
|
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 __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 void of_iounmap(struct resource *res, void __iomem *base, unsigned long size);
|
||||||
|
|
||||||
extern struct of_device *of_find_device_by_node(struct device_node *);
|
/* These are just here during the transition */
|
||||||
|
#include <linux/of_device.h>
|
||||||
extern const struct of_device_id *of_match_device(
|
#include <linux/of_platform.h>
|
||||||
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);
|
|
||||||
|
|
||||||
#endif /* __KERNEL__ */
|
#endif /* __KERNEL__ */
|
||||||
#endif /* _ASM_SPARC64_OF_DEVICE_H */
|
#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
|
#define _SPARC64_PROM_H
|
||||||
#ifdef __KERNEL__
|
#ifdef __KERNEL__
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Definitions for talking to the Open Firmware PROM on
|
* Definitions for talking to the Open Firmware PROM on
|
||||||
* Power Macintosh computers.
|
* Power Macintosh computers.
|
||||||
@ -17,11 +16,17 @@
|
|||||||
* as published by the Free Software Foundation; either version
|
* as published by the Free Software Foundation; either version
|
||||||
* 2 of the License, or (at your option) any later version.
|
* 2 of the License, or (at your option) any later version.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <linux/proc_fs.h>
|
#include <linux/proc_fs.h>
|
||||||
#include <asm/atomic.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 phandle;
|
||||||
typedef u32 ihandle;
|
typedef u32 ihandle;
|
||||||
|
|
||||||
@ -63,54 +68,31 @@ struct of_irq_controller {
|
|||||||
void *data;
|
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_IS_DYNAMIC(x) test_bit(OF_DYNAMIC, &x->_flags)
|
||||||
#define OF_MARK_DYNAMIC(x) set_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_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_set_property(struct device_node *node, const char *name, void *val, int len);
|
||||||
extern int of_getintprop_default(struct device_node *np,
|
extern int of_getintprop_default(struct device_node *np,
|
||||||
const char *name,
|
const char *name,
|
||||||
int def);
|
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);
|
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 /* __KERNEL__ */
|
||||||
#endif /* _SPARC64_PROM_H */
|
#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 New Issue
Block a user