in qcom/hidma_mgmt.c [162:319]
static int hidma_mgmt_probe(struct platform_device *pdev)
{
struct hidma_mgmt_dev *mgmtdev;
struct resource *res;
void __iomem *virtaddr;
int irq;
int rc;
u32 val;
pm_runtime_set_autosuspend_delay(&pdev->dev, HIDMA_AUTOSUSPEND_TIMEOUT);
pm_runtime_use_autosuspend(&pdev->dev);
pm_runtime_set_active(&pdev->dev);
pm_runtime_enable(&pdev->dev);
pm_runtime_get_sync(&pdev->dev);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
virtaddr = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(virtaddr)) {
rc = -ENOMEM;
goto out;
}
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
rc = irq;
goto out;
}
mgmtdev = devm_kzalloc(&pdev->dev, sizeof(*mgmtdev), GFP_KERNEL);
if (!mgmtdev) {
rc = -ENOMEM;
goto out;
}
mgmtdev->pdev = pdev;
mgmtdev->addrsize = resource_size(res);
mgmtdev->virtaddr = virtaddr;
rc = device_property_read_u32(&pdev->dev, "dma-channels",
&mgmtdev->dma_channels);
if (rc) {
dev_err(&pdev->dev, "number of channels missing\n");
goto out;
}
rc = device_property_read_u32(&pdev->dev,
"channel-reset-timeout-cycles",
&mgmtdev->chreset_timeout_cycles);
if (rc) {
dev_err(&pdev->dev, "channel reset timeout missing\n");
goto out;
}
rc = device_property_read_u32(&pdev->dev, "max-write-burst-bytes",
&mgmtdev->max_write_request);
if (rc) {
dev_err(&pdev->dev, "max-write-burst-bytes missing\n");
goto out;
}
if (max_write_request &&
(max_write_request != mgmtdev->max_write_request)) {
dev_info(&pdev->dev, "overriding max-write-burst-bytes: %d\n",
max_write_request);
mgmtdev->max_write_request = max_write_request;
} else
max_write_request = mgmtdev->max_write_request;
rc = device_property_read_u32(&pdev->dev, "max-read-burst-bytes",
&mgmtdev->max_read_request);
if (rc) {
dev_err(&pdev->dev, "max-read-burst-bytes missing\n");
goto out;
}
if (max_read_request &&
(max_read_request != mgmtdev->max_read_request)) {
dev_info(&pdev->dev, "overriding max-read-burst-bytes: %d\n",
max_read_request);
mgmtdev->max_read_request = max_read_request;
} else
max_read_request = mgmtdev->max_read_request;
rc = device_property_read_u32(&pdev->dev, "max-write-transactions",
&mgmtdev->max_wr_xactions);
if (rc) {
dev_err(&pdev->dev, "max-write-transactions missing\n");
goto out;
}
if (max_wr_xactions &&
(max_wr_xactions != mgmtdev->max_wr_xactions)) {
dev_info(&pdev->dev, "overriding max-write-transactions: %d\n",
max_wr_xactions);
mgmtdev->max_wr_xactions = max_wr_xactions;
} else
max_wr_xactions = mgmtdev->max_wr_xactions;
rc = device_property_read_u32(&pdev->dev, "max-read-transactions",
&mgmtdev->max_rd_xactions);
if (rc) {
dev_err(&pdev->dev, "max-read-transactions missing\n");
goto out;
}
if (max_rd_xactions &&
(max_rd_xactions != mgmtdev->max_rd_xactions)) {
dev_info(&pdev->dev, "overriding max-read-transactions: %d\n",
max_rd_xactions);
mgmtdev->max_rd_xactions = max_rd_xactions;
} else
max_rd_xactions = mgmtdev->max_rd_xactions;
mgmtdev->priority = devm_kcalloc(&pdev->dev,
mgmtdev->dma_channels,
sizeof(*mgmtdev->priority),
GFP_KERNEL);
if (!mgmtdev->priority) {
rc = -ENOMEM;
goto out;
}
mgmtdev->weight = devm_kcalloc(&pdev->dev,
mgmtdev->dma_channels,
sizeof(*mgmtdev->weight), GFP_KERNEL);
if (!mgmtdev->weight) {
rc = -ENOMEM;
goto out;
}
rc = hidma_mgmt_setup(mgmtdev);
if (rc) {
dev_err(&pdev->dev, "setup failed\n");
goto out;
}
/* start the HW */
val = readl(mgmtdev->virtaddr + HIDMA_CFG_OFFSET);
val |= 1;
writel(val, mgmtdev->virtaddr + HIDMA_CFG_OFFSET);
rc = hidma_mgmt_init_sys(mgmtdev);
if (rc) {
dev_err(&pdev->dev, "sysfs setup failed\n");
goto out;
}
dev_info(&pdev->dev,
"HW rev: %d.%d @ %pa with %d physical channels\n",
mgmtdev->hw_version_major, mgmtdev->hw_version_minor,
&res->start, mgmtdev->dma_channels);
platform_set_drvdata(pdev, mgmtdev);
pm_runtime_mark_last_busy(&pdev->dev);
pm_runtime_put_autosuspend(&pdev->dev);
return 0;
out:
pm_runtime_put_sync_suspend(&pdev->dev);
pm_runtime_disable(&pdev->dev);
return rc;
}