static struct ibmebus_dev* __devinit ibmebus_register_device_common( struct ibmebus_dev *dev, const char *name) { int err = 0; dev->name = name; dev->ofdev.dev.parent = &ibmebus_bus_device.ofdev.dev; dev->ofdev.dev.bus = &ibmebus_bus_type; dev->ofdev.dev.release = ibmebus_dev_release; dev->ofdev.dev.archdata.of_node = dev->ofdev.node; dev->ofdev.dev.archdata.dma_ops = &ibmebus_dma_ops; dev->ofdev.dev.archdata.numa_node = of_node_to_nid(dev->ofdev.node); /* An ibmebusdev is based on a of_device. We have to change the * bus type to use our own DMA mapping operations. */ if ((err = of_device_register(&dev->ofdev)) != 0) { printk(KERN_ERR "%s: failed to register device (%d).\n", __FUNCTION__, err); return NULL; } device_create_file(&dev->ofdev.dev, &dev_attr_name); return dev; }
/** * vio_register_device_node: - Register a new vio device. * @of_node: The OF node for this device. * * Creates and initializes a vio_dev structure from the data in * of_node and adds it to the list of virtual devices. * Returns a pointer to the created vio_dev or NULL if node has * NULL device_type or compatible fields. */ struct vio_dev *vio_register_device_node(struct device_node *of_node) { struct vio_dev *viodev; const unsigned int *unit_address; /* we need the 'device_type' property, in order to match with drivers */ if (of_node->type == NULL) { printk(KERN_WARNING "%s: node %s missing 'device_type'\n", __func__, of_node->name ? of_node->name : "<unknown>"); return NULL; } unit_address = of_get_property(of_node, "reg", NULL); if (unit_address == NULL) { printk(KERN_WARNING "%s: node %s missing 'reg'\n", __func__, of_node->name ? of_node->name : "<unknown>"); return NULL; } /* allocate a vio_dev for this node */ viodev = kzalloc(sizeof(struct vio_dev), GFP_KERNEL); if (viodev == NULL) return NULL; viodev->irq = irq_of_parse_and_map(of_node, 0); snprintf(viodev->dev.bus_id, BUS_ID_SIZE, "%x", *unit_address); viodev->name = of_node->name; viodev->type = of_node->type; viodev->unit_address = *unit_address; if (firmware_has_feature(FW_FEATURE_ISERIES)) { unit_address = of_get_property(of_node, "linux,unit_address", NULL); if (unit_address != NULL) viodev->unit_address = *unit_address; } viodev->dev.archdata.of_node = of_node_get(of_node); viodev->dev.archdata.dma_ops = &dma_iommu_ops; viodev->dev.archdata.dma_data = vio_build_iommu_table(viodev); viodev->dev.archdata.numa_node = 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; /* register with generic device framework */ if (device_register(&viodev->dev)) { printk(KERN_ERR "%s: failed to register device %s\n", __func__, viodev->dev.bus_id); /* XXX free TCE table */ kfree(viodev); return NULL; } return viodev; }
static int __init of_create_spu(struct spu *spu, void *data) { int ret; struct device_node *spe = (struct device_node *)data; static int legacy_map = 0, legacy_irq = 0; spu->devnode = of_node_get(spe); spu->spe_id = find_spu_unit_number(spe); spu->node = of_node_to_nid(spe); if (spu->node >= MAX_NUMNODES) { printk(KERN_WARNING "SPE %s on node %d ignored," " node number too big\n", spe->full_name, spu->node); printk(KERN_WARNING "Check if CONFIG_NUMA is enabled.\n"); ret = -ENODEV; goto out; } ret = spu_map_device(spu); if (ret) { if (!legacy_map) { legacy_map = 1; printk(KERN_WARNING "%s: Legacy device tree found, " "trying to map old style\n", __FUNCTION__); } ret = spu_map_device_old(spu); if (ret) { printk(KERN_ERR "Unable to map %s\n", spu->name); goto out; } } ret = spu_map_interrupts(spu, spe); if (ret) { if (!legacy_irq) { legacy_irq = 1; printk(KERN_WARNING "%s: Legacy device tree found, " "trying old style irq\n", __FUNCTION__); } ret = spu_map_interrupts_old(spu, spe); if (ret) { printk(KERN_ERR "%s: could not map interrupts", spu->name); goto out_unmap; } } pr_debug("Using SPE %s %p %p %p %p %d\n", spu->name, spu->local_store, spu->problem, spu->priv1, spu->priv2, spu->number); goto out; out_unmap: spu_unmap(spu); out: return ret; }
/* * Enumerate the possible CPU set from the device tree and build the * cpu logical map array containing MPIDR values related to logical * cpus. Assumes that cpu_logical_map(0) has already been initialized. */ static void __init of_parse_and_init_cpus(void) { struct device_node *dn = NULL; while ((dn = of_find_node_by_type(dn, "cpu"))) { u64 hwid = of_get_cpu_mpidr(dn); if (hwid == INVALID_HWID) goto next; if (is_mpidr_duplicate(cpu_count, hwid)) { pr_err("%s: duplicate cpu reg properties in the DT\n", dn->full_name); goto next; } /* * The numbering scheme requires that the boot CPU * must be assigned logical id 0. Record it so that * the logical map built from DT is validated and can * be used. */ if (hwid == cpu_logical_map(0)) { if (bootcpu_valid) { pr_err("%s: duplicate boot cpu reg property in DT\n", dn->full_name); goto next; } bootcpu_valid = true; /* * cpu_logical_map has already been * initialized and the boot cpu doesn't need * the enable-method so continue without * incrementing cpu. */ continue; } if (cpu_count >= NR_CPUS) goto next; pr_debug("cpu logical map 0x%llx\n", hwid); cpu_logical_map(cpu_count) = hwid; early_map_cpu_to_node(cpu_count, of_node_to_nid(dn)); next: cpu_count++; } }
int of_device_register(struct of_device *ofdev) { BUG_ON(ofdev->node == NULL); device_initialize(&ofdev->dev); /* device_add will assume that this device is on the same node as * the parent. If there is no parent defined, set the node * explicitly */ if (!ofdev->dev.parent) set_dev_node(&ofdev->dev, of_node_to_nid(ofdev->node)); return device_add(&ofdev->dev); }
int of_device_add(struct platform_device *ofdev) { BUG_ON(ofdev->dev.of_node == NULL); /* name and id have to be set so that the platform bus doesn't get * confused on matching */ ofdev->name = dev_name(&ofdev->dev); ofdev->id = -1; /* device_add will assume that this device is on the same node as * the parent. If there is no parent defined, set the node * explicitly */ if (!ofdev->dev.parent) set_dev_node(&ofdev->dev, of_node_to_nid(ofdev->dev.of_node)); /* make sure we add the resources to the appropriate lists */ platform_device_link_resources(ofdev); return device_add(&ofdev->dev); }
struct of_device* of_platform_device_create(struct device_node *np, const char *bus_id, struct device *parent) { struct of_device *dev; dev = kmalloc(sizeof(*dev), GFP_KERNEL); if (!dev) return NULL; memset(dev, 0, sizeof(*dev)); dev->node = of_node_get(np); dev->dma_mask = 0xffffffffUL; dev->dev.dma_mask = &dev->dma_mask; dev->dev.parent = parent; dev->dev.bus = &of_platform_bus_type; dev->dev.release = of_release_dev; dev->dev.archdata.of_node = np; dev->dev.archdata.numa_node = of_node_to_nid(np); /* We do not fill the DMA ops for platform devices by default. * This is currently the responsibility of the platform code * to do such, possibly using a device notifier */ if (bus_id) strlcpy(dev->dev.bus_id, bus_id, BUS_ID_SIZE); else of_platform_make_bus_id(dev); if (of_device_register(dev) != 0) { kfree(dev); return NULL; } return dev; }
/** * __irq_domain_add() - Allocate a new irq_domain data structure * @fwnode: firmware node for the interrupt controller * @size: Size of linear map; 0 for radix mapping only * @hwirq_max: Maximum number of interrupts supported by controller * @direct_max: Maximum value of direct maps; Use ~0 for no limit; 0 for no * direct mapping * @ops: domain callbacks * @host_data: Controller private data pointer * * Allocates and initialize and irq_domain structure. * Returns pointer to IRQ domain, or NULL on failure. */ struct irq_domain *__irq_domain_add(struct fwnode_handle *fwnode, int size, irq_hw_number_t hwirq_max, int direct_max, const struct irq_domain_ops *ops, void *host_data) { struct device_node *of_node = to_of_node(fwnode); struct irqchip_fwid *fwid; struct irq_domain *domain; static atomic_t unknown_domains; domain = kzalloc_node(sizeof(*domain) + (sizeof(unsigned int) * size), GFP_KERNEL, of_node_to_nid(of_node)); if (WARN_ON(!domain)) return NULL; if (fwnode && is_fwnode_irqchip(fwnode)) { fwid = container_of(fwnode, struct irqchip_fwid, fwnode); switch (fwid->type) { case IRQCHIP_FWNODE_NAMED: case IRQCHIP_FWNODE_NAMED_ID: domain->name = kstrdup(fwid->name, GFP_KERNEL); if (!domain->name) { kfree(domain); return NULL; } domain->flags |= IRQ_DOMAIN_NAME_ALLOCATED; break; default: domain->fwnode = fwnode; domain->name = fwid->name; break; } #ifdef CONFIG_ACPI } else if (is_acpi_device_node(fwnode)) {