mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-07-23 07:12:09 +00:00
sparc64: add MDESC node name property to VIO device metadata
Add the MDESC node name of MDESC client to VIO device metadata. It is later used to uniquely identify a node in the MDESC. VIO & MDESC APIs are updated to handle this node name. Signed-off-by: Jagannathan Raman <jag.raman@oracle.com> Reviewed-by: Liam Merwick <liam.merwick@oracle.com> Reviewed-by: Shannon Nelson <shannon.nelson@oracle.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
0ab2fcd69d
commit
06f3c3ac60
4 changed files with 65 additions and 48 deletions
|
@ -63,9 +63,10 @@ u64 mdesc_arc_target(struct mdesc_handle *hp, u64 arc);
|
||||||
void mdesc_update(void);
|
void mdesc_update(void);
|
||||||
|
|
||||||
struct mdesc_notifier_client {
|
struct mdesc_notifier_client {
|
||||||
void (*add)(struct mdesc_handle *handle, u64 node);
|
void (*add)(struct mdesc_handle *handle, u64 node,
|
||||||
void (*remove)(struct mdesc_handle *handle, u64 node);
|
const char *node_name);
|
||||||
|
void (*remove)(struct mdesc_handle *handle, u64 node,
|
||||||
|
const char *node_name);
|
||||||
const char *node_name;
|
const char *node_name;
|
||||||
struct mdesc_notifier_client *next;
|
struct mdesc_notifier_client *next;
|
||||||
};
|
};
|
||||||
|
|
|
@ -316,12 +316,14 @@ static inline u32 vio_dring_prev(struct vio_dring_state *dr, u32 index)
|
||||||
}
|
}
|
||||||
|
|
||||||
#define VIO_MAX_TYPE_LEN 32
|
#define VIO_MAX_TYPE_LEN 32
|
||||||
|
#define VIO_MAX_NAME_LEN 32
|
||||||
#define VIO_MAX_COMPAT_LEN 64
|
#define VIO_MAX_COMPAT_LEN 64
|
||||||
|
|
||||||
struct vio_dev {
|
struct vio_dev {
|
||||||
u64 mp;
|
u64 mp;
|
||||||
struct device_node *dp;
|
struct device_node *dp;
|
||||||
|
|
||||||
|
char node_name[VIO_MAX_NAME_LEN];
|
||||||
char type[VIO_MAX_TYPE_LEN];
|
char type[VIO_MAX_TYPE_LEN];
|
||||||
char compat[VIO_MAX_COMPAT_LEN];
|
char compat[VIO_MAX_COMPAT_LEN];
|
||||||
int compat_len;
|
int compat_len;
|
||||||
|
|
|
@ -291,7 +291,7 @@ void mdesc_register_notifier(struct mdesc_notifier_client *client)
|
||||||
client_list = client;
|
client_list = client;
|
||||||
|
|
||||||
mdesc_for_each_node_by_name(cur_mdesc, node, client->node_name)
|
mdesc_for_each_node_by_name(cur_mdesc, node, client->node_name)
|
||||||
client->add(cur_mdesc, node);
|
client->add(cur_mdesc, node, client->node_name);
|
||||||
|
|
||||||
mutex_unlock(&mdesc_mutex);
|
mutex_unlock(&mdesc_mutex);
|
||||||
}
|
}
|
||||||
|
@ -399,55 +399,61 @@ static bool ds_port_node_match(union md_node_info *a_node_info,
|
||||||
static void invoke_on_missing(const char *name,
|
static void invoke_on_missing(const char *name,
|
||||||
struct mdesc_handle *a,
|
struct mdesc_handle *a,
|
||||||
struct mdesc_handle *b,
|
struct mdesc_handle *b,
|
||||||
void (*func)(struct mdesc_handle *, u64))
|
void (*func)(struct mdesc_handle *, u64,
|
||||||
|
const char *node_name))
|
||||||
{
|
{
|
||||||
u64 node;
|
mdesc_node_info_get_f get_info_func;
|
||||||
|
mdesc_node_info_rel_f rel_info_func;
|
||||||
|
mdesc_node_match_f node_match_func;
|
||||||
|
union md_node_info a_node_info;
|
||||||
|
union md_node_info b_node_info;
|
||||||
|
bool found;
|
||||||
|
u64 a_node;
|
||||||
|
u64 b_node;
|
||||||
|
int rv;
|
||||||
|
|
||||||
mdesc_for_each_node_by_name(a, node, name) {
|
/*
|
||||||
int found = 0, is_vdc_port = 0;
|
* Find the get_info, rel_info and node_match ops for the given
|
||||||
const char *name_prop;
|
* node name
|
||||||
const u64 *id;
|
*/
|
||||||
u64 fnode;
|
mdesc_get_node_ops(name, &get_info_func, &rel_info_func,
|
||||||
|
&node_match_func);
|
||||||
|
|
||||||
name_prop = mdesc_get_property(a, node, "name", NULL);
|
/* If we didn't find a match, the node type is not supported */
|
||||||
if (name_prop && !strcmp(name_prop, "vdc-port")) {
|
if (!get_info_func || !rel_info_func || !node_match_func) {
|
||||||
is_vdc_port = 1;
|
pr_err("MD: %s node type is not supported\n", name);
|
||||||
id = parent_cfg_handle(a, node);
|
return;
|
||||||
} else
|
}
|
||||||
id = mdesc_get_property(a, node, "id", NULL);
|
|
||||||
|
|
||||||
if (!id) {
|
mdesc_for_each_node_by_name(a, a_node, name) {
|
||||||
printk(KERN_ERR "MD: Cannot find ID for %s node.\n",
|
found = false;
|
||||||
(name_prop ? name_prop : name));
|
|
||||||
|
rv = get_info_func(a, a_node, &a_node_info);
|
||||||
|
if (rv != 0) {
|
||||||
|
pr_err("MD: Cannot find 1 or more required match properties for %s node.\n",
|
||||||
|
name);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
mdesc_for_each_node_by_name(b, fnode, name) {
|
/* Check each node in B for node matching a_node */
|
||||||
const u64 *fid;
|
mdesc_for_each_node_by_name(b, b_node, name) {
|
||||||
|
rv = get_info_func(b, b_node, &b_node_info);
|
||||||
|
if (rv != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (is_vdc_port) {
|
if (node_match_func(&a_node_info, &b_node_info)) {
|
||||||
name_prop = mdesc_get_property(b, fnode,
|
found = true;
|
||||||
"name", NULL);
|
rel_info_func(&b_node_info);
|
||||||
if (!name_prop ||
|
|
||||||
strcmp(name_prop, "vdc-port"))
|
|
||||||
continue;
|
|
||||||
fid = parent_cfg_handle(b, fnode);
|
|
||||||
if (!fid) {
|
|
||||||
printk(KERN_ERR "MD: Cannot find ID "
|
|
||||||
"for vdc-port node.\n");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
fid = mdesc_get_property(b, fnode,
|
|
||||||
"id", NULL);
|
|
||||||
|
|
||||||
if (*id == *fid) {
|
|
||||||
found = 1;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rel_info_func(&b_node_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rel_info_func(&a_node_info);
|
||||||
|
|
||||||
if (!found)
|
if (!found)
|
||||||
func(a, node);
|
func(a, a_node, name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -219,6 +219,7 @@ int vio_set_intr(unsigned long dev_ino, int state)
|
||||||
EXPORT_SYMBOL(vio_set_intr);
|
EXPORT_SYMBOL(vio_set_intr);
|
||||||
|
|
||||||
static struct vio_dev *vio_create_one(struct mdesc_handle *hp, u64 mp,
|
static struct vio_dev *vio_create_one(struct mdesc_handle *hp, u64 mp,
|
||||||
|
const char *node_name,
|
||||||
struct device *parent)
|
struct device *parent)
|
||||||
{
|
{
|
||||||
const char *type, *compat, *bus_id_name;
|
const char *type, *compat, *bus_id_name;
|
||||||
|
@ -236,7 +237,7 @@ static struct vio_dev *vio_create_one(struct mdesc_handle *hp, u64 mp,
|
||||||
tlen = strlen(type) + 1;
|
tlen = strlen(type) + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (tlen > VIO_MAX_TYPE_LEN) {
|
if (tlen > VIO_MAX_TYPE_LEN || strlen(type) >= VIO_MAX_TYPE_LEN) {
|
||||||
printk(KERN_ERR "VIO: Type string [%s] is too long.\n",
|
printk(KERN_ERR "VIO: Type string [%s] is too long.\n",
|
||||||
type);
|
type);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -335,6 +336,11 @@ static struct vio_dev *vio_create_one(struct mdesc_handle *hp, u64 mp,
|
||||||
|
|
||||||
printk(KERN_INFO "VIO: Adding device %s\n", dev_name(&vdev->dev));
|
printk(KERN_INFO "VIO: Adding device %s\n", dev_name(&vdev->dev));
|
||||||
|
|
||||||
|
/* node_name is NULL for the parent/channel-devices node */
|
||||||
|
if (node_name != NULL)
|
||||||
|
(void) snprintf(vdev->node_name, VIO_MAX_NAME_LEN, "%s",
|
||||||
|
node_name);
|
||||||
|
|
||||||
err = device_register(&vdev->dev);
|
err = device_register(&vdev->dev);
|
||||||
if (err) {
|
if (err) {
|
||||||
printk(KERN_ERR "VIO: Could not register device %s, err=%d\n",
|
printk(KERN_ERR "VIO: Could not register device %s, err=%d\n",
|
||||||
|
@ -349,9 +355,10 @@ static struct vio_dev *vio_create_one(struct mdesc_handle *hp, u64 mp,
|
||||||
return vdev;
|
return vdev;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vio_add(struct mdesc_handle *hp, u64 node)
|
static void vio_add(struct mdesc_handle *hp, u64 node,
|
||||||
|
const char *node_name)
|
||||||
{
|
{
|
||||||
(void) vio_create_one(hp, node, &root_vdev->dev);
|
(void) vio_create_one(hp, node, node_name, &root_vdev->dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct vio_md_node_query {
|
struct vio_md_node_query {
|
||||||
|
@ -375,7 +382,7 @@ static int vio_md_node_match(struct device *dev, void *arg)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vio_remove(struct mdesc_handle *hp, u64 node)
|
static void vio_remove(struct mdesc_handle *hp, u64 node, const char *node_name)
|
||||||
{
|
{
|
||||||
const char *type;
|
const char *type;
|
||||||
const u64 *id, *cfg_handle;
|
const u64 *id, *cfg_handle;
|
||||||
|
@ -446,7 +453,8 @@ static struct mdesc_notifier_client vio_device_notifier = {
|
||||||
* under "openboot" that we should not mess with as aparently that is
|
* under "openboot" that we should not mess with as aparently that is
|
||||||
* reserved exclusively for OBP use.
|
* reserved exclusively for OBP use.
|
||||||
*/
|
*/
|
||||||
static void vio_add_ds(struct mdesc_handle *hp, u64 node)
|
static void vio_add_ds(struct mdesc_handle *hp, u64 node,
|
||||||
|
const char *node_name)
|
||||||
{
|
{
|
||||||
int found;
|
int found;
|
||||||
u64 a;
|
u64 a;
|
||||||
|
@ -463,7 +471,7 @@ static void vio_add_ds(struct mdesc_handle *hp, u64 node)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (found)
|
if (found)
|
||||||
(void) vio_create_one(hp, node, &root_vdev->dev);
|
(void) vio_create_one(hp, node, node_name, &root_vdev->dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct mdesc_notifier_client vio_ds_notifier = {
|
static struct mdesc_notifier_client vio_ds_notifier = {
|
||||||
|
@ -530,7 +538,7 @@ static int __init vio_init(void)
|
||||||
|
|
||||||
cdev_cfg_handle = *cfg_handle;
|
cdev_cfg_handle = *cfg_handle;
|
||||||
|
|
||||||
root_vdev = vio_create_one(hp, root, NULL);
|
root_vdev = vio_create_one(hp, root, NULL, NULL);
|
||||||
err = -ENODEV;
|
err = -ENODEV;
|
||||||
if (!root_vdev) {
|
if (!root_vdev) {
|
||||||
printk(KERN_ERR "VIO: Could not create root device.\n");
|
printk(KERN_ERR "VIO: Could not create root device.\n");
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue