Re: [RFC PATCH 3/4] powerpc: refactor of_get_cpu_node to supportother architectures

From: Benjamin Herrenschmidt
Date: Fri Aug 16 2013 - 00:55:48 EST


On Thu, 2013-08-15 at 18:09 +0100, Sudeep KarkadaNagesha wrote:
> From: Sudeep KarkadaNagesha <sudeep.karkadanagesha@xxxxxxx>
>
> Currently different drivers requiring to access cpu device node are
> parsing the device tree themselves. Since the ordering in the DT need
> not match the logical cpu ordering, the parsing logic needs to consider
> that. However, this has resulted in lots of code duplication and in some
> cases even incorrect logic.

.../...

>
> +bool arch_match_cpu_phys_id(int cpu, u64 phys_id)
> +{
> + return (int)phys_id == get_hard_smp_processor_id(cpu);
> +}

Naming is a bit gross. You might want to make it clearer that
we are talking about CPU IDs in the device-tree here.

> +static bool __of_find_n_match_cpu_property(struct device_node *cpun,
> + const char *prop_name, int cpu, unsigned int *thread)
> +{
> + const __be32 *cell;
> + int ac, prop_len, tid;
> + u64 hwid;
> +
> + ac = of_n_addr_cells(cpun);
> + cell = of_get_property(cpun, prop_name, &prop_len);
> + if (!cell)
> + return false;
> + prop_len /= sizeof(*cell);
> + for (tid = 0; tid < prop_len; tid++) {
> + hwid = of_read_number(cell, ac);
> + if (arch_match_cpu_phys_id(cpu, hwid)) {
> + if (thread)
> + *thread = tid;
> + return true;
> + }

Missing: cell += ac;

> + }
> + return false;
> +}
> +
> /* Find the device node for a given logical cpu number, also returns the cpu
> * local thread number (index in ibm,interrupt-server#s) if relevant and
> * asked for (non NULL)
> */
> struct device_node *of_get_cpu_node(int cpu, unsigned int *thread)
> {
> - int hardid;
> - struct device_node *np;
> + struct device_node *cpun, *cpus;
>
> - hardid = get_hard_smp_processor_id(cpu);
> + cpus = of_find_node_by_path("/cpus");
> + if (!cpus) {
> + pr_warn("Missing cpus node, bailing out\n");
> + return NULL;
> + }
>
> - for_each_node_by_type(np, "cpu") {
> - const u32 *intserv;
> - unsigned int plen, t;
> + for_each_child_of_node(cpus, cpun) {
> + if (of_node_cmp(cpun->type, "cpu"))
> + continue;
>
> /* Check for ibm,ppc-interrupt-server#s. If it doesn't exist
> * fallback to "reg" property and assume no threads
> */
> - intserv = of_get_property(np, "ibm,ppc-interrupt-server#s",
> - &plen);
> - if (intserv == NULL) {
> - const u32 *reg = of_get_property(np, "reg", NULL);
> - if (reg == NULL)
> - continue;
> - if (*reg == hardid) {
> - if (thread)
> - *thread = 0;
> - return np;
> - }
> - } else {
> - plen /= sizeof(u32);
> - for (t = 0; t < plen; t++) {
> - if (hardid == intserv[t]) {
> - if (thread)
> - *thread = t;
> - return np;
> - }
> - }
> - }
> + if (__of_find_n_match_cpu_property(cpun,
> + "ibm,ppc-interrupt-server#s", cpu, thread))
> + return cpun;
> +
> + if (__of_find_n_match_cpu_property(cpun, "reg", cpu, thread))
> + return cpun;
> }
> return NULL;
> }

Cheers,
Ben.


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/