Merge branch 'sh/stable-updates'
authorPaul Mundt <lethal@linux-sh.org>
Sat, 15 Aug 2009 03:59:42 +0000 (12:59 +0900)
committerPaul Mundt <lethal@linux-sh.org>
Sat, 15 Aug 2009 03:59:42 +0000 (12:59 +0900)
104 files changed:
arch/sh/Kconfig
arch/sh/Kconfig.debug
arch/sh/Makefile
arch/sh/boards/Kconfig
arch/sh/boards/mach-highlander/setup.c
arch/sh/boards/mach-kfr2r09/Makefile [new file with mode: 0644]
arch/sh/boards/mach-kfr2r09/lcd_wqvga.c [new file with mode: 0644]
arch/sh/boards/mach-kfr2r09/setup.c [new file with mode: 0644]
arch/sh/boards/mach-se/7724/setup.c
arch/sh/boards/mach-x3proto/setup.c
arch/sh/boot/.gitignore
arch/sh/boot/Makefile
arch/sh/boot/compressed/.gitignore [new file with mode: 0644]
arch/sh/boot/compressed/Makefile
arch/sh/boot/compressed/misc.c [new file with mode: 0644]
arch/sh/boot/compressed/misc_32.c [deleted file]
arch/sh/boot/compressed/misc_64.c [deleted file]
arch/sh/boot/compressed/piggy.S [deleted file]
arch/sh/boot/compressed/vmlinux.scr [new file with mode: 0644]
arch/sh/boot/romimage/Makefile [new file with mode: 0644]
arch/sh/boot/romimage/head.S [new file with mode: 0644]
arch/sh/boot/romimage/vmlinux.scr [new file with mode: 0644]
arch/sh/configs/kfr2r09_defconfig [new file with mode: 0644]
arch/sh/include/asm/dma-sh.h
arch/sh/include/asm/dwarf.h [new file with mode: 0644]
arch/sh/include/asm/entry-macros.S
arch/sh/include/asm/ftrace.h
arch/sh/include/asm/hardirq.h
arch/sh/include/asm/hwblk.h [new file with mode: 0644]
arch/sh/include/asm/lmb.h [new file with mode: 0644]
arch/sh/include/asm/pgtable_32.h
arch/sh/include/asm/sections.h
arch/sh/include/asm/stacktrace.h [new file with mode: 0644]
arch/sh/include/asm/suspend.h
arch/sh/include/asm/syscall_32.h
arch/sh/include/asm/thread_info.h
arch/sh/include/asm/unwinder.h [new file with mode: 0644]
arch/sh/include/asm/vmlinux.lds.h [new file with mode: 0644]
arch/sh/include/cpu-sh4/cpu/dma-sh4a.h
arch/sh/include/cpu-sh4/cpu/sh7722.h
arch/sh/include/cpu-sh4/cpu/sh7723.h
arch/sh/include/cpu-sh4/cpu/sh7724.h
arch/sh/include/mach-common/mach/migor.h [deleted file]
arch/sh/include/mach-common/mach/romimage.h [new file with mode: 0644]
arch/sh/include/mach-kfr2r09/mach/kfr2r09.h [new file with mode: 0644]
arch/sh/include/mach-kfr2r09/mach/partner-jet-setup.txt [new file with mode: 0644]
arch/sh/include/mach-kfr2r09/mach/romimage.h [new file with mode: 0644]
arch/sh/include/mach-migor/mach/migor.h [new file with mode: 0644]
arch/sh/kernel/Makefile_32
arch/sh/kernel/Makefile_64
arch/sh/kernel/asm-offsets.c
arch/sh/kernel/cpu/Makefile
arch/sh/kernel/cpu/hwblk.c [new file with mode: 0644]
arch/sh/kernel/cpu/init.c
arch/sh/kernel/cpu/sh2/entry.S
arch/sh/kernel/cpu/sh2a/entry.S
arch/sh/kernel/cpu/sh3/entry.S
arch/sh/kernel/cpu/sh4a/Makefile
arch/sh/kernel/cpu/sh4a/clock-sh7722.c
arch/sh/kernel/cpu/sh4a/clock-sh7723.c
arch/sh/kernel/cpu/sh4a/clock-sh7724.c
arch/sh/kernel/cpu/sh4a/hwblk-sh7722.c [new file with mode: 0644]
arch/sh/kernel/cpu/sh4a/hwblk-sh7723.c [new file with mode: 0644]
arch/sh/kernel/cpu/sh4a/hwblk-sh7724.c [new file with mode: 0644]
arch/sh/kernel/cpu/sh4a/setup-sh7366.c
arch/sh/kernel/cpu/sh4a/setup-sh7722.c
arch/sh/kernel/cpu/sh4a/setup-sh7723.c
arch/sh/kernel/cpu/shmobile/Makefile
arch/sh/kernel/cpu/shmobile/cpuidle.c [new file with mode: 0644]
arch/sh/kernel/cpu/shmobile/pm.c
arch/sh/kernel/dumpstack.c [new file with mode: 0644]
arch/sh/kernel/dwarf.c [new file with mode: 0644]
arch/sh/kernel/early_printk.c
arch/sh/kernel/entry-common.S
arch/sh/kernel/ftrace.c
arch/sh/kernel/io_trapped.c
arch/sh/kernel/irq.c
arch/sh/kernel/process_32.c
arch/sh/kernel/ptrace_32.c
arch/sh/kernel/setup.c
arch/sh/kernel/sh_ksyms_32.c
arch/sh/kernel/stacktrace.c
arch/sh/kernel/time.c
arch/sh/kernel/traps_32.c
arch/sh/kernel/unwinder.c [new file with mode: 0644]
arch/sh/kernel/vmlinux.lds.S
arch/sh/lib/Makefile
arch/sh/lib/mcount.S
arch/sh/mm/fault_32.c
arch/sh/mm/ioremap_64.c
arch/sh/mm/numa.c
arch/sh/oprofile/backtrace.c
arch/sh/tools/mach-types
drivers/serial/sh-sci.c
drivers/usb/gadget/Kconfig
drivers/usb/gadget/m66592-udc.c
drivers/usb/gadget/m66592-udc.h
drivers/usb/host/Kconfig
drivers/usb/host/r8a66597-hcd.c
drivers/usb/host/r8a66597.h
drivers/video/Kconfig
drivers/video/sh_mobile_lcdcfb.c
include/linux/usb/m66592.h [new file with mode: 0644]
include/linux/usb/r8a66597.h

index e2bdd7b94fd916cd4307ff5d53f841feb8e17c80..c4a955d2545176c3962e89abe29b70ef831c3d93 100644 (file)
@@ -10,12 +10,16 @@ config SUPERH
        select EMBEDDED
        select HAVE_CLK
        select HAVE_IDE
+       select HAVE_LMB
        select HAVE_OPROFILE
        select HAVE_GENERIC_DMA_COHERENT
        select HAVE_IOREMAP_PROT if MMU
        select HAVE_ARCH_TRACEHOOK
        select HAVE_DMA_API_DEBUG
        select HAVE_PERF_COUNTERS
+       select HAVE_KERNEL_GZIP
+       select HAVE_KERNEL_BZIP2
+       select HAVE_KERNEL_LZMA
        select RTC_LIB
        select GENERIC_ATOMIC64
        help
@@ -31,6 +35,9 @@ config SUPERH32
        select HAVE_FUNCTION_TRACER
        select HAVE_FTRACE_MCOUNT_RECORD
        select HAVE_DYNAMIC_FTRACE
+       select HAVE_FUNCTION_TRACE_MCOUNT_TEST
+       select HAVE_FTRACE_SYSCALLS
+       select HAVE_FUNCTION_GRAPH_TRACER
        select HAVE_ARCH_KGDB
        select ARCH_HIBERNATION_POSSIBLE if MMU
 
index 39224b57c6efe5ae5d37a45c68d34811fbc0f047..741d20fab2e19dabbde67d671e570272d1736039 100644 (file)
@@ -38,11 +38,12 @@ config EARLY_SCIF_CONSOLE_PORT
        default "0xffe00000" if CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7763 || \
                                CPU_SUBTYPE_SH7722 || CPU_SUBTYPE_SH7366 || \
                                CPU_SUBTYPE_SH7343
-       default "0xffea0000" if CPU_SUBTYPE_SH7785
+       default "0xffeb0000" if CPU_SUBTYPE_SH7785
        default "0xffeb0000" if CPU_SUBTYPE_SH7786
        default "0xfffe8000" if CPU_SUBTYPE_SH7203
        default "0xfffe9800" if CPU_SUBTYPE_SH7206 || CPU_SUBTYPE_SH7263
        default "0xffe80000" if CPU_SH4
+       default "0xa4000150" if CPU_SH3
        default "0x00000000"
 
 config EARLY_PRINTK
@@ -61,12 +62,14 @@ config EARLY_PRINTK
          select both the EARLY_SCIF_CONSOLE and SH_STANDARD_BIOS, using
          the kernel command line option to toggle back and forth.
 
-config DEBUG_STACKOVERFLOW
+config STACK_DEBUG
        bool "Check for stack overflows"
        depends on DEBUG_KERNEL && SUPERH32
        help
          This option will cause messages to be printed if free stack space
-         drops below a certain limit.
+         drops below a certain limit. Saying Y here will add overhead to
+         every function call and will therefore incur a major
+         performance hit. Most users should say N.
 
 config DEBUG_STACK_USAGE
        bool "Stack utilization instrumentation"
@@ -107,6 +110,14 @@ config DUMP_CODE
 
          Those looking for more verbose debugging output should say Y.
 
+config DWARF_UNWINDER
+       bool "Enable the DWARF unwinder for stacktraces"
+       select FRAME_POINTER
+       default n
+       help
+         Enabling this option will make stacktraces more accurate, at
+         the cost of an increase in overall kernel size.
+
 config SH_NO_BSS_INIT
        bool "Avoid zeroing BSS (to speed-up startup on suitable platforms)"
        depends on DEBUG_KERNEL
@@ -123,4 +134,9 @@ config SH64_SR_WATCH
        bool "Debug: set SR.WATCH to enable hardware watchpoints and trace"
        depends on SUPERH64
 
+config MCOUNT
+       def_bool y
+       depends on SUPERH32
+       depends on STACK_DEBUG || FUNCTION_TRACER
+
 endmenu
index 75d049b03f7e04231de0525ba6b57e3779fe2984..e26421bf9976d5db761d5f139b7d81e37ff3e08e 100644 (file)
@@ -136,6 +136,7 @@ machdir-$(CONFIG_SH_7751_SYSTEMH)           += mach-systemh
 machdir-$(CONFIG_SH_EDOSK7705)                 += mach-edosk7705
 machdir-$(CONFIG_SH_HIGHLANDER)                        += mach-highlander
 machdir-$(CONFIG_SH_MIGOR)                     += mach-migor
+machdir-$(CONFIG_SH_KFR2R09)                   += mach-kfr2r09
 machdir-$(CONFIG_SH_SDK7780)                   += mach-sdk7780
 machdir-$(CONFIG_SH_X3PROTO)                   += mach-x3proto
 machdir-$(CONFIG_SH_SH7763RDP)                 += mach-sh7763rdp
@@ -186,17 +187,27 @@ KBUILD_CFLAGS             += -pipe $(cflags-y)
 KBUILD_CPPFLAGS                += $(cflags-y)
 KBUILD_AFLAGS          += $(cflags-y)
 
+ifeq ($(CONFIG_MCOUNT),y)
+  KBUILD_CFLAGS += -pg
+endif
+
+ifeq ($(CONFIG_DWARF_UNWINDER),y)
+  KBUILD_CFLAGS += -fasynchronous-unwind-tables
+endif
+
 libs-$(CONFIG_SUPERH32)                := arch/sh/lib/ $(libs-y)
 libs-$(CONFIG_SUPERH64)                := arch/sh/lib64/ $(libs-y)
 
-PHONY += maketools FORCE
+BOOT_TARGETS = uImage uImage.bz2 uImage.gz uImage.lzma uImage.srec \
+              zImage vmlinux.srec romImage
+PHONY += maketools $(BOOT_TARGETS) FORCE
 
 maketools:  include/linux/version.h FORCE
        $(Q)$(MAKE) $(build)=arch/sh/tools include/asm-sh/machtypes.h
 
 all: $(KBUILD_IMAGE)
 
-zImage uImage uImage.srec vmlinux.srec: vmlinux
+$(BOOT_TARGETS): vmlinux
        $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
 
 compressed: zImage
@@ -208,10 +219,14 @@ archclean:
        $(Q)$(MAKE) $(clean)=arch/sh/kernel/vsyscall
 
 define archhelp
-       @echo '* zImage                    - Compressed kernel image'
+       @echo '  zImage                    - Compressed kernel image'
+       @echo '  romImage                  - Compressed ROM image, if supported'
        @echo '  vmlinux.srec              - Create an ELF S-record'
-       @echo '  uImage                    - Create a bootable image for U-Boot'
-       @echo '  uImage.srec               - Create an S-record for U-Boot'
+       @echo '* uImage                    - Alias to bootable U-Boot image'
+       @echo '  uImage.srec               - Create an S-record for U-Boot'
+       @echo '* uImage.gz                 - Kernel-only image for U-Boot (gzip)'
+       @echo '  uImage.bz2                - Kernel-only image for U-Boot (bzip2)'
+       @echo '  uImage.lzma               - Kernel-only image for U-Boot (lzma)'
 endef
 
 CLEAN_FILES += include/asm-sh/machtypes.h
index 2b1af0eefa6ab9d693fbc68819f28a5ce777316c..db04c85971ad57e9b219c158cd7a644c0fcafd1c 100644 (file)
@@ -193,6 +193,13 @@ config SH_AP325RXA
          Renesas "AP-325RXA" support.
          Compatible with ALGO SYSTEM CO.,LTD. "AP-320A"
 
+config SH_KFR2R09
+       bool "KFR2R09"
+       depends on CPU_SUBTYPE_SH7724
+       select ARCH_REQUIRE_GPIOLIB
+       help
+         "Kit For R2R for 2009" support.
+
 config SH_SH7763RDP
        bool "SH7763RDP"
        depends on CPU_SUBTYPE_SH7763
index 1639f89150005d588ba96e32d481a78385950c9a..566e69d8d7291895b49b2a7276bec94ba09a19e0 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/irq.h>
 #include <linux/interrupt.h>
 #include <linux/usb/r8a66597.h>
+#include <linux/usb/m66592.h>
 #include <net/ax88796.h>
 #include <asm/machvec.h>
 #include <mach/highlander.h>
@@ -60,6 +61,11 @@ static struct platform_device r8a66597_usb_host_device = {
        .resource       = r8a66597_usb_host_resources,
 };
 
+static struct m66592_platdata usbf_platdata = {
+       .xtal = M66592_PLATDATA_XTAL_24MHZ,
+       .vif = 1,
+};
+
 static struct resource m66592_usb_peripheral_resources[] = {
        [0] = {
                .name   = "m66592_udc",
@@ -81,6 +87,7 @@ static struct platform_device m66592_usb_peripheral_device = {
        .dev = {
                .dma_mask               = NULL,         /* don't use dma */
                .coherent_dma_mask      = 0xffffffff,
+               .platform_data          = &usbf_platdata,
        },
        .num_resources  = ARRAY_SIZE(m66592_usb_peripheral_resources),
        .resource       = m66592_usb_peripheral_resources,
diff --git a/arch/sh/boards/mach-kfr2r09/Makefile b/arch/sh/boards/mach-kfr2r09/Makefile
new file mode 100644 (file)
index 0000000..5d58678
--- /dev/null
@@ -0,0 +1,2 @@
+obj-y   := setup.o
+obj-$(CONFIG_FB_SH_MOBILE_LCDC)        +=  lcd_wqvga.o
diff --git a/arch/sh/boards/mach-kfr2r09/lcd_wqvga.c b/arch/sh/boards/mach-kfr2r09/lcd_wqvga.c
new file mode 100644 (file)
index 0000000..8ccb1cc
--- /dev/null
@@ -0,0 +1,332 @@
+/*
+ * KFR2R09 LCD panel support
+ *
+ * Copyright (C) 2009 Magnus Damm
+ *
+ * Register settings based on the out-of-tree t33fb.c driver
+ * Copyright (C) 2008 Lineo Solutions, Inc.
+ *
+ * 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 for
+ * more details.
+ */
+
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/gpio.h>
+#include <video/sh_mobile_lcdc.h>
+#include <mach/kfr2r09.h>
+#include <cpu/sh7724.h>
+
+/* The on-board LCD module is a Hitachi TX07D34VM0AAA. This module is made
+ * up of a 240x400 LCD hooked up to a R61517 driver IC. The driver IC is
+ * communicating with the main port of the LCDC using an 18-bit SYS interface.
+ *
+ * The device code for this LCD module is 0x01221517.
+ */
+
+static const unsigned char data_frame_if[] = {
+       0x02, /* WEMODE: 1=cont, 0=one-shot */
+       0x00, 0x00,
+       0x00, /* EPF, DFM */
+       0x02, /* RIM[1] : 1 (18bpp) */
+};
+
+static const unsigned char data_panel[] = {
+       0x0b,
+       0x63, /* 400 lines */
+       0x04, 0x00, 0x00, 0x04, 0x11, 0x00, 0x00,
+};
+
+static const unsigned char data_timing[] = {
+       0x00, 0x00, 0x13, 0x08, 0x08,
+};
+
+static const unsigned char data_timing_src[] = {
+       0x11, 0x01, 0x00, 0x01,
+};
+
+static const unsigned char data_gamma[] = {
+       0x01, 0x02, 0x08, 0x23, 0x03, 0x0c, 0x00, 0x06, 0x00, 0x00,
+       0x01, 0x00, 0x0c, 0x23, 0x03, 0x08, 0x02, 0x06, 0x00, 0x00,
+};
+
+static const unsigned char data_power[] = {
+       0x07, 0xc5, 0xdc, 0x02, 0x33, 0x0a,
+};
+
+static unsigned long read_reg(void *sohandle,
+                             struct sh_mobile_lcdc_sys_bus_ops *so)
+{
+       return so->read_data(sohandle);
+}
+
+static void write_reg(void *sohandle,
+                     struct sh_mobile_lcdc_sys_bus_ops *so,
+                     int i, unsigned long v)
+{
+       if (i)
+               so->write_data(sohandle, v); /* PTH4/LCDRS High [param, 17:0] */
+       else
+               so->write_index(sohandle, v); /* PTH4/LCDRS Low [cmd, 7:0] */
+}
+
+static void write_data(void *sohandle,
+                      struct sh_mobile_lcdc_sys_bus_ops *so,
+                      unsigned char const *data, int no_data)
+{
+       int i;
+
+       for (i = 0; i < no_data; i++)
+               write_reg(sohandle, so, 1, data[i]);
+}
+
+static unsigned long read_device_code(void *sohandle,
+                                     struct sh_mobile_lcdc_sys_bus_ops *so)
+{
+       unsigned long device_code;
+
+       /* access protect OFF */
+       write_reg(sohandle, so, 0, 0xb0);
+       write_reg(sohandle, so, 1, 0x00);
+
+       /* deep standby OFF */
+       write_reg(sohandle, so, 0, 0xb1);
+       write_reg(sohandle, so, 1, 0x00);
+
+       /* device code command */
+       write_reg(sohandle, so, 0, 0xbf);
+       mdelay(50);
+
+       /* dummy read */
+       read_reg(sohandle, so);
+
+       /* read device code */
+       device_code = ((read_reg(sohandle, so) & 0xff) << 24);
+       device_code |= ((read_reg(sohandle, so) & 0xff) << 16);
+       device_code |= ((read_reg(sohandle, so) & 0xff) << 8);
+       device_code |= (read_reg(sohandle, so) & 0xff);
+
+       return device_code;
+}
+
+static void write_memory_start(void *sohandle,
+                              struct sh_mobile_lcdc_sys_bus_ops *so)
+{
+       write_reg(sohandle, so, 0, 0x2c);
+}
+
+static void clear_memory(void *sohandle,
+                        struct sh_mobile_lcdc_sys_bus_ops *so)
+{
+       int i;
+
+       /* write start */
+       write_memory_start(sohandle, so);
+
+       /* paint it black */
+       for (i = 0; i < (240 * 400); i++)
+               write_reg(sohandle, so, 1, 0x00);
+}
+
+static void display_on(void *sohandle,
+                      struct sh_mobile_lcdc_sys_bus_ops *so)
+{
+       /* access protect off */
+       write_reg(sohandle, so, 0, 0xb0);
+       write_reg(sohandle, so, 1, 0x00);
+
+       /* exit deep standby mode */
+       write_reg(sohandle, so, 0, 0xb1);
+       write_reg(sohandle, so, 1, 0x00);
+
+       /* frame memory I/F */
+       write_reg(sohandle, so, 0, 0xb3);
+       write_data(sohandle, so, data_frame_if, ARRAY_SIZE(data_frame_if));
+
+       /* display mode and frame memory write mode */
+       write_reg(sohandle, so, 0, 0xb4);
+       write_reg(sohandle, so, 1, 0x00); /* DBI, internal clock */
+
+       /* panel */
+       write_reg(sohandle, so, 0, 0xc0);
+       write_data(sohandle, so, data_panel, ARRAY_SIZE(data_panel));
+
+       /* timing (normal) */
+       write_reg(sohandle, so, 0, 0xc1);
+       write_data(sohandle, so, data_timing, ARRAY_SIZE(data_timing));
+
+       /* timing (partial) */
+       write_reg(sohandle, so, 0, 0xc2);
+       write_data(sohandle, so, data_timing, ARRAY_SIZE(data_timing));
+
+       /* timing (idle) */
+       write_reg(sohandle, so, 0, 0xc3);
+       write_data(sohandle, so, data_timing, ARRAY_SIZE(data_timing));
+
+       /* timing (source/VCOM/gate driving) */
+       write_reg(sohandle, so, 0, 0xc4);
+       write_data(sohandle, so, data_timing_src, ARRAY_SIZE(data_timing_src));
+
+       /* gamma (red) */
+       write_reg(sohandle, so, 0, 0xc8);
+       write_data(sohandle, so, data_gamma, ARRAY_SIZE(data_gamma));
+
+       /* gamma (green) */
+       write_reg(sohandle, so, 0, 0xc9);
+       write_data(sohandle, so, data_gamma, ARRAY_SIZE(data_gamma));
+
+       /* gamma (blue) */
+       write_reg(sohandle, so, 0, 0xca);
+       write_data(sohandle, so, data_gamma, ARRAY_SIZE(data_gamma));
+
+       /* power (common) */
+       write_reg(sohandle, so, 0, 0xd0);
+       write_data(sohandle, so, data_power, ARRAY_SIZE(data_power));
+
+       /* VCOM */
+       write_reg(sohandle, so, 0, 0xd1);
+       write_reg(sohandle, so, 1, 0x00);
+       write_reg(sohandle, so, 1, 0x0f);
+       write_reg(sohandle, so, 1, 0x02);
+
+       /* power (normal) */
+       write_reg(sohandle, so, 0, 0xd2);
+       write_reg(sohandle, so, 1, 0x63);
+       write_reg(sohandle, so, 1, 0x24);
+
+       /* power (partial) */
+       write_reg(sohandle, so, 0, 0xd3);
+       write_reg(sohandle, so, 1, 0x63);
+       write_reg(sohandle, so, 1, 0x24);
+
+       /* power (idle) */
+       write_reg(sohandle, so, 0, 0xd4);
+       write_reg(sohandle, so, 1, 0x63);
+       write_reg(sohandle, so, 1, 0x24);
+
+       write_reg(sohandle, so, 0, 0xd8);
+       write_reg(sohandle, so, 1, 0x77);
+       write_reg(sohandle, so, 1, 0x77);
+
+       /* TE signal */
+       write_reg(sohandle, so, 0, 0x35);
+       write_reg(sohandle, so, 1, 0x00);
+
+       /* TE signal line */
+       write_reg(sohandle, so, 0, 0x44);
+       write_reg(sohandle, so, 1, 0x00);
+       write_reg(sohandle, so, 1, 0x00);
+
+       /* column address */
+       write_reg(sohandle, so, 0, 0x2a);
+       write_reg(sohandle, so, 1, 0x00);
+       write_reg(sohandle, so, 1, 0x00);
+       write_reg(sohandle, so, 1, 0x00);
+       write_reg(sohandle, so, 1, 0xef);
+
+       /* page address */
+       write_reg(sohandle, so, 0, 0x2b);
+       write_reg(sohandle, so, 1, 0x00);
+       write_reg(sohandle, so, 1, 0x00);
+       write_reg(sohandle, so, 1, 0x01);
+       write_reg(sohandle, so, 1, 0x8f);
+
+       /* exit sleep mode */
+       write_reg(sohandle, so, 0, 0x11);
+
+       mdelay(120);
+
+       /* clear vram */
+       clear_memory(sohandle, so);
+
+       /* display ON */
+       write_reg(sohandle, so, 0, 0x29);
+       mdelay(1);
+
+       write_memory_start(sohandle, so);
+}
+
+int kfr2r09_lcd_setup(void *board_data, void *sohandle,
+                     struct sh_mobile_lcdc_sys_bus_ops *so)
+{
+       /* power on */
+       gpio_set_value(GPIO_PTF4, 0);  /* PROTECT/ -> L */
+       gpio_set_value(GPIO_PTE4, 0);  /* LCD_RST/ -> L */
+       gpio_set_value(GPIO_PTF4, 1);  /* PROTECT/ -> H */
+       udelay(1100);
+       gpio_set_value(GPIO_PTE4, 1);  /* LCD_RST/ -> H */
+       udelay(10);
+       gpio_set_value(GPIO_PTF4, 0);  /* PROTECT/ -> L */
+       mdelay(20);
+
+       if (read_device_code(sohandle, so) != 0x01221517)
+               return -ENODEV;
+
+       pr_info("KFR2R09 WQVGA LCD Module detected.\n");
+
+       display_on(sohandle, so);
+       return 0;
+}
+
+#define CTRL_CKSW       0x10
+#define CTRL_C10        0x20
+#define CTRL_CPSW       0x80
+#define MAIN_MLED4      0x40
+#define MAIN_MSW        0x80
+
+static int kfr2r09_lcd_backlight(int on)
+{
+       struct i2c_adapter *a;
+       struct i2c_msg msg;
+       unsigned char buf[2];
+       int ret;
+
+       a = i2c_get_adapter(0);
+       if (!a)
+               return -ENODEV;
+
+       buf[0] = 0x00;
+       if (on)
+               buf[1] = CTRL_CPSW | CTRL_C10 | CTRL_CKSW;
+       else
+               buf[1] = 0;
+
+       msg.addr = 0x75;
+       msg.buf = buf;
+       msg.len = 2;
+       msg.flags = 0;
+       ret = i2c_transfer(a, &msg, 1);
+       if (ret != 1)
+               return -ENODEV;
+
+       buf[0] = 0x01;
+       if (on)
+               buf[1] = MAIN_MSW | MAIN_MLED4 | 0x0c;
+       else
+               buf[1] = 0;
+
+       msg.addr = 0x75;
+       msg.buf = buf;
+       msg.len = 2;
+       msg.flags = 0;
+       ret = i2c_transfer(a, &msg, 1);
+       if (ret != 1)
+               return -ENODEV;
+
+       return 0;
+}
+
+void kfr2r09_lcd_on(void *board_data)
+{
+       kfr2r09_lcd_backlight(1);
+}
+
+void kfr2r09_lcd_off(void *board_data)
+{
+       kfr2r09_lcd_backlight(0);
+}
diff --git a/arch/sh/boards/mach-kfr2r09/setup.c b/arch/sh/boards/mach-kfr2r09/setup.c
new file mode 100644 (file)
index 0000000..bdb10c2
--- /dev/null
@@ -0,0 +1,270 @@
+/*
+ * KFR2R09 board support code
+ *
+ * Copyright (C) 2009 Magnus Damm
+ *
+ * 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
+ * for more details.
+ */
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/onenand.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/gpio.h>
+#include <linux/input.h>
+#include <video/sh_mobile_lcdc.h>
+#include <asm/clock.h>
+#include <asm/machvec.h>
+#include <asm/io.h>
+#include <asm/sh_keysc.h>
+#include <cpu/sh7724.h>
+#include <mach/kfr2r09.h>
+
+static struct mtd_partition kfr2r09_nor_flash_partitions[] =
+{
+       {
+               .name = "boot",
+               .offset = 0,
+               .size = (4 * 1024 * 1024),
+               .mask_flags = MTD_WRITEABLE,    /* Read-only */
+       },
+       {
+               .name = "other",
+               .offset = MTDPART_OFS_APPEND,
+               .size = MTDPART_SIZ_FULL,
+       },
+};
+
+static struct physmap_flash_data kfr2r09_nor_flash_data = {
+       .width          = 2,
+       .parts          = kfr2r09_nor_flash_partitions,
+       .nr_parts       = ARRAY_SIZE(kfr2r09_nor_flash_partitions),
+};
+
+static struct resource kfr2r09_nor_flash_resources[] = {
+       [0] = {
+               .name           = "NOR Flash",
+               .start          = 0x00000000,
+               .end            = 0x03ffffff,
+               .flags          = IORESOURCE_MEM,
+       }
+};
+
+static struct platform_device kfr2r09_nor_flash_device = {
+       .name           = "physmap-flash",
+       .resource       = kfr2r09_nor_flash_resources,
+       .num_resources  = ARRAY_SIZE(kfr2r09_nor_flash_resources),
+       .dev            = {
+               .platform_data = &kfr2r09_nor_flash_data,
+       },
+};
+
+static struct resource kfr2r09_nand_flash_resources[] = {
+       [0] = {
+               .name           = "NAND Flash",
+               .start          = 0x10000000,
+               .end            = 0x1001ffff,
+               .flags          = IORESOURCE_MEM,
+       }
+};
+
+static struct platform_device kfr2r09_nand_flash_device = {
+       .name           = "onenand-flash",
+       .resource       = kfr2r09_nand_flash_resources,
+       .num_resources  = ARRAY_SIZE(kfr2r09_nand_flash_resources),
+};
+
+static struct sh_keysc_info kfr2r09_sh_keysc_info = {
+       .mode = SH_KEYSC_MODE_1, /* KEYOUT0->4, KEYIN0->4 */
+       .scan_timing = 3,
+       .delay = 10,
+       .keycodes = {
+               KEY_PHONE, KEY_CLEAR, KEY_MAIL, KEY_WWW, KEY_ENTER,
+               KEY_1, KEY_2, KEY_3, 0, KEY_UP,
+               KEY_4, KEY_5, KEY_6, 0, KEY_LEFT,
+               KEY_7, KEY_8, KEY_9, KEY_PROG1, KEY_RIGHT,
+               KEY_S, KEY_0, KEY_P, KEY_PROG2, KEY_DOWN,
+               0, 0, 0, 0, 0
+       },
+};
+
+static struct resource kfr2r09_sh_keysc_resources[] = {
+       [0] = {
+               .name   = "KEYSC",
+               .start  = 0x044b0000,
+               .end    = 0x044b000f,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = 79,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device kfr2r09_sh_keysc_device = {
+       .name           = "sh_keysc",
+       .id             = 0, /* "keysc0" clock */
+       .num_resources  = ARRAY_SIZE(kfr2r09_sh_keysc_resources),
+       .resource       = kfr2r09_sh_keysc_resources,
+       .dev    = {
+               .platform_data  = &kfr2r09_sh_keysc_info,
+       },
+};
+
+static struct sh_mobile_lcdc_info kfr2r09_sh_lcdc_info = {
+       .clock_source = LCDC_CLK_BUS,
+       .ch[0] = {
+               .chan = LCDC_CHAN_MAINLCD,
+               .bpp = 16,
+               .interface_type = SYS18,
+               .clock_divider = 6,
+               .flags = LCDC_FLAGS_DWPOL,
+               .lcd_cfg = {
+                       .name = "TX07D34VM0AAA",
+                       .xres = 240,
+                       .yres = 400,
+                       .left_margin = 0,
+                       .right_margin = 16,
+                       .hsync_len = 8,
+                       .upper_margin = 0,
+                       .lower_margin = 1,
+                       .vsync_len = 1,
+                       .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+               },
+               .lcd_size_cfg = {
+                       .width = 35,
+                       .height = 58,
+               },
+               .board_cfg = {
+                       .setup_sys = kfr2r09_lcd_setup,
+                       .display_on = kfr2r09_lcd_on,
+                       .display_off = kfr2r09_lcd_off,
+               },
+               .sys_bus_cfg = {
+                       .ldmt2r = 0x07010904,
+                       .ldmt3r = 0x14012914,
+                       /* set 1s delay to encourage fsync() */
+                       .deferred_io_msec = 1000,
+               },
+       }
+};
+
+static struct resource kfr2r09_sh_lcdc_resources[] = {
+       [0] = {
+               .name   = "LCDC",
+               .start  = 0xfe940000, /* P4-only space */
+               .end    = 0xfe941fff,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = 106,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device kfr2r09_sh_lcdc_device = {
+       .name           = "sh_mobile_lcdc_fb",
+       .num_resources  = ARRAY_SIZE(kfr2r09_sh_lcdc_resources),
+       .resource       = kfr2r09_sh_lcdc_resources,
+       .dev    = {
+               .platform_data  = &kfr2r09_sh_lcdc_info,
+       },
+};
+
+static struct platform_device *kfr2r09_devices[] __initdata = {
+       &kfr2r09_nor_flash_device,
+       &kfr2r09_nand_flash_device,
+       &kfr2r09_sh_keysc_device,
+       &kfr2r09_sh_lcdc_device,
+};
+
+#define BSC_CS0BCR 0xfec10004
+#define BSC_CS0WCR 0xfec10024
+#define BSC_CS4BCR 0xfec10010
+#define BSC_CS4WCR 0xfec10030
+
+static int __init kfr2r09_devices_setup(void)
+{
+       /* enable SCIF1 serial port for YC401 console support */
+       gpio_request(GPIO_FN_SCIF1_RXD, NULL);
+       gpio_request(GPIO_FN_SCIF1_TXD, NULL);
+
+       /* setup NOR flash at CS0 */
+       ctrl_outl(0x36db0400, BSC_CS0BCR);
+       ctrl_outl(0x00000500, BSC_CS0WCR);
+
+       /* setup NAND flash at CS4 */
+       ctrl_outl(0x36db0400, BSC_CS4BCR);
+       ctrl_outl(0x00000500, BSC_CS4WCR);
+
+       /* setup KEYSC pins */
+       gpio_request(GPIO_FN_KEYOUT0, NULL);
+       gpio_request(GPIO_FN_KEYOUT1, NULL);
+       gpio_request(GPIO_FN_KEYOUT2, NULL);
+       gpio_request(GPIO_FN_KEYOUT3, NULL);
+       gpio_request(GPIO_FN_KEYOUT4_IN6, NULL);
+       gpio_request(GPIO_FN_KEYIN0, NULL);
+       gpio_request(GPIO_FN_KEYIN1, NULL);
+       gpio_request(GPIO_FN_KEYIN2, NULL);
+       gpio_request(GPIO_FN_KEYIN3, NULL);
+       gpio_request(GPIO_FN_KEYIN4, NULL);
+       gpio_request(GPIO_FN_KEYOUT5_IN5, NULL);
+
+       /* setup LCDC pins for SYS panel */
+       gpio_request(GPIO_FN_LCDD17, NULL);
+       gpio_request(GPIO_FN_LCDD16, NULL);
+       gpio_request(GPIO_FN_LCDD15, NULL);
+       gpio_request(GPIO_FN_LCDD14, NULL);
+       gpio_request(GPIO_FN_LCDD13, NULL);
+       gpio_request(GPIO_FN_LCDD12, NULL);
+       gpio_request(GPIO_FN_LCDD11, NULL);
+       gpio_request(GPIO_FN_LCDD10, NULL);
+       gpio_request(GPIO_FN_LCDD9, NULL);
+       gpio_request(GPIO_FN_LCDD8, NULL);
+       gpio_request(GPIO_FN_LCDD7, NULL);
+       gpio_request(GPIO_FN_LCDD6, NULL);
+       gpio_request(GPIO_FN_LCDD5, NULL);
+       gpio_request(GPIO_FN_LCDD4, NULL);
+       gpio_request(GPIO_FN_LCDD3, NULL);
+       gpio_request(GPIO_FN_LCDD2, NULL);
+       gpio_request(GPIO_FN_LCDD1, NULL);
+       gpio_request(GPIO_FN_LCDD0, NULL);
+       gpio_request(GPIO_FN_LCDRS, NULL); /* LCD_RS */
+       gpio_request(GPIO_FN_LCDCS, NULL); /* LCD_CS/ */
+       gpio_request(GPIO_FN_LCDRD, NULL); /* LCD_RD/ */
+       gpio_request(GPIO_FN_LCDWR, NULL); /* LCD_WR/ */
+       gpio_request(GPIO_FN_LCDVSYN, NULL); /* LCD_VSYNC */
+       gpio_request(GPIO_PTE4, NULL); /* LCD_RST/ */
+       gpio_direction_output(GPIO_PTE4, 1);
+       gpio_request(GPIO_PTF4, NULL); /* PROTECT/ */
+       gpio_direction_output(GPIO_PTF4, 1);
+       gpio_request(GPIO_PTU0, NULL); /* LEDSTDBY/ */
+       gpio_direction_output(GPIO_PTU0, 1);
+
+       return platform_add_devices(kfr2r09_devices,
+                                   ARRAY_SIZE(kfr2r09_devices));
+}
+device_initcall(kfr2r09_devices_setup);
+
+/* Return the board specific boot mode pin configuration */
+static int kfr2r09_mode_pins(void)
+{
+       /* MD0=1, MD1=1, MD2=0: Clock Mode 3
+        * MD3=0: 16-bit Area0 Bus Width
+        * MD5=1: Little Endian
+        * MD8=1: Test Mode Disabled
+        */
+       return MODE_PIN0 | MODE_PIN1 | MODE_PIN5 | MODE_PIN8;
+}
+
+/*
+ * The Machine Vector
+ */
+static struct sh_machine_vector mv_kfr2r09 __initmv = {
+       .mv_name                = "kfr2r09",
+       .mv_mode_pins           = kfr2r09_mode_pins,
+};
index 15456a0773bfc598e3e49f97292861cd50eb9c63..9162081504ef43ccf61e61d2765a08710b8fbd8f 100644 (file)
  * SW41 : abxx xxxx  -> a = 0 : Analog  monitor
  *                          1 : Digital monitor
  *                      b = 0 : VGA
- *                          1 : SVGA
+ *                          1 : 720p
+ */
+
+/*
+ * about 720p
+ *
+ * When you use 1280 x 720 lcdc output,
+ * you should change OSC6 lcdc clock from 25.175MHz to 74.25MHz,
+ * and change SW41 to use 720p
  */
 
 /* Heartbeat */
@@ -305,6 +313,7 @@ static struct platform_device sh_eth_device = {
 };
 
 static struct r8a66597_platdata sh7724_usb0_host_data = {
+       .on_chip = 1,
 };
 
 static struct resource sh7724_usb0_host_resources[] = {
@@ -421,6 +430,32 @@ static int __init devices_setup(void)
        /* turn on USB clocks, use external clock */
        ctrl_outw((ctrl_inw(PORT_MSELCRB) & ~0xc000) | 0x8000, PORT_MSELCRB);
 
+#ifdef CONFIG_PM
+       /* Let LED9 show STATUS2 */
+       gpio_request(GPIO_FN_STATUS2, NULL);
+
+       /* Lit LED10 show STATUS0 */
+       gpio_request(GPIO_FN_STATUS0, NULL);
+
+       /* Lit LED11 show PDSTATUS */
+       gpio_request(GPIO_FN_PDSTATUS, NULL);
+#else
+       /* Lit LED9 */
+       gpio_request(GPIO_PTJ6, NULL);
+       gpio_direction_output(GPIO_PTJ6, 1);
+       gpio_export(GPIO_PTJ6, 0);
+
+       /* Lit LED10 */
+       gpio_request(GPIO_PTJ5, NULL);
+       gpio_direction_output(GPIO_PTJ5, 1);
+       gpio_export(GPIO_PTJ5, 0);
+
+       /* Lit LED11 */
+       gpio_request(GPIO_PTJ7, NULL);
+       gpio_direction_output(GPIO_PTJ7, 1);
+       gpio_export(GPIO_PTJ7, 0);
+#endif
+
        /* enable USB0 port */
        ctrl_outw(0x0600, 0xa40501d4);
 
@@ -546,15 +581,15 @@ static int __init devices_setup(void)
        sh_eth_init();
 
        if (sw & SW41_B) {
-               /* SVGA */
-               lcdc_info.ch[0].lcd_cfg.xres         = 800;
-               lcdc_info.ch[0].lcd_cfg.yres         = 600;
-               lcdc_info.ch[0].lcd_cfg.left_margin  = 142;
-               lcdc_info.ch[0].lcd_cfg.right_margin = 52;
-               lcdc_info.ch[0].lcd_cfg.hsync_len    = 96;
-               lcdc_info.ch[0].lcd_cfg.upper_margin = 24;
-               lcdc_info.ch[0].lcd_cfg.lower_margin = 2;
-               lcdc_info.ch[0].lcd_cfg.vsync_len    = 2;
+               /* 720p */
+               lcdc_info.ch[0].lcd_cfg.xres         = 1280;
+               lcdc_info.ch[0].lcd_cfg.yres         = 720;
+               lcdc_info.ch[0].lcd_cfg.left_margin  = 220;
+               lcdc_info.ch[0].lcd_cfg.right_margin = 110;
+               lcdc_info.ch[0].lcd_cfg.hsync_len    = 40;
+               lcdc_info.ch[0].lcd_cfg.upper_margin = 20;
+               lcdc_info.ch[0].lcd_cfg.lower_margin = 5;
+               lcdc_info.ch[0].lcd_cfg.vsync_len    = 5;
        } else {
                /* VGA */
                lcdc_info.ch[0].lcd_cfg.xres         = 640;
index 8913ae39a8025db3f789ccf2e75bd2094730d19e..efe4cb9f8a77d27edc8fe632b25aafd2acb19e1f 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/irq.h>
 #include <linux/interrupt.h>
 #include <linux/usb/r8a66597.h>
+#include <linux/usb/m66592.h>
 #include <asm/ilsel.h>
 
 static struct resource heartbeat_resources[] = {
@@ -89,6 +90,11 @@ static struct platform_device r8a66597_usb_host_device = {
        .resource       = r8a66597_usb_host_resources,
 };
 
+static struct m66592_platdata usbf_platdata = {
+       .xtal = M66592_PLATDATA_XTAL_24MHZ,
+       .vif = 1,
+};
+
 static struct resource m66592_usb_peripheral_resources[] = {
        [0] = {
                .name   = "m66592_udc",
@@ -109,6 +115,7 @@ static struct platform_device m66592_usb_peripheral_device = {
        .dev = {
                .dma_mask               = NULL,         /* don't use dma */
                .coherent_dma_mask      = 0xffffffff,
+               .platform_data          = &usbf_platdata,
        },
        .num_resources  = ARRAY_SIZE(m66592_usb_peripheral_resources),
        .resource       = m66592_usb_peripheral_resources,
index aad5edddf93baf232cafbb216172a5e712a4fe31..541087d2029c8e859768677aa2f88e4706c466ad 100644 (file)
@@ -1,4 +1,3 @@
 zImage
-vmlinux.srec
-uImage
-uImage.srec
+vmlinux*
+uImage*
index 78efb04c28f3dfb2362e6610318491a99e08ce54..a1316872be6fc67e7148476151ca1f22ba280450 100644 (file)
@@ -20,8 +20,13 @@ CONFIG_BOOT_LINK_OFFSET      ?= 0x00800000
 CONFIG_ZERO_PAGE_OFFSET        ?= 0x00001000
 CONFIG_ENTRY_OFFSET    ?= 0x00001000
 
-targets := zImage vmlinux.srec uImage uImage.srec
-subdir- := compressed
+suffix-$(CONFIG_KERNEL_GZIP)  := gz
+suffix-$(CONFIG_KERNEL_BZIP2) := bz2
+suffix-$(CONFIG_KERNEL_LZMA)  := lzma
+
+targets := zImage vmlinux.srec romImage uImage uImage.srec uImage.gz uImage.bz2 uImage.lzma
+extra-y += vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma
+subdir- := compressed romimage
 
 $(obj)/zImage: $(obj)/compressed/vmlinux FORCE
        $(call if_changed,objcopy)
@@ -30,6 +35,13 @@ $(obj)/zImage: $(obj)/compressed/vmlinux FORCE
 $(obj)/compressed/vmlinux: FORCE
        $(Q)$(MAKE) $(build)=$(obj)/compressed $@
 
+$(obj)/romImage: $(obj)/romimage/vmlinux FORCE
+       $(call if_changed,objcopy)
+       @echo '  Kernel: $@ is ready'
+
+$(obj)/romimage/vmlinux: $(obj)/zImage FORCE
+       $(Q)$(MAKE) $(build)=$(obj)/romimage $@
+
 KERNEL_MEMORY := 0x00000000
 ifeq ($(CONFIG_PMB_FIXED),y)
 KERNEL_MEMORY := $(shell /bin/bash -c 'printf "0x%08x" \
@@ -40,9 +52,6 @@ KERNEL_MEMORY := $(shell /bin/bash -c 'printf "0x%08x" \
                     $$[$(CONFIG_MEMORY_START)]')
 endif
 
-export CONFIG_PAGE_OFFSET CONFIG_MEMORY_START CONFIG_BOOT_LINK_OFFSET \
-       CONFIG_ZERO_PAGE_OFFSET CONFIG_ENTRY_OFFSET KERNEL_MEMORY
-
 KERNEL_LOAD    := $(shell /bin/bash -c 'printf "0x%08x" \
                     $$[$(CONFIG_PAGE_OFFSET)  + \
                        $(KERNEL_MEMORY) + \
@@ -55,19 +64,30 @@ KERNEL_ENTRY        := $(shell /bin/bash -c 'printf "0x%08x" \
 
 quiet_cmd_uimage = UIMAGE  $@
       cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A sh -O linux -T kernel \
-                  -C gzip -a $(KERNEL_LOAD) -e $(KERNEL_ENTRY) \
+                  -C $(2) -a $(KERNEL_LOAD) -e $(KERNEL_ENTRY) \
                   -n 'Linux-$(KERNELRELEASE)' -d $< $@
 
-$(obj)/uImage: $(obj)/vmlinux.bin.gz FORCE
-       $(call if_changed,uimage)
-       @echo '  Image $@ is ready'
-
 $(obj)/vmlinux.bin: vmlinux FORCE
        $(call if_changed,objcopy)
 
 $(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE
        $(call if_changed,gzip)
 
+$(obj)/vmlinux.bin.bz2: $(obj)/vmlinux.bin FORCE
+       $(call if_changed,bzip2)
+
+$(obj)/vmlinux.bin.lzma: $(obj)/vmlinux.bin FORCE
+       $(call if_changed,lzma)
+
+$(obj)/uImage.bz2: $(obj)/vmlinux.bin.bz2
+       $(call if_changed,uimage,bzip2)
+
+$(obj)/uImage.gz: $(obj)/vmlinux.bin.gz
+       $(call if_changed,uimage,gzip)
+
+$(obj)/uImage.lzma: $(obj)/vmlinux.bin.lzma
+       $(call if_changed,uimage,lzma)
+
 OBJCOPYFLAGS_vmlinux.srec := -I binary -O srec
 $(obj)/vmlinux.srec: $(obj)/compressed/vmlinux
        $(call if_changed,objcopy)
@@ -76,5 +96,9 @@ OBJCOPYFLAGS_uImage.srec := -I binary -O srec
 $(obj)/uImage.srec: $(obj)/uImage
        $(call if_changed,objcopy)
 
-clean-files    += uImage uImage.srec vmlinux.srec \
-                  vmlinux.bin vmlinux.bin.gz
+$(obj)/uImage: $(obj)/uImage.$(suffix-y)
+       @ln -sf $(notdir $<) $@
+       @echo '  Image $@ is ready'
+
+export CONFIG_PAGE_OFFSET CONFIG_MEMORY_START CONFIG_BOOT_LINK_OFFSET \
+       CONFIG_ZERO_PAGE_OFFSET CONFIG_ENTRY_OFFSET KERNEL_MEMORY suffix-y
diff --git a/arch/sh/boot/compressed/.gitignore b/arch/sh/boot/compressed/.gitignore
new file mode 100644 (file)
index 0000000..2374a83
--- /dev/null
@@ -0,0 +1 @@
+vmlinux.bin.*
index 9531bf1b7c2f878b632f154f5e9a4bd06717758b..6182eca5180ac53390acc88f527c035a228ed027 100644 (file)
@@ -5,9 +5,10 @@
 #
 
 targets                := vmlinux vmlinux.bin vmlinux.bin.gz \
-                  head_$(BITS).o misc_$(BITS).o piggy.o
+                  vmlinux.bin.bz2 vmlinux.bin.lzma \
+                  head_$(BITS).o misc.o piggy.o
 
-OBJECTS = $(obj)/head_$(BITS).o $(obj)/misc_$(BITS).o $(obj)/cache.o
+OBJECTS = $(obj)/head_$(BITS).o $(obj)/misc.o $(obj)/cache.o
 
 ifdef CONFIG_SH_STANDARD_BIOS
 OBJECTS += $(obj)/../../kernel/sh_bios.o
@@ -23,7 +24,7 @@ IMAGE_OFFSET  := $(shell /bin/bash -c 'printf "0x%08x" \
 
 LIBGCC := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name)
 
-ifeq ($(CONFIG_FUNCTION_TRACER),y)
+ifeq ($(CONFIG_MCOUNT),y)
 ORIG_CFLAGS := $(KBUILD_CFLAGS)
 KBUILD_CFLAGS = $(subst -pg, , $(ORIG_CFLAGS))
 endif
@@ -38,10 +39,18 @@ $(obj)/vmlinux: $(OBJECTS) $(obj)/piggy.o $(LIBGCC) FORCE
 $(obj)/vmlinux.bin: vmlinux FORCE
        $(call if_changed,objcopy)
 
-$(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE
+vmlinux.bin.all-y := $(obj)/vmlinux.bin
+
+$(obj)/vmlinux.bin.gz: $(vmlinux.bin.all-y) FORCE
        $(call if_changed,gzip)
+$(obj)/vmlinux.bin.bz2: $(vmlinux.bin.all-y) FORCE
+       $(call if_changed,bzip2)
+$(obj)/vmlinux.bin.lzma: $(vmlinux.bin.all-y) FORCE
+       $(call if_changed,lzma)
 
 OBJCOPYFLAGS += -R .empty_zero_page
 
-$(obj)/piggy.o: $(obj)/piggy.S $(obj)/vmlinux.bin.gz FORCE
-       $(call if_changed,as_o_S)
+LDFLAGS_piggy.o := -r --format binary --oformat $(ld-bfd) -T
+
+$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.$(suffix-y) FORCE
+       $(call if_changed,ld)
diff --git a/arch/sh/boot/compressed/misc.c b/arch/sh/boot/compressed/misc.c
new file mode 100644 (file)
index 0000000..fd56a71
--- /dev/null
@@ -0,0 +1,149 @@
+/*
+ * arch/sh/boot/compressed/misc.c
+ *
+ * This is a collection of several routines from gzip-1.0.3
+ * adapted for Linux.
+ *
+ * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
+ *
+ * Adapted for SH by Stuart Menefy, Aug 1999
+ *
+ * Modified to use standard LinuxSH BIOS by Greg Banks 7Jul2000
+ */
+
+#include <asm/uaccess.h>
+#include <asm/addrspace.h>
+#include <asm/page.h>
+#include <asm/sh_bios.h>
+
+/*
+ * gzip declarations
+ */
+
+#define STATIC static
+
+#undef memset
+#undef memcpy
+#define memzero(s, n)     memset ((s), 0, (n))
+
+/* cache.c */
+#define CACHE_ENABLE      0
+#define CACHE_DISABLE     1
+int cache_control(unsigned int command);
+
+extern char input_data[];
+extern int input_len;
+static unsigned char *output;
+
+static void error(char *m);
+
+int puts(const char *);
+
+extern int _text;              /* Defined in vmlinux.lds.S */
+extern int _end;
+static unsigned long free_mem_ptr;
+static unsigned long free_mem_end_ptr;
+
+#ifdef CONFIG_HAVE_KERNEL_BZIP2
+#define HEAP_SIZE      0x400000
+#else
+#define HEAP_SIZE      0x10000
+#endif
+
+#ifdef CONFIG_KERNEL_GZIP
+#include "../../../../lib/decompress_inflate.c"
+#endif
+
+#ifdef CONFIG_KERNEL_BZIP2
+#include "../../../../lib/decompress_bunzip2.c"
+#endif
+
+#ifdef CONFIG_KERNEL_LZMA
+#include "../../../../lib/decompress_unlzma.c"
+#endif
+
+#ifdef CONFIG_SH_STANDARD_BIOS
+size_t strlen(const char *s)
+{
+       int i = 0;
+
+       while (*s++)
+               i++;
+       return i;
+}
+
+int puts(const char *s)
+{
+       int len = strlen(s);
+       sh_bios_console_write(s, len);
+       return len;
+}
+#else
+int puts(const char *s)
+{
+       /* This should be updated to use the sh-sci routines */
+       return 0;
+}
+#endif
+
+void* memset(void* s, int c, size_t n)
+{
+       int i;
+       char *ss = (char*)s;
+
+       for (i=0;i<n;i++) ss[i] = c;
+       return s;
+}
+
+void* memcpy(void* __dest, __const void* __src,
+                           size_t __n)
+{
+       int i;
+       char *d = (char *)__dest, *s = (char *)__src;
+
+       for (i=0;i<__n;i++) d[i] = s[i];
+       return __dest;
+}
+
+static void error(char *x)
+{
+       puts("\n\n");
+       puts(x);
+       puts("\n\n -- System halted");
+
+       while(1);       /* Halt */
+}
+
+#ifdef CONFIG_SUPERH64
+#define stackalign     8
+#else
+#define stackalign     4
+#endif
+
+#define STACK_SIZE (4096)
+long __attribute__ ((aligned(stackalign))) user_stack[STACK_SIZE];
+long *stack_start = &user_stack[STACK_SIZE];
+
+void decompress_kernel(void)
+{
+       unsigned long output_addr;
+
+#ifdef CONFIG_SUPERH64
+       output_addr = (CONFIG_MEMORY_START + 0x2000);
+#else
+       output_addr = PHYSADDR((unsigned long)&_text+PAGE_SIZE);
+#ifdef CONFIG_29BIT
+       output_addr |= P2SEG;
+#endif
+#endif
+
+       output = (unsigned char *)output_addr;
+       free_mem_ptr = (unsigned long)&_end;
+       free_mem_end_ptr = free_mem_ptr + HEAP_SIZE;
+
+       puts("Uncompressing Linux... ");
+       cache_control(CACHE_ENABLE);
+       decompress(input_data, input_len, NULL, NULL, output, NULL, error);
+       cache_control(CACHE_DISABLE);
+       puts("Ok, booting the kernel.\n");
+}
diff --git a/arch/sh/boot/compressed/misc_32.c b/arch/sh/boot/compressed/misc_32.c
deleted file mode 100644 (file)
index efdba6b..0000000
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * arch/sh/boot/compressed/misc.c
- *
- * This is a collection of several routines from gzip-1.0.3
- * adapted for Linux.
- *
- * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
- *
- * Adapted for SH by Stuart Menefy, Aug 1999
- *
- * Modified to use standard LinuxSH BIOS by Greg Banks 7Jul2000
- */
-
-#include <asm/uaccess.h>
-#include <asm/addrspace.h>
-#include <asm/page.h>
-#ifdef CONFIG_SH_STANDARD_BIOS
-#include <asm/sh_bios.h>
-#endif
-
-/*
- * gzip declarations
- */
-
-#define OF(args)  args
-#define STATIC static
-
-#undef memset
-#undef memcpy
-#define memzero(s, n)     memset ((s), 0, (n))
-
-typedef unsigned char  uch;
-typedef unsigned short ush;
-typedef unsigned long  ulg;
-
-#define WSIZE 0x8000           /* Window size must be at least 32k, */
-                               /* and a power of two */
-
-static uch *inbuf;          /* input buffer */
-static uch window[WSIZE];    /* Sliding window buffer */
-
-static unsigned insize = 0;  /* valid bytes in inbuf */
-static unsigned inptr = 0;   /* index of next byte to be processed in inbuf */
-static unsigned outcnt = 0;  /* bytes in output buffer */
-
-/* gzip flag byte */
-#define ASCII_FLAG   0x01 /* bit 0 set: file probably ASCII text */
-#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */
-#define EXTRA_FIELD  0x04 /* bit 2 set: extra field present */
-#define ORIG_NAME    0x08 /* bit 3 set: original file name present */
-#define COMMENT      0x10 /* bit 4 set: file comment present */
-#define ENCRYPTED    0x20 /* bit 5 set: file is encrypted */
-#define RESERVED     0xC0 /* bit 6,7:   reserved */
-
-#define get_byte()  (inptr < insize ? inbuf[inptr++] : fill_inbuf())
-
-/* Diagnostic functions */
-#ifdef DEBUG
-#  define Assert(cond,msg) {if(!(cond)) error(msg);}
-#  define Trace(x) fprintf x
-#  define Tracev(x) {if (verbose) fprintf x ;}
-#  define Tracevv(x) {if (verbose>1) fprintf x ;}
-#  define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
-#  define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
-#else
-#  define Assert(cond,msg)
-#  define Trace(x)
-#  define Tracev(x)
-#  define Tracevv(x)
-#  define Tracec(c,x)
-#  define Tracecv(c,x)
-#endif
-
-static int  fill_inbuf(void);
-static void flush_window(void);
-static void error(char *m);
-
-extern char input_data[];
-extern int input_len;
-
-static long bytes_out = 0;
-static uch *output_data;
-static unsigned long output_ptr = 0;
-
-static void error(char *m);
-
-int puts(const char *);
-
-extern int _text;              /* Defined in vmlinux.lds.S */
-extern int _end;
-static unsigned long free_mem_ptr;
-static unsigned long free_mem_end_ptr;
-
-#define HEAP_SIZE             0x10000
-
-#include "../../../../lib/inflate.c"
-
-#ifdef CONFIG_SH_STANDARD_BIOS
-size_t strlen(const char *s)
-{
-       int i = 0;
-
-       while (*s++)
-               i++;
-       return i;
-}
-
-int puts(const char *s)
-{
-       int len = strlen(s);
-       sh_bios_console_write(s, len);
-       return len;
-}
-#else
-int puts(const char *s)
-{
-       /* This should be updated to use the sh-sci routines */
-       return 0;
-}
-#endif
-
-void* memset(void* s, int c, size_t n)
-{
-       int i;
-       char *ss = (char*)s;
-
-       for (i=0;i<n;i++) ss[i] = c;
-       return s;
-}
-
-void* memcpy(void* __dest, __const void* __src,
-                           size_t __n)
-{
-       int i;
-       char *d = (char *)__dest, *s = (char *)__src;
-
-       for (i=0;i<__n;i++) d[i] = s[i];
-       return __dest;
-}
-
-/* ===========================================================================
- * Fill the input buffer. This is called only when the buffer is empty
- * and at least one byte is really needed.
- */
-static int fill_inbuf(void)
-{
-       if (insize != 0) {
-               error("ran out of input data");
-       }
-
-       inbuf = input_data;
-       insize = input_len;
-       inptr = 1;
-       return inbuf[0];
-}
-
-/* ===========================================================================
- * Write the output window window[0..outcnt-1] and update crc and bytes_out.
- * (Used for the decompressed data only.)
- */
-static void flush_window(void)
-{
-    ulg c = crc;         /* temporary variable */
-    unsigned n;
-    uch *in, *out, ch;
-
-    in = window;
-    out = &output_data[output_ptr];
-    for (n = 0; n < outcnt; n++) {
-           ch = *out++ = *in++;
-           c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
-    }
-    crc = c;
-    bytes_out += (ulg)outcnt;
-    output_ptr += (ulg)outcnt;
-    outcnt = 0;
-}
-
-static void error(char *x)
-{
-       puts("\n\n");
-       puts(x);
-       puts("\n\n -- System halted");
-
-       while(1);       /* Halt */
-}
-
-#define STACK_SIZE (4096)
-long user_stack [STACK_SIZE];
-long* stack_start = &user_stack[STACK_SIZE];
-
-void decompress_kernel(void)
-{
-       output_data = NULL;
-       output_ptr = PHYSADDR((unsigned long)&_text+PAGE_SIZE);
-#ifdef CONFIG_29BIT
-       output_ptr |= P2SEG;
-#endif
-       free_mem_ptr = (unsigned long)&_end;
-       free_mem_end_ptr = free_mem_ptr + HEAP_SIZE;
-
-       makecrc();
-       puts("Uncompressing Linux... ");
-       gunzip();
-       puts("Ok, booting the kernel.\n");
-}
diff --git a/arch/sh/boot/compressed/misc_64.c b/arch/sh/boot/compressed/misc_64.c
deleted file mode 100644 (file)
index 2941657..0000000
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- * arch/sh/boot/compressed/misc_64.c
- *
- * This is a collection of several routines from gzip-1.0.3
- * adapted for Linux.
- *
- * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
- *
- * Adapted for SHmedia from sh by Stuart Menefy, May 2002
- */
-
-#include <asm/uaccess.h>
-
-/* cache.c */
-#define CACHE_ENABLE      0
-#define CACHE_DISABLE     1
-int cache_control(unsigned int command);
-
-/*
- * gzip declarations
- */
-
-#define OF(args)  args
-#define STATIC static
-
-#undef memset
-#undef memcpy
-#define memzero(s, n)     memset ((s), 0, (n))
-
-typedef unsigned char uch;
-typedef unsigned short ush;
-typedef unsigned long ulg;
-
-#define WSIZE 0x8000           /* Window size must be at least 32k, */
-                               /* and a power of two */
-
-static uch *inbuf;             /* input buffer */
-static uch window[WSIZE];      /* Sliding window buffer */
-
-static unsigned insize = 0;    /* valid bytes in inbuf */
-static unsigned inptr = 0;     /* index of next byte to be processed in inbuf */
-static unsigned outcnt = 0;    /* bytes in output buffer */
-
-/* gzip flag byte */
-#define ASCII_FLAG   0x01      /* bit 0 set: file probably ASCII text */
-#define CONTINUATION 0x02      /* bit 1 set: continuation of multi-part gzip file */
-#define EXTRA_FIELD  0x04      /* bit 2 set: extra field present */
-#define ORIG_NAME    0x08      /* bit 3 set: original file name present */
-#define COMMENT      0x10      /* bit 4 set: file comment present */
-#define ENCRYPTED    0x20      /* bit 5 set: file is encrypted */
-#define RESERVED     0xC0      /* bit 6,7:   reserved */
-
-#define get_byte()  (inptr < insize ? inbuf[inptr++] : fill_inbuf())
-
-/* Diagnostic functions */
-#ifdef DEBUG
-#  define Assert(cond,msg) {if(!(cond)) error(msg);}
-#  define Trace(x) fprintf x
-#  define Tracev(x) {if (verbose) fprintf x ;}
-#  define Tracevv(x) {if (verbose>1) fprintf x ;}
-#  define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
-#  define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
-#else
-#  define Assert(cond,msg)
-#  define Trace(x)
-#  define Tracev(x)
-#  define Tracevv(x)
-#  define Tracec(c,x)
-#  define Tracecv(c,x)
-#endif
-
-static int fill_inbuf(void);
-static void flush_window(void);
-static void error(char *m);
-
-extern char input_data[];
-extern int input_len;
-
-static long bytes_out = 0;
-static uch *output_data;
-static unsigned long output_ptr = 0;
-
-static void error(char *m);
-
-static void puts(const char *);
-
-extern int _text;              /* Defined in vmlinux.lds.S */
-extern int _end;
-static unsigned long free_mem_ptr;
-static unsigned long free_mem_end_ptr;
-
-#define HEAP_SIZE             0x10000
-
-#include "../../../../lib/inflate.c"
-
-void puts(const char *s)
-{
-}
-
-void *memset(void *s, int c, size_t n)
-{
-       int i;
-       char *ss = (char *) s;
-
-       for (i = 0; i < n; i++)
-               ss[i] = c;
-       return s;
-}
-
-void *memcpy(void *__dest, __const void *__src, size_t __n)
-{
-       int i;
-       char *d = (char *) __dest, *s = (char *) __src;
-
-       for (i = 0; i < __n; i++)
-               d[i] = s[i];
-       return __dest;
-}
-
-/* ===========================================================================
- * Fill the input buffer. This is called only when the buffer is empty
- * and at least one byte is really needed.
- */
-static int fill_inbuf(void)
-{
-       if (insize != 0) {
-               error("ran out of input data\n");
-       }
-
-       inbuf = input_data;
-       insize = input_len;
-       inptr = 1;
-       return inbuf[0];
-}
-
-/* ===========================================================================
- * Write the output window window[0..outcnt-1] and update crc and bytes_out.
- * (Used for the decompressed data only.)
- */
-static void flush_window(void)
-{
-       ulg c = crc;            /* temporary variable */
-       unsigned n;
-       uch *in, *out, ch;
-
-       in = window;
-       out = &output_data[output_ptr];
-       for (n = 0; n < outcnt; n++) {
-               ch = *out++ = *in++;
-               c = crc_32_tab[((int) c ^ ch) & 0xff] ^ (c >> 8);
-       }
-       crc = c;
-       bytes_out += (ulg) outcnt;
-       output_ptr += (ulg) outcnt;
-       outcnt = 0;
-       puts(".");
-}
-
-static void error(char *x)
-{
-       puts("\n\n");
-       puts(x);
-       puts("\n\n -- System halted");
-
-       while (1) ;             /* Halt */
-}
-
-#define STACK_SIZE (4096)
-long __attribute__ ((aligned(8))) user_stack[STACK_SIZE];
-long *stack_start = &user_stack[STACK_SIZE];
-
-void decompress_kernel(void)
-{
-       output_data = (uch *) (CONFIG_MEMORY_START + 0x2000);
-       free_mem_ptr = (unsigned long) &_end;
-       free_mem_end_ptr = free_mem_ptr + HEAP_SIZE;
-
-       makecrc();
-       puts("Uncompressing Linux... ");
-       cache_control(CACHE_ENABLE);
-       gunzip();
-       puts("\n");
-
-#if 0
-       /* When booting from ROM may want to do something like this if the
-        * boot loader doesn't.
-        */
-
-       /* Set up the parameters and command line */
-       {
-               volatile unsigned int *parambase =
-                   (int *) (CONFIG_MEMORY_START + 0x1000);
-
-               parambase[0] = 0x1;     /* MOUNT_ROOT_RDONLY */
-               parambase[1] = 0x0;     /* RAMDISK_FLAGS */
-               parambase[2] = 0x0200;  /* ORIG_ROOT_DEV */
-               parambase[3] = 0x0;     /* LOADER_TYPE */
-               parambase[4] = 0x0;     /* INITRD_START */
-               parambase[5] = 0x0;     /* INITRD_SIZE */
-               parambase[6] = 0;
-
-               strcpy((char *) ((int) parambase + 0x100),
-                      "console=ttySC0,38400");
-       }
-#endif
-
-       puts("Ok, booting the kernel.\n");
-
-       cache_control(CACHE_DISABLE);
-}
diff --git a/arch/sh/boot/compressed/piggy.S b/arch/sh/boot/compressed/piggy.S
deleted file mode 100644 (file)
index 5660719..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-       .global input_len, input_data
-       .data
-input_len:
-       .long   input_data_end - input_data
-input_data:
-       .incbin "arch/sh/boot/compressed/vmlinux.bin.gz"
-input_data_end:
-       .end
diff --git a/arch/sh/boot/compressed/vmlinux.scr b/arch/sh/boot/compressed/vmlinux.scr
new file mode 100644 (file)
index 0000000..f02382a
--- /dev/null
@@ -0,0 +1,10 @@
+SECTIONS
+{
+  .rodata.compressed : {
+       input_len = .;
+       LONG(input_data_end - input_data) input_data = .;
+       *(.data)
+       output_len = . - 4;
+       input_data_end = .;
+       }
+}
diff --git a/arch/sh/boot/romimage/Makefile b/arch/sh/boot/romimage/Makefile
new file mode 100644 (file)
index 0000000..5806eee
--- /dev/null
@@ -0,0 +1,19 @@
+#
+# linux/arch/sh/boot/romimage/Makefile
+#
+# create an image suitable for burning to flash from zImage
+#
+
+targets                := vmlinux head.o
+
+OBJECTS = $(obj)/head.o
+LDFLAGS_vmlinux := --oformat $(ld-bfd) -Ttext 0 -e romstart
+
+$(obj)/vmlinux: $(OBJECTS) $(obj)/piggy.o FORCE
+       $(call if_changed,ld)
+       @:
+
+LDFLAGS_piggy.o := -r --format binary --oformat $(ld-bfd) -T
+
+$(obj)/piggy.o: $(obj)/vmlinux.scr arch/sh/boot/zImage FORCE
+       $(call if_changed,ld)
diff --git a/arch/sh/boot/romimage/head.S b/arch/sh/boot/romimage/head.S
new file mode 100644 (file)
index 0000000..219bc62
--- /dev/null
@@ -0,0 +1,10 @@
+/*
+ *  linux/arch/sh/boot/romimage/head.S
+ *
+ * Board specific setup code, executed before zImage loader
+ */
+
+.text
+       .global romstart
+romstart:
+#include <mach/romimage.h>
diff --git a/arch/sh/boot/romimage/vmlinux.scr b/arch/sh/boot/romimage/vmlinux.scr
new file mode 100644 (file)
index 0000000..287c08f
--- /dev/null
@@ -0,0 +1,6 @@
+SECTIONS
+{
+  .text : {
+       *(.data)
+       }
+}
diff --git a/arch/sh/configs/kfr2r09_defconfig b/arch/sh/configs/kfr2r09_defconfig
new file mode 100644 (file)
index 0000000..90e575c
--- /dev/null
@@ -0,0 +1,877 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.31-rc3
+# Thu Jul 23 17:45:09 2009
+#
+CONFIG_SUPERH=y
+CONFIG_SUPERH32=y
+# CONFIG_SUPERH64 is not set
+CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_IRQ_PER_CPU=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_SYS_SUPPORTS_CMT=y
+CONFIG_SYS_SUPPORTS_TMU=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
+CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_BZIP2=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_GROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+# CONFIG_RT_GROUP_SCHED is not set
+CONFIG_USER_SCHED=y
+# CONFIG_CGROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+# CONFIG_KALLSYMS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_HAVE_PERF_COUNTERS=y
+
+#
+# Performance Counters
+#
+# CONFIG_PERF_COUNTERS is not set
+CONFIG_VM_EVENT_COUNTERS=y
+# CONFIG_STRIP_ASM_SYMS is not set
+CONFIG_COMPAT_BRK=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+# CONFIG_MODULES is not set
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_AS is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_NOOP=y
+CONFIG_DEFAULT_IOSCHED="noop"
+# CONFIG_FREEZER is not set
+
+#
+# System type
+#
+CONFIG_CPU_SH4=y
+CONFIG_CPU_SH4A=y
+CONFIG_CPU_SHX2=y
+CONFIG_ARCH_SHMOBILE=y
+# CONFIG_CPU_SUBTYPE_SH7619 is not set
+# CONFIG_CPU_SUBTYPE_SH7201 is not set
+# CONFIG_CPU_SUBTYPE_SH7203 is not set
+# CONFIG_CPU_SUBTYPE_SH7206 is not set
+# CONFIG_CPU_SUBTYPE_SH7263 is not set
+# CONFIG_CPU_SUBTYPE_MXG is not set
+# CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
+# CONFIG_CPU_SUBTYPE_SH7707 is not set
+# CONFIG_CPU_SUBTYPE_SH7708 is not set
+# CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
+# CONFIG_CPU_SUBTYPE_SH7712 is not set
+# CONFIG_CPU_SUBTYPE_SH7720 is not set
+# CONFIG_CPU_SUBTYPE_SH7721 is not set
+# CONFIG_CPU_SUBTYPE_SH7750 is not set
+# CONFIG_CPU_SUBTYPE_SH7091 is not set
+# CONFIG_CPU_SUBTYPE_SH7750R is not set
+# CONFIG_CPU_SUBTYPE_SH7750S is not set
+# CONFIG_CPU_SUBTYPE_SH7751 is not set
+# CONFIG_CPU_SUBTYPE_SH7751R is not set
+# CONFIG_CPU_SUBTYPE_SH7760 is not set
+# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+# CONFIG_CPU_SUBTYPE_SH7723 is not set
+CONFIG_CPU_SUBTYPE_SH7724=y
+# CONFIG_CPU_SUBTYPE_SH7763 is not set
+# CONFIG_CPU_SUBTYPE_SH7770 is not set
+# CONFIG_CPU_SUBTYPE_SH7780 is not set
+# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
+# CONFIG_CPU_SUBTYPE_SHX3 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+# CONFIG_CPU_SUBTYPE_SH7722 is not set
+# CONFIG_CPU_SUBTYPE_SH7366 is not set
+
+#
+# Memory management options
+#
+CONFIG_QUICKLIST=y
+CONFIG_MMU=y
+CONFIG_PAGE_OFFSET=0x80000000
+CONFIG_FORCE_MAX_ZONEORDER=11
+CONFIG_MEMORY_START=0x08000000
+CONFIG_MEMORY_SIZE=0x08000000
+CONFIG_29BIT=y
+# CONFIG_X2TLB is not set
+CONFIG_VSYSCALL=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_DEFAULT=y
+CONFIG_MAX_ACTIVE_REGIONS=1
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_SPARSEMEM_STATIC=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_NR_QUICK=2
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+
+#
+# Cache configuration
+#
+CONFIG_CACHE_WRITEBACK=y
+# CONFIG_CACHE_WRITETHROUGH is not set
+# CONFIG_CACHE_OFF is not set
+
+#
+# Processor features
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_CPU_BIG_ENDIAN is not set
+CONFIG_SH_FPU=y
+# CONFIG_SH_STORE_QUEUES is not set
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_SR_RB=y
+CONFIG_CPU_HAS_FPU=y
+
+#
+# Board support
+#
+# CONFIG_SH_7724_SOLUTION_ENGINE is not set
+CONFIG_SH_KFR2R09=y
+
+#
+# Timer and clock configuration
+#
+# CONFIG_SH_TIMER_TMU is not set
+CONFIG_SH_TIMER_CMT=y
+CONFIG_SH_PCLK_FREQ=33333333
+CONFIG_SH_CLK_CPG=y
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+
+#
+# DMA support
+#
+# CONFIG_SH_DMA is not set
+
+#
+# Companion Chips
+#
+
+#
+# Additional SuperH Device Drivers
+#
+# CONFIG_HEARTBEAT is not set
+# CONFIG_PUSH_SWITCH is not set
+
+#
+# Kernel features
+#
+# CONFIG_HZ_100 is not set
+# CONFIG_HZ_250 is not set
+# CONFIG_HZ_300 is not set
+CONFIG_HZ_1000=y
+CONFIG_HZ=1000
+# CONFIG_SCHED_HRTICK is not set
+CONFIG_KEXEC=y
+# CONFIG_CRASH_DUMP is not set
+# CONFIG_SECCOMP is not set
+# CONFIG_PREEMPT_NONE is not set
+CONFIG_PREEMPT_VOLUNTARY=y
+# CONFIG_PREEMPT is not set
+CONFIG_GUSA=y
+# CONFIG_SPARSE_IRQ is not set
+
+#
+# Boot options
+#
+CONFIG_ZERO_PAGE_OFFSET=0x00001000
+CONFIG_BOOT_LINK_OFFSET=0x00800000
+CONFIG_ENTRY_OFFSET=0x00001000
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=ttySC1,115200"
+
+#
+# Bus options
+#
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options (EXPERIMENTAL)
+#
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+# CONFIG_SUSPEND is not set
+# CONFIG_HIBERNATION is not set
+CONFIG_CPU_IDLE=y
+CONFIG_CPU_IDLE_GOV_LADDER=y
+CONFIG_CPU_IDLE_GOV_MENU=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+CONFIG_MTD_PHYSMAP=y
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+# CONFIG_MTD_NAND is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
+# UBI - Unsorted block images
+#
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_WL_THRESHOLD=4096
+CONFIG_MTD_UBI_BEB_RESERVE=1
+# CONFIG_MTD_UBI_GLUEBI is not set
+
+#
+# UBI debugging options
+#
+# CONFIG_MTD_UBI_DEBUG is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_BLK_DEV_HD is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_NETDEVICES is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_GPIO is not set
+# CONFIG_KEYBOARD_MATRIX is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+CONFIG_KEYBOARD_SH_KEYSC=y
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=6
+CONFIG_SERIAL_SH_SCI_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+# CONFIG_I2C_CHARDEV is not set
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_DESIGNWARE is not set
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+CONFIG_I2C_SH_MOBILE=y
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+# CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO expanders:
+#
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_SOUND is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+CONFIG_UIO=y
+# CONFIG_UIO_PDRV is not set
+CONFIG_UIO_PDRV_GENIRQ=y
+# CONFIG_UIO_SMX is not set
+# CONFIG_UIO_SERCOS3 is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+# CONFIG_EXT2_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+CONFIG_FILE_LOCKING=y
+# CONFIG_FSNOTIFY is not set
+# CONFIG_INOTIFY is not set
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLBFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+# CONFIG_MISC_FILESYSTEMS is not set
+# CONFIG_NETWORK_FILESYSTEMS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_NLS is not set
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_HAVE_FTRACE_SYSCALLS=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_DMA_API_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_SH_STANDARD_BIOS is not set
+# CONFIG_EARLY_SCIF_CONSOLE is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_CRYPTO is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+CONFIG_CRC_T10DIF=y
+CONFIG_CRC_ITU_T=y
+CONFIG_CRC32=y
+CONFIG_CRC7=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_HAVE_LMB=y
+CONFIG_NLATTR=y
+CONFIG_GENERIC_ATOMIC64=y
index 0c8f8e14622a73c8eb99f0ddc7e0a816670f3098..68a5f4cb0343eeffa2750543a87f7ea3bbd11d0d 100644 (file)
@@ -16,6 +16,7 @@
 
 /* DMAOR contorl: The DMAOR access size is different by CPU.*/
 #if defined(CONFIG_CPU_SUBTYPE_SH7723) || \
+    defined(CONFIG_CPU_SUBTYPE_SH7724) || \
     defined(CONFIG_CPU_SUBTYPE_SH7780) || \
     defined(CONFIG_CPU_SUBTYPE_SH7785)
 #define dmaor_read_reg(n) \
diff --git a/arch/sh/include/asm/dwarf.h b/arch/sh/include/asm/dwarf.h
new file mode 100644 (file)
index 0000000..60b1807
--- /dev/null
@@ -0,0 +1,402 @@
+/*
+ * Copyright (C) 2009 Matt Fleming <matt@console-pimps.org>
+ *
+ * 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
+ * for more details.
+ *
+ */
+#ifndef __ASM_SH_DWARF_H
+#define __ASM_SH_DWARF_H
+
+#ifdef CONFIG_DWARF_UNWINDER
+
+/*
+ * DWARF expression operations
+ */
+#define DW_OP_addr     0x03
+#define DW_OP_deref    0x06
+#define DW_OP_const1u  0x08
+#define DW_OP_const1s  0x09
+#define DW_OP_const2u  0x0a
+#define DW_OP_const2s  0x0b
+#define DW_OP_const4u  0x0c
+#define DW_OP_const4s  0x0d
+#define DW_OP_const8u  0x0e
+#define DW_OP_const8s  0x0f
+#define DW_OP_constu   0x10
+#define DW_OP_consts   0x11
+#define DW_OP_dup      0x12
+#define DW_OP_drop     0x13
+#define DW_OP_over     0x14
+#define DW_OP_pick     0x15
+#define DW_OP_swap     0x16
+#define DW_OP_rot      0x17
+#define DW_OP_xderef   0x18
+#define DW_OP_abs      0x19
+#define DW_OP_and      0x1a
+#define DW_OP_div      0x1b
+#define DW_OP_minus    0x1c
+#define DW_OP_mod      0x1d
+#define DW_OP_mul      0x1e
+#define DW_OP_neg      0x1f
+#define DW_OP_not      0x20
+#define DW_OP_or       0x21
+#define DW_OP_plus     0x22
+#define DW_OP_plus_uconst      0x23
+#define DW_OP_shl      0x24
+#define DW_OP_shr      0x25
+#define DW_OP_shra     0x26
+#define DW_OP_xor      0x27
+#define DW_OP_skip     0x2f
+#define DW_OP_bra      0x28
+#define DW_OP_eq       0x29
+#define DW_OP_ge       0x2a
+#define DW_OP_gt       0x2b
+#define DW_OP_le       0x2c
+#define DW_OP_lt       0x2d
+#define DW_OP_ne       0x2e
+#define DW_OP_lit0     0x30
+#define DW_OP_lit1     0x31
+#define DW_OP_lit2     0x32
+#define DW_OP_lit3     0x33
+#define DW_OP_lit4     0x34
+#define DW_OP_lit5     0x35
+#define DW_OP_lit6     0x36
+#define DW_OP_lit7     0x37
+#define DW_OP_lit8     0x38
+#define DW_OP_lit9     0x39
+#define DW_OP_lit10    0x3a
+#define DW_OP_lit11    0x3b
+#define DW_OP_lit12    0x3c
+#define DW_OP_lit13    0x3d
+#define DW_OP_lit14    0x3e
+#define DW_OP_lit15    0x3f
+#define DW_OP_lit16    0x40
+#define DW_OP_lit17    0x41
+#define DW_OP_lit18    0x42
+#define DW_OP_lit19    0x43
+#define DW_OP_lit20    0x44
+#define DW_OP_lit21    0x45
+#define DW_OP_lit22    0x46
+#define DW_OP_lit23    0x47
+#define DW_OP_lit24    0x48
+#define DW_OP_lit25    0x49
+#define DW_OP_lit26    0x4a
+#define DW_OP_lit27    0x4b
+#define DW_OP_lit28    0x4c
+#define DW_OP_lit29    0x4d
+#define DW_OP_lit30    0x4e
+#define DW_OP_lit31    0x4f
+#define DW_OP_reg0     0x50
+#define DW_OP_reg1     0x51
+#define DW_OP_reg2     0x52
+#define DW_OP_reg3     0x53
+#define DW_OP_reg4     0x54
+#define DW_OP_reg5     0x55
+#define DW_OP_reg6     0x56
+#define DW_OP_reg7     0x57
+#define DW_OP_reg8     0x58
+#define DW_OP_reg9     0x59
+#define DW_OP_reg10    0x5a
+#define DW_OP_reg11    0x5b
+#define DW_OP_reg12    0x5c
+#define DW_OP_reg13    0x5d
+#define DW_OP_reg14    0x5e
+#define DW_OP_reg15    0x5f
+#define DW_OP_reg16    0x60
+#define DW_OP_reg17    0x61
+#define DW_OP_reg18    0x62
+#define DW_OP_reg19    0x63
+#define DW_OP_reg20    0x64
+#define DW_OP_reg21    0x65
+#define DW_OP_reg22    0x66
+#define DW_OP_reg23    0x67
+#define DW_OP_reg24    0x68
+#define DW_OP_reg25    0x69
+#define DW_OP_reg26    0x6a
+#define DW_OP_reg27    0x6b
+#define DW_OP_reg28    0x6c
+#define DW_OP_reg29    0x6d
+#define DW_OP_reg30    0x6e
+#define DW_OP_reg31    0x6f
+#define DW_OP_breg0    0x70
+#define DW_OP_breg1    0x71
+#define DW_OP_breg2    0x72
+#define DW_OP_breg3    0x73
+#define DW_OP_breg4    0x74
+#define DW_OP_breg5    0x75
+#define DW_OP_breg6    0x76
+#define DW_OP_breg7    0x77
+#define DW_OP_breg8    0x78
+#define DW_OP_breg9    0x79
+#define DW_OP_breg10   0x7a
+#define DW_OP_breg11   0x7b
+#define DW_OP_breg12   0x7c
+#define DW_OP_breg13   0x7d
+#define DW_OP_breg14   0x7e
+#define DW_OP_breg15   0x7f
+#define DW_OP_breg16   0x80
+#define DW_OP_breg17   0x81
+#define DW_OP_breg18   0x82
+#define DW_OP_breg19   0x83
+#define DW_OP_breg20   0x84
+#define DW_OP_breg21   0x85
+#define DW_OP_breg22   0x86
+#define DW_OP_breg23   0x87
+#define DW_OP_breg24   0x88
+#define DW_OP_breg25   0x89
+#define DW_OP_breg26   0x8a
+#define DW_OP_breg27   0x8b
+#define DW_OP_breg28   0x8c
+#define DW_OP_breg29   0x8d
+#define DW_OP_breg30   0x8e
+#define DW_OP_breg31   0x8f
+#define DW_OP_regx     0x90
+#define DW_OP_fbreg    0x91
+#define DW_OP_bregx    0x92
+#define DW_OP_piece    0x93
+#define DW_OP_deref_size       0x94
+#define DW_OP_xderef_size      0x95
+#define DW_OP_nop      0x96
+#define DW_OP_push_object_address      0x97
+#define DW_OP_call2    0x98
+#define DW_OP_call4    0x99
+#define DW_OP_call_ref 0x9a
+#define DW_OP_form_tls_address 0x9b
+#define DW_OP_call_frame_cfa   0x9c
+#define DW_OP_bit_piece        0x9d
+#define DW_OP_lo_user  0xe0
+#define DW_OP_hi_user  0xff
+
+/*
+ * Addresses used in FDE entries in the .eh_frame section may be encoded
+ * using one of the following encodings.
+ */
+#define DW_EH_PE_absptr        0x00
+#define DW_EH_PE_omit  0xff
+#define DW_EH_PE_uleb128       0x01
+#define DW_EH_PE_udata2        0x02
+#define DW_EH_PE_udata4        0x03
+#define DW_EH_PE_udata8        0x04
+#define DW_EH_PE_sleb128       0x09
+#define DW_EH_PE_sdata2        0x0a
+#define DW_EH_PE_sdata4        0x0b
+#define DW_EH_PE_sdata8        0x0c
+#define DW_EH_PE_signed        0x09
+
+#define DW_EH_PE_pcrel 0x10
+
+/*
+ * The architecture-specific register number that contains the return
+ * address in the .debug_frame table.
+ */
+#define DWARF_ARCH_RA_REG      17
+
+#ifndef __ASSEMBLY__
+/*
+ * Read either the frame pointer (r14) or the stack pointer (r15).
+ * NOTE: this MUST be inlined.
+ */
+static __always_inline unsigned long dwarf_read_arch_reg(unsigned int reg)
+{
+       unsigned long value;
+
+       switch (reg) {
+       case 14:
+               __asm__ __volatile__("mov r14, %0\n" : "=r" (value));
+               break;
+       case 15:
+               __asm__ __volatile__("mov r15, %0\n" : "=r" (value));
+               break;
+       default:
+               BUG();
+       }
+
+       return value;
+}
+
+/**
+ *     dwarf_cie - Common Information Entry
+ */
+struct dwarf_cie {
+       unsigned long length;
+       unsigned long cie_id;
+       unsigned char version;
+       const char *augmentation;
+       unsigned int code_alignment_factor;
+       int data_alignment_factor;
+
+       /* Which column in the rule table represents return addr of func. */
+       unsigned int return_address_reg;
+
+       unsigned char *initial_instructions;
+       unsigned char *instructions_end;
+
+       unsigned char encoding;
+
+       unsigned long cie_pointer;
+
+       struct list_head link;
+
+       unsigned long flags;
+#define DWARF_CIE_Z_AUGMENTATION       (1 << 0)
+};
+
+/**
+ *     dwarf_fde - Frame Description Entry
+ */
+struct dwarf_fde {
+       unsigned long length;
+       unsigned long cie_pointer;
+       struct dwarf_cie *cie;
+       unsigned long initial_location;
+       unsigned long address_range;
+       unsigned char *instructions;
+       unsigned char *end;
+       struct list_head link;
+};
+
+/**
+ *     dwarf_frame - DWARF information for a frame in the call stack
+ */
+struct dwarf_frame {
+       struct dwarf_frame *prev, *next;
+
+       unsigned long pc;
+
+       struct dwarf_reg *regs;
+       unsigned int num_regs;  /* how many regs are allocated? */
+
+       unsigned int depth;     /* what level are we in the callstack? */
+
+       unsigned long cfa;
+
+       /* Valid when DW_FRAME_CFA_REG_OFFSET is set in flags */
+       unsigned int cfa_register;
+       unsigned int cfa_offset;
+
+       /* Valid when DW_FRAME_CFA_REG_EXP is set in flags */
+       unsigned char *cfa_expr;
+       unsigned int cfa_expr_len;
+
+       unsigned long flags;
+#define DWARF_FRAME_CFA_REG_OFFSET     (1 << 0)
+#define DWARF_FRAME_CFA_REG_EXP                (1 << 1)
+
+       unsigned long return_addr;
+};
+
+/**
+ *     dwarf_reg - DWARF register
+ *     @flags: Describes how to calculate the value of this register
+ */
+struct dwarf_reg {
+       unsigned long addr;
+       unsigned long flags;
+#define DWARF_REG_OFFSET       (1 << 0)
+};
+
+/**
+ *     dwarf_stack - a DWARF stack contains a collection of DWARF frames
+ *     @depth: the number of frames in the stack
+ *     @level: an array of DWARF frames, indexed by stack level
+ *
+ */
+struct dwarf_stack {
+       unsigned int depth;
+       struct dwarf_frame **level;
+};
+
+/*
+ * Call Frame instruction opcodes.
+ */
+#define DW_CFA_advance_loc     0x40
+#define DW_CFA_offset          0x80
+#define DW_CFA_restore         0xc0
+#define DW_CFA_nop             0x00
+#define DW_CFA_set_loc         0x01
+#define DW_CFA_advance_loc1    0x02
+#define DW_CFA_advance_loc2    0x03
+#define DW_CFA_advance_loc4    0x04
+#define DW_CFA_offset_extended 0x05
+#define DW_CFA_restore_extended        0x06
+#define DW_CFA_undefined       0x07
+#define DW_CFA_same_value      0x08
+#define DW_CFA_register                0x09
+#define DW_CFA_remember_state  0x0a
+#define DW_CFA_restore_state   0x0b
+#define DW_CFA_def_cfa         0x0c
+#define DW_CFA_def_cfa_register        0x0d
+#define DW_CFA_def_cfa_offset  0x0e
+#define DW_CFA_def_cfa_expression      0x0f
+#define DW_CFA_expression      0x10
+#define DW_CFA_offset_extended_sf      0x11
+#define DW_CFA_def_cfa_sf      0x12
+#define DW_CFA_def_cfa_offset_sf       0x13
+#define DW_CFA_val_offset      0x14
+#define DW_CFA_val_offset_sf   0x15
+#define DW_CFA_val_expression  0x16
+#define DW_CFA_lo_user         0x1c
+#define DW_CFA_hi_user         0x3f
+
+/*
+ * Some call frame instructions encode their operands in the opcode. We
+ * need some helper functions to extract both the opcode and operands
+ * from an instruction.
+ */
+static inline unsigned int DW_CFA_opcode(unsigned long insn)
+{
+       return (insn & 0xc0);
+}
+
+static inline unsigned int DW_CFA_operand(unsigned long insn)
+{
+       return (insn & 0x3f);
+}
+
+#define DW_EH_FRAME_CIE        0               /* .eh_frame CIE IDs are 0 */
+#define DW_CIE_ID      0xffffffff
+#define DW64_CIE_ID    0xffffffffffffffffULL
+
+/*
+ * DWARF FDE/CIE length field values.
+ */
+#define DW_EXT_LO      0xfffffff0
+#define DW_EXT_HI      0xffffffff
+#define DW_EXT_DWARF64 DW_EXT_HI
+
+extern void dwarf_unwinder_init(void);
+
+extern struct dwarf_frame *dwarf_unwind_stack(unsigned long,
+                                             struct dwarf_frame *);
+#endif /* __ASSEMBLY__ */
+
+#define CFI_STARTPROC  .cfi_startproc
+#define CFI_ENDPROC    .cfi_endproc
+#define CFI_DEF_CFA    .cfi_def_cfa
+#define CFI_REGISTER   .cfi_register
+#define CFI_REL_OFFSET .cfi_rel_offset
+
+#else
+
+/*
+ * Use the asm comment character to ignore the rest of the line.
+ */
+#define CFI_IGNORE     !
+
+#define CFI_STARTPROC  CFI_IGNORE
+#define CFI_ENDPROC    CFI_IGNORE
+#define CFI_DEF_CFA    CFI_IGNORE
+#define CFI_REGISTER   CFI_IGNORE
+#define CFI_REL_OFFSET CFI_IGNORE
+
+#ifndef __ASSEMBLY__
+static inline void dwarf_unwinder_init(void)
+{
+}
+#endif
+
+#endif /* CONFIG_DWARF_UNWINDER */
+
+#endif /* __ASM_SH_DWARF_H */
index 3a4752a657220e10729a00fbdb3507b3aa7df1b8..64fd0de24dafe244ac6b9dc3e94ffbe9e8795ae8 100644 (file)
 #endif 
        .endm
 
+#ifdef CONFIG_TRACE_IRQFLAGS
+
+       .macro  TRACE_IRQS_ON
+       mov.l   r0, @-r15
+       mov.l   r1, @-r15
+       mov.l   r2, @-r15
+       mov.l   r3, @-r15
+       mov.l   r4, @-r15
+       mov.l   r5, @-r15
+       mov.l   r6, @-r15
+       mov.l   r7, @-r15
+
+       mov.l   7834f, r0
+       jsr     @r0
+        nop
+
+       mov.l   @r15+, r7
+       mov.l   @r15+, r6
+       mov.l   @r15+, r5
+       mov.l   @r15+, r4
+       mov.l   @r15+, r3
+       mov.l   @r15+, r2
+       mov.l   @r15+, r1
+       mov.l   @r15+, r0
+       mov.l   7834f, r0
+
+       bra     7835f
+        nop
+       .balign 4
+7834:  .long   trace_hardirqs_on
+7835:
+       .endm
+       .macro  TRACE_IRQS_OFF
+
+       mov.l   r0, @-r15
+       mov.l   r1, @-r15
+       mov.l   r2, @-r15
+       mov.l   r3, @-r15
+       mov.l   r4, @-r15
+       mov.l   r5, @-r15
+       mov.l   r6, @-r15
+       mov.l   r7, @-r15
+
+       mov.l   7834f, r0
+       jsr     @r0
+        nop
+
+       mov.l   @r15+, r7
+       mov.l   @r15+, r6
+       mov.l   @r15+, r5
+       mov.l   @r15+, r4
+       mov.l   @r15+, r3
+       mov.l   @r15+, r2
+       mov.l   @r15+, r1
+       mov.l   @r15+, r0
+       mov.l   7834f, r0
+
+       bra     7835f
+        nop
+       .balign 4
+7834:  .long   trace_hardirqs_off
+7835:
+       .endm
+
+#else
+       .macro  TRACE_IRQS_ON
+       .endm
+
+       .macro  TRACE_IRQS_OFF
+       .endm
+#endif
+
 #if defined(CONFIG_CPU_SH2A) || defined(CONFIG_CPU_SH4)
 # define PREF(x)       pref    @x
 #else
 # define PREF(x)       nop
 #endif
+
+       /*
+        * Macro for use within assembly. Because the DWARF unwinder
+        * needs to use the frame register to unwind the stack, we
+        * need to setup r14 with the value of the stack pointer as
+        * the return address is usually on the stack somewhere.
+        */
+       .macro  setup_frame_reg
+#ifdef CONFIG_DWARF_UNWINDER
+       mov     r15, r14
+#endif
+       .endm
index 8fea7d8c8258946038bbc3a10cd25b8fa8675ab9..7e0bcc4d4a96e88d8ac9ce9e49b8ac8bca3791eb 100644 (file)
@@ -11,10 +11,13 @@ extern void mcount(void);
 #define MCOUNT_ADDR            ((long)(mcount))
 
 #ifdef CONFIG_DYNAMIC_FTRACE
-#define CALLER_ADDR            ((long)(ftrace_caller))
+#define CALL_ADDR              ((long)(ftrace_call))
 #define STUB_ADDR              ((long)(ftrace_stub))
+#define GRAPH_ADDR             ((long)(ftrace_graph_call))
+#define CALLER_ADDR            ((long)(ftrace_caller))
 
-#define MCOUNT_INSN_OFFSET     ((STUB_ADDR - CALLER_ADDR) >> 1)
+#define MCOUNT_INSN_OFFSET     ((STUB_ADDR - CALL_ADDR) - 4)
+#define GRAPH_INSN_OFFSET      ((CALLER_ADDR - GRAPH_ADDR) - 4)
 
 struct dyn_arch_ftrace {
        /* No extra data needed on sh */
index 715ee237fc77bc045f556965321c601a9d5f5c54..a5be4afa790bc1526b4144ad6100f7c8ac751723 100644 (file)
@@ -1,16 +1,9 @@
 #ifndef __ASM_SH_HARDIRQ_H
 #define __ASM_SH_HARDIRQ_H
 
-#include <linux/threads.h>
-#include <linux/irq.h>
-
-/* entry.S is sensitive to the offsets of these fields */
-typedef struct {
-       unsigned int __softirq_pending;
-} ____cacheline_aligned irq_cpustat_t;
-
-#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
-
 extern void ack_bad_irq(unsigned int irq);
+#define ack_bad_irq ack_bad_irq
+
+#include <asm-generic/hardirq.h>
 
 #endif /* __ASM_SH_HARDIRQ_H */
diff --git a/arch/sh/include/asm/hwblk.h b/arch/sh/include/asm/hwblk.h
new file mode 100644 (file)
index 0000000..c01d72c
--- /dev/null
@@ -0,0 +1,70 @@
+#ifndef __ASM_SH_HWBLK_H
+#define __ASM_SH_HWBLK_H
+
+#include <asm/clock.h>
+#include <asm/io.h>
+
+#define HWBLK_CNT_USAGE 0
+#define HWBLK_CNT_NR 1
+
+#define HWBLK_AREA_FLAG_PARENT (1 << 0) /* valid parent */
+
+#define HWBLK_AREA(_flags, _parent)            \
+{                                              \
+       .flags = _flags,                        \
+       .parent = _parent,                      \
+}
+
+struct hwblk_area {
+       int cnt[HWBLK_CNT_NR];
+       unsigned char parent;
+       unsigned char flags;
+};
+
+#define HWBLK(_mstp, _bit, _area)              \
+{                                              \
+       .mstp = (void __iomem *)_mstp,          \
+       .bit = _bit,                            \
+       .area = _area,                          \
+}
+
+struct hwblk {
+       void __iomem *mstp;
+       unsigned char bit;
+       unsigned char area;
+       int cnt[HWBLK_CNT_NR];
+};
+
+struct hwblk_info {
+       struct hwblk_area *areas;
+       int nr_areas;
+       struct hwblk *hwblks;
+       int nr_hwblks;
+};
+
+/* Should be defined by processor-specific code */
+int arch_hwblk_init(void);
+int arch_hwblk_sleep_mode(void);
+
+int hwblk_register(struct hwblk_info *info);
+int hwblk_init(void);
+
+void hwblk_enable(struct hwblk_info *info, int hwblk);
+void hwblk_disable(struct hwblk_info *info, int hwblk);
+
+void hwblk_cnt_inc(struct hwblk_info *info, int hwblk, int cnt);
+void hwblk_cnt_dec(struct hwblk_info *info, int hwblk, int cnt);
+
+/* allow clocks to enable and disable hardware blocks */
+#define SH_HWBLK_CLK(_name, _id, _parent, _hwblk, _flags)      \
+{                                                      \
+       .name           = _name,                        \
+       .id             = _id,                          \
+       .parent         = _parent,                      \
+       .arch_flags     = _hwblk,                       \
+       .flags          = _flags,                       \
+}
+
+int sh_hwblk_clk_register(struct clk *clks, int nr);
+
+#endif /* __ASM_SH_HWBLK_H */
diff --git a/arch/sh/include/asm/lmb.h b/arch/sh/include/asm/lmb.h
new file mode 100644 (file)
index 0000000..9b437f6
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef __ASM_SH_LMB_H
+#define __ASM_SH_LMB_H
+
+#define LMB_REAL_LIMIT 0
+
+#endif /* __ASM_SH_LMB_H */
index 72ea209195bd1103443b6548b7f1f8d483616e21..0db19db913c76ecd1de170fc5c6c28813f12ab10 100644 (file)
@@ -20,7 +20,7 @@
  * - Bit 9 is reserved by everyone and used by _PAGE_PROTNONE.
  *
  * - Bits 10 and 11 are low bits of the PPN that are reserved on >= 4K pages.
- *   Bit 10 is used for _PAGE_ACCESSED, bit 11 remains unused.
+ *   Bit 10 is used for _PAGE_ACCESSED, and bit 11 is used for _PAGE_SPECIAL.
  *
  * - On 29 bit platforms, bits 31 to 29 are used for the space attributes
  *   and timing control which (together with bit 0) are moved into the
@@ -52,6 +52,7 @@
 #define _PAGE_PROTNONE 0x200           /* software: if not present  */
 #define _PAGE_ACCESSED 0x400           /* software: page referenced */
 #define _PAGE_FILE     _PAGE_WT        /* software: pagecache or swap? */
+#define _PAGE_SPECIAL  0x800           /* software: special page */
 
 #define _PAGE_SZ_MASK  (_PAGE_SZ0 | _PAGE_SZ1)
 #define _PAGE_PR_MASK  (_PAGE_RW | _PAGE_USER)
 # define _PAGE_SZHUGE  (_PAGE_FLAGS_HARD)
 #endif
 
+/*
+ * Mask of bits that are to be preserved accross pgprot changes.
+ */
 #define _PAGE_CHG_MASK \
-       (PTE_MASK | _PAGE_ACCESSED | _PAGE_CACHABLE | _PAGE_DIRTY)
+       (PTE_MASK | _PAGE_ACCESSED | _PAGE_CACHABLE | \
+        _PAGE_DIRTY | _PAGE_SPECIAL)
 
 #ifndef __ASSEMBLY__
 
@@ -328,7 +333,7 @@ static inline void set_pte(pte_t *ptep, pte_t pte)
 #define pte_dirty(pte)         ((pte).pte_low & _PAGE_DIRTY)
 #define pte_young(pte)         ((pte).pte_low & _PAGE_ACCESSED)
 #define pte_file(pte)          ((pte).pte_low & _PAGE_FILE)
-#define pte_special(pte)       (0)
+#define pte_special(pte)       ((pte).pte_low & _PAGE_SPECIAL)
 
 #ifdef CONFIG_X2TLB
 #define pte_write(pte)         ((pte).pte_high & _PAGE_EXT_USER_WRITE)
@@ -358,8 +363,9 @@ PTE_BIT_FUNC(low, mkclean, &= ~_PAGE_DIRTY);
 PTE_BIT_FUNC(low, mkdirty, |= _PAGE_DIRTY);
 PTE_BIT_FUNC(low, mkold, &= ~_PAGE_ACCESSED);
 PTE_BIT_FUNC(low, mkyoung, |= _PAGE_ACCESSED);
+PTE_BIT_FUNC(low, mkspecial, |= _PAGE_SPECIAL);
 
-static inline pte_t pte_mkspecial(pte_t pte) { return pte; }
+#define __HAVE_ARCH_PTE_SPECIAL
 
 /*
  * Macro and implementation to make a page protection as uncachable.
index 01a4076a3719b5d42661157836e5dde18943ba02..a78701da775b9d6dd2e246c80983562095bf6e54 100644 (file)
@@ -7,6 +7,7 @@ extern void __nosave_begin, __nosave_end;
 extern long __machvec_start, __machvec_end;
 extern char __uncached_start, __uncached_end;
 extern char _ebss[];
+extern char __start_eh_frame[], __stop_eh_frame[];
 
 #endif /* __ASM_SH_SECTIONS_H */
 
diff --git a/arch/sh/include/asm/stacktrace.h b/arch/sh/include/asm/stacktrace.h
new file mode 100644 (file)
index 0000000..7970182
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2009  Matt Fleming
+ *
+ * Based on:
+ *     The x86 implementation - arch/x86/include/asm/stacktrace.h
+ */
+#ifndef _ASM_SH_STACKTRACE_H
+#define _ASM_SH_STACKTRACE_H
+
+/* Generic stack tracer with callbacks */
+
+struct stacktrace_ops {
+       void (*warning)(void *data, char *msg);
+       /* msg must contain %s for the symbol */
+       void (*warning_symbol)(void *data, char *msg, unsigned long symbol);
+       void (*address)(void *data, unsigned long address, int reliable);
+       /* On negative return stop dumping */
+       int (*stack)(void *data, char *name);
+};
+
+void dump_trace(struct task_struct *tsk, struct pt_regs *regs,
+               unsigned long *stack,
+               const struct stacktrace_ops *ops, void *data);
+
+#endif /* _ASM_SH_STACKTRACE_H */
index b1b995370e7957713dbebf8d15b6fb5ab05f7abc..5c8ea28ff7a49ead05d8394601cfdb1c791787d0 100644 (file)
@@ -10,6 +10,15 @@ struct swsusp_arch_regs {
        struct pt_regs user_regs;
        unsigned long bank1_regs[8];
 };
+
+void sh_mobile_call_standby(unsigned long mode);
+
+#ifdef CONFIG_CPU_IDLE
+void sh_mobile_setup_cpuidle(void);
+#else
+static inline void sh_mobile_setup_cpuidle(void) {}
+#endif
+
 #endif
 
 /* flags passed to assembly suspend code */
index 6f83f2cc45c16887e126cbffa5e14a28f9b63104..7d80df4f09cb6349117329cd2ce8cd50ccfa64d8 100644 (file)
@@ -65,6 +65,7 @@ static inline void syscall_get_arguments(struct task_struct *task,
        case 3: args[2] = regs->regs[6];
        case 2: args[1] = regs->regs[5];
        case 1: args[0] = regs->regs[4];
+       case 0:
                break;
        default:
                BUG();
index d570ac2e5cb99838b486c0f65cf120ba710e20e5..5123bcaa8509e0cbbf7f7e736bbb290d02673b34 100644 (file)
@@ -97,7 +97,7 @@ static inline struct thread_info *current_thread_info(void)
 
 extern struct thread_info *alloc_thread_info(struct task_struct *tsk);
 extern void free_thread_info(struct thread_info *ti);
+
 #endif /* THREAD_SHIFT < PAGE_SHIFT */
 
 #endif /* __ASSEMBLY__ */
@@ -116,6 +116,7 @@ extern void free_thread_info(struct thread_info *ti);
 #define TIF_SYSCALL_AUDIT      5       /* syscall auditing active */
 #define TIF_SECCOMP            6       /* secure computing */
 #define TIF_NOTIFY_RESUME      7       /* callback before returning to user */
+#define TIF_SYSCALL_FTRACE     8       /* for ftrace syscall instrumentation */
 #define TIF_USEDFPU            16      /* FPU was used by this task this quantum (SMP) */
 #define TIF_POLLING_NRFLAG     17      /* true if poll_idle() is polling TIF_NEED_RESCHED */
 #define TIF_MEMDIE             18
@@ -129,25 +130,27 @@ extern void free_thread_info(struct thread_info *ti);
 #define _TIF_SYSCALL_AUDIT     (1 << TIF_SYSCALL_AUDIT)
 #define _TIF_SECCOMP           (1 << TIF_SECCOMP)
 #define _TIF_NOTIFY_RESUME     (1 << TIF_NOTIFY_RESUME)
+#define _TIF_SYSCALL_FTRACE    (1 << TIF_SYSCALL_FTRACE)
 #define _TIF_USEDFPU           (1 << TIF_USEDFPU)
 #define _TIF_POLLING_NRFLAG    (1 << TIF_POLLING_NRFLAG)
 #define _TIF_FREEZE            (1 << TIF_FREEZE)
 
 /*
- * _TIF_ALLWORK_MASK and _TIF_WORK_MASK need to fit within a byte, or we
+ * _TIF_ALLWORK_MASK and _TIF_WORK_MASK need to fit within 2 bytes, or we
  * blow the tst immediate size constraints and need to fix up
  * arch/sh/kernel/entry-common.S.
  */
 
 /* work to do in syscall trace */
 #define _TIF_WORK_SYSCALL_MASK (_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP | \
-                                _TIF_SYSCALL_AUDIT | _TIF_SECCOMP)
+                                _TIF_SYSCALL_AUDIT | _TIF_SECCOMP    | \
+                                _TIF_SYSCALL_FTRACE)
 
 /* work to do on any return to u-space */
 #define _TIF_ALLWORK_MASK      (_TIF_SYSCALL_TRACE | _TIF_SIGPENDING      | \
                                 _TIF_NEED_RESCHED  | _TIF_SYSCALL_AUDIT   | \
                                 _TIF_SINGLESTEP    | _TIF_RESTORE_SIGMASK | \
-                                _TIF_NOTIFY_RESUME)
+                                _TIF_NOTIFY_RESUME | _TIF_SYSCALL_FTRACE)
 
 /* work to do on interrupt/exception return */
 #define _TIF_WORK_MASK         (_TIF_ALLWORK_MASK & ~(_TIF_SYSCALL_TRACE | \
diff --git a/arch/sh/include/asm/unwinder.h b/arch/sh/include/asm/unwinder.h
new file mode 100644 (file)
index 0000000..3dc5514
--- /dev/null
@@ -0,0 +1,25 @@
+#ifndef _LINUX_UNWINDER_H
+#define _LINUX_UNWINDER_H
+
+#include <asm/stacktrace.h>
+
+struct unwinder {
+       const char *name;
+       struct list_head list;
+       int rating;
+       void (*dump)(struct task_struct *, struct pt_regs *,
+                    unsigned long *, const struct stacktrace_ops *, void *);
+};
+
+extern int unwinder_init(void);
+extern int unwinder_register(struct unwinder *);
+
+extern void unwind_stack(struct task_struct *, struct pt_regs *,
+                        unsigned long *, const struct stacktrace_ops *,
+                        void *);
+
+extern void stack_reader_dump(struct task_struct *, struct pt_regs *,
+                             unsigned long *, const struct stacktrace_ops *,
+                             void *);
+
+#endif /* _LINUX_UNWINDER_H */
diff --git a/arch/sh/include/asm/vmlinux.lds.h b/arch/sh/include/asm/vmlinux.lds.h
new file mode 100644 (file)
index 0000000..244ec4a
--- /dev/null
@@ -0,0 +1,17 @@
+#ifndef __ASM_SH_VMLINUX_LDS_H
+#define __ASM_SH_VMLINUX_LDS_H
+
+#include <asm-generic/vmlinux.lds.h>
+
+#ifdef CONFIG_DWARF_UNWINDER
+#define DWARF_EH_FRAME                                                 \
+       .eh_frame : AT(ADDR(.eh_frame) - LOAD_OFFSET) {                 \
+                 VMLINUX_SYMBOL(__start_eh_frame) = .;                 \
+                 *(.eh_frame)                                          \
+                 VMLINUX_SYMBOL(__stop_eh_frame) = .;                  \
+       }
+#else
+#define DWARF_EH_FRAME
+#endif
+
+#endif /* __ASM_SH_VMLINUX_LDS_H */
index 0ed5178fed69bc46ec722e6ee1fa1417652477b6..f0886bc880e029d795dff5393b0f0c4d82a071cc 100644 (file)
@@ -16,7 +16,8 @@
 #define DMAE0_IRQ      38
 #define SH_DMAC_BASE0  0xFF608020
 #define SH_DMARS_BASE  0xFF609000
-#elif defined(CONFIG_CPU_SUBTYPE_SH7723)
+#elif defined(CONFIG_CPU_SUBTYPE_SH7723) || \
+      defined(CONFIG_CPU_SUBTYPE_SH7724)
 #define DMTE0_IRQ      48      /* DMAC0A*/
 #define DMTE4_IRQ      40      /* DMAC0B */
 #define DMTE6_IRQ      42
index 738ea43c5038d72613d940126f2fde0dddbd0aa2..48560407cbe1c92acff99ff7fb858a4f5b1172a8 100644 (file)
@@ -221,4 +221,18 @@ enum {
        GPIO_FN_KEYOUT3, GPIO_FN_KEYOUT4_IN6, GPIO_FN_KEYOUT5_IN5,
 };
 
+enum {
+       HWBLK_UNKNOWN = 0,
+       HWBLK_TLB, HWBLK_IC, HWBLK_OC, HWBLK_URAM, HWBLK_XYMEM,
+       HWBLK_INTC, HWBLK_DMAC, HWBLK_SHYWAY, HWBLK_HUDI,
+       HWBLK_UBC, HWBLK_TMU, HWBLK_CMT, HWBLK_RWDT, HWBLK_FLCTL,
+       HWBLK_SCIF0, HWBLK_SCIF1, HWBLK_SCIF2, HWBLK_SIO,
+       HWBLK_SIOF0, HWBLK_SIOF1, HWBLK_IIC, HWBLK_RTC,
+       HWBLK_TPU, HWBLK_IRDA, HWBLK_SDHI, HWBLK_SIM, HWBLK_KEYSC,
+       HWBLK_TSIF, HWBLK_USBF, HWBLK_2DG, HWBLK_SIU, HWBLK_VOU,
+       HWBLK_JPU, HWBLK_BEU, HWBLK_CEU, HWBLK_VEU, HWBLK_VPU,
+       HWBLK_LCDC,
+       HWBLK_NR,
+};
+
 #endif /* __ASM_SH7722_H__ */
index 14c8ca936781c270b6cbcbab7e592430cc57c38e..9b36fae72324026ebac9ddaeb0df7936a48568a3 100644 (file)
@@ -265,4 +265,21 @@ enum {
        GPIO_FN_IDEA1, GPIO_FN_IDEA0,
 };
 
+enum {
+       HWBLK_UNKNOWN = 0,
+       HWBLK_TLB, HWBLK_IC, HWBLK_OC, HWBLK_L2C, HWBLK_ILMEM, HWBLK_FPU,
+       HWBLK_INTC, HWBLK_DMAC0, HWBLK_SHYWAY,
+       HWBLK_HUDI, HWBLK_DBG, HWBLK_UBC, HWBLK_SUBC,
+       HWBLK_TMU0, HWBLK_CMT, HWBLK_RWDT, HWBLK_DMAC1, HWBLK_TMU1,
+       HWBLK_FLCTL,
+       HWBLK_SCIF0, HWBLK_SCIF1, HWBLK_SCIF2,
+       HWBLK_SCIF3, HWBLK_SCIF4, HWBLK_SCIF5,
+       HWBLK_MSIOF0, HWBLK_MSIOF1, HWBLK_MERAM, HWBLK_IIC, HWBLK_RTC,
+       HWBLK_ATAPI, HWBLK_ADC, HWBLK_TPU, HWBLK_IRDA, HWBLK_TSIF, HWBLK_ICB,
+       HWBLK_SDHI0, HWBLK_SDHI1, HWBLK_KEYSC, HWBLK_USB,
+       HWBLK_2DG, HWBLK_SIU, HWBLK_VEU2H1, HWBLK_VOU, HWBLK_BEU, HWBLK_CEU,
+       HWBLK_VEU2H0, HWBLK_VPU, HWBLK_LCDC,
+       HWBLK_NR,
+};
+
 #endif /* __ASM_SH7723_H__ */
index 66fd1184359ecf4a3656870f9fad1a4076b525b9..0cd1f71a11168e52d1d4fa51e324a26a95eb2793 100644 (file)
@@ -266,4 +266,21 @@ enum {
        GPIO_FN_INTC_IRQ1, GPIO_FN_INTC_IRQ0,
 };
 
+enum {
+       HWBLK_UNKNOWN = 0,
+       HWBLK_TLB, HWBLK_IC, HWBLK_OC, HWBLK_RSMEM, HWBLK_ILMEM, HWBLK_L2C,
+       HWBLK_FPU, HWBLK_INTC, HWBLK_DMAC0, HWBLK_SHYWAY,
+       HWBLK_HUDI, HWBLK_DBG, HWBLK_UBC,
+       HWBLK_TMU0, HWBLK_CMT, HWBLK_RWDT, HWBLK_DMAC1, HWBLK_TMU1,
+       HWBLK_SCIF0, HWBLK_SCIF1, HWBLK_SCIF2, HWBLK_SCIF3,
+       HWBLK_SCIF4, HWBLK_SCIF5, HWBLK_MSIOF0, HWBLK_MSIOF1,
+       HWBLK_KEYSC, HWBLK_RTC, HWBLK_IIC0, HWBLK_IIC1,
+       HWBLK_MMC, HWBLK_ETHER, HWBLK_ATAPI, HWBLK_TPU, HWBLK_IRDA,
+       HWBLK_TSIF, HWBLK_USB1, HWBLK_USB0, HWBLK_2DG,
+       HWBLK_SDHI0, HWBLK_SDHI1, HWBLK_VEU1, HWBLK_CEU1, HWBLK_BEU1,
+       HWBLK_2DDMAC, HWBLK_SPU, HWBLK_JPU, HWBLK_VOU,
+       HWBLK_BEU0, HWBLK_CEU0, HWBLK_VEU0, HWBLK_VPU, HWBLK_LCDC,
+       HWBLK_NR,
+};
+
 #endif /* __ASM_SH7724_H__ */
diff --git a/arch/sh/include/mach-common/mach/migor.h b/arch/sh/include/mach-common/mach/migor.h
deleted file mode 100644 (file)
index e451f02..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-#ifndef __ASM_SH_MIGOR_H
-#define __ASM_SH_MIGOR_H
-
-/*
- * linux/include/asm-sh/migor.h
- *
- * Copyright (C) 2008 Renesas Solutions
- *
- * Portions Copyright (C) 2007 Nobuhiro Iwamatsu
- *
- * 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
- * for more details.
- *
- */
-#include <asm/addrspace.h>
-
-/* GPIO */
-#define PORT_PACR 0xa4050100
-#define PORT_PDCR 0xa4050106
-#define PORT_PECR 0xa4050108
-#define PORT_PHCR 0xa405010e
-#define PORT_PJCR 0xa4050110
-#define PORT_PKCR 0xa4050112
-#define PORT_PLCR 0xa4050114
-#define PORT_PMCR 0xa4050116
-#define PORT_PRCR 0xa405011c
-#define PORT_PTCR 0xa4050140
-#define PORT_PUCR 0xa4050142
-#define PORT_PVCR 0xa4050144
-#define PORT_PWCR 0xa4050146
-#define PORT_PXCR 0xa4050148
-#define PORT_PYCR 0xa405014a
-#define PORT_PZCR 0xa405014c
-#define PORT_PADR 0xa4050120
-#define PORT_PHDR 0xa405012e
-#define PORT_PTDR 0xa4050160
-#define PORT_PWDR 0xa4050166
-
-#define PORT_HIZCRA 0xa4050158
-#define PORT_HIZCRC 0xa405015c
-
-#define PORT_MSELCRB 0xa4050182
-
-#define PORT_PSELA 0xa405014e
-#define PORT_PSELB 0xa4050150
-#define PORT_PSELC 0xa4050152
-#define PORT_PSELD 0xa4050154
-#define PORT_PSELE 0xa4050156
-
-#define PORT_HIZCRA 0xa4050158
-#define PORT_HIZCRB 0xa405015a
-#define PORT_HIZCRC 0xa405015c
-
-#define BSC_CS4BCR 0xfec10010
-#define BSC_CS6ABCR 0xfec1001c
-#define BSC_CS4WCR 0xfec10030
-
-#include <video/sh_mobile_lcdc.h>
-
-int migor_lcd_qvga_setup(void *board_data, void *sys_ops_handle,
-                        struct sh_mobile_lcdc_sys_bus_ops *sys_ops);
-
-#endif /* __ASM_SH_MIGOR_H */
diff --git a/arch/sh/include/mach-common/mach/romimage.h b/arch/sh/include/mach-common/mach/romimage.h
new file mode 100644 (file)
index 0000000..267e241
--- /dev/null
@@ -0,0 +1 @@
+/* do nothing here by default */
diff --git a/arch/sh/include/mach-kfr2r09/mach/kfr2r09.h b/arch/sh/include/mach-kfr2r09/mach/kfr2r09.h
new file mode 100644 (file)
index 0000000..174374e
--- /dev/null
@@ -0,0 +1,21 @@
+#ifndef __ASM_SH_KFR2R09_H
+#define __ASM_SH_KFR2R09_H
+
+#include <video/sh_mobile_lcdc.h>
+
+#ifdef CONFIG_FB_SH_MOBILE_LCDC
+void kfr2r09_lcd_on(void *board_data);
+void kfr2r09_lcd_off(void *board_data);
+int kfr2r09_lcd_setup(void *board_data, void *sys_ops_handle,
+                     struct sh_mobile_lcdc_sys_bus_ops *sys_ops);
+#else
+static inline void kfr2r09_lcd_on(void *board_data) {}
+static inline void kfr2r09_lcd_off(void *board_data) {}
+static inline int kfr2r09_lcd_setup(void *board_data, void *sys_ops_handle,
+                                   struct sh_mobile_lcdc_sys_bus_ops *sys_ops)
+{
+       return -ENODEV;
+}
+#endif
+
+#endif /* __ASM_SH_KFR2R09_H */
diff --git a/arch/sh/include/mach-kfr2r09/mach/partner-jet-setup.txt b/arch/sh/include/mach-kfr2r09/mach/partner-jet-setup.txt
new file mode 100644 (file)
index 0000000..9c85088
--- /dev/null
@@ -0,0 +1,134 @@
+LIST "partner-jet-setup.txt - 20090729 Magnus Damm"
+LIST "set up enough of the kfr2r09 hardware to boot the kernel"
+
+LIST "zImage (RAM boot)"
+LIST "This script can be used to boot the kernel from RAM via JTAG:"
+LIST "> < partner-jet-setup.txt"
+LIST "> RD zImage, 0xa8800000"
+LIST "> G=0xa8800000"
+
+LIST "romImage (Flash boot)"
+LIST "Use the following command to burn the zImage to flash via JTAG:"
+LIST "> RD romImage, 0"
+
+LIST "--------------------------------"
+
+LIST "disable watchdog"
+EW 0xa4520004, 0xa507
+
+LIST "select mode for cs5 + cs6"
+ED 0xff800020, 0xa5a50001
+ED 0xfec10000, 0x0000001b
+
+LIST "setup clocks"
+ED 0xa4150004, 0x00000050
+ED 0xa4150000, 0x91053508
+WAIT 1
+ED 0xa4150024, 0x00005000
+
+LIST "setup pins"
+EB 0xa4050120, 0x00
+EB 0xa4050122, 0x00
+EB 0xa4050124, 0x00
+EB 0xa4050126, 0x00
+EB 0xa4050128, 0xA0
+EB 0xa405012A, 0x10
+EB 0xa405012C, 0x00
+EB 0xa405012E, 0x00
+EB 0xa4050130, 0x00
+EB 0xa4050132, 0x00
+EB 0xa4050134, 0x01
+EB 0xa4050136, 0x40
+EB 0xa4050138, 0x00
+EB 0xa405013A, 0x00
+EB 0xa405013C, 0x00
+EB 0xa405013E, 0x20
+EB 0xa4050160, 0x00
+EB 0xa4050162, 0x40
+EB 0xa4050164, 0x03
+EB 0xa4050166, 0x00
+EB 0xa4050168, 0x00
+EB 0xa405016A, 0x00
+EB 0xa405016C, 0x00
+
+EW 0xa405014E, 0x5660
+EW 0xa4050150, 0x0145
+EW 0xa4050152, 0x1550
+EW 0xa4050154, 0x0200
+EW 0xa4050156, 0x0040
+
+EW 0xa4050158, 0x0000
+EW 0xa405015a, 0x0000
+EW 0xa405015c, 0x0000
+EW 0xa405015e, 0x0000
+
+EW 0xa4050180, 0x0000
+EW 0xa4050182, 0x8002
+EW 0xa4050184, 0x0000
+
+EW 0xa405018a, 0x9991
+EW 0xa405018c, 0x8011
+EW 0xa405018e, 0x9550
+
+EW 0xa4050100, 0x0000
+EW 0xa4050102, 0x5540
+EW 0xa4050104, 0x0000
+EW 0xa4050106, 0x0000
+EW 0xa4050108, 0x4550
+EW 0xa405010a, 0x0130
+EW 0xa405010c, 0x0555
+EW 0xa405010e, 0x0000
+EW 0xa4050110, 0x0000
+EW 0xa4050112, 0xAAA8
+EW 0xa4050114, 0x8305
+EW 0xa4050116, 0x10F0
+EW 0xa4050118, 0x0F50
+EW 0xa405011a, 0x0000
+EW 0xa405011c, 0x0000
+EW 0xa405011e, 0x0555
+EW 0xa4050140, 0x0000
+EW 0xa4050142, 0x5141
+EW 0xa4050144, 0x5005
+EW 0xa4050146, 0xAAA9
+EW 0xa4050148, 0xFAA9
+EW 0xa405014a, 0x3000
+EW 0xa405014c, 0x0000
+
+LIST "setup sdram"
+ED 0xFD000108, 0x40000301
+ED 0xFD000020, 0x011B0002
+ED 0xFD000030, 0x03060E02
+ED 0xFD000034, 0x01020102
+ED 0xFD000038, 0x01090406
+ED 0xFD000008, 0x00000004
+ED 0xFD000040, 0x00000001
+ED 0xFD000040, 0x00000000
+ED 0xFD000018, 0x00000001
+
+WAIT 1
+
+ED 0xFD000014, 0x00000002
+ED 0xFD000060, 0x00000032
+ED 0xFD000060, 0x00020000
+ED 0xFD000014, 0x00000004
+ED 0xFD000014, 0x00000004
+ED 0xFD000010, 0x00000001
+ED 0xFD000044, 0x000004AF
+ED 0xFD000048, 0x20CF0037
+
+LIST "read 16 bytes from sdram"
+DD 0xa8000000, 0xa8000000, 1
+DD 0xa8000004, 0xa8000004, 1
+DD 0xa8000008, 0xa8000008, 1
+DD 0xa800000c, 0xa800000c, 1
+
+ED 0xFD000014, 0x00000002
+ED 0xFD000014, 0x00000004
+ED 0xFD000108, 0x40000300
+ED 0xFD000040, 0x00010000
+
+LIST "write to internal ram"
+ED 0xfd8007fc, 0
+
+LIST "setup cache"
+ED 0xff00001c, 0x0000090b
diff --git a/arch/sh/include/mach-kfr2r09/mach/romimage.h b/arch/sh/include/mach-kfr2r09/mach/romimage.h
new file mode 100644 (file)
index 0000000..f5aa8e1
--- /dev/null
@@ -0,0 +1,75 @@
+/* kfr2r09 board specific boot code:
+ * converts the "partner-jet-script.txt" script into assembly
+ * the assembly code is the first code to be executed in the romImage
+ */
+
+/* The LIST command is used to include comments in the script */
+.macro LIST comment
+.endm
+
+/* The ED command is used to write a 32-bit word */
+.macro  ED, addr, data
+        mov.l 1f ,r1
+        mov.l 2f ,r0
+        mov.l r0, @r1
+       bra 3f
+        nop
+       .align 2
+1:     .long \addr
+2:     .long \data
+3:
+.endm
+
+/* The EW command is used to write a 16-bit word */
+.macro  EW, addr, data
+        mov.l 1f ,r1
+        mov.l 2f ,r0
+        mov.w r0, @r1
+       bra 3f
+        nop
+       .align 2
+1:     .long \addr
+2:     .long \data
+3:
+.endm
+
+/* The EB command is used to write an 8-bit word */
+.macro  EB, addr, data
+        mov.l 1f ,r1
+        mov.l 2f ,r0
+        mov.b r0, @r1
+       bra 3f
+        nop
+       .align 2
+1:     .long \addr
+2:     .long \data
+3:
+.endm
+
+/* The WAIT command is used to delay the execution */
+.macro  WAIT, time
+        mov.l  2f ,r3
+1:
+        nop
+        tst     r3, r3
+        bf/s    1b
+         dt      r3
+       bra     3f
+        nop
+       .align 2
+2:     .long \time * 100
+3:
+.endm
+
+/* The DD command is used to read a 32-bit word */
+.macro  DD, addr, addr2, nr
+        mov.l 1f ,r1
+        mov.l @r1, r0
+       bra 2f
+        nop
+       .align 2
+1:     .long \addr
+2:
+.endm
+
+#include "partner-jet-setup.txt"
diff --git a/arch/sh/include/mach-migor/mach/migor.h b/arch/sh/include/mach-migor/mach/migor.h
new file mode 100644 (file)
index 0000000..cee6cb8
--- /dev/null
@@ -0,0 +1,14 @@
+#ifndef __ASM_SH_MIGOR_H
+#define __ASM_SH_MIGOR_H
+
+#define PORT_MSELCRB 0xa4050182
+#define BSC_CS4BCR 0xfec10010
+#define BSC_CS6ABCR 0xfec1001c
+#define BSC_CS4WCR 0xfec10030
+
+#include <video/sh_mobile_lcdc.h>
+
+int migor_lcd_qvga_setup(void *board_data, void *sys_ops_handle,
+                        struct sh_mobile_lcdc_sys_bus_ops *sys_ops);
+
+#endif /* __ASM_SH_MIGOR_H */
index 9411e3e31e686d8b45da7b1f5d1a058d3c61c3f2..f2245ebf0b31e14f5c97ea0d95bc4369bf062962 100644 (file)
@@ -9,10 +9,10 @@ ifdef CONFIG_FUNCTION_TRACER
 CFLAGS_REMOVE_ftrace.o = -pg
 endif
 
-obj-y  := debugtraps.o idle.o io.o io_generic.o irq.o                  \
+obj-y  := debugtraps.o dumpstack.o idle.o io.o io_generic.o irq.o      \
           machvec.o process_32.o ptrace_32.o setup.o signal_32.o       \
-          sys_sh.o sys_sh32.o syscalls_32.o time.o topology.o  \
-          traps.o traps_32.o
+          sys_sh.o sys_sh32.o syscalls_32.o time.o topology.o          \
+          traps.o traps_32.o unwinder.o
 
 obj-y                          += cpu/
 obj-$(CONFIG_VSYSCALL)         += vsyscall/
@@ -29,8 +29,11 @@ obj-$(CONFIG_IO_TRAPPED)     += io_trapped.o
 obj-$(CONFIG_KPROBES)          += kprobes.o
 obj-$(CONFIG_GENERIC_GPIO)     += gpio.o
 obj-$(CONFIG_DYNAMIC_FTRACE)   += ftrace.o
+obj-$(CONFIG_FTRACE_SYSCALLS)  += ftrace.o
+obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o
 obj-$(CONFIG_DUMP_CODE)                += disassemble.o
 obj-$(CONFIG_HIBERNATION)      += swsusp.o
+obj-$(CONFIG_DWARF_UNWINDER)   += dwarf.o
 
 obj-$(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST)    += localtimer.o
 
index 67b9f6c6326b6bf1cf1cb7d34f024ca1f876958e..639ee514266cc539cd5494776a6eca7e1bdb86ee 100644 (file)
@@ -2,7 +2,7 @@ extra-y := head_64.o init_task.o vmlinux.lds
 
 obj-y  := debugtraps.o idle.o io.o io_generic.o irq.o machvec.o process_64.o \
           ptrace_64.o setup.o signal_64.o sys_sh.o sys_sh64.o \
-          syscalls_64.o time.o topology.o traps.o traps_64.o
+          syscalls_64.o time.o topology.o traps.o traps_64.o unwinder.o
 
 obj-y                          += cpu/
 obj-$(CONFIG_SMP)              += smp.o
@@ -13,6 +13,7 @@ obj-$(CONFIG_CRASH_DUMP)      += crash_dump.o
 obj-$(CONFIG_STACKTRACE)       += stacktrace.o
 obj-$(CONFIG_IO_TRAPPED)       += io_trapped.o
 obj-$(CONFIG_GENERIC_GPIO)     += gpio.o
+obj-$(CONFIG_DWARF_UNWINDER)   += dwarf.o
 
 obj-$(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST)    += localtimer.o
 
index 99aceb28ee2475818186f6477ce17950bacc7afc..d218e808294ef5deda82aee64444f3dccb92161c 100644 (file)
@@ -26,6 +26,7 @@ int main(void)
        DEFINE(TI_CPU,          offsetof(struct thread_info, cpu));
        DEFINE(TI_PRE_COUNT,    offsetof(struct thread_info, preempt_count));
        DEFINE(TI_RESTART_BLOCK,offsetof(struct thread_info, restart_block));
+       DEFINE(TI_SIZE,         sizeof(struct thread_info));
 
 #ifdef CONFIG_HIBERNATION
        DEFINE(PBE_ADDRESS, offsetof(struct pbe, address));
index eecad7cbd61e98f70beaa5699c5379f6886624cd..3d6b9312dc4751fad9cfb8baccf20e4029d431e1 100644 (file)
@@ -19,4 +19,4 @@ obj-$(CONFIG_UBC_WAKEUP)      += ubc.o
 obj-$(CONFIG_SH_ADC)           += adc.o
 obj-$(CONFIG_SH_CLK_CPG)       += clock-cpg.o
 
-obj-y  += irq/ init.o clock.o
+obj-y  += irq/ init.o clock.o hwblk.o
diff --git a/arch/sh/kernel/cpu/hwblk.c b/arch/sh/kernel/cpu/hwblk.c
new file mode 100644 (file)
index 0000000..c0ad7d4
--- /dev/null
@@ -0,0 +1,155 @@
+#include <linux/clk.h>
+#include <linux/compiler.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/spinlock.h>
+#include <asm/suspend.h>
+#include <asm/hwblk.h>
+#include <asm/clock.h>
+
+static DEFINE_SPINLOCK(hwblk_lock);
+
+static void hwblk_area_mod_cnt(struct hwblk_info *info,
+                              int area, int counter, int value, int goal)
+{
+       struct hwblk_area *hap = info->areas + area;
+
+       hap->cnt[counter] += value;
+
+       if (hap->cnt[counter] != goal)
+               return;
+
+       if (hap->flags & HWBLK_AREA_FLAG_PARENT)
+               hwblk_area_mod_cnt(info, hap->parent, counter, value, goal);
+}
+
+
+static int __hwblk_mod_cnt(struct hwblk_info *info, int hwblk,
+                         int counter, int value, int goal)
+{
+       struct hwblk *hp = info->hwblks + hwblk;
+
+       hp->cnt[counter] += value;
+       if (hp->cnt[counter] == goal)
+               hwblk_area_mod_cnt(info, hp->area, counter, value, goal);
+
+       return hp->cnt[counter];
+}
+
+static void hwblk_mod_cnt(struct hwblk_info *info, int hwblk,
+                         int counter, int value, int goal)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&hwblk_lock, flags);
+       __hwblk_mod_cnt(info, hwblk, counter, value, goal);
+       spin_unlock_irqrestore(&hwblk_lock, flags);
+}
+
+void hwblk_cnt_inc(struct hwblk_info *info, int hwblk, int counter)
+{
+       hwblk_mod_cnt(info, hwblk, counter, 1, 1);
+}
+
+void hwblk_cnt_dec(struct hwblk_info *info, int hwblk, int counter)
+{
+       hwblk_mod_cnt(info, hwblk, counter, -1, 0);
+}
+
+void hwblk_enable(struct hwblk_info *info, int hwblk)
+{
+       struct hwblk *hp = info->hwblks + hwblk;
+       unsigned long tmp;
+       unsigned long flags;
+       int ret;
+
+       spin_lock_irqsave(&hwblk_lock, flags);
+
+       ret = __hwblk_mod_cnt(info, hwblk, HWBLK_CNT_USAGE, 1, 1);
+       if (ret == 1) {
+               tmp = __raw_readl(hp->mstp);
+               tmp &= ~(1 << hp->bit);
+               __raw_writel(tmp, hp->mstp);
+       }
+
+       spin_unlock_irqrestore(&hwblk_lock, flags);
+}
+
+void hwblk_disable(struct hwblk_info *info, int hwblk)
+{
+       struct hwblk *hp = info->hwblks + hwblk;
+       unsigned long tmp;
+       unsigned long flags;
+       int ret;
+
+       spin_lock_irqsave(&hwblk_lock, flags);
+
+       ret = __hwblk_mod_cnt(info, hwblk, HWBLK_CNT_USAGE, -1, 0);
+       if (ret == 0) {
+               tmp = __raw_readl(hp->mstp);
+               tmp |= 1 << hp->bit;
+               __raw_writel(tmp, hp->mstp);
+       }
+
+       spin_unlock_irqrestore(&hwblk_lock, flags);
+}
+
+struct hwblk_info *hwblk_info;
+
+int __init hwblk_register(struct hwblk_info *info)
+{
+       hwblk_info = info;
+       return 0;
+}
+
+int __init __weak arch_hwblk_init(void)
+{
+       return 0;
+}
+
+int __weak arch_hwblk_sleep_mode(void)
+{
+       return SUSP_SH_SLEEP;
+}
+
+int __init hwblk_init(void)
+{
+       return arch_hwblk_init();
+}
+
+/* allow clocks to enable and disable hardware blocks */
+static int sh_hwblk_clk_enable(struct clk *clk)
+{
+       if (!hwblk_info)
+               return -ENOENT;
+
+       hwblk_enable(hwblk_info, clk->arch_flags);
+       return 0;
+}
+
+static void sh_hwblk_clk_disable(struct clk *clk)
+{
+       if (hwblk_info)
+               hwblk_disable(hwblk_info, clk->arch_flags);
+}
+
+static struct clk_ops sh_hwblk_clk_ops = {
+       .enable         = sh_hwblk_clk_enable,
+       .disable        = sh_hwblk_clk_disable,
+       .recalc         = followparent_recalc,
+};
+
+int __init sh_hwblk_clk_register(struct clk *clks, int nr)
+{
+       struct clk *clkp;
+       int ret = 0;
+       int k;
+
+       for (k = 0; !ret && (k < nr); k++) {
+               clkp = clks + k;
+               clkp->ops = &sh_hwblk_clk_ops;
+               ret |= clk_register(clkp);
+       }
+
+       return ret;
+}
index ad85421099cdd49ba32b48c28065c90004e9a3a5..d40b9db5be033e933eed558c8d4145226715bb50 100644 (file)
@@ -3,7 +3,7 @@
  *
  * CPU init code
  *
- * Copyright (C) 2002 - 2007  Paul Mundt
+ * Copyright (C) 2002 - 2009  Paul Mundt
  * Copyright (C) 2003  Richard Curnow
  *
  * This file is subject to the terms and conditions of the GNU General Public
@@ -62,6 +62,37 @@ static void __init speculative_execution_init(void)
 #define speculative_execution_init()   do { } while (0)
 #endif
 
+#ifdef CONFIG_CPU_SH4A
+#define EXPMASK                        0xff2f0004
+#define EXPMASK_RTEDS          (1 << 0)
+#define EXPMASK_BRDSSLP                (1 << 1)
+#define EXPMASK_MMCAW          (1 << 4)
+
+static void __init expmask_init(void)
+{
+       unsigned long expmask = __raw_readl(EXPMASK);
+
+       /*
+        * Future proofing.
+        *
+        * Disable support for slottable sleep instruction
+        * and non-nop instructions in the rte delay slot.
+        */
+       expmask &= ~(EXPMASK_RTEDS | EXPMASK_BRDSSLP);
+
+       /*
+        * Enable associative writes to the memory-mapped cache array
+        * until the cache flush ops have been rewritten.
+        */
+       expmask |= EXPMASK_MMCAW;
+
+       __raw_writel(expmask, EXPMASK);
+       ctrl_barrier();
+}
+#else
+#define expmask_init() do { } while (0)
+#endif
+
 /* 2nd-level cache init */
 void __uses_jump_to_uncached __attribute__ ((weak)) l2_cache_init(void)
 {
@@ -321,4 +352,5 @@ asmlinkage void __init sh_cpu_init(void)
 #endif
 
        speculative_execution_init();
+       expmask_init();
 }
index becc54c456924077d45053ab4e0a3f22a1300e8e..c8a4331d9b8d7398e98df914178bb6ed4aed1eb9 100644 (file)
@@ -227,8 +227,9 @@ ENTRY(sh_bios_handler)
        mov.l   @r15+, r14
        add     #8,r15
        lds.l   @r15+, pr
+       mov.l   @r15+,r15
        rte
-        mov.l  @r15+,r15
+        nop
        .align  2
 1:     .long   gdb_vbr_vector
 #endif /* CONFIG_SH_STANDARD_BIOS */
index ab3903eeda5cac2b19e79956a129fb3e3c4bd861..222742ddc0d6a656ae16b3e5eb9ae5ba0ddb3691 100644 (file)
@@ -176,8 +176,9 @@ ENTRY(sh_bios_handler)
        movml.l @r15+,r14
        add     #8,r15
        lds.l   @r15+, pr
+       mov.l   @r15+,r15
        rte
-        mov.l  @r15+,r15
+        nop
        .align  2
 1:     .long   gdb_vbr_vector
 #endif /* CONFIG_SH_STANDARD_BIOS */
index 3cb531f233f24cd27edcf1f8aedd7d86201c0d5c..67ad6467c694b43cfca77b28bd96ee9a3648c5a8 100644 (file)
@@ -137,6 +137,7 @@ ENTRY(tlb_protection_violation_store)
         mov    #1, r5
 
 call_dpf:
+       setup_frame_reg
        mov.l   1f, r0
        mov     r5, r8
        mov.l   @r0, r6
index ebdd391d5f429f115aaf3d23036283cd80f4ba9c..12cddf4c721d225b27ca9ea1ce4744880377e806 100644 (file)
@@ -25,9 +25,9 @@ clock-$(CONFIG_CPU_SUBTYPE_SH7780)    := clock-sh7780.o
 clock-$(CONFIG_CPU_SUBTYPE_SH7785)     := clock-sh7785.o
 clock-$(CONFIG_CPU_SUBTYPE_SH7786)     := clock-sh7786.o
 clock-$(CONFIG_CPU_SUBTYPE_SH7343)     := clock-sh7343.o
-clock-$(CONFIG_CPU_SUBTYPE_SH7722)     := clock-sh7722.o
-clock-$(CONFIG_CPU_SUBTYPE_SH7723)     := clock-sh7723.o
-clock-$(CONFIG_CPU_SUBTYPE_SH7724)     := clock-sh7724.o
+clock-$(CONFIG_CPU_SUBTYPE_SH7722)     := clock-sh7722.o hwblk-sh7722.o
+clock-$(CONFIG_CPU_SUBTYPE_SH7723)     := clock-sh7723.o hwblk-sh7723.o
+clock-$(CONFIG_CPU_SUBTYPE_SH7724)     := clock-sh7724.o hwblk-sh7724.o
 clock-$(CONFIG_CPU_SUBTYPE_SH7366)     := clock-sh7366.o
 clock-$(CONFIG_CPU_SUBTYPE_SHX3)       := clock-shx3.o
 
index 40f859354f793507c1a0feb7899f4840570f00b8..5b1bbbe63b1ba06c6854273852e7d832ba805d59 100644 (file)
@@ -22,6 +22,8 @@
 #include <linux/kernel.h>
 #include <linux/io.h>
 #include <asm/clock.h>
+#include <asm/hwblk.h>
+#include <cpu/sh7722.h>
 
 /* SH7722 registers */
 #define FRQCR          0xa4150000
@@ -30,9 +32,6 @@
 #define SCLKBCR                0xa415000c
 #define IRDACLKCR      0xa4150018
 #define PLLCR          0xa4150024
-#define MSTPCR0                0xa4150030
-#define MSTPCR1                0xa4150034
-#define MSTPCR2                0xa4150038
 #define DLLFRQ         0xa4150050
 
 /* Fixed 32 KHz root clock for RTC and Power Management purposes */
@@ -140,35 +139,37 @@ struct clk div6_clks[] = {
        SH_CLK_DIV6("video_clk", &pll_clk, VCLKCR, 0),
 };
 
-#define MSTP(_str, _parent, _reg, _bit, _flags) \
-  SH_CLK_MSTP32(_str, -1, _parent, _reg, _bit, _flags)
+#define R_CLK &r_clk
+#define P_CLK &div4_clks[DIV4_P]
+#define B_CLK &div4_clks[DIV4_B]
+#define U_CLK &div4_clks[DIV4_U]
 
 static struct clk mstp_clks[] = {
-       MSTP("uram0", &div4_clks[DIV4_U], MSTPCR0, 28, CLK_ENABLE_ON_INIT),
-       MSTP("xymem0", &div4_clks[DIV4_B], MSTPCR0, 26, CLK_ENABLE_ON_INIT),
-       MSTP("tmu0", &div4_clks[DIV4_P], MSTPCR0, 15, 0),
-       MSTP("cmt0", &r_clk, MSTPCR0, 14, 0),
-       MSTP("rwdt0", &r_clk, MSTPCR0, 13, 0),
-       MSTP("flctl0", &div4_clks[DIV4_P], MSTPCR0, 10, 0),
-       MSTP("scif0", &div4_clks[DIV4_P], MSTPCR0, 7, 0),
-       MSTP("scif1", &div4_clks[DIV4_P], MSTPCR0, 6, 0),
-       MSTP("scif2", &div4_clks[DIV4_P], MSTPCR0, 5, 0),
-
-       MSTP("i2c0", &div4_clks[DIV4_P], MSTPCR1, 9, 0),
-       MSTP("rtc0", &r_clk, MSTPCR1, 8, 0),
-
-       MSTP("sdhi0", &div4_clks[DIV4_P], MSTPCR2, 18, 0),
-       MSTP("keysc0", &r_clk, MSTPCR2, 14, 0),
-       MSTP("usbf0", &div4_clks[DIV4_P], MSTPCR2, 11, 0),
-       MSTP("2dg0", &div4_clks[DIV4_B], MSTPCR2, 9, 0),
-       MSTP("siu0", &div4_clks[DIV4_B], MSTPCR2, 8, 0),
-       MSTP("vou0", &div4_clks[DIV4_B], MSTPCR2, 5, 0),
-       MSTP("jpu0", &div4_clks[DIV4_B], MSTPCR2, 6, CLK_ENABLE_ON_INIT),
-       MSTP("beu0", &div4_clks[DIV4_B], MSTPCR2, 4, 0),
-       MSTP("ceu0", &div4_clks[DIV4_B], MSTPCR2, 3, 0),
-       MSTP("veu0", &div4_clks[DIV4_B], MSTPCR2, 2, CLK_ENABLE_ON_INIT),
-       MSTP("vpu0", &div4_clks[DIV4_B], MSTPCR2, 1, CLK_ENABLE_ON_INIT),
-       MSTP("lcdc0", &div4_clks[DIV4_B], MSTPCR2, 0, 0),
+       SH_HWBLK_CLK("uram0", -1, U_CLK, HWBLK_URAM, CLK_ENABLE_ON_INIT),
+       SH_HWBLK_CLK("xymem0", -1, B_CLK, HWBLK_XYMEM, CLK_ENABLE_ON_INIT),
+       SH_HWBLK_CLK("tmu0", -1, P_CLK, HWBLK_TMU, 0),
+       SH_HWBLK_CLK("cmt0", -1, R_CLK, HWBLK_CMT, 0),
+       SH_HWBLK_CLK("rwdt0", -1, R_CLK, HWBLK_RWDT, 0),
+       SH_HWBLK_CLK("flctl0", -1, P_CLK, HWBLK_FLCTL, 0),
+       SH_HWBLK_CLK("scif0", -1, P_CLK, HWBLK_SCIF0, 0),
+       SH_HWBLK_CLK("scif1", -1, P_CLK, HWBLK_SCIF1, 0),
+       SH_HWBLK_CLK("scif2", -1, P_CLK, HWBLK_SCIF2, 0),
+
+       SH_HWBLK_CLK("i2c0", -1, P_CLK, HWBLK_IIC, 0),
+       SH_HWBLK_CLK("rtc0", -1, R_CLK, HWBLK_RTC, 0),
+
+       SH_HWBLK_CLK("sdhi0", -1, P_CLK, HWBLK_SDHI, 0),
+       SH_HWBLK_CLK("keysc0", -1, R_CLK, HWBLK_KEYSC, 0),
+       SH_HWBLK_CLK("usbf0", -1, P_CLK, HWBLK_USBF, 0),
+       SH_HWBLK_CLK("2dg0", -1, B_CLK, HWBLK_2DG, 0),
+       SH_HWBLK_CLK("siu0", -1, B_CLK, HWBLK_SIU, 0),
+       SH_HWBLK_CLK("vou0", -1, B_CLK, HWBLK_VOU, 0),
+       SH_HWBLK_CLK("jpu0", -1, B_CLK, HWBLK_JPU, CLK_ENABLE_ON_INIT),
+       SH_HWBLK_CLK("beu0", -1, B_CLK, HWBLK_BEU, 0),
+       SH_HWBLK_CLK("ceu0", -1, B_CLK, HWBLK_CEU, 0),
+       SH_HWBLK_CLK("veu0", -1, B_CLK, HWBLK_VEU, CLK_ENABLE_ON_INIT),
+       SH_HWBLK_CLK("vpu0", -1, B_CLK, HWBLK_VPU, CLK_ENABLE_ON_INIT),
+       SH_HWBLK_CLK("lcdc0", -1, P_CLK, HWBLK_LCDC, 0),
 };
 
 int __init arch_clk_init(void)
@@ -191,7 +192,7 @@ int __init arch_clk_init(void)
                ret = sh_clk_div6_register(div6_clks, ARRAY_SIZE(div6_clks));
 
        if (!ret)
-               ret = sh_clk_mstp32_register(mstp_clks, ARRAY_SIZE(mstp_clks));
+               ret = sh_hwblk_clk_register(mstp_clks, ARRAY_SIZE(mstp_clks));
 
        return ret;
 }
index e67c2678b8ae61ae058696884149b05391733508..e5c63911403ceaa6a952f48bddff6206033a6027 100644 (file)
@@ -22,6 +22,8 @@
 #include <linux/kernel.h>
 #include <linux/io.h>
 #include <asm/clock.h>
+#include <asm/hwblk.h>
+#include <cpu/sh7723.h>
 
 /* SH7723 registers */
 #define FRQCR          0xa4150000
@@ -30,9 +32,6 @@
 #define SCLKBCR                0xa415000c
 #define IRDACLKCR      0xa4150018
 #define PLLCR          0xa4150024
-#define MSTPCR0                0xa4150030
-#define MSTPCR1                0xa4150034
-#define MSTPCR2                0xa4150038
 #define DLLFRQ         0xa4150050
 
 /* Fixed 32 KHz root clock for RTC and Power Management purposes */
@@ -140,60 +139,64 @@ struct clk div6_clks[] = {
        SH_CLK_DIV6("video_clk", &pll_clk, VCLKCR, 0),
 };
 
-#define MSTP(_str, _parent, _reg, _bit, _force_on, _need_cpg, _need_ram) \
-  SH_CLK_MSTP32(_str, -1, _parent, _reg, _bit, _force_on * CLK_ENABLE_ON_INIT)
+#define R_CLK (&r_clk)
+#define P_CLK (&div4_clks[DIV4_P])
+#define B_CLK (&div4_clks[DIV4_B])
+#define U_CLK (&div4_clks[DIV4_U])
+#define I_CLK (&div4_clks[DIV4_I])
+#define SH_CLK (&div4_clks[DIV4_SH])
 
 static struct clk mstp_clks[] = {
        /* See page 60 of Datasheet V1.0: Overview -> Block Diagram */
-       MSTP("tlb0", &div4_clks[DIV4_I], MSTPCR0, 31, 1, 1, 0),
-       MSTP("ic0", &div4_clks[DIV4_I], MSTPCR0, 30, 1, 1, 0),
-       MSTP("oc0", &div4_clks[DIV4_I], MSTPCR0, 29, 1, 1, 0),
-       MSTP("l2c0", &div4_clks[DIV4_SH], MSTPCR0, 28, 1, 1, 0),
-       MSTP("ilmem0", &div4_clks[DIV4_I], MSTPCR0, 27, 1, 1, 0),
-       MSTP("fpu0", &div4_clks[DIV4_I], MSTPCR0, 24, 1, 1, 0),
-       MSTP("intc0", &div4_clks[DIV4_I], MSTPCR0, 22, 1, 1, 0),
-       MSTP("dmac0", &div4_clks[DIV4_B], MSTPCR0, 21, 0, 1, 1),
-       MSTP("sh0", &div4_clks[DIV4_SH], MSTPCR0, 20, 0, 1, 0),
-       MSTP("hudi0", &div4_clks[DIV4_P], MSTPCR0, 19, 0, 1, 0),
-       MSTP("ubc0", &div4_clks[DIV4_I], MSTPCR0, 17, 0, 1, 0),
-       MSTP("tmu0", &div4_clks[DIV4_P], MSTPCR0, 15, 0, 1, 0),
-       MSTP("cmt0", &r_clk, MSTPCR0, 14, 0, 0, 0),
-       MSTP("rwdt0", &r_clk, MSTPCR0, 13, 0, 0, 0),
-       MSTP("dmac1", &div4_clks[DIV4_B], MSTPCR0, 12, 0, 1, 1),
-       MSTP("tmu1", &div4_clks[DIV4_P], MSTPCR0, 11, 0, 1, 0),
-       MSTP("flctl0", &div4_clks[DIV4_P], MSTPCR0, 10, 0, 1, 0),
-       MSTP("scif0", &div4_clks[DIV4_P], MSTPCR0, 9, 0, 1, 0),
-       MSTP("scif1", &div4_clks[DIV4_P], MSTPCR0, 8, 0, 1, 0),
-       MSTP("scif2", &div4_clks[DIV4_P], MSTPCR0, 7, 0, 1, 0),
-       MSTP("scif3", &div4_clks[DIV4_B], MSTPCR0, 6, 0, 1, 0),
-       MSTP("scif4", &div4_clks[DIV4_B], MSTPCR0, 5, 0, 1, 0),
-       MSTP("scif5", &div4_clks[DIV4_B], MSTPCR0, 4, 0, 1, 0),
-       MSTP("msiof0", &div4_clks[DIV4_B], MSTPCR0, 2, 0, 1, 0),
-       MSTP("msiof1", &div4_clks[DIV4_B], MSTPCR0, 1, 0, 1, 0),
-       MSTP("meram0", &div4_clks[DIV4_SH], MSTPCR0, 0, 1, 1, 0),
-
-       MSTP("i2c0", &div4_clks[DIV4_P], MSTPCR1, 9, 0, 1, 0),
-       MSTP("rtc0", &r_clk, MSTPCR1, 8, 0, 0, 0),
-
-       MSTP("atapi0", &div4_clks[DIV4_SH], MSTPCR2, 28, 0, 1, 0),
-       MSTP("adc0", &div4_clks[DIV4_P], MSTPCR2, 27, 0, 1, 0),
-       MSTP("tpu0", &div4_clks[DIV4_B], MSTPCR2, 25, 0, 1, 0),
-       MSTP("irda0", &div4_clks[DIV4_P], MSTPCR2, 24, 0, 1, 0),
-       MSTP("tsif0", &div4_clks[DIV4_B], MSTPCR2, 22, 0, 1, 0),
-       MSTP("icb0", &div4_clks[DIV4_B], MSTPCR2, 21, 0, 1, 1),
-       MSTP("sdhi0", &div4_clks[DIV4_B], MSTPCR2, 18, 0, 1, 0),
-       MSTP("sdhi1", &div4_clks[DIV4_B], MSTPCR2, 17, 0, 1, 0),
-       MSTP("keysc0", &r_clk, MSTPCR2, 14, 0, 0, 0),
-       MSTP("usb0", &div4_clks[DIV4_B], MSTPCR2, 11, 0, 1, 0),
-       MSTP("2dg0", &div4_clks[DIV4_B], MSTPCR2, 10, 0, 1, 1),
-       MSTP("siu0", &div4_clks[DIV4_B], MSTPCR2, 8, 0, 1, 0),
-       MSTP("veu1", &div4_clks[DIV4_B], MSTPCR2, 6, 1, 1, 1),
-       MSTP("vou0", &div4_clks[DIV4_B], MSTPCR2, 5, 0, 1, 1),
-       MSTP("beu0", &div4_clks[DIV4_B], MSTPCR2, 4, 0, 1, 1),
-       MSTP("ceu0", &div4_clks[DIV4_B], MSTPCR2, 3, 0, 1, 1),
-       MSTP("veu0", &div4_clks[DIV4_B], MSTPCR2, 2, 1, 1, 1),
-       MSTP("vpu0", &div4_clks[DIV4_B], MSTPCR2, 1, 1, 1, 1),
-       MSTP("lcdc0", &div4_clks[DIV4_B], MSTPCR2, 0, 0, 1, 1),
+       SH_HWBLK_CLK("tlb0", -1, I_CLK, HWBLK_TLB, CLK_ENABLE_ON_INIT),
+       SH_HWBLK_CLK("ic0", -1, I_CLK, HWBLK_IC, CLK_ENABLE_ON_INIT),
+       SH_HWBLK_CLK("oc0", -1, I_CLK, HWBLK_OC, CLK_ENABLE_ON_INIT),
+       SH_HWBLK_CLK("l2c0", -1, SH_CLK, HWBLK_L2C, CLK_ENABLE_ON_INIT),
+       SH_HWBLK_CLK("ilmem0", -1, I_CLK, HWBLK_ILMEM, CLK_ENABLE_ON_INIT),
+       SH_HWBLK_CLK("fpu0", -1, I_CLK, HWBLK_FPU, CLK_ENABLE_ON_INIT),
+       SH_HWBLK_CLK("intc0", -1, I_CLK, HWBLK_INTC, CLK_ENABLE_ON_INIT),
+       SH_HWBLK_CLK("dmac0", -1, B_CLK, HWBLK_DMAC0, 0),
+       SH_HWBLK_CLK("sh0", -1, SH_CLK, HWBLK_SHYWAY, CLK_ENABLE_ON_INIT),
+       SH_HWBLK_CLK("hudi0", -1, P_CLK, HWBLK_HUDI, 0),
+       SH_HWBLK_CLK("ubc0", -1, I_CLK, HWBLK_UBC, 0),
+       SH_HWBLK_CLK("tmu0", -1, P_CLK, HWBLK_TMU0, 0),
+       SH_HWBLK_CLK("cmt0", -1, R_CLK, HWBLK_CMT, 0),
+       SH_HWBLK_CLK("rwdt0", -1, R_CLK, HWBLK_RWDT, 0),
+       SH_HWBLK_CLK("dmac1", -1, B_CLK, HWBLK_DMAC1, 0),
+       SH_HWBLK_CLK("tmu1", -1, P_CLK, HWBLK_TMU1, 0),
+       SH_HWBLK_CLK("flctl0", -1, P_CLK, HWBLK_FLCTL, 0),
+       SH_HWBLK_CLK("scif0", -1, P_CLK, HWBLK_SCIF0, 0),
+       SH_HWBLK_CLK("scif1", -1, P_CLK, HWBLK_SCIF1, 0),
+       SH_HWBLK_CLK("scif2", -1, P_CLK, HWBLK_SCIF2, 0),
+       SH_HWBLK_CLK("scif3", -1, B_CLK, HWBLK_SCIF3, 0),
+       SH_HWBLK_CLK("scif4", -1, B_CLK, HWBLK_SCIF4, 0),
+       SH_HWBLK_CLK("scif5", -1, B_CLK, HWBLK_SCIF5, 0),
+       SH_HWBLK_CLK("msiof0", -1, B_CLK, HWBLK_MSIOF0, 0),
+       SH_HWBLK_CLK("msiof1", -1, B_CLK, HWBLK_MSIOF1, 0),
+       SH_HWBLK_CLK("meram0", -1, SH_CLK, HWBLK_MERAM, 0),
+
+       SH_HWBLK_CLK("i2c0", -1, P_CLK, HWBLK_IIC, 0),
+       SH_HWBLK_CLK("rtc0", -1, R_CLK, HWBLK_RTC, 0),
+
+       SH_HWBLK_CLK("atapi0", -1, SH_CLK, HWBLK_ATAPI, 0),
+       SH_HWBLK_CLK("adc0", -1, P_CLK, HWBLK_ADC, 0),
+       SH_HWBLK_CLK("tpu0", -1, B_CLK, HWBLK_TPU, 0),
+       SH_HWBLK_CLK("irda0", -1, P_CLK, HWBLK_IRDA, 0),
+       SH_HWBLK_CLK("tsif0", -1, B_CLK, HWBLK_TSIF, 0),
+       SH_HWBLK_CLK("icb0", -1, B_CLK, HWBLK_ICB, CLK_ENABLE_ON_INIT),
+       SH_HWBLK_CLK("sdhi0", -1, B_CLK, HWBLK_SDHI0, 0),
+       SH_HWBLK_CLK("sdhi1", -1, B_CLK, HWBLK_SDHI1, 0),
+       SH_HWBLK_CLK("keysc0", -1, R_CLK, HWBLK_KEYSC, 0),
+       SH_HWBLK_CLK("usb0", -1, B_CLK, HWBLK_USB, 0),
+       SH_HWBLK_CLK("2dg0", -1, B_CLK, HWBLK_2DG, 0),
+       SH_HWBLK_CLK("siu0", -1, B_CLK, HWBLK_SIU, 0),
+       SH_HWBLK_CLK("veu1", -1, B_CLK, HWBLK_VEU2H1, CLK_ENABLE_ON_INIT),
+       SH_HWBLK_CLK("vou0", -1, B_CLK, HWBLK_VOU, 0),
+       SH_HWBLK_CLK("beu0", -1, B_CLK, HWBLK_BEU, 0),
+       SH_HWBLK_CLK("ceu0", -1, B_CLK, HWBLK_CEU, 0),
+       SH_HWBLK_CLK("veu0", -1, B_CLK, HWBLK_VEU2H0, CLK_ENABLE_ON_INIT),
+       SH_HWBLK_CLK("vpu0", -1, B_CLK, HWBLK_VPU, CLK_ENABLE_ON_INIT),
+       SH_HWBLK_CLK("lcdc0", -1, B_CLK, HWBLK_LCDC, 0),
 };
 
 int __init arch_clk_init(void)
@@ -216,7 +219,7 @@ int __init arch_clk_init(void)
                ret = sh_clk_div6_register(div6_clks, ARRAY_SIZE(div6_clks));
 
        if (!ret)
-               ret = sh_clk_mstp32_register(mstp_clks, ARRAY_SIZE(mstp_clks));
+               ret = sh_hwblk_clk_register(mstp_clks, ARRAY_SIZE(mstp_clks));
 
        return ret;
 }
index 5d5c9b952883a6d5d60bb3bae5e11befec71a3cc..34611d97378e82d3483f08d0813d564866d30960 100644 (file)
@@ -22,6 +22,8 @@
 #include <linux/kernel.h>
 #include <linux/io.h>
 #include <asm/clock.h>
+#include <asm/hwblk.h>
+#include <cpu/sh7724.h>
 
 /* SH7724 registers */
 #define FRQCRA         0xa4150000
@@ -31,9 +33,6 @@
 #define FCLKBCR                0xa415000c
 #define IRDACLKCR      0xa4150018
 #define PLLCR          0xa4150024
-#define MSTPCR0                0xa4150030
-#define MSTPCR1                0xa4150034
-#define MSTPCR2                0xa4150038
 #define SPUCLKCR       0xa415003c
 #define FLLFRQ         0xa4150050
 #define LSTATS         0xa4150060
@@ -156,64 +155,67 @@ struct clk div6_clks[] = {
        SH_CLK_DIV6("spu_clk", &div3_clk, SPUCLKCR, 0),
 };
 
-#define MSTP(_str, _parent, _reg, _bit, _force_on, _need_cpg, _need_ram) \
-  SH_CLK_MSTP32(_str, -1, _parent, _reg, _bit, _force_on * CLK_ENABLE_ON_INIT)
+#define R_CLK (&r_clk)
+#define P_CLK (&div4_clks[DIV4_P])
+#define B_CLK (&div4_clks[DIV4_B])
+#define I_CLK (&div4_clks[DIV4_I])
+#define SH_CLK (&div4_clks[DIV4_SH])
 
 static struct clk mstp_clks[] = {
-       MSTP("tlb0", &div4_clks[DIV4_I], MSTPCR0, 31, 1, 1, 0),
-       MSTP("ic0", &div4_clks[DIV4_I], MSTPCR0, 30, 1, 1, 0),
-       MSTP("oc0", &div4_clks[DIV4_I], MSTPCR0, 29, 1, 1, 0),
-       MSTP("rs0", &div4_clks[DIV4_B], MSTPCR0, 28, 1, 1, 0),
-       MSTP("ilmem0", &div4_clks[DIV4_I], MSTPCR0, 27, 1, 1, 0),
-       MSTP("l2c0", &div4_clks[DIV4_SH], MSTPCR0, 26, 1, 1, 0),
-       MSTP("fpu0", &div4_clks[DIV4_I], MSTPCR0, 24, 1, 1, 0),
-       MSTP("intc0", &div4_clks[DIV4_P], MSTPCR0, 22, 1, 1, 0),
-       MSTP("dmac0", &div4_clks[DIV4_B], MSTPCR0, 21, 0, 1, 1),
-       MSTP("sh0", &div4_clks[DIV4_SH], MSTPCR0, 20, 0, 1, 0),
-       MSTP("hudi0", &div4_clks[DIV4_P], MSTPCR0, 19, 0, 1, 0),
-       MSTP("ubc0", &div4_clks[DIV4_I], MSTPCR0, 17, 0, 1, 0),
-       MSTP("tmu0", &div4_clks[DIV4_P], MSTPCR0, 15, 0, 1, 0),
-       MSTP("cmt0", &r_clk, MSTPCR0, 14, 0, 0, 0),
-       MSTP("rwdt0", &r_clk, MSTPCR0, 13, 0, 0, 0),
-       MSTP("dmac1", &div4_clks[DIV4_B], MSTPCR0, 12, 0, 1, 1),
-       MSTP("tmu1", &div4_clks[DIV4_P], MSTPCR0, 10, 0, 1, 0),
-       MSTP("scif0", &div4_clks[DIV4_P], MSTPCR0, 9, 0, 1, 0),
-       MSTP("scif1", &div4_clks[DIV4_P], MSTPCR0, 8, 0, 1, 0),
-       MSTP("scif2", &div4_clks[DIV4_P], MSTPCR0, 7, 0, 1, 0),
-       MSTP("scif3", &div4_clks[DIV4_B], MSTPCR0, 6, 0, 1, 0),
-       MSTP("scif4", &div4_clks[DIV4_B], MSTPCR0, 5, 0, 1, 0),
-       MSTP("scif5", &div4_clks[DIV4_B], MSTPCR0, 4, 0, 1, 0),
-       MSTP("msiof0", &div4_clks[DIV4_B], MSTPCR0, 2, 0, 1, 0),
-       MSTP("msiof1", &div4_clks[DIV4_B], MSTPCR0, 1, 0, 1, 0),
-
-       MSTP("keysc0", &r_clk, MSTPCR1, 12, 0, 0, 0),
-       MSTP("rtc0", &r_clk, MSTPCR1, 11, 0, 0, 0),
-       MSTP("i2c0", &div4_clks[DIV4_P], MSTPCR1, 9, 0, 1, 0),
-       MSTP("i2c1", &div4_clks[DIV4_P], MSTPCR1, 8, 0, 1, 0),
-
-       MSTP("mmc0", &div4_clks[DIV4_B], MSTPCR2, 29, 0, 1, 0),
-       MSTP("eth0", &div4_clks[DIV4_B], MSTPCR2, 28, 0, 1, 0),
-       MSTP("atapi0", &div4_clks[DIV4_B], MSTPCR2, 26, 0, 1, 0),
-       MSTP("tpu0", &div4_clks[DIV4_B], MSTPCR2, 25, 0, 1, 0),
-       MSTP("irda0", &div4_clks[DIV4_P], MSTPCR2, 24, 0, 1, 0),
-       MSTP("tsif0", &div4_clks[DIV4_B], MSTPCR2, 22, 0, 1, 0),
-       MSTP("usb1", &div4_clks[DIV4_B], MSTPCR2, 21, 0, 1, 1),
-       MSTP("usb0", &div4_clks[DIV4_B], MSTPCR2, 20, 0, 1, 1),
-       MSTP("2dg0", &div4_clks[DIV4_B], MSTPCR2, 19, 0, 1, 1),
-       MSTP("sdhi0", &div4_clks[DIV4_B], MSTPCR2, 18, 0, 1, 0),
-       MSTP("sdhi1", &div4_clks[DIV4_B], MSTPCR2, 17, 0, 1, 0),
-       MSTP("veu1", &div4_clks[DIV4_B], MSTPCR2, 15, 1, 1, 1),
-       MSTP("ceu1", &div4_clks[DIV4_B], MSTPCR2, 13, 0, 1, 1),
-       MSTP("beu1", &div4_clks[DIV4_B], MSTPCR2, 12, 0, 1, 1),
-       MSTP("2ddmac0", &div4_clks[DIV4_SH], MSTPCR2, 10, 0, 1, 1),
-       MSTP("spu0", &div4_clks[DIV4_B], MSTPCR2, 9, 0, 1, 0),
-       MSTP("jpu0", &div4_clks[DIV4_B], MSTPCR2, 6, 1, 1, 1),
-       MSTP("vou0", &div4_clks[DIV4_B], MSTPCR2, 5, 0, 1, 1),
-       MSTP("beu0", &div4_clks[DIV4_B], MSTPCR2, 4, 0, 1, 1),
-       MSTP("ceu0", &div4_clks[DIV4_B], MSTPCR2, 3, 0, 1, 1),
-       MSTP("veu0", &div4_clks[DIV4_B], MSTPCR2, 2, 1, 1, 1),
-       MSTP("vpu0", &div4_clks[DIV4_B], MSTPCR2, 1, 1, 1, 1),
-       MSTP("lcdc0", &div4_clks[DIV4_B], MSTPCR2, 0, 0, 1, 1),
+       SH_HWBLK_CLK("tlb0", -1, I_CLK, HWBLK_TLB, CLK_ENABLE_ON_INIT),
+       SH_HWBLK_CLK("ic0", -1, I_CLK, HWBLK_IC, CLK_ENABLE_ON_INIT),
+       SH_HWBLK_CLK("oc0", -1, I_CLK, HWBLK_OC, CLK_ENABLE_ON_INIT),
+       SH_HWBLK_CLK("rs0", -1, B_CLK, HWBLK_RSMEM, CLK_ENABLE_ON_INIT),
+       SH_HWBLK_CLK("ilmem0", -1, I_CLK, HWBLK_ILMEM, CLK_ENABLE_ON_INIT),
+       SH_HWBLK_CLK("l2c0", -1, SH_CLK, HWBLK_L2C, CLK_ENABLE_ON_INIT),
+       SH_HWBLK_CLK("fpu0", -1, I_CLK, HWBLK_FPU, CLK_ENABLE_ON_INIT),
+       SH_HWBLK_CLK("intc0", -1, P_CLK, HWBLK_INTC, CLK_ENABLE_ON_INIT),
+       SH_HWBLK_CLK("dmac0", -1, B_CLK, HWBLK_DMAC0, 0),
+       SH_HWBLK_CLK("sh0", -1, SH_CLK, HWBLK_SHYWAY, CLK_ENABLE_ON_INIT),
+       SH_HWBLK_CLK("hudi0", -1, P_CLK, HWBLK_HUDI, 0),
+       SH_HWBLK_CLK("ubc0", -1, I_CLK, HWBLK_UBC, 0),
+       SH_HWBLK_CLK("tmu0", -1, P_CLK, HWBLK_TMU0, 0),
+       SH_HWBLK_CLK("cmt0", -1, R_CLK, HWBLK_CMT, 0),
+       SH_HWBLK_CLK("rwdt0", -1, R_CLK, HWBLK_RWDT, 0),
+       SH_HWBLK_CLK("dmac1", -1, B_CLK, HWBLK_DMAC1, 0),
+       SH_HWBLK_CLK("tmu1", -1, P_CLK, HWBLK_TMU1, 0),
+       SH_HWBLK_CLK("scif0", -1, P_CLK, HWBLK_SCIF0, 0),
+       SH_HWBLK_CLK("scif1", -1, P_CLK, HWBLK_SCIF1, 0),
+       SH_HWBLK_CLK("scif2", -1, P_CLK, HWBLK_SCIF2, 0),
+       SH_HWBLK_CLK("scif3", -1, B_CLK, HWBLK_SCIF3, 0),
+       SH_HWBLK_CLK("scif4", -1, B_CLK, HWBLK_SCIF4, 0),
+       SH_HWBLK_CLK("scif5", -1, B_CLK, HWBLK_SCIF5, 0),
+       SH_HWBLK_CLK("msiof0", -1, B_CLK, HWBLK_MSIOF0, 0),
+       SH_HWBLK_CLK("msiof1", -1, B_CLK, HWBLK_MSIOF1, 0),
+
+       SH_HWBLK_CLK("keysc0", -1, R_CLK, HWBLK_KEYSC, 0),
+       SH_HWBLK_CLK("rtc0", -1, R_CLK, HWBLK_RTC, 0),
+       SH_HWBLK_CLK("i2c0", -1, P_CLK, HWBLK_IIC0, 0),
+       SH_HWBLK_CLK("i2c1", -1, P_CLK, HWBLK_IIC1, 0),
+
+       SH_HWBLK_CLK("mmc0", -1, B_CLK, HWBLK_MMC, 0),
+       SH_HWBLK_CLK("eth0", -1, B_CLK, HWBLK_ETHER, 0),
+       SH_HWBLK_CLK("atapi0", -1, B_CLK, HWBLK_ATAPI, 0),
+       SH_HWBLK_CLK("tpu0", -1, B_CLK, HWBLK_TPU, 0),
+       SH_HWBLK_CLK("irda0", -1, P_CLK, HWBLK_IRDA, 0),
+       SH_HWBLK_CLK("tsif0", -1, B_CLK, HWBLK_TSIF, 0),
+       SH_HWBLK_CLK("usb1", -1, B_CLK, HWBLK_USB1, 0),
+       SH_HWBLK_CLK("usb0", -1, B_CLK, HWBLK_USB0, 0),
+       SH_HWBLK_CLK("2dg0", -1, B_CLK, HWBLK_2DG, 0),
+       SH_HWBLK_CLK("sdhi0", -1, B_CLK, HWBLK_SDHI0, 0),
+       SH_HWBLK_CLK("sdhi1", -1, B_CLK, HWBLK_SDHI1, 0),
+       SH_HWBLK_CLK("veu1", -1, B_CLK, HWBLK_VEU1, CLK_ENABLE_ON_INIT),
+       SH_HWBLK_CLK("ceu1", -1, B_CLK, HWBLK_CEU1, 0),
+       SH_HWBLK_CLK("beu1", -1, B_CLK, HWBLK_BEU1, 0),
+       SH_HWBLK_CLK("2ddmac0", -1, SH_CLK, HWBLK_2DDMAC, 0),
+       SH_HWBLK_CLK("spu0", -1, B_CLK, HWBLK_SPU, 0),
+       SH_HWBLK_CLK("jpu0", -1, B_CLK, HWBLK_JPU, CLK_ENABLE_ON_INIT),
+       SH_HWBLK_CLK("vou0", -1, B_CLK, HWBLK_VOU, 0),
+       SH_HWBLK_CLK("beu0", -1, B_CLK, HWBLK_BEU0, 0),
+       SH_HWBLK_CLK("ceu0", -1, B_CLK, HWBLK_CEU0, 0),
+       SH_HWBLK_CLK("veu0", -1, B_CLK, HWBLK_VEU0, CLK_ENABLE_ON_INIT),
+       SH_HWBLK_CLK("vpu0", -1, B_CLK, HWBLK_VPU, CLK_ENABLE_ON_INIT),
+       SH_HWBLK_CLK("lcdc0", -1, B_CLK, HWBLK_LCDC, 0),
 };
 
 int __init arch_clk_init(void)
@@ -236,7 +238,7 @@ int __init arch_clk_init(void)
                ret = sh_clk_div6_register(div6_clks, ARRAY_SIZE(div6_clks));
 
        if (!ret)
-               ret = sh_clk_mstp32_register(mstp_clks, ARRAY_SIZE(mstp_clks));
+               ret = sh_hwblk_clk_register(mstp_clks, ARRAY_SIZE(mstp_clks));
 
        return ret;
 }
diff --git a/arch/sh/kernel/cpu/sh4a/hwblk-sh7722.c b/arch/sh/kernel/cpu/sh4a/hwblk-sh7722.c
new file mode 100644 (file)
index 0000000..a288b5d
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ * arch/sh/kernel/cpu/sh4a/hwblk-sh7722.c
+ *
+ * SH7722 hardware block support
+ *
+ * Copyright (C) 2009 Magnus Damm
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <asm/suspend.h>
+#include <asm/hwblk.h>
+#include <cpu/sh7722.h>
+
+/* SH7722 registers */
+#define MSTPCR0                0xa4150030
+#define MSTPCR1                0xa4150034
+#define MSTPCR2                0xa4150038
+
+/* SH7722 Power Domains */
+enum { CORE_AREA, SUB_AREA, CORE_AREA_BM };
+static struct hwblk_area sh7722_hwblk_area[] = {
+       [CORE_AREA] = HWBLK_AREA(0, 0),
+       [CORE_AREA_BM] = HWBLK_AREA(HWBLK_AREA_FLAG_PARENT, CORE_AREA),
+       [SUB_AREA] = HWBLK_AREA(0, 0),
+};
+
+/* Table mapping HWBLK to Module Stop Bit and Power Domain */
+static struct hwblk sh7722_hwblk[HWBLK_NR] = {
+       [HWBLK_TLB] = HWBLK(MSTPCR0, 31, CORE_AREA),
+       [HWBLK_IC] = HWBLK(MSTPCR0, 30, CORE_AREA),
+       [HWBLK_OC] = HWBLK(MSTPCR0, 29, CORE_AREA),
+       [HWBLK_URAM] = HWBLK(MSTPCR0, 28, CORE_AREA),
+       [HWBLK_XYMEM] = HWBLK(MSTPCR0, 26, CORE_AREA),
+       [HWBLK_INTC] = HWBLK(MSTPCR0, 22, CORE_AREA),
+       [HWBLK_DMAC] = HWBLK(MSTPCR0, 21, CORE_AREA_BM),
+       [HWBLK_SHYWAY] = HWBLK(MSTPCR0, 20, CORE_AREA),
+       [HWBLK_HUDI] = HWBLK(MSTPCR0, 19, CORE_AREA),
+       [HWBLK_UBC] = HWBLK(MSTPCR0, 17, CORE_AREA),
+       [HWBLK_TMU] = HWBLK(MSTPCR0, 15, CORE_AREA),
+       [HWBLK_CMT] = HWBLK(MSTPCR0, 14, SUB_AREA),
+       [HWBLK_RWDT] = HWBLK(MSTPCR0, 13, SUB_AREA),
+       [HWBLK_FLCTL] = HWBLK(MSTPCR0, 10, CORE_AREA),
+       [HWBLK_SCIF0] = HWBLK(MSTPCR0, 7, CORE_AREA),
+       [HWBLK_SCIF1] = HWBLK(MSTPCR0, 6, CORE_AREA),
+       [HWBLK_SCIF2] = HWBLK(MSTPCR0, 5, CORE_AREA),
+       [HWBLK_SIO] = HWBLK(MSTPCR0, 3, CORE_AREA),
+       [HWBLK_SIOF0] = HWBLK(MSTPCR0, 2, CORE_AREA),
+       [HWBLK_SIOF1] = HWBLK(MSTPCR0, 1, CORE_AREA),
+
+       [HWBLK_IIC] = HWBLK(MSTPCR1, 9, CORE_AREA),
+       [HWBLK_RTC] = HWBLK(MSTPCR1, 8, SUB_AREA),
+
+       [HWBLK_TPU] = HWBLK(MSTPCR2, 25, CORE_AREA),
+       [HWBLK_IRDA] = HWBLK(MSTPCR2, 24, CORE_AREA),
+       [HWBLK_SDHI] = HWBLK(MSTPCR2, 18, CORE_AREA),
+       [HWBLK_SIM] = HWBLK(MSTPCR2, 16, CORE_AREA),
+       [HWBLK_KEYSC] = HWBLK(MSTPCR2, 14, SUB_AREA),
+       [HWBLK_TSIF] = HWBLK(MSTPCR2, 13, SUB_AREA),
+       [HWBLK_USBF] = HWBLK(MSTPCR2, 11, CORE_AREA),
+       [HWBLK_2DG] = HWBLK(MSTPCR2, 9, CORE_AREA_BM),
+       [HWBLK_SIU] = HWBLK(MSTPCR2, 8, CORE_AREA),
+       [HWBLK_JPU] = HWBLK(MSTPCR2, 6, CORE_AREA_BM),
+       [HWBLK_VOU] = HWBLK(MSTPCR2, 5, CORE_AREA_BM),
+       [HWBLK_BEU] = HWBLK(MSTPCR2, 4, CORE_AREA_BM),
+       [HWBLK_CEU] = HWBLK(MSTPCR2, 3, CORE_AREA_BM),
+       [HWBLK_VEU] = HWBLK(MSTPCR2, 2, CORE_AREA_BM),
+       [HWBLK_VPU] = HWBLK(MSTPCR2, 1, CORE_AREA_BM),
+       [HWBLK_LCDC] = HWBLK(MSTPCR2, 0, CORE_AREA_BM),
+};
+
+static struct hwblk_info sh7722_hwblk_info = {
+       .areas = sh7722_hwblk_area,
+       .nr_areas = ARRAY_SIZE(sh7722_hwblk_area),
+       .hwblks = sh7722_hwblk,
+       .nr_hwblks = ARRAY_SIZE(sh7722_hwblk),
+};
+
+int arch_hwblk_sleep_mode(void)
+{
+       if (!sh7722_hwblk_area[CORE_AREA].cnt[HWBLK_CNT_USAGE])
+               return SUSP_SH_STANDBY | SUSP_SH_SF;
+
+       if (!sh7722_hwblk_area[CORE_AREA_BM].cnt[HWBLK_CNT_USAGE])
+               return SUSP_SH_SLEEP | SUSP_SH_SF;
+
+       return SUSP_SH_SLEEP;
+}
+
+int __init arch_hwblk_init(void)
+{
+       return hwblk_register(&sh7722_hwblk_info);
+}
diff --git a/arch/sh/kernel/cpu/sh4a/hwblk-sh7723.c b/arch/sh/kernel/cpu/sh4a/hwblk-sh7723.c
new file mode 100644 (file)
index 0000000..a7f4684
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * arch/sh/kernel/cpu/sh4a/hwblk-sh7723.c
+ *
+ * SH7723 hardware block support
+ *
+ * Copyright (C) 2009 Magnus Damm
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <asm/suspend.h>
+#include <asm/hwblk.h>
+#include <cpu/sh7723.h>
+
+/* SH7723 registers */
+#define MSTPCR0                0xa4150030
+#define MSTPCR1                0xa4150034
+#define MSTPCR2                0xa4150038
+
+/* SH7723 Power Domains */
+enum { CORE_AREA, SUB_AREA, CORE_AREA_BM };
+static struct hwblk_area sh7723_hwblk_area[] = {
+       [CORE_AREA] = HWBLK_AREA(0, 0),
+       [CORE_AREA_BM] = HWBLK_AREA(HWBLK_AREA_FLAG_PARENT, CORE_AREA),
+       [SUB_AREA] = HWBLK_AREA(0, 0),
+};
+
+/* Table mapping HWBLK to Module Stop Bit and Power Domain */
+static struct hwblk sh7723_hwblk[HWBLK_NR] = {
+       [HWBLK_TLB] = HWBLK(MSTPCR0, 31, CORE_AREA),
+       [HWBLK_IC] = HWBLK(MSTPCR0, 30, CORE_AREA),
+       [HWBLK_OC] = HWBLK(MSTPCR0, 29, CORE_AREA),
+       [HWBLK_L2C] = HWBLK(MSTPCR0, 28, CORE_AREA),
+       [HWBLK_ILMEM] = HWBLK(MSTPCR0, 27, CORE_AREA),
+       [HWBLK_FPU] = HWBLK(MSTPCR0, 24, CORE_AREA),
+       [HWBLK_INTC] = HWBLK(MSTPCR0, 22, CORE_AREA),
+       [HWBLK_DMAC0] = HWBLK(MSTPCR0, 21, CORE_AREA_BM),
+       [HWBLK_SHYWAY] = HWBLK(MSTPCR0, 20, CORE_AREA),
+       [HWBLK_HUDI] = HWBLK(MSTPCR0, 19, CORE_AREA),
+       [HWBLK_DBG] = HWBLK(MSTPCR0, 18, CORE_AREA),
+       [HWBLK_UBC] = HWBLK(MSTPCR0, 17, CORE_AREA),
+       [HWBLK_SUBC] = HWBLK(MSTPCR0, 16, CORE_AREA),
+       [HWBLK_TMU0] = HWBLK(MSTPCR0, 15, CORE_AREA),
+       [HWBLK_CMT] = HWBLK(MSTPCR0, 14, SUB_AREA),
+       [HWBLK_RWDT] = HWBLK(MSTPCR0, 13, SUB_AREA),
+       [HWBLK_DMAC1] = HWBLK(MSTPCR0, 12, CORE_AREA_BM),
+       [HWBLK_TMU1] = HWBLK(MSTPCR0, 11, CORE_AREA),
+       [HWBLK_FLCTL] = HWBLK(MSTPCR0, 10, CORE_AREA),
+       [HWBLK_SCIF0] = HWBLK(MSTPCR0, 9, CORE_AREA),
+       [HWBLK_SCIF1] = HWBLK(MSTPCR0, 8, CORE_AREA),
+       [HWBLK_SCIF2] = HWBLK(MSTPCR0, 7, CORE_AREA),
+       [HWBLK_SCIF3] = HWBLK(MSTPCR0, 6, CORE_AREA),
+       [HWBLK_SCIF4] = HWBLK(MSTPCR0, 5, CORE_AREA),
+       [HWBLK_SCIF5] = HWBLK(MSTPCR0, 4, CORE_AREA),
+       [HWBLK_MSIOF0] = HWBLK(MSTPCR0, 2, CORE_AREA),
+       [HWBLK_MSIOF1] = HWBLK(MSTPCR0, 1, CORE_AREA),
+       [HWBLK_MERAM] = HWBLK(MSTPCR0, 0, CORE_AREA),
+
+       [HWBLK_IIC] = HWBLK(MSTPCR1, 9, CORE_AREA),
+       [HWBLK_RTC] = HWBLK(MSTPCR1, 8, SUB_AREA),
+
+       [HWBLK_ATAPI] = HWBLK(MSTPCR2, 28, CORE_AREA_BM),
+       [HWBLK_ADC] = HWBLK(MSTPCR2, 27, CORE_AREA),
+       [HWBLK_TPU] = HWBLK(MSTPCR2, 25, CORE_AREA),
+       [HWBLK_IRDA] = HWBLK(MSTPCR2, 24, CORE_AREA),
+       [HWBLK_TSIF] = HWBLK(MSTPCR2, 22, CORE_AREA),
+       [HWBLK_ICB] = HWBLK(MSTPCR2, 21, CORE_AREA_BM),
+       [HWBLK_SDHI0] = HWBLK(MSTPCR2, 18, CORE_AREA),
+       [HWBLK_SDHI1] = HWBLK(MSTPCR2, 17, CORE_AREA),
+       [HWBLK_KEYSC] = HWBLK(MSTPCR2, 14, SUB_AREA),
+       [HWBLK_USB] = HWBLK(MSTPCR2, 11, CORE_AREA),
+       [HWBLK_2DG] = HWBLK(MSTPCR2, 10, CORE_AREA_BM),
+       [HWBLK_SIU] = HWBLK(MSTPCR2, 8, CORE_AREA),
+       [HWBLK_VEU2H1] = HWBLK(MSTPCR2, 6, CORE_AREA_BM),
+       [HWBLK_VOU] = HWBLK(MSTPCR2, 5, CORE_AREA_BM),
+       [HWBLK_BEU] = HWBLK(MSTPCR2, 4, CORE_AREA_BM),
+       [HWBLK_CEU] = HWBLK(MSTPCR2, 3, CORE_AREA_BM),
+       [HWBLK_VEU2H0] = HWBLK(MSTPCR2, 2, CORE_AREA_BM),
+       [HWBLK_VPU] = HWBLK(MSTPCR2, 1, CORE_AREA_BM),
+       [HWBLK_LCDC] = HWBLK(MSTPCR2, 0, CORE_AREA_BM),
+};
+
+static struct hwblk_info sh7723_hwblk_info = {
+       .areas = sh7723_hwblk_area,
+       .nr_areas = ARRAY_SIZE(sh7723_hwblk_area),
+       .hwblks = sh7723_hwblk,
+       .nr_hwblks = ARRAY_SIZE(sh7723_hwblk),
+};
+
+int arch_hwblk_sleep_mode(void)
+{
+       if (!sh7723_hwblk_area[CORE_AREA].cnt[HWBLK_CNT_USAGE])
+               return SUSP_SH_STANDBY | SUSP_SH_SF;
+
+       if (!sh7723_hwblk_area[CORE_AREA_BM].cnt[HWBLK_CNT_USAGE])
+               return SUSP_SH_SLEEP | SUSP_SH_SF;
+
+       return SUSP_SH_SLEEP;
+}
+
+int __init arch_hwblk_init(void)
+{
+       return hwblk_register(&sh7723_hwblk_info);
+}
diff --git a/arch/sh/kernel/cpu/sh4a/hwblk-sh7724.c b/arch/sh/kernel/cpu/sh4a/hwblk-sh7724.c
new file mode 100644 (file)
index 0000000..1613ad6
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+ * arch/sh/kernel/cpu/sh4a/hwblk-sh7724.c
+ *
+ * SH7724 hardware block support
+ *
+ * Copyright (C) 2009 Magnus Damm
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <asm/suspend.h>
+#include <asm/hwblk.h>
+#include <cpu/sh7724.h>
+
+/* SH7724 registers */
+#define MSTPCR0                0xa4150030
+#define MSTPCR1                0xa4150034
+#define MSTPCR2                0xa4150038
+
+/* SH7724 Power Domains */
+enum { CORE_AREA, SUB_AREA, CORE_AREA_BM };
+static struct hwblk_area sh7724_hwblk_area[] = {
+       [CORE_AREA] = HWBLK_AREA(0, 0),
+       [CORE_AREA_BM] = HWBLK_AREA(HWBLK_AREA_FLAG_PARENT, CORE_AREA),
+       [SUB_AREA] = HWBLK_AREA(0, 0),
+};
+
+/* Table mapping HWBLK to Module Stop Bit and Power Domain */
+static struct hwblk sh7724_hwblk[HWBLK_NR] = {
+       [HWBLK_TLB] = HWBLK(MSTPCR0, 31, CORE_AREA),
+       [HWBLK_IC] = HWBLK(MSTPCR0, 30, CORE_AREA),
+       [HWBLK_OC] = HWBLK(MSTPCR0, 29, CORE_AREA),
+       [HWBLK_RSMEM] = HWBLK(MSTPCR0, 28, CORE_AREA),
+       [HWBLK_ILMEM] = HWBLK(MSTPCR0, 27, CORE_AREA),
+       [HWBLK_L2C] = HWBLK(MSTPCR0, 26, CORE_AREA),
+       [HWBLK_FPU] = HWBLK(MSTPCR0, 24, CORE_AREA),
+       [HWBLK_INTC] = HWBLK(MSTPCR0, 22, CORE_AREA),
+       [HWBLK_DMAC0] = HWBLK(MSTPCR0, 21, CORE_AREA_BM),
+       [HWBLK_SHYWAY] = HWBLK(MSTPCR0, 20, CORE_AREA),
+       [HWBLK_HUDI] = HWBLK(MSTPCR0, 19, CORE_AREA),
+       [HWBLK_DBG] = HWBLK(MSTPCR0, 18, CORE_AREA),
+       [HWBLK_UBC] = HWBLK(MSTPCR0, 17, CORE_AREA),
+       [HWBLK_TMU0] = HWBLK(MSTPCR0, 15, CORE_AREA),
+       [HWBLK_CMT] = HWBLK(MSTPCR0, 14, SUB_AREA),
+       [HWBLK_RWDT] = HWBLK(MSTPCR0, 13, SUB_AREA),
+       [HWBLK_DMAC1] = HWBLK(MSTPCR0, 12, CORE_AREA_BM),
+       [HWBLK_TMU1] = HWBLK(MSTPCR0, 10, CORE_AREA),
+       [HWBLK_SCIF0] = HWBLK(MSTPCR0, 9, CORE_AREA),
+       [HWBLK_SCIF1] = HWBLK(MSTPCR0, 8, CORE_AREA),
+       [HWBLK_SCIF2] = HWBLK(MSTPCR0, 7, CORE_AREA),
+       [HWBLK_SCIF3] = HWBLK(MSTPCR0, 6, CORE_AREA),
+       [HWBLK_SCIF4] = HWBLK(MSTPCR0, 5, CORE_AREA),
+       [HWBLK_SCIF5] = HWBLK(MSTPCR0, 4, CORE_AREA),
+       [HWBLK_MSIOF0] = HWBLK(MSTPCR0, 2, CORE_AREA),
+       [HWBLK_MSIOF1] = HWBLK(MSTPCR0, 1, CORE_AREA),
+
+       [HWBLK_KEYSC] = HWBLK(MSTPCR1, 12, SUB_AREA),
+       [HWBLK_RTC] = HWBLK(MSTPCR1, 11, SUB_AREA),
+       [HWBLK_IIC0] = HWBLK(MSTPCR1, 9, CORE_AREA),
+       [HWBLK_IIC1] = HWBLK(MSTPCR1, 8, CORE_AREA),
+
+       [HWBLK_MMC] = HWBLK(MSTPCR2, 29, CORE_AREA),
+       [HWBLK_ETHER] = HWBLK(MSTPCR2, 28, CORE_AREA_BM),
+       [HWBLK_ATAPI] = HWBLK(MSTPCR2, 26, CORE_AREA_BM),
+       [HWBLK_TPU] = HWBLK(MSTPCR2, 25, CORE_AREA),
+       [HWBLK_IRDA] = HWBLK(MSTPCR2, 24, CORE_AREA),
+       [HWBLK_TSIF] = HWBLK(MSTPCR2, 22, CORE_AREA),
+       [HWBLK_USB1] = HWBLK(MSTPCR2, 21, CORE_AREA),
+       [HWBLK_USB0] = HWBLK(MSTPCR2, 20, CORE_AREA),
+       [HWBLK_2DG] = HWBLK(MSTPCR2, 19, CORE_AREA_BM),
+       [HWBLK_SDHI0] = HWBLK(MSTPCR2, 18, CORE_AREA),
+       [HWBLK_SDHI1] = HWBLK(MSTPCR2, 17, CORE_AREA),
+       [HWBLK_VEU1] = HWBLK(MSTPCR2, 15, CORE_AREA_BM),
+       [HWBLK_CEU1] = HWBLK(MSTPCR2, 13, CORE_AREA_BM),
+       [HWBLK_BEU1] = HWBLK(MSTPCR2, 12, CORE_AREA_BM),
+       [HWBLK_2DDMAC] = HWBLK(MSTPCR2, 10, CORE_AREA_BM),
+       [HWBLK_SPU] = HWBLK(MSTPCR2, 9, CORE_AREA_BM),
+       [HWBLK_JPU] = HWBLK(MSTPCR2, 6, CORE_AREA_BM),
+       [HWBLK_VOU] = HWBLK(MSTPCR2, 5, CORE_AREA_BM),
+       [HWBLK_BEU0] = HWBLK(MSTPCR2, 4, CORE_AREA_BM),
+       [HWBLK_CEU0] = HWBLK(MSTPCR2, 3, CORE_AREA_BM),
+       [HWBLK_VEU0] = HWBLK(MSTPCR2, 2, CORE_AREA_BM),
+       [HWBLK_VPU] = HWBLK(MSTPCR2, 1, CORE_AREA_BM),
+       [HWBLK_LCDC] = HWBLK(MSTPCR2, 0, CORE_AREA_BM),
+};
+
+static struct hwblk_info sh7724_hwblk_info = {
+       .areas = sh7724_hwblk_area,
+       .nr_areas = ARRAY_SIZE(sh7724_hwblk_area),
+       .hwblks = sh7724_hwblk,
+       .nr_hwblks = ARRAY_SIZE(sh7724_hwblk),
+};
+
+int arch_hwblk_sleep_mode(void)
+{
+       if (!sh7724_hwblk_area[CORE_AREA].cnt[HWBLK_CNT_USAGE])
+               return SUSP_SH_STANDBY | SUSP_SH_SF;
+
+       if (!sh7724_hwblk_area[CORE_AREA_BM].cnt[HWBLK_CNT_USAGE])
+               return SUSP_SH_SLEEP | SUSP_SH_SF;
+
+       return SUSP_SH_SLEEP;
+}
+
+int __init arch_hwblk_init(void)
+{
+       return hwblk_register(&sh7724_hwblk_info);
+}
index 1a956b1beccc5f320f7e7fd206669bd2d69c2ac8..4a9010bf4fd389e2aba11a392a9281dc3102ce22 100644 (file)
@@ -40,7 +40,7 @@ static struct platform_device iic_device = {
 };
 
 static struct r8a66597_platdata r8a66597_data = {
-       /* This set zero to all members */
+       .on_chip = 1,
 };
 
 static struct resource usb_host_resources[] = {
index cda76ebf87c386a4e51f51a62f874971e41c9cd2..67b0d87fcb27057b699ba28144d62704db230288 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/serial_sci.h>
 #include <linux/mm.h>
 #include <linux/uio_driver.h>
+#include <linux/usb/m66592.h>
 #include <linux/sh_timer.h>
 #include <asm/clock.h>
 #include <asm/mmzone.h>
@@ -47,9 +48,13 @@ static struct platform_device rtc_device = {
        .resource       = rtc_resources,
 };
 
+static struct m66592_platdata usbf_platdata = {
+       .on_chip = 1,
+};
+
 static struct resource usbf_resources[] = {
        [0] = {
-               .name   = "m66592_udc",
+               .name   = "USBF",
                .start  = 0x04480000,
                .end    = 0x044800FF,
                .flags  = IORESOURCE_MEM,
@@ -67,6 +72,7 @@ static struct platform_device usbf_device = {
        .dev = {
                .dma_mask               = NULL,
                .coherent_dma_mask      = 0xffffffff,
+               .platform_data          = &usbf_platdata,
        },
        .num_resources  = ARRAY_SIZE(usbf_resources),
        .resource       = usbf_resources,
index b45dace9539fdf23cf0af0d46159438f0f045f29..26dc4d3232526ddb7f31450c15ebd8b5fe23b277 100644 (file)
@@ -398,7 +398,7 @@ static struct platform_device rtc_device = {
 };
 
 static struct r8a66597_platdata r8a66597_data = {
-       /* This set zero to all members */
+       .on_chip = 1,
 };
 
 static struct resource sh7723_usb_host_resources[] = {
index 08bfa7c7db29b5fb48c63a7d77419e522be0dba4..e8a5111e848abd1ac463a62492736dbe7861bf30 100644 (file)
@@ -4,3 +4,4 @@
 
 # Power Management & Sleep mode
 obj-$(CONFIG_PM)       += pm.o sleep.o
+obj-$(CONFIG_CPU_IDLE) += cpuidle.o
diff --git a/arch/sh/kernel/cpu/shmobile/cpuidle.c b/arch/sh/kernel/cpu/shmobile/cpuidle.c
new file mode 100644 (file)
index 0000000..4afdd97
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * arch/sh/kernel/cpu/shmobile/cpuidle.c
+ *
+ * Cpuidle support code for SuperH Mobile
+ *
+ *  Copyright (C) 2009 Magnus Damm
+ *
+ * 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
+ * for more details.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/suspend.h>
+#include <linux/cpuidle.h>
+#include <asm/suspend.h>
+#include <asm/uaccess.h>
+#include <asm/hwblk.h>
+
+static unsigned long cpuidle_mode[] = {
+       SUSP_SH_SLEEP, /* regular sleep mode */
+       SUSP_SH_SLEEP | SUSP_SH_SF, /* sleep mode + self refresh */
+};
+
+static int cpuidle_sleep_enter(struct cpuidle_device *dev,
+                              struct cpuidle_state *state)
+{
+       unsigned long allowed_mode = arch_hwblk_sleep_mode();
+       ktime_t before, after;
+       int requested_state = state - &dev->states[0];
+       int allowed_state;
+       int k;
+
+       /* convert allowed mode to allowed state */
+       for (k = ARRAY_SIZE(cpuidle_mode) - 1; k > 0; k--)
+               if (cpuidle_mode[k] == allowed_mode)
+                       break;
+
+       allowed_state = k;
+
+       /* take the following into account for sleep mode selection:
+        * - allowed_state: best mode allowed by hardware (clock deps)
+        * - requested_state: best mode allowed by software (latencies)
+        */
+       k = min_t(int, allowed_state, requested_state);
+
+       dev->last_state = &dev->states[k];
+       before = ktime_get();
+       sh_mobile_call_standby(cpuidle_mode[k]);
+       after = ktime_get();
+       return ktime_to_ns(ktime_sub(after, before)) >> 10;
+}
+
+static struct cpuidle_device cpuidle_dev;
+static struct cpuidle_driver cpuidle_driver = {
+       .name =         "sh_idle",
+       .owner =        THIS_MODULE,
+};
+
+void sh_mobile_setup_cpuidle(void)
+{
+       struct cpuidle_device *dev = &cpuidle_dev;
+       struct cpuidle_state *state;
+       int i;
+
+       cpuidle_register_driver(&cpuidle_driver);
+
+       for (i = 0; i < CPUIDLE_STATE_MAX; i++) {
+               dev->states[i].name[0] = '\0';
+               dev->states[i].desc[0] = '\0';
+       }
+
+       i = CPUIDLE_DRIVER_STATE_START;
+
+       state = &dev->states[i++];
+       snprintf(state->name, CPUIDLE_NAME_LEN, "C0");
+       strncpy(state->desc, "SuperH Sleep Mode", CPUIDLE_DESC_LEN);
+       state->exit_latency = 1;
+       state->target_residency = 1 * 2;
+       state->power_usage = 3;
+       state->flags = 0;
+       state->flags |= CPUIDLE_FLAG_SHALLOW;
+       state->flags |= CPUIDLE_FLAG_TIME_VALID;
+       state->enter = cpuidle_sleep_enter;
+
+       dev->safe_state = state;
+
+       state = &dev->states[i++];
+       snprintf(state->name, CPUIDLE_NAME_LEN, "C1");
+       strncpy(state->desc, "SuperH Sleep Mode [SF]", CPUIDLE_DESC_LEN);
+       state->exit_latency = 100;
+       state->target_residency = 1 * 2;
+       state->power_usage = 1;
+       state->flags = 0;
+       state->flags |= CPUIDLE_FLAG_TIME_VALID;
+       state->enter = cpuidle_sleep_enter;
+
+       dev->state_count = i;
+
+       cpuidle_register_device(dev);
+}
index 8c067adf683016c5091f74a463ee66b14ae25c71..de078d24ce569632c2798bb29c12dc5cadc18c87 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * arch/sh/kernel/cpu/sh4a/pm-sh_mobile.c
+ * arch/sh/kernel/cpu/shmobile/pm.c
  *
  * Power management support code for SuperH Mobile
  *
  *
  * R-standby mode is unsupported, but will be added in the future
  * U-standby mode is low priority since it needs bootloader hacks
- *
- * All modes should be tied in with cpuidle. But before that can
- * happen we need to keep track of enabled hardware blocks so we
- * can avoid entering sleep modes that stop clocks to hardware
- * blocks that are in use even though the cpu core is idle.
  */
 
+#define ILRAM_BASE 0xe5200000
+
 extern const unsigned char sh_mobile_standby[];
 extern const unsigned int sh_mobile_standby_size;
 
-static void sh_mobile_call_standby(unsigned long mode)
+void sh_mobile_call_standby(unsigned long mode)
 {
        extern void *vbr_base;
-       void *onchip_mem = (void *)0xe5200000; /* ILRAM */
+       void *onchip_mem = (void *)ILRAM_BASE;
        void (*standby_onchip_mem)(unsigned long) = onchip_mem;
 
        /* Note: Wake up from sleep may generate exceptions!
@@ -55,11 +52,6 @@ static void sh_mobile_call_standby(unsigned long mode)
        if (mode & SUSP_SH_SF)
                asm volatile("ldc %0, vbr" : : "r" (onchip_mem) : "memory");
 
-       /* Copy the assembly snippet to the otherwise ununsed ILRAM */
-       memcpy(onchip_mem, sh_mobile_standby, sh_mobile_standby_size);
-       wmb();
-       ctrl_barrier();
-
        /* Let assembly snippet in on-chip memory handle the rest */
        standby_onchip_mem(mode);
 
@@ -85,7 +77,15 @@ static struct platform_suspend_ops sh_pm_ops = {
 
 static int __init sh_pm_init(void)
 {
+       void *onchip_mem = (void *)ILRAM_BASE;
+
+       /* Copy the assembly snippet to the otherwise ununsed ILRAM */
+       memcpy(onchip_mem, sh_mobile_standby, sh_mobile_standby_size);
+       wmb();
+       ctrl_barrier();
+
        suspend_set_ops(&sh_pm_ops);
+       sh_mobile_setup_cpuidle();
        return 0;
 }
 
diff --git a/arch/sh/kernel/dumpstack.c b/arch/sh/kernel/dumpstack.c
new file mode 100644 (file)
index 0000000..6f5ad15
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ *  Copyright (C) 2000, 2001, 2002 Andi Kleen, SuSE Labs
+ *  Copyright (C) 2009  Matt Fleming
+ */
+#include <linux/kallsyms.h>
+#include <linux/ftrace.h>
+#include <linux/debug_locks.h>
+#include <asm/unwinder.h>
+#include <asm/stacktrace.h>
+
+void printk_address(unsigned long address, int reliable)
+{
+       printk(" [<%p>] %s%pS\n", (void *) address,
+                       reliable ? "" : "? ", (void *) address);
+}
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+static void
+print_ftrace_graph_addr(unsigned long addr, void *data,
+                       const struct stacktrace_ops *ops,
+                       struct thread_info *tinfo, int *graph)
+{
+       struct task_struct *task = tinfo->task;
+       unsigned long ret_addr;
+       int index = task->curr_ret_stack;
+
+       if (addr != (unsigned long)return_to_handler)
+               return;
+
+       if (!task->ret_stack || index < *graph)
+               return;
+
+       index -= *graph;
+       ret_addr = task->ret_stack[index].ret;
+
+       ops->address(data, ret_addr, 1);
+
+       (*graph)++;
+}
+#else
+static inline void
+print_ftrace_graph_addr(unsigned long addr, void *data,
+                       const struct stacktrace_ops *ops,
+                       struct thread_info *tinfo, int *graph)
+{ }
+#endif
+
+void
+stack_reader_dump(struct task_struct *task, struct pt_regs *regs,
+                 unsigned long *sp, const struct stacktrace_ops *ops,
+                 void *data)
+{
+       struct thread_info *context;
+       int graph = 0;
+
+       context = (struct thread_info *)
+               ((unsigned long)sp & (~(THREAD_SIZE - 1)));
+
+       while (!kstack_end(sp)) {
+               unsigned long addr = *sp++;
+
+               if (__kernel_text_address(addr)) {
+                       ops->address(data, addr, 1);
+
+                       print_ftrace_graph_addr(addr, data, ops,
+                                               context, &graph);
+               }
+       }
+}
+
+static void
+print_trace_warning_symbol(void *data, char *msg, unsigned long symbol)
+{
+       printk(data);
+       print_symbol(msg, symbol);
+       printk("\n");
+}
+
+static void print_trace_warning(void *data, char *msg)
+{
+       printk("%s%s\n", (char *)data, msg);
+}
+
+static int print_trace_stack(void *data, char *name)
+{
+       printk("%s <%s> ", (char *)data, name);
+       return 0;
+}
+
+/*
+ * Print one address/symbol entries per line.
+ */
+static void print_trace_address(void *data, unsigned long addr, int reliable)
+{
+       printk(data);
+       printk_address(addr, reliable);
+}
+
+static const struct stacktrace_ops print_trace_ops = {
+       .warning = print_trace_warning,
+       .warning_symbol = print_trace_warning_symbol,
+       .stack = print_trace_stack,
+       .address = print_trace_address,
+};
+
+void show_trace(struct task_struct *tsk, unsigned long *sp,
+               struct pt_regs *regs)
+{
+       if (regs && user_mode(regs))
+               return;
+
+       printk("\nCall trace:\n");
+
+       unwind_stack(tsk, regs, sp, &print_trace_ops, "");
+
+       printk("\n");
+
+       if (!tsk)
+               tsk = current;
+
+       debug_show_held_locks(tsk);
+}
diff --git a/arch/sh/kernel/dwarf.c b/arch/sh/kernel/dwarf.c
new file mode 100644 (file)
index 0000000..c6c5764
--- /dev/null
@@ -0,0 +1,902 @@
+/*
+ * Copyright (C) 2009 Matt Fleming <matt@console-pimps.org>
+ *
+ * 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
+ * for more details.
+ *
+ * This is an implementation of a DWARF unwinder. Its main purpose is
+ * for generating stacktrace information. Based on the DWARF 3
+ * specification from http://www.dwarfstd.org.
+ *
+ * TODO:
+ *     - DWARF64 doesn't work.
+ */
+
+/* #define DEBUG */
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/list.h>
+#include <linux/mm.h>
+#include <asm/dwarf.h>
+#include <asm/unwinder.h>
+#include <asm/sections.h>
+#include <asm/unaligned.h>
+#include <asm/dwarf.h>
+#include <asm/stacktrace.h>
+
+static LIST_HEAD(dwarf_cie_list);
+DEFINE_SPINLOCK(dwarf_cie_lock);
+
+static LIST_HEAD(dwarf_fde_list);
+DEFINE_SPINLOCK(dwarf_fde_lock);
+
+static struct dwarf_cie *cached_cie;
+
+/*
+ * Figure out whether we need to allocate some dwarf registers. If dwarf
+ * registers have already been allocated then we may need to realloc
+ * them. "reg" is a register number that we need to be able to access
+ * after this call.
+ *
+ * Register numbers start at zero, therefore we need to allocate space
+ * for "reg" + 1 registers.
+ */
+static void dwarf_frame_alloc_regs(struct dwarf_frame *frame,
+                                  unsigned int reg)
+{
+       struct dwarf_reg *regs;
+       unsigned int num_regs = reg + 1;
+       size_t new_size;
+       size_t old_size;
+
+       new_size = num_regs * sizeof(*regs);
+       old_size = frame->num_regs * sizeof(*regs);
+
+       /* Fast path: don't allocate any regs if we've already got enough. */
+       if (frame->num_regs >= num_regs)
+               return;
+
+       regs = kzalloc(new_size, GFP_ATOMIC);
+       if (!regs) {
+               printk(KERN_WARNING "Unable to allocate DWARF registers\n");
+               /*
+                * Let's just bomb hard here, we have no way to
+                * gracefully recover.
+                */
+               BUG();
+       }
+
+       if (frame->regs) {
+               memcpy(regs, frame->regs, old_size);
+               kfree(frame->regs);
+       }
+
+       frame->regs = regs;
+       frame->num_regs = num_regs;
+}
+
+/**
+ *     dwarf_read_addr - read dwarf data
+ *     @src: source address of data
+ *     @dst: destination address to store the data to
+ *
+ *     Read 'n' bytes from @src, where 'n' is the size of an address on
+ *     the native machine. We return the number of bytes read, which
+ *     should always be 'n'. We also have to be careful when reading
+ *     from @src and writing to @dst, because they can be arbitrarily
+ *     aligned. Return 'n' - the number of bytes read.
+ */
+static inline int dwarf_read_addr(unsigned long *src, unsigned long *dst)
+{
+       u32 val = get_unaligned(src);
+       put_unaligned(val, dst);
+       return sizeof(unsigned long *);
+}
+
+/**
+ *     dwarf_read_uleb128 - read unsigned LEB128 data
+ *     @addr: the address where the ULEB128 data is stored
+ *     @ret: address to store the result
+ *
+ *     Decode an unsigned LEB128 encoded datum. The algorithm is taken
+ *     from Appendix C of the DWARF 3 spec. For information on the
+ *     encodings refer to section "7.6 - Variable Length Data". Return
+ *     the number of bytes read.
+ */
+static inline unsigned long dwarf_read_uleb128(char *addr, unsigned int *ret)
+{
+       unsigned int result;
+       unsigned char byte;
+       int shift, count;
+
+       result = 0;
+       shift = 0;
+       count = 0;
+
+       while (1) {
+               byte = __raw_readb(addr);
+               addr++;
+               count++;
+
+               result |= (byte & 0x7f) << shift;
+               shift += 7;
+
+               if (!(byte & 0x80))
+                       break;
+       }
+
+       *ret = result;
+
+       return count;
+}
+
+/**
+ *     dwarf_read_leb128 - read signed LEB128 data
+ *     @addr: the address of the LEB128 encoded data
+ *     @ret: address to store the result
+ *
+ *     Decode signed LEB128 data. The algorithm is taken from Appendix
+ *     C of the DWARF 3 spec. Return the number of bytes read.
+ */
+static inline unsigned long dwarf_read_leb128(char *addr, int *ret)
+{
+       unsigned char byte;
+       int result, shift;
+       int num_bits;
+       int count;
+
+       result = 0;
+       shift = 0;
+       count = 0;
+
+       while (1) {
+               byte = __raw_readb(addr);
+               addr++;
+               result |= (byte & 0x7f) << shift;
+               shift += 7;
+               count++;
+
+               if (!(byte & 0x80))
+                       break;
+       }
+
+       /* The number of bits in a signed integer. */
+       num_bits = 8 * sizeof(result);
+
+       if ((shift < num_bits) && (byte & 0x40))
+               result |= (-1 << shift);
+
+       *ret = result;
+
+       return count;
+}
+
+/**
+ *     dwarf_read_encoded_value - return the decoded value at @addr
+ *     @addr: the address of the encoded value
+ *     @val: where to write the decoded value
+ *     @encoding: the encoding with which we can decode @addr
+ *
+ *     GCC emits encoded address in the .eh_frame FDE entries. Decode
+ *     the value at @addr using @encoding. The decoded value is written
+ *     to @val and the number of bytes read is returned.
+ */
+static int dwarf_read_encoded_value(char *addr, unsigned long *val,
+                                   char encoding)
+{
+       unsigned long decoded_addr = 0;
+       int count = 0;
+
+       switch (encoding & 0x70) {
+       case DW_EH_PE_absptr:
+               break;
+       case DW_EH_PE_pcrel:
+               decoded_addr = (unsigned long)addr;
+               break;
+       default:
+               pr_debug("encoding=0x%x\n", (encoding & 0x70));
+               BUG();
+       }
+
+       if ((encoding & 0x07) == 0x00)
+               encoding |= DW_EH_PE_udata4;
+
+       switch (encoding & 0x0f) {
+       case DW_EH_PE_sdata4:
+       case DW_EH_PE_udata4:
+               count += 4;
+               decoded_addr += get_unaligned((u32 *)addr);
+               __raw_writel(decoded_addr, val);
+               break;
+       default:
+               pr_debug("encoding=0x%x\n", encoding);
+               BUG();
+       }
+
+       return count;
+}
+
+/**
+ *     dwarf_entry_len - return the length of an FDE or CIE
+ *     @addr: the address of the entry
+ *     @len: the length of the entry
+ *
+ *     Read the initial_length field of the entry and store the size of
+ *     the entry in @len. We return the number of bytes read. Return a
+ *     count of 0 on error.
+ */
+static inline int dwarf_entry_len(char *addr, unsigned long *len)
+{
+       u32 initial_len;
+       int count;
+
+       initial_len = get_unaligned((u32 *)addr);
+       count = 4;
+
+       /*
+        * An initial length field value in the range DW_LEN_EXT_LO -
+        * DW_LEN_EXT_HI indicates an extension, and should not be
+        * interpreted as a length. The only extension that we currently
+        * understand is the use of DWARF64 addresses.
+        */
+       if (initial_len >= DW_EXT_LO && initial_len <= DW_EXT_HI) {
+               /*
+                * The 64-bit length field immediately follows the
+                * compulsory 32-bit length field.
+                */
+               if (initial_len == DW_EXT_DWARF64) {
+                       *len = get_unaligned((u64 *)addr + 4);
+                       count = 12;
+               } else {
+                       printk(KERN_WARNING "Unknown DWARF extension\n");
+                       count = 0;
+               }
+       } else
+               *len = initial_len;
+
+       return count;
+}
+
+/**
+ *     dwarf_lookup_cie - locate the cie
+ *     @cie_ptr: pointer to help with lookup
+ */
+static struct dwarf_cie *dwarf_lookup_cie(unsigned long cie_ptr)
+{
+       struct dwarf_cie *cie, *n;
+       unsigned long flags;
+
+       spin_lock_irqsave(&dwarf_cie_lock, flags);
+
+       /*
+        * We've cached the last CIE we looked up because chances are
+        * that the FDE wants this CIE.
+        */
+       if (cached_cie && cached_cie->cie_pointer == cie_ptr) {
+               cie = cached_cie;
+               goto out;
+       }
+
+       list_for_each_entry_safe(cie, n, &dwarf_cie_list, link) {
+               if (cie->cie_pointer == cie_ptr) {
+                       cached_cie = cie;
+                       break;
+               }
+       }
+
+       /* Couldn't find the entry in the list. */
+       if (&cie->link == &dwarf_cie_list)
+               cie = NULL;
+out:
+       spin_unlock_irqrestore(&dwarf_cie_lock, flags);
+       return cie;
+}
+
+/**
+ *     dwarf_lookup_fde - locate the FDE that covers pc
+ *     @pc: the program counter
+ */
+struct dwarf_fde *dwarf_lookup_fde(unsigned long pc)
+{
+       unsigned long flags;
+       struct dwarf_fde *fde, *n;
+
+       spin_lock_irqsave(&dwarf_fde_lock, flags);
+       list_for_each_entry_safe(fde, n, &dwarf_fde_list, link) {
+               unsigned long start, end;
+
+               start = fde->initial_location;
+               end = fde->initial_location + fde->address_range;
+
+               if (pc >= start && pc < end)
+                       break;
+       }
+
+       /* Couldn't find the entry in the list. */
+       if (&fde->link == &dwarf_fde_list)
+               fde = NULL;
+
+       spin_unlock_irqrestore(&dwarf_fde_lock, flags);
+
+       return fde;
+}
+
+/**
+ *     dwarf_cfa_execute_insns - execute instructions to calculate a CFA
+ *     @insn_start: address of the first instruction
+ *     @insn_end: address of the last instruction
+ *     @cie: the CIE for this function
+ *     @fde: the FDE for this function
+ *     @frame: the instructions calculate the CFA for this frame
+ *     @pc: the program counter of the address we're interested in
+ *     @define_ra: keep executing insns until the return addr reg is defined?
+ *
+ *     Execute the Call Frame instruction sequence starting at
+ *     @insn_start and ending at @insn_end. The instructions describe
+ *     how to calculate the Canonical Frame Address of a stackframe.
+ *     Store the results in @frame.
+ */
+static int dwarf_cfa_execute_insns(unsigned char *insn_start,
+                                  unsigned char *insn_end,
+                                  struct dwarf_cie *cie,
+                                  struct dwarf_fde *fde,
+                                  struct dwarf_frame *frame,
+                                  unsigned long pc,
+                                  bool define_ra)
+{
+       unsigned char insn;
+       unsigned char *current_insn;
+       unsigned int count, delta, reg, expr_len, offset;
+       bool seen_ra_reg;
+
+       current_insn = insn_start;
+
+       /*
+        * If we're executing instructions for the dwarf_unwind_stack()
+        * FDE we need to keep executing instructions until the value of
+        * DWARF_ARCH_RA_REG is defined. See the comment in
+        * dwarf_unwind_stack() for more details.
+        */
+       if (define_ra)
+               seen_ra_reg = false;
+       else
+               seen_ra_reg = true;
+
+       while (current_insn < insn_end && (frame->pc <= pc || !seen_ra_reg) ) {
+               insn = __raw_readb(current_insn++);
+
+               if (!seen_ra_reg) {
+                       if (frame->num_regs >= DWARF_ARCH_RA_REG &&
+                           frame->regs[DWARF_ARCH_RA_REG].flags)
+                               seen_ra_reg = true;
+               }
+
+               /*
+                * Firstly, handle the opcodes that embed their operands
+                * in the instructions.
+                */
+               switch (DW_CFA_opcode(insn)) {
+               case DW_CFA_advance_loc:
+                       delta = DW_CFA_operand(insn);
+                       delta *= cie->code_alignment_factor;
+                       frame->pc += delta;
+                       continue;
+                       /* NOTREACHED */
+               case DW_CFA_offset:
+                       reg = DW_CFA_operand(insn);
+                       count = dwarf_read_uleb128(current_insn, &offset);
+                       current_insn += count;
+                       offset *= cie->data_alignment_factor;
+                       dwarf_frame_alloc_regs(frame, reg);
+                       frame->regs[reg].addr = offset;
+                       frame->regs[reg].flags |= DWARF_REG_OFFSET;
+                       continue;
+                       /* NOTREACHED */
+               case DW_CFA_restore:
+                       reg = DW_CFA_operand(insn);
+                       continue;
+                       /* NOTREACHED */
+               }
+
+               /*
+                * Secondly, handle the opcodes that don't embed their
+                * operands in the instruction.
+                */
+               switch (insn) {
+               case DW_CFA_nop:
+                       continue;
+               case DW_CFA_advance_loc1:
+                       delta = *current_insn++;
+                       frame->pc += delta * cie->code_alignment_factor;
+                       break;
+               case DW_CFA_advance_loc2:
+                       delta = get_unaligned((u16 *)current_insn);
+                       current_insn += 2;
+                       frame->pc += delta * cie->code_alignment_factor;
+                       break;
+               case DW_CFA_advance_loc4:
+                       delta = get_unaligned((u32 *)current_insn);
+                       current_insn += 4;
+                       frame->pc += delta * cie->code_alignment_factor;
+                       break;
+               case DW_CFA_offset_extended:
+                       count = dwarf_read_uleb128(current_insn, &reg);
+                       current_insn += count;
+                       count = dwarf_read_uleb128(current_insn, &offset);
+                       current_insn += count;
+                       offset *= cie->data_alignment_factor;
+                       break;
+               case DW_CFA_restore_extended:
+                       count = dwarf_read_uleb128(current_insn, &reg);
+                       current_insn += count;
+                       break;
+               case DW_CFA_undefined:
+                       count = dwarf_read_uleb128(current_insn, &reg);
+                       current_insn += count;
+                       break;
+               case DW_CFA_def_cfa:
+                       count = dwarf_read_uleb128(current_insn,
+                                                  &frame->cfa_register);
+                       current_insn += count;
+                       count = dwarf_read_uleb128(current_insn,
+                                                  &frame->cfa_offset);
+                       current_insn += count;
+
+                       frame->flags |= DWARF_FRAME_CFA_REG_OFFSET;
+                       break;
+               case DW_CFA_def_cfa_register:
+                       count = dwarf_read_uleb128(current_insn,
+                                                  &frame->cfa_register);
+                       current_insn += count;
+                       frame->cfa_offset = 0;
+                       frame->flags |= DWARF_FRAME_CFA_REG_OFFSET;
+                       break;
+               case DW_CFA_def_cfa_offset:
+                       count = dwarf_read_uleb128(current_insn, &offset);
+                       current_insn += count;
+                       frame->cfa_offset = offset;
+                       break;
+               case DW_CFA_def_cfa_expression:
+                       count = dwarf_read_uleb128(current_insn, &expr_len);
+                       current_insn += count;
+
+                       frame->cfa_expr = current_insn;
+                       frame->cfa_expr_len = expr_len;
+                       current_insn += expr_len;
+
+                       frame->flags |= DWARF_FRAME_CFA_REG_EXP;
+                       break;
+               case DW_CFA_offset_extended_sf:
+                       count = dwarf_read_uleb128(current_insn, &reg);
+                       current_insn += count;
+                       count = dwarf_read_leb128(current_insn, &offset);
+                       current_insn += count;
+                       offset *= cie->data_alignment_factor;
+                       dwarf_frame_alloc_regs(frame, reg);
+                       frame->regs[reg].flags |= DWARF_REG_OFFSET;
+                       frame->regs[reg].addr = offset;
+                       break;
+               case DW_CFA_val_offset:
+                       count = dwarf_read_uleb128(current_insn, &reg);
+                       current_insn += count;
+                       count = dwarf_read_leb128(current_insn, &offset);
+                       offset *= cie->data_alignment_factor;
+                       frame->regs[reg].flags |= DWARF_REG_OFFSET;
+                       frame->regs[reg].addr = offset;
+                       break;
+               default:
+                       pr_debug("unhandled DWARF instruction 0x%x\n", insn);
+                       break;
+               }
+       }
+
+       return 0;
+}
+
+/**
+ *     dwarf_unwind_stack - recursively unwind the stack
+ *     @pc: address of the function to unwind
+ *     @prev: struct dwarf_frame of the previous stackframe on the callstack
+ *
+ *     Return a struct dwarf_frame representing the most recent frame
+ *     on the callstack. Each of the lower (older) stack frames are
+ *     linked via the "prev" member.
+ */
+struct dwarf_frame *dwarf_unwind_stack(unsigned long pc,
+                                      struct dwarf_frame *prev)
+{
+       struct dwarf_frame *frame;
+       struct dwarf_cie *cie;
+       struct dwarf_fde *fde;
+       unsigned long addr;
+       int i, offset;
+       bool define_ra = false;
+
+       /*
+        * If this is the first invocation of this recursive function we
+        * need get the contents of a physical register to get the CFA
+        * in order to begin the virtual unwinding of the stack.
+        *
+        * Setting "define_ra" to true indictates that we want
+        * dwarf_cfa_execute_insns() to continue executing instructions
+        * until we know how to calculate the value of DWARF_ARCH_RA_REG
+        * (which we need in order to kick off the whole unwinding
+        * process).
+        *
+        * NOTE: the return address is guaranteed to be setup by the
+        * time this function makes its first function call.
+        */
+       if (!pc && !prev) {
+               pc = (unsigned long)&dwarf_unwind_stack;
+               define_ra = true;
+       }
+
+       frame = kzalloc(sizeof(*frame), GFP_ATOMIC);
+       if (!frame)
+               return NULL;
+
+       frame->prev = prev;
+
+       fde = dwarf_lookup_fde(pc);
+       if (!fde) {
+               /*
+                * This is our normal exit path - the one that stops the
+                * recursion. There's two reasons why we might exit
+                * here,
+                *
+                *      a) pc has no asscociated DWARF frame info and so
+                *      we don't know how to unwind this frame. This is
+                *      usually the case when we're trying to unwind a
+                *      frame that was called from some assembly code
+                *      that has no DWARF info, e.g. syscalls.
+                *
+                *      b) the DEBUG info for pc is bogus. There's
+                *      really no way to distinguish this case from the
+                *      case above, which sucks because we could print a
+                *      warning here.
+                */
+               return NULL;
+       }
+
+       cie = dwarf_lookup_cie(fde->cie_pointer);
+
+       frame->pc = fde->initial_location;
+
+       /* CIE initial instructions */
+       dwarf_cfa_execute_insns(cie->initial_instructions,
+                               cie->instructions_end, cie, fde,
+                               frame, pc, false);
+
+       /* FDE instructions */
+       dwarf_cfa_execute_insns(fde->instructions, fde->end, cie,
+                               fde, frame, pc, define_ra);
+
+       /* Calculate the CFA */
+       switch (frame->flags) {
+       case DWARF_FRAME_CFA_REG_OFFSET:
+               if (prev) {
+                       BUG_ON(!prev->regs[frame->cfa_register].flags);
+
+                       addr = prev->cfa;
+                       addr += prev->regs[frame->cfa_register].addr;
+                       frame->cfa = __raw_readl(addr);
+
+               } else {
+                       /*
+                        * Again, this is the first invocation of this
+                        * recurisve function. We need to physically
+                        * read the contents of a register in order to
+                        * get the Canonical Frame Address for this
+                        * function.
+                        */
+                       frame->cfa = dwarf_read_arch_reg(frame->cfa_register);
+               }
+
+               frame->cfa += frame->cfa_offset;
+               break;
+       default:
+               BUG();
+       }
+
+       /* If we haven't seen the return address reg, we're screwed. */
+       BUG_ON(!frame->regs[DWARF_ARCH_RA_REG].flags);
+
+       for (i = 0; i <= frame->num_regs; i++) {
+               struct dwarf_reg *reg = &frame->regs[i];
+
+               if (!reg->flags)
+                       continue;
+
+               offset = reg->addr;
+               offset += frame->cfa;
+       }
+
+       addr = frame->cfa + frame->regs[DWARF_ARCH_RA_REG].addr;
+       frame->return_addr = __raw_readl(addr);
+
+       frame->next = dwarf_unwind_stack(frame->return_addr, frame);
+       return frame;
+}
+
+static int dwarf_parse_cie(void *entry, void *p, unsigned long len,
+                          unsigned char *end)
+{
+       struct dwarf_cie *cie;
+       unsigned long flags;
+       int count;
+
+       cie = kzalloc(sizeof(*cie), GFP_KERNEL);
+       if (!cie)
+               return -ENOMEM;
+
+       cie->length = len;
+
+       /*
+        * Record the offset into the .eh_frame section
+        * for this CIE. It allows this CIE to be
+        * quickly and easily looked up from the
+        * corresponding FDE.
+        */
+       cie->cie_pointer = (unsigned long)entry;
+
+       cie->version = *(char *)p++;
+       BUG_ON(cie->version != 1);
+
+       cie->augmentation = p;
+       p += strlen(cie->augmentation) + 1;
+
+       count = dwarf_read_uleb128(p, &cie->code_alignment_factor);
+       p += count;
+
+       count = dwarf_read_leb128(p, &cie->data_alignment_factor);
+       p += count;
+
+       /*
+        * Which column in the rule table contains the
+        * return address?
+        */
+       if (cie->version == 1) {
+               cie->return_address_reg = __raw_readb(p);
+               p++;
+       } else {
+               count = dwarf_read_uleb128(p, &cie->return_address_reg);
+               p += count;
+       }
+
+       if (cie->augmentation[0] == 'z') {
+               unsigned int length, count;
+               cie->flags |= DWARF_CIE_Z_AUGMENTATION;
+
+               count = dwarf_read_uleb128(p, &length);
+               p += count;
+
+               BUG_ON((unsigned char *)p > end);
+
+               cie->initial_instructions = p + length;
+               cie->augmentation++;
+       }
+
+       while (*cie->augmentation) {
+               /*
+                * "L" indicates a byte showing how the
+                * LSDA pointer is encoded. Skip it.
+                */
+               if (*cie->augmentation == 'L') {
+                       p++;
+                       cie->augmentation++;
+               } else if (*cie->augmentation == 'R') {
+                       /*
+                        * "R" indicates a byte showing
+                        * how FDE addresses are
+                        * encoded.
+                        */
+                       cie->encoding = *(char *)p++;
+                       cie->augmentation++;
+               } else if (*cie->augmentation == 'P') {
+                       /*
+                        * "R" indicates a personality
+                        * routine in the CIE
+                        * augmentation.
+                        */
+                       BUG();
+               } else if (*cie->augmentation == 'S') {
+                       BUG();
+               } else {
+                       /*
+                        * Unknown augmentation. Assume
+                        * 'z' augmentation.
+                        */
+                       p = cie->initial_instructions;
+                       BUG_ON(!p);
+                       break;
+               }
+       }
+
+       cie->initial_instructions = p;
+       cie->instructions_end = end;
+
+       /* Add to list */
+       spin_lock_irqsave(&dwarf_cie_lock, flags);
+       list_add_tail(&cie->link, &dwarf_cie_list);
+       spin_unlock_irqrestore(&dwarf_cie_lock, flags);
+
+       return 0;
+}
+
+static int dwarf_parse_fde(void *entry, u32 entry_type,
+                          void *start, unsigned long len)
+{
+       struct dwarf_fde *fde;
+       struct dwarf_cie *cie;
+       unsigned long flags;
+       int count;
+       void *p = start;
+
+       fde = kzalloc(sizeof(*fde), GFP_KERNEL);
+       if (!fde)
+               return -ENOMEM;
+
+       fde->length = len;
+
+       /*
+        * In a .eh_frame section the CIE pointer is the
+        * delta between the address within the FDE
+        */
+       fde->cie_pointer = (unsigned long)(p - entry_type - 4);
+
+       cie = dwarf_lookup_cie(fde->cie_pointer);
+       fde->cie = cie;
+
+       if (cie->encoding)
+               count = dwarf_read_encoded_value(p, &fde->initial_location,
+                                                cie->encoding);
+       else
+               count = dwarf_read_addr(p, &fde->initial_location);
+
+       p += count;
+
+       if (cie->encoding)
+               count = dwarf_read_encoded_value(p, &fde->address_range,
+                                                cie->encoding & 0x0f);
+       else
+               count = dwarf_read_addr(p, &fde->address_range);
+
+       p += count;
+
+       if (fde->cie->flags & DWARF_CIE_Z_AUGMENTATION) {
+               unsigned int length;
+               count = dwarf_read_uleb128(p, &length);
+               p += count + length;
+       }
+
+       /* Call frame instructions. */
+       fde->instructions = p;
+       fde->end = start + len;
+
+       /* Add to list. */
+       spin_lock_irqsave(&dwarf_fde_lock, flags);
+       list_add_tail(&fde->link, &dwarf_fde_list);
+       spin_unlock_irqrestore(&dwarf_fde_lock, flags);
+
+       return 0;
+}
+
+static void dwarf_unwinder_dump(struct task_struct *task, struct pt_regs *regs,
+                               unsigned long *sp,
+                               const struct stacktrace_ops *ops, void *data)
+{
+       struct dwarf_frame *frame;
+
+       frame = dwarf_unwind_stack(0, NULL);
+
+       while (frame && frame->return_addr) {
+               ops->address(data, frame->return_addr, 1);
+               frame = frame->next;
+       }
+}
+
+static struct unwinder dwarf_unwinder = {
+       .name = "dwarf-unwinder",
+       .dump = dwarf_unwinder_dump,
+       .rating = 150,
+};
+
+static void dwarf_unwinder_cleanup(void)
+{
+       struct dwarf_cie *cie, *m;
+       struct dwarf_fde *fde, *n;
+       unsigned long flags;
+
+       /*
+        * Deallocate all the memory allocated for the DWARF unwinder.
+        * Traverse all the FDE/CIE lists and remove and free all the
+        * memory associated with those data structures.
+        */
+       spin_lock_irqsave(&dwarf_cie_lock, flags);
+       list_for_each_entry_safe(cie, m, &dwarf_cie_list, link)
+               kfree(cie);
+       spin_unlock_irqrestore(&dwarf_cie_lock, flags);
+
+       spin_lock_irqsave(&dwarf_fde_lock, flags);
+       list_for_each_entry_safe(fde, n, &dwarf_fde_list, link)
+               kfree(fde);
+       spin_unlock_irqrestore(&dwarf_fde_lock, flags);
+}
+
+/**
+ *     dwarf_unwinder_init - initialise the dwarf unwinder
+ *
+ *     Build the data structures describing the .dwarf_frame section to
+ *     make it easier to lookup CIE and FDE entries. Because the
+ *     .eh_frame section is packed as tightly as possible it is not
+ *     easy to lookup the FDE for a given PC, so we build a list of FDE
+ *     and CIE entries that make it easier.
+ */
+void dwarf_unwinder_init(void)
+{
+       u32 entry_type;
+       void *p, *entry;
+       int count, err;
+       unsigned long len;
+       unsigned int c_entries, f_entries;
+       unsigned char *end;
+       INIT_LIST_HEAD(&dwarf_cie_list);
+       INIT_LIST_HEAD(&dwarf_fde_list);
+
+       c_entries = 0;
+       f_entries = 0;
+       entry = &__start_eh_frame;
+
+       while ((char *)entry < __stop_eh_frame) {
+               p = entry;
+
+               count = dwarf_entry_len(p, &len);
+               if (count == 0) {
+                       /*
+                        * We read a bogus length field value. There is
+                        * nothing we can do here apart from disabling
+                        * the DWARF unwinder. We can't even skip this
+                        * entry and move to the next one because 'len'
+                        * tells us where our next entry is.
+                        */
+                       goto out;
+               } else
+                       p += count;
+
+               /* initial length does not include itself */
+               end = p + len;
+
+               entry_type = get_unaligned((u32 *)p);
+               p += 4;
+
+               if (entry_type == DW_EH_FRAME_CIE) {
+                       err = dwarf_parse_cie(entry, p, len, end);
+                       if (err < 0)
+                               goto out;
+                       else
+                               c_entries++;
+               } else {
+                       err = dwarf_parse_fde(entry, entry_type, p, len);
+                       if (err < 0)
+                               goto out;
+                       else
+                               f_entries++;
+               }
+
+               entry = (char *)entry + len + 4;
+       }
+
+       printk(KERN_INFO "DWARF unwinder initialised: read %u CIEs, %u FDEs\n",
+              c_entries, f_entries);
+
+       err = unwinder_register(&dwarf_unwinder);
+       if (err)
+               goto out;
+
+       return;
+
+out:
+       printk(KERN_ERR "Failed to initialise DWARF unwinder: %d\n", err);
+       dwarf_unwinder_cleanup();
+}
index a952dcf9999d43bedbef8ff275aa3517fb13ab91..81a46145ffa5b01af702ff04863b19c128d3574b 100644 (file)
@@ -134,7 +134,7 @@ static void scif_sercon_init(char *s)
        sci_out(&scif_port, SCFCR, 0x0030);     /* TTRG=b'11 */
        sci_out(&scif_port, SCSCR, 0x0030);     /* TE, RE */
 }
-#elif defined(CONFIG_CPU_SH4)
+#elif defined(CONFIG_CPU_SH4) || defined(CONFIG_CPU_SH3)
 #define DEFAULT_BAUD 115200
 /*
  * Simple SCIF init, primarily aimed at SH7750 and other similar SH-4
@@ -220,8 +220,7 @@ static int __init setup_early_printk(char *buf)
                early_console = &scif_console;
 
 #if !defined(CONFIG_SH_STANDARD_BIOS)
-#if defined(CONFIG_CPU_SH4) || defined(CONFIG_CPU_SUBTYPE_SH7720) || \
-    defined(CONFIG_CPU_SUBTYPE_SH7721)
+#if defined(CONFIG_CPU_SH4) || defined(CONFIG_CPU_SH3)
                scif_sercon_init(buf + 6);
 #endif
 #endif
index d62359cfbbe20723e39a7b304b02446dc78c686d..e63178fefb9b880251fce26071a778c57bcd072c 100644 (file)
  *     syscall #
  *
  */
+#include <asm/dwarf.h>
 
 #if defined(CONFIG_PREEMPT)
-#  define preempt_stop()       cli
+#  define preempt_stop()       cli ; TRACE_IRQS_OFF
 #else
 #  define preempt_stop()
 #  define resume_kernel                __restore_all
        .align  2
 ENTRY(exception_error)
        !
-#ifdef CONFIG_TRACE_IRQFLAGS
-       mov.l   2f, r0
-       jsr     @r0
-        nop
-#endif
+       TRACE_IRQS_ON
        sti
        mov.l   1f, r0
        jmp     @r0
@@ -67,22 +64,28 @@ ENTRY(exception_error)
 
        .align  2
 1:     .long   do_exception_error
-#ifdef CONFIG_TRACE_IRQFLAGS
-2:     .long   trace_hardirqs_on
-#endif
 
        .align  2
 ret_from_exception:
+       CFI_STARTPROC simple
+       CFI_DEF_CFA r14, 0
+       CFI_REL_OFFSET 17, 64
+       CFI_REL_OFFSET 15, 0
+       CFI_REL_OFFSET 14, 56
        preempt_stop()
-#ifdef CONFIG_TRACE_IRQFLAGS
-       mov.l   4f, r0
-       jsr     @r0
-        nop
-#endif
 ENTRY(ret_from_irq)
        !
        mov     #OFF_SR, r0
        mov.l   @(r0,r15), r0   ! get status register
+
+       shlr2   r0
+       and     #0x3c, r0
+       cmp/eq  #0x3c, r0
+       bt      9f
+       TRACE_IRQS_ON
+9:
+       mov     #OFF_SR, r0
+       mov.l   @(r0,r15), r0   ! get status register
        shll    r0
        shll    r0              ! kernel space?
        get_current_thread_info r8, r0
@@ -125,13 +128,9 @@ noresched:
 ENTRY(resume_userspace)
        ! r8: current_thread_info
        cli
-#ifdef CONFIG_TRACE_IRQFLAGS
-       mov.l   5f, r0
-       jsr     @r0
-        nop
-#endif
+       TRACE_IRQS_OfF
        mov.l   @(TI_FLAGS,r8), r0              ! current_thread_info->flags
-       tst     #_TIF_WORK_MASK, r0
+       tst     #(_TIF_WORK_MASK & 0xff), r0
        bt/s    __restore_all
         tst    #_TIF_NEED_RESCHED, r0
 
@@ -156,14 +155,10 @@ work_resched:
        jsr     @r1                             ! schedule
         nop
        cli
-#ifdef CONFIG_TRACE_IRQFLAGS
-       mov.l   5f, r0
-       jsr     @r0
-        nop
-#endif
+       TRACE_IRQS_OFF
        !
        mov.l   @(TI_FLAGS,r8), r0              ! current_thread_info->flags
-       tst     #_TIF_WORK_MASK, r0
+       tst     #(_TIF_WORK_MASK & 0xff), r0
        bt      __restore_all
        bra     work_pending
         tst    #_TIF_NEED_RESCHED, r0
@@ -172,23 +167,15 @@ work_resched:
 1:     .long   schedule
 2:     .long   do_notify_resume
 3:     .long   resume_userspace
-#ifdef CONFIG_TRACE_IRQFLAGS
-4:     .long   trace_hardirqs_on
-5:     .long   trace_hardirqs_off
-#endif
 
        .align  2
 syscall_exit_work:
        ! r0: current_thread_info->flags
        ! r8: current_thread_info
-       tst     #_TIF_WORK_SYSCALL_MASK, r0
+       tst     #(_TIF_WORK_SYSCALL_MASK & 0xff), r0
        bt/s    work_pending
         tst    #_TIF_NEED_RESCHED, r0
-#ifdef CONFIG_TRACE_IRQFLAGS
-       mov.l   5f, r0
-       jsr     @r0
-        nop
-#endif
+       TRACE_IRQS_ON
        sti
        mov     r15, r4
        mov.l   8f, r0                  ! do_syscall_trace_leave
@@ -259,6 +246,7 @@ debug_trap:
         nop
        bra     __restore_all
         nop
+       CFI_ENDPROC
 
        .align  2
 1:     .long   debug_trap_table
@@ -304,6 +292,7 @@ ret_from_fork:
  * system calls and debug traps through their respective jump tables.
  */
 ENTRY(system_call)
+       setup_frame_reg
 #if !defined(CONFIG_CPU_SH2)
        mov.l   1f, r9
        mov.l   @r9, r8         ! Read from TRA (Trap Address) Register
@@ -321,18 +310,18 @@ ENTRY(system_call)
        bt/s    debug_trap              ! it's a debug trap..
         nop
 
-#ifdef CONFIG_TRACE_IRQFLAGS
-       mov.l   5f, r10
-       jsr     @r10
-        nop
-#endif
+       TRACE_IRQS_ON
        sti
 
        !
        get_current_thread_info r8, r10
        mov.l   @(TI_FLAGS,r8), r8
-       mov     #_TIF_WORK_SYSCALL_MASK, r10
+       mov     #(_TIF_WORK_SYSCALL_MASK & 0xff), r10
+       mov     #(_TIF_WORK_SYSCALL_MASK >> 8), r9
        tst     r10, r8
+       shll8   r9
+       bf      syscall_trace_entry
+       tst     r9, r8
        bf      syscall_trace_entry
        !
        mov.l   2f, r8                  ! Number of syscalls
@@ -351,15 +340,15 @@ syscall_call:
        !
 syscall_exit:
        cli
-#ifdef CONFIG_TRACE_IRQFLAGS
-       mov.l   6f, r0
-       jsr     @r0
-        nop
-#endif
+       TRACE_IRQS_OFF
        !
        get_current_thread_info r8, r0
        mov.l   @(TI_FLAGS,r8), r0              ! current_thread_info->flags
-       tst     #_TIF_ALLWORK_MASK, r0
+       tst     #(_TIF_ALLWORK_MASK & 0xff), r0
+       mov     #(_TIF_ALLWORK_MASK >> 8), r1
+       bf      syscall_exit_work
+       shlr8   r0
+       tst     r0, r1
        bf      syscall_exit_work
        bra     __restore_all
         nop
@@ -369,9 +358,5 @@ syscall_exit:
 #endif
 2:     .long   NR_syscalls
 3:     .long   sys_call_table
-#ifdef CONFIG_TRACE_IRQFLAGS
-5:     .long   trace_hardirqs_on
-6:     .long   trace_hardirqs_off
-#endif
 7:     .long   do_syscall_trace_enter
 8:     .long   do_syscall_trace_leave
index 066f37dc32a907fb4480f3e241b15a404f900134..6647dfcb781d4c07a117fd5cb4114327a3038267 100644 (file)
 #include <linux/string.h>
 #include <linux/init.h>
 #include <linux/io.h>
+#include <linux/kernel.h>
 #include <asm/ftrace.h>
 #include <asm/cacheflush.h>
+#include <asm/unistd.h>
+#include <trace/syscall.h>
 
+#ifdef CONFIG_DYNAMIC_FTRACE
 static unsigned char ftrace_replaced_code[MCOUNT_INSN_SIZE];
 
 static unsigned char ftrace_nop[4];
@@ -131,3 +135,189 @@ int __init ftrace_dyn_arch_init(void *data)
 
        return 0;
 }
+#endif /* CONFIG_DYNAMIC_FTRACE */
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+#ifdef CONFIG_DYNAMIC_FTRACE
+extern void ftrace_graph_call(void);
+
+static int ftrace_mod(unsigned long ip, unsigned long old_addr,
+                     unsigned long new_addr)
+{
+       unsigned char code[MCOUNT_INSN_SIZE];
+
+       if (probe_kernel_read(code, (void *)ip, MCOUNT_INSN_SIZE))
+               return -EFAULT;
+
+       if (old_addr != __raw_readl((unsigned long *)code))
+               return -EINVAL;
+
+       __raw_writel(new_addr, ip);
+       return 0;
+}
+
+int ftrace_enable_ftrace_graph_caller(void)
+{
+       unsigned long ip, old_addr, new_addr;
+
+       ip = (unsigned long)(&ftrace_graph_call) + GRAPH_INSN_OFFSET;
+       old_addr = (unsigned long)(&skip_trace);
+       new_addr = (unsigned long)(&ftrace_graph_caller);
+
+       return ftrace_mod(ip, old_addr, new_addr);
+}
+
+int ftrace_disable_ftrace_graph_caller(void)
+{
+       unsigned long ip, old_addr, new_addr;
+
+       ip = (unsigned long)(&ftrace_graph_call) + GRAPH_INSN_OFFSET;
+       old_addr = (unsigned long)(&ftrace_graph_caller);
+       new_addr = (unsigned long)(&skip_trace);
+
+       return ftrace_mod(ip, old_addr, new_addr);
+}
+#endif /* CONFIG_DYNAMIC_FTRACE */
+
+/*
+ * Hook the return address and push it in the stack of return addrs
+ * in the current thread info.
+ *
+ * This is the main routine for the function graph tracer. The function
+ * graph tracer essentially works like this:
+ *
+ * parent is the stack address containing self_addr's return address.
+ * We pull the real return address out of parent and store it in
+ * current's ret_stack. Then, we replace the return address on the stack
+ * with the address of return_to_handler. self_addr is the function that
+ * called mcount.
+ *
+ * When self_addr returns, it will jump to return_to_handler which calls
+ * ftrace_return_to_handler. ftrace_return_to_handler will pull the real
+ * return address off of current's ret_stack and jump to it.
+ */
+void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr)
+{
+       unsigned long old;
+       int faulted, err;
+       struct ftrace_graph_ent trace;
+       unsigned long return_hooker = (unsigned long)&return_to_handler;
+
+       if (unlikely(atomic_read(&current->tracing_graph_pause)))
+               return;
+
+       /*
+        * Protect against fault, even if it shouldn't
+        * happen. This tool is too much intrusive to
+        * ignore such a protection.
+        */
+       __asm__ __volatile__(
+               "1:                                             \n\t"
+               "mov.l          @%2, %0                         \n\t"
+               "2:                                             \n\t"
+               "mov.l          %3, @%2                         \n\t"
+               "mov            #0, %1                          \n\t"
+               "3:                                             \n\t"
+               ".section .fixup, \"ax\"                        \n\t"
+               "4:                                             \n\t"
+               "mov.l          5f, %0                          \n\t"
+               "jmp            @%0                             \n\t"
+               " mov           #1, %1                          \n\t"
+               ".balign 4                                      \n\t"
+               "5:     .long 3b                                \n\t"
+               ".previous                                      \n\t"
+               ".section __ex_table,\"a\"                      \n\t"
+               ".long 1b, 4b                                   \n\t"
+               ".long 2b, 4b                                   \n\t"
+               ".previous                                      \n\t"
+               : "=&r" (old), "=r" (faulted)
+               : "r" (parent), "r" (return_hooker)
+       );
+
+       if (unlikely(faulted)) {
+               ftrace_graph_stop();
+               WARN_ON(1);
+               return;
+       }
+
+       err = ftrace_push_return_trace(old, self_addr, &trace.depth, 0);
+       if (err == -EBUSY) {
+               __raw_writel(old, parent);
+               return;
+       }
+
+       trace.func = self_addr;
+
+       /* Only trace if the calling function expects to */
+       if (!ftrace_graph_entry(&trace)) {
+               current->curr_ret_stack--;
+               __raw_writel(old, parent);
+       }
+}
+#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
+
+#ifdef CONFIG_FTRACE_SYSCALLS
+
+extern unsigned long __start_syscalls_metadata[];
+extern unsigned long __stop_syscalls_metadata[];
+extern unsigned long *sys_call_table;
+
+static struct syscall_metadata **syscalls_metadata;
+
+static struct syscall_metadata *find_syscall_meta(unsigned long *syscall)
+{
+       struct syscall_metadata *start;
+       struct syscall_metadata *stop;
+       char str[KSYM_SYMBOL_LEN];
+
+
+       start = (struct syscall_metadata *)__start_syscalls_metadata;
+       stop = (struct syscall_metadata *)__stop_syscalls_metadata;
+       kallsyms_lookup((unsigned long) syscall, NULL, NULL, NULL, str);
+
+       for ( ; start < stop; start++) {
+               if (start->name && !strcmp(start->name, str))
+                       return start;
+       }
+
+       return NULL;
+}
+
+#define FTRACE_SYSCALL_MAX     (NR_syscalls - 1)
+
+struct syscall_metadata *syscall_nr_to_meta(int nr)
+{
+       if (!syscalls_metadata || nr >= FTRACE_SYSCALL_MAX || nr < 0)
+               return NULL;
+
+       return syscalls_metadata[nr];
+}
+
+void arch_init_ftrace_syscalls(void)
+{
+       int i;
+       struct syscall_metadata *meta;
+       unsigned long **psys_syscall_table = &sys_call_table;
+       static atomic_t refs;
+
+       if (atomic_inc_return(&refs) != 1)
+               goto end;
+
+       syscalls_metadata = kzalloc(sizeof(*syscalls_metadata) *
+                                       FTRACE_SYSCALL_MAX, GFP_KERNEL);
+       if (!syscalls_metadata) {
+               WARN_ON(1);
+               return;
+       }
+
+       for (i = 0; i < FTRACE_SYSCALL_MAX; i++) {
+               meta = find_syscall_meta(psys_syscall_table[i]);
+               syscalls_metadata[i] = meta;
+       }
+       return;
+
+       /* Paranoid: avoid overflow */
+end:
+       atomic_dec(&refs);
+}
+#endif /* CONFIG_FTRACE_SYSCALLS */
index 77dfecb643739d5e6abd8ec153289c1ba90a4d6a..e27a19e1f46ec2d06893784e971fe705e38bf91c 100644 (file)
@@ -112,14 +112,15 @@ void __iomem *match_trapped_io_handler(struct list_head *list,
        struct trapped_io *tiop;
        struct resource *res;
        int k, len;
+       unsigned long flags;
 
-       spin_lock_irq(&trapped_lock);
+       spin_lock_irqsave(&trapped_lock, flags);
        list_for_each_entry(tiop, list, list) {
                voffs = 0;
                for (k = 0; k < tiop->num_resources; k++) {
                        res = tiop->resource + k;
                        if (res->start == offset) {
-                               spin_unlock_irq(&trapped_lock);
+                               spin_unlock_irqrestore(&trapped_lock, flags);
                                return tiop->virt_base + voffs;
                        }
 
@@ -127,7 +128,7 @@ void __iomem *match_trapped_io_handler(struct list_head *list,
                        voffs += roundup(len, PAGE_SIZE);
                }
        }
-       spin_unlock_irq(&trapped_lock);
+       spin_unlock_irqrestore(&trapped_lock, flags);
        return NULL;
 }
 EXPORT_SYMBOL_GPL(match_trapped_io_handler);
index 3d09062f4682718b43ec607649ca466ddcc6f670..2bb43dc74f227c97dcc616dbc50fe41a7e82d25c 100644 (file)
@@ -14,6 +14,7 @@
 #include <asm/processor.h>
 #include <asm/machvec.h>
 #include <asm/uaccess.h>
+#include <asm/dwarf.h>
 #include <asm/thread_info.h>
 #include <cpu/mmu_context.h>
 
@@ -114,23 +115,6 @@ asmlinkage int do_IRQ(unsigned int irq, struct pt_regs *regs)
 #endif
 
        irq_enter();
-
-#ifdef CONFIG_DEBUG_STACKOVERFLOW
-       /* Debugging check for stack overflow: is there less than 1KB free? */
-       {
-               long sp;
-
-               __asm__ __volatile__ ("and r15, %0" :
-                                       "=r" (sp) : "0" (THREAD_SIZE - 1));
-
-               if (unlikely(sp < (sizeof(struct thread_info) + STACK_WARN))) {
-                       printk("do_IRQ: stack overflow: %ld\n",
-                              sp - sizeof(struct thread_info));
-                       dump_stack();
-               }
-       }
-#endif
-
        irq = irq_demux(intc_evt2irq(irq));
 
 #ifdef CONFIG_IRQSTACKS
@@ -278,6 +262,9 @@ void __init init_IRQ(void)
                sh_mv.mv_init_irq();
 
        irq_ctx_init(smp_processor_id());
+
+       /* This needs to be early, but not too early.. */
+       dwarf_unwinder_init();
 }
 
 #ifdef CONFIG_SPARSE_IRQ
index 92d7740faab19d92b412e387e448052e431162aa..9fee977f176b7c95fe64c878b9ed84f25ee3777c 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/tick.h>
 #include <linux/reboot.h>
 #include <linux/fs.h>
+#include <linux/ftrace.h>
 #include <linux/preempt.h>
 #include <asm/uaccess.h>
 #include <asm/mmu_context.h>
@@ -264,8 +265,8 @@ static void ubc_set_tracing(int asid, unsigned long pc)
  *     switch_to(x,y) should switch tasks from x to y.
  *
  */
-struct task_struct *__switch_to(struct task_struct *prev,
-                               struct task_struct *next)
+__notrace_funcgraph struct task_struct *
+__switch_to(struct task_struct *prev, struct task_struct *next)
 {
 #if defined(CONFIG_SH_FPU)
        unlazy_fpu(prev, task_pt_regs(prev));
index 3392e835a374af8895fe8330444854117ebea7a3..c198eceaee94dbef536ee9e0db32a2a002abfea6 100644 (file)
@@ -34,6 +34,8 @@
 #include <asm/syscalls.h>
 #include <asm/fpu.h>
 
+#include <trace/syscall.h>
+
 /*
  * This routine will get a word off of the process kernel stack.
  */
@@ -459,6 +461,9 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
                 */
                ret = -1L;
 
+       if (unlikely(test_thread_flag(TIF_SYSCALL_FTRACE)))
+               ftrace_syscall_enter(regs);
+
        if (unlikely(current->audit_context))
                audit_syscall_entry(audit_arch(), regs->regs[3],
                                    regs->regs[4], regs->regs[5],
@@ -475,6 +480,9 @@ asmlinkage void do_syscall_trace_leave(struct pt_regs *regs)
                audit_syscall_exit(AUDITSC_RESULT(regs->regs[0]),
                                   regs->regs[0]);
 
+       if (unlikely(test_thread_flag(TIF_SYSCALL_FTRACE)))
+               ftrace_syscall_exit(regs);
+
        step = test_thread_flag(TIF_SINGLESTEP);
        if (step || test_thread_flag(TIF_SYSCALL_TRACE))
                tracehook_report_syscall_exit(regs, step);
index dd38338553ef5484306907ae7465e36f93afa7c6..ceb409bf7741433bf5fd2c720a39ed0613eb4686 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/platform_device.h>
+#include <linux/lmb.h>
 #include <asm/uaccess.h>
 #include <asm/io.h>
 #include <asm/page.h>
@@ -233,39 +234,45 @@ void __init __add_active_range(unsigned int nid, unsigned long start_pfn,
 void __init setup_bootmem_allocator(unsigned long free_pfn)
 {
        unsigned long bootmap_size;
+       unsigned long bootmap_pages, bootmem_paddr;
+       u64 total_pages = (lmb_end_of_DRAM() - __MEMORY_START) >> PAGE_SHIFT;
+       int i;
+
+       bootmap_pages = bootmem_bootmap_pages(total_pages);
+
+       bootmem_paddr = lmb_alloc(bootmap_pages << PAGE_SHIFT, PAGE_SIZE);
 
        /*
         * Find a proper area for the bootmem bitmap. After this
         * bootstrap step all allocations (until the page allocator
         * is intact) must be done via bootmem_alloc().
         */
-       bootmap_size = init_bootmem_node(NODE_DATA(0), free_pfn,
+       bootmap_size = init_bootmem_node(NODE_DATA(0),
+                                        bootmem_paddr >> PAGE_SHIFT,
                                         min_low_pfn, max_low_pfn);
 
-       __add_active_range(0, min_low_pfn, max_low_pfn);
-       register_bootmem_low_pages();
-
-       node_set_online(0);
+       /* Add active regions with valid PFNs. */
+       for (i = 0; i < lmb.memory.cnt; i++) {
+               unsigned long start_pfn, end_pfn;
+               start_pfn = lmb.memory.region[i].base >> PAGE_SHIFT;
+               end_pfn = start_pfn + lmb_size_pages(&lmb.memory, i);
+               __add_active_range(0, start_pfn, end_pfn);
+       }
 
        /*
-        * Reserve the kernel text and
-        * Reserve the bootmem bitmap. We do this in two steps (first step
-        * was init_bootmem()), because this catches the (definitely buggy)
-        * case of us accidentally initializing the bootmem allocator with
-        * an invalid RAM area.
+        * Add all physical memory to the bootmem map and mark each
+        * area as present.
         */
-       reserve_bootmem(__MEMORY_START + CONFIG_ZERO_PAGE_OFFSET,
-                       (PFN_PHYS(free_pfn) + bootmap_size + PAGE_SIZE - 1) -
-                       (__MEMORY_START + CONFIG_ZERO_PAGE_OFFSET),
-                       BOOTMEM_DEFAULT);
+       register_bootmem_low_pages();
 
-       /*
-        * Reserve physical pages below CONFIG_ZERO_PAGE_OFFSET.
-        */
-       if (CONFIG_ZERO_PAGE_OFFSET != 0)
-               reserve_bootmem(__MEMORY_START, CONFIG_ZERO_PAGE_OFFSET,
+       /* Reserve the sections we're already using. */
+       for (i = 0; i < lmb.reserved.cnt; i++)
+               reserve_bootmem(lmb.reserved.region[i].base,
+                               lmb_size_bytes(&lmb.reserved, i),
                                BOOTMEM_DEFAULT);
 
+       node_set_online(0);
+
        sparse_memory_present_with_active_regions(0);
 
 #ifdef CONFIG_BLK_DEV_INITRD
@@ -296,12 +303,37 @@ void __init setup_bootmem_allocator(unsigned long free_pfn)
 static void __init setup_memory(void)
 {
        unsigned long start_pfn;
+       u64 base = min_low_pfn << PAGE_SHIFT;
+       u64 size = (max_low_pfn << PAGE_SHIFT) - base;
 
        /*
         * Partially used pages are not usable - thus
         * we are rounding upwards:
         */
        start_pfn = PFN_UP(__pa(_end));
+
+       lmb_add(base, size);
+
+       /*
+        * Reserve the kernel text and
+        * Reserve the bootmem bitmap. We do this in two steps (first step
+        * was init_bootmem()), because this catches the (definitely buggy)
+        * case of us accidentally initializing the bootmem allocator with
+        * an invalid RAM area.
+        */
+       lmb_reserve(__MEMORY_START + CONFIG_ZERO_PAGE_OFFSET,
+                   (PFN_PHYS(start_pfn) + PAGE_SIZE - 1) -
+                   (__MEMORY_START + CONFIG_ZERO_PAGE_OFFSET));
+
+       /*
+        * Reserve physical pages below CONFIG_ZERO_PAGE_OFFSET.
+        */
+       if (CONFIG_ZERO_PAGE_OFFSET != 0)
+               lmb_reserve(__MEMORY_START, CONFIG_ZERO_PAGE_OFFSET);
+
+       lmb_analyze();
+       lmb_dump_all();
+
        setup_bootmem_allocator(start_pfn);
 }
 #else
@@ -402,6 +434,7 @@ void __init setup_arch(char **cmdline_p)
        nodes_clear(node_online_map);
 
        /* Setup bootmem with available RAM */
+       lmb_init();
        setup_memory();
        sparse_init();
 
index fcc5de31f83b81a6a1305bae666623b0e212e34e..cec610888e283d19a575eea5bbd33c0eed0c996d 100644 (file)
@@ -106,8 +106,8 @@ EXPORT_SYMBOL(flush_dcache_page);
 EXPORT_SYMBOL(clear_user_page);
 #endif
 
-#ifdef CONFIG_FUNCTION_TRACER
-EXPORT_SYMBOL(mcount);
+#ifdef CONFIG_MCOUNT
+DECLARE_EXPORT(mcount);
 #endif
 EXPORT_SYMBOL(csum_partial);
 EXPORT_SYMBOL(csum_partial_copy_generic);
index 1a2a5eb76e41cd419182b358d24127758838a997..c2e45c48409cd64588f4ca460b4841bcad8a2909 100644 (file)
 #include <linux/stacktrace.h>
 #include <linux/thread_info.h>
 #include <linux/module.h>
+#include <asm/unwinder.h>
 #include <asm/ptrace.h>
+#include <asm/stacktrace.h>
+
+static void save_stack_warning(void *data, char *msg)
+{
+}
+
+static void
+save_stack_warning_symbol(void *data, char *msg, unsigned long symbol)
+{
+}
+
+static int save_stack_stack(void *data, char *name)
+{
+       return 0;
+}
 
 /*
  * Save stack-backtrace addresses into a stack_trace buffer.
  */
+static void save_stack_address(void *data, unsigned long addr, int reliable)
+{
+       struct stack_trace *trace = data;
+
+       if (!reliable)
+               return;
+
+       if (trace->skip > 0) {
+               trace->skip--;
+               return;
+       }
+
+       if (trace->nr_entries < trace->max_entries)
+               trace->entries[trace->nr_entries++] = addr;
+}
+
+static const struct stacktrace_ops save_stack_ops = {
+       .warning = save_stack_warning,
+       .warning_symbol = save_stack_warning_symbol,
+       .stack = save_stack_stack,
+       .address = save_stack_address,
+};
+
 void save_stack_trace(struct stack_trace *trace)
 {
        unsigned long *sp = (unsigned long *)current_stack_pointer;
 
-       while (!kstack_end(sp)) {
-               unsigned long addr = *sp++;
-
-               if (__kernel_text_address(addr)) {
-                       if (trace->skip > 0)
-                               trace->skip--;
-                       else
-                               trace->entries[trace->nr_entries++] = addr;
-                       if (trace->nr_entries >= trace->max_entries)
-                               break;
-               }
-       }
+       unwind_stack(current, NULL, sp,  &save_stack_ops, trace);
+       if (trace->nr_entries < trace->max_entries)
+               trace->entries[trace->nr_entries++] = ULONG_MAX;
 }
 EXPORT_SYMBOL_GPL(save_stack_trace);
 
+static void
+save_stack_address_nosched(void *data, unsigned long addr, int reliable)
+{
+       struct stack_trace *trace = (struct stack_trace *)data;
+
+       if (!reliable)
+               return;
+
+       if (in_sched_functions(addr))
+               return;
+
+       if (trace->skip > 0) {
+               trace->skip--;
+               return;
+       }
+
+       if (trace->nr_entries < trace->max_entries)
+               trace->entries[trace->nr_entries++] = addr;
+}
+
+static const struct stacktrace_ops save_stack_ops_nosched = {
+       .warning = save_stack_warning,
+       .warning_symbol = save_stack_warning_symbol,
+       .stack = save_stack_stack,
+       .address = save_stack_address_nosched,
+};
+
 void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
 {
        unsigned long *sp = (unsigned long *)tsk->thread.sp;
 
-       while (!kstack_end(sp)) {
-               unsigned long addr = *sp++;
-
-               if (__kernel_text_address(addr)) {
-                       if (in_sched_functions(addr))
-                               break;
-                       if (trace->skip > 0)
-                               trace->skip--;
-                       else
-                               trace->entries[trace->nr_entries++] = addr;
-                       if (trace->nr_entries >= trace->max_entries)
-                               break;
-               }
-       }
+       unwind_stack(current, NULL, sp,  &save_stack_ops_nosched, trace);
+       if (trace->nr_entries < trace->max_entries)
+               trace->entries[trace->nr_entries++] = ULONG_MAX;
 }
 EXPORT_SYMBOL_GPL(save_stack_trace_tsk);
index 9b352a1e3fb47af66009127566b2c25b79a66167..7f95f479060fe9557f78c66252b17b857f4a8605 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/smp.h>
 #include <linux/rtc.h>
 #include <asm/clock.h>
+#include <asm/hwblk.h>
 #include <asm/rtc.h>
 
 /* Dummy RTC ops */
@@ -91,11 +92,27 @@ module_init(rtc_generic_init);
 
 void (*board_time_init)(void);
 
+static void __init sh_late_time_init(void)
+{
+       /*
+        * Make sure all compiled-in early timers register themselves.
+        *
+        * Run probe() for two "earlytimer" devices, these will be the
+        * clockevents and clocksource devices respectively. In the event
+        * that only a clockevents device is available, we -ENODEV on the
+        * clocksource and the jiffies clocksource is used transparently
+        * instead. No error handling is necessary here.
+        */
+       early_platform_driver_register_all("earlytimer");
+       early_platform_driver_probe("earlytimer", 2, 0);
+}
+
 void __init time_init(void)
 {
        if (board_time_init)
                board_time_init();
 
+       hwblk_init();
        clk_init();
 
        rtc_sh_get_time(&xtime);
@@ -106,15 +123,5 @@ void __init time_init(void)
        local_timer_setup(smp_processor_id());
 #endif
 
-       /*
-        * Make sure all compiled-in early timers register themselves.
-        *
-        * Run probe() for two "earlytimer" devices, these will be the
-        * clockevents and clocksource devices respectively. In the event
-        * that only a clockevents device is available, we -ENODEV on the
-        * clocksource and the jiffies clocksource is used transparently
-        * instead. No error handling is necessary here.
-        */
-       early_platform_driver_register_all("earlytimer");
-       early_platform_driver_probe("earlytimer", 2, 0);
+       late_time_init = sh_late_time_init;
 }
index 2b772776fcda9e50cf6d7dfe0373668ad52307bb..563426487c6bea7aafab8c98a10b137412b7dfce 100644 (file)
@@ -858,30 +858,6 @@ void __init trap_init(void)
        per_cpu_trap_init();
 }
 
-void show_trace(struct task_struct *tsk, unsigned long *sp,
-               struct pt_regs *regs)
-{
-       unsigned long addr;
-
-       if (regs && user_mode(regs))
-               return;
-
-       printk("\nCall trace:\n");
-
-       while (!kstack_end(sp)) {
-               addr = *sp++;
-               if (kernel_text_address(addr))
-                       print_ip_sym(addr);
-       }
-
-       printk("\n");
-
-       if (!tsk)
-               tsk = current;
-
-       debug_show_held_locks(tsk);
-}
-
 void show_stack(struct task_struct *tsk, unsigned long *sp)
 {
        unsigned long stack;
diff --git a/arch/sh/kernel/unwinder.c b/arch/sh/kernel/unwinder.c
new file mode 100644 (file)
index 0000000..2b30fa2
--- /dev/null
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2009  Matt Fleming
+ *
+ * Based, in part, on kernel/time/clocksource.c.
+ *
+ * This file provides arbitration code for stack unwinders.
+ *
+ * Multiple stack unwinders can be available on a system, usually with
+ * the most accurate unwinder being the currently active one.
+ */
+#include <linux/errno.h>
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include <asm/unwinder.h>
+#include <asm/atomic.h>
+
+/*
+ * This is the most basic stack unwinder an architecture can
+ * provide. For architectures without reliable frame pointers, e.g.
+ * RISC CPUs, it can be implemented by looking through the stack for
+ * addresses that lie within the kernel text section.
+ *
+ * Other CPUs, e.g. x86, can use their frame pointer register to
+ * construct more accurate stack traces.
+ */
+static struct list_head unwinder_list;
+static struct unwinder stack_reader = {
+       .name = "stack-reader",
+       .dump = stack_reader_dump,
+       .rating = 50,
+       .list = {
+               .next = &unwinder_list,
+               .prev = &unwinder_list,
+       },
+};
+
+/*
+ * "curr_unwinder" points to the stack unwinder currently in use. This
+ * is the unwinder with the highest rating.
+ *
+ * "unwinder_list" is a linked-list of all available unwinders, sorted
+ * by rating.
+ *
+ * All modifications of "curr_unwinder" and "unwinder_list" must be
+ * performed whilst holding "unwinder_lock".
+ */
+static struct unwinder *curr_unwinder = &stack_reader;
+
+static struct list_head unwinder_list = {
+       .next = &stack_reader.list,
+       .prev = &stack_reader.list,
+};
+
+static DEFINE_SPINLOCK(unwinder_lock);
+
+static atomic_t unwinder_running = ATOMIC_INIT(0);
+
+/**
+ * select_unwinder - Select the best registered stack unwinder.
+ *
+ * Private function. Must hold unwinder_lock when called.
+ *
+ * Select the stack unwinder with the best rating. This is useful for
+ * setting up curr_unwinder.
+ */
+static struct unwinder *select_unwinder(void)
+{
+       struct unwinder *best;
+
+       if (list_empty(&unwinder_list))
+               return NULL;
+
+       best = list_entry(unwinder_list.next, struct unwinder, list);
+       if (best == curr_unwinder)
+               return NULL;
+
+       return best;
+}
+
+/*
+ * Enqueue the stack unwinder sorted by rating.
+ */
+static int unwinder_enqueue(struct unwinder *ops)
+{
+       struct list_head *tmp, *entry = &unwinder_list;
+
+       list_for_each(tmp, &unwinder_list) {
+               struct unwinder *o;
+
+               o = list_entry(tmp, struct unwinder, list);
+               if (o == ops)
+                       return -EBUSY;
+               /* Keep track of the place, where to insert */
+               if (o->rating >= ops->rating)
+                       entry = tmp;
+       }
+       list_add(&ops->list, entry);
+
+       return 0;
+}
+
+/**
+ * unwinder_register - Used to install new stack unwinder
+ * @u: unwinder to be registered
+ *
+ * Install the new stack unwinder on the unwinder list, which is sorted
+ * by rating.
+ *
+ * Returns -EBUSY if registration fails, zero otherwise.
+ */
+int unwinder_register(struct unwinder *u)
+{
+       unsigned long flags;
+       int ret;
+
+       spin_lock_irqsave(&unwinder_lock, flags);
+       ret = unwinder_enqueue(u);
+       if (!ret)
+               curr_unwinder = select_unwinder();
+       spin_unlock_irqrestore(&unwinder_lock, flags);
+
+       return ret;
+}
+
+/*
+ * Unwind the call stack and pass information to the stacktrace_ops
+ * functions. Also handle the case where we need to switch to a new
+ * stack dumper because the current one faulted unexpectedly.
+ */
+void unwind_stack(struct task_struct *task, struct pt_regs *regs,
+                 unsigned long *sp, const struct stacktrace_ops *ops,
+                 void *data)
+{
+       unsigned long flags;
+
+       /*
+        * The problem with unwinders with high ratings is that they are
+        * inherently more complicated than the simple ones with lower
+        * ratings. We are therefore more likely to fault in the
+        * complicated ones, e.g. hitting BUG()s. If we fault in the
+        * code for the current stack unwinder we try to downgrade to
+        * one with a lower rating.
+        *
+        * Hopefully this will give us a semi-reliable stacktrace so we
+        * can diagnose why curr_unwinder->dump() faulted.
+        */
+       if (atomic_inc_return(&unwinder_running) != 1) {
+               spin_lock_irqsave(&unwinder_lock, flags);
+
+               if (!list_is_singular(&unwinder_list)) {
+                       list_del(&curr_unwinder->list);
+                       curr_unwinder = select_unwinder();
+               }
+
+               spin_unlock_irqrestore(&unwinder_lock, flags);
+               atomic_dec(&unwinder_running);
+       }
+
+       curr_unwinder->dump(task, regs, sp, ops, data);
+
+       atomic_dec(&unwinder_running);
+}
index f53c76acaede2f1af80aaec431e53308c4681bee..1b7d9d541e018303ca5b9273dd2683f1d061a0fa 100644 (file)
@@ -12,7 +12,7 @@ OUTPUT_ARCH(sh)
 
 #include <asm/thread_info.h>
 #include <asm/cache.h>
-#include <asm-generic/vmlinux.lds.h>
+#include <asm/vmlinux.lds.h>
 
 ENTRY(_start)
 SECTIONS
@@ -50,12 +50,7 @@ SECTIONS
                _etext = .;             /* End of text section */
        } = 0x0009
 
-       . = ALIGN(16);          /* Exception table */
-       __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
-               __start___ex_table = .;
-               *(__ex_table)
-               __stop___ex_table = .;
-       }
+       EXCEPTION_TABLE(16)
 
        NOTES
        RO_DATA(PAGE_SIZE)
@@ -71,69 +66,16 @@ SECTIONS
                __uncached_end = .;
        }
 
-       . = ALIGN(THREAD_SIZE);
-       .data : AT(ADDR(.data) - LOAD_OFFSET) {         /* Data */
-               *(.data.init_task)
-
-               . = ALIGN(L1_CACHE_BYTES);
-               *(.data.cacheline_aligned)
-
-               . = ALIGN(L1_CACHE_BYTES);
-               *(.data.read_mostly)
-
-               . = ALIGN(PAGE_SIZE);
-               *(.data.page_aligned)
-
-               __nosave_begin = .;
-               *(.data.nosave)
-               . = ALIGN(PAGE_SIZE);
-               __nosave_end = .;
-
-               DATA_DATA
-               CONSTRUCTORS
-       }
+       RW_DATA_SECTION(L1_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE)
 
        _edata = .;                     /* End of data section */
 
-       . = ALIGN(PAGE_SIZE);           /* Init code and data */
-       .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
-               __init_begin = .;
-               _sinittext = .;
-               INIT_TEXT
-               _einittext = .;
-       }
-
-       .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) { INIT_DATA }
-
-       . = ALIGN(16);
-       .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) {
-               __setup_start = .;
-               *(.init.setup)
-               __setup_end = .;
-       }
-
-       .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) {
-               __initcall_start = .;
-               INITCALLS
-               __initcall_end = .;
-       }
-
-       .con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) {
-               __con_initcall_start = .;
-               *(.con_initcall.init)
-               __con_initcall_end = .;
-       }
-
-       SECURITY_INIT
+       DWARF_EH_FRAME
 
-#ifdef CONFIG_BLK_DEV_INITRD
-       . = ALIGN(PAGE_SIZE);
-       .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) {
-               __initramfs_start = .;
-               *(.init.ramfs)
-               __initramfs_end = .;
-       }
-#endif
+       . = ALIGN(PAGE_SIZE);           /* Init code and data */
+       __init_begin = .;
+       INIT_TEXT_SECTION(PAGE_SIZE)
+       INIT_DATA_SECTION(16)
 
        . = ALIGN(4);
        .machvec.init : AT(ADDR(.machvec.init) - LOAD_OFFSET) {
@@ -152,16 +94,10 @@ SECTIONS
        .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) { EXIT_DATA }
 
        . = ALIGN(PAGE_SIZE);
-       .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
-               __init_end = .;
-               __bss_start = .;                /* BSS */
-               *(.bss.page_aligned)
-               *(.bss)
-               *(COMMON)
-               . = ALIGN(4);
-               _ebss = .;                      /* uClinux MTD sucks */
-               _end = . ;
-       }
+       __init_end = .;
+       BSS_SECTION(0, PAGE_SIZE, 4)
+       _ebss = .;                      /* uClinux MTD sucks */
+       _end = . ;
 
        /*
         * When something in the kernel is NOT compiled as a module, the
@@ -170,7 +106,7 @@ SECTIONS
         * it's a module.
         */
        /DISCARD/ : {
-               *(.exitcall.exit)
+               EXIT_CALL
        }
 
        STABS_DEBUG
index aaea580b65bba98ccf687296fe4a6a735fe72ccc..c2b28d8b2dd1b2faef732da7cae6cac81278ee47 100644 (file)
@@ -24,7 +24,7 @@ memcpy-y                      := memcpy.o
 memcpy-$(CONFIG_CPU_SH4)       := memcpy-sh4.o
 
 lib-$(CONFIG_MMU)              += copy_page.o clear_page.o
-lib-$(CONFIG_FUNCTION_TRACER)  += mcount.o
+lib-$(CONFIG_MCOUNT)           += mcount.o
 lib-y                          += $(memcpy-y) $(udivsi3-y)
 
 EXTRA_CFLAGS += -Werror
index 110fbfe1831f87cb04fe8d21675dc4055d66f61e..84a57761f17e90ee8cfdfd71dfce2b02480002a4 100644 (file)
@@ -1,14 +1,16 @@
 /*
  * arch/sh/lib/mcount.S
  *
- *  Copyright (C) 2008  Paul Mundt
- *  Copyright (C) 2008  Matt Fleming
+ *  Copyright (C) 2008, 2009  Paul Mundt
+ *  Copyright (C) 2008, 2009  Matt Fleming
  *
  * 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
  * for more details.
  */
 #include <asm/ftrace.h>
+#include <asm/thread_info.h>
+#include <asm/asm-offsets.h>
 
 #define MCOUNT_ENTER()         \
        mov.l   r4, @-r15;      \
        rts;                    \
         mov.l  @r15+, r4
 
+#ifdef CONFIG_STACK_DEBUG
+/*
+ * Perform diagnostic checks on the state of the kernel stack.
+ *
+ * Check for stack overflow. If there is less than 1KB free
+ * then it has overflowed.
+ *
+ * Make sure the stack pointer contains a valid address. Valid
+ * addresses for kernel stacks are anywhere after the bss
+ * (after _ebss) and anywhere in init_thread_union (init_stack).
+ */
+#define STACK_CHECK()                                  \
+       mov     #(THREAD_SIZE >> 10), r0;               \
+       shll8   r0;                                     \
+       shll2   r0;                                     \
+                                                       \
+       /* r1 = sp & (THREAD_SIZE - 1) */               \
+       mov     #-1, r1;                                \
+       add     r0, r1;                                 \
+       and     r15, r1;                                \
+                                                       \
+       mov     #TI_SIZE, r3;                           \
+       mov     #(STACK_WARN >> 8), r2;                 \
+       shll8   r2;                                     \
+       add     r3, r2;                                 \
+                                                       \
+       /* Is the stack overflowing? */                 \
+       cmp/hi  r2, r1;                                 \
+       bf      stack_panic;                            \
+                                                       \
+       /* If sp > _ebss then we're OK. */              \
+       mov.l   .L_ebss, r1;                            \
+       cmp/hi  r1, r15;                                \
+       bt      1f;                                     \
+                                                       \
+       /* If sp < init_stack, we're not OK. */         \
+       mov.l   .L_init_thread_union, r1;               \
+       cmp/hs  r1, r15;                                \
+       bf      stack_panic;                            \
+                                                       \
+       /* If sp > init_stack && sp < _ebss, not OK. */ \
+       add     r0, r1;                                 \
+       cmp/hs  r1, r15;                                \
+       bt      stack_panic;                            \
+1:
+#else
+#define STACK_CHECK()
+#endif /* CONFIG_STACK_DEBUG */
+
        .align 2
        .globl  _mcount
        .type   _mcount,@function
        .type   mcount,@function
 _mcount:
 mcount:
+       STACK_CHECK()
+
+#ifndef CONFIG_FUNCTION_TRACER
+       rts
+        nop
+#else
+#ifndef CONFIG_DYNAMIC_FTRACE
+       mov.l   .Lfunction_trace_stop, r0
+       mov.l   @r0, r0
+       tst     r0, r0
+       bf      ftrace_stub
+#endif
+
        MCOUNT_ENTER()
 
 #ifdef CONFIG_DYNAMIC_FTRACE
@@ -52,16 +116,69 @@ mcount_call:
        jsr     @r6
         nop
 
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+       mov.l   .Lftrace_graph_return, r6
+       mov.l   .Lftrace_stub, r7
+       cmp/eq  r6, r7
+       bt      1f
+
+       mov.l   .Lftrace_graph_caller, r0
+       jmp     @r0
+        nop
+
+1:
+       mov.l   .Lftrace_graph_entry, r6
+       mov.l   .Lftrace_graph_entry_stub, r7
+       cmp/eq  r6, r7
+       bt      skip_trace
+
+       mov.l   .Lftrace_graph_caller, r0
+       jmp     @r0
+        nop
+
+       .align 2
+.Lftrace_graph_return:
+       .long   ftrace_graph_return
+.Lftrace_graph_entry:
+       .long   ftrace_graph_entry
+.Lftrace_graph_entry_stub:
+       .long   ftrace_graph_entry_stub
+.Lftrace_graph_caller:
+       .long   ftrace_graph_caller
+#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
+
+       .globl skip_trace
 skip_trace:
        MCOUNT_LEAVE()
 
        .align 2
 .Lftrace_trace_function:
-       .long   ftrace_trace_function
+       .long   ftrace_trace_function
 
 #ifdef CONFIG_DYNAMIC_FTRACE
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+/*
+ * NOTE: Do not move either ftrace_graph_call or ftrace_caller
+ * as this will affect the calculation of GRAPH_INSN_OFFSET.
+ */
+       .globl ftrace_graph_call
+ftrace_graph_call:
+       mov.l   .Lskip_trace, r0
+       jmp     @r0
+        nop
+
+       .align 2
+.Lskip_trace:
+       .long   skip_trace
+#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
+
        .globl ftrace_caller
 ftrace_caller:
+       mov.l   .Lfunction_trace_stop, r0
+       mov.l   @r0, r0
+       tst     r0, r0
+       bf      ftrace_stub
+
        MCOUNT_ENTER()
 
        .globl ftrace_call
@@ -70,9 +187,18 @@ ftrace_call:
        jsr     @r6
         nop
 
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+       bra     ftrace_graph_call
+        nop
+#else
        MCOUNT_LEAVE()
+#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
 #endif /* CONFIG_DYNAMIC_FTRACE */
 
+       .align 2
+.Lfunction_trace_stop:
+       .long   function_trace_stop
+
 /*
  * NOTE: From here on the locations of the .Lftrace_stub label and
  * ftrace_stub itself are fixed. Adding additional data here will skew
@@ -80,7 +206,6 @@ ftrace_call:
  * Place new labels either after the ftrace_stub body, or before
  * ftrace_caller. You have been warned.
  */
-       .align 2
 .Lftrace_stub:
        .long   ftrace_stub
 
@@ -88,3 +213,98 @@ ftrace_call:
 ftrace_stub:
        rts
         nop
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+       .globl  ftrace_graph_caller
+ftrace_graph_caller:
+       mov.l   2f, r0
+       mov.l   @r0, r0
+       tst     r0, r0
+       bt      1f
+
+       mov.l   3f, r1
+       jmp     @r1
+        nop
+1:
+       /*
+        * MCOUNT_ENTER() pushed 5 registers onto the stack, so
+        * the stack address containing our return address is
+        * r15 + 20.
+        */
+       mov     #20, r0
+       add     r15, r0
+       mov     r0, r4
+
+       mov.l   .Lprepare_ftrace_return, r0
+       jsr     @r0
+        nop
+
+       MCOUNT_LEAVE()
+
+       .align 2
+2:     .long   function_trace_stop
+3:     .long   skip_trace
+.Lprepare_ftrace_return:
+       .long   prepare_ftrace_return
+
+       .globl  return_to_handler
+return_to_handler:
+       /*
+        * Save the return values.
+        */
+       mov.l   r0, @-r15
+       mov.l   r1, @-r15
+
+       mov     #0, r4
+
+       mov.l   .Lftrace_return_to_handler, r0
+       jsr     @r0
+        nop
+
+       /*
+        * The return value from ftrace_return_handler has the real
+        * address that we should return to.
+        */
+       lds     r0, pr
+       mov.l   @r15+, r1
+       rts
+        mov.l  @r15+, r0
+
+
+       .align 2
+.Lftrace_return_to_handler:
+       .long   ftrace_return_to_handler
+#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
+#endif /* CONFIG_FUNCTION_TRACER */
+
+#ifdef CONFIG_STACK_DEBUG
+       .globl  stack_panic
+stack_panic:
+       mov.l   .Ldump_stack, r0
+       jsr     @r0
+        nop
+
+       mov.l   .Lpanic, r0
+       jsr     @r0
+        mov.l  .Lpanic_s, r4
+
+       rts
+        nop
+
+       .align 2
+.L_ebss:
+       .long   _ebss
+.L_init_thread_union:
+       .long   init_thread_union
+.Lpanic:
+       .long   panic
+.Lpanic_s:
+       .long   .Lpanic_str
+.Ldump_stack:
+       .long   dump_stack
+
+       .section        .rodata
+       .align 2
+.Lpanic_str:
+       .string "Stack error"
+#endif /* CONFIG_STACK_DEBUG */
index 71925946f1e16d6294301581ade0bb6f0fda050a..dbbdeba2cee5e2e508c9bcbb485548f7223fa9cf 100644 (file)
@@ -2,7 +2,7 @@
  * Page fault handler for SH with an MMU.
  *
  *  Copyright (C) 1999  Niibe Yutaka
- *  Copyright (C) 2003 - 2008  Paul Mundt
+ *  Copyright (C) 2003 - 2009  Paul Mundt
  *
  *  Based on linux/arch/i386/mm/fault.c:
  *   Copyright (C) 1995  Linus Torvalds
@@ -25,18 +25,91 @@ static inline int notify_page_fault(struct pt_regs *regs, int trap)
 {
        int ret = 0;
 
-#ifdef CONFIG_KPROBES
-       if (!user_mode(regs)) {
+       if (kprobes_built_in() && !user_mode(regs)) {
                preempt_disable();
                if (kprobe_running() && kprobe_fault_handler(regs, trap))
                        ret = 1;
                preempt_enable();
        }
-#endif
 
        return ret;
 }
 
+static inline pmd_t *vmalloc_sync_one(pgd_t *pgd, unsigned long address)
+{
+       unsigned index = pgd_index(address);
+       pgd_t *pgd_k;
+       pud_t *pud, *pud_k;
+       pmd_t *pmd, *pmd_k;
+
+       pgd += index;
+       pgd_k = init_mm.pgd + index;
+
+       if (!pgd_present(*pgd_k))
+               return NULL;
+
+       pud = pud_offset(pgd, address);
+       pud_k = pud_offset(pgd_k, address);
+       if (!pud_present(*pud_k))
+               return NULL;
+
+       pmd = pmd_offset(pud, address);
+       pmd_k = pmd_offset(pud_k, address);
+       if (!pmd_present(*pmd_k))
+               return NULL;
+
+       if (!pmd_present(*pmd))
+               set_pmd(pmd, *pmd_k);
+       else {
+               /*
+                * The page tables are fully synchronised so there must
+                * be another reason for the fault. Return NULL here to
+                * signal that we have not taken care of the fault.
+                */
+               BUG_ON(pmd_page(*pmd) != pmd_page(*pmd_k));
+               return NULL;
+       }
+
+       return pmd_k;
+}
+
+/*
+ * Handle a fault on the vmalloc or module mapping area
+ */
+static noinline int vmalloc_fault(unsigned long address)
+{
+       pgd_t *pgd_k;
+       pmd_t *pmd_k;
+       pte_t *pte_k;
+
+       /* Make sure we are in vmalloc area: */
+       if (!(address >= VMALLOC_START && address < VMALLOC_END))
+               return -1;
+
+       /*
+        * Synchronize this task's top level page-table
+        * with the 'reference' page table.
+        *
+        * Do _not_ use "current" here. We might be inside
+        * an interrupt in the middle of a task switch..
+        */
+       pgd_k = get_TTB();
+       pmd_k = vmalloc_sync_one(pgd_k, address);
+       if (!pmd_k)
+               return -1;
+
+       pte_k = pte_offset_kernel(pmd_k, address);
+       if (!pte_present(*pte_k))
+               return -1;
+
+       return 0;
+}
+
+static int fault_in_kernel_space(unsigned long address)
+{
+       return address >= TASK_SIZE;
+}
+
 /*
  * This routine handles page faults.  It determines the address,
  * and the problem, and then passes it off to one of the appropriate
@@ -46,6 +119,7 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs,
                                        unsigned long writeaccess,
                                        unsigned long address)
 {
+       unsigned long vec;
        struct task_struct *tsk;
        struct mm_struct *mm;
        struct vm_area_struct * vma;
@@ -53,59 +127,30 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs,
        int fault;
        siginfo_t info;
 
-       /*
-        * We don't bother with any notifier callbacks here, as they are
-        * all handled through the __do_page_fault() fast-path.
-        */
-
        tsk = current;
+       mm = tsk->mm;
        si_code = SEGV_MAPERR;
+       vec = lookup_exception_vector();
 
-       if (unlikely(address >= TASK_SIZE)) {
-               /*
-                * Synchronize this task's top level page-table
-                * with the 'reference' page table.
-                *
-                * Do _not_ use "tsk" here. We might be inside
-                * an interrupt in the middle of a task switch..
-                */
-               int offset = pgd_index(address);
-               pgd_t *pgd, *pgd_k;
-               pud_t *pud, *pud_k;
-               pmd_t *pmd, *pmd_k;
-
-               pgd = get_TTB() + offset;
-               pgd_k = swapper_pg_dir + offset;
-
-               if (!pgd_present(*pgd)) {
-                       if (!pgd_present(*pgd_k))
-                               goto bad_area_nosemaphore;
-                       set_pgd(pgd, *pgd_k);
+       /*
+        * We fault-in kernel-space virtual memory on-demand. The
+        * 'reference' page table is init_mm.pgd.
+        *
+        * NOTE! We MUST NOT take any locks for this case. We may
+        * be in an interrupt or a critical region, and should
+        * only copy the information from the master page table,
+        * nothing more.
+        */
+       if (unlikely(fault_in_kernel_space(address))) {
+               if (vmalloc_fault(address) >= 0)
                        return;
-               }
-
-               pud = pud_offset(pgd, address);
-               pud_k = pud_offset(pgd_k, address);
-
-               if (!pud_present(*pud)) {
-                       if (!pud_present(*pud_k))
-                               goto bad_area_nosemaphore;
-                       set_pud(pud, *pud_k);
+               if (notify_page_fault(regs, vec))
                        return;
-               }
 
-               pmd = pmd_offset(pud, address);
-               pmd_k = pmd_offset(pud_k, address);
-               if (pmd_present(*pmd) || !pmd_present(*pmd_k))
-                       goto bad_area_nosemaphore;
-               set_pmd(pmd, *pmd_k);
-
-               return;
+               goto bad_area_nosemaphore;
        }
 
-       mm = tsk->mm;
-
-       if (unlikely(notify_page_fault(regs, lookup_exception_vector())))
+       if (unlikely(notify_page_fault(regs, vec)))
                return;
 
        /* Only enable interrupts if they were on before the fault */
@@ -115,8 +160,8 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs,
        perf_swcounter_event(PERF_COUNT_SW_PAGE_FAULTS, 1, 0, regs, address);
 
        /*
-        * If we're in an interrupt or have no user
-        * context, we must not take the fault..
+        * If we're in an interrupt, have no user context or are running
+        * in an atomic region then we must not take the fault:
         */
        if (in_atomic() || !mm)
                goto no_context;
@@ -132,10 +177,11 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs,
                goto bad_area;
        if (expand_stack(vma, address))
                goto bad_area;
-/*
- * Ok, we have a good vm_area for this memory access, so
- * we can handle it..
- */
+
+       /*
+        * Ok, we have a good vm_area for this memory access, so
+        * we can handle it..
+        */
 good_area:
        si_code = SEGV_ACCERR;
        if (writeaccess) {
@@ -173,10 +219,10 @@ survive:
        up_read(&mm->mmap_sem);
        return;
 
-/*
- * Something tried to access memory that isn't in our memory map..
- * Fix it, but check if it's kernel or user first..
- */
+       /*
       * Something tried to access memory that isn't in our memory map..
       * Fix it, but check if it's kernel or user first..
       */
 bad_area:
        up_read(&mm->mmap_sem);
 
index 828c8597219da2b0e07fe9c73218b4d186521d92..b16843d02b76f424051988266c58488d8c93951f 100644 (file)
@@ -94,7 +94,6 @@ static struct resource *shmedia_find_resource(struct resource *root,
 static void __iomem *shmedia_alloc_io(unsigned long phys, unsigned long size,
                                      const char *name, unsigned long flags)
 {
-       static int printed_full;
        struct xresource *xres;
        struct resource *res;
        char *tack;
@@ -108,11 +107,8 @@ static void __iomem *shmedia_alloc_io(unsigned long phys, unsigned long size,
                tack = xres->xname;
                res = &xres->xres;
        } else {
-               if (!printed_full) {
-                       printk(KERN_NOTICE "%s: done with statics, "
+               printk_once(KERN_NOTICE "%s: done with statics, "
                               "switching to kmalloc\n", __func__);
-                       printed_full = 1;
-               }
                tlen = strlen(name);
                tack = kmalloc(sizeof(struct resource) + tlen + 1, GFP_KERNEL);
                if (!tack)
index 095d93bec7cd2aebe1b6b6b408b13eff1e2a617b..9b784fdb947c70eb90c4d14411b2bfb2feac3b8e 100644 (file)
@@ -9,6 +9,7 @@
  */
 #include <linux/module.h>
 #include <linux/bootmem.h>
+#include <linux/lmb.h>
 #include <linux/mm.h>
 #include <linux/numa.h>
 #include <linux/pfn.h>
@@ -26,6 +27,15 @@ EXPORT_SYMBOL_GPL(node_data);
 void __init setup_memory(void)
 {
        unsigned long free_pfn = PFN_UP(__pa(_end));
+       u64 base = min_low_pfn << PAGE_SHIFT;
+       u64 size = (max_low_pfn << PAGE_SHIFT) - min_low_pfn;
+
+       lmb_add(base, size);
+
+       /* Reserve the LMB regions used by the kernel, initrd, etc.. */
+       lmb_reserve(__MEMORY_START + CONFIG_ZERO_PAGE_OFFSET,
+                   (PFN_PHYS(free_pfn) + PAGE_SIZE - 1) -
+                   (__MEMORY_START + CONFIG_ZERO_PAGE_OFFSET));
 
        /*
         * Node 0 sets up its pgdat at the first available pfn,
@@ -45,24 +55,23 @@ void __init setup_memory(void)
 
 void __init setup_bootmem_node(int nid, unsigned long start, unsigned long end)
 {
-       unsigned long bootmap_pages, bootmap_start, bootmap_size;
-       unsigned long start_pfn, free_pfn, end_pfn;
+       unsigned long bootmap_pages;
+       unsigned long start_pfn, end_pfn;
+       unsigned long bootmem_paddr;
 
        /* Don't allow bogus node assignment */
        BUG_ON(nid > MAX_NUMNODES || nid == 0);
 
-       /*
-        * The free pfn starts at the beginning of the range, and is
-        * advanced as necessary for pgdat and node map allocations.
-        */
-       free_pfn = start_pfn = start >> PAGE_SHIFT;
+       start_pfn = start >> PAGE_SHIFT;
        end_pfn = end >> PAGE_SHIFT;
 
+       lmb_add(start, end - start);
+
        __add_active_range(nid, start_pfn, end_pfn);
 
        /* Node-local pgdat */
-       NODE_DATA(nid) = pfn_to_kaddr(free_pfn);
-       free_pfn += PFN_UP(sizeof(struct pglist_data));
+       NODE_DATA(nid) = __va(lmb_alloc_base(sizeof(struct pglist_data),
+                                            SMP_CACHE_BYTES, end_pfn));
        memset(NODE_DATA(nid), 0, sizeof(struct pglist_data));
 
        NODE_DATA(nid)->bdata = &bootmem_node_data[nid];
@@ -71,16 +80,17 @@ void __init setup_bootmem_node(int nid, unsigned long start, unsigned long end)
 
        /* Node-local bootmap */
        bootmap_pages = bootmem_bootmap_pages(end_pfn - start_pfn);
-       bootmap_start = (unsigned long)pfn_to_kaddr(free_pfn);
-       bootmap_size = init_bootmem_node(NODE_DATA(nid), free_pfn, start_pfn,
-                                   end_pfn);
+       bootmem_paddr = lmb_alloc_base(bootmap_pages << PAGE_SHIFT,
+                                      PAGE_SIZE, end_pfn);
+       init_bootmem_node(NODE_DATA(nid), bootmem_paddr >> PAGE_SHIFT,
+                         start_pfn, end_pfn);
 
        free_bootmem_with_active_regions(nid, end_pfn);
 
        /* Reserve the pgdat and bootmap space with the bootmem allocator */
        reserve_bootmem_node(NODE_DATA(nid), start_pfn << PAGE_SHIFT,
                             sizeof(struct pglist_data), BOOTMEM_DEFAULT);
-       reserve_bootmem_node(NODE_DATA(nid), free_pfn << PAGE_SHIFT,
+       reserve_bootmem_node(NODE_DATA(nid), bootmem_paddr,
                             bootmap_pages << PAGE_SHIFT, BOOTMEM_DEFAULT);
 
        /* It's up */
index 9499a2914f89b4e10eeae491ddd1cd0a3975021f..2bc74de23f08ddb425c086999af359874416e3b6 100644 (file)
 #include <linux/sched.h>
 #include <linux/kallsyms.h>
 #include <linux/mm.h>
+#include <asm/unwinder.h>
 #include <asm/ptrace.h>
 #include <asm/uaccess.h>
 #include <asm/sections.h>
+#include <asm/stacktrace.h>
+
+static void backtrace_warning_symbol(void *data, char *msg,
+                                    unsigned long symbol)
+{
+       /* Ignore warnings */
+}
+
+static void backtrace_warning(void *data, char *msg)
+{
+       /* Ignore warnings */
+}
+
+static int backtrace_stack(void *data, char *name)
+{
+       /* Yes, we want all stacks */
+       return 0;
+}
+
+static void backtrace_address(void *data, unsigned long addr, int reliable)
+{
+       unsigned int *depth = data;
+
+       if ((*depth)--)
+               oprofile_add_trace(addr);
+}
+
+static struct stacktrace_ops backtrace_ops = {
+       .warning = backtrace_warning,
+       .warning_symbol = backtrace_warning_symbol,
+       .stack = backtrace_stack,
+       .address = backtrace_address,
+};
 
 /* Limit to stop backtracing too far. */
 static int backtrace_limit = 20;
@@ -47,50 +81,6 @@ user_backtrace(unsigned long *stackaddr, struct pt_regs *regs)
        return stackaddr;
 }
 
-/*
- * |             | /\ Higher addresses
- * |             |
- * --------------- stack base (address of current_thread_info)
- * | thread info |
- * .             .
- * |    stack    |
- * --------------- saved regs->regs[15] value if valid
- * .             .
- * --------------- struct pt_regs stored on stack (struct pt_regs *)
- * |             |
- * .             .
- * |             |
- * --------------- ???
- * |             |
- * |             | \/ Lower addresses
- *
- * Thus, &pt_regs <-> stack base restricts the valid(ish) fp values
- */
-static int valid_kernel_stack(unsigned long *stackaddr, struct pt_regs *regs)
-{
-       unsigned long stack = (unsigned long)regs;
-       unsigned long stack_base = (stack & ~(THREAD_SIZE - 1)) + THREAD_SIZE;
-
-       return ((unsigned long)stackaddr > stack) && ((unsigned long)stackaddr < stack_base);
-}
-
-static unsigned long *
-kernel_backtrace(unsigned long *stackaddr, struct pt_regs *regs)
-{
-       unsigned long addr;
-
-       /*
-        * If not a valid kernel address, keep going till we find one
-        * or the SP stops being a valid address.
-        */
-       do {
-               addr = *stackaddr++;
-               oprofile_add_trace(addr);
-       } while (valid_kernel_stack(stackaddr, regs));
-
-       return stackaddr;
-}
-
 void sh_backtrace(struct pt_regs * const regs, unsigned int depth)
 {
        unsigned long *stackaddr;
@@ -103,9 +93,9 @@ void sh_backtrace(struct pt_regs * const regs, unsigned int depth)
 
        stackaddr = (unsigned long *)regs->regs[15];
        if (!user_mode(regs)) {
-               while (depth-- && valid_kernel_stack(stackaddr, regs))
-                       stackaddr = kernel_backtrace(stackaddr, regs);
-
+               if (depth)
+                       unwind_stack(NULL, regs, stackaddr,
+                                    &backtrace_ops, &depth);
                return;
        }
 
index fec3a53b86504391375d200462825ae3d74cd132..09eef360dde13342792025fcf098819e78d9e012 100644 (file)
@@ -56,3 +56,4 @@ SH7785LCR             SH_SH7785LCR
 URQUELL                        SH_URQUELL
 ESPT                   SH_ESPT
 POLARIS                        SH_POLARIS
+KFR2R09                        SH_KFR2R09
index 8e2feb563347151d220ed23155074dc5e0f0c761..4cbb87ad070ac122d1e7a635c81afd7c19e32c61 100644 (file)
@@ -662,10 +662,11 @@ static irqreturn_t sci_rx_interrupt(int irq, void *port)
 static irqreturn_t sci_tx_interrupt(int irq, void *ptr)
 {
        struct uart_port *port = ptr;
+       unsigned long flags;
 
-       spin_lock_irq(&port->lock);
+       spin_lock_irqsave(&port->lock, flags);
        sci_transmit_chars(port);
-       spin_unlock_irq(&port->lock);
+       spin_unlock_irqrestore(&port->lock, flags);
 
        return IRQ_HANDLED;
 }
index 7f8e83a954ac6881861bdc0d2e334ea85944db7a..b7f10bc25c2c366d2594184e3623424f405717ce 100644 (file)
@@ -360,16 +360,6 @@ config USB_M66592
        default USB_GADGET
        select USB_GADGET_SELECTED
 
-config SUPERH_BUILT_IN_M66592
-       boolean "Enable SuperH built-in USB like the M66592"
-       depends on USB_GADGET_M66592 && CPU_SUBTYPE_SH7722
-       help
-          SH7722 has USB like the M66592.
-
-          The transfer rate is very slow when use "Ethernet Gadget".
-          However, this problem is improved if change a value of
-          NET_IP_ALIGN to 4.
-
 #
 # Controllers available only in discrete form (and all PCI controllers)
 #
index 43dcf9e1af6b06bc46379ccfe1bcfb05aa25f524..a61c70caff128259817f0cb5658a781155543079 100644 (file)
 
 #include "m66592-udc.h"
 
-
 MODULE_DESCRIPTION("M66592 USB gadget driver");
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Yoshihiro Shimoda");
 MODULE_ALIAS("platform:m66592_udc");
 
-#define DRIVER_VERSION "18 Oct 2007"
-
-/* module parameters */
-#if defined(CONFIG_SUPERH_BUILT_IN_M66592)
-static unsigned short endian = M66592_LITTLE;
-module_param(endian, ushort, 0644);
-MODULE_PARM_DESC(endian, "data endian: big=0, little=0 (default=0)");
-#else
-static unsigned short clock = M66592_XTAL24;
-module_param(clock, ushort, 0644);
-MODULE_PARM_DESC(clock, "input clock: 48MHz=32768, 24MHz=16384, 12MHz=0 "
-               "(default=16384)");
-
-static unsigned short vif = M66592_LDRV;
-module_param(vif, ushort, 0644);
-MODULE_PARM_DESC(vif, "input VIF: 3.3V=32768, 1.5V=0 (default=32768)");
-
-static unsigned short endian;
-module_param(endian, ushort, 0644);
-MODULE_PARM_DESC(endian, "data endian: big=256, little=0 (default=0)");
-
-static unsigned short irq_sense = M66592_INTL;
-module_param(irq_sense, ushort, 0644);
-MODULE_PARM_DESC(irq_sense, "IRQ sense: low level=2, falling edge=0 "
-               "(default=2)");
-#endif
+#define DRIVER_VERSION "21 July 2009"
 
 static const char udc_name[] = "m66592_udc";
 static const char *m66592_ep_name[] = {
@@ -244,6 +218,7 @@ static inline int get_buffer_size(struct m66592 *m66592, u16 pipenum)
 static inline void pipe_change(struct m66592 *m66592, u16 pipenum)
 {
        struct m66592_ep *ep = m66592->pipenum2ep[pipenum];
+       unsigned short mbw;
 
        if (ep->use_dma)
                return;
@@ -252,7 +227,12 @@ static inline void pipe_change(struct m66592 *m66592, u16 pipenum)
 
        ndelay(450);
 
-       m66592_bset(m66592, M66592_MBW, ep->fifosel);
+       if (m66592->pdata->on_chip)
+               mbw = M66592_MBW_32;
+       else
+               mbw = M66592_MBW_16;
+
+       m66592_bset(m66592, mbw, ep->fifosel);
 }
 
 static int pipe_buffer_setting(struct m66592 *m66592,
@@ -276,24 +256,27 @@ static int pipe_buffer_setting(struct m66592 *m66592,
                buf_bsize = 0;
                break;
        case M66592_BULK:
-               bufnum = m66592->bi_bufnum +
-                        (info->pipe - M66592_BASE_PIPENUM_BULK) * 16;
-               m66592->bi_bufnum += 16;
+               /* isochronous pipes may be used as bulk pipes */
+               if (info->pipe > M66592_BASE_PIPENUM_BULK)
+                       bufnum = info->pipe - M66592_BASE_PIPENUM_BULK;
+               else
+                       bufnum = info->pipe - M66592_BASE_PIPENUM_ISOC;
+
+               bufnum = M66592_BASE_BUFNUM + (bufnum * 16);
                buf_bsize = 7;
                pipecfg |= M66592_DBLB;
                if (!info->dir_in)
                        pipecfg |= M66592_SHTNAK;
                break;
        case M66592_ISO:
-               bufnum = m66592->bi_bufnum +
+               bufnum = M66592_BASE_BUFNUM +
                         (info->pipe - M66592_BASE_PIPENUM_ISOC) * 16;
-               m66592->bi_bufnum += 16;
                buf_bsize = 7;
                break;
        }
-       if (m66592->bi_bufnum > M66592_MAX_BUFNUM) {
-               pr_err("m66592 pipe memory is insufficient(%d)\n",
-                               m66592->bi_bufnum);
+
+       if (buf_bsize && ((bufnum + 16) >= M66592_MAX_BUFNUM)) {
+               pr_err("m66592 pipe memory is insufficient\n");
                return -ENOMEM;
        }
 
@@ -313,17 +296,6 @@ static void pipe_buffer_release(struct m66592 *m66592,
        if (info->pipe == 0)
                return;
 
-       switch (info->type) {
-       case M66592_BULK:
-               if (is_bulk_pipe(info->pipe))
-                       m66592->bi_bufnum -= 16;
-               break;
-       case M66592_ISO:
-               if (is_isoc_pipe(info->pipe))
-                       m66592->bi_bufnum -= 16;
-               break;
-       }
-
        if (is_bulk_pipe(info->pipe)) {
                m66592->bulk--;
        } else if (is_interrupt_pipe(info->pipe))
@@ -340,6 +312,7 @@ static void pipe_buffer_release(struct m66592 *m66592,
 static void pipe_initialize(struct m66592_ep *ep)
 {
        struct m66592 *m66592 = ep->m66592;
+       unsigned short mbw;
 
        m66592_mdfy(m66592, 0, M66592_CURPIPE, ep->fifosel);
 
@@ -351,7 +324,12 @@ static void pipe_initialize(struct m66592_ep *ep)
 
                ndelay(450);
 
-               m66592_bset(m66592, M66592_MBW, ep->fifosel);
+               if (m66592->pdata->on_chip)
+                       mbw = M66592_MBW_32;
+               else
+                       mbw = M66592_MBW_16;
+
+               m66592_bset(m66592, mbw, ep->fifosel);
        }
 }
 
@@ -367,15 +345,13 @@ static void m66592_ep_setting(struct m66592 *m66592, struct m66592_ep *ep,
                        ep->fifosel = M66592_D0FIFOSEL;
                        ep->fifoctr = M66592_D0FIFOCTR;
                        ep->fifotrn = M66592_D0FIFOTRN;
-#if !defined(CONFIG_SUPERH_BUILT_IN_M66592)
-               } else if (m66592->num_dma == 1) {
+               } else if (!m66592->pdata->on_chip && m66592->num_dma == 1) {
                        m66592->num_dma++;
                        ep->use_dma = 1;
                        ep->fifoaddr = M66592_D1FIFO;
                        ep->fifosel = M66592_D1FIFOSEL;
                        ep->fifoctr = M66592_D1FIFOCTR;
                        ep->fifotrn = M66592_D1FIFOTRN;
-#endif
                } else {
                        ep->use_dma = 0;
                        ep->fifoaddr = M66592_CFIFO;
@@ -620,76 +596,120 @@ static void start_ep0(struct m66592_ep *ep, struct m66592_request *req)
        }
 }
 
-#if defined(CONFIG_SUPERH_BUILT_IN_M66592)
 static void init_controller(struct m66592 *m66592)
 {
-       m66592_bset(m66592, M66592_HSE, M66592_SYSCFG);         /* High spd */
-       m66592_bclr(m66592, M66592_USBE, M66592_SYSCFG);
-       m66592_bclr(m66592, M66592_DPRPU, M66592_SYSCFG);
-       m66592_bset(m66592, M66592_USBE, M66592_SYSCFG);
+       unsigned int endian;
 
-       /* This is a workaound for SH7722 2nd cut */
-       m66592_bset(m66592, 0x8000, M66592_DVSTCTR);
-       m66592_bset(m66592, 0x1000, M66592_TESTMODE);
-       m66592_bclr(m66592, 0x8000, M66592_DVSTCTR);
+       if (m66592->pdata->on_chip) {
+               if (m66592->pdata->endian)
+                       endian = 0; /* big endian */
+               else
+                       endian = M66592_LITTLE; /* little endian */
 
-       m66592_bset(m66592, M66592_INTL, M66592_INTENB1);
+               m66592_bset(m66592, M66592_HSE, M66592_SYSCFG); /* High spd */
+               m66592_bclr(m66592, M66592_USBE, M66592_SYSCFG);
+               m66592_bclr(m66592, M66592_DPRPU, M66592_SYSCFG);
+               m66592_bset(m66592, M66592_USBE, M66592_SYSCFG);
 
-       m66592_write(m66592, 0, M66592_CFBCFG);
-       m66592_write(m66592, 0, M66592_D0FBCFG);
-       m66592_bset(m66592, endian, M66592_CFBCFG);
-       m66592_bset(m66592, endian, M66592_D0FBCFG);
-}
-#else  /* #if defined(CONFIG_SUPERH_BUILT_IN_M66592) */
-static void init_controller(struct m66592 *m66592)
-{
-       m66592_bset(m66592, (vif & M66592_LDRV) | (endian & M66592_BIGEND),
-                       M66592_PINCFG);
-       m66592_bset(m66592, M66592_HSE, M66592_SYSCFG);         /* High spd */
-       m66592_mdfy(m66592, clock & M66592_XTAL, M66592_XTAL, M66592_SYSCFG);
+               /* This is a workaound for SH7722 2nd cut */
+               m66592_bset(m66592, 0x8000, M66592_DVSTCTR);
+               m66592_bset(m66592, 0x1000, M66592_TESTMODE);
+               m66592_bclr(m66592, 0x8000, M66592_DVSTCTR);
 
-       m66592_bclr(m66592, M66592_USBE, M66592_SYSCFG);
-       m66592_bclr(m66592, M66592_DPRPU, M66592_SYSCFG);
-       m66592_bset(m66592, M66592_USBE, M66592_SYSCFG);
+               m66592_bset(m66592, M66592_INTL, M66592_INTENB1);
 
-       m66592_bset(m66592, M66592_XCKE, M66592_SYSCFG);
+               m66592_write(m66592, 0, M66592_CFBCFG);
+               m66592_write(m66592, 0, M66592_D0FBCFG);
+               m66592_bset(m66592, endian, M66592_CFBCFG);
+               m66592_bset(m66592, endian, M66592_D0FBCFG);
+       } else {
+               unsigned int clock, vif, irq_sense;
 
-       msleep(3);
+               if (m66592->pdata->endian)
+                       endian = M66592_BIGEND; /* big endian */
+               else
+                       endian = 0; /* little endian */
 
-       m66592_bset(m66592, M66592_RCKE | M66592_PLLC, M66592_SYSCFG);
+               if (m66592->pdata->vif)
+                       vif = M66592_LDRV; /* 3.3v */
+               else
+                       vif = 0; /* 1.5v */
 
-       msleep(1);
+               switch (m66592->pdata->xtal) {
+               case M66592_PLATDATA_XTAL_12MHZ:
+                       clock = M66592_XTAL12;
+                       break;
+               case M66592_PLATDATA_XTAL_24MHZ:
+                       clock = M66592_XTAL24;
+                       break;
+               case M66592_PLATDATA_XTAL_48MHZ:
+                       clock = M66592_XTAL48;
+                       break;
+               default:
+                       pr_warning("m66592-udc: xtal configuration error\n");
+                       clock = 0;
+               }
 
-       m66592_bset(m66592, M66592_SCKE, M66592_SYSCFG);
+               switch (m66592->irq_trigger) {
+               case IRQF_TRIGGER_LOW:
+                       irq_sense = M66592_INTL;
+                       break;
+               case IRQF_TRIGGER_FALLING:
+                       irq_sense = 0;
+                       break;
+               default:
+                       pr_warning("m66592-udc: irq trigger config error\n");
+                       irq_sense = 0;
+               }
+
+               m66592_bset(m66592,
+                           (vif & M66592_LDRV) | (endian & M66592_BIGEND),
+                           M66592_PINCFG);
+               m66592_bset(m66592, M66592_HSE, M66592_SYSCFG); /* High spd */
+               m66592_mdfy(m66592, clock & M66592_XTAL, M66592_XTAL,
+                           M66592_SYSCFG);
+               m66592_bclr(m66592, M66592_USBE, M66592_SYSCFG);
+               m66592_bclr(m66592, M66592_DPRPU, M66592_SYSCFG);
+               m66592_bset(m66592, M66592_USBE, M66592_SYSCFG);
+
+               m66592_bset(m66592, M66592_XCKE, M66592_SYSCFG);
+
+               msleep(3);
 
-       m66592_bset(m66592, irq_sense & M66592_INTL, M66592_INTENB1);
-       m66592_write(m66592, M66592_BURST | M66592_CPU_ADR_RD_WR,
-                       M66592_DMA0CFG);
+               m66592_bset(m66592, M66592_RCKE | M66592_PLLC, M66592_SYSCFG);
+
+               msleep(1);
+
+               m66592_bset(m66592, M66592_SCKE, M66592_SYSCFG);
+
+               m66592_bset(m66592, irq_sense & M66592_INTL, M66592_INTENB1);
+               m66592_write(m66592, M66592_BURST | M66592_CPU_ADR_RD_WR,
+                            M66592_DMA0CFG);
+       }
 }
-#endif /* #if defined(CONFIG_SUPERH_BUILT_IN_M66592) */
 
 static void disable_controller(struct m66592 *m66592)
 {
-#if !defined(CONFIG_SUPERH_BUILT_IN_M66592)
-       m66592_bclr(m66592, M66592_SCKE, M66592_SYSCFG);
-       udelay(1);
-       m66592_bclr(m66592, M66592_PLLC, M66592_SYSCFG);
-       udelay(1);
-       m66592_bclr(m66592, M66592_RCKE, M66592_SYSCFG);
-       udelay(1);
-       m66592_bclr(m66592, M66592_XCKE, M66592_SYSCFG);
-#endif
+       if (!m66592->pdata->on_chip) {
+               m66592_bclr(m66592, M66592_SCKE, M66592_SYSCFG);
+               udelay(1);
+               m66592_bclr(m66592, M66592_PLLC, M66592_SYSCFG);
+               udelay(1);
+               m66592_bclr(m66592, M66592_RCKE, M66592_SYSCFG);
+               udelay(1);
+               m66592_bclr(m66592, M66592_XCKE, M66592_SYSCFG);
+       }
 }
 
 static void m66592_start_xclock(struct m66592 *m66592)
 {
-#if !defined(CONFIG_SUPERH_BUILT_IN_M66592)
        u16 tmp;
 
-       tmp = m66592_read(m66592, M66592_SYSCFG);
-       if (!(tmp & M66592_XCKE))
-               m66592_bset(m66592, M66592_XCKE, M66592_SYSCFG);
-#endif
+       if (!m66592->pdata->on_chip) {
+               tmp = m66592_read(m66592, M66592_SYSCFG);
+               if (!(tmp & M66592_XCKE))
+                       m66592_bset(m66592, M66592_XCKE, M66592_SYSCFG);
+       }
 }
 
 /*-------------------------------------------------------------------------*/
@@ -1177,8 +1197,7 @@ static irqreturn_t m66592_irq(int irq, void *_m66592)
        intsts0 = m66592_read(m66592, M66592_INTSTS0);
        intenb0 = m66592_read(m66592, M66592_INTENB0);
 
-#if defined(CONFIG_SUPERH_BUILT_IN_M66592)
-       if (!intsts0 && !intenb0) {
+       if (m66592->pdata->on_chip && !intsts0 && !intenb0) {
                /*
                 * When USB clock stops, it cannot read register. Even if a
                 * clock stops, the interrupt occurs. So this driver turn on
@@ -1188,7 +1207,6 @@ static irqreturn_t m66592_irq(int irq, void *_m66592)
                intsts0 = m66592_read(m66592, M66592_INTSTS0);
                intenb0 = m66592_read(m66592, M66592_INTENB0);
        }
-#endif
 
        savepipe = m66592_read(m66592, M66592_CFIFOSEL);
 
@@ -1534,9 +1552,11 @@ static int __exit m66592_remove(struct platform_device *pdev)
        iounmap(m66592->reg);
        free_irq(platform_get_irq(pdev, 0), m66592);
        m66592_free_request(&m66592->ep[0].ep, m66592->ep0_req);
-#if defined(CONFIG_SUPERH_BUILT_IN_M66592) && defined(CONFIG_HAVE_CLK)
-       clk_disable(m66592->clk);
-       clk_put(m66592->clk);
+#ifdef CONFIG_HAVE_CLK
+       if (m66592->pdata->on_chip) {
+               clk_disable(m66592->clk);
+               clk_put(m66592->clk);
+       }
 #endif
        kfree(m66592);
        return 0;
@@ -1548,11 +1568,10 @@ static void nop_completion(struct usb_ep *ep, struct usb_request *r)
 
 static int __init m66592_probe(struct platform_device *pdev)
 {
-       struct resource *res;
-       int irq;
+       struct resource *res, *ires;
        void __iomem *reg = NULL;
        struct m66592 *m66592 = NULL;
-#if defined(CONFIG_SUPERH_BUILT_IN_M66592) && defined(CONFIG_HAVE_CLK)
+#ifdef CONFIG_HAVE_CLK
        char clk_name[8];
 #endif
        int ret = 0;
@@ -1565,10 +1584,11 @@ static int __init m66592_probe(struct platform_device *pdev)
                goto clean_up;
        }
 
-       irq = platform_get_irq(pdev, 0);
-       if (irq < 0) {
+       ires = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+       if (!ires) {
                ret = -ENODEV;
-               pr_err("platform_get_irq error.\n");
+               dev_err(&pdev->dev,
+                       "platform_get_resource IORESOURCE_IRQ error.\n");
                goto clean_up;
        }
 
@@ -1579,6 +1599,12 @@ static int __init m66592_probe(struct platform_device *pdev)
                goto clean_up;
        }
 
+       if (pdev->dev.platform_data == NULL) {
+               dev_err(&pdev->dev, "no platform data\n");
+               ret = -ENODEV;
+               goto clean_up;
+       }
+
        /* initialize ucd */
        m66592 = kzalloc(sizeof(struct m66592), GFP_KERNEL);
        if (m66592 == NULL) {
@@ -1586,6 +1612,9 @@ static int __init m66592_probe(struct platform_device *pdev)
                goto clean_up;
        }
 
+       m66592->pdata = pdev->dev.platform_data;
+       m66592->irq_trigger = ires->flags & IRQF_TRIGGER_MASK;
+
        spin_lock_init(&m66592->lock);
        dev_set_drvdata(&pdev->dev, m66592);
 
@@ -1603,24 +1632,25 @@ static int __init m66592_probe(struct platform_device *pdev)
        m66592->timer.data = (unsigned long)m66592;
        m66592->reg = reg;
 
-       m66592->bi_bufnum = M66592_BASE_BUFNUM;
-
-       ret = request_irq(irq, m66592_irq, IRQF_DISABLED | IRQF_SHARED,
+       ret = request_irq(ires->start, m66592_irq, IRQF_DISABLED | IRQF_SHARED,
                        udc_name, m66592);
        if (ret < 0) {
                pr_err("request_irq error (%d)\n", ret);
                goto clean_up;
        }
 
-#if defined(CONFIG_SUPERH_BUILT_IN_M66592) && defined(CONFIG_HAVE_CLK)
-       snprintf(clk_name, sizeof(clk_name), "usbf%d", pdev->id);
-       m66592->clk = clk_get(&pdev->dev, clk_name);
-       if (IS_ERR(m66592->clk)) {
-               dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name);
-               ret = PTR_ERR(m66592->clk);
-               goto clean_up2;
+#ifdef CONFIG_HAVE_CLK
+       if (m66592->pdata->on_chip) {
+               snprintf(clk_name, sizeof(clk_name), "usbf%d", pdev->id);
+               m66592->clk = clk_get(&pdev->dev, clk_name);
+               if (IS_ERR(m66592->clk)) {
+                       dev_err(&pdev->dev, "cannot get clock \"%s\"\n",
+                               clk_name);
+                       ret = PTR_ERR(m66592->clk);
+                       goto clean_up2;
+               }
+               clk_enable(m66592->clk);
        }
-       clk_enable(m66592->clk);
 #endif
        INIT_LIST_HEAD(&m66592->gadget.ep_list);
        m66592->gadget.ep0 = &m66592->ep[0].ep;
@@ -1662,12 +1692,14 @@ static int __init m66592_probe(struct platform_device *pdev)
        return 0;
 
 clean_up3:
-#if defined(CONFIG_SUPERH_BUILT_IN_M66592) && defined(CONFIG_HAVE_CLK)
-       clk_disable(m66592->clk);
-       clk_put(m66592->clk);
+#ifdef CONFIG_HAVE_CLK
+       if (m66592->pdata->on_chip) {
+               clk_disable(m66592->clk);
+               clk_put(m66592->clk);
+       }
 clean_up2:
 #endif
-       free_irq(irq, m66592);
+       free_irq(ires->start, m66592);
 clean_up:
        if (m66592) {
                if (m66592->ep0_req)
index 286ce07e7960423ac2a18f4b2075c440fab1b010..8b960deed68069baf74cbfce86415450373ca001 100644 (file)
 #ifndef __M66592_UDC_H__
 #define __M66592_UDC_H__
 
-#if defined(CONFIG_SUPERH_BUILT_IN_M66592) && defined(CONFIG_HAVE_CLK)
+#ifdef CONFIG_HAVE_CLK
 #include <linux/clk.h>
 #endif
 
+#include <linux/usb/m66592.h>
+
 #define M66592_SYSCFG          0x00
 #define M66592_XTAL            0xC000  /* b15-14: Crystal selection */
 #define   M66592_XTAL48                 0x8000         /* 48MHz */
 #define   M66592_P_TST_J        0x0001         /* PERI TEST J */
 #define   M66592_P_TST_NORMAL   0x0000         /* PERI Normal Mode */
 
-#if defined(CONFIG_SUPERH_BUILT_IN_M66592)
+/* built-in registers */
 #define M66592_CFBCFG          0x0A
 #define M66592_D0FBCFG         0x0C
 #define M66592_LITTLE          0x0100  /* b8: Little endian mode */
-#else
+/* external chip case */
 #define M66592_PINCFG          0x0A
 #define M66592_LDRV            0x8000  /* b15: Drive Current Adjust */
 #define M66592_BIGEND          0x0100  /* b8: Big endian mode */
 #define M66592_PKTM            0x0020  /* b5: Packet mode */
 #define M66592_DENDE           0x0010  /* b4: Dend enable */
 #define M66592_OBUS            0x0004  /* b2: OUTbus mode */
-#endif /* #if defined(CONFIG_SUPERH_BUILT_IN_M66592) */
 
+/* common case */
 #define M66592_CFIFO           0x10
 #define M66592_D0FIFO          0x14
 #define M66592_D1FIFO          0x18
 #define M66592_REW             0x4000  /* b14: Buffer rewind */
 #define M66592_DCLRM           0x2000  /* b13: DMA buffer clear mode */
 #define M66592_DREQE           0x1000  /* b12: DREQ output enable */
-#if defined(CONFIG_SUPERH_BUILT_IN_M66592)
-#define M66592_MBW             0x0800  /* b11: Maximum bit width for FIFO */
-#else
-#define M66592_MBW             0x0400  /* b10: Maximum bit width for FIFO */
-#define   M66592_MBW_8          0x0000   /*  8bit */
-#define   M66592_MBW_16                 0x0400   /* 16bit */
-#endif /* #if defined(CONFIG_SUPERH_BUILT_IN_M66592) */
+#define M66592_MBW_8           0x0000   /*  8bit */
+#define M66592_MBW_16          0x0400   /* 16bit */
+#define M66592_MBW_32          0x0800   /* 32bit */
 #define M66592_TRENB           0x0200  /* b9: Transaction counter enable */
 #define M66592_TRCLR           0x0100  /* b8: Transaction counter clear */
 #define M66592_DEZPM           0x0080  /* b7: Zero-length packet mode */
@@ -480,9 +478,11 @@ struct m66592_ep {
 struct m66592 {
        spinlock_t              lock;
        void __iomem            *reg;
-#if defined(CONFIG_SUPERH_BUILT_IN_M66592) && defined(CONFIG_HAVE_CLK)
+#ifdef CONFIG_HAVE_CLK
        struct clk *clk;
 #endif
+       struct m66592_platdata  *pdata;
+       unsigned long           irq_trigger;
 
        struct usb_gadget               gadget;
        struct usb_gadget_driver        *driver;
@@ -506,7 +506,6 @@ struct m66592 {
        int interrupt;
        int isochronous;
        int num_dma;
-       int bi_bufnum;  /* bulk and isochronous's bufnum */
 };
 
 #define gadget_to_m66592(_gadget) container_of(_gadget, struct m66592, gadget)
@@ -547,13 +546,13 @@ static inline void m66592_read_fifo(struct m66592 *m66592,
 {
        unsigned long fifoaddr = (unsigned long)m66592->reg + offset;
 
-#if defined(CONFIG_SUPERH_BUILT_IN_M66592)
-       len = (len + 3) / 4;
-       insl(fifoaddr, buf, len);
-#else
-       len = (len + 1) / 2;
-       insw(fifoaddr, buf, len);
-#endif
+       if (m66592->pdata->on_chip) {
+               len = (len + 3) / 4;
+               insl(fifoaddr, buf, len);
+       } else {
+               len = (len + 1) / 2;
+               insw(fifoaddr, buf, len);
+       }
 }
 
 static inline void m66592_write(struct m66592 *m66592, u16 val,
@@ -567,33 +566,34 @@ static inline void m66592_write_fifo(struct m66592 *m66592,
                void *buf, unsigned long len)
 {
        unsigned long fifoaddr = (unsigned long)m66592->reg + offset;
-#if defined(CONFIG_SUPERH_BUILT_IN_M66592)
-       unsigned long count;
-       unsigned char *pb;
-       int i;
-
-       count = len / 4;
-       outsl(fifoaddr, buf, count);
-
-       if (len & 0x00000003) {
-               pb = buf + count * 4;
-               for (i = 0; i < (len & 0x00000003); i++) {
-                       if (m66592_read(m66592, M66592_CFBCFG)) /* little */
-                               outb(pb[i], fifoaddr + (3 - i));
-                       else
-                               outb(pb[i], fifoaddr + i);
+
+       if (m66592->pdata->on_chip) {
+               unsigned long count;
+               unsigned char *pb;
+               int i;
+
+               count = len / 4;
+               outsl(fifoaddr, buf, count);
+
+               if (len & 0x00000003) {
+                       pb = buf + count * 4;
+                       for (i = 0; i < (len & 0x00000003); i++) {
+                               if (m66592_read(m66592, M66592_CFBCFG)) /* le */
+                                       outb(pb[i], fifoaddr + (3 - i));
+                               else
+                                       outb(pb[i], fifoaddr + i);
+                       }
+               }
+       } else {
+               unsigned long odd = len & 0x0001;
+
+               len = len / 2;
+               outsw(fifoaddr, buf, len);
+               if (odd) {
+                       unsigned char *p = buf + len*2;
+                       outb(*p, fifoaddr);
                }
        }
-#else
-       unsigned long odd = len & 0x0001;
-
-       len = len / 2;
-       outsw(fifoaddr, buf, len);
-       if (odd) {
-               unsigned char *p = buf + len*2;
-               outb(*p, fifoaddr);
-       }
-#endif /* #if defined(CONFIG_SUPERH_BUILT_IN_M66592) */
 }
 
 static inline void m66592_mdfy(struct m66592 *m66592, u16 val, u16 pat,
index 1a920c70b5a150f0a2670f8d170d579c582544ac..f21ca7d27a4305d7e27a093a7561cde91cfa9d3f 100644 (file)
@@ -336,13 +336,6 @@ config USB_R8A66597_HCD
          To compile this driver as a module, choose M here: the
          module will be called r8a66597-hcd.
 
-config SUPERH_ON_CHIP_R8A66597
-       boolean "Enable SuperH on-chip R8A66597 USB"
-       depends on USB_R8A66597_HCD && (CPU_SUBTYPE_SH7366 || CPU_SUBTYPE_SH7723 || CPU_SUBTYPE_SH7724)
-       help
-          This driver enables support for the on-chip R8A66597 in the
-          SH7366, SH7723 and SH7724 processors.
-
 config USB_WHCI_HCD
        tristate "Wireless USB Host Controller Interface (WHCI) driver (EXPERIMENTAL)"
        depends on EXPERIMENTAL
index e18f74946e6824a427bd5b3b0185ee79ffebcd35..749b53742828ad4a4a06767b797c9cc4a9bf4045 100644 (file)
@@ -91,43 +91,43 @@ static int r8a66597_clock_enable(struct r8a66597 *r8a66597)
        u16 tmp;
        int i = 0;
 
-#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597)
-#if defined(CONFIG_HAVE_CLK)
-       clk_enable(r8a66597->clk);
+       if (r8a66597->pdata->on_chip) {
+#ifdef CONFIG_HAVE_CLK
+               clk_enable(r8a66597->clk);
 #endif
-       do {
-               r8a66597_write(r8a66597, SCKE, SYSCFG0);
-               tmp = r8a66597_read(r8a66597, SYSCFG0);
-               if (i++ > 1000) {
-                       printk(KERN_ERR "r8a66597: register access fail.\n");
-                       return -ENXIO;
-               }
-       } while ((tmp & SCKE) != SCKE);
-       r8a66597_write(r8a66597, 0x04, 0x02);
-#else
-       do {
-               r8a66597_write(r8a66597, USBE, SYSCFG0);
-               tmp = r8a66597_read(r8a66597, SYSCFG0);
-               if (i++ > 1000) {
-                       printk(KERN_ERR "r8a66597: register access fail.\n");
-                       return -ENXIO;
-               }
-       } while ((tmp & USBE) != USBE);
-       r8a66597_bclr(r8a66597, USBE, SYSCFG0);
-       r8a66597_mdfy(r8a66597, get_xtal_from_pdata(r8a66597->pdata), XTAL,
-                       SYSCFG0);
+               do {
+                       r8a66597_write(r8a66597, SCKE, SYSCFG0);
+                       tmp = r8a66597_read(r8a66597, SYSCFG0);
+                       if (i++ > 1000) {
+                               printk(KERN_ERR "r8a66597: reg access fail.\n");
+                               return -ENXIO;
+                       }
+               } while ((tmp & SCKE) != SCKE);
+               r8a66597_write(r8a66597, 0x04, 0x02);
+       } else {
+               do {
+                       r8a66597_write(r8a66597, USBE, SYSCFG0);
+                       tmp = r8a66597_read(r8a66597, SYSCFG0);
+                       if (i++ > 1000) {
+                               printk(KERN_ERR "r8a66597: reg access fail.\n");
+                               return -ENXIO;
+                       }
+               } while ((tmp & USBE) != USBE);
+               r8a66597_bclr(r8a66597, USBE, SYSCFG0);
+               r8a66597_mdfy(r8a66597, get_xtal_from_pdata(r8a66597->pdata),
+                             XTAL, SYSCFG0);
 
-       i = 0;
-       r8a66597_bset(r8a66597, XCKE, SYSCFG0);
-       do {
-               msleep(1);
-               tmp = r8a66597_read(r8a66597, SYSCFG0);
-               if (i++ > 500) {
-                       printk(KERN_ERR "r8a66597: register access fail.\n");
-                       return -ENXIO;
-               }
-       } while ((tmp & SCKE) != SCKE);
-#endif /* #if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) */
+               i = 0;
+               r8a66597_bset(r8a66597, XCKE, SYSCFG0);
+               do {
+                       msleep(1);
+                       tmp = r8a66597_read(r8a66597, SYSCFG0);
+                       if (i++ > 500) {
+                               printk(KERN_ERR "r8a66597: reg access fail.\n");
+                               return -ENXIO;
+                       }
+               } while ((tmp & SCKE) != SCKE);
+       }
 
        return 0;
 }
@@ -136,15 +136,16 @@ static void r8a66597_clock_disable(struct r8a66597 *r8a66597)
 {
        r8a66597_bclr(r8a66597, SCKE, SYSCFG0);
        udelay(1);
-#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597)
-#if defined(CONFIG_HAVE_CLK)
-       clk_disable(r8a66597->clk);
-#endif
-#else
-       r8a66597_bclr(r8a66597, PLLC, SYSCFG0);
-       r8a66597_bclr(r8a66597, XCKE, SYSCFG0);
-       r8a66597_bclr(r8a66597, USBE, SYSCFG0);
+
+       if (r8a66597->pdata->on_chip) {
+#ifdef CONFIG_HAVE_CLK
+               clk_disable(r8a66597->clk);
 #endif
+       } else {
+               r8a66597_bclr(r8a66597, PLLC, SYSCFG0);
+               r8a66597_bclr(r8a66597, XCKE, SYSCFG0);
+               r8a66597_bclr(r8a66597, USBE, SYSCFG0);
+       }
 }
 
 static void r8a66597_enable_port(struct r8a66597 *r8a66597, int port)
@@ -205,7 +206,7 @@ static int enable_controller(struct r8a66597 *r8a66597)
 
        r8a66597_bset(r8a66597, SIGNE | SACKE, INTENB1);
 
-       for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++)
+       for (port = 0; port < r8a66597->max_root_hub; port++)
                r8a66597_enable_port(r8a66597, port);
 
        return 0;
@@ -218,7 +219,7 @@ static void disable_controller(struct r8a66597 *r8a66597)
        r8a66597_write(r8a66597, 0, INTENB0);
        r8a66597_write(r8a66597, 0, INTSTS0);
 
-       for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++)
+       for (port = 0; port < r8a66597->max_root_hub; port++)
                r8a66597_disable_port(r8a66597, port);
 
        r8a66597_clock_disable(r8a66597);
@@ -249,11 +250,12 @@ static int is_hub_limit(char *devpath)
        return ((strlen(devpath) >= 4) ? 1 : 0);
 }
 
-static void get_port_number(char *devpath, u16 *root_port, u16 *hub_port)
+static void get_port_number(struct r8a66597 *r8a66597,
+                           char *devpath, u16 *root_port, u16 *hub_port)
 {
        if (root_port) {
                *root_port = (devpath[0] & 0x0F) - 1;
-               if (*root_port >= R8A66597_MAX_ROOT_HUB)
+               if (*root_port >= r8a66597->max_root_hub)
                        printk(KERN_ERR "r8a66597: Illegal root port number.\n");
        }
        if (hub_port)
@@ -355,7 +357,8 @@ static int make_r8a66597_device(struct r8a66597 *r8a66597,
        INIT_LIST_HEAD(&dev->device_list);
        list_add_tail(&dev->device_list, &r8a66597->child_device);
 
-       get_port_number(urb->dev->devpath, &dev->root_port, &dev->hub_port);
+       get_port_number(r8a66597, urb->dev->devpath,
+                       &dev->root_port, &dev->hub_port);
        if (!is_child_device(urb->dev->devpath))
                r8a66597->root_hub[dev->root_port].dev = dev;
 
@@ -420,7 +423,7 @@ static void free_usb_address(struct r8a66597 *r8a66597,
        list_del(&dev->device_list);
        kfree(dev);
 
-       for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++) {
+       for (port = 0; port < r8a66597->max_root_hub; port++) {
                if (r8a66597->root_hub[port].dev == dev) {
                        r8a66597->root_hub[port].dev = NULL;
                        break;
@@ -495,10 +498,20 @@ static void r8a66597_pipe_toggle(struct r8a66597 *r8a66597,
                r8a66597_bset(r8a66597, SQCLR, pipe->pipectr);
 }
 
+static inline unsigned short mbw_value(struct r8a66597 *r8a66597)
+{
+       if (r8a66597->pdata->on_chip)
+               return MBW_32;
+       else
+               return MBW_16;
+}
+
 /* this function must be called with interrupt disabled */
 static inline void cfifo_change(struct r8a66597 *r8a66597, u16 pipenum)
 {
-       r8a66597_mdfy(r8a66597, MBW | pipenum, MBW | CURPIPE, CFIFOSEL);
+       unsigned short mbw = mbw_value(r8a66597);
+
+       r8a66597_mdfy(r8a66597, mbw | pipenum, mbw | CURPIPE, CFIFOSEL);
        r8a66597_reg_wait(r8a66597, CFIFOSEL, CURPIPE, pipenum);
 }
 
@@ -506,11 +519,13 @@ static inline void cfifo_change(struct r8a66597 *r8a66597, u16 pipenum)
 static inline void fifo_change_from_pipe(struct r8a66597 *r8a66597,
                                         struct r8a66597_pipe *pipe)
 {
+       unsigned short mbw = mbw_value(r8a66597);
+
        cfifo_change(r8a66597, 0);
-       r8a66597_mdfy(r8a66597, MBW | 0, MBW | CURPIPE, D0FIFOSEL);
-       r8a66597_mdfy(r8a66597, MBW | 0, MBW | CURPIPE, D1FIFOSEL);
+       r8a66597_mdfy(r8a66597, mbw | 0, mbw | CURPIPE, D0FIFOSEL);
+       r8a66597_mdfy(r8a66597, mbw | 0, mbw | CURPIPE, D1FIFOSEL);
 
-       r8a66597_mdfy(r8a66597, MBW | pipe->info.pipenum, MBW | CURPIPE,
+       r8a66597_mdfy(r8a66597, mbw | pipe->info.pipenum, mbw | CURPIPE,
                      pipe->fifosel);
        r8a66597_reg_wait(r8a66597, pipe->fifosel, CURPIPE, pipe->info.pipenum);
 }
@@ -742,9 +757,13 @@ static void enable_r8a66597_pipe_dma(struct r8a66597 *r8a66597,
                                     struct r8a66597_pipe *pipe,
                                     struct urb *urb)
 {
-#if !defined(CONFIG_SUPERH_ON_CHIP_R8A66597)
        int i;
        struct r8a66597_pipe_info *info = &pipe->info;
+       unsigned short mbw = mbw_value(r8a66597);
+
+       /* pipe dma is only for external controlles */
+       if (r8a66597->pdata->on_chip)
+               return;
 
        if ((pipe->info.pipenum != 0) && (info->type != R8A66597_INT)) {
                for (i = 0; i < R8A66597_MAX_DMA_CHANNEL; i++) {
@@ -763,8 +782,8 @@ static void enable_r8a66597_pipe_dma(struct r8a66597 *r8a66597,
                        set_pipe_reg_addr(pipe, i);
 
                        cfifo_change(r8a66597, 0);
-                       r8a66597_mdfy(r8a66597, MBW | pipe->info.pipenum,
-                                     MBW | CURPIPE, pipe->fifosel);
+                       r8a66597_mdfy(r8a66597, mbw | pipe->info.pipenum,
+                                     mbw | CURPIPE, pipe->fifosel);
 
                        r8a66597_reg_wait(r8a66597, pipe->fifosel, CURPIPE,
                                          pipe->info.pipenum);
@@ -772,7 +791,6 @@ static void enable_r8a66597_pipe_dma(struct r8a66597 *r8a66597,
                        break;
                }
        }
-#endif /* #if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) */
 }
 
 /* this function must be called with interrupt disabled */
@@ -1769,7 +1787,7 @@ static void r8a66597_timer(unsigned long _r8a66597)
 
        spin_lock_irqsave(&r8a66597->lock, flags);
 
-       for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++)
+       for (port = 0; port < r8a66597->max_root_hub; port++)
                r8a66597_root_hub_control(r8a66597, port);
 
        spin_unlock_irqrestore(&r8a66597->lock, flags);
@@ -1807,7 +1825,7 @@ static void set_address_zero(struct r8a66597 *r8a66597, struct urb *urb)
        u16 root_port, hub_port;
 
        if (usb_address == 0) {
-               get_port_number(urb->dev->devpath,
+               get_port_number(r8a66597, urb->dev->devpath,
                                &root_port, &hub_port);
                set_devadd_reg(r8a66597, 0,
                               get_r8a66597_usb_speed(urb->dev->speed),
@@ -2082,7 +2100,7 @@ static int r8a66597_hub_status_data(struct usb_hcd *hcd, char *buf)
 
        *buf = 0;       /* initialize (no change) */
 
-       for (i = 0; i < R8A66597_MAX_ROOT_HUB; i++) {
+       for (i = 0; i < r8a66597->max_root_hub; i++) {
                if (r8a66597->root_hub[i].port & 0xffff0000)
                        *buf |= 1 << (i + 1);
        }
@@ -2097,11 +2115,11 @@ static void r8a66597_hub_descriptor(struct r8a66597 *r8a66597,
 {
        desc->bDescriptorType = 0x29;
        desc->bHubContrCurrent = 0;
-       desc->bNbrPorts = R8A66597_MAX_ROOT_HUB;
+       desc->bNbrPorts = r8a66597->max_root_hub;
        desc->bDescLength = 9;
        desc->bPwrOn2PwrGood = 0;
        desc->wHubCharacteristics = cpu_to_le16(0x0011);
-       desc->bitmap[0] = ((1 << R8A66597_MAX_ROOT_HUB) - 1) << 1;
+       desc->bitmap[0] = ((1 << r8a66597->max_root_hub) - 1) << 1;
        desc->bitmap[1] = ~0;
 }
 
@@ -2129,7 +2147,7 @@ static int r8a66597_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
                }
                break;
        case ClearPortFeature:
-               if (wIndex > R8A66597_MAX_ROOT_HUB)
+               if (wIndex > r8a66597->max_root_hub)
                        goto error;
                if (wLength != 0)
                        goto error;
@@ -2162,12 +2180,12 @@ static int r8a66597_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
                *buf = 0x00;
                break;
        case GetPortStatus:
-               if (wIndex > R8A66597_MAX_ROOT_HUB)
+               if (wIndex > r8a66597->max_root_hub)
                        goto error;
                *(__le32 *)buf = cpu_to_le32(rh->port);
                break;
        case SetPortFeature:
-               if (wIndex > R8A66597_MAX_ROOT_HUB)
+               if (wIndex > r8a66597->max_root_hub)
                        goto error;
                if (wLength != 0)
                        goto error;
@@ -2216,7 +2234,7 @@ static int r8a66597_bus_suspend(struct usb_hcd *hcd)
 
        dbg("%s", __func__);
 
-       for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++) {
+       for (port = 0; port < r8a66597->max_root_hub; port++) {
                struct r8a66597_root_hub *rh = &r8a66597->root_hub[port];
                unsigned long dvstctr_reg = get_dvstctr_reg(port);
 
@@ -2247,7 +2265,7 @@ static int r8a66597_bus_resume(struct usb_hcd *hcd)
 
        dbg("%s", __func__);
 
-       for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++) {
+       for (port = 0; port < r8a66597->max_root_hub; port++) {
                struct r8a66597_root_hub *rh = &r8a66597->root_hub[port];
                unsigned long dvstctr_reg = get_dvstctr_reg(port);
 
@@ -2305,16 +2323,16 @@ static struct hc_driver r8a66597_hc_driver = {
 };
 
 #if defined(CONFIG_PM)
-static int r8a66597_suspend(struct platform_device *pdev, pm_message_t state)
+static int r8a66597_suspend(struct device *dev)
 {
-       struct r8a66597         *r8a66597 = dev_get_drvdata(&pdev->dev);
+       struct r8a66597         *r8a66597 = dev_get_drvdata(dev);
        int port;
 
        dbg("%s", __func__);
 
        disable_controller(r8a66597);
 
-       for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++) {
+       for (port = 0; port < r8a66597->max_root_hub; port++) {
                struct r8a66597_root_hub *rh = &r8a66597->root_hub[port];
 
                rh->port = 0x00000000;
@@ -2323,9 +2341,9 @@ static int r8a66597_suspend(struct platform_device *pdev, pm_message_t state)
        return 0;
 }
 
-static int r8a66597_resume(struct platform_device *pdev)
+static int r8a66597_resume(struct device *dev)
 {
-       struct r8a66597         *r8a66597 = dev_get_drvdata(&pdev->dev);
+       struct r8a66597         *r8a66597 = dev_get_drvdata(dev);
        struct usb_hcd          *hcd = r8a66597_to_hcd(r8a66597);
 
        dbg("%s", __func__);
@@ -2335,9 +2353,17 @@ static int r8a66597_resume(struct platform_device *pdev)
 
        return 0;
 }
+
+static struct dev_pm_ops r8a66597_dev_pm_ops = {
+       .suspend = r8a66597_suspend,
+       .resume = r8a66597_resume,
+       .poweroff = r8a66597_suspend,
+       .restore = r8a66597_resume,
+};
+
+#define R8A66597_DEV_PM_OPS    (&r8a66597_dev_pm_ops)
 #else  /* if defined(CONFIG_PM) */
-#define r8a66597_suspend       NULL
-#define r8a66597_resume                NULL
+#define R8A66597_DEV_PM_OPS    NULL
 #endif
 
 static int __init_or_module r8a66597_remove(struct platform_device *pdev)
@@ -2348,8 +2374,9 @@ static int __init_or_module r8a66597_remove(struct platform_device *pdev)
        del_timer_sync(&r8a66597->rh_timer);
        usb_remove_hcd(hcd);
        iounmap((void *)r8a66597->reg);
-#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) && defined(CONFIG_HAVE_CLK)
-       clk_put(r8a66597->clk);
+#ifdef CONFIG_HAVE_CLK
+       if (r8a66597->pdata->on_chip)
+               clk_put(r8a66597->clk);
 #endif
        usb_put_hcd(hcd);
        return 0;
@@ -2357,7 +2384,7 @@ static int __init_or_module r8a66597_remove(struct platform_device *pdev)
 
 static int __devinit r8a66597_probe(struct platform_device *pdev)
 {
-#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) && defined(CONFIG_HAVE_CLK)
+#ifdef CONFIG_HAVE_CLK
        char clk_name[8];
 #endif
        struct resource *res = NULL, *ires;
@@ -2419,15 +2446,20 @@ static int __devinit r8a66597_probe(struct platform_device *pdev)
        r8a66597->pdata = pdev->dev.platform_data;
        r8a66597->irq_sense_low = irq_trigger == IRQF_TRIGGER_LOW;
 
-#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) && defined(CONFIG_HAVE_CLK)
-       snprintf(clk_name, sizeof(clk_name), "usb%d", pdev->id);
-       r8a66597->clk = clk_get(&pdev->dev, clk_name);
-       if (IS_ERR(r8a66597->clk)) {
-               dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name);
-               ret = PTR_ERR(r8a66597->clk);
-               goto clean_up2;
-       }
+       if (r8a66597->pdata->on_chip) {
+#ifdef CONFIG_HAVE_CLK
+               snprintf(clk_name, sizeof(clk_name), "usb%d", pdev->id);
+               r8a66597->clk = clk_get(&pdev->dev, clk_name);
+               if (IS_ERR(r8a66597->clk)) {
+                       dev_err(&pdev->dev, "cannot get clock \"%s\"\n",
+                               clk_name);
+                       ret = PTR_ERR(r8a66597->clk);
+                       goto clean_up2;
+               }
 #endif
+               r8a66597->max_root_hub = 1;
+       } else
+               r8a66597->max_root_hub = 2;
 
        spin_lock_init(&r8a66597->lock);
        init_timer(&r8a66597->rh_timer);
@@ -2457,8 +2489,9 @@ static int __devinit r8a66597_probe(struct platform_device *pdev)
        return 0;
 
 clean_up3:
-#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) && defined(CONFIG_HAVE_CLK)
-       clk_put(r8a66597->clk);
+#ifdef CONFIG_HAVE_CLK
+       if (r8a66597->pdata->on_chip)
+               clk_put(r8a66597->clk);
 clean_up2:
 #endif
        usb_put_hcd(hcd);
@@ -2473,11 +2506,10 @@ clean_up:
 static struct platform_driver r8a66597_driver = {
        .probe =        r8a66597_probe,
        .remove =       r8a66597_remove,
-       .suspend =      r8a66597_suspend,
-       .resume =       r8a66597_resume,
        .driver         = {
                .name = (char *) hcd_name,
                .owner  = THIS_MODULE,
+               .pm     = R8A66597_DEV_PM_OPS,
        },
 };
 
index d72680b433f93c2309d7c17acbee40cab8281c45..228e3fb23854e7b3fe0f403c360f1fdb0bdf7414 100644 (file)
 #ifndef __R8A66597_H__
 #define __R8A66597_H__
 
-#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) && defined(CONFIG_HAVE_CLK)
+#ifdef CONFIG_HAVE_CLK
 #include <linux/clk.h>
 #endif
 
 #include <linux/usb/r8a66597.h>
 
-#define SYSCFG0                0x00
-#define SYSCFG1                0x02
-#define SYSSTS0                0x04
-#define SYSSTS1                0x06
-#define DVSTCTR0       0x08
-#define DVSTCTR1       0x0A
-#define TESTMODE       0x0C
-#define PINCFG         0x0E
-#define DMA0CFG                0x10
-#define DMA1CFG                0x12
-#define CFIFO          0x14
-#define D0FIFO         0x18
-#define D1FIFO         0x1C
-#define CFIFOSEL       0x20
-#define CFIFOCTR       0x22
-#define CFIFOSIE       0x24
-#define D0FIFOSEL      0x28
-#define D0FIFOCTR      0x2A
-#define D1FIFOSEL      0x2C
-#define D1FIFOCTR      0x2E
-#define INTENB0                0x30
-#define INTENB1                0x32
-#define INTENB2                0x34
-#define BRDYENB                0x36
-#define NRDYENB                0x38
-#define BEMPENB                0x3A
-#define SOFCFG         0x3C
-#define INTSTS0                0x40
-#define INTSTS1                0x42
-#define INTSTS2                0x44
-#define BRDYSTS                0x46
-#define NRDYSTS                0x48
-#define BEMPSTS                0x4A
-#define FRMNUM         0x4C
-#define UFRMNUM                0x4E
-#define USBADDR                0x50
-#define USBREQ         0x54
-#define USBVAL         0x56
-#define USBINDX                0x58
-#define USBLENG                0x5A
-#define DCPCFG         0x5C
-#define DCPMAXP                0x5E
-#define DCPCTR         0x60
-#define PIPESEL                0x64
-#define PIPECFG                0x68
-#define PIPEBUF                0x6A
-#define PIPEMAXP       0x6C
-#define PIPEPERI       0x6E
-#define PIPE1CTR       0x70
-#define PIPE2CTR       0x72
-#define PIPE3CTR       0x74
-#define PIPE4CTR       0x76
-#define PIPE5CTR       0x78
-#define PIPE6CTR       0x7A
-#define PIPE7CTR       0x7C
-#define PIPE8CTR       0x7E
-#define PIPE9CTR       0x80
-#define PIPE1TRE       0x90
-#define PIPE1TRN       0x92
-#define PIPE2TRE       0x94
-#define PIPE2TRN       0x96
-#define PIPE3TRE       0x98
-#define PIPE3TRN       0x9A
-#define PIPE4TRE       0x9C
-#define        PIPE4TRN        0x9E
-#define        PIPE5TRE        0xA0
-#define        PIPE5TRN        0xA2
-#define DEVADD0                0xD0
-#define DEVADD1                0xD2
-#define DEVADD2                0xD4
-#define DEVADD3                0xD6
-#define DEVADD4                0xD8
-#define DEVADD5                0xDA
-#define DEVADD6                0xDC
-#define DEVADD7                0xDE
-#define DEVADD8                0xE0
-#define DEVADD9                0xE2
-#define DEVADDA                0xE4
-
-/* System Configuration Control Register */
-#define        XTAL            0xC000  /* b15-14: Crystal selection */
-#define          XTAL48         0x8000   /* 48MHz */
-#define          XTAL24         0x4000   /* 24MHz */
-#define          XTAL12         0x0000   /* 12MHz */
-#define        XCKE            0x2000  /* b13: External clock enable */
-#define        PLLC            0x0800  /* b11: PLL control */
-#define        SCKE            0x0400  /* b10: USB clock enable */
-#define        PCSDIS          0x0200  /* b9: not CS wakeup */
-#define        LPSME           0x0100  /* b8: Low power sleep mode */
-#define        HSE             0x0080  /* b7: Hi-speed enable */
-#define        DCFM            0x0040  /* b6: Controller function select  */
-#define        DRPD            0x0020  /* b5: D+/- pull down control */
-#define        DPRPU           0x0010  /* b4: D+ pull up control */
-#define        USBE            0x0001  /* b0: USB module operation enable */
-
-/* System Configuration Status Register */
-#define        OVCBIT          0x8000  /* b15-14: Over-current bit */
-#define        OVCMON          0xC000  /* b15-14: Over-current monitor */
-#define        SOFEA           0x0020  /* b5: SOF monitor */
-#define        IDMON           0x0004  /* b3: ID-pin monitor */
-#define        LNST            0x0003  /* b1-0: D+, D- line status */
-#define          SE1            0x0003   /* SE1 */
-#define          FS_KSTS        0x0002   /* Full-Speed K State */
-#define          FS_JSTS        0x0001   /* Full-Speed J State */
-#define          LS_JSTS        0x0002   /* Low-Speed J State */
-#define          LS_KSTS        0x0001   /* Low-Speed K State */
-#define          SE0            0x0000   /* SE0 */
-
-/* Device State Control Register */
-#define        EXTLP0          0x0400  /* b10: External port */
-#define        VBOUT           0x0200  /* b9: VBUS output */
-#define        WKUP            0x0100  /* b8: Remote wakeup */
-#define        RWUPE           0x0080  /* b7: Remote wakeup sense */
-#define        USBRST          0x0040  /* b6: USB reset enable */
-#define        RESUME          0x0020  /* b5: Resume enable */
-#define        UACT            0x0010  /* b4: USB bus enable */
-#define        RHST            0x0007  /* b1-0: Reset handshake status */
-#define          HSPROC         0x0004   /* HS handshake is processing */
-#define          HSMODE         0x0003   /* Hi-Speed mode */
-#define          FSMODE         0x0002   /* Full-Speed mode */
-#define          LSMODE         0x0001   /* Low-Speed mode */
-#define          UNDECID        0x0000   /* Undecided */
-
-/* Test Mode Register */
-#define        UTST                    0x000F  /* b3-0: Test select */
-#define          H_TST_PACKET           0x000C   /* HOST TEST Packet */
-#define          H_TST_SE0_NAK          0x000B   /* HOST TEST SE0 NAK */
-#define          H_TST_K                0x000A   /* HOST TEST K */
-#define          H_TST_J                0x0009   /* HOST TEST J */
-#define          H_TST_NORMAL           0x0000   /* HOST Normal Mode */
-#define          P_TST_PACKET           0x0004   /* PERI TEST Packet */
-#define          P_TST_SE0_NAK          0x0003   /* PERI TEST SE0 NAK */
-#define          P_TST_K                0x0002   /* PERI TEST K */
-#define          P_TST_J                0x0001   /* PERI TEST J */
-#define          P_TST_NORMAL           0x0000   /* PERI Normal Mode */
-
-/* Data Pin Configuration Register */
-#define        LDRV                    0x8000  /* b15: Drive Current Adjust */
-#define          VIF1                    0x0000                /* VIF = 1.8V */
-#define          VIF3                    0x8000                /* VIF = 3.3V */
-#define        INTA                    0x0001  /* b1: USB INT-pin active */
-
-/* DMAx Pin Configuration Register */
-#define        DREQA                   0x4000  /* b14: Dreq active select */
-#define        BURST                   0x2000  /* b13: Burst mode */
-#define        DACKA                   0x0400  /* b10: Dack active select */
-#define        DFORM                   0x0380  /* b9-7: DMA mode select */
-#define          CPU_ADR_RD_WR          0x0000   /* Address + RD/WR mode (CPU bus) */
-#define          CPU_DACK_RD_WR         0x0100   /* DACK + RD/WR mode (CPU bus) */
-#define          CPU_DACK_ONLY          0x0180   /* DACK only mode (CPU bus) */
-#define          SPLIT_DACK_ONLY        0x0200   /* DACK only mode (SPLIT bus) */
-#define        DENDA                   0x0040  /* b6: Dend active select */
-#define        PKTM                    0x0020  /* b5: Packet mode */
-#define        DENDE                   0x0010  /* b4: Dend enable */
-#define        OBUS                    0x0004  /* b2: OUTbus mode */
-
-/* CFIFO/DxFIFO Port Select Register */
-#define        RCNT            0x8000  /* b15: Read count mode */
-#define        REW             0x4000  /* b14: Buffer rewind */
-#define        DCLRM           0x2000  /* b13: DMA buffer clear mode */
-#define        DREQE           0x1000  /* b12: DREQ output enable */
-#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597)
-#define        MBW             0x0800
-#else
-#define        MBW             0x0400  /* b10: Maximum bit width for FIFO access */
-#endif
-#define          MBW_8          0x0000   /*  8bit */
-#define          MBW_16         0x0400   /* 16bit */
-#define        BIGEND          0x0100  /* b8: Big endian mode */
-#define          BYTE_LITTLE    0x0000         /* little dendian */
-#define          BYTE_BIG       0x0100         /* big endifan */
-#define        ISEL            0x0020  /* b5: DCP FIFO port direction select */
-#define        CURPIPE         0x000F  /* b2-0: PIPE select */
-
-/* CFIFO/DxFIFO Port Control Register */
-#define        BVAL            0x8000  /* b15: Buffer valid flag */
-#define        BCLR            0x4000  /* b14: Buffer clear */
-#define        FRDY            0x2000  /* b13: FIFO ready */
-#define        DTLN            0x0FFF  /* b11-0: FIFO received data length */
-
-/* Interrupt Enable Register 0 */
-#define        VBSE    0x8000  /* b15: VBUS interrupt */
-#define        RSME    0x4000  /* b14: Resume interrupt */
-#define        SOFE    0x2000  /* b13: Frame update interrupt */
-#define        DVSE    0x1000  /* b12: Device state transition interrupt */
-#define        CTRE    0x0800  /* b11: Control transfer stage transition interrupt */
-#define        BEMPE   0x0400  /* b10: Buffer empty interrupt */
-#define        NRDYE   0x0200  /* b9: Buffer not ready interrupt */
-#define        BRDYE   0x0100  /* b8: Buffer ready interrupt */
-
-/* Interrupt Enable Register 1 */
-#define        OVRCRE          0x8000  /* b15: Over-current interrupt */
-#define        BCHGE           0x4000  /* b14: USB us chenge interrupt */
-#define        DTCHE           0x1000  /* b12: Detach sense interrupt */
-#define        ATTCHE          0x0800  /* b11: Attach sense interrupt */
-#define        EOFERRE         0x0040  /* b6: EOF error interrupt */
-#define        SIGNE           0x0020  /* b5: SETUP IGNORE interrupt */
-#define        SACKE           0x0010  /* b4: SETUP ACK interrupt */
-
-/* BRDY Interrupt Enable/Status Register */
-#define        BRDY9           0x0200  /* b9: PIPE9 */
-#define        BRDY8           0x0100  /* b8: PIPE8 */
-#define        BRDY7           0x0080  /* b7: PIPE7 */
-#define        BRDY6           0x0040  /* b6: PIPE6 */
-#define        BRDY5           0x0020  /* b5: PIPE5 */
-#define        BRDY4           0x0010  /* b4: PIPE4 */
-#define        BRDY3           0x0008  /* b3: PIPE3 */
-#define        BRDY2           0x0004  /* b2: PIPE2 */
-#define        BRDY1           0x0002  /* b1: PIPE1 */
-#define        BRDY0           0x0001  /* b1: PIPE0 */
-
-/* NRDY Interrupt Enable/Status Register */
-#define        NRDY9           0x0200  /* b9: PIPE9 */
-#define        NRDY8           0x0100  /* b8: PIPE8 */
-#define        NRDY7           0x0080  /* b7: PIPE7 */
-#define        NRDY6           0x0040  /* b6: PIPE6 */
-#define        NRDY5           0x0020  /* b5: PIPE5 */
-#define        NRDY4           0x0010  /* b4: PIPE4 */
-#define        NRDY3           0x0008  /* b3: PIPE3 */
-#define        NRDY2           0x0004  /* b2: PIPE2 */
-#define        NRDY1           0x0002  /* b1: PIPE1 */
-#define        NRDY0           0x0001  /* b1: PIPE0 */
-
-/* BEMP Interrupt Enable/Status Register */
-#define        BEMP9           0x0200  /* b9: PIPE9 */
-#define        BEMP8           0x0100  /* b8: PIPE8 */
-#define        BEMP7           0x0080  /* b7: PIPE7 */
-#define        BEMP6           0x0040  /* b6: PIPE6 */
-#define        BEMP5           0x0020  /* b5: PIPE5 */
-#define        BEMP4           0x0010  /* b4: PIPE4 */
-#define        BEMP3           0x0008  /* b3: PIPE3 */
-#define        BEMP2           0x0004  /* b2: PIPE2 */
-#define        BEMP1           0x0002  /* b1: PIPE1 */
-#define        BEMP0           0x0001  /* b0: PIPE0 */
-
-/* SOF Pin Configuration Register */
-#define        TRNENSEL        0x0100  /* b8: Select transaction enable period */
-#define        BRDYM           0x0040  /* b6: BRDY clear timing */
-#define        INTL            0x0020  /* b5: Interrupt sense select */
-#define        EDGESTS         0x0010  /* b4:  */
-#define        SOFMODE         0x000C  /* b3-2: SOF pin select */
-#define          SOF_125US      0x0008   /* SOF OUT 125us Frame Signal */
-#define          SOF_1MS        0x0004   /* SOF OUT 1ms Frame Signal */
-#define          SOF_DISABLE    0x0000   /* SOF OUT Disable */
-
-/* Interrupt Status Register 0 */
-#define        VBINT   0x8000  /* b15: VBUS interrupt */
-#define        RESM    0x4000  /* b14: Resume interrupt */
-#define        SOFR    0x2000  /* b13: SOF frame update interrupt */
-#define        DVST    0x1000  /* b12: Device state transition interrupt */
-#define        CTRT    0x0800  /* b11: Control transfer stage transition interrupt */
-#define        BEMP    0x0400  /* b10: Buffer empty interrupt */
-#define        NRDY    0x0200  /* b9: Buffer not ready interrupt */
-#define        BRDY    0x0100  /* b8: Buffer ready interrupt */
-#define        VBSTS   0x0080  /* b7: VBUS input port */
-#define        DVSQ    0x0070  /* b6-4: Device state */
-#define          DS_SPD_CNFG    0x0070   /* Suspend Configured */
-#define          DS_SPD_ADDR    0x0060   /* Suspend Address */
-#define          DS_SPD_DFLT    0x0050   /* Suspend Default */
-#define          DS_SPD_POWR    0x0040   /* Suspend Powered */
-#define          DS_SUSP        0x0040   /* Suspend */
-#define          DS_CNFG        0x0030   /* Configured */
-#define          DS_ADDS        0x0020   /* Address */
-#define          DS_DFLT        0x0010   /* Default */
-#define          DS_POWR        0x0000   /* Powered */
-#define        DVSQS           0x0030  /* b5-4: Device state */
-#define        VALID           0x0008  /* b3: Setup packet detected flag */
-#define        CTSQ            0x0007  /* b2-0: Control transfer stage */
-#define          CS_SQER        0x0006   /* Sequence error */
-#define          CS_WRND        0x0005   /* Control write nodata status stage */
-#define          CS_WRSS        0x0004   /* Control write status stage */
-#define          CS_WRDS        0x0003   /* Control write data stage */
-#define          CS_RDSS        0x0002   /* Control read status stage */
-#define          CS_RDDS        0x0001   /* Control read data stage */
-#define          CS_IDST        0x0000   /* Idle or setup stage */
-
-/* Interrupt Status Register 1 */
-#define        OVRCR           0x8000  /* b15: Over-current interrupt */
-#define        BCHG            0x4000  /* b14: USB bus chenge interrupt */
-#define        DTCH            0x1000  /* b12: Detach sense interrupt */
-#define        ATTCH           0x0800  /* b11: Attach sense interrupt */
-#define        EOFERR          0x0040  /* b6: EOF-error interrupt */
-#define        SIGN            0x0020  /* b5: Setup ignore interrupt */
-#define        SACK            0x0010  /* b4: Setup acknowledge interrupt */
-
-/* Frame Number Register */
-#define        OVRN            0x8000  /* b15: Overrun error */
-#define        CRCE            0x4000  /* b14: Received data error */
-#define        FRNM            0x07FF  /* b10-0: Frame number */
-
-/* Micro Frame Number Register */
-#define        UFRNM           0x0007  /* b2-0: Micro frame number */
-
-/* Default Control Pipe Maxpacket Size Register */
-/* Pipe Maxpacket Size Register */
-#define        DEVSEL  0xF000  /* b15-14: Device address select */
-#define        MAXP    0x007F  /* b6-0: Maxpacket size of default control pipe */
-
-/* Default Control Pipe Control Register */
-#define        BSTS            0x8000  /* b15: Buffer status */
-#define        SUREQ           0x4000  /* b14: Send USB request  */
-#define        CSCLR           0x2000  /* b13: complete-split status clear */
-#define        CSSTS           0x1000  /* b12: complete-split status */
-#define        SUREQCLR        0x0800  /* b11: stop setup request */
-#define        SQCLR           0x0100  /* b8: Sequence toggle bit clear */
-#define        SQSET           0x0080  /* b7: Sequence toggle bit set */
-#define        SQMON           0x0040  /* b6: Sequence toggle bit monitor */
-#define        PBUSY           0x0020  /* b5: pipe busy */
-#define        PINGE           0x0010  /* b4: ping enable */
-#define        CCPL            0x0004  /* b2: Enable control transfer complete */
-#define        PID             0x0003  /* b1-0: Response PID */
-#define          PID_STALL11    0x0003   /* STALL */
-#define          PID_STALL      0x0002   /* STALL */
-#define          PID_BUF        0x0001   /* BUF */
-#define          PID_NAK        0x0000   /* NAK */
-
-/* Pipe Window Select Register */
-#define        PIPENM          0x0007  /* b2-0: Pipe select */
-
-/* Pipe Configuration Register */
-#define        R8A66597_TYP    0xC000  /* b15-14: Transfer type */
-#define          R8A66597_ISO   0xC000           /* Isochronous */
-#define          R8A66597_INT   0x8000           /* Interrupt */
-#define          R8A66597_BULK  0x4000           /* Bulk */
-#define        R8A66597_BFRE   0x0400  /* b10: Buffer ready interrupt mode select */
-#define        R8A66597_DBLB   0x0200  /* b9: Double buffer mode select */
-#define        R8A66597_CNTMD  0x0100  /* b8: Continuous transfer mode select */
-#define        R8A66597_SHTNAK 0x0080  /* b7: Transfer end NAK */
-#define        R8A66597_DIR    0x0010  /* b4: Transfer direction select */
-#define        R8A66597_EPNUM  0x000F  /* b3-0: Eendpoint number select */
-
-/* Pipe Buffer Configuration Register */
-#define        BUFSIZE         0x7C00  /* b14-10: Pipe buffer size */
-#define        BUFNMB          0x007F  /* b6-0: Pipe buffer number */
-#define        PIPE0BUF        256
-#define        PIPExBUF        64
-
-/* Pipe Maxpacket Size Register */
-#define        MXPS            0x07FF  /* b10-0: Maxpacket size */
-
-/* Pipe Cycle Configuration Register */
-#define        IFIS    0x1000  /* b12: Isochronous in-buffer flush mode select */
-#define        IITV    0x0007  /* b2-0: Isochronous interval */
-
-/* Pipex Control Register */
-#define        BSTS    0x8000  /* b15: Buffer status */
-#define        INBUFM  0x4000  /* b14: IN buffer monitor (Only for PIPE1 to 5) */
-#define        CSCLR   0x2000  /* b13: complete-split status clear */
-#define        CSSTS   0x1000  /* b12: complete-split status */
-#define        ATREPM  0x0400  /* b10: Auto repeat mode */
-#define        ACLRM   0x0200  /* b9: Out buffer auto clear mode */
-#define        SQCLR   0x0100  /* b8: Sequence toggle bit clear */
-#define        SQSET   0x0080  /* b7: Sequence toggle bit set */
-#define        SQMON   0x0040  /* b6: Sequence toggle bit monitor */
-#define        PBUSY   0x0020  /* b5: pipe busy */
-#define        PID     0x0003  /* b1-0: Response PID */
-
-/* PIPExTRE */
-#define        TRENB           0x0200  /* b9: Transaction counter enable */
-#define        TRCLR           0x0100  /* b8: Transaction counter clear */
-
-/* PIPExTRN */
-#define        TRNCNT          0xFFFF  /* b15-0: Transaction counter */
-
-/* DEVADDx */
-#define        UPPHUB          0x7800
-#define        HUBPORT         0x0700
-#define        USBSPD          0x00C0
-#define        RTPORT          0x0001
-
 #define R8A66597_MAX_NUM_PIPE          10
 #define R8A66597_BUF_BSIZE             8
 #define R8A66597_MAX_DEVICE            10
-#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597)
-#define R8A66597_MAX_ROOT_HUB          1
-#else
 #define R8A66597_MAX_ROOT_HUB          2
-#endif
 #define R8A66597_MAX_SAMPLING          5
 #define R8A66597_RH_POLL_TIME          10
 #define R8A66597_MAX_DMA_CHANNEL       2
@@ -487,7 +113,7 @@ struct r8a66597_root_hub {
 struct r8a66597 {
        spinlock_t lock;
        unsigned long reg;
-#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) && defined(CONFIG_HAVE_CLK)
+#ifdef CONFIG_HAVE_CLK
        struct clk *clk;
 #endif
        struct r8a66597_platdata        *pdata;
@@ -504,6 +130,7 @@ struct r8a66597 {
        unsigned short interval_map;
        unsigned char pipe_cnt[R8A66597_MAX_NUM_PIPE];
        unsigned char dma_map;
+       unsigned int max_root_hub;
 
        struct list_head child_device;
        unsigned long child_connect_map[4];
@@ -550,21 +177,22 @@ static inline void r8a66597_read_fifo(struct r8a66597 *r8a66597,
                                      unsigned long offset, u16 *buf,
                                      int len)
 {
-#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597)
        unsigned long fifoaddr = r8a66597->reg + offset;
        unsigned long count;
 
-       count = len / 4;
-       insl(fifoaddr, buf, count);
+       if (r8a66597->pdata->on_chip) {
+               count = len / 4;
+               insl(fifoaddr, buf, count);
 
-       if (len & 0x00000003) {
-               unsigned long tmp = inl(fifoaddr);
-               memcpy((unsigned char *)buf + count * 4, &tmp, len & 0x03);
+               if (len & 0x00000003) {
+                       unsigned long tmp = inl(fifoaddr);
+                       memcpy((unsigned char *)buf + count * 4, &tmp,
+                              len & 0x03);
+               }
+       } else {
+               len = (len + 1) / 2;
+               insw(fifoaddr, buf, len);
        }
-#else
-       len = (len + 1) / 2;
-       insw(r8a66597->reg + offset, buf, len);
-#endif
 }
 
 static inline void r8a66597_write(struct r8a66597 *r8a66597, u16 val,
@@ -578,33 +206,33 @@ static inline void r8a66597_write_fifo(struct r8a66597 *r8a66597,
                                       int len)
 {
        unsigned long fifoaddr = r8a66597->reg + offset;
-#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597)
        unsigned long count;
        unsigned char *pb;
        int i;
 
-       count = len / 4;
-       outsl(fifoaddr, buf, count);
+       if (r8a66597->pdata->on_chip) {
+               count = len / 4;
+               outsl(fifoaddr, buf, count);
+
+               if (len & 0x00000003) {
+                       pb = (unsigned char *)buf + count * 4;
+                       for (i = 0; i < (len & 0x00000003); i++) {
+                               if (r8a66597_read(r8a66597, CFIFOSEL) & BIGEND)
+                                       outb(pb[i], fifoaddr + i);
+                               else
+                                       outb(pb[i], fifoaddr + 3 - i);
+                       }
+               }
+       } else {
+               int odd = len & 0x0001;
 
-       if (len & 0x00000003) {
-               pb = (unsigned char *)buf + count * 4;
-               for (i = 0; i < (len & 0x00000003); i++) {
-                       if (r8a66597_read(r8a66597, CFIFOSEL) & BIGEND)
-                               outb(pb[i], fifoaddr + i);
-                       else
-                               outb(pb[i], fifoaddr + 3 - i);
+               len = len / 2;
+               outsw(fifoaddr, buf, len);
+               if (unlikely(odd)) {
+                       buf = &buf[len];
+                       outb((unsigned char)*buf, fifoaddr);
                }
        }
-#else
-       int odd = len & 0x0001;
-
-       len = len / 2;
-       outsw(fifoaddr, buf, len);
-       if (unlikely(odd)) {
-               buf = &buf[len];
-               outb((unsigned char)*buf, fifoaddr);
-       }
-#endif
 }
 
 static inline void r8a66597_mdfy(struct r8a66597 *r8a66597,
index 3b54b39401781a7b42c076b66cad74eab0ff5259..7e2c9774f08fbfc9df5f0093d32854e6ed94cffa 100644 (file)
@@ -1867,7 +1867,7 @@ config FB_W100
 
 config FB_SH_MOBILE_LCDC
        tristate "SuperH Mobile LCDC framebuffer support"
-       depends on FB && SUPERH
+       depends on FB && SUPERH && HAVE_CLK
        select FB_SYS_FILLRECT
        select FB_SYS_COPYAREA
        select FB_SYS_IMAGEBLIT
index 07f22b625632872c10476c33ab5dab5e97792adc..fc3f9662ceae8d778f2790307050b04db8f5226d 100644 (file)
@@ -42,11 +42,9 @@ struct sh_mobile_lcdc_chan {
 struct sh_mobile_lcdc_priv {
        void __iomem *base;
        int irq;
-#ifdef CONFIG_HAVE_CLK
        atomic_t clk_usecnt;
        struct clk *dot_clk;
        struct clk *clk;
-#endif
        unsigned long lddckr;
        struct sh_mobile_lcdc_chan ch[2];
        int started;
@@ -156,6 +154,7 @@ static void lcdc_sys_write_index(void *handle, unsigned long data)
        lcdc_write(ch->lcdc, _LDDWD0R, data | 0x10000000);
        lcdc_wait_bit(ch->lcdc, _LDSR, 2, 0);
        lcdc_write(ch->lcdc, _LDDWAR, 1 | (lcdc_chan_is_sublcd(ch) ? 2 : 0));
+       lcdc_wait_bit(ch->lcdc, _LDSR, 2, 0);
 }
 
 static void lcdc_sys_write_data(void *handle, unsigned long data)
@@ -165,6 +164,7 @@ static void lcdc_sys_write_data(void *handle, unsigned long data)
        lcdc_write(ch->lcdc, _LDDWD0R, data | 0x11000000);
        lcdc_wait_bit(ch->lcdc, _LDSR, 2, 0);
        lcdc_write(ch->lcdc, _LDDWAR, 1 | (lcdc_chan_is_sublcd(ch) ? 2 : 0));
+       lcdc_wait_bit(ch->lcdc, _LDSR, 2, 0);
 }
 
 static unsigned long lcdc_sys_read_data(void *handle)
@@ -175,8 +175,9 @@ static unsigned long lcdc_sys_read_data(void *handle)
        lcdc_wait_bit(ch->lcdc, _LDSR, 2, 0);
        lcdc_write(ch->lcdc, _LDDRAR, 1 | (lcdc_chan_is_sublcd(ch) ? 2 : 0));
        udelay(1);
+       lcdc_wait_bit(ch->lcdc, _LDSR, 2, 0);
 
-       return lcdc_read(ch->lcdc, _LDDRDR) & 0xffff;
+       return lcdc_read(ch->lcdc, _LDDRDR) & 0x3ffff;
 }
 
 struct sh_mobile_lcdc_sys_bus_ops sh_mobile_lcdc_sys_bus_ops = {
@@ -185,7 +186,6 @@ struct sh_mobile_lcdc_sys_bus_ops sh_mobile_lcdc_sys_bus_ops = {
        lcdc_sys_read_data,
 };
 
-#ifdef CONFIG_HAVE_CLK
 static void sh_mobile_lcdc_clk_on(struct sh_mobile_lcdc_priv *priv)
 {
        if (atomic_inc_and_test(&priv->clk_usecnt)) {
@@ -203,10 +203,6 @@ static void sh_mobile_lcdc_clk_off(struct sh_mobile_lcdc_priv *priv)
                clk_disable(priv->clk);
        }
 }
-#else
-static void sh_mobile_lcdc_clk_on(struct sh_mobile_lcdc_priv *priv) {}
-static void sh_mobile_lcdc_clk_off(struct sh_mobile_lcdc_priv *priv) {}
-#endif
 
 static int sh_mobile_lcdc_sginit(struct fb_info *info,
                                  struct list_head *pagelist)
@@ -520,7 +516,6 @@ static void sh_mobile_lcdc_stop(struct sh_mobile_lcdc_priv *priv)
                board_cfg = &ch->cfg.board_cfg;
                if (board_cfg->display_off)
                        board_cfg->display_off(board_cfg->board_data);
-
        }
 
        /* stop the lcdc */
@@ -579,9 +574,7 @@ static int sh_mobile_lcdc_setup_clocks(struct platform_device *pdev,
                                       int clock_source,
                                       struct sh_mobile_lcdc_priv *priv)
 {
-#ifdef CONFIG_HAVE_CLK
        char clk_name[8];
-#endif
        char *str;
        int icksel;
 
@@ -595,7 +588,6 @@ static int sh_mobile_lcdc_setup_clocks(struct platform_device *pdev,
 
        priv->lddckr = icksel << 16;
 
-#ifdef CONFIG_HAVE_CLK
        atomic_set(&priv->clk_usecnt, -1);
        snprintf(clk_name, sizeof(clk_name), "lcdc%d", pdev->id);
        priv->clk = clk_get(&pdev->dev, clk_name);
@@ -603,7 +595,7 @@ static int sh_mobile_lcdc_setup_clocks(struct platform_device *pdev,
                dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name);
                return PTR_ERR(priv->clk);
        }
-       
+
        if (str) {
                priv->dot_clk = clk_get(&pdev->dev, str);
                if (IS_ERR(priv->dot_clk)) {
@@ -612,7 +604,6 @@ static int sh_mobile_lcdc_setup_clocks(struct platform_device *pdev,
                        return PTR_ERR(priv->dot_clk);
                }
        }
-#endif
 
        return 0;
 }
@@ -947,11 +938,9 @@ static int sh_mobile_lcdc_remove(struct platform_device *pdev)
                framebuffer_release(info);
        }
 
-#ifdef CONFIG_HAVE_CLK
        if (priv->dot_clk)
                clk_put(priv->dot_clk);
        clk_put(priv->clk);
-#endif
 
        if (priv->base)
                iounmap(priv->base);
diff --git a/include/linux/usb/m66592.h b/include/linux/usb/m66592.h
new file mode 100644 (file)
index 0000000..cda9625
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * M66592 driver platform data
+ *
+ * Copyright (C) 2009  Renesas Solutions Corp.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#ifndef __LINUX_USB_M66592_H
+#define __LINUX_USB_M66592_H
+
+#define M66592_PLATDATA_XTAL_12MHZ     0x01
+#define M66592_PLATDATA_XTAL_24MHZ     0x02
+#define M66592_PLATDATA_XTAL_48MHZ     0x03
+
+struct m66592_platdata {
+       /* one = on chip controller, zero = external controller */
+       unsigned        on_chip:1;
+
+       /* one = big endian, zero = little endian */
+       unsigned        endian:1;
+
+       /* (external controller only) M66592_PLATDATA_XTAL_nnMHZ */
+       unsigned        xtal:2;
+
+       /* (external controller only) one = 3.3V, zero = 1.5V */
+       unsigned        vif:1;
+
+};
+
+#endif /* __LINUX_USB_M66592_H */
+
index e9f0384fa20cdb326103957bca091c2b5b416e7d..26d2167340573e8e2b8fa9cf7b7e96344fb39422 100644 (file)
 #define R8A66597_PLATDATA_XTAL_48MHZ   0x03
 
 struct r8a66597_platdata {
-       /* This ops can controll port power instead of DVSTCTR register. */
+       /* This callback can control port power instead of DVSTCTR register. */
        void (*port_power)(int port, int power);
 
+       /* set one = on chip controller, set zero = external controller */
+       unsigned        on_chip:1;
+
        /* (external controller only) set R8A66597_PLATDATA_XTAL_nnMHZ */
        unsigned        xtal:2;
 
@@ -40,5 +43,373 @@ struct r8a66597_platdata {
        /* set one = big endian, set zero = little endian */
        unsigned        endian:1;
 };
-#endif
+
+/* Register definitions */
+#define SYSCFG0                0x00
+#define SYSCFG1                0x02
+#define SYSSTS0                0x04
+#define SYSSTS1                0x06
+#define DVSTCTR0       0x08
+#define DVSTCTR1       0x0A
+#define TESTMODE       0x0C
+#define PINCFG         0x0E
+#define DMA0CFG                0x10
+#define DMA1CFG                0x12
+#define CFIFO          0x14
+#define D0FIFO         0x18
+#define D1FIFO         0x1C
+#define CFIFOSEL       0x20
+#define CFIFOCTR       0x22
+#define CFIFOSIE       0x24
+#define D0FIFOSEL      0x28
+#define D0FIFOCTR      0x2A
+#define D1FIFOSEL      0x2C
+#define D1FIFOCTR      0x2E
+#define INTENB0                0x30
+#define INTENB1                0x32
+#define INTENB2                0x34
+#define BRDYENB                0x36
+#define NRDYENB                0x38
+#define BEMPENB                0x3A
+#define SOFCFG         0x3C
+#define INTSTS0                0x40
+#define INTSTS1                0x42
+#define INTSTS2                0x44
+#define BRDYSTS                0x46
+#define NRDYSTS                0x48
+#define BEMPSTS                0x4A
+#define FRMNUM         0x4C
+#define UFRMNUM                0x4E
+#define USBADDR                0x50
+#define USBREQ         0x54
+#define USBVAL         0x56
+#define USBINDX                0x58
+#define USBLENG                0x5A
+#define DCPCFG         0x5C
+#define DCPMAXP                0x5E
+#define DCPCTR         0x60
+#define PIPESEL                0x64
+#define PIPECFG                0x68
+#define PIPEBUF                0x6A
+#define PIPEMAXP       0x6C
+#define PIPEPERI       0x6E
+#define PIPE1CTR       0x70
+#define PIPE2CTR       0x72
+#define PIPE3CTR       0x74
+#define PIPE4CTR       0x76
+#define PIPE5CTR       0x78
+#define PIPE6CTR       0x7A
+#define PIPE7CTR       0x7C
+#define PIPE8CTR       0x7E
+#define PIPE9CTR       0x80
+#define PIPE1TRE       0x90
+#define PIPE1TRN       0x92
+#define PIPE2TRE       0x94
+#define PIPE2TRN       0x96
+#define PIPE3TRE       0x98
+#define PIPE3TRN       0x9A
+#define PIPE4TRE       0x9C
+#define        PIPE4TRN        0x9E
+#define        PIPE5TRE        0xA0
+#define        PIPE5TRN        0xA2
+#define DEVADD0                0xD0
+#define DEVADD1                0xD2
+#define DEVADD2                0xD4
+#define DEVADD3                0xD6
+#define DEVADD4                0xD8
+#define DEVADD5                0xDA
+#define DEVADD6                0xDC
+#define DEVADD7                0xDE
+#define DEVADD8                0xE0
+#define DEVADD9                0xE2
+#define DEVADDA                0xE4
+
+/* System Configuration Control Register */
+#define        XTAL            0xC000  /* b15-14: Crystal selection */
+#define          XTAL48         0x8000   /* 48MHz */
+#define          XTAL24         0x4000   /* 24MHz */
+#define          XTAL12         0x0000   /* 12MHz */
+#define        XCKE            0x2000  /* b13: External clock enable */
+#define        PLLC            0x0800  /* b11: PLL control */
+#define        SCKE            0x0400  /* b10: USB clock enable */
+#define        PCSDIS          0x0200  /* b9: not CS wakeup */
+#define        LPSME           0x0100  /* b8: Low power sleep mode */
+#define        HSE             0x0080  /* b7: Hi-speed enable */
+#define        DCFM            0x0040  /* b6: Controller function select  */
+#define        DRPD            0x0020  /* b5: D+/- pull down control */
+#define        DPRPU           0x0010  /* b4: D+ pull up control */
+#define        USBE            0x0001  /* b0: USB module operation enable */
+
+/* System Configuration Status Register */
+#define        OVCBIT          0x8000  /* b15-14: Over-current bit */
+#define        OVCMON          0xC000  /* b15-14: Over-current monitor */
+#define        SOFEA           0x0020  /* b5: SOF monitor */
+#define        IDMON           0x0004  /* b3: ID-pin monitor */
+#define        LNST            0x0003  /* b1-0: D+, D- line status */
+#define          SE1            0x0003   /* SE1 */
+#define          FS_KSTS        0x0002   /* Full-Speed K State */
+#define          FS_JSTS        0x0001   /* Full-Speed J State */
+#define          LS_JSTS        0x0002   /* Low-Speed J State */
+#define          LS_KSTS        0x0001   /* Low-Speed K State */
+#define          SE0            0x0000   /* SE0 */
+
+/* Device State Control Register */
+#define        EXTLP0          0x0400  /* b10: External port */
+#define        VBOUT           0x0200  /* b9: VBUS output */
+#define        WKUP            0x0100  /* b8: Remote wakeup */
+#define        RWUPE           0x0080  /* b7: Remote wakeup sense */
+#define        USBRST          0x0040  /* b6: USB reset enable */
+#define        RESUME          0x0020  /* b5: Resume enable */
+#define        UACT            0x0010  /* b4: USB bus enable */
+#define        RHST            0x0007  /* b1-0: Reset handshake status */
+#define          HSPROC         0x0004   /* HS handshake is processing */
+#define          HSMODE         0x0003   /* Hi-Speed mode */
+#define          FSMODE         0x0002   /* Full-Speed mode */
+#define          LSMODE         0x0001   /* Low-Speed mode */
+#define          UNDECID        0x0000   /* Undecided */
+
+/* Test Mode Register */
+#define        UTST                    0x000F  /* b3-0: Test select */
+#define          H_TST_PACKET           0x000C   /* HOST TEST Packet */
+#define          H_TST_SE0_NAK          0x000B   /* HOST TEST SE0 NAK */
+#define          H_TST_K                0x000A   /* HOST TEST K */
+#define          H_TST_J                0x0009   /* HOST TEST J */
+#define          H_TST_NORMAL           0x0000   /* HOST Normal Mode */
+#define          P_TST_PACKET           0x0004   /* PERI TEST Packet */
+#define          P_TST_SE0_NAK          0x0003   /* PERI TEST SE0 NAK */
+#define          P_TST_K                0x0002   /* PERI TEST K */
+#define          P_TST_J                0x0001   /* PERI TEST J */
+#define          P_TST_NORMAL           0x0000   /* PERI Normal Mode */
+
+/* Data Pin Configuration Register */
+#define        LDRV                    0x8000  /* b15: Drive Current Adjust */
+#define          VIF1                    0x0000                /* VIF = 1.8V */
+#define          VIF3                    0x8000                /* VIF = 3.3V */
+#define        INTA                    0x0001  /* b1: USB INT-pin active */
+
+/* DMAx Pin Configuration Register */
+#define        DREQA                   0x4000  /* b14: Dreq active select */
+#define        BURST                   0x2000  /* b13: Burst mode */
+#define        DACKA                   0x0400  /* b10: Dack active select */
+#define        DFORM                   0x0380  /* b9-7: DMA mode select */
+#define          CPU_ADR_RD_WR          0x0000   /* Address + RD/WR mode (CPU bus) */
+#define          CPU_DACK_RD_WR         0x0100   /* DACK + RD/WR mode (CPU bus) */
+#define          CPU_DACK_ONLY          0x0180   /* DACK only mode (CPU bus) */
+#define          SPLIT_DACK_ONLY        0x0200   /* DACK only mode (SPLIT bus) */
+#define        DENDA                   0x0040  /* b6: Dend active select */
+#define        PKTM                    0x0020  /* b5: Packet mode */
+#define        DENDE                   0x0010  /* b4: Dend enable */
+#define        OBUS                    0x0004  /* b2: OUTbus mode */
+
+/* CFIFO/DxFIFO Port Select Register */
+#define        RCNT            0x8000  /* b15: Read count mode */
+#define        REW             0x4000  /* b14: Buffer rewind */
+#define        DCLRM           0x2000  /* b13: DMA buffer clear mode */
+#define        DREQE           0x1000  /* b12: DREQ output enable */
+#define          MBW_8          0x0000   /*  8bit */
+#define          MBW_16         0x0400   /* 16bit */
+#define          MBW_32         0x0800   /* 32bit */
+#define        BIGEND          0x0100  /* b8: Big endian mode */
+#define          BYTE_LITTLE    0x0000         /* little dendian */
+#define          BYTE_BIG       0x0100         /* big endifan */
+#define        ISEL            0x0020  /* b5: DCP FIFO port direction select */
+#define        CURPIPE         0x000F  /* b2-0: PIPE select */
+
+/* CFIFO/DxFIFO Port Control Register */
+#define        BVAL            0x8000  /* b15: Buffer valid flag */
+#define        BCLR            0x4000  /* b14: Buffer clear */
+#define        FRDY            0x2000  /* b13: FIFO ready */
+#define        DTLN            0x0FFF  /* b11-0: FIFO received data length */
+
+/* Interrupt Enable Register 0 */
+#define        VBSE    0x8000  /* b15: VBUS interrupt */
+#define        RSME    0x4000  /* b14: Resume interrupt */
+#define        SOFE    0x2000  /* b13: Frame update interrupt */
+#define        DVSE    0x1000  /* b12: Device state transition interrupt */
+#define        CTRE    0x0800  /* b11: Control transfer stage transition interrupt */
+#define        BEMPE   0x0400  /* b10: Buffer empty interrupt */
+#define        NRDYE   0x0200  /* b9: Buffer not ready interrupt */
+#define        BRDYE   0x0100  /* b8: Buffer ready interrupt */
+
+/* Interrupt Enable Register 1 */
+#define        OVRCRE          0x8000  /* b15: Over-current interrupt */
+#define        BCHGE           0x4000  /* b14: USB us chenge interrupt */
+#define        DTCHE           0x1000  /* b12: Detach sense interrupt */
+#define        ATTCHE          0x0800  /* b11: Attach sense interrupt */
+#define        EOFERRE         0x0040  /* b6: EOF error interrupt */
+#define        SIGNE           0x0020  /* b5: SETUP IGNORE interrupt */
+#define        SACKE           0x0010  /* b4: SETUP ACK interrupt */
+
+/* BRDY Interrupt Enable/Status Register */
+#define        BRDY9           0x0200  /* b9: PIPE9 */
+#define        BRDY8           0x0100  /* b8: PIPE8 */
+#define        BRDY7           0x0080  /* b7: PIPE7 */
+#define        BRDY6           0x0040  /* b6: PIPE6 */
+#define        BRDY5           0x0020  /* b5: PIPE5 */
+#define        BRDY4           0x0010  /* b4: PIPE4 */
+#define        BRDY3           0x0008  /* b3: PIPE3 */
+#define        BRDY2           0x0004  /* b2: PIPE2 */
+#define        BRDY1           0x0002  /* b1: PIPE1 */
+#define        BRDY0           0x0001  /* b1: PIPE0 */
+
+/* NRDY Interrupt Enable/Status Register */
+#define        NRDY9           0x0200  /* b9: PIPE9 */
+#define        NRDY8           0x0100  /* b8: PIPE8 */
+#define        NRDY7           0x0080  /* b7: PIPE7 */
+#define        NRDY6           0x0040  /* b6: PIPE6 */
+#define        NRDY5           0x0020  /* b5: PIPE5 */
+#define        NRDY4           0x0010  /* b4: PIPE4 */
+#define        NRDY3           0x0008  /* b3: PIPE3 */
+#define        NRDY2           0x0004  /* b2: PIPE2 */
+#define        NRDY1           0x0002  /* b1: PIPE1 */
+#define        NRDY0           0x0001  /* b1: PIPE0 */
+
+/* BEMP Interrupt Enable/Status Register */
+#define        BEMP9           0x0200  /* b9: PIPE9 */
+#define        BEMP8           0x0100  /* b8: PIPE8 */
+#define        BEMP7           0x0080  /* b7: PIPE7 */
+#define        BEMP6           0x0040  /* b6: PIPE6 */
+#define        BEMP5           0x0020  /* b5: PIPE5 */
+#define        BEMP4           0x0010  /* b4: PIPE4 */
+#define        BEMP3           0x0008  /* b3: PIPE3 */
+#define        BEMP2           0x0004  /* b2: PIPE2 */
+#define        BEMP1           0x0002  /* b1: PIPE1 */
+#define        BEMP0           0x0001  /* b0: PIPE0 */
+
+/* SOF Pin Configuration Register */
+#define        TRNENSEL        0x0100  /* b8: Select transaction enable period */
+#define        BRDYM           0x0040  /* b6: BRDY clear timing */
+#define        INTL            0x0020  /* b5: Interrupt sense select */
+#define        EDGESTS         0x0010  /* b4:  */
+#define        SOFMODE         0x000C  /* b3-2: SOF pin select */
+#define          SOF_125US      0x0008   /* SOF OUT 125us Frame Signal */
+#define          SOF_1MS        0x0004   /* SOF OUT 1ms Frame Signal */
+#define          SOF_DISABLE    0x0000   /* SOF OUT Disable */
+
+/* Interrupt Status Register 0 */
+#define        VBINT   0x8000  /* b15: VBUS interrupt */
+#define        RESM    0x4000  /* b14: Resume interrupt */
+#define        SOFR    0x2000  /* b13: SOF frame update interrupt */
+#define        DVST    0x1000  /* b12: Device state transition interrupt */
+#define        CTRT    0x0800  /* b11: Control transfer stage transition interrupt */
+#define        BEMP    0x0400  /* b10: Buffer empty interrupt */
+#define        NRDY    0x0200  /* b9: Buffer not ready interrupt */
+#define        BRDY    0x0100  /* b8: Buffer ready interrupt */
+#define        VBSTS   0x0080  /* b7: VBUS input port */
+#define        DVSQ    0x0070  /* b6-4: Device state */
+#define          DS_SPD_CNFG    0x0070   /* Suspend Configured */
+#define          DS_SPD_ADDR    0x0060   /* Suspend Address */
+#define          DS_SPD_DFLT    0x0050   /* Suspend Default */
+#define          DS_SPD_POWR    0x0040   /* Suspend Powered */
+#define          DS_SUSP        0x0040   /* Suspend */
+#define          DS_CNFG        0x0030   /* Configured */
+#define          DS_ADDS        0x0020   /* Address */
+#define          DS_DFLT        0x0010   /* Default */
+#define          DS_POWR        0x0000   /* Powered */
+#define        DVSQS           0x0030  /* b5-4: Device state */
+#define        VALID           0x0008  /* b3: Setup packet detected flag */
+#define        CTSQ            0x0007  /* b2-0: Control transfer stage */
+#define          CS_SQER        0x0006   /* Sequence error */
+#define          CS_WRND        0x0005   /* Control write nodata status stage */
+#define          CS_WRSS        0x0004   /* Control write status stage */
+#define          CS_WRDS        0x0003   /* Control write data stage */
+#define          CS_RDSS        0x0002   /* Control read status stage */
+#define          CS_RDDS        0x0001   /* Control read data stage */
+#define          CS_IDST        0x0000   /* Idle or setup stage */
+
+/* Interrupt Status Register 1 */
+#define        OVRCR           0x8000  /* b15: Over-current interrupt */
+#define        BCHG            0x4000  /* b14: USB bus chenge interrupt */
+#define        DTCH            0x1000  /* b12: Detach sense interrupt */
+#define        ATTCH           0x0800  /* b11: Attach sense interrupt */
+#define        EOFERR          0x0040  /* b6: EOF-error interrupt */
+#define        SIGN            0x0020  /* b5: Setup ignore interrupt */
+#define        SACK            0x0010  /* b4: Setup acknowledge interrupt */
+
+/* Frame Number Register */
+#define        OVRN            0x8000  /* b15: Overrun error */
+#define        CRCE            0x4000  /* b14: Received data error */
+#define        FRNM            0x07FF  /* b10-0: Frame number */
+
+/* Micro Frame Number Register */
+#define        UFRNM           0x0007  /* b2-0: Micro frame number */
+
+/* Default Control Pipe Maxpacket Size Register */
+/* Pipe Maxpacket Size Register */
+#define        DEVSEL  0xF000  /* b15-14: Device address select */
+#define        MAXP    0x007F  /* b6-0: Maxpacket size of default control pipe */
+
+/* Default Control Pipe Control Register */
+#define        BSTS            0x8000  /* b15: Buffer status */
+#define        SUREQ           0x4000  /* b14: Send USB request  */
+#define        CSCLR           0x2000  /* b13: complete-split status clear */
+#define        CSSTS           0x1000  /* b12: complete-split status */
+#define        SUREQCLR        0x0800  /* b11: stop setup request */
+#define        SQCLR           0x0100  /* b8: Sequence toggle bit clear */
+#define        SQSET           0x0080  /* b7: Sequence toggle bit set */
+#define        SQMON           0x0040  /* b6: Sequence toggle bit monitor */
+#define        PBUSY           0x0020  /* b5: pipe busy */
+#define        PINGE           0x0010  /* b4: ping enable */
+#define        CCPL            0x0004  /* b2: Enable control transfer complete */
+#define        PID             0x0003  /* b1-0: Response PID */
+#define          PID_STALL11    0x0003   /* STALL */
+#define          PID_STALL      0x0002   /* STALL */
+#define          PID_BUF        0x0001   /* BUF */
+#define          PID_NAK        0x0000   /* NAK */
+
+/* Pipe Window Select Register */
+#define        PIPENM          0x0007  /* b2-0: Pipe select */
+
+/* Pipe Configuration Register */
+#define        R8A66597_TYP    0xC000  /* b15-14: Transfer type */
+#define          R8A66597_ISO   0xC000           /* Isochronous */
+#define          R8A66597_INT   0x8000           /* Interrupt */
+#define          R8A66597_BULK  0x4000           /* Bulk */
+#define        R8A66597_BFRE   0x0400  /* b10: Buffer ready interrupt mode select */
+#define        R8A66597_DBLB   0x0200  /* b9: Double buffer mode select */
+#define        R8A66597_CNTMD  0x0100  /* b8: Continuous transfer mode select */
+#define        R8A66597_SHTNAK 0x0080  /* b7: Transfer end NAK */
+#define        R8A66597_DIR    0x0010  /* b4: Transfer direction select */
+#define        R8A66597_EPNUM  0x000F  /* b3-0: Eendpoint number select */
+
+/* Pipe Buffer Configuration Register */
+#define        BUFSIZE         0x7C00  /* b14-10: Pipe buffer size */
+#define        BUFNMB          0x007F  /* b6-0: Pipe buffer number */
+#define        PIPE0BUF        256
+#define        PIPExBUF        64
+
+/* Pipe Maxpacket Size Register */
+#define        MXPS            0x07FF  /* b10-0: Maxpacket size */
+
+/* Pipe Cycle Configuration Register */
+#define        IFIS    0x1000  /* b12: Isochronous in-buffer flush mode select */
+#define        IITV    0x0007  /* b2-0: Isochronous interval */
+
+/* Pipex Control Register */
+#define        BSTS    0x8000  /* b15: Buffer status */
+#define        INBUFM  0x4000  /* b14: IN buffer monitor (Only for PIPE1 to 5) */
+#define        CSCLR   0x2000  /* b13: complete-split status clear */
+#define        CSSTS   0x1000  /* b12: complete-split status */
+#define        ATREPM  0x0400  /* b10: Auto repeat mode */
+#define        ACLRM   0x0200  /* b9: Out buffer auto clear mode */
+#define        SQCLR   0x0100  /* b8: Sequence toggle bit clear */
+#define        SQSET   0x0080  /* b7: Sequence toggle bit set */
+#define        SQMON   0x0040  /* b6: Sequence toggle bit monitor */
+#define        PBUSY   0x0020  /* b5: pipe busy */
+#define        PID     0x0003  /* b1-0: Response PID */
+
+/* PIPExTRE */
+#define        TRENB           0x0200  /* b9: Transaction counter enable */
+#define        TRCLR           0x0100  /* b8: Transaction counter clear */
+
+/* PIPExTRN */
+#define        TRNCNT          0xFFFF  /* b15-0: Transaction counter */
+
+/* DEVADDx */
+#define        UPPHUB          0x7800
+#define        HUBPORT         0x0700
+#define        USBSPD          0x00C0
+#define        RTPORT          0x0001
+
+#endif /* __LINUX_USB_R8A66597_H */