Merge tag 'dt-for-3.6' of git://sources.calxeda.com/kernel/linux
Linus Torvalds [Tue, 24 Jul 2012 21:07:22 +0000 (14:07 -0700)]
Pull devicetree updates from Rob Herring:
 "A small set of changes for devicetree:
   - Couple of Documentation fixes
   - Addition of new helper function of_node_full_name
   - Improve of_parse_phandle_with_args return values
   - Some NULL related sparse fixes"

Grant's busy packing.

* tag 'dt-for-3.6' of git://sources.calxeda.com/kernel/linux:
  of: mtd: nuke useless const qualifier
  devicetree: add helper inline for retrieving a node's full name
  of: return -ENOENT when no property
  usage-model.txt: fix typo machine_init->init_machine
  of: Fix null pointer related warnings in base.c file
  LED: Fix missing semicolon in OF documentation
  of: fix a few typos in the binding documentation

1  2 
arch/powerpc/kernel/pci-common.c
arch/powerpc/kernel/vio.c
arch/powerpc/platforms/cell/iommu.c
arch/powerpc/platforms/pseries/iommu.c
drivers/of/base.c
include/linux/of.h

@@@ -248,8 -248,7 +248,7 @@@ static int pci_read_irq_line(struct pci
        } else {
                pr_debug(" Got one, spec %d cells (0x%08x 0x%08x...) on %s\n",
                         oirq.size, oirq.specifier[0], oirq.specifier[1],
-                        oirq.controller ? oirq.controller->full_name :
-                        "<default>");
+                        of_node_full_name(oirq.controller));
  
                virq = irq_create_of_mapping(oirq.controller, oirq.specifier,
                                             oirq.size);
@@@ -1628,8 -1627,7 +1627,7 @@@ void __devinit pcibios_scan_phb(struct 
        struct device_node *node = hose->dn;
        int mode;
  
-       pr_debug("PCI: Scanning PHB %s\n",
-                node ? node->full_name : "<NO NAME>");
+       pr_debug("PCI: Scanning PHB %s\n", of_node_full_name(node));
  
        /* Get some IO space for the new PHB */
        pcibios_setup_phb_io_space(hose);
                pci_free_resource_list(&resources);
                return;
        }
 -      bus->secondary = hose->first_busno;
        hose->bus = bus;
  
        /* Get probe mode and perform scan */
