coresight: turn on pcsave during first hotplug if enabled in boot

When PC save is enabled via kernel command line or config item
but we boot with maxcpus parameter value of less than number of
present cpus, cpus that are not included as part of maxcpus don't
get PC save feature enabled during kernel init since those cpus
would not be online.

This change ensures that for such cpus, first hotplug after the
respective cpu's ETM probe is done, enables PC save feature if
the feature is enabled via kernel command line or config item but
hasn't already been enabled.

Change-Id: I9cae33654539ed72885fdf11cd603c7c776512c1
Signed-off-by: Pratik Patel <pratikp@codeaurora.org>
This commit is contained in:
Pratik Patel 2012-11-15 09:57:29 -08:00 committed by Iliyan Malchev
parent 03aff310ed
commit 1e28f91301

View file

@ -234,6 +234,8 @@ struct etm_drvdata {
uint32_t timestamp_event;
bool pcsave_impl;
bool pcsave_enable;
bool pcsave_sticky_enable;
bool pcsave_boot_enable;
};
static struct etm_drvdata *etmdrvdata[NR_CPUS];
@ -1516,7 +1518,7 @@ static ssize_t etm_show_pcsave(struct device *dev,
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
}
static int __etm_store_pcsave(struct etm_drvdata *drvdata, unsigned long val)
static int ____etm_store_pcsave(struct etm_drvdata *drvdata, unsigned long val)
{
int ret = 0;
@ -1524,7 +1526,6 @@ static int __etm_store_pcsave(struct etm_drvdata *drvdata, unsigned long val)
if (ret)
return ret;
get_online_cpus();
spin_lock(&drvdata->spinlock);
if (val) {
if (drvdata->pcsave_enable)
@ -1535,6 +1536,7 @@ static int __etm_store_pcsave(struct etm_drvdata *drvdata, unsigned long val)
if (ret)
goto out;
drvdata->pcsave_enable = true;
drvdata->pcsave_sticky_enable = true;
dev_info(drvdata->dev, "PC save enabled\n");
} else {
@ -1551,12 +1553,22 @@ static int __etm_store_pcsave(struct etm_drvdata *drvdata, unsigned long val)
}
out:
spin_unlock(&drvdata->spinlock);
put_online_cpus();
clk_disable_unprepare(drvdata->clk);
return ret;
}
static int __etm_store_pcsave(struct etm_drvdata *drvdata, unsigned long val)
{
int ret;
get_online_cpus();
ret = ____etm_store_pcsave(drvdata, val);
put_online_cpus();
return ret;
}
static ssize_t etm_store_pcsave(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t size)
@ -1642,6 +1654,13 @@ static int etm_cpu_callback(struct notifier_block *nfb, unsigned long action,
}
break;
case CPU_ONLINE:
if (etmdrvdata[cpu] && etmdrvdata[cpu]->pcsave_boot_enable &&
!etmdrvdata[cpu]->pcsave_sticky_enable) {
____etm_store_pcsave(etmdrvdata[cpu], 1);
}
break;
case CPU_DYING:
if (etmdrvdata[cpu] && etmdrvdata[cpu]->enable) {
spin_lock(&etmdrvdata[cpu]->spinlock);
@ -1894,8 +1913,10 @@ static int __devinit etm_probe(struct platform_device *pdev)
if (boot_enable)
coresight_enable(drvdata->csdev);
if (drvdata->pcsave_impl && boot_pcsave_enable)
__etm_store_pcsave(drvdata, true);
if (drvdata->pcsave_impl && boot_pcsave_enable) {
__etm_store_pcsave(drvdata, 1);
drvdata->pcsave_boot_enable = true;
}
return 0;
err2: