diff options
Diffstat (limited to 'drivers/hwtracing/coresight/coresight-catu.c')
| -rw-r--r-- | drivers/hwtracing/coresight/coresight-catu.c | 106 |
1 files changed, 56 insertions, 50 deletions
diff --git a/drivers/hwtracing/coresight/coresight-catu.c b/drivers/hwtracing/coresight/coresight-catu.c index bfea880d6dfb..69b36bae97ab 100644 --- a/drivers/hwtracing/coresight/coresight-catu.c +++ b/drivers/hwtracing/coresight/coresight-catu.c @@ -113,9 +113,8 @@ typedef u64 cate_t; * containing the data page pointer for @offset. If @daddrp is not NULL, * @daddrp points the DMA address of the beginning of the table. */ -static inline cate_t *catu_get_table(struct tmc_sg_table *catu_table, - unsigned long offset, - dma_addr_t *daddrp) +static cate_t *catu_get_table(struct tmc_sg_table *catu_table, unsigned long offset, + dma_addr_t *daddrp) { unsigned long buf_size = tmc_sg_table_buf_size(catu_table); unsigned int table_nr, pg_idx, pg_offset; @@ -165,12 +164,12 @@ static void catu_dump_table(struct tmc_sg_table *catu_table) } #else -static inline void catu_dump_table(struct tmc_sg_table *catu_table) +static void catu_dump_table(struct tmc_sg_table *catu_table) { } #endif -static inline cate_t catu_make_entry(dma_addr_t addr) +static cate_t catu_make_entry(dma_addr_t addr) { return addr ? CATU_VALID_ENTRY(addr) : 0; } @@ -269,7 +268,7 @@ catu_init_sg_table(struct device *catu_dev, int node, * Each table can address upto 1MB and we can have * CATU_PAGES_PER_SYSPAGE tables in a system page. */ - nr_tpages = DIV_ROUND_UP(size, SZ_1M) / CATU_PAGES_PER_SYSPAGE; + nr_tpages = DIV_ROUND_UP(size, CATU_PAGES_PER_SYSPAGE * SZ_1M); catu_table = tmc_alloc_sg_table(catu_dev, node, nr_tpages, size >> PAGE_SHIFT, pages); if (IS_ERR(catu_table)) @@ -390,7 +389,7 @@ static const struct attribute_group *catu_groups[] = { }; -static inline int catu_wait_for_ready(struct catu_drvdata *drvdata) +static int catu_wait_for_ready(struct catu_drvdata *drvdata) { struct csdev_access *csa = &drvdata->csdev->access; @@ -398,7 +397,7 @@ static inline int catu_wait_for_ready(struct catu_drvdata *drvdata) } static int catu_enable_hw(struct catu_drvdata *drvdata, enum cs_mode cs_mode, - void *data) + struct coresight_path *path) { int rc; u32 control, mode; @@ -426,7 +425,7 @@ static int catu_enable_hw(struct catu_drvdata *drvdata, enum cs_mode cs_mode, etrdev = coresight_find_input_type( csdev->pdata, CORESIGHT_DEV_TYPE_SINK, etr_subtype); if (etrdev) { - etr_buf = tmc_etr_get_buffer(etrdev, cs_mode, data); + etr_buf = tmc_etr_get_buffer(etrdev, cs_mode, path); if (IS_ERR(etr_buf)) return PTR_ERR(etr_buf); } @@ -456,14 +455,19 @@ static int catu_enable_hw(struct catu_drvdata *drvdata, enum cs_mode cs_mode, } static int catu_enable(struct coresight_device *csdev, enum cs_mode mode, - void *data) + struct coresight_path *path) { - int rc; + int rc = 0; struct catu_drvdata *catu_drvdata = csdev_to_catu_drvdata(csdev); - CS_UNLOCK(catu_drvdata->base); - rc = catu_enable_hw(catu_drvdata, mode, data); - CS_LOCK(catu_drvdata->base); + guard(raw_spinlock_irqsave)(&catu_drvdata->spinlock); + if (csdev->refcnt == 0) { + CS_UNLOCK(catu_drvdata->base); + rc = catu_enable_hw(catu_drvdata, mode, path); + CS_LOCK(catu_drvdata->base); + } + if (!rc) + csdev->refcnt++; return rc; } @@ -484,14 +488,17 @@ static int catu_disable_hw(struct catu_drvdata *drvdata) return rc; } -static int catu_disable(struct coresight_device *csdev, void *__unused) +static int catu_disable(struct coresight_device *csdev, struct coresight_path *path) { - int rc; + int rc = 0; struct catu_drvdata *catu_drvdata = csdev_to_catu_drvdata(csdev); - CS_UNLOCK(catu_drvdata->base); - rc = catu_disable_hw(catu_drvdata); - CS_LOCK(catu_drvdata->base); + guard(raw_spinlock_irqsave)(&catu_drvdata->spinlock); + if (--csdev->refcnt == 0) { + CS_UNLOCK(catu_drvdata->base); + rc = catu_disable_hw(catu_drvdata); + CS_LOCK(catu_drvdata->base); + } return rc; } @@ -508,11 +515,21 @@ static int __catu_probe(struct device *dev, struct resource *res) { int ret = 0; u32 dma_mask; - struct catu_drvdata *drvdata = dev_get_drvdata(dev); + struct catu_drvdata *drvdata; struct coresight_desc catu_desc; struct coresight_platform_data *pdata = NULL; void __iomem *base; + drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); + if (!drvdata) + return -ENOMEM; + + dev_set_drvdata(dev, drvdata); + + ret = coresight_get_enable_clocks(dev, &drvdata->pclk, &drvdata->atclk); + if (ret) + return ret; + catu_desc.name = coresight_alloc_device_name(&catu_devs, dev); if (!catu_desc.name) return -ENOMEM; @@ -550,6 +567,7 @@ static int __catu_probe(struct device *dev, struct resource *res) dev->platform_data = pdata; drvdata->base = base; + raw_spin_lock_init(&drvdata->spinlock); catu_desc.access = CSDEV_ACCESS_IOMEM(base); catu_desc.pdata = pdata; catu_desc.dev = dev; @@ -558,6 +576,7 @@ static int __catu_probe(struct device *dev, struct resource *res) catu_desc.subtype.helper_subtype = CORESIGHT_DEV_SUBTYPE_HELPER_CATU; catu_desc.ops = &catu_ops; + coresight_clear_self_claim_tag(&catu_desc.access); drvdata->csdev = coresight_register(&catu_desc); if (IS_ERR(drvdata->csdev)) ret = PTR_ERR(drvdata->csdev); @@ -567,14 +586,8 @@ out: static int catu_probe(struct amba_device *adev, const struct amba_id *id) { - struct catu_drvdata *drvdata; int ret; - drvdata = devm_kzalloc(&adev->dev, sizeof(*drvdata), GFP_KERNEL); - if (!drvdata) - return -ENOMEM; - - amba_set_drvdata(adev, drvdata); ret = __catu_probe(&adev->dev, &adev->res); if (!ret) pm_runtime_put(&adev->dev); @@ -594,7 +607,7 @@ static void catu_remove(struct amba_device *adev) __catu_remove(&adev->dev); } -static struct amba_id catu_ids[] = { +static const struct amba_id catu_ids[] = { CS_AMBA_ID(0x000bb9ee), {}, }; @@ -614,29 +627,16 @@ static struct amba_driver catu_driver = { static int catu_platform_probe(struct platform_device *pdev) { struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - struct catu_drvdata *drvdata; int ret = 0; - drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL); - if (!drvdata) - return -ENOMEM; - - drvdata->pclk = coresight_get_enable_apb_pclk(&pdev->dev); - if (IS_ERR(drvdata->pclk)) - return -ENODEV; - pm_runtime_get_noresume(&pdev->dev); pm_runtime_set_active(&pdev->dev); pm_runtime_enable(&pdev->dev); - dev_set_drvdata(&pdev->dev, drvdata); ret = __catu_probe(&pdev->dev, res); pm_runtime_put(&pdev->dev); - if (ret) { + if (ret) pm_runtime_disable(&pdev->dev); - if (!IS_ERR_OR_NULL(drvdata->pclk)) - clk_put(drvdata->pclk); - } return ret; } @@ -650,8 +650,6 @@ static void catu_platform_remove(struct platform_device *pdev) __catu_remove(&pdev->dev); pm_runtime_disable(&pdev->dev); - if (!IS_ERR_OR_NULL(drvdata->pclk)) - clk_put(drvdata->pclk); } #ifdef CONFIG_PM @@ -659,18 +657,26 @@ static int catu_runtime_suspend(struct device *dev) { struct catu_drvdata *drvdata = dev_get_drvdata(dev); - if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk)) - clk_disable_unprepare(drvdata->pclk); + clk_disable_unprepare(drvdata->atclk); + clk_disable_unprepare(drvdata->pclk); + return 0; } static int catu_runtime_resume(struct device *dev) { struct catu_drvdata *drvdata = dev_get_drvdata(dev); + int ret; - if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk)) - clk_prepare_enable(drvdata->pclk); - return 0; + ret = clk_prepare_enable(drvdata->pclk); + if (ret) + return ret; + + ret = clk_prepare_enable(drvdata->atclk); + if (ret) + clk_disable_unprepare(drvdata->pclk); + + return ret; } #endif @@ -689,7 +695,7 @@ MODULE_DEVICE_TABLE(acpi, catu_acpi_ids); static struct platform_driver catu_platform_driver = { .probe = catu_platform_probe, - .remove_new = catu_platform_remove, + .remove = catu_platform_remove, .driver = { .name = "coresight-catu-platform", .acpi_match_table = ACPI_PTR(catu_acpi_ids), @@ -702,7 +708,7 @@ static int __init catu_init(void) { int ret; - ret = coresight_init_driver("catu", &catu_driver, &catu_platform_driver); + ret = coresight_init_driver("catu", &catu_driver, &catu_platform_driver, THIS_MODULE); tmc_etr_set_catu_ops(&etr_catu_buf_ops); return ret; } |
