Skip to content

Commit cc878b6

Browse files
coresight: tmc: adding mode of operation for link/sinks
Moving tmc_drvdata::enable to a local_t mode. That way the sink interface is aware of it's orgin and the foundation for mutual exclusion between the sysFS and Perf interface can be laid out. Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org> Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> (cherry picked from commit f2facc3366d77e78dbc8bf865f1e4a6227a7f0e5)
1 parent 09c5cf1 commit cc878b6

3 files changed

Lines changed: 40 additions & 14 deletions

File tree

drivers/hwtracing/coresight/coresight-tmc-etf.c

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ static int tmc_enable_etf_sink(struct coresight_device *csdev, u32 mode)
111111
int ret = 0;
112112
bool used = false;
113113
char *buf = NULL;
114+
long val;
114115
unsigned long flags;
115116
struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
116117

@@ -140,6 +141,15 @@ static int tmc_enable_etf_sink(struct coresight_device *csdev, u32 mode)
140141
goto out;
141142
}
142143

144+
val = local_xchg(&drvdata->mode, mode);
145+
/*
146+
* In sysFS mode we can have multiple writers per sink. Since this
147+
* sink is already enabled no memory is needed and the HW need not be
148+
* touched.
149+
*/
150+
if (val == CS_MODE_SYSFS)
151+
goto out;
152+
143153
/*
144154
* If drvdata::buf isn't NULL, memory was allocated for a previous
145155
* trace run but wasn't read. If so simply zero-out the memory.
@@ -157,7 +167,6 @@ static int tmc_enable_etf_sink(struct coresight_device *csdev, u32 mode)
157167
}
158168

159169
tmc_etb_enable_hw(drvdata);
160-
drvdata->enable = true;
161170
out:
162171
spin_unlock_irqrestore(&drvdata->spinlock, flags);
163172

@@ -173,6 +182,7 @@ static int tmc_enable_etf_sink(struct coresight_device *csdev, u32 mode)
173182

174183
static void tmc_disable_etf_sink(struct coresight_device *csdev)
175184
{
185+
long val;
176186
unsigned long flags;
177187
struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
178188

@@ -182,8 +192,11 @@ static void tmc_disable_etf_sink(struct coresight_device *csdev)
182192
return;
183193
}
184194

185-
tmc_etb_disable_hw(drvdata);
186-
drvdata->enable = false;
195+
val = local_xchg(&drvdata->mode, CS_MODE_DISABLED);
196+
/* Disable the TMC only if it needs to */
197+
if (val != CS_MODE_DISABLED)
198+
tmc_etb_disable_hw(drvdata);
199+
187200
spin_unlock_irqrestore(&drvdata->spinlock, flags);
188201

189202
dev_info(drvdata->dev, "TMC-ETB/ETF disabled\n");
@@ -202,7 +215,7 @@ static int tmc_enable_etf_link(struct coresight_device *csdev,
202215
}
203216

204217
tmc_etf_enable_hw(drvdata);
205-
drvdata->enable = true;
218+
local_set(&drvdata->mode, CS_MODE_SYSFS);
206219
spin_unlock_irqrestore(&drvdata->spinlock, flags);
207220

208221
dev_info(drvdata->dev, "TMC-ETF enabled\n");
@@ -222,7 +235,7 @@ static void tmc_disable_etf_link(struct coresight_device *csdev,
222235
}
223236

224237
tmc_etf_disable_hw(drvdata);
225-
drvdata->enable = false;
238+
local_set(&drvdata->mode, CS_MODE_DISABLED);
226239
spin_unlock_irqrestore(&drvdata->spinlock, flags);
227240

228241
dev_info(drvdata->dev, "TMC disabled\n");
@@ -279,7 +292,7 @@ int tmc_read_prepare_etb(struct tmc_drvdata *drvdata)
279292
}
280293

281294
/* Disable the TMC if need be */
282-
if (drvdata->enable)
295+
if (local_read(&drvdata->mode) == CS_MODE_SYSFS)
283296
tmc_etb_disable_hw(drvdata);
284297

285298
drvdata->reading = true;
@@ -310,7 +323,7 @@ int tmc_read_unprepare_etb(struct tmc_drvdata *drvdata)
310323
}
311324

