瀏覽代碼

Merge git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6:
  sh: Fix up HAVE_PERF_COUNTERS typo.
  sh: Fix up more dma-mapping fallout.
  sh: SH7786 SMP support.
  sh: Wire up the uncached fixmap on sh64 as well.
  sh: Use local TLB flush in set_pte_phys().
  sh: Provide cpu_idle_wait() to fix up cpuidle/SMP build.
Linus Torvalds 16 年之前
父節點
當前提交
626f380d0b

+ 10 - 2
arch/sh/Kconfig

@@ -15,7 +15,7 @@ config SUPERH
 	select HAVE_IOREMAP_PROT if MMU
 	select HAVE_IOREMAP_PROT if MMU
 	select HAVE_ARCH_TRACEHOOK
 	select HAVE_ARCH_TRACEHOOK
 	select HAVE_DMA_API_DEBUG
 	select HAVE_DMA_API_DEBUG
-	select HAVE_PERF_COUNTER
+	select HAVE_PERF_COUNTERS
 	select RTC_LIB
 	select RTC_LIB
 	select GENERIC_ATOMIC64
 	select GENERIC_ATOMIC64
 	help
 	help
@@ -71,6 +71,9 @@ config GENERIC_HARDIRQS_NO__DO_IRQ
 config GENERIC_IRQ_PROBE
 config GENERIC_IRQ_PROBE
 	def_bool y
 	def_bool y
 
 
+config IRQ_PER_CPU
+	def_bool y
+
 config GENERIC_GPIO
 config GENERIC_GPIO
 	def_bool n
 	def_bool n
 
 
@@ -151,6 +154,9 @@ config ARCH_NO_VIRT_TO_BUS
 config ARCH_HAS_DEFAULT_IDLE
 config ARCH_HAS_DEFAULT_IDLE
 	def_bool y
 	def_bool y
 
 
+config ARCH_HAS_CPU_IDLE_WAIT
+	def_bool y
+
 config IO_TRAPPED
 config IO_TRAPPED
 	bool
 	bool
 
 
@@ -411,6 +417,8 @@ config CPU_SUBTYPE_SH7786
 	select CPU_HAS_PTEAEX
 	select CPU_HAS_PTEAEX
 	select ARCH_SPARSEMEM_ENABLE
 	select ARCH_SPARSEMEM_ENABLE
 	select SYS_SUPPORTS_NUMA
 	select SYS_SUPPORTS_NUMA
+	select SYS_SUPPORTS_SMP
+	select GENERIC_CLOCKEVENTS_BROADCAST if SMP
 
 
 config CPU_SUBTYPE_SHX3
 config CPU_SUBTYPE_SHX3
 	bool "Support SH-X3 processor"
 	bool "Support SH-X3 processor"
@@ -648,7 +656,7 @@ config NR_CPUS
 	int "Maximum number of CPUs (2-32)"
 	int "Maximum number of CPUs (2-32)"
 	range 2 32
 	range 2 32
 	depends on SMP
 	depends on SMP
-	default "4" if CPU_SHX3
+	default "4" if CPU_SUBTYPE_SHX3
 	default "2"
 	default "2"
 	help
 	help
 	  This allows you to specify the maximum number of CPUs which this
 	  This allows you to specify the maximum number of CPUs which this

+ 6 - 6
arch/sh/include/asm/dma-mapping.h

@@ -97,7 +97,7 @@ static inline void dma_unmap_page(struct device *dev, dma_addr_t dma_address,
 	dma_unmap_single(dev, dma_address, size, dir);
 	dma_unmap_single(dev, dma_address, size, dir);
 }
 }
 
 
