linux/arch/powerpc/kernel/of_platform.c
<<
>>
Prefs
   1/*
   2 *    Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp.
   3 *                       <benh@kernel.crashing.org>
   4 *    and                Arnd Bergmann, IBM Corp.
   5 *
   6 *  This program is free software; you can redistribute it and/or
   7 *  modify it under the terms of the GNU General Public License
   8 *  as published by the Free Software Foundation; either version
   9 *  2 of the License, or (at your option) any later version.
  10 *
  11 */
  12
  13#undef DEBUG
  14
  15#include <linux/string.h>
  16#include <linux/kernel.h>
  17#include <linux/init.h>
  18#include <linux/module.h>
  19#include <linux/mod_devicetable.h>
  20#include <linux/slab.h>
  21#include <linux/pci.h>
  22#include <linux/of.h>
  23#include <linux/of_device.h>
  24#include <linux/of_platform.h>
  25
  26#include <asm/errno.h>
  27#include <asm/topology.h>
  28#include <asm/pci-bridge.h>
  29#include <asm/ppc-pci.h>
  30#include <asm/atomic.h>
  31
  32/*
  33 * The list of OF IDs below is used for matching bus types in the
  34 * system whose devices are to be exposed as of_platform_devices.
  35 *
  36 * This is the default list valid for most platforms. This file provides
  37 * functions who can take an explicit list if necessary though
  38 *
  39 * The search is always performed recursively looking for children of
  40 * the provided device_node and recursively if such a children matches
  41 * a bus type in the list
  42 */
  43
  44static const struct of_device_id of_default_bus_ids[] = {
  45        { .type = "soc", },
  46        { .compatible = "soc", },
  47        { .type = "spider", },
  48        { .type = "axon", },
  49        { .type = "plb5", },
  50        { .type = "plb4", },
  51        { .type = "opb", },
  52        { .type = "ebc", },
  53        {},
  54};
  55
  56struct bus_type of_platform_bus_type = {
  57       .uevent  = of_device_uevent,
  58};
  59EXPORT_SYMBOL(of_platform_bus_type);
  60
  61static int __init of_bus_driver_init(void)
  62{
  63        return of_bus_type_init(&of_platform_bus_type, "of_platform");
  64}
  65
  66postcore_initcall(of_bus_driver_init);
  67
  68struct of_device* of_platform_device_create(struct device_node *np,
  69                                            const char *bus_id,
  70                                            struct device *parent)
  71{
  72        struct of_device *dev;
  73
  74        dev = of_device_alloc(np, bus_id, parent);
  75        if (!dev)
  76                return NULL;
  77
  78        dev->dma_mask = 0xffffffffUL;
  79        dev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
  80
  81        dev->dev.bus = &of_platform_bus_type;
  82
  83        /* We do not fill the DMA ops for platform devices by default.
  84         * This is currently the responsibility of the platform code
  85         * to do such, possibly using a device notifier
  86         */
  87
  88        if (of_device_register(dev) != 0) {
  89                of_device_free(dev);
  90                return NULL;
  91        }
  92
  93        return dev;
  94}
  95EXPORT_SYMBOL(of_platform_device_create);
  96
  97
  98
  99/**
 100 * of_platform_bus_create - Create an OF device for a bus node and all its
 101 * children. Optionally recursively instanciate matching busses.
 102 * @bus: device node of the bus to instanciate
 103 * @matches: match table, NULL to use the default, OF_NO_DEEP_PROBE to
 104 * disallow recursive creation of child busses
 105 */
 106static int of_platform_bus_create(const struct device_node *bus,
 107                                  const struct of_device_id *matches,
 108                                  struct device *parent)
 109{
 110        struct device_node *child;
 111        struct of_device *dev;
 112        int rc = 0;
 113
 114        for_each_child_of_node(bus, child) {
 115                pr_debug("   create child: %s\n", child->full_name);
 116                dev = of_platform_device_create(child, NULL, parent);
 117                if (dev == NULL)
 118                        rc = -ENOMEM;
 119                else if (!of_match_node(matches, child))
 120                        continue;
 121                if (rc == 0) {
 122                        pr_debug("   and sub busses\n");
 123                        rc = of_platform_bus_create(child, matches, &dev->dev);
 124                } if (rc) {
 125                        of_node_put(child);
 126                        break;
 127                }
 128        }
 129        return rc;
 130}
 131
 132/**
 133 * of_platform_bus_probe - Probe the device-tree for platform busses
 134 * @root: parent of the first level to probe or NULL for the root of the tree
 135 * @matches: match table, NULL to use the default
 136 * @parent: parent to hook devices from, NULL for toplevel
 137 *
 138 * Note that children of the provided root are not instanciated as devices
 139 * unless the specified root itself matches the bus list and is not NULL.
 140 */
 141
 142int of_platform_bus_probe(struct device_node *root,
 143                          const struct of_device_id *matches,
 144                          struct device *parent)
 145{
 146        struct device_node *child;
 147        struct of_device *dev;
 148        int rc = 0;
 149
 150        if (matches == NULL)
 151                matches = of_default_bus_ids;
 152        if (matches == OF_NO_DEEP_PROBE)
 153                return -EINVAL;
 154        if (root == NULL)
 155                root = of_find_node_by_path("/");
 156        else
 157                of_node_get(root);
 158
 159        pr_debug("of_platform_bus_probe()\n");
 160        pr_debug(" starting at: %s\n", root->full_name);
 161
 162        /* Do a self check of bus type, if there's a match, create
 163         * children
 164         */
 165        if (of_match_node(matches, root)) {
 166                pr_debug(" root match, create all sub devices\n");
 167                dev = of_platform_device_create(root, NULL, parent);
 168                if (dev == NULL) {
 169                        rc = -ENOMEM;
 170                        goto bail;
 171                }
 172                pr_debug(" create all sub busses\n");
 173                rc = of_platform_bus_create(root, matches, &dev->dev);
 174                goto bail;
 175        }
 176        for_each_child_of_node(root, child) {
 177                if (!of_match_node(matches, child))
 178                        continue;
 179
 180                pr_debug("  match: %s\n", child->full_name);
 181                dev = of_platform_device_create(child, NULL, parent);
 182                if (dev == NULL)
 183                        rc = -ENOMEM;
 184                else
 185                        rc = of_platform_bus_create(child, matches, &dev->dev);
 186                if (rc) {
 187                        of_node_put(child);
 188                        break;
 189                }
 190        }
 191 bail:
 192        of_node_put(root);
 193        return rc;
 194}
 195EXPORT_SYMBOL(of_platform_bus_probe);
 196
 197static int of_dev_node_match(struct device *dev, void *data)
 198{
 199        return to_of_device(dev)->node == data;
 200}
 201
 202struct of_device *of_find_device_by_node(struct device_node *np)
 203{
 204        struct device *dev;
 205
 206        dev = bus_find_device(&of_platform_bus_type,
 207                              NULL, np, of_dev_node_match);
 208        if (dev)
 209                return to_of_device(dev);
 210        return NULL;
 211}
 212EXPORT_SYMBOL(of_find_device_by_node);
 213
 214static int of_dev_phandle_match(struct device *dev, void *data)
 215{
 216        phandle *ph = data;
 217        return to_of_device(dev)->node->linux_phandle == *ph;
 218}
 219
 220struct of_device *of_find_device_by_phandle(phandle ph)
 221{
 222        struct device *dev;
 223
 224        dev = bus_find_device(&of_platform_bus_type,
 225                              NULL, &ph, of_dev_phandle_match);
 226        if (dev)
 227                return to_of_device(dev);
 228        return NULL;
 229}
 230EXPORT_SYMBOL(of_find_device_by_phandle);
 231
 232
 233#ifdef CONFIG_PPC_OF_PLATFORM_PCI
 234
 235/* The probing of PCI controllers from of_platform is currently
 236 * 64 bits only, mostly due to gratuitous differences between
 237 * the 32 and 64 bits PCI code on PowerPC and the 32 bits one
 238 * lacking some bits needed here.
 239 */
 240
 241static int __devinit of_pci_phb_probe(struct of_device *dev,
 242                                      const struct of_device_id *match)
 243{
 244        struct pci_controller *phb;
 245
 246        /* Check if we can do that ... */
 247        if (ppc_md.pci_setup_phb == NULL)
 248                return -ENODEV;
 249
 250        printk(KERN_INFO "Setting up PCI bus %s\n", dev->node->full_name);
 251
 252        /* Alloc and setup PHB data structure */
 253        phb = pcibios_alloc_controller(dev->node);
 254        if (!phb)
 255                return -ENODEV;
 256
 257        /* Setup parent in sysfs */
 258        phb->parent = &dev->dev;
 259
 260        /* Setup the PHB using arch provided callback */
 261        if (ppc_md.pci_setup_phb(phb)) {
 262                pcibios_free_controller(phb);
 263                return -ENODEV;
 264        }
 265
 266        /* Process "ranges" property */
 267        pci_process_bridge_OF_ranges(phb, dev->node, 0);
 268
 269        /* Init pci_dn data structures */
 270        pci_devs_phb_init_dynamic(phb);
 271
 272        /* Register devices with EEH */
 273#ifdef CONFIG_EEH
 274        if (dev->node->child)
 275                eeh_add_device_tree_early(dev->node);
 276#endif /* CONFIG_EEH */
 277
 278        /* Scan the bus */
 279        pcibios_scan_phb(phb, dev->node);
 280        if (phb->bus == NULL)
 281                return -ENXIO;
 282
 283        /* Claim resources. This might need some rework as well depending
 284         * wether we are doing probe-only or not, like assigning unassigned
 285         * resources etc...
 286         */
 287        pcibios_claim_one_bus(phb->bus);
 288
 289        /* Finish EEH setup */
 290#ifdef CONFIG_EEH
 291        eeh_add_device_tree_late(phb->bus);
 292#endif
 293
 294        /* Add probed PCI devices to the device model */
 295        pci_bus_add_devices(phb->bus);
 296
 297        return 0;
 298}
 299
 300static struct of_device_id of_pci_phb_ids[] = {
 301        { .type = "pci", },
 302        { .type = "pcix", },
 303        { .type = "pcie", },
 304        { .type = "pciex", },
 305        { .type = "ht", },
 306        {}
 307};
 308
 309static struct of_platform_driver of_pci_phb_driver = {
 310        .match_table = of_pci_phb_ids,
 311        .probe = of_pci_phb_probe,
 312        .driver = {
 313                .name = "of-pci",
 314        },
 315};
 316
 317static __init int of_pci_phb_init(void)
 318{
 319        return of_register_platform_driver(&of_pci_phb_driver);
 320}
 321
 322device_initcall(of_pci_phb_init);
 323
 324#endif /* CONFIG_PPC_OF_PLATFORM_PCI */
 325