Merge tag 'for-linus-5.3' of git://github.com/cminyard/linux-ipmi
[linux-2.6-block.git] / drivers / hwtracing / coresight / coresight-tmc.c
index 3f718729d741060eff20002cdf78c74655983e21..be37aff573b44a225de50a1dd36475cafc1ecfc5 100644 (file)
 #include "coresight-priv.h"
 #include "coresight-tmc.h"
 
+DEFINE_CORESIGHT_DEVLIST(etb_devs, "tmc_etb");
+DEFINE_CORESIGHT_DEVLIST(etf_devs, "tmc_etf");
+DEFINE_CORESIGHT_DEVLIST(etr_devs, "tmc_etr");
+
 void tmc_wait_for_tmcready(struct tmc_drvdata *drvdata)
 {
        /* Ensure formatter, unformatter and hardware fifo are empty */
        if (coresight_timeout(drvdata->base,
                              TMC_STS, TMC_STS_TMCREADY_BIT, 1)) {
-               dev_err(drvdata->dev,
+               dev_err(&drvdata->csdev->dev,
                        "timeout while waiting for TMC to be Ready\n");
        }
 }
@@ -49,7 +53,7 @@ void tmc_flush_and_stop(struct tmc_drvdata *drvdata)
        /* Ensure flush completes */
        if (coresight_timeout(drvdata->base,
                              TMC_FFCR, TMC_FFCR_FLUSHMAN_BIT, 0)) {
-               dev_err(drvdata->dev,
+               dev_err(&drvdata->csdev->dev,
                "timeout while waiting for completion of Manual Flush\n");
        }
 
@@ -83,7 +87,7 @@ static int tmc_read_prepare(struct tmc_drvdata *drvdata)
        }
 
        if (!ret)
-               dev_dbg(drvdata->dev, "TMC read start\n");
+               dev_dbg(&drvdata->csdev->dev, "TMC read start\n");
 
        return ret;
 }
@@ -105,7 +109,7 @@ static int tmc_read_unprepare(struct tmc_drvdata *drvdata)
        }
 
        if (!ret)
-               dev_dbg(drvdata->dev, "TMC read end\n");
+               dev_dbg(&drvdata->csdev->dev, "TMC read end\n");
 
        return ret;
 }
@@ -122,7 +126,7 @@ static int tmc_open(struct inode *inode, struct file *file)
 
        nonseekable_open(inode, file);
 
-       dev_dbg(drvdata->dev, "%s: successfully opened\n", __func__);
+       dev_dbg(&drvdata->csdev->dev, "%s: successfully opened\n", __func__);
        return 0;
 }
 
@@ -152,12 +156,13 @@ static ssize_t tmc_read(struct file *file, char __user *data, size_t len,
                return 0;
 
        if (copy_to_user(data, bufp, actual)) {
-               dev_dbg(drvdata->dev, "%s: copy_to_user failed\n", __func__);
+               dev_dbg(&drvdata->csdev->dev,
+                       "%s: copy_to_user failed\n", __func__);
                return -EFAULT;
        }
 
        *ppos += actual;
-       dev_dbg(drvdata->dev, "%zu bytes copied\n", actual);
+       dev_dbg(&drvdata->csdev->dev, "%zu bytes copied\n", actual);
 
        return actual;
 }
@@ -172,7 +177,7 @@ static int tmc_release(struct inode *inode, struct file *file)
        if (ret)
                return ret;
 
-       dev_dbg(drvdata->dev, "%s: released\n", __func__);
+       dev_dbg(&drvdata->csdev->dev, "%s: released\n", __func__);
        return 0;
 }
 
@@ -332,24 +337,22 @@ const struct attribute_group *coresight_tmc_groups[] = {
        NULL,
 };
 
-static inline bool tmc_etr_can_use_sg(struct tmc_drvdata *drvdata)
+static inline bool tmc_etr_can_use_sg(struct device *dev)
 {
-       return fwnode_property_present(drvdata->dev->fwnode,
-                                      "arm,scatter-gather");
+       return fwnode_property_present(dev->fwnode, "arm,scatter-gather");
 }
 
 /* Detect and initialise the capabilities of a TMC ETR */
-static int tmc_etr_setup_caps(struct tmc_drvdata *drvdata,
-                            u32 devid, void *dev_caps)
+static int tmc_etr_setup_caps(struct device *parent, u32 devid, void *dev_caps)
 {
        int rc;
-
        u32 dma_mask = 0;
+       struct tmc_drvdata *drvdata = dev_get_drvdata(parent);
 
        /* Set the unadvertised capabilities */
        tmc_etr_init_caps(drvdata, (u32)(unsigned long)dev_caps);
 
-       if (!(devid & TMC_DEVID_NOSCAT) && tmc_etr_can_use_sg(drvdata))
+       if (!(devid & TMC_DEVID_NOSCAT) && tmc_etr_can_use_sg(parent))
                tmc_etr_set_cap(drvdata, TMC_ETR_SG);
 
        /* Check if the AXI address width is available */
@@ -367,18 +370,27 @@ static int tmc_etr_setup_caps(struct tmc_drvdata *drvdata,
        case 44:
        case 48:
        case 52:
-               dev_info(drvdata->dev, "Detected dma mask %dbits\n", dma_mask);
+               dev_info(parent, "Detected dma mask %dbits\n", dma_mask);
                break;
        default:
                dma_mask = 40;
        }
 
-       rc = dma_set_mask_and_coherent(drvdata->dev, DMA_BIT_MASK(dma_mask));
+       rc = dma_set_mask_and_coherent(parent, DMA_BIT_MASK(dma_mask));
        if (rc)
-               dev_err(drvdata->dev, "Failed to setup DMA mask: %d\n", rc);
+               dev_err(parent, "Failed to setup DMA mask: %d\n", rc);
        return rc;
 }
 
