[PATCH V10 7/7] dma: qcom_hidma: add support for object hierarchy
Andy Shevchenko
andy.shevchenko at gmail.com
Sat Dec 19 10:37:00 PST 2015
On Thu, Dec 17, 2015 at 7:01 PM, Sinan Kaya <okaya at codeaurora.org> wrote:
> In order to create a relationship model between the channels and the
> management object, we are adding support for object hierarchy to the
> drivers. This patch simplifies the userspace application development.
> We will not have to traverse different firmware paths based on device
> tree or ACPI baed kernels.
>
> No matter what flavor of kernel is used, objects will be represented as
> platform devices.
>
> The new layout is as follows:
>
> hidmam_10: hidma-mgmt at 0x5A000000 {
> compatible = "qcom,hidma-mgmt-1.0";
> ...
>
> hidma_10: hidma at 0x5a010000 {
> compatible = "qcom,hidma-1.0";
> ...
> }
> }
>
> The hidma_mgmt_init detects each instance of the hidma-mgmt-1.0 objects
> in device tree and calls into the channel driver to create platform devices
> for each child of the management object.
>
> Signed-off-by: Sinan Kaya <okaya at codeaurora.org>
> +What: /sys/devices/platform/hidma-*/chid
> + /sys/devices/platform/QCOM8061:*/chid
> +Date: Dec 2015
> +KernelVersion: 4.4
> +Contact: "Sinan Kaya <okaya at cudeaurora.org>"
> +Description:
> + Contains the ID of the channel within the HIDMA instance.
> + It is used to associate a given HIDMA channel with the
> + priority and weight calls in the management interface.
> -module_platform_driver(hidma_mgmt_driver);
> +#ifdef CONFIG_OF
> +static int object_counter;
> +
> +static int __init hidma_mgmt_of_populate_channels(struct device_node *np)
> +{
> + struct platform_device *pdev_parent = of_find_device_by_node(np);
> + struct platform_device_info pdevinfo;
> + struct of_phandle_args out_irq;
> + struct device_node *child;
> + struct resource *res;
> + const __be32 *cell;
Always BE ?
> + int ret = 0, size, i, num;
> + u64 addr, addr_size;
resource_size_t
> +
> + for_each_available_child_of_node(np, child) {
> + int iter = 0;
> +
> + cell = of_get_property(child, "reg", &size);
> + if (!cell) {
> + ret = -EINVAL;
> + goto out;
> + }
> +
> + size /= (sizeof(*cell));
Redundant parens. I think it might be good to use common sense for
operator precedence, here is a radical example of ignoring it. And
this is not the first case.
> + num = size /
> + (of_n_addr_cells(child) + of_n_size_cells(child)) + 1;
> +
> + /* allocate a resource array */
> + res = kcalloc(num, sizeof(*res), GFP_KERNEL);
> + if (!res) {
> + ret = -ENOMEM;
> + goto out;
> + }
> +
> + /* read each reg value */
> + i = 0;
> + while (i < size) {
> + addr = of_read_number(&cell[i],
> + of_n_addr_cells(child));
> + i += of_n_addr_cells(child);
> +
> + addr_size = of_read_number(&cell[i],
> + of_n_size_cells(child));
> + i += of_n_size_cells(child);
> +
> + res[iter].start = addr;
> + res[iter].end = res[iter].start + addr_size - 1;
> + res[iter].flags = IORESOURCE_MEM;
res->start = …
…
res++;
> + iter++;
> + }
> +
> + ret = of_irq_parse_one(child, 0, &out_irq);
> + if (ret)
> + goto out;
> +
> + res[iter].start = irq_create_of_mapping(&out_irq);
> + res[iter].name = "hidma event irq";
> + res[iter].flags = IORESOURCE_IRQ;
Ditto.
> +
> + pdevinfo.fwnode = &child->fwnode;
> + pdevinfo.parent = pdev_parent ? &pdev_parent->dev : NULL;
> + pdevinfo.name = child->name;
> + pdevinfo.id = object_counter++;
> + pdevinfo.res = res;
> + pdevinfo.num_res = num;
> + pdevinfo.data = NULL;
> + pdevinfo.size_data = 0;
> + pdevinfo.dma_mask = DMA_BIT_MASK(64);
> + platform_device_register_full(&pdevinfo);
> +
> + kfree(res);
> + res = NULL;
> + }
> +out:
> + kfree(res);
> +
> + return ret;
> +}
> +#endif
> +
> +static int __init hidma_mgmt_init(void)
> +{
> +#ifdef CONFIG_OF
> + struct device_node *child;
> +
> + for (child = of_find_matching_node(NULL, hidma_mgmt_match); child;
> + child = of_find_matching_node(child, hidma_mgmt_match)) {
> + /* device tree based firmware here */
> + hidma_mgmt_of_populate_channels(child);
> + of_node_put(child);
> + }
And why this is can't be done in probe of parent node driver?
> +#endif
> + platform_driver_register(&hidma_mgmt_driver);
> +
> + return 0;
> +}
> +module_init(hidma_mgmt_init);
--
With Best Regards,
Andy Shevchenko
More information about the linux-arm-kernel
mailing list