diff --git a/drivers/hwtracing/coresight/coresight-byte-cntr.c b/drivers/hwtracing/coresight/coresight-byte-cntr.c index 80f2a3f6322c..e30d2d8127a5 100644 --- a/drivers/hwtracing/coresight/coresight-byte-cntr.c +++ b/drivers/hwtracing/coresight/coresight-byte-cntr.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -18,7 +18,7 @@ #define CSR_BYTECNTVAL (0x06C) -static void tmc_etr_read_bytes(struct byte_cntr *byte_cntr_data, loff_t *ppos, +static void tmc_etr_read_bytes(struct byte_cntr *byte_cntr_data, long offset, size_t bytes, size_t *len, char **bufp) { struct tmc_drvdata *tmcdrvdata = byte_cntr_data->tmcdrvdata; @@ -27,12 +27,12 @@ static void tmc_etr_read_bytes(struct byte_cntr *byte_cntr_data, loff_t *ppos, if (*len >= bytes) *len = bytes; - else if (((uint32_t)*ppos % bytes) + *len > bytes) - *len = bytes - ((uint32_t)*ppos % bytes); + else if (((uint32_t)offset % bytes) + *len > bytes) + *len = bytes - ((uint32_t)offset % bytes); - actual = tmc_etr_buf_get_data(etr_buf, *ppos, *len, bufp); + actual = tmc_etr_buf_get_data(etr_buf, offset, *len, bufp); *len = actual; - if (actual == bytes || (actual + (uint32_t)*ppos) % bytes == 0) + if (actual == bytes || (actual + (uint32_t)offset) % bytes == 0) atomic_dec(&byte_cntr_data->irq_cnt); } @@ -50,22 +50,42 @@ static irqreturn_t etr_handler(int irq, void *data) wake_up(&byte_cntr_data->wq); } + byte_cntr_data->total_irq++; + return IRQ_HANDLED; } -static long tmc_etr_flush_remaining_bytes(struct tmc_drvdata *tmcdrvdata, loff_t *ppos, - char **bufpp) +static long tmc_etr_flush_remaining_bytes(struct tmc_drvdata *tmcdrvdata, long offset, + size_t len, char **bufpp) { long rwp_offset, req_size, actual = 0; - struct etr_buf *etr_buf = tmcdrvdata->sysfs_buf; + struct etr_buf *etr_buf; + struct device *dev; + int rc = 0; + + if (!tmcdrvdata) + return -EINVAL; + + etr_buf = tmcdrvdata->sysfs_buf; + dev = &tmcdrvdata->csdev->dev; + + rc = pm_runtime_get_sync(dev->parent); + if (rc < 0) { + pm_runtime_put_noidle(dev->parent); + return rc; + } rwp_offset = tmc_get_rwp_offset(tmcdrvdata); - req_size = ((rwp_offset < *ppos) ? tmcdrvdata->size : 0) + - rwp_offset - *ppos; + pm_runtime_put(dev->parent); + req_size = ((rwp_offset < offset) ? tmcdrvdata->size : 0) + + rwp_offset - offset; + + if (req_size > len) + req_size = len; if (req_size > 0) - actual = tmc_etr_buf_get_data(etr_buf, *ppos, req_size, bufpp); + actual = tmc_etr_buf_get_data(etr_buf, offset, req_size, bufpp); return actual; } @@ -85,7 +105,8 @@ static ssize_t tmc_etr_byte_cntr_read(struct file *fp, char __user *data, mutex_lock(&byte_cntr_data->byte_cntr_lock); if (!byte_cntr_data->read_active) { - actual = tmc_etr_flush_remaining_bytes(tmcdrvdata, ppos, &bufp); + actual = tmc_etr_flush_remaining_bytes(tmcdrvdata, + byte_cntr_data->offset, len, &bufp); if (actual > 0) { len = actual; goto copy; @@ -104,7 +125,8 @@ static ssize_t tmc_etr_byte_cntr_read(struct file *fp, char __user *data, return -ERESTARTSYS; mutex_lock(&byte_cntr_data->byte_cntr_lock); if (!byte_cntr_data->read_active) { - actual = tmc_etr_flush_remaining_bytes(tmcdrvdata, ppos, &bufp); + actual = tmc_etr_flush_remaining_bytes(tmcdrvdata, + byte_cntr_data->offset, len, &bufp); if (actual > 0) { len = actual; goto copy; @@ -115,11 +137,12 @@ static ssize_t tmc_etr_byte_cntr_read(struct file *fp, char __user *data, } } - tmc_etr_read_bytes(byte_cntr_data, ppos, + tmc_etr_read_bytes(byte_cntr_data, byte_cntr_data->offset, byte_cntr_data->block_size, &len, &bufp); } else { - actual = tmc_etr_flush_remaining_bytes(tmcdrvdata, ppos, &bufp); + actual = tmc_etr_flush_remaining_bytes(tmcdrvdata, + byte_cntr_data->offset, len, &bufp); if (actual > 0) { len = actual; goto copy; @@ -137,10 +160,12 @@ static ssize_t tmc_etr_byte_cntr_read(struct file *fp, char __user *data, return -EFAULT; } - if (*ppos + len >= tmcdrvdata->size) - *ppos = 0; + byte_cntr_data->total_size += len; + + if (byte_cntr_data->offset + len >= tmcdrvdata->size) + byte_cntr_data->offset = 0; else - *ppos += len; + byte_cntr_data->offset += len; goto out; @@ -192,6 +217,8 @@ EXPORT_SYMBOL(tmc_etr_byte_cntr_stop); static int tmc_etr_byte_cntr_release(struct inode *in, struct file *fp) { struct byte_cntr *byte_cntr_data = fp->private_data; + struct device *dev = &byte_cntr_data->tmcdrvdata->csdev->dev; + int rc; mutex_lock(&byte_cntr_data->byte_cntr_lock); byte_cntr_data->read_active = false; @@ -203,6 +230,21 @@ static int tmc_etr_byte_cntr_release(struct inode *in, struct file *fp) byte_cntr_data->irqctrl_offset, 0); disable_irq_wake(byte_cntr_data->byte_cntr_irq); + + rc = pm_runtime_get_sync(dev->parent); + if (rc < 0) { + pm_runtime_put_noidle(dev->parent); + } else { + byte_cntr_data->rwp_offset = + tmc_get_rwp_offset(byte_cntr_data->tmcdrvdata); + + pm_runtime_put(dev->parent); + } + + dev_dbg(dev, "send data total size: %lld bytes, irq_cnt: %lld, offset: %lld rwp_offset: %lld\n", + byte_cntr_data->total_size, byte_cntr_data->total_irq, + byte_cntr_data->offset, byte_cntr_data->rwp_offset); + byte_cntr_data->total_irq = 0; mutex_unlock(&byte_cntr_data->byte_cntr_lock); return 0; @@ -239,6 +281,8 @@ static int tmc_etr_byte_cntr_open(struct inode *in, struct file *fp) nonseekable_open(in, fp); byte_cntr_data->enable = true; byte_cntr_data->read_active = true; + byte_cntr_data->total_size = 0; + byte_cntr_data->offset = tmc_get_rwp_offset(tmcdrvdata); mutex_unlock(&byte_cntr_data->byte_cntr_lock); return 0; } diff --git a/drivers/hwtracing/coresight/coresight-byte-cntr.h b/drivers/hwtracing/coresight/coresight-byte-cntr.h index 3380fda029f8..634e8724bdd9 100644 --- a/drivers/hwtracing/coresight/coresight-byte-cntr.h +++ b/drivers/hwtracing/coresight/coresight-byte-cntr.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef _CORESIGHT_BYTE_CNTR_H @@ -34,6 +34,10 @@ struct byte_cntr { const char *class_name; int irqctrl_offset; unsigned long offset; + unsigned long rwp_offset; + uint64_t total_size; + uint64_t total_irq; + }; extern void tmc_etr_byte_cntr_start(struct byte_cntr *byte_cntr_data); diff --git a/drivers/hwtracing/coresight/coresight-tmc-usb.c b/drivers/hwtracing/coresight/coresight-tmc-usb.c index 08b766a8edce..f0bf16d1d17b 100644 --- a/drivers/hwtracing/coresight/coresight-tmc-usb.c +++ b/drivers/hwtracing/coresight/coresight-tmc-usb.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Description: CoreSight TMC USB driver */ @@ -82,6 +82,7 @@ static int usb_bypass_start(struct byte_cntr *byte_cntr_data) USB_BLK_SIZE / 8); atomic_set(&byte_cntr_data->irq_cnt, 0); + byte_cntr_data->total_size = 0; mutex_unlock(&byte_cntr_data->usb_bypass_lock); return 0; @@ -102,6 +103,10 @@ static void usb_bypass_stop(struct byte_cntr *byte_cntr_data) wake_up(&byte_cntr_data->usb_wait_wq); pr_info("coresight: stop usb bypass\n"); coresight_csr_set_byte_cntr(byte_cntr_data->csr, byte_cntr_data->irqctrl_offset, 0); + dev_dbg(&byte_cntr_data->tmcdrvdata->csdev->dev, + "write to usb data total size: %lld bytes, irq_cnt: %lld, offset: %ld\n", + byte_cntr_data->total_size, byte_cntr_data->total_irq, byte_cntr_data->offset); + byte_cntr_data->total_irq = 0; mutex_unlock(&byte_cntr_data->usb_bypass_lock); } @@ -172,7 +177,7 @@ static int usb_transfer_small_packet(struct byte_cntr *drvdata, size_t *small_si "Write data failed:%d\n", ret); goto out; } - + drvdata->total_size += actual; atomic_dec(&drvdata->usb_free_buf); } else { dev_dbg(&tmcdrvdata->csdev->dev, @@ -289,6 +294,7 @@ static void usb_read_work_fn(struct work_struct *work) continue; return; } + drvdata->total_size += actual_total; atomic_dec(&drvdata->usb_free_buf); } else {