+static u32 tmc_etr_get_default_buffer_size(struct device *dev)
+{
+       u32 size;
+
+       if (fwnode_property_read_u32(dev->fwnode, "arm,buffer-size", &size))
+               size = SZ_1M;
+       return size;
+}
+
 static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
 {
        int ret = 0;
@@ -389,23 +401,13 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
        struct tmc_drvdata *drvdata;
        struct resource *res = &adev->res;
        struct coresight_desc desc = { 0 };
-       struct device_node *np = adev->dev.of_node;
-
-       if (np) {
-               pdata = of_get_coresight_platform_data(dev, np);
-               if (IS_ERR(pdata)) {
-                       ret = PTR_ERR(pdata);
-                       goto out;
-               }
-               adev->dev.platform_data = pdata;
-       }
+       struct coresight_dev_list *dev_list = NULL;
 
        ret = -ENOMEM;
        drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
        if (!drvdata)
                goto out;
 
-       drvdata->dev = &adev->dev;
        dev_set_drvdata(dev, drvdata);
 
        /* Validity for the resource is already checked by the AMBA core */
@@ -425,18 +427,11 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
        /* This device is not associated with a session */
        drvdata->pid = -1;
 
-       if (drvdata->config_type == TMC_CONFIG_TYPE_ETR) {
-               if (np)
-                       ret = of_property_read_u32(np,
-                                                  "arm,buffer-size",
-                                                  &drvdata->size);
-               if (ret)
-                       drvdata->size = SZ_1M;
-       } else {
+       if (drvdata->config_type == TMC_CONFIG_TYPE_ETR)
+               drvdata->size = tmc_etr_get_default_buffer_size(dev);
+       else
                drvdata->size = readl_relaxed(drvdata->base + TMC_RSZ) * 4;
-       }
 
-       desc.pdata = pdata;
        desc.dev = dev;
        desc.groups = coresight_tmc_groups;
 
@@ -445,36 +440,53 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
                desc.type = CORESIGHT_DEV_TYPE_SINK;
                desc.subtype.sink_subtype = CORESIGHT_DEV_SUBTYPE_SINK_BUFFER;
                desc.ops = &tmc_etb_cs_ops;
+               dev_list = &etb_devs;
                break;
        case TMC_CONFIG_TYPE_ETR:
                desc.type = CORESIGHT_DEV_TYPE_SINK;
                desc.subtype.sink_subtype = CORESIGHT_DEV_SUBTYPE_SINK_BUFFER;
                desc.ops = &tmc_etr_cs_ops;
-               ret = tmc_etr_setup_caps(drvdata, devid,
+               ret = tmc_etr_setup_caps(dev, devid,
                                         coresight_get_uci_data(id));
                if (ret)
                        goto out;
                idr_init(&drvdata->idr);
                mutex_init(&drvdata->idr_mutex);
+               dev_list = &etr_devs;
                break;
        case TMC_CONFIG_TYPE_ETF:
                desc.type = CORESIGHT_DEV_TYPE_LINKSINK;
                desc.subtype.link_subtype = CORESIGHT_DEV_SUBTYPE_LINK_FIFO;
                desc.ops = &tmc_etf_cs_ops;
+               dev_list = &etf_devs;
                break;
        default:
-               pr_err("%s: Unsupported TMC config\n", pdata->name);
+               pr_err("%s: Unsupported TMC config\n", desc.name);
                ret = -EINVAL;
                goto out;
        }
 
+       desc.name = coresight_alloc_device_name(dev_list, dev);
+       if (!desc.name) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       pdata = coresight_get_platform_data(dev);
+       if (IS_ERR(pdata)) {
+               ret = PTR_ERR(pdata);
+               goto out;
+       }
+       adev->dev.platform_data = pdata;
+       desc.pdata = pdata;
+
        drvdata->csdev = coresight_register(&desc);
        if (IS_ERR(drvdata->csdev)) {
                ret = PTR_ERR(drvdata->csdev);
                goto out;
        }
 
-       drvdata->miscdev.name = pdata->name;
+       drvdata->miscdev.name = desc.name;
        drvdata->miscdev.minor = MISC_DYNAMIC_MINOR;
        drvdata->miscdev.fops = &tmc_fops;
        ret = misc_register(&drvdata->miscdev);