فهرست منبع

Merge git://git.kernel.org/pub/scm/linux/kernel/git/czankel/xtensa-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/czankel/xtensa-2.6:
  xtensa: Fix linker script to include .literal sections
  xtensa: update s6105_defconfig for ccount calibration
  xtensa: implement ccount calibration for s6000
  xtensa: fix wrong extern declaration renamed in code using it
  xtensa: register gpio chip before use
  xtensa: always use correct stack pointer for stack traces
  xtensa: Fix checksum header file
  xtensa: Fix architecture specific Kconfig
Linus Torvalds 16 سال پیش
والد
کامیت
45d447406a

+ 3 - 4
arch/xtensa/Kconfig

@@ -80,6 +80,7 @@ config XTENSA_VARIANT_S6000
 	bool "s6000 - Stretch software configurable processor"
 	bool "s6000 - Stretch software configurable processor"
 	select VARIANT_IRQ_SWITCH
 	select VARIANT_IRQ_SWITCH
 	select ARCH_REQUIRE_GPIOLIB
 	select ARCH_REQUIRE_GPIOLIB
+	select XTENSA_CALIBRATE_CCOUNT
 endchoice
 endchoice
 
 
 config XTENSA_UNALIGNED_USER
 config XTENSA_UNALIGNED_USER
@@ -137,6 +138,8 @@ config PCI
 
 
 source "drivers/pci/Kconfig"
 source "drivers/pci/Kconfig"
 
 
+endmenu
+
 menu "Platform options"
 menu "Platform options"
 
 
 choice
 choice
@@ -153,8 +156,6 @@ config XTENSA_PLATFORM_ISS
 
 
 config XTENSA_PLATFORM_XT2000
 config XTENSA_PLATFORM_XT2000
 	bool "XT2000"
 	bool "XT2000"
-	select XTENSA_CALIBRATE_CCOUNT
-	select PCI
 	help
 	help
 	  XT2000 is the name of Tensilica's feature-rich emulation platform.
 	  XT2000 is the name of Tensilica's feature-rich emulation platform.
 	  This hardware is capable of running a full Linux distribution.
 	  This hardware is capable of running a full Linux distribution.
@@ -192,8 +193,6 @@ config CMDLINE
 
 
 source "mm/Kconfig"
 source "mm/Kconfig"
 
 
-endmenu
-
 config HOTPLUG
 config HOTPLUG
 	bool "Support for hot-pluggable devices"
 	bool "Support for hot-pluggable devices"
 	help
 	help

+ 1 - 2
arch/xtensa/configs/s6105_defconfig

@@ -115,7 +115,7 @@ CONFIG_XTENSA_VARIANT_S6000=y
 CONFIG_PREEMPT=y
 CONFIG_PREEMPT=y
 # CONFIG_MATH_EMULATION is not set
 # CONFIG_MATH_EMULATION is not set
 # CONFIG_HIGHMEM is not set
 # CONFIG_HIGHMEM is not set
-# CONFIG_XTENSA_CALIBRATE_CCOUNT is not set
+CONFIG_XTENSA_CALIBRATE_CCOUNT=y
 CONFIG_SERIAL_CONSOLE=y
 CONFIG_SERIAL_CONSOLE=y
 # CONFIG_XTENSA_ISS_NETWORK is not set
 # CONFIG_XTENSA_ISS_NETWORK is not set
 
 
@@ -131,7 +131,6 @@ CONFIG_SERIAL_CONSOLE=y
 # CONFIG_XTENSA_PLATFORM_ISS is not set
 # CONFIG_XTENSA_PLATFORM_ISS is not set
 # CONFIG_XTENSA_PLATFORM_XT2000 is not set
 # CONFIG_XTENSA_PLATFORM_XT2000 is not set
 CONFIG_XTENSA_PLATFORM_S6105=y
 CONFIG_XTENSA_PLATFORM_S6105=y
-CONFIG_XTENSA_CPU_CLOCK=300
 CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_CMDLINE_BOOL=y
 CONFIG_CMDLINE_BOOL=y
 CONFIG_CMDLINE="console=ttyS1,38400 debug bootmem_debug loglevel=7"
 CONFIG_CMDLINE="console=ttyS1,38400 debug bootmem_debug loglevel=7"

+ 4 - 2
arch/xtensa/include/asm/checksum.h

@@ -113,7 +113,8 @@ static __inline__ __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
 	   are modified, we must also specify them as outputs, or gcc
 	   are modified, we must also specify them as outputs, or gcc
 	   will assume they contain their original values. */
 	   will assume they contain their original values. */
 		: "=r" (sum), "=r" (iph), "=r" (ihl), "=&r" (tmp), "=&r" (endaddr)
 		: "=r" (sum), "=r" (iph), "=r" (ihl), "=&r" (tmp), "=&r" (endaddr)
-		: "1" (iph), "2" (ihl));
+		: "1" (iph), "2" (ihl)
+		: "memory");
 
 
 	return	csum_fold(sum);
 	return	csum_fold(sum);
 }
 }
@@ -227,7 +228,8 @@ static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
 		"1:\t"
 		"1:\t"
 		: "=r" (sum), "=&r" (__dummy)
 		: "=r" (sum), "=&r" (__dummy)
 		: "r" (saddr), "r" (daddr),
 		: "r" (saddr), "r" (daddr),
-		  "r" (htonl(len)), "r" (htonl(proto)), "0" (sum));
+		  "r" (htonl(len)), "r" (htonl(proto)), "0" (sum)
+		: "memory");
 
 
 	return csum_fold(sum);
 	return csum_fold(sum);
 }
 }

+ 2 - 2
arch/xtensa/include/asm/timex.h

@@ -39,9 +39,9 @@
 
 
 #ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT
 #ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT
 extern unsigned long ccount_per_jiffy;
 extern unsigned long ccount_per_jiffy;
-extern unsigned long ccount_nsec;
+extern unsigned long nsec_per_ccount;
 #define CCOUNT_PER_JIFFY ccount_per_jiffy
 #define CCOUNT_PER_JIFFY ccount_per_jiffy
-#define NSEC_PER_CCOUNT  ccount_nsec
+#define NSEC_PER_CCOUNT  nsec_per_ccount
 #else
 #else
 #define CCOUNT_PER_JIFFY (CONFIG_XTENSA_CPU_CLOCK*(1000000UL/HZ))
 #define CCOUNT_PER_JIFFY (CONFIG_XTENSA_CPU_CLOCK*(1000000UL/HZ))
 #define NSEC_PER_CCOUNT (1000UL / CONFIG_XTENSA_CPU_CLOCK)
 #define NSEC_PER_CCOUNT (1000UL / CONFIG_XTENSA_CPU_CLOCK)

+ 18 - 3
arch/xtensa/kernel/Makefile

@@ -4,15 +4,30 @@
 
 
 extra-y := head.o vmlinux.lds
 extra-y := head.o vmlinux.lds
 
 
-
 obj-y := align.o entry.o irq.o coprocessor.o process.o ptrace.o \
 obj-y := align.o entry.o irq.o coprocessor.o process.o ptrace.o \
 	 setup.o signal.o syscall.o time.o traps.o vectors.o platform.o  \
 	 setup.o signal.o syscall.o time.o traps.o vectors.o platform.o  \
 	 pci-dma.o init_task.o io.o
 	 pci-dma.o init_task.o io.o
 
 
-## windowspill.o
-
 obj-$(CONFIG_KGDB) += xtensa-stub.o
 obj-$(CONFIG_KGDB) += xtensa-stub.o
 obj-$(CONFIG_PCI) += pci.o
 obj-$(CONFIG_PCI) += pci.o
 obj-$(CONFIG_MODULES) += xtensa_ksyms.o module.o
 obj-$(CONFIG_MODULES) += xtensa_ksyms.o module.o
 
 
