in ti/knav_qmss_queue.c [1755:1887]
static int knav_queue_probe(struct platform_device *pdev)
{
struct device_node *node = pdev->dev.of_node;
struct device_node *qmgrs, *queue_pools, *regions, *pdsps;
const struct of_device_id *match;
struct device *dev = &pdev->dev;
u32 temp[2];
int ret;
if (!node) {
dev_err(dev, "device tree info unavailable\n");
return -ENODEV;
}
kdev = devm_kzalloc(dev, sizeof(struct knav_device), GFP_KERNEL);
if (!kdev) {
dev_err(dev, "memory allocation failed\n");
return -ENOMEM;
}
match = of_match_device(of_match_ptr(keystone_qmss_of_match), dev);
if (match && match->data)
kdev->version = QMSS_66AK2G;
platform_set_drvdata(pdev, kdev);
kdev->dev = dev;
INIT_LIST_HEAD(&kdev->queue_ranges);
INIT_LIST_HEAD(&kdev->qmgrs);
INIT_LIST_HEAD(&kdev->pools);
INIT_LIST_HEAD(&kdev->regions);
INIT_LIST_HEAD(&kdev->pdsps);
pm_runtime_enable(&pdev->dev);
ret = pm_runtime_get_sync(&pdev->dev);
if (ret < 0) {
pm_runtime_put_noidle(&pdev->dev);
dev_err(dev, "Failed to enable QMSS\n");
return ret;
}
if (of_property_read_u32_array(node, "queue-range", temp, 2)) {
dev_err(dev, "queue-range not specified\n");
ret = -ENODEV;
goto err;
}
kdev->base_id = temp[0];
kdev->num_queues = temp[1];
/* Initialize queue managers using device tree configuration */
qmgrs = of_get_child_by_name(node, "qmgrs");
if (!qmgrs) {
dev_err(dev, "queue manager info not specified\n");
ret = -ENODEV;
goto err;
}
ret = knav_queue_init_qmgrs(kdev, qmgrs);
of_node_put(qmgrs);
if (ret)
goto err;
/* get pdsp configuration values from device tree */
pdsps = of_get_child_by_name(node, "pdsps");
if (pdsps) {
ret = knav_queue_init_pdsps(kdev, pdsps);
if (ret)
goto err;
ret = knav_queue_start_pdsps(kdev);
if (ret)
goto err;
}
of_node_put(pdsps);
/* get usable queue range values from device tree */
queue_pools = of_get_child_by_name(node, "queue-pools");
if (!queue_pools) {
dev_err(dev, "queue-pools not specified\n");
ret = -ENODEV;
goto err;
}
ret = knav_setup_queue_pools(kdev, queue_pools);
of_node_put(queue_pools);
if (ret)
goto err;
ret = knav_get_link_ram(kdev, "linkram0", &kdev->link_rams[0]);
if (ret) {
dev_err(kdev->dev, "could not setup linking ram\n");
goto err;
}
ret = knav_get_link_ram(kdev, "linkram1", &kdev->link_rams[1]);
if (ret) {
/*
* nothing really, we have one linking ram already, so we just
* live within our means
*/
}
ret = knav_queue_setup_link_ram(kdev);
if (ret)
goto err;
regions = of_get_child_by_name(node, "descriptor-regions");
if (!regions) {
dev_err(dev, "descriptor-regions not specified\n");
ret = -ENODEV;
goto err;
}
ret = knav_queue_setup_regions(kdev, regions);
of_node_put(regions);
if (ret)
goto err;
ret = knav_queue_init_queues(kdev);
if (ret < 0) {
dev_err(dev, "hwqueue initialization failed\n");
goto err;
}
debugfs_create_file("qmss", S_IFREG | S_IRUGO, NULL, NULL,
&knav_queue_debug_fops);
device_ready = true;
return 0;
err:
knav_queue_stop_pdsps(kdev);
knav_queue_free_regions(kdev);
knav_free_queue_ranges(kdev);
pm_runtime_put_sync(&pdev->dev);
pm_runtime_disable(&pdev->dev);
return ret;
}