Procházet zdrojové kódy

Remove CONFIG_PM dependency from au1x wait in cpu_probe.
Additional work necessary to completely remove that config option.

Signed-off-by: Ralf Baechle <ralf@linux-mips.org>

Pete Popov před 20 roky
rodič
revize
494900af68

+ 1 - 2
arch/mips/au1000/common/power.c

@@ -297,7 +297,6 @@ static int pm_do_suspend(ctl_table * ctl, int write, struct file *file,
 			 void *buffer, size_t * len)
 {
 	int retval = 0;
-	void	au1k_wait(void);
 
 	if (!write) {
 		*len = 0;
@@ -306,7 +305,7 @@ static int pm_do_suspend(ctl_table * ctl, int write, struct file *file,
 		if (retval)
 			return retval;
 		suspend_mode = 1;
-		au1k_wait();
+
 		retval = pm_send_all(PM_RESUME, (void *) 0);
 	}
 	return retval;

+ 2 - 3
arch/mips/au1000/common/time.c

@@ -57,7 +57,7 @@ unsigned long missed_heart_beats = 0;
 static unsigned long r4k_offset; /* Amount to increment compare reg each time */
 static unsigned long r4k_cur;    /* What counter should be at next timer irq */
 int	no_au1xxx_32khz;
-void	(*au1k_wait_ptr)(void);
+int allow_au1k_wait = 0; /* default off for CP0 Counter */
 
 /* Cycle counter value at the previous timer interrupt.. */
 static unsigned int timerhi = 0, timerlo = 0;
@@ -387,7 +387,6 @@ void au1xxx_timer_setup(struct irqaction *irq)
 {
         unsigned int est_freq;
 	extern unsigned long (*do_gettimeoffset)(void);
-	extern void au1k_wait(void);
 
 	printk("calculating r4koff... ");
 	r4k_offset = cal_r4koff();
@@ -451,7 +450,7 @@ void au1xxx_timer_setup(struct irqaction *irq)
 
 		/* We can use the real 'wait' instruction.
 		*/
-		au1k_wait_ptr = au1k_wait;
+		allow_au1k_wait = 1;
 	}
 
 #else

+ 19 - 24
arch/mips/kernel/cpu-probe.c

@@ -51,29 +51,25 @@ static void r4k_wait(void)
 		".set\tmips0");
 }
 
-/*
- * The Au1xxx wait is available only if we run CONFIG_PM and
- * the timer setup found we had a 32KHz counter available.
- * There are still problems with functions that may call au1k_wait
- * directly, but that will be discovered pretty quickly.
- */
-extern void (*au1k_wait_ptr)(void);
-
-void au1k_wait(void)
+/* The Au1xxx wait is available only if using 32khz counter or
+ * external timer source, but specifically not CP0 Counter. */
+static void au1k_wait(void)
 {
-#ifdef CONFIG_PM
+	unsigned long addr;
 	/* using the wait instruction makes CP0 counter unusable */
-	__asm__(".set\tmips3\n\t"
+	__asm__("la %0,au1k_wait\n\t"
+		".set mips3\n\t"
+		"cache 0x14,0(%0)\n\t"
+		"cache 0x14,32(%0)\n\t"
+		"sync\n\t"
+		"nop\n\t"
 		"wait\n\t"
 		"nop\n\t"
 		"nop\n\t"
 		"nop\n\t"
 		"nop\n\t"
-		".set\tmips0");
-#else
-	__asm__("nop\n\t"
-		"nop");
-#endif
+		".set mips0\n\t"
+		: : "r" (addr));
 }
 
 static inline void check_wait(void)
@@ -112,21 +108,20 @@ static inline void check_wait(void)
 		cpu_wait = r4k_wait;
 		printk(" available.\n");
 		break;
-#ifdef CONFIG_PM
 	case CPU_AU1000:
 	case CPU_AU1100:
 	case CPU_AU1500:
 	case CPU_AU1550:
 	case CPU_AU1200:
-		if (au1k_wait_ptr != NULL) {
-			cpu_wait = au1k_wait_ptr;
-			printk(" available.\n");
-		}
-		else {
-			printk(" unavailable.\n");
+		{
+			extern int allow_au1k_wait; /* au1000/common/time.c */
+			if (allow_au1k_wait) {
+				cpu_wait = au1k_wait;
+				printk(" available.\n");
+			} else
+				printk(" unavailable.\n");
 		}
 		break;
-#endif
 	default:
 		printk(" unavailable.\n");
 		break;