/* * dim2_probe - dim2 probe handler * @pdev: platform device structure * * Register the dim2 interface with mostcore and initialize it. * Return 0 on success, negative on failure. */ static int dim2_probe(struct platform_device *pdev) { struct dim2_hdm *dev; struct resource *res; int ret, i; struct kobject *kobj; int irq; dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); if (!dev) return -ENOMEM; dev->atx_idx = -1; platform_set_drvdata(pdev, dev); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); dev->io_base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(dev->io_base)) return PTR_ERR(dev->io_base); irq = platform_get_irq(pdev, 0); if (irq < 0) { dev_err(&pdev->dev, "failed to get ahb0_int irq\n"); return -ENODEV; } ret = devm_request_irq(&pdev->dev, irq, dim2_ahb_isr, 0, "dim2_ahb0_int", dev); if (ret) { dev_err(&pdev->dev, "failed to request ahb0_int irq %d\n", irq); return ret; } irq = platform_get_irq(pdev, 1); if (irq < 0) { dev_err(&pdev->dev, "failed to get mlb_int irq\n"); return -ENODEV; } ret = devm_request_irq(&pdev->dev, irq, dim2_mlb_isr, 0, "dim2_mlb_int", dev); if (ret) { dev_err(&pdev->dev, "failed to request mlb_int irq %d\n", irq); return ret; } init_waitqueue_head(&dev->netinfo_waitq); dev->deliver_netinfo = 0; dev->netinfo_task = kthread_run(&deliver_netinfo_thread, (void *)dev, "dim2_netinfo"); if (IS_ERR(dev->netinfo_task)) return PTR_ERR(dev->netinfo_task); for (i = 0; i < DMA_CHANNELS; i++) { struct most_channel_capability *cap = dev->capabilities + i; struct hdm_channel *hdm_ch = dev->hch + i; INIT_LIST_HEAD(&hdm_ch->pending_list); INIT_LIST_HEAD(&hdm_ch->started_list); hdm_ch->is_initialized = false; snprintf(hdm_ch->name, sizeof(hdm_ch->name), "ca%d", i * 2 + 2); cap->name_suffix = hdm_ch->name; cap->direction = MOST_CH_RX | MOST_CH_TX; cap->data_type = MOST_CH_CONTROL | MOST_CH_ASYNC | MOST_CH_ISOC | MOST_CH_SYNC; cap->num_buffers_packet = MAX_BUFFERS_PACKET; cap->buffer_size_packet = MAX_BUF_SIZE_PACKET; cap->num_buffers_streaming = MAX_BUFFERS_STREAMING; cap->buffer_size_streaming = MAX_BUF_SIZE_STREAMING; } { const char *fmt; if (sizeof(res->start) == sizeof(long long)) fmt = "dim2-%016llx"; else if (sizeof(res->start) == sizeof(long)) fmt = "dim2-%016lx"; else fmt = "dim2-%016x"; snprintf(dev->name, sizeof(dev->name), fmt, res->start); } dev->most_iface.interface = ITYPE_MEDIALB_DIM2; dev->most_iface.description = dev->name; dev->most_iface.num_channels = DMA_CHANNELS; dev->most_iface.channel_vector = dev->capabilities; dev->most_iface.configure = configure_channel; dev->most_iface.enqueue = enqueue; dev->most_iface.poison_channel = poison_channel; dev->most_iface.request_netinfo = request_netinfo; kobj = most_register_interface(&dev->most_iface); if (IS_ERR(kobj)) { ret = PTR_ERR(kobj); dev_err(&pdev->dev, "failed to register MOST interface\n"); goto err_stop_thread; } ret = dim2_sysfs_probe(&dev->bus, kobj); if (ret) goto err_unreg_iface; ret = startup_dim(pdev); if (ret) { dev_err(&pdev->dev, "failed to initialize DIM2\n"); goto err_destroy_bus; } return 0; err_destroy_bus: dim2_sysfs_destroy(&dev->bus); err_unreg_iface: most_deregister_interface(&dev->most_iface); err_stop_thread: kthread_stop(dev->netinfo_task); return ret; }
/* * dim2_probe - dim2 probe handler * @pdev: platform device structure * * Register the dim2 interface with mostcore and initialize it. * Return 0 on success, negative on failure. */ static int dim2_probe(struct platform_device *pdev) { const struct dim2_platform_data *pdata; const struct of_device_id *of_id; const char *clock_speed; struct dim2_hdm *dev; struct resource *res; int ret, i; u8 hal_ret; int irq; enum { MLB_INT_IDX, AHB0_INT_IDX }; dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); if (!dev) return -ENOMEM; dev->atx_idx = -1; platform_set_drvdata(pdev, dev); ret = of_property_read_string(pdev->dev.of_node, "microchip,clock-speed", &clock_speed); if (ret) { dev_err(&pdev->dev, "missing dt property clock-speed\n"); return ret; } ret = get_dim2_clk_speed(clock_speed, &dev->clk_speed); if (ret) { dev_err(&pdev->dev, "bad dt property clock-speed\n"); return ret; } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); dev->io_base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(dev->io_base)) return PTR_ERR(dev->io_base); of_id = of_match_node(dim2_of_match, pdev->dev.of_node); pdata = of_id->data; ret = pdata && pdata->enable ? pdata->enable(pdev) : 0; if (ret) return ret; dev->disable_platform = pdata ? pdata->disable : 0; dev_info(&pdev->dev, "sync: num of frames per sub-buffer: %u\n", fcnt); hal_ret = dim_startup(dev->io_base, dev->clk_speed, fcnt); if (hal_ret != DIM_NO_ERROR) { dev_err(&pdev->dev, "dim_startup failed: %d\n", hal_ret); ret = -ENODEV; goto err_disable_platform; } irq = platform_get_irq(pdev, AHB0_INT_IDX); if (irq < 0) { dev_err(&pdev->dev, "failed to get ahb0_int irq: %d\n", irq); ret = irq; goto err_shutdown_dim; } ret = devm_request_irq(&pdev->dev, irq, dim2_ahb_isr, 0, "dim2_ahb0_int", dev); if (ret) { dev_err(&pdev->dev, "failed to request ahb0_int irq %d\n", irq); goto err_shutdown_dim; } irq = platform_get_irq(pdev, MLB_INT_IDX); if (irq < 0) { dev_err(&pdev->dev, "failed to get mlb_int irq: %d\n", irq); ret = irq; goto err_shutdown_dim; } ret = devm_request_irq(&pdev->dev, irq, dim2_mlb_isr, 0, "dim2_mlb_int", dev); if (ret) { dev_err(&pdev->dev, "failed to request mlb_int irq %d\n", irq); goto err_shutdown_dim; } init_waitqueue_head(&dev->netinfo_waitq); dev->deliver_netinfo = 0; dev->netinfo_task = kthread_run(&deliver_netinfo_thread, dev, "dim2_netinfo"); if (IS_ERR(dev->netinfo_task)) { ret = PTR_ERR(dev->netinfo_task); goto err_shutdown_dim; } for (i = 0; i < DMA_CHANNELS; i++) { struct most_channel_capability *cap = dev->capabilities + i; struct hdm_channel *hdm_ch = dev->hch + i; INIT_LIST_HEAD(&hdm_ch->pending_list); INIT_LIST_HEAD(&hdm_ch->started_list); hdm_ch->is_initialized = false; snprintf(hdm_ch->name, sizeof(hdm_ch->name), "ca%d", i * 2 + 2); cap->name_suffix = hdm_ch->name; cap->direction = MOST_CH_RX | MOST_CH_TX; cap->data_type = MOST_CH_CONTROL | MOST_CH_ASYNC | MOST_CH_ISOC | MOST_CH_SYNC; cap->num_buffers_packet = MAX_BUFFERS_PACKET; cap->buffer_size_packet = MAX_BUF_SIZE_PACKET; cap->num_buffers_streaming = MAX_BUFFERS_STREAMING; cap->buffer_size_streaming = MAX_BUF_SIZE_STREAMING; } { const char *fmt; if (sizeof(res->start) == sizeof(long long)) fmt = "dim2-%016llx"; else if (sizeof(res->start) == sizeof(long)) fmt = "dim2-%016lx"; else fmt = "dim2-%016x"; snprintf(dev->name, sizeof(dev->name), fmt, res->start); } dev->most_iface.interface = ITYPE_MEDIALB_DIM2; dev->most_iface.description = dev->name; dev->most_iface.num_channels = DMA_CHANNELS; dev->most_iface.channel_vector = dev->capabilities; dev->most_iface.configure = configure_channel; dev->most_iface.enqueue = enqueue; dev->most_iface.dma_alloc = dma_alloc; dev->most_iface.dma_free = dma_free; dev->most_iface.poison_channel = poison_channel; dev->most_iface.request_netinfo = request_netinfo; dev->most_iface.driver_dev = &pdev->dev; dev->dev.init_name = "dim2_state"; dev->dev.parent = &dev->most_iface.dev; ret = most_register_interface(&dev->most_iface); if (ret) { dev_err(&pdev->dev, "failed to register MOST interface\n"); goto err_stop_thread; } ret = dim2_sysfs_probe(&dev->dev); if (ret) { dev_err(&pdev->dev, "failed to create sysfs attribute\n"); goto err_unreg_iface; } return 0; err_unreg_iface: most_deregister_interface(&dev->most_iface); err_stop_thread: kthread_stop(dev->netinfo_task); err_shutdown_dim: dim_shutdown(); err_disable_platform: if (dev->disable_platform) dev->disable_platform(pdev); return ret; }
/* * dim2_probe - dim2 probe handler * @pdev: platform device structure * * Register the dim2 interface with mostcore and initialize it. * Return 0 on success, negative on failure. */ static int dim2_probe(struct platform_device *pdev) { struct dim2_hdm *dev; struct resource *res; int ret, i; struct kobject *kobj; dev = kzalloc(sizeof(*dev), GFP_KERNEL); if (!dev) return -ENOMEM; dev->atx_idx = -1; platform_set_drvdata(pdev, dev); #if defined(ENABLE_HDM_TEST) test_dev = dev; #else res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { pr_err("no memory region defined\n"); ret = -ENOENT; goto err_free_dev; } if (!request_mem_region(res->start, resource_size(res), pdev->name)) { pr_err("failed to request mem region\n"); ret = -EBUSY; goto err_free_dev; } dev->io_base = ioremap(res->start, resource_size(res)); if (!dev->io_base) { pr_err("failed to ioremap\n"); ret = -ENOMEM; goto err_release_mem; } ret = platform_get_irq(pdev, 0); if (ret < 0) { pr_err("failed to get irq\n"); goto err_unmap_io; } dev->irq_ahb0 = ret; ret = request_irq(dev->irq_ahb0, dim2_ahb_isr, 0, "mlb_ahb0", dev); if (ret) { pr_err("failed to request IRQ: %d, err: %d\n", dev->irq_ahb0, ret); goto err_unmap_io; } #endif init_waitqueue_head(&dev->netinfo_waitq); dev->deliver_netinfo = 0; dev->netinfo_task = kthread_run(&deliver_netinfo_thread, (void *)dev, "dim2_netinfo"); if (IS_ERR(dev->netinfo_task)) { ret = PTR_ERR(dev->netinfo_task); goto err_free_irq; } for (i = 0; i < DMA_CHANNELS; i++) { struct most_channel_capability *cap = dev->capabilities + i; struct hdm_channel *hdm_ch = dev->hch + i; INIT_LIST_HEAD(&hdm_ch->pending_list); INIT_LIST_HEAD(&hdm_ch->started_list); hdm_ch->is_initialized = false; snprintf(hdm_ch->name, sizeof(hdm_ch->name), "ca%d", i * 2 + 2); cap->name_suffix = hdm_ch->name; cap->direction = MOST_CH_RX | MOST_CH_TX; cap->data_type = MOST_CH_CONTROL | MOST_CH_ASYNC | MOST_CH_ISOC_AVP | MOST_CH_SYNC; cap->num_buffers_packet = MAX_BUFFERS_PACKET; cap->buffer_size_packet = MAX_BUF_SIZE_PACKET; cap->num_buffers_streaming = MAX_BUFFERS_STREAMING; cap->buffer_size_streaming = MAX_BUF_SIZE_STREAMING; } { const char *fmt; if (sizeof(res->start) == sizeof(long long)) fmt = "dim2-%016llx"; else if (sizeof(res->start) == sizeof(long)) fmt = "dim2-%016lx"; else fmt = "dim2-%016x"; snprintf(dev->name, sizeof(dev->name), fmt, res->start); } dev->most_iface.interface = ITYPE_MEDIALB_DIM2; dev->most_iface.description = dev->name; dev->most_iface.num_channels = DMA_CHANNELS; dev->most_iface.channel_vector = dev->capabilities; dev->most_iface.configure = configure_channel; dev->most_iface.enqueue = enqueue; dev->most_iface.poison_channel = poison_channel; dev->most_iface.request_netinfo = request_netinfo; kobj = most_register_interface(&dev->most_iface); if (IS_ERR(kobj)) { ret = PTR_ERR(kobj); pr_err("failed to register MOST interface\n"); goto err_stop_thread; } ret = dim2_sysfs_probe(&dev->bus, kobj); if (ret) goto err_unreg_iface; ret = startup_dim(pdev); if (ret) { pr_err("failed to initialize DIM2\n"); goto err_destroy_bus; } return 0; err_destroy_bus: dim2_sysfs_destroy(&dev->bus); err_unreg_iface: most_deregister_interface(&dev->most_iface); err_stop_thread: kthread_stop(dev->netinfo_task); err_free_irq: #if !defined(ENABLE_HDM_TEST) free_irq(dev->irq_ahb0, dev); err_unmap_io: iounmap(dev->io_base); err_release_mem: release_mem_region(res->start, resource_size(res)); err_free_dev: #endif kfree(dev); return ret; }