in rack-meter.c [367:525]
static int rackmeter_probe(struct macio_dev* mdev,
const struct of_device_id *match)
{
struct device_node *i2s = NULL, *np = NULL;
struct rackmeter *rm = NULL;
struct resource ri2s, rdma;
int rc = -ENODEV;
pr_debug("rackmeter_probe()\n");
/* Get i2s-a node */
for_each_child_of_node(mdev->ofdev.dev.of_node, i2s)
if (of_node_name_eq(i2s, "i2s-a"))
break;
if (i2s == NULL) {
pr_debug(" i2s-a child not found\n");
goto bail;
}
/* Get lightshow or virtual sound */
for_each_child_of_node(i2s, np) {
if (of_node_name_eq(np, "lightshow"))
break;
if (of_node_name_eq(np, "sound") &&
of_get_property(np, "virtual", NULL) != NULL)
break;
}
if (np == NULL) {
pr_debug(" lightshow or sound+virtual child not found\n");
goto bail;
}
/* Create and initialize our instance data */
rm = kzalloc(sizeof(*rm), GFP_KERNEL);
if (rm == NULL) {
printk(KERN_ERR "rackmeter: failed to allocate memory !\n");
rc = -ENOMEM;
goto bail_release;
}
rm->mdev = mdev;
rm->i2s = i2s;
mutex_init(&rm->sem);
dev_set_drvdata(&mdev->ofdev.dev, rm);
/* Check resources availability. We need at least resource 0 and 1 */
#if 0 /* Use that when i2s-a is finally an mdev per-se */
if (macio_resource_count(mdev) < 2 || macio_irq_count(mdev) < 2) {
printk(KERN_ERR
"rackmeter: found match but lacks resources: %pOF"
" (%d resources, %d interrupts)\n",
mdev->ofdev.dev.of_node);
rc = -ENXIO;
goto bail_free;
}
if (macio_request_resources(mdev, "rackmeter")) {
printk(KERN_ERR
"rackmeter: failed to request resources: %pOF\n",
mdev->ofdev.dev.of_node);
rc = -EBUSY;
goto bail_free;
}
rm->irq = macio_irq(mdev, 1);
#else
rm->irq = irq_of_parse_and_map(i2s, 1);
if (!rm->irq ||
of_address_to_resource(i2s, 0, &ri2s) ||
of_address_to_resource(i2s, 1, &rdma)) {
printk(KERN_ERR
"rackmeter: found match but lacks resources: %pOF",
mdev->ofdev.dev.of_node);
rc = -ENXIO;
goto bail_free;
}
#endif
pr_debug(" i2s @0x%08x\n", (unsigned int)ri2s.start);
pr_debug(" dma @0x%08x\n", (unsigned int)rdma.start);
pr_debug(" irq %d\n", rm->irq);
rm->ubuf = (u8 *)__get_free_page(GFP_KERNEL);
if (rm->ubuf == NULL) {
printk(KERN_ERR
"rackmeter: failed to allocate samples page !\n");
rc = -ENOMEM;
goto bail_release;
}
rm->dma_buf_v = dma_alloc_coherent(&macio_get_pci_dev(mdev)->dev,
sizeof(struct rackmeter_dma),
&rm->dma_buf_p, GFP_KERNEL);
if (rm->dma_buf_v == NULL) {
printk(KERN_ERR
"rackmeter: failed to allocate dma buffer !\n");
rc = -ENOMEM;
goto bail_free_samples;
}
#if 0
rm->i2s_regs = ioremap(macio_resource_start(mdev, 0), 0x1000);
#else
rm->i2s_regs = ioremap(ri2s.start, 0x1000);
#endif
if (rm->i2s_regs == NULL) {
printk(KERN_ERR
"rackmeter: failed to map i2s registers !\n");
rc = -ENXIO;
goto bail_free_dma;
}
#if 0
rm->dma_regs = ioremap(macio_resource_start(mdev, 1), 0x100);
#else
rm->dma_regs = ioremap(rdma.start, 0x100);
#endif
if (rm->dma_regs == NULL) {
printk(KERN_ERR
"rackmeter: failed to map dma registers !\n");
rc = -ENXIO;
goto bail_unmap_i2s;
}
rc = rackmeter_setup(rm);
if (rc) {
printk(KERN_ERR
"rackmeter: failed to initialize !\n");
rc = -ENXIO;
goto bail_unmap_dma;
}
rc = request_irq(rm->irq, rackmeter_irq, 0, "rackmeter", rm);
if (rc != 0) {
printk(KERN_ERR
"rackmeter: failed to request interrupt !\n");
goto bail_stop_dma;
}
of_node_put(np);
return 0;
bail_stop_dma:
DBDMA_DO_RESET(rm->dma_regs);
bail_unmap_dma:
iounmap(rm->dma_regs);
bail_unmap_i2s:
iounmap(rm->i2s_regs);
bail_free_dma:
dma_free_coherent(&macio_get_pci_dev(mdev)->dev,
sizeof(struct rackmeter_dma),
rm->dma_buf_v, rm->dma_buf_p);
bail_free_samples:
free_page((unsigned long)rm->ubuf);
bail_release:
#if 0
macio_release_resources(mdev);
#endif
bail_free:
kfree(rm);
bail:
of_node_put(i2s);
of_node_put(np);
dev_set_drvdata(&mdev->ofdev.dev, NULL);
return rc;
}