Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4d7cba74 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "coresight: stm: Remove spin lock usage for channel allocation"

parents 2b733f5f 262e85b1
Loading
Loading
Loading
Loading
+26 −15
Original line number Diff line number Diff line
/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2017, 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
@@ -30,19 +30,26 @@

static struct stm_drvdata *stmdrvdata;

static uint32_t stm_channel_alloc(uint32_t off)
static uint32_t stm_channel_alloc(void)
{
	struct stm_drvdata *drvdata = stmdrvdata;
	uint32_t ch;
	unsigned long flags;
	uint32_t ch, off, num_ch_per_cpu;
	int cpu;

	num_ch_per_cpu = drvdata->numsp/num_present_cpus();

	spin_lock_irqsave(&drvdata->spinlock, flags);
	do {
	cpu = get_cpu();

	off = num_ch_per_cpu * cpu;
	ch = find_next_zero_bit(drvdata->chs.bitmap,
				drvdata->numsp, off);
	} while ((ch < drvdata->numsp) &&
		 test_and_set_bit(ch, drvdata->chs.bitmap));
	spin_unlock_irqrestore(&drvdata->spinlock, flags);
	if (unlikely(ch >= (off + num_ch_per_cpu))) {
		put_cpu();
		return drvdata->numsp;
	}

	set_bit(ch, drvdata->chs.bitmap);
	put_cpu();

	return ch;
}
@@ -65,11 +72,8 @@ static int stm_ost_send(void *addr, const void *data, uint32_t count)
static void stm_channel_free(uint32_t ch)
{
	struct stm_drvdata *drvdata = stmdrvdata;
	unsigned long flags;

	spin_lock_irqsave(&drvdata->spinlock, flags);
	clear_bit(ch, drvdata->chs.bitmap);
	spin_unlock_irqrestore(&drvdata->spinlock, flags);
}

static int stm_trace_ost_header(unsigned long ch_addr, uint32_t flags,
@@ -146,7 +150,14 @@ static inline int __stm_trace(uint32_t flags, uint8_t entity_id,
	unsigned long ch_addr;

	/* allocate channel and get the channel address */
	ch = stm_channel_alloc(0);
	ch = stm_channel_alloc();
	if (unlikely(ch >= drvdata->numsp)) {
		drvdata->ch_alloc_fail_count++;
		dev_err_ratelimited(drvdata->dev,
				    "Channel allocation failed %d",
				    drvdata->ch_alloc_fail_count);
		return 0;
	}

	ch_addr = (unsigned long)stm_channel_addr(drvdata, ch);

+2 −2
Original line number Diff line number Diff line
/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
 *
 * Description: CoreSight System Trace Macrocell driver
 *
@@ -729,7 +729,7 @@ static u32 stm_num_stimulus_port(struct stm_drvdata *drvdata)
	numsp &= 0x1ffff;
	if (!numsp)
		numsp = STM_32_CHANNEL;
	return numsp;
	return STM_32_CHANNEL;
}

static void stm_init_default_data(struct stm_drvdata *drvdata)
+2 −0
Original line number Diff line number Diff line
@@ -70,6 +70,7 @@ struct channel_space {
 * @stmheer:		settings for register STMHEER.
 * @stmheter:		settings for register STMHETER.
 * @stmhebsr:		settings for register STMHEBSR.
 * @ch_alloc_fail_count:	Number of ch allocation failures over time.
 */
struct stm_drvdata {
	void __iomem		*base;
@@ -90,6 +91,7 @@ struct stm_drvdata {
	u32			stmheer;
	u32			stmheter;
	u32			stmhebsr;
	u32			ch_alloc_fail_count;
};

#ifdef CONFIG_CORESIGHT_STM