-static inline void dma_sync_single(struct device *dev, dma_addr_t dma_handle,
+static inline void __dma_sync_single(struct device *dev, dma_addr_t dma_handle,
 				   size_t size, enum dma_data_direction dir)
 				   size_t size, enum dma_data_direction dir)
 {
 {
 #if defined(CONFIG_PCI) && !defined(CONFIG_SH_PCIDMA_NONCOHERENT)
 #if defined(CONFIG_PCI) && !defined(CONFIG_SH_PCIDMA_NONCOHERENT)
@@ -119,7 +119,7 @@ static inline void dma_sync_single_range(struct device *dev,
 	dma_cache_sync(dev, phys_to_virt(dma_handle) + offset, size, dir);
 	dma_cache_sync(dev, phys_to_virt(dma_handle) + offset, size, dir);
 }
 }
 
 
-static inline void dma_sync_sg(struct device *dev, struct scatterlist *sg,
+static inline void __dma_sync_sg(struct device *dev, struct scatterlist *sg,
 			       int nelems, enum dma_data_direction dir)
 			       int nelems, enum dma_data_direction dir)
 {
 {
 	int i;
 	int i;
@@ -137,7 +137,7 @@ static inline void dma_sync_single_for_cpu(struct device *dev,
 					   dma_addr_t dma_handle, size_t size,
 					   dma_addr_t dma_handle, size_t size,
 					   enum dma_data_direction dir)
 					   enum dma_data_direction dir)
 {
 {
-	dma_sync_single(dev, dma_handle, size, dir);
+	__dma_sync_single(dev, dma_handle, size, dir);
 	debug_dma_sync_single_for_cpu(dev, dma_handle, size, dir);
 	debug_dma_sync_single_for_cpu(dev, dma_handle, size, dir);
 }
 }
 
 
@@ -146,7 +146,7 @@ static inline void dma_sync_single_for_device(struct device *dev,
 					      size_t size,
 					      size_t size,
 					      enum dma_data_direction dir)
 					      enum dma_data_direction dir)
 {
 {
-	dma_sync_single(dev, dma_handle, size, dir);
+	__dma_sync_single(dev, dma_handle, size, dir);
 	debug_dma_sync_single_for_device(dev, dma_handle, size, dir);
 	debug_dma_sync_single_for_device(dev, dma_handle, size, dir);
 }
 }
 
 
@@ -177,7 +177,7 @@ static inline void dma_sync_sg_for_cpu(struct device *dev,
 				       struct scatterlist *sg, int nelems,
 				       struct scatterlist *sg, int nelems,
 				       enum dma_data_direction dir)
 				       enum dma_data_direction dir)
 {
 {
-	dma_sync_sg(dev, sg, nelems, dir);
+	__dma_sync_sg(dev, sg, nelems, dir);
 	debug_dma_sync_sg_for_cpu(dev, sg, nelems, dir);
 	debug_dma_sync_sg_for_cpu(dev, sg, nelems, dir);
 }
 }
 
 
@@ -185,7 +185,7 @@ static inline void dma_sync_sg_for_device(struct device *dev,
 					  struct scatterlist *sg, int nelems,
 					  struct scatterlist *sg, int nelems,
 					  enum dma_data_direction dir)
 					  enum dma_data_direction dir)
 {
 {
-	dma_sync_sg(dev, sg, nelems, dir);
+	__dma_sync_sg(dev, sg, nelems, dir);
 	debug_dma_sync_sg_for_device(dev, sg, nelems, dir);
 	debug_dma_sync_sg_for_device(dev, sg, nelems, dir);
 }
 }
 
 

+ 1 - 0
arch/sh/include/asm/system.h

@@ -154,6 +154,7 @@ extern struct dentry *sh_debugfs_root;
 
 
 void per_cpu_trap_init(void);
 void per_cpu_trap_init(void);
 void default_idle(void);
 void default_idle(void);
+void cpu_idle_wait(void);
 
 
 asmlinkage void break_point_trap(void);
 asmlinkage void break_point_trap(void);
 
 

+ 3 - 3
arch/sh/kernel/cpu/sh4a/Makefile

@@ -16,7 +16,7 @@ obj-$(CONFIG_CPU_SUBTYPE_SH7366)	+= setup-sh7366.o
 obj-$(CONFIG_CPU_SUBTYPE_SHX3)		+= setup-shx3.o
 obj-$(CONFIG_CPU_SUBTYPE_SHX3)		+= setup-shx3.o
 
 
 # SMP setup
 # SMP setup
-smp-$(CONFIG_CPU_SUBTYPE_SHX3)		:= smp-shx3.o
+smp-$(CONFIG_CPU_SHX3)			:= smp-shx3.o
 
 
 # Primary on-chip clocks (common)
 # Primary on-chip clocks (common)
 clock-$(CONFIG_CPU_SUBTYPE_SH7763)	:= clock-sh7763.o
 clock-$(CONFIG_CPU_SUBTYPE_SH7763)	:= clock-sh7763.o
