@@ -80,4 +80,6 @@ struct imc_pmu {
#define UNKNOWN_DOMAIN -1
int imc_get_domain(struct device_node *pmu_dev);
+void core_imc_disable(void);
+void thread_imc_disable(void);
#endif /* PPC_POWERNV_IMC_PMU_DEF_H */
@@ -317,7 +317,7 @@ static void core_imc_control_disable(void)
opal_core_imc_counters_control(OPAL_CORE_IMC_DISABLE, 0, 0, 0);
}
-static void core_imc_disable(void)
+void core_imc_disable(void)
{
on_each_cpu_mask(&core_imc_cpumask,
(smp_call_func_t)core_imc_control_disable, NULL, 1);
@@ -710,6 +710,16 @@ void thread_imc_cpu_init(void)
on_each_cpu(thread_imc_mem_alloc, NULL, 1);
}
+static void thread_imc_ldbar_disable(void *dummy)
+{
+ mtspr(SPRN_LDBAR, 0);
+}
+
+void thread_imc_disable(void)
+{
+ on_each_cpu(thread_imc_ldbar_disable, NULL, 1);
+}
+
/*
* init_imc_pmu : Setup the IMC pmu device in "pmu_ptr" and its events
* "events".
@@ -34,6 +34,8 @@
extern struct perchip_nest_info nest_perchip_info[IMC_MAX_CHIPS];
extern struct imc_pmu *per_nest_pmu_arr[IMC_MAX_PMUS];
extern struct imc_pmu *core_imc_pmu;
+extern void core_imc_disable(void);
+extern void thread_imc_disable(void);
extern int init_imc_pmu(struct imc_events *events,
int idx, struct imc_pmu *pmu_ptr);
@@ -532,6 +534,12 @@ static int opal_imc_counters_probe(struct platform_device *pdev)
return -ENODEV;
}
+static void opal_imc_counters_shutdown(struct platform_device *pdev)
+{
+ core_imc_disable();
+ thread_imc_disable();
+}
+
static const struct of_device_id opal_imc_match[] = {
{ .compatible = IMC_DTB_COMPAT },
{},
@@ -543,6 +551,7 @@ static struct platform_driver opal_imc_driver = {
.of_match_table = opal_imc_match,
},
.probe = opal_imc_counters_probe,
+ .shutdown = opal_imc_counters_shutdown,
};
MODULE_DEVICE_TABLE(of, opal_imc_match);