Browse Source

Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6:
  sparc64: setup_valid_addr_bitmap_from_pavail() should be __init
  sparc: Fix resource flags for PCI children in OF device tree.
  sparc32: Implement smp_call_function_single().
Linus Torvalds 17 years ago
parent
commit
44e7ed3961

+ 15 - 10
arch/sparc/include/asm/smp_32.h

@@ -50,27 +50,24 @@ struct seq_file;
 void smp_bogo(struct seq_file *);
 void smp_info(struct seq_file *);
 
-BTFIXUPDEF_CALL(void, smp_cross_call, smpfunc_t, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long)
+BTFIXUPDEF_CALL(void, smp_cross_call, smpfunc_t, cpumask_t, unsigned long, unsigned long, unsigned long, unsigned long)
 BTFIXUPDEF_CALL(int, __hard_smp_processor_id, void)
 BTFIXUPDEF_BLACKBOX(hard_smp_processor_id)
 BTFIXUPDEF_BLACKBOX(load_current)
 
-#define smp_cross_call(func,arg1,arg2,arg3,arg4,arg5) BTFIXUP_CALL(smp_cross_call)(func,arg1,arg2,arg3,arg4,arg5)
+#define smp_cross_call(func,mask,arg1,arg2,arg3,arg4) BTFIXUP_CALL(smp_cross_call)(func,mask,arg1,arg2,arg3,arg4)
 
-static inline void xc0(smpfunc_t func) { smp_cross_call(func, 0, 0, 0, 0, 0); }
+static inline void xc0(smpfunc_t func) { smp_cross_call(func, cpu_online_map, 0, 0, 0, 0); }
 static inline void xc1(smpfunc_t func, unsigned long arg1)
-{ smp_cross_call(func, arg1, 0, 0, 0, 0); }
+{ smp_cross_call(func, cpu_online_map, arg1, 0, 0, 0); }
 static inline void xc2(smpfunc_t func, unsigned long arg1, unsigned long arg2)
-{ smp_cross_call(func, arg1, arg2, 0, 0, 0); }
+{ smp_cross_call(func, cpu_online_map, arg1, arg2, 0, 0); }
 static inline void xc3(smpfunc_t func, unsigned long arg1, unsigned long arg2,
 			   unsigned long arg3)
-{ smp_cross_call(func, arg1, arg2, arg3, 0, 0); }
+{ smp_cross_call(func, cpu_online_map, arg1, arg2, arg3, 0); }
 static inline void xc4(smpfunc_t func, unsigned long arg1, unsigned long arg2,
 			   unsigned long arg3, unsigned long arg4)
