On 08/15/2013 12:23 AM, Tyrel Datwyler wrote: > Currently the device nodes created in the device subtree returned by a call to > dlpar_configure_connector are all named in the root node. This is because the > the node name in the work area returned by ibm,configure-connector rtas call > only contains the node name and not the entire node path. Passing the parent > node where the new subtree will be created to dlpar_configure_connector allows > the correct node path to be prefixed in the full_name field. > > Signed-off-by: Tyrel Datwyler <tyr...@linux.vnet.ibm.com>
Acked-by: Nathan Fontenot <nf...@linux.vnet.ibm.com> > --- > arch/powerpc/platforms/pseries/dlpar.c | 55 > ++++++++++++++++--------------- > arch/powerpc/platforms/pseries/mobility.c | 11 +++---- > arch/powerpc/platforms/pseries/pseries.h | 2 +- > 3 files changed, 34 insertions(+), 34 deletions(-) > > diff --git a/arch/powerpc/platforms/pseries/dlpar.c > b/arch/powerpc/platforms/pseries/dlpar.c > index c855233..4ea667d 100644 > --- a/arch/powerpc/platforms/pseries/dlpar.c > +++ b/arch/powerpc/platforms/pseries/dlpar.c > @@ -63,21 +63,24 @@ static struct property *dlpar_parse_cc_property(struct > cc_workarea *ccwa) > return prop; > } > > -static struct device_node *dlpar_parse_cc_node(struct cc_workarea *ccwa) > +static struct device_node *dlpar_parse_cc_node(struct cc_workarea *ccwa, > + const char *path) > { > struct device_node *dn; > char *name; > > + /* If parent node path is "/" advance path to NULL terminator to > + * prevent double leading slashs in full_name. > + */ > + if (!path[1]) > + path++; > + > dn = kzalloc(sizeof(*dn), GFP_KERNEL); > if (!dn) > return NULL; > > - /* The configure connector reported name does not contain a > - * preceding '/', so we allocate a buffer large enough to > - * prepend this to the full_name. > - */ > name = (char *)ccwa + ccwa->name_offset; > - dn->full_name = kasprintf(GFP_KERNEL, "/%s", name); > + dn->full_name = kasprintf(GFP_KERNEL, "%s/%s", path, name); > if (!dn->full_name) { > kfree(dn); > return NULL; > @@ -123,7 +126,8 @@ void dlpar_free_cc_nodes(struct device_node *dn) > #define CALL_AGAIN -2 > #define ERR_CFG_USE -9003 > > -struct device_node *dlpar_configure_connector(u32 drc_index) > +struct device_node *dlpar_configure_connector(u32 drc_index, > + struct device_node *parent) > { > struct device_node *dn; > struct device_node *first_dn = NULL; > @@ -132,6 +136,7 @@ struct device_node *dlpar_configure_connector(u32 > drc_index) > struct property *last_property = NULL; > struct cc_workarea *ccwa; > char *data_buf; > + const char *parent_path = parent->full_name; > int cc_token; > int rc = -1; > > @@ -165,7 +170,7 @@ struct device_node *dlpar_configure_connector(u32 > drc_index) > break; > > case NEXT_SIBLING: > - dn = dlpar_parse_cc_node(ccwa); > + dn = dlpar_parse_cc_node(ccwa, parent_path); > if (!dn) > goto cc_error; > > @@ -175,13 +180,17 @@ struct device_node *dlpar_configure_connector(u32 > drc_index) > break; > > case NEXT_CHILD: > - dn = dlpar_parse_cc_node(ccwa); > + if (first_dn) > + parent_path = last_dn->full_name; > + > + dn = dlpar_parse_cc_node(ccwa, parent_path); > if (!dn) > goto cc_error; > > - if (!first_dn) > + if (!first_dn) { > + dn->parent = parent; > first_dn = dn; > - else { > + } else { > dn->parent = last_dn; > if (last_dn) > last_dn->child = dn; > @@ -205,6 +214,7 @@ struct device_node *dlpar_configure_connector(u32 > drc_index) > > case PREV_PARENT: > last_dn = last_dn->parent; > + parent_path = last_dn->parent->full_name; > break; > > case CALL_AGAIN: > @@ -383,9 +393,8 @@ out: > > static ssize_t dlpar_cpu_probe(const char *buf, size_t count) > { > - struct device_node *dn; > + struct device_node *dn, *parent; > unsigned long drc_index; > - char *cpu_name; > int rc; > > cpu_hotplug_driver_lock(); > @@ -395,25 +404,19 @@ static ssize_t dlpar_cpu_probe(const char *buf, size_t > count) > goto out; > } > > - dn = dlpar_configure_connector(drc_index); > - if (!dn) { > - rc = -EINVAL; > + parent = of_find_node_by_path("/cpus"); > + if (!parent) { > + rc = -ENODEV; > goto out; > } > > - /* configure-connector reports cpus as living in the base > - * directory of the device tree. CPUs actually live in the > - * cpus directory so we need to fixup the full_name. > - */ > - cpu_name = kasprintf(GFP_KERNEL, "/cpus%s", dn->full_name); > - if (!cpu_name) { > - dlpar_free_cc_nodes(dn); > - rc = -ENOMEM; > + dn = dlpar_configure_connector(drc_index, parent); > + if (!dn) { > + rc = -EINVAL; > goto out; > } > > - kfree(dn->full_name); > - dn->full_name = cpu_name; > + of_node_put(parent); > > rc = dlpar_acquire_drc(drc_index); > if (rc) { > diff --git a/arch/powerpc/platforms/pseries/mobility.c > b/arch/powerpc/platforms/pseries/mobility.c > index ed5426f..ff102e2 100644 > --- a/arch/powerpc/platforms/pseries/mobility.c > +++ b/arch/powerpc/platforms/pseries/mobility.c > @@ -216,17 +216,14 @@ static int add_dt_node(u32 parent_phandle, u32 > drc_index) > struct device_node *parent_dn; > int rc; > > - dn = dlpar_configure_connector(drc_index); > - if (!dn) > + parent_dn = of_find_node_by_phandle(parent_phandle); > + if (!parent_dn) > return -ENOENT; > > - parent_dn = of_find_node_by_phandle(parent_phandle); > - if (!parent_dn) { > - dlpar_free_cc_nodes(dn); > + dn = dlpar_configure_connector(drc_index, parent_dn); > + if (!dn) > return -ENOENT; > - } > > - dn->parent = parent_dn; > rc = dlpar_attach_node(dn); > if (rc) > dlpar_free_cc_nodes(dn); > diff --git a/arch/powerpc/platforms/pseries/pseries.h > b/arch/powerpc/platforms/pseries/pseries.h > index c2a3a25..defb3c9 100644 > --- a/arch/powerpc/platforms/pseries/pseries.h > +++ b/arch/powerpc/platforms/pseries/pseries.h > @@ -56,7 +56,7 @@ extern void hvc_vio_init_early(void); > /* Dynamic logical Partitioning/Mobility */ > extern void dlpar_free_cc_nodes(struct device_node *); > extern void dlpar_free_cc_property(struct property *); > -extern struct device_node *dlpar_configure_connector(u32); > +extern struct device_node *dlpar_configure_connector(u32, struct device_node > *); > extern int dlpar_attach_node(struct device_node *); > extern int dlpar_detach_node(struct device_node *); > > _______________________________________________ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev