diff --git a/drivers/coresight/coresight-csr.c b/drivers/coresight/coresight-csr.c index e734ecef8a67..4774c7610f9f 100644 --- a/drivers/coresight/coresight-csr.c +++ b/drivers/coresight/coresight-csr.c @@ -119,6 +119,21 @@ void msm_qdss_csr_disable_bam_to_usb(void) } EXPORT_SYMBOL_GPL(msm_qdss_csr_disable_bam_to_usb); +void msm_qdss_csr_disable_flush(void) +{ + struct csr_drvdata *drvdata = csrdrvdata; + uint32_t usbflshctrl; + + CSR_UNLOCK(drvdata); + + usbflshctrl = csr_readl(drvdata, CSR_USBFLSHCTRL); + usbflshctrl &= ~0x2; + csr_writel(drvdata, usbflshctrl, CSR_USBFLSHCTRL); + + CSR_LOCK(drvdata); +} +EXPORT_SYMBOL_GPL(msm_qdss_csr_disable_flush); + static int __devinit csr_probe(struct platform_device *pdev) { int ret; diff --git a/drivers/coresight/coresight-priv.h b/drivers/coresight/coresight-priv.h index 77d0ef5cde8b..258ff0959ee1 100644 --- a/drivers/coresight/coresight-priv.h +++ b/drivers/coresight/coresight-priv.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved. +/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -39,9 +39,11 @@ #ifdef CONFIG_CORESIGHT_CSR extern void msm_qdss_csr_enable_bam_to_usb(void); extern void msm_qdss_csr_disable_bam_to_usb(void); +extern void msm_qdss_csr_disable_flush(void); #else static inline void msm_qdss_csr_enable_bam_to_usb(void) {} static inline void msm_qdss_csr_disable_bam_to_usb(void) {} +static inline void msm_qdss_csr_disable_flush(void) {} #endif #ifdef CONFIG_CORESIGHT_ETM extern unsigned int etm_readl_cp14(uint32_t off); diff --git a/drivers/coresight/coresight-tmc.c b/drivers/coresight/coresight-tmc.c index bc77049dabb0..10eabca6f5f2 100644 --- a/drivers/coresight/coresight-tmc.c +++ b/drivers/coresight/coresight-tmc.c @@ -155,6 +155,18 @@ struct tmc_drvdata { uint32_t trigger_cntr; }; +static void tmc_wait_for_flush(struct tmc_drvdata *drvdata) +{ + int count; + + /* Ensure no flush is in progress */ + for (count = TIMEOUT_US; BVAL(tmc_readl(drvdata, TMC_FFSR), 0) != 0 + && count > 0; count--) + udelay(1); + WARN(count == 0, "timeout while waiting for TMC flush, TMC_FFSR: %#x\n", + tmc_readl(drvdata, TMC_FFSR)); +} + static void tmc_wait_for_ready(struct tmc_drvdata *drvdata) { int count; @@ -238,7 +250,7 @@ static void __tmc_etr_enable_to_bam(struct tmc_drvdata *drvdata) tmc_writel(drvdata, bamdata->data_fifo.phys_base, TMC_DBALO); tmc_writel(drvdata, 0x0, TMC_DBAHI); - tmc_writel(drvdata, 0x133, TMC_FFCR); + tmc_writel(drvdata, 0x103, TMC_FFCR); tmc_writel(drvdata, drvdata->trigger_cntr, TMC_TRG); __tmc_enable(drvdata); @@ -298,14 +310,18 @@ static void __tmc_etr_disable_to_bam(struct tmc_drvdata *drvdata) if (!drvdata->enable_to_bam) return; + /* Ensure periodic flush is disabled in CSR block */ + msm_qdss_csr_disable_flush(); + TMC_UNLOCK(drvdata); + tmc_wait_for_flush(drvdata); tmc_flush_and_stop(drvdata); __tmc_disable(drvdata); TMC_LOCK(drvdata); - /* Disable CSR registers */ + /* Disable CSR configuration */ msm_qdss_csr_disable_bam_to_usb(); drvdata->enable_to_bam = false; }