@@ -38,6 +38,6 @@ pinmux-$(CONFIG_CPU_SUBTYPE_SH7724)	:= pinmux-sh7724.o
 pinmux-$(CONFIG_CPU_SUBTYPE_SH7785)	:= pinmux-sh7785.o
 pinmux-$(CONFIG_CPU_SUBTYPE_SH7785)	:= pinmux-sh7785.o
 pinmux-$(CONFIG_CPU_SUBTYPE_SH7786)	:= pinmux-sh7786.o
 pinmux-$(CONFIG_CPU_SUBTYPE_SH7786)	:= pinmux-sh7786.o
 
 
-obj-y			+= $(clock-y)
-obj-$(CONFIG_SMP)	+= $(smp-y)
+obj-y				+= $(clock-y)
+obj-$(CONFIG_SMP)		+= $(smp-y)
 obj-$(CONFIG_GENERIC_GPIO)	+= $(pinmux-y)
 obj-$(CONFIG_GENERIC_GPIO)	+= $(pinmux-y)

+ 9 - 20
arch/sh/kernel/cpu/sh4a/setup-sh7786.c

@@ -595,9 +595,8 @@ enum {
 	HSPI,
 	HSPI,
 	GPIO0, GPIO1,
 	GPIO0, GPIO1,
 	Thermal,
 	Thermal,
-	INTC0, INTC1, INTC2, INTC3, INTC4, INTC5, INTC6, INTC7,
-
-	/* interrupt groups */
+	INTICI0, INTICI1, INTICI2, INTICI3,
+	INTICI4, INTICI5, INTICI6, INTICI7,
 };
 };
 
 
 static struct intc_vect vectors[] __initdata = {
 static struct intc_vect vectors[] __initdata = {
@@ -638,10 +637,12 @@ static struct intc_vect vectors[] __initdata = {
 	INTC_VECT(HSPI, 0xe80),
 	INTC_VECT(HSPI, 0xe80),
 	INTC_VECT(GPIO0, 0xea0), INTC_VECT(GPIO1, 0xec0),
 	INTC_VECT(GPIO0, 0xea0), INTC_VECT(GPIO1, 0xec0),
 	INTC_VECT(Thermal, 0xee0),
 	INTC_VECT(Thermal, 0xee0),
+	INTC_VECT(INTICI0, 0xf00), INTC_VECT(INTICI1, 0xf20),
+	INTC_VECT(INTICI2, 0xf40), INTC_VECT(INTICI3, 0xf60),
+	INTC_VECT(INTICI4, 0xf80), INTC_VECT(INTICI5, 0xfa0),
+	INTC_VECT(INTICI6, 0xfc0), INTC_VECT(INTICI7, 0xfe0),
 };
 };
 
 
-/* FIXME: Main CPU support only now */
-#if 1 /* Main CPU */
 #define CnINTMSK0	0xfe410030
 #define CnINTMSK0	0xfe410030
 #define CnINTMSK1	0xfe410040
 #define CnINTMSK1	0xfe410040
 #define CnINTMSKCLR0	0xfe410050
 #define CnINTMSKCLR0	0xfe410050
@@ -654,21 +655,6 @@ static struct intc_vect vectors[] __initdata = {
 #define CnINT2MSKCR1	0xfe410a34
 #define CnINT2MSKCR1	0xfe410a34
 #define CnINT2MSKCR2	0xfe410a38
 #define CnINT2MSKCR2	0xfe410a38
 #define CnINT2MSKCR3	0xfe410a3c
 #define CnINT2MSKCR3	0xfe410a3c
-#else /* Sub CPU */
-#define CnINTMSK0	0xfe410034
-#define CnINTMSK1	0xfe410044
-#define CnINTMSKCLR0	0xfe410054
-#define CnINTMSKCLR1	0xfe410064
-#define CnINT2MSKR0	0xfe410b20
-#define CnINT2MSKR1	0xfe410b24
-#define CnINT2MSKR2	0xfe410b28
-#define CnINT2MSKR3	0xfe410b2c
-#define CnINT2MSKCR0	0xfe410b30
-#define CnINT2MSKCR1	0xfe410b34
-#define CnINT2MSKCR2	0xfe410b38
-#define CnINT2MSKCR3	0xfe410b3c
-#endif
-
 #define INTMSK2		0xfe410068
 #define INTMSK2		0xfe410068
 #define INTMSKCLR2	0xfe41006c
 #define INTMSKCLR2	0xfe41006c
 
 
@@ -753,6 +739,9 @@ static struct intc_prio_reg prio_registers[] __initdata = {
 						  GPIO1, Thermal } },
 						  GPIO1, Thermal } },
 	{ 0xfe41085c, 0, 32, 8, /* INT2PRI23 */ { 0, 0, 0, 0 } },
 	{ 0xfe41085c, 0, 32, 8, /* INT2PRI23 */ { 0, 0, 0, 0 } },
 	{ 0xfe410860, 0, 32, 8, /* INT2PRI24 */ { 0, 0, 0, 0 } },
 	{ 0xfe410860, 0, 32, 8, /* INT2PRI24 */ { 0, 0, 0, 0 } },