@@@ -37,6 -37,8 +37,6 @@@
  #include <asm/page.h>
  #include <asm/hvcall.h>
  
 -static struct bus_type vio_bus_type;
 -
  static struct vio_dev vio_bus_device  = { /* fake "parent" device */
        .name = "vio",
        .type = "",
@@@ -623,7 -625,7 +623,7 @@@ struct dma_map_ops vio_dma_mapping_ops 
   * vio_cmo_set_dev_desired - Set desired entitlement for a device
   *
   * @viodev: struct vio_dev for device to alter
 - * @new_desired: new desired entitlement level in bytes
 + * @desired: new desired entitlement level in bytes
   *
   * For use by devices to request a change to their entitlement at runtime or
   * through sysfs.  The desired entitlement level is changed and a balancing
@@@ -1260,7 -1262,7 +1260,7 @@@ static int vio_bus_remove(struct devic
  
  /**
   * vio_register_driver: - Register a new vio driver
 - * @drv:      The vio_driver structure to be registered.
 + * @viodrv:   The vio_driver structure to be registered.
   */
  int __vio_register_driver(struct vio_driver *viodrv, struct module *owner,
                          const char *mod_name)
@@@ -1280,7 -1282,7 +1280,7 @@@ EXPORT_SYMBOL(__vio_register_driver)
  
  /**
   * vio_unregister_driver - Remove registration of vio driver.
 - * @driver:   The vio_driver struct to be removed form registration
 + * @viodrv:   The vio_driver struct to be removed form registration
   */
  void vio_unregister_driver(struct vio_driver *viodrv)
  {
@@@ -1294,8 -1296,7 +1294,7 @@@ static void __devinit vio_dev_release(s
        struct iommu_table *tbl = get_iommu_table_base(dev);
  
        if (tbl)
-               iommu_free_table(tbl, dev->of_node ?
-                       dev->of_node->full_name : dev_name(dev));
+               iommu_free_table(tbl, of_node_full_name(dev->of_node));
        of_node_put(dev->of_node);
        kfree(to_vio_dev(dev));
  }
@@@ -1395,27 -1396,21 +1394,27 @@@ struct vio_dev *vio_register_device_nod
        viodev->name = of_node->name;
        viodev->dev.of_node = of_node_get(of_node);
  
 -      if (firmware_has_feature(FW_FEATURE_CMO))
 -              vio_cmo_set_dma_ops(viodev);
 -      else
 -              set_dma_ops(&viodev->dev, &dma_iommu_ops);
 -      set_iommu_table_base(&viodev->dev, vio_build_iommu_table(viodev));
        set_dev_node(&viodev->dev, of_node_to_nid(of_node));
  
        /* init generic 'struct device' fields: */
        viodev->dev.parent = &vio_bus_device.dev;
        viodev->dev.bus = &vio_bus_type;
        viodev->dev.release = vio_dev_release;
 -        /* needed to ensure proper operation of coherent allocations
 -         * later, in case driver doesn't set it explicitly */
 -        dma_set_mask(&viodev->dev, DMA_BIT_MASK(64));
 -        dma_set_coherent_mask(&viodev->dev, DMA_BIT_MASK(64));
 +
 +      if (of_get_property(viodev->dev.of_node, "ibm,my-dma-window", NULL)) {
 +              if (firmware_has_feature(FW_FEATURE_CMO))
 +                      vio_cmo_set_dma_ops(viodev);
 +              else
 +                      set_dma_ops(&viodev->dev, &dma_iommu_ops);
 +
 +              set_iommu_table_base(&viodev->dev,
 +                                   vio_build_iommu_table(viodev));
 +
 +              /* needed to ensure proper operation of coherent allocations
 +               * later, in case driver doesn't set it explicitly */
 +              dma_set_mask(&viodev->dev, DMA_BIT_MASK(64));
 +              dma_set_coherent_mask(&viodev->dev, DMA_BIT_MASK(64));
 +      }
  
        /* register with generic device framework */
        if (device_register(&viodev->dev)) {
@@@ -1495,18 -1490,12 +1494,18 @@@ static int __init vio_bus_init(void
        if (firmware_has_feature(FW_FEATURE_CMO))
                vio_cmo_bus_init();
  
 +      return 0;
 +}
 +postcore_initcall(vio_bus_init);
 +
 +static int __init vio_device_init(void)
 +{
        vio_bus_scan_register_devices("vdevice");
        vio_bus_scan_register_devices("ibm,platform-facilities");
  
        return 0;
  }
 -__initcall(vio_bus_init);
 +device_initcall(vio_device_init);
  
  static ssize_t name_show(struct device *dev,
                struct device_attribute *attr, char *buf)
@@@ -1519,7 -1508,7 +1518,7 @@@ static ssize_t devspec_show(struct devi
  {
        struct device_node *of_node = dev->of_node;
  
-       return sprintf(buf, "%s\n", of_node ? of_node->full_name : "none");
+       return sprintf(buf, "%s\n", of_node_full_name(of_node));
  }
  
  static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
@@@ -1578,7 -1567,7 +1577,7 @@@ static int vio_hotplug(struct device *d
        return 0;
  }
  
 -static struct bus_type vio_bus_type = {
 +struct bus_type vio_bus_type = {
        .name = "vio",
        .dev_attrs = vio_dev_attrs,
        .uevent = vio_hotplug,
@@@ -518,6 -518,7 +518,6 @@@ cell_iommu_setup_window(struct cbe_iomm
        __set_bit(0, window->table.it_map);
        tce_build_cell(&window->table, window->table.it_offset, 1,
                       (unsigned long)iommu->pad_page, DMA_TO_DEVICE, NULL);
 -      window->table.it_hint = window->table.it_blocksize;
  
        return window;
  }
@@@ -551,8 -552,7 +551,7 @@@ static struct iommu_table *cell_get_iom
        iommu = cell_iommu_for_node(dev_to_node(dev));
        if (iommu == NULL || list_empty(&iommu->windows)) {
                printk(KERN_ERR "iommu: missing iommu for %s (node %d)\n",
-                      dev->of_node ? dev->of_node->full_name : "?",
-                      dev_to_node(dev));
+                      of_node_full_name(dev->of_node), dev_to_node(dev));
                return NULL;
        }
        window = list_entry(iommu->windows.next, struct iommu_window, list);
@@@ -192,15 -192,12 +192,15 @@@ static int tce_buildmulti_pSeriesLP(str
        long l, limit;
        long tcenum_start = tcenum, npages_start = npages;
        int ret = 0;
 +      unsigned long flags;
  
        if (npages == 1) {
                return tce_build_pSeriesLP(tbl, tcenum, npages, uaddr,
                                           direction, attrs);
        }
  
 +      local_irq_save(flags);  /* to protect tcep and the page behind it */
 +
        tcep = __get_cpu_var(tce_page);
  
        /* This is safe to do since interrupts are off when we're called
                tcep = (u64 *)__get_free_page(GFP_ATOMIC);
                /* If allocation fails, fall back to the loop implementation */
                if (!tcep) {
 +                      local_irq_restore(flags);
                        return tce_build_pSeriesLP(tbl, tcenum, npages, uaddr,
                                            direction, attrs);
                }
                tcenum += limit;
        } while (npages > 0 && !rc);
  
 +      local_irq_restore(flags);
 +
        if (unlikely(rc == H_NOT_ENOUGH_RESOURCES)) {
                ret = (int)rc;
                tce_freemulti_pSeriesLP(tbl, tcenum_start,
@@@ -713,21 -707,6 +713,21 @@@ static int __init disable_ddw_setup(cha
  
  early_param("disable_ddw", disable_ddw_setup);
  
 +static inline void __remove_ddw(struct device_node *np, const u32 *ddw_avail, u64 liobn)
 +{
 +      int ret;
 +
 +      ret = rtas_call(ddw_avail[2], 1, 1, NULL, liobn);
 +      if (ret)
 +              pr_warning("%s: failed to remove DMA window: rtas returned "
 +                      "%d to ibm,remove-pe-dma-window(%x) %llx\n",
 +                      np->full_name, ret, ddw_avail[2], liobn);
 +      else
 +              pr_debug("%s: successfully removed DMA window: rtas returned "
 +                      "%d to ibm,remove-pe-dma-window(%x) %llx\n",
 +                      np->full_name, ret, ddw_avail[2], liobn);
 +}
 +
  static void remove_ddw(struct device_node *np)
  {
        struct dynamic_dma_window_prop *dwp;
                pr_debug("%s successfully cleared tces in window.\n",
                         np->full_name);
  
 -      ret = rtas_call(ddw_avail[2], 1, 1, NULL, liobn);
 -      if (ret)
 -              pr_warning("%s: failed to remove direct window: rtas returned "
 -                      "%d to ibm,remove-pe-dma-window(%x) %llx\n",
 -                      np->full_name, ret, ddw_avail[2], liobn);
 -      else
 -              pr_debug("%s: successfully removed direct window: rtas returned "
 -                      "%d to ibm,remove-pe-dma-window(%x) %llx\n",
 -                      np->full_name, ret, ddw_avail[2], liobn);
 +      __remove_ddw(np, ddw_avail, liobn);
  
  delprop:
        ret = prom_remove_property(np, win64);
@@@ -882,35 -869,6 +882,35 @@@ static int create_ddw(struct pci_dev *d
        return ret;
  }
  
 +static void restore_default_window(struct pci_dev *dev,
 +                              u32 ddw_restore_token, unsigned long liobn)
 +{
 +      struct eeh_dev *edev;
 +      u32 cfg_addr;
 +      u64 buid;
 +      int ret;
 +
 +      /*
 +       * Get the config address and phb buid of the PE window.
 +       * Rely on eeh to retrieve this for us.
 +       * Retrieve them from the pci device, not the node with the
 +       * dma-window property
 +       */
 +      edev = pci_dev_to_eeh_dev(dev);
 +      cfg_addr = edev->config_addr;
 +      if (edev->pe_config_addr)
 +              cfg_addr = edev->pe_config_addr;
 +      buid = edev->phb->buid;
 +
 +      do {
 +              ret = rtas_call(ddw_restore_token, 3, 1, NULL, cfg_addr,
 +                                      BUID_HI(buid), BUID_LO(buid));
 +      } while (rtas_busy_delay(ret));
 +      dev_info(&dev->dev,
 +              "ibm,reset-pe-dma-windows(%x) %x %x %x returned %d\n",
 +               ddw_restore_token, cfg_addr, BUID_HI(buid), BUID_LO(buid), ret);
 +}
 +
  /*
   * If the PE supports dynamic dma windows, and there is space for a table
   * that can map all pages in a linear offset, then setup such a table,
@@@ -931,13 -889,9 +931,13 @@@ static u64 enable_ddw(struct pci_dev *d
        u64 dma_addr, max_addr;
        struct device_node *dn;
        const u32 *uninitialized_var(ddw_avail);
 +      const u32 *uninitialized_var(ddw_extensions);
 +      u32 ddw_restore_token = 0;
        struct direct_window *window;
        struct property *win64;
        struct dynamic_dma_window_prop *ddwprop;
 +      const void *dma_window = NULL;
 +      unsigned long liobn, offset, size;
  
        mutex_lock(&direct_window_init_mutex);
  
        if (!ddw_avail || len < 3 * sizeof(u32))
                goto out_unlock;
  
 -       /*
 +      /*
 +       * the extensions property is only required to exist in certain
 +       * levels of firmware and later
 +       * the ibm,ddw-extensions property is a list with the first
 +       * element containing the number of extensions and each
 +       * subsequent entry is a value corresponding to that extension
 +       */
 +      ddw_extensions = of_get_property(pdn, "ibm,ddw-extensions", &len);
 +      if (ddw_extensions) {
 +              /*
 +               * each new defined extension length should be added to
 +               * the top of the switch so the "earlier" entries also
 +               * get picked up
 +               */
 +              switch (ddw_extensions[0]) {
 +                      /* ibm,reset-pe-dma-windows */
 +                      case 1:
 +                              ddw_restore_token = ddw_extensions[1];
 +                              break;
 +              }
 +      }
 +
 +      /*
 +       * Only remove the existing DMA window if we can restore back to
 +       * the default state. Removing the existing window maximizes the
 +       * resources available to firmware for dynamic window creation.
 +       */
 +      if (ddw_restore_token) {
 +              dma_window = of_get_property(pdn, "ibm,dma-window", NULL);
 +              of_parse_dma_window(pdn, dma_window, &liobn, &offset, &size);
 +              __remove_ddw(pdn, ddw_avail, liobn);
 +      }
 +
 +      /*
         * Query if there is a second window of size to map the
         * whole partition.  Query returns number of windows, largest
         * block assigned to PE (partition endpoint), and two bitmasks
        dn = pci_device_to_OF_node(dev);
        ret = query_ddw(dev, ddw_avail, &query);
        if (ret != 0)
 -              goto out_unlock;
 +              goto out_restore_window;
  
        if (query.windows_available == 0) {
                /*
                 * trading in for a larger page size.
                 */
                dev_dbg(&dev->dev, "no free dynamic windows");
 -              goto out_unlock;
 +              goto out_restore_window;
        }
        if (query.page_size & 4) {
                page_shift = 24; /* 16MB */
        } else {
                dev_dbg(&dev->dev, "no supported direct page size in mask %x",
                          query.page_size);
 -              goto out_unlock;
 +              goto out_restore_window;
        }
        /* verify the window * number of ptes will map the partition */
        /* check largest block * page size > max memory hotplug addr */
                dev_dbg(&dev->dev, "can't map partiton max 0x%llx with %u "
                          "%llu-sized pages\n", max_addr,  query.largest_available_block,
                          1ULL << page_shift);
 -              goto out_unlock;
 +              goto out_restore_window;
        }
        len = order_base_2(max_addr);
        win64 = kzalloc(sizeof(struct property), GFP_KERNEL);
        if (!win64) {
                dev_info(&dev->dev,
                        "couldn't allocate property for 64bit dma window\n");
 -              goto out_unlock;
 +              goto out_restore_window;
        }
        win64->name = kstrdup(DIRECT64_PROPNAME, GFP_KERNEL);
        win64->value = ddwprop = kmalloc(sizeof(*ddwprop), GFP_KERNEL);
@@@ -1097,10 -1018,6 +1097,10 @@@ out_free_prop
        kfree(win64->value);
        kfree(win64);
  
 +out_restore_window:
 +      if (ddw_restore_token)
 +              restore_default_window(dev, ddw_restore_token, liobn);
 +
  out_unlock:
        mutex_unlock(&direct_window_init_mutex);
        return dma_addr;
@@@ -1134,7 -1051,7 +1134,7 @@@ static void pci_dma_dev_setup_pSeriesLP
        if (!pdn || !PCI_DN(pdn)) {
                printk(KERN_WARNING "pci_dma_dev_setup_pSeriesLP: "
                       "no DMA window found for pci dev=%s dn=%s\n",
-                                pci_name(dev), dn? dn->full_name : "<null>");
+                                pci_name(dev), of_node_full_name(dn));
                return;
        }
        pr_debug("  parent is %s\n", pdn->full_name);
diff --combined drivers/of/base.c
@@@ -173,9 -173,9 +173,9 @@@ struct property *of_find_property(cons
                return NULL;
  
        read_lock(&devtree_lock);
-       for (pp = np->properties; pp != 0; pp = pp->next) {
+       for (pp = np->properties; pp; pp = pp->next) {
                if (of_prop_cmp(pp->name, name) == 0) {
-                       if (lenp != 0)
+                       if (lenp)
                                *lenp = pp->length;
                        break;
                }
@@@ -497,7 -497,7 +497,7 @@@ struct device_node *of_find_node_with_p
        read_lock(&devtree_lock);
        np = from ? from->allnext : allnodes;
        for (; np; np = np->allnext) {
-               for (pp = np->properties; pp != 0; pp = pp->next) {
+               for (pp = np->properties; pp; pp = pp->next) {
                        if (of_prop_cmp(pp->name, prop_name) == 0) {
                                of_node_get(np);
                                goto out;
@@@ -902,7 -902,7 +902,7 @@@ int of_parse_phandle_with_args(struct d
        /* Retrieve the phandle list property */
        list = of_get_property(np, list_name, &size);
        if (!list)
-               return -EINVAL;
+               return -ENOENT;
        list_end = list + size / sizeof(*list);
  
        /* Loop over the phandles until all the requested entry is found */
@@@ -1051,8 -1051,7 +1051,8 @@@ int prom_remove_property(struct device_
  }
  
  /*
 - * prom_update_property - Update a property in a node.
 + * prom_update_property - Update a property in a node, if the property does
 + * not exist, add it.
   *
   * Note that we don't actually remove it, since we have given out
   * who-knows-how-many pointers to the data using get-property.
   * and add the new property to the property list
   */
  int prom_update_property(struct device_node *np,
 -                       struct property *newprop,
 -                       struct property *oldprop)
 +                       struct property *newprop)
  {
 -      struct property **next;
 +      struct property **next, *oldprop;
        unsigned long flags;
        int found = 0;
  
 +      if (!newprop->name)
 +              return -EINVAL;
 +
 +      oldprop = of_find_property(np, newprop->name, NULL);
 +      if (!oldprop)
 +              return prom_add_property(np, newprop);
 +
        write_lock_irqsave(&devtree_lock, flags);
        next = &np->properties;
        while (*next) {
@@@ -1180,7 -1173,7 +1180,7 @@@ static void of_alias_add(struct alias_p
        ap->stem[stem_len] = 0;
        list_add_tail(&ap->link, &aliases_lookup);
        pr_debug("adding DT alias:%s: stem=%s id=%i node=%s\n",
-                ap->alias, ap->stem, ap->id, np ? np->full_name : NULL);
+                ap->alias, ap->stem, ap->id, of_node_full_name(np));
  }
  
  /**
diff --combined include/linux/of.h
@@@ -163,6 -163,11 +163,11 @@@ static inline int of_node_to_nid(struc
  #define of_node_to_nid of_node_to_nid
  #endif
  
+ static inline const char* of_node_full_name(struct device_node *np)
+ {
+       return np ? np->full_name : "<no-node>";
+ }
  extern struct device_node *of_find_node_by_name(struct device_node *from,
        const char *name);
  #define for_each_node_by_name(dn, name) \
@@@ -260,7 -265,8 +265,7 @@@ extern int of_machine_is_compatible(con
  extern int prom_add_property(struct device_node* np, struct property* prop);
  extern int prom_remove_property(struct device_node *np, struct property *prop);
  extern int prom_update_property(struct device_node *np,
 -                              struct property *newprop,
 -                              struct property *oldprop);
 +                              struct property *newprop);
  
  #if defined(CONFIG_OF_DYNAMIC)
  /* For updating the device tree at runtime */
@@@ -302,6 -308,11 +307,11 @@@ const char *of_prop_next_string(struct 
  
  #else /* CONFIG_OF */
  
+ static inline const char* of_node_full_name(struct device_node *np)
+ {
+       return "<no-node>";
+ }
  static inline bool of_have_populated_dt(void)
  {
        return false;