-{ smp_cross_call(func, arg1, arg2, arg3, arg4, 0); }
-static inline void xc5(smpfunc_t func, unsigned long arg1, unsigned long arg2,
-			   unsigned long arg3, unsigned long arg4, unsigned long arg5)
-{ smp_cross_call(func, arg1, arg2, arg3, arg4, arg5); }
+{ smp_cross_call(func, cpu_online_map, arg1, arg2, arg3, arg4); }
 
 static inline int smp_call_function(void (*func)(void *info), void *info, int wait)
 {
@@ -78,6 +75,14 @@ static inline int smp_call_function(void (*func)(void *info), void *info, int wa
 	return 0;
 }
 
+static inline int smp_call_function_single(int cpuid, void (*func) (void *info),
+					   void *info, int wait)
+{
+	smp_cross_call((smpfunc_t)func, cpumask_of_cpu(cpuid),
+		       (unsigned long) info, 0, 0, 0);
+	return 0;
+}
+
 static inline int cpu_logical_map(int cpu)
 {
 	return cpu;

+ 14 - 5
arch/sparc/kernel/of_device.c

@@ -70,7 +70,7 @@ struct of_bus {
 				       int *addrc, int *sizec);
 	int		(*map)(u32 *addr, const u32 *range,
 			       int na, int ns, int pna);
-	unsigned int	(*get_flags)(const u32 *addr);
+	unsigned long	(*get_flags)(const u32 *addr, unsigned long);
 };
 
 /*
@@ -130,8 +130,10 @@ static int of_bus_default_map(u32 *addr, const u32 *range,
 	return 0;
 }
 
-static unsigned int of_bus_default_get_flags(const u32 *addr)
+static unsigned long of_bus_default_get_flags(const u32 *addr, unsigned long flags)
 {
+	if (flags)
+		return flags;
 	return IORESOURCE_MEM;
 }
 
@@ -194,17 +196,21 @@ static int of_bus_pci_map(u32 *addr, const u32 *range,
 	return 0;
 }
 
-static unsigned int of_bus_pci_get_flags(const u32 *addr)
+static unsigned long of_bus_pci_get_flags(const u32 *addr, unsigned long flags)
 {
-	unsigned int flags = 0;
 	u32 w = addr[0];
 
+	/* For PCI, we override whatever child busses may have used.  */
+	flags = 0;
 	switch((w >> 24) & 0x03) {
 	case 0x01:
 		flags |= IORESOURCE_IO;
+		break;
+
 	case 0x02: /* 32 bits */
 	case 0x03: /* 64 bits */
 		flags |= IORESOURCE_MEM;
+		break;
 	}
 	if (w & 0x40000000)
 		flags |= IORESOURCE_PREFETCH;
@@ -362,10 +368,11 @@ static void __init build_device_resources(struct of_device *op,
 		int pna, pns;
 
 		size = of_read_addr(reg + na, ns);
-		flags = bus->get_flags(reg);
 
 		memcpy(addr, reg, na * 4);
 
+		flags = bus->get_flags(reg, 0);
+
 		/* If the immediate parent has no ranges property to apply,
 		 * just use a 1<->1 mapping.
 		 */
@@ -393,6 +400,8 @@ static void __init build_device_resources(struct of_device *op,
 					       dna, dns, pna))
 				break;
 
+			flags = pbus->get_flags(addr, flags);
+
 			dna = pna;
 			dns = pns;
 			dbus = pbus;

+ 10 - 6
arch/sparc/kernel/sun4d_smp.c

@@ -262,8 +262,9 @@ static struct smp_funcall {
 static DEFINE_SPINLOCK(cross_call_lock);
 
 /* Cross calls must be serialized, at least currently. */
-void smp4d_cross_call(smpfunc_t func, unsigned long arg1, unsigned long arg2,
-		    unsigned long arg3, unsigned long arg4, unsigned long arg5)
+static void smp4d_cross_call(smpfunc_t func, cpumask_t mask, unsigned long arg1,
+			     unsigned long arg2, unsigned long arg3,
+			     unsigned long arg4)
 {
 	if(smp_processors_ready) {
 		register int high = smp_highest_cpu;
@@ -278,7 +279,7 @@ void smp4d_cross_call(smpfunc_t func, unsigned long arg1, unsigned long arg2,
 			register unsigned long a2 asm("i2") = arg2;
 			register unsigned long a3 asm("i3") = arg3;
 			register unsigned long a4 asm("i4") = arg4;
-			register unsigned long a5 asm("i5") = arg5;
+			register unsigned long a5 asm("i5") = 0;
 
 			__asm__ __volatile__(
 				"std %0, [%6]\n\t"
@@ -290,11 +291,10 @@ void smp4d_cross_call(smpfunc_t func, unsigned long arg1, unsigned long arg2,
 
 		/* Init receive/complete mapping, plus fire the IPI's off. */
 		{
-			cpumask_t mask;
 			register int i;
 
-			mask = cpumask_of_cpu(hard_smp4d_processor_id());
-			cpus_andnot(mask, cpu_online_map, mask);
+			cpu_clear(smp_processor_id(), mask);
+			cpus_and(mask, cpu_online_map, mask);
 			for(i = 0; i <= high; i++) {
 				if (cpu_isset(i, mask)) {
 					ccall_info.processors_in[i] = 0;
@@ -309,12 +309,16 @@ void smp4d_cross_call(smpfunc_t func, unsigned long arg1, unsigned long arg2,
 
 			i = 0;
 			do {
+				if (!cpu_isset(i, mask))
+					continue;
 				while(!ccall_info.processors_in[i])
 					barrier();
 			} while(++i <= high);
 
 			i = 0;
 			do {
+				if (!cpu_isset(i, mask))
+					continue;
 				while(!ccall_info.processors_out[i])
 					barrier();
 			} while(++i <= high);

+ 8 - 4
arch/sparc/kernel/sun4m_smp.c

@@ -244,9 +244,9 @@ static struct smp_funcall {
 static DEFINE_SPINLOCK(cross_call_lock);
 
 /* Cross calls must be serialized, at least currently. */
-static void smp4m_cross_call(smpfunc_t func, unsigned long arg1,
+static void smp4m_cross_call(smpfunc_t func, cpumask_t mask, unsigned long arg1,
 			     unsigned long arg2, unsigned long arg3,
-			     unsigned long arg4, unsigned long arg5)
+			     unsigned long arg4)
 {
 		register int ncpus = SUN4M_NCPUS;
 		unsigned long flags;
@@ -259,14 +259,14 @@ static void smp4m_cross_call(smpfunc_t func, unsigned long arg1,
 		ccall_info.arg2 = arg2;
 		ccall_info.arg3 = arg3;
 		ccall_info.arg4 = arg4;
-		ccall_info.arg5 = arg5;
+		ccall_info.arg5 = 0;
 
 		/* Init receive/complete mapping, plus fire the IPI's off. */
 		{
-			cpumask_t mask = cpu_online_map;
 			register int i;
 
 			cpu_clear(smp_processor_id(), mask);
+			cpus_and(mask, cpu_online_map, mask);
 			for(i = 0; i < ncpus; i++) {
 				if (cpu_isset(i, mask)) {
 					ccall_info.processors_in[i] = 0;
@@ -284,12 +284,16 @@ static void smp4m_cross_call(smpfunc_t func, unsigned long arg1,
 
 			i = 0;
 			do {
+				if (!cpu_isset(i, mask))
+					continue;
 				while(!ccall_info.processors_in[i])
 					barrier();
 			} while(++i < ncpus);
 
 			i = 0;
 			do {
+				if (!cpu_isset(i, mask))
+					continue;
 				while(!ccall_info.processors_out[i])
 					barrier();
 			} while(++i < ncpus);

+ 14 - 6
arch/sparc64/kernel/of_device.c

@@ -96,7 +96,7 @@ struct of_bus {
 				       int *addrc, int *sizec);
 	int		(*map)(u32 *addr, const u32 *range,
 			       int na, int ns, int pna);
-	unsigned int	(*get_flags)(const u32 *addr);
+	unsigned long	(*get_flags)(const u32 *addr, unsigned long);
 };
 
 /*
@@ -156,8 +156,10 @@ static int of_bus_default_map(u32 *addr, const u32 *range,
 	return 0;
 }
 
-static unsigned int of_bus_default_get_flags(const u32 *addr)
+static unsigned long of_bus_default_get_flags(const u32 *addr, unsigned long flags)
 {
+	if (flags)
+		return flags;
 	return IORESOURCE_MEM;
 }
 
@@ -249,17 +251,21 @@ static int of_bus_pci_map(u32 *addr, const u32 *range,
 	return 0;
 }
 
-static unsigned int of_bus_pci_get_flags(const u32 *addr)
+static unsigned long of_bus_pci_get_flags(const u32 *addr, unsigned long flags)
 {
-	unsigned int flags = 0;
 	u32 w = addr[0];
 
+	/* For PCI, we override whatever child busses may have used.  */
+	flags = 0;
 	switch((w >> 24) & 0x03) {
 	case 0x01:
 		flags |= IORESOURCE_IO;
+		break;
+
 	case 0x02: /* 32 bits */
 	case 0x03: /* 64 bits */
 		flags |= IORESOURCE_MEM;
+		break;
 	}
 	if (w & 0x40000000)
 		flags |= IORESOURCE_PREFETCH;
@@ -478,10 +484,10 @@ static void __init build_device_resources(struct of_device *op,
 		int pna, pns;
 
 		size = of_read_addr(reg + na, ns);
-		flags = bus->get_flags(reg);
-
 		memcpy(addr, reg, na * 4);
 
+		flags = bus->get_flags(addr, 0);
+
 		if (use_1to1_mapping(pp)) {
 			result = of_read_addr(addr, na);
 			goto build_res;
@@ -506,6 +512,8 @@ static void __init build_device_resources(struct of_device *op,
 					       dna, dns, pna))
 				break;
 
+			flags = pbus->get_flags(addr, flags);
+
 			dna = pna;
 			dns = pns;
 			dbus = pbus;

+ 1 - 1
arch/sparc64/mm/init.c

@@ -1843,7 +1843,7 @@ static int pavail_rescan_ents __initdata;
  * memory list again, and make sure it provides at least as much
  * memory as 'pavail' does.
  */
-static void setup_valid_addr_bitmap_from_pavail(void)
+static void __init setup_valid_addr_bitmap_from_pavail(void)
 {
 	int i;