]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
Merge remote-tracking branch 'devicetree/devicetree/next'
authorThierry Reding <treding@nvidia.com>
Thu, 24 Oct 2013 12:37:22 +0000 (14:37 +0200)
committerThierry Reding <treding@nvidia.com>
Thu, 24 Oct 2013 12:37:22 +0000 (14:37 +0200)
arch/sparc/kernel/prom_64.c
drivers/of/address.c
drivers/of/base.c
drivers/of/irq.c
include/linux/cpu.h

index d397d7fc5c2830e288ddc60abc0c6465368db28f..6b39125eb9271d986b32896fcd35015cbd752ef8 100644 (file)
@@ -373,6 +373,59 @@ static const char *get_mid_prop(void)
        return (tlb_type == spitfire ? "upa-portid" : "portid");
 }
 
+bool arch_find_n_match_cpu_physical_id(struct device_node *cpun,
+                                      int cpu, unsigned int *thread)
+{
+       const char *mid_prop = get_mid_prop();
+       int this_cpu_id;
+
+       /* On hypervisor based platforms we interrogate the 'reg'
+        * property.  On everything else we look for a 'upa-portis',
+        * 'portid', or 'cpuid' property.
+        */
+
+       if (tlb_type == hypervisor) {
+               struct property *prop = of_find_property(cpun, "reg", NULL);
+               u32 *regs;
+
+               if (!prop) {
+                       pr_warn("CPU node missing reg property\n");
+                       return false;
+               }
+               regs = prop->value;
+               this_cpu_id = regs[0] & 0x0fffffff;
+       } else {
+               this_cpu_id = of_getintprop_default(cpun, mid_prop, -1);
+
+               if (this_cpu_id < 0) {
+                       mid_prop = "cpuid";
+                       this_cpu_id = of_getintprop_default(cpun, mid_prop, -1);
+               }
+               if (this_cpu_id < 0) {
+                       pr_warn("CPU node missing cpu ID property\n");
+                       return false;
+               }
+       }
+       if (this_cpu_id == cpu) {
+               if (thread) {
+                       int proc_id = cpu_data(cpu).proc_id;
+
+                       /* On sparc64, the cpu thread information is obtained
+                        * either from OBP or the machine description.  We've
+                        * actually probed this information already long before
+                        * this interface gets called so instead of interrogating
+                        * both the OF node and the MDESC again, just use what
+                        * we discovered already.
+                        */
+                       if (proc_id < 0)
+                               proc_id = 0;
+                       *thread = proc_id;
+               }
+               return true;
+       }
+       return false;
+}
+
 static void *of_iterate_over_cpus(void *(*func)(struct device_node *, int, int), int arg)
 {
        struct device_node *dp;
index b55c2189076064c1d9a8015079370046ad8ae615..71180b91bfbe7d9ef3167fe497cea72fb890f515 100644 (file)
@@ -489,7 +489,7 @@ static u64 __of_translate_address(struct device_node *dev,
        int na, ns, pna, pns;
        u64 result = OF_BAD_ADDR;
 
-       pr_debug("OF: ** translation for device %s **\n", dev->full_name);
+       pr_debug("OF: ** translation for device %s **\n", of_node_full_name(dev));
 
        /* Increase refcount at current level */
        of_node_get(dev);
@@ -504,13 +504,13 @@ static u64 __of_translate_address(struct device_node *dev,
        bus->count_cells(dev, &na, &ns);
        if (!OF_CHECK_COUNTS(na, ns)) {
                printk(KERN_ERR "prom_parse: Bad cell count for %s\n",
-                      dev->full_name);
+                      of_node_full_name(dev));
                goto bail;
        }
        memcpy(addr, in_addr, na * 4);
 
        pr_debug("OF: bus is %s (na=%d, ns=%d) on %s\n",
-           bus->name, na, ns, parent->full_name);
+           bus->name, na, ns, of_node_full_name(parent));
        of_dump_addr("OF: translating address:", addr, na);
 
        /* Translate */
index 7d4c70f859e30687bcd0892c195f9cbfc34826dc..3ae106d8979149e57fb1bce2cab413191014da39 100644 (file)
@@ -265,9 +265,9 @@ static bool __of_find_n_match_cpu_property(struct device_node *cpun,
 
        ac = of_n_addr_cells(cpun);
        cell = of_get_property(cpun, prop_name, &prop_len);
-       if (!cell)
+       if (!cell || !ac)
                return false;
-       prop_len /= sizeof(*cell);
+       prop_len /= sizeof(*cell) * ac;
        for (tid = 0; tid < prop_len; tid++) {
                hwid = of_read_number(cell, ac);
                if (arch_match_cpu_phys_id(cpu, hwid)) {
@@ -280,6 +280,31 @@ static bool __of_find_n_match_cpu_property(struct device_node *cpun,
        return false;
 }
 
+/*
+ * arch_find_n_match_cpu_physical_id - See if the given device node is
+ * for the cpu corresponding to logical cpu 'cpu'.  Return true if so,
+ * else false.  If 'thread' is non-NULL, the local thread number within the
+ * core is returned in it.
+ */
+bool __weak arch_find_n_match_cpu_physical_id(struct device_node *cpun,
+                                             int cpu, unsigned int *thread)
+{
+       /* Check for non-standard "ibm,ppc-interrupt-server#s" property
+        * for thread ids on PowerPC. If it doesn't exist fallback to
+        * standard "reg" property.
+        */
+       if (IS_ENABLED(CONFIG_PPC) &&
+           __of_find_n_match_cpu_property(cpun,
+                                          "ibm,ppc-interrupt-server#s",
+                                          cpu, thread))
+               return true;
+
+       if (__of_find_n_match_cpu_property(cpun, "reg", cpu, thread))
+               return true;
+
+       return false;
+}
+
 /**
  * of_get_cpu_node - Get device node associated with the given logical CPU
  *
@@ -300,24 +325,10 @@ static bool __of_find_n_match_cpu_property(struct device_node *cpun,
  */
 struct device_node *of_get_cpu_node(int cpu, unsigned int *thread)
 {
-       struct device_node *cpun, *cpus;
-
-       cpus = of_find_node_by_path("/cpus");
-       if (!cpus)
-               return NULL;
+       struct device_node *cpun;
 
-       for_each_child_of_node(cpus, cpun) {
-               if (of_node_cmp(cpun->type, "cpu"))
-                       continue;
-               /* Check for non-standard "ibm,ppc-interrupt-server#s" property
-                * for thread ids on PowerPC. If it doesn't exist fallback to
-                * standard "reg" property.
-                */
-               if (IS_ENABLED(CONFIG_PPC) &&
-                       __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))
+       for_each_node_by_type(cpun, "cpu") {
+               if (arch_find_n_match_cpu_physical_id(cpun, cpu, thread))
                        return cpun;
        }
        return NULL;
index 1752988d6aa80224ced68ab6e62744c77e8ab4be..90068f91491152da9d6445bd50cfbec1a5e163b0 100644 (file)
@@ -102,7 +102,7 @@ int of_irq_map_raw(struct device_node *parent, const __be32 *intspec,
        int imaplen, match, i;
 
        pr_debug("of_irq_map_raw: par=%s,intspec=[0x%08x 0x%08x...],ointsize=%d\n",
-                parent->full_name, be32_to_cpup(intspec),
+                of_node_full_name(parent), be32_to_cpup(intspec),
                 be32_to_cpup(intspec + 1), ointsize);
 
        ipar = of_node_get(parent);
@@ -126,7 +126,7 @@ int of_irq_map_raw(struct device_node *parent, const __be32 *intspec,
                goto fail;
        }
 
-       pr_debug("of_irq_map_raw: ipar=%s, size=%d\n", ipar->full_name, intsize);
+       pr_debug("of_irq_map_raw: ipar=%s, size=%d\n", of_node_full_name(ipar), intsize);
 
        if (ointsize != intsize)
                return -EINVAL;
@@ -287,7 +287,7 @@ int of_irq_map_one(struct device_node *device, int index, struct of_irq *out_irq
        u32 intsize, intlen;
        int res = -EINVAL;
 
-       pr_debug("of_irq_map_one: dev=%s, index=%d\n", device->full_name, index);
+       pr_debug("of_irq_map_one: dev=%s, index=%d\n", of_node_full_name(device), index);
 
        /* OldWorld mac stuff is "special", handle out of line */
        if (of_irq_workarounds & OF_IMAP_OLDWORLD_MAC)
@@ -354,8 +354,8 @@ int of_irq_to_resource(struct device_node *dev, int index, struct resource *r)
                                              &name);
 
                r->start = r->end = irq;
-               r->flags = IORESOURCE_IRQ;
-               r->name = name ? name : dev->full_name;
+               r->flags = IORESOURCE_IRQ | irqd_get_trigger_type(irq_get_irq_data(irq));
+               r->name = name ? name : of_node_full_name(dev);
        }
 
        return irq;
index 3434ef7de017de0d5a33e7dd5dbfb173678c58c0..03e235ad1bba31bf4ba7fe155d9d64566179866c 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/cpumask.h>
 
 struct device;
+struct device_node;
 
 struct cpu {
        int node_id;            /* The node which contains the CPU */
@@ -29,6 +30,8 @@ extern int register_cpu(struct cpu *cpu, int num);
 extern struct device *get_cpu_device(unsigned cpu);
 extern bool cpu_is_hotpluggable(unsigned cpu);
 extern bool arch_match_cpu_phys_id(int cpu, u64 phys_id);
+extern bool arch_find_n_match_cpu_physical_id(struct device_node *cpun,
+                                             int cpu, unsigned int *thread);
 
 extern int cpu_add_dev_attr(struct device_attribute *attr);
 extern void cpu_remove_dev_attr(struct device_attribute *attr);