From: Mikael Pettersson <mikpe@csd.uu.se>

- PPC32 cleanups: change get_cpu_cache() to return a pointer instead
  of an lvalue; eliminate duplicated initialisation and cleanup code;
  reduce size of non-preemptible code regions

Signed-off-by: Mikael Pettersson <mikpe@csd.uu.se>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 25-akpm/drivers/perfctr/ppc.c       |   44 ++++++++++--------------------------
 25-akpm/drivers/perfctr/ppc_tests.c |    2 +
 2 files changed, 15 insertions(+), 31 deletions(-)

diff -puN drivers/perfctr/ppc.c~perfctr-update-4-6-ppc32-cleanups drivers/perfctr/ppc.c
--- 25/drivers/perfctr/ppc.c~perfctr-update-4-6-ppc32-cleanups	2004-06-30 10:59:25.821614736 -0700
+++ 25-akpm/drivers/perfctr/ppc.c	2004-06-30 10:59:25.828613672 -0700
@@ -22,7 +22,7 @@ struct per_cpu_cache {	/* roughly a subs
 	unsigned int ppc_mmcr[3];
 } ____cacheline_aligned;
 static DEFINE_PER_CPU(struct per_cpu_cache, per_cpu_cache);
-#define get_cpu_cache()	__get_cpu_var(per_cpu_cache)
+#define get_cpu_cache()	(&__get_cpu_var(per_cpu_cache))
 
 /* Structure for counter snapshots, as 32-bit values. */
 struct perfctr_low_ctrs {
@@ -245,7 +245,7 @@ static void ppc_read_counters(/*const*/ 
 	if (state->cstatus & (1<<30)) {
 		unsigned int mmcr0 = mfspr(SPRN_MMCR0);
 		state->ppc_mmcr[0] = mmcr0;
-		get_cpu_cache().ppc_mmcr[0] = mmcr0;
+		get_cpu_cache()->ppc_mmcr[0] = mmcr0;
 	}
 }
 
@@ -367,7 +367,7 @@ static void ppc_write_control(const stru
 	struct per_cpu_cache *cache;
 	unsigned int value;
 
-	cache = &get_cpu_cache();
+	cache = get_cpu_cache();
 	if (cache->k1.id == state->k1.id)
 		return;
 	/*
@@ -466,7 +466,7 @@ void perfctr_cpu_ireload(struct perfctr_
 #ifdef CONFIG_SMP
 	clear_isuspend_cpu(state);
 #else
-	get_cpu_cache().k1.id = 0;
+	get_cpu_cache()->k1.id = 0;
 #endif
 }
 
@@ -609,7 +609,7 @@ static void perfctr_cpu_clear_counters(v
 {
 	struct per_cpu_cache *cache;
 
-	cache = &get_cpu_cache();
+	cache = get_cpu_cache();
 	memset(cache, 0, sizeof *cache);
 	cache->k1.id = -1;
 
@@ -848,18 +848,17 @@ static int __init unknown_init(void)
 	return 0;
 }
 
-static void __init perfctr_cpu_init_one(void *ignore)
+static void perfctr_cpu_clear_one(void *ignore)
 {
-	/* PREEMPT note: when called via smp_call_function(),
+	/* PREEMPT note: when called via on_each_cpu(),
 	   this is in IRQ context with preemption disabled. */
 	perfctr_cpu_clear_counters();
 }
 
-static void __exit perfctr_cpu_exit_one(void *ignore)
+static void perfctr_cpu_reset(void)
 {
-	/* PREEMPT note: when called via smp_call_function(),
-	   this is in IRQ context with preemption disabled. */
-	perfctr_cpu_clear_counters();
+	on_each_cpu(perfctr_cpu_clear_one, NULL, 1, 1);
+	perfctr_cpu_set_ihandler(NULL);
 }
 
 static int init_done;
@@ -868,8 +867,6 @@ int __init perfctr_cpu_init(void)
 {
 	int err;
 
-	preempt_disable();
-
 	perfctr_info.cpu_features = 0;
 
 	err = known_init();
@@ -879,22 +876,15 @@ int __init perfctr_cpu_init(void)
 			goto out;
 	}
 
-	perfctr_cpu_init_one(NULL);
-	smp_call_function(perfctr_cpu_init_one, NULL, 1, 1);
-	perfctr_cpu_set_ihandler(NULL);
+	perfctr_cpu_reset();
 	init_done = 1;
  out:
-	preempt_enable();
 	return err;
 }
 
 void __exit perfctr_cpu_exit(void)
 {
-	preempt_disable();
-	perfctr_cpu_exit_one(NULL);
-	smp_call_function(perfctr_cpu_exit_one, NULL, 1, 1);
-	perfctr_cpu_set_ihandler(NULL);
-	preempt_enable();
+	perfctr_cpu_reset();
 }
 
 /****************************************************************
@@ -920,13 +910,6 @@ const char *perfctr_cpu_reserve(const ch
 	return ret;
 }
 
-static void perfctr_cpu_clear_one(void *ignore)
-{
-	/* PREEMPT note: when called via smp_call_function(),
-	   this is in IRQ context with preemption disabled. */
-	perfctr_cpu_clear_counters();
-}
-
 void perfctr_cpu_release(const char *service)
 {
 	down(&mutex);
@@ -935,8 +918,7 @@ void perfctr_cpu_release(const char *ser
 		       __FUNCTION__, service, current_service);
 	} else {
 		/* power down the counters */
-		on_each_cpu(perfctr_cpu_clear_one, NULL, 1, 1);
-		perfctr_cpu_set_ihandler(NULL);
+		perfctr_cpu_reset();
 		current_service = 0;
 	}
 	up(&mutex);
diff -puN drivers/perfctr/ppc_tests.c~perfctr-update-4-6-ppc32-cleanups drivers/perfctr/ppc_tests.c
--- 25/drivers/perfctr/ppc_tests.c~perfctr-update-4-6-ppc32-cleanups	2004-06-30 10:59:25.823614432 -0700
+++ 25-akpm/drivers/perfctr/ppc_tests.c	2004-06-30 10:59:25.828613672 -0700
@@ -282,5 +282,7 @@ measure_overheads(int have_mmcr1)
 
 void __init perfctr_ppc_init_tests(int have_mmcr1)
 {
+	preempt_disable();
 	measure_overheads(have_mmcr1);
+	preempt_enable();
 }
_