Skip to content

Commit

Permalink
hwtracing/coresight-etm4x: Convert to hotplug state machine
Browse files Browse the repository at this point in the history
This driver has an asymmetry of ONLINE code without any corresponding tear
down code. Otherwise, this is a straightforward conversion.

Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Anna-Maria Gleixner <anna-maria@linutronix.de>
Acked-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-arm-kernel@lists.infradead.org
Cc: rt@linutronix.de
Link: http://lkml.kernel.org/r/20160713153337.228918408@linutronix.de
Signed-off-by: Ingo Molnar <mingo@kernel.org>
  • Loading branch information
Sebastian Andrzej Siewior authored and Ingo Molnar committed Jul 15, 2016
1 parent 2b5283d commit 58eb457
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 38 deletions.
87 changes: 49 additions & 38 deletions drivers/hwtracing/coresight/coresight-etm4x.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ static int etm4_count;
static struct etmv4_drvdata *etmdrvdata[NR_CPUS];
static void etm4_set_default(struct etmv4_config *config);

static enum cpuhp_state hp_online;

static void etm4_os_unlock(struct etmv4_drvdata *drvdata)
{
/* Writing any value to ETMOSLAR unlocks the trace registers */
Expand Down Expand Up @@ -673,47 +675,44 @@ void etm4_config_trace_mode(struct etmv4_config *config)
config->addr_acc[ETM_DEFAULT_ADDR_COMP + 1] = addr_acc;
}

static int etm4_cpu_callback(struct notifier_block *nfb, unsigned long action,
void *hcpu)
static int etm4_online_cpu(unsigned int cpu)
{
unsigned int cpu = (unsigned long)hcpu;

if (!etmdrvdata[cpu])
goto out;

switch (action & (~CPU_TASKS_FROZEN)) {
case CPU_STARTING:
spin_lock(&etmdrvdata[cpu]->spinlock);
if (!etmdrvdata[cpu]->os_unlock) {
etm4_os_unlock(etmdrvdata[cpu]);
etmdrvdata[cpu]->os_unlock = true;
}

if (local_read(&etmdrvdata[cpu]->mode))
etm4_enable_hw(etmdrvdata[cpu]);
spin_unlock(&etmdrvdata[cpu]->spinlock);
break;
return 0;

case CPU_ONLINE:
if (etmdrvdata[cpu]->boot_enable &&
!etmdrvdata[cpu]->sticky_enable)
coresight_enable(etmdrvdata[cpu]->csdev);
break;
if (etmdrvdata[cpu]->boot_enable && !etmdrvdata[cpu]->sticky_enable)
coresight_enable(etmdrvdata[cpu]->csdev);
return 0;
}

case CPU_DYING:
spin_lock(&etmdrvdata[cpu]->spinlock);
if (local_read(&etmdrvdata[cpu]->mode))
etm4_disable_hw(etmdrvdata[cpu]);
spin_unlock(&etmdrvdata[cpu]->spinlock);
break;
static int etm4_starting_cpu(unsigned int cpu)
{
if (!etmdrvdata[cpu])
return 0;

spin_lock(&etmdrvdata[cpu]->spinlock);
if (!etmdrvdata[cpu]->os_unlock) {
etm4_os_unlock(etmdrvdata[cpu]);
etmdrvdata[cpu]->os_unlock = true;
}
out:
return NOTIFY_OK;

if (local_read(&etmdrvdata[cpu]->mode))
etm4_enable_hw(etmdrvdata[cpu]);
spin_unlock(&etmdrvdata[cpu]->spinlock);
return 0;
}

static struct notifier_block etm4_cpu_notifier = {
.notifier_call = etm4_cpu_callback,
};
static int etm4_dying_cpu(unsigned int cpu)
{
if (!etmdrvdata[cpu])
return 0;

spin_lock(&etmdrvdata[cpu]->spinlock);
if (local_read(&etmdrvdata[cpu]->mode))
etm4_disable_hw(etmdrvdata[cpu]);
spin_unlock(&etmdrvdata[cpu]->spinlock);
return 0;
}

static void etm4_init_trace_id(struct etmv4_drvdata *drvdata)
{
Expand Down Expand Up @@ -767,8 +766,17 @@ static int etm4_probe(struct amba_device *adev, const struct amba_id *id)
etm4_init_arch_data, drvdata, 1))
dev_err(dev, "ETM arch init failed\n");

if (!etm4_count++)
register_hotcpu_notifier(&etm4_cpu_notifier);
if (!etm4_count++) {
cpuhp_setup_state_nocalls(CPUHP_AP_ARM_CORESIGHT4_STARTING,
"AP_ARM_CORESIGHT4_STARTING",
etm4_starting_cpu, etm4_dying_cpu);
ret = cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN,
"AP_ARM_CORESIGHT4_ONLINE",
etm4_online_cpu, NULL);
if (ret < 0)
goto err_arch_supported;
hp_online = ret;
}

put_online_cpus();

Expand Down Expand Up @@ -809,8 +817,11 @@ static int etm4_probe(struct amba_device *adev, const struct amba_id *id)
return 0;

err_arch_supported:
if (--etm4_count == 0)
unregister_hotcpu_notifier(&etm4_cpu_notifier);
if (--etm4_count == 0) {
cpuhp_remove_state_nocalls(CPUHP_AP_ARM_CORESIGHT4_STARTING);
if (hp_online)
cpuhp_remove_state_nocalls(hp_online);
}
return ret;
}

Expand Down
1 change: 1 addition & 0 deletions include/linux/cpuhotplug.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ enum cpuhp_state {
CPUHP_AP_KVM_ARM_TIMER_STARTING,
CPUHP_AP_ARM_XEN_STARTING,
CPUHP_AP_ARM_CORESIGHT_STARTING,
CPUHP_AP_ARM_CORESIGHT4_STARTING,
CPUHP_AP_LEDTRIG_STARTING,
CPUHP_AP_NOTIFY_STARTING,
CPUHP_AP_ONLINE,
Expand Down

0 comments on commit 58eb457

Please sign in to comment.