312325
/* Re-enable the TMC if need be */
313-
if (drvdata->enable) {
326+
if (local_read(&drvdata->mode) == CS_MODE_SYSFS) {
314327
/*
315328
* The trace run will continue with the same allocated trace
316329
* buffer. As such zero-out the buffer so that we don't end

drivers/hwtracing/coresight/coresight-tmc-etr.c

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ static int tmc_enable_etr_sink(struct coresight_device *csdev, u32 mode)
8686
{
8787
int ret = 0;
8888
bool used = false;
89+
long val;
8990
unsigned long flags;
9091
void __iomem *vaddr = NULL;
9192
dma_addr_t paddr;
@@ -122,6 +123,15 @@ static int tmc_enable_etr_sink(struct coresight_device *csdev, u32 mode)
122123
goto out;
123124
}
124125

126+
val = local_xchg(&drvdata->mode, mode);
127+
/*
128+
* In sysFS mode we can have multiple writers per sink. Since this
129+
* sink is already enabled no memory is needed and the HW need not be
130+
* touched.
131+
*/
132+
if (val == CS_MODE_SYSFS)
133+
goto out;
134+
125135
/*
126136
* If drvdata::buf == NULL, use the memory allocated above.
127137
* Otherwise a buffer still exists from a previous session, so
@@ -137,7 +147,6 @@ static int tmc_enable_etr_sink(struct coresight_device *csdev, u32 mode)
137147
memset(drvdata->vaddr, 0, drvdata->size);
138148

139149
tmc_etr_enable_hw(drvdata);
140-
drvdata->enable = true;
141150
out:
142151
spin_unlock_irqrestore(&drvdata->spinlock, flags);
143152

@@ -153,6 +162,7 @@ static int tmc_enable_etr_sink(struct coresight_device *csdev, u32 mode)
153162

154163
static void tmc_disable_etr_sink(struct coresight_device *csdev)
155164
{
165+
long val;
156166
unsigned long flags;
157167
struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
158168

@@ -162,8 +172,11 @@ static void tmc_disable_etr_sink(struct coresight_device *csdev)
162172
return;
163173
}
164174

165-
tmc_etr_disable_hw(drvdata);
166-
drvdata->enable = false;
175+
val = local_xchg(&drvdata->mode, CS_MODE_DISABLED);
176+
/* Disable the TMC only if it needs to */
177+
if (val != CS_MODE_DISABLED)
178+
tmc_etr_disable_hw(drvdata);
179+
167180
spin_unlock_irqrestore(&drvdata->spinlock, flags);
168181

169182
dev_info(drvdata->dev, "TMC-ETR disabled\n");
@@ -200,7 +213,7 @@ int tmc_read_prepare_etr(struct tmc_drvdata *drvdata)
200213
}
201214

202215
/* Disable the TMC if need be */
203-
if (drvdata->enable)
216+
if (local_read(&drvdata->mode) == CS_MODE_SYSFS)
204217
tmc_etr_disable_hw(drvdata);
205218

206219
drvdata->reading = true;
@@ -223,7 +236,7 @@ int tmc_read_unprepare_etr(struct tmc_drvdata *drvdata)
223236
spin_lock_irqsave(&drvdata->spinlock, flags);
224237

225238
/* RE-enable the TMC if need be */
226-
if (drvdata->enable) {
239+
if (local_read(&drvdata->mode) == CS_MODE_SYSFS) {
227240
/*
228241
* The trace run will continue with the same allocated trace
229242
* buffer. As such zero-out the buffer so that we don't end

drivers/hwtracing/coresight/coresight-tmc.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ enum tmc_mem_intf_width {
9898
* @paddr: DMA start location in RAM.
9999
* @vaddr: virtual representation of @paddr.
100100
* @size: @buf size.
101-
* @enable: this TMC is being used.
101+
* @mode: how this TMC is being used.
102102
* @config_type: TMC variant, must be of type @tmc_config_type.
103103
* @trigger_cntr: amount of words to store after a trigger.
104104
*/
@@ -113,7 +113,7 @@ struct tmc_drvdata {
113113
dma_addr_t paddr;
114114
void __iomem *vaddr;
115115
u32 size;
116-
bool enable;
116+
local_t mode;
117117
enum tmc_config_type config_type;
118118
u32 trigger_cntr;
119119
};

0 commit comments

Comments
 (0)