diff options
Diffstat (limited to 'drivers/staging/axis-fifo')
-rw-r--r-- | drivers/staging/axis-fifo/axis-fifo.c | 301 | ||||
-rw-r--r-- | drivers/staging/axis-fifo/axis-fifo.txt | 18 |
2 files changed, 90 insertions, 229 deletions
diff --git a/drivers/staging/axis-fifo/axis-fifo.c b/drivers/staging/axis-fifo/axis-fifo.c index 805437fa249a..39e6c59df1e9 100644 --- a/drivers/staging/axis-fifo/axis-fifo.c +++ b/drivers/staging/axis-fifo/axis-fifo.c @@ -125,7 +125,6 @@ MODULE_PARM_DESC(write_timeout, "ms to wait before blocking write() timing out; struct axis_fifo { int irq; /* interrupt */ - struct resource *mem; /* physical memory */ void __iomem *base_addr; /* kernel space memory */ unsigned int rx_fifo_depth; /* max words in the receive fifo */ @@ -701,6 +700,68 @@ static int get_dts_property(struct axis_fifo *fifo, return 0; } +static int axis_fifo_parse_dt(struct axis_fifo *fifo) +{ + int ret; + unsigned int value; + + ret = get_dts_property(fifo, "xlnx,axi-str-rxd-tdata-width", &value); + if (ret) { + dev_err(fifo->dt_device, "missing xlnx,axi-str-rxd-tdata-width property\n"); + goto end; + } else if (value != 32) { + dev_err(fifo->dt_device, "xlnx,axi-str-rxd-tdata-width only supports 32 bits\n"); + ret = -EIO; + goto end; + } + + ret = get_dts_property(fifo, "xlnx,axi-str-txd-tdata-width", &value); + if (ret) { + dev_err(fifo->dt_device, "missing xlnx,axi-str-txd-tdata-width property\n"); + goto end; + } else if (value != 32) { + dev_err(fifo->dt_device, "xlnx,axi-str-txd-tdata-width only supports 32 bits\n"); + ret = -EIO; + goto end; + } + + ret = get_dts_property(fifo, "xlnx,rx-fifo-depth", + &fifo->rx_fifo_depth); + if (ret) { + dev_err(fifo->dt_device, "missing xlnx,rx-fifo-depth property\n"); + ret = -EIO; + goto end; + } + + ret = get_dts_property(fifo, "xlnx,tx-fifo-depth", + &fifo->tx_fifo_depth); + if (ret) { + dev_err(fifo->dt_device, "missing xlnx,tx-fifo-depth property\n"); + ret = -EIO; + goto end; + } + + /* IP sets TDFV to fifo depth - 4 so we will do the same */ + fifo->tx_fifo_depth -= 4; + + ret = get_dts_property(fifo, "xlnx,use-rx-data", &fifo->has_rx_fifo); + if (ret) { + dev_err(fifo->dt_device, "missing xlnx,use-rx-data property\n"); + ret = -EIO; + goto end; + } + + ret = get_dts_property(fifo, "xlnx,use-tx-data", &fifo->has_tx_fifo); + if (ret) { + dev_err(fifo->dt_device, "missing xlnx,use-tx-data property\n"); + ret = -EIO; + goto end; + } + +end: + return ret; +} + static int axis_fifo_probe(struct platform_device *pdev) { struct resource *r_irq; /* interrupt resources */ @@ -712,34 +773,6 @@ static int axis_fifo_probe(struct platform_device *pdev) int rc = 0; /* error return value */ - /* IP properties from device tree */ - unsigned int rxd_tdata_width; - unsigned int txc_tdata_width; - unsigned int txd_tdata_width; - unsigned int tdest_width; - unsigned int tid_width; - unsigned int tuser_width; - unsigned int data_interface_type; - unsigned int has_tdest; - unsigned int has_tid; - unsigned int has_tkeep; - unsigned int has_tstrb; - unsigned int has_tuser; - unsigned int rx_fifo_depth; - unsigned int rx_programmable_empty_threshold; - unsigned int rx_programmable_full_threshold; - unsigned int axi_id_width; - unsigned int axi4_data_width; - unsigned int select_xpm; - unsigned int tx_fifo_depth; - unsigned int tx_programmable_empty_threshold; - unsigned int tx_programmable_full_threshold; - unsigned int use_rx_cut_through; - unsigned int use_rx_data; - unsigned int use_tx_control; - unsigned int use_tx_cut_through; - unsigned int use_tx_data; - /* ---------------------------- * init wrapper device * ---------------------------- @@ -772,32 +805,19 @@ static int axis_fifo_probe(struct platform_device *pdev) goto err_initial; } - fifo->mem = r_mem; - /* request physical memory */ - if (!request_mem_region(fifo->mem->start, resource_size(fifo->mem), - DRIVER_NAME)) { - dev_err(fifo->dt_device, - "couldn't lock memory region at 0x%pa\n", - &fifo->mem->start); - rc = -EBUSY; + fifo->base_addr = devm_ioremap_resource(fifo->dt_device, r_mem); + if (IS_ERR(fifo->base_addr)) { + rc = PTR_ERR(fifo->base_addr); + dev_err(fifo->dt_device, "can't remap IO resource (%d)\n", rc); goto err_initial; } - dev_dbg(fifo->dt_device, "got memory location [0x%pa - 0x%pa]\n", - &fifo->mem->start, &fifo->mem->end); - - /* map physical memory to kernel virtual address space */ - fifo->base_addr = ioremap(fifo->mem->start, resource_size(fifo->mem)); - if (!fifo->base_addr) { - dev_err(fifo->dt_device, "couldn't map physical memory\n"); - rc = -ENOMEM; - goto err_mem; - } + dev_dbg(fifo->dt_device, "remapped memory to 0x%p\n", fifo->base_addr); /* create unique device name */ snprintf(device_name, sizeof(device_name), "%s_%pa", - DRIVER_NAME, &fifo->mem->start); + DRIVER_NAME, &r_mem->start); dev_dbg(fifo->dt_device, "device name [%s]\n", device_name); @@ -806,164 +826,9 @@ static int axis_fifo_probe(struct platform_device *pdev) * ---------------------------- */ - /* retrieve device tree properties */ - rc = get_dts_property(fifo, "xlnx,axi-str-rxd-tdata-width", - &rxd_tdata_width); - if (rc) - goto err_unmap; - rc = get_dts_property(fifo, "xlnx,axi-str-txc-tdata-width", - &txc_tdata_width); - if (rc) - goto err_unmap; - rc = get_dts_property(fifo, "xlnx,axi-str-txd-tdata-width", - &txd_tdata_width); - if (rc) - goto err_unmap; - rc = get_dts_property(fifo, "xlnx,axis-tdest-width", &tdest_width); - if (rc) - goto err_unmap; - rc = get_dts_property(fifo, "xlnx,axis-tid-width", &tid_width); - if (rc) - goto err_unmap; - rc = get_dts_property(fifo, "xlnx,axis-tuser-width", &tuser_width); - if (rc) - goto err_unmap; - rc = get_dts_property(fifo, "xlnx,data-interface-type", - &data_interface_type); - if (rc) - goto err_unmap; - rc = get_dts_property(fifo, "xlnx,has-axis-tdest", &has_tdest); - if (rc) - goto err_unmap; - rc = get_dts_property(fifo, "xlnx,has-axis-tid", &has_tid); - if (rc) - goto err_unmap; - rc = get_dts_property(fifo, "xlnx,has-axis-tkeep", &has_tkeep); - if (rc) - goto err_unmap; - rc = get_dts_property(fifo, "xlnx,has-axis-tstrb", &has_tstrb); - if (rc) - goto err_unmap; - rc = get_dts_property(fifo, "xlnx,has-axis-tuser", &has_tuser); - if (rc) - goto err_unmap; - rc = get_dts_property(fifo, "xlnx,rx-fifo-depth", &rx_fifo_depth); - if (rc) - goto err_unmap; - rc = get_dts_property(fifo, "xlnx,rx-fifo-pe-threshold", - &rx_programmable_empty_threshold); - if (rc) - goto err_unmap; - rc = get_dts_property(fifo, "xlnx,rx-fifo-pf-threshold", - &rx_programmable_full_threshold); - if (rc) - goto err_unmap; - rc = get_dts_property(fifo, "xlnx,s-axi-id-width", &axi_id_width); - if (rc) - goto err_unmap; - rc = get_dts_property(fifo, "xlnx,s-axi4-data-width", &axi4_data_width); - if (rc) - goto err_unmap; - rc = get_dts_property(fifo, "xlnx,select-xpm", &select_xpm); + rc = axis_fifo_parse_dt(fifo); if (rc) - goto err_unmap; - rc = get_dts_property(fifo, "xlnx,tx-fifo-depth", &tx_fifo_depth); - if (rc) - goto err_unmap; - rc = get_dts_property(fifo, "xlnx,tx-fifo-pe-threshold", - &tx_programmable_empty_threshold); - if (rc) - goto err_unmap; - rc = get_dts_property(fifo, "xlnx,tx-fifo-pf-threshold", - &tx_programmable_full_threshold); - if (rc) - goto err_unmap; - rc = get_dts_property(fifo, "xlnx,use-rx-cut-through", - &use_rx_cut_through); - if (rc) - goto err_unmap; - rc = get_dts_property(fifo, "xlnx,use-rx-data", &use_rx_data); - if (rc) - goto err_unmap; - rc = get_dts_property(fifo, "xlnx,use-tx-ctrl", &use_tx_control); - if (rc) - goto err_unmap; - rc = get_dts_property(fifo, "xlnx,use-tx-cut-through", - &use_tx_cut_through); - if (rc) - goto err_unmap; - rc = get_dts_property(fifo, "xlnx,use-tx-data", &use_tx_data); - if (rc) - goto err_unmap; - - /* check validity of device tree properties */ - if (rxd_tdata_width != 32) { - dev_err(fifo->dt_device, - "rxd_tdata_width width [%u] unsupported\n", - rxd_tdata_width); - rc = -EIO; - goto err_unmap; - } - if (txd_tdata_width != 32) { - dev_err(fifo->dt_device, - "txd_tdata_width width [%u] unsupported\n", - txd_tdata_width); - rc = -EIO; - goto err_unmap; - } - if (has_tdest) { - dev_err(fifo->dt_device, "tdest not supported\n"); - rc = -EIO; - goto err_unmap; - } - if (has_tid) { - dev_err(fifo->dt_device, "tid not supported\n"); - rc = -EIO; - goto err_unmap; - } - if (has_tkeep) { - dev_err(fifo->dt_device, "tkeep not supported\n"); - rc = -EIO; - goto err_unmap; - } - if (has_tstrb) { - dev_err(fifo->dt_device, "tstrb not supported\n"); - rc = -EIO; - goto err_unmap; - } - if (has_tuser) { - dev_err(fifo->dt_device, "tuser not supported\n"); - rc = -EIO; - goto err_unmap; - } - if (use_rx_cut_through) { - dev_err(fifo->dt_device, "rx cut-through not supported\n"); - rc = -EIO; - goto err_unmap; - } - if (use_tx_cut_through) { - dev_err(fifo->dt_device, "tx cut-through not supported\n"); - rc = -EIO; - goto err_unmap; - } - if (use_tx_control) { - dev_err(fifo->dt_device, "tx control not supported\n"); - rc = -EIO; - goto err_unmap; - } - - /* TODO - * these exist in the device tree but it's unclear what they do - * - select-xpm - * - data-interface-type - */ - - /* set device wrapper properties based on IP config */ - fifo->rx_fifo_depth = rx_fifo_depth; - /* IP sets TDFV to fifo depth - 4 so we will do the same */ - fifo->tx_fifo_depth = tx_fifo_depth - 4; - fifo->has_rx_fifo = use_rx_data; - fifo->has_tx_fifo = use_tx_data; + goto err_initial; reset_ip_core(fifo); @@ -976,18 +841,19 @@ static int axis_fifo_probe(struct platform_device *pdev) r_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (!r_irq) { dev_err(fifo->dt_device, "no IRQ found for 0x%pa\n", - &fifo->mem->start); + &r_mem->start); rc = -EIO; - goto err_unmap; + goto err_initial; } /* request IRQ */ fifo->irq = r_irq->start; - rc = request_irq(fifo->irq, &axis_fifo_irq, 0, DRIVER_NAME, fifo); + rc = devm_request_irq(fifo->dt_device, fifo->irq, &axis_fifo_irq, 0, + DRIVER_NAME, fifo); if (rc) { dev_err(fifo->dt_device, "couldn't allocate interrupt %i\n", fifo->irq); - goto err_unmap; + goto err_initial; } /* ---------------------------- @@ -998,7 +864,7 @@ static int axis_fifo_probe(struct platform_device *pdev) /* allocate device number */ rc = alloc_chrdev_region(&fifo->devt, 0, 1, DRIVER_NAME); if (rc < 0) - goto err_irq; + goto err_initial; dev_dbg(fifo->dt_device, "allocated device number major %i minor %i\n", MAJOR(fifo->devt), MINOR(fifo->devt)); @@ -1022,14 +888,14 @@ static int axis_fifo_probe(struct platform_device *pdev) } /* create sysfs entries */ - rc = sysfs_create_group(&fifo->device->kobj, &axis_fifo_attrs_group); + rc = devm_device_add_group(fifo->device, &axis_fifo_attrs_group); if (rc < 0) { dev_err(fifo->dt_device, "couldn't register sysfs group\n"); goto err_cdev; } dev_info(fifo->dt_device, "axis-fifo created at %pa mapped to 0x%pa, irq=%i, major=%i, minor=%i\n", - &fifo->mem->start, &fifo->base_addr, fifo->irq, + &r_mem->start, &fifo->base_addr, fifo->irq, MAJOR(fifo->devt), MINOR(fifo->devt)); return 0; @@ -1040,12 +906,6 @@ err_dev: device_destroy(axis_fifo_driver_class, fifo->devt); err_chrdev_region: unregister_chrdev_region(fifo->devt, 1); -err_irq: - free_irq(fifo->irq, fifo); -err_unmap: - iounmap(fifo->base_addr); -err_mem: - release_mem_region(fifo->mem->start, resource_size(fifo->mem)); err_initial: dev_set_drvdata(dev, NULL); return rc; @@ -1056,15 +916,12 @@ static int axis_fifo_remove(struct platform_device *pdev) struct device *dev = &pdev->dev; struct axis_fifo *fifo = dev_get_drvdata(dev); - sysfs_remove_group(&fifo->device->kobj, &axis_fifo_attrs_group); cdev_del(&fifo->char_device); dev_set_drvdata(fifo->device, NULL); device_destroy(axis_fifo_driver_class, fifo->devt); unregister_chrdev_region(fifo->devt, 1); - free_irq(fifo->irq, fifo); - iounmap(fifo->base_addr); - release_mem_region(fifo->mem->start, resource_size(fifo->mem)); dev_set_drvdata(dev, NULL); + return 0; } diff --git a/drivers/staging/axis-fifo/axis-fifo.txt b/drivers/staging/axis-fifo/axis-fifo.txt index 85d88c010e72..5828e1b8e822 100644 --- a/drivers/staging/axis-fifo/axis-fifo.txt +++ b/drivers/staging/axis-fifo/axis-fifo.txt @@ -25,10 +25,10 @@ Required properties: - xlnx,axi-str-txc-tdata-width: Should be <0x20> - xlnx,axi-str-txd-protocol: Should be "XIL_AXI_STREAM_ETH_DATA" - xlnx,axi-str-txd-tdata-width: Should be <0x20> -- xlnx,axis-tdest-width: AXI-Stream TDEST width -- xlnx,axis-tid-width: AXI-Stream TID width -- xlnx,axis-tuser-width: AXI-Stream TUSER width -- xlnx,data-interface-type: Should be <0x0> +- xlnx,axis-tdest-width: AXI-Stream TDEST width (ignored by the driver) +- xlnx,axis-tid-width: AXI-Stream TID width (ignored by the driver) +- xlnx,axis-tuser-width: AXI-Stream TUSER width (ignored by the driver) +- xlnx,data-interface-type: Should be <0x0> (ignored by the driver) - xlnx,has-axis-tdest: Should be <0x0> (this feature isn't supported) - xlnx,has-axis-tid: Should be <0x0> (this feature isn't supported) - xlnx,has-axis-tkeep: Should be <0x0> (this feature isn't supported) @@ -36,13 +36,17 @@ Required properties: - xlnx,has-axis-tuser: Should be <0x0> (this feature isn't supported) - xlnx,rx-fifo-depth: Depth of RX FIFO in words - xlnx,rx-fifo-pe-threshold: RX programmable empty interrupt threshold + (ignored by the driver) - xlnx,rx-fifo-pf-threshold: RX programmable full interrupt threshold -- xlnx,s-axi-id-width: Should be <0x4> -- xlnx,s-axi4-data-width: Should be <0x20> -- xlnx,select-xpm: Should be <0x0> + (ignored by the driver) +- xlnx,s-axi-id-width: Should be <0x4> (ignored by the driver) +- xlnx,s-axi4-data-width: Should be <0x20> (ignored by the driver) +- xlnx,select-xpm: Should be <0x0> (ignored by the driver) - xlnx,tx-fifo-depth: Depth of TX FIFO in words - xlnx,tx-fifo-pe-threshold: TX programmable empty interrupt threshold + (ignored by the driver) - xlnx,tx-fifo-pf-threshold: TX programmable full interrupt threshold + (ignored by the driver) - xlnx,use-rx-cut-through: Should be <0x0> (this feature isn't supported) - xlnx,use-rx-data: <0x1> if RX FIFO is enabled, <0x0> otherwise - xlnx,use-tx-ctrl: Should be <0x0> (this feature isn't supported) |