+# In the Xtensa architecture, assembly generates literals which must always
+# precede the L32R instruction with a relative offset less than 256 kB.
+# Therefore, the .text and .literal section must be combined in parenthesis
+# in the linker script, such as: *(.literal .text).
+#
+# We need to post-process the generated vmlinux.lds scripts to convert
+# *(xxx.text) to  *(xxx.literal xxx.text) for the following text sections:
+#   .text .ref.text .*init.text .*exit.text .text.*
+#
+# Replicate rules in scripts/Makefile.build
+
+sed-y = -e 's/(\(\.[a-z]*it\|\.ref\|\)\.text)/(\1.literal \1.text)/g'	\
+	-e 's/(\(\.text\.[a-z]*\))/(\1.literal \1)/g'
+
+quiet_cmd__cpp_lds_S = LDS     $@
+      cmd__cpp_lds_S = $(CPP) $(cpp_flags) -D__ASSEMBLY__ $< | sed $(sed-y) >$@
 
 
+$(obj)/vmlinux.lds: $(src)/vmlinux.lds.S FORCE
+	$(call if_changed_dep,_cpp_lds_S)

+ 14 - 2
arch/xtensa/kernel/traps.c

@@ -369,6 +369,18 @@ void show_regs(struct pt_regs * regs)
 		       regs->syscall);
 		       regs->syscall);
 }
 }
 
 
