]> git.karo-electronics.de Git - linux-beck.git/commitdiff
Merge tag 'devicetree-for-linus' of git://git.secretlab.ca/git/linux-2.6
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 7 Jan 2012 20:18:52 +0000 (12:18 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 7 Jan 2012 20:18:52 +0000 (12:18 -0800)
devicetree/next changes queued for v3.3 merge window

* tag 'devicetree-for-linus-20120104' of git://git.secretlab.ca/git/linux-2.6:
  ARM: prom.h: Fix build error by removing unneeded header file
  irq: check domain hwirq range for DT translate
  dt: add empty of_get_node/of_put_node functions
  of/pdt: fix section mismatch warning
  i2c-designware: add OF binding support
  dt/i2c: Enumerate some of the known trivial i2c devices
  dt: reform for_each_property to for_each_property_of_node
  ARM/of: allow *machine_desc.dt_compat to be const
  of/base: Take NULL string into account for property with multiple strings
  OF/device-tree: Add some entries to vendor-prefixes.txt

Fix up trivial add-add conflicts in include/linux/of.h

1  2 
arch/arm/include/asm/mach/arch.h
drivers/of/base.c
include/linux/of.h
kernel/irq/irqdomain.c

index bcb0c883e21ed06aa18c9f48354314c877523a8b,02a718adb5989d5fd59e9444a2793019fed6fd37..d7692cafde7fdd3d0b4e297620fbf2dd45d611d6
@@@ -19,7 -19,7 +19,7 @@@ struct machine_desc 
        unsigned int            nr;             /* architecture number  */
        const char              *name;          /* architecture name    */
        unsigned long           atag_offset;    /* tagged list (relative) */
-       const char              **dt_compat;    /* array of device tree
+       const char *const       *dt_compat;     /* array of device tree
                                                 * 'compatible' strings */
  
        unsigned int            nr_irqs;        /* number of IRQs */
        unsigned int            video_start;    /* start of video RAM   */
        unsigned int            video_end;      /* end of video RAM     */
  
 -      unsigned int            reserve_lp0 :1; /* never has lp0        */
 -      unsigned int            reserve_lp1 :1; /* never has lp1        */
 -      unsigned int            reserve_lp2 :1; /* never has lp2        */
 -      unsigned int            soft_reboot :1; /* soft reboot          */
 +      unsigned char           reserve_lp0 :1; /* never has lp0        */
 +      unsigned char           reserve_lp1 :1; /* never has lp1        */
 +      unsigned char           reserve_lp2 :1; /* never has lp2        */
 +      char                    restart_mode;   /* default restart mode */
        void                    (*fixup)(struct tag *, char **,
                                         struct meminfo *);
        void                    (*reserve)(void);/* reserve mem blocks  */
@@@ -46,7 -46,6 +46,7 @@@
  #ifdef CONFIG_MULTI_IRQ_HANDLER
        void                    (*handle_irq)(struct pt_regs *);
  #endif
 +      void                    (*restart)(char, const char *);
  };
  
  /*
diff --combined drivers/of/base.c
index c6db9ab9046e59c59e373c7a4e4f5b45e83001da,0181eeb88c926e8ce3c2704931c62c1202426f7b..133908a6fd8db5270f3845ce387b3724d3845b7d
@@@ -752,7 -752,7 +752,7 @@@ int of_property_read_string_index(struc
  
        for (i = 0; total < prop->length; total += l, p += l) {
                l = strlen(p) + 1;
-               if ((*p != 0) && (i++ == index)) {
+               if (i++ == index) {
                        *output = p;
                        return 0;
                }
@@@ -790,11 -790,9 +790,9 @@@ int of_property_count_strings(struct de
  
        p = prop->value;
  
-       for (i = 0; total < prop->length; total += l, p += l) {
+       for (i = 0; total < prop->length; total += l, p += l, i++)
                l = strlen(p) + 1;
-               if (*p != 0)
-                       i++;
-       }
        return i;
  }
  EXPORT_SYMBOL_GPL(of_property_count_strings);
@@@ -824,19 -822,17 +822,19 @@@ of_parse_phandle(struct device_node *np
  EXPORT_SYMBOL(of_parse_phandle);
  
  /**
 - * of_parse_phandles_with_args - Find a node pointed by phandle in a list
 + * of_parse_phandle_with_args() - Find a node pointed by phandle in a list
   * @np:               pointer to a device tree node containing a list
   * @list_name:        property name that contains a list
   * @cells_name:       property name that specifies phandles' arguments count
   * @index:    index of a phandle to parse out
 - * @out_node: optional pointer to device_node struct pointer (will be filled)
 - * @out_args: optional pointer to arguments pointer (will be filled)
 + * @out_args: optional pointer to output arguments structure (will be filled)
   *
   * This function is useful to parse lists of phandles and their arguments.
 - * Returns 0 on success and fills out_node and out_args, on error returns
 - * appropriate errno value.
 + * Returns 0 on success and fills out_args, on error returns appropriate
 + * errno value.
 + *
 + * Caller is responsible to call of_node_put() on the returned out_args->node
 + * pointer.
   *
   * Example:
   *
   * }
   *
   * To get a device_node of the `node2' node you may call this:
 - * of_parse_phandles_with_args(node3, "list", "#list-cells", 2, &node2, &args);
 + * of_parse_phandle_with_args(node3, "list", "#list-cells", 1, &args);
   */
 -int of_parse_phandles_with_args(struct device_node *np, const char *list_name,
 +int of_parse_phandle_with_args(struct device_node *np, const char *list_name,
                                const char *cells_name, int index,
 -                              struct device_node **out_node,
 -                              const void **out_args)
 +                              struct of_phandle_args *out_args)
  {
 -      int ret = -EINVAL;
 -      const __be32 *list;
 -      const __be32 *list_end;
 -      int size;
 -      int cur_index = 0;
 +      const __be32 *list, *list_end;
 +      int size, cur_index = 0;
 +      uint32_t count = 0;
        struct device_node *node = NULL;
 -      const void *args = NULL;
 +      phandle phandle;
  
 +      /* Retrieve the phandle list property */
        list = of_get_property(np, list_name, &size);
 -      if (!list) {
 -              ret = -ENOENT;
 -              goto err0;
 -      }
 +      if (!list)
 +              return -EINVAL;
        list_end = list + size / sizeof(*list);
  
 +      /* Loop over the phandles until all the requested entry is found */
        while (list < list_end) {
 -              const __be32 *cells;
 -              phandle phandle;
 +              count = 0;
  
 +              /*
 +               * If phandle is 0, then it is an empty entry with no
 +               * arguments.  Skip forward to the next entry.
 +               */
                phandle = be32_to_cpup(list++);
 -              args = list;
 -
 -              /* one cell hole in the list = <>; */
 -              if (!phandle)
 -                      goto next;
 -
 -              node = of_find_node_by_phandle(phandle);
 -              if (!node) {
 -                      pr_debug("%s: could not find phandle\n",
 -                               np->full_name);
 -                      goto err0;
 -              }
 +              if (phandle) {
 +                      /*
 +                       * Find the provider node and parse the #*-cells
 +                       * property to determine the argument length
 +                       */
 +                      node = of_find_node_by_phandle(phandle);
 +                      if (!node) {
 +                              pr_err("%s: could not find phandle\n",
 +                                       np->full_name);
 +                              break;
 +                      }
 +                      if (of_property_read_u32(node, cells_name, &count)) {
 +                              pr_err("%s: could not get %s for %s\n",
 +                                       np->full_name, cells_name,
 +                                       node->full_name);
 +                              break;
 +                      }
  
 -              cells = of_get_property(node, cells_name, &size);
 -              if (!cells || size != sizeof(*cells)) {
 -                      pr_debug("%s: could not get %s for %s\n",
 -                               np->full_name, cells_name, node->full_name);
 -                      goto err1;
 +                      /*
 +                       * Make sure that the arguments actually fit in the
 +                       * remaining property data length
 +                       */
 +                      if (list + count > list_end) {
 +                              pr_err("%s: arguments longer than property\n",
 +                                       np->full_name);
 +                              break;
 +                      }
                }
  
 -              list += be32_to_cpup(cells);
 -              if (list > list_end) {
 -                      pr_debug("%s: insufficient arguments length\n",
 -                               np->full_name);
 -                      goto err1;
 +              /*
 +               * All of the error cases above bail out of the loop, so at
 +               * this point, the parsing is successful. If the requested
 +               * index matches, then fill the out_args structure and return,
 +               * or return -ENOENT for an empty entry.
 +               */
 +              if (cur_index == index) {
 +                      if (!phandle)
 +                              return -ENOENT;
 +
 +                      if (out_args) {
 +                              int i;
 +                              if (WARN_ON(count > MAX_PHANDLE_ARGS))
 +                                      count = MAX_PHANDLE_ARGS;
 +                              out_args->np = node;
 +                              out_args->args_count = count;
 +                              for (i = 0; i < count; i++)
 +                                      out_args->args[i] = be32_to_cpup(list++);
 +                      }
 +                      return 0;
                }
 -next:
 -              if (cur_index == index)
 -                      break;
  
                of_node_put(node);
                node = NULL;
 -              args = NULL;
 +              list += count;
                cur_index++;
        }
  
 -      if (!node) {
 -              /*
 -               * args w/o node indicates that the loop above has stopped at
 -               * the 'hole' cell. Report this differently.
 -               */
 -              if (args)
 -                      ret = -EEXIST;
 -              else
 -                      ret = -ENOENT;
 -              goto err0;
 -      }
 -
 -      if (out_node)
 -              *out_node = node;
 -      if (out_args)
 -              *out_args = args;
 -
 -      return 0;
 -err1:
 -      of_node_put(node);
 -err0:
 -      pr_debug("%s failed with status %d\n", __func__, ret);
 -      return ret;
 +      /* Loop exited without finding a valid entry; return an error */
 +      if (node)
 +              of_node_put(node);
 +      return -EINVAL;
  }
 -EXPORT_SYMBOL(of_parse_phandles_with_args);
 +EXPORT_SYMBOL(of_parse_phandle_with_args);
  
  /**
   * prom_add_property - Add a property to a node
@@@ -1163,7 -1157,7 +1161,7 @@@ void of_alias_scan(void * (*dt_alloc)(u
        if (!of_aliases)
                return;
  
-       for_each_property(pp, of_aliases->properties) {
+       for_each_property_of_node(of_aliases, pp) {
                const char *start = pp->name;
                const char *end = start + strlen(start);
                struct device_node *np;
diff --combined include/linux/of.h
index ea44fd72af5fb02e02550e2163e4e7860eacf301,9abd3ec3c2ac1e54a53cc2d2961d92ecda679a89..a75a831e2057f96e3519d100f988a584e18ac669
@@@ -65,13 -65,20 +65,27 @@@ struct device_node 
  #endif
  };
  
 +#define MAX_PHANDLE_ARGS 8
 +struct of_phandle_args {
 +      struct device_node *np;
 +      int args_count;
 +      uint32_t args[MAX_PHANDLE_ARGS];
 +};
 +
+ #if defined(CONFIG_SPARC) || !defined(CONFIG_OF)
+ /* Dummy ref counting routines - to be implemented later */
+ static inline struct device_node *of_node_get(struct device_node *node)
+ {
+       return node;
+ }
+ static inline void of_node_put(struct device_node *node)
+ {
+ }
+ #else
+ extern struct device_node *of_node_get(struct device_node *node);
+ extern void of_node_put(struct device_node *node);
+ #endif
  #ifdef CONFIG_OF
  
  /* Pointer for first entry in chain of all nodes. */
@@@ -102,21 -109,6 +116,6 @@@ static inline void of_node_set_flag(str
  
  extern struct device_node *of_find_all_nodes(struct device_node *prev);
  
- #if defined(CONFIG_SPARC)
- /* Dummy ref counting routines - to be implemented later */
- static inline struct device_node *of_node_get(struct device_node *node)
- {
-       return node;
- }
- static inline void of_node_put(struct device_node *node)
- {
- }
- #else
- extern struct device_node *of_node_get(struct device_node *node);
- extern void of_node_put(struct device_node *node);
- #endif
  /*
   * OF address retrieval & translation
   */
@@@ -226,8 -218,8 +225,8 @@@ extern int of_device_is_available(cons
  extern const void *of_get_property(const struct device_node *node,
                                const char *name,
                                int *lenp);
- #define for_each_property(pp, properties) \
-       for (pp = properties; pp != NULL; pp = pp->next)
+ #define for_each_property_of_node(dn, pp) \
+       for (pp = dn->properties; pp != NULL; pp = pp->next)
  
  extern int of_n_addr_cells(struct device_node *np);
  extern int of_n_size_cells(struct device_node *np);
@@@ -237,9 -229,9 +236,9 @@@ extern int of_modalias_node(struct devi
  extern struct device_node *of_parse_phandle(struct device_node *np,
                                            const char *phandle_name,
                                            int index);
 -extern int of_parse_phandles_with_args(struct device_node *np,
 +extern int of_parse_phandle_with_args(struct device_node *np,
        const char *list_name, const char *cells_name, int index,
 -      struct device_node **out_node, const void **out_args);
 +      struct of_phandle_args *out_args);
  
  extern void of_alias_scan(void * (*dt_alloc)(u64 size, u64 align));
  extern int of_alias_get_id(struct device_node *np, const char *stem);
diff --combined kernel/irq/irqdomain.c
index 7ca523b249ef55fbfa551555b268236763bac80b,8bd7479b83905243ddd8af60ce3ebeba0901c317..1f9e26526b69961ad73d3ddc1d0b788b6ca291d7
@@@ -135,6 -135,9 +135,9 @@@ int irq_domain_simple_dt_translate(stru
                return -EINVAL;
        if (intsize < 1)
                return -EINVAL;
+       if (d->nr_irq && ((intspec[0] < d->hwirq_base) ||
+           (intspec[0] >= d->hwirq_base + d->nr_irq)))
+               return -EINVAL;
  
        *out_hwirq = intspec[0];
        *out_type = IRQ_TYPE_NONE;
        return 0;
  }
  
 -struct irq_domain_ops irq_domain_simple_ops = {
 -      .dt_translate = irq_domain_simple_dt_translate,
 -};
 -EXPORT_SYMBOL_GPL(irq_domain_simple_ops);
 -
  /**
   * irq_domain_create_simple() - Set up a 'simple' translation range
   */
@@@ -177,10 -185,3 +180,10 @@@ void irq_domain_generate_simple(const s
  }
  EXPORT_SYMBOL_GPL(irq_domain_generate_simple);
  #endif /* CONFIG_OF_IRQ */
 +
 +struct irq_domain_ops irq_domain_simple_ops = {
 +#ifdef CONFIG_OF_IRQ
 +      .dt_translate = irq_domain_simple_dt_translate,
 +#endif /* CONFIG_OF_IRQ */
 +};
 +EXPORT_SYMBOL_GPL(irq_domain_simple_ops);