+	{ 0xfe410090, 0xfe4100a0, 32, 4, /* CnICIPRI / CnICIPRICLR */
+	  { INTICI7, INTICI6, INTICI5, INTICI4,
+	    INTICI3, INTICI2, INTICI1, INTICI0 }, INTC_SMP(4, 2) },
 };
 };
 
 
 static DECLARE_INTC_DESC(intc_desc, "sh7786", vectors, NULL,
 static DECLARE_INTC_DESC(intc_desc, "sh7786", vectors, NULL,

+ 22 - 1
arch/sh/kernel/idle.c

@@ -1,7 +1,7 @@
 /*
 /*
  * The idle loop for all SuperH platforms.
  * The idle loop for all SuperH platforms.
  *
  *
- *  Copyright (C) 2002 - 2008  Paul Mundt
+ *  Copyright (C) 2002 - 2009  Paul Mundt
  *
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * License.  See the file "COPYING" in the main directory of this archive
@@ -15,6 +15,7 @@
 #include <linux/preempt.h>
 #include <linux/preempt.h>
 #include <linux/thread_info.h>
 #include <linux/thread_info.h>
 #include <linux/irqflags.h>
 #include <linux/irqflags.h>
+#include <linux/smp.h>
 #include <asm/pgalloc.h>
 #include <asm/pgalloc.h>
 #include <asm/system.h>
 #include <asm/system.h>
 #include <asm/atomic.h>
 #include <asm/atomic.h>
@@ -79,3 +80,23 @@ void cpu_idle(void)
 		check_pgt_cache();
 		check_pgt_cache();
 	}
 	}
 }
 }
+
+static void do_nothing(void *unused)
+{
+}
+
+/*
+ * cpu_idle_wait - Used to ensure that all the CPUs discard old value of
+ * pm_idle and update to new pm_idle value. Required while changing pm_idle
+ * handler on SMP systems.
+ *
+ * Caller must have changed pm_idle to the new value before the call. Old
+ * pm_idle value will not be used by any CPU after the return of this function.
+ */
+void cpu_idle_wait(void)
+{
+	smp_mb();
+	/* kick all the CPUs so that they exit out of pm_idle */
+	smp_call_function(do_nothing, NULL, 1);
+}
+EXPORT_SYMBOL_GPL(cpu_idle_wait);

+ 1 - 3
arch/sh/mm/init.c

@@ -70,7 +70,7 @@ static void set_pte_phys(unsigned long addr, unsigned long phys, pgprot_t prot)
 	}
 	}
 
 
 	set_pte(pte, pfn_pte(phys >> PAGE_SHIFT, prot));
 	set_pte(pte, pfn_pte(phys >> PAGE_SHIFT, prot));
-	flush_tlb_one(get_asid(), addr);
+	local_flush_tlb_one(get_asid(), addr);
 }
 }
 
 
 /*
 /*
@@ -177,10 +177,8 @@ void __init paging_init(void)
 
 
 	free_area_init_nodes(max_zone_pfns);
 	free_area_init_nodes(max_zone_pfns);
 
 
-#ifdef CONFIG_SUPERH32
 	/* Set up the uncached fixmap */
 	/* Set up the uncached fixmap */
 	set_fixmap_nocache(FIX_UNCACHED, __pa(&__uncached_start));
 	set_fixmap_nocache(FIX_UNCACHED, __pa(&__uncached_start));
-#endif
 }
 }
 
 
 static struct kcore_list kcore_mem, kcore_vmalloc;
 static struct kcore_list kcore_mem, kcore_vmalloc;