[PATCH 6/8] powerpc/pseries: make dlpar_configure_connector parent node aware
Nathan Fontenot
nfont at linux.vnet.ibm.com
Mon Aug 19 23:53:45 EST 2013
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 <tyreld at linux.vnet.ibm.com>
Acked-by: Nathan Fontenot <nfont at 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 *);
>
>
More information about the Linuxppc-dev
mailing list