+static __always_inline unsigned long *stack_pointer(struct task_struct *task)
+{
+	unsigned long *sp;
+
+	if (!task || task == current)
+		__asm__ __volatile__ ("mov %0, a1\n" : "=a"(sp));
+	else
+		sp = (unsigned long *)task->thread.sp;
+
+	return sp;
+}
+
 void show_trace(struct task_struct *task, unsigned long *sp)
 void show_trace(struct task_struct *task, unsigned long *sp)
 {
 {
 	unsigned long a0, a1, pc;
 	unsigned long a0, a1, pc;
@@ -377,7 +389,7 @@ void show_trace(struct task_struct *task, unsigned long *sp)
 	if (sp)
 	if (sp)
 		a1 = (unsigned long)sp;
 		a1 = (unsigned long)sp;
 	else
 	else
-		a1 = task->thread.sp;
+		a1 = (unsigned long)stack_pointer(task);
 
 
 	sp_start = a1 & ~(THREAD_SIZE-1);
 	sp_start = a1 & ~(THREAD_SIZE-1);
 	sp_end = sp_start + THREAD_SIZE;
 	sp_end = sp_start + THREAD_SIZE;
@@ -420,7 +432,7 @@ void show_stack(struct task_struct *task, unsigned long *sp)
 	unsigned long *stack;
 	unsigned long *stack;
 
 
 	if (!sp)
 	if (!sp)
-		sp = (unsigned long *)task->thread.sp;
+		sp = stack_pointer(task);
  	stack = sp;
  	stack = sp;
 
 
 	printk("\nStack: ");
 	printk("\nStack: ");

+ 1 - 3
arch/xtensa/kernel/vmlinux.lds.S

@@ -87,7 +87,7 @@ SECTIONS
   {
   {
     /* The HEAD_TEXT section must be the first section! */
     /* The HEAD_TEXT section must be the first section! */
     HEAD_TEXT
     HEAD_TEXT
-    *(.literal .text)
+    TEXT_TEXT
     VMLINUX_SYMBOL(__sched_text_start) = .;
     VMLINUX_SYMBOL(__sched_text_start) = .;
     *(.sched.literal .sched.text)
     *(.sched.literal .sched.text)
     VMLINUX_SYMBOL(__sched_text_end) = .;
     VMLINUX_SYMBOL(__sched_text_end) = .;
@@ -139,8 +139,6 @@ SECTIONS
   __init_begin = .;
   __init_begin = .;
   .init.text : {
   .init.text : {
   	_sinittext = .;
   	_sinittext = .;
-	*(.init.literal) *(.cpuinit.literal) 
-	*(.devinit.literal) *(.meminit.literal)
 	INIT_TEXT
 	INIT_TEXT
 	_einittext = .;
 	_einittext = .;
   }
   }

+ 3 - 0
arch/xtensa/platforms/s6105/setup.c

@@ -10,6 +10,8 @@
 #include <asm/bootparam.h>
 #include <asm/bootparam.h>
 
 
 #include <variant/hardware.h>
 #include <variant/hardware.h>
+#include <variant/gpio.h>
+
 #include <platform/gpio.h>
 #include <platform/gpio.h>
 
 
 void platform_halt(void)
 void platform_halt(void)
@@ -47,6 +49,7 @@ void __init platform_setup(char **cmdline)
 
 
 void __init platform_init(bp_tag_t *first)
 void __init platform_init(bp_tag_t *first)
 {
 {
+	s6_gpio_init();
 	gpio_request(GPIO_LED1_NGREEN, "led1_green");
 	gpio_request(GPIO_LED1_NGREEN, "led1_green");
 	gpio_request(GPIO_LED1_RED, "led1_red");
 	gpio_request(GPIO_LED1_RED, "led1_red");
 	gpio_direction_output(GPIO_LED1_NGREEN, 1);
 	gpio_direction_output(GPIO_LED1_NGREEN, 1);

+ 1 - 0
arch/xtensa/variants/s6000/Makefile

@@ -1,3 +1,4 @@
 # s6000 Makefile
 # s6000 Makefile
 
 
 obj-y		+= irq.o gpio.o
 obj-y		+= irq.o gpio.o
+obj-$(CONFIG_XTENSA_CALIBRATE_CCOUNT)	+= delay.o

+ 27 - 0
arch/xtensa/variants/s6000/delay.c

@@ -0,0 +1,27 @@
+#include <asm/delay.h>
+#include <asm/timex.h>
+#include <asm/io.h>
+#include <variant/hardware.h>
+
+#define LOOPS 10
+void platform_calibrate_ccount(void)
+{
+	u32 uninitialized_var(a);
+	u32 uninitialized_var(u);
+	u32 b;
+	u32 tstamp = S6_REG_GREG1 + S6_GREG1_GLOBAL_TIMER;
+	int i = LOOPS+1;
+	do {
+		u32 t = u;
+		asm volatile(
+		"1:	l32i %0, %2, 0 ;"
+		"	beq %0, %1, 1b ;"
+		: "=&a"(u) : "a"(t), "a"(tstamp));
+		b = xtensa_get_ccount();
+		if (i == LOOPS)
+			a = b;
+	} while (--i >= 0);
+	b -= a;
+	nsec_per_ccount = (LOOPS * 10000) / b;
+	ccount_per_jiffy = b * (100000UL / (LOOPS * HZ));
+}

+ 1 - 2
arch/xtensa/variants/s6000/gpio.c

@@ -64,8 +64,7 @@ static struct gpio_chip gpiochip = {
 	.exported = 0, /* no exporting to userspace */
 	.exported = 0, /* no exporting to userspace */
 };
 };
 
 
-static int gpio_init(void)
+int s6_gpio_init(void)
 {
 {
 	return gpiochip_add(&gpiochip);
 	return gpiochip_add(&gpiochip);
 }
 }
-device_initcall(gpio_init);

+ 6 - 0
arch/xtensa/variants/s6000/include/variant/gpio.h

@@ -0,0 +1,6 @@
+#ifndef _XTENSA_VARIANT_S6000_GPIO_H
+#define _XTENSA_VARIANT_S6000_GPIO_H
+
+extern int s6_gpio_init(void);
+
+#endif /* _XTENSA_VARIANT_S6000_GPIO_H */