[PATCH 1/2] Error: Fix mmdc compilation errors due to cpu notifier
Nitin Chaudhary
nitinchaudhary1289 at gmail.com
Tue Aug 16 17:59:20 PDT 2016
---
arch/arm/mach-imx/mmdc.c | 89 ++++++++++++++++++++++------------------------
include/linux/cpuhotplug.h | 1 +
2 files changed, 44 insertions(+), 46 deletions(-)
diff --git a/arch/arm/mach-imx/mmdc.c b/arch/arm/mach-imx/mmdc.c
index 372b59c..95c222d 100644
--- a/arch/arm/mach-imx/mmdc.c
+++ b/arch/arm/mach-imx/mmdc.c
@@ -77,13 +77,14 @@ struct mmdc_pmu
struct pmu pmu;
void __iomem *mmdc_base;
cpumask_t cpu;
- struct notifier_block cpu_nb;
struct hrtimer hrtimer;
unsigned int irq;
struct device *dev;
struct perf_event *mmdc_events[MMDC_NUM_COUNTERS];
};
+static struct mmdc_pmu *pmu_mmdc;
+
static unsigned int mmdc_poll_period_us = 1000000;
module_param_named(pmu_poll_period_us, mmdc_poll_period_us, uint,
S_IRUGO | S_IWUSR);
@@ -96,7 +97,6 @@ static ktime_t mmdc_timer_period(void)
static ssize_t mmdc_cpumask_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
- struct mmdc_pmu *pmu_mmdc = dev_get_drvdata(dev);
return cpumap_print_to_pagebuf(true, buf, &pmu_mmdc->cpu);
}
@@ -149,7 +149,7 @@ static const struct attribute_group * attr_groups[] = {
NULL,
};
-static u32 mmdc_read_counter(struct mmdc_pmu *pmu_mmdc, int cfg, u64 prev_val)
+static u32 mmdc_read_counter(int cfg, u64 prev_val)
{
u32 val;
void __iomem *mmdc_base, *reg;
@@ -184,7 +184,6 @@ static u32 mmdc_read_counter(struct mmdc_pmu *pmu_mmdc, int cfg, u64 prev_val)
static void mmdc_enable_profiling(struct perf_event *event)
{
- struct mmdc_pmu *pmu_mmdc = to_mmdc_pmu(event->pmu);
void __iomem *mmdc_base, *reg;
mmdc_base = pmu_mmdc->mmdc_base;
@@ -193,32 +192,27 @@ static void mmdc_enable_profiling(struct perf_event *event)
writel_relaxed(DBG_EN, reg);
}
-static int mmdc_cpu_notifier(struct notifier_block *nb,
- unsigned long action, void *hcpu)
+static int mmdc_cpu_offline(unsigned int cpu)
{
- struct mmdc_pmu *pmu_mmdc = container_of(nb, struct mmdc_pmu, cpu_nb);
- unsigned int cpu = (long)hcpu; /* for (long) see kernel/cpu.c */
unsigned int target;
-
- switch (action & ~CPU_TASKS_FROZEN) {
- case CPU_DOWN_PREPARE:
- if (!cpumask_test_and_clear_cpu(cpu, &pmu_mmdc->cpu))
- break;
- target = cpumask_any_but(cpu_online_mask, cpu);
- if (target >= nr_cpu_ids)
- break;
- perf_pmu_migrate_context(&pmu_mmdc->pmu, cpu, target);
- cpumask_set_cpu(target, &pmu_mmdc->cpu);
- default:
- break;
- }
-
- return NOTIFY_OK;
+ struct mmdc_pmu *pmu_ptr = pmu_mmdc;
+ if (!cpumask_test_and_clear_cpu(cpu, &pmu_ptr->cpu))
+ return 0;
+ target = cpumask_any_but(cpu_online_mask, cpu);
+ if (target >= nr_cpu_ids)
+ return 0;
+
+ perf_pmu_migrate_context(&pmu_ptr->pmu, cpu, target);
+ cpumask_set_cpu(target, &pmu_ptr->cpu);
+ /*
+ if(pmu_ptr->irq)
+ WARN_ON(irq_set_affinity_hint(pmu_ptr->irq, &pmu_ptr->cpu) != 0);
+ */
+ return 0;
}
static int mmdc_event_init(struct perf_event *event)
{
- struct mmdc_pmu *pmu_mmdc = to_mmdc_pmu(event->pmu);
if (event->attr.type != event->pmu->type)
return -ENOENT;
@@ -243,17 +237,15 @@ static int mmdc_event_init(struct perf_event *event)
static void mmdc_event_update(struct perf_event * event)
{
- struct mmdc_pmu *pmu_mmdc = to_mmdc_pmu(event->pmu);
u32 val;
u64 prev_val;
prev_val = local64_read(&event->count);
- val = mmdc_read_counter(pmu_mmdc, (int) event->attr.config, prev_val);
+ val = mmdc_read_counter((int)event->attr.config, prev_val);
local64_add(val - (u32)(prev_val&0xFFFFFFFF) , &event->count);
}
static void mmdc_event_start(struct perf_event *event, int flags)
{
- struct mmdc_pmu *pmu_mmdc = to_mmdc_pmu(event->pmu);
void __iomem *mmdc_base, *reg;
local64_set(&event->count, 0);
@@ -268,7 +260,6 @@ static void mmdc_event_start(struct perf_event *event, int flags)
static int mmdc_event_add(struct perf_event *event, int flags)
{
- struct mmdc_pmu *pmu_mmdc = to_mmdc_pmu(event->pmu);
int cfg = (int)event->attr.config;
if (cfg >= 1 && cfg <= MMDC_NUM_COUNTERS)
pmu_mmdc->mmdc_events[cfg - 1] = event;
@@ -279,7 +270,6 @@ static int mmdc_event_add(struct perf_event *event, int flags)
static void mmdc_event_stop(struct perf_event *event, int flags)
{
- struct mmdc_pmu *pmu_mmdc = to_mmdc_pmu(event->pmu);
void __iomem *mmdc_base, *reg;
int cfg = (int)event->attr.config;
@@ -300,7 +290,7 @@ static void mmdc_event_del(struct perf_event *event, int flags)
mmdc_event_stop(event, PERF_EF_UPDATE);
}
-static void mmdc_overflow_handler(struct mmdc_pmu *pmu_mmdc)
+static void mmdc_overflow_handler(void)
{
int i;
u32 val;
@@ -312,7 +302,7 @@ static void mmdc_overflow_handler(struct mmdc_pmu *pmu_mmdc)
if (event)
{
prev_val = local64_read(&event->count);
- val = mmdc_read_counter(pmu_mmdc, i + 1, prev_val);
+ val = mmdc_read_counter(i + 1, prev_val);
local64_add(val - (u32)(prev_val&0xFFFFFFFF) , &event->count);
}
}
@@ -320,16 +310,13 @@ static void mmdc_overflow_handler(struct mmdc_pmu *pmu_mmdc)
static enum hrtimer_restart mmdc_timer_handler(struct hrtimer *hrtimer)
{
- struct mmdc_pmu *pmu_mmdc = container_of(hrtimer, struct mmdc_pmu,
- hrtimer);
-
- mmdc_overflow_handler(pmu_mmdc);
+ mmdc_overflow_handler();
hrtimer_forward_now(hrtimer, mmdc_timer_period());
return HRTIMER_RESTART;
}
-static int mmdc_pmu_init(struct mmdc_pmu *pmu_mmdc, void __iomem *mmdc_base, struct device *dev)
+static int mmdc_pmu_init(void __iomem *mmdc_base, struct device *dev)
{
int mmdc_num;
*pmu_mmdc = (struct mmdc_pmu) {
@@ -347,12 +334,9 @@ static int mmdc_pmu_init(struct mmdc_pmu *pmu_mmdc, void __iomem *mmdc_base, str
};
mmdc_num = ida_simple_get(&mmdc_ida, 0, 0, GFP_KERNEL);
-
+
cpumask_set_cpu(smp_processor_id(), &pmu_mmdc->cpu);
- pmu_mmdc->cpu_nb.notifier_call = mmdc_cpu_notifier;
- pmu_mmdc->cpu_nb.priority = CPU_PRI_PERF + 1;
-
pmu_mmdc->dev = dev;
return mmdc_num;
}
@@ -361,11 +345,11 @@ static int imx_mmdc_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
void __iomem *mmdc_base, *reg;
- struct mmdc_pmu *pmu_mmdc;
char * name;
u32 val;
- int timeout = 0x400;
+ int timeout = 0x800;
int mmdc_num;
+ int err;
mmdc_base = of_iomap(np, 0);
WARN_ON(!mmdc_base);
@@ -390,7 +374,7 @@ static int imx_mmdc_probe(struct platform_device *pdev)
if (unlikely(!timeout)) {
pr_warn("%s: failed to enable automatic power saving\n",
__func__);
- return -EBUSY;
+ //return -EBUSY;
}
pmu_mmdc = kzalloc(sizeof(*pmu_mmdc), GFP_KERNEL);
@@ -398,12 +382,18 @@ static int imx_mmdc_probe(struct platform_device *pdev)
pr_err("failed to allocate PMU device!\n");
return -ENOMEM;
}
- mmdc_num = mmdc_pmu_init(pmu_mmdc, mmdc_base, &pdev->dev);
+ mmdc_num = mmdc_pmu_init(mmdc_base, &pdev->dev);
dev_info(pmu_mmdc->dev, "No access to interrupts, using timer.\n");
hrtimer_init(&pmu_mmdc->hrtimer, CLOCK_MONOTONIC,
HRTIMER_MODE_REL);
pmu_mmdc->hrtimer.function = mmdc_timer_handler;
- register_cpu_notifier(&pmu_mmdc->cpu_nb);
+
+ err = cpuhp_setup_state(CPUHP_AP_PERF_ARM_MMDC_ONLINE,
+ "AP_PERF_ARM_MMDC_ONLINE", NULL,
+ mmdc_cpu_offline);
+ if(err)
+ goto error_cpu_notifier;
+
if (mmdc_num == 0) {
name = "mmdc";
} else {
@@ -413,12 +403,19 @@ static int imx_mmdc_probe(struct platform_device *pdev)
}
platform_set_drvdata(pdev, pmu_mmdc);
perf_pmu_register(&(pmu_mmdc->pmu), name, -1);
+
+ dev_info(pmu_mmdc->dev, "%s success\n",__func__);
+
return 0;
+
+error_cpu_notifier:
+ cpuhp_remove_state_nocalls(CPUHP_AP_PERF_ARM_MMDC_ONLINE);
+ kfree(pmu_mmdc);
+ return err;
}
static int imx_mmdc_remove(struct platform_device *pdev)
{
- struct mmdc_pmu *pmu_mmdc = platform_get_drvdata(pdev);
perf_pmu_unregister(&pmu_mmdc->pmu);
kfree(pmu_mmdc);
return 0;
diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h
index 242bf53..c059342 100644
--- a/include/linux/cpuhotplug.h
+++ b/include/linux/cpuhotplug.h
@@ -86,6 +86,7 @@ enum cpuhp_state {
CPUHP_AP_PERF_S390_SF_ONLINE,
CPUHP_AP_PERF_ARM_CCI_ONLINE,
CPUHP_AP_PERF_ARM_CCN_ONLINE,
+ CPUHP_AP_PERF_ARM_MMDC_ONLINE,
CPUHP_AP_WORKQUEUE_ONLINE,
CPUHP_AP_RCUTREE_ONLINE,
CPUHP_AP_NOTIFY_ONLINE,
--
2.7.4
More information about the linux-arm-kernel
mailing list