aboutsummaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/alpha/boot/bootpz.c6
-rw-r--r--arch/alpha/boot/tools/objstrip.c1
-rw-r--r--arch/alpha/kernel/osf_sys.c7
-rw-r--r--arch/alpha/kernel/srmcons.c2
-rw-r--r--arch/arm/mm/mmap.c3
-rw-r--r--arch/arm26/Kconfig3
-rw-r--r--arch/blackfin/Kconfig989
-rw-r--r--arch/blackfin/Makefile80
-rw-r--r--arch/blackfin/boot/Makefile27
-rw-r--r--arch/blackfin/defconfig1314
-rw-r--r--arch/blackfin/kernel/Makefile14
-rw-r--r--arch/blackfin/kernel/asm-offsets.c136
-rw-r--r--arch/blackfin/kernel/bfin_dma_5xx.c742
-rw-r--r--arch/blackfin/kernel/bfin_gpio.c637
-rw-r--r--arch/blackfin/kernel/bfin_ksyms.c119
-rw-r--r--arch/blackfin/kernel/dma-mapping.c183
-rw-r--r--arch/blackfin/kernel/dualcore_test.c49
-rw-r--r--arch/blackfin/kernel/entry.S94
-rw-r--r--arch/blackfin/kernel/flat.c101
-rw-r--r--arch/blackfin/kernel/init_task.c60
-rw-r--r--arch/blackfin/kernel/irqchip.c147
-rw-r--r--arch/blackfin/kernel/module.c429
-rw-r--r--arch/blackfin/kernel/process.c394
-rw-r--r--arch/blackfin/kernel/ptrace.c430
-rw-r--r--arch/blackfin/kernel/setup.c902
-rw-r--r--arch/blackfin/kernel/signal.c356
-rw-r--r--arch/blackfin/kernel/sys_bfin.c115
-rw-r--r--arch/blackfin/kernel/time.c326
-rw-r--r--arch/blackfin/kernel/traps.c649
-rw-r--r--arch/blackfin/kernel/vmlinux.lds.S228
-rw-r--r--arch/blackfin/lib/Makefile11
-rw-r--r--arch/blackfin/lib/ashldi3.c58
-rw-r--r--arch/blackfin/lib/ashrdi3.c59
-rw-r--r--arch/blackfin/lib/checksum.c140
-rw-r--r--arch/blackfin/lib/divsi3.S216
-rw-r--r--arch/blackfin/lib/gcclib.h47
-rw-r--r--arch/blackfin/lib/ins.S69
-rw-r--r--arch/blackfin/lib/lshrdi3.c72
-rw-r--r--arch/blackfin/lib/memchr.S70
-rw-r--r--arch/blackfin/lib/memcmp.S110
-rw-r--r--arch/blackfin/lib/memcpy.S142
-rw-r--r--arch/blackfin/lib/memmove.S103
-rw-r--r--arch/blackfin/lib/memset.S109
-rw-r--r--arch/blackfin/lib/modsi3.S79
-rw-r--r--arch/blackfin/lib/muldi3.c99
-rw-r--r--arch/blackfin/lib/outs.S62
-rw-r--r--arch/blackfin/lib/smulsi3_highpart.S30
-rw-r--r--arch/blackfin/lib/strcmp.c11
-rw-r--r--arch/blackfin/lib/strcpy.c11
-rw-r--r--arch/blackfin/lib/strncmp.c11
-rw-r--r--arch/blackfin/lib/strncpy.c11
-rw-r--r--arch/blackfin/lib/udivsi3.S298
-rw-r--r--arch/blackfin/lib/umodsi3.S66
-rw-r--r--arch/blackfin/lib/umulsi3_highpart.S23
-rw-r--r--arch/blackfin/mach-bf533/Kconfig92
-rw-r--r--arch/blackfin/mach-bf533/Makefile9
-rw-r--r--arch/blackfin/mach-bf533/boards/Makefile8
-rw-r--r--arch/blackfin/mach-bf533/boards/cm_bf533.c267
-rw-r--r--arch/blackfin/mach-bf533/boards/ezkit.c224
-rw-r--r--arch/blackfin/mach-bf533/boards/generic_board.c95
-rw-r--r--arch/blackfin/mach-bf533/boards/stamp.c321
-rw-r--r--arch/blackfin/mach-bf533/cpu.c161
-rw-r--r--arch/blackfin/mach-bf533/head.S774
-rw-r--r--arch/blackfin/mach-bf533/ints-priority.c65
-rw-r--r--arch/blackfin/mach-bf537/Kconfig141
-rw-r--r--arch/blackfin/mach-bf537/Makefile9
-rw-r--r--arch/blackfin/mach-bf537/boards/Makefile9
-rw-r--r--arch/blackfin/mach-bf537/boards/cm_bf537.c364
-rw-r--r--arch/blackfin/mach-bf537/boards/eth_mac.c51
-rw-r--r--arch/blackfin/mach-bf537/boards/generic_board.c445
-rw-r--r--arch/blackfin/mach-bf537/boards/led.S183
-rw-r--r--arch/blackfin/mach-bf537/boards/pnav10.c523
-rw-r--r--arch/blackfin/mach-bf537/boards/stamp.c615
-rw-r--r--arch/blackfin/mach-bf537/cpu.c161
-rw-r--r--arch/blackfin/mach-bf537/head.S602
-rw-r--r--arch/blackfin/mach-bf537/ints-priority.c74
-rw-r--r--arch/blackfin/mach-bf561/Kconfig222
-rw-r--r--arch/blackfin/mach-bf561/Makefile9
-rw-r--r--arch/blackfin/mach-bf561/boards/Makefile7
-rw-r--r--arch/blackfin/mach-bf561/boards/cm_bf561.c289
-rw-r--r--arch/blackfin/mach-bf561/boards/ezkit.c147
-rw-r--r--arch/blackfin/mach-bf561/boards/generic_board.c82
-rw-r--r--arch/blackfin/mach-bf561/coreb.c402
-rw-r--r--arch/blackfin/mach-bf561/head.S512
-rw-r--r--arch/blackfin/mach-bf561/ints-priority.c108
-rw-r--r--arch/blackfin/mach-common/Makefile12
-rw-r--r--arch/blackfin/mach-common/cache.S253
-rw-r--r--arch/blackfin/mach-common/cacheinit.S137
-rw-r--r--arch/blackfin/mach-common/cplbhdlr.S130
-rw-r--r--arch/blackfin/mach-common/cplbinfo.c211
-rw-r--r--arch/blackfin/mach-common/cplbmgr.S607
-rw-r--r--arch/blackfin/mach-common/dpmc.S418
-rw-r--r--arch/blackfin/mach-common/entry.S1207
-rw-r--r--arch/blackfin/mach-common/interrupt.S253
-rw-r--r--arch/blackfin/mach-common/ints-priority-dc.c476
-rw-r--r--arch/blackfin/mach-common/ints-priority-sc.c577
-rw-r--r--arch/blackfin/mach-common/irqpanic.c194
-rw-r--r--arch/blackfin/mach-common/lock.S204
-rw-r--r--arch/blackfin/mach-common/pm.c181
-rw-r--r--arch/blackfin/mm/Makefile5
-rw-r--r--arch/blackfin/mm/blackfin_sram.c540
-rw-r--r--arch/blackfin/mm/blackfin_sram.h38
-rw-r--r--arch/blackfin/mm/init.c208
-rw-r--r--arch/blackfin/oprofile/Kconfig29
-rw-r--r--arch/blackfin/oprofile/Makefile14
-rw-r--r--arch/blackfin/oprofile/common.c168
-rw-r--r--arch/blackfin/oprofile/op_blackfin.h98
-rw-r--r--arch/blackfin/oprofile/op_model_bf533.c161
-rw-r--r--arch/blackfin/oprofile/timer_int.c74
-rw-r--r--arch/cris/arch-v32/kernel/fasttimer.c30
-rw-r--r--arch/cris/kernel/profile.c81
-rw-r--r--arch/frv/Kconfig4
-rw-r--r--arch/frv/mm/elf-fdpic.c4
-rw-r--r--arch/h8300/Kconfig8
-rw-r--r--arch/h8300/Makefile2
-rw-r--r--arch/h8300/boot/Makefile12
-rw-r--r--arch/h8300/boot/compressed/Makefile37
-rw-r--r--arch/h8300/boot/compressed/head.S47
-rw-r--r--arch/h8300/boot/compressed/misc.c219
-rw-r--r--arch/h8300/kernel/Makefile6
-rw-r--r--arch/h8300/kernel/irq.c211
-rw-r--r--arch/h8300/kernel/setup.c3
-rw-r--r--arch/h8300/kernel/time.c54
-rw-r--r--arch/h8300/mm/kmap.c4
-rw-r--r--arch/h8300/platform/h8300h/Makefile2
-rw-r--r--arch/h8300/platform/h8300h/entry.S4
-rw-r--r--arch/h8300/platform/h8300h/generic/Makefile2
-rw-r--r--arch/h8300/platform/h8300h/ints_h8300h.c85
-rw-r--r--arch/h8300/platform/h8s/entry.S17
-rw-r--r--arch/i386/Kconfig4
-rw-r--r--arch/i386/kernel/alternative.c4
-rw-r--r--arch/i386/mm/hugetlbpage.c6
-rw-r--r--arch/i386/mm/init.c15
-rw-r--r--arch/ia64/kernel/sys_ia64.c7
-rw-r--r--arch/ia64/mm/hugetlbpage.c8
-rw-r--r--arch/ia64/mm/init.c2
-rw-r--r--arch/m68k/amiga/amiints.c2
-rw-r--r--arch/m68k/amiga/cia.c4
-rw-r--r--arch/m68k/apollo/dn_ints.c2
-rw-r--r--arch/m68k/atari/ataints.c2
-rw-r--r--arch/m68k/atari/atasound.h33
-rw-r--r--arch/m68k/kernel/ints.c4
-rw-r--r--arch/m68k/mac/macints.c2
-rw-r--r--arch/m68k/q40/q40ints.c2
-rw-r--r--arch/m68k/sun3/sun3ints.c2
-rw-r--r--arch/mips/Kconfig3
-rw-r--r--arch/mips/pmc-sierra/msp71xx/msp_serial.c165
-rw-r--r--arch/parisc/kernel/sys_parisc.c5
-rw-r--r--arch/powerpc/Kconfig13
-rw-r--r--arch/powerpc/kernel/legacy_serial.c3
-rw-r--r--arch/powerpc/mm/hugetlbpage.c24
-rw-r--r--arch/powerpc/mm/init_64.c3
-rw-r--r--arch/powerpc/platforms/cell/spufs/inode.c3
-rw-r--r--arch/s390/Kconfig3
-rw-r--r--arch/sh/Kconfig97
-rw-r--r--arch/sh/Kconfig.debug20
-rw-r--r--arch/sh/Makefile6
-rw-r--r--arch/sh/boards/hp6xx/Makefile4
-rw-r--r--arch/sh/boards/hp6xx/setup.c67
-rw-r--r--arch/sh/boards/landisk/Makefile2
-rw-r--r--arch/sh/boards/landisk/gio.c167
-rw-r--r--arch/sh/boards/landisk/io.c250
-rw-r--r--arch/sh/boards/landisk/irq.c83
-rw-r--r--arch/sh/boards/landisk/landisk_pwb.c346
-rw-r--r--arch/sh/boards/landisk/psw.c143
-rw-r--r--arch/sh/boards/landisk/rtc.c91
-rw-r--r--arch/sh/boards/landisk/setup.c163
-rw-r--r--arch/sh/boards/lboxre2/Makefile5
-rw-r--r--arch/sh/boards/lboxre2/irq.c31
-rw-r--r--arch/sh/boards/lboxre2/setup.c85
-rw-r--r--arch/sh/boards/renesas/r7780rp/Kconfig18
-rw-r--r--arch/sh/boards/renesas/r7780rp/Makefile6
-rw-r--r--arch/sh/boards/renesas/r7780rp/irq-r7780rp.c21
-rw-r--r--arch/sh/boards/renesas/r7780rp/irq-r7785rp.c29
-rw-r--r--arch/sh/boards/renesas/r7780rp/irq.c25
-rw-r--r--arch/sh/boards/renesas/r7780rp/setup.c78
-rw-r--r--arch/sh/boards/se/770x/io.c2
-rw-r--r--arch/sh/boards/se/770x/irq.c57
-rw-r--r--arch/sh/boards/se/770x/setup.c30
-rw-r--r--arch/sh/boards/se/7722/Makefile10
-rw-r--r--arch/sh/boards/se/7722/irq.c101
-rw-r--r--arch/sh/boards/se/7722/setup.c148
-rw-r--r--arch/sh/boards/se/7751/setup.c148
-rw-r--r--arch/sh/boards/se/7780/Makefile10
-rw-r--r--arch/sh/boards/se/7780/irq.c89
-rw-r--r--arch/sh/boards/se/7780/setup.c122
-rw-r--r--arch/sh/configs/lboxre2_defconfig1271
-rw-r--r--arch/sh/configs/r7780rp_defconfig108
-rw-r--r--arch/sh/configs/r7785rp_defconfig1334
-rw-r--r--arch/sh/configs/se7705_defconfig106
-rw-r--r--arch/sh/configs/se7712_defconfig1088
-rw-r--r--arch/sh/configs/se7722_defconfig980
-rw-r--r--arch/sh/configs/se7780_defconfig1309
-rw-r--r--arch/sh/drivers/Kconfig10
-rw-r--r--arch/sh/drivers/heartbeat.c13
-rw-r--r--arch/sh/drivers/pci/Makefile5
-rw-r--r--arch/sh/drivers/pci/fixups-lboxre2.c41
-rw-r--r--arch/sh/drivers/pci/fixups-se7780.c60
-rw-r--r--arch/sh/drivers/pci/ops-landisk.c4
-rw-r--r--arch/sh/drivers/pci/ops-lboxre2.c63
-rw-r--r--arch/sh/drivers/pci/ops-r7780rp.c27
-rw-r--r--arch/sh/drivers/pci/ops-se7780.c96
-rw-r--r--arch/sh/drivers/pci/ops-sh4.c6
-rw-r--r--arch/sh/drivers/pci/pci-sh4.h2
-rw-r--r--arch/sh/drivers/pci/pci-sh7751.c15
-rw-r--r--arch/sh/drivers/pci/pci-sh7780.c45
-rw-r--r--arch/sh/drivers/pci/pci-sh7780.h19
-rw-r--r--arch/sh/kernel/Makefile1
-rw-r--r--arch/sh/kernel/cf-enabler.c28
-rw-r--r--arch/sh/kernel/cpu/clock.c102
-rw-r--r--arch/sh/kernel/cpu/init.c19
-rw-r--r--arch/sh/kernel/cpu/irq/Makefile2
-rw-r--r--arch/sh/kernel/cpu/irq/intc2.c3
-rw-r--r--arch/sh/kernel/cpu/irq/pint.c56
-rw-r--r--arch/sh/kernel/cpu/sh3/Makefile1
-rw-r--r--arch/sh/kernel/cpu/sh3/probe.c3
-rw-r--r--arch/sh/kernel/cpu/sh3/setup-sh7705.c54
-rw-r--r--arch/sh/kernel/cpu/sh3/setup-sh7709.c29
-rw-r--r--arch/sh/kernel/cpu/sh3/setup-sh7710.c60
-rw-r--r--arch/sh/kernel/cpu/sh4/clock-sh4-202.c3
-rw-r--r--arch/sh/kernel/cpu/sh4/probe.c8
-rw-r--r--arch/sh/kernel/cpu/sh4a/Makefile4
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7722.c600
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7785.c162
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7785.c103
-rw-r--r--arch/sh/kernel/crash_dump.c46
-rw-r--r--arch/sh/kernel/irq.c5
-rw-r--r--arch/sh/kernel/kgdb_stub.c490
-rw-r--r--arch/sh/kernel/machine_kexec.c29
-rw-r--r--arch/sh/kernel/process.c14
-rw-r--r--arch/sh/kernel/setup.c267
-rw-r--r--arch/sh/kernel/sh_ksyms.c1
-rw-r--r--arch/sh/kernel/timers/timer-tmu.c4
-rw-r--r--arch/sh/kernel/traps.c73
-rw-r--r--arch/sh/kernel/vmlinux.lds.S47
-rw-r--r--arch/sh/lib/Makefile4
-rw-r--r--arch/sh/lib/udivdi3.c16
-rw-r--r--arch/sh/mm/Kconfig20
-rw-r--r--arch/sh/mm/fault.c39
-rw-r--r--arch/sh/mm/init.c197
-rw-r--r--arch/sh/tools/mach-types2
-rw-r--r--arch/sparc64/Kconfig4
-rw-r--r--arch/sparc64/mm/hugetlbpage.c6
-rw-r--r--arch/sparc64/mm/init.c24
-rw-r--r--arch/sparc64/mm/tsb.c5
-rw-r--r--arch/um/drivers/chan_kern.c1
-rw-r--r--arch/um/drivers/chan_user.c14
-rw-r--r--arch/um/drivers/cow_sys.h18
-rw-r--r--arch/um/drivers/daemon_user.c31
-rw-r--r--arch/um/drivers/fd.c1
-rw-r--r--arch/um/drivers/harddog_user.c1
-rw-r--r--arch/um/drivers/line.c1
-rw-r--r--arch/um/drivers/mcast_user.c16
-rw-r--r--arch/um/drivers/mconsole_kern.c1
-rw-r--r--arch/um/drivers/mconsole_user.c1
-rw-r--r--arch/um/drivers/mmapper_kern.c1
-rw-r--r--arch/um/drivers/net_kern.c162
-rw-r--r--arch/um/drivers/net_user.c4
-rw-r--r--arch/um/drivers/pcap_user.c38
-rw-r--r--arch/um/drivers/port_user.c1
-rw-r--r--arch/um/drivers/pty.c2
-rw-r--r--arch/um/drivers/slip_user.c7
-rw-r--r--arch/um/drivers/slirp_user.c4
-rw-r--r--arch/um/drivers/ssl.c5
-rw-r--r--arch/um/drivers/stdio_console.c5
-rw-r--r--arch/um/drivers/tty.c1
-rw-r--r--arch/um/drivers/ubd_kern.c351
-rw-r--r--arch/um/drivers/ubd_user.c16
-rw-r--r--arch/um/drivers/xterm.c1
-rw-r--r--arch/um/include/arch.h15
-rw-r--r--arch/um/include/as-layout.h35
-rw-r--r--arch/um/include/common-offsets.h2
-rw-r--r--arch/um/include/kern_util.h13
-rw-r--r--arch/um/include/net_kern.h2
-rw-r--r--arch/um/include/net_user.h2
-rw-r--r--arch/um/include/os.h17
-rw-r--r--arch/um/include/skas/mode_kern_skas.h2
-rw-r--r--arch/um/include/tlb.h8
-rw-r--r--arch/um/include/tt/uaccess-tt.h2
-rw-r--r--arch/um/include/um_malloc.h1
-rw-r--r--arch/um/include/user.h29
-rw-r--r--arch/um/include/user_util.h69
-rw-r--r--arch/um/kernel/exec.c2
-rw-r--r--arch/um/kernel/init_task.c1
-rw-r--r--arch/um/kernel/initrd.c33
-rw-r--r--arch/um/kernel/irq.c16
-rw-r--r--arch/um/kernel/ksyms.c2
-rw-r--r--arch/um/kernel/mem.c4
-rw-r--r--arch/um/kernel/physmem.c230
-rw-r--r--arch/um/kernel/process.c125
-rw-r--r--arch/um/kernel/reboot.c1
-rw-r--r--arch/um/kernel/signal.c1
-rw-r--r--arch/um/kernel/skas/exec.c12
-rw-r--r--arch/um/kernel/skas/process.c2
-rw-r--r--arch/um/kernel/skas/tlb.c87
-rw-r--r--arch/um/kernel/smp.c28
-rw-r--r--arch/um/kernel/syscall.c1
-rw-r--r--arch/um/kernel/sysrq.c1
-rw-r--r--arch/um/kernel/time.c15
-rw-r--r--arch/um/kernel/tlb.c226
-rw-r--r--arch/um/kernel/trap.c50
-rw-r--r--arch/um/kernel/tt/exec_kern.c1
-rw-r--r--arch/um/kernel/tt/exec_user.c1
-rw-r--r--arch/um/kernel/tt/gdb.c3
-rw-r--r--arch/um/kernel/tt/include/mode_kern-tt.h52
-rw-r--r--arch/um/kernel/tt/mem.c1
-rw-r--r--arch/um/kernel/tt/mem_user.c1
-rw-r--r--arch/um/kernel/tt/process_kern.c4
-rw-r--r--arch/um/kernel/tt/ptproxy/proxy.c6
-rw-r--r--arch/um/kernel/tt/ptproxy/ptrace.c1
-rw-r--r--arch/um/kernel/tt/ptproxy/sysdep.c1
-rw-r--r--arch/um/kernel/tt/ptproxy/wait.c1
-rw-r--r--arch/um/kernel/tt/syscall_user.c1
-rw-r--r--arch/um/kernel/tt/tlb.c1
-rw-r--r--arch/um/kernel/tt/tracer.c1
-rw-r--r--arch/um/kernel/tt/trap_user.c1
-rw-r--r--arch/um/kernel/tt/uaccess_user.c1
-rw-r--r--arch/um/kernel/um_arch.c84
-rw-r--r--arch/um/os-Linux/aio.c61
-rw-r--r--arch/um/os-Linux/drivers/ethertap_user.c66
-rw-r--r--arch/um/os-Linux/drivers/tuntap_user.c44
-rw-r--r--arch/um/os-Linux/file.c47
-rw-r--r--arch/um/os-Linux/helper.c31
-rw-r--r--arch/um/os-Linux/irq.c1
-rw-r--r--arch/um/os-Linux/main.c23
-rw-r--r--arch/um/os-Linux/mem.c15
-rw-r--r--arch/um/os-Linux/process.c45
-rw-r--r--arch/um/os-Linux/sigio.c164
-rw-r--r--arch/um/os-Linux/signal.c1
-rw-r--r--arch/um/os-Linux/skas/mem.c75
-rw-r--r--arch/um/os-Linux/skas/process.c190
-rw-r--r--arch/um/os-Linux/skas/trap.c49
-rw-r--r--arch/um/os-Linux/start_up.c173
-rw-r--r--arch/um/os-Linux/sys-i386/tls.c2
-rw-r--r--arch/um/os-Linux/time.c1
-rw-r--r--arch/um/os-Linux/trap.c1
-rw-r--r--arch/um/os-Linux/tt.c4
-rw-r--r--arch/um/os-Linux/tty_log.c28
-rw-r--r--arch/um/os-Linux/util.c26
-rw-r--r--arch/um/sys-i386/bugs.c78
-rw-r--r--arch/um/sys-i386/fault.c18
-rw-r--r--arch/um/sys-i386/ptrace_user.c17
-rw-r--r--arch/um/sys-i386/signal.c84
-rw-r--r--arch/um/sys-i386/tls.c11
-rw-r--r--arch/um/sys-i386/user-offsets.c10
-rw-r--r--arch/um/sys-ppc/sigcontext.c1
-rw-r--r--arch/um/sys-x86_64/bugs.c104
-rw-r--r--arch/um/sys-x86_64/fault.c30
-rw-r--r--arch/um/sys-x86_64/signal.c32
-rw-r--r--arch/um/sys-x86_64/user-offsets.c6
-rw-r--r--arch/v850/Kconfig4
-rw-r--r--arch/v850/kernel/time.c75
-rw-r--r--arch/x86_64/kernel/e820.c26
-rw-r--r--arch/x86_64/kernel/machine_kexec.c16
-rw-r--r--arch/x86_64/kernel/setup.c9
-rw-r--r--arch/x86_64/kernel/smp.c2
-rw-r--r--arch/x86_64/kernel/sys_x86_64.c3
-rw-r--r--arch/x86_64/mm/init.c31
-rw-r--r--arch/x86_64/mm/ioremap.c9
-rw-r--r--arch/x86_64/mm/pageattr.c16
-rw-r--r--arch/xtensa/platform-iss/network.c2
361 files changed, 35444 insertions, 4421 deletions
diff --git a/arch/alpha/boot/bootpz.c b/arch/alpha/boot/bootpz.c
index 4307bde80a3..1036b515e20 100644
--- a/arch/alpha/boot/bootpz.c
+++ b/arch/alpha/boot/bootpz.c
@@ -467,3 +467,9 @@ start_kernel(void)
#endif
runkernel();
}
+
+ /* dummy function, should never be called. */
+void *__kmalloc(size_t size, gfp_t flags)
+{
+ return (void *)NULL;
+}
diff --git a/arch/alpha/boot/tools/objstrip.c b/arch/alpha/boot/tools/objstrip.c
index 67beb1b45e4..96154e768a2 100644
--- a/arch/alpha/boot/tools/objstrip.c
+++ b/arch/alpha/boot/tools/objstrip.c
@@ -25,7 +25,6 @@
#include <linux/a.out.h>
#include <linux/coff.h>
#include <linux/param.h>
-#include <linux/string.h>
#ifdef __ELF__
# include <linux/elf.h>
#endif
diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c
index be133f1f75a..ea405f5713c 100644
--- a/arch/alpha/kernel/osf_sys.c
+++ b/arch/alpha/kernel/osf_sys.c
@@ -93,7 +93,6 @@ osf_set_program_attributes(unsigned long text_start, unsigned long text_len,
* offset differences aren't the same as "d_reclen").
*/
#define NAME_OFFSET offsetof (struct osf_dirent, d_name)
-#define ROUND_UP(x) (((x)+3) & ~3)
struct osf_dirent {
unsigned int d_ino;
@@ -115,7 +114,7 @@ osf_filldir(void *__buf, const char *name, int namlen, loff_t offset,
{
struct osf_dirent __user *dirent;
struct osf_dirent_callback *buf = (struct osf_dirent_callback *) __buf;
- unsigned int reclen = ROUND_UP(NAME_OFFSET + namlen + 1);
+ unsigned int reclen = ALIGN(NAME_OFFSET + namlen + 1, sizeof(u32));
unsigned int d_ino;
buf->error = -EINVAL; /* only used if we fail */
@@ -174,7 +173,6 @@ osf_getdirentries(unsigned int fd, struct osf_dirent __user *dirent,
return error;
}
-#undef ROUND_UP
#undef NAME_OFFSET
asmlinkage unsigned long
@@ -1267,6 +1265,9 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
if (len > limit)
return -ENOMEM;
+ if (flags & MAP_FIXED)
+ return addr;
+
/* First, see if the given suggestion fits.
The OSF/1 loader (/sbin/loader) relies on us returning an
diff --git a/arch/alpha/kernel/srmcons.c b/arch/alpha/kernel/srmcons.c
index 75692320386..85a821aaceb 100644
--- a/arch/alpha/kernel/srmcons.c
+++ b/arch/alpha/kernel/srmcons.c
@@ -164,9 +164,9 @@ srmcons_get_private_struct(struct srmcons_private **ps)
int retval = 0;
if (srmconsp == NULL) {
+ srmconsp = kmalloc(sizeof(*srmconsp), GFP_KERNEL);
spin_lock_irqsave(&srmconsp_lock, flags);
- srmconsp = kmalloc(sizeof(*srmconsp), GFP_KERNEL);
if (srmconsp == NULL)
retval = -ENOMEM;
else {
diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c
index b0b5f469407..2c4c2422cd1 100644
--- a/arch/arm/mm/mmap.c
+++ b/arch/arm/mm/mmap.c
@@ -49,8 +49,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
#endif
/*
- * We should enforce the MAP_FIXED case. However, currently
- * the generic kernel code doesn't allow us to handle this.
+ * We enforce the MAP_FIXED case.
*/
if (flags & MAP_FIXED) {
if (aliasing && flags & MAP_SHARED && addr & (SHMLBA - 1))
diff --git a/arch/arm26/Kconfig b/arch/arm26/Kconfig
index 989113dce41..20688bc13e9 100644
--- a/arch/arm26/Kconfig
+++ b/arch/arm26/Kconfig
@@ -57,9 +57,6 @@ config GENERIC_CALIBRATE_DELAY
bool
default y
-config GENERIC_BUST_SPINLOCK
- bool
-
config ZONE_DMA
bool
default y
diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig
new file mode 100644
index 00000000000..1a493050932
--- /dev/null
+++ b/arch/blackfin/Kconfig
@@ -0,0 +1,989 @@
+#
+# For a description of the syntax of this configuration file,
+# see Documentation/kbuild/kconfig-language.txt.
+#
+
+mainmenu "uClinux/Blackfin (w/o MMU) Kernel Configuration"
+
+config MMU
+ bool
+ default n
+
+config FPU
+ bool
+ default n
+
+config RWSEM_GENERIC_SPINLOCK
+ bool
+ default y
+
+config RWSEM_XCHGADD_ALGORITHM
+ bool
+ default n
+
+config BLACKFIN
+ bool
+ default y
+
+config BFIN
+ bool
+ default y
+
+config SEMAPHORE_SLEEPERS
+ bool
+ default y
+
+config GENERIC_FIND_NEXT_BIT
+ bool
+ default y
+
+config GENERIC_HWEIGHT
+ bool
+ default y
+
+config GENERIC_HARDIRQS
+ bool
+ default y
+
+config GENERIC_IRQ_PROBE
+ bool
+ default y
+
+config GENERIC_TIME
+ bool
+ default n
+
+config GENERIC_CALIBRATE_DELAY
+ bool
+ default y
+
+config FORCE_MAX_ZONEORDER
+ int
+ default "14"
+
+config GENERIC_CALIBRATE_DELAY
+ bool
+ default y
+
+config IRQCHIP_DEMUX_GPIO
+ bool
+ default y
+
+source "init/Kconfig"
+source "kernel/Kconfig.preempt"
+
+menu "Blackfin Processor Options"
+
+comment "Processor and Board Settings"
+
+choice
+ prompt "CPU"
+ default BF533
+
+config BF531
+ bool "BF531"
+ help
+ BF531 Processor Support.
+
+config BF532
+ bool "BF532"
+ help
+ BF532 Processor Support.
+
+config BF533
+ bool "BF533"
+ help
+ BF533 Processor Support.
+
+config BF534
+ bool "BF534"
+ help
+ BF534 Processor Support.
+
+config BF536
+ bool "BF536"
+ help
+ BF536 Processor Support.
+
+config BF537
+ bool "BF537"
+ help
+ BF537 Processor Support.
+
+config BF561
+ bool "BF561"
+ help
+ Not Supported Yet - Work in progress - BF561 Processor Support.
+
+endchoice
+
+choice
+ prompt "Silicon Rev"
+ default BF_REV_0_2 if BF537
+ default BF_REV_0_3 if BF533
+
+config BF_REV_0_2
+ bool "0.2"
+ depends on (BF537 || BF536 || BF534)
+
+config BF_REV_0_3
+ bool "0.3"
+ depends on (BF561 || BF537 || BF536 || BF534 || BF533 || BF532 || BF531)
+
+config BF_REV_0_4
+ bool "0.4"
+ depends on (BF561 || BF533 || BF532 || BF531)
+
+config BF_REV_0_5
+ bool "0.5"
+ depends on (BF561 || BF533 || BF532 || BF531)
+
+endchoice
+
+config BFIN_DUAL_CORE
+ bool
+ depends on (BF561)
+ default y
+
+config BFIN_SINGLE_CORE
+ bool
+ depends on !BFIN_DUAL_CORE
+ default y
+
+choice
+ prompt "System type"
+ default BFIN533_STAMP
+ help
+ Do NOT change the board here. Please use the top level
+ configuration to ensure that all the other settings are
+ correct.
+
+config BFIN533_EZKIT
+ bool "BF533-EZKIT"
+ depends on (BF533 || BF532 || BF531)
+ help
+ BF533-EZKIT-LITE board Support.
+
+config BFIN533_STAMP
+ bool "BF533-STAMP"
+ depends on (BF533 || BF532 || BF531)
+ help
+ BF533-STAMP board Support.
+
+config BFIN537_STAMP
+ bool "BF537-STAMP"
+ depends on (BF537 || BF536 || BF534)
+ help
+ BF537-STAMP board Support.
+
+config BFIN533_BLUETECHNIX_CM
+ bool "Bluetechnix CM-BF533"
+ depends on (BF533)
+ help
+ CM-BF533 support for EVAL- and DEV-Board.
+
+config BFIN537_BLUETECHNIX_CM
+ bool "Bluetechnix CM-BF537"
+ depends on (BF537)
+ help
+ CM-BF537 support for EVAL- and DEV-Board.
+
+config BFIN561_BLUETECHNIX_CM
+ bool "BF561-CM"
+ depends on (BF561)
+ help
+ CM-BF561 support for EVAL- and DEV-Board.
+
+config BFIN561_EZKIT
+ bool "BF561-EZKIT"
+ depends on (BF561)
+ help
+ BF561-EZKIT-LITE board Support.
+
+config PNAV10
+ bool "PNAV 1.0 board"
+ depends on (BF537)
+ help
+ PNAV 1.0 board Support.
+
+config GENERIC_BOARD
+ bool "Custom"
+ depends on (BF537 || BF536 \
+ || BF534 || BF561 || BF535 || BF533 || BF532 || BF531)
+ help
+ GENERIC or Custom board Support.
+
+endchoice
+
+config MEM_GENERIC_BOARD
+ bool
+ depends on GENERIC_BOARD
+ default y
+
+config MEM_MT48LC64M4A2FB_7E
+ bool
+ depends on (BFIN533_STAMP)
+ default y
+
+config MEM_MT48LC16M16A2TG_75
+ bool
+ depends on (BFIN533_EZKIT || BFIN561_EZKIT \
+ || BFIN533_BLUETECHNIX_CM || BFIN537_BLUETECHNIX_CM)
+ default y
+
+config MEM_MT48LC32M8A2_75
+ bool
+ depends on (BFIN537_STAMP || PNAV10)
+ default y
+
+config MEM_MT48LC8M32B2B5_7
+ bool
+ depends on (BFIN561_BLUETECHNIX_CM)
+ default y
+
+config BFIN_SHARED_FLASH_ENET
+ bool
+ depends on (BFIN533_STAMP)
+ default y
+
+source "arch/blackfin/mach-bf533/Kconfig"
+source "arch/blackfin/mach-bf561/Kconfig"
+source "arch/blackfin/mach-bf537/Kconfig"
+
+menu "Board customizations"
+
+config CMDLINE_BOOL
+ bool "Default bootloader kernel arguments"
+
+config CMDLINE
+ string "Initial kernel command string"
+ depends on CMDLINE_BOOL
+ default "console=ttyBF0,57600"
+ help
+ If you don't have a boot loader capable of passing a command line string
+ to the kernel, you may specify one here. As a minimum, you should specify
+ the memory size and the root device (e.g., mem=8M, root=/dev/nfs).
+
+comment "Board Setup"
+
+config CLKIN_HZ
+ int "Crystal Frequency in Hz"
+ default "11059200" if BFIN533_STAMP
+ default "27000000" if BFIN533_EZKIT
+ default "25000000" if BFIN537_STAMP
+ default "30000000" if BFIN561_EZKIT
+ default "24576000" if PNAV10
+ help
+ The frequency of CLKIN crystal oscillator on the board in Hz.
+
+config MEM_SIZE
+ int "SDRAM Memory Size in MBytes"
+ default 32 if BFIN533_EZKIT
+ default 64 if BFIN537_STAMP
+ default 64 if BFIN561_EZKIT
+ default 128 if BFIN533_STAMP
+ default 64 if PNAV10
+
+config MEM_ADD_WIDTH
+ int "SDRAM Memory Address Width"
+ default 9 if BFIN533_EZKIT
+ default 9 if BFIN561_EZKIT
+ default 10 if BFIN537_STAMP
+ default 11 if BFIN533_STAMP
+ default 10 if PNAV10
+
+config ENET_FLASH_PIN
+ int "PF port/pin used for flash and ethernet sharing"
+ depends on (BFIN533_STAMP)
+ default 0
+ help
+ PF port/pin used for flash and ethernet sharing to allow other PF
+ pins to be used on other platforms without having to touch common
+ code.
+ For example: PF0 --> 0,PF1 --> 1,PF2 --> 2, etc.
+
+config BOOT_LOAD
+ hex "Kernel load address for booting"
+ default "0x1000"
+ help
+ This option allows you to set the load address of the kernel.
+ This can be useful if you are on a board which has a small amount
+ of memory or you wish to reserve some memory at the beginning of
+ the address space.
+
+ Note that you generally want to keep this value at or above 4k
+ (0x1000) as this will allow the kernel to capture NULL pointer
+ references.
+
+comment "LED Status Indicators"
+ depends on (BFIN533_STAMP || BFIN533_BLUETECHNIX_CM)
+
+config BFIN_ALIVE_LED
+ bool "Enable Board Alive"
+ depends on (BFIN533_STAMP || BFIN533_BLUETECHNIX_CM)
+ default n
+ help
+ Blink the LEDs you select when the kernel is running. Helps detect
+ a hung kernel.
+
+config BFIN_ALIVE_LED_NUM
+ int "LED"
+ depends on BFIN_ALIVE_LED
+ range 1 3 if BFIN533_STAMP
+ default "3" if BFIN533_STAMP
+ help
+ Select the LED (marked on the board) for you to blink.
+
+config BFIN_IDLE_LED
+ bool "Enable System Load/Idle LED"
+ depends on (BFIN533_STAMP || BFIN533_BLUETECHNIX_CM)
+ default n
+ help
+ Blinks the LED you select when to determine kernel load.
+
+config BFIN_IDLE_LED_NUM
+ int "LED"
+ depends on BFIN_IDLE_LED
+ range 1 3 if BFIN533_STAMP
+ default "2" if BFIN533_STAMP
+ help
+ Select the LED (marked on the board) for you to blink.
+
+#
+# Sorry - but you need to put the hex address here -
+#
+
+# Flag Data register
+config BFIN_ALIVE_LED_PORT
+ hex
+ default 0xFFC00700 if (BFIN533_STAMP)
+
+# Peripheral Flag Direction Register
+config BFIN_ALIVE_LED_DPORT
+ hex
+ default 0xFFC00730 if (BFIN533_STAMP)
+
+config BFIN_ALIVE_LED_PIN
+ hex
+ default 0x04 if (BFIN533_STAMP && BFIN_ALIVE_LED_NUM = 1)
+ default 0x08 if (BFIN533_STAMP && BFIN_ALIVE_LED_NUM = 2)
+ default 0x10 if (BFIN533_STAMP && BFIN_ALIVE_LED_NUM = 3)
+
+config BFIN_IDLE_LED_PORT
+ hex
+ default 0xFFC00700 if (BFIN533_STAMP)
+
+# Peripheral Flag Direction Register
+config BFIN_IDLE_LED_DPORT
+ hex
+ default 0xFFC00730 if (BFIN533_STAMP)
+
+config BFIN_IDLE_LED_PIN
+ hex
+ default 0x04 if (BFIN533_STAMP && BFIN_IDLE_LED_NUM = 1)
+ default 0x08 if (BFIN533_STAMP && BFIN_IDLE_LED_NUM = 2)
+ default 0x10 if (BFIN533_STAMP && BFIN_IDLE_LED_NUM = 3)
+
+comment "Console UART Setup"
+
+choice
+ prompt "Baud Rate"
+ default BAUD_57600
+config BAUD_9600
+ bool "9600"
+config BAUD_19200
+ bool "19200"
+config BAUD_38400
+ bool "38400"
+config BAUD_57600
+ bool "57600"
+config BAUD_115200
+ bool "115200"
+endchoice
+
+choice
+ prompt "Parity"
+ default BAUD_NO_PARITY
+config BAUD_NO_PARITY
+ bool "No Parity"
+config BAUD_PARITY
+ bool "Parity"
+endchoice
+
+choice
+ prompt "Stop Bits"
+ default BAUD_1_STOPBIT
+config BAUD_1_STOPBIT
+ bool "1"
+config BAUD_2_STOPBIT
+ bool "2"
+endchoice
+
+endmenu
+
+
+menu "Blackfin Kernel Optimizations"
+
+comment "Timer Tick"
+
+source kernel/Kconfig.hz
+
+comment "Memory Optimizations"
+
+config I_ENTRY_L1
+ bool "Locate interrupt entry code in L1 Memory"
+ default y
+ help
+ If enabled interrupt entry code (STORE/RESTORE CONTEXT) is linked
+ into L1 instruction memory.(less latency)
+
+config EXCPT_IRQ_SYSC_L1
+ bool "Locate entire ASM lowlevel excepetion / interrupt - Syscall and CPLB handler code in L1 Memory"
+ default y
+ help
+ If enabled entire ASM lowlevel exception and interrupt entry code (STORE/RESTORE CONTEXT) is linked
+ into L1 instruction memory.(less latency)
+
+config DO_IRQ_L1
+ bool "Locate frequently called do_irq dispatcher function in L1 Memory"
+ default y
+ help
+ If enabled frequently called do_irq dispatcher function is linked
+ into L1 instruction memory.(less latency)
+
+config CORE_TIMER_IRQ_L1
+ bool "Locate frequently called timer_interrupt() function in L1 Memory"
+ default y
+ help
+ If enabled frequently called timer_interrupt() function is linked
+ into L1 instruction memory.(less latency)
+
+config IDLE_L1
+ bool "Locate frequently idle function in L1 Memory"
+ default y
+ help
+ If enabled frequently called idle function is linked
+ into L1 instruction memory.(less latency)
+
+config SCHEDULE_L1
+ bool "Locate kernel schedule function in L1 Memory"
+ default y
+ help
+ If enabled frequently called kernel schedule is linked
+ into L1 instruction memory.(less latency)
+
+config ARITHMETIC_OPS_L1
+ bool "Locate kernel owned arithmetic functions in L1 Memory"
+ default y
+ help
+ If enabled arithmetic functions are linked
+ into L1 instruction memory.(less latency)
+
+config ACCESS_OK_L1
+ bool "Locate access_ok function in L1 Memory"
+ default y
+ help
+ If enabled access_ok function is linked
+ into L1 instruction memory.(less latency)
+
+config MEMSET_L1
+ bool "Locate memset function in L1 Memory"
+ default y
+ help
+ If enabled memset function is linked
+ into L1 instruction memory.(less latency)
+
+config MEMCPY_L1
+ bool "Locate memcpy function in L1 Memory"
+ default y
+ help
+ If enabled memcpy function is linked
+ into L1 instruction memory.(less latency)
+
+config SYS_BFIN_SPINLOCK_L1
+ bool "Locate sys_bfin_spinlock function in L1 Memory"
+ default y
+ help
+ If enabled sys_bfin_spinlock function is linked
+ into L1 instruction memory.(less latency)
+
+config IP_CHECKSUM_L1
+ bool "Locate IP Checksum function in L1 Memory"
+ default n
+ help
+ If enabled IP Checksum function is linked
+ into L1 instruction memory.(less latency)
+
+config CACHELINE_ALIGNED_L1
+ bool "Locate cacheline_aligned data to L1 Data Memory"
+ default y
+ depends on !BF531
+ help
+ If enabled cacheline_anligned data is linked
+ into L1 data memory.(less latency)
+
+config SYSCALL_TAB_L1
+ bool "Locate Syscall Table L1 Data Memory"
+ default n
+ depends on !BF531
+ help
+ If enabled the Syscall LUT is linked
+ into L1 data memory.(less latency)
+
+config CPLB_SWITCH_TAB_L1
+ bool "Locate CPLB Switch Tables L1 Data Memory"
+ default n
+ depends on !BF531
+ help
+ If enabled the CPLB Switch Tables are linked
+ into L1 data memory.(less latency)
+
+endmenu
+
+
+choice
+ prompt "Kernel executes from"
+ help
+ Choose the memory type that the kernel will be running in.
+
+config RAMKERNEL
+ bool "RAM"
+ help
+ The kernel will be resident in RAM when running.
+
+config ROMKERNEL
+ bool "ROM"
+ help
+ The kernel will be resident in FLASH/ROM when running.
+
+endchoice
+
+source "mm/Kconfig"
+
+config LARGE_ALLOCS
+ bool "Allow allocating large blocks (> 1MB) of memory"
+ help
+ Allow the slab memory allocator to keep chains for very large
+ memory sizes - upto 32MB. You may need this if your system has
+ a lot of RAM, and you need to able to allocate very large
+ contiguous chunks. If unsure, say N.
+
+config BFIN_DMA_5XX
+ bool "Enable DMA Support"
+ depends on (BF533 || BF532 || BF531 || BF537 || BF536 || BF534 || BF561)
+ default y
+ help
+ DMA driver for BF5xx.
+
+choice
+ prompt "Uncached SDRAM region"
+ default DMA_UNCACHED_1M
+ depends BFIN_DMA_5XX
+config DMA_UNCACHED_2M
+ bool "Enable 2M DMA region"
+config DMA_UNCACHED_1M
+ bool "Enable 1M DMA region"
+config DMA_UNCACHED_NONE
+ bool "Disable DMA region"
+endchoice
+
+
+comment "Cache Support"
+config BLKFIN_CACHE
+ bool "Enable ICACHE"
+config BLKFIN_DCACHE
+ bool "Enable DCACHE"
+config BLKFIN_DCACHE_BANKA
+ bool "Enable only 16k BankA DCACHE - BankB is SRAM"
+ depends on BLKFIN_DCACHE && !BF531
+ default n
+config BLKFIN_CACHE_LOCK
+ bool "Enable Cache Locking"
+
+choice
+ prompt "Policy"
+ depends on BLKFIN_DCACHE
+ default BLKFIN_WB
+config BLKFIN_WB
+ bool "Write back"
+ help
+ Write Back Policy:
+ Cached data will be written back to SDRAM only when needed.
+ This can give a nice increase in performance, but beware of
+ broken drivers that do not properly invalidate/flush their
+ cache.
+
+ Write Through Policy:
+ Cached data will always be written back to SDRAM when the
+ cache is updated. This is a completely safe setting, but
+ performance is worse than Write Back.
+
+ If you are unsure of the options and you want to be safe,
+ then go with Write Through.
+
+config BLKFIN_WT
+ bool "Write through"
+ help
+ Write Back Policy:
+ Cached data will be written back to SDRAM only when needed.
+ This can give a nice increase in performance, but beware of
+ broken drivers that do not properly invalidate/flush their
+ cache.
+
+ Write Through Policy:
+ Cached data will always be written back to SDRAM when the
+ cache is updated. This is a completely safe setting, but
+ performance is worse than Write Back.
+
+ If you are unsure of the options and you want to be safe,
+ then go with Write Through.
+
+endchoice
+
+config L1_MAX_PIECE
+ int "Set the max L1 SRAM pieces"
+ default 16
+ help
+ Set the max memory pieces for the L1 SRAM allocation algorithm.
+ Min value is 16. Max value is 1024.
+
+menu "Clock Settings"
+
+
+config BFIN_KERNEL_CLOCK
+ bool "Re-program Clocks while Kernel boots?"
+ default n
+ help
+ This option decides if kernel clocks are re-programed from the
+ bootloader settings. If the clocks are not set, the SDRAM settings
+ are also not changed, and the Bootloader does 100% of the hardware
+ configuration.
+
+config VCO_MULT
+ int "VCO Multiplier"
+ depends on BFIN_KERNEL_CLOCK
+ default "22" if BFIN533_EZKIT
+ default "45" if BFIN533_STAMP
+ default "20" if BFIN537_STAMP
+ default "22" if BFIN533_BLUETECHNIX_CM
+ default "20" if BFIN537_BLUETECHNIX_CM
+ default "20" if BFIN561_BLUETECHNIX_CM
+ default "20" if BFIN561_EZKIT
+
+config CCLK_DIV
+ int "Core Clock Divider"
+ depends on BFIN_KERNEL_CLOCK
+ default 1 if BFIN533_EZKIT
+ default 1 if BFIN533_STAMP
+ default 1 if BFIN537_STAMP
+ default 1 if BFIN533_BLUETECHNIX_CM
+ default 1 if BFIN537_BLUETECHNIX_CM
+ default 1 if BFIN561_BLUETECHNIX_CM
+ default 1 if BFIN561_EZKIT
+
+config SCLK_DIV
+ int "System Clock Divider"
+ depends on BFIN_KERNEL_CLOCK
+ default 5 if BFIN533_EZKIT
+ default 5 if BFIN533_STAMP
+ default 4 if BFIN537_STAMP
+ default 5 if BFIN533_BLUETECHNIX_CM
+ default 4 if BFIN537_BLUETECHNIX_CM
+ default 4 if BFIN561_BLUETECHNIX_CM
+ default 5 if BFIN561_EZKIT
+
+config CLKIN_HALF
+ bool "Half ClockIn"
+ depends on BFIN_KERNEL_CLOCK
+ default n
+
+config PLL_BYPASS
+ bool "Bypass PLL"
+ depends on BFIN_KERNEL_CLOCK
+ default n
+
+endmenu
+
+comment "Asynchonous Memory Configuration"
+
+menu "EBIU_AMBCTL Global Control"
+config C_AMCKEN
+ bool "Enable CLKOUT"
+ default y
+
+config C_CDPRIO
+ bool "DMA has priority over core for ext. accesses"
+ default n
+
+config C_B0PEN
+ depends on BF561
+ bool "Bank 0 16 bit packing enable"
+ default y
+
+config C_B1PEN
+ depends on BF561
+ bool "Bank 1 16 bit packing enable"
+ default y
+
+config C_B2PEN
+ depends on BF561
+ bool "Bank 2 16 bit packing enable"
+ default y
+
+config C_B3PEN
+ depends on BF561
+ bool "Bank 3 16 bit packing enable"
+ default n
+
+choice
+ prompt"Enable Asynchonous Memory Banks"
+ default C_AMBEN_ALL
+
+config C_AMBEN
+ bool "Disable All Banks"
+
+config C_AMBEN_B0
+ bool "Enable Bank 0"
+
+config C_AMBEN_B0_B1
+ bool "Enable Bank 0 & 1"
+
+config C_AMBEN_B0_B1_B2
+ bool "Enable Bank 0 & 1 & 2"
+
+config C_AMBEN_ALL
+ bool "Enable All Banks"
+endchoice
+endmenu
+
+menu "EBIU_AMBCTL Control"
+config BANK_0
+ hex "Bank 0"
+ default 0x7BB0
+
+config BANK_1
+ hex "Bank 1"
+ default 0x7BB0
+
+config BANK_2
+ hex "Bank 2"
+ default 0x7BB0
+
+config BANK_3
+ hex "Bank 3"
+ default 0x99B3
+endmenu
+
+endmenu
+
+#############################################################################
+menu "Bus options (PCI, PCMCIA, EISA, MCA, ISA)"
+
+config PCI
+ bool "PCI support"
+ help
+ Support for PCI bus.
+
+source "drivers/pci/Kconfig"
+
+config HOTPLUG
+ bool "Support for hot-pluggable device"
+ help
+ Say Y here if you want to plug devices into your computer while
+ the system is running, and be able to use them quickly. In many
+ cases, the devices can likewise be unplugged at any time too.
+
+ One well known example of this is PCMCIA- or PC-cards, credit-card
+ size devices such as network cards, modems or hard drives which are
+ plugged into slots found on all modern laptop computers. Another
+ example, used on modern desktops as well as laptops, is USB.
+
+ Enable HOTPLUG and KMOD, and build a modular kernel. Get agent
+ software (at <http://linux-hotplug.sourceforge.net/>) and install it.
+ Then your kernel will automatically call out to a user mode "policy
+ agent" (/sbin/hotplug) to load modules and set up software needed
+ to use devices as you hotplug them.
+
+source "drivers/pcmcia/Kconfig"
+
+source "drivers/pci/hotplug/Kconfig"
+
+endmenu
+
+menu "Executable file formats"
+
+source "fs/Kconfig.binfmt"
+
+endmenu
+
+menu "Power management options"
+source "kernel/power/Kconfig"
+
+choice
+ prompt "Select PM Wakeup Event Source"
+ default PM_WAKEUP_GPIO_BY_SIC_IWR
+ depends on PM
+ help
+ If you have a GPIO already configured as input with the corresponding PORTx_MASK
+ bit set - "Specify Wakeup Event by SIC_IWR value"
+
+config PM_WAKEUP_GPIO_BY_SIC_IWR
+ bool "Specify Wakeup Event by SIC_IWR value"
+config PM_WAKEUP_BY_GPIO
+ bool "Cause Wakeup Event by GPIO"
+config PM_WAKEUP_GPIO_API
+ bool "Configure Wakeup Event by PM GPIO API"
+
+endchoice
+
+config PM_WAKEUP_SIC_IWR
+ hex "Wakeup Events (SIC_IWR)"
+ depends on PM_WAKEUP_GPIO_BY_SIC_IWR
+ default 0x80000000 if (BF537 || BF536 || BF534)
+ default 0x100000 if (BF533 || BF532 || BF531)
+
+config PM_WAKEUP_GPIO_NUMBER
+ int "Wakeup GPIO number"
+ range 0 47
+ depends on PM_WAKEUP_BY_GPIO
+ default 2 if BFIN537_STAMP
+
+choice
+ prompt "GPIO Polarity"
+ depends on PM_WAKEUP_BY_GPIO
+ default PM_WAKEUP_GPIO_POLAR_H
+config PM_WAKEUP_GPIO_POLAR_H
+ bool "Active High"
+config PM_WAKEUP_GPIO_POLAR_L
+ bool "Active Low"
+config PM_WAKEUP_GPIO_POLAR_EDGE_F
+ bool "Falling EDGE"
+config PM_WAKEUP_GPIO_POLAR_EDGE_R
+ bool "Rising EDGE"
+config PM_WAKEUP_GPIO_POLAR_EDGE_B
+ bool "Both EDGE"
+endchoice
+
+endmenu
+
+if (BF537 || BF533)
+
+menu "CPU Frequency scaling"
+
+source "drivers/cpufreq/Kconfig"
+
+config CPU_FREQ
+ bool
+ default n
+ help
+ If you want to enable this option, you should select the
+ DPMC driver from Character Devices.
+endmenu
+
+endif
+
+source "net/Kconfig"
+
+source "drivers/Kconfig"
+
+source "fs/Kconfig"
+
+source "arch/blackfin/oprofile/Kconfig"
+
+menu "Kernel hacking"
+
+source "lib/Kconfig.debug"
+
+config DEBUG_HWERR
+ bool "Hardware error interrupt debugging"
+ depends on DEBUG_KERNEL
+ help
+ When enabled, the hardware error interrupt is never disabled, and
+ will happen immediately when an error condition occurs. This comes
+ at a slight cost in code size, but is necessary if you are getting
+ hardware error interrupts and need to know where they are coming
+ from.
+
+config DEBUG_ICACHE_CHECK
+ bool "Check Instruction cache coherancy"
+ depends on DEBUG_KERNEL
+ depends on DEBUG_HWERR
+ help
+ Say Y here if you are getting wierd unexplained errors. This will
+ ensure that icache is what SDRAM says it should be, by doing a
+ byte wise comparision between SDRAM and instruction cache. This
+ also relocates the irq_panic() function to L1 memory, (which is
+ un-cached).
+
+config DEBUG_KERNEL_START
+ bool "Debug Kernel Startup"
+ depends on DEBUG_KERNEL
+ help
+ Say Y here to put in an mini-execption handler before the kernel
+ replaces the bootloader exception handler. This will stop kernels
+ from dieing at startup with no visible error messages.
+
+config DEBUG_SERIAL_EARLY_INIT
+ bool "Initialize serial driver early"
+ default n
+ depends on SERIAL_BFIN
+ help
+ Say Y here if you want to get kernel output early when kernel
+ crashes before the normal console initialization. If this option
+ is enable, console output will always go to the ttyBF0, no matter
+ what kernel boot paramters you set.
+
+config DEBUG_HUNT_FOR_ZERO
+ bool "Catch NULL pointer reads/writes"
+ default y
+ help
+ Say Y here to catch reads/writes to anywhere in the memory range
+ from 0x0000 - 0x0FFF (the first 4k) of memory. This is useful in
+ catching common programming errors such as NULL pointer dereferences.
+
+ Misbehaving applications will be killed (generate a SEGV) while the
+ kernel will trigger a panic.
+
+ Enabling this option will take up an extra entry in CPLB table.
+ Otherwise, there is no extra overhead.
+
+config DEBUG_BFIN_NO_KERN_HWTRACE
+ bool "Trace user apps (turn off hwtrace in kernel)"
+ default n
+ help
+ Some pieces of the kernel contain a lot of flow changes which can
+ quickly fill up the hardware trace buffer. When debugging crashes,
+ the hardware trace may indicate that the problem lies in kernel
+ space when in reality an application is buggy.
+
+ Say Y here to disable hardware tracing in some known "jumpy" pieces
+ of code so that the trace buffer will extend further back.
+
+config DUAL_CORE_TEST_MODULE
+ tristate "Dual Core Test Module"
+ depends on (BF561)
+ default n
+ help
+ Say Y here to build-in dual core test module for dual core test.
+
+config CPLB_INFO
+ bool "Display the CPLB information"
+ help
+ Display the CPLB information.
+
+config ACCESS_CHECK
+ bool "Check the user pointer address"
+ default y
+ help
+ Usually the pointer transfer from user space is checked to see if its
+ address is in the kernel space.
+
+ Say N here to disable that check to improve the performance.
+
+endmenu
+
+source "security/Kconfig"
+
+source "crypto/Kconfig"
+
+source "lib/Kconfig"
diff --git a/arch/blackfin/Makefile b/arch/blackfin/Makefile
new file mode 100644
index 00000000000..52d4dbdb2b1
--- /dev/null
+++ b/arch/blackfin/Makefile
@@ -0,0 +1,80 @@
+#
+# arch/blackfin/Makefile
+#
+# 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.
+#
+
+
+CROSS_COMPILE ?= bfin-uclinux-
+LDFLAGS_vmlinux := -X
+OBJCOPYFLAGS := -O binary -R .note -R .comment -S
+GZFLAGS := -9
+
+CFLAGS_MODULE += -mlong-calls
+KALLSYMS += --symbol-prefix=_
+
+
+# setup the machine name and the machine dependent settings
+machine-$(CONFIG_BF531) := bf533
+machine-$(CONFIG_BF532) := bf533
+machine-$(CONFIG_BF533) := bf533
+machine-$(CONFIG_BF534) := bf537
+machine-$(CONFIG_BF536) := bf537
+machine-$(CONFIG_BF537) := bf537
+machine-$(CONFIG_BF561) := bf561
+MACHINE := $(machine-y)
+export MACHINE
+
+
+head-y := arch/$(ARCH)/mach-$(MACHINE)/head.o arch/$(ARCH)/kernel/init_task.o
+
+core-y += arch/$(ARCH)/kernel/ arch/$(ARCH)/mm/ arch/$(ARCH)/mach-common/
+
+# If we have a machine-specific directory, then include it in the build.
+ifneq ($(machine-y),)
+core-y += arch/$(ARCH)/mach-$(MACHINE)/
+core-y += arch/$(ARCH)/mach-$(MACHINE)/boards/
+endif
+
+libs-y += arch/$(ARCH)/lib/
+
+drivers-$(CONFIG_OPROFILE) += arch/$(ARCH)/oprofile/
+
+
+
+# Update machine arch symlinks if something which affects
+# them changed. We use .mach to indicate when they were updated
+# last, otherwise make uses the target directory mtime.
+
+include/asm-blackfin/.mach: $(wildcard include/config/arch/*.h) include/config/auto.conf
+ @echo ' SYMLINK include/asm-$(ARCH)/mach-$(MACHINE) -> include/asm-$(ARCH)/mach'
+ifneq ($(KBUILD_SRC),)
+ $(Q)mkdir -p include/asm-$(ARCH)
+ $(Q)ln -fsn $(srctree)/include/asm-$(ARCH)/mach-$(MACHINE) include/asm-$(ARCH)/mach
+else
+ $(Q)ln -fsn mach-$(MACHINE) include/asm-$(ARCH)/mach
+endif
+ @touch $@
+
+CLEAN_FILES += \
+ include/asm-$(ARCH)/asm-offsets.h \
+ arch/$(ARCH)/kernel/asm-offsets.s \
+ include/asm-$(ARCH)/mach \
+ include/asm-$(ARCH)/.mach
+
+archprepare: include/asm-blackfin/.mach
+archclean:
+ $(Q)$(MAKE) $(clean)=$(boot)
+
+
+all: vmImage
+boot := arch/$(ARCH)/boot
+BOOT_TARGETS = vmImage
+.PHONY: $(BOOT_TARGETS)
+$(BOOT_TARGETS): vmlinux
+ $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
+define archhelp
+ echo '* vmImage - Kernel-only image for U-Boot (arch/$(ARCH)/boot/vmImage)'
+endef
diff --git a/arch/blackfin/boot/Makefile b/arch/blackfin/boot/Makefile
new file mode 100644
index 00000000000..49e8098d4c2
--- /dev/null
+++ b/arch/blackfin/boot/Makefile
@@ -0,0 +1,27 @@
+#
+# arch/blackfin/boot/Makefile
+#
+# 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.
+#
+
+MKIMAGE := $(srctree)/scripts/mkuboot.sh
+
+targets := vmImage
+extra-y += vmlinux.bin vmlinux.gz
+
+quiet_cmd_uimage = UIMAGE $@
+ cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A $(ARCH) -O linux -T kernel \
+ -C gzip -a $(CONFIG_BOOT_LOAD) -e $(CONFIG_BOOT_LOAD) -n 'Linux-$(KERNELRELEASE)' \
+ -d $< $@
+
+$(obj)/vmlinux.bin: vmlinux FORCE
+ $(call if_changed,objcopy)
+
+$(obj)/vmlinux.gz: $(obj)/vmlinux.bin FORCE
+ $(call if_changed,gzip)
+
+$(obj)/vmImage: $(obj)/vmlinux.gz
+ $(call if_changed,uimage)
+ @echo 'Kernel: $@ is ready'
diff --git a/arch/blackfin/defconfig b/arch/blackfin/defconfig
new file mode 100644
index 00000000000..d5904ca994c
--- /dev/null
+++ b/arch/blackfin/defconfig
@@ -0,0 +1,1314 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.20
+#
+# CONFIG_MMU is not set
+# CONFIG_FPU is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_BFIN=y
+CONFIG_SEMAPHORE_SLEEPERS=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_UCLINUX=y
+CONFIG_FORCE_MAX_ZONEORDER=14
+CONFIG_IRQCHIP_DEMUX_GPIO=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_SYSFS_DEPRECATED=y
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS 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_LIMIT_PAGECACHE is not set
+CONFIG_BUDDY=y
+# CONFIG_NP2 is not set
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
+CONFIG_TINY_SHMEM=y
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+
+#
+# Block layer
+#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+# CONFIG_IOSCHED_DEADLINE is not set
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
+# Blackfin Processor Options
+#
+
+#
+# Processor and Board Settings
+#
+# CONFIG_BF531 is not set
+# CONFIG_BF532 is not set
+# CONFIG_BF533 is not set
+# CONFIG_BF534 is not set
+# CONFIG_BF535 is not set
+# CONFIG_BF536 is not set
+CONFIG_BF537=y
+# CONFIG_BF561 is not set
+CONFIG_BF_REV_0_2=y
+# CONFIG_BF_REV_0_3 is not set
+# CONFIG_BF_REV_0_4 is not set
+# CONFIG_BF_REV_0_5 is not set
+CONFIG_BLACKFIN=y
+CONFIG_BFIN_SINGLE_CORE=y
+# CONFIG_BFIN533_EZKIT is not set
+# CONFIG_BFIN533_STAMP is not set
+CONFIG_BFIN537_STAMP=y
+# CONFIG_BFIN533_BLUETECHNIX_CM is not set
+# CONFIG_BFIN537_BLUETECHNIX_CM is not set
+# CONFIG_BFIN561_BLUETECHNIX_CM is not set
+# CONFIG_BFIN561_EZKIT is not set
+# CONFIG_PNAV10 is not set
+# CONFIG_GENERIC_BOARD is not set
+CONFIG_MEM_MT48LC32M8A2_75=y
+CONFIG_IRQ_PLL_WAKEUP=7
+
+#
+# BF537 Specific Configuration
+#
+
+#
+# PORT F/G Selection
+#
+CONFIG_BF537_PORT_F=y
+# CONFIG_BF537_PORT_G is not set
+# CONFIG_BF537_PORT_H is not set
+
+#
+# Interrupt Priority Assignment
+#
+
+#
+# Priority
+#
+CONFIG_IRQ_DMA_ERROR=7
+CONFIG_IRQ_ERROR=7
+CONFIG_IRQ_RTC=8
+CONFIG_IRQ_PPI=8
+CONFIG_IRQ_SPORT0_RX=9
+CONFIG_IRQ_SPORT0_TX=9
+CONFIG_IRQ_SPORT1_RX=9
+CONFIG_IRQ_SPORT1_TX=9
+CONFIG_IRQ_TWI=10
+CONFIG_IRQ_SPI=10
+CONFIG_IRQ_UART0_RX=10
+CONFIG_IRQ_UART0_TX=10
+CONFIG_IRQ_UART1_RX=10
+CONFIG_IRQ_UART1_TX=10
+CONFIG_IRQ_CAN_RX=11
+CONFIG_IRQ_CAN_TX=11
+CONFIG_IRQ_MAC_RX=11
+CONFIG_IRQ_MAC_TX=11
+CONFIG_IRQ_TMR0=12
+CONFIG_IRQ_TMR1=12
+CONFIG_IRQ_TMR2=12
+CONFIG_IRQ_TMR3=12
+CONFIG_IRQ_TMR4=12
+CONFIG_IRQ_TMR5=12
+CONFIG_IRQ_TMR6=12
+CONFIG_IRQ_TMR7=12
+CONFIG_IRQ_PROG_INTA=12
+CONFIG_IRQ_PORTG_INTB=12
+CONFIG_IRQ_MEM_DMA0=13
+CONFIG_IRQ_MEM_DMA1=13
+CONFIG_IRQ_WATCH=13
+
+#
+# Board customizations
+#
+
+#
+# Board Setup
+#
+CONFIG_CLKIN_HZ=25000000
+CONFIG_MEM_SIZE=64
+CONFIG_MEM_ADD_WIDTH=10
+CONFIG_BOOT_LOAD=0x1000
+
+#
+# Console UART Setup
+#
+# CONFIG_BAUD_9600 is not set
+# CONFIG_BAUD_19200 is not set
+# CONFIG_BAUD_38400 is not set
+CONFIG_BAUD_57600=y
+# CONFIG_BAUD_115200 is not set
+CONFIG_BAUD_NO_PARITY=y
+# CONFIG_BAUD_PARITY is not set
+CONFIG_BAUD_1_STOPBIT=y
+# CONFIG_BAUD_2_STOPBIT is not set
+
+#
+# Blackfin Kernel Optimizations
+#
+
+#
+# Timer Tick
+#
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+
+#
+# Memory Optimizations
+#
+CONFIG_I_ENTRY_L1=y
+CONFIG_RAMKERNEL=y
+# CONFIG_ROMKERNEL 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 is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_LARGE_ALLOCS=y
+CONFIG_BFIN_DMA_5XX=y
+# CONFIG_DMA_UNCACHED_2M is not set
+CONFIG_DMA_UNCACHED_1M=y
+# CONFIG_DMA_UNCACHED_NONE is not set
+
+#
+# Cache Support
+#
+CONFIG_BLKFIN_CACHE=y
+CONFIG_BLKFIN_DCACHE=y
+# CONFIG_BLKFIN_CACHE_LOCK is not set
+# CONFIG_BLKFIN_WB is not set
+CONFIG_BLKFIN_WT=y
+CONFIG_L1_MAX_PIECE=16
+
+#
+# Clock Settings
+#
+# CONFIG_BFIN_KERNEL_CLOCK is not set
+
+#
+# Asynchonous Memory Configuration
+#
+
+#
+# EBIU_AMBCTL Global Control
+#
+CONFIG_C_AMCKEN=y
+CONFIG_C_CDPRIO=y
+# CONFIG_C_AMBEN is not set
+# CONFIG_C_AMBEN_B0 is not set
+# CONFIG_C_AMBEN_B0_B1 is not set
+# CONFIG_C_AMBEN_B0_B1_B2 is not set
+CONFIG_C_AMBEN_ALL=y
+
+#
+# EBIU_AMBCTL Control
+#
+CONFIG_BANK_0=0x7BB0
+CONFIG_BANK_1=0x7BB0
+CONFIG_BANK_2=0x7BB0
+CONFIG_BANK_3=0x99B3
+
+#
+# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
+#
+# CONFIG_PCI is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PCI Hotplug Support
+#
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF_FDPIC=y
+CONFIG_BINFMT_FLAT=y
+CONFIG_BINFMT_ZFLAT=y
+# CONFIG_BINFMT_SHARED_FLAT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+CONFIG_PM=y
+CONFIG_PM_LEGACY=y
+# CONFIG_PM_DEBUG is not set
+# CONFIG_PM_SYSFS_DEPRECATED is not set
+CONFIG_PM_WAKEUP_GPIO_BY_SIC_IWR=y
+# CONFIG_PM_WAKEUP_BY_GPIO is not set
+# CONFIG_PM_WAKEUP_GPIO_API is not set
+CONFIG_PM_WAKEUP_SIC_IWR=0x80000000
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# 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=y
+# CONFIG_IP_PNP_DHCP is not set
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+# 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=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# 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_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETLABEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE 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
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+CONFIG_IRDA=m
+
+#
+# IrDA protocols
+#
+CONFIG_IRLAN=m
+CONFIG_IRCOMM=m
+# CONFIG_IRDA_ULTRA is not set
+
+#
+# IrDA options
+#
+CONFIG_IRDA_CACHE_LAST_LSAP=y
+# CONFIG_IRDA_FAST_RR is not set
+# CONFIG_IRDA_DEBUG is not set
+
+#
+# Infrared-port device drivers
+#
+
+#
+# SIR device drivers
+#
+CONFIG_IRTTY_SIR=m
+
+#
+# Dongle support
+#
+# CONFIG_DONGLE is not set
+
+#
+# Old SIR device drivers
+#
+# CONFIG_IRPORT_SIR is not set
+
+#
+# Old Serial dongle support
+#
+
+#
+# FIR device drivers
+#
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=m
+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
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+CONFIG_MTD_JEDECPROBE=m
+CONFIG_MTD_GEN_PROBE=m
+# 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 is not set
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_MW320D=m
+CONFIG_MTD_RAM=y
+CONFIG_MTD_ROM=m
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+
+#
+# Mapping drivers for chip access
+#
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+# CONFIG_MTD_PHYSMAP is not set
+CONFIG_MTD_BF5xx=m
+CONFIG_BFIN_FLASH_SIZE=0x400000
+CONFIG_EBIU_FLASH_BASE=0x20000000
+
+#
+# FLASH_EBIU_AMBCTL Control
+#
+CONFIG_BFIN_FLASH_BANK_0=0x7BB0
+CONFIG_BFIN_FLASH_BANK_1=0x7BB0
+CONFIG_BFIN_FLASH_BANK_2=0x7BB0
+CONFIG_BFIN_FLASH_BANK_3=0x7BB0
+CONFIG_MTD_UCLINUX=y
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_DATAFLASH is not set
+# CONFIG_MTD_M25P80 is not set
+# 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
+
+#
+# NAND Flash Device Drivers
+#
+CONFIG_MTD_NAND=m
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_SMC is not set
+CONFIG_MTD_NAND_BFIN=m
+CONFIG_BFIN_NAND_BASE=0x20212000
+CONFIG_BFIN_NAND_CLE=2
+CONFIG_BFIN_NAND_ALE=1
+CONFIG_BFIN_NAND_READY=3
+CONFIG_MTD_NAND_IDS=m
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+
+#
+# OneNAND Flash Device Drivers
+#
+# CONFIG_MTD_ONENAND is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# 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=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# Misc devices
+#
+# CONFIG_TIFM_CORE is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# I2O device support
+#
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_SMC91X is not set
+CONFIG_BFIN_MAC=y
+CONFIG_BFIN_MAC_USE_L1=y
+CONFIG_BFIN_TX_DESC_NUM=10
+CONFIG_BFIN_RX_DESC_NUM=20
+# CONFIG_BFIN_MAC_RMII is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+
+#
+# Ethernet (10000 Mbit)
+#
+
+#
+# Token Ring devices
+#
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+CONFIG_INPUT_EVDEV=m
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+CONFIG_INPUT_MISC=y
+# CONFIG_INPUT_UINPUT is not set
+# CONFIG_BF53X_PFBUTTONS is not set
+CONFIG_TWI_KEYPAD=m
+CONFIG_BFIN_TWIKEYPAD_IRQ_PFX=72
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_AD9960 is not set
+# CONFIG_SPI_ADC_BF533 is not set
+# CONFIG_BF533_PFLAGS is not set
+# CONFIG_BF5xx_PPIFCD is not set
+# CONFIG_BF5xx_TIMERS is not set
+# CONFIG_BF5xx_PPI is not set
+CONFIG_BFIN_SPORT=y
+# CONFIG_BFIN_TIMER_LATENCY is not set
+CONFIG_TWI_LCD=m
+CONFIG_TWI_LCD_SLAVE_ADDR=34
+# CONFIG_AD5304 is not set
+# CONFIG_VT is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_BFIN=y
+CONFIG_SERIAL_BFIN_CONSOLE=y
+CONFIG_SERIAL_BFIN_DMA=y
+# CONFIG_SERIAL_BFIN_PIO is not set
+CONFIG_SERIAL_BFIN_UART0=y
+# CONFIG_BFIN_UART0_CTSRTS is not set
+# CONFIG_SERIAL_BFIN_UART1 is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_BFIN_SPORT is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+
+#
+# CAN, the car bus and industrial fieldbus
+#
+CONFIG_CAN4LINUX=y
+
+#
+# linux embedded drivers
+#
+# CONFIG_CAN_MCF5282 is not set
+# CONFIG_CAN_UNCTWINCAN is not set
+CONFIG_CAN_BLACKFIN=m
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_GEN_RTC is not set
+CONFIG_BLACKFIN_DPMC=y
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
+# I2C support
+#
+CONFIG_I2C=m
+CONFIG_I2C_CHARDEV=m
+
+#
+# I2C Algorithms
+#
+# CONFIG_I2C_ALGOBIT is not set
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+
+#
+# I2C Hardware Bus support
+#
+# CONFIG_I2C_BFIN_GPIO is not set
+CONFIG_I2C_BFIN_TWI=m
+CONFIG_TWICLK_KHZ=50
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_PCA_ISA is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
+CONFIG_SENSORS_AD5252=m
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_SENSORS_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_MAX6875 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
+
+#
+# SPI support
+#
+CONFIG_SPI=y
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+# CONFIG_SPI_BITBANG is not set
+CONFIG_SPI_BFIN=y
+
+#
+# SPI Protocol Masters
+#
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ASB100 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_FSCHER is not set
+# CONFIG_SENSORS_FSCPOS is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM70 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47M192 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83791D is not set
+# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+CONFIG_FIRMWARE_EDID=y
+CONFIG_FB=m
+CONFIG_FB_CFB_FILLRECT=m
+CONFIG_FB_CFB_COPYAREA=m
+CONFIG_FB_CFB_IMAGEBLIT=m
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+CONFIG_FB_BFIN_7171=m
+CONFIG_FB_BFIN_7393=m
+CONFIG_NTSC=y
+# CONFIG_PAL is not set
+# CONFIG_NTSC_640x480 is not set
+# CONFIG_PAL_640x480 is not set
+# CONFIG_NTSC_YCBCR is not set
+# CONFIG_PAL_YCBCR is not set
+CONFIG_ADV7393_1XMEM=y
+# CONFIG_ADV7393_2XMEM is not set
+CONFIG_FB_BF537_LQ035=m
+CONFIG_LQ035_SLAVE_ADDR=0x58
+# CONFIG_FB_BFIN_LANDSCAPE is not set
+# CONFIG_FB_BFIN_BGR is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_VIRTUAL is not set
+
+#
+# Logo configuration
+#
+# CONFIG_LOGO is not set
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=m
+CONFIG_BACKLIGHT_DEVICE=y
+CONFIG_LCD_CLASS_DEVICE=m
+CONFIG_LCD_DEVICE=y
+
+#
+# Sound
+#
+CONFIG_SOUND=m
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=m
+CONFIG_SND_TIMER=m
+CONFIG_SND_PCM=m
+# CONFIG_SND_SEQUENCER is not set
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+CONFIG_SND_PCM_OSS_PLUGINS=y
+# CONFIG_SND_DYNAMIC_MINORS is not set
+CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+
+#
+# Generic devices
+#
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+
+#
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME is not set
+
+#
+# HID Devices
+#
+CONFIG_HID=y
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+# CONFIG_USB is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_SPI_MMC is not set
+# CONFIG_MMC is not set
+
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
+# InfiniBand support
+#
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+
+#
+# RTC drivers
+#
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_TEST is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+CONFIG_RTC_DRV_BFIN=y
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
+# Virtualization
+#
+
+#
+# PBX support
+#
+# CONFIG_PBX is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+# CONFIG_EXT2_FS_POSIX_ACL is not set
+# CONFIG_EXT2_FS_SECURITY is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4DEV_FS is not set
+CONFIG_FS_MBCACHE=y
+# 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_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS 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_SYSCTL=y
+CONFIG_SYSFS=y
+# CONFIG_TMPFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_YAFFS_FS=m
+CONFIG_YAFFS_YAFFS1=y
+# CONFIG_YAFFS_DOES_ECC is not set
+CONFIG_YAFFS_YAFFS2=y
+CONFIG_YAFFS_AUTO_YAFFS2=y
+# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set
+CONFIG_YAFFS_CHECKPOINT_RESERVED_BLOCKS=10
+# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set
+# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set
+CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y
+CONFIG_JFFS2_FS=m
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=m
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=m
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+CONFIG_SMB_FS=m
+# CONFIG_SMB_NLS_DEFAULT is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS=m
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Distributed Lock Manager
+#
+# CONFIG_DLM is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_HUNT_FOR_ZERO=y
+# CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE is not set
+# CONFIG_BOOTPARAM is not set
+# CONFIG_NO_KERNEL_MSG is not set
+CONFIG_CPLB_INFO=y
+# CONFIG_NO_ACCESS_CHECK is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+CONFIG_SECURITY=y
+# CONFIG_SECURITY_NETWORK is not set
+CONFIG_SECURITY_CAPABILITIES=y
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_CRC_CCITT=m
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_PLIST=y
+CONFIG_IOMAP_COPY=y
diff --git a/arch/blackfin/kernel/Makefile b/arch/blackfin/kernel/Makefile
new file mode 100644
index 00000000000..f3b7d2f9d49
--- /dev/null
+++ b/arch/blackfin/kernel/Makefile
@@ -0,0 +1,14 @@
+#
+# arch/blackfin/kernel/Makefile
+#
+
+extra-y := init_task.o vmlinux.lds
+
+obj-y := \
+ entry.o process.o bfin_ksyms.o ptrace.o setup.o signal.o \
+ sys_bfin.o time.o traps.o irqchip.o dma-mapping.o bfin_gpio.o \
+ flat.o
+
+obj-$(CONFIG_MODULES) += module.o
+obj-$(CONFIG_BFIN_DMA_5XX) += bfin_dma_5xx.o
+obj-$(CONFIG_DUAL_CORE_TEST_MODULE) += dualcore_test.o
diff --git a/arch/blackfin/kernel/asm-offsets.c b/arch/blackfin/kernel/asm-offsets.c
new file mode 100644
index 00000000000..41d9a9f8970
--- /dev/null
+++ b/arch/blackfin/kernel/asm-offsets.c
@@ -0,0 +1,136 @@
+/*
+ * File: arch/blackfin/kernel/asm-offsets.c
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description: generate definitions needed by assembly language modules.
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/stddef.h>
+#include <linux/sched.h>
+#include <linux/kernel_stat.h>
+#include <linux/ptrace.h>
+#include <linux/hardirq.h>
+#include <asm/irq.h>
+#include <asm/thread_info.h>
+
+#define DEFINE(sym, val) \
+ asm volatile("\n->" #sym " %0 " #val : : "i" (val))
+
+int main(void)
+{
+ /* offsets into the task struct */
+ DEFINE(TASK_STATE, offsetof(struct task_struct, state));
+ DEFINE(TASK_FLAGS, offsetof(struct task_struct, flags));
+ DEFINE(TASK_PTRACE, offsetof(struct task_struct, ptrace));
+ DEFINE(TASK_BLOCKED, offsetof(struct task_struct, blocked));
+ DEFINE(TASK_THREAD, offsetof(struct task_struct, thread));
+ DEFINE(TASK_THREAD_INFO, offsetof(struct task_struct, thread_info));
+ DEFINE(TASK_MM, offsetof(struct task_struct, mm));
+ DEFINE(TASK_ACTIVE_MM, offsetof(struct task_struct, active_mm));
+ DEFINE(TASK_SIGPENDING, offsetof(struct task_struct, pending));
+
+ /* offsets into the irq_cpustat_t struct */
+ DEFINE(CPUSTAT_SOFTIRQ_PENDING,
+ offsetof(irq_cpustat_t, __softirq_pending));
+
+ /* offsets into the thread struct */
+ DEFINE(THREAD_KSP, offsetof(struct thread_struct, ksp));
+ DEFINE(THREAD_USP, offsetof(struct thread_struct, usp));
+ DEFINE(THREAD_SR, offsetof(struct thread_struct, seqstat));
+ DEFINE(PT_SR, offsetof(struct thread_struct, seqstat));
+ DEFINE(THREAD_ESP0, offsetof(struct thread_struct, esp0));
+ DEFINE(THREAD_PC, offsetof(struct thread_struct, pc));
+ DEFINE(KERNEL_STACK_SIZE, THREAD_SIZE);
+
+ /* offsets into the pt_regs */
+ DEFINE(PT_ORIG_P0, offsetof(struct pt_regs, orig_p0));
+ DEFINE(PT_ORIG_PC, offsetof(struct pt_regs, orig_pc));
+ DEFINE(PT_R0, offsetof(struct pt_regs, r0));
+ DEFINE(PT_R1, offsetof(struct pt_regs, r1));
+ DEFINE(PT_R2, offsetof(struct pt_regs, r2));
+ DEFINE(PT_R3, offsetof(struct pt_regs, r3));
+ DEFINE(PT_R4, offsetof(struct pt_regs, r4));
+ DEFINE(PT_R5, offsetof(struct pt_regs, r5));
+ DEFINE(PT_R6, offsetof(struct pt_regs, r6));
+ DEFINE(PT_R7, offsetof(struct pt_regs, r7));
+
+ DEFINE(PT_P0, offsetof(struct pt_regs, p0));
+ DEFINE(PT_P1, offsetof(struct pt_regs, p1));
+ DEFINE(PT_P2, offsetof(struct pt_regs, p2));
+ DEFINE(PT_P3, offsetof(struct pt_regs, p3));
+ DEFINE(PT_P4, offsetof(struct pt_regs, p4));
+ DEFINE(PT_P5, offsetof(struct pt_regs, p5));
+
+ DEFINE(PT_FP, offsetof(struct pt_regs, fp));
+ DEFINE(PT_USP, offsetof(struct pt_regs, usp));
+ DEFINE(PT_I0, offsetof(struct pt_regs, i0));
+ DEFINE(PT_I1, offsetof(struct pt_regs, i1));
+ DEFINE(PT_I2, offsetof(struct pt_regs, i2));
+ DEFINE(PT_I3, offsetof(struct pt_regs, i3));
+ DEFINE(PT_M0, offsetof(struct pt_regs, m0));
+ DEFINE(PT_M1, offsetof(struct pt_regs, m1));
+ DEFINE(PT_M2, offsetof(struct pt_regs, m2));
+ DEFINE(PT_M3, offsetof(struct pt_regs, m3));
+ DEFINE(PT_L0, offsetof(struct pt_regs, l0));
+ DEFINE(PT_L1, offsetof(struct pt_regs, l1));
+ DEFINE(PT_L2, offsetof(struct pt_regs, l2));
+ DEFINE(PT_L3, offsetof(struct pt_regs, l3));
+ DEFINE(PT_B0, offsetof(struct pt_regs, b0));
+ DEFINE(PT_B1, offsetof(struct pt_regs, b1));
+ DEFINE(PT_B2, offsetof(struct pt_regs, b2));
+ DEFINE(PT_B3, offsetof(struct pt_regs, b3));
+ DEFINE(PT_A0X, offsetof(struct pt_regs, a0x));
+ DEFINE(PT_A0W, offsetof(struct pt_regs, a0w));
+ DEFINE(PT_A1X, offsetof(struct pt_regs, a1x));
+ DEFINE(PT_A1W, offsetof(struct pt_regs, a1w));
+ DEFINE(PT_LC0, offsetof(struct pt_regs, lc0));
+ DEFINE(PT_LC1, offsetof(struct pt_regs, lc1));
+ DEFINE(PT_LT0, offsetof(struct pt_regs, lt0));
+ DEFINE(PT_LT1, offsetof(struct pt_regs, lt1));
+ DEFINE(PT_LB0, offsetof(struct pt_regs, lb0));
+ DEFINE(PT_LB1, offsetof(struct pt_regs, lb1));
+ DEFINE(PT_ASTAT, offsetof(struct pt_regs, astat));
+ DEFINE(PT_RESERVED, offsetof(struct pt_regs, reserved));
+ DEFINE(PT_RETS, offsetof(struct pt_regs, rets));
+ DEFINE(PT_PC, offsetof(struct pt_regs, pc));
+ DEFINE(PT_RETX, offsetof(struct pt_regs, retx));
+ DEFINE(PT_RETN, offsetof(struct pt_regs, retn));
+ DEFINE(PT_RETE, offsetof(struct pt_regs, rete));
+ DEFINE(PT_SEQSTAT, offsetof(struct pt_regs, seqstat));
+ DEFINE(PT_SYSCFG, offsetof(struct pt_regs, syscfg));
+ DEFINE(PT_IPEND, offsetof(struct pt_regs, ipend));
+ DEFINE(SIZEOF_PTREGS, sizeof(struct pt_regs));
+ DEFINE(PT_TEXT_ADDR, sizeof(struct pt_regs)); /* Needed by gdb */
+ DEFINE(PT_TEXT_END_ADDR, 4 + sizeof(struct pt_regs));/* Needed by gdb */
+ DEFINE(PT_DATA_ADDR, 8 + sizeof(struct pt_regs)); /* Needed by gdb */
+ DEFINE(PT_FDPIC_EXEC, 12 + sizeof(struct pt_regs)); /* Needed by gdb */
+ DEFINE(PT_FDPIC_INTERP, 16 + sizeof(struct pt_regs));/* Needed by gdb */
+
+ /* signal defines */
+ DEFINE(SIGSEGV, SIGSEGV);
+ DEFINE(SIGTRAP, SIGTRAP);
+
+ return 0;
+}
diff --git a/arch/blackfin/kernel/bfin_dma_5xx.c b/arch/blackfin/kernel/bfin_dma_5xx.c
new file mode 100644
index 00000000000..8ea079ebecb
--- /dev/null
+++ b/arch/blackfin/kernel/bfin_dma_5xx.c
@@ -0,0 +1,742 @@
+/*
+ * File: arch/blackfin/kernel/bfin_dma_5xx.c
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description: This file contains the simple DMA Implementation for Blackfin
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+
+#include <asm/dma.h>
+#include <asm/cacheflush.h>
+
+/* Remove unused code not exported by symbol or internally called */
+#define REMOVE_DEAD_CODE
+
+/**************************************************************************
+ * Global Variables
+***************************************************************************/
+
+static struct dma_channel dma_ch[MAX_BLACKFIN_DMA_CHANNEL];
+#if defined (CONFIG_BF561)
+static struct dma_register *base_addr[MAX_BLACKFIN_DMA_CHANNEL] = {
+ (struct dma_register *) DMA1_0_NEXT_DESC_PTR,
+ (struct dma_register *) DMA1_1_NEXT_DESC_PTR,
+ (struct dma_register *) DMA1_2_NEXT_DESC_PTR,
+ (struct dma_register *) DMA1_3_NEXT_DESC_PTR,
+ (struct dma_register *) DMA1_4_NEXT_DESC_PTR,
+ (struct dma_register *) DMA1_5_NEXT_DESC_PTR,
+ (struct dma_register *) DMA1_6_NEXT_DESC_PTR,
+ (struct dma_register *) DMA1_7_NEXT_DESC_PTR,
+ (struct dma_register *) DMA1_8_NEXT_DESC_PTR,
+ (struct dma_register *) DMA1_9_NEXT_DESC_PTR,
+ (struct dma_register *) DMA1_10_NEXT_DESC_PTR,
+ (struct dma_register *) DMA1_11_NEXT_DESC_PTR,
+ (struct dma_register *) DMA2_0_NEXT_DESC_PTR,
+ (struct dma_register *) DMA2_1_NEXT_DESC_PTR,
+ (struct dma_register *) DMA2_2_NEXT_DESC_PTR,
+ (struct dma_register *) DMA2_3_NEXT_DESC_PTR,
+ (struct dma_register *) DMA2_4_NEXT_DESC_PTR,
+ (struct dma_register *) DMA2_5_NEXT_DESC_PTR,
+ (struct dma_register *) DMA2_6_NEXT_DESC_PTR,
+ (struct dma_register *) DMA2_7_NEXT_DESC_PTR,
+ (struct dma_register *) DMA2_8_NEXT_DESC_PTR,
+ (struct dma_register *) DMA2_9_NEXT_DESC_PTR,
+ (struct dma_register *) DMA2_10_NEXT_DESC_PTR,
+ (struct dma_register *) DMA2_11_NEXT_DESC_PTR,
+ (struct dma_register *) MDMA1_D0_NEXT_DESC_PTR,
+ (struct dma_register *) MDMA1_S0_NEXT_DESC_PTR,
+ (struct dma_register *) MDMA1_D1_NEXT_DESC_PTR,
+ (struct dma_register *) MDMA1_S1_NEXT_DESC_PTR,
+ (struct dma_register *) MDMA2_D0_NEXT_DESC_PTR,
+ (struct dma_register *) MDMA2_S0_NEXT_DESC_PTR,
+ (struct dma_register *) MDMA2_D1_NEXT_DESC_PTR,
+ (struct dma_register *) MDMA2_S1_NEXT_DESC_PTR,
+ (struct dma_register *) IMDMA_D0_NEXT_DESC_PTR,
+ (struct dma_register *) IMDMA_S0_NEXT_DESC_PTR,
+ (struct dma_register *) IMDMA_D1_NEXT_DESC_PTR,
+ (struct dma_register *) IMDMA_S1_NEXT_DESC_PTR,
+};
+#else
+static struct dma_register *base_addr[MAX_BLACKFIN_DMA_CHANNEL] = {
+ (struct dma_register *) DMA0_NEXT_DESC_PTR,
+ (struct dma_register *) DMA1_NEXT_DESC_PTR,
+ (struct dma_register *) DMA2_NEXT_DESC_PTR,
+ (struct dma_register *) DMA3_NEXT_DESC_PTR,
+ (struct dma_register *) DMA4_NEXT_DESC_PTR,
+ (struct dma_register *) DMA5_NEXT_DESC_PTR,
+ (struct dma_register *) DMA6_NEXT_DESC_PTR,
+ (struct dma_register *) DMA7_NEXT_DESC_PTR,
+#if (defined(CONFIG_BF537) || defined(CONFIG_BF534) || defined(CONFIG_BF536))
+ (struct dma_register *) DMA8_NEXT_DESC_PTR,
+ (struct dma_register *) DMA9_NEXT_DESC_PTR,
+ (struct dma_register *) DMA10_NEXT_DESC_PTR,
+ (struct dma_register *) DMA11_NEXT_DESC_PTR,
+#endif
+ (struct dma_register *) MDMA_D0_NEXT_DESC_PTR,
+ (struct dma_register *) MDMA_S0_NEXT_DESC_PTR,
+ (struct dma_register *) MDMA_D1_NEXT_DESC_PTR,
+ (struct dma_register *) MDMA_S1_NEXT_DESC_PTR,
+};
+#endif
+
+/*------------------------------------------------------------------------------
+ * Set the Buffer Clear bit in the Configuration register of specific DMA
+ * channel. This will stop the descriptor based DMA operation.
+ *-----------------------------------------------------------------------------*/
+static void clear_dma_buffer(unsigned int channel)
+{
+ dma_ch[channel].regs->cfg |= RESTART;
+ SSYNC();
+ dma_ch[channel].regs->cfg &= ~RESTART;
+ SSYNC();
+}
+
+int __init blackfin_dma_init(void)
+{
+ int i;
+
+ printk(KERN_INFO "Blackfin DMA Controller\n");
+
+ for (i = 0; i < MAX_BLACKFIN_DMA_CHANNEL; i++) {
+ dma_ch[i].chan_status = DMA_CHANNEL_FREE;
+ dma_ch[i].regs = base_addr[i];
+ mutex_init(&(dma_ch[i].dmalock));
+ }
+
+ return 0;
+}
+
+arch_initcall(blackfin_dma_init);
+
+/*
+ * Form the channel find the irq number for that channel.
+ */
+#if !defined(CONFIG_BF561)
+
+static int bf533_channel2irq(unsigned int channel)
+{
+ int ret_irq = -1;
+
+ switch (channel) {
+ case CH_PPI:
+ ret_irq = IRQ_PPI;
+ break;
+
+#if (defined(CONFIG_BF537) || defined(CONFIG_BF534) || defined(CONFIG_BF536))
+ case CH_EMAC_RX:
+ ret_irq = IRQ_MAC_RX;
+ break;
+
+ case CH_EMAC_TX:
+ ret_irq = IRQ_MAC_TX;
+ break;
+
+ case CH_UART1_RX:
+ ret_irq = IRQ_UART1_RX;
+ break;
+
+ case CH_UART1_TX:
+ ret_irq = IRQ_UART1_TX;
+ break;
+#endif
+
+ case CH_SPORT0_RX:
+ ret_irq = IRQ_SPORT0_RX;
+ break;
+
+ case CH_SPORT0_TX:
+ ret_irq = IRQ_SPORT0_TX;
+ break;
+
+ case CH_SPORT1_RX:
+ ret_irq = IRQ_SPORT1_RX;
+ break;
+
+ case CH_SPORT1_TX:
+ ret_irq = IRQ_SPORT1_TX;
+ break;
+
+ case CH_SPI:
+ ret_irq = IRQ_SPI;
+ break;
+
+ case CH_UART_RX:
+ ret_irq = IRQ_UART_RX;
+ break;
+
+ case CH_UART_TX:
+ ret_irq = IRQ_UART_TX;
+ break;
+
+ case CH_MEM_STREAM0_SRC:
+ case CH_MEM_STREAM0_DEST:
+ ret_irq = IRQ_MEM_DMA0;
+ break;
+
+ case CH_MEM_STREAM1_SRC:
+ case CH_MEM_STREAM1_DEST:
+ ret_irq = IRQ_MEM_DMA1;
+ break;
+ }
+ return ret_irq;
+}
+
+# define channel2irq(channel) bf533_channel2irq(channel)
+
+#else
+
+static int bf561_channel2irq(unsigned int channel)
+{
+ int ret_irq = -1;
+
+ switch (channel) {
+ case CH_PPI0:
+ ret_irq = IRQ_PPI0;
+ break;
+ case CH_PPI1:
+ ret_irq = IRQ_PPI1;
+ break;
+ case CH_SPORT0_RX:
+ ret_irq = IRQ_SPORT0_RX;
+ break;
+ case CH_SPORT0_TX:
+ ret_irq = IRQ_SPORT0_TX;
+ break;
+ case CH_SPORT1_RX:
+ ret_irq = IRQ_SPORT1_RX;
+ break;
+ case CH_SPORT1_TX:
+ ret_irq = IRQ_SPORT1_TX;
+ break;
+ case CH_SPI:
+ ret_irq = IRQ_SPI;
+ break;
+ case CH_UART_RX:
+ ret_irq = IRQ_UART_RX;
+ break;
+ case CH_UART_TX:
+ ret_irq = IRQ_UART_TX;
+ break;
+
+ case CH_MEM_STREAM0_SRC:
+ case CH_MEM_STREAM0_DEST:
+ ret_irq = IRQ_MEM_DMA0;
+ break;
+ case CH_MEM_STREAM1_SRC:
+ case CH_MEM_STREAM1_DEST:
+ ret_irq = IRQ_MEM_DMA1;
+ break;
+ case CH_MEM_STREAM2_SRC:
+ case CH_MEM_STREAM2_DEST:
+ ret_irq = IRQ_MEM_DMA2;
+ break;
+ case CH_MEM_STREAM3_SRC:
+ case CH_MEM_STREAM3_DEST:
+ ret_irq = IRQ_MEM_DMA3;
+ break;
+
+ case CH_IMEM_STREAM0_SRC:
+ case CH_IMEM_STREAM0_DEST:
+ ret_irq = IRQ_IMEM_DMA0;
+ break;
+ case CH_IMEM_STREAM1_SRC:
+ case CH_IMEM_STREAM1_DEST:
+ ret_irq = IRQ_IMEM_DMA1;
+ break;
+ }
+ return ret_irq;
+}
+
+# define channel2irq(channel) bf561_channel2irq(channel)
+
+#endif
+
+/*------------------------------------------------------------------------------
+ * Request the specific DMA channel from the system.
+ *-----------------------------------------------------------------------------*/
+int request_dma(unsigned int channel, char *device_id)
+{
+
+ pr_debug("request_dma() : BEGIN \n");
+ mutex_lock(&(dma_ch[channel].dmalock));
+
+ if ((dma_ch[channel].chan_status == DMA_CHANNEL_REQUESTED)
+ || (dma_ch[channel].chan_status == DMA_CHANNEL_ENABLED)) {
+ mutex_unlock(&(dma_ch[channel].dmalock));
+ pr_debug("DMA CHANNEL IN USE \n");
+ return -EBUSY;
+ } else {
+ dma_ch[channel].chan_status = DMA_CHANNEL_REQUESTED;
+ pr_debug("DMA CHANNEL IS ALLOCATED \n");
+ }
+
+ mutex_unlock(&(dma_ch[channel].dmalock));
+
+ dma_ch[channel].device_id = device_id;
+ dma_ch[channel].irq_callback = NULL;
+
+ /* This is to be enabled by putting a restriction -
+ * you have to request DMA, before doing any operations on
+ * descriptor/channel
+ */
+ pr_debug("request_dma() : END \n");
+ return channel;
+}
+EXPORT_SYMBOL(request_dma);
+
+int set_dma_callback(unsigned int channel, dma_interrupt_t callback, void *data)
+{
+ int ret_irq = 0;
+
+ BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE
+ && channel < MAX_BLACKFIN_DMA_CHANNEL));
+
+ if (callback != NULL) {
+ int ret_val;
+ ret_irq = channel2irq(channel);
+
+ dma_ch[channel].data = data;
+
+ ret_val =
+ request_irq(ret_irq, (void *)callback, IRQF_DISABLED,
+ dma_ch[channel].device_id, data);
+ if (ret_val) {
+ printk(KERN_NOTICE
+ "Request irq in DMA engine failed.\n");
+ return -EPERM;
+ }
+ dma_ch[channel].irq_callback = callback;
+ }
+ return 0;
+}
+EXPORT_SYMBOL(set_dma_callback);
+
+void free_dma(unsigned int channel)
+{
+ int ret_irq;
+
+ pr_debug("freedma() : BEGIN \n");
+ BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE
+ && channel < MAX_BLACKFIN_DMA_CHANNEL));
+
+ /* Halt the DMA */
+ disable_dma(channel);
+ clear_dma_buffer(channel);
+
+ if (dma_ch[channel].irq_callback != NULL) {
+ ret_irq = channel2irq(channel);
+ free_irq(ret_irq, dma_ch[channel].data);
+ }
+
+ /* Clear the DMA Variable in the Channel */
+ mutex_lock(&(dma_ch[channel].dmalock));
+ dma_ch[channel].chan_status = DMA_CHANNEL_FREE;
+ mutex_unlock(&(dma_ch[channel].dmalock));
+
+ pr_debug("freedma() : END \n");
+}
+EXPORT_SYMBOL(free_dma);
+
+void dma_enable_irq(unsigned int channel)
+{
+ int ret_irq;
+
+ pr_debug("dma_enable_irq() : BEGIN \n");
+ BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE
+ && channel < MAX_BLACKFIN_DMA_CHANNEL));
+
+ ret_irq = channel2irq(channel);
+ enable_irq(ret_irq);
+}
+EXPORT_SYMBOL(dma_enable_irq);
+
+void dma_disable_irq(unsigned int channel)
+{
+ int ret_irq;
+
+ pr_debug("dma_disable_irq() : BEGIN \n");
+ BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE
+ && channel < MAX_BLACKFIN_DMA_CHANNEL));
+
+ ret_irq = channel2irq(channel);
+ disable_irq(ret_irq);
+}
+EXPORT_SYMBOL(dma_disable_irq);
+
+int dma_channel_active(unsigned int channel)
+{
+ if (dma_ch[channel].chan_status == DMA_CHANNEL_FREE) {
+ return 0;
+ } else {
+ return 1;
+ }
+}
+EXPORT_SYMBOL(dma_channel_active);
+
+/*------------------------------------------------------------------------------
+* stop the specific DMA channel.
+*-----------------------------------------------------------------------------*/
+void disable_dma(unsigned int channel)
+{
+ pr_debug("stop_dma() : BEGIN \n");
+
+ BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE
+ && channel < MAX_BLACKFIN_DMA_CHANNEL));
+
+ dma_ch[channel].regs->cfg &= ~DMAEN; /* Clean the enable bit */
+ SSYNC();
+ dma_ch[channel].chan_status = DMA_CHANNEL_REQUESTED;
+ /* Needs to be enabled Later */
+ pr_debug("stop_dma() : END \n");
+ return;
+}
+EXPORT_SYMBOL(disable_dma);
+
+void enable_dma(unsigned int channel)
+{
+ pr_debug("enable_dma() : BEGIN \n");
+
+ BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE
+ && channel < MAX_BLACKFIN_DMA_CHANNEL));
+
+ dma_ch[channel].chan_status = DMA_CHANNEL_ENABLED;
+ dma_ch[channel].regs->curr_x_count = 0;
+ dma_ch[channel].regs->curr_y_count = 0;
+
+ dma_ch[channel].regs->cfg |= DMAEN; /* Set the enable bit */
+ SSYNC();
+ pr_debug("enable_dma() : END \n");
+ return;
+}
+EXPORT_SYMBOL(enable_dma);
+
+/*------------------------------------------------------------------------------
+* Set the Start Address register for the specific DMA channel
+* This function can be used for register based DMA,
+* to setup the start address
+* addr: Starting address of the DMA Data to be transferred.
+*-----------------------------------------------------------------------------*/
+void set_dma_start_addr(unsigned int channel, unsigned long addr)
+{
+ pr_debug("set_dma_start_addr() : BEGIN \n");
+
+ BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE
+ && channel < MAX_BLACKFIN_DMA_CHANNEL));
+
+ dma_ch[channel].regs->start_addr = addr;
+ SSYNC();
+ pr_debug("set_dma_start_addr() : END\n");
+}
+EXPORT_SYMBOL(set_dma_start_addr);
+
+void set_dma_next_desc_addr(unsigned int channel, unsigned long addr)
+{
+ pr_debug("set_dma_next_desc_addr() : BEGIN \n");
+
+ BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE
+ && channel < MAX_BLACKFIN_DMA_CHANNEL));
+
+ dma_ch[channel].regs->next_desc_ptr = addr;
+ SSYNC();
+ pr_debug("set_dma_start_addr() : END\n");
+}
+EXPORT_SYMBOL(set_dma_next_desc_addr);
+
+void set_dma_x_count(unsigned int channel, unsigned short x_count)
+{
+ BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE
+ && channel < MAX_BLACKFIN_DMA_CHANNEL));
+
+ dma_ch[channel].regs->x_count = x_count;
+ SSYNC();
+}
+EXPORT_SYMBOL(set_dma_x_count);
+
+void set_dma_y_count(unsigned int channel, unsigned short y_count)
+{
+ BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE
+ && channel < MAX_BLACKFIN_DMA_CHANNEL));
+
+ dma_ch[channel].regs->y_count = y_count;
+ SSYNC();
+}
+EXPORT_SYMBOL(set_dma_y_count);
+
+void set_dma_x_modify(unsigned int channel, short x_modify)
+{
+ BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE
+ && channel < MAX_BLACKFIN_DMA_CHANNEL));
+
+ dma_ch[channel].regs->x_modify = x_modify;
+ SSYNC();
+}
+EXPORT_SYMBOL(set_dma_x_modify);
+
+void set_dma_y_modify(unsigned int channel, short y_modify)
+{
+ BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE
+ && channel < MAX_BLACKFIN_DMA_CHANNEL));
+
+ dma_ch[channel].regs->y_modify = y_modify;
+ SSYNC();
+}
+EXPORT_SYMBOL(set_dma_y_modify);
+
+void set_dma_config(unsigned int channel, unsigned short config)
+{
+ BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE
+ && channel < MAX_BLACKFIN_DMA_CHANNEL));
+
+ dma_ch[channel].regs->cfg = config;
+ SSYNC();
+}
+EXPORT_SYMBOL(set_dma_config);
+
+unsigned short
+set_bfin_dma_config(char direction, char flow_mode,
+ char intr_mode, char dma_mode, char width)
+{
+ unsigned short config;
+
+ config =
+ ((direction << 1) | (width << 2) | (dma_mode << 4) |
+ (intr_mode << 6) | (flow_mode << 12) | RESTART);
+ return config;
+}
+EXPORT_SYMBOL(set_bfin_dma_config);
+
+void set_dma_sg(unsigned int channel, struct dmasg * sg, int nr_sg)
+{
+ BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE
+ && channel < MAX_BLACKFIN_DMA_CHANNEL));
+
+ dma_ch[channel].regs->cfg |= ((nr_sg & 0x0F) << 8);
+
+ dma_ch[channel].regs->next_desc_ptr = (unsigned int)sg;
+
+ SSYNC();
+}
+EXPORT_SYMBOL(set_dma_sg);
+
+/*------------------------------------------------------------------------------
+ * Get the DMA status of a specific DMA channel from the system.
+ *-----------------------------------------------------------------------------*/
+unsigned short get_dma_curr_irqstat(unsigned int channel)
+{
+ BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE
+ && channel < MAX_BLACKFIN_DMA_CHANNEL));
+
+ return dma_ch[channel].regs->irq_status;
+}
+EXPORT_SYMBOL(get_dma_curr_irqstat);
+
+/*------------------------------------------------------------------------------
+ * Clear the DMA_DONE bit in DMA status. Stop the DMA completion interrupt.
+ *-----------------------------------------------------------------------------*/
+void clear_dma_irqstat(unsigned int channel)
+{
+ BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE
+ && channel < MAX_BLACKFIN_DMA_CHANNEL));
+ dma_ch[channel].regs->irq_status |= 3;
+}
+EXPORT_SYMBOL(clear_dma_irqstat);
+
+/*------------------------------------------------------------------------------
+ * Get current DMA xcount of a specific DMA channel from the system.
+ *-----------------------------------------------------------------------------*/
+unsigned short get_dma_curr_xcount(unsigned int channel)
+{
+ BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE
+ && channel < MAX_BLACKFIN_DMA_CHANNEL));
+
+ return dma_ch[channel].regs->curr_x_count;
+}
+EXPORT_SYMBOL(get_dma_curr_xcount);
+
+/*------------------------------------------------------------------------------
+ * Get current DMA ycount of a specific DMA channel from the system.
+ *-----------------------------------------------------------------------------*/
+unsigned short get_dma_curr_ycount(unsigned int channel)
+{
+ BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE
+ && channel < MAX_BLACKFIN_DMA_CHANNEL));
+
+ return dma_ch[channel].regs->curr_y_count;
+}
+EXPORT_SYMBOL(get_dma_curr_ycount);
+
+void *dma_memcpy(void *dest, const void *src, size_t size)
+{
+ int direction; /* 1 - address decrease, 0 - address increase */
+ int flag_align; /* 1 - address aligned, 0 - address unaligned */
+ int flag_2D; /* 1 - 2D DMA needed, 0 - 1D DMA needed */
+
+ if (size <= 0)
+ return NULL;
+
+ if ((unsigned long)src < memory_end)
+ blackfin_dcache_flush_range((unsigned int)src,
+ (unsigned int)(src + size));
+
+ bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR);
+
+ if ((unsigned long)src < (unsigned long)dest)
+ direction = 1;
+ else
+ direction = 0;
+
+ if ((((unsigned long)dest % 2) == 0) && (((unsigned long)src % 2) == 0)
+ && ((size % 2) == 0))
+ flag_align = 1;
+ else
+ flag_align = 0;
+
+ if (size > 0x10000) /* size > 64K */
+ flag_2D = 1;
+ else
+ flag_2D = 0;
+
+ /* Setup destination and source start address */
+ if (direction) {
+ if (flag_align) {
+ bfin_write_MDMA_D0_START_ADDR(dest + size - 2);
+ bfin_write_MDMA_S0_START_ADDR(src + size - 2);
+ } else {
+ bfin_write_MDMA_D0_START_ADDR(dest + size - 1);
+ bfin_write_MDMA_S0_START_ADDR(src + size - 1);
+ }
+ } else {
+ bfin_write_MDMA_D0_START_ADDR(dest);
+ bfin_write_MDMA_S0_START_ADDR(src);
+ }
+
+ /* Setup destination and source xcount */
+ if (flag_2D) {
+ if (flag_align) {
+ bfin_write_MDMA_D0_X_COUNT(1024 / 2);
+ bfin_write_MDMA_S0_X_COUNT(1024 / 2);
+ } else {
+ bfin_write_MDMA_D0_X_COUNT(1024);
+ bfin_write_MDMA_S0_X_COUNT(1024);
+ }
+ bfin_write_MDMA_D0_Y_COUNT(size >> 10);
+ bfin_write_MDMA_S0_Y_COUNT(size >> 10);
+ } else {
+ if (flag_align) {
+ bfin_write_MDMA_D0_X_COUNT(size / 2);
+ bfin_write_MDMA_S0_X_COUNT(size / 2);
+ } else {
+ bfin_write_MDMA_D0_X_COUNT(size);
+ bfin_write_MDMA_S0_X_COUNT(size);
+ }
+ }
+
+ /* Setup destination and source xmodify and ymodify */
+ if (direction) {
+ if (flag_align) {
+ bfin_write_MDMA_D0_X_MODIFY(-2);
+ bfin_write_MDMA_S0_X_MODIFY(-2);
+ if (flag_2D) {
+ bfin_write_MDMA_D0_Y_MODIFY(-2);
+ bfin_write_MDMA_S0_Y_MODIFY(-2);
+ }
+ } else {
+ bfin_write_MDMA_D0_X_MODIFY(-1);
+ bfin_write_MDMA_S0_X_MODIFY(-1);
+ if (flag_2D) {
+ bfin_write_MDMA_D0_Y_MODIFY(-1);
+ bfin_write_MDMA_S0_Y_MODIFY(-1);
+ }
+ }
+ } else {
+ if (flag_align) {
+ bfin_write_MDMA_D0_X_MODIFY(2);
+ bfin_write_MDMA_S0_X_MODIFY(2);
+ if (flag_2D) {
+ bfin_write_MDMA_D0_Y_MODIFY(2);
+ bfin_write_MDMA_S0_Y_MODIFY(2);
+ }
+ } else {
+ bfin_write_MDMA_D0_X_MODIFY(1);
+ bfin_write_MDMA_S0_X_MODIFY(1);
+ if (flag_2D) {
+ bfin_write_MDMA_D0_Y_MODIFY(1);
+ bfin_write_MDMA_S0_Y_MODIFY(1);
+ }
+ }
+ }
+
+ /* Enable source DMA */
+ if (flag_2D) {
+ if (flag_align) {
+ bfin_write_MDMA_S0_CONFIG(DMAEN | DMA2D | WDSIZE_16);
+ bfin_write_MDMA_D0_CONFIG(WNR | DI_EN | DMAEN | DMA2D | WDSIZE_16);
+ } else {
+ bfin_write_MDMA_S0_CONFIG(DMAEN | DMA2D);
+ bfin_write_MDMA_D0_CONFIG(WNR | DI_EN | DMAEN | DMA2D);
+ }
+ } else {
+ if (flag_align) {
+ bfin_write_MDMA_S0_CONFIG(DMAEN | WDSIZE_16);
+ bfin_write_MDMA_D0_CONFIG(WNR | DI_EN | DMAEN | WDSIZE_16);
+ } else {
+ bfin_write_MDMA_S0_CONFIG(DMAEN);
+ bfin_write_MDMA_D0_CONFIG(WNR | DI_EN | DMAEN);
+ }
+ }
+
+ while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE))
+ ;
+
+ bfin_write_MDMA_D0_IRQ_STATUS(bfin_read_MDMA_D0_IRQ_STATUS() |
+ (DMA_DONE | DMA_ERR));
+
+ bfin_write_MDMA_S0_CONFIG(0);
+ bfin_write_MDMA_D0_CONFIG(0);
+
+ if ((unsigned long)dest < memory_end)
+ blackfin_dcache_invalidate_range((unsigned int)dest,
+ (unsigned int)(dest + size));
+
+ return dest;
+}
+EXPORT_SYMBOL(dma_memcpy);
+
+void *safe_dma_memcpy(void *dest, const void *src, size_t size)
+{
+ int flags = 0;
+ void *addr;
+ local_irq_save(flags);
+ addr = dma_memcpy(dest, src, size);
+ local_irq_restore(flags);
+ return addr;
+}
+EXPORT_SYMBOL(safe_dma_memcpy);
diff --git a/arch/blackfin/kernel/bfin_gpio.c b/arch/blackfin/kernel/bfin_gpio.c
new file mode 100644
index 00000000000..e9f24a9a46b
--- /dev/null
+++ b/arch/blackfin/kernel/bfin_gpio.c
@@ -0,0 +1,637 @@
+/*
+ * File: arch/blackfin/kernel/bfin_gpio.c
+ * Based on:
+ * Author: Michael Hennerich (hennerich@blackfin.uclinux.org)
+ *
+ * Created:
+ * Description: GPIO Abstraction Layer
+ *
+ * Modified:
+ * Copyright 2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/*
+* Number BF537/6/4 BF561 BF533/2/1
+*
+* GPIO_0 PF0 PF0 PF0
+* GPIO_1 PF1 PF1 PF1
+* GPIO_2 PF2 PF2 PF2
+* GPIO_3 PF3 PF3 PF3
+* GPIO_4 PF4 PF4 PF4
+* GPIO_5 PF5 PF5 PF5
+* GPIO_6 PF6 PF6 PF6
+* GPIO_7 PF7 PF7 PF7
+* GPIO_8 PF8 PF8 PF8
+* GPIO_9 PF9 PF9 PF9
+* GPIO_10 PF10 PF10 PF10
+* GPIO_11 PF11 PF11 PF11
+* GPIO_12 PF12 PF12 PF12
+* GPIO_13 PF13 PF13 PF13
+* GPIO_14 PF14 PF14 PF14
+* GPIO_15 PF15 PF15 PF15
+* GPIO_16 PG0 PF16
+* GPIO_17 PG1 PF17
+* GPIO_18 PG2 PF18
+* GPIO_19 PG3 PF19
+* GPIO_20 PG4 PF20
+* GPIO_21 PG5 PF21
+* GPIO_22 PG6 PF22
+* GPIO_23 PG7 PF23
+* GPIO_24 PG8 PF24
+* GPIO_25 PG9 PF25
+* GPIO_26 PG10 PF26
+* GPIO_27 PG11 PF27
+* GPIO_28 PG12 PF28
+* GPIO_29 PG13 PF29
+* GPIO_30 PG14 PF30
+* GPIO_31 PG15 PF31
+* GPIO_32 PH0 PF32
+* GPIO_33 PH1 PF33
+* GPIO_34 PH2 PF34
+* GPIO_35 PH3 PF35
+* GPIO_36 PH4 PF36
+* GPIO_37 PH5 PF37
+* GPIO_38 PH6 PF38
+* GPIO_39 PH7 PF39
+* GPIO_40 PH8 PF40
+* GPIO_41 PH9 PF41
+* GPIO_42 PH10 PF42
+* GPIO_43 PH11 PF43
+* GPIO_44 PH12 PF44
+* GPIO_45 PH13 PF45
+* GPIO_46 PH14 PF46
+* GPIO_47 PH15 PF47
+*/
+
+#include <linux/module.h>
+#include <linux/err.h>
+#include <asm/blackfin.h>
+#include <asm/gpio.h>
+#include <linux/irq.h>
+
+#ifdef BF533_FAMILY
+static struct gpio_port_t *gpio_bankb[gpio_bank(MAX_BLACKFIN_GPIOS)] = {
+ (struct gpio_port_t *) FIO_FLAG_D,
+};
+#endif
+
+#ifdef BF537_FAMILY
+static struct gpio_port_t *gpio_bankb[gpio_bank(MAX_BLACKFIN_GPIOS)] = {
+ (struct gpio_port_t *) PORTFIO,
+ (struct gpio_port_t *) PORTGIO,
+ (struct gpio_port_t *) PORTHIO,
+};
+
+static unsigned short *port_fer[gpio_bank(MAX_BLACKFIN_GPIOS)] = {
+ (unsigned short *) PORTF_FER,
+ (unsigned short *) PORTG_FER,
+ (unsigned short *) PORTH_FER,
+};
+
+#endif
+
+#ifdef BF561_FAMILY
+static struct gpio_port_t *gpio_bankb[gpio_bank(MAX_BLACKFIN_GPIOS)] = {
+ (struct gpio_port_t *) FIO0_FLAG_D,
+ (struct gpio_port_t *) FIO1_FLAG_D,
+ (struct gpio_port_t *) FIO2_FLAG_D,
+};
+#endif
+
+static unsigned short reserved_map[gpio_bank(MAX_BLACKFIN_GPIOS)];
+
+#ifdef CONFIG_PM
+static unsigned short wakeup_map[gpio_bank(MAX_BLACKFIN_GPIOS)];
+static unsigned char wakeup_flags_map[MAX_BLACKFIN_GPIOS];
+static struct gpio_port_s gpio_bank_saved[gpio_bank(MAX_BLACKFIN_GPIOS)];
+
+#ifdef BF533_FAMILY
+static unsigned int sic_iwr_irqs[gpio_bank(MAX_BLACKFIN_GPIOS)] = {IRQ_PROG_INTB};
+#endif
+
+#ifdef BF537_FAMILY
+static unsigned int sic_iwr_irqs[gpio_bank(MAX_BLACKFIN_GPIOS)] = {IRQ_PROG_INTB, IRQ_PORTG_INTB, IRQ_MAC_TX};
+#endif
+
+#ifdef BF561_FAMILY
+static unsigned int sic_iwr_irqs[gpio_bank(MAX_BLACKFIN_GPIOS)] = {IRQ_PROG0_INTB, IRQ_PROG1_INTB, IRQ_PROG2_INTB};
+#endif
+
+#endif /* CONFIG_PM */
+
+inline int check_gpio(unsigned short gpio)
+{
+ if (gpio > MAX_BLACKFIN_GPIOS)
+ return -EINVAL;
+ return 0;
+}
+
+#ifdef BF537_FAMILY
+void port_setup(unsigned short gpio, unsigned short usage)
+{
+ if (usage == GPIO_USAGE) {
+ if (*port_fer[gpio_bank(gpio)] & gpio_bit(gpio))
+ printk(KERN_WARNING "bfin-gpio: Possible Conflict with Peripheral "
+ "usage and GPIO %d detected!\n", gpio);
+ *port_fer[gpio_bank(gpio)] &= ~gpio_bit(gpio);
+ } else
+ *port_fer[gpio_bank(gpio)] |= gpio_bit(gpio);
+ SSYNC();
+}
+#else
+# define port_setup(...) do { } while (0)
+#endif
+
+
+void default_gpio(unsigned short gpio)
+{
+ unsigned short bank,bitmask;
+
+ bank = gpio_bank(gpio);
+ bitmask = gpio_bit(gpio);
+
+ gpio_bankb[bank]->maska_clear = bitmask;
+ gpio_bankb[bank]->maskb_clear = bitmask;
+ SSYNC();
+ gpio_bankb[bank]->inen &= ~bitmask;
+ gpio_bankb[bank]->dir &= ~bitmask;
+ gpio_bankb[bank]->polar &= ~bitmask;
+ gpio_bankb[bank]->both &= ~bitmask;
+ gpio_bankb[bank]->edge &= ~bitmask;
+}
+
+
+int __init bfin_gpio_init(void)
+{
+ int i;
+
+ printk(KERN_INFO "Blackfin GPIO Controller\n");
+
+ for (i = 0; i < MAX_BLACKFIN_GPIOS; i+=GPIO_BANKSIZE)
+ reserved_map[gpio_bank(i)] = 0;
+
+#if defined(BF537_FAMILY) && (defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE))
+# if defined(CONFIG_BFIN_MAC_RMII)
+ reserved_map[PORT_H] = 0xC373;
+# else
+ reserved_map[PORT_H] = 0xFFFF;
+# endif
+#endif
+
+ return 0;
+}
+
+arch_initcall(bfin_gpio_init);
+
+
+/***********************************************************
+*
+* FUNCTIONS: Blackfin General Purpose Ports Access Functions
+*
+* INPUTS/OUTPUTS:
+* gpio - GPIO Number between 0 and MAX_BLACKFIN_GPIOS
+*
+*
+* DESCRIPTION: These functions abstract direct register access
+* to Blackfin processor General Purpose
+* Ports Regsiters
+*
+* CAUTION: These functions do not belong to the GPIO Driver API
+*************************************************************
+* MODIFICATION HISTORY :
+**************************************************************/
+
+/* Set a specific bit */
+
+#define SET_GPIO(name) \
+void set_gpio_ ## name(unsigned short gpio, unsigned short arg) \
+{ \
+ unsigned long flags; \
+ BUG_ON(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio))); \
+ local_irq_save(flags); \
+ if (arg) \
+ gpio_bankb[gpio_bank(gpio)]->name |= gpio_bit(gpio); \
+ else \
+ gpio_bankb[gpio_bank(gpio)]->name &= ~gpio_bit(gpio); \
+ local_irq_restore(flags); \
+} \
+EXPORT_SYMBOL(set_gpio_ ## name);
+
+SET_GPIO(dir)
+SET_GPIO(inen)
+SET_GPIO(polar)
+SET_GPIO(edge)
+SET_GPIO(both)
+
+
+#define SET_GPIO_SC(name) \
+void set_gpio_ ## name(unsigned short gpio, unsigned short arg) \
+{ \
+ BUG_ON(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio))); \
+ if (arg) \
+ gpio_bankb[gpio_bank(gpio)]->name ## _set = gpio_bit(gpio); \
+ else \
+ gpio_bankb[gpio_bank(gpio)]->name ## _clear = gpio_bit(gpio); \
+} \
+EXPORT_SYMBOL(set_gpio_ ## name);
+
+SET_GPIO_SC(maska)
+SET_GPIO_SC(maskb)
+
+#if defined(ANOMALY_05000311)
+void set_gpio_data(unsigned short gpio, unsigned short arg)
+{
+ unsigned long flags;
+ BUG_ON(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio)));
+ local_irq_save(flags);
+ if (arg)
+ gpio_bankb[gpio_bank(gpio)]->data_set = gpio_bit(gpio);
+ else
+ gpio_bankb[gpio_bank(gpio)]->data_clear = gpio_bit(gpio);
+ bfin_read_CHIPID();
+ local_irq_restore(flags);
+}
+EXPORT_SYMBOL(set_gpio_data);
+#else
+SET_GPIO_SC(data)
+#endif
+
+
+#if defined(ANOMALY_05000311)
+void set_gpio_toggle(unsigned short gpio)
+{
+ unsigned long flags;
+ BUG_ON(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio)));
+ local_irq_save(flags);
+ gpio_bankb[gpio_bank(gpio)]->toggle = gpio_bit(gpio);
+ bfin_read_CHIPID();
+ local_irq_restore(flags);
+}
+#else
+void set_gpio_toggle(unsigned short gpio)
+{
+ BUG_ON(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio)));
+ gpio_bankb[gpio_bank(gpio)]->toggle = gpio_bit(gpio);
+}
+#endif
+EXPORT_SYMBOL(set_gpio_toggle);
+
+
+/*Set current PORT date (16-bit word)*/
+
+#define SET_GPIO_P(name) \
+void set_gpiop_ ## name(unsigned short gpio, unsigned short arg) \
+{ \
+ gpio_bankb[gpio_bank(gpio)]->name = arg; \
+} \
+EXPORT_SYMBOL(set_gpiop_ ## name);
+
+SET_GPIO_P(dir)
+SET_GPIO_P(inen)
+SET_GPIO_P(polar)
+SET_GPIO_P(edge)
+SET_GPIO_P(both)
+SET_GPIO_P(maska)
+SET_GPIO_P(maskb)
+
+
+#if defined(ANOMALY_05000311)
+void set_gpiop_data(unsigned short gpio, unsigned short arg)
+{
+ unsigned long flags;
+ local_irq_save(flags);
+ gpio_bankb[gpio_bank(gpio)]->data = arg;
+ bfin_read_CHIPID();
+ local_irq_restore(flags);
+}
+EXPORT_SYMBOL(set_gpiop_data);
+#else
+SET_GPIO_P(data)
+#endif
+
+
+
+/* Get a specific bit */
+
+#define GET_GPIO(name) \
+unsigned short get_gpio_ ## name(unsigned short gpio) \
+{ \
+ return (0x01 & (gpio_bankb[gpio_bank(gpio)]->name >> gpio_sub_n(gpio))); \
+} \
+EXPORT_SYMBOL(get_gpio_ ## name);
+
+GET_GPIO(dir)
+GET_GPIO(inen)
+GET_GPIO(polar)
+GET_GPIO(edge)
+GET_GPIO(both)
+GET_GPIO(maska)
+GET_GPIO(maskb)
+
+
+#if defined(ANOMALY_05000311)
+unsigned short get_gpio_data(unsigned short gpio)
+{
+ unsigned long flags;
+ unsigned short ret;
+ BUG_ON(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio)));
+ local_irq_save(flags);
+ ret = 0x01 & (gpio_bankb[gpio_bank(gpio)]->data >> gpio_sub_n(gpio));
+ bfin_read_CHIPID();
+ local_irq_restore(flags);
+ return ret;
+}
+EXPORT_SYMBOL(get_gpio_data);
+#else
+GET_GPIO(data)
+#endif
+
+/*Get current PORT date (16-bit word)*/
+
+#define GET_GPIO_P(name) \
+unsigned short get_gpiop_ ## name(unsigned short gpio) \
+{ \
+ return (gpio_bankb[gpio_bank(gpio)]->name);\
+} \
+EXPORT_SYMBOL(get_gpiop_ ## name);
+
+GET_GPIO_P(dir)
+GET_GPIO_P(inen)
+GET_GPIO_P(polar)
+GET_GPIO_P(edge)
+GET_GPIO_P(both)
+GET_GPIO_P(maska)
+GET_GPIO_P(maskb)
+
+#if defined(ANOMALY_05000311)
+unsigned short get_gpiop_data(unsigned short gpio)
+{
+ unsigned long flags;
+ unsigned short ret;
+ local_irq_save(flags);
+ ret = gpio_bankb[gpio_bank(gpio)]->data;
+ bfin_read_CHIPID();
+ local_irq_restore(flags);
+ return ret;
+}
+EXPORT_SYMBOL(get_gpiop_data);
+#else
+GET_GPIO_P(data)
+#endif
+
+#ifdef CONFIG_PM
+/***********************************************************
+*
+* FUNCTIONS: Blackfin PM Setup API
+*
+* INPUTS/OUTPUTS:
+* gpio - GPIO Number between 0 and MAX_BLACKFIN_GPIOS
+* type -
+* PM_WAKE_RISING
+* PM_WAKE_FALLING
+* PM_WAKE_HIGH
+* PM_WAKE_LOW
+* PM_WAKE_BOTH_EDGES
+*
+* DESCRIPTION: Blackfin PM Driver API
+*
+* CAUTION:
+*************************************************************
+* MODIFICATION HISTORY :
+**************************************************************/
+int gpio_pm_wakeup_request(unsigned short gpio, unsigned char type)
+{
+ unsigned long flags;
+
+ if ((check_gpio(gpio) < 0) || !type)
+ return -EINVAL;
+
+ local_irq_save(flags);
+
+ wakeup_map[gpio_bank(gpio)] |= gpio_bit(gpio);
+ wakeup_flags_map[gpio] = type;
+ local_irq_restore(flags);
+
+ return 0;
+}
+EXPORT_SYMBOL(gpio_pm_wakeup_request);
+
+void gpio_pm_wakeup_free(unsigned short gpio)
+{
+ unsigned long flags;
+
+ if (check_gpio(gpio) < 0)
+ return;
+
+ local_irq_save(flags);
+
+ wakeup_map[gpio_bank(gpio)] &= ~gpio_bit(gpio);
+
+ local_irq_restore(flags);
+}
+EXPORT_SYMBOL(gpio_pm_wakeup_free);
+
+static int bfin_gpio_wakeup_type(unsigned short gpio, unsigned char type)
+{
+ port_setup(gpio, GPIO_USAGE);
+ set_gpio_dir(gpio, 0);
+ set_gpio_inen(gpio, 1);
+
+ if (type & (PM_WAKE_RISING | PM_WAKE_FALLING))
+ set_gpio_edge(gpio, 1);
+ else
+ set_gpio_edge(gpio, 0);
+
+ if ((type & (PM_WAKE_BOTH_EDGES)) == (PM_WAKE_BOTH_EDGES))
+ set_gpio_both(gpio, 1);
+ else
+ set_gpio_both(gpio, 0);
+
+ if ((type & (PM_WAKE_FALLING | PM_WAKE_LOW)))
+ set_gpio_polar(gpio, 1);
+ else
+ set_gpio_polar(gpio, 0);
+
+ SSYNC();
+
+ return 0;
+}
+
+u32 gpio_pm_setup(void)
+{
+ u32 sic_iwr = 0;
+ u16 bank, mask, i, gpio;
+
+ for (i = 0; i < MAX_BLACKFIN_GPIOS; i+=GPIO_BANKSIZE) {
+ mask = wakeup_map[gpio_bank(i)];
+ bank = gpio_bank(i);
+
+ gpio_bank_saved[bank].maskb = gpio_bankb[bank]->maskb;
+ gpio_bankb[bank]->maskb = 0;
+
+ if (mask) {
+#ifdef BF537_FAMILY
+ gpio_bank_saved[bank].fer = *port_fer[bank];
+#endif
+ gpio_bank_saved[bank].inen = gpio_bankb[bank]->inen;
+ gpio_bank_saved[bank].polar = gpio_bankb[bank]->polar;
+ gpio_bank_saved[bank].dir = gpio_bankb[bank]->dir;
+ gpio_bank_saved[bank].edge = gpio_bankb[bank]->edge;
+ gpio_bank_saved[bank].both = gpio_bankb[bank]->both;
+
+ gpio = i;
+
+ while (mask) {
+ if (mask & 1) {
+ bfin_gpio_wakeup_type(gpio, wakeup_flags_map[gpio]);
+ set_gpio_data(gpio, 0); /*Clear*/
+ }
+ gpio++;
+ mask >>= 1;
+ }
+
+ sic_iwr |= 1 << (sic_iwr_irqs[bank] - (IRQ_CORETMR + 1));
+ gpio_bankb[bank]->maskb_set = wakeup_map[gpio_bank(i)];
+ }
+ }
+
+ if (sic_iwr)
+ return sic_iwr;
+ else
+ return IWR_ENABLE_ALL;
+}
+
+
+void gpio_pm_restore(void)
+{
+ u16 bank, mask, i;
+
+ for (i = 0; i < MAX_BLACKFIN_GPIOS; i+=GPIO_BANKSIZE) {
+ mask = wakeup_map[gpio_bank(i)];
+ bank = gpio_bank(i);
+
+ if (mask) {
+#ifdef BF537_FAMILY
+ *port_fer[bank] = gpio_bank_saved[bank].fer;
+#endif
+ gpio_bankb[bank]->inen = gpio_bank_saved[bank].inen;
+ gpio_bankb[bank]->dir = gpio_bank_saved[bank].dir;
+ gpio_bankb[bank]->polar = gpio_bank_saved[bank].polar;
+ gpio_bankb[bank]->edge = gpio_bank_saved[bank].edge;
+ gpio_bankb[bank]->both = gpio_bank_saved[bank].both;
+ }
+
+ gpio_bankb[bank]->maskb = gpio_bank_saved[bank].maskb;
+ }
+}
+
+#endif
+
+/***********************************************************
+*
+* FUNCTIONS: Blackfin GPIO Driver
+*
+* INPUTS/OUTPUTS:
+* gpio - GPIO Number between 0 and MAX_BLACKFIN_GPIOS
+*
+*
+* DESCRIPTION: Blackfin GPIO Driver API
+*
+* CAUTION:
+*************************************************************
+* MODIFICATION HISTORY :
+**************************************************************/
+
+int gpio_request(unsigned short gpio, const char *label)
+{
+ unsigned long flags;
+
+ if (check_gpio(gpio) < 0)
+ return -EINVAL;
+
+ local_irq_save(flags);
+
+ if (unlikely(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio))) {
+ printk(KERN_ERR "bfin-gpio: GPIO %d is already reserved!\n", gpio);
+ dump_stack();
+ local_irq_restore(flags);
+ return -EBUSY;
+ }
+ reserved_map[gpio_bank(gpio)] |= gpio_bit(gpio);
+
+ local_irq_restore(flags);
+
+ port_setup(gpio, GPIO_USAGE);
+
+ return 0;
+}
+EXPORT_SYMBOL(gpio_request);
+
+
+void gpio_free(unsigned short gpio)
+{
+ unsigned long flags;
+
+ if (check_gpio(gpio) < 0)
+ return;
+
+ local_irq_save(flags);
+
+ if (unlikely(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio)))) {
+ printk(KERN_ERR "bfin-gpio: GPIO %d wasn't reserved!\n", gpio);
+ dump_stack();
+ local_irq_restore(flags);
+ return;
+ }
+
+ default_gpio(gpio);
+
+ reserved_map[gpio_bank(gpio)] &= ~gpio_bit(gpio);
+
+ local_irq_restore(flags);
+}
+EXPORT_SYMBOL(gpio_free);
+
+
+void gpio_direction_input(unsigned short gpio)
+{
+ unsigned long flags;
+
+ BUG_ON(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio)));
+
+ local_irq_save(flags);
+ gpio_bankb[gpio_bank(gpio)]->dir &= ~gpio_bit(gpio);
+ gpio_bankb[gpio_bank(gpio)]->inen |= gpio_bit(gpio);
+ local_irq_restore(flags);
+}
+EXPORT_SYMBOL(gpio_direction_input);
+
+void gpio_direction_output(unsigned short gpio)
+{
+ unsigned long flags;
+
+ BUG_ON(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio)));
+
+ local_irq_save(flags);
+ gpio_bankb[gpio_bank(gpio)]->inen &= ~gpio_bit(gpio);
+ gpio_bankb[gpio_bank(gpio)]->dir |= gpio_bit(gpio);
+ local_irq_restore(flags);
+}
+EXPORT_SYMBOL(gpio_direction_output);
diff --git a/arch/blackfin/kernel/bfin_ksyms.c b/arch/blackfin/kernel/bfin_ksyms.c
new file mode 100644
index 00000000000..f64ecb638fa
--- /dev/null
+++ b/arch/blackfin/kernel/bfin_ksyms.c
@@ -0,0 +1,119 @@
+/*
+ * File: arch/blackfin/kernel/bfin_ksyms.c
+ * Based on: none - original work
+ * Author:
+ *
+ * Created:
+ * Description:
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/module.h>
+#include <asm/irq.h>
+#include <asm/checksum.h>
+#include <asm/cacheflush.h>
+#include <asm/uaccess.h>
+
+/* platform dependent support */
+
+EXPORT_SYMBOL(__ioremap);
+EXPORT_SYMBOL(strcmp);
+EXPORT_SYMBOL(strncmp);
+EXPORT_SYMBOL(dump_thread);
+
+EXPORT_SYMBOL(ip_fast_csum);
+
+EXPORT_SYMBOL(kernel_thread);
+
+EXPORT_SYMBOL(__up);
+EXPORT_SYMBOL(__down);
+EXPORT_SYMBOL(__down_trylock);
+EXPORT_SYMBOL(__down_interruptible);
+
+EXPORT_SYMBOL(is_in_rom);
+
+/* Networking helper routines. */
+EXPORT_SYMBOL(csum_partial_copy);
+
+/* The following are special because they're not called
+ * explicitly (the C compiler generates them). Fortunately,
+ * their interface isn't gonna change any time soon now, so
+ * it's OK to leave it out of version control.
+ */
+EXPORT_SYMBOL(memcpy);
+EXPORT_SYMBOL(memset);
+EXPORT_SYMBOL(memcmp);
+EXPORT_SYMBOL(memmove);
+EXPORT_SYMBOL(memchr);
+EXPORT_SYMBOL(get_wchan);
+
+/*
+ * libgcc functions - functions that are used internally by the
+ * compiler... (prototypes are not correct though, but that
+ * doesn't really matter since they're not versioned).
+ */
+extern void __ashldi3(void);
+extern void __ashrdi3(void);
+extern void __smulsi3_highpart(void);
+extern void __umulsi3_highpart(void);
+extern void __divsi3(void);
+extern void __lshrdi3(void);
+extern void __modsi3(void);
+extern void __muldi3(void);
+extern void __udivsi3(void);
+extern void __umodsi3(void);
+
+/* gcc lib functions */
+EXPORT_SYMBOL(__ashldi3);
+EXPORT_SYMBOL(__ashrdi3);
+EXPORT_SYMBOL(__umulsi3_highpart);
+EXPORT_SYMBOL(__smulsi3_highpart);
+EXPORT_SYMBOL(__divsi3);
+EXPORT_SYMBOL(__lshrdi3);
+EXPORT_SYMBOL(__modsi3);
+EXPORT_SYMBOL(__muldi3);
+EXPORT_SYMBOL(__udivsi3);
+EXPORT_SYMBOL(__umodsi3);
+
+EXPORT_SYMBOL(outsb);
+EXPORT_SYMBOL(insb);
+EXPORT_SYMBOL(outsw);
+EXPORT_SYMBOL(insw);
+EXPORT_SYMBOL(outsl);
+EXPORT_SYMBOL(insl);
+EXPORT_SYMBOL(irq_flags);
+EXPORT_SYMBOL(iounmap);
+EXPORT_SYMBOL(blackfin_dcache_invalidate_range);
+EXPORT_SYMBOL(blackfin_icache_dcache_flush_range);
+EXPORT_SYMBOL(blackfin_icache_flush_range);
+EXPORT_SYMBOL(blackfin_dcache_flush_range);
+EXPORT_SYMBOL(blackfin_dflush_page);
+
+EXPORT_SYMBOL(csum_partial);
+EXPORT_SYMBOL(__init_begin);
+EXPORT_SYMBOL(__init_end);
+EXPORT_SYMBOL(_ebss_l1);
+EXPORT_SYMBOL(_stext_l1);
+EXPORT_SYMBOL(_etext_l1);
+EXPORT_SYMBOL(_sdata_l1);
+EXPORT_SYMBOL(_ebss_b_l1);
+EXPORT_SYMBOL(_sdata_b_l1);
diff --git a/arch/blackfin/kernel/dma-mapping.c b/arch/blackfin/kernel/dma-mapping.c
new file mode 100644
index 00000000000..539eb24e062
--- /dev/null
+++ b/arch/blackfin/kernel/dma-mapping.c
@@ -0,0 +1,183 @@
+/*
+ * File: arch/blackfin/kernel/dma-mapping.c
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description: Dynamic DMA mapping support.
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/bootmem.h>
+#include <linux/spinlock.h>
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <asm/cacheflush.h>
+#include <asm/io.h>
+#include <asm/bfin-global.h>
+
+static spinlock_t dma_page_lock;
+static unsigned int *dma_page;
+static unsigned int dma_pages;
+static unsigned long dma_base;
+static unsigned long dma_size;
+static unsigned int dma_initialized;
+
+void dma_alloc_init(unsigned long start, unsigned long end)
+{
+ spin_lock_init(&dma_page_lock);
+ dma_initialized = 0;
+
+ dma_page = (unsigned int *)__get_free_page(GFP_KERNEL);
+ memset(dma_page, 0, PAGE_SIZE);
+ dma_base = PAGE_ALIGN(start);
+ dma_size = PAGE_ALIGN(end) - PAGE_ALIGN(start);
+ dma_pages = dma_size >> PAGE_SHIFT;
+ memset((void *)dma_base, 0, DMA_UNCACHED_REGION);
+ dma_initialized = 1;
+
+ printk(KERN_INFO "%s: dma_page @ 0x%p - %d pages at 0x%08lx\n", __FUNCTION__,
+ dma_page, dma_pages, dma_base);
+}
+
+static inline unsigned int get_pages(size_t size)
+{
+ return ((size - 1) >> PAGE_SHIFT) + 1;
+}
+
+static unsigned long __alloc_dma_pages(unsigned int pages)
+{
+ unsigned long ret = 0, flags;
+ int i, count = 0;
+
+ if (dma_initialized == 0)
+ dma_alloc_init(_ramend - DMA_UNCACHED_REGION, _ramend);
+
+ spin_lock_irqsave(&dma_page_lock, flags);
+
+ for (i = 0; i < dma_pages;) {
+ if (dma_page[i++] == 0) {
+ if (++count == pages) {
+ while (count--)
+ dma_page[--i] = 1;
+ ret = dma_base + (i << PAGE_SHIFT);
+ break;
+ }
+ } else
+ count = 0;
+ }
+ spin_unlock_irqrestore(&dma_page_lock, flags);
+ return ret;
+}
+
+static void __free_dma_pages(unsigned long addr, unsigned int pages)
+{
+ unsigned long page = (addr - dma_base) >> PAGE_SHIFT;
+ unsigned long flags;
+ int i;
+
+ if ((page + pages) > dma_pages) {
+ printk(KERN_ERR "%s: freeing outside range.\n", __FUNCTION__);
+ BUG();
+ }
+
+ spin_lock_irqsave(&dma_page_lock, flags);
+ for (i = page; i < page + pages; i++) {
+ dma_page[i] = 0;
+ }
+ spin_unlock_irqrestore(&dma_page_lock, flags);
+}
+
+void *dma_alloc_coherent(struct device *dev, size_t size,
+ dma_addr_t * dma_handle, gfp_t gfp)
+{
+ void *ret;
+
+ ret = (void *)__alloc_dma_pages(get_pages(size));
+
+ if (ret) {
+ memset(ret, 0, size);
+ *dma_handle = virt_to_phys(ret);
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL(dma_alloc_coherent);
+
+void
+dma_free_coherent(struct device *dev, size_t size, void *vaddr,
+ dma_addr_t dma_handle)
+{
+ __free_dma_pages((unsigned long)vaddr, get_pages(size));
+}
+EXPORT_SYMBOL(dma_free_coherent);
+
+/*
+ * Dummy functions defined for some existing drivers
+ */
+
+dma_addr_t
+dma_map_single(struct device *dev, void *ptr, size_t size,
+ enum dma_data_direction direction)
+{
+ BUG_ON(direction == DMA_NONE);
+
+ invalidate_dcache_range((unsigned long)ptr,
+ (unsigned long)ptr + size);
+
+ return (dma_addr_t) ptr;
+}
+EXPORT_SYMBOL(dma_map_single);
+
+int
+dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
+ enum dma_data_direction direction)
+{
+ int i;
+
+ BUG_ON(direction == DMA_NONE);
+
+ for (i = 0; i < nents; i++)
+ invalidate_dcache_range(sg_dma_address(&sg[i]),
+ sg_dma_address(&sg[i]) +
+ sg_dma_len(&sg[i]));
+
+ return nents;
+}
+EXPORT_SYMBOL(dma_map_sg);
+
+void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
+ enum dma_data_direction direction)
+{
+ BUG_ON(direction == DMA_NONE);
+}
+EXPORT_SYMBOL(dma_unmap_single);
+
+void dma_unmap_sg(struct device *dev, struct scatterlist *sg,
+ int nhwentries, enum dma_data_direction direction)
+{
+ BUG_ON(direction == DMA_NONE);
+}
+EXPORT_SYMBOL(dma_unmap_sg);
diff --git a/arch/blackfin/kernel/dualcore_test.c b/arch/blackfin/kernel/dualcore_test.c
new file mode 100644
index 00000000000..8b89c99f9df
--- /dev/null
+++ b/arch/blackfin/kernel/dualcore_test.c
@@ -0,0 +1,49 @@
+/*
+ * File: arch/blackfin/kernel/dualcore_test.c
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description: Small test code for CoreB on a BF561
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+
+static int *testarg = (int*)0xfeb00000;
+
+static int test_init(void)
+{
+ *testarg = 1;
+ printk("Dual core test module inserted: set testarg = [%d]\n @ [%p]\n",
+ *testarg, testarg);
+ return 0;
+}
+
+static void test_exit(void)
+{
+ printk("Dual core test module removed: testarg = [%d]\n", *testarg);
+}
+
+module_init(test_init);
+module_exit(test_exit);
diff --git a/arch/blackfin/kernel/entry.S b/arch/blackfin/kernel/entry.S
new file mode 100644
index 00000000000..5880b270bd5
--- /dev/null
+++ b/arch/blackfin/kernel/entry.S
@@ -0,0 +1,94 @@
+/*
+ * File: arch/blackfin/kernel/entry.S
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/linkage.h>
+#include <asm/thread_info.h>
+#include <asm/errno.h>
+#include <asm/asm-offsets.h>
+
+#include <asm/mach-common/context.S>
+
+#ifdef CONFIG_EXCPT_IRQ_SYSC_L1
+.section .l1.text
+#else
+.text
+#endif
+
+ENTRY(_ret_from_fork)
+ SP += -12;
+ call _schedule_tail;
+ SP += 12;
+ r0 = [sp + PT_IPEND];
+ cc = bittst(r0,1);
+ if cc jump .Lin_kernel;
+ RESTORE_CONTEXT
+ rti;
+.Lin_kernel:
+ bitclr(r0,1);
+ [sp + PT_IPEND] = r0;
+ /* do a 'fake' RTI by jumping to [RETI]
+ * to avoid clearing supervisor mode in child
+ */
+ RESTORE_ALL_SYS
+ p0 = reti;
+ jump (p0);
+
+ENTRY(_sys_fork)
+ r0 = -EINVAL;
+ rts;
+
+ENTRY(_sys_vfork)
+ r0 = sp;
+ r0 += 24;
+ [--sp] = rets;
+ SP += -12;
+ call _bfin_vfork;
+ SP += 12;
+ rets = [sp++];
+ rts;
+
+ENTRY(_sys_clone)
+ r0 = sp;
+ r0 += 24;
+ [--sp] = rets;
+ SP += -12;
+ call _bfin_clone;
+ SP += 12;
+ rets = [sp++];
+ rts;
+
+ENTRY(_sys_rt_sigreturn)
+ r0 = sp;
+ r0 += 24;
+ [--sp] = rets;
+ SP += -12;
+ call _do_rt_sigreturn;
+ SP += 12;
+ rets = [sp++];
+ rts;
diff --git a/arch/blackfin/kernel/flat.c b/arch/blackfin/kernel/flat.c
new file mode 100644
index 00000000000..a92587b628b
--- /dev/null
+++ b/arch/blackfin/kernel/flat.c
@@ -0,0 +1,101 @@
+/*
+ * arch/blackfin/kernel/flat.c
+ *
+ * Copyright (C) 2007 Analog Devices, Inc.
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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/module.h>
+#include <linux/sched.h>
+#include <linux/flat.h>
+
+#define FLAT_BFIN_RELOC_TYPE_16_BIT 0
+#define FLAT_BFIN_RELOC_TYPE_16H_BIT 1
+#define FLAT_BFIN_RELOC_TYPE_32_BIT 2
+
+unsigned long bfin_get_addr_from_rp(unsigned long *ptr,
+ unsigned long relval,
+ unsigned long flags,
+ unsigned long *persistent)
+{
+ unsigned short *usptr = (unsigned short *)ptr;
+ int type = (relval >> 26) & 7;
+ unsigned long val;
+
+ switch (type) {
+ case FLAT_BFIN_RELOC_TYPE_16_BIT:
+ case FLAT_BFIN_RELOC_TYPE_16H_BIT:
+ usptr = (unsigned short *)ptr;
+ pr_debug("*usptr = %x", get_unaligned(usptr));
+ val = get_unaligned(usptr);
+ val += *persistent;
+ break;
+
+ case FLAT_BFIN_RELOC_TYPE_32_BIT:
+ pr_debug("*ptr = %lx", get_unaligned(ptr));
+ val = get_unaligned(ptr);
+ break;
+
+ default:
+ pr_debug("BINFMT_FLAT: Unknown relocation type %x\n",
+ type);
+
+ return 0;
+ }
+
+ /*
+ * Stack-relative relocs contain the offset into the stack, we
+ * have to add the stack's start address here and return 1 from
+ * flat_addr_absolute to prevent the normal address calculations
+ */
+ if (relval & (1 << 29))
+ return val + current->mm->context.end_brk;
+
+ if ((flags & FLAT_FLAG_GOTPIC) == 0)
+ val = htonl(val);
+ return val;
+}
+EXPORT_SYMBOL(bfin_get_addr_from_rp);
+
+/*
+ * Insert the address ADDR into the symbol reference at RP;
+ * RELVAL is the raw relocation-table entry from which RP is derived
+ */
+void bfin_put_addr_at_rp(unsigned long *ptr, unsigned long addr,
+ unsigned long relval)
+{
+ unsigned short *usptr = (unsigned short *)ptr;
+ int type = (relval >> 26) & 7;
+
+ switch (type) {
+ case FLAT_BFIN_RELOC_TYPE_16_BIT:
+ put_unaligned(addr, usptr);
+ pr_debug("new value %x at %p", get_unaligned(usptr),
+ usptr);
+ break;
+
+ case FLAT_BFIN_RELOC_TYPE_16H_BIT:
+ put_unaligned(addr >> 16, usptr);
+ pr_debug("new value %x", get_unaligned(usptr));
+ break;
+
+ case FLAT_BFIN_RELOC_TYPE_32_BIT:
+ put_unaligned(addr, ptr);
+ pr_debug("new ptr =%lx", get_unaligned(ptr));
+ break;
+ }
+}
+EXPORT_SYMBOL(bfin_put_addr_at_rp);
diff --git a/arch/blackfin/kernel/init_task.c b/arch/blackfin/kernel/init_task.c
new file mode 100644
index 00000000000..b45188f8512
--- /dev/null
+++ b/arch/blackfin/kernel/init_task.c
@@ -0,0 +1,60 @@
+/*
+ * File: arch/blackfin/kernel/init_task.c
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description: This file contains the simple DMA Implementation for Blackfin
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/init_task.h>
+#include <linux/mqueue.h>
+
+static struct fs_struct init_fs = INIT_FS;
+static struct files_struct init_files = INIT_FILES;
+static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
+static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
+
+struct mm_struct init_mm = INIT_MM(init_mm);
+EXPORT_SYMBOL(init_mm);
+
+/*
+ * Initial task structure.
+ *
+ * All other task structs will be allocated on slabs in fork.c
+ */
+struct task_struct init_task = INIT_TASK(init_task);
+EXPORT_SYMBOL(init_task);
+
+/*
+ * Initial thread structure.
+ *
+ * We need to make sure that this is 8192-byte aligned due to the
+ * way process stacks are handled. This is done by having a special
+ * "init_task" linker map entry.
+ */
+union thread_union init_thread_union
+ __attribute__ ((__section__(".data.init_task"))) = {
+INIT_THREAD_INFO(init_task)};
diff --git a/arch/blackfin/kernel/irqchip.c b/arch/blackfin/kernel/irqchip.c
new file mode 100644
index 00000000000..df5bf022cf7
--- /dev/null
+++ b/arch/blackfin/kernel/irqchip.c
@@ -0,0 +1,147 @@
+/*
+ * File: arch/blackfin/kernel/irqchip.c
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description: This file contains the simple DMA Implementation for Blackfin
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/kernel_stat.h>
+#include <linux/module.h>
+#include <linux/random.h>
+#include <linux/seq_file.h>
+#include <linux/kallsyms.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+
+static unsigned long irq_err_count;
+static spinlock_t irq_controller_lock;
+
+/*
+ * Dummy mask/unmask handler
+ */
+void dummy_mask_unmask_irq(unsigned int irq)
+{
+}
+
+void ack_bad_irq(unsigned int irq)
+{
+ irq_err_count += 1;
+ printk(KERN_ERR "IRQ: spurious interrupt %d\n", irq);
+}
+EXPORT_SYMBOL(ack_bad_irq);
+
+static struct irq_chip bad_chip = {
+ .ack = dummy_mask_unmask_irq,
+ .mask = dummy_mask_unmask_irq,
+ .unmask = dummy_mask_unmask_irq,
+};
+
+static struct irq_desc bad_irq_desc = {
+ .chip = &bad_chip,
+ .handle_irq = handle_bad_irq,
+ .depth = 1,
+};
+
+int show_interrupts(struct seq_file *p, void *v)
+{
+ int i = *(loff_t *) v;
+ struct irqaction *action;
+ unsigned long flags;
+
+ if (i < NR_IRQS) {
+ spin_lock_irqsave(&irq_desc[i].lock, flags);
+ action = irq_desc[i].action;
+ if (!action)
+ goto unlock;
+
+ seq_printf(p, "%3d: %10u ", i, kstat_irqs(i));
+ seq_printf(p, " %s", action->name);
+ for (action = action->next; action; action = action->next)
+ seq_printf(p, ", %s", action->name);
+
+ seq_putc(p, '\n');
+ unlock:
+ spin_unlock_irqrestore(&irq_desc[i].lock, flags);
+ } else if (i == NR_IRQS) {
+ seq_printf(p, "Err: %10lu\n", irq_err_count);
+ }
+ return 0;
+}
+
+/*
+ * do_IRQ handles all hardware IRQ's. Decoded IRQs should not
+ * come via this function. Instead, they should provide their
+ * own 'handler'
+ */
+
+#ifdef CONFIG_DO_IRQ_L1
+asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs)__attribute__((l1_text));
+#endif
+
+asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs)
+{
+ struct pt_regs *old_regs;
+ struct irq_desc *desc = irq_desc + irq;
+ unsigned short pending, other_ints;
+
+ old_regs = set_irq_regs(regs);
+
+ /*
+ * Some hardware gives randomly wrong interrupts. Rather
+ * than crashing, do something sensible.
+ */
+ if (irq >= NR_IRQS)
+ desc = &bad_irq_desc;
+
+ irq_enter();
+
+ generic_handle_irq(irq);
+
+ /* If we're the only interrupt running (ignoring IRQ15 which is for
+ syscalls), lower our priority to IRQ14 so that softirqs run at
+ that level. If there's another, lower-level interrupt, irq_exit
+ will defer softirqs to that. */
+ CSYNC();
+ pending = bfin_read_IPEND() & ~0x8000;
+ other_ints = pending & (pending - 1);
+ if (other_ints == 0)
+ lower_to_irq14();
+ irq_exit();
+
+ set_irq_regs(old_regs);
+}
+
+void __init init_IRQ(void)
+{
+ struct irq_desc *desc;
+ int irq;
+
+ spin_lock_init(&irq_controller_lock);
+ for (irq = 0, desc = irq_desc; irq < NR_IRQS; irq++, desc++) {
+ *desc = bad_irq_desc;
+ }
+
+ init_arch_irq();
+}
diff --git a/arch/blackfin/kernel/module.c b/arch/blackfin/kernel/module.c
new file mode 100644
index 00000000000..372f756f1ad
--- /dev/null
+++ b/arch/blackfin/kernel/module.c
@@ -0,0 +1,429 @@
+/*
+ * File: arch/blackfin/kernel/module.c
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+
+#include <linux/moduleloader.h>
+#include <linux/elf.h>
+#include <linux/vmalloc.h>
+#include <linux/fs.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <asm/dma.h>
+#include <asm/cacheflush.h>
+
+/*
+ * handle arithmetic relocations.
+ * See binutils/bfd/elf32-bfin.c for more details
+ */
+#define RELOC_STACK_SIZE 100
+static uint32_t reloc_stack[RELOC_STACK_SIZE];
+static unsigned int reloc_stack_tos;
+
+#define is_reloc_stack_empty() ((reloc_stack_tos > 0)?0:1)
+
+static void reloc_stack_push(uint32_t value)
+{
+ reloc_stack[reloc_stack_tos++] = value;
+}
+
+static uint32_t reloc_stack_pop(void)
+{
+ return reloc_stack[--reloc_stack_tos];
+}
+
+static uint32_t reloc_stack_operate(unsigned int oper, struct module *mod)
+{
+ uint32_t value;
+
+ switch (oper) {
+ case R_add:
+ value = reloc_stack[reloc_stack_tos - 2] +
+ reloc_stack[reloc_stack_tos - 1];
+ reloc_stack_tos -= 2;
+ break;
+ case R_sub:
+ value = reloc_stack[reloc_stack_tos - 2] -
+ reloc_stack[reloc_stack_tos - 1];
+ reloc_stack_tos -= 2;
+ break;
+ case R_mult:
+ value = reloc_stack[reloc_stack_tos - 2] *
+ reloc_stack[reloc_stack_tos - 1];
+ reloc_stack_tos -= 2;
+ break;
+ case R_div:
+ value = reloc_stack[reloc_stack_tos - 2] /
+ reloc_stack[reloc_stack_tos - 1];
+ reloc_stack_tos -= 2;
+ break;
+ case R_mod:
+ value = reloc_stack[reloc_stack_tos - 2] %
+ reloc_stack[reloc_stack_tos - 1];
+ reloc_stack_tos -= 2;
+ break;
+ case R_lshift:
+ value = reloc_stack[reloc_stack_tos - 2] <<
+ reloc_stack[reloc_stack_tos - 1];
+ reloc_stack_tos -= 2;
+ break;
+ case R_rshift:
+ value = reloc_stack[reloc_stack_tos - 2] >>
+ reloc_stack[reloc_stack_tos - 1];
+ reloc_stack_tos -= 2;
+ break;
+ case R_and:
+ value = reloc_stack[reloc_stack_tos - 2] &
+ reloc_stack[reloc_stack_tos - 1];
+ reloc_stack_tos -= 2;
+ break;
+ case R_or:
+ value = reloc_stack[reloc_stack_tos - 2] |
+ reloc_stack[reloc_stack_tos - 1];
+ reloc_stack_tos -= 2;
+ break;
+ case R_xor:
+ value = reloc_stack[reloc_stack_tos - 2] ^
+ reloc_stack[reloc_stack_tos - 1];
+ reloc_stack_tos -= 2;
+ break;
+ case R_land:
+ value = reloc_stack[reloc_stack_tos - 2] &&
+ reloc_stack[reloc_stack_tos - 1];
+ reloc_stack_tos -= 2;
+ break;
+ case R_lor:
+ value = reloc_stack[reloc_stack_tos - 2] ||
+ reloc_stack[reloc_stack_tos - 1];
+ reloc_stack_tos -= 2;
+ break;
+ case R_neg:
+ value = -reloc_stack[reloc_stack_tos - 1];
+ reloc_stack_tos--;
+ break;
+ case R_comp:
+ value = ~reloc_stack[reloc_stack_tos - 1];
+ reloc_stack_tos -= 1;
+ break;
+ default:
+ printk(KERN_WARNING "module %s: unhandled reloction\n",
+ mod->name);
+ return 0;
+ }
+
+ /* now push the new value back on stack */
+ reloc_stack_push(value);
+
+ return value;
+}
+
+void *module_alloc(unsigned long size)
+{
+ if (size == 0)
+ return NULL;
+ return vmalloc(size);
+}
+
+/* Free memory returned from module_alloc */
+void module_free(struct module *mod, void *module_region)
+{
+ vfree(module_region);
+}
+
+/* Transfer the section to the L1 memory */
+int
+module_frob_arch_sections(Elf_Ehdr * hdr, Elf_Shdr * sechdrs,
+ char *secstrings, struct module *mod)
+{
+ Elf_Shdr *s, *sechdrs_end = sechdrs + hdr->e_shnum;
+ void *dest = NULL;
+
+ for (s = sechdrs; s < sechdrs_end; ++s) {
+ if ((strcmp(".l1.text", secstrings + s->sh_name) == 0) ||
+ ((strcmp(".text", secstrings + s->sh_name)==0) &&
+ (hdr->e_flags & FLG_CODE_IN_L1) && (s->sh_size > 0))) {
+ mod->arch.text_l1 = s;
+ dest = l1_inst_sram_alloc(s->sh_size);
+ if (dest == NULL) {
+ printk(KERN_ERR
+ "module %s: L1 instruction memory allocation failed\n",
+ mod->name);
+ return -1;
+ }
+ dma_memcpy(dest, (void *)s->sh_addr, s->sh_size);
+ s->sh_flags &= ~SHF_ALLOC;
+ s->sh_addr = (unsigned long)dest;
+ }
+ if ((strcmp(".l1.data", secstrings + s->sh_name) == 0)||
+ ((strcmp(".data", secstrings + s->sh_name)==0) &&
+ (hdr->e_flags & FLG_DATA_IN_L1) && (s->sh_size > 0))) {
+ mod->arch.data_a_l1 = s;
+ dest = l1_data_sram_alloc(s->sh_size);
+ if (dest == NULL) {
+ printk(KERN_ERR
+ "module %s: L1 data memory allocation failed\n",
+ mod->name);
+ return -1;
+ }
+ memcpy(dest, (void *)s->sh_addr, s->sh_size);
+ s->sh_flags &= ~SHF_ALLOC;
+ s->sh_addr = (unsigned long)dest;
+ }
+ if (strcmp(".l1.bss", secstrings + s->sh_name) == 0 ||
+ ((strcmp(".bss", secstrings + s->sh_name)==0) &&
+ (hdr->e_flags & FLG_DATA_IN_L1) && (s->sh_size > 0))) {
+ mod->arch.bss_a_l1 = s;
+ dest = l1_data_sram_alloc(s->sh_size);
+ if (dest == NULL) {
+ printk(KERN_ERR
+ "module %s: L1 data memory allocation failed\n",
+ mod->name);
+ return -1;
+ }
+ memset(dest, 0, s->sh_size);
+ s->sh_flags &= ~SHF_ALLOC;
+ s->sh_addr = (unsigned long)dest;
+ }
+ if (strcmp(".l1.data.B", secstrings + s->sh_name) == 0) {
+ mod->arch.data_b_l1 = s;
+ dest = l1_data_B_sram_alloc(s->sh_size);
+ if (dest == NULL) {
+ printk(KERN_ERR
+ "module %s: L1 data memory allocation failed\n",
+ mod->name);
+ return -1;
+ }
+ memcpy(dest, (void *)s->sh_addr, s->sh_size);
+ s->sh_flags &= ~SHF_ALLOC;
+ s->sh_addr = (unsigned long)dest;
+ }
+ if (strcmp(".l1.bss.B", secstrings + s->sh_name) == 0) {
+ mod->arch.bss_b_l1 = s;
+ dest = l1_data_B_sram_alloc(s->sh_size);
+ if (dest == NULL) {
+ printk(KERN_ERR
+ "module %s: L1 data memory allocation failed\n",
+ mod->name);
+ return -1;
+ }
+ memset(dest, 0, s->sh_size);
+ s->sh_flags &= ~SHF_ALLOC;
+ s->sh_addr = (unsigned long)dest;
+ }
+ }
+ return 0;
+}
+
+int
+apply_relocate(Elf_Shdr * sechdrs, const char *strtab,
+ unsigned int symindex, unsigned int relsec, struct module *me)
+{
+ printk(KERN_ERR "module %s: .rel unsupported\n", me->name);
+ return -ENOEXEC;
+}
+
+/*************************************************************************/
+/* FUNCTION : apply_relocate_add */
+/* ABSTRACT : Blackfin specific relocation handling for the loadable */
+/* modules. Modules are expected to be .o files. */
+/* Arithmetic relocations are handled. */
+/* We do not expect LSETUP to be split and hence is not */
+/* handled. */
+/* R_byte and R_byte2 are also not handled as the gas */
+/* does not generate it. */
+/*************************************************************************/
+int
+apply_relocate_add(Elf_Shdr * sechdrs, const char *strtab,
+ unsigned int symindex, unsigned int relsec,
+ struct module *mod)
+{
+ unsigned int i;
+ unsigned short tmp;
+ Elf32_Rela *rel = (void *)sechdrs[relsec].sh_addr;
+ Elf32_Sym *sym;
+ uint32_t *location32;
+ uint16_t *location16;
+ uint32_t value;
+
+ pr_debug("Applying relocate section %u to %u\n", relsec,
+ sechdrs[relsec].sh_info);
+ for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
+ /* This is where to make the change */
+ location16 =
+ (uint16_t *) (sechdrs[sechdrs[relsec].sh_info].sh_addr +
+ rel[i].r_offset);
+ location32 = (uint32_t *) location16;
+ /* This is the symbol it is referring to. Note that all
+ undefined symbols have been resolved. */
+ sym = (Elf32_Sym *) sechdrs[symindex].sh_addr
+ + ELF32_R_SYM(rel[i].r_info);
+ if (is_reloc_stack_empty()) {
+ value = sym->st_value;
+ } else {
+ value = reloc_stack_pop();
+ }
+ value += rel[i].r_addend;
+ pr_debug("location is %x, value is %x type is %d \n",
+ (unsigned int) location32, value,
+ ELF32_R_TYPE(rel[i].r_info));
+
+ switch (ELF32_R_TYPE(rel[i].r_info)) {
+
+ case R_pcrel24:
+ case R_pcrel24_jump_l:
+ /* Add the value, subtract its postition */
+ location16 =
+ (uint16_t *) (sechdrs[sechdrs[relsec].sh_info].
+ sh_addr + rel[i].r_offset - 2);
+ location32 = (uint32_t *) location16;
+ value -= (uint32_t) location32;
+ value >>= 1;
+ pr_debug("value is %x, before %x-%x after %x-%x\n", value,
+ *location16, *(location16 + 1),
+ (*location16 & 0xff00) | (value >> 16 & 0x00ff),
+ value & 0xffff);
+ *location16 =
+ (*location16 & 0xff00) | (value >> 16 & 0x00ff);
+ *(location16 + 1) = value & 0xffff;
+ break;
+ case R_pcrel12_jump:
+ case R_pcrel12_jump_s:
+ value -= (uint32_t) location32;
+ value >>= 1;
+ *location16 = (value & 0xfff);
+ break;
+ case R_pcrel10:
+ value -= (uint32_t) location32;
+ value >>= 1;
+ *location16 = (value & 0x3ff);
+ break;
+ case R_luimm16:
+ pr_debug("before %x after %x\n", *location16,
+ (value & 0xffff));
+ tmp = (value & 0xffff);
+ if((unsigned long)location16 >= L1_CODE_START) {
+ dma_memcpy(location16, &tmp, 2);
+ } else
+ *location16 = tmp;
+ break;
+ case R_huimm16:
+ pr_debug("before %x after %x\n", *location16,
+ ((value >> 16) & 0xffff));
+ tmp = ((value >> 16) & 0xffff);
+ if((unsigned long)location16 >= L1_CODE_START) {
+ dma_memcpy(location16, &tmp, 2);
+ } else
+ *location16 = tmp;
+ break;
+ case R_rimm16:
+ *location16 = (value & 0xffff);
+ break;
+ case R_byte4_data:
+ pr_debug("before %x after %x\n", *location32, value);
+ *location32 = value;
+ break;
+ case R_push:
+ reloc_stack_push(value);
+ break;
+ case R_const:
+ reloc_stack_push(rel[i].r_addend);
+ break;
+ case R_add:
+ case R_sub:
+ case R_mult:
+ case R_div:
+ case R_mod:
+ case R_lshift:
+ case R_rshift:
+ case R_and:
+ case R_or:
+ case R_xor:
+ case R_land:
+ case R_lor:
+ case R_neg:
+ case R_comp:
+ reloc_stack_operate(ELF32_R_TYPE(rel[i].r_info), mod);
+ break;
+ default:
+ printk(KERN_ERR "module %s: Unknown relocation: %u\n",
+ mod->name, ELF32_R_TYPE(rel[i].r_info));
+ return -ENOEXEC;
+ }
+ }
+ return 0;
+}
+
+int
+module_finalize(const Elf_Ehdr * hdr,
+ const Elf_Shdr * sechdrs, struct module *mod)
+{
+ unsigned int i, strindex = 0, symindex = 0;
+ char *secstrings;
+
+ secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
+
+ for (i = 1; i < hdr->e_shnum; i++) {
+ /* Internal symbols and strings. */
+ if (sechdrs[i].sh_type == SHT_SYMTAB) {
+ symindex = i;
+ strindex = sechdrs[i].sh_link;
+ }
+ }
+
+ for (i = 1; i < hdr->e_shnum; i++) {
+ const char *strtab = (char *)sechdrs[strindex].sh_addr;
+ unsigned int info = sechdrs[i].sh_info;
+
+ /* Not a valid relocation section? */
+ if (info >= hdr->e_shnum)
+ continue;
+
+ if ((sechdrs[i].sh_type == SHT_RELA) &&
+ ((strcmp(".rela.l1.text", secstrings + sechdrs[i].sh_name) == 0)||
+ ((strcmp(".rela.text", secstrings + sechdrs[i].sh_name) == 0) &&
+ (hdr->e_flags & FLG_CODE_IN_L1)))) {
+ apply_relocate_add((Elf_Shdr *) sechdrs, strtab,
+ symindex, i, mod);
+ }
+ }
+ return 0;
+}
+
+void module_arch_cleanup(struct module *mod)
+{
+ if ((mod->arch.text_l1) && (mod->arch.text_l1->sh_addr))
+ l1_inst_sram_free((void*)mod->arch.text_l1->sh_addr);
+ if ((mod->arch.data_a_l1) && (mod->arch.data_a_l1->sh_addr))
+ l1_data_sram_free((void*)mod->arch.data_a_l1->sh_addr);
+ if ((mod->arch.bss_a_l1) && (mod->arch.bss_a_l1->sh_addr))
+ l1_data_sram_free((void*)mod->arch.bss_a_l1->sh_addr);
+ if ((mod->arch.data_b_l1) && (mod->arch.data_b_l1->sh_addr))
+ l1_data_B_sram_free((void*)mod->arch.data_b_l1->sh_addr);
+ if ((mod->arch.bss_b_l1) && (mod->arch.bss_b_l1->sh_addr))
+ l1_data_B_sram_free((void*)mod->arch.bss_b_l1->sh_addr);
+}
diff --git a/arch/blackfin/kernel/process.c b/arch/blackfin/kernel/process.c
new file mode 100644
index 00000000000..3eff7439d8d
--- /dev/null
+++ b/arch/blackfin/kernel/process.c
@@ -0,0 +1,394 @@
+/*
+ * File: arch/blackfin/kernel/process.c
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description: Blackfin architecture-dependent process handling.
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/module.h>
+#include <linux/smp_lock.h>
+#include <linux/unistd.h>
+#include <linux/user.h>
+#include <linux/a.out.h>
+
+#include <asm/blackfin.h>
+#include <asm/uaccess.h>
+
+#define LED_ON 0
+#define LED_OFF 1
+
+asmlinkage void ret_from_fork(void);
+
+/* Points to the SDRAM backup memory for the stack that is currently in
+ * L1 scratchpad memory.
+ */
+void *current_l1_stack_save;
+
+/* The number of tasks currently using a L1 stack area. The SRAM is
+ * allocated/deallocated whenever this changes from/to zero.
+ */
+int nr_l1stack_tasks;
+
+/* Start and length of the area in L1 scratchpad memory which we've allocated
+ * for process stacks.
+ */
+void *l1_stack_base;
+unsigned long l1_stack_len;
+
+/*
+ * Powermanagement idle function, if any..
+ */
+void (*pm_idle)(void) = NULL;
+EXPORT_SYMBOL(pm_idle);
+
+void (*pm_power_off)(void) = NULL;
+EXPORT_SYMBOL(pm_power_off);
+
+/*
+ * We are using a different LED from the one used to indicate timer interrupt.
+ */
+#if defined(CONFIG_BFIN_IDLE_LED)
+static inline void leds_switch(int flag)
+{
+ unsigned short tmp = 0;
+
+ tmp = bfin_read_CONFIG_BFIN_IDLE_LED_PORT();
+ SSYNC();
+
+ if (flag == LED_ON)
+ tmp &= ~CONFIG_BFIN_IDLE_LED_PIN; /* light on */
+ else
+ tmp |= CONFIG_BFIN_IDLE_LED_PIN; /* light off */
+
+ bfin_write_CONFIG_BFIN_IDLE_LED_PORT(tmp);
+ SSYNC();
+
+}
+#else
+static inline void leds_switch(int flag)
+{
+}
+#endif
+
+/*
+ * The idle loop on BFIN
+ */
+#ifdef CONFIG_IDLE_L1
+void default_idle(void)__attribute__((l1_text));
+void cpu_idle(void)__attribute__((l1_text));
+#endif
+
+void default_idle(void)
+{
+ while (!need_resched()) {
+ leds_switch(LED_OFF);
+ local_irq_disable();
+ if (likely(!need_resched()))
+ idle_with_irq_disabled();
+ local_irq_enable();
+ leds_switch(LED_ON);
+ }
+}
+
+void (*idle)(void) = default_idle;
+
+/*
+ * The idle thread. There's no useful work to be
+ * done, so just try to conserve power and have a
+ * low exit latency (ie sit in a loop waiting for
+ * somebody to say that they'd like to reschedule)
+ */
+void cpu_idle(void)
+{
+ /* endless idle loop with no priority at all */
+ while (1) {
+ idle();
+ preempt_enable_no_resched();
+ schedule();
+ preempt_disable();
+ }
+}
+
+void machine_restart(char *__unused)
+{
+#if defined(CONFIG_BLKFIN_CACHE)
+ bfin_write_IMEM_CONTROL(0x01);
+ SSYNC();
+#endif
+ bfin_reset();
+ /* Dont do anything till the reset occurs */
+ while (1) {
+ SSYNC();
+ }
+}
+
+void machine_halt(void)
+{
+ for (;;)
+ asm volatile ("idle");
+}
+
+void machine_power_off(void)
+{
+ for (;;)
+ asm volatile ("idle");
+}
+
+void show_regs(struct pt_regs *regs)
+{
+ printk(KERN_NOTICE "\n");
+ printk(KERN_NOTICE
+ "PC: %08lu Status: %04lu SysStatus: %04lu RETS: %08lu\n",
+ regs->pc, regs->astat, regs->seqstat, regs->rets);
+ printk(KERN_NOTICE
+ "A0.x: %08lx A0.w: %08lx A1.x: %08lx A1.w: %08lx\n",
+ regs->a0x, regs->a0w, regs->a1x, regs->a1w);
+ printk(KERN_NOTICE "P0: %08lx P1: %08lx P2: %08lx P3: %08lx\n",
+ regs->p0, regs->p1, regs->p2, regs->p3);
+ printk(KERN_NOTICE "P4: %08lx P5: %08lx\n", regs->p4, regs->p5);
+ printk(KERN_NOTICE "R0: %08lx R1: %08lx R2: %08lx R3: %08lx\n",
+ regs->r0, regs->r1, regs->r2, regs->r3);
+ printk(KERN_NOTICE "R4: %08lx R5: %08lx R6: %08lx R7: %08lx\n",
+ regs->r4, regs->r5, regs->r6, regs->r7);
+
+ if (!(regs->ipend))
+ printk("USP: %08lx\n", rdusp());
+}
+
+/* Fill in the fpu structure for a core dump. */
+
+int dump_fpu(struct pt_regs *regs, elf_fpregset_t * fpregs)
+{
+ return 1;
+}
+
+/*
+ * This gets run with P1 containing the
+ * function to call, and R1 containing
+ * the "args". Note P0 is clobbered on the way here.
+ */
+void kernel_thread_helper(void);
+__asm__(".section .text\n"
+ ".align 4\n"
+ "_kernel_thread_helper:\n\t"
+ "\tsp += -12;\n\t"
+ "\tr0 = r1;\n\t" "\tcall (p1);\n\t" "\tcall _do_exit;\n" ".previous");
+
+/*
+ * Create a kernel thread.
+ */
+pid_t kernel_thread(int (*fn) (void *), void *arg, unsigned long flags)
+{
+ struct pt_regs regs;
+
+ memset(&regs, 0, sizeof(regs));
+
+ regs.r1 = (unsigned long)arg;
+ regs.p1 = (unsigned long)fn;
+ regs.pc = (unsigned long)kernel_thread_helper;
+ regs.orig_p0 = -1;
+ /* Set bit 2 to tell ret_from_fork we should be returning to kernel
+ mode. */
+ regs.ipend = 0x8002;
+ __asm__ __volatile__("%0 = syscfg;":"=da"(regs.syscfg):);
+ return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL,
+ NULL);
+}
+
+void flush_thread(void)
+{
+}
+
+asmlinkage int bfin_vfork(struct pt_regs *regs)
+{
+ return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, rdusp(), regs, 0, NULL,
+ NULL);
+}
+
+asmlinkage int bfin_clone(struct pt_regs *regs)
+{
+ unsigned long clone_flags;
+ unsigned long newsp;
+
+ /* syscall2 puts clone_flags in r0 and usp in r1 */
+ clone_flags = regs->r0;
+ newsp = regs->r1;
+ if (!newsp)
+ newsp = rdusp();
+ else
+ newsp -= 12;
+ return do_fork(clone_flags, newsp, regs, 0, NULL, NULL);
+}
+
+int
+copy_thread(int nr, unsigned long clone_flags,
+ unsigned long usp, unsigned long topstk,
+ struct task_struct *p, struct pt_regs *regs)
+{
+ struct pt_regs *childregs;
+
+ childregs = (struct pt_regs *) (task_stack_page(p) + THREAD_SIZE) - 1;
+ *childregs = *regs;
+ childregs->r0 = 0;
+
+ p->thread.usp = usp;
+ p->thread.ksp = (unsigned long)childregs;
+ p->thread.pc = (unsigned long)ret_from_fork;
+
+ return 0;
+}
+
+/*
+ * fill in the user structure for a core dump..
+ */
+void dump_thread(struct pt_regs *regs, struct user *dump)
+{
+ dump->magic = CMAGIC;
+ dump->start_code = 0;
+ dump->start_stack = rdusp() & ~(PAGE_SIZE - 1);
+ dump->u_tsize = ((unsigned long)current->mm->end_code) >> PAGE_SHIFT;
+ dump->u_dsize = ((unsigned long)(current->mm->brk +
+ (PAGE_SIZE - 1))) >> PAGE_SHIFT;
+ dump->u_dsize -= dump->u_tsize;
+ dump->u_ssize = 0;
+
+ if (dump->start_stack < TASK_SIZE)
+ dump->u_ssize =
+ ((unsigned long)(TASK_SIZE -
+ dump->start_stack)) >> PAGE_SHIFT;
+
+ dump->u_ar0 = (struct user_regs_struct *)((int)&dump->regs - (int)dump);
+
+ dump->regs.r0 = regs->r0;
+ dump->regs.r1 = regs->r1;
+ dump->regs.r2 = regs->r2;
+ dump->regs.r3 = regs->r3;
+ dump->regs.r4 = regs->r4;
+ dump->regs.r5 = regs->r5;
+ dump->regs.r6 = regs->r6;
+ dump->regs.r7 = regs->r7;
+ dump->regs.p0 = regs->p0;
+ dump->regs.p1 = regs->p1;
+ dump->regs.p2 = regs->p2;
+ dump->regs.p3 = regs->p3;
+ dump->regs.p4 = regs->p4;
+ dump->regs.p5 = regs->p5;
+ dump->regs.orig_p0 = regs->orig_p0;
+ dump->regs.a0w = regs->a0w;
+ dump->regs.a1w = regs->a1w;
+ dump->regs.a0x = regs->a0x;
+ dump->regs.a1x = regs->a1x;
+ dump->regs.rets = regs->rets;
+ dump->regs.astat = regs->astat;
+ dump->regs.pc = regs->pc;
+}
+
+/*
+ * sys_execve() executes a new program.
+ */
+
+asmlinkage int sys_execve(char *name, char **argv, char **envp)
+{
+ int error;
+ char *filename;
+ struct pt_regs *regs = (struct pt_regs *)((&name) + 6);
+
+ lock_kernel();
+ filename = getname(name);
+ error = PTR_ERR(filename);
+ if (IS_ERR(filename))
+ goto out;
+ error = do_execve(filename, argv, envp, regs);
+ putname(filename);
+ out:
+ unlock_kernel();
+ return error;
+}
+
+unsigned long get_wchan(struct task_struct *p)
+{
+ unsigned long fp, pc;
+ unsigned long stack_page;
+ int count = 0;
+ if (!p || p == current || p->state == TASK_RUNNING)
+ return 0;
+
+ stack_page = (unsigned long)p;
+ fp = p->thread.usp;
+ do {
+ if (fp < stack_page + sizeof(struct thread_info) ||
+ fp >= 8184 + stack_page)
+ return 0;
+ pc = ((unsigned long *)fp)[1];
+ if (!in_sched_functions(pc))
+ return pc;
+ fp = *(unsigned long *)fp;
+ }
+ while (count++ < 16);
+ return 0;
+}
+
+#if defined(CONFIG_ACCESS_CHECK)
+int _access_ok(unsigned long addr, unsigned long size)
+{
+
+ if (addr > (addr + size))
+ return 0;
+ if (segment_eq(get_fs(),KERNEL_DS))
+ return 1;
+#ifdef CONFIG_MTD_UCLINUX
+ if (addr >= memory_start && (addr + size) <= memory_end)
+ return 1;
+ if (addr >= memory_mtd_end && (addr + size) <= physical_mem_end)
+ return 1;
+#else
+ if (addr >= memory_start && (addr + size) <= physical_mem_end)
+ return 1;
+#endif
+ if (addr >= (unsigned long)__init_begin &&
+ addr + size <= (unsigned long)__init_end)
+ return 1;
+ if (addr >= L1_SCRATCH_START
+ && addr + size <= L1_SCRATCH_START + L1_SCRATCH_LENGTH)
+ return 1;
+#if L1_CODE_LENGTH != 0
+ if (addr >= L1_CODE_START + (_etext_l1 - _stext_l1)
+ && addr + size <= L1_CODE_START + L1_CODE_LENGTH)
+ return 1;
+#endif
+#if L1_DATA_A_LENGTH != 0
+ if (addr >= L1_DATA_A_START + (_ebss_l1 - _sdata_l1)
+ && addr + size <= L1_DATA_A_START + L1_DATA_A_LENGTH)
+ return 1;
+#endif
+#if L1_DATA_B_LENGTH != 0
+ if (addr >= L1_DATA_B_START
+ && addr + size <= L1_DATA_B_START + L1_DATA_B_LENGTH)
+ return 1;
+#endif
+ return 0;
+}
+EXPORT_SYMBOL(_access_ok);
+#endif /* CONFIG_ACCESS_CHECK */
diff --git a/arch/blackfin/kernel/ptrace.c b/arch/blackfin/kernel/ptrace.c
new file mode 100644
index 00000000000..d7c8e514cb9
--- /dev/null
+++ b/arch/blackfin/kernel/ptrace.c
@@ -0,0 +1,430 @@
+/*
+ * File: arch/blackfin/kernel/ptrace.c
+ * Based on: Taken from linux/kernel/ptrace.c
+ * Author: linux/kernel/ptrace.c is by Ross Biro 1/23/92, edited by Linus Torvalds
+ *
+ * Created: 1/23/92
+ * Description:
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/errno.h>
+#include <linux/ptrace.h>
+#include <linux/user.h>
+#include <linux/signal.h>
+
+#include <asm/uaccess.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/processor.h>
+#include <asm/asm-offsets.h>
+#include <asm/dma.h>
+
+#define MAX_SHARED_LIBS 3
+#define TEXT_OFFSET 0
+/*
+ * does not yet catch signals sent when the child dies.
+ * in exit.c or in signal.c.
+ */
+
+/* determines which bits in the SYSCFG reg the user has access to. */
+/* 1 = access 0 = no access */
+#define SYSCFG_MASK 0x0007 /* SYSCFG reg */
+/* sets the trace bits. */
+#define TRACE_BITS 0x0001
+
+/* Find the stack offset for a register, relative to thread.esp0. */
+#define PT_REG(reg) ((long)&((struct pt_regs *)0)->reg)
+
+/*
+ * Get the address of the live pt_regs for the specified task.
+ * These are saved onto the top kernel stack when the process
+ * is not running.
+ *
+ * Note: if a user thread is execve'd from kernel space, the
+ * kernel stack will not be empty on entry to the kernel, so
+ * ptracing these tasks will fail.
+ */
+static inline struct pt_regs *get_user_regs(struct task_struct *task)
+{
+ return (struct pt_regs *)
+ ((unsigned long)task->thread_info +
+ (THREAD_SIZE - sizeof(struct pt_regs)));
+}
+
+/*
+ * Get all user integer registers.
+ */
+static inline int ptrace_getregs(struct task_struct *tsk, void __user * uregs)
+{
+ struct pt_regs *regs = get_user_regs(tsk);
+ return copy_to_user(uregs, regs, sizeof(struct pt_regs)) ? -EFAULT : 0;
+}
+
+/* Mapping from PT_xxx to the stack offset at which the register is
+ * saved. Notice that usp has no stack-slot and needs to be treated
+ * specially (see get_reg/put_reg below).
+ */
+
+/*
+ * Get contents of register REGNO in task TASK.
+ */
+static inline long get_reg(struct task_struct *task, int regno)
+{
+ unsigned char *reg_ptr;
+
+ struct pt_regs *regs =
+ (struct pt_regs *)((unsigned long)task->thread_info +
+ (THREAD_SIZE - sizeof(struct pt_regs)));
+ reg_ptr = (char *)regs;
+
+ switch (regno) {
+ case PT_USP:
+ return task->thread.usp;
+ default:
+ if (regno <= 216)
+ return *(long *)(reg_ptr + regno);
+ }
+ /* slight mystery ... never seems to come here but kernel misbehaves without this code! */
+
+ printk(KERN_WARNING "Request to get for unknown register %d\n", regno);
+ return 0;
+}
+
+/*
+ * Write contents of register REGNO in task TASK.
+ */
+static inline int
+put_reg(struct task_struct *task, int regno, unsigned long data)
+{
+ char * reg_ptr;
+
+ struct pt_regs *regs =
+ (struct pt_regs *)((unsigned long)task->thread_info +
+ (THREAD_SIZE - sizeof(struct pt_regs)));
+ reg_ptr = (char *)regs;
+
+ switch (regno) {
+ case PT_PC:
+ /*********************************************************************/
+ /* At this point the kernel is most likely in exception. */
+ /* The RETX register will be used to populate the pc of the process. */
+ /*********************************************************************/
+ regs->retx = data;
+ regs->pc = data;
+ break;
+ case PT_RETX:
+ break; /* regs->retx = data; break; */
+ case PT_USP:
+ regs->usp = data;
+ task->thread.usp = data;
+ break;
+ default:
+ if (regno <= 216)
+ *(long *)(reg_ptr + regno) = data;
+ }
+ return 0;
+}
+
+/*
+ * check that an address falls within the bounds of the target process's memory mappings
+ */
+static inline int is_user_addr_valid(struct task_struct *child,
+ unsigned long start, unsigned long len)
+{
+ struct vm_list_struct *vml;
+ struct sram_list_struct *sraml;
+
+ for (vml = child->mm->context.vmlist; vml; vml = vml->next)
+ if (start >= vml->vma->vm_start && start + len <= vml->vma->vm_end)
+ return 0;
+
+ for (sraml = child->mm->context.sram_list; sraml; sraml = sraml->next)
+ if (start >= (unsigned long)sraml->addr
+ && start + len <= (unsigned long)sraml->addr + sraml->length)
+ return 0;
+
+ return -EIO;
+}
+
+/*
+ * Called by kernel/ptrace.c when detaching..
+ *
+ * Make sure the single step bit is not set.
+ */
+void ptrace_disable(struct task_struct *child)
+{
+ unsigned long tmp;
+ /* make sure the single step bit is not set. */
+ tmp = get_reg(child, PT_SR) & ~(TRACE_BITS << 16);
+ put_reg(child, PT_SR, tmp);
+}
+
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+{
+ int ret;
+ int add = 0;
+
+ switch (request) {
+ /* when I and D space are separate, these will need to be fixed. */
+ case PTRACE_PEEKDATA:
+ pr_debug("ptrace: PEEKDATA\n");
+ add = MAX_SHARED_LIBS * 4; /* space between text and data */
+ /* fall through */
+ case PTRACE_PEEKTEXT: /* read word at location addr. */
+ {
+ unsigned long tmp = 0;
+ int copied;
+
+ ret = -EIO;
+ pr_debug("ptrace: PEEKTEXT at addr 0x%08lx + add %d %ld\n", addr, add,
+ sizeof(data));
+ if (is_user_addr_valid(child, addr + add, sizeof(tmp)) < 0)
+ break;
+ pr_debug("ptrace: user address is valid\n");
+
+#if L1_CODE_LENGTH != 0
+ if (addr + add >= L1_CODE_START
+ && addr + add + sizeof(tmp) <= L1_CODE_START + L1_CODE_LENGTH) {
+ safe_dma_memcpy (&tmp, (const void *)(addr + add), sizeof(tmp));
+ copied = sizeof(tmp);
+ } else
+#endif
+ copied =
+ access_process_vm(child, addr + add, &tmp,
+ sizeof(tmp), 0);
+ pr_debug("ptrace: copied size %d [0x%08lx]\n", copied, tmp);
+ if (copied != sizeof(tmp))
+ break;
+ ret = put_user(tmp, (unsigned long *)data);
+ break;
+ }
+
+ /* read the word at location addr in the USER area. */
+ case PTRACE_PEEKUSR:
+ {
+ unsigned long tmp;
+ ret = -EIO;
+ tmp = 0;
+ if ((addr & 3) || (addr > (sizeof(struct pt_regs) + 16))) {
+ printk(KERN_WARNING "ptrace error : PEEKUSR : temporarily returning "
+ "0 - %x sizeof(pt_regs) is %lx\n",
+ (int)addr, sizeof(struct pt_regs));
+ break;
+ }
+ if (addr == sizeof(struct pt_regs)) {
+ /* PT_TEXT_ADDR */
+ tmp = child->mm->start_code + TEXT_OFFSET;
+ } else if (addr == (sizeof(struct pt_regs) + 4)) {
+ /* PT_TEXT_END_ADDR */
+ tmp = child->mm->end_code;
+ } else if (addr == (sizeof(struct pt_regs) + 8)) {
+ /* PT_DATA_ADDR */
+ tmp = child->mm->start_data;
+#ifdef CONFIG_BINFMT_ELF_FDPIC
+ } else if (addr == (sizeof(struct pt_regs) + 12)) {
+ tmp = child->mm->context.exec_fdpic_loadmap;
+ } else if (addr == (sizeof(struct pt_regs) + 16)) {
+ tmp = child->mm->context.interp_fdpic_loadmap;
+#endif
+ } else {
+ tmp = get_reg(child, addr);
+ }
+ ret = put_user(tmp, (unsigned long *)data);
+ break;
+ }
+
+ /* when I and D space are separate, this will have to be fixed. */
+ case PTRACE_POKEDATA:
+ printk(KERN_NOTICE "ptrace: PTRACE_PEEKDATA\n");
+ /* fall through */
+ case PTRACE_POKETEXT: /* write the word at location addr. */
+ {
+ int copied;
+
+ ret = -EIO;
+ pr_debug("ptrace: POKETEXT at addr 0x%08lx + add %d %ld bytes %lx\n",
+ addr, add, sizeof(data), data);
+ if (is_user_addr_valid(child, addr + add, sizeof(data)) < 0)
+ break;
+ pr_debug("ptrace: user address is valid\n");
+
+#if L1_CODE_LENGTH != 0
+ if (addr + add >= L1_CODE_START
+ && addr + add + sizeof(data) <= L1_CODE_START + L1_CODE_LENGTH) {
+ safe_dma_memcpy ((void *)(addr + add), &data, sizeof(data));
+ copied = sizeof(data);
+ } else
+#endif
+ copied =
+ access_process_vm(child, addr + add, &data,
+ sizeof(data), 1);
+ pr_debug("ptrace: copied size %d\n", copied);
+ if (copied != sizeof(data))
+ break;
+ ret = 0;
+ break;
+ }
+
+ case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
+ ret = -EIO;
+ if ((addr & 3) || (addr > (sizeof(struct pt_regs) + 16))) {
+ printk(KERN_WARNING "ptrace error : POKEUSR: temporarily returning 0\n");
+ break;
+ }
+
+ if (addr >= (sizeof(struct pt_regs))) {
+ ret = 0;
+ break;
+ }
+ if (addr == PT_SYSCFG) {
+ data &= SYSCFG_MASK;
+ data |= get_reg(child, PT_SYSCFG);
+ }
+ ret = put_reg(child, addr, data);
+ break;
+
+ case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
+ case PTRACE_CONT:
+ { /* restart after signal. */
+ long tmp;
+
+ pr_debug("ptrace_cont\n");
+
+ ret = -EIO;
+ if (!valid_signal(data))
+ break;
+ if (request == PTRACE_SYSCALL)
+ set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
+ else
+ clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
+
+ child->exit_code = data;
+ /* make sure the single step bit is not set. */
+ tmp = get_reg(child, PT_SYSCFG) & ~(TRACE_BITS);
+ put_reg(child, PT_SYSCFG, tmp);
+ pr_debug("before wake_up_process\n");
+ wake_up_process(child);
+ ret = 0;
+ break;
+ }
+
+ /*
+ * make the child exit. Best I can do is send it a sigkill.
+ * perhaps it should be put in the status that it wants to
+ * exit.
+ */
+ case PTRACE_KILL:
+ {
+ long tmp;
+ ret = 0;
+ if (child->exit_state == EXIT_ZOMBIE) /* already dead */
+ break;
+ child->exit_code = SIGKILL;
+ /* make sure the single step bit is not set. */
+ tmp = get_reg(child, PT_SYSCFG) & ~(TRACE_BITS);
+ put_reg(child, PT_SYSCFG, tmp);
+ wake_up_process(child);
+ break;
+ }
+
+ case PTRACE_SINGLESTEP:
+ { /* set the trap flag. */
+ long tmp;
+
+ pr_debug("single step\n");
+ ret = -EIO;
+ if (!valid_signal(data))
+ break;
+ clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
+
+ tmp = get_reg(child, PT_SYSCFG) | (TRACE_BITS);
+ put_reg(child, PT_SYSCFG, tmp);
+
+ child->exit_code = data;
+ /* give it a chance to run. */
+ wake_up_process(child);
+ ret = 0;
+ break;
+ }
+
+ case PTRACE_DETACH:
+ { /* detach a process that was attached. */
+ ret = ptrace_detach(child, data);
+ break;
+ }
+
+ case PTRACE_GETREGS:
+ {
+
+ /* Get all gp regs from the child. */
+ ret = ptrace_getregs(child, (void __user *)data);
+ break;
+ }
+
+ case PTRACE_SETREGS:
+ {
+ printk(KERN_NOTICE
+ "ptrace: SETREGS: **** NOT IMPLEMENTED ***\n");
+ /* Set all gp regs in the child. */
+ ret = 0;
+ break;
+ }
+ default:
+ ret = ptrace_request(child, request, addr, data);
+ break;
+ }
+
+ return ret;
+}
+
+asmlinkage void syscall_trace(void)
+{
+
+ if (!test_thread_flag(TIF_SYSCALL_TRACE))
+ return;
+
+ if (!(current->ptrace & PT_PTRACED))
+ return;
+
+ /* the 0x80 provides a way for the tracing parent to distinguish
+ * between a syscall stop and SIGTRAP delivery
+ */
+ ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
+ ? 0x80 : 0));
+
+ /*
+ * this isn't the same as continuing with a signal, but it will do
+ * for normal use. strace only continues with a signal if the
+ * stopping signal is not SIGTRAP. -brl
+ */
+ if (current->exit_code) {
+ send_sig(current->exit_code, current, 1);
+ current->exit_code = 0;
+ }
+}
diff --git a/arch/blackfin/kernel/setup.c b/arch/blackfin/kernel/setup.c
new file mode 100644
index 00000000000..342bb8dd56a
--- /dev/null
+++ b/arch/blackfin/kernel/setup.c
@@ -0,0 +1,902 @@
+/*
+ * File: arch/blackfin/kernel/setup.c
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/delay.h>
+#include <linux/console.h>
+#include <linux/bootmem.h>
+#include <linux/seq_file.h>
+#include <linux/cpu.h>
+#include <linux/module.h>
+#include <linux/console.h>
+#include <linux/tty.h>
+
+#include <linux/ext2_fs.h>
+#include <linux/cramfs_fs.h>
+#include <linux/romfs_fs.h>
+
+#include <asm/cacheflush.h>
+#include <asm/blackfin.h>
+#include <asm/cplbinit.h>
+
+unsigned long memory_start, memory_end, physical_mem_end;
+unsigned long reserved_mem_dcache_on;
+unsigned long reserved_mem_icache_on;
+EXPORT_SYMBOL(memory_start);
+EXPORT_SYMBOL(memory_end);
+EXPORT_SYMBOL(physical_mem_end);
+EXPORT_SYMBOL(_ramend);
+
+#ifdef CONFIG_MTD_UCLINUX
+unsigned long memory_mtd_end, memory_mtd_start, mtd_size;
+unsigned long _ebss;
+EXPORT_SYMBOL(memory_mtd_end);
+EXPORT_SYMBOL(memory_mtd_start);
+EXPORT_SYMBOL(mtd_size);
+#endif
+
+char command_line[COMMAND_LINE_SIZE];
+
+#if defined(CONFIG_BLKFIN_DCACHE) || defined(CONFIG_BLKFIN_CACHE)
+static void generate_cpl_tables(void);
+#endif
+
+void __init bf53x_cache_init(void)
+{
+#if defined(CONFIG_BLKFIN_DCACHE) || defined(CONFIG_BLKFIN_CACHE)
+ generate_cpl_tables();
+#endif
+
+#ifdef CONFIG_BLKFIN_CACHE
+ bfin_icache_init();
+ printk(KERN_INFO "Instruction Cache Enabled\n");
+#endif
+
+#ifdef CONFIG_BLKFIN_DCACHE
+ bfin_dcache_init();
+ printk(KERN_INFO "Data Cache Enabled"
+# if defined CONFIG_BLKFIN_WB
+ " (write-back)"
+# elif defined CONFIG_BLKFIN_WT
+ " (write-through)"
+# endif
+ "\n");
+#endif
+}
+
+void bf53x_relocate_l1_mem(void)
+{
+ unsigned long l1_code_length;
+ unsigned long l1_data_a_length;
+ unsigned long l1_data_b_length;
+
+ l1_code_length = _etext_l1 - _stext_l1;
+ if (l1_code_length > L1_CODE_LENGTH)
+ l1_code_length = L1_CODE_LENGTH;
+ /* cannot complain as printk is not available as yet.
+ * But we can continue booting and complain later!
+ */
+
+ /* Copy _stext_l1 to _etext_l1 to L1 instruction SRAM */
+ dma_memcpy(_stext_l1, _l1_lma_start, l1_code_length);
+
+ l1_data_a_length = _ebss_l1 - _sdata_l1;
+ if (l1_data_a_length > L1_DATA_A_LENGTH)
+ l1_data_a_length = L1_DATA_A_LENGTH;
+
+ /* Copy _sdata_l1 to _ebss_l1 to L1 data bank A SRAM */
+ dma_memcpy(_sdata_l1, _l1_lma_start + l1_code_length, l1_data_a_length);
+
+ l1_data_b_length = _ebss_b_l1 - _sdata_b_l1;
+ if (l1_data_b_length > L1_DATA_B_LENGTH)
+ l1_data_b_length = L1_DATA_B_LENGTH;
+
+ /* Copy _sdata_b_l1 to _ebss_b_l1 to L1 data bank B SRAM */
+ dma_memcpy(_sdata_b_l1, _l1_lma_start + l1_code_length +
+ l1_data_a_length, l1_data_b_length);
+
+}
+
+/*
+ * Initial parsing of the command line. Currently, we support:
+ * - Controlling the linux memory size: mem=xxx[KMG]
+ * - Controlling the physical memory size: max_mem=xxx[KMG][$][#]
+ * $ -> reserved memory is dcacheable
+ * # -> reserved memory is icacheable
+ */
+static __init void parse_cmdline_early(char *cmdline_p)
+{
+ char c = ' ', *to = cmdline_p;
+ unsigned int memsize;
+ for (;;) {
+ if (c == ' ') {
+
+ if (!memcmp(to, "mem=", 4)) {
+ to += 4;
+ memsize = memparse(to, &to);
+ if (memsize)
+ _ramend = memsize;
+
+ } else if (!memcmp(to, "max_mem=", 8)) {
+ to += 8;
+ memsize = memparse(to, &to);
+ if (memsize) {
+ physical_mem_end = memsize;
+ if (*to != ' ') {
+ if (*to == '$'
+ || *(to + 1) == '$')
+ reserved_mem_dcache_on =
+ 1;
+ if (*to == '#'
+ || *(to + 1) == '#')
+ reserved_mem_icache_on =
+ 1;
+ }
+ }
+ }
+
+ }
+ c = *(to++);
+ if (!c)
+ break;
+ }
+}
+
+void __init setup_arch(char **cmdline_p)
+{
+ int bootmap_size;
+ unsigned long l1_length, sclk, cclk;
+#ifdef CONFIG_MTD_UCLINUX
+ unsigned long mtd_phys = 0;
+#endif
+
+ cclk = get_cclk();
+ sclk = get_sclk();
+
+#if !defined(CONFIG_BFIN_KERNEL_CLOCK) && defined(ANOMALY_05000273)
+ if (cclk == sclk)
+ panic("ANOMALY 05000273, SCLK can not be same as CCLK");
+#endif
+
+#if defined(ANOMALY_05000266)
+ bfin_read_IMDMA_D0_IRQ_STATUS();
+ bfin_read_IMDMA_D1_IRQ_STATUS();
+#endif
+
+#ifdef DEBUG_SERIAL_EARLY_INIT
+ bfin_console_init(); /* early console registration */
+ /* this give a chance to get printk() working before crash. */
+#endif
+
+#if defined(CONFIG_CHR_DEV_FLASH) || defined(CONFIG_BLK_DEV_FLASH)
+ /* we need to initialize the Flashrom device here since we might
+ * do things with flash early on in the boot
+ */
+ flash_probe();
+#endif
+
+#if defined(CONFIG_CMDLINE_BOOL)
+ memset(command_line, 0, sizeof(command_line));
+ strncpy(&command_line[0], CONFIG_CMDLINE, sizeof(command_line));
+ command_line[sizeof(command_line) - 1] = 0;
+#endif
+
+ /* Keep a copy of command line */
+ *cmdline_p = &command_line[0];
+ memcpy(boot_command_line, command_line, COMMAND_LINE_SIZE);
+ boot_command_line[COMMAND_LINE_SIZE - 1] = 0;
+
+ /* setup memory defaults from the user config */
+ physical_mem_end = 0;
+ _ramend = CONFIG_MEM_SIZE * 1024 * 1024;
+
+ parse_cmdline_early(&command_line[0]);
+
+ if (physical_mem_end == 0)
+ physical_mem_end = _ramend;
+
+ /* by now the stack is part of the init task */
+ memory_end = _ramend - DMA_UNCACHED_REGION;
+
+ _ramstart = (unsigned long)__bss_stop;
+ memory_start = PAGE_ALIGN(_ramstart);
+
+#if defined(CONFIG_MTD_UCLINUX)
+ /* generic memory mapped MTD driver */
+ memory_mtd_end = memory_end;
+
+ mtd_phys = _ramstart;
+ mtd_size = PAGE_ALIGN(*((unsigned long *)(mtd_phys + 8)));
+
+# if defined(CONFIG_EXT2_FS) || defined(CONFIG_EXT3_FS)
+ if (*((unsigned short *)(mtd_phys + 0x438)) == EXT2_SUPER_MAGIC)
+ mtd_size =
+ PAGE_ALIGN(*((unsigned long *)(mtd_phys + 0x404)) << 10);
+# endif
+
+# if defined(CONFIG_CRAMFS)
+ if (*((unsigned long *)(mtd_phys)) == CRAMFS_MAGIC)
+ mtd_size = PAGE_ALIGN(*((unsigned long *)(mtd_phys + 0x4)));
+# endif
+
+# if defined(CONFIG_ROMFS_FS)
+ if (((unsigned long *)mtd_phys)[0] == ROMSB_WORD0
+ && ((unsigned long *)mtd_phys)[1] == ROMSB_WORD1)
+ mtd_size =
+ PAGE_ALIGN(be32_to_cpu(((unsigned long *)mtd_phys)[2]));
+# if (defined(CONFIG_BLKFIN_CACHE) && defined(ANOMALY_05000263))
+ /* Due to a Hardware Anomaly we need to limit the size of usable
+ * instruction memory to max 60MB, 56 if HUNT_FOR_ZERO is on
+ * 05000263 - Hardware loop corrupted when taking an ICPLB exception
+ */
+# if (defined(CONFIG_DEBUG_HUNT_FOR_ZERO))
+ if (memory_end >= 56 * 1024 * 1024)
+ memory_end = 56 * 1024 * 1024;
+# else
+ if (memory_end >= 60 * 1024 * 1024)
+ memory_end = 60 * 1024 * 1024;
+# endif /* CONFIG_DEBUG_HUNT_FOR_ZERO */
+# endif /* ANOMALY_05000263 */
+# endif /* CONFIG_ROMFS_FS */
+
+ memory_end -= mtd_size;
+
+ if (mtd_size == 0) {
+ console_init();
+ panic("Don't boot kernel without rootfs attached.\n");
+ }
+
+ /* Relocate MTD image to the top of memory after the uncached memory area */
+ dma_memcpy((char *)memory_end, __bss_stop, mtd_size);
+
+ memory_mtd_start = memory_end;
+ _ebss = memory_mtd_start; /* define _ebss for compatible */
+#endif /* CONFIG_MTD_UCLINUX */
+
+#if (defined(CONFIG_BLKFIN_CACHE) && defined(ANOMALY_05000263))
+ /* Due to a Hardware Anomaly we need to limit the size of usable
+ * instruction memory to max 60MB, 56 if HUNT_FOR_ZERO is on
+ * 05000263 - Hardware loop corrupted when taking an ICPLB exception
+ */
+#if (defined(CONFIG_DEBUG_HUNT_FOR_ZERO))
+ if (memory_end >= 56 * 1024 * 1024)
+ memory_end = 56 * 1024 * 1024;
+#else
+ if (memory_end >= 60 * 1024 * 1024)
+ memory_end = 60 * 1024 * 1024;
+#endif /* CONFIG_DEBUG_HUNT_FOR_ZERO */
+ printk(KERN_NOTICE "Warning: limiting memory to %liMB due to hardware anomaly 05000263\n", memory_end >> 20);
+#endif /* ANOMALY_05000263 */
+
+#if !defined(CONFIG_MTD_UCLINUX)
+ memory_end -= SIZE_4K; /*In case there is no valid CPLB behind memory_end make sure we don't get to close*/
+#endif
+ init_mm.start_code = (unsigned long)_stext;
+ init_mm.end_code = (unsigned long)_etext;
+ init_mm.end_data = (unsigned long)_edata;
+ init_mm.brk = (unsigned long)0;
+
+ init_leds();
+
+ printk(KERN_INFO "Blackfin support (C) 2004-2007 Analog Devices, Inc.\n");
+ printk(KERN_INFO "Compiled for ADSP-%s Rev 0.%d\n", CPU, bfin_compiled_revid());
+ if (bfin_revid() != bfin_compiled_revid())
+ printk(KERN_ERR "Warning: Compiled for Rev %d, but running on Rev %d\n",
+ bfin_compiled_revid(), bfin_revid());
+ if (bfin_revid() < SUPPORTED_REVID)
+ printk(KERN_ERR "Warning: Unsupported Chip Revision ADSP-%s Rev 0.%d detected\n",
+ CPU, bfin_revid());
+ printk(KERN_INFO "Blackfin Linux support by http://blackfin.uclinux.org/\n");
+
+ printk(KERN_INFO "Processor Speed: %lu MHz core clock and %lu Mhz System Clock\n",
+ cclk / 1000000, sclk / 1000000);
+
+#if defined(ANOMALY_05000273)
+ if ((cclk >> 1) <= sclk)
+ printk("\n\n\nANOMALY_05000273: CCLK must be >= 2*SCLK !!!\n\n\n");
+#endif
+
+ printk(KERN_INFO "Board Memory: %ldMB\n", physical_mem_end >> 20);
+ printk(KERN_INFO "Kernel Managed Memory: %ldMB\n", _ramend >> 20);
+
+ printk(KERN_INFO "Memory map:\n"
+ KERN_INFO " text = 0x%p-0x%p\n"
+ KERN_INFO " init = 0x%p-0x%p\n"
+ KERN_INFO " data = 0x%p-0x%p\n"
+ KERN_INFO " stack = 0x%p-0x%p\n"
+ KERN_INFO " bss = 0x%p-0x%p\n"
+ KERN_INFO " available = 0x%p-0x%p\n"
+#ifdef CONFIG_MTD_UCLINUX
+ KERN_INFO " rootfs = 0x%p-0x%p\n"
+#endif
+#if DMA_UNCACHED_REGION > 0
+ KERN_INFO " DMA Zone = 0x%p-0x%p\n"
+#endif
+ , _stext, _etext,
+ __init_begin, __init_end,
+ _sdata, _edata,
+ (void*)&init_thread_union, (void*)((int)(&init_thread_union) + 0x2000),
+ __bss_start, __bss_stop,
+ (void*)_ramstart, (void*)memory_end
+#ifdef CONFIG_MTD_UCLINUX
+ , (void*)memory_mtd_start, (void*)(memory_mtd_start + mtd_size)
+#endif
+#if DMA_UNCACHED_REGION > 0
+ , (void*)(_ramend - DMA_UNCACHED_REGION), (void*)(_ramend)
+#endif
+ );
+
+ /*
+ * give all the memory to the bootmap allocator, tell it to put the
+ * boot mem_map at the start of memory
+ */
+ bootmap_size = init_bootmem_node(NODE_DATA(0), memory_start >> PAGE_SHIFT, /* map goes here */
+ PAGE_OFFSET >> PAGE_SHIFT,
+ memory_end >> PAGE_SHIFT);
+ /*
+ * free the usable memory, we have to make sure we do not free
+ * the bootmem bitmap so we then reserve it after freeing it :-)
+ */
+ free_bootmem(memory_start, memory_end - memory_start);
+
+ reserve_bootmem(memory_start, bootmap_size);
+ /*
+ * get kmalloc into gear
+ */
+ paging_init();
+
+ /* check the size of the l1 area */
+ l1_length = _etext_l1 - _stext_l1;
+ if (l1_length > L1_CODE_LENGTH)
+ panic("L1 memory overflow\n");
+
+ l1_length = _ebss_l1 - _sdata_l1;
+ if (l1_length > L1_DATA_A_LENGTH)
+ panic("L1 memory overflow\n");
+
+ bf53x_cache_init();
+
+#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+# if defined(CONFIG_BFIN_SHARED_FLASH_ENET) && defined(CONFIG_BFIN533_STAMP)
+ /* setup BF533_STAMP CPLD to route AMS3 to Ethernet MAC */
+ bfin_write_FIO_DIR(bfin_read_FIO_DIR() | (1 << CONFIG_ENET_FLASH_PIN));
+ bfin_write_FIO_FLAG_S(1 << CONFIG_ENET_FLASH_PIN);
+ SSYNC();
+# endif
+# if defined (CONFIG_BFIN561_EZKIT)
+ bfin_write_FIO0_DIR(bfin_read_FIO0_DIR() | (1 << 12));
+ SSYNC();
+# endif /* defined (CONFIG_BFIN561_EZKIT) */
+#endif
+
+ printk(KERN_INFO "Hardware Trace Enabled\n");
+ bfin_write_TBUFCTL(0x03);
+}
+
+#if defined(CONFIG_BF561)
+static struct cpu cpu[2];
+#else
+static struct cpu cpu[1];
+#endif
+static int __init topology_init(void)
+{
+#if defined (CONFIG_BF561)
+ register_cpu(&cpu[0], 0);
+ register_cpu(&cpu[1], 1);
+ return 0;
+#else
+ return register_cpu(cpu, 0);
+#endif
+}
+
+subsys_initcall(topology_init);
+
+#if defined(CONFIG_BLKFIN_DCACHE) || defined(CONFIG_BLKFIN_CACHE)
+u16 lock_kernel_check(u32 start, u32 end)
+{
+ if ((start <= (u32) _stext && end >= (u32) _end)
+ || (start >= (u32) _stext && end <= (u32) _end))
+ return IN_KERNEL;
+ return 0;
+}
+
+static unsigned short __init
+fill_cplbtab(struct cplb_tab *table,
+ unsigned long start, unsigned long end,
+ unsigned long block_size, unsigned long cplb_data)
+{
+ int i;
+
+ switch (block_size) {
+ case SIZE_4M:
+ i = 3;
+ break;
+ case SIZE_1M:
+ i = 2;
+ break;
+ case SIZE_4K:
+ i = 1;
+ break;
+ case SIZE_1K:
+ default:
+ i = 0;
+ break;
+ }
+
+ cplb_data = (cplb_data & ~(3 << 16)) | (i << 16);
+
+ while ((start < end) && (table->pos < table->size)) {
+
+ table->tab[table->pos++] = start;
+
+ if (lock_kernel_check(start, start + block_size) == IN_KERNEL)
+ table->tab[table->pos++] =
+ cplb_data | CPLB_LOCK | CPLB_DIRTY;
+ else
+ table->tab[table->pos++] = cplb_data;
+
+ start += block_size;
+ }
+ return 0;
+}
+
+static unsigned short __init
+close_cplbtab(struct cplb_tab *table)
+{
+
+ while (table->pos < table->size) {
+
+ table->tab[table->pos++] = 0;
+ table->tab[table->pos++] = 0; /* !CPLB_VALID */
+ }
+ return 0;
+}
+
+static void __init generate_cpl_tables(void)
+{
+
+ u16 i, j, process;
+ u32 a_start, a_end, as, ae, as_1m;
+
+ struct cplb_tab *t_i = NULL;
+ struct cplb_tab *t_d = NULL;
+ struct s_cplb cplb;
+
+ cplb.init_i.size = MAX_CPLBS;
+ cplb.init_d.size = MAX_CPLBS;
+ cplb.switch_i.size = MAX_SWITCH_I_CPLBS;
+ cplb.switch_d.size = MAX_SWITCH_D_CPLBS;
+
+ cplb.init_i.pos = 0;
+ cplb.init_d.pos = 0;
+ cplb.switch_i.pos = 0;
+ cplb.switch_d.pos = 0;
+
+ cplb.init_i.tab = icplb_table;
+ cplb.init_d.tab = dcplb_table;
+ cplb.switch_i.tab = ipdt_table;
+ cplb.switch_d.tab = dpdt_table;
+
+ cplb_data[SDRAM_KERN].end = memory_end;
+
+#ifdef CONFIG_MTD_UCLINUX
+ cplb_data[SDRAM_RAM_MTD].start = memory_mtd_start;
+ cplb_data[SDRAM_RAM_MTD].end = memory_mtd_start + mtd_size;
+ cplb_data[SDRAM_RAM_MTD].valid = mtd_size > 0;
+# if defined(CONFIG_ROMFS_FS)
+ cplb_data[SDRAM_RAM_MTD].attr |= I_CPLB;
+
+ /*
+ * The ROMFS_FS size is often not multiple of 1MB.
+ * This can cause multiple CPLB sets covering the same memory area.
+ * This will then cause multiple CPLB hit exceptions.
+ * Workaround: We ensure a contiguous memory area by extending the kernel
+ * memory section over the mtd section.
+ * For ROMFS_FS memory must be covered with ICPLBs anyways.
+ * So there is no difference between kernel and mtd memory setup.
+ */
+
+ cplb_data[SDRAM_KERN].end = memory_mtd_start + mtd_size;;
+ cplb_data[SDRAM_RAM_MTD].valid = 0;
+
+# endif
+#else
+ cplb_data[SDRAM_RAM_MTD].valid = 0;
+#endif
+
+ cplb_data[SDRAM_DMAZ].start = _ramend - DMA_UNCACHED_REGION;
+ cplb_data[SDRAM_DMAZ].end = _ramend;
+
+ cplb_data[RES_MEM].start = _ramend;
+ cplb_data[RES_MEM].end = physical_mem_end;
+
+ if (reserved_mem_dcache_on)
+ cplb_data[RES_MEM].d_conf = SDRAM_DGENERIC;
+ else
+ cplb_data[RES_MEM].d_conf = SDRAM_DNON_CHBL;
+
+ if (reserved_mem_icache_on)
+ cplb_data[RES_MEM].i_conf = SDRAM_IGENERIC;
+ else
+ cplb_data[RES_MEM].i_conf = SDRAM_INON_CHBL;
+
+ for (i = ZERO_P; i <= L2_MEM; i++) {
+
+ if (cplb_data[i].valid) {
+
+ as_1m = cplb_data[i].start % SIZE_1M;
+
+ /* We need to make sure all sections are properly 1M aligned
+ * However between Kernel Memory and the Kernel mtd section, depending on the
+ * rootfs size, there can be overlapping memory areas.
+ */
+
+ if (as_1m && i!=L1I_MEM && i!=L1D_MEM) {
+#ifdef CONFIG_MTD_UCLINUX
+ if (i == SDRAM_RAM_MTD) {
+ if ((cplb_data[SDRAM_KERN].end + 1) > cplb_data[SDRAM_RAM_MTD].start)
+ cplb_data[SDRAM_RAM_MTD].start = (cplb_data[i].start & (-2*SIZE_1M)) + SIZE_1M;
+ else
+ cplb_data[SDRAM_RAM_MTD].start = (cplb_data[i].start & (-2*SIZE_1M));
+ } else
+#endif
+ printk(KERN_WARNING "Unaligned Start of %s at 0x%X\n",
+ cplb_data[i].name, cplb_data[i].start);
+ }
+
+ as = cplb_data[i].start % SIZE_4M;
+ ae = cplb_data[i].end % SIZE_4M;
+
+ if (as)
+ a_start = cplb_data[i].start + (SIZE_4M - (as));
+ else
+ a_start = cplb_data[i].start;
+
+ a_end = cplb_data[i].end - ae;
+
+ for (j = INITIAL_T; j <= SWITCH_T; j++) {
+
+ switch (j) {
+ case INITIAL_T:
+ if (cplb_data[i].attr & INITIAL_T) {
+ t_i = &cplb.init_i;
+ t_d = &cplb.init_d;
+ process = 1;
+ } else
+ process = 0;
+ break;
+ case SWITCH_T:
+ if (cplb_data[i].attr & SWITCH_T) {
+ t_i = &cplb.switch_i;
+ t_d = &cplb.switch_d;
+ process = 1;
+ } else
+ process = 0;
+ break;
+ default:
+ process = 0;
+ break;
+ }
+
+ if (process) {
+ if (cplb_data[i].attr & I_CPLB) {
+
+ if (cplb_data[i].psize) {
+ fill_cplbtab(t_i,
+ cplb_data[i].start,
+ cplb_data[i].end,
+ cplb_data[i].psize,
+ cplb_data[i].i_conf);
+ } else {
+ /*icplb_table */
+#if (defined(CONFIG_BLKFIN_CACHE) && defined(ANOMALY_05000263))
+ if (i == SDRAM_KERN) {
+ fill_cplbtab(t_i,
+ cplb_data[i].start,
+ cplb_data[i].end,
+ SIZE_4M,
+ cplb_data[i].i_conf);
+ } else
+#endif
+ {
+ fill_cplbtab(t_i,
+ cplb_data[i].start,
+ a_start,
+ SIZE_1M,
+ cplb_data[i].i_conf);
+ fill_cplbtab(t_i,
+ a_start,
+ a_end,
+ SIZE_4M,
+ cplb_data[i].i_conf);
+ fill_cplbtab(t_i, a_end,
+ cplb_data[i].end,
+ SIZE_1M,
+ cplb_data[i].i_conf);
+ }
+ }
+
+ }
+ if (cplb_data[i].attr & D_CPLB) {
+
+ if (cplb_data[i].psize) {
+ fill_cplbtab(t_d,
+ cplb_data[i].start,
+ cplb_data[i].end,
+ cplb_data[i].psize,
+ cplb_data[i].d_conf);
+ } else {
+/*dcplb_table*/
+ fill_cplbtab(t_d,
+ cplb_data[i].start,
+ a_start, SIZE_1M,
+ cplb_data[i].d_conf);
+ fill_cplbtab(t_d, a_start,
+ a_end, SIZE_4M,
+ cplb_data[i].d_conf);
+ fill_cplbtab(t_d, a_end,
+ cplb_data[i].end,
+ SIZE_1M,
+ cplb_data[i].d_conf);
+
+ }
+
+ }
+ }
+ }
+
+ }
+ }
+
+/* close tables */
+
+ close_cplbtab(&cplb.init_i);
+ close_cplbtab(&cplb.init_d);
+
+ cplb.init_i.tab[cplb.init_i.pos] = -1;
+ cplb.init_d.tab[cplb.init_d.pos] = -1;
+ cplb.switch_i.tab[cplb.switch_i.pos] = -1;
+ cplb.switch_d.tab[cplb.switch_d.pos] = -1;
+
+}
+
+#endif
+
+static inline u_long get_vco(void)
+{
+ u_long msel;
+ u_long vco;
+
+ msel = (bfin_read_PLL_CTL() >> 9) & 0x3F;
+ if (0 == msel)
+ msel = 64;
+
+ vco = CONFIG_CLKIN_HZ;
+ vco >>= (1 & bfin_read_PLL_CTL()); /* DF bit */
+ vco = msel * vco;
+ return vco;
+}
+
+/*Get the Core clock*/
+u_long get_cclk(void)
+{
+ u_long csel, ssel;
+ if (bfin_read_PLL_STAT() & 0x1)
+ return CONFIG_CLKIN_HZ;
+
+ ssel = bfin_read_PLL_DIV();
+ csel = ((ssel >> 4) & 0x03);
+ ssel &= 0xf;
+ if (ssel && ssel < (1 << csel)) /* SCLK > CCLK */
+ return get_vco() / ssel;
+ return get_vco() >> csel;
+}
+
+EXPORT_SYMBOL(get_cclk);
+
+/* Get the System clock */
+u_long get_sclk(void)
+{
+ u_long ssel;
+
+ if (bfin_read_PLL_STAT() & 0x1)
+ return CONFIG_CLKIN_HZ;
+
+ ssel = (bfin_read_PLL_DIV() & 0xf);
+ if (0 == ssel) {
+ printk(KERN_WARNING "Invalid System Clock\n");
+ ssel = 1;
+ }
+
+ return get_vco() / ssel;
+}
+
+EXPORT_SYMBOL(get_sclk);
+
+/*
+ * Get CPU information for use by the procfs.
+ */
+static int show_cpuinfo(struct seq_file *m, void *v)
+{
+ char *cpu, *mmu, *fpu, *name;
+ uint32_t revid;
+
+ u_long cclk = 0, sclk = 0;
+ u_int dcache_size = 0, dsup_banks = 0;
+
+ cpu = CPU;
+ mmu = "none";
+ fpu = "none";
+ revid = bfin_revid();
+ name = bfin_board_name;
+
+ cclk = get_cclk();
+ sclk = get_sclk();
+
+ seq_printf(m, "CPU:\t\tADSP-%s Rev. 0.%d\n"
+ "MMU:\t\t%s\n"
+ "FPU:\t\t%s\n"
+ "Core Clock:\t%9lu Hz\n"
+ "System Clock:\t%9lu Hz\n"
+ "BogoMips:\t%lu.%02lu\n"
+ "Calibration:\t%lu loops\n",
+ cpu, revid, mmu, fpu,
+ cclk,
+ sclk,
+ (loops_per_jiffy * HZ) / 500000,
+ ((loops_per_jiffy * HZ) / 5000) % 100,
+ (loops_per_jiffy * HZ));
+ seq_printf(m, "Board Name:\t%s\n", name);
+ seq_printf(m, "Board Memory:\t%ld MB\n", physical_mem_end >> 20);
+ seq_printf(m, "Kernel Memory:\t%ld MB\n", (unsigned long)_ramend >> 20);
+ if (bfin_read_IMEM_CONTROL() & (ENICPLB | IMC))
+ seq_printf(m, "I-CACHE:\tON\n");
+ else
+ seq_printf(m, "I-CACHE:\tOFF\n");
+ if ((bfin_read_DMEM_CONTROL()) & (ENDCPLB | DMC_ENABLE))
+ seq_printf(m, "D-CACHE:\tON"
+#if defined CONFIG_BLKFIN_WB
+ " (write-back)"
+#elif defined CONFIG_BLKFIN_WT
+ " (write-through)"
+#endif
+ "\n");
+ else
+ seq_printf(m, "D-CACHE:\tOFF\n");
+
+
+ switch(bfin_read_DMEM_CONTROL() & (1 << DMC0_P | 1 << DMC1_P)) {
+ case ACACHE_BSRAM:
+ seq_printf(m, "DBANK-A:\tCACHE\n" "DBANK-B:\tSRAM\n");
+ dcache_size = 16;
+ dsup_banks = 1;
+ break;
+ case ACACHE_BCACHE:
+ seq_printf(m, "DBANK-A:\tCACHE\n" "DBANK-B:\tCACHE\n");
+ dcache_size = 32;
+ dsup_banks = 2;
+ break;
+ case ASRAM_BSRAM:
+ seq_printf(m, "DBANK-A:\tSRAM\n" "DBANK-B:\tSRAM\n");
+ dcache_size = 0;
+ dsup_banks = 0;
+ break;
+ default:
+ break;
+ }
+
+
+ seq_printf(m, "I-CACHE Size:\t%dKB\n", BLKFIN_ICACHESIZE / 1024);
+ seq_printf(m, "D-CACHE Size:\t%dKB\n", dcache_size);
+ seq_printf(m, "I-CACHE Setup:\t%d Sub-banks/%d Ways, %d Lines/Way\n",
+ BLKFIN_ISUBBANKS, BLKFIN_IWAYS, BLKFIN_ILINES);
+ seq_printf(m,
+ "D-CACHE Setup:\t%d Super-banks/%d Sub-banks/%d Ways, %d Lines/Way\n",
+ dsup_banks, BLKFIN_DSUBBANKS, BLKFIN_DWAYS,
+ BLKFIN_DLINES);
+#ifdef CONFIG_BLKFIN_CACHE_LOCK
+ switch (read_iloc()) {
+ case WAY0_L:
+ seq_printf(m, "Way0 Locked-Down\n");
+ break;
+ case WAY1_L:
+ seq_printf(m, "Way1 Locked-Down\n");
+ break;
+ case WAY01_L:
+ seq_printf(m, "Way0,Way1 Locked-Down\n");
+ break;
+ case WAY2_L:
+ seq_printf(m, "Way2 Locked-Down\n");
+ break;
+ case WAY02_L:
+ seq_printf(m, "Way0,Way2 Locked-Down\n");
+ break;
+ case WAY12_L:
+ seq_printf(m, "Way1,Way2 Locked-Down\n");
+ break;
+ case WAY012_L:
+ seq_printf(m, "Way0,Way1 & Way2 Locked-Down\n");
+ break;
+ case WAY3_L:
+ seq_printf(m, "Way3 Locked-Down\n");
+ break;
+ case WAY03_L:
+ seq_printf(m, "Way0,Way3 Locked-Down\n");
+ break;
+ case WAY13_L:
+ seq_printf(m, "Way1,Way3 Locked-Down\n");
+ break;
+ case WAY013_L:
+ seq_printf(m, "Way 0,Way1,Way3 Locked-Down\n");
+ break;
+ case WAY32_L:
+ seq_printf(m, "Way3,Way2 Locked-Down\n");
+ break;
+ case WAY320_L:
+ seq_printf(m, "Way3,Way2,Way0 Locked-Down\n");
+ break;
+ case WAY321_L:
+ seq_printf(m, "Way3,Way2,Way1 Locked-Down\n");
+ break;
+ case WAYALL_L:
+ seq_printf(m, "All Ways are locked\n");
+ break;
+ default:
+ seq_printf(m, "No Ways are locked\n");
+ }
+#endif
+ return 0;
+}
+
+static void *c_start(struct seq_file *m, loff_t *pos)
+{
+ return *pos < NR_CPUS ? ((void *)0x12345678) : NULL;
+}
+
+static void *c_next(struct seq_file *m, void *v, loff_t *pos)
+{
+ ++*pos;
+ return c_start(m, pos);
+}
+
+static void c_stop(struct seq_file *m, void *v)
+{
+}
+
+struct seq_operations cpuinfo_op = {
+ .start = c_start,
+ .next = c_next,
+ .stop = c_stop,
+ .show = show_cpuinfo,
+};
+
+void cmdline_init(unsigned long r0)
+{
+ if (r0)
+ strncpy(command_line, (char *)r0, COMMAND_LINE_SIZE);
+}
diff --git a/arch/blackfin/kernel/signal.c b/arch/blackfin/kernel/signal.c
new file mode 100644
index 00000000000..316e65c3439
--- /dev/null
+++ b/arch/blackfin/kernel/signal.c
@@ -0,0 +1,356 @@
+/*
+ * File: arch/blackfin/kernel/signal.c
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/signal.h>
+#include <linux/syscalls.h>
+#include <linux/ptrace.h>
+#include <linux/tty.h>
+#include <linux/personality.h>
+#include <linux/binfmts.h>
+#include <linux/freezer.h>
+
+#include <asm/uaccess.h>
+#include <asm/cacheflush.h>
+#include <asm/ucontext.h>
+
+#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
+
+struct fdpic_func_descriptor {
+ unsigned long text;
+ unsigned long GOT;
+};
+
+struct rt_sigframe {
+ int sig;
+ struct siginfo *pinfo;
+ void *puc;
+ char retcode[8];
+ struct siginfo info;
+ struct ucontext uc;
+};
+
+asmlinkage int sys_sigaltstack(const stack_t * uss, stack_t * uoss)
+{
+ return do_sigaltstack(uss, uoss, rdusp());
+}
+
+static inline int
+rt_restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc, int *pr0)
+{
+ unsigned long usp = 0;
+ int err = 0;
+
+#define RESTORE(x) err |= __get_user(regs->x, &sc->sc_##x)
+
+ /* restore passed registers */
+ RESTORE(r0); RESTORE(r1); RESTORE(r2); RESTORE(r3);
+ RESTORE(r4); RESTORE(r5); RESTORE(r6); RESTORE(r7);
+ RESTORE(p0); RESTORE(p1); RESTORE(p2); RESTORE(p3);
+ RESTORE(p4); RESTORE(p5);
+ err |= __get_user(usp, &sc->sc_usp);
+ wrusp(usp);
+ RESTORE(a0w); RESTORE(a1w);
+ RESTORE(a0x); RESTORE(a1x);
+ RESTORE(astat);
+ RESTORE(rets);
+ RESTORE(pc);
+ RESTORE(retx);
+ RESTORE(fp);
+ RESTORE(i0); RESTORE(i1); RESTORE(i2); RESTORE(i3);
+ RESTORE(m0); RESTORE(m1); RESTORE(m2); RESTORE(m3);
+ RESTORE(l0); RESTORE(l1); RESTORE(l2); RESTORE(l3);
+ RESTORE(b0); RESTORE(b1); RESTORE(b2); RESTORE(b3);
+ RESTORE(lc0); RESTORE(lc1);
+ RESTORE(lt0); RESTORE(lt1);
+ RESTORE(lb0); RESTORE(lb1);
+ RESTORE(seqstat);
+
+ regs->orig_p0 = -1; /* disable syscall checks */
+
+ *pr0 = regs->r0;
+ return err;
+}
+
+asmlinkage int do_rt_sigreturn(unsigned long __unused)
+{
+ struct pt_regs *regs = (struct pt_regs *)__unused;
+ unsigned long usp = rdusp();
+ struct rt_sigframe *frame = (struct rt_sigframe *)(usp);
+ sigset_t set;
+ int r0;
+
+ if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
+ goto badframe;
+ if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
+ goto badframe;
+
+ sigdelsetmask(&set, ~_BLOCKABLE);
+ spin_lock_irq(&current->sighand->siglock);
+ current->blocked = set;
+ recalc_sigpending();
+ spin_unlock_irq(&current->sighand->siglock);
+
+ if (rt_restore_sigcontext(regs, &frame->uc.uc_mcontext, &r0))
+ goto badframe;
+
+ if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->usp) == -EFAULT)
+ goto badframe;
+
+ return r0;
+
+ badframe:
+ force_sig(SIGSEGV, current);
+ return 0;
+}
+
+static inline int rt_setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs)
+{
+ int err = 0;
+
+#define SETUP(x) err |= __put_user(regs->x, &sc->sc_##x)
+
+ SETUP(r0); SETUP(r1); SETUP(r2); SETUP(r3);
+ SETUP(r4); SETUP(r5); SETUP(r6); SETUP(r7);
+ SETUP(p0); SETUP(p1); SETUP(p2); SETUP(p3);
+ SETUP(p4); SETUP(p5);
+ err |= __put_user(rdusp(), &sc->sc_usp);
+ SETUP(a0w); SETUP(a1w);
+ SETUP(a0x); SETUP(a1x);
+ SETUP(astat);
+ SETUP(rets);
+ SETUP(pc);
+ SETUP(retx);
+ SETUP(fp);
+ SETUP(i0); SETUP(i1); SETUP(i2); SETUP(i3);
+ SETUP(m0); SETUP(m1); SETUP(m2); SETUP(m3);
+ SETUP(l0); SETUP(l1); SETUP(l2); SETUP(l3);
+ SETUP(b0); SETUP(b1); SETUP(b2); SETUP(b3);
+ SETUP(lc0); SETUP(lc1);
+ SETUP(lt0); SETUP(lt1);
+ SETUP(lb0); SETUP(lb1);
+ SETUP(seqstat);
+
+ return err;
+}
+
+static inline void push_cache(unsigned long vaddr, unsigned int len)
+{
+ flush_icache_range(vaddr, vaddr + len);
+}
+
+static inline void *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
+ size_t frame_size)
+{
+ unsigned long usp;
+
+ /* Default to using normal stack. */
+ usp = rdusp();
+
+ /* This is the X/Open sanctioned signal stack switching. */
+ if (ka->sa.sa_flags & SA_ONSTACK) {
+ if (!on_sig_stack(usp))
+ usp = current->sas_ss_sp + current->sas_ss_size;
+ }
+ return (void *)((usp - frame_size) & -8UL);
+}
+
+static int
+setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t * info,
+ sigset_t * set, struct pt_regs *regs)
+{
+ struct rt_sigframe *frame;
+ int err = 0;
+
+ frame = get_sigframe(ka, regs, sizeof(*frame));
+
+ err |= __put_user((current_thread_info()->exec_domain
+ && current_thread_info()->exec_domain->signal_invmap
+ && sig < 32
+ ? current_thread_info()->exec_domain->
+ signal_invmap[sig] : sig), &frame->sig);
+
+ err |= __put_user(&frame->info, &frame->pinfo);
+ err |= __put_user(&frame->uc, &frame->puc);
+ err |= copy_siginfo_to_user(&frame->info, info);
+
+ /* Create the ucontext. */
+ err |= __put_user(0, &frame->uc.uc_flags);
+ err |= __put_user(0, &frame->uc.uc_link);
+ err |=
+ __put_user((void *)current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
+ err |= __put_user(sas_ss_flags(rdusp()), &frame->uc.uc_stack.ss_flags);
+ err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
+ err |= rt_setup_sigcontext(&frame->uc.uc_mcontext, regs);
+ err |= copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
+
+ /* Set up to return from userspace. */
+ err |= __put_user(0x28, &(frame->retcode[0]));
+ err |= __put_user(0xe1, &(frame->retcode[1]));
+ err |= __put_user(0xad, &(frame->retcode[2]));
+ err |= __put_user(0x00, &(frame->retcode[3]));
+ err |= __put_user(0xa0, &(frame->retcode[4]));
+ err |= __put_user(0x00, &(frame->retcode[5]));
+
+ if (err)
+ goto give_sigsegv;
+
+ push_cache((unsigned long)&frame->retcode, sizeof(frame->retcode));
+
+ /* Set up registers for signal handler */
+ wrusp((unsigned long)frame);
+ if (get_personality & FDPIC_FUNCPTRS) {
+ struct fdpic_func_descriptor __user *funcptr =
+ (struct fdpic_func_descriptor *) ka->sa.sa_handler;
+ __get_user(regs->pc, &funcptr->text);
+ __get_user(regs->p3, &funcptr->GOT);
+ } else
+ regs->pc = (unsigned long)ka->sa.sa_handler;
+ regs->rets = (unsigned long)(frame->retcode);
+
+ regs->r0 = frame->sig;
+ regs->r1 = (unsigned long)(&frame->info);
+ regs->r2 = (unsigned long)(&frame->uc);
+
+ return 0;
+
+ give_sigsegv:
+ if (sig == SIGSEGV)
+ ka->sa.sa_handler = SIG_DFL;
+ force_sig(SIGSEGV, current);
+ return -EFAULT;
+}
+
+static inline void
+handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler)
+{
+ switch (regs->r0) {
+ case -ERESTARTNOHAND:
+ if (!has_handler)
+ goto do_restart;
+ regs->r0 = -EINTR;
+ break;
+
+ case -ERESTARTSYS:
+ if (has_handler && !(ka->sa.sa_flags & SA_RESTART)) {
+ regs->r0 = -EINTR;
+ break;
+ }
+ /* fallthrough */
+ case -ERESTARTNOINTR:
+ do_restart:
+ regs->p0 = regs->orig_p0;
+ regs->r0 = regs->orig_r0;
+ regs->pc -= 2;
+ break;
+ }
+}
+
+/*
+ * OK, we're invoking a handler
+ */
+static int
+handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka,
+ sigset_t *oldset, struct pt_regs *regs)
+{
+ int ret;
+
+ /* are we from a system call? to see pt_regs->orig_p0 */
+ if (regs->orig_p0 >= 0)
+ /* If so, check system call restarting.. */
+ handle_restart(regs, ka, 1);
+
+ /* set up the stack frame */
+ ret = setup_rt_frame(sig, ka, info, oldset, regs);
+
+ if (ret == 0) {
+ spin_lock_irq(&current->sighand->siglock);
+ sigorsets(&current->blocked, &current->blocked,
+ &ka->sa.sa_mask);
+ if (!(ka->sa.sa_flags & SA_NODEFER))
+ sigaddset(&current->blocked, sig);
+ recalc_sigpending();
+ spin_unlock_irq(&current->sighand->siglock);
+ }
+ return ret;
+}
+
+/*
+ * Note that 'init' is a special process: it doesn't get signals it doesn't
+ * want to handle. Thus you cannot kill init even with a SIGKILL even by
+ * mistake.
+ *
+ * Note that we go through the signals twice: once to check the signals
+ * that the kernel can handle, and then we build all the user-level signal
+ * handling stack-frames in one go after that.
+ */
+asmlinkage void do_signal(struct pt_regs *regs)
+{
+ siginfo_t info;
+ int signr;
+ struct k_sigaction ka;
+ sigset_t *oldset;
+
+ current->thread.esp0 = (unsigned long)regs;
+
+ if (try_to_freeze())
+ goto no_signal;
+
+ if (test_thread_flag(TIF_RESTORE_SIGMASK))
+ oldset = &current->saved_sigmask;
+ else
+ oldset = &current->blocked;
+
+ signr = get_signal_to_deliver(&info, &ka, regs, NULL);
+ if (signr > 0) {
+ /* Whee! Actually deliver the signal. */
+ if (handle_signal(signr, &info, &ka, oldset, regs) == 0) {
+ /* a signal was successfully delivered; the saved
+ * sigmask will have been stored in the signal frame,
+ * and will be restored by sigreturn, so we can simply
+ * clear the TIF_RESTORE_SIGMASK flag */
+ if (test_thread_flag(TIF_RESTORE_SIGMASK))
+ clear_thread_flag(TIF_RESTORE_SIGMASK);
+ }
+
+ return;
+ }
+
+no_signal:
+ /* Did we come from a system call? */
+ if (regs->orig_p0 >= 0)
+ /* Restart the system call - no handlers present */
+ handle_restart(regs, NULL, 0);
+
+ /* if there's no signal to deliver, we just put the saved sigmask
+ * back */
+ if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
+ clear_thread_flag(TIF_RESTORE_SIGMASK);
+ sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
+ }
+}
diff --git a/arch/blackfin/kernel/sys_bfin.c b/arch/blackfin/kernel/sys_bfin.c
new file mode 100644
index 00000000000..f436e6743f5
--- /dev/null
+++ b/arch/blackfin/kernel/sys_bfin.c
@@ -0,0 +1,115 @@
+/*
+ * File: arch/blackfin/kernel/sys_bfin.c
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description: This file contains various random system calls that
+ * have a non-standard calling sequence on the Linux/bfin
+ * platform.
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/smp_lock.h>
+#include <linux/spinlock.h>
+#include <linux/sem.h>
+#include <linux/msg.h>
+#include <linux/shm.h>
+#include <linux/syscalls.h>
+#include <linux/mman.h>
+#include <linux/file.h>
+
+#include <asm/cacheflush.h>
+#include <asm/uaccess.h>
+#include <asm/ipc.h>
+#include <asm/dma.h>
+#include <asm/unistd.h>
+
+/*
+ * sys_pipe() is the normal C calling standard for creating
+ * a pipe. It's not the way unix traditionally does this, though.
+ */
+asmlinkage int sys_pipe(unsigned long *fildes)
+{
+ int fd[2];
+ int error;
+
+ error = do_pipe(fd);
+ if (!error) {
+ if (copy_to_user(fildes, fd, 2 * sizeof(int)))
+ error = -EFAULT;
+ }
+ return error;
+}
+
+/* common code for old and new mmaps */
+static inline long
+do_mmap2(unsigned long addr, unsigned long len,
+ unsigned long prot, unsigned long flags,
+ unsigned long fd, unsigned long pgoff)
+{
+ int error = -EBADF;
+ struct file *file = NULL;
+
+ flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+ if (!(flags & MAP_ANONYMOUS)) {
+ file = fget(fd);
+ if (!file)
+ goto out;
+ }
+
+ down_write(&current->mm->mmap_sem);
+ error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
+ up_write(&current->mm->mmap_sem);
+
+ if (file)
+ fput(file);
+ out:
+ return error;
+}
+
+asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
+ unsigned long prot, unsigned long flags,
+ unsigned long fd, unsigned long pgoff)
+{
+ return do_mmap2(addr, len, prot, flags, fd, pgoff);
+}
+
+asmlinkage int sys_getpagesize(void)
+{
+ return PAGE_SIZE;
+}
+
+asmlinkage void *sys_sram_alloc(size_t size, unsigned long flags)
+{
+ return sram_alloc_with_lsl(size, flags);
+}
+
+asmlinkage int sys_sram_free(const void *addr)
+{
+ return sram_free_with_lsl(addr);
+}
+
+asmlinkage void *sys_dma_memcpy(void *dest, const void *src, size_t len)
+{
+ return safe_dma_memcpy(dest, src, len);
+}
diff --git a/arch/blackfin/kernel/time.c b/arch/blackfin/kernel/time.c
new file mode 100644
index 00000000000..f578176b6d9
--- /dev/null
+++ b/arch/blackfin/kernel/time.c
@@ -0,0 +1,326 @@
+/*
+ * File: arch/blackfin/kernel/time.c
+ * Based on: none - original work
+ * Author:
+ *
+ * Created:
+ * Description: This file contains the bfin-specific time handling details.
+ * Most of the stuff is located in the machine specific files.
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/module.h>
+#include <linux/profile.h>
+#include <linux/interrupt.h>
+#include <linux/time.h>
+#include <linux/irq.h>
+
+#include <asm/blackfin.h>
+
+/* This is an NTP setting */
+#define TICK_SIZE (tick_nsec / 1000)
+
+static void time_sched_init(irqreturn_t(*timer_routine)
+ (int, void *));
+static unsigned long gettimeoffset(void);
+static inline void do_leds(void);
+
+#if (defined(CONFIG_BFIN_ALIVE_LED) || defined(CONFIG_BFIN_IDLE_LED))
+void __init init_leds(void)
+{
+ unsigned int tmp = 0;
+
+#if defined(CONFIG_BFIN_ALIVE_LED)
+ /* config pins as output. */
+ tmp = bfin_read_CONFIG_BFIN_ALIVE_LED_DPORT();
+ SSYNC();
+ bfin_write_CONFIG_BFIN_ALIVE_LED_DPORT(tmp | CONFIG_BFIN_ALIVE_LED_PIN);
+ SSYNC();
+
+ /* First set led be off */
+ tmp = bfin_read_CONFIG_BFIN_ALIVE_LED_PORT();
+ SSYNC();
+ bfin_write_CONFIG_BFIN_ALIVE_LED_PORT(tmp | CONFIG_BFIN_ALIVE_LED_PIN); /* light off */
+ SSYNC();
+#endif
+
+#if defined(CONFIG_BFIN_IDLE_LED)
+ /* config pins as output. */
+ tmp = bfin_read_CONFIG_BFIN_IDLE_LED_DPORT();
+ SSYNC();
+ bfin_write_CONFIG_BFIN_IDLE_LED_DPORT(tmp | CONFIG_BFIN_IDLE_LED_PIN);
+ SSYNC();
+
+ /* First set led be off */
+ tmp = bfin_read_CONFIG_BFIN_IDLE_LED_PORT();
+ SSYNC();
+ bfin_write_CONFIG_BFIN_IDLE_LED_PORT(tmp | CONFIG_BFIN_IDLE_LED_PIN); /* light off */
+ SSYNC();
+#endif
+}
+#else
+void __init init_leds(void)
+{
+}
+#endif
+
+#if defined(CONFIG_BFIN_ALIVE_LED)
+static inline void do_leds(void)
+{
+ static unsigned int count = 50;
+ static int flag = 0;
+ unsigned short tmp = 0;
+
+ if (--count == 0) {
+ count = 50;
+ flag = ~flag;
+ }
+ tmp = bfin_read_CONFIG_BFIN_ALIVE_LED_PORT();
+ SSYNC();
+
+ if (flag)
+ tmp &= ~CONFIG_BFIN_ALIVE_LED_PIN; /* light on */
+ else
+ tmp |= CONFIG_BFIN_ALIVE_LED_PIN; /* light off */
+
+ bfin_write_CONFIG_BFIN_ALIVE_LED_PORT(tmp);
+ SSYNC();
+
+}
+#else
+static inline void do_leds(void)
+{
+}
+#endif
+
+static struct irqaction bfin_timer_irq = {
+ .name = "BFIN Timer Tick",
+ .flags = IRQF_DISABLED
+};
+
+/*
+ * The way that the Blackfin core timer works is:
+ * - CCLK is divided by a programmable 8-bit pre-scaler (TSCALE)
+ * - Every time TSCALE ticks, a 32bit is counted down (TCOUNT)
+ *
+ * If you take the fastest clock (1ns, or 1GHz to make the math work easier)
+ * 10ms is 10,000,000 clock ticks, which fits easy into a 32-bit counter
+ * (32 bit counter is 4,294,967,296ns or 4.2 seconds) so, we don't need
+ * to use TSCALE, and program it to zero (which is pass CCLK through).
+ * If you feel like using it, try to keep HZ * TIMESCALE to some
+ * value that divides easy (like power of 2).
+ */
+
+#define TIME_SCALE 1
+
+static void
+time_sched_init(irqreturn_t(*timer_routine) (int, void *))
+{
+ u32 tcount;
+
+ /* power up the timer, but don't enable it just yet */
+ bfin_write_TCNTL(1);
+ CSYNC();
+
+ /*
+ * the TSCALE prescaler counter.
+ */
+ bfin_write_TSCALE((TIME_SCALE - 1));
+
+ tcount = ((get_cclk() / (HZ * TIME_SCALE)) - 1);
+ bfin_write_TPERIOD(tcount);
+ bfin_write_TCOUNT(tcount);
+
+ /* now enable the timer */
+ CSYNC();
+
+ bfin_write_TCNTL(7);
+
+ bfin_timer_irq.handler = (irq_handler_t)timer_routine;
+ /* call setup_irq instead of request_irq because request_irq calls
+ * kmalloc which has not been initialized yet
+ */
+ setup_irq(IRQ_CORETMR, &bfin_timer_irq);
+}
+
+/*
+ * Should return useconds since last timer tick
+ */
+static unsigned long gettimeoffset(void)
+{
+ unsigned long offset;
+ unsigned long clocks_per_jiffy;
+
+ clocks_per_jiffy = bfin_read_TPERIOD();
+ offset =
+ (clocks_per_jiffy -
+ bfin_read_TCOUNT()) / (((clocks_per_jiffy + 1) * HZ) /
+ USEC_PER_SEC);
+
+ /* Check if we just wrapped the counters and maybe missed a tick */
+ if ((bfin_read_ILAT() & (1 << IRQ_CORETMR))
+ && (offset < (100000 / HZ / 2)))
+ offset += (USEC_PER_SEC / HZ);
+
+ return offset;
+}
+
+static inline int set_rtc_mmss(unsigned long nowtime)
+{
+ return 0;
+}
+
+/*
+ * timer_interrupt() needs to keep up the real-time clock,
+ * as well as call the "do_timer()" routine every clocktick
+ */
+#ifdef CONFIG_CORE_TIMER_IRQ_L1
+irqreturn_t timer_interrupt(int irq, void *dummy)__attribute__((l1_text));
+#endif
+
+irqreturn_t timer_interrupt(int irq, void *dummy)
+{
+ /* last time the cmos clock got updated */
+ static long last_rtc_update = 0;
+
+ write_seqlock(&xtime_lock);
+
+ do_timer(1);
+ do_leds();
+
+#ifndef CONFIG_SMP
+ update_process_times(user_mode(get_irq_regs()));
+#endif
+ profile_tick(CPU_PROFILING);
+
+ /*
+ * If we have an externally synchronized Linux clock, then update
+ * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
+ * called as close as possible to 500 ms before the new second starts.
+ */
+
+ if (ntp_synced() &&
+ xtime.tv_sec > last_rtc_update + 660 &&
+ (xtime.tv_nsec / NSEC_PER_USEC) >=
+ 500000 - ((unsigned)TICK_SIZE) / 2
+ && (xtime.tv_nsec / NSEC_PER_USEC) <=
+ 500000 + ((unsigned)TICK_SIZE) / 2) {
+ if (set_rtc_mmss(xtime.tv_sec) == 0)
+ last_rtc_update = xtime.tv_sec;
+ else
+ /* Do it again in 60s. */
+ last_rtc_update = xtime.tv_sec - 600;
+ }
+ write_sequnlock(&xtime_lock);
+ return IRQ_HANDLED;
+}
+
+void __init time_init(void)
+{
+ time_t secs_since_1970 = (365 * 37 + 9) * 24 * 60 * 60; /* 1 Jan 2007 */
+
+#ifdef CONFIG_RTC_DRV_BFIN
+ /* [#2663] hack to filter junk RTC values that would cause
+ * userspace to have to deal with time values greater than
+ * 2^31 seconds (which uClibc cannot cope with yet)
+ */
+ if ((bfin_read_RTC_STAT() & 0xC0000000) == 0xC0000000) {
+ printk(KERN_NOTICE "bfin-rtc: invalid date; resetting\n");
+ bfin_write_RTC_STAT(0);
+ }
+#endif
+
+ /* Initialize xtime. From now on, xtime is updated with timer interrupts */
+ xtime.tv_sec = secs_since_1970;
+ xtime.tv_nsec = 0;
+
+ wall_to_monotonic.tv_sec = -xtime.tv_sec;
+
+ time_sched_init(timer_interrupt);
+}
+
+#ifndef CONFIG_GENERIC_TIME
+void do_gettimeofday(struct timeval *tv)
+{
+ unsigned long flags;
+ unsigned long seq;
+ unsigned long usec, sec;
+
+ do {
+ seq = read_seqbegin_irqsave(&xtime_lock, flags);
+ usec = gettimeoffset();
+ sec = xtime.tv_sec;
+ usec += (xtime.tv_nsec / NSEC_PER_USEC);
+ }
+ while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
+
+ while (usec >= USEC_PER_SEC) {
+ usec -= USEC_PER_SEC;
+ sec++;
+ }
+
+ tv->tv_sec = sec;
+ tv->tv_usec = usec;
+}
+EXPORT_SYMBOL(do_gettimeofday);
+
+int do_settimeofday(struct timespec *tv)
+{
+ time_t wtm_sec, sec = tv->tv_sec;
+ long wtm_nsec, nsec = tv->tv_nsec;
+
+ if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
+ return -EINVAL;
+
+ write_seqlock_irq(&xtime_lock);
+ /*
+ * This is revolting. We need to set the xtime.tv_usec
+ * correctly. However, the value in this location is
+ * is value at the last tick.
+ * Discover what correction gettimeofday
+ * would have done, and then undo it!
+ */
+ nsec -= (gettimeoffset() * NSEC_PER_USEC);
+
+ wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
+ wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
+
+ set_normalized_timespec(&xtime, sec, nsec);
+ set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
+
+ ntp_clear();
+
+ write_sequnlock_irq(&xtime_lock);
+ clock_was_set();
+
+ return 0;
+}
+EXPORT_SYMBOL(do_settimeofday);
+#endif /* !CONFIG_GENERIC_TIME */
+
+/*
+ * Scheduler clock - returns current time in nanosec units.
+ */
+unsigned long long sched_clock(void)
+{
+ return (unsigned long long)jiffies *(NSEC_PER_SEC / HZ);
+}
diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c
new file mode 100644
index 00000000000..9556b73de80
--- /dev/null
+++ b/arch/blackfin/kernel/traps.c
@@ -0,0 +1,649 @@
+/*
+ * File: arch/blackfin/kernel/traps.c
+ * Based on:
+ * Author: Hamish Macdonald
+ *
+ * Created:
+ * Description: uses S/W interrupt 15 for the system calls
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <asm/uaccess.h>
+#include <asm/traps.h>
+#include <asm/cacheflush.h>
+#include <asm/blackfin.h>
+#include <asm/uaccess.h>
+#include <asm/irq_handler.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/kallsyms.h>
+
+#ifdef CONFIG_KGDB
+# include <linux/debugger.h>
+# include <linux/kgdb.h>
+#endif
+
+/* Initiate the event table handler */
+void __init trap_init(void)
+{
+ CSYNC();
+ bfin_write_EVT3(trap);
+ CSYNC();
+}
+
+asmlinkage void trap_c(struct pt_regs *fp);
+
+int kstack_depth_to_print = 48;
+
+static int printk_address(unsigned long address)
+{
+ struct vm_list_struct *vml;
+ struct task_struct *p;
+ struct mm_struct *mm;
+
+#ifdef CONFIG_KALLSYMS
+ unsigned long offset = 0, symsize;
+ const char *symname;
+ char *modname;
+ char *delim = ":";
+ char namebuf[128];
+
+ /* look up the address and see if we are in kernel space */
+ symname = kallsyms_lookup(address, &symsize, &offset, &modname, namebuf);
+
+ if (symname) {
+ /* yeah! kernel space! */
+ if (!modname)
+ modname = delim = "";
+ return printk("<0x%p> { %s%s%s%s + 0x%lx }",
+ (void*)address, delim, modname, delim, symname,
+ (unsigned long)offset);
+
+ }
+#endif
+
+ /* looks like we're off in user-land, so let's walk all the
+ * mappings of all our processes and see if we can't be a whee
+ * bit more specific
+ */
+ write_lock_irq(&tasklist_lock);
+ for_each_process(p) {
+ mm = get_task_mm(p);
+ if (!mm)
+ continue;
+
+ vml = mm->context.vmlist;
+ while (vml) {
+ struct vm_area_struct *vma = vml->vma;
+
+ if (address >= vma->vm_start && address < vma->vm_end) {
+ char *name = p->comm;
+ struct file *file = vma->vm_file;
+ if (file) {
+ char _tmpbuf[256];
+ name = d_path(file->f_dentry,
+ file->f_vfsmnt,
+ _tmpbuf,
+ sizeof(_tmpbuf));
+ }
+
+ write_unlock_irq(&tasklist_lock);
+ return printk("<0x%p> [ %s + 0x%lx ]",
+ (void*)address, name,
+ (unsigned long)
+ ((address - vma->vm_start) +
+ (vma->vm_pgoff << PAGE_SHIFT)));
+ }
+
+ vml = vml->next;
+ }
+ }
+ write_unlock_irq(&tasklist_lock);
+
+ /* we were unable to find this address anywhere */
+ return printk("[<0x%p>]", (void*)address);
+}
+
+#define trace_buffer_save(x) \
+ do { \
+ (x) = bfin_read_TBUFCTL(); \
+ bfin_write_TBUFCTL((x) & ~TBUFEN); \
+ } while (0)
+#define trace_buffer_restore(x) \
+ do { \
+ bfin_write_TBUFCTL((x)); \
+ } while (0)
+
+asmlinkage void trap_c(struct pt_regs *fp)
+{
+ int j, sig = 0;
+ siginfo_t info;
+ unsigned long trapnr = fp->seqstat & SEQSTAT_EXCAUSE;
+
+#ifdef CONFIG_KGDB
+# define CHK_DEBUGGER_TRAP() do { CHK_DEBUGGER(trapnr, sig, info.si_code, fp,); } while (0)
+# define CHK_DEBUGGER_TRAP_MAYBE() do { if (kgdb_connected) CHK_DEBUGGER_TRAP(); } while (0)
+#else
+# define CHK_DEBUGGER_TRAP() do { } while (0)
+# define CHK_DEBUGGER_TRAP_MAYBE() do { } while (0)
+#endif
+
+ trace_buffer_save(j);
+
+ /* trap_c() will be called for exceptions. During exceptions
+ * processing, the pc value should be set with retx value.
+ * With this change we can cleanup some code in signal.c- TODO
+ */
+ fp->orig_pc = fp->retx;
+ /* printk("exception: 0x%x, ipend=%x, reti=%x, retx=%x\n",
+ trapnr, fp->ipend, fp->pc, fp->retx); */
+
+ /* send the appropriate signal to the user program */
+ switch (trapnr) {
+
+ /* This table works in conjuction with the one in ./mach-common/entry.S
+ * Some exceptions are handled there (in assembly, in exception space)
+ * Some are handled here, (in C, in interrupt space)
+ * Some, like CPLB, are handled in both, where the normal path is
+ * handled in assembly/exception space, and the error path is handled
+ * here
+ */
+
+ /* 0x00 - Linux Syscall, getting here is an error */
+ /* 0x01 - userspace gdb breakpoint, handled here */
+ case VEC_EXCPT01:
+ info.si_code = TRAP_ILLTRAP;
+ sig = SIGTRAP;
+ CHK_DEBUGGER_TRAP_MAYBE();
+ /* Check if this is a breakpoint in kernel space */
+ if (fp->ipend & 0xffc0)
+ return;
+ else
+ break;
+#ifdef CONFIG_KGDB
+ case VEC_EXCPT02 : /* gdb connection */
+ info.si_code = TRAP_ILLTRAP;
+ sig = SIGTRAP;
+ CHK_DEBUGGER_TRAP();
+ return;
+#else
+ /* 0x02 - User Defined, Caught by default */
+#endif
+ /* 0x03 - Atomic test and set */
+ case VEC_EXCPT03:
+ info.si_code = SEGV_STACKFLOW;
+ sig = SIGSEGV;
+ printk(KERN_EMERG EXC_0x03);
+ CHK_DEBUGGER_TRAP();
+ break;
+ /* 0x04 - spinlock - handled by _ex_spinlock,
+ getting here is an error */
+ /* 0x05 - User Defined, Caught by default */
+ /* 0x06 - User Defined, Caught by default */
+ /* 0x07 - User Defined, Caught by default */
+ /* 0x08 - User Defined, Caught by default */
+ /* 0x09 - User Defined, Caught by default */
+ /* 0x0A - User Defined, Caught by default */
+ /* 0x0B - User Defined, Caught by default */
+ /* 0x0C - User Defined, Caught by default */
+ /* 0x0D - User Defined, Caught by default */
+ /* 0x0E - User Defined, Caught by default */
+ /* 0x0F - User Defined, Caught by default */
+ /* 0x10 HW Single step, handled here */
+ case VEC_STEP:
+ info.si_code = TRAP_STEP;
+ sig = SIGTRAP;
+ CHK_DEBUGGER_TRAP_MAYBE();
+ /* Check if this is a single step in kernel space */
+ if (fp->ipend & 0xffc0)
+ return;
+ else
+ break;
+ /* 0x11 - Trace Buffer Full, handled here */
+ case VEC_OVFLOW:
+ info.si_code = TRAP_TRACEFLOW;
+ sig = SIGTRAP;
+ printk(KERN_EMERG EXC_0x11);
+ CHK_DEBUGGER_TRAP();
+ break;
+ /* 0x12 - Reserved, Caught by default */
+ /* 0x13 - Reserved, Caught by default */
+ /* 0x14 - Reserved, Caught by default */
+ /* 0x15 - Reserved, Caught by default */
+ /* 0x16 - Reserved, Caught by default */
+ /* 0x17 - Reserved, Caught by default */
+ /* 0x18 - Reserved, Caught by default */
+ /* 0x19 - Reserved, Caught by default */
+ /* 0x1A - Reserved, Caught by default */
+ /* 0x1B - Reserved, Caught by default */
+ /* 0x1C - Reserved, Caught by default */
+ /* 0x1D - Reserved, Caught by default */
+ /* 0x1E - Reserved, Caught by default */
+ /* 0x1F - Reserved, Caught by default */
+ /* 0x20 - Reserved, Caught by default */
+ /* 0x21 - Undefined Instruction, handled here */
+ case VEC_UNDEF_I:
+ info.si_code = ILL_ILLOPC;
+ sig = SIGILL;
+ printk(KERN_EMERG EXC_0x21);
+ CHK_DEBUGGER_TRAP();
+ break;
+ /* 0x22 - Illegal Instruction Combination, handled here */
+ case VEC_ILGAL_I:
+ info.si_code = ILL_ILLPARAOP;
+ sig = SIGILL;
+ printk(KERN_EMERG EXC_0x22);
+ CHK_DEBUGGER_TRAP();
+ break;
+ /* 0x23 - Data CPLB Protection Violation,
+ normal case is handled in _cplb_hdr */
+ case VEC_CPLB_VL:
+ info.si_code = ILL_CPLB_VI;
+ sig = SIGILL;
+ printk(KERN_EMERG EXC_0x23);
+ CHK_DEBUGGER_TRAP();
+ break;
+ /* 0x24 - Data access misaligned, handled here */
+ case VEC_MISALI_D:
+ info.si_code = BUS_ADRALN;
+ sig = SIGBUS;
+ printk(KERN_EMERG EXC_0x24);
+ CHK_DEBUGGER_TRAP();
+ break;
+ /* 0x25 - Unrecoverable Event, handled here */
+ case VEC_UNCOV:
+ info.si_code = ILL_ILLEXCPT;
+ sig = SIGILL;
+ printk(KERN_EMERG EXC_0x25);
+ CHK_DEBUGGER_TRAP();
+ break;
+ /* 0x26 - Data CPLB Miss, normal case is handled in _cplb_hdr,
+ error case is handled here */
+ case VEC_CPLB_M:
+ info.si_code = BUS_ADRALN;
+ sig = SIGBUS;
+ printk(KERN_EMERG EXC_0x26);
+ CHK_DEBUGGER_TRAP();
+ break;
+ /* 0x27 - Data CPLB Multiple Hits - Linux Trap Zero, handled here */
+ case VEC_CPLB_MHIT:
+ info.si_code = ILL_CPLB_MULHIT;
+#ifdef CONFIG_DEBUG_HUNT_FOR_ZERO
+ sig = SIGSEGV;
+ printk(KERN_EMERG "\n\nNULL pointer access (probably)\n");
+#else
+ sig = SIGILL;
+ printk(KERN_EMERG EXC_0x27);
+#endif
+ CHK_DEBUGGER_TRAP();
+ break;
+ /* 0x28 - Emulation Watchpoint, handled here */
+ case VEC_WATCH:
+ info.si_code = TRAP_WATCHPT;
+ sig = SIGTRAP;
+ pr_debug(EXC_0x28);
+ CHK_DEBUGGER_TRAP_MAYBE();
+ /* Check if this is a watchpoint in kernel space */
+ if (fp->ipend & 0xffc0)
+ return;
+ else
+ break;
+#ifdef CONFIG_BF535
+ /* 0x29 - Instruction fetch access error (535 only) */
+ case VEC_ISTRU_VL: /* ADSP-BF535 only (MH) */
+ info.si_code = BUS_OPFETCH;
+ sig = SIGBUS;
+ printk(KERN_EMERG "BF535: VEC_ISTRU_VL\n");
+ CHK_DEBUGGER_TRAP();
+ break;
+#else
+ /* 0x29 - Reserved, Caught by default */
+#endif
+ /* 0x2A - Instruction fetch misaligned, handled here */
+ case VEC_MISALI_I:
+ info.si_code = BUS_ADRALN;
+ sig = SIGBUS;
+ printk(KERN_EMERG EXC_0x2A);
+ CHK_DEBUGGER_TRAP();
+ break;
+ /* 0x2B - Instruction CPLB protection Violation,
+ handled in _cplb_hdr */
+ case VEC_CPLB_I_VL:
+ info.si_code = ILL_CPLB_VI;
+ sig = SIGILL;
+ printk(KERN_EMERG EXC_0x2B);
+ CHK_DEBUGGER_TRAP();
+ break;
+ /* 0x2C - Instruction CPLB miss, handled in _cplb_hdr */
+ case VEC_CPLB_I_M:
+ info.si_code = ILL_CPLB_MISS;
+ sig = SIGBUS;
+ printk(KERN_EMERG EXC_0x2C);
+ CHK_DEBUGGER_TRAP();
+ break;
+ /* 0x2D - Instruction CPLB Multiple Hits, handled here */
+ case VEC_CPLB_I_MHIT:
+ info.si_code = ILL_CPLB_MULHIT;
+#ifdef CONFIG_DEBUG_HUNT_FOR_ZERO
+ sig = SIGSEGV;
+ printk(KERN_EMERG "\n\nJump to address 0 - 0x0fff\n");
+#else
+ sig = SIGILL;
+ printk(KERN_EMERG EXC_0x2D);
+#endif
+ CHK_DEBUGGER_TRAP();
+ break;
+ /* 0x2E - Illegal use of Supervisor Resource, handled here */
+ case VEC_ILL_RES:
+ info.si_code = ILL_PRVOPC;
+ sig = SIGILL;
+ printk(KERN_EMERG EXC_0x2E);
+ CHK_DEBUGGER_TRAP();
+ break;
+ /* 0x2F - Reserved, Caught by default */
+ /* 0x30 - Reserved, Caught by default */
+ /* 0x31 - Reserved, Caught by default */
+ /* 0x32 - Reserved, Caught by default */
+ /* 0x33 - Reserved, Caught by default */
+ /* 0x34 - Reserved, Caught by default */
+ /* 0x35 - Reserved, Caught by default */
+ /* 0x36 - Reserved, Caught by default */
+ /* 0x37 - Reserved, Caught by default */
+ /* 0x38 - Reserved, Caught by default */
+ /* 0x39 - Reserved, Caught by default */
+ /* 0x3A - Reserved, Caught by default */
+ /* 0x3B - Reserved, Caught by default */
+ /* 0x3C - Reserved, Caught by default */
+ /* 0x3D - Reserved, Caught by default */
+ /* 0x3E - Reserved, Caught by default */
+ /* 0x3F - Reserved, Caught by default */
+ default:
+ info.si_code = TRAP_ILLTRAP;
+ sig = SIGTRAP;
+ printk(KERN_EMERG "Caught Unhandled Exception, code = %08lx\n",
+ (fp->seqstat & SEQSTAT_EXCAUSE));
+ CHK_DEBUGGER_TRAP();
+ break;
+ }
+
+ info.si_signo = sig;
+ info.si_errno = 0;
+ info.si_addr = (void *)fp->pc;
+ force_sig_info(sig, &info, current);
+ if (sig != 0 && sig != SIGTRAP) {
+ unsigned long stack;
+ dump_bfin_regs(fp, (void *)fp->retx);
+ dump_bfin_trace_buffer();
+ show_stack(current, &stack);
+ if (current->mm == NULL)
+ panic("Kernel exception");
+ }
+
+ /* if the address that we are about to return to is not valid, set it
+ * to a valid address, if we have a current application or panic
+ */
+ if (!(fp->pc <= physical_mem_end
+#if L1_CODE_LENGTH != 0
+ || (fp->pc >= L1_CODE_START &&
+ fp->pc <= (L1_CODE_START + L1_CODE_LENGTH))
+#endif
+ )) {
+ if (current->mm) {
+ fp->pc = current->mm->start_code;
+ } else {
+ printk(KERN_EMERG "I can't return to memory that doesn't exist - bad things happen\n");
+ panic("Help - I've fallen and can't get up\n");
+ }
+ }
+
+ trace_buffer_restore(j);
+ return;
+}
+
+/* Typical exception handling routines */
+
+void dump_bfin_trace_buffer(void)
+{
+ int tflags;
+ trace_buffer_save(tflags);
+
+ if (likely(bfin_read_TBUFSTAT() & TBUFCNT)) {
+ int i;
+ printk(KERN_EMERG "Hardware Trace:\n");
+ for (i = 0; bfin_read_TBUFSTAT() & TBUFCNT; i++) {
+ printk(KERN_EMERG "%2i Target : ", i);
+ printk_address((unsigned long)bfin_read_TBUF());
+ printk("\n" KERN_EMERG " Source : ");
+ printk_address((unsigned long)bfin_read_TBUF());
+ printk("\n");
+ }
+ }
+
+ trace_buffer_restore(tflags);
+}
+EXPORT_SYMBOL(dump_bfin_trace_buffer);
+
+static void show_trace(struct task_struct *tsk, unsigned long *sp)
+{
+ unsigned long addr;
+
+ printk("\nCall Trace:");
+#ifdef CONFIG_KALLSYMS
+ printk("\n");
+#endif
+
+ while (!kstack_end(sp)) {
+ addr = *sp++;
+ /*
+ * If the address is either in the text segment of the
+ * kernel, or in the region which contains vmalloc'ed
+ * memory, it *may* be the address of a calling
+ * routine; if so, print it so that someone tracing
+ * down the cause of the crash will be able to figure
+ * out the call path that was taken.
+ */
+ if (kernel_text_address(addr))
+ print_ip_sym(addr);
+ }
+
+ printk("\n");
+}
+
+void show_stack(struct task_struct *task, unsigned long *stack)
+{
+ unsigned long *endstack, addr;
+ int i;
+
+ /* Cannot call dump_bfin_trace_buffer() here as show_stack() is
+ * called externally in some places in the kernel.
+ */
+
+ if (!stack) {
+ if (task)
+ stack = (unsigned long *)task->thread.ksp;
+ else
+ stack = (unsigned long *)&stack;
+ }
+
+ addr = (unsigned long)stack;
+ endstack = (unsigned long *)PAGE_ALIGN(addr);
+
+ printk(KERN_EMERG "Stack from %08lx:", (unsigned long)stack);
+ for (i = 0; i < kstack_depth_to_print; i++) {
+ if (stack + 1 > endstack)
+ break;
+ if (i % 8 == 0)
+ printk("\n" KERN_EMERG " ");
+ printk(" %08lx", *stack++);
+ }
+
+ show_trace(task, stack);
+}
+
+void dump_stack(void)
+{
+ unsigned long stack;
+ int tflags;
+ trace_buffer_save(tflags);
+ dump_bfin_trace_buffer();
+ show_stack(current, &stack);
+ trace_buffer_restore(tflags);
+}
+
+EXPORT_SYMBOL(dump_stack);
+
+void dump_bfin_regs(struct pt_regs *fp, void *retaddr)
+{
+ if (current->pid) {
+ printk("\nCURRENT PROCESS:\n\n");
+ printk("COMM=%s PID=%d\n", current->comm, current->pid);
+ } else {
+ printk
+ ("\nNo Valid pid - Either things are really messed up, or you are in the kernel\n");
+ }
+
+ if (current->mm) {
+ printk("TEXT = 0x%p-0x%p DATA = 0x%p-0x%p\n"
+ "BSS = 0x%p-0x%p USER-STACK = 0x%p\n\n",
+ (void*)current->mm->start_code,
+ (void*)current->mm->end_code,
+ (void*)current->mm->start_data,
+ (void*)current->mm->end_data,
+ (void*)current->mm->end_data,
+ (void*)current->mm->brk,
+ (void*)current->mm->start_stack);
+ }
+
+ printk("return address: 0x%p; contents of [PC-16...PC+8]:\n", retaddr);
+ if (retaddr != 0 && retaddr <= (void*)physical_mem_end
+#if L1_CODE_LENGTH != 0
+ /* FIXME: Copy the code out of L1 Instruction SRAM through dma
+ memcpy. */
+ && !(retaddr >= (void*)L1_CODE_START
+ && retaddr < (void*)(L1_CODE_START + L1_CODE_LENGTH))
+#endif
+ ) {
+ int i = 0;
+ unsigned short x = 0;
+ for (i = -16; i < 8; i++) {
+ if (get_user(x, (unsigned short *)retaddr + i))
+ break;
+#ifndef CONFIG_DEBUG_HWERR
+ /* If one of the last few instructions was a STI
+ * it is likily that the error occured awhile ago
+ * and we just noticed
+ */
+ if (x >= 0x0040 && x <= 0x0047 && i <= 0)
+ panic("\n\nWARNING : You should reconfigure the kernel to turn on\n"
+ " 'Hardware error interrupt debugging'\n"
+ " The rest of this error is meanless\n");
+#endif
+
+ if (i == -8)
+ printk("\n");
+ if (i == 0)
+ printk("X\n");
+ printk("%04x ", x);
+ }
+ } else
+ printk("Cannot look at the [PC] for it is in unreadable L1 SRAM - sorry\n");
+
+ printk("\n\n");
+
+ printk("RETE: %08lx RETN: %08lx RETX: %08lx RETS: %08lx\n",
+ fp->rete, fp->retn, fp->retx, fp->rets);
+ printk("IPEND: %04lx SYSCFG: %04lx\n", fp->ipend, fp->syscfg);
+ printk("SEQSTAT: %08lx SP: %08lx\n", (long)fp->seqstat, (long)fp);
+ printk("R0: %08lx R1: %08lx R2: %08lx R3: %08lx\n",
+ fp->r0, fp->r1, fp->r2, fp->r3);
+ printk("R4: %08lx R5: %08lx R6: %08lx R7: %08lx\n",
+ fp->r4, fp->r5, fp->r6, fp->r7);
+ printk("P0: %08lx P1: %08lx P2: %08lx P3: %08lx\n",
+ fp->p0, fp->p1, fp->p2, fp->p3);
+ printk("P4: %08lx P5: %08lx FP: %08lx\n", fp->p4, fp->p5, fp->fp);
+ printk("A0.w: %08lx A0.x: %08lx A1.w: %08lx A1.x: %08lx\n",
+ fp->a0w, fp->a0x, fp->a1w, fp->a1x);
+
+ printk("LB0: %08lx LT0: %08lx LC0: %08lx\n", fp->lb0, fp->lt0,
+ fp->lc0);
+ printk("LB1: %08lx LT1: %08lx LC1: %08lx\n", fp->lb1, fp->lt1,
+ fp->lc1);
+ printk("B0: %08lx L0: %08lx M0: %08lx I0: %08lx\n", fp->b0, fp->l0,
+ fp->m0, fp->i0);
+ printk("B1: %08lx L1: %08lx M1: %08lx I1: %08lx\n", fp->b1, fp->l1,
+ fp->m1, fp->i1);
+ printk("B2: %08lx L2: %08lx M2: %08lx I2: %08lx\n", fp->b2, fp->l2,
+ fp->m2, fp->i2);
+ printk("B3: %08lx L3: %08lx M3: %08lx I3: %08lx\n", fp->b3, fp->l3,
+ fp->m3, fp->i3);
+
+ printk("\nUSP: %08lx ASTAT: %08lx\n", rdusp(), fp->astat);
+ if ((long)fp->seqstat & SEQSTAT_EXCAUSE) {
+ printk(KERN_EMERG "DCPLB_FAULT_ADDR=%p\n", (void*)bfin_read_DCPLB_FAULT_ADDR());
+ printk(KERN_EMERG "ICPLB_FAULT_ADDR=%p\n", (void*)bfin_read_ICPLB_FAULT_ADDR());
+ }
+
+ printk("\n\n");
+}
+
+#ifdef CONFIG_SYS_BFIN_SPINLOCK_L1
+asmlinkage int sys_bfin_spinlock(int *spinlock)__attribute__((l1_text));
+#endif
+
+asmlinkage int sys_bfin_spinlock(int *spinlock)
+{
+ int ret = 0;
+ int tmp = 0;
+
+ local_irq_disable();
+ ret = get_user(tmp, spinlock);
+ if (ret == 0) {
+ if (tmp)
+ ret = 1;
+ tmp = 1;
+ put_user(tmp, spinlock);
+ }
+ local_irq_enable();
+ return ret;
+}
+
+void panic_cplb_error(int cplb_panic, struct pt_regs *fp)
+{
+ switch (cplb_panic) {
+ case CPLB_NO_UNLOCKED:
+ printk(KERN_EMERG "All CPLBs are locked\n");
+ break;
+ case CPLB_PROT_VIOL:
+ return;
+ case CPLB_NO_ADDR_MATCH:
+ return;
+ case CPLB_UNKNOWN_ERR:
+ printk(KERN_EMERG "Unknown CPLB Exception\n");
+ break;
+ }
+
+ printk(KERN_EMERG "DCPLB_FAULT_ADDR=%p\n", (void*)bfin_read_DCPLB_FAULT_ADDR());
+ printk(KERN_EMERG "ICPLB_FAULT_ADDR=%p\n", (void*)bfin_read_ICPLB_FAULT_ADDR());
+ dump_bfin_regs(fp, (void *)fp->retx);
+ dump_stack();
+ panic("Unrecoverable event\n");
+}
diff --git a/arch/blackfin/kernel/vmlinux.lds.S b/arch/blackfin/kernel/vmlinux.lds.S
new file mode 100644
index 00000000000..6ae9ebbd8e5
--- /dev/null
+++ b/arch/blackfin/kernel/vmlinux.lds.S
@@ -0,0 +1,228 @@
+/*
+ * File: arch/blackfin/kernel/vmlinux.lds.S
+ * Based on: none - original work
+ * Author:
+ *
+ * Created: Tue Sep 21 2004
+ * Description: Master linker script for blackfin architecture
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#define VMLINUX_SYMBOL(_sym_) _##_sym_
+
+#include <asm-generic/vmlinux.lds.h>
+#include <asm/mem_map.h>
+
+
+OUTPUT_FORMAT("elf32-bfin")
+ENTRY(__start)
+_jiffies = _jiffies_64;
+
+MEMORY
+{
+ ram : ORIGIN = CONFIG_BOOT_LOAD, LENGTH = (CONFIG_MEM_SIZE * 1024 * 1024) - (CONFIG_BOOT_LOAD)
+ l1_data_a : ORIGIN = L1_DATA_A_START, LENGTH = L1_DATA_A_LENGTH
+ l1_data_b : ORIGIN = L1_DATA_B_START, LENGTH = L1_DATA_B_LENGTH
+ l1_code : ORIGIN = L1_CODE_START, LENGTH = L1_CODE_LENGTH
+ l1_scratch : ORIGIN = L1_SCRATCH_START, LENGTH = L1_SCRATCH_LENGTH
+}
+
+SECTIONS
+{
+ . = CONFIG_BOOT_LOAD;
+
+ .text :
+ {
+ _text = .;
+ __stext = .;
+ *(.text)
+ SCHED_TEXT
+ *(.text.lock)
+ . = ALIGN(16);
+ ___start___ex_table = .;
+ *(__ex_table)
+ ___stop___ex_table = .;
+
+ *($code)
+ *(.rodata)
+ *(.rodata.*)
+ *(__vermagic) /* Kernel version magic */
+ *(.rodata1)
+ *(.fixup)
+ *(.spinlock.text)
+
+ /* Kernel symbol table: Normal symbols */
+ . = ALIGN(4);
+ ___start___ksymtab = .;
+ *(__ksymtab)
+ ___stop___ksymtab = .;
+
+ /* Kernel symbol table: GPL-only symbols */
+ ___start___ksymtab_gpl = .;
+ *(__ksymtab_gpl)
+ ___stop___ksymtab_gpl = .;
+
+ /* Kernel symbol table: Normal unused symbols */ \
+ ___start___ksymtab_unused = .;
+ *(__ksymtab_unused)
+ ___stop___ksymtab_unused = .;
+
+ /* Kernel symbol table: GPL-only unused symbols */
+ ___start___ksymtab_unused_gpl = .;
+ *(__ksymtab_unused_gpl)
+ ___stop___ksymtab_unused_gpl = .;
+
+
+ /* Kernel symbol table: GPL-future symbols */
+ ___start___ksymtab_gpl_future = .;
+ *(__ksymtab_gpl_future)
+ ___stop___ksymtab_gpl_future = .;
+
+ /* Kernel symbol table: Normal symbols */
+ ___start___kcrctab = .;
+ *(__kcrctab)
+ ___stop___kcrctab = .;
+
+ /* Kernel symbol table: GPL-only symbols */
+ ___start___kcrctab_gpl = .;
+ *(__kcrctab_gpl)
+ ___stop___kcrctab_gpl = .;
+
+ /* Kernel symbol table: GPL-future symbols */
+ ___start___kcrctab_gpl_future = .;
+ *(__kcrctab_gpl_future)
+ ___stop___kcrctab_gpl_future = .;
+
+ /* Kernel symbol table: strings */
+ *(__ksymtab_strings)
+
+ . = ALIGN(4);
+ __etext = .;
+ } > ram
+
+ .init :
+ {
+ . = ALIGN(4096);
+ ___init_begin = .;
+ __sinittext = .;
+ *(.init.text)
+ __einittext = .;
+ *(.init.data)
+ . = ALIGN(16);
+ ___setup_start = .;
+ *(.init.setup)
+ ___setup_end = .;
+ ___start___param = .;
+ *(__param)
+ ___stop___param = .;
+ ___initcall_start = .;
+ INITCALLS
+ ___initcall_end = .;
+ ___con_initcall_start = .;
+ *(.con_initcall.init)
+ ___con_initcall_end = .;
+ ___security_initcall_start = .;
+ *(.security_initcall.init)
+ ___security_initcall_end = .;
+ . = ALIGN(4);
+ ___initramfs_start = .;
+ *(.init.ramfs)
+ ___initramfs_end = .;
+ . = ALIGN(4);
+ ___init_end = .;
+ } > ram
+
+ __l1_lma_start = .;
+
+ .text_l1 :
+ {
+ . = ALIGN(4);
+ __stext_l1 = .;
+ *(.l1.text)
+
+ . = ALIGN(4);
+ __etext_l1 = .;
+ } > l1_code AT > ram
+
+ .data_l1 :
+ {
+ . = ALIGN(4);
+ __sdata_l1 = .;
+ *(.l1.data)
+ __edata_l1 = .;
+
+ . = ALIGN(4);
+ __sbss_l1 = .;
+ *(.l1.bss)
+
+ . = ALIGN(32);
+ *(.data_l1.cacheline_aligned)
+
+ . = ALIGN(4);
+ __ebss_l1 = .;
+ } > l1_data_a AT > ram
+ .data_b_l1 :
+ {
+ . = ALIGN(4);
+ __sdata_b_l1 = .;
+ *(.l1.data.B)
+ __edata_b_l1 = .;
+
+ . = ALIGN(4);
+ __sbss_b_l1 = .;
+ *(.l1.bss.B)
+
+ . = ALIGN(4);
+ __ebss_b_l1 = .;
+ } > l1_data_b AT > ram
+
+ .data :
+ {
+ __sdata = .;
+ . = ALIGN(0x2000);
+ *(.data.init_task)
+ *(.data)
+
+ . = ALIGN(32);
+ *(.data.cacheline_aligned)
+
+ . = ALIGN(0x2000);
+ __edata = .;
+ } > ram
+
+ /DISCARD/ : { /* Exit code and data*/
+ *(.exit.text)
+ *(.exit.data)
+ *(.exitcall.exit)
+ } > ram
+
+ .bss :
+ {
+ . = ALIGN(4);
+ ___bss_start = .;
+ *(.bss)
+ *(COMMON)
+ . = ALIGN(4);
+ ___bss_stop = .;
+ __end = . ;
+ } > ram
+}
diff --git a/arch/blackfin/lib/Makefile b/arch/blackfin/lib/Makefile
new file mode 100644
index 00000000000..635288fc5f5
--- /dev/null
+++ b/arch/blackfin/lib/Makefile
@@ -0,0 +1,11 @@
+#
+# arch/blackfin/lib/Makefile
+#
+
+lib-y := \
+ ashldi3.o ashrdi3.o lshrdi3.o \
+ muldi3.o divsi3.o udivsi3.o modsi3.o umodsi3.o \
+ checksum.o memcpy.o memset.o memcmp.o memchr.o memmove.o \
+ strcmp.o strcpy.o strncmp.o strncpy.o \
+ umulsi3_highpart.o smulsi3_highpart.o \
+ ins.o outs.o
diff --git a/arch/blackfin/lib/ashldi3.c b/arch/blackfin/lib/ashldi3.c
new file mode 100644
index 00000000000..a8c279e9b19
--- /dev/null
+++ b/arch/blackfin/lib/ashldi3.c
@@ -0,0 +1,58 @@
+/*
+ * File: arch/blackfin/lib/ashldi3.c
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "gcclib.h"
+
+#ifdef CONFIG_ARITHMETIC_OPS_L1
+DItype __ashldi3(DItype u, word_type b)__attribute__((l1_text));
+#endif
+
+DItype __ashldi3(DItype u, word_type b)
+{
+ DIunion w;
+ word_type bm;
+ DIunion uu;
+
+ if (b == 0)
+ return u;
+
+ uu.ll = u;
+
+ bm = (sizeof(SItype) * BITS_PER_UNIT) - b;
+ if (bm <= 0) {
+ w.s.low = 0;
+ w.s.high = (USItype) uu.s.low << -bm;
+ } else {
+ USItype carries = (USItype) uu.s.low >> bm;
+ w.s.low = (USItype) uu.s.low << b;
+ w.s.high = ((USItype) uu.s.high << b) | carries;
+ }
+
+ return w.ll;
+}
diff --git a/arch/blackfin/lib/ashrdi3.c b/arch/blackfin/lib/ashrdi3.c
new file mode 100644
index 00000000000..a0d3419329c
--- /dev/null
+++ b/arch/blackfin/lib/ashrdi3.c
@@ -0,0 +1,59 @@
+/*
+ * File: arch/blackfin/lib/ashrdi3.c
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "gcclib.h"
+
+#ifdef CONFIG_ARITHMETIC_OPS_L1
+DItype __ashrdi3(DItype u, word_type b)__attribute__((l1_text));
+#endif
+
+DItype __ashrdi3(DItype u, word_type b)
+{
+ DIunion w;
+ word_type bm;
+ DIunion uu;
+
+ if (b == 0)
+ return u;
+
+ uu.ll = u;
+
+ bm = (sizeof(SItype) * BITS_PER_UNIT) - b;
+ if (bm <= 0) {
+ /* w.s.high = 1..1 or 0..0 */
+ w.s.high = uu.s.high >> (sizeof(SItype) * BITS_PER_UNIT - 1);
+ w.s.low = uu.s.high >> -bm;
+ } else {
+ USItype carries = (USItype) uu.s.high << bm;
+ w.s.high = uu.s.high >> b;
+ w.s.low = ((USItype) uu.s.low >> b) | carries;
+ }
+
+ return w.ll;
+}
diff --git a/arch/blackfin/lib/checksum.c b/arch/blackfin/lib/checksum.c
new file mode 100644
index 00000000000..42768e0c80c
--- /dev/null
+++ b/arch/blackfin/lib/checksum.c
@@ -0,0 +1,140 @@
+/*
+ * File: arch/blackfin/lib/checksum.c
+ * Based on: none - original work
+ * Author:
+ *
+ * Created:
+ * Description: An implementation of the TCP/IP protocol suite for the LINUX
+ * operating system. INET is implemented using the BSD Socket
+ * interface as the means of communication with the user level.
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <net/checksum.h>
+#include <asm/checksum.h>
+
+#ifdef CONFIG_IP_CHECKSUM_L1
+static unsigned short do_csum(const unsigned char *buff, int len)__attribute__((l1_text));
+#endif
+
+static unsigned short do_csum(const unsigned char *buff, int len)
+{
+ register unsigned long sum = 0;
+ int swappem = 0;
+
+ if (1 & (unsigned long)buff) {
+ sum = *buff << 8;
+ buff++;
+ len--;
+ ++swappem;
+ }
+
+ while (len > 1) {
+ sum += *(unsigned short *)buff;
+ buff += 2;
+ len -= 2;
+ }
+
+ if (len > 0)
+ sum += *buff;
+
+ /* Fold 32-bit sum to 16 bits */
+ while (sum >> 16)
+ sum = (sum & 0xffff) + (sum >> 16);
+
+ if (swappem)
+ sum = ((sum & 0xff00) >> 8) + ((sum & 0x00ff) << 8);
+
+ return sum;
+
+}
+
+/*
+ * This is a version of ip_compute_csum() optimized for IP headers,
+ * which always checksum on 4 octet boundaries.
+ */
+unsigned short ip_fast_csum(unsigned char *iph, unsigned int ihl)
+{
+ return ~do_csum(iph, ihl * 4);
+}
+
+/*
+ * computes the checksum of a memory block at buff, length len,
+ * and adds in "sum" (32-bit)
+ *
+ * returns a 32-bit number suitable for feeding into itself
+ * or csum_tcpudp_magic
+ *
+ * this function must be called with even lengths, except
+ * for the last fragment, which may be odd
+ *
+ * it's best to have buff aligned on a 32-bit boundary
+ */
+unsigned int csum_partial(const unsigned char *buff, int len, unsigned int sum)
+{
+ /*
+ * Just in case we get nasty checksum data...
+ * Like 0xffff6ec3 in the case of our IPv6 multicast header.
+ * We fold to begin with, as well as at the end.
+ */
+ sum = (sum & 0xffff) + (sum >> 16);
+
+ sum += do_csum(buff, len);
+
+ sum = (sum & 0xffff) + (sum >> 16);
+
+ return sum;
+}
+
+/*
+ * this routine is used for miscellaneous IP-like checksums, mainly
+ * in icmp.c
+ */
+unsigned short ip_compute_csum(const unsigned char *buff, int len)
+{
+ return ~do_csum(buff, len);
+}
+
+/*
+ * copy from fs while checksumming, otherwise like csum_partial
+ */
+
+unsigned int
+csum_partial_copy_from_user(const unsigned char *src, unsigned char *dst,
+ int len, int sum, int *csum_err)
+{
+ if (csum_err)
+ *csum_err = 0;
+ memcpy(dst, src, len);
+ return csum_partial(dst, len, sum);
+}
+
+/*
+ * copy from ds while checksumming, otherwise like csum_partial
+ */
+
+unsigned int csum_partial_copy(const unsigned char *src, unsigned char *dst,
+ int len, int sum)
+{
+ memcpy(dst, src, len);
+ return csum_partial(dst, len, sum);
+}
diff --git a/arch/blackfin/lib/divsi3.S b/arch/blackfin/lib/divsi3.S
new file mode 100644
index 00000000000..3e29861852b
--- /dev/null
+++ b/arch/blackfin/lib/divsi3.S
@@ -0,0 +1,216 @@
+/*
+ * File: arch/blackfin/lib/divsi3.S
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description: 16 / 32 bit signed division.
+ * Special cases :
+ * 1) If(numerator == 0)
+ * return 0
+ * 2) If(denominator ==0)
+ * return positive max = 0x7fffffff
+ * 3) If(numerator == denominator)
+ * return 1
+ * 4) If(denominator ==1)
+ * return numerator
+ * 5) If(denominator == -1)
+ * return -numerator
+ *
+ * Operand : R0 - Numerator (i)
+ * R1 - Denominator (i)
+ * R0 - Quotient (o)
+ * Registers Used : R2-R7,P0-P2
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+.global ___divsi3;
+
+#ifdef CONFIG_ARITHMETIC_OPS_L1
+.section .l1.text
+#else
+.text
+#endif
+
+.align 2;
+___divsi3 :
+
+
+ R3 = R0 ^ R1;
+ R0 = ABS R0;
+
+ CC = V;
+
+ r3 = rot r3 by -1;
+ r1 = abs r1; /* now both positive, r3.30 means "negate result",
+ ** r3.31 means overflow, add one to result
+ */
+ cc = r0 < r1;
+ if cc jump .Lret_zero;
+ r2 = r1 >> 15;
+ cc = r2;
+ if cc jump .Lidents;
+ r2 = r1 << 16;
+ cc = r2 <= r0;
+ if cc jump .Lidents;
+
+ DIVS(R0, R1);
+ DIVQ(R0, R1);
+ DIVQ(R0, R1);
+ DIVQ(R0, R1);
+ DIVQ(R0, R1);
+ DIVQ(R0, R1);
+ DIVQ(R0, R1);
+ DIVQ(R0, R1);
+ DIVQ(R0, R1);
+ DIVQ(R0, R1);
+ DIVQ(R0, R1);
+ DIVQ(R0, R1);
+ DIVQ(R0, R1);
+ DIVQ(R0, R1);
+ DIVQ(R0, R1);
+ DIVQ(R0, R1);
+ DIVQ(R0, R1);
+
+ R0 = R0.L (Z);
+ r1 = r3 >> 31; /* add overflow issue back in */
+ r0 = r0 + r1;
+ r1 = -r0;
+ cc = bittst(r3, 30);
+ if cc r0 = r1;
+ RTS;
+
+/* Can't use the primitives. Test common identities.
+** If the identity is true, return the value in R2.
+*/
+
+.Lidents:
+ CC = R1 == 0; /* check for divide by zero */
+ IF CC JUMP .Lident_return;
+
+ CC = R0 == 0; /* check for division of zero */
+ IF CC JUMP .Lzero_return;
+
+ CC = R0 == R1; /* check for identical operands */
+ IF CC JUMP .Lident_return;
+
+ CC = R1 == 1; /* check for divide by 1 */
+ IF CC JUMP .Lident_return;
+
+ R2.L = ONES R1;
+ R2 = R2.L (Z);
+ CC = R2 == 1;
+ IF CC JUMP .Lpower_of_two;
+
+ /* Identities haven't helped either.
+ ** Perform the full division process.
+ */
+
+ P1 = 31; /* Set loop counter */
+
+ [--SP] = (R7:5); /* Push registers R5-R7 */
+ R2 = -R1;
+ [--SP] = R2;
+ R2 = R0 << 1; /* R2 lsw of dividend */
+ R6 = R0 ^ R1; /* Get sign */
+ R5 = R6 >> 31; /* Shift sign to LSB */
+
+ R0 = 0 ; /* Clear msw partial remainder */
+ R2 = R2 | R5; /* Shift quotient bit */
+ R6 = R0 ^ R1; /* Get new quotient bit */
+
+ LSETUP(.Llst,.Llend) LC0 = P1; /* Setup loop */
+.Llst: R7 = R2 >> 31; /* record copy of carry from R2 */
+ R2 = R2 << 1; /* Shift 64 bit dividend up by 1 bit */
+ R0 = R0 << 1 || R5 = [SP];
+ R0 = R0 | R7; /* and add carry */
+ CC = R6 < 0; /* Check quotient(AQ) */
+ /* we might be subtracting divisor (AQ==0) */
+ IF CC R5 = R1; /* or we might be adding divisor (AQ==1)*/
+ R0 = R0 + R5; /* do add or subtract, as indicated by AQ */
+ R6 = R0 ^ R1; /* Generate next quotient bit */
+ R5 = R6 >> 31;
+ /* Assume AQ==1, shift in zero */
+ BITTGL(R5,0); /* tweak AQ to be what we want to shift in */
+.Llend: R2 = R2 + R5; /* and then set shifted-in value to
+ ** tweaked AQ.
+ */
+ r1 = r3 >> 31;
+ r2 = r2 + r1;
+ cc = bittst(r3,30);
+ r0 = -r2;
+ if !cc r0 = r2;
+ SP += 4;
+ (R7:5)= [SP++]; /* Pop registers R6-R7 */
+ RTS;
+
+.Lident_return:
+ CC = R1 == 0; /* check for divide by zero => 0x7fffffff */
+ R2 = -1 (X);
+ R2 >>= 1;
+ IF CC JUMP .Ltrue_ident_return;
+
+ CC = R0 == R1; /* check for identical operands => 1 */
+ R2 = 1 (Z);
+ IF CC JUMP .Ltrue_ident_return;
+
+ R2 = R0; /* assume divide by 1 => numerator */
+ /*FALLTHRU*/
+
+.Ltrue_ident_return:
+ R0 = R2; /* Return an identity value */
+ R2 = -R2;
+ CC = bittst(R3,30);
+ IF CC R0 = R2;
+.Lzero_return:
+ RTS; /* ...including zero */
+
+.Lpower_of_two:
+ /* Y has a single bit set, which means it's a power of two.
+ ** That means we can perform the division just by shifting
+ ** X to the right the appropriate number of bits
+ */
+
+ /* signbits returns the number of sign bits, minus one.
+ ** 1=>30, 2=>29, ..., 0x40000000=>0. Which means we need
+ ** to shift right n-signbits spaces. It also means 0x80000000
+ ** is a special case, because that *also* gives a signbits of 0
+ */
+
+ R2 = R0 >> 31;
+ CC = R1 < 0;
+ IF CC JUMP .Ltrue_ident_return;
+
+ R1.l = SIGNBITS R1;
+ R1 = R1.L (Z);
+ R1 += -30;
+ R0 = LSHIFT R0 by R1.L;
+ r1 = r3 >> 31;
+ r0 = r0 + r1;
+ R2 = -R0; // negate result if necessary
+ CC = bittst(R3,30);
+ IF CC R0 = R2;
+ RTS;
+
+.Lret_zero:
+ R0 = 0;
+ RTS;
diff --git a/arch/blackfin/lib/gcclib.h b/arch/blackfin/lib/gcclib.h
new file mode 100644
index 00000000000..9ccd39a135e
--- /dev/null
+++ b/arch/blackfin/lib/gcclib.h
@@ -0,0 +1,47 @@
+/*
+ * File: arch/blackfin/lib/gcclib.h
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#define BITS_PER_UNIT 8
+#define SI_TYPE_SIZE (sizeof (SItype) * BITS_PER_UNIT)
+
+typedef unsigned int UQItype __attribute__ ((mode(QI)));
+typedef int SItype __attribute__ ((mode(SI)));
+typedef unsigned int USItype __attribute__ ((mode(SI)));
+typedef int DItype __attribute__ ((mode(DI)));
+typedef int word_type __attribute__ ((mode(__word__)));
+typedef unsigned int UDItype __attribute__ ((mode(DI)));
+
+struct DIstruct {
+ SItype low, high;
+};
+
+typedef union {
+ struct DIstruct s;
+ DItype ll;
+} DIunion;
diff --git a/arch/blackfin/lib/ins.S b/arch/blackfin/lib/ins.S
new file mode 100644
index 00000000000..730d2b42753
--- /dev/null
+++ b/arch/blackfin/lib/ins.S
@@ -0,0 +1,69 @@
+/*
+ * File: arch/blackfin/lib/ins.S
+ * Based on:
+ * Author: Bas Vermeulen <bas@buyways.nl>
+ *
+ * Created: Tue Mar 22 15:27:24 CEST 2005
+ * Description: Implementation of ins{bwl} for BlackFin processors using zero overhead loops.
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ * Copyright (C) 2005 Bas Vermeulen, BuyWays BV <bas@buyways.nl>
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/linkage.h>
+
+.align 2
+
+ENTRY(_insl)
+ P0 = R0; /* P0 = port */
+ cli R3;
+ P1 = R1; /* P1 = address */
+ P2 = R2; /* P2 = count */
+ SSYNC;
+ LSETUP( .Llong_loop_s, .Llong_loop_e) LC0 = P2;
+.Llong_loop_s: R0 = [P0];
+.Llong_loop_e: [P1++] = R0;
+ sti R3;
+ RTS;
+
+ENTRY(_insw)
+ P0 = R0; /* P0 = port */
+ cli R3;
+ P1 = R1; /* P1 = address */
+ P2 = R2; /* P2 = count */
+ SSYNC;
+ LSETUP( .Lword_loop_s, .Lword_loop_e) LC0 = P2;
+.Lword_loop_s: R0 = W[P0];
+.Lword_loop_e: W[P1++] = R0;
+ sti R3;
+ RTS;
+
+ENTRY(_insb)
+ P0 = R0; /* P0 = port */
+ cli R3;
+ P1 = R1; /* P1 = address */
+ P2 = R2; /* P2 = count */
+ SSYNC;
+ LSETUP( .Lbyte_loop_s, .Lbyte_loop_e) LC0 = P2;
+.Lbyte_loop_s: R0 = B[P0];
+.Lbyte_loop_e: B[P1++] = R0;
+ sti R3;
+ RTS;
diff --git a/arch/blackfin/lib/lshrdi3.c b/arch/blackfin/lib/lshrdi3.c
new file mode 100644
index 00000000000..84b9c559222
--- /dev/null
+++ b/arch/blackfin/lib/lshrdi3.c
@@ -0,0 +1,72 @@
+/*
+ * File: arch/blackfin/lib/lshrdi3.c
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#define BITS_PER_UNIT 8
+
+typedef int SItype __attribute__ ((mode(SI)));
+typedef unsigned int USItype __attribute__ ((mode(SI)));
+typedef int DItype __attribute__ ((mode(DI)));
+typedef int word_type __attribute__ ((mode(__word__)));
+
+struct DIstruct {
+ SItype high, low;
+};
+
+typedef union {
+ struct DIstruct s;
+ DItype ll;
+} DIunion;
+
+#ifdef CONFIG_ARITHMETIC_OPS_L1
+DItype __lshrdi3(DItype u, word_type b)__attribute__((l1_text));
+#endif
+
+DItype __lshrdi3(DItype u, word_type b)
+{
+ DIunion w;
+ word_type bm;
+ DIunion uu;
+
+ if (b == 0)
+ return u;
+
+ uu.ll = u;
+
+ bm = (sizeof(SItype) * BITS_PER_UNIT) - b;
+ if (bm <= 0) {
+ w.s.high = 0;
+ w.s.low = (USItype) uu.s.high >> -bm;
+ } else {
+ USItype carries = (USItype) uu.s.high << bm;
+ w.s.high = (USItype) uu.s.high >> b;
+ w.s.low = ((USItype) uu.s.low >> b) | carries;
+ }
+
+ return w.ll;
+}
diff --git a/arch/blackfin/lib/memchr.S b/arch/blackfin/lib/memchr.S
new file mode 100644
index 00000000000..498122250d0
--- /dev/null
+++ b/arch/blackfin/lib/memchr.S
@@ -0,0 +1,70 @@
+/*
+ * File: arch/blackfin/lib/memchr.S
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/linkage.h>
+
+/* void *memchr(const void *s, int c, size_t n);
+ * R0 = address (s)
+ * R1 = sought byte (c)
+ * R2 = count (n)
+ *
+ * Returns pointer to located character.
+ */
+
+.text
+
+.align 2
+
+ENTRY(_memchr)
+ P0 = R0; /* P0 = address */
+ P2 = R2; /* P2 = count */
+ R1 = R1.B(Z);
+ CC = R2 == 0;
+ IF CC JUMP .Lfailed;
+
+.Lbytes:
+ LSETUP (.Lbyte_loop_s, .Lbyte_loop_e) LC0=P2;
+
+.Lbyte_loop_s:
+ R3 = B[P0++](Z);
+ CC = R3 == R1;
+ IF CC JUMP .Lfound;
+.Lbyte_loop_e:
+ NOP;
+
+.Lfailed:
+ R0=0;
+ RTS;
+
+.Lfound:
+ R0 = P0;
+ R0 += -1;
+ RTS;
+
+.size _memchr,.-_memchr
diff --git a/arch/blackfin/lib/memcmp.S b/arch/blackfin/lib/memcmp.S
new file mode 100644
index 00000000000..5b9502368fc
--- /dev/null
+++ b/arch/blackfin/lib/memcmp.S
@@ -0,0 +1,110 @@
+/*
+ * File: arch/blackfin/lib/memcmp.S
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/linkage.h>
+
+/* int memcmp(const void *s1, const void *s2, size_t n);
+ * R0 = First Address (s1)
+ * R1 = Second Address (s2)
+ * R2 = count (n)
+ *
+ * Favours word aligned data.
+ */
+
+.text
+
+.align 2
+
+ENTRY(_memcmp)
+ I1 = P3;
+ P0 = R0; /* P0 = s1 address */
+ P3 = R1; /* P3 = s2 Address */
+ P2 = R2 ; /* P2 = count */
+ CC = R2 <= 7(IU);
+ IF CC JUMP .Ltoo_small;
+ I0 = R1; /* s2 */
+ R1 = R1 | R0; /* OR addresses together */
+ R1 <<= 30; /* check bottom two bits */
+ CC = AZ; /* AZ set if zero. */
+ IF !CC JUMP .Lbytes ; /* Jump if addrs not aligned. */
+
+ P1 = P2 >> 2; /* count = n/4 */
+ R3 = 3;
+ R2 = R2 & R3; /* remainder */
+ P2 = R2; /* set remainder */
+
+ LSETUP (.Lquad_loop_s, .Lquad_loop_e) LC0=P1;
+.Lquad_loop_s:
+ MNOP || R0 = [P0++] || R1 = [I0++];
+ CC = R0 == R1;
+ IF !CC JUMP .Lquad_different;
+.Lquad_loop_e:
+ NOP;
+
+ P3 = I0; /* s2 */
+.Ltoo_small:
+ CC = P2 == 0; /* Check zero count*/
+ IF CC JUMP .Lfinished; /* very unlikely*/
+
+.Lbytes:
+ LSETUP (.Lbyte_loop_s, .Lbyte_loop_e) LC0=P2;
+.Lbyte_loop_s:
+ R1 = B[P3++](Z); /* *s2 */
+ R0 = B[P0++](Z); /* *s1 */
+ CC = R0 == R1;
+ IF !CC JUMP .Ldifferent;
+.Lbyte_loop_e:
+ NOP;
+
+.Ldifferent:
+ R0 = R0 - R1;
+ P3 = I1;
+ RTS;
+
+.Lquad_different:
+ /* We've read two quads which don't match.
+ * Can't just compare them, because we're
+ * a little-endian machine, so the MSBs of
+ * the regs occur at later addresses in the
+ * string.
+ * Arrange to re-read those two quads again,
+ * byte-by-byte.
+ */
+ P0 += -4; /* back up to the start of the */
+ P3 = I0; /* quads, and increase the*/
+ P2 += 4; /* remainder count*/
+ P3 += -4;
+ JUMP .Lbytes;
+
+.Lfinished:
+ R0 = 0;
+ P3 = I1;
+ RTS;
+
+.size _memcmp,.-_memcmp
diff --git a/arch/blackfin/lib/memcpy.S b/arch/blackfin/lib/memcpy.S
new file mode 100644
index 00000000000..c1e00eff541
--- /dev/null
+++ b/arch/blackfin/lib/memcpy.S
@@ -0,0 +1,142 @@
+/*
+ * File: arch/blackfin/lib/memcpy.S
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description: internal version of memcpy(), issued by the compiler
+ * to copy blocks of data around.
+ * This is really memmove() - it has to be able to deal with
+ * possible overlaps, because that ambiguity is when the compiler
+ * gives up and calls a function. We have our own, internal version
+ * so that we get something we trust, even if the user has redefined
+ * the normal symbol.
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/linkage.h>
+
+/* void *memcpy(void *dest, const void *src, size_t n);
+ * R0 = To Address (dest) (leave unchanged to form result)
+ * R1 = From Address (src)
+ * R2 = count
+ *
+ * Note: Favours word alignment
+ */
+
+#ifdef CONFIG_MEMCPY_L1
+.section .l1.text
+#else
+.text
+#endif
+
+.align 2
+
+ENTRY(_memcpy)
+ CC = R2 <= 0; /* length not positive? */
+ IF CC JUMP .L_P1L2147483647; /* Nothing to do */
+
+ P0 = R0 ; /* dst*/
+ P1 = R1 ; /* src*/
+ P2 = R2 ; /* length */
+
+ /* check for overlapping data */
+ CC = R1 < R0; /* src < dst */
+ IF !CC JUMP .Lno_overlap;
+ R3 = R1 + R2;
+ CC = R0 < R3; /* and dst < src+len */
+ IF CC JUMP .Lhas_overlap;
+
+.Lno_overlap:
+ /* Check for aligned data.*/
+
+ R3 = R1 | R0;
+ R0 = 0x3;
+ R3 = R3 & R0;
+ CC = R3; /* low bits set on either address? */
+ IF CC JUMP .Lnot_aligned;
+
+ /* Both addresses are word-aligned, so we can copy
+ at least part of the data using word copies.*/
+ P2 = P2 >> 2;
+ CC = P2 <= 2;
+ IF !CC JUMP .Lmore_than_seven;
+ /* less than eight bytes... */
+ P2 = R2;
+ LSETUP(.Lthree_start, .Lthree_end) LC0=P2;
+ R0 = R1; /* setup src address for return */
+.Lthree_start:
+ R3 = B[P1++] (X);
+.Lthree_end:
+ B[P0++] = R3;
+
+ RTS;
+
+.Lmore_than_seven:
+ /* There's at least eight bytes to copy. */
+ P2 += -1; /* because we unroll one iteration */
+ LSETUP(.Lword_loop, .Lword_loop) LC0=P2;
+ R0 = R1;
+ I1 = P1;
+ R3 = [I1++];
+.Lword_loop:
+ MNOP || [P0++] = R3 || R3 = [I1++];
+
+ [P0++] = R3;
+ /* Any remaining bytes to copy? */
+ R3 = 0x3;
+ R3 = R2 & R3;
+ CC = R3 == 0;
+ P1 = I1; /* in case there's something left, */
+ IF !CC JUMP .Lbytes_left;
+ RTS;
+.Lbytes_left: P2 = R3;
+.Lnot_aligned:
+ /* From here, we're copying byte-by-byte. */
+ LSETUP (.Lbyte_start, .Lbyte_end) LC0=P2;
+ R0 = R1; /* Save src address for return */
+.Lbyte_start:
+ R1 = B[P1++] (X);
+.Lbyte_end:
+ B[P0++] = R1;
+
+.L_P1L2147483647:
+ RTS;
+
+.Lhas_overlap:
+ /* Need to reverse the copying, because the
+ * dst would clobber the src.
+ * Don't bother to work out alignment for
+ * the reverse case.
+ */
+ R0 = R1; /* save src for later. */
+ P0 = P0 + P2;
+ P0 += -1;
+ P1 = P1 + P2;
+ P1 += -1;
+ LSETUP(.Lover_start, .Lover_end) LC0=P2;
+.Lover_start:
+ R1 = B[P1--] (X);
+.Lover_end:
+ B[P0--] = R1;
+
+ RTS;
diff --git a/arch/blackfin/lib/memmove.S b/arch/blackfin/lib/memmove.S
new file mode 100644
index 00000000000..2e5fb7f8df1
--- /dev/null
+++ b/arch/blackfin/lib/memmove.S
@@ -0,0 +1,103 @@
+/*
+ * File: arch/blackfin/lib/memmove.S
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/linkage.h>
+
+.align 2
+
+/*
+ * C Library function MEMMOVE
+ * R0 = To Address (leave unchanged to form result)
+ * R1 = From Address
+ * R2 = count
+ * Data may overlap
+ */
+
+ENTRY(_memmove)
+ I1 = P3;
+ P0 = R0; /* P0 = To address */
+ P3 = R1; /* P3 = From Address */
+ P2 = R2; /* P2 = count */
+ CC = P2 == 0; /* Check zero count*/
+ IF CC JUMP .Lfinished; /* very unlikely */
+
+ CC = R1 < R0 (IU); /* From < To */
+ IF !CC JUMP .Lno_overlap;
+ R3 = R1 + R2;
+ CC = R0 <= R3 (IU); /* (From+len) >= To */
+ IF CC JUMP .Loverlap;
+.Lno_overlap:
+ R3 = 11;
+ CC = R2 <= R3;
+ IF CC JUMP .Lbytes;
+ R3 = R1 | R0; /* OR addresses together */
+ R3 <<= 30; /* check bottom two bits */
+ CC = AZ; /* AZ set if zero.*/
+ IF !CC JUMP .Lbytes; /* Jump if addrs not aligned.*/
+
+ I0 = P3;
+ P1 = P2 >> 2; /* count = n/4 */
+ P1 += -1;
+ R3 = 3;
+ R2 = R2 & R3; /* remainder */
+ P2 = R2; /* set remainder */
+ R1 = [I0++];
+
+ LSETUP (.Lquad_loop, .Lquad_loop) LC0=P1;
+.Lquad_loop: MNOP || [P0++] = R1 || R1 = [I0++];
+ [P0++] = R1;
+
+ CC = P2 == 0; /* any remaining bytes? */
+ P3 = I0; /* Ammend P3 to updated ptr. */
+ IF !CC JUMP .Lbytes;
+ P3 = I1;
+ RTS;
+
+.Lbytes: LSETUP (.Lbyte2_s, .Lbyte2_e) LC0=P2;
+.Lbyte2_s: R1 = B[P3++](Z);
+.Lbyte2_e: B[P0++] = R1;
+
+.Lfinished: P3 = I1;
+ RTS;
+
+.Loverlap:
+ P2 += -1;
+ P0 = P0 + P2;
+ P3 = P3 + P2;
+ R1 = B[P3--] (Z);
+ CC = P2 == 0;
+ IF CC JUMP .Lno_loop;
+ LSETUP (.Lol_s, .Lol_e) LC0 = P2;
+.Lol_s: B[P0--] = R1;
+.Lol_e: R1 = B[P3--] (Z);
+.Lno_loop: B[P0] = R1;
+ P3 = I1;
+ RTS;
+
+.size _memmove,.-_memmove
diff --git a/arch/blackfin/lib/memset.S b/arch/blackfin/lib/memset.S
new file mode 100644
index 00000000000..ba6d047568d
--- /dev/null
+++ b/arch/blackfin/lib/memset.S
@@ -0,0 +1,109 @@
+/*
+ * File: arch/blackfin/lib/memset.S
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/linkage.h>
+
+.align 2
+
+#ifdef CONFIG_MEMSET_L1
+.section .l1.text
+#else
+.text
+#endif
+
+/*
+ * C Library function MEMSET
+ * R0 = address (leave unchanged to form result)
+ * R1 = filler byte
+ * R2 = count
+ * Favours word aligned data.
+ */
+
+ENTRY(_memset)
+ P0 = R0 ; /* P0 = address */
+ P2 = R2 ; /* P2 = count */
+ R3 = R0 + R2; /* end */
+ CC = R2 <= 7(IU);
+ IF CC JUMP .Ltoo_small;
+ R1 = R1.B (Z); /* R1 = fill char */
+ R2 = 3;
+ R2 = R0 & R2; /* addr bottom two bits */
+ CC = R2 == 0; /* AZ set if zero. */
+ IF !CC JUMP .Lforce_align ; /* Jump if addr not aligned. */
+
+.Laligned:
+ P1 = P2 >> 2; /* count = n/4 */
+ R2 = R1 << 8; /* create quad filler */
+ R2.L = R2.L + R1.L(NS);
+ R2.H = R2.L + R1.H(NS);
+ P2 = R3;
+
+ LSETUP (.Lquad_loop , .Lquad_loop) LC0=P1;
+.Lquad_loop:
+ [P0++] = R2;
+
+ CC = P0 == P2;
+ IF !CC JUMP .Lbytes_left;
+ RTS;
+
+.Lbytes_left:
+ R2 = R3; /* end point */
+ R3 = P0; /* current position */
+ R2 = R2 - R3; /* bytes left */
+ P2 = R2;
+
+.Ltoo_small:
+ CC = P2 == 0; /* Check zero count */
+ IF CC JUMP .Lfinished; /* Unusual */
+
+.Lbytes:
+ LSETUP (.Lbyte_loop , .Lbyte_loop) LC0=P2;
+.Lbyte_loop:
+ B[P0++] = R1;
+
+.Lfinished:
+ RTS;
+
+.Lforce_align:
+ CC = BITTST (R0, 0); /* odd byte */
+ R0 = 4;
+ R0 = R0 - R2;
+ P1 = R0;
+ R0 = P0; /* Recover return address */
+ IF !CC JUMP .Lskip1;
+ B[P0++] = R1;
+.Lskip1:
+ CC = R2 <= 2; /* 2 bytes */
+ P2 -= P1; /* reduce count */
+ IF !CC JUMP .Laligned;
+ B[P0++] = R1;
+ B[P0++] = R1;
+ JUMP .Laligned;
+
+.size _memset,.-_memset
diff --git a/arch/blackfin/lib/modsi3.S b/arch/blackfin/lib/modsi3.S
new file mode 100644
index 00000000000..528b8b1ccb3
--- /dev/null
+++ b/arch/blackfin/lib/modsi3.S
@@ -0,0 +1,79 @@
+/*
+ * File: arch/blackfin/lib/modsi3.S
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description: This program computes 32 bit signed remainder. It calls div32 function
+ * for quotient estimation.
+ *
+ * Registers used :
+ * Numerator/ Denominator in R0, R1
+ * R0 - returns remainder.
+ * R2-R7
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+.global ___modsi3;
+.type ___modsi3, STT_FUNC;
+.extern ___divsi3;
+.type ___divsi3, STT_FUNC;
+
+#ifdef CONFIG_ARITHMETIC_OPS_L1
+.section .l1.text
+#else
+.text
+#endif
+
+___modsi3:
+
+ CC=R0==0;
+ IF CC JUMP .LRETURN_R0; /* Return 0, if numerator == 0 */
+ CC=R1==0;
+ IF CC JUMP .LRETURN_ZERO; /* Return 0, if denominator == 0 */
+ CC=R0==R1;
+ IF CC JUMP .LRETURN_ZERO; /* Return 0, if numerator == denominator */
+ CC = R1 == 1;
+ IF CC JUMP .LRETURN_ZERO; /* Return 0, if denominator == 1 */
+ CC = R1 == -1;
+ IF CC JUMP .LRETURN_ZERO; /* Return 0, if denominator == -1 */
+
+ /* Valid input. Use __divsi3() to compute the quotient, and then
+ * derive the remainder from that. */
+
+ [--SP] = (R7:6); /* Push R7 and R6 */
+ [--SP] = RETS; /* and return address */
+ R7 = R0; /* Copy of R0 */
+ R6 = R1; /* Save for later */
+ SP += -12; /* Should always provide this space */
+ CALL ___divsi3; /* Compute signed quotient using ___divsi3()*/
+ SP += 12;
+ R0 *= R6; /* Quotient * divisor */
+ R0 = R7 - R0; /* Dividend - (quotient * divisor) */
+ RETS = [SP++]; /* Get back return address */
+ (R7:6) = [SP++]; /* Pop registers R7 and R4 */
+ RTS; /* Store remainder */
+
+.LRETURN_ZERO:
+ R0 = 0;
+.LRETURN_R0:
+ RTS;
diff --git a/arch/blackfin/lib/muldi3.c b/arch/blackfin/lib/muldi3.c
new file mode 100644
index 00000000000..303d0c6a6db
--- /dev/null
+++ b/arch/blackfin/lib/muldi3.c
@@ -0,0 +1,99 @@
+/*
+ * File: arch/blackfin/lib/muldi3.c
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef SI_TYPE_SIZE
+#define SI_TYPE_SIZE 32
+#endif
+#define __ll_b (1L << (SI_TYPE_SIZE / 2))
+#define __ll_lowpart(t) ((usitype) (t) % __ll_b)
+#define __ll_highpart(t) ((usitype) (t) / __ll_b)
+#define BITS_PER_UNIT 8
+
+#if !defined(umul_ppmm)
+#define umul_ppmm(w1, w0, u, v) \
+ do { \
+ usitype __x0, __x1, __x2, __x3; \
+ usitype __ul, __vl, __uh, __vh; \
+ \
+ __ul = __ll_lowpart (u); \
+ __uh = __ll_highpart (u); \
+ __vl = __ll_lowpart (v); \
+ __vh = __ll_highpart (v); \
+ \
+ __x0 = (usitype) __ul * __vl; \
+ __x1 = (usitype) __ul * __vh; \
+ __x2 = (usitype) __uh * __vl; \
+ __x3 = (usitype) __uh * __vh; \
+ \
+ __x1 += __ll_highpart (__x0);/* this can't give carry */ \
+ __x1 += __x2; /* but this indeed can */ \
+ if (__x1 < __x2) /* did we get it? */ \
+ __x3 += __ll_b; /* yes, add it in the proper pos. */ \
+ \
+ (w1) = __x3 + __ll_highpart (__x1); \
+ (w0) = __ll_lowpart (__x1) * __ll_b + __ll_lowpart (__x0); \
+ } while (0)
+#endif
+
+#if !defined(__umulsidi3)
+#define __umulsidi3(u, v) \
+ ({diunion __w; \
+ umul_ppmm (__w.s.high, __w.s.low, u, v); \
+ __w.ll; })
+#endif
+
+typedef unsigned int usitype __attribute__ ((mode(SI)));
+typedef int sitype __attribute__ ((mode(SI)));
+typedef int ditype __attribute__ ((mode(DI)));
+typedef int word_type __attribute__ ((mode(__word__)));
+
+struct distruct {
+ sitype low, high;
+};
+typedef union {
+ struct distruct s;
+ ditype ll;
+} diunion;
+
+#ifdef CONFIG_ARITHMETIC_OPS_L1
+ditype __muldi3(ditype u, ditype v)__attribute__((l1_text));
+#endif
+
+ditype __muldi3(ditype u, ditype v)
+{
+ diunion w;
+ diunion uu, vv;
+
+ uu.ll = u, vv.ll = v;
+ w.ll = __umulsidi3(uu.s.low, vv.s.low);
+ w.s.high += ((usitype) uu.s.low * (usitype) vv.s.high
+ + (usitype) uu.s.high * (usitype) vv.s.low);
+
+ return w.ll;
+}
diff --git a/arch/blackfin/lib/outs.S b/arch/blackfin/lib/outs.S
new file mode 100644
index 00000000000..f8c876fe893
--- /dev/null
+++ b/arch/blackfin/lib/outs.S
@@ -0,0 +1,62 @@
+/*
+ * File: arch/blackfin/lib/outs.S
+ * Based on:
+ * Author: Bas Vermeulen <bas@buyways.nl>
+ *
+ * Created: Tue Mar 22 15:27:24 CEST 2005
+ * Description: Implementation of outs{bwl} for BlackFin processors using zero overhead loops.
+ *
+ * Modified: Copyright (C) 2005 Bas Vermeulen, BuyWays BV <bas@buyways.nl>
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/linkage.h>
+
+.align 2
+
+ENTRY(_outsl)
+ P0 = R0; /* P0 = port */
+ P1 = R1; /* P1 = address */
+ P2 = R2; /* P2 = count */
+
+ LSETUP( .Llong_loop_s, .Llong_loop_e) LC0 = P2;
+.Llong_loop_s: R0 = [P1++];
+.Llong_loop_e: [P0] = R0;
+ RTS;
+
+ENTRY(_outsw)
+ P0 = R0; /* P0 = port */
+ P1 = R1; /* P1 = address */
+ P2 = R2; /* P2 = count */
+
+ LSETUP( .Lword_loop_s, .Lword_loop_e) LC0 = P2;
+.Lword_loop_s: R0 = W[P1++];
+.Lword_loop_e: W[P0] = R0;
+ RTS;
+
+ENTRY(_outsb)
+ P0 = R0; /* P0 = port */
+ P1 = R1; /* P1 = address */
+ P2 = R2; /* P2 = count */
+
+ LSETUP( .Lbyte_loop_s, .Lbyte_loop_e) LC0 = P2;
+.Lbyte_loop_s: R0 = B[P1++];
+.Lbyte_loop_e: B[P0] = R0;
+ RTS;
diff --git a/arch/blackfin/lib/smulsi3_highpart.S b/arch/blackfin/lib/smulsi3_highpart.S
new file mode 100644
index 00000000000..10b8f8da576
--- /dev/null
+++ b/arch/blackfin/lib/smulsi3_highpart.S
@@ -0,0 +1,30 @@
+.align 2
+.global ___smulsi3_highpart;
+.type ___smulsi3_highpart, STT_FUNC;
+
+#ifdef CONFIG_ARITHMETIC_OPS_L1
+.section .l1.text
+#else
+.text
+#endif
+
+___smulsi3_highpart:
+ R2 = R1.L * R0.L (FU);
+ R3 = R1.H * R0.L (IS,M);
+ R0 = R0.H * R1.H, R1 = R0.H * R1.L (IS,M);
+
+ R1.L = R2.H + R1.L;
+ cc = ac0;
+ R2 = cc;
+
+ R1.L = R1.L + R3.L;
+ cc = ac0;
+ R1 >>>= 16;
+ R3 >>>= 16;
+ R1 = R1 + R3;
+ R1 = R1 + R2;
+ R2 = cc;
+ R1 = R1 + R2;
+
+ R0 = R0 + R1;
+ RTS;
diff --git a/arch/blackfin/lib/strcmp.c b/arch/blackfin/lib/strcmp.c
new file mode 100644
index 00000000000..2ad47c4254b
--- /dev/null
+++ b/arch/blackfin/lib/strcmp.c
@@ -0,0 +1,11 @@
+#include <linux/types.h>
+
+#define strcmp __inline_strcmp
+#include <asm/string.h>
+#undef strcmp
+
+int strcmp(const char *dest, const char *src)
+{
+ return __inline_strcmp(dest, src);
+}
+
diff --git a/arch/blackfin/lib/strcpy.c b/arch/blackfin/lib/strcpy.c
new file mode 100644
index 00000000000..4dc835a8a19
--- /dev/null
+++ b/arch/blackfin/lib/strcpy.c
@@ -0,0 +1,11 @@
+#include <linux/types.h>
+
+#define strcpy __inline_strcpy
+#include <asm/string.h>
+#undef strcpy
+
+char *strcpy(char *dest, const char *src)
+{
+ return __inline_strcpy(dest, src);
+}
+
diff --git a/arch/blackfin/lib/strncmp.c b/arch/blackfin/lib/strncmp.c
new file mode 100644
index 00000000000..947bcfe3f3b
--- /dev/null
+++ b/arch/blackfin/lib/strncmp.c
@@ -0,0 +1,11 @@
+#include <linux/types.h>
+
+#define strncmp __inline_strncmp
+#include <asm/string.h>
+#undef strncmp
+
+int strncmp(const char *cs, const char *ct, size_t count)
+{
+ return __inline_strncmp(cs, ct, count);
+}
+
diff --git a/arch/blackfin/lib/strncpy.c b/arch/blackfin/lib/strncpy.c
new file mode 100644
index 00000000000..77a9b2e9509
--- /dev/null
+++ b/arch/blackfin/lib/strncpy.c
@@ -0,0 +1,11 @@
+#include <linux/types.h>
+
+#define strncpy __inline_strncpy
+#include <asm/string.h>
+#undef strncpy
+
+char *strncpy(char *dest, const char *src, size_t n)
+{
+ return __inline_strncpy(dest, src, n);
+}
+
diff --git a/arch/blackfin/lib/udivsi3.S b/arch/blackfin/lib/udivsi3.S
new file mode 100644
index 00000000000..d39a1291625
--- /dev/null
+++ b/arch/blackfin/lib/udivsi3.S
@@ -0,0 +1,298 @@
+/*
+ * File: arch/blackfin/lib/udivsi3.S
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/linkage.h>
+
+#define CARRY AC0
+
+#ifdef CONFIG_ARITHMETIC_OPS_L1
+.section .l1.text
+#else
+.text
+#endif
+
+
+ENTRY(___udivsi3)
+
+ CC = R0 < R1 (IU); /* If X < Y, always return 0 */
+ IF CC JUMP .Lreturn_ident;
+
+ R2 = R1 << 16;
+ CC = R2 <= R0 (IU);
+ IF CC JUMP .Lidents;
+
+ R2 = R0 >> 31; /* if X is a 31-bit number */
+ R3 = R1 >> 15; /* and Y is a 15-bit number */
+ R2 = R2 | R3; /* then it's okay to use the DIVQ builtins (fallthrough to fast)*/
+ CC = R2;
+ IF CC JUMP .Ly_16bit;
+
+/* METHOD 1: FAST DIVQ
+ We know we have a 31-bit dividend, and 15-bit divisor so we can use the
+ simple divq approach (first setting AQ to 0 - implying unsigned division,
+ then 16 DIVQ's).
+*/
+
+ AQ = CC; /* Clear AQ (CC==0) */
+
+/* ISR States: When dividing two integers (32.0/16.0) using divide primitives,
+ we need to shift the dividend one bit to the left.
+ We have already checked that we have a 31-bit number so we are safe to do
+ that.
+*/
+ R0 <<= 1;
+ DIVQ(R0, R1); // 1
+ DIVQ(R0, R1); // 2
+ DIVQ(R0, R1); // 3
+ DIVQ(R0, R1); // 4
+ DIVQ(R0, R1); // 5
+ DIVQ(R0, R1); // 6
+ DIVQ(R0, R1); // 7
+ DIVQ(R0, R1); // 8
+ DIVQ(R0, R1); // 9
+ DIVQ(R0, R1); // 10
+ DIVQ(R0, R1); // 11
+ DIVQ(R0, R1); // 12
+ DIVQ(R0, R1); // 13
+ DIVQ(R0, R1); // 14
+ DIVQ(R0, R1); // 15
+ DIVQ(R0, R1); // 16
+ R0 = R0.L (Z);
+ RTS;
+
+.Ly_16bit:
+ /* We know that the upper 17 bits of Y might have bits set,
+ ** or that the sign bit of X might have a bit. If Y is a
+ ** 16-bit number, but not bigger, then we can use the builtins
+ ** with a post-divide correction.
+ ** R3 currently holds Y>>15, which means R3's LSB is the
+ ** bit we're interested in.
+ */
+
+ /* According to the ISR, to use the Divide primitives for
+ ** unsigned integer divide, the useable range is 31 bits
+ */
+ CC = ! BITTST(R0, 31);
+
+ /* IF condition is true we can scale our inputs and use the divide primitives,
+ ** with some post-adjustment
+ */
+ R3 += -1; /* if so, Y is 0x00008nnn */
+ CC &= AZ;
+
+ /* If condition is true we can scale our inputs and use the divide primitives,
+ ** with some post-adjustment
+ */
+ R3 = R1 >> 1; /* Pre-scaled divisor for primitive case */
+ R2 = R0 >> 16;
+
+ R2 = R3 - R2; /* shifted divisor < upper 16 bits of dividend */
+ CC &= CARRY;
+ IF CC JUMP .Lshift_and_correct;
+
+ /* Fall through to the identities */
+
+/* METHOD 2: identities and manual calculation
+ We are not able to use the divide primites, but may still catch some special
+ cases.
+*/
+.Lidents:
+ /* Test for common identities. Value to be returned is placed in R2. */
+ CC = R0 == 0; /* 0/Y => 0 */
+ IF CC JUMP .Lreturn_r0;
+ CC = R0 == R1; /* X==Y => 1 */
+ IF CC JUMP .Lreturn_ident;
+ CC = R1 == 1; /* X/1 => X */
+ IF CC JUMP .Lreturn_ident;
+
+ R2.L = ONES R1;
+ R2 = R2.L (Z);
+ CC = R2 == 1;
+ IF CC JUMP .Lpower_of_two;
+
+ [--SP] = (R7:5); /* Push registers R5-R7 */
+
+ /* Idents don't match. Go for the full operation. */
+
+
+ R6 = 2; /* assume we'll shift two */
+ R3 = 1;
+
+ P2 = R1;
+ /* If either R0 or R1 have sign set, */
+ /* divide them by two, and note it's */
+ /* been done. */
+ CC = R1 < 0;
+ R2 = R1 >> 1;
+ IF CC R1 = R2; /* Possibly-shifted R1 */
+ IF !CC R6 = R3; /* R1 doesn't, so at most 1 shifted */
+
+ P0 = 0;
+ R3 = -R1;
+ [--SP] = R3;
+ R2 = R0 >> 1;
+ R2 = R0 >> 1;
+ CC = R0 < 0;
+ IF CC P0 = R6; /* Number of values divided */
+ IF !CC R2 = R0; /* Shifted R0 */
+
+ /* P0 is 0, 1 (NR/=2) or 2 (NR/=2, DR/=2) */
+
+ /* r2 holds Copy dividend */
+ R3 = 0; /* Clear partial remainder */
+ R7 = 0; /* Initialise quotient bit */
+
+ P1 = 32; /* Set loop counter */
+ LSETUP(.Lulst, .Lulend) LC0 = P1; /* Set loop counter */
+.Lulst: R6 = R2 >> 31; /* R6 = sign bit of R2, for carry */
+ R2 = R2 << 1; /* Shift 64 bit dividend up by 1 bit */
+ R3 = R3 << 1 || R5 = [SP];
+ R3 = R3 | R6; /* Include any carry */
+ CC = R7 < 0; /* Check quotient(AQ) */
+ /* If AQ==0, we'll sub divisor */
+ IF CC R5 = R1; /* and if AQ==1, we'll add it. */
+ R3 = R3 + R5; /* Add/sub divsor to partial remainder */
+ R7 = R3 ^ R1; /* Generate next quotient bit */
+
+ R5 = R7 >> 31; /* Get AQ */
+ BITTGL(R5, 0); /* Invert it, to get what we'll shift */
+.Lulend: R2 = R2 + R5; /* and "shift" it in. */
+
+ CC = P0 == 0; /* Check how many inputs we shifted */
+ IF CC JUMP .Lno_mult; /* if none... */
+ R6 = R2 << 1;
+ CC = P0 == 1;
+ IF CC R2 = R6; /* if 1, Q = Q*2 */
+ IF !CC R1 = P2; /* if 2, restore stored divisor */
+
+ R3 = R2; /* Copy of R2 */
+ R3 *= R1; /* Q * divisor */
+ R5 = R0 - R3; /* Z = (dividend - Q * divisor) */
+ CC = R1 <= R5 (IU); /* Check if divisor <= Z? */
+ R6 = CC; /* if yes, R6 = 1 */
+ R2 = R2 + R6; /* if yes, add one to quotient(Q) */
+.Lno_mult:
+ SP += 4;
+ (R7:5) = [SP++]; /* Pop registers R5-R7 */
+ R0 = R2; /* Store quotient */
+ RTS;
+
+.Lreturn_ident:
+ CC = R0 < R1 (IU); /* If X < Y, always return 0 */
+ R2 = 0;
+ IF CC JUMP .Ltrue_return_ident;
+ R2 = -1 (X); /* X/0 => 0xFFFFFFFF */
+ CC = R1 == 0;
+ IF CC JUMP .Ltrue_return_ident;
+ R2 = -R2; /* R2 now 1 */
+ CC = R0 == R1; /* X==Y => 1 */
+ IF CC JUMP .Ltrue_return_ident;
+ R2 = R0; /* X/1 => X */
+ /*FALLTHRU*/
+
+.Ltrue_return_ident:
+ R0 = R2;
+.Lreturn_r0:
+ RTS;
+
+.Lpower_of_two:
+ /* Y has a single bit set, which means it's a power of two.
+ ** That means we can perform the division just by shifting
+ ** X to the right the appropriate number of bits
+ */
+
+ /* signbits returns the number of sign bits, minus one.
+ ** 1=>30, 2=>29, ..., 0x40000000=>0. Which means we need
+ ** to shift right n-signbits spaces. It also means 0x80000000
+ ** is a special case, because that *also* gives a signbits of 0
+ */
+
+ R2 = R0 >> 31;
+ CC = R1 < 0;
+ IF CC JUMP .Ltrue_return_ident;
+
+ R1.l = SIGNBITS R1;
+ R1 = R1.L (Z);
+ R1 += -30;
+ R0 = LSHIFT R0 by R1.L;
+ RTS;
+
+/* METHOD 3: PRESCALE AND USE THE DIVIDE PRIMITIVES WITH SOME POST-CORRECTION
+ Two scaling operations are required to use the divide primitives with a
+ divisor > 0x7FFFF.
+ Firstly (as in method 1) we need to shift the dividend 1 to the left for
+ integer division.
+ Secondly we need to shift both the divisor and dividend 1 to the right so
+ both are in range for the primitives.
+ The left/right shift of the dividend does nothing so we can skip it.
+*/
+.Lshift_and_correct:
+ R2 = R0;
+ // R3 is already R1 >> 1
+ CC=!CC;
+ AQ = CC; /* Clear AQ, got here with CC = 0 */
+ DIVQ(R2, R3); // 1
+ DIVQ(R2, R3); // 2
+ DIVQ(R2, R3); // 3
+ DIVQ(R2, R3); // 4
+ DIVQ(R2, R3); // 5
+ DIVQ(R2, R3); // 6
+ DIVQ(R2, R3); // 7
+ DIVQ(R2, R3); // 8
+ DIVQ(R2, R3); // 9
+ DIVQ(R2, R3); // 10
+ DIVQ(R2, R3); // 11
+ DIVQ(R2, R3); // 12
+ DIVQ(R2, R3); // 13
+ DIVQ(R2, R3); // 14
+ DIVQ(R2, R3); // 15
+ DIVQ(R2, R3); // 16
+
+ /* According to the Instruction Set Reference:
+ To divide by a divisor > 0x7FFF,
+ 1. prescale and perform divide to obtain quotient (Q) (done above),
+ 2. multiply quotient by unscaled divisor (result M)
+ 3. subtract the product from the divident to get an error (E = X - M)
+ 4. if E < divisor (Y) subtract 1, if E > divisor (Y) add 1, else return quotient (Q)
+ */
+ R3 = R2.L (Z); /* Q = X' / Y' */
+ R2 = R3; /* Preserve Q */
+ R2 *= R1; /* M = Q * Y */
+ R2 = R0 - R2; /* E = X - M */
+ R0 = R3; /* Copy Q into result reg */
+
+/* Correction: If result of the multiply is negative, we overflowed
+ and need to correct the result by subtracting 1 from the result.*/
+ R3 = 0xFFFF (Z);
+ R2 = R2 >> 16; /* E >> 16 */
+ CC = R2 == R3;
+ R3 = 1 ;
+ R1 = R0 - R3;
+ IF CC R0 = R1;
+ RTS;
diff --git a/arch/blackfin/lib/umodsi3.S b/arch/blackfin/lib/umodsi3.S
new file mode 100644
index 00000000000..b55ce96ab89
--- /dev/null
+++ b/arch/blackfin/lib/umodsi3.S
@@ -0,0 +1,66 @@
+/*
+ * File: arch/blackfin/lib/umodsi3.S
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description: libgcc1 routines for Blackfin 5xx
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifdef CONFIG_ARITHMETIC_OPS_L1
+.section .l1.text
+#else
+.text
+#endif
+
+.extern ___udivsi3;
+.globl ___umodsi3
+___umodsi3:
+
+ CC=R0==0;
+ IF CC JUMP .LRETURN_R0; /* Return 0, if NR == 0 */
+ CC= R1==0;
+ IF CC JUMP .LRETURN_ZERO_VAL; /* Return 0, if DR == 0 */
+ CC=R0==R1;
+ IF CC JUMP .LRETURN_ZERO_VAL; /* Return 0, if NR == DR */
+ CC = R1 == 1;
+ IF CC JUMP .LRETURN_ZERO_VAL; /* Return 0, if DR == 1 */
+ CC = R0<R1 (IU);
+ IF CC JUMP .LRETURN_R0; /* Return dividend (R0),IF NR<DR */
+
+ [--SP] = (R7:6); /* Push registers and */
+ [--SP] = RETS; /* Return address */
+ R7 = R0; /* Copy of R0 */
+ R6 = R1;
+ SP += -12; /* Should always provide this space */
+ CALL ___udivsi3; /* Compute unsigned quotient using ___udiv32()*/
+ SP += 12;
+ R0 *= R6; /* Quotient * divisor */
+ R0 = R7 - R0; /* Dividend - (quotient * divisor) */
+ RETS = [SP++]; /* Pop return address */
+ ( R7:6) = [SP++]; /* And registers */
+ RTS; /* Return remainder */
+.LRETURN_ZERO_VAL:
+ R0 = 0;
+.LRETURN_R0:
+ RTS;
diff --git a/arch/blackfin/lib/umulsi3_highpart.S b/arch/blackfin/lib/umulsi3_highpart.S
new file mode 100644
index 00000000000..aac8218fb25
--- /dev/null
+++ b/arch/blackfin/lib/umulsi3_highpart.S
@@ -0,0 +1,23 @@
+.align 2
+.global ___umulsi3_highpart;
+.type ___umulsi3_highpart, STT_FUNC;
+
+#ifdef CONFIG_ARITHMETIC_OPS_L1
+.section .l1.text
+#else
+.text
+#endif
+
+___umulsi3_highpart:
+ R2 = R1.H * R0.H, R3 = R1.L * R0.H (FU);
+ R0 = R1.L * R0.L, R1 = R1.H * R0.L (FU);
+ R0 >>= 16;
+ /* Unsigned multiplication has the nice property that we can
+ ignore carry on this first addition. */
+ R0 = R0 + R3;
+ R0 = R0 + R1;
+ cc = ac0;
+ R1 = cc;
+ R1 = PACK(R1.l,R0.h);
+ R0 = R1 + R2;
+ RTS;
diff --git a/arch/blackfin/mach-bf533/Kconfig b/arch/blackfin/mach-bf533/Kconfig
new file mode 100644
index 00000000000..14297b3ed5c
--- /dev/null
+++ b/arch/blackfin/mach-bf533/Kconfig
@@ -0,0 +1,92 @@
+if (BF533 || BF532 || BF531)
+
+menu "BF533/2/1 Specific Configuration"
+
+comment "Interrupt Priority Assignment"
+menu "Priority"
+
+config UART_ERROR
+ int "UART ERROR"
+ default 7
+config SPORT0_ERROR
+ int "SPORT0 ERROR"
+ default 7
+config SPI_ERROR
+ int "SPI ERROR"
+ default 7
+config SPORT1_ERROR
+ int "SPORT1 ERROR"
+ default 7
+config PPI_ERROR
+ int "PPI ERROR"
+ default 7
+config DMA_ERROR
+ int "DMA ERROR"
+ default 7
+config PLLWAKE_ERROR
+ int "PLL WAKEUP ERROR"
+ default 7
+
+config RTC_ERROR
+ int "RTC ERROR"
+ default 8
+config DMA0_PPI
+ int "DMA0 PPI"
+ default 8
+
+config DMA1_SPORT0RX
+ int "DMA1 (SPORT0 RX)"
+ default 9
+config DMA2_SPORT0TX
+ int "DMA2 (SPORT0 TX)"
+ default 9
+config DMA3_SPORT1RX
+ int "DMA3 (SPORT1 RX)"
+ default 9
+config DMA4_SPORT1TX
+ int "DMA4 (SPORT1 TX)"
+ default 9
+config DMA5_SPI
+ int "DMA5 (SPI)"
+ default 10
+config DMA6_UARTRX
+ int "DMA6 (UART0 RX)"
+ default 10
+config DMA7_UARTTX
+ int "DMA7 (UART0 TX)"
+ default 10
+config TIMER0
+ int "TIMER0"
+ default 11
+config TIMER1
+ int "TIMER1"
+ default 11
+config TIMER2
+ int "TIMER2"
+ default 11
+config PFA
+ int "PF Interrupt A"
+ default 12
+config PFB
+ int "PF Interrupt B"
+ default 12
+config MEMDMA0
+ int "MEMORY DMA0"
+ default 13
+config MEMDMA1
+ int "MEMORY DMA1"
+ default 13
+config WDTIMER
+ int "WATCH DOG TIMER"
+ default 13
+
+ help
+ Enter the priority numbers between 7-13 ONLY. Others are Reserved.
+ This applies to all the above. It is not recommended to assign the
+ highest priority number 7 to UART or any other device.
+
+endmenu
+
+endmenu
+
+endif
diff --git a/arch/blackfin/mach-bf533/Makefile b/arch/blackfin/mach-bf533/Makefile
new file mode 100644
index 00000000000..76d2c2b8579
--- /dev/null
+++ b/arch/blackfin/mach-bf533/Makefile
@@ -0,0 +1,9 @@
+#
+# arch/blackfin/mach-bf533/Makefile
+#
+
+extra-y := head.o
+
+obj-y := ints-priority.o
+
+obj-$(CONFIG_CPU_FREQ_BF533) += cpu.o
diff --git a/arch/blackfin/mach-bf533/boards/Makefile b/arch/blackfin/mach-bf533/boards/Makefile
new file mode 100644
index 00000000000..12a631ab389
--- /dev/null
+++ b/arch/blackfin/mach-bf533/boards/Makefile
@@ -0,0 +1,8 @@
+#
+# arch/blackfin/mach-bf533/boards/Makefile
+#
+
+obj-$(CONFIG_GENERIC_BOARD) += generic_board.o
+obj-$(CONFIG_BFIN533_STAMP) += stamp.o
+obj-$(CONFIG_BFIN533_EZKIT) += ezkit.o
+obj-$(CONFIG_BFIN533_BLUETECHNIX_CM) += cm_bf533.o
diff --git a/arch/blackfin/mach-bf533/boards/cm_bf533.c b/arch/blackfin/mach-bf533/boards/cm_bf533.c
new file mode 100644
index 00000000000..23a7f607df3
--- /dev/null
+++ b/arch/blackfin/mach-bf533/boards/cm_bf533.c
@@ -0,0 +1,267 @@
+/*
+ * File: arch/blackfin/mach-bf533/boards/cm_bf533.c
+ * Based on: arch/blackfin/mach-bf533/boards/ezkit.c
+ * Author: Aidan Williams <aidan@nicta.com.au> Copright 2005
+ *
+ * Created: 2005
+ * Description: Board description file
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+#include <linux/usb_isp1362.h>
+#include <asm/irq.h>
+#include <asm/bfin5xx_spi.h>
+
+/*
+ * Name the Board for the /proc/cpuinfo
+ */
+char *bfin_board_name = "Bluetechnix CM BF533";
+
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+/* all SPI peripherals info goes here */
+
+static struct mtd_partition bfin_spi_flash_partitions[] = {
+ {
+ .name = "bootloader",
+ .size = 0x00020000,
+ .offset = 0,
+ .mask_flags = MTD_CAP_ROM
+ },{
+ .name = "kernel",
+ .size = 0xe0000,
+ .offset = 0x20000
+ },{
+ .name = "file system",
+ .size = 0x700000,
+ .offset = 0x00100000,
+ }
+};
+
+static struct flash_platform_data bfin_spi_flash_data = {
+ .name = "m25p80",
+ .parts = bfin_spi_flash_partitions,
+ .nr_parts = ARRAY_SIZE(bfin_spi_flash_partitions),
+ .type = "m25p64",
+};
+
+/* SPI flash chip (m25p64) */
+static struct bfin5xx_spi_chip spi_flash_chip_info = {
+ .enable_dma = 0, /* use dma transfer with this chip*/
+ .bits_per_word = 8,
+};
+
+/* SPI ADC chip */
+static struct bfin5xx_spi_chip spi_adc_chip_info = {
+ .enable_dma = 1, /* use dma transfer with this chip*/
+ .bits_per_word = 16,
+};
+
+#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
+ .enable_dma = 0,
+ .bits_per_word = 16,
+};
+#endif
+
+static struct spi_board_info bfin_spi_board_info[] __initdata = {
+ {
+ /* the modalias must be the same as spi device driver name */
+ .modalias = "m25p80", /* Name of spi_driver for this device */
+ .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1, /* Framework bus number */
+ .chip_select = 1, /* Framework chip select. On STAMP537 it is SPISSEL1*/
+ .platform_data = &bfin_spi_flash_data,
+ .controller_data = &spi_flash_chip_info,
+ .mode = SPI_MODE_3,
+ },{
+ .modalias = "bfin_spi_adc", /* Name of spi_driver for this device */
+ .max_speed_hz = 6250000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1, /* Framework bus number */
+ .chip_select = 2, /* Framework chip select. */
+ .platform_data = NULL, /* No spi_driver specific config */
+ .controller_data = &spi_adc_chip_info,
+ },
+#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+ {
+ .modalias = "ad1836-spi",
+ .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1,
+ .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT,
+ .controller_data = &ad1836_spi_chip_info,
+ },
+#endif
+};
+
+/* SPI controller data */
+static struct bfin5xx_spi_master spi_bfin_master_info = {
+ .num_chipselect = 8,
+ .enable_dma = 1, /* master has the ability to do dma transfer */
+};
+
+static struct platform_device spi_bfin_master_device = {
+ .name = "bfin-spi-master",
+ .id = 1, /* Bus number */
+ .dev = {
+ .platform_data = &spi_bfin_master_info, /* Passed to driver */
+ },
+};
+#endif /* spi master and devices */
+
+#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
+static struct platform_device rtc_device = {
+ .name = "rtc-bfin",
+ .id = -1,
+};
+#endif
+
+#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+static struct resource smc91x_resources[] = {
+ {
+ .start = 0x20200300,
+ .end = 0x20200300 + 16,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = IRQ_PF0,
+ .end = IRQ_PF0,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ },
+};
+static struct platform_device smc91x_device = {
+ .name = "smc91x",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(smc91x_resources),
+ .resource = smc91x_resources,
+};
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
+static struct resource bfin_uart_resources[] = {
+ {
+ .start = 0xFFC00400,
+ .end = 0xFFC004FF,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device bfin_uart_device = {
+ .name = "bfin-uart",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(bfin_uart_resources),
+ .resource = bfin_uart_resources,
+};
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+static struct platform_device bfin_sport0_uart_device = {
+ .name = "bfin-sport-uart",
+ .id = 0,
+};
+
+static struct platform_device bfin_sport1_uart_device = {
+ .name = "bfin-sport-uart",
+ .id = 1,
+};
+#endif
+
+#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
+static struct resource isp1362_hcd_resources[] = {
+ {
+ .start = 0x20308000,
+ .end = 0x20308000,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = 0x20308004,
+ .end = 0x20308004,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = IRQ_PF4,
+ .end = IRQ_PF4,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct isp1362_platform_data isp1362_priv = {
+ .sel15Kres = 1,
+ .clknotstop = 0,
+ .oc_enable = 0,
+ .int_act_high = 0,
+ .int_edge_triggered = 0,
+ .remote_wakeup_connected = 0,
+ .no_power_switching = 1,
+ .power_switching_mode = 0,
+};
+
+static struct platform_device isp1362_hcd_device = {
+ .name = "isp1362-hcd",
+ .id = 0,
+ .dev = {
+ .platform_data = &isp1362_priv,
+ },
+ .num_resources = ARRAY_SIZE(isp1362_hcd_resources),
+ .resource = isp1362_hcd_resources,
+};
+#endif
+
+static struct platform_device *cm_bf533_devices[] __initdata = {
+#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
+ &bfin_uart_device,
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+ &bfin_sport0_uart_device,
+ &bfin_sport1_uart_device,
+#endif
+
+#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
+ &rtc_device,
+#endif
+
+#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
+ &isp1362_hcd_device,
+#endif
+
+#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+ &smc91x_device,
+#endif
+
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+ &spi_bfin_master_device,
+#endif
+};
+
+static int __init cm_bf533_init(void)
+{
+ printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__);
+ platform_add_devices(cm_bf533_devices, ARRAY_SIZE(cm_bf533_devices));
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+ spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info));
+#endif
+ return 0;
+}
+
+arch_initcall(cm_bf533_init);
diff --git a/arch/blackfin/mach-bf533/boards/ezkit.c b/arch/blackfin/mach-bf533/boards/ezkit.c
new file mode 100644
index 00000000000..747298ea907
--- /dev/null
+++ b/arch/blackfin/mach-bf533/boards/ezkit.c
@@ -0,0 +1,224 @@
+/*
+ * File: arch/blackfin/mach-bf533/ezkit.c
+ * Based on: Orginal Work
+ * Author: Aidan Williams <aidan@nicta.com.au>
+ *
+ * Created: 2005
+ * Description:
+ *
+ * Modified: Robin Getz <rgetz@blackfin.uclinux.org> - Named the boards
+ * Copyright 2005 National ICT Australia (NICTA)
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+#include <linux/usb_isp1362.h>
+#include <asm/irq.h>
+#include <asm/bfin5xx_spi.h>
+
+/*
+ * Name the Board for the /proc/cpuinfo
+ */
+char *bfin_board_name = "ADDS-BF533-EZKIT";
+
+#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
+static struct platform_device rtc_device = {
+ .name = "rtc-bfin",
+ .id = -1,
+};
+#endif
+
+/*
+ * USB-LAN EzExtender board
+ * Driver needs to know address, irq and flag pin.
+ */
+#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+static struct resource smc91x_resources[] = {
+ {
+ .name = "smc91x-regs",
+ .start = 0x20310300,
+ .end = 0x20310300 + 16,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = IRQ_PF9,
+ .end = IRQ_PF9,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ },
+};
+static struct platform_device smc91x_device = {
+ .name = "smc91x",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(smc91x_resources),
+ .resource = smc91x_resources,
+};
+#endif
+
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+/* all SPI peripherals info goes here */
+
+#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
+static struct mtd_partition bfin_spi_flash_partitions[] = {
+ {
+ .name = "bootloader",
+ .size = 0x00020000,
+ .offset = 0,
+ .mask_flags = MTD_CAP_ROM
+ },{
+ .name = "kernel",
+ .size = 0xe0000,
+ .offset = 0x20000
+ },{
+ .name = "file system",
+ .size = 0x700000,
+ .offset = 0x00100000,
+ }
+};
+
+static struct flash_platform_data bfin_spi_flash_data = {
+ .name = "m25p80",
+ .parts = bfin_spi_flash_partitions,
+ .nr_parts = ARRAY_SIZE(bfin_spi_flash_partitions),
+ .type = "m25p64",
+};
+
+/* SPI flash chip (m25p64) */
+static struct bfin5xx_spi_chip spi_flash_chip_info = {
+ .enable_dma = 0, /* use dma transfer with this chip*/
+ .bits_per_word = 8,
+};
+#endif
+
+#if defined(CONFIG_SPI_ADC_BF533) || defined(CONFIG_SPI_ADC_BF533_MODULE)
+/* SPI ADC chip */
+static struct bfin5xx_spi_chip spi_adc_chip_info = {
+ .enable_dma = 1, /* use dma transfer with this chip*/
+ .bits_per_word = 16,
+};
+#endif
+
+#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
+ .enable_dma = 0,
+ .bits_per_word = 16,
+};
+#endif
+
+static struct spi_board_info bfin_spi_board_info[] __initdata = {
+#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
+ {
+ /* the modalias must be the same as spi device driver name */
+ .modalias = "m25p80", /* Name of spi_driver for this device */
+ .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1, /* Framework bus number */
+ .chip_select = 2, /* Framework chip select. On STAMP537 it is SPISSEL2*/
+ .platform_data = &bfin_spi_flash_data,
+ .controller_data = &spi_flash_chip_info,
+ .mode = SPI_MODE_3,
+ },
+#endif
+
+#if defined(CONFIG_SPI_ADC_BF533) || defined(CONFIG_SPI_ADC_BF533_MODULE)
+ {
+ .modalias = "bfin_spi_adc", /* Name of spi_driver for this device */
+ .max_speed_hz = 6250000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1, /* Framework bus number */
+ .chip_select = 1, /* Framework chip select. */
+ .platform_data = NULL, /* No spi_driver specific config */
+ .controller_data = &spi_adc_chip_info,
+ },
+#endif
+
+#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+ {
+ .modalias = "ad1836-spi",
+ .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1,
+ .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT,
+ .controller_data = &ad1836_spi_chip_info,
+ },
+#endif
+};
+
+/* SPI controller data */
+static struct bfin5xx_spi_master spi_bfin_master_info = {
+ .num_chipselect = 8,
+ .enable_dma = 1, /* master has the ability to do dma transfer */
+};
+
+static struct platform_device spi_bfin_master_device = {
+ .name = "bfin-spi-master",
+ .id = 1, /* Bus number */
+ .dev = {
+ .platform_data = &spi_bfin_master_info, /* Passed to driver */
+ },
+};
+#endif /* spi master and devices */
+
+#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
+static struct resource bfin_uart_resources[] = {
+ {
+ .start = 0xFFC00400,
+ .end = 0xFFC004FF,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device bfin_uart_device = {
+ .name = "bfin-uart",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(bfin_uart_resources),
+ .resource = bfin_uart_resources,
+};
+#endif
+
+static struct platform_device *ezkit_devices[] __initdata = {
+#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+ &smc91x_device,
+#endif
+
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+ &spi_bfin_master_device,
+#endif
+
+#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
+ &rtc_device,
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
+ &bfin_uart_device,
+#endif
+};
+
+static int __init ezkit_init(void)
+{
+ printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__);
+ platform_add_devices(ezkit_devices, ARRAY_SIZE(ezkit_devices));
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+ spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info));
+#endif
+ return 0;
+}
+
+arch_initcall(ezkit_init);
diff --git a/arch/blackfin/mach-bf533/boards/generic_board.c b/arch/blackfin/mach-bf533/boards/generic_board.c
new file mode 100644
index 00000000000..c0f43ccfbfb
--- /dev/null
+++ b/arch/blackfin/mach-bf533/boards/generic_board.c
@@ -0,0 +1,95 @@
+/*
+ * File: arch/blackfin/mach-bf533/generic_board.c
+ * Based on: arch/blackfin/mach-bf533/ezkit.c
+ * Author: Aidan Williams <aidan@nicta.com.au>
+ *
+ * Created: 2005
+ * Description:
+ *
+ * Modified:
+ * Copyright 2005 National ICT Australia (NICTA)
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <asm/irq.h>
+
+/*
+ * Name the Board for the /proc/cpuinfo
+ */
+char *bfin_board_name = "UNKNOWN BOARD";
+
+#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
+static struct platform_device rtc_device = {
+ .name = "rtc-bfin",
+ .id = -1,
+};
+#endif
+
+/*
+ * Driver needs to know address, irq and flag pin.
+ */
+#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+static struct resource smc91x_resources[] = {
+ {
+ .start = 0x20300300,
+ .end = 0x20300300 + 16,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = IRQ_PROG_INTB,
+ .end = IRQ_PROG_INTB,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ },{
+ /*
+ * denotes the flag pin and is used directly if
+ * CONFIG_IRQCHIP_DEMUX_GPIO is defined.
+ */
+ .start = IRQ_PF7,
+ .end = IRQ_PF7,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ },
+};
+
+static struct platform_device smc91x_device = {
+ .name = "smc91x",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(smc91x_resources),
+ .resource = smc91x_resources,
+};
+#endif
+
+static struct platform_device *generic_board_devices[] __initdata = {
+#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
+ &rtc_device,
+#endif
+
+#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+ &smc91x_device,
+#endif
+};
+
+static int __init generic_board_init(void)
+{
+ printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__);
+ return platform_add_devices(generic_board_devices, ARRAY_SIZE(generic_board_devices));
+}
+
+arch_initcall(generic_board_init);
diff --git a/arch/blackfin/mach-bf533/boards/stamp.c b/arch/blackfin/mach-bf533/boards/stamp.c
new file mode 100644
index 00000000000..d7b3a5d74e8
--- /dev/null
+++ b/arch/blackfin/mach-bf533/boards/stamp.c
@@ -0,0 +1,321 @@
+/*
+ * File: arch/blackfin/mach-bf533/stamp.c
+ * Based on: arch/blackfin/mach-bf533/ezkit.c
+ * Author: Aidan Williams <aidan@nicta.com.au>
+ *
+ * Created: 2005
+ * Description: Board Info File for the BF533-STAMP
+ *
+ * Modified:
+ * Copyright 2005 National ICT Australia (NICTA)
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
+#include <linux/usb_isp1362.h>
+#endif
+#include <asm/irq.h>
+#include <asm/bfin5xx_spi.h>
+
+/*
+ * Name the Board for the /proc/cpuinfo
+ */
+char *bfin_board_name = "ADDS-BF533-STAMP";
+
+#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
+static struct platform_device rtc_device = {
+ .name = "rtc-bfin",
+ .id = -1,
+};
+#endif
+
+/*
+ * Driver needs to know address, irq and flag pin.
+ */
+#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+static struct resource smc91x_resources[] = {
+ {
+ .name = "smc91x-regs",
+ .start = 0x20300300,
+ .end = 0x20300300 + 16,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = IRQ_PF7,
+ .end = IRQ_PF7,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ },
+};
+
+static struct platform_device smc91x_device = {
+ .name = "smc91x",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(smc91x_resources),
+ .resource = smc91x_resources,
+};
+#endif
+
+#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE)
+static struct resource net2272_bfin_resources[] = {
+ {
+ .start = 0x20300000,
+ .end = 0x20300000 + 0x100,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = IRQ_PF10,
+ .end = IRQ_PF10,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ },
+};
+
+static struct platform_device net2272_bfin_device = {
+ .name = "net2272",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(net2272_bfin_resources),
+ .resource = net2272_bfin_resources,
+};
+#endif
+
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+/* all SPI peripherals info goes here */
+
+#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
+static struct mtd_partition bfin_spi_flash_partitions[] = {
+ {
+ .name = "bootloader",
+ .size = 0x00020000,
+ .offset = 0,
+ .mask_flags = MTD_CAP_ROM
+ },{
+ .name = "kernel",
+ .size = 0xe0000,
+ .offset = 0x20000
+ },{
+ .name = "file system",
+ .size = 0x700000,
+ .offset = 0x00100000,
+ }
+};
+
+static struct flash_platform_data bfin_spi_flash_data = {
+ .name = "m25p80",
+ .parts = bfin_spi_flash_partitions,
+ .nr_parts = ARRAY_SIZE(bfin_spi_flash_partitions),
+ .type = "m25p64",
+};
+
+/* SPI flash chip (m25p64) */
+static struct bfin5xx_spi_chip spi_flash_chip_info = {
+ .enable_dma = 0, /* use dma transfer with this chip*/
+ .bits_per_word = 8,
+};
+#endif
+
+#if defined(CONFIG_SPI_ADC_BF533) || defined(CONFIG_SPI_ADC_BF533_MODULE)
+/* SPI ADC chip */
+static struct bfin5xx_spi_chip spi_adc_chip_info = {
+ .enable_dma = 1, /* use dma transfer with this chip*/
+ .bits_per_word = 16,
+};
+#endif
+
+#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
+ .enable_dma = 0,
+ .bits_per_word = 16,
+};
+#endif
+
+#if defined(CONFIG_PBX)
+static struct bfin5xx_spi_chip spi_si3xxx_chip_info = {
+ .ctl_reg = 0x4, /* send zero */
+ .enable_dma = 0,
+ .bits_per_word = 8,
+ .cs_change_per_word = 1,
+};
+#endif
+
+#if defined(CONFIG_AD5304) || defined(CONFIG_AD5304_MODULE)
+static struct bfin5xx_spi_chip ad5304_chip_info = {
+ .enable_dma = 0,
+ .bits_per_word = 16,
+};
+#endif
+
+static struct spi_board_info bfin_spi_board_info[] __initdata = {
+#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
+ {
+ /* the modalias must be the same as spi device driver name */
+ .modalias = "m25p80", /* Name of spi_driver for this device */
+ .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1, /* Framework bus number */
+ .chip_select = 2, /* Framework chip select. On STAMP537 it is SPISSEL2*/
+ .platform_data = &bfin_spi_flash_data,
+ .controller_data = &spi_flash_chip_info,
+ .mode = SPI_MODE_3,
+ },
+#endif
+
+#if defined(CONFIG_SPI_ADC_BF533) || defined(CONFIG_SPI_ADC_BF533_MODULE)
+ {
+ .modalias = "bfin_spi_adc", /* Name of spi_driver for this device */
+ .max_speed_hz = 6250000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1, /* Framework bus number */
+ .chip_select = 1, /* Framework chip select. */
+ .platform_data = NULL, /* No spi_driver specific config */
+ .controller_data = &spi_adc_chip_info,
+ },
+#endif
+
+#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+ {
+ .modalias = "ad1836-spi",
+ .max_speed_hz = 31250000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1,
+ .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT,
+ .controller_data = &ad1836_spi_chip_info,
+ },
+#endif
+
+#if defined(CONFIG_PBX)
+ {
+ .modalias = "fxs-spi",
+ .max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1,
+ .chip_select = 3,
+ .controller_data= &spi_si3xxx_chip_info,
+ .mode = SPI_MODE_3,
+ },
+ {
+ .modalias = "fxo-spi",
+ .max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1,
+ .chip_select = 2,
+ .controller_data= &spi_si3xxx_chip_info,
+ .mode = SPI_MODE_3,
+ },
+#endif
+
+#if defined(CONFIG_AD5304) || defined(CONFIG_AD5304_MODULE)
+ {
+ .modalias = "ad5304_spi",
+ .max_speed_hz = 1000000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1,
+ .chip_select = 2,
+ .platform_data = NULL,
+ .controller_data = &ad5304_chip_info,
+ .mode = SPI_MODE_2,
+ },
+#endif
+};
+
+/* SPI controller data */
+static struct bfin5xx_spi_master spi_bfin_master_info = {
+ .num_chipselect = 8,
+ .enable_dma = 1, /* master has the ability to do dma transfer */
+};
+
+static struct platform_device spi_bfin_master_device = {
+ .name = "bfin-spi-master",
+ .id = 1, /* Bus number */
+ .dev = {
+ .platform_data = &spi_bfin_master_info, /* Passed to driver */
+ },
+};
+#endif /* spi master and devices */
+
+#if defined(CONFIG_FB_BF537_LQ035) || defined(CONFIG_FB_BF537_LQ035_MODULE)
+static struct platform_device bfin_fb_device = {
+ .name = "bf537-fb",
+};
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
+static struct resource bfin_uart_resources[] = {
+ {
+ .start = 0xFFC00400,
+ .end = 0xFFC004FF,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device bfin_uart_device = {
+ .name = "bfin-uart",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(bfin_uart_resources),
+ .resource = bfin_uart_resources,
+};
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+static struct platform_device bfin_sport0_uart_device = {
+ .name = "bfin-sport-uart",
+ .id = 0,
+};
+
+static struct platform_device bfin_sport1_uart_device = {
+ .name = "bfin-sport-uart",
+ .id = 1,
+};
+#endif
+
+static struct platform_device *stamp_devices[] __initdata = {
+#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
+ &rtc_device,
+#endif
+
+#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+ &smc91x_device,
+#endif
+
+#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE)
+ &net2272_bfin_device,
+#endif
+
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+ &spi_bfin_master_device,
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
+ &bfin_uart_device,
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+ &bfin_sport0_uart_device,
+ &bfin_sport1_uart_device,
+#endif
+};
+
+static int __init stamp_init(void)
+{
+ printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__);
+ platform_add_devices(stamp_devices, ARRAY_SIZE(stamp_devices));
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+ spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info));
+#endif
+ return 0;
+}
+
+arch_initcall(stamp_init);
diff --git a/arch/blackfin/mach-bf533/cpu.c b/arch/blackfin/mach-bf533/cpu.c
new file mode 100644
index 00000000000..99547c4c290
--- /dev/null
+++ b/arch/blackfin/mach-bf533/cpu.c
@@ -0,0 +1,161 @@
+/*
+ * File: arch/blackfin/mach-bf533/cpu.c
+ * Based on:
+ * Author: michael.kang@analog.com
+ *
+ * Created:
+ * Description: clock scaling for the bf533
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/cpufreq.h>
+#include <asm/dpmc.h>
+#include <linux/fs.h>
+#include <asm/bfin-global.h>
+
+/* CONFIG_CLKIN_HZ=11059200 */
+#define VCO5 (CONFIG_CLKIN_HZ*45) /*497664000 */
+#define VCO4 (CONFIG_CLKIN_HZ*36) /*398131200 */
+#define VCO3 (CONFIG_CLKIN_HZ*27) /*298598400 */
+#define VCO2 (CONFIG_CLKIN_HZ*18) /*199065600 */
+#define VCO1 (CONFIG_CLKIN_HZ*9) /*99532800 */
+#define VCO(x) VCO##x
+
+#define FREQ(x) {VCO(x),VCO(x)/4},{VCO(x),VCO(x)/2},{VCO(x),VCO(x)}
+/* frequency */
+static struct cpufreq_frequency_table bf533_freq_table[] = {
+ FREQ(1),
+ FREQ(3),
+ {VCO4, VCO4 / 2}, {VCO4, VCO4},
+ FREQ(5),
+ {0, CPUFREQ_TABLE_END},
+};
+
+/*
+ * dpmc_fops->ioctl()
+ * static int dpmc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+ */
+static int bf533_getfreq(unsigned int cpu)
+{
+ unsigned long cclk_mhz, vco_mhz;
+
+ /* The driver only support single cpu */
+ if (cpu == 0)
+ dpmc_fops.ioctl(NULL, NULL, IOCTL_GET_CORECLOCK, &cclk_mhz);
+ else
+ cclk_mhz = -1;
+ return cclk_mhz;
+}
+
+static int bf533_target(struct cpufreq_policy *policy,
+ unsigned int target_freq, unsigned int relation)
+{
+ unsigned long cclk_mhz;
+ unsigned long vco_mhz;
+ unsigned long flags;
+ unsigned int index, vco_index;
+ int i;
+
+ struct cpufreq_freqs freqs;
+ if (cpufreq_frequency_table_target
+ (policy, bf533_freq_table, target_freq, relation, &index))
+ return -EINVAL;
+ cclk_mhz = bf533_freq_table[index].frequency;
+ vco_mhz = bf533_freq_table[index].index;
+
+ dpmc_fops.ioctl(NULL, NULL, IOCTL_CHANGE_FREQUENCY, &vco_mhz);
+ freqs.old = bf533_getfreq(0);
+ freqs.new = cclk_mhz;
+ freqs.cpu = 0;
+
+ pr_debug("cclk begin change to cclk %d,vco=%d,index=%d,target=%d,oldfreq=%d\n",
+ cclk_mhz, vco_mhz, index, target_freq, freqs.old);
+
+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+ local_irq_save(flags);
+ dpmc_fops.ioctl(NULL, NULL, IOCTL_SET_CCLK, &cclk_mhz);
+ local_irq_restore(flags);
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+
+ vco_mhz = get_vco();
+ cclk_mhz = get_cclk();
+ return 0;
+}
+
+/* make sure that only the "userspace" governor is run -- anything else wouldn't make sense on
+ * this platform, anyway.
+ */
+static int bf533_verify_speed(struct cpufreq_policy *policy)
+{
+ return cpufreq_frequency_table_verify(policy, &bf533_freq_table);
+}
+
+static int __init __bf533_cpu_init(struct cpufreq_policy *policy)
+{
+ int result;
+
+ if (policy->cpu != 0)
+ return -EINVAL;
+
+ policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
+
+ policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
+ /*Now ,only support one cpu */
+ policy->cur = bf533_getfreq(0);
+ cpufreq_frequency_table_get_attr(bf533_freq_table, policy->cpu);
+ return cpufreq_frequency_table_cpuinfo(policy, bf533_freq_table);
+}
+
+static struct freq_attr *bf533_freq_attr[] = {
+ &cpufreq_freq_attr_scaling_available_freqs,
+ NULL,
+};
+
+static struct cpufreq_driver bf533_driver = {
+ .verify = bf533_verify_speed,
+ .target = bf533_target,
+ .get = bf533_getfreq,
+ .init = __bf533_cpu_init,
+ .name = "bf533",
+ .owner = THIS_MODULE,
+ .attr = bf533_freq_attr,
+};
+
+static int __init bf533_cpu_init(void)
+{
+ return cpufreq_register_driver(&bf533_driver);
+}
+
+static void __exit bf533_cpu_exit(void)
+{
+ cpufreq_unregister_driver(&bf533_driver);
+}
+
+MODULE_AUTHOR("Mickael Kang");
+MODULE_DESCRIPTION("cpufreq driver for BF533 CPU");
+MODULE_LICENSE("GPL");
+
+module_init(bf533_cpu_init);
+module_exit(bf533_cpu_exit);
diff --git a/arch/blackfin/mach-bf533/head.S b/arch/blackfin/mach-bf533/head.S
new file mode 100644
index 00000000000..4808edb0680
--- /dev/null
+++ b/arch/blackfin/mach-bf533/head.S
@@ -0,0 +1,774 @@
+/*
+ * File: arch/blackfin/mach-bf533/head.S
+ * Based on:
+ * Author: Jeff Dionne <jeff@uclinux.org> COPYRIGHT 1998 D. Jeff Dionne
+ *
+ * Created: 1998
+ * Description: bf533 startup file
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/linkage.h>
+#include <asm/blackfin.h>
+#if CONFIG_BFIN_KERNEL_CLOCK
+#include <asm/mach/mem_init.h>
+#endif
+#if CONFIG_DEBUG_KERNEL_START
+#include <asm/mach-common/def_LPBlackfin.h>
+#endif
+
+.global __rambase
+.global __ramstart
+.global __ramend
+.extern ___bss_stop
+.extern ___bss_start
+.extern _bf53x_relocate_l1_mem
+
+#define INITIAL_STACK 0xFFB01000
+
+.text
+
+ENTRY(__start)
+ENTRY(__stext)
+ /* R0: argument of command line string, passed from uboot, save it */
+ R7 = R0;
+ /* Set the SYSCFG register */
+ R0 = 0x36;
+ /*Enable Cycle Counter and Nesting Of Interrupts(3rd Bit)*/
+ SYSCFG = R0;
+ R0 = 0;
+
+ /*Clear Out All the data and pointer Registers*/
+ R1 = R0;
+ R2 = R0;
+ R3 = R0;
+ R4 = R0;
+ R5 = R0;
+ R6 = R0;
+
+ P0 = R0;
+ P1 = R0;
+ P2 = R0;
+ P3 = R0;
+ P4 = R0;
+ P5 = R0;
+
+ LC0 = r0;
+ LC1 = r0;
+ L0 = r0;
+ L1 = r0;
+ L2 = r0;
+ L3 = r0;
+
+ /* Clear Out All the DAG Registers*/
+ B0 = r0;
+ B1 = r0;
+ B2 = r0;
+ B3 = r0;
+
+ I0 = r0;
+ I1 = r0;
+ I2 = r0;
+ I3 = r0;
+
+ M0 = r0;
+ M1 = r0;
+ M2 = r0;
+ M3 = r0;
+
+#if CONFIG_DEBUG_KERNEL_START
+
+/*
+ * Set up a temporary Event Vector Table, so if something bad happens before
+ * the kernel is fully started, it doesn't vector off into the bootloaders
+ * table
+ */
+ P0.l = lo(EVT2);
+ P0.h = hi(EVT2);
+ P1.l = lo(EVT15);
+ P1.h = hi(EVT15);
+ P2.l = debug_kernel_start_trap;
+ P2.h = debug_kernel_start_trap;
+
+ RTS = P2;
+ RTI = P2;
+ RTX = P2;
+ RTN = P2;
+ RTE = P2;
+
+.Lfill_temp_vector_table:
+ [P0++] = P2; /* Core Event Vector Table */
+ CC = P0 == P1;
+ if !CC JUMP .Lfill_temp_vector_table
+ P0 = r0;
+ P1 = r0;
+ P2 = r0;
+
+#endif
+
+ p0.h = hi(FIO_MASKA_C);
+ p0.l = lo(FIO_MASKA_C);
+ r0 = 0xFFFF(Z);
+ w[p0] = r0.L; /* Disable all interrupts */
+ ssync;
+
+ p0.h = hi(FIO_MASKB_C);
+ p0.l = lo(FIO_MASKB_C);
+ r0 = 0xFFFF(Z);
+ w[p0] = r0.L; /* Disable all interrupts */
+ ssync;
+
+ /* Turn off the icache */
+ p0.l = (IMEM_CONTROL & 0xFFFF);
+ p0.h = (IMEM_CONTROL >> 16);
+ R1 = [p0];
+ R0 = ~ENICPLB;
+ R0 = R0 & R1;
+
+ /* Anomaly 05000125 */
+#ifdef ANOMALY_05000125
+ CLI R2;
+ SSYNC;
+#endif
+ [p0] = R0;
+ SSYNC;
+#ifdef ANOMALY_05000125
+ STI R2;
+#endif
+
+ /* Turn off the dcache */
+ p0.l = (DMEM_CONTROL & 0xFFFF);
+ p0.h = (DMEM_CONTROL >> 16);
+ R1 = [p0];
+ R0 = ~ENDCPLB;
+ R0 = R0 & R1;
+
+ /* Anomaly 05000125 */
+#ifdef ANOMALY_05000125
+ CLI R2;
+ SSYNC;
+#endif
+ [p0] = R0;
+ SSYNC;
+#ifdef ANOMALY_05000125
+ STI R2;
+#endif
+
+ /* Initialise UART */
+ p0.h = hi(UART_LCR);
+ p0.l = lo(UART_LCR);
+ r0 = 0x0(Z);
+ w[p0] = r0.L; /* To enable DLL writes */
+ ssync;
+
+ p0.h = hi(UART_DLL);
+ p0.l = lo(UART_DLL);
+ r0 = 0x0(Z);
+ w[p0] = r0.L;
+ ssync;
+
+ p0.h = hi(UART_DLH);
+ p0.l = lo(UART_DLH);
+ r0 = 0x00(Z);
+ w[p0] = r0.L;
+ ssync;
+
+ p0.h = hi(UART_GCTL);
+ p0.l = lo(UART_GCTL);
+ r0 = 0x0(Z);
+ w[p0] = r0.L; /* To enable UART clock */
+ ssync;
+
+ /* Initialize stack pointer */
+ sp.l = lo(INITIAL_STACK);
+ sp.h = hi(INITIAL_STACK);
+ fp = sp;
+ usp = sp;
+
+ /* Put The Code for PLL Programming and SDRAM Programming in L1 ISRAM */
+ call _bf53x_relocate_l1_mem;
+#if CONFIG_BFIN_KERNEL_CLOCK
+ call _start_dma_code;
+#endif
+
+ /* Code for initializing Async memory banks */
+
+ p2.h = hi(EBIU_AMBCTL1);
+ p2.l = lo(EBIU_AMBCTL1);
+ r0.h = hi(AMBCTL1VAL);
+ r0.l = lo(AMBCTL1VAL);
+ [p2] = r0;
+ ssync;
+
+ p2.h = hi(EBIU_AMBCTL0);
+ p2.l = lo(EBIU_AMBCTL0);
+ r0.h = hi(AMBCTL0VAL);
+ r0.l = lo(AMBCTL0VAL);
+ [p2] = r0;
+ ssync;
+
+ p2.h = hi(EBIU_AMGCTL);
+ p2.l = lo(EBIU_AMGCTL);
+ r0 = AMGCTLVAL;
+ w[p2] = r0;
+ ssync;
+
+ /* This section keeps the processor in supervisor mode
+ * during kernel boot. Switches to user mode at end of boot.
+ * See page 3-9 of Hardware Reference manual for documentation.
+ */
+
+ /* EVT15 = _real_start */
+
+ p0.l = lo(EVT15);
+ p0.h = hi(EVT15);
+ p1.l = _real_start;
+ p1.h = _real_start;
+ [p0] = p1;
+ csync;
+
+ p0.l = lo(IMASK);
+ p0.h = hi(IMASK);
+ p1.l = IMASK_IVG15;
+ p1.h = 0x0;
+ [p0] = p1;
+ csync;
+
+ raise 15;
+ p0.l = .LWAIT_HERE;
+ p0.h = .LWAIT_HERE;
+ reti = p0;
+#if defined(ANOMALY_05000281)
+ nop; nop; nop;
+#endif
+ rti;
+
+.LWAIT_HERE:
+ jump .LWAIT_HERE;
+
+ENTRY(_real_start)
+ [ -- sp ] = reti;
+ p0.l = lo(WDOG_CTL);
+ p0.h = hi(WDOG_CTL);
+ r0 = 0xAD6(z);
+ w[p0] = r0; /* watchdog off for now */
+ ssync;
+
+ /* Code update for BSS size == 0
+ * Zero out the bss region.
+ */
+
+ p1.l = ___bss_start;
+ p1.h = ___bss_start;
+ p2.l = ___bss_stop;
+ p2.h = ___bss_stop;
+ r0 = 0;
+ p2 -= p1;
+ lsetup (.L_clear_bss, .L_clear_bss) lc0 = p2;
+.L_clear_bss:
+ B[p1++] = r0;
+
+ /* In case there is a NULL pointer reference
+ * Zero out region before stext
+ */
+
+ p1.l = 0x0;
+ p1.h = 0x0;
+ r0.l = __stext;
+ r0.h = __stext;
+ r0 = r0 >> 1;
+ p2 = r0;
+ r0 = 0;
+ lsetup (.L_clear_zero, .L_clear_zero) lc0 = p2;
+.L_clear_zero:
+ W[p1++] = r0;
+
+/* pass the uboot arguments to the global value command line */
+ R0 = R7;
+ call _cmdline_init;
+
+ p1.l = __rambase;
+ p1.h = __rambase;
+ r0.l = __sdata;
+ r0.h = __sdata;
+ [p1] = r0;
+
+ p1.l = __ramstart;
+ p1.h = __ramstart;
+ p3.l = ___bss_stop;
+ p3.h = ___bss_stop;
+
+ r1 = p3;
+ [p1] = r1;
+
+ /*
+ * load the current thread pointer and stack
+ */
+ r1.l = _init_thread_union;
+ r1.h = _init_thread_union;
+
+ r2.l = 0x2000;
+ r2.h = 0x0000;
+ r1 = r1 + r2;
+ sp = r1;
+ usp = sp;
+ fp = sp;
+ call _start_kernel;
+.L_exit:
+ jump.s .L_exit;
+
+.section .l1.text
+#if CONFIG_BFIN_KERNEL_CLOCK
+ENTRY(_start_dma_code)
+ p0.h = hi(SIC_IWR);
+ p0.l = lo(SIC_IWR);
+ r0.l = 0x1;
+ r0.h = 0x0;
+ [p0] = r0;
+ SSYNC;
+
+ /*
+ * Set PLL_CTL
+ * - [14:09] = MSEL[5:0] : CLKIN / VCO multiplication factors
+ * - [8] = BYPASS : BYPASS the PLL, run CLKIN into CCLK/SCLK
+ * - [7] = output delay (add 200ps of delay to mem signals)
+ * - [6] = input delay (add 200ps of input delay to mem signals)
+ * - [5] = PDWN : 1=All Clocks off
+ * - [3] = STOPCK : 1=Core Clock off
+ * - [1] = PLL_OFF : 1=Disable Power to PLL
+ * - [0] = DF : 1=Pass CLKIN/2 to PLL / 0=Pass CLKIN to PLL
+ * all other bits set to zero
+ */
+
+ p0.h = hi(PLL_LOCKCNT);
+ p0.l = lo(PLL_LOCKCNT);
+ r0 = 0x300(Z);
+ w[p0] = r0.l;
+ ssync;
+
+ P2.H = hi(EBIU_SDGCTL);
+ P2.L = lo(EBIU_SDGCTL);
+ R0 = [P2];
+ BITSET (R0, 24);
+ [P2] = R0;
+ SSYNC;
+
+ r0 = CONFIG_VCO_MULT & 63; /* Load the VCO multiplier */
+ r0 = r0 << 9; /* Shift it over, */
+ r1 = CLKIN_HALF; /* Do we need to divide CLKIN by 2?*/
+ r0 = r1 | r0;
+ r1 = PLL_BYPASS; /* Bypass the PLL? */
+ r1 = r1 << 8; /* Shift it over */
+ r0 = r1 | r0; /* add them all together */
+
+ p0.h = hi(PLL_CTL);
+ p0.l = lo(PLL_CTL); /* Load the address */
+ cli r2; /* Disable interrupts */
+ ssync;
+ w[p0] = r0.l; /* Set the value */
+ idle; /* Wait for the PLL to stablize */
+ sti r2; /* Enable interrupts */
+
+.Lcheck_again:
+ p0.h = hi(PLL_STAT);
+ p0.l = lo(PLL_STAT);
+ R0 = W[P0](Z);
+ CC = BITTST(R0,5);
+ if ! CC jump .Lcheck_again;
+
+ /* Configure SCLK & CCLK Dividers */
+ r0 = (CONFIG_CCLK_ACT_DIV | CONFIG_SCLK_DIV);
+ p0.h = hi(PLL_DIV);
+ p0.l = lo(PLL_DIV);
+ w[p0] = r0.l;
+ ssync;
+
+ p0.l = lo(EBIU_SDRRC);
+ p0.h = hi(EBIU_SDRRC);
+ r0 = mem_SDRRC;
+ w[p0] = r0.l;
+ ssync;
+
+ p0.l = (EBIU_SDBCTL & 0xFFFF);
+ p0.h = (EBIU_SDBCTL >> 16); /* SDRAM Memory Bank Control Register */
+ r0 = mem_SDBCTL;
+ w[p0] = r0.l;
+ ssync;
+
+ P2.H = hi(EBIU_SDGCTL);
+ P2.L = lo(EBIU_SDGCTL);
+ R0 = [P2];
+ BITCLR (R0, 24);
+ p0.h = hi(EBIU_SDSTAT);
+ p0.l = lo(EBIU_SDSTAT);
+ r2.l = w[p0];
+ cc = bittst(r2,3);
+ if !cc jump .Lskip;
+ NOP;
+ BITSET (R0, 23);
+.Lskip:
+ [P2] = R0;
+ SSYNC;
+
+ R0.L = lo(mem_SDGCTL);
+ R0.H = hi(mem_SDGCTL);
+ R1 = [p2];
+ R1 = R1 | R0;
+ [P2] = R1;
+ SSYNC;
+
+ p0.h = hi(SIC_IWR);
+ p0.l = lo(SIC_IWR);
+ r0.l = lo(IWR_ENABLE_ALL)
+ r0.h = hi(IWR_ENABLE_ALL)
+ [p0] = r0;
+ SSYNC;
+
+ RTS;
+#endif /* CONFIG_BFIN_KERNEL_CLOCK */
+
+ENTRY(_bfin_reset)
+ /* No more interrupts to be handled*/
+ CLI R6;
+ SSYNC;
+
+#if defined(CONFIG_BFIN_SHARED_FLASH_ENET)
+ p0.h = hi(FIO_INEN);
+ p0.l = lo(FIO_INEN);
+ r0.l = ~(1 << CONFIG_ENET_FLASH_PIN);
+ w[p0] = r0.l;
+
+ p0.h = hi(FIO_DIR);
+ p0.l = lo(FIO_DIR);
+ r0.l = (1 << CONFIG_ENET_FLASH_PIN);
+ w[p0] = r0.l;
+
+ p0.h = hi(FIO_FLAG_C);
+ p0.l = lo(FIO_FLAG_C);
+ r0.l = (1 << CONFIG_ENET_FLASH_PIN);
+ w[p0] = r0.l;
+#endif
+
+ /* Clear the bits 13-15 in SWRST if they werent cleared */
+ p0.h = hi(SWRST);
+ p0.l = lo(SWRST);
+ csync;
+ r0.l = w[p0];
+
+ /* Clear the IMASK register */
+ p0.h = hi(IMASK);
+ p0.l = lo(IMASK);
+ r0 = 0x0;
+ [p0] = r0;
+
+ /* Clear the ILAT register */
+ p0.h = hi(ILAT);
+ p0.l = lo(ILAT);
+ r0 = [p0];
+ [p0] = r0;
+ SSYNC;
+
+ /* Disable the WDOG TIMER */
+ p0.h = hi(WDOG_CTL);
+ p0.l = lo(WDOG_CTL);
+ r0.l = 0xAD6;
+ w[p0] = r0.l;
+ SSYNC;
+
+ /* Clear the sticky bit incase it is already set */
+ p0.h = hi(WDOG_CTL);
+ p0.l = lo(WDOG_CTL);
+ r0.l = 0x8AD6;
+ w[p0] = r0.l;
+ SSYNC;
+
+ /* Program the count value */
+ R0.l = 0x100;
+ R0.h = 0x0;
+ P0.h = hi(WDOG_CNT);
+ P0.l = lo(WDOG_CNT);
+ [P0] = R0;
+ SSYNC;
+
+ /* Program WDOG_STAT if necessary */
+ P0.h = hi(WDOG_CTL);
+ P0.l = lo(WDOG_CTL);
+ R0 = W[P0](Z);
+ CC = BITTST(R0,1);
+ if !CC JUMP .LWRITESTAT;
+ CC = BITTST(R0,2);
+ if !CC JUMP .LWRITESTAT;
+ JUMP .LSKIP_WRITE;
+
+.LWRITESTAT:
+ /* When watch dog timer is enabled, a write to STAT will load the contents of CNT to STAT */
+ R0 = 0x0000(z);
+ P0.h = hi(WDOG_STAT);
+ P0.l = lo(WDOG_STAT)
+ [P0] = R0;
+ SSYNC;
+
+.LSKIP_WRITE:
+ /* Enable the reset event */
+ P0.h = hi(WDOG_CTL);
+ P0.l = lo(WDOG_CTL);
+ R0 = W[P0](Z);
+ BITCLR(R0,1);
+ BITCLR(R0,2);
+ W[P0] = R0.L;
+ SSYNC;
+ NOP;
+
+ /* Enable the wdog counter */
+ R0 = W[P0](Z);
+ BITCLR(R0,4);
+ W[P0] = R0.L;
+ SSYNC;
+
+ IDLE;
+
+ RTS;
+
+#if CONFIG_DEBUG_KERNEL_START
+debug_kernel_start_trap:
+ /* Set up a temp stack in L1 - SDRAM might not be working */
+ P0.L = lo(L1_DATA_A_START + 0x100);
+ P0.H = hi(L1_DATA_A_START + 0x100);
+ SP = P0;
+
+ /* Make sure the Clocks are the way I think they should be */
+ r0 = CONFIG_VCO_MULT & 63; /* Load the VCO multiplier */
+ r0 = r0 << 9; /* Shift it over, */
+ r1 = CLKIN_HALF; /* Do we need to divide CLKIN by 2?*/
+ r0 = r1 | r0;
+ r1 = PLL_BYPASS; /* Bypass the PLL? */
+ r1 = r1 << 8; /* Shift it over */
+ r0 = r1 | r0; /* add them all together */
+
+ p0.h = hi(PLL_CTL);
+ p0.l = lo(PLL_CTL); /* Load the address */
+ cli r2; /* Disable interrupts */
+ ssync;
+ w[p0] = r0.l; /* Set the value */
+ idle; /* Wait for the PLL to stablize */
+ sti r2; /* Enable interrupts */
+
+.Lcheck_again1:
+ p0.h = hi(PLL_STAT);
+ p0.l = lo(PLL_STAT);
+ R0 = W[P0](Z);
+ CC = BITTST(R0,5);
+ if ! CC jump .Lcheck_again1;
+
+ /* Configure SCLK & CCLK Dividers */
+ r0 = (CONFIG_CCLK_ACT_DIV | CONFIG_SCLK_DIV);
+ p0.h = hi(PLL_DIV);
+ p0.l = lo(PLL_DIV);
+ w[p0] = r0.l;
+ ssync;
+
+ /* Make sure UART is enabled - you can never be sure */
+
+/*
+ * Setup for console. Argument comes from the menuconfig
+ */
+
+#ifdef CONFIG_BAUD_9600
+#define CONSOLE_BAUD_RATE 9600
+#elif CONFIG_BAUD_19200
+#define CONSOLE_BAUD_RATE 19200
+#elif CONFIG_BAUD_38400
+#define CONSOLE_BAUD_RATE 38400
+#elif CONFIG_BAUD_57600
+#define CONSOLE_BAUD_RATE 57600
+#elif CONFIG_BAUD_115200
+#define CONSOLE_BAUD_RATE 115200
+#endif
+
+ p0.h = hi(UART_GCTL);
+ p0.l = lo(UART_GCTL);
+ r0 = 0x00(Z);
+ w[p0] = r0.L; /* To Turn off UART clocks */
+ ssync;
+
+ p0.h = hi(UART_LCR);
+ p0.l = lo(UART_LCR);
+ r0 = 0x83(Z);
+ w[p0] = r0.L; /* To enable DLL writes */
+ ssync;
+
+ R1 = (((CONFIG_CLKIN_HZ * CONFIG_VCO_MULT) / CONFIG_SCLK_DIV) / (CONSOLE_BAUD_RATE * 16));
+
+ p0.h = hi(UART_DLL);
+ p0.l = lo(UART_DLL);
+ r0 = 0xFF(Z);
+ r0 = R1 & R0;
+ w[p0] = r0.L;
+ ssync;
+
+ p0.h = hi(UART_DLH);
+ p0.l = lo(UART_DLH);
+ r1 >>= 8 ;
+ w[p0] = r1.L;
+ ssync;
+
+ p0.h = hi(UART_GCTL);
+ p0.l = lo(UART_GCTL);
+ r0 = 0x0(Z);
+ w[p0] = r0.L; /* To enable UART clock */
+ ssync;
+
+ p0.h = hi(UART_LCR);
+ p0.l = lo(UART_LCR);
+ r0 = 0x03(Z);
+ w[p0] = r0.L; /* To Turn on UART */
+ ssync;
+
+ p0.h = hi(UART_GCTL);
+ p0.l = lo(UART_GCTL);
+ r0 = 0x01(Z);
+ w[p0] = r0.L; /* To Turn on UART Clocks */
+ ssync;
+
+ P0.h = hi(UART_THR);
+ P0.l = lo(UART_THR);
+ P1.h = hi(UART_LSR);
+ P1.l = lo(UART_LSR);
+
+ R0.L = 'K';
+ call .Lwait_char;
+ R0.L='e';
+ call .Lwait_char;
+ R0.L='r';
+ call .Lwait_char;
+ R0.L='n'
+ call .Lwait_char;
+ R0.L='e'
+ call .Lwait_char;
+ R0.L='l';
+ call .Lwait_char;
+ R0.L=' ';
+ call .Lwait_char;
+ R0.L='c';
+ call .Lwait_char;
+ R0.L='r';
+ call .Lwait_char;
+ R0.L='a';
+ call .Lwait_char;
+ R0.L='s';
+ call .Lwait_char;
+ R0.L='h';
+ call .Lwait_char;
+ R0.L='\r';
+ call .Lwait_char;
+ R0.L='\n';
+ call .Lwait_char;
+
+ R0.L='S';
+ call .Lwait_char;
+ R0.L='E';
+ call .Lwait_char;
+ R0.L='Q'
+ call .Lwait_char;
+ R0.L='S'
+ call .Lwait_char;
+ R0.L='T';
+ call .Lwait_char;
+ R0.L='A';
+ call .Lwait_char;
+ R0.L='T';
+ call .Lwait_char;
+ R0.L='=';
+ call .Lwait_char;
+ R2 = SEQSTAT;
+ call .Ldump_reg;
+
+ R0.L=' ';
+ call .Lwait_char;
+ R0.L='R';
+ call .Lwait_char;
+ R0.L='E'
+ call .Lwait_char;
+ R0.L='T'
+ call .Lwait_char;
+ R0.L='X';
+ call .Lwait_char;
+ R0.L='=';
+ call .Lwait_char;
+ R2 = RETX;
+ call .Ldump_reg;
+
+ R0.L='\r';
+ call .Lwait_char;
+ R0.L='\n';
+ call .Lwait_char;
+
+.Ldebug_kernel_start_trap_done:
+ JUMP .Ldebug_kernel_start_trap_done;
+.Ldump_reg:
+ R3 = 32;
+ R4 = 0x0F;
+ R5 = ':'; /* one past 9 */
+
+.Ldump_reg2:
+ R0 = R2;
+ R3 += -4;
+ R0 >>>= R3;
+ R0 = R0 & R4;
+ R0 += 0x30;
+ CC = R0 <= R5;
+ if CC JUMP .Ldump_reg1;
+ R0 += 7;
+
+.Ldump_reg1:
+ R1.l = W[P1];
+ CC = BITTST(R1, 5);
+ if !CC JUMP .Ldump_reg1;
+ W[P0] = r0;
+
+ CC = R3 == 0;
+ if !CC JUMP .Ldump_reg2
+ RTS;
+
+.Lwait_char:
+ R1.l = W[P1];
+ CC = BITTST(R1, 5);
+ if !CC JUMP .Lwait_char;
+ W[P0] = r0;
+ RTS;
+
+#endif /* CONFIG_DEBUG_KERNEL_START */
+
+.data
+
+/*
+ * Set up the usable of RAM stuff. Size of RAM is determined then
+ * an initial stack set up at the end.
+ */
+
+.align 4
+__rambase:
+.long 0
+__ramstart:
+.long 0
+__ramend:
+.long 0
diff --git a/arch/blackfin/mach-bf533/ints-priority.c b/arch/blackfin/mach-bf533/ints-priority.c
new file mode 100644
index 00000000000..36a69334520
--- /dev/null
+++ b/arch/blackfin/mach-bf533/ints-priority.c
@@ -0,0 +1,65 @@
+/*
+ * File: arch/blackfin/mach-bf533/ints-priority.c
+ * Based on:
+ * Author: Michael Hennerich
+ *
+ * Created: ?
+ * Description: Set up the interupt priorities
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/module.h>
+#include <asm/blackfin.h>
+#include <asm/irq.h>
+
+void program_IAR(void)
+{
+ /* Program the IAR0 Register with the configured priority */
+ bfin_write_SIC_IAR0(((CONFIG_PLLWAKE_ERROR - 7) << PLLWAKE_ERROR_POS) |
+ ((CONFIG_DMA_ERROR - 7) << DMA_ERROR_POS) |
+ ((CONFIG_PPI_ERROR - 7) << PPI_ERROR_POS) |
+ ((CONFIG_SPORT0_ERROR - 7) << SPORT0_ERROR_POS) |
+ ((CONFIG_SPI_ERROR - 7) << SPI_ERROR_POS) |
+ ((CONFIG_SPORT1_ERROR - 7) << SPORT1_ERROR_POS) |
+ ((CONFIG_UART_ERROR - 7) << UART_ERROR_POS) |
+ ((CONFIG_RTC_ERROR - 7) << RTC_ERROR_POS));
+
+ bfin_write_SIC_IAR1(((CONFIG_DMA0_PPI - 7) << DMA0_PPI_POS) |
+ ((CONFIG_DMA1_SPORT0RX - 7) << DMA1_SPORT0RX_POS) |
+ ((CONFIG_DMA2_SPORT0TX - 7) << DMA2_SPORT0TX_POS) |
+ ((CONFIG_DMA3_SPORT1RX - 7) << DMA3_SPORT1RX_POS) |
+ ((CONFIG_DMA4_SPORT1TX - 7) << DMA4_SPORT1TX_POS) |
+ ((CONFIG_DMA5_SPI - 7) << DMA5_SPI_POS) |
+ ((CONFIG_DMA6_UARTRX - 7) << DMA6_UARTRX_POS) |
+ ((CONFIG_DMA7_UARTTX - 7) << DMA7_UARTTX_POS));
+
+ bfin_write_SIC_IAR2(((CONFIG_TIMER0 - 7) << TIMER0_POS) |
+ ((CONFIG_TIMER1 - 7) << TIMER1_POS) |
+ ((CONFIG_TIMER2 - 7) << TIMER2_POS) |
+ ((CONFIG_PFA - 7) << PFA_POS) |
+ ((CONFIG_PFB - 7) << PFB_POS) |
+ ((CONFIG_MEMDMA0 - 7) << MEMDMA0_POS) |
+ ((CONFIG_MEMDMA1 - 7) << MEMDMA1_POS) |
+ ((CONFIG_WDTIMER - 7) << WDTIMER_POS));
+
+ SSYNC();
+}
diff --git a/arch/blackfin/mach-bf537/Kconfig b/arch/blackfin/mach-bf537/Kconfig
new file mode 100644
index 00000000000..cc9ae38a4dd
--- /dev/null
+++ b/arch/blackfin/mach-bf537/Kconfig
@@ -0,0 +1,141 @@
+if (BF537 || BF534 || BF536)
+
+menu "BF537 Specific Configuration"
+
+comment "PORT F/G Selection"
+choice
+ prompt "Select BF537/6/4 default GPIO PFx PORTx"
+ help
+ Quick Hack for BF537/6/4 default GPIO PFx PORTF.
+
+config BF537_PORT_F
+ bool "Select BF537/6/4 default GPIO PFx PORTF"
+ depends on (BF537 || BF536 || BF534)
+ help
+ Quick Hack for BF537/6/4 default GPIO PFx PORTF.
+
+config BF537_PORT_G
+ bool "Select BF537/6/4 default GPIO PFx PORTG"
+ depends on (BF537 || BF536 || BF534)
+ help
+ Quick Hack for BF537/6/4 default GPIO PFx PORTG.
+
+config BF537_PORT_H
+ bool "Select BF537/6/4 default GPIO PFx PORTH"
+ depends on (BF537 || BF536 || BF534)
+ help
+ Quick Hack for BF537/6/4 default GPIO PFx PORTH
+ Use only when Blackfin EMAC support is not required.
+
+endchoice
+
+comment "Interrupt Priority Assignment"
+menu "Priority"
+
+config IRQ_PLL_WAKEUP
+ int "IRQ_PLL_WAKEUP"
+ default 7
+config IRQ_DMA_ERROR
+ int "IRQ_DMA_ERROR Generic"
+ default 7
+config IRQ_ERROR
+ int "IRQ_ERROR: CAN MAC SPORT0 SPORT1 SPI UART0 UART1"
+ default 7
+config IRQ_RTC
+ int "IRQ_RTC"
+ default 8
+config IRQ_PPI
+ int "IRQ_PPI"
+ default 8
+config IRQ_SPORT0_RX
+ int "IRQ_SPORT0_RX"
+ default 9
+config IRQ_SPORT0_TX
+ int "IRQ_SPORT0_TX"
+ default 9
+config IRQ_SPORT1_RX
+ int "IRQ_SPORT1_RX"
+ default 9
+config IRQ_SPORT1_TX
+ int "IRQ_SPORT1_TX"
+ default 9
+config IRQ_TWI
+ int "IRQ_TWI"
+ default 10
+config IRQ_SPI
+ int "IRQ_SPI"
+ default 10
+config IRQ_UART0_RX
+ int "IRQ_UART0_RX"
+ default 10
+config IRQ_UART0_TX
+ int "IRQ_UART0_TX"
+ default 10
+config IRQ_UART1_RX
+ int "IRQ_UART1_RX"
+ default 10
+config IRQ_UART1_TX
+ int "IRQ_UART1_TX"
+ default 10
+config IRQ_CAN_RX
+ int "IRQ_CAN_RX"
+ default 11
+config IRQ_CAN_TX
+ int "IRQ_CAN_TX"
+ default 11
+config IRQ_MAC_RX
+ int "IRQ_MAC_RX"
+ default 11
+config IRQ_MAC_TX
+ int "IRQ_MAC_TX"
+ default 11
+config IRQ_TMR0
+ int "IRQ_TMR0"
+ default 12
+config IRQ_TMR1
+ int "IRQ_TMR1"
+ default 12
+config IRQ_TMR2
+ int "IRQ_TMR2"
+ default 12
+config IRQ_TMR3
+ int "IRQ_TMR3"
+ default 12
+config IRQ_TMR4
+ int "IRQ_TMR4"
+ default 12
+config IRQ_TMR5
+ int "IRQ_TMR5"
+ default 12
+config IRQ_TMR6
+ int "IRQ_TMR6"
+ default 12
+config IRQ_TMR7
+ int "IRQ_TMR7"
+ default 12
+config IRQ_PROG_INTA
+ int "IRQ_PROG_INTA"
+ default 12
+config IRQ_PORTG_INTB
+ int "IRQ_PORTG_INTB"
+ default 12
+config IRQ_MEM_DMA0
+ int "IRQ_MEM_DMA0"
+ default 13
+config IRQ_MEM_DMA1
+ int "IRQ_MEM_DMA1"
+ default 13
+config IRQ_WATCH
+ int "IRQ_WATCH"
+ default 13
+
+ help
+ Enter the priority numbers between 7-13 ONLY. Others are Reserved.
+ This applies to all the above. It is not recommended to assign the
+ highest priority number 7 to UART or any other device.
+
+endmenu
+
+endmenu
+
+endif
diff --git a/arch/blackfin/mach-bf537/Makefile b/arch/blackfin/mach-bf537/Makefile
new file mode 100644
index 00000000000..f32d44215bb
--- /dev/null
+++ b/arch/blackfin/mach-bf537/Makefile
@@ -0,0 +1,9 @@
+#
+# arch/blackfin/mach-bf537/Makefile
+#
+
+extra-y := head.o
+
+obj-y := ints-priority.o
+
+obj-$(CONFIG_CPU_FREQ) += cpu.o
diff --git a/arch/blackfin/mach-bf537/boards/Makefile b/arch/blackfin/mach-bf537/boards/Makefile
new file mode 100644
index 00000000000..23323cacc3a
--- /dev/null
+++ b/arch/blackfin/mach-bf537/boards/Makefile
@@ -0,0 +1,9 @@
+#
+# arch/blackfin/mach-bf537/boards/Makefile
+#
+
+obj-y += eth_mac.o
+obj-$(CONFIG_GENERIC_BOARD) += generic_board.o
+obj-$(CONFIG_BFIN537_STAMP) += stamp.o led.o
+obj-$(CONFIG_BFIN537_BLUETECHNIX_CM) += cm_bf537.o
+obj-$(CONFIG_PNAV10) += pnav10.o
diff --git a/arch/blackfin/mach-bf537/boards/cm_bf537.c b/arch/blackfin/mach-bf537/boards/cm_bf537.c
new file mode 100644
index 00000000000..6a60618a78e
--- /dev/null
+++ b/arch/blackfin/mach-bf537/boards/cm_bf537.c
@@ -0,0 +1,364 @@
+/*
+ * File: arch/blackfin/mach-bf537/boards/cm_bf537.c
+ * Based on: arch/blackfin/mach-bf533/boards/ezkit.c
+ * Author: Aidan Williams <aidan@nicta.com.au>
+ *
+ * Created: 2005
+ * Description: Board description file
+ *
+ * Modified:
+ * Copyright 2005 National ICT Australia (NICTA)
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+#include <linux/usb_isp1362.h>
+#include <asm/irq.h>
+#include <asm/bfin5xx_spi.h>
+
+/*
+ * Name the Board for the /proc/cpuinfo
+ */
+char *bfin_board_name = "Bluetechnix CM BF537";
+
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+/* all SPI peripherals info goes here */
+
+#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
+static struct mtd_partition bfin_spi_flash_partitions[] = {
+ {
+ .name = "bootloader",
+ .size = 0x00020000,
+ .offset = 0,
+ .mask_flags = MTD_CAP_ROM
+ },{
+ .name = "kernel",
+ .size = 0xe0000,
+ .offset = 0x20000
+ },{
+ .name = "file system",
+ .size = 0x700000,
+ .offset = 0x00100000,
+ }
+};
+
+static struct flash_platform_data bfin_spi_flash_data = {
+ .name = "m25p80",
+ .parts = bfin_spi_flash_partitions,
+ .nr_parts = ARRAY_SIZE(bfin_spi_flash_partitions),
+ .type = "m25p64",
+};
+
+/* SPI flash chip (m25p64) */
+static struct bfin5xx_spi_chip spi_flash_chip_info = {
+ .enable_dma = 0, /* use dma transfer with this chip*/
+ .bits_per_word = 8,
+};
+#endif
+
+#if defined(CONFIG_SPI_ADC_BF533) || defined(CONFIG_SPI_ADC_BF533_MODULE)
+/* SPI ADC chip */
+static struct bfin5xx_spi_chip spi_adc_chip_info = {
+ .enable_dma = 1, /* use dma transfer with this chip*/
+ .bits_per_word = 16,
+};
+#endif
+
+#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
+ .enable_dma = 0,
+ .bits_per_word = 16,
+};
+#endif
+
+#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE)
+static struct bfin5xx_spi_chip ad9960_spi_chip_info = {
+ .enable_dma = 0,
+ .bits_per_word = 16,
+};
+#endif
+
+#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE)
+static struct bfin5xx_spi_chip spi_mmc_chip_info = {
+ .enable_dma = 1,
+ .bits_per_word = 8,
+};
+#endif
+
+static struct spi_board_info bfin_spi_board_info[] __initdata = {
+#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
+ {
+ /* the modalias must be the same as spi device driver name */
+ .modalias = "m25p80", /* Name of spi_driver for this device */
+ .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1, /* Framework bus number */
+ .chip_select = 1, /* Framework chip select. On STAMP537 it is SPISSEL1*/
+ .platform_data = &bfin_spi_flash_data,
+ .controller_data = &spi_flash_chip_info,
+ .mode = SPI_MODE_3,
+ },
+#endif
+
+#if defined(CONFIG_SPI_ADC_BF533) || defined(CONFIG_SPI_ADC_BF533_MODULE)
+ {
+ .modalias = "bfin_spi_adc", /* Name of spi_driver for this device */
+ .max_speed_hz = 6250000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1, /* Framework bus number */
+ .chip_select = 1, /* Framework chip select. */
+ .platform_data = NULL, /* No spi_driver specific config */
+ .controller_data = &spi_adc_chip_info,
+ },
+#endif
+
+#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+ {
+ .modalias = "ad1836-spi",
+ .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1,
+ .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT,
+ .controller_data = &ad1836_spi_chip_info,
+ },
+#endif
+
+#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE)
+ {
+ .modalias = "ad9960-spi",
+ .max_speed_hz = 10000000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1,
+ .chip_select = 1,
+ .controller_data = &ad9960_spi_chip_info,
+ },
+#endif
+
+#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE)
+ {
+ .modalias = "spi_mmc_dummy",
+ .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1,
+ .chip_select = 7,
+ .platform_data = NULL,
+ .controller_data = &spi_mmc_chip_info,
+ .mode = SPI_MODE_3,
+ },
+ {
+ .modalias = "spi_mmc",
+ .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1,
+ .chip_select = CONFIG_SPI_MMC_CS_CHAN,
+ .platform_data = NULL,
+ .controller_data = &spi_mmc_chip_info,
+ .mode = SPI_MODE_3,
+ },
+#endif
+};
+
+/* SPI controller data */
+static struct bfin5xx_spi_master spi_bfin_master_info = {
+ .num_chipselect = 8,
+ .enable_dma = 1, /* master has the ability to do dma transfer */
+};
+
+static struct platform_device spi_bfin_master_device = {
+ .name = "bfin-spi-master",
+ .id = 1, /* Bus number */
+ .dev = {
+ .platform_data = &spi_bfin_master_info, /* Passed to driver */
+ },
+};
+#endif /* spi master and devices */
+
+#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
+static struct platform_device rtc_device = {
+ .name = "rtc-bfin",
+ .id = -1,
+};
+#endif
+
+#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+static struct resource smc91x_resources[] = {
+ {
+ .start = 0x20200300,
+ .end = 0x20200300 + 16,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = IRQ_PF14,
+ .end = IRQ_PF14,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ },
+};
+
+static struct platform_device smc91x_device = {
+ .name = "smc91x",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(smc91x_resources),
+ .resource = smc91x_resources,
+};
+#endif
+
+#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
+static struct resource isp1362_hcd_resources[] = {
+ {
+ .start = 0x20308000,
+ .end = 0x20308000,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = 0x20308004,
+ .end = 0x20308004,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = IRQ_PG15,
+ .end = IRQ_PG15,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ },
+};
+
+static struct isp1362_platform_data isp1362_priv = {
+ .sel15Kres = 1,
+ .clknotstop = 0,
+ .oc_enable = 0,
+ .int_act_high = 0,
+ .int_edge_triggered = 0,
+ .remote_wakeup_connected = 0,
+ .no_power_switching = 1,
+ .power_switching_mode = 0,
+};
+
+static struct platform_device isp1362_hcd_device = {
+ .name = "isp1362-hcd",
+ .id = 0,
+ .dev = {
+ .platform_data = &isp1362_priv,
+ },
+ .num_resources = ARRAY_SIZE(isp1362_hcd_resources),
+ .resource = isp1362_hcd_resources,
+};
+#endif
+
+#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE)
+static struct resource net2272_bfin_resources[] = {
+ {
+ .start = 0x20200000,
+ .end = 0x20200000 + 0x100,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = IRQ_PF7,
+ .end = IRQ_PF7,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ },
+};
+
+static struct platform_device net2272_bfin_device = {
+ .name = "net2272",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(net2272_bfin_resources),
+ .resource = net2272_bfin_resources,
+};
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
+static struct resource bfin_uart_resources[] = {
+ {
+ .start = 0xFFC00400,
+ .end = 0xFFC004FF,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = 0xFFC02000,
+ .end = 0xFFC020FF,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device bfin_uart_device = {
+ .name = "bfin-uart",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(bfin_uart_resources),
+ .resource = bfin_uart_resources,
+};
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+static struct platform_device bfin_sport0_uart_device = {
+ .name = "bfin-sport-uart",
+ .id = 0,
+};
+
+static struct platform_device bfin_sport1_uart_device = {
+ .name = "bfin-sport-uart",
+ .id = 1,
+};
+#endif
+
+#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+static struct platform_device bfin_mac_device = {
+ .name = "bfin_mac",
+};
+#endif
+
+static struct platform_device *cm_bf537_devices[] __initdata = {
+#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
+ &rtc_device,
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
+ &bfin_uart_device,
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+ &bfin_sport0_uart_device,
+ &bfin_sport1_uart_device,
+#endif
+
+#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
+ &isp1362_hcd_device,
+#endif
+
+#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+ &smc91x_device,
+#endif
+
+#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+ &bfin_mac_device,
+#endif
+
+#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE)
+ &net2272_bfin_device,
+#endif
+
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+ &spi_bfin_master_device,
+#endif
+};
+
+static int __init cm_bf537_init(void)
+{
+ printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__);
+ platform_add_devices(cm_bf537_devices, ARRAY_SIZE(cm_bf537_devices));
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+ spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info));
+#endif
+ return 0;
+}
+
+arch_initcall(cm_bf537_init);
diff --git a/arch/blackfin/mach-bf537/boards/eth_mac.c b/arch/blackfin/mach-bf537/boards/eth_mac.c
new file mode 100644
index 00000000000..e129a08d63d
--- /dev/null
+++ b/arch/blackfin/mach-bf537/boards/eth_mac.c
@@ -0,0 +1,51 @@
+/*
+ * arch/blackfin/mach-bf537/board/eth_mac.c
+ *
+ * Copyright (C) 2007 Analog Devices, Inc.
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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/module.h>
+#include <asm/blackfin.h>
+
+#if defined(CONFIG_GENERIC_BOARD) \
+ || defined(CONFIG_BFIN537_STAMP)
+
+/*
+ * Currently the MAC address is saved in Flash by U-Boot
+ */
+#define FLASH_MAC 0x203f0000
+
+void get_bf537_ether_addr(char *addr)
+{
+ unsigned int flash_mac = (unsigned int) FLASH_MAC;
+ *(u32 *)(&(addr[0])) = bfin_read32(flash_mac);
+ flash_mac += 4;
+ *(u16 *)(&(addr[4])) = bfin_read16(flash_mac);
+}
+
+#else
+
+/*
+ * Provide MAC address function for other specific board setting
+ */
+void get_bf537_ether_addr(char *addr)
+{
+ printk(KERN_WARNING "%s: No valid Ethernet MAC address found\n",__FILE__);
+}
+
+#endif
+
+EXPORT_SYMBOL(get_bf537_ether_addr);
diff --git a/arch/blackfin/mach-bf537/boards/generic_board.c b/arch/blackfin/mach-bf537/boards/generic_board.c
new file mode 100644
index 00000000000..9019c0edbe7
--- /dev/null
+++ b/arch/blackfin/mach-bf537/boards/generic_board.c
@@ -0,0 +1,445 @@
+/*
+ * File: arch/blackfin/mach-bf537/boards/generic_board.c
+ * Based on: arch/blackfin/mach-bf533/boards/ezkit.c
+ * Author: Aidan Williams <aidan@nicta.com.au>
+ *
+ * Created:
+ * Description:
+ *
+ * Modified:
+ * Copyright 2005 National ICT Australia (NICTA)
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+#include <linux/usb_isp1362.h>
+#include <asm/irq.h>
+#include <asm/bfin5xx_spi.h>
+#include <linux/usb_sl811.h>
+
+/*
+ * Name the Board for the /proc/cpuinfo
+ */
+char *bfin_board_name = "UNKNOWN BOARD";
+
+/*
+ * Driver needs to know address, irq and flag pin.
+ */
+
+#if defined(CONFIG_BFIN_CFPCMCIA) || defined(CONFIG_BFIN_CFPCMCIA_MODULE)
+static struct resource bfin_pcmcia_cf_resources[] = {
+ {
+ .start = 0x20310000, /* IO PORT */
+ .end = 0x20312000,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = 0x20311000, /* Attribute Memeory */
+ .end = 0x20311FFF,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = IRQ_PROG_INTA,
+ .end = IRQ_PROG_INTA,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
+ },{
+ .start = IRQ_PF4,
+ .end = IRQ_PF4,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
+ },{
+ .start = 6, /* Card Detect PF6 */
+ .end = 6,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device bfin_pcmcia_cf_device = {
+ .name = "bfin_cf_pcmcia",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(bfin_pcmcia_cf_resources),
+ .resource = bfin_pcmcia_cf_resources,
+};
+#endif
+
+#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
+static struct platform_device rtc_device = {
+ .name = "rtc-bfin",
+ .id = -1,
+};
+#endif
+
+#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+static struct resource smc91x_resources[] = {
+ {
+ .name = "smc91x-regs",
+ .start = 0x20300300,
+ .end = 0x20300300 + 16,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = IRQ_PROG_INTB,
+ .end = IRQ_PROG_INTB,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ },{
+ /*
+ * denotes the flag pin and is used directly if
+ * CONFIG_IRQCHIP_DEMUX_GPIO is defined.
+ */
+ .start = IRQ_PF7,
+ .end = IRQ_PF7,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ },
+};
+static struct platform_device smc91x_device = {
+ .name = "smc91x",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(smc91x_resources),
+ .resource = smc91x_resources,
+};
+#endif
+
+#if defined(CONFIG_USB_SL811_HCD) || defined(CONFIG_USB_SL811_HCD_MODULE)
+static struct resource sl811_hcd_resources[] = {
+ {
+ .start = 0x20340000,
+ .end = 0x20340000,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = 0x20340004,
+ .end = 0x20340004,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = IRQ_PROG_INTA,
+ .end = IRQ_PROG_INTA,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ },{
+ .start = IRQ_PF0 + CONFIG_USB_SL811_BFIN_GPIO,
+ .end = IRQ_PF0 + CONFIG_USB_SL811_BFIN_GPIO,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ },
+};
+
+#if defined(CONFIG_USB_SL811_BFIN_USE_VBUS)
+void sl811_port_power(struct device *dev, int is_on)
+{
+ unsigned short mask = (1<<CONFIG_USB_SL811_BFIN_GPIO_VBUS);
+
+ bfin_write_PORT_FER(bfin_read_PORT_FER() & ~mask);
+ bfin_write_FIO_DIR(bfin_read_FIO_DIR() | mask);
+
+ if (is_on)
+ bfin_write_FIO_FLAG_S(mask);
+ else
+ bfin_write_FIO_FLAG_C(mask);
+}
+#endif
+
+static struct sl811_platform_data sl811_priv = {
+ .potpg = 10,
+ .power = 250, /* == 500mA */
+#if defined(CONFIG_USB_SL811_BFIN_USE_VBUS)
+ .port_power = &sl811_port_power,
+#endif
+};
+
+static struct platform_device sl811_hcd_device = {
+ .name = "sl811-hcd",
+ .id = 0,
+ .dev = {
+ .platform_data = &sl811_priv,
+ },
+ .num_resources = ARRAY_SIZE(sl811_hcd_resources),
+ .resource = sl811_hcd_resources,
+};
+
+#endif
+
+#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
+static struct resource isp1362_hcd_resources[] = {
+ {
+ .start = 0x20360000,
+ .end = 0x20360000,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = 0x20360004,
+ .end = 0x20360004,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = IRQ_PROG_INTA,
+ .end = IRQ_PROG_INTA,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ },{
+ .start = IRQ_PF0 + CONFIG_USB_ISP1362_BFIN_GPIO,
+ .end = IRQ_PF0 + CONFIG_USB_ISP1362_BFIN_GPIO,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct isp1362_platform_data isp1362_priv = {
+ .sel15Kres = 1,
+ .clknotstop = 0,
+ .oc_enable = 0,
+ .int_act_high = 0,
+ .int_edge_triggered = 0,
+ .remote_wakeup_connected = 0,
+ .no_power_switching = 1,
+ .power_switching_mode = 0,
+};
+
+static struct platform_device isp1362_hcd_device = {
+ .name = "isp1362-hcd",
+ .id = 0,
+ .dev = {
+ .platform_data = &isp1362_priv,
+ },
+ .num_resources = ARRAY_SIZE(isp1362_hcd_resources),
+ .resource = isp1362_hcd_resources,
+};
+#endif
+
+#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+static struct platform_device bfin_mac_device = {
+ .name = "bfin_mac",
+};
+#endif
+
+#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE)
+static struct resource net2272_bfin_resources[] = {
+ {
+ .start = 0x20300000,
+ .end = 0x20300000 + 0x100,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = IRQ_PF7,
+ .end = IRQ_PF7,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ },
+};
+
+static struct platform_device net2272_bfin_device = {
+ .name = "net2272",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(net2272_bfin_resources),
+ .resource = net2272_bfin_resources,
+};
+#endif
+
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+/* all SPI peripherals info goes here */
+
+#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
+static struct mtd_partition bfin_spi_flash_partitions[] = {
+ {
+ .name = "bootloader",
+ .size = 0x00020000,
+ .offset = 0,
+ .mask_flags = MTD_CAP_ROM
+ },{
+ .name = "kernel",
+ .size = 0xe0000,
+ .offset = 0x20000
+ },{
+ .name = "file system",
+ .size = 0x700000,
+ .offset = 0x00100000,
+ }
+};
+
+static struct flash_platform_data bfin_spi_flash_data = {
+ .name = "m25p80",
+ .parts = bfin_spi_flash_partitions,
+ .nr_parts = ARRAY_SIZE(bfin_spi_flash_partitions),
+ .type = "m25p64",
+};
+
+/* SPI flash chip (m25p64) */
+static struct bfin5xx_spi_chip spi_flash_chip_info = {
+ .enable_dma = 0, /* use dma transfer with this chip*/
+ .bits_per_word = 8,
+};
+#endif
+
+#if defined(CONFIG_SPI_ADC_BF533) \
+ || defined(CONFIG_SPI_ADC_BF533_MODULE)
+/* SPI ADC chip */
+static struct bfin5xx_spi_chip spi_adc_chip_info = {
+ .enable_dma = 1, /* use dma transfer with this chip*/
+ .bits_per_word = 16,
+};
+#endif
+
+#if defined(CONFIG_SND_BLACKFIN_AD1836) \
+ || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
+ .enable_dma = 0,
+ .bits_per_word = 16,
+};
+#endif
+
+#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE)
+static struct bfin5xx_spi_chip ad9960_spi_chip_info = {
+ .enable_dma = 0,
+ .bits_per_word = 16,
+};
+#endif
+
+static struct spi_board_info bfin_spi_board_info[] __initdata = {
+#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
+ {
+ /* the modalias must be the same as spi device driver name */
+ .modalias = "m25p80", /* Name of spi_driver for this device */
+ .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1, /* Framework bus number */
+ .chip_select = 2, /* Framework chip select. On STAMP537 it is SPISSEL1*/
+ .platform_data = &bfin_spi_flash_data,
+ .controller_data = &spi_flash_chip_info,
+ .mode = SPI_MODE_3,
+ },
+#endif
+
+#if defined(CONFIG_SPI_ADC_BF533) || defined(CONFIG_SPI_ADC_BF533_MODULE)
+ {
+ .modalias = "bfin_spi_adc", /* Name of spi_driver for this device */
+ .max_speed_hz = 6250000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1, /* Framework bus number */
+ .chip_select = 1, /* Framework chip select. */
+ .platform_data = NULL, /* No spi_driver specific config */
+ .controller_data = &spi_adc_chip_info,
+ },
+#endif
+
+#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+ {
+ .modalias = "ad1836-spi",
+ .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1,
+ .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT,
+ .controller_data = &ad1836_spi_chip_info,
+ },
+#endif
+
+#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE)
+ {
+ .modalias = "ad9960-spi",
+ .max_speed_hz = 10000000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1,
+ .chip_select = 1,
+ .controller_data = &ad9960_spi_chip_info,
+ },
+#endif
+};
+
+/* SPI controller data */
+static struct bfin5xx_spi_master spi_bfin_master_info = {
+ .num_chipselect = 8,
+ .enable_dma = 1, /* master has the ability to do dma transfer */
+};
+
+static struct platform_device spi_bfin_master_device = {
+ .name = "bfin-spi-master",
+ .id = 1, /* Bus number */
+ .dev = {
+ .platform_data = &spi_bfin_master_info, /* Passed to driver */
+ },
+};
+#endif /* spi master and devices */
+
+#if defined(CONFIG_FB_BF537_LQ035) || defined(CONFIG_FB_BF537_LQ035_MODULE)
+static struct platform_device bfin_fb_device = {
+ .name = "bf537-fb",
+};
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
+static struct resource bfin_uart_resources[] = {
+ {
+ .start = 0xFFC00400,
+ .end = 0xFFC004FF,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = 0xFFC02000,
+ .end = 0xFFC020FF,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device bfin_uart_device = {
+ .name = "bfin-uart",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(bfin_uart_resources),
+ .resource = bfin_uart_resources,
+};
+#endif
+
+static struct platform_device *stamp_devices[] __initdata = {
+#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
+ &rtc_device,
+#endif
+
+#if defined(CONFIG_BFIN_CFPCMCIA) || defined(CONFIG_BFIN_CFPCMCIA_MODULE)
+ &bfin_pcmcia_cf_device,
+#endif
+
+#if defined(CONFIG_USB_SL811_HCD) || defined(CONFIG_USB_SL811_HCD_MODULE)
+ &sl811_hcd_device,
+#endif
+
+#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
+ &isp1362_hcd_device,
+#endif
+
+#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+ &smc91x_device,
+#endif
+
+#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+ &bfin_mac_device,
+#endif
+
+#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE)
+ &net2272_bfin_device,
+#endif
+
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+ &spi_bfin_master_device,
+#endif
+
+#if defined(CONFIG_FB_BF537_LQ035) || defined(CONFIG_FB_BF537_LQ035_MODULE)
+ &bfin_fb_device,
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
+ &bfin_uart_device,
+#endif
+};
+
+static int __init stamp_init(void)
+{
+ printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__);
+ platform_add_devices(stamp_devices, ARRAY_SIZE(stamp_devices));
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+ spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info));
+#endif
+ return 0;
+}
+
+arch_initcall(stamp_init);
diff --git a/arch/blackfin/mach-bf537/boards/led.S b/arch/blackfin/mach-bf537/boards/led.S
new file mode 100644
index 00000000000..4e9ea4283e5
--- /dev/null
+++ b/arch/blackfin/mach-bf537/boards/led.S
@@ -0,0 +1,183 @@
+/****************************************************
+ * LED1 ---- PF6 LED2 ---- PF7 *
+ * LED3 ---- PF8 LED4 ---- PF9 *
+ * LED5 ---- PF10 LED6 ---- PF11 *
+ ****************************************************/
+
+#include <linux/linkage.h>
+#include <asm/blackfin.h>
+
+/* All functions in this file save the registers they uses.
+ So there is no need to save any registers before calling them. */
+
+ .text;
+
+/* Initialize LEDs. */
+
+ENTRY(_led_init)
+ LINK 12;
+ [--SP] = P0;
+ [--SP] = R0;
+ [--SP] = R1;
+ [--SP] = R2;
+ R1 = PF6|PF7|PF8|PF9|PF10|PF11 (Z);
+ R2 = ~R1;
+
+ P0.H = hi(PORTF_FER);
+ P0.L = lo(PORTF_FER);
+ R0 = W[P0](Z);
+ SSYNC;
+ R0 = R0 & R2;
+ W[P0] = R0.L;
+ SSYNC;
+
+ P0.H = hi(PORTFIO_DIR);
+ P0.L = lo(PORTFIO_DIR);
+ R0 = W[P0](Z);
+ SSYNC;
+ R0 = R0 | R1;
+ W[P0] = R0.L;
+ SSYNC;
+
+ P0.H = hi(PORTFIO_INEN);
+ P0.L = lo(PORTFIO_INEN);
+ R0 = W[P0](Z);
+ SSYNC;
+ R0 = R0 & R2;
+ W[P0] = R0.L;
+ SSYNC;
+
+ R2 = [SP++];
+ R1 = [SP++];
+ R0 = [SP++];
+ P0 = [SP++];
+ UNLINK;
+ RTS;
+ .size _led_init, .-_led_init
+
+/* Set one LED on. Leave other LEDs unchanged.
+ It expects the LED number passed through R0. */
+
+ENTRY(_led_on)
+ LINK 12;
+ [--SP] = P0;
+ [--SP] = R1;
+ CALL _led_init;
+ R1 = 1;
+ R0 += 5;
+ R1 <<= R0;
+ P0.H = hi(PORTFIO);
+ P0.L = lo(PORTFIO);
+ R0 = W[P0](Z);
+ SSYNC;
+ R0 = R0 | R1;
+ W[P0] = R0.L;
+ SSYNC;
+ R1 = [SP++];
+ P0 = [SP++];
+ UNLINK;
+ RTS;
+ .size _led_on, .-_led_on
+
+/* Set one LED off. Leave other LEDs unchanged. */
+
+ENTRY(_led_off)
+ LINK 12;
+ [--SP] = P0;
+ [--SP] = R1;
+ CALL _led_init;
+ R1 = 1;
+ R0 += 5;
+ R1 <<= R0;
+ R1 = ~R1;
+ P0.H = hi(PORTFIO);
+ P0.L = lo(PORTFIO);
+ R0 = W[P0](Z);
+ SSYNC;
+ R0 = R0 & R1;
+ W[P0] = R0.L;
+ SSYNC;
+ R1 = [SP++];
+ P0 = [SP++];
+ UNLINK;
+ RTS;
+ .size _led_off, .-_led_off
+
+/* Toggle one LED. Leave other LEDs unchanged. */
+
+ENTRY(_led_toggle)
+ LINK 12;
+ [--SP] = P0;
+ [--SP] = R1;
+ CALL _led_init;
+ R1 = 1;
+ R0 += 5;
+ R1 <<= R0;
+ P0.H = hi(PORTFIO);
+ P0.L = lo(PORTFIO);
+ R0 = W[P0](Z);
+ SSYNC;
+ R0 = R0 ^ R1;
+ W[P0] = R0.L;
+ SSYNC;
+ R1 = [SP++];
+ P0 = [SP++];
+ UNLINK;
+ RTS;
+ .size _led_toggle, .-_led_toggle
+
+/* Display the number using LEDs in binary format. */
+
+ENTRY(_led_disp_num)
+ LINK 12;
+ [--SP] = P0;
+ [--SP] = R1;
+ [--SP] = R2;
+ CALL _led_init;
+ R1 = 0x3f(X);
+ R0 = R0 & R1;
+ R2 = 6(X);
+ R0 <<= R2;
+ R1 <<= R2;
+ P0.H = hi(PORTFIO);
+ P0.L = lo(PORTFIO);
+ R2 = W[P0](Z);
+ SSYNC;
+ R1 = ~R1;
+ R2 = R2 & R1;
+ R2 = R2 | R0;
+ W[P0] = R2.L;
+ SSYNC;
+ R2 = [SP++];
+ R1 = [SP++];
+ P0 = [SP++];
+ UNLINK;
+ RTS;
+ .size _led_disp_num, .-_led_disp_num
+
+/* Toggle the number using LEDs in binary format. */
+
+ENTRY(_led_toggle_num)
+ LINK 12;
+ [--SP] = P0;
+ [--SP] = R1;
+ [--SP] = R2;
+ CALL _led_init;
+ R1 = 0x3f(X);
+ R0 = R0 & R1;
+ R1 = 6(X);
+ R0 <<= R1;
+ P0.H = hi(PORTFIO);
+ P0.L = lo(PORTFIO);
+ R1 = W[P0](Z);
+ SSYNC;
+ R1 = R1 ^ R0;
+ W[P0] = R1.L;
+ SSYNC;
+ R2 = [SP++];
+ R1 = [SP++];
+ P0 = [SP++];
+ UNLINK;
+ RTS;
+ .size _led_toggle_num, .-_led_toggle_num
+
diff --git a/arch/blackfin/mach-bf537/boards/pnav10.c b/arch/blackfin/mach-bf537/boards/pnav10.c
new file mode 100644
index 00000000000..40d3a1b70ee
--- /dev/null
+++ b/arch/blackfin/mach-bf537/boards/pnav10.c
@@ -0,0 +1,523 @@
+/*
+ * File: arch/blackfin/mach-bf537/boards/stamp.c
+ * Based on: arch/blackfin/mach-bf533/boards/ezkit.c
+ * Author: Aidan Williams <aidan@nicta.com.au>
+ *
+ * Created:
+ * Description:
+ *
+ * Modified:
+ * Copyright 2005 National ICT Australia (NICTA)
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
+#include <linux/usb_isp1362.h>
+#endif
+#include <asm/irq.h>
+#include <asm/bfin5xx_spi.h>
+#include <linux/usb_sl811.h>
+
+#include <linux/spi/ad7877.h>
+
+/*
+ * Name the Board for the /proc/cpuinfo
+ */
+char *bfin_board_name = "PNAV-1.0";
+
+/*
+ * Driver needs to know address, irq and flag pin.
+ */
+
+#if defined(CONFIG_BFIN_CFPCMCIA) || defined(CONFIG_BFIN_CFPCMCIA_MODULE)
+static struct resource bfin_pcmcia_cf_resources[] = {
+ {
+ .start = 0x20310000, /* IO PORT */
+ .end = 0x20312000,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = 0x20311000, /* Attribute Memeory */
+ .end = 0x20311FFF,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = IRQ_PF4,
+ .end = IRQ_PF4,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
+ },{
+ .start = 6, /* Card Detect PF6 */
+ .end = 6,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device bfin_pcmcia_cf_device = {
+ .name = "bfin_cf_pcmcia",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(bfin_pcmcia_cf_resources),
+ .resource = bfin_pcmcia_cf_resources,
+};
+#endif
+
+#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
+static struct platform_device rtc_device = {
+ .name = "rtc-bfin",
+ .id = -1,
+};
+#endif
+
+#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+static struct resource smc91x_resources[] = {
+ {
+ .name = "smc91x-regs",
+ .start = 0x20300300,
+ .end = 0x20300300 + 16,
+ .flags = IORESOURCE_MEM,
+ },{
+
+ .start = IRQ_PF7,
+ .end = IRQ_PF7,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ },
+};
+static struct platform_device smc91x_device = {
+ .name = "smc91x",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(smc91x_resources),
+ .resource = smc91x_resources,
+};
+#endif
+
+#if defined(CONFIG_USB_SL811_HCD) || defined(CONFIG_USB_SL811_HCD_MODULE)
+static struct resource sl811_hcd_resources[] = {
+ {
+ .start = 0x20340000,
+ .end = 0x20340000,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = 0x20340004,
+ .end = 0x20340004,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = CONFIG_USB_SL811_BFIN_IRQ,
+ .end = CONFIG_USB_SL811_BFIN_IRQ,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ },
+};
+
+#if defined(CONFIG_USB_SL811_BFIN_USE_VBUS)
+void sl811_port_power(struct device *dev, int is_on)
+{
+ unsigned short mask = (1 << CONFIG_USB_SL811_BFIN_GPIO_VBUS);
+
+ bfin_write_PORT_FER(bfin_read_PORT_FER() & ~mask);
+ bfin_write_FIO_DIR(bfin_read_FIO_DIR() | mask);
+
+ if (is_on)
+ bfin_write_FIO_FLAG_S(mask);
+ else
+ bfin_write_FIO_FLAG_C(mask);
+}
+#endif
+
+static struct sl811_platform_data sl811_priv = {
+ .potpg = 10,
+ .power = 250, /* == 500mA */
+#if defined(CONFIG_USB_SL811_BFIN_USE_VBUS)
+ .port_power = &sl811_port_power,
+#endif
+};
+
+static struct platform_device sl811_hcd_device = {
+ .name = "sl811-hcd",
+ .id = 0,
+ .dev = {
+ .platform_data = &sl811_priv,
+ },
+ .num_resources = ARRAY_SIZE(sl811_hcd_resources),
+ .resource = sl811_hcd_resources,
+};
+#endif
+
+#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
+static struct resource isp1362_hcd_resources[] = {
+ {
+ .start = 0x20360000,
+ .end = 0x20360000,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = 0x20360004,
+ .end = 0x20360004,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = CONFIG_USB_ISP1362_BFIN_GPIO_IRQ,
+ .end = CONFIG_USB_ISP1362_BFIN_GPIO_IRQ,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ },
+};
+
+static struct isp1362_platform_data isp1362_priv = {
+ .sel15Kres = 1,
+ .clknotstop = 0,
+ .oc_enable = 0,
+ .int_act_high = 0,
+ .int_edge_triggered = 0,
+ .remote_wakeup_connected = 0,
+ .no_power_switching = 1,
+ .power_switching_mode = 0,
+};
+
+static struct platform_device isp1362_hcd_device = {
+ .name = "isp1362-hcd",
+ .id = 0,
+ .dev = {
+ .platform_data = &isp1362_priv,
+ },
+ .num_resources = ARRAY_SIZE(isp1362_hcd_resources),
+ .resource = isp1362_hcd_resources,
+};
+#endif
+
+#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+static struct platform_device bfin_mac_device = {
+ .name = "bfin_mac",
+};
+#endif
+
+#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE)
+static struct resource net2272_bfin_resources[] = {
+ {
+ .start = 0x20300000,
+ .end = 0x20300000 + 0x100,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = IRQ_PF7,
+ .end = IRQ_PF7,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ },
+};
+
+static struct platform_device net2272_bfin_device = {
+ .name = "net2272",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(net2272_bfin_resources),
+ .resource = net2272_bfin_resources,
+};
+#endif
+
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+/* all SPI peripherals info goes here */
+
+#if defined(CONFIG_MTD_M25P80) \
+ || defined(CONFIG_MTD_M25P80_MODULE)
+static struct mtd_partition bfin_spi_flash_partitions[] = {
+ {
+ .name = "bootloader",
+ .size = 0x00020000,
+ .offset = 0,
+ .mask_flags = MTD_CAP_ROM
+ },{
+ .name = "kernel",
+ .size = 0xe0000,
+ .offset = 0x20000
+ },{
+ .name = "file system",
+ .size = 0x700000,
+ .offset = 0x00100000,
+ }
+};
+
+static struct flash_platform_data bfin_spi_flash_data = {
+ .name = "m25p80",
+ .parts = bfin_spi_flash_partitions,
+ .nr_parts = ARRAY_SIZE(bfin_spi_flash_partitions),
+ .type = "m25p64",
+};
+
+/* SPI flash chip (m25p64) */
+static struct bfin5xx_spi_chip spi_flash_chip_info = {
+ .enable_dma = 0, /* use dma transfer with this chip*/
+ .bits_per_word = 8,
+};
+#endif
+
+#if defined(CONFIG_SPI_ADC_BF533) \
+ || defined(CONFIG_SPI_ADC_BF533_MODULE)
+/* SPI ADC chip */
+static struct bfin5xx_spi_chip spi_adc_chip_info = {
+ .enable_dma = 1, /* use dma transfer with this chip*/
+ .bits_per_word = 16,
+};
+#endif
+
+#if defined(CONFIG_SND_BLACKFIN_AD1836) \
+ || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
+ .enable_dma = 0,
+ .bits_per_word = 16,
+};
+#endif
+
+#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE)
+static struct bfin5xx_spi_chip ad9960_spi_chip_info = {
+ .enable_dma = 0,
+ .bits_per_word = 16,
+};
+#endif
+
+#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE)
+static struct bfin5xx_spi_chip spi_mmc_chip_info = {
+ .enable_dma = 1,
+ .bits_per_word = 8,
+};
+#endif
+
+#if defined(CONFIG_PBX)
+static struct bfin5xx_spi_chip spi_si3xxx_chip_info = {
+ .ctl_reg = 0x4, /* send zero */
+ .enable_dma = 0,
+ .bits_per_word = 8,
+ .cs_change_per_word = 1,
+};
+#endif
+
+
+#if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE)
+static struct bfin5xx_spi_chip spi_ad7877_chip_info = {
+ .cs_change_per_word = 1,
+ .enable_dma = 0,
+ .bits_per_word = 16,
+};
+
+static const struct ad7877_platform_data bfin_ad7877_ts_info = {
+ .model = 7877,
+ .vref_delay_usecs = 50, /* internal, no capacitor */
+ .x_plate_ohms = 419,
+ .y_plate_ohms = 486,
+ .pressure_max = 1000,
+ .pressure_min = 0,
+ .stopacq_polarity = 1,
+ .first_conversion_delay = 3,
+ .acquisition_time = 1,
+ .averaging = 1,
+ .pen_down_acc_interval = 1,
+};
+#endif
+
+static struct spi_board_info bfin_spi_board_info[] __initdata = {
+#if defined(CONFIG_MTD_M25P80) \
+ || defined(CONFIG_MTD_M25P80_MODULE)
+ {
+ /* the modalias must be the same as spi device driver name */
+ .modalias = "m25p80", /* Name of spi_driver for this device */
+ .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1, /* Framework bus number */
+ .chip_select = 1, /* Framework chip select. On STAMP537 it is SPISSEL1*/
+ .platform_data = &bfin_spi_flash_data,
+ .controller_data = &spi_flash_chip_info,
+ .mode = SPI_MODE_3,
+ },
+#endif
+
+#if defined(CONFIG_SPI_ADC_BF533) \
+ || defined(CONFIG_SPI_ADC_BF533_MODULE)
+ {
+ .modalias = "bfin_spi_adc", /* Name of spi_driver for this device */
+ .max_speed_hz = 6250000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1, /* Framework bus number */
+ .chip_select = 1, /* Framework chip select. */
+ .platform_data = NULL, /* No spi_driver specific config */
+ .controller_data = &spi_adc_chip_info,
+ },
+#endif
+
+#if defined(CONFIG_SND_BLACKFIN_AD1836) \
+ || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+ {
+ .modalias = "ad1836-spi",
+ .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1,
+ .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT,
+ .controller_data = &ad1836_spi_chip_info,
+ },
+#endif
+#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE)
+ {
+ .modalias = "ad9960-spi",
+ .max_speed_hz = 10000000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1,
+ .chip_select = 1,
+ .controller_data = &ad9960_spi_chip_info,
+ },
+#endif
+#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE)
+ {
+ .modalias = "spi_mmc_dummy",
+ .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1,
+ .chip_select = 7,
+ .platform_data = NULL,
+ .controller_data = &spi_mmc_chip_info,
+ .mode = SPI_MODE_3,
+ },
+ {
+ .modalias = "spi_mmc",
+ .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1,
+ .chip_select = CONFIG_SPI_MMC_CS_CHAN,
+ .platform_data = NULL,
+ .controller_data = &spi_mmc_chip_info,
+ .mode = SPI_MODE_3,
+ },
+#endif
+#if defined(CONFIG_PBX)
+ {
+ .modalias = "fxs-spi",
+ .max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1,
+ .chip_select = 3,
+ .controller_data= &spi_si3xxx_chip_info,
+ .mode = SPI_MODE_3,
+ },
+ {
+ .modalias = "fxo-spi",
+ .max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1,
+ .chip_select = 2,
+ .controller_data= &spi_si3xxx_chip_info,
+ .mode = SPI_MODE_3,
+ },
+#endif
+#if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE)
+{
+ .modalias = "ad7877",
+ .platform_data = &bfin_ad7877_ts_info,
+ .irq = IRQ_PF2,
+ .max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1,
+ .chip_select = 5,
+ .controller_data = &spi_ad7877_chip_info,
+},
+#endif
+
+};
+
+/* SPI controller data */
+static struct bfin5xx_spi_master spi_bfin_master_info = {
+ .num_chipselect = 8,
+ .enable_dma = 1, /* master has the ability to do dma transfer */
+};
+
+static struct platform_device spi_bfin_master_device = {
+ .name = "bfin-spi-master",
+ .id = 1, /* Bus number */
+ .dev = {
+ .platform_data = &spi_bfin_master_info, /* Passed to driver */
+ },
+};
+#endif /* spi master and devices */
+
+#if defined(CONFIG_FB_BF537_LQ035) || defined(CONFIG_FB_BF537_LQ035_MODULE)
+static struct platform_device bfin_fb_device = {
+ .name = "bf537-fb",
+};
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
+static struct resource bfin_uart_resources[] = {
+ {
+ .start = 0xFFC00400,
+ .end = 0xFFC004FF,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = 0xFFC02000,
+ .end = 0xFFC020FF,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device bfin_uart_device = {
+ .name = "bfin-uart",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(bfin_uart_resources),
+ .resource = bfin_uart_resources,
+};
+#endif
+
+
+static struct platform_device *stamp_devices[] __initdata = {
+#if defined(CONFIG_BFIN_CFPCMCIA) || defined(CONFIG_BFIN_CFPCMCIA_MODULE)
+ &bfin_pcmcia_cf_device,
+#endif
+
+#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
+ &rtc_device,
+#endif
+
+#if defined(CONFIG_USB_SL811_HCD) || defined(CONFIG_USB_SL811_HCD_MODULE)
+ &sl811_hcd_device,
+#endif
+
+#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
+ &isp1362_hcd_device,
+#endif
+
+#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+ &smc91x_device,
+#endif
+
+#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+ &bfin_mac_device,
+#endif
+
+#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE)
+ &net2272_bfin_device,
+#endif
+
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+ &spi_bfin_master_device,
+#endif
+
+#if defined(CONFIG_FB_BF537_LQ035) || defined(CONFIG_FB_BF537_LQ035_MODULE)
+ &bfin_fb_device,
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
+ &bfin_uart_device,
+#endif
+};
+
+static int __init stamp_init(void)
+{
+ printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__);
+ platform_add_devices(stamp_devices, ARRAY_SIZE(stamp_devices));
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+ spi_register_board_info(bfin_spi_board_info,
+ ARRAY_SIZE(bfin_spi_board_info));
+#endif
+ return 0;
+}
+
+arch_initcall(stamp_init);
diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c
new file mode 100644
index 00000000000..ba2f875a7f7
--- /dev/null
+++ b/arch/blackfin/mach-bf537/boards/stamp.c
@@ -0,0 +1,615 @@
+/*
+ * File: arch/blackfin/mach-bf537/boards/stamp.c
+ * Based on: arch/blackfin/mach-bf533/boards/ezkit.c
+ * Author: Aidan Williams <aidan@nicta.com.au>
+ *
+ * Created:
+ * Description:
+ *
+ * Modified:
+ * Copyright 2005 National ICT Australia (NICTA)
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
+#include <linux/usb_isp1362.h>
+#endif
+#include <asm/irq.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <asm/bfin5xx_spi.h>
+#include <linux/usb_sl811.h>
+
+#include <linux/spi/ad7877.h>
+
+/*
+ * Name the Board for the /proc/cpuinfo
+ */
+char *bfin_board_name = "ADDS-BF537-STAMP";
+
+/*
+ * Driver needs to know address, irq and flag pin.
+ */
+
+#define ISP1761_BASE 0x203C0000
+#define ISP1761_IRQ IRQ_PF7
+
+#if defined(CONFIG_USB_ISP1760_HCD) || defined(CONFIG_USB_ISP1760_HCD_MODULE)
+static struct resource bfin_isp1761_resources[] = {
+ [0] = {
+ .name = "isp1761-regs",
+ .start = ISP1761_BASE + 0x00000000,
+ .end = ISP1761_BASE + 0x000fffff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = ISP1761_IRQ,
+ .end = ISP1761_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device bfin_isp1761_device = {
+ .name = "isp1761",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(bfin_isp1761_resources),
+ .resource = bfin_isp1761_resources,
+};
+
+static struct platform_device *bfin_isp1761_devices[] = {
+ &bfin_isp1761_device,
+};
+
+int __init bfin_isp1761_init(void)
+{
+ unsigned int num_devices=ARRAY_SIZE(bfin_isp1761_devices);
+
+ printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__);
+ set_irq_type(ISP1761_IRQ, IRQF_TRIGGER_FALLING);
+
+ return platform_add_devices(bfin_isp1761_devices, num_devices);
+}
+
+void __exit bfin_isp1761_exit(void)
+{
+ platform_device_unregister(&bfin_isp1761_device);
+}
+
+arch_initcall(bfin_isp1761_init);
+#endif
+
+#if defined(CONFIG_BFIN_CFPCMCIA) || defined(CONFIG_BFIN_CFPCMCIA_MODULE)
+static struct resource bfin_pcmcia_cf_resources[] = {
+ {
+ .start = 0x20310000, /* IO PORT */
+ .end = 0x20312000,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = 0x20311000, /* Attribute Memeory */
+ .end = 0x20311FFF,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = IRQ_PF4,
+ .end = IRQ_PF4,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
+ },{
+ .start = 6, /* Card Detect PF6 */
+ .end = 6,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device bfin_pcmcia_cf_device = {
+ .name = "bfin_cf_pcmcia",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(bfin_pcmcia_cf_resources),
+ .resource = bfin_pcmcia_cf_resources,
+};
+#endif
+
+#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
+static struct platform_device rtc_device = {
+ .name = "rtc-bfin",
+ .id = -1,
+};
+#endif
+
+#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+static struct resource smc91x_resources[] = {
+ {
+ .name = "smc91x-regs",
+ .start = 0x20300300,
+ .end = 0x20300300 + 16,
+ .flags = IORESOURCE_MEM,
+ },{
+
+ .start = IRQ_PF7,
+ .end = IRQ_PF7,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ },
+};
+static struct platform_device smc91x_device = {
+ .name = "smc91x",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(smc91x_resources),
+ .resource = smc91x_resources,
+};
+#endif
+
+#if defined(CONFIG_USB_SL811_HCD) || defined(CONFIG_USB_SL811_HCD_MODULE)
+static struct resource sl811_hcd_resources[] = {
+ {
+ .start = 0x20340000,
+ .end = 0x20340000,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = 0x20340004,
+ .end = 0x20340004,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = CONFIG_USB_SL811_BFIN_IRQ,
+ .end = CONFIG_USB_SL811_BFIN_IRQ,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ },
+};
+
+#if defined(CONFIG_USB_SL811_BFIN_USE_VBUS)
+void sl811_port_power(struct device *dev, int is_on)
+{
+ unsigned short mask = (1 << CONFIG_USB_SL811_BFIN_GPIO_VBUS);
+
+ bfin_write_PORT_FER(bfin_read_PORT_FER() & ~mask);
+ bfin_write_FIO_DIR(bfin_read_FIO_DIR() | mask);
+
+ if (is_on)
+ bfin_write_FIO_FLAG_S(mask);
+ else
+ bfin_write_FIO_FLAG_C(mask);
+}
+#endif
+
+static struct sl811_platform_data sl811_priv = {
+ .potpg = 10,
+ .power = 250, /* == 500mA */
+#if defined(CONFIG_USB_SL811_BFIN_USE_VBUS)
+ .port_power = &sl811_port_power,
+#endif
+};
+
+static struct platform_device sl811_hcd_device = {
+ .name = "sl811-hcd",
+ .id = 0,
+ .dev = {
+ .platform_data = &sl811_priv,
+ },
+ .num_resources = ARRAY_SIZE(sl811_hcd_resources),
+ .resource = sl811_hcd_resources,
+};
+#endif
+
+#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
+static struct resource isp1362_hcd_resources[] = {
+ {
+ .start = 0x20360000,
+ .end = 0x20360000,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = 0x20360004,
+ .end = 0x20360004,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = CONFIG_USB_ISP1362_BFIN_GPIO_IRQ,
+ .end = CONFIG_USB_ISP1362_BFIN_GPIO_IRQ,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ },
+};
+
+static struct isp1362_platform_data isp1362_priv = {
+ .sel15Kres = 1,
+ .clknotstop = 0,
+ .oc_enable = 0,
+ .int_act_high = 0,
+ .int_edge_triggered = 0,
+ .remote_wakeup_connected = 0,
+ .no_power_switching = 1,
+ .power_switching_mode = 0,
+};
+
+static struct platform_device isp1362_hcd_device = {
+ .name = "isp1362-hcd",
+ .id = 0,
+ .dev = {
+ .platform_data = &isp1362_priv,
+ },
+ .num_resources = ARRAY_SIZE(isp1362_hcd_resources),
+ .resource = isp1362_hcd_resources,
+};
+#endif
+
+#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+static struct platform_device bfin_mac_device = {
+ .name = "bfin_mac",
+};
+#endif
+
+#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE)
+static struct resource net2272_bfin_resources[] = {
+ {
+ .start = 0x20300000,
+ .end = 0x20300000 + 0x100,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = IRQ_PF7,
+ .end = IRQ_PF7,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ },
+};
+
+static struct platform_device net2272_bfin_device = {
+ .name = "net2272",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(net2272_bfin_resources),
+ .resource = net2272_bfin_resources,
+};
+#endif
+
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+/* all SPI peripherals info goes here */
+
+#if defined(CONFIG_MTD_M25P80) \
+ || defined(CONFIG_MTD_M25P80_MODULE)
+static struct mtd_partition bfin_spi_flash_partitions[] = {
+ {
+ .name = "bootloader",
+ .size = 0x00020000,
+ .offset = 0,
+ .mask_flags = MTD_CAP_ROM
+ },{
+ .name = "kernel",
+ .size = 0xe0000,
+ .offset = 0x20000
+ },{
+ .name = "file system",
+ .size = 0x700000,
+ .offset = 0x00100000,
+ }
+};
+
+static struct flash_platform_data bfin_spi_flash_data = {
+ .name = "m25p80",
+ .parts = bfin_spi_flash_partitions,
+ .nr_parts = ARRAY_SIZE(bfin_spi_flash_partitions),
+ .type = "m25p64",
+};
+
+/* SPI flash chip (m25p64) */
+static struct bfin5xx_spi_chip spi_flash_chip_info = {
+ .enable_dma = 0, /* use dma transfer with this chip*/
+ .bits_per_word = 8,
+};
+#endif
+
+#if defined(CONFIG_SPI_ADC_BF533) \
+ || defined(CONFIG_SPI_ADC_BF533_MODULE)
+/* SPI ADC chip */
+static struct bfin5xx_spi_chip spi_adc_chip_info = {
+ .enable_dma = 1, /* use dma transfer with this chip*/
+ .bits_per_word = 16,
+};
+#endif
+
+#if defined(CONFIG_SND_BLACKFIN_AD1836) \
+ || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
+ .enable_dma = 0,
+ .bits_per_word = 16,
+};
+#endif
+
+#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE)
+static struct bfin5xx_spi_chip ad9960_spi_chip_info = {
+ .enable_dma = 0,
+ .bits_per_word = 16,
+};
+#endif
+
+#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE)
+static struct bfin5xx_spi_chip spi_mmc_chip_info = {
+ .enable_dma = 1,
+ .bits_per_word = 8,
+};
+#endif
+
+#if defined(CONFIG_PBX)
+static struct bfin5xx_spi_chip spi_si3xxx_chip_info = {
+ .ctl_reg = 0x4, /* send zero */
+ .enable_dma = 0,
+ .bits_per_word = 8,
+ .cs_change_per_word = 1,
+};
+#endif
+
+#if defined(CONFIG_AD5304) || defined(CONFIG_AD5304_MODULE)
+static struct bfin5xx_spi_chip ad5304_chip_info = {
+ .enable_dma = 0,
+ .bits_per_word = 16,
+};
+#endif
+
+#if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE)
+static struct bfin5xx_spi_chip spi_ad7877_chip_info = {
+// .cs_change_per_word = 1,
+ .enable_dma = 0,
+ .bits_per_word = 16,
+};
+
+static const struct ad7877_platform_data bfin_ad7877_ts_info = {
+ .model = 7877,
+ .vref_delay_usecs = 50, /* internal, no capacitor */
+ .x_plate_ohms = 419,
+ .y_plate_ohms = 486,
+ .pressure_max = 1000,
+ .pressure_min = 0,
+ .stopacq_polarity = 1,
+ .first_conversion_delay = 3,
+ .acquisition_time = 1,
+ .averaging = 1,
+ .pen_down_acc_interval = 1,
+};
+#endif
+
+static struct spi_board_info bfin_spi_board_info[] __initdata = {
+#if defined(CONFIG_MTD_M25P80) \
+ || defined(CONFIG_MTD_M25P80_MODULE)
+ {
+ /* the modalias must be the same as spi device driver name */
+ .modalias = "m25p80", /* Name of spi_driver for this device */
+ .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1, /* Framework bus number */
+ .chip_select = 1, /* Framework chip select. On STAMP537 it is SPISSEL1*/
+ .platform_data = &bfin_spi_flash_data,
+ .controller_data = &spi_flash_chip_info,
+ .mode = SPI_MODE_3,
+ },
+#endif
+
+#if defined(CONFIG_SPI_ADC_BF533) \
+ || defined(CONFIG_SPI_ADC_BF533_MODULE)
+ {
+ .modalias = "bfin_spi_adc", /* Name of spi_driver for this device */
+ .max_speed_hz = 6250000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1, /* Framework bus number */
+ .chip_select = 1, /* Framework chip select. */
+ .platform_data = NULL, /* No spi_driver specific config */
+ .controller_data = &spi_adc_chip_info,
+ },
+#endif
+
+#if defined(CONFIG_SND_BLACKFIN_AD1836) \
+ || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+ {
+ .modalias = "ad1836-spi",
+ .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1,
+ .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT,
+ .controller_data = &ad1836_spi_chip_info,
+ },
+#endif
+#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE)
+ {
+ .modalias = "ad9960-spi",
+ .max_speed_hz = 10000000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1,
+ .chip_select = 1,
+ .controller_data = &ad9960_spi_chip_info,
+ },
+#endif
+#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE)
+ {
+ .modalias = "spi_mmc_dummy",
+ .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1,
+ .chip_select = 0,
+ .platform_data = NULL,
+ .controller_data = &spi_mmc_chip_info,
+ .mode = SPI_MODE_3,
+ },
+ {
+ .modalias = "spi_mmc",
+ .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1,
+ .chip_select = CONFIG_SPI_MMC_CS_CHAN,
+ .platform_data = NULL,
+ .controller_data = &spi_mmc_chip_info,
+ .mode = SPI_MODE_3,
+ },
+#endif
+#if defined(CONFIG_PBX)
+ {
+ .modalias = "fxs-spi",
+ .max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1,
+ .chip_select = 3,
+ .controller_data= &spi_si3xxx_chip_info,
+ .mode = SPI_MODE_3,
+ },
+ {
+ .modalias = "fxo-spi",
+ .max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1,
+ .chip_select = 2,
+ .controller_data= &spi_si3xxx_chip_info,
+ .mode = SPI_MODE_3,
+ },
+#endif
+#if defined(CONFIG_AD5304) || defined(CONFIG_AD5304_MODULE)
+ {
+ .modalias = "ad5304_spi",
+ .max_speed_hz = 1250000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1,
+ .chip_select = 2,
+ .platform_data = NULL,
+ .controller_data = &ad5304_chip_info,
+ .mode = SPI_MODE_2,
+ },
+#endif
+#if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE)
+ {
+ .modalias = "ad7877",
+ .platform_data = &bfin_ad7877_ts_info,
+ .irq = IRQ_PF6,
+ .max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1,
+ .chip_select = 1,
+ .controller_data = &spi_ad7877_chip_info,
+ },
+#endif
+};
+
+/* SPI controller data */
+static struct bfin5xx_spi_master spi_bfin_master_info = {
+ .num_chipselect = 8,
+ .enable_dma = 1, /* master has the ability to do dma transfer */
+};
+
+static struct platform_device spi_bfin_master_device = {
+ .name = "bfin-spi-master",
+ .id = 1, /* Bus number */
+ .dev = {
+ .platform_data = &spi_bfin_master_info, /* Passed to driver */
+ },
+};
+#endif /* spi master and devices */
+
+#if defined(CONFIG_FB_BF537_LQ035) || defined(CONFIG_FB_BF537_LQ035_MODULE)
+static struct platform_device bfin_fb_device = {
+ .name = "bf537-fb",
+};
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
+static struct resource bfin_uart_resources[] = {
+ {
+ .start = 0xFFC00400,
+ .end = 0xFFC004FF,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = 0xFFC02000,
+ .end = 0xFFC020FF,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device bfin_uart_device = {
+ .name = "bfin-uart",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(bfin_uart_resources),
+ .resource = bfin_uart_resources,
+};
+#endif
+
+#if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE)
+static struct platform_device i2c_bfin_twi_device = {
+ .name = "i2c-bfin-twi",
+ .id = 0,
+};
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+static struct platform_device bfin_sport0_uart_device = {
+ .name = "bfin-sport-uart",
+ .id = 0,
+};
+
+static struct platform_device bfin_sport1_uart_device = {
+ .name = "bfin-sport-uart",
+ .id = 1,
+};
+#endif
+
+static struct platform_device *stamp_devices[] __initdata = {
+#if defined(CONFIG_BFIN_CFPCMCIA) || defined(CONFIG_BFIN_CFPCMCIA_MODULE)
+ &bfin_pcmcia_cf_device,
+#endif
+
+#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
+ &rtc_device,
+#endif
+
+#if defined(CONFIG_USB_SL811_HCD) || defined(CONFIG_USB_SL811_HCD_MODULE)
+ &sl811_hcd_device,
+#endif
+
+#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
+ &isp1362_hcd_device,
+#endif
+
+#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+ &smc91x_device,
+#endif
+
+#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+ &bfin_mac_device,
+#endif
+
+#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE)
+ &net2272_bfin_device,
+#endif
+
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+ &spi_bfin_master_device,
+#endif
+
+#if defined(CONFIG_FB_BF537_LQ035) || defined(CONFIG_FB_BF537_LQ035_MODULE)
+ &bfin_fb_device,
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
+ &bfin_uart_device,
+#endif
+
+#if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE)
+ &i2c_bfin_twi_device,
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+ &bfin_sport0_uart_device,
+ &bfin_sport1_uart_device,
+#endif
+};
+
+static int __init stamp_init(void)
+{
+ printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__);
+ platform_add_devices(stamp_devices, ARRAY_SIZE(stamp_devices));
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+ spi_register_board_info(bfin_spi_board_info,
+ ARRAY_SIZE(bfin_spi_board_info));
+#endif
+ return 0;
+}
+
+arch_initcall(stamp_init);
diff --git a/arch/blackfin/mach-bf537/cpu.c b/arch/blackfin/mach-bf537/cpu.c
new file mode 100644
index 00000000000..2d83b7e3546
--- /dev/null
+++ b/arch/blackfin/mach-bf537/cpu.c
@@ -0,0 +1,161 @@
+/*
+ * File: arch/blackfin/mach-bf537/cpu.c
+ * Based on:
+ * Author: michael.kang@analog.com
+ *
+ * Created:
+ * Description: clock scaling for the bf537
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/cpufreq.h>
+#include <asm/dpmc.h>
+#include <linux/fs.h>
+#include <asm/bfin-global.h>
+
+/* CONFIG_CLKIN_HZ=11059200 */
+#define VCO5 (CONFIG_CLKIN_HZ*45) /*497664000 */
+#define VCO4 (CONFIG_CLKIN_HZ*36) /*398131200 */
+#define VCO3 (CONFIG_CLKIN_HZ*27) /*298598400 */
+#define VCO2 (CONFIG_CLKIN_HZ*18) /*199065600 */
+#define VCO1 (CONFIG_CLKIN_HZ*9) /*99532800 */
+#define VCO(x) VCO##x
+
+#define FREQ(x) {VCO(x),VCO(x)/4},{VCO(x),VCO(x)/2},{VCO(x),VCO(x)}
+/* frequency */
+static struct cpufreq_frequency_table bf537_freq_table[] = {
+ FREQ(1),
+ FREQ(3),
+ {VCO4, VCO4 / 2}, {VCO4, VCO4},
+ FREQ(5),
+ {0, CPUFREQ_TABLE_END},
+};
+
+/*
+ * dpmc_fops->ioctl()
+ * static int dpmc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+ */
+static int bf537_getfreq(unsigned int cpu)
+{
+ unsigned long cclk_mhz, vco_mhz;
+
+ /* The driver only support single cpu */
+ if (cpu == 0)
+ dpmc_fops.ioctl(NULL, NULL, IOCTL_GET_CORECLOCK, &cclk_mhz);
+ else
+ cclk_mhz = -1;
+ return cclk_mhz;
+}
+
+static int bf537_target(struct cpufreq_policy *policy,
+ unsigned int target_freq, unsigned int relation)
+{
+ unsigned long cclk_mhz;
+ unsigned long vco_mhz;
+ unsigned long flags;
+ unsigned int index, vco_index;
+ int i;
+
+ struct cpufreq_freqs freqs;
+ if (cpufreq_frequency_table_target
+ (policy, bf537_freq_table, target_freq, relation, &index))
+ return -EINVAL;
+ cclk_mhz = bf537_freq_table[index].frequency;
+ vco_mhz = bf537_freq_table[index].index;
+
+ dpmc_fops.ioctl(NULL, NULL, IOCTL_CHANGE_FREQUENCY, &vco_mhz);
+ freqs.old = bf537_getfreq(0);
+ freqs.new = cclk_mhz;
+ freqs.cpu = 0;
+
+ pr_debug("cclk begin change to cclk %d,vco=%d,index=%d,target=%d,oldfreq=%d\n",
+ cclk_mhz, vco_mhz, index, target_freq, freqs.old);
+
+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+ local_irq_save(flags);
+ dpmc_fops.ioctl(NULL, NULL, IOCTL_SET_CCLK, &cclk_mhz);
+ local_irq_restore(flags);
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+
+ vco_mhz = get_vco();
+ cclk_mhz = get_cclk();
+ return 0;
+}
+
+/* make sure that only the "userspace" governor is run -- anything else wouldn't make sense on
+ * this platform, anyway.
+ */
+static int bf537_verify_speed(struct cpufreq_policy *policy)
+{
+ return cpufreq_frequency_table_verify(policy, &bf537_freq_table);
+}
+
+static int __init __bf537_cpu_init(struct cpufreq_policy *policy)
+{
+ int result;
+
+ if (policy->cpu != 0)
+ return -EINVAL;
+
+ policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
+
+ policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
+ /*Now ,only support one cpu */
+ policy->cur = bf537_getfreq(0);
+ cpufreq_frequency_table_get_attr(bf537_freq_table, policy->cpu);
+ return cpufreq_frequency_table_cpuinfo(policy, bf537_freq_table);
+}
+
+static struct freq_attr *bf537_freq_attr[] = {
+ &cpufreq_freq_attr_scaling_available_freqs,
+ NULL,
+};
+
+static struct cpufreq_driver bf537_driver = {
+ .verify = bf537_verify_speed,
+ .target = bf537_target,
+ .get = bf537_getfreq,
+ .init = __bf537_cpu_init,
+ .name = "bf537",
+ .owner = THIS_MODULE,
+ .attr = bf537_freq_attr,
+};
+
+static int __init bf537_cpu_init(void)
+{
+ return cpufreq_register_driver(&bf537_driver);
+}
+
+static void __exit bf537_cpu_exit(void)
+{
+ cpufreq_unregister_driver(&bf537_driver);
+}
+
+MODULE_AUTHOR("Mickael Kang");
+MODULE_DESCRIPTION("cpufreq driver for BF537 CPU");
+MODULE_LICENSE("GPL");
+
+module_init(bf537_cpu_init);
+module_exit(bf537_cpu_exit);
diff --git a/arch/blackfin/mach-bf537/head.S b/arch/blackfin/mach-bf537/head.S
new file mode 100644
index 00000000000..d104e1d8e07
--- /dev/null
+++ b/arch/blackfin/mach-bf537/head.S
@@ -0,0 +1,602 @@
+/*
+ * File: arch/blackfin/mach-bf537/head.S
+ * Based on: arch/blackfin/mach-bf533/head.S
+ * Author: Jeff Dionne <jeff@uclinux.org> COPYRIGHT 1998 D. Jeff Dionne
+ *
+ * Created: 1998
+ * Description: Startup code for Blackfin BF537
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/linkage.h>
+#include <asm/blackfin.h>
+#if CONFIG_BFIN_KERNEL_CLOCK
+#include <asm/mach/mem_init.h>
+#endif
+
+.global __rambase
+.global __ramstart
+.global __ramend
+.extern ___bss_stop
+.extern ___bss_start
+.extern _bf53x_relocate_l1_mem
+
+#define INITIAL_STACK 0xFFB01000
+
+.text
+
+ENTRY(__start)
+ENTRY(__stext)
+ /* R0: argument of command line string, passed from uboot, save it */
+ R7 = R0;
+ /* Set the SYSCFG register */
+ R0 = 0x36;
+ SYSCFG = R0; /*Enable Cycle Counter and Nesting Of Interrupts(3rd Bit)*/
+ R0 = 0;
+
+ /* Clear Out All the data and pointer Registers*/
+ R1 = R0;
+ R2 = R0;
+ R3 = R0;
+ R4 = R0;
+ R5 = R0;
+ R6 = R0;
+
+ P0 = R0;
+ P1 = R0;
+ P2 = R0;
+ P3 = R0;
+ P4 = R0;
+ P5 = R0;
+
+ LC0 = r0;
+ LC1 = r0;
+ L0 = r0;
+ L1 = r0;
+ L2 = r0;
+ L3 = r0;
+
+ /* Clear Out All the DAG Registers*/
+ B0 = r0;
+ B1 = r0;
+ B2 = r0;
+ B3 = r0;
+
+ I0 = r0;
+ I1 = r0;
+ I2 = r0;
+ I3 = r0;
+
+ M0 = r0;
+ M1 = r0;
+ M2 = r0;
+ M3 = r0;
+
+ /* Turn off the icache */
+ p0.l = (IMEM_CONTROL & 0xFFFF);
+ p0.h = (IMEM_CONTROL >> 16);
+ R1 = [p0];
+ R0 = ~ENICPLB;
+ R0 = R0 & R1;
+
+ /* Anomaly 05000125 */
+#ifdef ANOMALY_05000125
+ CLI R2;
+ SSYNC;
+#endif
+ [p0] = R0;
+ SSYNC;
+#ifdef ANOMALY_05000125
+ STI R2;
+#endif
+
+ /* Turn off the dcache */
+ p0.l = (DMEM_CONTROL & 0xFFFF);
+ p0.h = (DMEM_CONTROL >> 16);
+ R1 = [p0];
+ R0 = ~ENDCPLB;
+ R0 = R0 & R1;
+
+ /* Anomaly 05000125 */
+#ifdef ANOMALY_05000125
+ CLI R2;
+ SSYNC;
+#endif
+ [p0] = R0;
+ SSYNC;
+#ifdef ANOMALY_05000125
+ STI R2;
+#endif
+
+ /* Initialise General-Purpose I/O Modules on BF537 */
+ /* Rev 0.0 Anomaly 05000212 - PORTx_FER,
+ * PORT_MUX Registers Do Not accept "writes" correctly:
+ */
+ p0.h = hi(BFIN_PORT_MUX);
+ p0.l = lo(BFIN_PORT_MUX);
+#ifdef ANOMALY_05000212
+ R0.L = W[P0]; /* Read */
+ SSYNC;
+#endif
+ R0 = (PGDE_UART | PFTE_UART)(Z);
+#ifdef ANOMALY_05000212
+ W[P0] = R0.L; /* Write */
+ SSYNC;
+#endif
+ W[P0] = R0.L; /* Enable both UARTS */
+ SSYNC;
+
+ p0.h = hi(PORTF_FER);
+ p0.l = lo(PORTF_FER);
+#ifdef ANOMALY_05000212
+ R0.L = W[P0]; /* Read */
+ SSYNC;
+#endif
+ R0 = 0x000F(Z);
+#ifdef ANOMALY_05000212
+ W[P0] = R0.L; /* Write */
+ SSYNC;
+#endif
+ /* Enable peripheral function of PORTF for UART0 and UART1 */
+ W[P0] = R0.L;
+ SSYNC;
+
+#if !defined(CONFIG_BF534)
+ p0.h = hi(EMAC_SYSTAT);
+ p0.l = lo(EMAC_SYSTAT);
+ R0.h = 0xFFFF; /* Clear EMAC Interrupt Status bits */
+ R0.l = 0xFFFF;
+ [P0] = R0;
+ SSYNC;
+#endif
+
+#ifdef CONFIG_BF537_PORT_H
+ p0.h = hi(PORTH_FER);
+ p0.l = lo(PORTH_FER);
+ R0.L = W[P0]; /* Read */
+ SSYNC;
+ R0 = 0x0000;
+ W[P0] = R0.L; /* Write */
+ SSYNC;
+ W[P0] = R0.L; /* Disable peripheral function of PORTH */
+ SSYNC;
+#endif
+
+ /*Initialise UART*/
+ p0.h = hi(UART_LCR);
+ p0.l = lo(UART_LCR);
+ r0 = 0x0(Z);
+ w[p0] = r0.L; /* To enable DLL writes */
+ ssync;
+
+ p0.h = hi(UART_DLL);
+ p0.l = lo(UART_DLL);
+ r0 = 0x00(Z);
+ w[p0] = r0.L;
+ ssync;
+
+ p0.h = hi(UART_DLH);
+ p0.l = lo(UART_DLH);
+ r0 = 0x00(Z);
+ w[p0] = r0.L;
+ ssync;
+
+ p0.h = hi(UART_GCTL);
+ p0.l = lo(UART_GCTL);
+ r0 = 0x0(Z);
+ w[p0] = r0.L; /* To enable UART clock */
+ ssync;
+
+ /* Initialize stack pointer */
+ sp.l = lo(INITIAL_STACK);
+ sp.h = hi(INITIAL_STACK);
+ fp = sp;
+ usp = sp;
+
+ /* Put The Code for PLL Programming and SDRAM Programming in L1 ISRAM */
+ call _bf53x_relocate_l1_mem;
+#if CONFIG_BFIN_KERNEL_CLOCK
+ call _start_dma_code;
+#endif
+ /* Code for initializing Async memory banks */
+
+ p2.h = hi(EBIU_AMBCTL1);
+ p2.l = lo(EBIU_AMBCTL1);
+ r0.h = hi(AMBCTL1VAL);
+ r0.l = lo(AMBCTL1VAL);
+ [p2] = r0;
+ ssync;
+
+ p2.h = hi(EBIU_AMBCTL0);
+ p2.l = lo(EBIU_AMBCTL0);
+ r0.h = hi(AMBCTL0VAL);
+ r0.l = lo(AMBCTL0VAL);
+ [p2] = r0;
+ ssync;
+
+ p2.h = hi(EBIU_AMGCTL);
+ p2.l = lo(EBIU_AMGCTL);
+ r0 = AMGCTLVAL;
+ w[p2] = r0;
+ ssync;
+
+ /* This section keeps the processor in supervisor mode
+ * during kernel boot. Switches to user mode at end of boot.
+ * See page 3-9 of Hardware Reference manual for documentation.
+ */
+
+ /* EVT15 = _real_start */
+
+ p0.l = lo(EVT15);
+ p0.h = hi(EVT15);
+ p1.l = _real_start;
+ p1.h = _real_start;
+ [p0] = p1;
+ csync;
+
+ p0.l = lo(IMASK);
+ p0.h = hi(IMASK);
+ p1.l = IMASK_IVG15;
+ p1.h = 0x0;
+ [p0] = p1;
+ csync;
+
+ raise 15;
+ p0.l = .LWAIT_HERE;
+ p0.h = .LWAIT_HERE;
+ reti = p0;
+#if defined(ANOMALY_05000281)
+ nop; nop; nop;
+#endif
+ rti;
+
+.LWAIT_HERE:
+ jump .LWAIT_HERE;
+
+ENTRY(_real_start)
+ [ -- sp ] = reti;
+ p0.l = lo(WDOG_CTL);
+ p0.h = hi(WDOG_CTL);
+ r0 = 0xAD6(z);
+ w[p0] = r0; /* watchdog off for now */
+ ssync;
+
+ /* Code update for BSS size == 0
+ * Zero out the bss region.
+ */
+
+ p1.l = ___bss_start;
+ p1.h = ___bss_start;
+ p2.l = ___bss_stop;
+ p2.h = ___bss_stop;
+ r0 = 0;
+ p2 -= p1;
+ lsetup (.L_clear_bss, .L_clear_bss ) lc0 = p2;
+.L_clear_bss:
+ B[p1++] = r0;
+
+ /* In case there is a NULL pointer reference
+ * Zero out region before stext
+ */
+
+ p1.l = 0x0;
+ p1.h = 0x0;
+ r0.l = __stext;
+ r0.h = __stext;
+ r0 = r0 >> 1;
+ p2 = r0;
+ r0 = 0;
+ lsetup (.L_clear_zero, .L_clear_zero ) lc0 = p2;
+.L_clear_zero:
+ W[p1++] = r0;
+
+ /* pass the uboot arguments to the global value command line */
+ R0 = R7;
+ call _cmdline_init;
+
+ p1.l = __rambase;
+ p1.h = __rambase;
+ r0.l = __sdata;
+ r0.h = __sdata;
+ [p1] = r0;
+
+ p1.l = __ramstart;
+ p1.h = __ramstart;
+ p3.l = ___bss_stop;
+ p3.h = ___bss_stop;
+
+ r1 = p3;
+ [p1] = r1;
+
+
+ /*
+ * load the current thread pointer and stack
+ */
+ r1.l = _init_thread_union;
+ r1.h = _init_thread_union;
+
+ r2.l = 0x2000;
+ r2.h = 0x0000;
+ r1 = r1 + r2;
+ sp = r1;
+ usp = sp;
+ fp = sp;
+ call _start_kernel;
+.L_exit:
+ jump.s .L_exit;
+
+.section .l1.text
+#if CONFIG_BFIN_KERNEL_CLOCK
+ENTRY(_start_dma_code)
+
+ /* Enable PHY CLK buffer output */
+ p0.h = hi(VR_CTL);
+ p0.l = lo(VR_CTL);
+ r0.l = w[p0];
+ bitset(r0, 14);
+ w[p0] = r0.l;
+ ssync;
+
+ p0.h = hi(SIC_IWR);
+ p0.l = lo(SIC_IWR);
+ r0.l = 0x1;
+ r0.h = 0x0;
+ [p0] = r0;
+ SSYNC;
+
+ /*
+ * Set PLL_CTL
+ * - [14:09] = MSEL[5:0] : CLKIN / VCO multiplication factors
+ * - [8] = BYPASS : BYPASS the PLL, run CLKIN into CCLK/SCLK
+ * - [7] = output delay (add 200ps of delay to mem signals)
+ * - [6] = input delay (add 200ps of input delay to mem signals)
+ * - [5] = PDWN : 1=All Clocks off
+ * - [3] = STOPCK : 1=Core Clock off
+ * - [1] = PLL_OFF : 1=Disable Power to PLL
+ * - [0] = DF : 1=Pass CLKIN/2 to PLL / 0=Pass CLKIN to PLL
+ * all other bits set to zero
+ */
+
+ p0.h = hi(PLL_LOCKCNT);
+ p0.l = lo(PLL_LOCKCNT);
+ r0 = 0x300(Z);
+ w[p0] = r0.l;
+ ssync;
+
+ P2.H = hi(EBIU_SDGCTL);
+ P2.L = lo(EBIU_SDGCTL);
+ R0 = [P2];
+ BITSET (R0, 24);
+ [P2] = R0;
+ SSYNC;
+
+ r0 = CONFIG_VCO_MULT & 63; /* Load the VCO multiplier */
+ r0 = r0 << 9; /* Shift it over, */
+ r1 = CLKIN_HALF; /* Do we need to divide CLKIN by 2?*/
+ r0 = r1 | r0;
+ r1 = PLL_BYPASS; /* Bypass the PLL? */
+ r1 = r1 << 8; /* Shift it over */
+ r0 = r1 | r0; /* add them all together */
+
+ p0.h = hi(PLL_CTL);
+ p0.l = lo(PLL_CTL); /* Load the address */
+ cli r2; /* Disable interrupts */
+ ssync;
+ w[p0] = r0.l; /* Set the value */
+ idle; /* Wait for the PLL to stablize */
+ sti r2; /* Enable interrupts */
+
+.Lcheck_again:
+ p0.h = hi(PLL_STAT);
+ p0.l = lo(PLL_STAT);
+ R0 = W[P0](Z);
+ CC = BITTST(R0,5);
+ if ! CC jump .Lcheck_again;
+
+ /* Configure SCLK & CCLK Dividers */
+ r0 = (CONFIG_CCLK_ACT_DIV | CONFIG_SCLK_DIV);
+ p0.h = hi(PLL_DIV);
+ p0.l = lo(PLL_DIV);
+ w[p0] = r0.l;
+ ssync;
+
+ p0.l = lo(EBIU_SDRRC);
+ p0.h = hi(EBIU_SDRRC);
+ r0 = mem_SDRRC;
+ w[p0] = r0.l;
+ ssync;
+
+ p0.l = (EBIU_SDBCTL & 0xFFFF);
+ p0.h = (EBIU_SDBCTL >> 16); /* SDRAM Memory Bank Control Register */
+ r0 = mem_SDBCTL;
+ w[p0] = r0.l;
+ ssync;
+
+ P2.H = hi(EBIU_SDGCTL);
+ P2.L = lo(EBIU_SDGCTL);
+ R0 = [P2];
+ BITCLR (R0, 24);
+ p0.h = hi(EBIU_SDSTAT);
+ p0.l = lo(EBIU_SDSTAT);
+ r2.l = w[p0];
+ cc = bittst(r2,3);
+ if !cc jump .Lskip;
+ NOP;
+ BITSET (R0, 23);
+.Lskip:
+ [P2] = R0;
+ SSYNC;
+
+ R0.L = lo(mem_SDGCTL);
+ R0.H = hi(mem_SDGCTL);
+ R1 = [p2];
+ R1 = R1 | R0;
+ [P2] = R1;
+ SSYNC;
+
+ p0.h = hi(SIC_IWR);
+ p0.l = lo(SIC_IWR);
+ r0.l = lo(IWR_ENABLE_ALL);
+ r0.h = hi(IWR_ENABLE_ALL);
+ [p0] = r0;
+ SSYNC;
+
+ RTS;
+#endif /* CONFIG_BFIN_KERNEL_CLOCK */
+
+ENTRY(_bfin_reset)
+ /* No more interrupts to be handled*/
+ CLI R6;
+ SSYNC;
+
+#if defined(CONFIG_MTD_M25P80)
+/*
+ * The following code fix the SPI flash reboot issue,
+ * /CS signal of the chip which is using PF10 return to GPIO mode
+ */
+ p0.h = hi(PORTF_FER);
+ p0.l = lo(PORTF_FER);
+ r0.l = 0x0000;
+ w[p0] = r0.l;
+ SSYNC;
+
+/* /CS return to high */
+ p0.h = hi(PORTFIO);
+ p0.l = lo(PORTFIO);
+ r0.l = 0xFFFF;
+ w[p0] = r0.l;
+ SSYNC;
+
+/* Delay some time, This is necessary */
+ r1.h = 0;
+ r1.l = 0x400;
+ p1 = r1;
+ lsetup (_delay_lab1,_delay_lab1_end ) lc1 = p1;
+_delay_lab1:
+ r0.h = 0;
+ r0.l = 0x8000;
+ p0 = r0;
+ lsetup (_delay_lab0,_delay_lab0_end ) lc0 = p0;
+_delay_lab0:
+ nop;
+_delay_lab0_end:
+ nop;
+_delay_lab1_end:
+ nop;
+#endif
+
+ /* Clear the bits 13-15 in SWRST if they werent cleared */
+ p0.h = hi(SWRST);
+ p0.l = lo(SWRST);
+ csync;
+ r0.l = w[p0];
+
+ /* Clear the IMASK register */
+ p0.h = hi(IMASK);
+ p0.l = lo(IMASK);
+ r0 = 0x0;
+ [p0] = r0;
+
+ /* Clear the ILAT register */
+ p0.h = hi(ILAT);
+ p0.l = lo(ILAT);
+ r0 = [p0];
+ [p0] = r0;
+ SSYNC;
+
+ /* Disable the WDOG TIMER */
+ p0.h = hi(WDOG_CTL);
+ p0.l = lo(WDOG_CTL);
+ r0.l = 0xAD6;
+ w[p0] = r0.l;
+ SSYNC;
+
+ /* Clear the sticky bit incase it is already set */
+ p0.h = hi(WDOG_CTL);
+ p0.l = lo(WDOG_CTL);
+ r0.l = 0x8AD6;
+ w[p0] = r0.l;
+ SSYNC;
+
+ /* Program the count value */
+ R0.l = 0x100;
+ R0.h = 0x0;
+ P0.h = hi(WDOG_CNT);
+ P0.l = lo(WDOG_CNT);
+ [P0] = R0;
+ SSYNC;
+
+ /* Program WDOG_STAT if necessary */
+ P0.h = hi(WDOG_CTL);
+ P0.l = lo(WDOG_CTL);
+ R0 = W[P0](Z);
+ CC = BITTST(R0,1);
+ if !CC JUMP .LWRITESTAT;
+ CC = BITTST(R0,2);
+ if !CC JUMP .LWRITESTAT;
+ JUMP .LSKIP_WRITE;
+
+.LWRITESTAT:
+ /* When watch dog timer is enabled,
+ * a write to STAT will load the contents of CNT to STAT
+ */
+ R0 = 0x0000(z);
+ P0.h = hi(WDOG_STAT);
+ P0.l = lo(WDOG_STAT)
+ [P0] = R0;
+ SSYNC;
+
+.LSKIP_WRITE:
+ /* Enable the reset event */
+ P0.h = hi(WDOG_CTL);
+ P0.l = lo(WDOG_CTL);
+ R0 = W[P0](Z);
+ BITCLR(R0,1);
+ BITCLR(R0,2);
+ W[P0] = R0.L;
+ SSYNC;
+ NOP;
+
+ /* Enable the wdog counter */
+ R0 = W[P0](Z);
+ BITCLR(R0,4);
+ W[P0] = R0.L;
+ SSYNC;
+
+ IDLE;
+
+ RTS;
+
+.data
+
+/*
+ * Set up the usable of RAM stuff. Size of RAM is determined then
+ * an initial stack set up at the end.
+ */
+
+.align 4
+__rambase:
+.long 0
+__ramstart:
+.long 0
+__ramend:
+.long 0
diff --git a/arch/blackfin/mach-bf537/ints-priority.c b/arch/blackfin/mach-bf537/ints-priority.c
new file mode 100644
index 00000000000..fd6308eccbe
--- /dev/null
+++ b/arch/blackfin/mach-bf537/ints-priority.c
@@ -0,0 +1,74 @@
+/*
+ * File: arch/blackfin/mach-bf537/ints-priority.c
+ * Based on: arch/blackfin/mach-bf533/ints-priority.c
+ * Author: Michael Hennerich
+ *
+ * Created:
+ * Description: Set up the interupt priorities
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/module.h>
+#include <asm/blackfin.h>
+#include <asm/irq.h>
+
+void program_IAR(void)
+{
+ /* Program the IAR0 Register with the configured priority */
+ bfin_write_SIC_IAR0(((CONFIG_IRQ_PLL_WAKEUP - 7) << IRQ_PLL_WAKEUP_POS) |
+ ((CONFIG_IRQ_DMA_ERROR - 7) << IRQ_DMA_ERROR_POS) |
+ ((CONFIG_IRQ_ERROR - 7) << IRQ_ERROR_POS) |
+ ((CONFIG_IRQ_RTC - 7) << IRQ_RTC_POS) |
+ ((CONFIG_IRQ_PPI - 7) << IRQ_PPI_POS) |
+ ((CONFIG_IRQ_SPORT0_RX - 7) << IRQ_SPORT0_RX_POS) |
+ ((CONFIG_IRQ_SPORT0_TX - 7) << IRQ_SPORT0_TX_POS) |
+ ((CONFIG_IRQ_SPORT1_RX - 7) << IRQ_SPORT1_RX_POS));
+
+ bfin_write_SIC_IAR1(((CONFIG_IRQ_SPORT1_TX - 7) << IRQ_SPORT1_TX_POS) |
+ ((CONFIG_IRQ_TWI - 7) << IRQ_TWI_POS) |
+ ((CONFIG_IRQ_SPI - 7) << IRQ_SPI_POS) |
+ ((CONFIG_IRQ_UART0_RX - 7) << IRQ_UART0_RX_POS) |
+ ((CONFIG_IRQ_UART0_TX - 7) << IRQ_UART0_TX_POS) |
+ ((CONFIG_IRQ_UART1_RX - 7) << IRQ_UART1_RX_POS) |
+ ((CONFIG_IRQ_UART1_TX - 7) << IRQ_UART1_TX_POS) |
+ ((CONFIG_IRQ_CAN_RX - 7) << IRQ_CAN_RX_POS));
+
+ bfin_write_SIC_IAR2(((CONFIG_IRQ_CAN_TX - 7) << IRQ_CAN_TX_POS) |
+ ((CONFIG_IRQ_MAC_RX - 7) << IRQ_MAC_RX_POS) |
+ ((CONFIG_IRQ_MAC_TX - 7) << IRQ_MAC_TX_POS) |
+ ((CONFIG_IRQ_TMR0 - 7) << IRQ_TMR0_POS) |
+ ((CONFIG_IRQ_TMR1 - 7) << IRQ_TMR1_POS) |
+ ((CONFIG_IRQ_TMR2 - 7) << IRQ_TMR2_POS) |
+ ((CONFIG_IRQ_TMR3 - 7) << IRQ_TMR3_POS) |
+ ((CONFIG_IRQ_TMR4 - 7) << IRQ_TMR4_POS));
+
+ bfin_write_SIC_IAR3(((CONFIG_IRQ_TMR5 - 7) << IRQ_TMR5_POS) |
+ ((CONFIG_IRQ_TMR6 - 7) << IRQ_TMR6_POS) |
+ ((CONFIG_IRQ_TMR7 - 7) << IRQ_TMR7_POS) |
+ ((CONFIG_IRQ_PROG_INTA - 7) << IRQ_PROG_INTA_POS) |
+ ((CONFIG_IRQ_PORTG_INTB - 7) << IRQ_PORTG_INTB_POS) |
+ ((CONFIG_IRQ_MEM_DMA0 - 7) << IRQ_MEM_DMA0_POS) |
+ ((CONFIG_IRQ_MEM_DMA1 - 7) << IRQ_MEM_DMA1_POS) |
+ ((CONFIG_IRQ_WATCH - 7) << IRQ_WATCH_POS));
+
+ SSYNC();
+}
diff --git a/arch/blackfin/mach-bf561/Kconfig b/arch/blackfin/mach-bf561/Kconfig
new file mode 100644
index 00000000000..0a17c4cf005
--- /dev/null
+++ b/arch/blackfin/mach-bf561/Kconfig
@@ -0,0 +1,222 @@
+if BF561
+
+menu "BF561 Specific Configuration"
+
+comment "Core B Support"
+
+menu "Core B Support"
+
+config BF561_COREB
+ bool "Enable Core B support"
+ default y
+
+config BF561_COREB_RESET
+ bool "Enable Core B reset support"
+ default n
+ help
+ This requires code in the application that is loaded
+ into Core B. In order to reset, the application needs
+ to install an interrupt handler for Supplemental
+ Interrupt 0, that sets RETI to 0xff600000 and writes
+ bit 11 of SICB_SYSCR when bit 5 of SICA_SYSCR is 0.
+ This causes Core B to stall when Supplemental Interrupt
+ 0 is set, and will reset PC to 0xff600000 when
+ COREB_SRAM_INIT is cleared.
+
+endmenu
+
+comment "Interrupt Priority Assignment"
+
+menu "Priority"
+
+config IRQ_PLL_WAKEUP
+ int "PLL Wakeup Interrupt"
+ default 7
+config IRQ_DMA1_ERROR
+ int "DMA1 Error (generic)"
+ default 7
+config IRQ_DMA2_ERROR
+ int "DMA2 Error (generic)"
+ default 7
+config IRQ_IMDMA_ERROR
+ int "IMDMA Error (generic)"
+ default 7
+config IRQ_PPI0_ERROR
+ int "PPI0 Error Interrupt"
+ default 7
+config IRQ_PPI1_ERROR
+ int "PPI1 Error Interrupt"
+ default 7
+config IRQ_SPORT0_ERROR
+ int "SPORT0 Error Interrupt"
+ default 7
+config IRQ_SPORT1_ERROR
+ int "SPORT1 Error Interrupt"
+ default 7
+config IRQ_SPI_ERROR
+ int "SPI Error Interrupt"
+ default 7
+config IRQ_UART_ERROR
+ int "UART Error Interrupt"
+ default 7
+config IRQ_RESERVED_ERROR
+ int "Reserved Interrupt"
+ default 7
+config IRQ_DMA1_0
+ int "DMA1 0 Interrupt(PPI1)"
+ default 8
+config IRQ_DMA1_1
+ int "DMA1 1 Interrupt(PPI2)"
+ default 8
+config IRQ_DMA1_2
+ int "DMA1 2 Interrupt"
+ default 8
+config IRQ_DMA1_3
+ int "DMA1 3 Interrupt"
+ default 8
+config IRQ_DMA1_4
+ int "DMA1 4 Interrupt"
+ default 8
+config IRQ_DMA1_5
+ int "DMA1 5 Interrupt"
+ default 8
+config IRQ_DMA1_6
+ int "DMA1 6 Interrupt"
+ default 8
+config IRQ_DMA1_7
+ int "DMA1 7 Interrupt"
+ default 8
+config IRQ_DMA1_8
+ int "DMA1 8 Interrupt"
+ default 8
+config IRQ_DMA1_9
+ int "DMA1 9 Interrupt"
+ default 8
+config IRQ_DMA1_10
+ int "DMA1 10 Interrupt"
+ default 8
+config IRQ_DMA1_11
+ int "DMA1 11 Interrupt"
+ default 8
+config IRQ_DMA2_0
+ int "DMA2 0 (SPORT0 RX)"
+ default 9
+config IRQ_DMA2_1
+ int "DMA2 1 (SPORT0 TX)"
+ default 9
+config IRQ_DMA2_2
+ int "DMA2 2 (SPORT1 RX)"
+ default 9
+config IRQ_DMA2_3
+ int "DMA2 3 (SPORT2 TX)"
+ default 9
+config IRQ_DMA2_4
+ int "DMA2 4 (SPI)"
+ default 9
+config IRQ_DMA2_5
+ int "DMA2 5 (UART RX)"
+ default 9
+config IRQ_DMA2_6
+ int "DMA2 6 (UART TX)"
+ default 9
+config IRQ_DMA2_7
+ int "DMA2 7 Interrupt"
+ default 9
+config IRQ_DMA2_8
+ int "DMA2 8 Interrupt"
+ default 9
+config IRQ_DMA2_9
+ int "DMA2 9 Interrupt"
+ default 9
+config IRQ_DMA2_10
+ int "DMA2 10 Interrupt"
+ default 9
+config IRQ_DMA2_11
+ int "DMA2 11 Interrupt"
+ default 9
+config IRQ_TIMER0
+ int "TIMER 0 Interrupt"
+ default 10
+config IRQ_TIMER1
+ int "TIMER 1 Interrupt"
+ default 10
+config IRQ_TIMER2
+ int "TIMER 2 Interrupt"
+ default 10
+config IRQ_TIMER3
+ int "TIMER 3 Interrupt"
+ default 10
+config IRQ_TIMER4
+ int "TIMER 4 Interrupt"
+ default 10
+config IRQ_TIMER5
+ int "TIMER 5 Interrupt"
+ default 10
+config IRQ_TIMER6
+ int "TIMER 6 Interrupt"
+ default 10
+config IRQ_TIMER7
+ int "TIMER 7 Interrupt"
+ default 10
+config IRQ_TIMER8
+ int "TIMER 8 Interrupt"
+ default 10
+config IRQ_TIMER9
+ int "TIMER 9 Interrupt"
+ default 10
+config IRQ_TIMER10
+ int "TIMER 10 Interrupt"
+ default 10
+config IRQ_TIMER11
+ int "TIMER 11 Interrupt"
+ default 10
+config IRQ_PROG0_INTA
+ int "Programmable Flags0 A (8)"
+ default 11
+config IRQ_PROG0_INTB
+ int "Programmable Flags0 B (8)"
+ default 11
+config IRQ_PROG1_INTA
+ int "Programmable Flags1 A (8)"
+ default 11
+config IRQ_PROG1_INTB
+ int "Programmable Flags1 B (8)"
+ default 11
+config IRQ_PROG2_INTA
+ int "Programmable Flags2 A (8)"
+ default 11
+config IRQ_PROG2_INTB
+ int "Programmable Flags2 B (8)"
+ default 11
+config IRQ_DMA1_WRRD0
+ int "MDMA1 0 write/read INT"
+ default 8
+config IRQ_DMA1_WRRD1
+ int "MDMA1 1 write/read INT"
+ default 8
+config IRQ_DMA2_WRRD0
+ int "MDMA2 0 write/read INT"
+ default 9
+config IRQ_DMA2_WRRD1
+ int "MDMA2 1 write/read INT"
+ default 9
+config IRQ_IMDMA_WRRD0
+ int "IMDMA 0 write/read INT"
+ default 12
+config IRQ_IMDMA_WRRD1
+ int "IMDMA 1 write/read INT"
+ default 12
+config IRQ_WDTIMER
+ int "Watch Dog Timer"
+ default 13
+
+ help
+ Enter the priority numbers between 7-13 ONLY. Others are Reserved.
+ This applies to all the above. It is not recommended to assign the
+ highest priority number 7 to UART or any other device.
+
+endmenu
+
+endmenu
+
+endif
diff --git a/arch/blackfin/mach-bf561/Makefile b/arch/blackfin/mach-bf561/Makefile
new file mode 100644
index 00000000000..57f475a5516
--- /dev/null
+++ b/arch/blackfin/mach-bf561/Makefile
@@ -0,0 +1,9 @@
+#
+# arch/blackfin/mach-bf561/Makefile
+#
+
+extra-y := head.o
+
+obj-y := ints-priority.o
+
+obj-$(CONFIG_BF561_COREB) += coreb.o
diff --git a/arch/blackfin/mach-bf561/boards/Makefile b/arch/blackfin/mach-bf561/boards/Makefile
new file mode 100644
index 00000000000..886edc739ab
--- /dev/null
+++ b/arch/blackfin/mach-bf561/boards/Makefile
@@ -0,0 +1,7 @@
+#
+# arch/blackfin/mach-bf561/boards/Makefile
+#
+
+obj-$(CONFIG_GENERIC_BOARD) += generic_board.o
+obj-$(CONFIG_BFIN561_EZKIT) += ezkit.o
+obj-$(CONFIG_BFIN561_BLUETECHNIX_CM) += cm_bf561.o
diff --git a/arch/blackfin/mach-bf561/boards/cm_bf561.c b/arch/blackfin/mach-bf561/boards/cm_bf561.c
new file mode 100644
index 00000000000..6824e956d15
--- /dev/null
+++ b/arch/blackfin/mach-bf561/boards/cm_bf561.c
@@ -0,0 +1,289 @@
+/*
+ * File: arch/blackfin/mach-bf533/boards/cm_bf561.c
+ * Based on: arch/blackfin/mach-bf533/boards/ezkit.c
+ * Author: Aidan Williams <aidan@nicta.com.au> Copright 2005
+ *
+ * Created: 2006
+ * Description: Board description file
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+#include <linux/usb_isp1362.h>
+#include <asm/irq.h>
+#include <asm/bfin5xx_spi.h>
+
+/*
+ * Name the Board for the /proc/cpuinfo
+ */
+char *bfin_board_name = "Bluetechnix CM BF561";
+
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+/* all SPI perpherals info goes here */
+
+#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
+static struct mtd_partition bfin_spi_flash_partitions[] = {
+ {
+ .name = "bootloader",
+ .size = 0x00020000,
+ .offset = 0,
+ .mask_flags = MTD_CAP_ROM
+ },{
+ .name = "kernel",
+ .size = 0xe0000,
+ .offset = 0x20000
+ },{
+ .name = "file system",
+ .size = 0x700000,
+ .offset = 0x00100000,
+ }
+};
+
+static struct flash_platform_data bfin_spi_flash_data = {
+ .name = "m25p80",
+ .parts = bfin_spi_flash_partitions,
+ .nr_parts = ARRAY_SIZE(bfin_spi_flash_partitions),
+ .type = "m25p64",
+};
+
+/* SPI flash chip (m25p64) */
+static struct bfin5xx_spi_chip spi_flash_chip_info = {
+ .enable_dma = 0, /* use dma transfer with this chip*/
+ .bits_per_word = 8,
+};
+#endif
+
+#if defined(CONFIG_SPI_ADC_BF533) || defined(CONFIG_SPI_ADC_BF533_MODULE)
+/* SPI ADC chip */
+static struct bfin5xx_spi_chip spi_adc_chip_info = {
+ .enable_dma = 1, /* use dma transfer with this chip*/
+ .bits_per_word = 16,
+};
+#endif
+
+#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
+ .enable_dma = 0,
+ .bits_per_word = 16,
+};
+#endif
+
+#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE)
+static struct bfin5xx_spi_chip ad9960_spi_chip_info = {
+ .enable_dma = 0,
+ .bits_per_word = 16,
+};
+#endif
+
+#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE)
+static struct bfin5xx_spi_chip spi_mmc_chip_info = {
+ .enable_dma = 1,
+ .bits_per_word = 8,
+};
+#endif
+
+static struct spi_board_info bfin_spi_board_info[] __initdata = {
+#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
+ {
+ /* the modalias must be the same as spi device driver name */
+ .modalias = "m25p80", /* Name of spi_driver for this device */
+ .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1, /* Framework bus number */
+ .chip_select = 1, /* Framework chip select. On STAMP537 it is SPISSEL1*/
+ .platform_data = &bfin_spi_flash_data,
+ .controller_data = &spi_flash_chip_info,
+ .mode = SPI_MODE_3,
+ },
+#endif
+
+#if defined(CONFIG_SPI_ADC_BF533) || defined(CONFIG_SPI_ADC_BF533_MODULE)
+ {
+ .modalias = "bfin_spi_adc", /* Name of spi_driver for this device */
+ .max_speed_hz = 6250000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1, /* Framework bus number */
+ .chip_select = 1, /* Framework chip select. */
+ .platform_data = NULL, /* No spi_driver specific config */
+ .controller_data = &spi_adc_chip_info,
+ },
+#endif
+
+#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+ {
+ .modalias = "ad1836-spi",
+ .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1,
+ .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT,
+ .controller_data = &ad1836_spi_chip_info,
+ },
+#endif
+#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE)
+ {
+ .modalias = "ad9960-spi",
+ .max_speed_hz = 10000000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1,
+ .chip_select = 1,
+ .controller_data = &ad9960_spi_chip_info,
+ },
+#endif
+#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE)
+ {
+ .modalias = "spi_mmc",
+ .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1,
+ .chip_select = CONFIG_SPI_MMC_CS_CHAN,
+ .platform_data = NULL,
+ .controller_data = &spi_mmc_chip_info,
+ .mode = SPI_MODE_3,
+ },
+#endif
+};
+
+/* SPI controller data */
+static struct bfin5xx_spi_master spi_bfin_master_info = {
+ .num_chipselect = 8,
+ .enable_dma = 1, /* master has the ability to do dma transfer */
+};
+
+static struct platform_device spi_bfin_master_device = {
+ .name = "bfin-spi-master",
+ .id = 1, /* Bus number */
+ .dev = {
+ .platform_data = &spi_bfin_master_info, /* Passed to driver */
+ },
+};
+#endif /* spi master and devices */
+
+
+#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+
+static struct resource smc91x_resources[] = {
+ {
+ .name = "smc91x-regs",
+ .start = 0x28000300,
+ .end = 0x28000300 + 16,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = IRQ_PF0,
+ .end = IRQ_PF0,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ },
+};
+static struct platform_device smc91x_device = {
+ .name = "smc91x",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(smc91x_resources),
+ .resource = smc91x_resources,
+};
+#endif
+
+#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
+static struct resource isp1362_hcd_resources[] = {
+ {
+ .start = 0x24008000,
+ .end = 0x24008000,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = 0x24008004,
+ .end = 0x24008004,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = IRQ_PF47,
+ .end = IRQ_PF47,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ },
+};
+
+static struct isp1362_platform_data isp1362_priv = {
+ .sel15Kres = 1,
+ .clknotstop = 0,
+ .oc_enable = 0,
+ .int_act_high = 0,
+ .int_edge_triggered = 0,
+ .remote_wakeup_connected = 0,
+ .no_power_switching = 1,
+ .power_switching_mode = 0,
+};
+
+static struct platform_device isp1362_hcd_device = {
+ .name = "isp1362-hcd",
+ .id = 0,
+ .dev = {
+ .platform_data = &isp1362_priv,
+ },
+ .num_resources = ARRAY_SIZE(isp1362_hcd_resources),
+ .resource = isp1362_hcd_resources,
+};
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
+static struct resource bfin_uart_resources[] = {
+ {
+ .start = 0xFFC00400,
+ .end = 0xFFC004FF,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device bfin_uart_device = {
+ .name = "bfin-uart",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(bfin_uart_resources),
+ .resource = bfin_uart_resources,
+};
+#endif
+
+static struct platform_device *cm_bf561_devices[] __initdata = {
+
+#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
+ &bfin_uart_device,
+#endif
+
+#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
+ &isp1362_hcd_device,
+#endif
+
+#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+ &smc91x_device,
+#endif
+
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+ &spi_bfin_master_device,
+#endif
+
+};
+
+static int __init cm_bf561_init(void)
+{
+ printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__);
+ platform_add_devices(cm_bf561_devices, ARRAY_SIZE(cm_bf561_devices));
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+ spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info));
+#endif
+ return 0;
+}
+
+arch_initcall(cm_bf561_init);
diff --git a/arch/blackfin/mach-bf561/boards/ezkit.c b/arch/blackfin/mach-bf561/boards/ezkit.c
new file mode 100644
index 00000000000..14eb4f9a68e
--- /dev/null
+++ b/arch/blackfin/mach-bf561/boards/ezkit.c
@@ -0,0 +1,147 @@
+/*
+ * File: arch/blackfin/mach-bf561/ezkit.c
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <asm/irq.h>
+#include <asm/bfin5xx_spi.h>
+
+/*
+ * Name the Board for the /proc/cpuinfo
+ */
+char *bfin_board_name = "ADDS-BF561-EZKIT";
+
+/*
+ * USB-LAN EzExtender board
+ * Driver needs to know address, irq and flag pin.
+ */
+#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+static struct resource smc91x_resources[] = {
+ {
+ .name = "smc91x-regs",
+ .start = 0x2C010300,
+ .end = 0x2C010300 + 16,
+ .flags = IORESOURCE_MEM,
+ },{
+
+ .start = IRQ_PF9,
+ .end = IRQ_PF9,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ },
+};
+
+static struct platform_device smc91x_device = {
+ .name = "smc91x",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(smc91x_resources),
+ .resource = smc91x_resources,
+};
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
+static struct resource bfin_uart_resources[] = {
+ {
+ .start = 0xFFC00400,
+ .end = 0xFFC004FF,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device bfin_uart_device = {
+ .name = "bfin-uart",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(bfin_uart_resources),
+ .resource = bfin_uart_resources,
+};
+#endif
+
+#ifdef CONFIG_SPI_BFIN
+#if defined(CONFIG_SND_BLACKFIN_AD1836) \
+ || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
+ .enable_dma = 0,
+ .bits_per_word = 16,
+};
+#endif
+#endif
+
+/* SPI controller data */
+static struct bfin5xx_spi_master spi_bfin_master_info = {
+ .num_chipselect = 8,
+ .enable_dma = 1, /* master has the ability to do dma transfer */
+};
+
+static struct platform_device spi_bfin_master_device = {
+ .name = "bfin-spi-master",
+ .id = 1, /* Bus number */
+ .dev = {
+ .platform_data = &spi_bfin_master_info, /* Passed to driver */
+ },
+};
+
+static struct spi_board_info bfin_spi_board_info[] __initdata = {
+#if defined(CONFIG_SND_BLACKFIN_AD1836) \
+ || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+ {
+ .modalias = "ad1836-spi",
+ .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1,
+ .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT,
+ .controller_data = &ad1836_spi_chip_info,
+ },
+#endif
+};
+
+static struct platform_device *ezkit_devices[] __initdata = {
+#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+ &smc91x_device,
+#endif
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+ &spi_bfin_master_device,
+#endif
+#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
+ &bfin_uart_device,
+#endif
+};
+
+static int __init ezkit_init(void)
+{
+ int ret;
+
+ printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__);
+ ret = platform_add_devices(ezkit_devices,
+ ARRAY_SIZE(ezkit_devices));
+ if (ret < 0)
+ return ret;
+ return spi_register_board_info(bfin_spi_board_info,
+ ARRAY_SIZE(bfin_spi_board_info));
+}
+
+arch_initcall(ezkit_init);
diff --git a/arch/blackfin/mach-bf561/boards/generic_board.c b/arch/blackfin/mach-bf561/boards/generic_board.c
new file mode 100644
index 00000000000..585ecdd2f6a
--- /dev/null
+++ b/arch/blackfin/mach-bf561/boards/generic_board.c
@@ -0,0 +1,82 @@
+/*
+ * File: arch/blackfin/mach-bf561/generic_board.c
+ * Based on: arch/blackfin/mach-bf533/ezkit.c
+ * Author: Aidan Williams <aidan@nicta.com.au>
+ *
+ * Created:
+ * Description:
+ *
+ * Modified:
+ * Copyright 2005 National ICT Australia (NICTA)
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <asm/irq.h>
+
+char *bfin_board_name = "UNKNOWN BOARD";
+
+/*
+ * Driver needs to know address, irq and flag pin.
+ */
+#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+static struct resource smc91x_resources[] = {
+ {
+ .start = 0x2C010300,
+ .end = 0x2C010300 + 16,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = IRQ_PROG_INTB,
+ .end = IRQ_PROG_INTB,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ },{
+ /*
+ * denotes the flag pin and is used directly if
+ * CONFIG_IRQCHIP_DEMUX_GPIO is defined.
+ */
+ .start = IRQ_PF9,
+ .end = IRQ_PF9,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ },
+};
+
+static struct platform_device smc91x_device = {
+ .name = "smc91x",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(smc91x_resources),
+ .resource = smc91x_resources,
+};
+#endif
+
+static struct platform_device *generic_board_devices[] __initdata = {
+#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+ &smc91x_device,
+#endif
+};
+
+static int __init generic_board_init(void)
+{
+ printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__);
+ return platform_add_devices(generic_board_devices,
+ ARRAY_SIZE(generic_board_devices));
+}
+
+arch_initcall(generic_board_init);
diff --git a/arch/blackfin/mach-bf561/coreb.c b/arch/blackfin/mach-bf561/coreb.c
new file mode 100644
index 00000000000..b28582fe083
--- /dev/null
+++ b/arch/blackfin/mach-bf561/coreb.c
@@ -0,0 +1,402 @@
+/*
+ * File: arch/blackfin/mach-bf561/coreb.c
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description: Handle CoreB on a BF561
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/mm.h>
+#include <linux/miscdevice.h>
+#include <linux/device.h>
+#include <linux/ioport.h>
+#include <linux/module.h>
+#include <asm/dma.h>
+#include <asm/uaccess.h>
+
+#define MODULE_VER "v0.1"
+
+static spinlock_t coreb_lock;
+static wait_queue_head_t coreb_dma_wait;
+
+#define COREB_IS_OPEN 0x00000001
+#define COREB_IS_RUNNING 0x00000010
+
+#define CMD_COREB_INDEX 1
+#define CMD_COREB_START 2
+#define CMD_COREB_STOP 3
+#define CMD_COREB_RESET 4
+
+#define COREB_MINOR 229
+
+static unsigned long coreb_status = 0;
+static unsigned long coreb_base = 0xff600000;
+static unsigned long coreb_size = 0x4000;
+int coreb_dma_done;
+
+static loff_t coreb_lseek(struct file *file, loff_t offset, int origin);
+static ssize_t coreb_read(struct file *file, char *buf, size_t count,
+ loff_t * ppos);
+static ssize_t coreb_write(struct file *file, const char *buf, size_t count,
+ loff_t * ppos);
+static int coreb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
+ unsigned long arg);
+static int coreb_open(struct inode *inode, struct file *file);
+static int coreb_release(struct inode *inode, struct file *file);
+
+static irqreturn_t coreb_dma_interrupt(int irq, void *dev_id)
+{
+ clear_dma_irqstat(CH_MEM_STREAM2_DEST);
+ coreb_dma_done = 1;
+ wake_up_interruptible(&coreb_dma_wait);
+ return IRQ_HANDLED;
+}
+
+static ssize_t coreb_write(struct file *file, const char *buf, size_t count,
+ loff_t * ppos)
+{
+ unsigned long p = *ppos;
+ ssize_t wrote = 0;
+
+ if (p + count > coreb_size)
+ return -EFAULT;
+
+ while (count > 0) {
+ int len = count;
+
+ if (len > PAGE_SIZE)
+ len = PAGE_SIZE;
+
+ coreb_dma_done = 0;
+
+ /* Source Channel */
+ set_dma_start_addr(CH_MEM_STREAM2_SRC, (unsigned long)buf);
+ set_dma_x_count(CH_MEM_STREAM2_SRC, len);
+ set_dma_x_modify(CH_MEM_STREAM2_SRC, sizeof(char));
+ set_dma_config(CH_MEM_STREAM2_SRC, RESTART);
+ /* Destination Channel */
+ set_dma_start_addr(CH_MEM_STREAM2_DEST, coreb_base + p);
+ set_dma_x_count(CH_MEM_STREAM2_DEST, len);
+ set_dma_x_modify(CH_MEM_STREAM2_DEST, sizeof(char));
+ set_dma_config(CH_MEM_STREAM2_DEST, WNR | RESTART | DI_EN);
+
+ enable_dma(CH_MEM_STREAM2_SRC);
+ enable_dma(CH_MEM_STREAM2_DEST);
+
+ wait_event_interruptible(coreb_dma_wait, coreb_dma_done);
+
+ disable_dma(CH_MEM_STREAM2_SRC);
+ disable_dma(CH_MEM_STREAM2_DEST);
+
+ count -= len;
+ wrote += len;
+ buf += len;
+ p += len;
+ }
+ *ppos = p;
+ return wrote;
+}
+
+static ssize_t coreb_read(struct file *file, char *buf, size_t count,
+ loff_t * ppos)
+{
+ unsigned long p = *ppos;
+ ssize_t read = 0;
+
+ if ((p + count) > coreb_size)
+ return -EFAULT;
+
+ while (count > 0) {
+ int len = count;
+
+ if (len > PAGE_SIZE)
+ len = PAGE_SIZE;
+
+ coreb_dma_done = 0;
+
+ /* Source Channel */
+ set_dma_start_addr(CH_MEM_STREAM2_SRC, coreb_base + p);
+ set_dma_x_count(CH_MEM_STREAM2_SRC, len);
+ set_dma_x_modify(CH_MEM_STREAM2_SRC, sizeof(char));
+ set_dma_config(CH_MEM_STREAM2_SRC, RESTART);
+ /* Destination Channel */
+ set_dma_start_addr(CH_MEM_STREAM2_DEST, (unsigned long)buf);
+ set_dma_x_count(CH_MEM_STREAM2_DEST, len);
+ set_dma_x_modify(CH_MEM_STREAM2_DEST, sizeof(char));
+ set_dma_config(CH_MEM_STREAM2_DEST, WNR | RESTART | DI_EN);
+
+ enable_dma(CH_MEM_STREAM2_SRC);
+ enable_dma(CH_MEM_STREAM2_DEST);
+
+ wait_event_interruptible(coreb_dma_wait, coreb_dma_done);
+
+ disable_dma(CH_MEM_STREAM2_SRC);
+ disable_dma(CH_MEM_STREAM2_DEST);
+
+ count -= len;
+ read += len;
+ buf += len;
+ p += len;
+ }
+
+ return read;
+}
+
+static loff_t coreb_lseek(struct file *file, loff_t offset, int origin)
+{
+ loff_t ret;
+
+ mutex_lock(&file->f_dentry->d_inode->i_mutex);
+
+ switch (origin) {
+ case 0 /* SEEK_SET */ :
+ if (offset < coreb_size) {
+ file->f_pos = offset;
+ ret = file->f_pos;
+ } else
+ ret = -EINVAL;
+ break;
+ case 1 /* SEEK_CUR */ :
+ if ((offset + file->f_pos) < coreb_size) {
+ file->f_pos += offset;
+ ret = file->f_pos;
+ } else
+ ret = -EINVAL;
+ default:
+ ret = -EINVAL;
+ }
+ mutex_unlock(&file->f_dentry->d_inode->i_mutex);
+ return ret;
+}
+
+static int coreb_open(struct inode *inode, struct file *file)
+{
+ spin_lock_irq(&coreb_lock);
+
+ if (coreb_status & COREB_IS_OPEN)
+ goto out_busy;
+
+ coreb_status |= COREB_IS_OPEN;
+
+ spin_unlock_irq(&coreb_lock);
+ return 0;
+
+ out_busy:
+ spin_unlock_irq(&coreb_lock);
+ return -EBUSY;
+}
+
+static int coreb_release(struct inode *inode, struct file *file)
+{
+ spin_lock_irq(&coreb_lock);
+ coreb_status &= ~COREB_IS_OPEN;
+ spin_unlock_irq(&coreb_lock);
+ return 0;
+}
+
+static int coreb_ioctl(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ int retval = 0;
+ int coreb_index = 0;
+
+ switch (cmd) {
+ case CMD_COREB_INDEX:
+ if (copy_from_user(&coreb_index, (int *)arg, sizeof(int))) {
+ retval = -EFAULT;
+ break;
+ }
+
+ spin_lock_irq(&coreb_lock);
+ switch (coreb_index) {
+ case 0:
+ coreb_base = 0xff600000;
+ coreb_size = 0x4000;
+ break;
+ case 1:
+ coreb_base = 0xff610000;
+ coreb_size = 0x4000;
+ break;
+ case 2:
+ coreb_base = 0xff500000;
+ coreb_size = 0x8000;
+ break;
+ case 3:
+ coreb_base = 0xff400000;
+ coreb_size = 0x8000;
+ break;
+ default:
+ retval = -EINVAL;
+ break;
+ }
+ spin_unlock_irq(&coreb_lock);
+
+ mutex_lock(&file->f_dentry->d_inode->i_mutex);
+ file->f_pos = 0;
+ mutex_unlock(&file->f_dentry->d_inode->i_mutex);
+ break;
+ case CMD_COREB_START:
+ spin_lock_irq(&coreb_lock);
+ if (coreb_status & COREB_IS_RUNNING) {
+ retval = -EBUSY;
+ break;
+ }
+ printk(KERN_INFO "Starting Core B\n");
+ coreb_status |= COREB_IS_RUNNING;
+ bfin_write_SICA_SYSCR(bfin_read_SICA_SYSCR() & ~0x0020);
+ SSYNC();
+ spin_lock_irq(&coreb_lock);
+ break;
+#if defined(CONFIG_BF561_COREB_RESET)
+ case CMD_COREB_STOP:
+ spin_lock_irq(&coreb_lock);
+ printk(KERN_INFO "Stopping Core B\n");
+ bfin_write_SICA_SYSCR(bfin_read_SICA_SYSCR() | 0x0020);
+ bfin_write_SICB_SYSCR(bfin_read_SICB_SYSCR() | 0x0080);
+ coreb_status &= ~COREB_IS_RUNNING;
+ spin_lock_irq(&coreb_lock);
+ break;
+ case CMD_COREB_RESET:
+ printk(KERN_INFO "Resetting Core B\n");
+ bfin_write_SICB_SYSCR(bfin_read_SICB_SYSCR() | 0x0080);
+ break;
+#endif
+ }
+
+ return retval;
+}
+
+static struct file_operations coreb_fops = {
+ .owner = THIS_MODULE,
+ .llseek = coreb_lseek,
+ .read = coreb_read,
+ .write = coreb_write,
+ .ioctl = coreb_ioctl,
+ .open = coreb_open,
+ .release = coreb_release
+};
+
+static struct miscdevice coreb_dev = {
+ COREB_MINOR,
+ "coreb",
+ &coreb_fops
+};
+
+static ssize_t coreb_show_status(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ return sprintf(buf,
+ "Base Address:\t0x%08lx\n"
+ "Core B is %s\n"
+ "SICA_SYSCR:\t%04x\n"
+ "SICB_SYSCR:\t%04x\n"
+ "\n"
+ "IRQ Status:\tCore A\t\tCore B\n"
+ "ISR0:\t\t%08x\t\t%08x\n"
+ "ISR1:\t\t%08x\t\t%08x\n"
+ "IMASK0:\t\t%08x\t\t%08x\n"
+ "IMASK1:\t\t%08x\t\t%08x\n",
+ coreb_base,
+ coreb_status & COREB_IS_RUNNING ? "running" : "stalled",
+ bfin_read_SICA_SYSCR(), bfin_read_SICB_SYSCR(),
+ bfin_read_SICA_ISR0(), bfin_read_SICB_ISR0(),
+ bfin_read_SICA_ISR1(), bfin_read_SICB_ISR0(),
+ bfin_read_SICA_IMASK0(), bfin_read_SICB_IMASK0(),
+ bfin_read_SICA_IMASK1(), bfin_read_SICB_IMASK1());
+}
+
+static DEVICE_ATTR(coreb_status, S_IRUGO, coreb_show_status, NULL);
+
+int __init bf561_coreb_init(void)
+{
+ init_waitqueue_head(&coreb_dma_wait);
+
+ spin_lock_init(&coreb_lock);
+ /* Request the core memory regions for Core B */
+ if (request_mem_region(0xff600000, 0x4000,
+ "Core B - Instruction SRAM") == NULL)
+ goto exit;
+
+ if (request_mem_region(0xFF610000, 0x4000,
+ "Core B - Instruction SRAM") == NULL)
+ goto release_instruction_a_sram;
+
+ if (request_mem_region(0xFF500000, 0x8000,
+ "Core B - Data Bank B SRAM") == NULL)
+ goto release_instruction_b_sram;
+
+ if (request_mem_region(0xff400000, 0x8000,
+ "Core B - Data Bank A SRAM") == NULL)
+ goto release_data_b_sram;
+
+ if (request_dma(CH_MEM_STREAM2_DEST, "Core B - DMA Destination") < 0)
+ goto release_data_a_sram;
+
+ if (request_dma(CH_MEM_STREAM2_SRC, "Core B - DMA Source") < 0)
+ goto release_dma_dest;
+
+ set_dma_callback(CH_MEM_STREAM2_DEST, coreb_dma_interrupt, NULL);
+
+ misc_register(&coreb_dev);
+
+ if (device_create_file(coreb_dev.this_device, &dev_attr_coreb_status))
+ goto release_dma_src;
+
+ printk(KERN_INFO "BF561 Core B driver %s initialized.\n", MODULE_VER);
+ return 0;
+
+ release_dma_src:
+ free_dma(CH_MEM_STREAM2_SRC);
+ release_dma_dest:
+ free_dma(CH_MEM_STREAM2_DEST);
+ release_data_a_sram:
+ release_mem_region(0xff400000, 0x8000);
+ release_data_b_sram:
+ release_mem_region(0xff500000, 0x8000);
+ release_instruction_b_sram:
+ release_mem_region(0xff610000, 0x4000);
+ release_instruction_a_sram:
+ release_mem_region(0xff600000, 0x4000);
+ exit:
+ return -ENOMEM;
+}
+
+void __exit bf561_coreb_exit(void)
+{
+ device_remove_file(coreb_dev.this_device, &dev_attr_coreb_status);
+ misc_deregister(&coreb_dev);
+
+ release_mem_region(0xff610000, 0x4000);
+ release_mem_region(0xff600000, 0x4000);
+ release_mem_region(0xff500000, 0x8000);
+ release_mem_region(0xff400000, 0x8000);
+
+ free_dma(CH_MEM_STREAM2_DEST);
+ free_dma(CH_MEM_STREAM2_SRC);
+}
+
+module_init(bf561_coreb_init);
+module_exit(bf561_coreb_exit);
+
+MODULE_AUTHOR("Bas Vermeulen <bvermeul@blackstar.xs4all.nl>");
+MODULE_DESCRIPTION("BF561 Core B Support");
diff --git a/arch/blackfin/mach-bf561/head.S b/arch/blackfin/mach-bf561/head.S
new file mode 100644
index 00000000000..7bca478526b
--- /dev/null
+++ b/arch/blackfin/mach-bf561/head.S
@@ -0,0 +1,512 @@
+/*
+ * File: arch/blackfin/mach-bf561/head.S
+ * Based on: arch/blackfin/mach-bf533/head.S
+ * Author:
+ *
+ * Created:
+ * Description: BF561 startup file
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/linkage.h>
+#include <asm/blackfin.h>
+#if CONFIG_BFIN_KERNEL_CLOCK
+#include <asm/mach/mem_init.h>
+#endif
+
+.global __rambase
+.global __ramstart
+.global __ramend
+.extern ___bss_stop
+.extern ___bss_start
+.extern _bf53x_relocate_l1_mem
+
+#define INITIAL_STACK 0xFFB01000
+
+.text
+
+ENTRY(__start)
+ENTRY(__stext)
+ /* R0: argument of command line string, passed from uboot, save it */
+ R7 = R0;
+ /* Set the SYSCFG register */
+ R0 = 0x36;
+ SYSCFG = R0; /*Enable Cycle Counter and Nesting Of Interrupts(3rd Bit)*/
+ R0 = 0;
+
+ /*Clear Out All the data and pointer Registers*/
+ R1 = R0;
+ R2 = R0;
+ R3 = R0;
+ R4 = R0;
+ R5 = R0;
+ R6 = R0;
+
+ P0 = R0;
+ P1 = R0;
+ P2 = R0;
+ P3 = R0;
+ P4 = R0;
+ P5 = R0;
+
+ LC0 = r0;
+ LC1 = r0;
+ L0 = r0;
+ L1 = r0;
+ L2 = r0;
+ L3 = r0;
+
+ /* Clear Out All the DAG Registers*/
+ B0 = r0;
+ B1 = r0;
+ B2 = r0;
+ B3 = r0;
+
+ I0 = r0;
+ I1 = r0;
+ I2 = r0;
+ I3 = r0;
+
+ M0 = r0;
+ M1 = r0;
+ M2 = r0;
+ M3 = r0;
+
+ /* Turn off the icache */
+ p0.l = (IMEM_CONTROL & 0xFFFF);
+ p0.h = (IMEM_CONTROL >> 16);
+ R1 = [p0];
+ R0 = ~ENICPLB;
+ R0 = R0 & R1;
+
+ /* Anomaly 05000125 */
+#ifdef ANOMALY_05000125
+ CLI R2;
+ SSYNC;
+#endif
+ [p0] = R0;
+ SSYNC;
+#ifdef ANOMALY_05000125
+ STI R2;
+#endif
+
+ /* Turn off the dcache */
+ p0.l = (DMEM_CONTROL & 0xFFFF);
+ p0.h = (DMEM_CONTROL >> 16);
+ R1 = [p0];
+ R0 = ~ENDCPLB;
+ R0 = R0 & R1;
+
+ /* Anomaly 05000125 */
+#ifdef ANOMALY_05000125
+ CLI R2;
+ SSYNC;
+#endif
+ [p0] = R0;
+ SSYNC;
+#ifdef ANOMALY_05000125
+ STI R2;
+#endif
+
+ /* Initialise UART*/
+ p0.h = hi(UART_LCR);
+ p0.l = lo(UART_LCR);
+ r0 = 0x0(Z);
+ w[p0] = r0.L; /* To enable DLL writes */
+ ssync;
+
+ p0.h = hi(UART_DLL);
+ p0.l = lo(UART_DLL);
+ r0 = 0x0(Z);
+ w[p0] = r0.L;
+ ssync;
+
+ p0.h = hi(UART_DLH);
+ p0.l = lo(UART_DLH);
+ r0 = 0x00(Z);
+ w[p0] = r0.L;
+ ssync;
+
+ p0.h = hi(UART_GCTL);
+ p0.l = lo(UART_GCTL);
+ r0 = 0x0(Z);
+ w[p0] = r0.L; /* To enable UART clock */
+ ssync;
+
+ /* Initialize stack pointer */
+ sp.l = lo(INITIAL_STACK);
+ sp.h = hi(INITIAL_STACK);
+ fp = sp;
+ usp = sp;
+
+ /* Put The Code for PLL Programming and SDRAM Programming in L1 ISRAM */
+ call _bf53x_relocate_l1_mem;
+#if CONFIG_BFIN_KERNEL_CLOCK
+ call _start_dma_code;
+#endif
+
+ /* Code for initializing Async memory banks */
+
+ p2.h = hi(EBIU_AMBCTL1);
+ p2.l = lo(EBIU_AMBCTL1);
+ r0.h = hi(AMBCTL1VAL);
+ r0.l = lo(AMBCTL1VAL);
+ [p2] = r0;
+ ssync;
+
+ p2.h = hi(EBIU_AMBCTL0);
+ p2.l = lo(EBIU_AMBCTL0);
+ r0.h = hi(AMBCTL0VAL);
+ r0.l = lo(AMBCTL0VAL);
+ [p2] = r0;
+ ssync;
+
+ p2.h = hi(EBIU_AMGCTL);
+ p2.l = lo(EBIU_AMGCTL);
+ r0 = AMGCTLVAL;
+ w[p2] = r0;
+ ssync;
+
+ /* This section keeps the processor in supervisor mode
+ * during kernel boot. Switches to user mode at end of boot.
+ * See page 3-9 of Hardware Reference manual for documentation.
+ */
+
+ /* EVT15 = _real_start */
+
+ p0.l = lo(EVT15);
+ p0.h = hi(EVT15);
+ p1.l = _real_start;
+ p1.h = _real_start;
+ [p0] = p1;
+ csync;
+
+ p0.l = lo(IMASK);
+ p0.h = hi(IMASK);
+ p1.l = IMASK_IVG15;
+ p1.h = 0x0;
+ [p0] = p1;
+ csync;
+
+ raise 15;
+ p0.l = .LWAIT_HERE;
+ p0.h = .LWAIT_HERE;
+ reti = p0;
+#if defined(ANOMALY_05000281)
+ nop; nop; nop;
+#endif
+ rti;
+
+.LWAIT_HERE:
+ jump .LWAIT_HERE;
+
+ENTRY(_real_start)
+ [ -- sp ] = reti;
+ p0.l = lo(WDOGA_CTL);
+ p0.h = hi(WDOGA_CTL);
+ r0 = 0xAD6(z);
+ w[p0] = r0; /* watchdog off for now */
+ ssync;
+
+ /* Code update for BSS size == 0
+ * Zero out the bss region.
+ */
+
+ p1.l = ___bss_start;
+ p1.h = ___bss_start;
+ p2.l = ___bss_stop;
+ p2.h = ___bss_stop;
+ r0 = 0;
+ p2 -= p1;
+ lsetup (.L_clear_bss, .L_clear_bss ) lc0 = p2;
+.L_clear_bss:
+ B[p1++] = r0;
+
+ /* In case there is a NULL pointer reference
+ * Zero out region before stext
+ */
+
+ p1.l = 0x0;
+ p1.h = 0x0;
+ r0.l = __stext;
+ r0.h = __stext;
+ r0 = r0 >> 1;
+ p2 = r0;
+ r0 = 0;
+ lsetup (.L_clear_zero, .L_clear_zero ) lc0 = p2;
+.L_clear_zero:
+ W[p1++] = r0;
+
+/* pass the uboot arguments to the global value command line */
+ R0 = R7;
+ call _cmdline_init;
+
+ p1.l = __rambase;
+ p1.h = __rambase;
+ r0.l = __sdata;
+ r0.h = __sdata;
+ [p1] = r0;
+
+ p1.l = __ramstart;
+ p1.h = __ramstart;
+ p3.l = ___bss_stop;
+ p3.h = ___bss_stop;
+
+ r1 = p3;
+ [p1] = r1;
+
+ /*
+ * load the current thread pointer and stack
+ */
+ r1.l = _init_thread_union;
+ r1.h = _init_thread_union;
+
+ r2.l = 0x2000;
+ r2.h = 0x0000;
+ r1 = r1 + r2;
+ sp = r1;
+ usp = sp;
+ fp = sp;
+ call _start_kernel;
+.L_exit:
+ jump.s .L_exit;
+
+.section .l1.text
+#if CONFIG_BFIN_KERNEL_CLOCK
+ENTRY(_start_dma_code)
+ p0.h = hi(SICA_IWR0);
+ p0.l = lo(SICA_IWR0);
+ r0.l = 0x1;
+ [p0] = r0;
+ SSYNC;
+
+ /*
+ * Set PLL_CTL
+ * - [14:09] = MSEL[5:0] : CLKIN / VCO multiplication factors
+ * - [8] = BYPASS : BYPASS the PLL, run CLKIN into CCLK/SCLK
+ * - [7] = output delay (add 200ps of delay to mem signals)
+ * - [6] = input delay (add 200ps of input delay to mem signals)
+ * - [5] = PDWN : 1=All Clocks off
+ * - [3] = STOPCK : 1=Core Clock off
+ * - [1] = PLL_OFF : 1=Disable Power to PLL
+ * - [0] = DF : 1=Pass CLKIN/2 to PLL / 0=Pass CLKIN to PLL
+ * all other bits set to zero
+ */
+
+ p0.h = hi(PLL_LOCKCNT);
+ p0.l = lo(PLL_LOCKCNT);
+ r0 = 0x300(Z);
+ w[p0] = r0.l;
+ ssync;
+
+ P2.H = hi(EBIU_SDGCTL);
+ P2.L = lo(EBIU_SDGCTL);
+ R0 = [P2];
+ BITSET (R0, 24);
+ [P2] = R0;
+ SSYNC;
+
+ r0 = CONFIG_VCO_MULT & 63; /* Load the VCO multiplier */
+ r0 = r0 << 9; /* Shift it over, */
+ r1 = CLKIN_HALF; /* Do we need to divide CLKIN by 2?*/
+ r0 = r1 | r0;
+ r1 = PLL_BYPASS; /* Bypass the PLL? */
+ r1 = r1 << 8; /* Shift it over */
+ r0 = r1 | r0; /* add them all together */
+
+ p0.h = hi(PLL_CTL);
+ p0.l = lo(PLL_CTL); /* Load the address */
+ cli r2; /* Disable interrupts */
+ ssync;
+ w[p0] = r0.l; /* Set the value */
+ idle; /* Wait for the PLL to stablize */
+ sti r2; /* Enable interrupts */
+
+.Lcheck_again:
+ p0.h = hi(PLL_STAT);
+ p0.l = lo(PLL_STAT);
+ R0 = W[P0](Z);
+ CC = BITTST(R0,5);
+ if ! CC jump .Lcheck_again;
+
+ /* Configure SCLK & CCLK Dividers */
+ r0 = (CONFIG_CCLK_ACT_DIV | CONFIG_SCLK_DIV);
+ p0.h = hi(PLL_DIV);
+ p0.l = lo(PLL_DIV);
+ w[p0] = r0.l;
+ ssync;
+
+ p0.l = lo(EBIU_SDRRC);
+ p0.h = hi(EBIU_SDRRC);
+ r0 = mem_SDRRC;
+ w[p0] = r0.l;
+ ssync;
+
+ p0.l = (EBIU_SDBCTL & 0xFFFF);
+ p0.h = (EBIU_SDBCTL >> 16); /* SDRAM Memory Bank Control Register */
+ r0 = mem_SDBCTL;
+ w[p0] = r0.l;
+ ssync;
+
+ P2.H = hi(EBIU_SDGCTL);
+ P2.L = lo(EBIU_SDGCTL);
+ R0 = [P2];
+ BITCLR (R0, 24);
+ p0.h = hi(EBIU_SDSTAT);
+ p0.l = lo(EBIU_SDSTAT);
+ r2.l = w[p0];
+ cc = bittst(r2,3);
+ if !cc jump .Lskip;
+ NOP;
+ BITSET (R0, 23);
+.Lskip:
+ [P2] = R0;
+ SSYNC;
+
+ R0.L = lo(mem_SDGCTL);
+ R0.H = hi(mem_SDGCTL);
+ R1 = [p2];
+ R1 = R1 | R0;
+ [P2] = R1;
+ SSYNC;
+
+ RTS;
+#endif /* CONFIG_BFIN_KERNEL_CLOCK */
+
+ENTRY(_bfin_reset)
+ /* No more interrupts to be handled*/
+ CLI R6;
+ SSYNC;
+
+#if defined(CONFIG_BFIN_SHARED_FLASH_ENET)
+ p0.h = hi(FIO_INEN);
+ p0.l = lo(FIO_INEN);
+ r0.l = ~(PF1 | PF0);
+ w[p0] = r0.l;
+
+ p0.h = hi(FIO_DIR);
+ p0.l = lo(FIO_DIR);
+ r0.l = (PF1 | PF0);
+ w[p0] = r0.l;
+
+ p0.h = hi(FIO_FLAG_C);
+ p0.l = lo(FIO_FLAG_C);
+ r0.l = (PF1 | PF0);
+ w[p0] = r0.l;
+#endif
+
+ /* Clear the bits 13-15 in SWRST if they werent cleared */
+ p0.h = hi(SICA_SWRST);
+ p0.l = lo(SICA_SWRST);
+ csync;
+ r0.l = w[p0];
+
+ /* Clear the IMASK register */
+ p0.h = hi(IMASK);
+ p0.l = lo(IMASK);
+ r0 = 0x0;
+ [p0] = r0;
+
+ /* Clear the ILAT register */
+ p0.h = hi(ILAT);
+ p0.l = lo(ILAT);
+ r0 = [p0];
+ [p0] = r0;
+ SSYNC;
+
+ /* Disable the WDOG TIMER */
+ p0.h = hi(WDOGA_CTL);
+ p0.l = lo(WDOGA_CTL);
+ r0.l = 0xAD6;
+ w[p0] = r0.l;
+ SSYNC;
+
+ /* Clear the sticky bit incase it is already set */
+ p0.h = hi(WDOGA_CTL);
+ p0.l = lo(WDOGA_CTL);
+ r0.l = 0x8AD6;
+ w[p0] = r0.l;
+ SSYNC;
+
+ /* Program the count value */
+ R0.l = 0x100;
+ R0.h = 0x0;
+ P0.h = hi(WDOGA_CNT);
+ P0.l = lo(WDOGA_CNT);
+ [P0] = R0;
+ SSYNC;
+
+ /* Program WDOG_STAT if necessary */
+ P0.h = hi(WDOGA_CTL);
+ P0.l = lo(WDOGA_CTL);
+ R0 = W[P0](Z);
+ CC = BITTST(R0,1);
+ if !CC JUMP .LWRITESTAT;
+ CC = BITTST(R0,2);
+ if !CC JUMP .LWRITESTAT;
+ JUMP .LSKIP_WRITE;
+
+.LWRITESTAT:
+ /* When watch dog timer is enabled,
+ * a write to STAT will load the contents of CNT to STAT
+ */
+ R0 = 0x0000(z);
+ P0.h = hi(WDOGA_STAT);
+ P0.l = lo(WDOGA_STAT)
+ [P0] = R0;
+ SSYNC;
+
+.LSKIP_WRITE:
+ /* Enable the reset event */
+ P0.h = hi(WDOGA_CTL);
+ P0.l = lo(WDOGA_CTL);
+ R0 = W[P0](Z);
+ BITCLR(R0,1);
+ BITCLR(R0,2);
+ W[P0] = R0.L;
+ SSYNC;
+ NOP;
+
+ /* Enable the wdog counter */
+ R0 = W[P0](Z);
+ BITCLR(R0,4);
+ W[P0] = R0.L;
+ SSYNC;
+
+ IDLE;
+
+ RTS;
+
+.data
+
+/*
+ * Set up the usable of RAM stuff. Size of RAM is determined then
+ * an initial stack set up at the end.
+ */
+
+.align 4
+__rambase:
+.long 0
+__ramstart:
+.long 0
+__ramend:
+.long 0
diff --git a/arch/blackfin/mach-bf561/ints-priority.c b/arch/blackfin/mach-bf561/ints-priority.c
new file mode 100644
index 00000000000..89c52ff95b2
--- /dev/null
+++ b/arch/blackfin/mach-bf561/ints-priority.c
@@ -0,0 +1,108 @@
+/*
+ * File: arch/blackfin/mach-bf561/ints-priority.c
+ * Based on: arch/blackfin/mach-bf537/ints-priority.c
+ * Author: Michael Hennerich
+ *
+ * Created:
+ * Description: Set up the interupt priorities
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/module.h>
+#include <asm/blackfin.h>
+#include <asm/irq.h>
+
+void program_IAR(void)
+{
+ /* Program the IAR0 Register with the configured priority */
+ bfin_write_SICA_IAR0(((CONFIG_IRQ_PLL_WAKEUP - 7) << IRQ_PLL_WAKEUP_POS) |
+ ((CONFIG_IRQ_DMA1_ERROR - 7) << IRQ_DMA1_ERROR_POS) |
+ ((CONFIG_IRQ_DMA2_ERROR - 7) << IRQ_DMA2_ERROR_POS) |
+ ((CONFIG_IRQ_IMDMA_ERROR - 7) << IRQ_IMDMA_ERROR_POS) |
+ ((CONFIG_IRQ_PPI0_ERROR - 7) << IRQ_PPI0_ERROR_POS) |
+ ((CONFIG_IRQ_PPI1_ERROR - 7) << IRQ_PPI1_ERROR_POS) |
+ ((CONFIG_IRQ_SPORT0_ERROR - 7) << IRQ_SPORT0_ERROR_POS) |
+ ((CONFIG_IRQ_SPORT1_ERROR - 7) << IRQ_SPORT1_ERROR_POS));
+
+ bfin_write_SICA_IAR1(((CONFIG_IRQ_SPI_ERROR - 7) << IRQ_SPI_ERROR_POS) |
+ ((CONFIG_IRQ_UART_ERROR - 7) << IRQ_UART_ERROR_POS) |
+ ((CONFIG_IRQ_RESERVED_ERROR - 7) << IRQ_RESERVED_ERROR_POS) |
+ ((CONFIG_IRQ_DMA1_0 - 7) << IRQ_DMA1_0_POS) |
+ ((CONFIG_IRQ_DMA1_1 - 7) << IRQ_DMA1_1_POS) |
+ ((CONFIG_IRQ_DMA1_2 - 7) << IRQ_DMA1_2_POS) |
+ ((CONFIG_IRQ_DMA1_3 - 7) << IRQ_DMA1_3_POS) |
+ ((CONFIG_IRQ_DMA1_4 - 7) << IRQ_DMA1_4_POS));
+
+ bfin_write_SICA_IAR2(((CONFIG_IRQ_DMA1_5 - 7) << IRQ_DMA1_5_POS) |
+ ((CONFIG_IRQ_DMA1_6 - 7) << IRQ_DMA1_6_POS) |
+ ((CONFIG_IRQ_DMA1_7 - 7) << IRQ_DMA1_7_POS) |
+ ((CONFIG_IRQ_DMA1_8 - 7) << IRQ_DMA1_8_POS) |
+ ((CONFIG_IRQ_DMA1_9 - 7) << IRQ_DMA1_9_POS) |
+ ((CONFIG_IRQ_DMA1_10 - 7) << IRQ_DMA1_10_POS) |
+ ((CONFIG_IRQ_DMA1_11 - 7) << IRQ_DMA1_11_POS) |
+ ((CONFIG_IRQ_DMA2_0 - 7) << IRQ_DMA2_0_POS));
+
+ bfin_write_SICA_IAR3(((CONFIG_IRQ_DMA2_1 - 7) << IRQ_DMA2_1_POS) |
+ ((CONFIG_IRQ_DMA2_2 - 7) << IRQ_DMA2_2_POS) |
+ ((CONFIG_IRQ_DMA2_3 - 7) << IRQ_DMA2_3_POS) |
+ ((CONFIG_IRQ_DMA2_4 - 7) << IRQ_DMA2_4_POS) |
+ ((CONFIG_IRQ_DMA2_5 - 7) << IRQ_DMA2_5_POS) |
+ ((CONFIG_IRQ_DMA2_6 - 7) << IRQ_DMA2_6_POS) |
+ ((CONFIG_IRQ_DMA2_7 - 7) << IRQ_DMA2_7_POS) |
+ ((CONFIG_IRQ_DMA2_8 - 7) << IRQ_DMA2_8_POS));
+
+ bfin_write_SICA_IAR4(((CONFIG_IRQ_DMA2_9 - 7) << IRQ_DMA2_9_POS) |
+ ((CONFIG_IRQ_DMA2_10 - 7) << IRQ_DMA2_10_POS) |
+ ((CONFIG_IRQ_DMA2_11 - 7) << IRQ_DMA2_11_POS) |
+ ((CONFIG_IRQ_TIMER0 - 7) << IRQ_TIMER0_POS) |
+ ((CONFIG_IRQ_TIMER1 - 7) << IRQ_TIMER1_POS) |
+ ((CONFIG_IRQ_TIMER2 - 7) << IRQ_TIMER2_POS) |
+ ((CONFIG_IRQ_TIMER3 - 7) << IRQ_TIMER3_POS) |
+ ((CONFIG_IRQ_TIMER4 - 7) << IRQ_TIMER4_POS));
+
+ bfin_write_SICA_IAR5(((CONFIG_IRQ_TIMER5 - 7) << IRQ_TIMER5_POS) |
+ ((CONFIG_IRQ_TIMER6 - 7) << IRQ_TIMER6_POS) |
+ ((CONFIG_IRQ_TIMER7 - 7) << IRQ_TIMER7_POS) |
+ ((CONFIG_IRQ_TIMER8 - 7) << IRQ_TIMER8_POS) |
+ ((CONFIG_IRQ_TIMER9 - 7) << IRQ_TIMER9_POS) |
+ ((CONFIG_IRQ_TIMER10 - 7) << IRQ_TIMER10_POS) |
+ ((CONFIG_IRQ_TIMER11 - 7) << IRQ_TIMER11_POS) |
+ ((CONFIG_IRQ_PROG0_INTA - 7) << IRQ_PROG0_INTA_POS));
+
+ bfin_write_SICA_IAR6(((CONFIG_IRQ_PROG0_INTB - 7) << IRQ_PROG0_INTB_POS) |
+ ((CONFIG_IRQ_PROG1_INTA - 7) << IRQ_PROG1_INTA_POS) |
+ ((CONFIG_IRQ_PROG1_INTB - 7) << IRQ_PROG1_INTB_POS) |
+ ((CONFIG_IRQ_PROG2_INTA - 7) << IRQ_PROG2_INTA_POS) |
+ ((CONFIG_IRQ_PROG2_INTB - 7) << IRQ_PROG2_INTB_POS) |
+ ((CONFIG_IRQ_DMA1_WRRD0 - 7) << IRQ_DMA1_WRRD0_POS) |
+ ((CONFIG_IRQ_DMA1_WRRD1 - 7) << IRQ_DMA1_WRRD1_POS) |
+ ((CONFIG_IRQ_DMA2_WRRD0 - 7) << IRQ_DMA2_WRRD0_POS));
+
+ bfin_write_SICA_IAR7(((CONFIG_IRQ_DMA2_WRRD1 - 7) << IRQ_DMA2_WRRD1_POS) |
+ ((CONFIG_IRQ_IMDMA_WRRD0 - 7) << IRQ_IMDMA_WRRD0_POS) |
+ ((CONFIG_IRQ_IMDMA_WRRD1 - 7) << IRQ_IMDMA_WRRD1_POS) |
+ ((CONFIG_IRQ_WDTIMER - 7) << IRQ_WDTIMER_POS) |
+ (0 << IRQ_RESERVED_1_POS) | (0 << IRQ_RESERVED_2_POS) |
+ (0 << IRQ_SUPPLE_0_POS) | (0 << IRQ_SUPPLE_1_POS));
+
+ SSYNC();
+}
diff --git a/arch/blackfin/mach-common/Makefile b/arch/blackfin/mach-common/Makefile
new file mode 100644
index 00000000000..d3a49073d19
--- /dev/null
+++ b/arch/blackfin/mach-common/Makefile
@@ -0,0 +1,12 @@
+#
+# arch/blackfin/mach-common/Makefile
+#
+
+obj-y := \
+ cache.o cacheinit.o cplbhdlr.o cplbmgr.o entry.o \
+ interrupt.o lock.o dpmc.o irqpanic.o
+
+obj-$(CONFIG_CPLB_INFO) += cplbinfo.o
+obj-$(CONFIG_BFIN_SINGLE_CORE) += ints-priority-sc.o
+obj-$(CONFIG_BFIN_DUAL_CORE) += ints-priority-dc.o
+obj-$(CONFIG_PM) += pm.o
diff --git a/arch/blackfin/mach-common/cache.S b/arch/blackfin/mach-common/cache.S
new file mode 100644
index 00000000000..bb9446ef66e
--- /dev/null
+++ b/arch/blackfin/mach-common/cache.S
@@ -0,0 +1,253 @@
+/*
+ * File: arch/blackfin/mach-common/cache.S
+ * Based on:
+ * Author: LG Soft India
+ *
+ * Created:
+ * Description: cache control support
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/linkage.h>
+#include <asm/cplb.h>
+#include <asm/entry.h>
+#include <asm/blackfin.h>
+#include <asm/cache.h>
+
+.text
+.align 2
+ENTRY(_cache_invalidate)
+
+ /*
+ * Icache or DcacheA or DcacheB Invalidation
+ * or any combination thereof
+ * R0 has bits
+ * CPLB_ENABLE_ICACHE_P,CPLB_ENABLE_DCACHE_P,CPLB_ENABLE_DCACHE2_P
+ * set as required
+ */
+ [--SP] = R7;
+
+ R7 = R0;
+ CC = BITTST(R7,CPLB_ENABLE_ICACHE_P);
+ IF !CC JUMP .Lno_icache;
+ [--SP] = RETS;
+ CALL _icache_invalidate;
+ RETS = [SP++];
+.Lno_icache:
+ CC = BITTST(R7,CPLB_ENABLE_DCACHE_P);
+ IF !CC JUMP .Lno_dcache_a;
+ R0 = 0; /* specifies bank A */
+ [--SP] = RETS;
+ CALL _dcache_invalidate;
+ RETS = [SP++];
+.Lno_dcache_a:
+ CC = BITTST(R7,CPLB_ENABLE_DCACHE2_P);
+ IF !CC JUMP .Lno_dcache_b;
+ R0 = 0;
+ BITSET(R0, 23); /* specifies bank B */
+ [--SP] = RETS;
+ CALL _dcache_invalidate;
+ RETS = [SP++];
+.Lno_dcache_b:
+ R7 = [SP++];
+ RTS;
+
+/* Invalidate the Entire Instruction cache by
+ * disabling IMC bit
+ */
+ENTRY(_icache_invalidate)
+ENTRY(_invalidate_entire_icache)
+ [--SP] = ( R7:5);
+
+ P0.L = (IMEM_CONTROL & 0xFFFF);
+ P0.H = (IMEM_CONTROL >> 16);
+ R7 = [P0];
+
+ /* Clear the IMC bit , All valid bits in the instruction
+ * cache are set to the invalid state
+ */
+ BITCLR(R7,IMC_P);
+ CLI R6;
+ SSYNC; /* SSYNC required before invalidating cache. */
+ .align 8;
+ [P0] = R7;
+ SSYNC;
+ STI R6;
+
+ /* Configures the instruction cache agian */
+ R6 = (IMC | ENICPLB);
+ R7 = R7 | R6;
+
+ CLI R6;
+ SSYNC; /* SSYNC required before writing to IMEM_CONTROL. */
+ .align 8;
+ [P0] = R7;
+ SSYNC;
+ STI R6;
+
+ ( R7:5) = [SP++];
+ RTS;
+
+/*
+ * blackfin_cache_flush_range(start, end)
+ * Invalidate all cache lines assocoiated with this
+ * area of memory.
+ *
+ * start: Start address
+ * end: End address
+ */
+ENTRY(_blackfin_icache_flush_range)
+ R2 = -L1_CACHE_BYTES;
+ R2 = R0 & R2;
+ P0 = R2;
+ P1 = R1;
+ CSYNC;
+ IFLUSH [P0];
+1:
+ IFLUSH [P0++];
+ CC = P0 < P1 (iu);
+ IF CC JUMP 1b (bp);
+ IFLUSH [P0];
+ SSYNC;
+ RTS;
+
+/*
+ * blackfin_icache_dcache_flush_range(start, end)
+ * FLUSH all cache lines assocoiated with this
+ * area of memory.
+ *
+ * start: Start address
+ * end: End address
+ */
+
+ENTRY(_blackfin_icache_dcache_flush_range)
+ R2 = -L1_CACHE_BYTES;
+ R2 = R0 & R2;
+ P0 = R2;
+ P1 = R1;
+ CSYNC;
+ IFLUSH [P0];
+1:
+ FLUSH [P0];
+ IFLUSH [P0++];
+ CC = P0 < P1 (iu);
+ IF CC JUMP 1b (bp);
+ IFLUSH [P0];
+ FLUSH [P0];
+ SSYNC;
+ RTS;
+
+/* Throw away all D-cached data in specified region without any obligation to
+ * write them back. However, we must clean the D-cached entries around the
+ * boundaries of the start and/or end address is not cache aligned.
+ *
+ * Start: start address,
+ * end : end address.
+ */
+
+ENTRY(_blackfin_dcache_invalidate_range)
+ R2 = -L1_CACHE_BYTES;
+ R2 = R0 & R2;
+ P0 = R2;
+ P1 = R1;
+ CSYNC;
+ FLUSHINV[P0];
+1:
+ FLUSHINV[P0++];
+ CC = P0 < P1 (iu);
+ IF CC JUMP 1b (bp);
+
+ /* If the data crosses a cache line, then we'll be pointing to
+ * the last cache line, but won't have flushed/invalidated it yet,
+ * so do one more.
+ */
+ FLUSHINV[P0];
+ SSYNC;
+ RTS;
+
+/* Invalidate the Entire Data cache by
+ * clearing DMC[1:0] bits
+ */
+ENTRY(_invalidate_entire_dcache)
+ENTRY(_dcache_invalidate)
+ [--SP] = ( R7:6);
+
+ P0.L = (DMEM_CONTROL & 0xFFFF);
+ P0.H = (DMEM_CONTROL >> 16);
+ R7 = [P0];
+
+ /* Clear the DMC[1:0] bits, All valid bits in the data
+ * cache are set to the invalid state
+ */
+ BITCLR(R7,DMC0_P);
+ BITCLR(R7,DMC1_P);
+ CLI R6;
+ SSYNC; /* SSYNC required before writing to DMEM_CONTROL. */
+ .align 8;
+ [P0] = R7;
+ SSYNC;
+ STI R6;
+
+ /* Configures the data cache again */
+
+ R6 = DMEM_CNTR;
+ R7 = R7 | R6;
+
+ CLI R6;
+ SSYNC; /* SSYNC required before writing to DMEM_CONTROL. */
+ .align 8;
+ [P0] = R7;
+ SSYNC;
+ STI R6;
+
+ ( R7:6) = [SP++];
+ RTS;
+
+ENTRY(_blackfin_dcache_flush_range)
+ R2 = -L1_CACHE_BYTES;
+ R2 = R0 & R2;
+ P0 = R2;
+ P1 = R1;
+ CSYNC;
+ FLUSH[P0];
+1:
+ FLUSH[P0++];
+ CC = P0 < P1 (iu);
+ IF CC JUMP 1b (bp);
+
+ /* If the data crosses a cache line, then we'll be pointing to
+ * the last cache line, but won't have flushed it yet, so do
+ * one more.
+ */
+ FLUSH[P0];
+ SSYNC;
+ RTS;
+
+ENTRY(_blackfin_dflush_page)
+ P1 = 1 << (PAGE_SHIFT - L1_CACHE_SHIFT);
+ P0 = R0;
+ CSYNC;
+ FLUSH[P0];
+ LSETUP (.Lfl1, .Lfl1) LC0 = P1;
+.Lfl1: FLUSH [P0++];
+ SSYNC;
+ RTS;
diff --git a/arch/blackfin/mach-common/cacheinit.S b/arch/blackfin/mach-common/cacheinit.S
new file mode 100644
index 00000000000..8c17f099e5e
--- /dev/null
+++ b/arch/blackfin/mach-common/cacheinit.S
@@ -0,0 +1,137 @@
+/*
+ * File: arch/blackfin/mach-common/cacheinit.S
+ * Based on:
+ * Author: LG Soft India
+ *
+ * Created: ?
+ * Description: cache initialization
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* This function sets up the data and instruction cache. The
+ * tables like icplb table, dcplb table and Page Descriptor table
+ * are defined in cplbtab.h. You can configure those tables for
+ * your suitable requirements
+ */
+
+#include <linux/linkage.h>
+#include <asm/blackfin.h>
+
+.text
+
+#if defined(CONFIG_BLKFIN_CACHE)
+ENTRY(_bfin_icache_init)
+
+ /* Initialize Instruction CPLBS */
+
+ I0.L = (ICPLB_ADDR0 & 0xFFFF);
+ I0.H = (ICPLB_ADDR0 >> 16);
+
+ I1.L = (ICPLB_DATA0 & 0xFFFF);
+ I1.H = (ICPLB_DATA0 >> 16);
+
+ I2.L = _icplb_table;
+ I2.H = _icplb_table;
+
+ r1 = -1; /* end point comparison */
+ r3 = 15; /* max counter */
+
+/* read entries from table */
+
+.Lread_iaddr:
+ R0 = [I2++];
+ CC = R0 == R1;
+ IF CC JUMP .Lidone;
+ [I0++] = R0;
+
+.Lread_idata:
+ R2 = [I2++];
+ [I1++] = R2;
+ R3 = R3 + R1;
+ CC = R3 == R1;
+ IF !CC JUMP .Lread_iaddr;
+
+.Lidone:
+ /* Enable Instruction Cache */
+ P0.l = (IMEM_CONTROL & 0xFFFF);
+ P0.h = (IMEM_CONTROL >> 16);
+ R1 = [P0];
+ R0 = (IMC | ENICPLB);
+ R0 = R0 | R1;
+
+ /* Anomaly 05000125 */
+ CLI R2;
+ SSYNC; /* SSYNC required before writing to IMEM_CONTROL. */
+ .align 8;
+ [P0] = R0;
+ SSYNC;
+ STI R2;
+ RTS;
+#endif
+
+#if defined(CONFIG_BLKFIN_DCACHE)
+ENTRY(_bfin_dcache_init)
+
+ /* Initialize Data CPLBS */
+
+ I0.L = (DCPLB_ADDR0 & 0xFFFF);
+ I0.H = (DCPLB_ADDR0 >> 16);
+
+ I1.L = (DCPLB_DATA0 & 0xFFFF);
+ I1.H = (DCPLB_DATA0 >> 16);
+
+ I2.L = _dcplb_table;
+ I2.H = _dcplb_table;
+
+ R1 = -1; /* end point comparison */
+ R3 = 15; /* max counter */
+
+ /* read entries from table */
+.Lread_daddr:
+ R0 = [I2++];
+ cc = R0 == R1;
+ IF CC JUMP .Lddone;
+ [I0++] = R0;
+
+.Lread_ddata:
+ R2 = [I2++];
+ [I1++] = R2;
+ R3 = R3 + R1;
+ CC = R3 == R1;
+ IF !CC JUMP .Lread_daddr;
+.Lddone:
+ P0.L = (DMEM_CONTROL & 0xFFFF);
+ P0.H = (DMEM_CONTROL >> 16);
+ R1 = [P0];
+
+ R0 = DMEM_CNTR;
+
+ R0 = R0 | R1;
+ /* Anomaly 05000125 */
+ CLI R2;
+ SSYNC; /* SSYNC required before writing to DMEM_CONTROL. */
+ .align 8;
+ [P0] = R0;
+ SSYNC;
+ STI R2;
+ RTS;
+#endif
diff --git a/arch/blackfin/mach-common/cplbhdlr.S b/arch/blackfin/mach-common/cplbhdlr.S
new file mode 100644
index 00000000000..b979067c49e
--- /dev/null
+++ b/arch/blackfin/mach-common/cplbhdlr.S
@@ -0,0 +1,130 @@
+/*
+ * File: arch/blackfin/mach-common/cplbhdlr.S
+ * Based on:
+ * Author: LG Soft India
+ *
+ * Created: ?
+ * Description: CPLB exception handler
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/linkage.h>
+#include <asm/cplb.h>
+#include <asm/entry.h>
+
+#ifdef CONFIG_EXCPT_IRQ_SYSC_L1
+.section .l1.text
+#else
+.text
+#endif
+
+.type _cplb_mgr, STT_FUNC;
+.type _panic_cplb_error, STT_FUNC;
+
+.align 2
+
+.global __cplb_hdr;
+.type __cplb_hdr, STT_FUNC;
+ENTRY(__cplb_hdr)
+ R2 = SEQSTAT;
+
+ /* Mask the contents of SEQSTAT and leave only EXCAUSE in R2 */
+ R2 <<= 26;
+ R2 >>= 26;
+
+ R1 = 0x23; /* Data access CPLB protection violation */
+ CC = R2 == R1;
+ IF !CC JUMP .Lnot_data_write;
+ R0 = 2; /* is a write to data space*/
+ JUMP .Lis_icplb_miss;
+
+.Lnot_data_write:
+ R1 = 0x2C; /* CPLB miss on an instruction fetch */
+ CC = R2 == R1;
+ R0 = 0; /* is_data_miss == False*/
+ IF CC JUMP .Lis_icplb_miss;
+
+ R1 = 0x26;
+ CC = R2 == R1;
+ IF !CC JUMP .Lunknown;
+
+ R0 = 1; /* is_data_miss == True*/
+
+.Lis_icplb_miss:
+
+#if defined(CONFIG_BLKFIN_CACHE) || defined(CONFIG_BLKFIN_DCACHE)
+# if defined(CONFIG_BLKFIN_CACHE) && !defined(CONFIG_BLKFIN_DCACHE)
+ R1 = CPLB_ENABLE_ICACHE;
+# endif
+# if !defined(CONFIG_BLKFIN_CACHE) && defined(CONFIG_BLKFIN_DCACHE)
+ R1 = CPLB_ENABLE_DCACHE;
+# endif
+# if defined(CONFIG_BLKFIN_CACHE) && defined(CONFIG_BLKFIN_DCACHE)
+ R1 = CPLB_ENABLE_DCACHE | CPLB_ENABLE_ICACHE;
+# endif
+#else
+ R1 = 0;
+#endif
+
+ [--SP] = RETS;
+ CALL _cplb_mgr;
+ RETS = [SP++];
+ CC = R0 == 0;
+ IF !CC JUMP .Lnot_replaced;
+ RTS;
+
+/*
+ * Diagnostic exception handlers
+ */
+.Lunknown:
+ R0 = CPLB_UNKNOWN_ERR;
+ JUMP .Lcplb_error;
+
+.Lnot_replaced:
+ CC = R0 == CPLB_NO_UNLOCKED;
+ IF !CC JUMP .Lnext_check;
+ R0 = CPLB_NO_UNLOCKED;
+ JUMP .Lcplb_error;
+
+.Lnext_check:
+ CC = R0 == CPLB_NO_ADDR_MATCH;
+ IF !CC JUMP .Lnext_check2;
+ R0 = CPLB_NO_ADDR_MATCH;
+ JUMP .Lcplb_error;
+
+.Lnext_check2:
+ CC = R0 == CPLB_PROT_VIOL;
+ IF !CC JUMP .Lstrange_return_from_cplb_mgr;
+ R0 = CPLB_PROT_VIOL;
+ JUMP .Lcplb_error;
+
+.Lstrange_return_from_cplb_mgr:
+ IDLE;
+ CSYNC;
+ JUMP .Lstrange_return_from_cplb_mgr;
+
+.Lcplb_error:
+ R1 = sp;
+ SP += -12;
+ call _panic_cplb_error;
+ SP += 12;
+ JUMP _handle_bad_cplb;
diff --git a/arch/blackfin/mach-common/cplbinfo.c b/arch/blackfin/mach-common/cplbinfo.c
new file mode 100644
index 00000000000..d65fac39d1b
--- /dev/null
+++ b/arch/blackfin/mach-common/cplbinfo.c
@@ -0,0 +1,211 @@
+/*
+ * File: arch/blackfin/mach-common/cplbinfo.c
+ * Based on:
+ * Author: Sonic Zhang <sonic.zhang@analog.com>
+ *
+ * Created: Jan. 2005
+ * Description: Display CPLB status
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/proc_fs.h>
+
+#include <asm/current.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+
+#include <asm/cplb.h>
+#include <asm/blackfin.h>
+
+#define CPLB_I 1
+#define CPLB_D 2
+
+#define SYNC_SYS SSYNC()
+#define SYNC_CORE CSYNC()
+
+#define CPLB_BIT_PAGESIZE 0x30000
+
+static int page_size_table[4] = {
+ 0x00000400, /* 1K */
+ 0x00001000, /* 4K */
+ 0x00100000, /* 1M */
+ 0x00400000 /* 4M */
+};
+
+static char page_size_string_table[][4] = { "1K", "4K", "1M", "4M" };
+
+static int cplb_find_entry(unsigned long *cplb_addr,
+ unsigned long *cplb_data, unsigned long addr,
+ unsigned long data)
+{
+ int ii;
+
+ for (ii = 0; ii < 16; ii++)
+ if (addr >= cplb_addr[ii] && addr < cplb_addr[ii] +
+ page_size_table[(cplb_data[ii] & CPLB_BIT_PAGESIZE) >> 16]
+ && (cplb_data[ii] == data))
+ return ii;
+
+ return -1;
+}
+
+static char *cplb_print_entry(char *buf, int type)
+{
+ unsigned long *p_addr = dpdt_table;
+ unsigned long *p_data = dpdt_table + 1;
+ unsigned long *p_icount = dpdt_swapcount_table;
+ unsigned long *p_ocount = dpdt_swapcount_table + 1;
+ unsigned long *cplb_addr = (unsigned long *)DCPLB_ADDR0;
+ unsigned long *cplb_data = (unsigned long *)DCPLB_DATA0;
+ int entry = 0, used_cplb = 0;
+
+ if (type == CPLB_I) {
+ buf += sprintf(buf, "Instrction CPLB entry:\n");
+ p_addr = ipdt_table;
+ p_data = ipdt_table + 1;
+ p_icount = ipdt_swapcount_table;
+ p_ocount = ipdt_swapcount_table + 1;
+ cplb_addr = (unsigned long *)ICPLB_ADDR0;
+ cplb_data = (unsigned long *)ICPLB_DATA0;
+ } else
+ buf += sprintf(buf, "Data CPLB entry:\n");
+
+ buf += sprintf(buf, "Address\t\tData\tSize\tValid\tLocked\tSwapin\
+\tiCount\toCount\n");
+
+ while (*p_addr != 0xffffffff) {
+ entry = cplb_find_entry(cplb_addr, cplb_data, *p_addr, *p_data);
+ if (entry >= 0)
+ used_cplb |= 1 << entry;
+
+ buf +=
+ sprintf(buf,
+ "0x%08lx\t0x%05lx\t%s\t%c\t%c\t%2d\t%ld\t%ld\n",
+ *p_addr, *p_data,
+ page_size_string_table[(*p_data & 0x30000) >> 16],
+ (*p_data & CPLB_VALID) ? 'Y' : 'N',
+ (*p_data & CPLB_LOCK) ? 'Y' : 'N', entry, *p_icount,
+ *p_ocount);
+
+ p_addr += 2;
+ p_data += 2;
+ p_icount += 2;
+ p_ocount += 2;
+ }
+
+ if (used_cplb != 0xffff) {
+ buf += sprintf(buf, "Unused/mismatched CPLBs:\n");
+
+ for (entry = 0; entry < 16; entry++)
+ if (0 == ((1 << entry) & used_cplb)) {
+ int flags = cplb_data[entry];
+ buf +=
+ sprintf(buf,
+ "%2d: 0x%08lx\t0x%05x\t%s\t%c\t%c\n",
+ entry, cplb_addr[entry], flags,
+ page_size_string_table[(flags &
+ 0x30000) >>
+ 16],
+ (flags & CPLB_VALID) ? 'Y' : 'N',
+ (flags & CPLB_LOCK) ? 'Y' : 'N');
+ }
+ }
+
+ buf += sprintf(buf, "\n");
+
+ return buf;
+}
+
+static int cplbinfo_proc_output(char *buf)
+{
+ char *p;
+
+ p = buf;
+
+ p += sprintf(p,
+ "------------------ CPLB Information ------------------\n\n");
+
+ if (bfin_read_IMEM_CONTROL() & ENICPLB)
+ p = cplb_print_entry(p, CPLB_I);
+ else
+ p += sprintf(p, "Instruction CPLB is disabled.\n\n");
+
+ if (bfin_read_DMEM_CONTROL() & ENDCPLB)
+ p = cplb_print_entry(p, CPLB_D);
+ else
+ p += sprintf(p, "Data CPLB is disabled.\n");
+
+ return p - buf;
+}
+
+static int cplbinfo_read_proc(char *page, char **start, off_t off,
+ int count, int *eof, void *data)
+{
+ int len;
+
+ len = cplbinfo_proc_output(page);
+ if (len <= off + count)
+ *eof = 1;
+ *start = page + off;
+ len -= off;
+ if (len > count)
+ len = count;
+ if (len < 0)
+ len = 0;
+ return len;
+}
+
+static int cplbinfo_write_proc(struct file *file, const char __user *buffer,
+ unsigned long count, void *data)
+{
+ printk(KERN_INFO "Reset the CPLB swap in/out counts.\n");
+ memset(ipdt_swapcount_table, 0, MAX_SWITCH_I_CPLBS * sizeof(unsigned long));
+ memset(dpdt_swapcount_table, 0, MAX_SWITCH_D_CPLBS * sizeof(unsigned long));
+
+ return count;
+}
+
+static int __init cplbinfo_init(void)
+{
+ struct proc_dir_entry *entry;
+
+ if ((entry = create_proc_entry("cplbinfo", 0, NULL)) == NULL) {
+ return -ENOMEM;
+ }
+
+ entry->read_proc = cplbinfo_read_proc;
+ entry->write_proc = cplbinfo_write_proc;
+ entry->data = NULL;
+
+ return 0;
+}
+
+static void __exit cplbinfo_exit(void)
+{
+ remove_proc_entry("cplbinfo", NULL);
+}
+
+module_init(cplbinfo_init);
+module_exit(cplbinfo_exit);
diff --git a/arch/blackfin/mach-common/cplbmgr.S b/arch/blackfin/mach-common/cplbmgr.S
new file mode 100644
index 00000000000..f5efc4bc65e
--- /dev/null
+++ b/arch/blackfin/mach-common/cplbmgr.S
@@ -0,0 +1,607 @@
+/*
+ * File: arch/blackfin/mach-common/cplbmgtr.S
+ * Based on:
+ * Author: LG Soft India
+ *
+ * Created: ?
+ * Description: CPLB replacement routine for CPLB mismatch
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* Usage: int _cplb_mgr(is_data_miss,int enable_cache)
+ * is_data_miss==2 => Mark as Dirty, write to the clean data page
+ * is_data_miss==1 => Replace a data CPLB.
+ * is_data_miss==0 => Replace an instruction CPLB.
+ *
+ * Returns:
+ * CPLB_RELOADED => Successfully updated CPLB table.
+ * CPLB_NO_UNLOCKED => All CPLBs are locked, so cannot be evicted.
+ * This indicates that the CPLBs in the configuration
+ * tablei are badly configured, as this should never
+ * occur.
+ * CPLB_NO_ADDR_MATCH => The address being accessed, that triggered the
+ * exception, is not covered by any of the CPLBs in
+ * the configuration table. The application is
+ * presumably misbehaving.
+ * CPLB_PROT_VIOL => The address being accessed, that triggered the
+ * exception, was not a first-write to a clean Write
+ * Back Data page, and so presumably is a genuine
+ * violation of the page's protection attributes.
+ * The application is misbehaving.
+ */
+
+#include <linux/linkage.h>
+#include <asm/blackfin.h>
+#include <asm/cplb.h>
+
+#ifdef CONFIG_EXCPT_IRQ_SYSC_L1
+.section .l1.text
+#else
+.text
+#endif
+
+.align 2;
+ENTRY(_cplb_mgr)
+
+ [--SP]=( R7:4,P5:3 );
+
+ CC = R0 == 2;
+ IF CC JUMP .Ldcplb_write;
+
+ CC = R0 == 0;
+ IF !CC JUMP .Ldcplb_miss_compare;
+
+ /* ICPLB Miss Exception. We need to choose one of the
+ * currently-installed CPLBs, and replace it with one
+ * from the configuration table.
+ */
+
+ P4.L = (ICPLB_FAULT_ADDR & 0xFFFF);
+ P4.H = (ICPLB_FAULT_ADDR >> 16);
+
+ P1 = 16;
+ P5.L = _page_size_table;
+ P5.H = _page_size_table;
+
+ P0.L = (ICPLB_DATA0 & 0xFFFF);
+ P0.H = (ICPLB_DATA0 >> 16);
+ R4 = [P4]; /* Get faulting address*/
+ R6 = 64; /* Advance past the fault address, which*/
+ R6 = R6 + R4; /* we'll use if we find a match*/
+ R3 = ((16 << 8) | 2); /* Extract mask, bits 16 and 17.*/
+
+ R5 = 0;
+.Lisearch:
+
+ R1 = [P0-0x100]; /* Address for this CPLB */
+
+ R0 = [P0++]; /* Info for this CPLB*/
+ CC = BITTST(R0,0); /* Is the CPLB valid?*/
+ IF !CC JUMP .Lnomatch; /* Skip it, if not.*/
+ CC = R4 < R1(IU); /* If fault address less than page start*/
+ IF CC JUMP .Lnomatch; /* then skip this one.*/
+ R2 = EXTRACT(R0,R3.L) (Z); /* Get page size*/
+ P1 = R2;
+ P1 = P5 + (P1<<2); /* index into page-size table*/
+ R2 = [P1]; /* Get the page size*/
+ R1 = R1 + R2; /* and add to page start, to get page end*/
+ CC = R4 < R1(IU); /* and see whether fault addr is in page.*/
+ IF !CC R4 = R6; /* If so, advance the address and finish loop.*/
+ IF !CC JUMP .Lisearch_done;
+.Lnomatch:
+ /* Go around again*/
+ R5 += 1;
+ CC = BITTST(R5, 4); /* i.e CC = R5 >= 16*/
+ IF !CC JUMP .Lisearch;
+
+.Lisearch_done:
+ I0 = R4; /* Fault address we'll search for*/
+
+ /* set up pointers */
+ P0.L = (ICPLB_DATA0 & 0xFFFF);
+ P0.H = (ICPLB_DATA0 >> 16);
+
+ /* The replacement procedure for ICPLBs */
+
+ P4.L = (IMEM_CONTROL & 0xFFFF);
+ P4.H = (IMEM_CONTROL >> 16);
+
+ /* disable cplbs */
+ R5 = [P4]; /* Control Register*/
+ BITCLR(R5,ENICPLB_P);
+ CLI R1;
+ SSYNC; /* SSYNC required before writing to IMEM_CONTROL. */
+ .align 8;
+ [P4] = R5;
+ SSYNC;
+ STI R1;
+
+ R1 = -1; /* end point comparison */
+ R3 = 16; /* counter */
+
+ /* Search through CPLBs for first non-locked entry */
+ /* Overwrite it by moving everyone else up by 1 */
+.Licheck_lock:
+ R0 = [P0++];
+ R3 = R3 + R1;
+ CC = R3 == R1;
+ IF CC JUMP .Lall_locked;
+ CC = BITTST(R0, 0); /* an invalid entry is good */
+ IF !CC JUMP .Lifound_victim;
+ CC = BITTST(R0,1); /* but a locked entry isn't */
+ IF CC JUMP .Licheck_lock;
+
+.Lifound_victim:
+#ifdef CONFIG_CPLB_INFO
+ R7 = [P0 - 0x104];
+ P2.L = _ipdt_table;
+ P2.H = _ipdt_table;
+ P3.L = _ipdt_swapcount_table;
+ P3.H = _ipdt_swapcount_table;
+ P3 += -4;
+.Licount:
+ R2 = [P2]; /* address from config table */
+ P2 += 8;
+ P3 += 8;
+ CC = R2==-1;
+ IF CC JUMP .Licount_done;
+ CC = R7==R2;
+ IF !CC JUMP .Licount;
+ R7 = [P3];
+ R7 += 1;
+ [P3] = R7;
+ CSYNC;
+.Licount_done:
+#endif
+ LC0=R3;
+ LSETUP(.Lis_move,.Lie_move) LC0;
+.Lis_move:
+ R0 = [P0];
+ [P0 - 4] = R0;
+ R0 = [P0 - 0x100];
+ [P0-0x104] = R0;
+.Lie_move:P0+=4;
+
+ /* We've made space in the ICPLB table, so that ICPLB15
+ * is now free to be overwritten. Next, we have to determine
+ * which CPLB we need to install, from the configuration
+ * table. This is a matter of getting the start-of-page
+ * addresses and page-lengths from the config table, and
+ * determining whether the fault address falls within that
+ * range.
+ */
+
+ P2.L = _ipdt_table;
+ P2.H = _ipdt_table;
+#ifdef CONFIG_CPLB_INFO
+ P3.L = _ipdt_swapcount_table;
+ P3.H = _ipdt_swapcount_table;
+ P3 += -8;
+#endif
+ P0.L = _page_size_table;
+ P0.H = _page_size_table;
+
+ /* Retrieve our fault address (which may have been advanced
+ * because the faulting instruction crossed a page boundary).
+ */
+
+ R0 = I0;
+
+ /* An extraction pattern, to get the page-size bits from
+ * the CPLB data entry. Bits 16-17, so two bits at posn 16.
+ */
+
+ R1 = ((16<<8)|2);
+.Linext: R4 = [P2++]; /* address from config table */
+ R2 = [P2++]; /* data from config table */
+#ifdef CONFIG_CPLB_INFO
+ P3 += 8;
+#endif
+
+ CC = R4 == -1; /* End of config table*/
+ IF CC JUMP .Lno_page_in_table;
+
+ /* See if failed address > start address */
+ CC = R4 <= R0(IU);
+ IF !CC JUMP .Linext;
+
+ /* extract page size (17:16)*/
+ R3 = EXTRACT(R2, R1.L) (Z);
+
+ /* add page size to addr to get range */
+
+ P5 = R3;
+ P5 = P0 + (P5 << 2); /* scaled, for int access*/
+ R3 = [P5];
+ R3 = R3 + R4;
+
+ /* See if failed address < (start address + page size) */
+ CC = R0 < R3(IU);
+ IF !CC JUMP .Linext;
+
+ /* We've found a CPLB in the config table that covers
+ * the faulting address, so install this CPLB into the
+ * last entry of the table.
+ */
+
+ P1.L = (ICPLB_DATA15 & 0xFFFF); /* ICPLB_DATA15 */
+ P1.H = (ICPLB_DATA15 >> 16);
+ [P1] = R2;
+ [P1-0x100] = R4;
+#ifdef CONFIG_CPLB_INFO
+ R3 = [P3];
+ R3 += 1;
+ [P3] = R3;
+#endif
+
+ /* P4 points to IMEM_CONTROL, and R5 contains its old
+ * value, after we disabled ICPLBS. Re-enable them.
+ */
+
+ BITSET(R5,ENICPLB_P);
+ CLI R2;
+ SSYNC; /* SSYNC required before writing to IMEM_CONTROL. */
+ .align 8;
+ [P4] = R5;
+ SSYNC;
+ STI R2;
+
+ ( R7:4,P5:3 ) = [SP++];
+ R0 = CPLB_RELOADED;
+ RTS;
+
+/* FAILED CASES*/
+.Lno_page_in_table:
+ ( R7:4,P5:3 ) = [SP++];
+ R0 = CPLB_NO_ADDR_MATCH;
+ RTS;
+.Lall_locked:
+ ( R7:4,P5:3 ) = [SP++];
+ R0 = CPLB_NO_UNLOCKED;
+ RTS;
+.Lprot_violation:
+ ( R7:4,P5:3 ) = [SP++];
+ R0 = CPLB_PROT_VIOL;
+ RTS;
+
+.Ldcplb_write:
+
+ /* if a DCPLB is marked as write-back (CPLB_WT==0), and
+ * it is clean (CPLB_DIRTY==0), then a write to the
+ * CPLB's page triggers a protection violation. We have to
+ * mark the CPLB as dirty, to indicate that there are
+ * pending writes associated with the CPLB.
+ */
+
+ P4.L = (DCPLB_STATUS & 0xFFFF);
+ P4.H = (DCPLB_STATUS >> 16);
+ P3.L = (DCPLB_DATA0 & 0xFFFF);
+ P3.H = (DCPLB_DATA0 >> 16);
+ R5 = [P4];
+
+ /* A protection violation can be caused by more than just writes
+ * to a clean WB page, so we have to ensure that:
+ * - It's a write
+ * - to a clean WB page
+ * - and is allowed in the mode the access occurred.
+ */
+
+ CC = BITTST(R5, 16); /* ensure it was a write*/
+ IF !CC JUMP .Lprot_violation;
+
+ /* to check the rest, we have to retrieve the DCPLB.*/
+
+ /* The low half of DCPLB_STATUS is a bit mask*/
+
+ R2 = R5.L (Z); /* indicating which CPLB triggered the event.*/
+ R3 = 30; /* so we can use this to determine the offset*/
+ R2.L = SIGNBITS R2;
+ R2 = R2.L (Z); /* into the DCPLB table.*/
+ R3 = R3 - R2;
+ P4 = R3;
+ P3 = P3 + (P4<<2);
+ R3 = [P3]; /* Retrieve the CPLB*/
+
+ /* Now we can check whether it's a clean WB page*/
+
+ CC = BITTST(R3, 14); /* 0==WB, 1==WT*/
+ IF CC JUMP .Lprot_violation;
+ CC = BITTST(R3, 7); /* 0 == clean, 1 == dirty*/
+ IF CC JUMP .Lprot_violation;
+
+ /* Check whether the write is allowed in the mode that was active.*/
+
+ R2 = 1<<3; /* checking write in user mode*/
+ CC = BITTST(R5, 17); /* 0==was user, 1==was super*/
+ R5 = CC;
+ R2 <<= R5; /* if was super, check write in super mode*/
+ R2 = R3 & R2;
+ CC = R2 == 0;
+ IF CC JUMP .Lprot_violation;
+
+ /* It's a genuine write-to-clean-page.*/
+
+ BITSET(R3, 7); /* mark as dirty*/
+ [P3] = R3; /* and write back.*/
+ NOP;
+ CSYNC;
+ ( R7:4,P5:3 ) = [SP++];
+ R0 = CPLB_RELOADED;
+ RTS;
+
+.Ldcplb_miss_compare:
+
+ /* Data CPLB Miss event. We need to choose a CPLB to
+ * evict, and then locate a new CPLB to install from the
+ * config table, that covers the faulting address.
+ */
+
+ P1.L = (DCPLB_DATA15 & 0xFFFF);
+ P1.H = (DCPLB_DATA15 >> 16);
+
+ P4.L = (DCPLB_FAULT_ADDR & 0xFFFF);
+ P4.H = (DCPLB_FAULT_ADDR >> 16);
+ R4 = [P4];
+ I0 = R4;
+
+ /* The replacement procedure for DCPLBs*/
+
+ R6 = R1; /* Save for later*/
+
+ /* Turn off CPLBs while we work.*/
+ P4.L = (DMEM_CONTROL & 0xFFFF);
+ P4.H = (DMEM_CONTROL >> 16);
+ R5 = [P4];
+ BITCLR(R5,ENDCPLB_P);
+ CLI R0;
+ SSYNC; /* SSYNC required before writing to DMEM_CONTROL. */
+ .align 8;
+ [P4] = R5;
+ SSYNC;
+ STI R0;
+
+ /* Start looking for a CPLB to evict. Our order of preference
+ * is: invalid CPLBs, clean CPLBs, dirty CPLBs. Locked CPLBs
+ * are no good.
+ */
+
+ I1.L = (DCPLB_DATA0 & 0xFFFF);
+ I1.H = (DCPLB_DATA0 >> 16);
+ P1 = 2;
+ P2 = 16;
+ I2.L = _dcplb_preference;
+ I2.H = _dcplb_preference;
+ LSETUP(.Lsdsearch1, .Ledsearch1) LC0 = P1;
+.Lsdsearch1:
+ R0 = [I2++]; /* Get the bits we're interested in*/
+ P0 = I1; /* Go back to start of table*/
+ LSETUP (.Lsdsearch2, .Ledsearch2) LC1 = P2;
+.Lsdsearch2:
+ R1 = [P0++]; /* Fetch each installed CPLB in turn*/
+ R2 = R1 & R0; /* and test for interesting bits.*/
+ CC = R2 == 0; /* If none are set, it'll do.*/
+ IF !CC JUMP .Lskip_stack_check;
+
+ R2 = [P0 - 0x104]; /* R2 - PageStart */
+ P3.L = _page_size_table; /* retrieve end address */
+ P3.H = _page_size_table; /* retrieve end address */
+ R3 = 0x1002; /* 16th - position, 2 bits -length */
+#ifdef ANOMALY_05000209
+ nop; /* Anomaly 05000209 */
+#endif
+ R7 = EXTRACT(R1,R3.l);
+ R7 = R7 << 2; /* Page size index offset */
+ P5 = R7;
+ P3 = P3 + P5;
+ R7 = [P3]; /* page size in bytes */
+
+ R7 = R2 + R7; /* R7 - PageEnd */
+ R4 = SP; /* Test SP is in range */
+
+ CC = R7 < R4; /* if PageEnd < SP */
+ IF CC JUMP .Ldfound_victim;
+ R3 = 0x284; /* stack length from start of trap till
+ * the point.
+ * 20 stack locations for future modifications
+ */
+ R4 = R4 + R3;
+ CC = R4 < R2; /* if SP + stacklen < PageStart */
+ IF CC JUMP .Ldfound_victim;
+.Lskip_stack_check:
+
+.Ledsearch2: NOP;
+.Ledsearch1: NOP;
+
+ /* If we got here, we didn't find a DCPLB we considered
+ * replacable, which means all of them were locked.
+ */
+
+ JUMP .Lall_locked;
+.Ldfound_victim:
+
+#ifdef CONFIG_CPLB_INFO
+ R7 = [P0 - 0x104];
+ P2.L = _dpdt_table;
+ P2.H = _dpdt_table;
+ P3.L = _dpdt_swapcount_table;
+ P3.H = _dpdt_swapcount_table;
+ P3 += -4;
+.Ldicount:
+ R2 = [P2];
+ P2 += 8;
+ P3 += 8;
+ CC = R2==-1;
+ IF CC JUMP .Ldicount_done;
+ CC = R7==R2;
+ IF !CC JUMP .Ldicount;
+ R7 = [P3];
+ R7 += 1;
+ [P3] = R7;
+.Ldicount_done:
+#endif
+
+ /* Clean down the hardware loops*/
+ R2 = 0;
+ LC1 = R2;
+ LC0 = R2;
+
+ /* There's a suitable victim in [P0-4] (because we've
+ * advanced already).
+ */
+
+.LDdoverwrite:
+
+ /* [P0-4] is a suitable victim CPLB, so we want to
+ * overwrite it by moving all the following CPLBs
+ * one space closer to the start.
+ */
+
+ R1.L = (DCPLB_DATA16 & 0xFFFF); /* DCPLB_DATA15 + 4 */
+ R1.H = (DCPLB_DATA16 >> 16);
+ R0 = P0;
+
+ /* If the victim happens to be in DCPLB15,
+ * we don't need to move anything.
+ */
+
+ CC = R1 == R0;
+ IF CC JUMP .Lde_moved;
+ R1 = R1 - R0;
+ R1 >>= 2;
+ P1 = R1;
+ LSETUP(.Lds_move, .Lde_move) LC0=P1;
+.Lds_move:
+ R0 = [P0++]; /* move data */
+ [P0 - 8] = R0;
+ R0 = [P0-0x104] /* move address */
+.Lde_move: [P0-0x108] = R0;
+
+ /* We've now made space in DCPLB15 for the new CPLB to be
+ * installed. The next stage is to locate a CPLB in the
+ * config table that covers the faulting address.
+ */
+
+.Lde_moved:NOP;
+ R0 = I0; /* Our faulting address */
+
+ P2.L = _dpdt_table;
+ P2.H = _dpdt_table;
+#ifdef CONFIG_CPLB_INFO
+ P3.L = _dpdt_swapcount_table;
+ P3.H = _dpdt_swapcount_table;
+ P3 += -8;
+#endif
+
+ P1.L = _page_size_table;
+ P1.H = _page_size_table;
+
+ /* An extraction pattern, to retrieve bits 17:16.*/
+
+ R1 = (16<<8)|2;
+.Ldnext: R4 = [P2++]; /* address */
+ R2 = [P2++]; /* data */
+#ifdef CONFIG_CPLB_INFO
+ P3 += 8;
+#endif
+
+ CC = R4 == -1;
+ IF CC JUMP .Lno_page_in_table;
+
+ /* See if failed address > start address */
+ CC = R4 <= R0(IU);
+ IF !CC JUMP .Ldnext;
+
+ /* extract page size (17:16)*/
+ R3 = EXTRACT(R2, R1.L) (Z);
+
+ /* add page size to addr to get range */
+
+ P5 = R3;
+ P5 = P1 + (P5 << 2);
+ R3 = [P5];
+ R3 = R3 + R4;
+
+ /* See if failed address < (start address + page size) */
+ CC = R0 < R3(IU);
+ IF !CC JUMP .Ldnext;
+
+ /* We've found the CPLB that should be installed, so
+ * write it into CPLB15, masking off any caching bits
+ * if necessary.
+ */
+
+ P1.L = (DCPLB_DATA15 & 0xFFFF);
+ P1.H = (DCPLB_DATA15 >> 16);
+
+ /* If the DCPLB has cache bits set, but caching hasn't
+ * been enabled, then we want to mask off the cache-in-L1
+ * bit before installing. Moreover, if caching is off, we
+ * also want to ensure that the DCPLB has WT mode set, rather
+ * than WB, since WB pages still trigger first-write exceptions
+ * even when not caching is off, and the page isn't marked as
+ * cachable. Finally, we could mark the page as clean, not dirty,
+ * but we choose to leave that decision to the user; if the user
+ * chooses to have a CPLB pre-defined as dirty, then they always
+ * pay the cost of flushing during eviction, but don't pay the
+ * cost of first-write exceptions to mark the page as dirty.
+ */
+
+#ifdef CONFIG_BLKFIN_WT
+ BITSET(R6, 14); /* Set WT*/
+#endif
+
+ [P1] = R2;
+ [P1-0x100] = R4;
+#ifdef CONFIG_CPLB_INFO
+ R3 = [P3];
+ R3 += 1;
+ [P3] = R3;
+#endif
+
+ /* We've installed the CPLB, so re-enable CPLBs. P4
+ * points to DMEM_CONTROL, and R5 is the value we
+ * last wrote to it, when we were disabling CPLBs.
+ */
+
+ BITSET(R5,ENDCPLB_P);
+ CLI R2;
+ .align 8;
+ [P4] = R5;
+ SSYNC;
+ STI R2;
+
+ ( R7:4,P5:3 ) = [SP++];
+ R0 = CPLB_RELOADED;
+ RTS;
+
+.data
+.align 4;
+_page_size_table:
+.byte4 0x00000400; /* 1K */
+.byte4 0x00001000; /* 4K */
+.byte4 0x00100000; /* 1M */
+.byte4 0x00400000; /* 4M */
+
+.align 4;
+_dcplb_preference:
+.byte4 0x00000001; /* valid bit */
+.byte4 0x00000002; /* lock bit */
diff --git a/arch/blackfin/mach-common/dpmc.S b/arch/blackfin/mach-common/dpmc.S
new file mode 100644
index 00000000000..97cdcd6a00d
--- /dev/null
+++ b/arch/blackfin/mach-common/dpmc.S
@@ -0,0 +1,418 @@
+/*
+ * File: arch/blackfin/mach-common/dpmc.S
+ * Based on:
+ * Author: LG Soft India
+ *
+ * Created: ?
+ * Description: Watchdog Timer APIs
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/linkage.h>
+#include <asm/blackfin.h>
+#include <asm/mach/irq.h>
+
+.text
+
+ENTRY(_unmask_wdog_wakeup_evt)
+ [--SP] = ( R7:0, P5:0 );
+#if defined(CONFIG_BF561)
+ P0.H = hi(SICA_IWR1);
+ P0.L = lo(SICA_IWR1);
+#else
+ P0.h = (SIC_IWR >> 16);
+ P0.l = (SIC_IWR & 0xFFFF);
+#endif
+ R7 = [P0];
+#if defined(CONFIG_BF561)
+ BITSET(R7, 27);
+#else
+ BITSET(R7,(IRQ_WATCH - IVG7));
+#endif
+ [P0] = R7;
+ SSYNC;
+
+ ( R7:0, P5:0 ) = [SP++];
+ RTS;
+
+.LWRITE_TO_STAT:
+ /* When watch dog timer is enabled, a write to STAT will load the
+ * contents of CNT to STAT
+ */
+ R7 = 0x0000(z);
+#if defined(CONFIG_BF561)
+ P0.h = (WDOGA_STAT >> 16);
+ P0.l = (WDOGA_STAT & 0xFFFF);
+#else
+ P0.h = (WDOG_STAT >> 16);
+ P0.l = (WDOG_STAT & 0xFFFF);
+#endif
+ [P0] = R7;
+ SSYNC;
+ JUMP .LSKIP_WRITE_TO_STAT;
+
+ENTRY(_program_wdog_timer)
+ [--SP] = ( R7:0, P5:0 );
+#if defined(CONFIG_BF561)
+ P0.h = (WDOGA_CNT >> 16);
+ P0.l = (WDOGA_CNT & 0xFFFF);
+#else
+ P0.h = (WDOG_CNT >> 16);
+ P0.l = (WDOG_CNT & 0xFFFF);
+#endif
+ [P0] = R0;
+ SSYNC;
+
+#if defined(CONFIG_BF561)
+ P0.h = (WDOGA_CTL >> 16);
+ P0.l = (WDOGA_CTL & 0xFFFF);
+#else
+ P0.h = (WDOG_CTL >> 16);
+ P0.l = (WDOG_CTL & 0xFFFF);
+#endif
+ R7 = W[P0](Z);
+ CC = BITTST(R7,1);
+ if !CC JUMP .LWRITE_TO_STAT;
+ CC = BITTST(R7,2);
+ if !CC JUMP .LWRITE_TO_STAT;
+
+.LSKIP_WRITE_TO_STAT:
+#if defined(CONFIG_BF561)
+ P0.h = (WDOGA_CTL >> 16);
+ P0.l = (WDOGA_CTL & 0xFFFF);
+#else
+ P0.h = (WDOG_CTL >> 16);
+ P0.l = (WDOG_CTL & 0xFFFF);
+#endif
+ R7 = W[P0](Z);
+ BITCLR(R7,1); /* Enable GP event */
+ BITSET(R7,2);
+ W[P0] = R7.L;
+ SSYNC;
+ NOP;
+
+ R7 = W[P0](Z);
+ BITCLR(R7,4); /* Enable the wdog counter */
+ W[P0] = R7.L;
+ SSYNC;
+
+ ( R7:0, P5:0 ) = [SP++];
+ RTS;
+
+ENTRY(_clear_wdog_wakeup_evt)
+ [--SP] = ( R7:0, P5:0 );
+
+#if defined(CONFIG_BF561)
+ P0.h = (WDOGA_CTL >> 16);
+ P0.l = (WDOGA_CTL & 0xFFFF);
+#else
+ P0.h = (WDOG_CTL >> 16);
+ P0.l = (WDOG_CTL & 0xFFFF);
+#endif
+ R7 = 0x0AD6(Z);
+ W[P0] = R7.L;
+ SSYNC;
+
+ R7 = W[P0](Z);
+ BITSET(R7,15);
+ W[P0] = R7.L;
+ SSYNC;
+
+ R7 = W[P0](Z);
+ BITSET(R7,1);
+ BITSET(R7,2);
+ W[P0] = R7.L;
+ SSYNC;
+
+ ( R7:0, P5:0 ) = [SP++];
+ RTS;
+
+ENTRY(_disable_wdog_timer)
+ [--SP] = ( R7:0, P5:0 );
+#if defined(CONFIG_BF561)
+ P0.h = (WDOGA_CTL >> 16);
+ P0.l = (WDOGA_CTL & 0xFFFF);
+#else
+ P0.h = (WDOG_CTL >> 16);
+ P0.l = (WDOG_CTL & 0xFFFF);
+#endif
+ R7 = 0xAD6(Z);
+ W[P0] = R7.L;
+ SSYNC;
+ ( R7:0, P5:0 ) = [SP++];
+ RTS;
+
+#if !defined(CONFIG_BF561)
+
+.section .l1.text
+
+ENTRY(_sleep_mode)
+ [--SP] = ( R7:0, P5:0 );
+ [--SP] = RETS;
+
+ call _set_sic_iwr;
+
+ R0 = 0xFFFF (Z);
+ call _set_rtc_istat
+
+ P0.H = hi(PLL_CTL);
+ P0.L = lo(PLL_CTL);
+ R1 = W[P0](z);
+ BITSET (R1, 3);
+ W[P0] = R1.L;
+
+ CLI R2;
+ SSYNC;
+ IDLE;
+ STI R2;
+
+ call _test_pll_locked;
+
+ R0 = IWR_ENABLE(0);
+ call _set_sic_iwr;
+
+ P0.H = hi(PLL_CTL);
+ P0.L = lo(PLL_CTL);
+ R7 = w[p0](z);
+ BITCLR (R7, 3);
+ BITCLR (R7, 5);
+ w[p0] = R7.L;
+ IDLE;
+ call _test_pll_locked;
+
+ RETS = [SP++];
+ ( R7:0, P5:0 ) = [SP++];
+ RTS;
+
+ENTRY(_hibernate_mode)
+ [--SP] = ( R7:0, P5:0 );
+ [--SP] = RETS;
+
+ call _set_sic_iwr;
+
+ R0 = 0xFFFF (Z);
+ call _set_rtc_istat
+
+ P0.H = hi(VR_CTL);
+ P0.L = lo(VR_CTL);
+ R1 = W[P0](z);
+ BITSET (R1, 8);
+ BITCLR (R1, 0);
+ BITCLR (R1, 1);
+ W[P0] = R1.L;
+ SSYNC;
+
+ CLI R2;
+ IDLE;
+
+ /* Actually, adding anything may not be necessary...SDRAM contents
+ * are lost
+ */
+
+ENTRY(_deep_sleep)
+ [--SP] = ( R7:0, P5:0 );
+ [--SP] = RETS;
+
+ CLI R4;
+
+ call _set_sic_iwr;
+
+ call _set_sdram_srfs;
+
+ /* Clear all the interrupts,bits sticky */
+ R0 = 0xFFFF (Z);
+ call _set_rtc_istat
+
+ P0.H = hi(PLL_CTL);
+ P0.L = lo(PLL_CTL);
+ R0 = W[P0](z);
+ BITSET (R0, 5);
+ W[P0] = R0.L;
+
+ call _test_pll_locked;
+
+ SSYNC;
+ IDLE;
+
+ call _unset_sdram_srfs;
+
+ call _test_pll_locked;
+
+ R0 = IWR_ENABLE(0);
+ call _set_sic_iwr;
+
+ P0.H = hi(PLL_CTL);
+ P0.L = lo(PLL_CTL);
+ R0 = w[p0](z);
+ BITCLR (R0, 3);
+ BITCLR (R0, 5);
+ BITCLR (R0, 8);
+ w[p0] = R0;
+ IDLE;
+ call _test_pll_locked;
+
+ STI R4;
+
+ RETS = [SP++];
+ ( R7:0, P5:0 ) = [SP++];
+ RTS;
+
+ENTRY(_sleep_deeper)
+ [--SP] = ( R7:0, P5:0 );
+ [--SP] = RETS;
+
+ CLI R4;
+
+ P3 = R0;
+ R0 = IWR_ENABLE(0);
+ call _set_sic_iwr;
+ call _set_sdram_srfs;
+
+ /* Clear all the interrupts,bits sticky */
+ R0 = 0xFFFF (Z);
+ call _set_rtc_istat
+
+ P0.H = hi(PLL_DIV);
+ P0.L = lo(PLL_DIV);
+ R6 = W[P0](z);
+ R0.L = 0xF;
+ W[P0] = R0.l;
+
+ P0.H = hi(PLL_CTL);
+ P0.L = lo(PLL_CTL);
+ R5 = W[P0](z);
+ R0.L = (MIN_VC/CONFIG_CLKIN_HZ) << 9;
+ W[P0] = R0.l;
+
+ SSYNC;
+ IDLE;
+
+ call _test_pll_locked;
+
+ P0.H = hi(VR_CTL);
+ P0.L = lo(VR_CTL);
+ R7 = W[P0](z);
+ R1 = 0x6;
+ R1 <<= 16;
+ R2 = 0x0404(Z);
+ R1 = R1|R2;
+
+ R2 = DEPOSIT(R7, R1);
+ W[P0] = R2;
+
+ SSYNC;
+ IDLE;
+
+ call _test_pll_locked;
+
+ P0.H = hi(PLL_CTL);
+ P0.L = lo(PLL_CTL);
+ R0 = W[P0](z);
+ BITSET (R0, 3);
+ W[P0] = R0.L;
+
+ R0 = P3;
+ call _set_sic_iwr;
+
+ SSYNC;
+ IDLE;
+
+ call _test_pll_locked;
+
+ R0 = IWR_ENABLE(0);
+ call _set_sic_iwr;
+
+ P0.H = hi(VR_CTL);
+ P0.L = lo(VR_CTL);
+ W[P0]= R7;
+
+ SSYNC;
+ IDLE;
+
+ call _test_pll_locked;
+
+ P0.H = hi(PLL_DIV);
+ P0.L = lo(PLL_DIV);
+ W[P0]= R6;
+
+ P0.H = hi(PLL_CTL);
+ P0.L = lo(PLL_CTL);
+ w[p0] = R5;
+ IDLE;
+ call _test_pll_locked;
+
+ call _unset_sdram_srfs;
+
+ STI R4;
+
+ RETS = [SP++];
+ ( R7:0, P5:0 ) = [SP++];
+ RTS;
+
+ENTRY(_set_sdram_srfs)
+ /* set the sdram to self refresh mode */
+ P0.H = hi(EBIU_SDGCTL);
+ P0.L = lo(EBIU_SDGCTL);
+ R2 = [P0];
+ R3.H = hi(SRFS);
+ R3.L = lo(SRFS);
+ R2 = R2|R3;
+ [P0] = R2;
+ ssync;
+ RTS;
+
+ENTRY(_unset_sdram_srfs)
+ /* set the sdram out of self refresh mode */
+ P0.H = hi(EBIU_SDGCTL);
+ P0.L = lo(EBIU_SDGCTL);
+ R2 = [P0];
+ R3.H = hi(SRFS);
+ R3.L = lo(SRFS);
+ R3 = ~R3;
+ R2 = R2&R3;
+ [P0] = R2;
+ ssync;
+ RTS;
+
+ENTRY(_set_sic_iwr)
+ P0.H = hi(SIC_IWR);
+ P0.L = lo(SIC_IWR);
+ [P0] = R0;
+ SSYNC;
+ RTS;
+
+ENTRY(_set_rtc_istat)
+ P0.H = hi(RTC_ISTAT);
+ P0.L = lo(RTC_ISTAT);
+ w[P0] = R0.L;
+ SSYNC;
+ RTS;
+
+ENTRY(_test_pll_locked)
+ P0.H = hi(PLL_STAT);
+ P0.L = lo(PLL_STAT);
+1:
+ R0 = W[P0] (Z);
+ CC = BITTST(R0,5);
+ IF !CC JUMP 1b;
+ RTS;
+#endif
diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S
new file mode 100644
index 00000000000..8eb0a902348
--- /dev/null
+++ b/arch/blackfin/mach-common/entry.S
@@ -0,0 +1,1207 @@
+/*
+ * File: arch/blackfin/mach-common/entry.S
+ * Based on:
+ * Author: Linus Torvalds
+ *
+ * Created: ?
+ * Description: contains the system-call and fault low-level handling routines.
+ * This also contains the timer-interrupt handler, as well as all
+ * interrupts and faults that can result in a task-switch.
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/*
+ * 25-Dec-2004 - LG Soft India
+ * 1. Fix in return_from_int, to make sure any pending
+ * system call in ILAT for this process to get
+ * executed, otherwise in case context switch happens,
+ * system call of first process (i.e in ILAT) will be
+ * carried forward to the switched process.
+ * 2. Removed Constant references for the following
+ * a. IPEND
+ * b. EXCAUSE mask
+ * c. PAGE Mask
+ */
+
+/*
+ * NOTE: This code handles signal-recognition, which happens every time
+ * after a timer-interrupt and after each system call.
+ */
+
+
+#include <linux/linkage.h>
+#include <asm/blackfin.h>
+#include <asm/unistd.h>
+#include <asm/errno.h>
+#include <asm/thread_info.h> /* TIF_NEED_RESCHED */
+#include <asm/asm-offsets.h>
+
+#include <asm/mach-common/context.S>
+
+#ifdef CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE
+ /*
+ * TODO: this should be proper save/restore, but for now
+ * we'll just cheat and use 0x1/0x13
+ */
+# define DEBUG_START_HWTRACE \
+ P5.l = LO(TBUFCTL); \
+ P5.h = HI(TBUFCTL); \
+ R7 = 0x13; \
+ [P5] = R7;
+# define DEBUG_STOP_HWTRACE \
+ P5.l = LO(TBUFCTL); \
+ P5.h = HI(TBUFCTL); \
+ R7 = 0x01; \
+ [P5] = R7;
+#else
+# define DEBUG_START_HWTRACE
+# define DEBUG_STOP_HWTRACE
+#endif
+
+#ifdef CONFIG_EXCPT_IRQ_SYSC_L1
+.section .l1.text
+#else
+.text
+#endif
+
+/* Slightly simplified and streamlined entry point for CPLB misses.
+ * This one does not lower the level to IRQ5, and thus can be used to
+ * patch up CPLB misses on the kernel stack.
+ */
+ENTRY(_ex_dcplb)
+#if defined(ANOMALY_05000261)
+ /*
+ * Work around an anomaly: if we see a new DCPLB fault, return
+ * without doing anything. Then, if we get the same fault again,
+ * handle it.
+ */
+ p5.l = _last_cplb_fault_retx;
+ p5.h = _last_cplb_fault_retx;
+ r7 = [p5];
+ r6 = retx;
+ [p5] = r6;
+ cc = r6 == r7;
+ if !cc jump _return_from_exception;
+ /* fall through */
+#endif
+
+ENTRY(_ex_icplb)
+ (R7:6,P5:4) = [sp++];
+ ASTAT = [sp++];
+ SAVE_ALL_SYS
+ call __cplb_hdr;
+ DEBUG_START_HWTRACE
+ RESTORE_ALL_SYS
+ SP = RETN;
+ rtx;
+
+ENTRY(_ex_spinlock)
+ /* Transform this into a syscall - twiddle the syscall vector. */
+ p5.l = lo(EVT15);
+ p5.h = hi(EVT15);
+ r7.l = _spinlock_bh;
+ r7.h = _spinlock_bh;
+ [p5] = r7;
+ csync;
+ /* Fall through. */
+
+ENTRY(_ex_syscall)
+ DEBUG_START_HWTRACE
+ (R7:6,P5:4) = [sp++];
+ ASTAT = [sp++];
+ raise 15; /* invoked by TRAP #0, for sys call */
+ sp = retn;
+ rtx
+
+ENTRY(_spinlock_bh)
+ SAVE_ALL_SYS
+ /* To end up here, vector 15 was changed - so we have to change it
+ * back.
+ */
+ p0.l = lo(EVT15);
+ p0.h = hi(EVT15);
+ p1.l = _evt_system_call;
+ p1.h = _evt_system_call;
+ [p0] = p1;
+ csync;
+ r0 = [sp + PT_R0];
+ sp += -12;
+ call _sys_bfin_spinlock;
+ sp += 12;
+ [SP + PT_R0] = R0;
+ RESTORE_ALL_SYS
+ rti;
+
+ENTRY(_ex_soft_bp)
+ r7 = retx;
+ r7 += -2;
+ retx = r7;
+ jump.s _ex_trap_c;
+
+ENTRY(_ex_single_step)
+ r7 = retx;
+ r6 = reti;
+ cc = r7 == r6;
+ if cc jump _return_from_exception
+ r7 = syscfg;
+ bitclr (r7, 0);
+ syscfg = R7;
+
+ p5.l = lo(IPEND);
+ p5.h = hi(IPEND);
+ r6 = [p5];
+ cc = bittst(r6, 5);
+ if !cc jump _ex_trap_c;
+ p4.l = lo(EVT5);
+ p4.h = hi(EVT5);
+ r6.h = _exception_to_level5;
+ r6.l = _exception_to_level5;
+ r7 = [p4];
+ cc = r6 == r7;
+ if !cc jump _ex_trap_c;
+
+_return_from_exception:
+ DEBUG_START_HWTRACE
+ (R7:6,P5:4) = [sp++];
+ ASTAT = [sp++];
+ sp = retn;
+ rtx;
+
+ENTRY(_handle_bad_cplb)
+ /* To get here, we just tried and failed to change a CPLB
+ * so, handle things in trap_c (C code), by lowering to
+ * IRQ5, just like we normally do. Since this is not a
+ * "normal" return path, we have a do alot of stuff to
+ * the stack to get ready so, we can fall through - we
+ * need to make a CPLB exception look like a normal exception
+ */
+
+ DEBUG_START_HWTRACE
+ RESTORE_ALL_SYS
+ [--sp] = ASTAT;
+ [--sp] = (R7:6, P5:4);
+
+ENTRY(_ex_trap_c)
+ /* Call C code (trap_c) to handle the exception, which most
+ * likely involves sending a signal to the current process.
+ * To avoid double faults, lower our priority to IRQ5 first.
+ */
+ P5.h = _exception_to_level5;
+ P5.l = _exception_to_level5;
+ p4.l = lo(EVT5);
+ p4.h = hi(EVT5);
+ [p4] = p5;
+ csync;
+
+ /* Disable all interrupts, but make sure level 5 is enabled so
+ * we can switch to that level. Save the old mask. */
+ cli r6;
+ p4.l = _excpt_saved_imask;
+ p4.h = _excpt_saved_imask;
+ [p4] = r6;
+ r6 = 0x3f;
+ sti r6;
+
+ /* Save the excause into a circular buffer, in case the instruction
+ * which caused this excecptions causes others.
+ */
+ P5.l = _in_ptr_excause;
+ P5.h = _in_ptr_excause;
+ R7 = [P5];
+ R7 += 4;
+ R6 = 0xF;
+ R7 = R7 & R6;
+ [P5] = R7;
+ R6.l = _excause_circ_buf;
+ R6.h = _excause_circ_buf;
+ R7 = R7 + R6;
+ p5 = R7;
+ R6 = SEQSTAT;
+ [P5] = R6;
+
+ DEBUG_START_HWTRACE
+ (R7:6,P5:4) = [sp++];
+ ASTAT = [sp++];
+ SP = RETN;
+ raise 5;
+ rtx;
+
+ENTRY(_exception_to_level5)
+ SAVE_ALL_SYS
+
+ /* Restore interrupt mask. We haven't pushed RETI, so this
+ * doesn't enable interrupts until we return from this handler. */
+ p4.l = _excpt_saved_imask;
+ p4.h = _excpt_saved_imask;
+ r6 = [p4];
+ sti r6;
+
+ /* Restore the hardware error vector. */
+ P5.h = _evt_ivhw;
+ P5.l = _evt_ivhw;
+ p4.l = lo(EVT5);
+ p4.h = hi(EVT5);
+ [p4] = p5;
+ csync;
+
+ p2.l = lo(IPEND);
+ p2.h = hi(IPEND);
+ csync;
+ r0 = [p2]; /* Read current IPEND */
+ [sp + PT_IPEND] = r0; /* Store IPEND */
+
+ /* Pop the excause from the circular buffer and push it on the stack
+ * (in the right place - if you change the location of SEQSTAT, you
+ * must change this offset.
+ */
+.L_excep_to_5_again:
+ P5.l = _out_ptr_excause;
+ P5.h = _out_ptr_excause;
+ R7 = [P5];
+ R7 += 4;
+ R6 = 0xF;
+ R7 = R7 & R6;
+ [P5] = R7;
+ R6.l = _excause_circ_buf;
+ R6.h = _excause_circ_buf;
+ R7 = R7 + R6;
+ P5 = R7;
+ R1 = [P5];
+ [SP + 8] = r1;
+
+ r0 = sp; /* stack frame pt_regs pointer argument ==> r0 */
+ SP += -12;
+ call _trap_c;
+ SP += 12;
+
+ /* See if anything else is in the exception buffer
+ * if there is, process it
+ */
+ P5.l = _out_ptr_excause;
+ P5.h = _out_ptr_excause;
+ P4.l = _in_ptr_excause;
+ P4.h = _in_ptr_excause;
+ R6 = [P5];
+ R7 = [P4];
+ CC = R6 == R7;
+ if ! CC JUMP .L_excep_to_5_again
+
+ call _ret_from_exception;
+ RESTORE_ALL_SYS
+ rti;
+
+ENTRY(_trap) /* Exception: 4th entry into system event table(supervisor mode)*/
+ /* Since the kernel stack can be anywhere, it's not guaranteed to be
+ * covered by a CPLB. Switch to an exception stack; use RETN as a
+ * scratch register (for want of a better option).
+ */
+ retn = sp;
+ sp.l = _exception_stack_top;
+ sp.h = _exception_stack_top;
+ /* Try to deal with syscalls quickly. */
+ [--sp] = ASTAT;
+ [--sp] = (R7:6, P5:4);
+ DEBUG_STOP_HWTRACE
+ r7 = SEQSTAT; /* reason code is in bit 5:0 */
+ r6.l = lo(SEQSTAT_EXCAUSE);
+ r6.h = hi(SEQSTAT_EXCAUSE);
+ r7 = r7 & r6;
+ p5.h = _extable;
+ p5.l = _extable;
+ p4 = r7;
+ p5 = p5 + (p4 << 2);
+ p4 = [p5];
+ jump (p4);
+
+.Lbadsys:
+ r7 = -ENOSYS; /* signextending enough */
+ [sp + PT_R0] = r7; /* return value from system call */
+ jump .Lsyscall_really_exit;
+
+ENTRY(_kernel_execve)
+ link SIZEOF_PTREGS;
+ p0 = sp;
+ r3 = SIZEOF_PTREGS / 4;
+ r4 = 0(x);
+0:
+ [p0++] = r4;
+ r3 += -1;
+ cc = r3 == 0;
+ if !cc jump 0b (bp);
+
+ p0 = sp;
+ sp += -16;
+ [sp + 12] = p0;
+ call _do_execve;
+ SP += 16;
+ cc = r0 == 0;
+ if ! cc jump 1f;
+ /* Success. Copy our temporary pt_regs to the top of the kernel
+ * stack and do a normal exception return.
+ */
+ r1 = sp;
+ r0 = (-KERNEL_STACK_SIZE) (x);
+ r1 = r1 & r0;
+ p2 = r1;
+ p3 = [p2];
+ r0 = KERNEL_STACK_SIZE - 4 (z);
+ p1 = r0;
+ p1 = p1 + p2;
+
+ p0 = fp;
+ r4 = [p0--];
+ r3 = SIZEOF_PTREGS / 4;
+0:
+ r4 = [p0--];
+ [p1--] = r4;
+ r3 += -1;
+ cc = r3 == 0;
+ if ! cc jump 0b (bp);
+
+ r0 = (KERNEL_STACK_SIZE - SIZEOF_PTREGS) (z);
+ p1 = r0;
+ p1 = p1 + p2;
+ sp = p1;
+ r0 = syscfg;
+ [SP + PT_SYSCFG] = r0;
+ [p3 + (TASK_THREAD + THREAD_KSP)] = sp;
+
+ RESTORE_CONTEXT;
+ rti;
+1:
+ unlink;
+ rts;
+
+ENTRY(_system_call)
+ /* Store IPEND */
+ p2.l = lo(IPEND);
+ p2.h = hi(IPEND);
+ csync;
+ r0 = [p2];
+ [sp + PT_IPEND] = r0;
+
+ /* Store RETS for now */
+ r0 = rets;
+ [sp + PT_RESERVED] = r0;
+ /* Set the stack for the current process */
+ r7 = sp;
+ r6.l = lo(ALIGN_PAGE_MASK);
+ r6.h = hi(ALIGN_PAGE_MASK);
+ r7 = r7 & r6; /* thread_info */
+ p2 = r7;
+ p2 = [p2];
+
+ [p2+(TASK_THREAD+THREAD_KSP)] = sp;
+
+ /* Check the System Call */
+ r7 = __NR_syscall;
+ /* System call number is passed in P0 */
+ r6 = p0;
+ cc = r6 < r7;
+ if ! cc jump .Lbadsys;
+
+ /* are we tracing syscalls?*/
+ r7 = sp;
+ r6.l = lo(ALIGN_PAGE_MASK);
+ r6.h = hi(ALIGN_PAGE_MASK);
+ r7 = r7 & r6;
+ p2 = r7;
+ r7 = [p2+TI_FLAGS];
+ CC = BITTST(r7,TIF_SYSCALL_TRACE);
+ if CC JUMP _sys_trace;
+
+ /* Execute the appropriate system call */
+
+ p4 = p0;
+ p5.l = _sys_call_table;
+ p5.h = _sys_call_table;
+ p5 = p5 + (p4 << 2);
+ r0 = [sp + PT_R0];
+ r1 = [sp + PT_R1];
+ r2 = [sp + PT_R2];
+ p5 = [p5];
+
+ [--sp] = r5;
+ [--sp] = r4;
+ [--sp] = r3;
+ SP += -12;
+ call (p5);
+ SP += 24;
+ [sp + PT_R0] = r0;
+
+.Lresume_userspace:
+ r7 = sp;
+ r4.l = lo(ALIGN_PAGE_MASK);
+ r4.h = hi(ALIGN_PAGE_MASK);
+ r7 = r7 & r4; /* thread_info->flags */
+ p5 = r7;
+.Lresume_userspace_1:
+ /* Disable interrupts. */
+ [--sp] = reti;
+ reti = [sp++];
+
+ r7 = [p5 + TI_FLAGS];
+ r4.l = lo(_TIF_WORK_MASK);
+ r4.h = hi(_TIF_WORK_MASK);
+ r7 = r7 & r4;
+
+.Lsyscall_resched:
+ cc = BITTST(r7, TIF_NEED_RESCHED);
+ if !cc jump .Lsyscall_sigpending;
+
+ /* Reenable interrupts. */
+ [--sp] = reti;
+ r0 = [sp++];
+
+ SP += -12;
+ call _schedule;
+ SP += 12;
+
+ jump .Lresume_userspace_1;
+
+.Lsyscall_sigpending:
+ cc = BITTST(r7, TIF_RESTORE_SIGMASK);
+ if cc jump .Lsyscall_do_signals;
+ cc = BITTST(r7, TIF_SIGPENDING);
+ if !cc jump .Lsyscall_really_exit;
+.Lsyscall_do_signals:
+ /* Reenable interrupts. */
+ [--sp] = reti;
+ r0 = [sp++];
+
+ r0 = sp;
+ SP += -12;
+ call _do_signal;
+ SP += 12;
+
+.Lsyscall_really_exit:
+ r5 = [sp + PT_RESERVED];
+ rets = r5;
+ rts;
+
+_sys_trace:
+ call _syscall_trace;
+
+ /* Execute the appropriate system call */
+
+ p4 = [SP + PT_P0];
+ p5.l = _sys_call_table;
+ p5.h = _sys_call_table;
+ p5 = p5 + (p4 << 2);
+ r0 = [sp + PT_R0];
+ r1 = [sp + PT_R1];
+ r2 = [sp + PT_R2];
+ r3 = [sp + PT_R3];
+ r4 = [sp + PT_R4];
+ r5 = [sp + PT_R5];
+ p5 = [p5];
+
+ [--sp] = r5;
+ [--sp] = r4;
+ [--sp] = r3;
+ SP += -12;
+ call (p5);
+ SP += 24;
+ [sp + PT_R0] = r0;
+
+ call _syscall_trace;
+ jump .Lresume_userspace;
+
+ENTRY(_resume)
+ /*
+ * Beware - when entering resume, prev (the current task) is
+ * in r0, next (the new task) is in r1.
+ */
+ p0 = r0;
+ p1 = r1;
+ [--sp] = rets;
+ [--sp] = fp;
+ [--sp] = (r7:4, p5:3);
+
+ /* save usp */
+ p2 = usp;
+ [p0+(TASK_THREAD+THREAD_USP)] = p2;
+
+ /* save current kernel stack pointer */
+ [p0+(TASK_THREAD+THREAD_KSP)] = sp;
+
+ /* save program counter */
+ r1.l = _new_old_task;
+ r1.h = _new_old_task;
+ [p0+(TASK_THREAD+THREAD_PC)] = r1;
+
+ /* restore the kernel stack pointer */
+ sp = [p1+(TASK_THREAD+THREAD_KSP)];
+
+ /* restore user stack pointer */
+ p0 = [p1+(TASK_THREAD+THREAD_USP)];
+ usp = p0;
+
+ /* restore pc */
+ p0 = [p1+(TASK_THREAD+THREAD_PC)];
+ jump (p0);
+
+ /*
+ * Following code actually lands up in a new (old) task.
+ */
+
+_new_old_task:
+ (r7:4, p5:3) = [sp++];
+ fp = [sp++];
+ rets = [sp++];
+
+ /*
+ * When we come out of resume, r0 carries "old" task, becuase we are
+ * in "new" task.
+ */
+ rts;
+
+ENTRY(_ret_from_exception)
+ p2.l = lo(IPEND);
+ p2.h = hi(IPEND);
+
+ csync;
+ r0 = [p2];
+ [sp + PT_IPEND] = r0;
+
+1:
+ r1 = 0x37(Z);
+ r2 = ~r1;
+ r2.h = 0;
+ r0 = r2 & r0;
+ cc = r0 == 0;
+ if !cc jump 4f; /* if not return to user mode, get out */
+
+ /* Make sure any pending system call or deferred exception
+ * return in ILAT for this process to get executed, otherwise
+ * in case context switch happens, system call of
+ * first process (i.e in ILAT) will be carried
+ * forward to the switched process
+ */
+
+ p2.l = lo(ILAT);
+ p2.h = hi(ILAT);
+ r0 = [p2];
+ r1 = (EVT_IVG14 | EVT_IVG15) (z);
+ r0 = r0 & r1;
+ cc = r0 == 0;
+ if !cc jump 5f;
+
+ /* Set the stack for the current process */
+ r7 = sp;
+ r4.l = lo(ALIGN_PAGE_MASK);
+ r4.h = hi(ALIGN_PAGE_MASK);
+ r7 = r7 & r4; /* thread_info->flags */
+ p5 = r7;
+ r7 = [p5 + TI_FLAGS];
+ r4.l = lo(_TIF_WORK_MASK);
+ r4.h = hi(_TIF_WORK_MASK);
+ r7 = r7 & r4;
+ cc = r7 == 0;
+ if cc jump 4f;
+
+ p0.l = lo(EVT15);
+ p0.h = hi(EVT15);
+ p1.l = _schedule_and_signal;
+ p1.h = _schedule_and_signal;
+ [p0] = p1;
+ csync;
+ raise 15; /* raise evt14 to do signal or reschedule */
+4:
+ r0 = syscfg;
+ bitclr(r0, 0);
+ syscfg = r0;
+5:
+ rts;
+
+ENTRY(_return_from_int)
+ /* If someone else already raised IRQ 15, do nothing. */
+ csync;
+ p2.l = lo(ILAT);
+ p2.h = hi(ILAT);
+ r0 = [p2];
+ cc = bittst (r0, EVT_IVG15_P);
+ if cc jump 2f;
+
+ /* if not return to user mode, get out */
+ p2.l = lo(IPEND);
+ p2.h = hi(IPEND);
+ r0 = [p2];
+ r1 = 0x17(Z);
+ r2 = ~r1;
+ r2.h = 0;
+ r0 = r2 & r0;
+ r1 = 1;
+ r1 = r0 - r1;
+ r2 = r0 & r1;
+ cc = r2 == 0;
+ if !cc jump 2f;
+
+ /* Lower the interrupt level to 15. */
+ p0.l = lo(EVT15);
+ p0.h = hi(EVT15);
+ p1.l = _schedule_and_signal_from_int;
+ p1.h = _schedule_and_signal_from_int;
+ [p0] = p1;
+ csync;
+#if defined(ANOMALY_05000281)
+ r0.l = lo(CONFIG_BOOT_LOAD);
+ r0.h = hi(CONFIG_BOOT_LOAD);
+ reti = r0;
+#endif
+ r0 = 0x801f (z);
+ STI r0;
+ raise 15; /* raise evt15 to do signal or reschedule */
+ rti;
+2:
+ rts;
+
+ENTRY(_lower_to_irq14)
+#if defined(ANOMALY_05000281)
+ r0.l = lo(CONFIG_BOOT_LOAD);
+ r0.h = hi(CONFIG_BOOT_LOAD);
+ reti = r0;
+#endif
+ r0 = 0x401f;
+ sti r0;
+ raise 14;
+ rti;
+ENTRY(_evt14_softirq)
+#ifdef CONFIG_DEBUG_HWERR
+ r0 = 0x3f;
+ sti r0;
+#else
+ cli r0;
+#endif
+ [--sp] = RETI;
+ SP += 4;
+ rts;
+
+_schedule_and_signal_from_int:
+ /* To end up here, vector 15 was changed - so we have to change it
+ * back.
+ */
+ p0.l = lo(EVT15);
+ p0.h = hi(EVT15);
+ p1.l = _evt_system_call;
+ p1.h = _evt_system_call;
+ [p0] = p1;
+ csync;
+ p1 = rets;
+ [sp + PT_RESERVED] = p1;
+
+ p0.l = _irq_flags;
+ p0.h = _irq_flags;
+ r0 = [p0];
+ sti r0;
+
+ jump.s .Lresume_userspace;
+
+_schedule_and_signal:
+ SAVE_CONTEXT_SYSCALL
+ /* To end up here, vector 15 was changed - so we have to change it
+ * back.
+ */
+ p0.l = lo(EVT15);
+ p0.h = hi(EVT15);
+ p1.l = _evt_system_call;
+ p1.h = _evt_system_call;
+ [p0] = p1;
+ csync;
+ p0.l = 1f;
+ p0.h = 1f;
+ [sp + PT_RESERVED] = P0;
+ call .Lresume_userspace;
+1:
+ RESTORE_CONTEXT
+ rti;
+
+/* Make sure when we start, that the circular buffer is initialized properly
+ * R0 and P0 are call clobbered, so we can use them here.
+ */
+ENTRY(_init_exception_buff)
+ r0 = 0;
+ p0.h = _in_ptr_excause;
+ p0.l = _in_ptr_excause;
+ [p0] = r0;
+ p0.h = _out_ptr_excause;
+ p0.l = _out_ptr_excause;
+ [p0] = r0;
+ rts;
+
+/*
+ * Put these in the kernel data section - that should always be covered by
+ * a CPLB. This is needed to ensure we don't get double fault conditions
+ */
+
+#ifdef CONFIG_SYSCALL_TAB_L1
+.section .l1.data
+#else
+.data
+#endif
+ALIGN
+_extable:
+ /* entry for each EXCAUSE[5:0]
+ * This table bmust be in sync with the table in ./kernel/traps.c
+ * EXCPT instruction can provide 4 bits of EXCAUSE, allowing 16 to be user defined
+ */
+ .long _ex_syscall; /* 0x00 - User Defined - Linux Syscall */
+ .long _ex_soft_bp /* 0x01 - User Defined - Software breakpoint */
+ .long _ex_trap_c /* 0x02 - User Defined */
+ .long _ex_trap_c /* 0x03 - User Defined - Atomic test and set service */
+ .long _ex_spinlock /* 0x04 - User Defined */
+ .long _ex_trap_c /* 0x05 - User Defined */
+ .long _ex_trap_c /* 0x06 - User Defined */
+ .long _ex_trap_c /* 0x07 - User Defined */
+ .long _ex_trap_c /* 0x08 - User Defined */
+ .long _ex_trap_c /* 0x09 - User Defined */
+ .long _ex_trap_c /* 0x0A - User Defined */
+ .long _ex_trap_c /* 0x0B - User Defined */
+ .long _ex_trap_c /* 0x0C - User Defined */
+ .long _ex_trap_c /* 0x0D - User Defined */
+ .long _ex_trap_c /* 0x0E - User Defined */
+ .long _ex_trap_c /* 0x0F - User Defined */
+ .long _ex_single_step /* 0x10 - HW Single step */
+ .long _ex_trap_c /* 0x11 - Trace Buffer Full */
+ .long _ex_trap_c /* 0x12 - Reserved */
+ .long _ex_trap_c /* 0x13 - Reserved */
+ .long _ex_trap_c /* 0x14 - Reserved */
+ .long _ex_trap_c /* 0x15 - Reserved */
+ .long _ex_trap_c /* 0x16 - Reserved */
+ .long _ex_trap_c /* 0x17 - Reserved */
+ .long _ex_trap_c /* 0x18 - Reserved */
+ .long _ex_trap_c /* 0x19 - Reserved */
+ .long _ex_trap_c /* 0x1A - Reserved */
+ .long _ex_trap_c /* 0x1B - Reserved */
+ .long _ex_trap_c /* 0x1C - Reserved */
+ .long _ex_trap_c /* 0x1D - Reserved */
+ .long _ex_trap_c /* 0x1E - Reserved */
+ .long _ex_trap_c /* 0x1F - Reserved */
+ .long _ex_trap_c /* 0x20 - Reserved */
+ .long _ex_trap_c /* 0x21 - Undefined Instruction */
+ .long _ex_trap_c /* 0x22 - Illegal Instruction Combination */
+ .long _ex_dcplb /* 0x23 - Data CPLB Protection Violation */
+ .long _ex_trap_c /* 0x24 - Data access misaligned */
+ .long _ex_trap_c /* 0x25 - Unrecoverable Event */
+ .long _ex_dcplb /* 0x26 - Data CPLB Miss */
+ .long _ex_trap_c /* 0x27 - Data CPLB Multiple Hits - Linux Trap Zero */
+ .long _ex_trap_c /* 0x28 - Emulation Watchpoint */
+ .long _ex_trap_c /* 0x29 - Instruction fetch access error (535 only) */
+ .long _ex_trap_c /* 0x2A - Instruction fetch misaligned */
+ .long _ex_icplb /* 0x2B - Instruction CPLB protection Violation */
+ .long _ex_icplb /* 0x2C - Instruction CPLB miss */
+ .long _ex_trap_c /* 0x2D - Instruction CPLB Multiple Hits */
+ .long _ex_trap_c /* 0x2E - Illegal use of Supervisor Resource */
+ .long _ex_trap_c /* 0x2E - Illegal use of Supervisor Resource */
+ .long _ex_trap_c /* 0x2F - Reserved */
+ .long _ex_trap_c /* 0x30 - Reserved */
+ .long _ex_trap_c /* 0x31 - Reserved */
+ .long _ex_trap_c /* 0x32 - Reserved */
+ .long _ex_trap_c /* 0x33 - Reserved */
+ .long _ex_trap_c /* 0x34 - Reserved */
+ .long _ex_trap_c /* 0x35 - Reserved */
+ .long _ex_trap_c /* 0x36 - Reserved */
+ .long _ex_trap_c /* 0x37 - Reserved */
+ .long _ex_trap_c /* 0x38 - Reserved */
+ .long _ex_trap_c /* 0x39 - Reserved */
+ .long _ex_trap_c /* 0x3A - Reserved */
+ .long _ex_trap_c /* 0x3B - Reserved */
+ .long _ex_trap_c /* 0x3C - Reserved */
+ .long _ex_trap_c /* 0x3D - Reserved */
+ .long _ex_trap_c /* 0x3E - Reserved */
+ .long _ex_trap_c /* 0x3F - Reserved */
+
+ALIGN
+ENTRY(_sys_call_table)
+ .long _sys_ni_syscall /* 0 - old "setup()" system call*/
+ .long _sys_exit
+ .long _sys_fork
+ .long _sys_read
+ .long _sys_write
+ .long _sys_open /* 5 */
+ .long _sys_close
+ .long _sys_ni_syscall /* old waitpid */
+ .long _sys_creat
+ .long _sys_link
+ .long _sys_unlink /* 10 */
+ .long _sys_execve
+ .long _sys_chdir
+ .long _sys_time
+ .long _sys_mknod
+ .long _sys_chmod /* 15 */
+ .long _sys_chown /* chown16 */
+ .long _sys_ni_syscall /* old break syscall holder */
+ .long _sys_ni_syscall /* old stat */
+ .long _sys_lseek
+ .long _sys_getpid /* 20 */
+ .long _sys_mount
+ .long _sys_ni_syscall /* old umount */
+ .long _sys_setuid
+ .long _sys_getuid
+ .long _sys_stime /* 25 */
+ .long _sys_ptrace
+ .long _sys_alarm
+ .long _sys_ni_syscall /* old fstat */
+ .long _sys_pause
+ .long _sys_ni_syscall /* old utime */ /* 30 */
+ .long _sys_ni_syscall /* old stty syscall holder */
+ .long _sys_ni_syscall /* old gtty syscall holder */
+ .long _sys_access
+ .long _sys_nice
+ .long _sys_ni_syscall /* 35 */ /* old ftime syscall holder */
+ .long _sys_sync
+ .long _sys_kill
+ .long _sys_rename
+ .long _sys_mkdir
+ .long _sys_rmdir /* 40 */
+ .long _sys_dup
+ .long _sys_pipe
+ .long _sys_times
+ .long _sys_ni_syscall /* old prof syscall holder */
+ .long _sys_brk /* 45 */
+ .long _sys_setgid
+ .long _sys_getgid
+ .long _sys_ni_syscall /* old sys_signal */
+ .long _sys_geteuid /* geteuid16 */
+ .long _sys_getegid /* getegid16 */ /* 50 */
+ .long _sys_acct
+ .long _sys_umount /* recycled never used phys() */
+ .long _sys_ni_syscall /* old lock syscall holder */
+ .long _sys_ioctl
+ .long _sys_fcntl /* 55 */
+ .long _sys_ni_syscall /* old mpx syscall holder */
+ .long _sys_setpgid
+ .long _sys_ni_syscall /* old ulimit syscall holder */
+ .long _sys_ni_syscall /* old old uname */
+ .long _sys_umask /* 60 */
+ .long _sys_chroot
+ .long _sys_ustat
+ .long _sys_dup2
+ .long _sys_getppid
+ .long _sys_getpgrp /* 65 */
+ .long _sys_setsid
+ .long _sys_ni_syscall /* old sys_sigaction */
+ .long _sys_sgetmask
+ .long _sys_ssetmask
+ .long _sys_setreuid /* setreuid16 */ /* 70 */
+ .long _sys_setregid /* setregid16 */
+ .long _sys_ni_syscall /* old sys_sigsuspend */
+ .long _sys_ni_syscall /* old sys_sigpending */
+ .long _sys_sethostname
+ .long _sys_setrlimit /* 75 */
+ .long _sys_ni_syscall /* old getrlimit */
+ .long _sys_getrusage
+ .long _sys_gettimeofday
+ .long _sys_settimeofday
+ .long _sys_getgroups /* getgroups16 */ /* 80 */
+ .long _sys_setgroups /* setgroups16 */
+ .long _sys_ni_syscall /* old_select */
+ .long _sys_symlink
+ .long _sys_ni_syscall /* old lstat */
+ .long _sys_readlink /* 85 */
+ .long _sys_uselib
+ .long _sys_ni_syscall /* sys_swapon */
+ .long _sys_reboot
+ .long _sys_ni_syscall /* old_readdir */
+ .long _sys_ni_syscall /* sys_mmap */ /* 90 */
+ .long _sys_munmap
+ .long _sys_truncate
+ .long _sys_ftruncate
+ .long _sys_fchmod
+ .long _sys_fchown /* fchown16 */ /* 95 */
+ .long _sys_getpriority
+ .long _sys_setpriority
+ .long _sys_ni_syscall /* old profil syscall holder */
+ .long _sys_statfs
+ .long _sys_fstatfs /* 100 */
+ .long _sys_ni_syscall
+ .long _sys_ni_syscall /* old sys_socketcall */
+ .long _sys_syslog
+ .long _sys_setitimer
+ .long _sys_getitimer /* 105 */
+ .long _sys_newstat
+ .long _sys_newlstat
+ .long _sys_newfstat
+ .long _sys_ni_syscall /* old uname */
+ .long _sys_ni_syscall /* iopl for i386 */ /* 110 */
+ .long _sys_vhangup
+ .long _sys_ni_syscall /* obsolete idle() syscall */
+ .long _sys_ni_syscall /* vm86old for i386 */
+ .long _sys_wait4
+ .long _sys_ni_syscall /* 115 */ /* sys_swapoff */
+ .long _sys_sysinfo
+ .long _sys_ni_syscall /* old sys_ipc */
+ .long _sys_fsync
+ .long _sys_ni_syscall /* old sys_sigreturn */
+ .long _sys_clone /* 120 */
+ .long _sys_setdomainname
+ .long _sys_newuname
+ .long _sys_ni_syscall /* old sys_modify_ldt */
+ .long _sys_adjtimex
+ .long _sys_ni_syscall /* 125 */ /* sys_mprotect */
+ .long _sys_ni_syscall /* old sys_sigprocmask */
+ .long _sys_ni_syscall /* old "creat_module" */
+ .long _sys_init_module
+ .long _sys_delete_module
+ .long _sys_ni_syscall /* 130: old "get_kernel_syms" */
+ .long _sys_quotactl
+ .long _sys_getpgid
+ .long _sys_fchdir
+ .long _sys_bdflush
+ .long _sys_ni_syscall /* 135 */ /* sys_sysfs */
+ .long _sys_personality
+ .long _sys_ni_syscall /* for afs_syscall */
+ .long _sys_setfsuid /* setfsuid16 */
+ .long _sys_setfsgid /* setfsgid16 */
+ .long _sys_llseek /* 140 */
+ .long _sys_getdents
+ .long _sys_ni_syscall /* sys_select */
+ .long _sys_flock
+ .long _sys_ni_syscall /* sys_msync */
+ .long _sys_readv /* 145 */
+ .long _sys_writev
+ .long _sys_getsid
+ .long _sys_fdatasync
+ .long _sys_sysctl
+ .long _sys_ni_syscall /* 150 */ /* sys_mlock */
+ .long _sys_ni_syscall /* sys_munlock */
+ .long _sys_ni_syscall /* sys_mlockall */
+ .long _sys_ni_syscall /* sys_munlockall */
+ .long _sys_sched_setparam
+ .long _sys_sched_getparam /* 155 */
+ .long _sys_sched_setscheduler
+ .long _sys_sched_getscheduler
+ .long _sys_sched_yield
+ .long _sys_sched_get_priority_max
+ .long _sys_sched_get_priority_min /* 160 */
+ .long _sys_sched_rr_get_interval
+ .long _sys_nanosleep
+ .long _sys_ni_syscall /* sys_mremap */
+ .long _sys_setresuid /* setresuid16 */
+ .long _sys_getresuid /* getresuid16 */ /* 165 */
+ .long _sys_ni_syscall /* for vm86 */
+ .long _sys_ni_syscall /* old "query_module" */
+ .long _sys_ni_syscall /* sys_poll */
+ .long _sys_ni_syscall /* sys_nfsservctl */
+ .long _sys_setresgid /* setresgid16 */ /* 170 */
+ .long _sys_getresgid /* getresgid16 */
+ .long _sys_prctl
+ .long _sys_rt_sigreturn
+ .long _sys_rt_sigaction
+ .long _sys_rt_sigprocmask /* 175 */
+ .long _sys_rt_sigpending
+ .long _sys_rt_sigtimedwait
+ .long _sys_rt_sigqueueinfo
+ .long _sys_rt_sigsuspend
+ .long _sys_pread64 /* 180 */
+ .long _sys_pwrite64
+ .long _sys_lchown /* lchown16 */
+ .long _sys_getcwd
+ .long _sys_capget
+ .long _sys_capset /* 185 */
+ .long _sys_sigaltstack
+ .long _sys_sendfile
+ .long _sys_ni_syscall /* streams1 */
+ .long _sys_ni_syscall /* streams2 */
+ .long _sys_vfork /* 190 */
+ .long _sys_getrlimit
+ .long _sys_mmap2
+ .long _sys_truncate64
+ .long _sys_ftruncate64
+ .long _sys_stat64 /* 195 */
+ .long _sys_lstat64
+ .long _sys_fstat64
+ .long _sys_chown
+ .long _sys_getuid
+ .long _sys_getgid /* 200 */
+ .long _sys_geteuid
+ .long _sys_getegid
+ .long _sys_setreuid
+ .long _sys_setregid
+ .long _sys_getgroups /* 205 */
+ .long _sys_setgroups
+ .long _sys_fchown
+ .long _sys_setresuid
+ .long _sys_getresuid
+ .long _sys_setresgid /* 210 */
+ .long _sys_getresgid
+ .long _sys_lchown
+ .long _sys_setuid
+ .long _sys_setgid
+ .long _sys_setfsuid /* 215 */
+ .long _sys_setfsgid
+ .long _sys_pivot_root
+ .long _sys_ni_syscall /* sys_mincore */
+ .long _sys_ni_syscall /* sys_madvise */
+ .long _sys_getdents64 /* 220 */
+ .long _sys_fcntl64
+ .long _sys_ni_syscall /* reserved for TUX */
+ .long _sys_ni_syscall
+ .long _sys_gettid
+ .long _sys_ni_syscall /* 225 */ /* sys_readahead */
+ .long _sys_setxattr
+ .long _sys_lsetxattr
+ .long _sys_fsetxattr
+ .long _sys_getxattr
+ .long _sys_lgetxattr /* 230 */
+ .long _sys_fgetxattr
+ .long _sys_listxattr
+ .long _sys_llistxattr
+ .long _sys_flistxattr
+ .long _sys_removexattr /* 235 */
+ .long _sys_lremovexattr
+ .long _sys_fremovexattr
+ .long _sys_tkill
+ .long _sys_sendfile64
+ .long _sys_futex /* 240 */
+ .long _sys_sched_setaffinity
+ .long _sys_sched_getaffinity
+ .long _sys_ni_syscall /* sys_set_thread_area */
+ .long _sys_ni_syscall /* sys_get_thread_area */
+ .long _sys_io_setup /* 245 */
+ .long _sys_io_destroy
+ .long _sys_io_getevents
+ .long _sys_io_submit
+ .long _sys_io_cancel
+ .long _sys_ni_syscall /* 250 */ /* sys_alloc_hugepages */
+ .long _sys_ni_syscall /* sys_freec_hugepages */
+ .long _sys_exit_group
+ .long _sys_lookup_dcookie
+ .long _sys_bfin_spinlock
+ .long _sys_epoll_create /* 255 */
+ .long _sys_epoll_ctl
+ .long _sys_epoll_wait
+ .long _sys_ni_syscall /* remap_file_pages */
+ .long _sys_set_tid_address
+ .long _sys_timer_create /* 260 */
+ .long _sys_timer_settime
+ .long _sys_timer_gettime
+ .long _sys_timer_getoverrun
+ .long _sys_timer_delete
+ .long _sys_clock_settime /* 265 */
+ .long _sys_clock_gettime
+ .long _sys_clock_getres
+ .long _sys_clock_nanosleep
+ .long _sys_statfs64
+ .long _sys_fstatfs64 /* 270 */
+ .long _sys_tgkill
+ .long _sys_utimes
+ .long _sys_fadvise64_64
+ .long _sys_ni_syscall /* vserver */
+ .long _sys_ni_syscall /* 275, mbind */
+ .long _sys_ni_syscall /* get_mempolicy */
+ .long _sys_ni_syscall /* set_mempolicy */
+ .long _sys_mq_open
+ .long _sys_mq_unlink
+ .long _sys_mq_timedsend /* 280 */
+ .long _sys_mq_timedreceive
+ .long _sys_mq_notify
+ .long _sys_mq_getsetattr
+ .long _sys_ni_syscall /* kexec_load */
+ .long _sys_waitid /* 285 */
+ .long _sys_add_key
+ .long _sys_request_key
+ .long _sys_keyctl
+ .long _sys_ioprio_set
+ .long _sys_ioprio_get /* 290 */
+ .long _sys_inotify_init
+ .long _sys_inotify_add_watch
+ .long _sys_inotify_rm_watch
+ .long _sys_ni_syscall /* migrate_pages */
+ .long _sys_openat /* 295 */
+ .long _sys_mkdirat
+ .long _sys_mknodat
+ .long _sys_fchownat
+ .long _sys_futimesat
+ .long _sys_fstatat64 /* 300 */
+ .long _sys_unlinkat
+ .long _sys_renameat
+ .long _sys_linkat
+ .long _sys_symlinkat
+ .long _sys_readlinkat /* 305 */
+ .long _sys_fchmodat
+ .long _sys_faccessat
+ .long _sys_pselect6
+ .long _sys_ppoll
+ .long _sys_unshare /* 310 */
+ .long _sys_sram_alloc
+ .long _sys_sram_free
+ .long _sys_dma_memcpy
+ .long _sys_accept
+ .long _sys_bind /* 315 */
+ .long _sys_connect
+ .long _sys_getpeername
+ .long _sys_getsockname
+ .long _sys_getsockopt
+ .long _sys_listen /* 320 */
+ .long _sys_recv
+ .long _sys_recvfrom
+ .long _sys_recvmsg
+ .long _sys_send
+ .long _sys_sendmsg /* 325 */
+ .long _sys_sendto
+ .long _sys_setsockopt
+ .long _sys_shutdown
+ .long _sys_socket
+ .long _sys_socketpair /* 330 */
+ .long _sys_semctl
+ .long _sys_semget
+ .long _sys_semop
+ .long _sys_msgctl
+ .long _sys_msgget /* 335 */
+ .long _sys_msgrcv
+ .long _sys_msgsnd
+ .long _sys_shmat
+ .long _sys_shmctl
+ .long _sys_shmdt /* 340 */
+ .long _sys_shmget
+ .rept NR_syscalls-(.-_sys_call_table)/4
+ .long _sys_ni_syscall
+ .endr
+_excpt_saved_imask:
+ .long 0;
+
+_exception_stack:
+ .rept 1024
+ .long 0;
+ .endr
+_exception_stack_top:
+
+#if defined(ANOMALY_05000261)
+/* Used by the assembly entry point to work around an anomaly. */
+_last_cplb_fault_retx:
+ .long 0;
+#endif
+/*
+ * Single instructions can have multiple faults, which need to be
+ * handled by traps.c, in irq5. We store the exception cause to ensure
+ * we don't miss a double fault condition
+ */
+ENTRY(_in_ptr_excause)
+ .long 0;
+ENTRY(_out_ptr_excause)
+ .long 0;
+ALIGN
+ENTRY(_excause_circ_buf)
+ .rept 4
+ .long 0
+ .endr
diff --git a/arch/blackfin/mach-common/interrupt.S b/arch/blackfin/mach-common/interrupt.S
new file mode 100644
index 00000000000..dd45664f0d0
--- /dev/null
+++ b/arch/blackfin/mach-common/interrupt.S
@@ -0,0 +1,253 @@
+/*
+ * File: arch/blackfin/mach-common/interrupt.S
+ * Based on:
+ * Author: D. Jeff Dionne <jeff@ryeham.ee.ryerson.ca>
+ * Kenneth Albanowski <kjahds@kjahds.com>
+ *
+ * Created: ?
+ * Description: Interrupt Entries
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <asm/blackfin.h>
+#include <asm/mach/irq.h>
+#include <linux/autoconf.h>
+#include <linux/linkage.h>
+#include <asm/entry.h>
+#include <asm/asm-offsets.h>
+
+#include <asm/mach-common/context.S>
+
+#ifdef CONFIG_I_ENTRY_L1
+.section .l1.text
+#else
+.text
+#endif
+
+.align 4 /* just in case */
+
+/*
+ * initial interrupt handlers
+ */
+
+#ifndef CONFIG_KGDB
+ /* interrupt routine for emulation - 0 */
+ /* Currently used only if GDB stub is not in - invalid */
+ /* gdb-stub set the evt itself */
+ /* save registers for post-mortem only */
+ENTRY(_evt_emulation)
+ SAVE_ALL_SYS
+#ifdef CONFIG_FRAME_POINTER
+ fp = 0;
+#endif
+ r0 = IRQ_EMU;
+ r1 = sp;
+ SP += -12;
+ call _irq_panic;
+ SP += 12;
+ /* - GDB stub fills this in by itself (if defined) */
+ rte;
+#endif
+
+/* Common interrupt entry code. First we do CLI, then push
+ * RETI, to keep interrupts disabled, but to allow this state to be changed
+ * by local_bh_enable.
+ * R0 contains the interrupt number, while R1 may contain the value of IPEND,
+ * or garbage if IPEND won't be needed by the ISR. */
+__common_int_entry:
+ [--sp] = fp;
+ [--sp] = usp;
+
+ [--sp] = i0;
+ [--sp] = i1;
+ [--sp] = i2;
+ [--sp] = i3;
+
+ [--sp] = m0;
+ [--sp] = m1;
+ [--sp] = m2;
+ [--sp] = m3;
+
+ [--sp] = l0;
+ [--sp] = l1;
+ [--sp] = l2;
+ [--sp] = l3;
+
+ [--sp] = b0;
+ [--sp] = b1;
+ [--sp] = b2;
+ [--sp] = b3;
+ [--sp] = a0.x;
+ [--sp] = a0.w;
+ [--sp] = a1.x;
+ [--sp] = a1.w;
+
+ [--sp] = LC0;
+ [--sp] = LC1;
+ [--sp] = LT0;
+ [--sp] = LT1;
+ [--sp] = LB0;
+ [--sp] = LB1;
+
+ [--sp] = ASTAT;
+
+ [--sp] = r0; /* Skip reserved */
+ [--sp] = RETS;
+ r2 = RETI;
+ [--sp] = r2;
+ [--sp] = RETX;
+ [--sp] = RETN;
+ [--sp] = RETE;
+ [--sp] = SEQSTAT;
+ [--sp] = r1; /* IPEND - R1 may or may not be set up before jumping here. */
+
+ /* Switch to other method of keeping interrupts disabled. */
+#ifdef CONFIG_DEBUG_HWERR
+ r1 = 0x3f;
+ sti r1;
+#else
+ cli r1;
+#endif
+ [--sp] = RETI; /* orig_pc */
+ /* Clear all L registers. */
+ r1 = 0 (x);
+ l0 = r1;
+ l1 = r1;
+ l2 = r1;
+ l3 = r1;
+#ifdef CONFIG_FRAME_POINTER
+ fp = 0;
+#endif
+
+#ifdef ANOMALY_05000283
+ cc = r7 == r7;
+ p5.h = 0xffc0;
+ p5.l = 0x0014;
+ if cc jump 1f;
+ r7.l = W[p5];
+1:
+#endif
+ r1 = sp;
+ SP += -12;
+ call _do_irq;
+ SP += 12;
+ call _return_from_int;
+.Lcommon_restore_context:
+ RESTORE_CONTEXT
+ rti;
+
+/* interrupt routine for ivhw - 5 */
+ENTRY(_evt_ivhw)
+ SAVE_CONTEXT
+#ifdef CONFIG_FRAME_POINTER
+ fp = 0;
+#endif
+#ifdef ANOMALY_05000283
+ cc = r7 == r7;
+ p5.h = 0xffc0;
+ p5.l = 0x0014;
+ if cc jump 1f;
+ r7.l = W[p5];
+1:
+#endif
+ p0.l = lo(TBUFCTL);
+ p0.h = hi(TBUFCTL);
+ r0 = 1;
+ [p0] = r0;
+ r0 = IRQ_HWERR;
+ r1 = sp;
+
+#ifdef CONFIG_HARDWARE_PM
+ r7 = SEQSTAT;
+ r7 = r7 >>> 0xe;
+ r6 = 0x1F;
+ r7 = r7 & r6;
+ r5 = 0x12;
+ cc = r7 == r5;
+ if cc jump .Lcall_do_ovf; /* deal with performance counter overflow */
+#endif
+
+ SP += -12;
+ call _irq_panic;
+ SP += 12;
+ rti;
+#ifdef CONFIG_HARDWARE_PM
+.Lcall_do_ovf:
+
+ SP += -12;
+ call _pm_overflow;
+ SP += 12;
+
+ jump .Lcommon_restore_context;
+#endif
+
+/* interrupt routine for evt2 - 2. This is NMI. */
+ENTRY(_evt_evt2)
+ SAVE_CONTEXT
+#ifdef CONFIG_FRAME_POINTER
+ fp = 0;
+#endif
+#ifdef ANOMALY_05000283
+ cc = r7 == r7;
+ p5.h = 0xffc0;
+ p5.l = 0x0014;
+ if cc jump 1f;
+ r7.l = W[p5];
+1:
+#endif
+ r0 = IRQ_NMI;
+ r1 = sp;
+ SP += -12;
+ call _asm_do_IRQ;
+ SP += 12;
+ RESTORE_CONTEXT
+ rtn;
+
+/* interrupt routine for core timer - 6 */
+ENTRY(_evt_timer)
+ TIMER_INTERRUPT_ENTRY(EVT_IVTMR_P)
+
+/* interrupt routine for evt7 - 7 */
+ENTRY(_evt_evt7)
+ INTERRUPT_ENTRY(EVT_IVG7_P)
+ENTRY(_evt_evt8)
+ INTERRUPT_ENTRY(EVT_IVG8_P)
+ENTRY(_evt_evt9)
+ INTERRUPT_ENTRY(EVT_IVG9_P)
+ENTRY(_evt_evt10)
+ INTERRUPT_ENTRY(EVT_IVG10_P)
+ENTRY(_evt_evt11)
+ INTERRUPT_ENTRY(EVT_IVG11_P)
+ENTRY(_evt_evt12)
+ INTERRUPT_ENTRY(EVT_IVG12_P)
+ENTRY(_evt_evt13)
+ INTERRUPT_ENTRY(EVT_IVG13_P)
+
+
+ /* interrupt routine for system_call - 15 */
+ENTRY(_evt_system_call)
+ SAVE_CONTEXT_SYSCALL
+#ifdef CONFIG_FRAME_POINTER
+ fp = 0;
+#endif
+ call _system_call;
+ jump .Lcommon_restore_context;
diff --git a/arch/blackfin/mach-common/ints-priority-dc.c b/arch/blackfin/mach-common/ints-priority-dc.c
new file mode 100644
index 00000000000..f3cf07036c2
--- /dev/null
+++ b/arch/blackfin/mach-common/ints-priority-dc.c
@@ -0,0 +1,476 @@
+/*
+ * File: arch/blackfin/mach-common/ints-priority-dc.c
+ * Based on:
+ * Author:
+ *
+ * Created: ?
+ * Description: Set up the interupt priorities
+ *
+ * Modified:
+ * 1996 Roman Zippel
+ * 1999 D. Jeff Dionne <jeff@uclinux.org>
+ * 2000-2001 Lineo, Inc. D. Jefff Dionne <jeff@lineo.ca>
+ * 2002 Arcturus Networks Inc. MaTed <mated@sympatico.ca>
+ * 2003 Metrowerks/Motorola
+ * 2003 Bas Vermeulen <bas@buyways.nl>
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/module.h>
+#include <linux/kernel_stat.h>
+#include <linux/seq_file.h>
+#include <linux/irq.h>
+#ifdef CONFIG_KGDB
+#include <linux/kgdb.h>
+#endif
+#include <asm/traps.h>
+#include <asm/blackfin.h>
+#include <asm/gpio.h>
+#include <asm/irq_handler.h>
+
+/*
+ * NOTES:
+ * - we have separated the physical Hardware interrupt from the
+ * levels that the LINUX kernel sees (see the description in irq.h)
+ * -
+ */
+
+unsigned long irq_flags = 0;
+
+/* The number of spurious interrupts */
+atomic_t num_spurious;
+
+struct ivgx {
+ /* irq number for request_irq, available in mach-bf561/irq.h */
+ int irqno;
+ /* corresponding bit in the SICA_ISR0 register */
+ int isrflag0;
+ /* corresponding bit in the SICA_ISR1 register */
+ int isrflag1;
+} ivg_table[NR_PERI_INTS];
+
+struct ivg_slice {
+ /* position of first irq in ivg_table for given ivg */
+ struct ivgx *ifirst;
+ struct ivgx *istop;
+} ivg7_13[IVG13 - IVG7 + 1];
+
+static void search_IAR(void);
+
+/*
+ * Search SIC_IAR and fill tables with the irqvalues
+ * and their positions in the SIC_ISR register.
+ */
+static void __init search_IAR(void)
+{
+ unsigned ivg, irq_pos = 0;
+ for (ivg = 0; ivg <= IVG13 - IVG7; ivg++) {
+ int irqn;
+
+ ivg7_13[ivg].istop = ivg7_13[ivg].ifirst = &ivg_table[irq_pos];
+
+ for (irqn = 0; irqn < NR_PERI_INTS; irqn++) {
+ int iar_shift = (irqn & 7) * 4;
+ if (ivg ==
+ (0xf &
+ bfin_read32((unsigned long *)SICA_IAR0 +
+ (irqn >> 3)) >> iar_shift)) {
+ ivg_table[irq_pos].irqno = IVG7 + irqn;
+ ivg_table[irq_pos].isrflag0 =
+ (irqn < 32 ? (1 << irqn) : 0);
+ ivg_table[irq_pos].isrflag1 =
+ (irqn < 32 ? 0 : (1 << (irqn - 32)));
+ ivg7_13[ivg].istop++;
+ irq_pos++;
+ }
+ }
+ }
+}
+
+/*
+ * This is for BF561 internal IRQs
+ */
+
+static void ack_noop(unsigned int irq)
+{
+ /* Dummy function. */
+}
+
+static void bf561_core_mask_irq(unsigned int irq)
+{
+ irq_flags &= ~(1 << irq);
+ if (!irqs_disabled())
+ local_irq_enable();
+}
+
+static void bf561_core_unmask_irq(unsigned int irq)
+{
+ irq_flags |= 1 << irq;
+ /*
+ * If interrupts are enabled, IMASK must contain the same value
+ * as irq_flags. Make sure that invariant holds. If interrupts
+ * are currently disabled we need not do anything; one of the
+ * callers will take care of setting IMASK to the proper value
+ * when reenabling interrupts.
+ * local_irq_enable just does "STI irq_flags", so it's exactly
+ * what we need.
+ */
+ if (!irqs_disabled())
+ local_irq_enable();
+ return;
+}
+
+static void bf561_internal_mask_irq(unsigned int irq)
+{
+ unsigned long irq_mask;
+ if ((irq - (IRQ_CORETMR + 1)) < 32) {
+ irq_mask = (1 << (irq - (IRQ_CORETMR + 1)));
+ bfin_write_SICA_IMASK0(bfin_read_SICA_IMASK0() & ~irq_mask);
+ } else {
+ irq_mask = (1 << (irq - (IRQ_CORETMR + 1) - 32));
+ bfin_write_SICA_IMASK1(bfin_read_SICA_IMASK1() & ~irq_mask);
+ }
+}
+
+static void bf561_internal_unmask_irq(unsigned int irq)
+{
+ unsigned long irq_mask;
+
+ if ((irq - (IRQ_CORETMR + 1)) < 32) {
+ irq_mask = (1 << (irq - (IRQ_CORETMR + 1)));
+ bfin_write_SICA_IMASK0(bfin_read_SICA_IMASK0() | irq_mask);
+ } else {
+ irq_mask = (1 << (irq - (IRQ_CORETMR + 1) - 32));
+ bfin_write_SICA_IMASK1(bfin_read_SICA_IMASK1() | irq_mask);
+ }
+ SSYNC();
+}
+
+static struct irq_chip bf561_core_irqchip = {
+ .ack = ack_noop,
+ .mask = bf561_core_mask_irq,
+ .unmask = bf561_core_unmask_irq,
+};
+
+static struct irq_chip bf561_internal_irqchip = {
+ .ack = ack_noop,
+ .mask = bf561_internal_mask_irq,
+ .unmask = bf561_internal_unmask_irq,
+};
+
+#ifdef CONFIG_IRQCHIP_DEMUX_GPIO
+static unsigned short gpio_enabled[gpio_bank(MAX_BLACKFIN_GPIOS)];
+static unsigned short gpio_edge_triggered[gpio_bank(MAX_BLACKFIN_GPIOS)];
+
+static void bf561_gpio_ack_irq(unsigned int irq)
+{
+ u16 gpionr = irq - IRQ_PF0;
+
+ if(gpio_edge_triggered[gpio_bank(gpionr)] & gpio_bit(gpionr)) {
+ set_gpio_data(gpionr, 0);
+ SSYNC();
+ }
+}
+
+static void bf561_gpio_mask_ack_irq(unsigned int irq)
+{
+ u16 gpionr = irq - IRQ_PF0;
+
+ if(gpio_edge_triggered[gpio_bank(gpionr)] & gpio_bit(gpionr)) {
+ set_gpio_data(gpionr, 0);
+ SSYNC();
+ }
+
+ set_gpio_maska(gpionr, 0);
+ SSYNC();
+}
+
+static void bf561_gpio_mask_irq(unsigned int irq)
+{
+ set_gpio_maska(irq - IRQ_PF0, 0);
+ SSYNC();
+}
+
+static void bf561_gpio_unmask_irq(unsigned int irq)
+{
+ set_gpio_maska(irq - IRQ_PF0, 1);
+ SSYNC();
+}
+
+static unsigned int bf561_gpio_irq_startup(unsigned int irq)
+{
+ unsigned int ret;
+ u16 gpionr = irq - IRQ_PF0;
+
+ if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) {
+
+ ret = gpio_request(gpionr, NULL);
+ if(ret)
+ return ret;
+
+ }
+
+ gpio_enabled[gpio_bank(gpionr)] |= gpio_bit(gpionr);
+ bf561_gpio_unmask_irq(irq);
+
+ return ret;
+
+}
+
+static void bf561_gpio_irq_shutdown(unsigned int irq)
+{
+ bf561_gpio_mask_irq(irq);
+ gpio_free(irq - IRQ_PF0);
+ gpio_enabled[gpio_bank(irq - IRQ_PF0)] &= ~gpio_bit(irq - IRQ_PF0);
+}
+
+static int bf561_gpio_irq_type(unsigned int irq, unsigned int type)
+{
+
+ unsigned int ret;
+ u16 gpionr = irq - IRQ_PF0;
+
+
+ if (type == IRQ_TYPE_PROBE) {
+ /* only probe unenabled GPIO interrupt lines */
+ if (gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))
+ return 0;
+ type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING;
+
+ }
+
+ if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING |
+ IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) {
+
+ if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) {
+
+ ret = gpio_request(gpionr, NULL);
+ if(ret)
+ return ret;
+
+ }
+
+ gpio_enabled[gpio_bank(gpionr)] |= gpio_bit(gpionr);
+ } else {
+ gpio_enabled[gpio_bank(gpionr)] &= ~gpio_bit(gpionr);
+ return 0;
+ }
+
+
+ set_gpio_dir(gpionr, 0);
+ set_gpio_inen(gpionr, 1);
+
+
+ if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) {
+ gpio_edge_triggered[gpio_bank(gpionr)] |= gpio_bit(gpionr);
+ set_gpio_edge(gpionr, 1);
+ } else {
+ set_gpio_edge(gpionr, 0);
+ gpio_edge_triggered[gpio_bank(gpionr)] &= ~gpio_bit(gpionr);
+ }
+
+ if ((type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING))
+ == (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING))
+ set_gpio_both(gpionr, 1);
+ else
+ set_gpio_both(gpionr, 0);
+
+ if ((type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_LEVEL_LOW)))
+ set_gpio_polar(gpionr, 1); /* low or falling edge denoted by one */
+ else
+ set_gpio_polar(gpionr, 0); /* high or rising edge denoted by zero */
+
+ SSYNC();
+
+ if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING))
+ set_irq_handler(irq, handle_edge_irq);
+ else
+ set_irq_handler(irq, handle_level_irq);
+
+ return 0;
+}
+
+static struct irq_chip bf561_gpio_irqchip = {
+ .ack = bf561_gpio_ack_irq,
+ .mask = bf561_gpio_mask_irq,
+ .mask_ack = bf561_gpio_mask_ack_irq,
+ .unmask = bf561_gpio_unmask_irq,
+ .set_type = bf561_gpio_irq_type,
+ .startup = bf561_gpio_irq_startup,
+ .shutdown = bf561_gpio_irq_shutdown
+};
+
+static void bf561_demux_gpio_irq(unsigned int inta_irq,
+ struct irq_desc *intb_desc)
+{
+ int irq, flag_d, mask;
+ u16 gpio;
+
+ switch (inta_irq) {
+ case IRQ_PROG0_INTA:
+ irq = IRQ_PF0;
+ break;
+ case IRQ_PROG1_INTA:
+ irq = IRQ_PF16;
+ break;
+ case IRQ_PROG2_INTA:
+ irq = IRQ_PF32;
+ break;
+ default:
+ dump_stack();
+ return;
+ }
+
+ gpio = irq - IRQ_PF0;
+
+ flag_d = get_gpiop_data(gpio);
+ mask = flag_d & (gpio_enabled[gpio_bank(gpio)] &
+ get_gpiop_maska(gpio));
+
+ do {
+ if (mask & 1) {
+ struct irq_desc *desc = irq_desc + irq;
+ desc->handle_irq(irq, desc);
+ }
+ irq++;
+ mask >>= 1;
+ } while (mask);
+
+
+}
+
+#endif /* CONFIG_IRQCHIP_DEMUX_GPIO */
+
+/*
+ * This function should be called during kernel startup to initialize
+ * the BFin IRQ handling routines.
+ */
+int __init init_arch_irq(void)
+{
+ int irq;
+ unsigned long ilat = 0;
+ /* Disable all the peripheral intrs - page 4-29 HW Ref manual */
+ bfin_write_SICA_IMASK0(SIC_UNMASK_ALL);
+ bfin_write_SICA_IMASK1(SIC_UNMASK_ALL);
+ SSYNC();
+
+ local_irq_disable();
+
+ init_exception_buff();
+
+#ifndef CONFIG_KGDB
+ bfin_write_EVT0(evt_emulation);
+#endif
+ bfin_write_EVT2(evt_evt2);
+ bfin_write_EVT3(trap);
+ bfin_write_EVT5(evt_ivhw);
+ bfin_write_EVT6(evt_timer);
+ bfin_write_EVT7(evt_evt7);
+ bfin_write_EVT8(evt_evt8);
+ bfin_write_EVT9(evt_evt9);
+ bfin_write_EVT10(evt_evt10);
+ bfin_write_EVT11(evt_evt11);
+ bfin_write_EVT12(evt_evt12);
+ bfin_write_EVT13(evt_evt13);
+ bfin_write_EVT14(evt14_softirq);
+ bfin_write_EVT15(evt_system_call);
+ CSYNC();
+
+ for (irq = 0; irq < SYS_IRQS; irq++) {
+ if (irq <= IRQ_CORETMR)
+ set_irq_chip(irq, &bf561_core_irqchip);
+ else
+ set_irq_chip(irq, &bf561_internal_irqchip);
+#ifdef CONFIG_IRQCHIP_DEMUX_GPIO
+ if ((irq != IRQ_PROG0_INTA) &&
+ (irq != IRQ_PROG1_INTA) && (irq != IRQ_PROG2_INTA)) {
+#endif
+ set_irq_handler(irq, handle_simple_irq);
+#ifdef CONFIG_IRQCHIP_DEMUX_GPIO
+ } else {
+ set_irq_chained_handler(irq, bf561_demux_gpio_irq);
+ }
+#endif
+
+ }
+
+#ifdef CONFIG_IRQCHIP_DEMUX_GPIO
+ for (irq = IRQ_PF0; irq <= IRQ_PF47; irq++) {
+ set_irq_chip(irq, &bf561_gpio_irqchip);
+ /* if configured as edge, then will be changed to do_edge_IRQ */
+ set_irq_handler(irq, handle_level_irq);
+ }
+#endif
+ bfin_write_IMASK(0);
+ CSYNC();
+ ilat = bfin_read_ILAT();
+ CSYNC();
+ bfin_write_ILAT(ilat);
+ CSYNC();
+
+ printk(KERN_INFO "Configuring Blackfin Priority Driven Interrupts\n");
+ /* IMASK=xxx is equivalent to STI xx or irq_flags=xx,
+ * local_irq_enable()
+ */
+ program_IAR();
+ /* Therefore it's better to setup IARs before interrupts enabled */
+ search_IAR();
+
+ /* Enable interrupts IVG7-15 */
+ irq_flags = irq_flags | IMASK_IVG15 |
+ IMASK_IVG14 | IMASK_IVG13 | IMASK_IVG12 | IMASK_IVG11 |
+ IMASK_IVG10 | IMASK_IVG9 | IMASK_IVG8 | IMASK_IVG7 | IMASK_IVGHW;
+
+ return 0;
+}
+
+#ifdef CONFIG_DO_IRQ_L1
+void do_irq(int vec, struct pt_regs *fp)__attribute__((l1_text));
+#endif
+
+void do_irq(int vec, struct pt_regs *fp)
+{
+ if (vec == EVT_IVTMR_P) {
+ vec = IRQ_CORETMR;
+ } else {
+ struct ivgx *ivg = ivg7_13[vec - IVG7].ifirst;
+ struct ivgx *ivg_stop = ivg7_13[vec - IVG7].istop;
+ unsigned long sic_status0, sic_status1;
+
+ SSYNC();
+ sic_status0 = bfin_read_SICA_IMASK0() & bfin_read_SICA_ISR0();
+ sic_status1 = bfin_read_SICA_IMASK1() & bfin_read_SICA_ISR1();
+
+ for (;; ivg++) {
+ if (ivg >= ivg_stop) {
+ atomic_inc(&num_spurious);
+ return;
+ } else if ((sic_status0 & ivg->isrflag0) ||
+ (sic_status1 & ivg->isrflag1))
+ break;
+ }
+ vec = ivg->irqno;
+ }
+ asm_do_IRQ(vec, fp);
+
+#ifdef CONFIG_KGDB
+ kgdb_process_breakpoint();
+#endif
+}
diff --git a/arch/blackfin/mach-common/ints-priority-sc.c b/arch/blackfin/mach-common/ints-priority-sc.c
new file mode 100644
index 00000000000..34b62288ec3
--- /dev/null
+++ b/arch/blackfin/mach-common/ints-priority-sc.c
@@ -0,0 +1,577 @@
+/*
+ * File: arch/blackfin/mach-common/ints-priority-sc.c
+ * Based on:
+ * Author:
+ *
+ * Created: ?
+ * Description: Set up the interupt priorities
+ *
+ * Modified:
+ * 1996 Roman Zippel
+ * 1999 D. Jeff Dionne <jeff@uclinux.org>
+ * 2000-2001 Lineo, Inc. D. Jefff Dionne <jeff@lineo.ca>
+ * 2002 Arcturus Networks Inc. MaTed <mated@sympatico.ca>
+ * 2003 Metrowerks/Motorola
+ * 2003 Bas Vermeulen <bas@buyways.nl>
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/module.h>
+#include <linux/kernel_stat.h>
+#include <linux/seq_file.h>
+#include <linux/irq.h>
+#ifdef CONFIG_KGDB
+#include <linux/kgdb.h>
+#endif
+#include <asm/traps.h>
+#include <asm/blackfin.h>
+#include <asm/gpio.h>
+#include <asm/irq_handler.h>
+
+#ifdef BF537_FAMILY
+# define BF537_GENERIC_ERROR_INT_DEMUX
+#else
+# undef BF537_GENERIC_ERROR_INT_DEMUX
+#endif
+
+/*
+ * NOTES:
+ * - we have separated the physical Hardware interrupt from the
+ * levels that the LINUX kernel sees (see the description in irq.h)
+ * -
+ */
+
+unsigned long irq_flags = 0;
+
+/* The number of spurious interrupts */
+atomic_t num_spurious;
+
+struct ivgx {
+ /* irq number for request_irq, available in mach-bf533/irq.h */
+ int irqno;
+ /* corresponding bit in the SIC_ISR register */
+ int isrflag;
+} ivg_table[NR_PERI_INTS];
+
+struct ivg_slice {
+ /* position of first irq in ivg_table for given ivg */
+ struct ivgx *ifirst;
+ struct ivgx *istop;
+} ivg7_13[IVG13 - IVG7 + 1];
+
+static void search_IAR(void);
+
+/*
+ * Search SIC_IAR and fill tables with the irqvalues
+ * and their positions in the SIC_ISR register.
+ */
+static void __init search_IAR(void)
+{
+ unsigned ivg, irq_pos = 0;
+ for (ivg = 0; ivg <= IVG13 - IVG7; ivg++) {
+ int irqn;
+
+ ivg7_13[ivg].istop = ivg7_13[ivg].ifirst =
+ &ivg_table[irq_pos];
+
+ for (irqn = 0; irqn < NR_PERI_INTS; irqn++) {
+ int iar_shift = (irqn & 7) * 4;
+ if (ivg ==
+ (0xf &
+ bfin_read32((unsigned long *) SIC_IAR0 +
+ (irqn >> 3)) >> iar_shift)) {
+ ivg_table[irq_pos].irqno = IVG7 + irqn;
+ ivg_table[irq_pos].isrflag = 1 << irqn;
+ ivg7_13[ivg].istop++;
+ irq_pos++;
+ }
+ }
+ }
+}
+
+/*
+ * This is for BF533 internal IRQs
+ */
+
+static void ack_noop(unsigned int irq)
+{
+ /* Dummy function. */
+}
+
+static void bfin_core_mask_irq(unsigned int irq)
+{
+ irq_flags &= ~(1 << irq);
+ if (!irqs_disabled())
+ local_irq_enable();
+}
+
+static void bfin_core_unmask_irq(unsigned int irq)
+{
+ irq_flags |= 1 << irq;
+ /*
+ * If interrupts are enabled, IMASK must contain the same value
+ * as irq_flags. Make sure that invariant holds. If interrupts
+ * are currently disabled we need not do anything; one of the
+ * callers will take care of setting IMASK to the proper value
+ * when reenabling interrupts.
+ * local_irq_enable just does "STI irq_flags", so it's exactly
+ * what we need.
+ */
+ if (!irqs_disabled())
+ local_irq_enable();
+ return;
+}
+
+static void bfin_internal_mask_irq(unsigned int irq)
+{
+ bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() &
+ ~(1 << (irq - (IRQ_CORETMR + 1))));
+ SSYNC();
+}
+
+static void bfin_internal_unmask_irq(unsigned int irq)
+{
+ bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() |
+ (1 << (irq - (IRQ_CORETMR + 1))));
+ SSYNC();
+}
+
+static struct irq_chip bfin_core_irqchip = {
+ .ack = ack_noop,
+ .mask = bfin_core_mask_irq,
+ .unmask = bfin_core_unmask_irq,
+};
+
+static struct irq_chip bfin_internal_irqchip = {
+ .ack = ack_noop,
+ .mask = bfin_internal_mask_irq,
+ .unmask = bfin_internal_unmask_irq,
+};
+
+#ifdef BF537_GENERIC_ERROR_INT_DEMUX
+static int error_int_mask;
+
+static void bfin_generic_error_ack_irq(unsigned int irq)
+{
+
+}
+
+static void bfin_generic_error_mask_irq(unsigned int irq)
+{
+ error_int_mask &= ~(1L << (irq - IRQ_PPI_ERROR));
+
+ if (!error_int_mask) {
+ local_irq_disable();
+ bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() &
+ ~(1 <<
+ (IRQ_GENERIC_ERROR -
+ (IRQ_CORETMR + 1))));
+ SSYNC();
+ local_irq_enable();
+ }
+}
+
+static void bfin_generic_error_unmask_irq(unsigned int irq)
+{
+ local_irq_disable();
+ bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() | 1 <<
+ (IRQ_GENERIC_ERROR - (IRQ_CORETMR + 1)));
+ SSYNC();
+ local_irq_enable();
+
+ error_int_mask |= 1L << (irq - IRQ_PPI_ERROR);
+}
+
+static struct irq_chip bfin_generic_error_irqchip = {
+ .ack = bfin_generic_error_ack_irq,
+ .mask = bfin_generic_error_mask_irq,
+ .unmask = bfin_generic_error_unmask_irq,
+};
+
+static void bfin_demux_error_irq(unsigned int int_err_irq,
+ struct irq_desc *intb_desc)
+{
+ int irq = 0;
+
+ SSYNC();
+
+#if (defined(CONFIG_BF537) || defined(CONFIG_BF536))
+ if (bfin_read_EMAC_SYSTAT() & EMAC_ERR_MASK)
+ irq = IRQ_MAC_ERROR;
+ else
+#endif
+ if (bfin_read_SPORT0_STAT() & SPORT_ERR_MASK)
+ irq = IRQ_SPORT0_ERROR;
+ else if (bfin_read_SPORT1_STAT() & SPORT_ERR_MASK)
+ irq = IRQ_SPORT1_ERROR;
+ else if (bfin_read_PPI_STATUS() & PPI_ERR_MASK)
+ irq = IRQ_PPI_ERROR;
+ else if (bfin_read_CAN_GIF() & CAN_ERR_MASK)
+ irq = IRQ_CAN_ERROR;
+ else if (bfin_read_SPI_STAT() & SPI_ERR_MASK)
+ irq = IRQ_SPI_ERROR;
+ else if ((bfin_read_UART0_IIR() & UART_ERR_MASK_STAT1) &&
+ (bfin_read_UART0_IIR() & UART_ERR_MASK_STAT0))
+ irq = IRQ_UART0_ERROR;
+ else if ((bfin_read_UART1_IIR() & UART_ERR_MASK_STAT1) &&
+ (bfin_read_UART1_IIR() & UART_ERR_MASK_STAT0))
+ irq = IRQ_UART1_ERROR;
+
+ if (irq) {
+ if (error_int_mask & (1L << (irq - IRQ_PPI_ERROR))) {
+ struct irq_desc *desc = irq_desc + irq;
+ desc->handle_irq(irq, desc);
+ } else {
+
+ switch (irq) {
+ case IRQ_PPI_ERROR:
+ bfin_write_PPI_STATUS(PPI_ERR_MASK);
+ break;
+#if (defined(CONFIG_BF537) || defined(CONFIG_BF536))
+ case IRQ_MAC_ERROR:
+ bfin_write_EMAC_SYSTAT(EMAC_ERR_MASK);
+ break;
+#endif
+ case IRQ_SPORT0_ERROR:
+ bfin_write_SPORT0_STAT(SPORT_ERR_MASK);
+ break;
+
+ case IRQ_SPORT1_ERROR:
+ bfin_write_SPORT1_STAT(SPORT_ERR_MASK);
+ break;
+
+ case IRQ_CAN_ERROR:
+ bfin_write_CAN_GIS(CAN_ERR_MASK);
+ break;
+
+ case IRQ_SPI_ERROR:
+ bfin_write_SPI_STAT(SPI_ERR_MASK);
+ break;
+
+ default:
+ break;
+ }
+
+ pr_debug("IRQ %d:"
+ " MASKED PERIPHERAL ERROR INTERRUPT ASSERTED\n",
+ irq);
+ }
+ } else
+ printk(KERN_ERR
+ "%s : %s : LINE %d :\nIRQ ?: PERIPHERAL ERROR"
+ " INTERRUPT ASSERTED BUT NO SOURCE FOUND\n",
+ __FUNCTION__, __FILE__, __LINE__);
+
+
+}
+#endif /* BF537_GENERIC_ERROR_INT_DEMUX */
+
+#ifdef CONFIG_IRQCHIP_DEMUX_GPIO
+
+static unsigned short gpio_enabled[gpio_bank(MAX_BLACKFIN_GPIOS)];
+static unsigned short gpio_edge_triggered[gpio_bank(MAX_BLACKFIN_GPIOS)];
+
+static void bfin_gpio_ack_irq(unsigned int irq)
+{
+ u16 gpionr = irq - IRQ_PF0;
+
+ if (gpio_edge_triggered[gpio_bank(gpionr)] & gpio_bit(gpionr)) {
+ set_gpio_data(gpionr, 0);
+ SSYNC();
+ }
+}
+
+static void bfin_gpio_mask_ack_irq(unsigned int irq)
+{
+ u16 gpionr = irq - IRQ_PF0;
+
+ if (gpio_edge_triggered[gpio_bank(gpionr)] & gpio_bit(gpionr)) {
+ set_gpio_data(gpionr, 0);
+ SSYNC();
+ }
+
+ set_gpio_maska(gpionr, 0);
+ SSYNC();
+}
+
+static void bfin_gpio_mask_irq(unsigned int irq)
+{
+ set_gpio_maska(irq - IRQ_PF0, 0);
+ SSYNC();
+}
+
+static void bfin_gpio_unmask_irq(unsigned int irq)
+{
+ set_gpio_maska(irq - IRQ_PF0, 1);
+ SSYNC();
+}
+
+static unsigned int bfin_gpio_irq_startup(unsigned int irq)
+{
+ unsigned int ret;
+ u16 gpionr = irq - IRQ_PF0;
+
+ if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) {
+ ret = gpio_request(gpionr, NULL);
+ if (ret)
+ return ret;
+ }
+
+ gpio_enabled[gpio_bank(gpionr)] |= gpio_bit(gpionr);
+ bfin_gpio_unmask_irq(irq);
+
+ return ret;
+}
+
+static void bfin_gpio_irq_shutdown(unsigned int irq)
+{
+ bfin_gpio_mask_irq(irq);
+ gpio_free(irq - IRQ_PF0);
+ gpio_enabled[gpio_bank(irq - IRQ_PF0)] &= ~gpio_bit(irq - IRQ_PF0);
+}
+
+static int bfin_gpio_irq_type(unsigned int irq, unsigned int type)
+{
+
+ unsigned int ret;
+ u16 gpionr = irq - IRQ_PF0;
+
+ if (type == IRQ_TYPE_PROBE) {
+ /* only probe unenabled GPIO interrupt lines */
+ if (gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))
+ return 0;
+ type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING;
+ }
+
+ if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING |
+ IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW))
+ {
+ if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) {
+ ret = gpio_request(gpionr, NULL);
+ if (ret)
+ return ret;
+ }
+
+ gpio_enabled[gpio_bank(gpionr)] |= gpio_bit(gpionr);
+ } else {
+ gpio_enabled[gpio_bank(gpionr)] &= ~gpio_bit(gpionr);
+ return 0;
+ }
+
+ set_gpio_dir(gpionr, 0);
+ set_gpio_inen(gpionr, 1);
+
+ if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) {
+ gpio_edge_triggered[gpio_bank(gpionr)] |= gpio_bit(gpionr);
+ set_gpio_edge(gpionr, 1);
+ } else {
+ set_gpio_edge(gpionr, 0);
+ gpio_edge_triggered[gpio_bank(gpionr)] &= ~gpio_bit(gpionr);
+ }
+
+ if ((type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING))
+ == (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING))
+ set_gpio_both(gpionr, 1);
+ else
+ set_gpio_both(gpionr, 0);
+
+ if ((type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_LEVEL_LOW)))
+ set_gpio_polar(gpionr, 1); /* low or falling edge denoted by one */
+ else
+ set_gpio_polar(gpionr, 0); /* high or rising edge denoted by zero */
+
+ SSYNC();
+
+ if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING))
+ set_irq_handler(irq, handle_edge_irq);
+ else
+ set_irq_handler(irq, handle_level_irq);
+
+ return 0;
+}
+
+
+static struct irq_chip bfin_gpio_irqchip = {
+ .ack = bfin_gpio_ack_irq,
+ .mask = bfin_gpio_mask_irq,
+ .mask_ack = bfin_gpio_mask_ack_irq,
+ .unmask = bfin_gpio_unmask_irq,
+ .set_type = bfin_gpio_irq_type,
+ .startup = bfin_gpio_irq_startup,
+ .shutdown = bfin_gpio_irq_shutdown
+};
+
+static void bfin_demux_gpio_irq(unsigned int intb_irq,
+ struct irq_desc *intb_desc)
+{
+ u16 i;
+
+ for (i = 0; i < MAX_BLACKFIN_GPIOS; i+=16) {
+ int irq = IRQ_PF0 + i;
+ int flag_d = get_gpiop_data(i);
+ int mask =
+ flag_d & (gpio_enabled[gpio_bank(i)] &
+ get_gpiop_maska(i));
+
+ while (mask) {
+ if (mask & 1) {
+ struct irq_desc *desc = irq_desc + irq;
+ desc->handle_irq(irq, desc);
+ }
+ irq++;
+ mask >>= 1;
+ }
+ }
+}
+
+#endif /* CONFIG_IRQCHIP_DEMUX_GPIO */
+
+/*
+ * This function should be called during kernel startup to initialize
+ * the BFin IRQ handling routines.
+ */
+int __init init_arch_irq(void)
+{
+ int irq;
+ unsigned long ilat = 0;
+ /* Disable all the peripheral intrs - page 4-29 HW Ref manual */
+ bfin_write_SIC_IMASK(SIC_UNMASK_ALL);
+ SSYNC();
+
+ local_irq_disable();
+
+#ifndef CONFIG_KGDB
+ bfin_write_EVT0(evt_emulation);
+#endif
+ bfin_write_EVT2(evt_evt2);
+ bfin_write_EVT3(trap);
+ bfin_write_EVT5(evt_ivhw);
+ bfin_write_EVT6(evt_timer);
+ bfin_write_EVT7(evt_evt7);
+ bfin_write_EVT8(evt_evt8);
+ bfin_write_EVT9(evt_evt9);
+ bfin_write_EVT10(evt_evt10);
+ bfin_write_EVT11(evt_evt11);
+ bfin_write_EVT12(evt_evt12);
+ bfin_write_EVT13(evt_evt13);
+ bfin_write_EVT14(evt14_softirq);
+ bfin_write_EVT15(evt_system_call);
+ CSYNC();
+
+ for (irq = 0; irq < SYS_IRQS; irq++) {
+ if (irq <= IRQ_CORETMR)
+ set_irq_chip(irq, &bfin_core_irqchip);
+ else
+ set_irq_chip(irq, &bfin_internal_irqchip);
+#ifdef BF537_GENERIC_ERROR_INT_DEMUX
+ if (irq != IRQ_GENERIC_ERROR) {
+#endif
+
+#ifdef CONFIG_IRQCHIP_DEMUX_GPIO
+ if ((irq != IRQ_PROG_INTA) /*PORT F & G MASK_A Interrupt*/
+# if defined(BF537_FAMILY) && !(defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE))
+ && (irq != IRQ_MAC_RX) /*PORT H MASK_A Interrupt*/
+# endif
+ ) {
+#endif
+ set_irq_handler(irq, handle_simple_irq);
+#ifdef CONFIG_IRQCHIP_DEMUX_GPIO
+ } else {
+ set_irq_chained_handler(irq,
+ bfin_demux_gpio_irq);
+ }
+#endif
+
+#ifdef BF537_GENERIC_ERROR_INT_DEMUX
+ } else {
+ set_irq_handler(irq, bfin_demux_error_irq);
+ }
+#endif
+ }
+#ifdef BF537_GENERIC_ERROR_INT_DEMUX
+ for (irq = IRQ_PPI_ERROR; irq <= IRQ_UART1_ERROR; irq++) {
+ set_irq_chip(irq, &bfin_generic_error_irqchip);
+ set_irq_handler(irq, handle_level_irq);
+ }
+#endif
+
+#ifdef CONFIG_IRQCHIP_DEMUX_GPIO
+ for (irq = IRQ_PF0; irq < NR_IRQS; irq++) {
+ set_irq_chip(irq, &bfin_gpio_irqchip);
+ /* if configured as edge, then will be changed to do_edge_IRQ */
+ set_irq_handler(irq, handle_level_irq);
+ }
+#endif
+ bfin_write_IMASK(0);
+ CSYNC();
+ ilat = bfin_read_ILAT();
+ CSYNC();
+ bfin_write_ILAT(ilat);
+ CSYNC();
+
+ printk(KERN_INFO
+ "Configuring Blackfin Priority Driven Interrupts\n");
+ /* IMASK=xxx is equivalent to STI xx or irq_flags=xx,
+ * local_irq_enable()
+ */
+ program_IAR();
+ /* Therefore it's better to setup IARs before interrupts enabled */
+ search_IAR();
+
+ /* Enable interrupts IVG7-15 */
+ irq_flags = irq_flags | IMASK_IVG15 |
+ IMASK_IVG14 | IMASK_IVG13 | IMASK_IVG12 | IMASK_IVG11 |
+ IMASK_IVG10 | IMASK_IVG9 | IMASK_IVG8 | IMASK_IVG7 |
+ IMASK_IVGHW;
+
+ return 0;
+}
+
+#ifdef CONFIG_DO_IRQ_L1
+void do_irq(int vec, struct pt_regs *fp)__attribute__((l1_text));
+#endif
+
+void do_irq(int vec, struct pt_regs *fp)
+{
+ if (vec == EVT_IVTMR_P) {
+ vec = IRQ_CORETMR;
+ } else {
+ struct ivgx *ivg = ivg7_13[vec - IVG7].ifirst;
+ struct ivgx *ivg_stop = ivg7_13[vec - IVG7].istop;
+ unsigned long sic_status;
+
+ SSYNC();
+ sic_status = bfin_read_SIC_IMASK() & bfin_read_SIC_ISR();
+
+ for (;; ivg++) {
+ if (ivg >= ivg_stop) {
+ atomic_inc(&num_spurious);
+ return;
+ } else if (sic_status & ivg->isrflag)
+ break;
+ }
+ vec = ivg->irqno;
+ }
+ asm_do_IRQ(vec, fp);
+
+#ifdef CONFIG_KGDB
+ kgdb_process_breakpoint();
+#endif
+}
diff --git a/arch/blackfin/mach-common/irqpanic.c b/arch/blackfin/mach-common/irqpanic.c
new file mode 100644
index 00000000000..f05e3dadaf3
--- /dev/null
+++ b/arch/blackfin/mach-common/irqpanic.c
@@ -0,0 +1,194 @@
+/*
+ * File: arch/blackfin/mach-common/irqpanic.c
+ * Based on:
+ * Author:
+ *
+ * Created: ?
+ * Description: panic kernel with dump information
+ *
+ * Modified: rgetz - added cache checking code 14Feb06
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/module.h>
+#include <linux/kernel_stat.h>
+#include <linux/sched.h>
+#include <asm/traps.h>
+#include <asm/blackfin.h>
+
+#include "../oprofile/op_blackfin.h"
+
+#ifdef CONFIG_DEBUG_ICACHE_CHECK
+#define L1_ICACHE_START 0xffa10000
+#define L1_ICACHE_END 0xffa13fff
+void irq_panic(int reason, struct pt_regs *regs) __attribute__ ((l1_text));
+#endif
+
+/*
+ * irq_panic - calls panic with string setup
+ */
+asmlinkage void irq_panic(int reason, struct pt_regs *regs)
+{
+ int sig = 0;
+ siginfo_t info;
+
+#ifdef CONFIG_DEBUG_ICACHE_CHECK
+ unsigned int cmd, tag, ca, cache_hi, cache_lo, *pa;
+ unsigned short i, j, die;
+ unsigned int bad[10][6];
+
+ /* check entire cache for coherency
+ * Since printk is in cacheable memory,
+ * don't call it until you have checked everything
+ */
+
+ die = 0;
+ i = 0;
+
+ /* check icache */
+
+ for (ca = L1_ICACHE_START; ca <= L1_ICACHE_END && i < 10; ca += 32) {
+
+ /* Grab various address bits for the itest_cmd fields */
+ cmd = (((ca & 0x3000) << 4) | /* ca[13:12] for SBNK[1:0] */
+ ((ca & 0x0c00) << 16) | /* ca[11:10] for WAYSEL[1:0] */
+ ((ca & 0x3f8)) | /* ca[09:03] for SET[4:0] and DW[1:0] */
+ 0); /* Access Tag, Read access */
+
+ SSYNC();
+ bfin_write_ITEST_COMMAND(cmd);
+ SSYNC();
+ tag = bfin_read_ITEST_DATA0();
+ SSYNC();
+
+ /* if tag is marked as valid, check it */
+ if (tag & 1) {
+ /* The icache is arranged in 4 groups of 64-bits */
+ for (j = 0; j < 32; j += 8) {
+ cmd = ((((ca + j) & 0x3000) << 4) | /* ca[13:12] for SBNK[1:0] */
+ (((ca + j) & 0x0c00) << 16) | /* ca[11:10] for WAYSEL[1:0] */
+ (((ca + j) & 0x3f8)) | /* ca[09:03] for SET[4:0] and DW[1:0] */
+ 4); /* Access Data, Read access */
+
+ SSYNC();
+ bfin_write_ITEST_COMMAND(cmd);
+ SSYNC();
+
+ cache_hi = bfin_read_ITEST_DATA1();
+ cache_lo = bfin_read_ITEST_DATA0();
+
+ pa = ((unsigned int *)((tag & 0xffffcc00) |
+ ((ca + j) & ~(0xffffcc00))));
+
+ /*
+ * Debugging this, enable
+ *
+ * printk("addr: %08x %08x%08x | %08x%08x\n",
+ * ((unsigned int *)((tag & 0xffffcc00) | ((ca+j) & ~(0xffffcc00)))),
+ * cache_hi, cache_lo, *(pa+1), *pa);
+ */
+
+ if (cache_hi != *(pa + 1) || cache_lo != *pa) {
+ /* Since icache is not working, stay out of it, by not printing */
+ die = 1;
+ bad[i][0] = (ca + j);
+ bad[i][1] = cache_hi;
+ bad[i][2] = cache_lo;
+ bad[i][3] = ((tag & 0xffffcc00) |
+ ((ca + j) & ~(0xffffcc00)));
+ bad[i][4] = *(pa + 1);
+ bad[i][5] = *(pa);
+ i++;
+ }
+ }
+ }
+ }
+ if (die) {
+ printk(KERN_EMERG "icache coherency error\n");
+ for (j = 0; j <= i; j++) {
+ printk(KERN_EMERG
+ "cache address : %08x cache value : %08x%08x\n",
+ bad[j][0], bad[j][1], bad[j][2]);
+ printk(KERN_EMERG
+ "physical address: %08x SDRAM value : %08x%08x\n",
+ bad[j][3], bad[j][4], bad[j][5]);
+ }
+ panic("icache coherency error");
+ } else {
+ printk(KERN_EMERG "icache checked, and OK\n");
+ }
+#endif
+
+ printk(KERN_EMERG "\n");
+ printk(KERN_EMERG "Exception: IRQ 0x%x entered\n", reason);
+ printk(KERN_EMERG " code=[0x%08lx], stack frame=0x%08lx, "
+ " bad PC=0x%08lx\n",
+ (unsigned long)regs->seqstat,
+ (unsigned long)regs,
+ (unsigned long)regs->pc);
+ if (reason == 0x5) {
+ printk(KERN_EMERG "----------- HARDWARE ERROR -----------\n");
+
+ /* There is only need to check for Hardware Errors, since other
+ * EXCEPTIONS are handled in TRAPS.c (MH)
+ */
+ switch (regs->seqstat & SEQSTAT_HWERRCAUSE) {
+ case (SEQSTAT_HWERRCAUSE_SYSTEM_MMR): /* System MMR Error */
+ info.si_code = BUS_ADRALN;
+ sig = SIGBUS;
+ printk(KERN_EMERG HWC_x2);
+ break;
+ case (SEQSTAT_HWERRCAUSE_EXTERN_ADDR): /* External Memory Addressing Error */
+ info.si_code = BUS_ADRERR;
+ sig = SIGBUS;
+ printk(KERN_EMERG HWC_x3);
+ break;
+ case (SEQSTAT_HWERRCAUSE_PERF_FLOW): /* Performance Monitor Overflow */
+ printk(KERN_EMERG HWC_x12);
+ break;
+ case (SEQSTAT_HWERRCAUSE_RAISE_5): /* RAISE 5 instruction */
+ printk(KERN_EMERG HWC_x18);
+ break;
+ default: /* Reserved */
+ printk(KERN_EMERG HWC_default);
+ break;
+ }
+ }
+
+ regs->ipend = bfin_read_IPEND();
+ dump_bfin_regs(regs, (void *)regs->pc);
+ if (0 == (info.si_signo = sig) || 0 == user_mode(regs)) /* in kernelspace */
+ panic("Unhandled IRQ or exceptions!\n");
+ else { /* in userspace */
+ info.si_errno = 0;
+ info.si_addr = (void *)regs->pc;
+ force_sig_info(sig, &info, current);
+ }
+}
+
+#ifdef CONFIG_HARDWARE_PM
+/*
+ * call the handler of Performance overflow
+ */
+asmlinkage void pm_overflow(int irq, struct pt_regs *regs)
+{
+ pm_overflow_handler(irq, regs);
+}
+#endif
diff --git a/arch/blackfin/mach-common/lock.S b/arch/blackfin/mach-common/lock.S
new file mode 100644
index 00000000000..2cbb15b3392
--- /dev/null
+++ b/arch/blackfin/mach-common/lock.S
@@ -0,0 +1,204 @@
+/*
+ * File: arch/blackfin/mach-common/lock.S
+ * Based on:
+ * Author: LG Soft India
+ *
+ * Created: ?
+ * Description: kernel locks
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/linkage.h>
+#include <asm/cplb.h>
+#include <asm/blackfin.h>
+
+.text
+
+#ifdef CONFIG_BLKFIN_CACHE_LOCK
+
+/* When you come here, it is assumed that
+ * R0 - Which way to be locked
+ */
+
+ENTRY(_cache_grab_lock)
+
+ [--SP]=( R7:0,P5:0 );
+
+ P1.H = (IMEM_CONTROL >> 16);
+ P1.L = (IMEM_CONTROL & 0xFFFF);
+ P5.H = (ICPLB_ADDR0 >> 16);
+ P5.L = (ICPLB_ADDR0 & 0xFFFF);
+ P4.H = (ICPLB_DATA0 >> 16);
+ P4.L = (ICPLB_DATA0 & 0xFFFF);
+ R7 = R0;
+
+ /* If the code of interest already resides in the cache
+ * invalidate the entire cache itself.
+ * invalidate_entire_icache;
+ */
+
+ SP += -12;
+ [--SP] = RETS;
+ CALL _invalidate_entire_icache;
+ RETS = [SP++];
+ SP += 12;
+
+ /* Disable the Interrupts*/
+
+ CLI R3;
+
+.LLOCK_WAY:
+
+ /* Way0 - 0xFFA133E0
+ * Way1 - 0xFFA137E0
+ * Way2 - 0xFFA13BE0 Total Way Size = 4K
+ * Way3 - 0xFFA13FE0
+ */
+
+ /* Procedure Ex. -Set the locks for other ways by setting ILOC[3:1]
+ * Only Way0 of the instruction cache can now be
+ * replaced by a new code
+ */
+
+ R5 = R7;
+ CC = BITTST(R7,0);
+ IF CC JUMP .LCLEAR1;
+ R7 = 0;
+ BITSET(R7,0);
+ JUMP .LDONE1;
+
+.LCLEAR1:
+ R7 = 0;
+ BITCLR(R7,0);
+.LDONE1: R4 = R7 << 3;
+ R7 = [P1];
+ R7 = R7 | R4;
+ SSYNC; /* SSYNC required writing to IMEM_CONTROL. */
+ .align 8;
+ [P1] = R7;
+ SSYNC;
+
+ R7 = R5;
+ CC = BITTST(R7,1);
+ IF CC JUMP .LCLEAR2;
+ R7 = 0;
+ BITSET(R7,1);
+ JUMP .LDONE2;
+
+.LCLEAR2:
+ R7 = 0;
+ BITCLR(R7,1);
+.LDONE2: R4 = R7 << 3;
+ R7 = [P1];
+ R7 = R7 | R4;
+ SSYNC; /* SSYNC required writing to IMEM_CONTROL. */
+ .align 8;
+ [P1] = R7;
+ SSYNC;
+
+ R7 = R5;
+ CC = BITTST(R7,2);
+ IF CC JUMP .LCLEAR3;
+ R7 = 0;
+ BITSET(R7,2);
+ JUMP .LDONE3;
+.LCLEAR3:
+ R7 = 0;
+ BITCLR(R7,2);
+.LDONE3: R4 = R7 << 3;
+ R7 = [P1];
+ R7 = R7 | R4;
+ SSYNC; /* SSYNC required writing to IMEM_CONTROL. */
+ .align 8;
+ [P1] = R7;
+ SSYNC;
+
+
+ R7 = R5;
+ CC = BITTST(R7,3);
+ IF CC JUMP .LCLEAR4;
+ R7 = 0;
+ BITSET(R7,3);
+ JUMP .LDONE4;
+.LCLEAR4:
+ R7 = 0;
+ BITCLR(R7,3);
+.LDONE4: R4 = R7 << 3;
+ R7 = [P1];
+ R7 = R7 | R4;
+ SSYNC; /* SSYNC required writing to IMEM_CONTROL. */
+ .align 8;
+ [P1] = R7;
+ SSYNC;
+
+ STI R3;
+
+ ( R7:0,P5:0 ) = [SP++];
+
+ RTS;
+
+/* After the execution of critical code, the code is now locked into
+ * the cache way. Now we need to set ILOC.
+ *
+ * R0 - Which way to be locked
+ */
+
+ENTRY(_cache_lock)
+
+ [--SP]=( R7:0,P5:0 );
+
+ P1.H = (IMEM_CONTROL >> 16);
+ P1.L = (IMEM_CONTROL & 0xFFFF);
+
+ /* Disable the Interrupts*/
+ CLI R3;
+
+ R7 = [P1];
+ R2 = 0xFFFFFF87 (X);
+ R7 = R7 & R2;
+ R0 = R0 << 3;
+ R7 = R0 | R7;
+ SSYNC; /* SSYNC required writing to IMEM_CONTROL. */
+ .align 8;
+ [P1] = R7;
+ SSYNC;
+ /* Renable the Interrupts */
+ STI R3;
+
+ ( R7:0,P5:0 ) = [SP++];
+ RTS;
+
+#endif /* BLKFIN_CACHE_LOCK */
+
+/* Return the ILOC bits of IMEM_CONTROL
+ */
+
+ENTRY(_read_iloc)
+
+ P1.H = (IMEM_CONTROL >> 16);
+ P1.L = (IMEM_CONTROL & 0xFFFF);
+ R1 = 0xF;
+ R0 = [P1];
+ R0 = R0 >> 3;
+ R0 = R0 & R1;
+
+ RTS;
diff --git a/arch/blackfin/mach-common/pm.c b/arch/blackfin/mach-common/pm.c
new file mode 100644
index 00000000000..deb27272c65
--- /dev/null
+++ b/arch/blackfin/mach-common/pm.c
@@ -0,0 +1,181 @@
+/*
+ * File: arch/blackfin/mach-common/pm.c
+ * Based on: arm/mach-omap/pm.c
+ * Author: Cliff Brake <cbrake@accelent.com> Copyright (c) 2001
+ *
+ * Created: 2001
+ * Description: Power management for the bfin
+ *
+ * Modified: Nicolas Pitre - PXA250 support
+ * Copyright (c) 2002 Monta Vista Software, Inc.
+ * David Singleton - OMAP1510
+ * Copyright (c) 2002 Monta Vista Software, Inc.
+ * Dirk Behme <dirk.behme@de.bosch.com> - OMAP1510/1610
+ * Copyright 2004
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/pm.h>
+#include <linux/sched.h>
+#include <linux/proc_fs.h>
+
+#include <asm/io.h>
+#include <asm/dpmc.h>
+#include <asm/irq.h>
+
+
+#ifdef CONFIG_PM_WAKEUP_GPIO_POLAR_H
+#define WAKEUP_TYPE PM_WAKE_HIGH
+#endif
+
+#ifdef CONFIG_PM_WAKEUP_GPIO_POLAR_L
+#define WAKEUP_TYPE PM_WAKE_LOW
+#endif
+
+#ifdef CONFIG_PM_WAKEUP_GPIO_POLAR_EDGE_F
+#define WAKEUP_TYPE PM_WAKE_FALLING
+#endif
+
+#ifdef CONFIG_PM_WAKEUP_GPIO_POLAR_EDGE_R
+#define WAKEUP_TYPE PM_WAKE_RISING
+#endif
+
+#ifdef CONFIG_PM_WAKEUP_GPIO_POLAR_EDGE_B
+#define WAKEUP_TYPE PM_WAKE_BOTH_EDGES
+#endif
+
+void bfin_pm_suspend_standby_enter(void)
+{
+#ifdef CONFIG_PM_WAKEUP_BY_GPIO
+ gpio_pm_wakeup_request(CONFIG_PM_WAKEUP_GPIO_NUMBER, WAKEUP_TYPE);
+#endif
+
+#if defined(CONFIG_PM_WAKEUP_BY_GPIO) || defined(CONFIG_PM_WAKEUP_GPIO_API)
+ {
+ u32 flags;
+
+ local_irq_save(flags);
+
+ sleep_deeper(gpio_pm_setup()); /*Goto Sleep*/
+
+ gpio_pm_restore();
+
+ bfin_write_SIC_IWR(IWR_ENABLE_ALL);
+
+ local_irq_restore(flags);
+ }
+#endif
+
+#if defined(CONFIG_PM_WAKEUP_GPIO_BY_SIC_IWR)
+ sleep_deeper(CONFIG_PM_WAKEUP_SIC_IWR);
+ bfin_write_SIC_IWR(IWR_ENABLE_ALL);
+#endif /* CONFIG_PM_WAKEUP_GPIO_BY_SIC_IWR */
+}
+
+
+/*
+ * bfin_pm_prepare - Do preliminary suspend work.
+ * @state: suspend state we're entering.
+ *
+ */
+static int bfin_pm_prepare(suspend_state_t state)
+{
+ int error = 0;
+
+ switch (state) {
+ case PM_SUSPEND_STANDBY:
+ break;
+ case PM_SUSPEND_MEM:
+ return -ENOTSUPP;
+
+ case PM_SUSPEND_DISK:
+ return -ENOTSUPP;
+
+ default:
+ return -EINVAL;
+ }
+
+ return error;
+}
+
+/*
+ * bfin_pm_enter - Actually enter a sleep state.
+ * @state: State we're entering.
+ *
+ */
+static int bfin_pm_enter(suspend_state_t state)
+{
+ switch (state) {
+ case PM_SUSPEND_STANDBY:
+ bfin_pm_suspend_standby_enter();
+ break;
+ case PM_SUSPEND_MEM:
+ return -ENOTSUPP;
+
+ case PM_SUSPEND_DISK:
+ return -ENOTSUPP;
+
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/*
+ * bfin_pm_finish - Finish up suspend sequence.
+ * @state: State we're coming out of.
+ *
+ * This is called after we wake back up (or if entering the sleep state
+ * failed).
+ */
+static int bfin_pm_finish(suspend_state_t state)
+{
+ switch (state) {
+ case PM_SUSPEND_STANDBY:
+ break;
+
+ case PM_SUSPEND_MEM:
+ return -ENOTSUPP;
+
+ case PM_SUSPEND_DISK:
+ return -ENOTSUPP;
+
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+struct pm_ops bfin_pm_ops = {
+ .pm_disk_mode = PM_DISK_PLATFORM,
+ .prepare = bfin_pm_prepare,
+ .enter = bfin_pm_enter,
+ .finish = bfin_pm_finish,
+};
+
+static int __init bfin_pm_init(void)
+{
+ pm_set_ops(&bfin_pm_ops);
+ return 0;
+}
+
+__initcall(bfin_pm_init);
diff --git a/arch/blackfin/mm/Makefile b/arch/blackfin/mm/Makefile
new file mode 100644
index 00000000000..2a7202ce01f
--- /dev/null
+++ b/arch/blackfin/mm/Makefile
@@ -0,0 +1,5 @@
+#
+# arch/blackfin/mm/Makefile
+#
+
+obj-y := blackfin_sram.o init.o
diff --git a/arch/blackfin/mm/blackfin_sram.c b/arch/blackfin/mm/blackfin_sram.c
new file mode 100644
index 00000000000..dd0c6501c42
--- /dev/null
+++ b/arch/blackfin/mm/blackfin_sram.c
@@ -0,0 +1,540 @@
+/*
+ * File: arch/blackfin/mm/blackfin_sram.c
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description: SRAM driver for Blackfin ADSP-BF5xx
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/autoconf.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/miscdevice.h>
+#include <linux/ioport.h>
+#include <linux/fcntl.h>
+#include <linux/init.h>
+#include <linux/poll.h>
+#include <linux/proc_fs.h>
+#include <linux/spinlock.h>
+#include <linux/rtc.h>
+#include <asm/blackfin.h>
+#include "blackfin_sram.h"
+
+spinlock_t l1sram_lock, l1_data_sram_lock, l1_inst_sram_lock;
+
+#if CONFIG_L1_MAX_PIECE < 16
+#undef CONFIG_L1_MAX_PIECE
+#define CONFIG_L1_MAX_PIECE 16
+#endif
+
+#if CONFIG_L1_MAX_PIECE > 1024
+#undef CONFIG_L1_MAX_PIECE
+#define CONFIG_L1_MAX_PIECE 1024
+#endif
+
+#define SRAM_SLT_NULL 0
+#define SRAM_SLT_FREE 1
+#define SRAM_SLT_ALLOCATED 2
+
+/* the data structure for L1 scratchpad and DATA SRAM */
+struct l1_sram_piece {
+ void *paddr;
+ int size;
+ int flag;
+};
+
+static struct l1_sram_piece l1_ssram[CONFIG_L1_MAX_PIECE];
+
+#if L1_DATA_A_LENGTH != 0
+static struct l1_sram_piece l1_data_A_sram[CONFIG_L1_MAX_PIECE];
+#endif
+
+#if L1_DATA_B_LENGTH != 0
+static struct l1_sram_piece l1_data_B_sram[CONFIG_L1_MAX_PIECE];
+#endif
+
+#if L1_CODE_LENGTH != 0
+static struct l1_sram_piece l1_inst_sram[CONFIG_L1_MAX_PIECE];
+#endif
+
+/* L1 Scratchpad SRAM initialization function */
+void l1sram_init(void)
+{
+ printk(KERN_INFO "Blackfin Scratchpad data SRAM: %d KB\n",
+ L1_SCRATCH_LENGTH >> 10);
+
+ memset(&l1_ssram, 0x00, sizeof(l1_ssram));
+ l1_ssram[0].paddr = (void*)L1_SCRATCH_START;
+ l1_ssram[0].size = L1_SCRATCH_LENGTH;
+ l1_ssram[0].flag = SRAM_SLT_FREE;
+
+ /* mutex initialize */
+ spin_lock_init(&l1sram_lock);
+}
+
+void l1_data_sram_init(void)
+{
+#if L1_DATA_A_LENGTH != 0
+ printk(KERN_INFO "Blackfin DATA_A SRAM: %d KB\n",
+ L1_DATA_A_LENGTH >> 10);
+
+ memset(&l1_data_A_sram, 0x00, sizeof(l1_data_A_sram));
+ l1_data_A_sram[0].paddr = (void*)L1_DATA_A_START +
+ (_ebss_l1 - _sdata_l1);
+ l1_data_A_sram[0].size = L1_DATA_A_LENGTH - (_ebss_l1 - _sdata_l1);
+ l1_data_A_sram[0].flag = SRAM_SLT_FREE;
+#endif
+#if L1_DATA_B_LENGTH != 0
+ printk(KERN_INFO "Blackfin DATA_B SRAM: %d KB\n",
+ L1_DATA_B_LENGTH >> 10);
+
+ memset(&l1_data_B_sram, 0x00, sizeof(l1_data_B_sram));
+ l1_data_B_sram[0].paddr = (void*)L1_DATA_B_START;
+ l1_data_B_sram[0].size = L1_DATA_B_LENGTH;
+ l1_data_B_sram[0].flag = SRAM_SLT_FREE;
+#endif
+
+ /* mutex initialize */
+ spin_lock_init(&l1_data_sram_lock);
+}
+
+void l1_inst_sram_init(void)
+{
+#if L1_CODE_LENGTH != 0
+ printk(KERN_INFO "Blackfin Instruction SRAM: %d KB\n",
+ L1_CODE_LENGTH >> 10);
+
+ memset(&l1_inst_sram, 0x00, sizeof(l1_inst_sram));
+ l1_inst_sram[0].paddr = (void*)L1_CODE_START + (_etext_l1 - _stext_l1);
+ l1_inst_sram[0].size = L1_CODE_LENGTH - (_etext_l1 - _stext_l1);
+ l1_inst_sram[0].flag = SRAM_SLT_FREE;
+#endif
+
+ /* mutex initialize */
+ spin_lock_init(&l1_inst_sram_lock);
+}
+
+/* L1 memory allocate function */
+static void *_l1_sram_alloc(size_t size, struct l1_sram_piece *pfree, int count)
+{
+ int i, index = 0;
+ void *addr = NULL;
+
+ if (size <= 0)
+ return NULL;
+
+ /* Align the size */
+ size = (size + 3) & ~3;
+
+ /* not use the good method to match the best slot !!! */
+ /* search an available memeory slot */
+ for (i = 0; i < count; i++) {
+ if ((pfree[i].flag == SRAM_SLT_FREE)
+ && (pfree[i].size >= size)) {
+ addr = pfree[i].paddr;
+ pfree[i].flag = SRAM_SLT_ALLOCATED;
+ index = i;
+ break;
+ }
+ }
+ if (i >= count)
+ return NULL;
+
+ /* updated the NULL memeory slot !!! */
+ if (pfree[i].size > size) {
+ for (i = 0; i < count; i++) {
+ if (pfree[i].flag == SRAM_SLT_NULL) {
+ pfree[i].flag = SRAM_SLT_FREE;
+ pfree[i].paddr = addr + size;
+ pfree[i].size = pfree[index].size - size;
+ pfree[index].size = size;
+ break;
+ }
+ }
+ }
+
+ return addr;
+}
+
+/* Allocate the largest available block. */
+static void *_l1_sram_alloc_max(struct l1_sram_piece *pfree, int count,
+ unsigned long *psize)
+{
+ unsigned long best = 0;
+ int i, index = -1;
+ void *addr = NULL;
+
+ /* search an available memeory slot */
+ for (i = 0; i < count; i++) {
+ if (pfree[i].flag == SRAM_SLT_FREE && pfree[i].size > best) {
+ addr = pfree[i].paddr;
+ index = i;
+ best = pfree[i].size;
+ }
+ }
+ if (index < 0)
+ return NULL;
+ *psize = best;
+
+ pfree[index].flag = SRAM_SLT_ALLOCATED;
+ return addr;
+}
+
+/* L1 memory free function */
+static int _l1_sram_free(const void *addr,
+ struct l1_sram_piece *pfree, int count)
+{
+ int i, index = 0;
+
+ /* search the relevant memory slot */
+ for (i = 0; i < count; i++) {
+ if (pfree[i].paddr == addr) {
+ if (pfree[i].flag != SRAM_SLT_ALLOCATED) {
+ /* error log */
+ return -1;
+ }
+ index = i;
+ break;
+ }
+ }
+ if (i >= count)
+ return -1;
+
+ pfree[index].flag = SRAM_SLT_FREE;
+
+ /* link the next address slot */
+ for (i = 0; i < count; i++) {
+ if (((pfree[index].paddr + pfree[index].size) == pfree[i].paddr)
+ && (pfree[i].flag == SRAM_SLT_FREE)) {
+ pfree[i].flag = SRAM_SLT_NULL;
+ pfree[index].size += pfree[i].size;
+ pfree[index].flag = SRAM_SLT_FREE;
+ break;
+ }
+ }
+
+ /* link the last address slot */
+ for (i = 0; i < count; i++) {
+ if (((pfree[i].paddr + pfree[i].size) == pfree[index].paddr) &&
+ (pfree[i].flag == SRAM_SLT_FREE)) {
+ pfree[index].flag = SRAM_SLT_NULL;
+ pfree[i].size += pfree[index].size;
+ break;
+ }
+ }
+
+ return 0;
+}
+
+int sram_free(const void *addr)
+{
+ if (0) {}
+#if L1_CODE_LENGTH != 0
+ else if (addr >= (void *)L1_CODE_START
+ && addr < (void *)(L1_CODE_START + L1_CODE_LENGTH))
+ return l1_inst_sram_free(addr);
+#endif
+#if L1_DATA_A_LENGTH != 0
+ else if (addr >= (void *)L1_DATA_A_START
+ && addr < (void *)(L1_DATA_A_START + L1_DATA_A_LENGTH))
+ return l1_data_A_sram_free(addr);
+#endif
+#if L1_DATA_B_LENGTH != 0
+ else if (addr >= (void *)L1_DATA_B_START
+ && addr < (void *)(L1_DATA_B_START + L1_DATA_B_LENGTH))
+ return l1_data_B_sram_free(addr);
+#endif
+ else
+ return -1;
+}
+EXPORT_SYMBOL(sram_free);
+
+void *l1_data_A_sram_alloc(size_t size)
+{
+ unsigned flags;
+ void *addr = NULL;
+
+ /* add mutex operation */
+ spin_lock_irqsave(&l1_data_sram_lock, flags);
+
+#if L1_DATA_A_LENGTH != 0
+ addr = _l1_sram_alloc(size, l1_data_A_sram, ARRAY_SIZE(l1_data_A_sram));
+#endif
+
+ /* add mutex operation */
+ spin_unlock_irqrestore(&l1_data_sram_lock, flags);
+
+ pr_debug("Allocated address in l1_data_A_sram_alloc is 0x%lx+0x%lx\n",
+ (long unsigned int)addr, size);
+
+ return addr;
+}
+EXPORT_SYMBOL(l1_data_A_sram_alloc);
+
+int l1_data_A_sram_free(const void *addr)
+{
+ unsigned flags;
+ int ret;
+
+ /* add mutex operation */
+ spin_lock_irqsave(&l1_data_sram_lock, flags);
+
+#if L1_DATA_A_LENGTH != 0
+ ret = _l1_sram_free(addr,
+ l1_data_A_sram, ARRAY_SIZE(l1_data_A_sram));
+#else
+ ret = -1;
+#endif
+
+ /* add mutex operation */
+ spin_unlock_irqrestore(&l1_data_sram_lock, flags);
+
+ return ret;
+}
+EXPORT_SYMBOL(l1_data_A_sram_free);
+
+void *l1_data_B_sram_alloc(size_t size)
+{
+#if L1_DATA_B_LENGTH != 0
+ unsigned flags;
+ void *addr;
+
+ /* add mutex operation */
+ spin_lock_irqsave(&l1_data_sram_lock, flags);
+
+ addr = _l1_sram_alloc(size, l1_data_B_sram, ARRAY_SIZE(l1_data_B_sram));
+
+ /* add mutex operation */
+ spin_unlock_irqrestore(&l1_data_sram_lock, flags);
+
+ pr_debug("Allocated address in l1_data_B_sram_alloc is 0x%lx+0x%lx\n",
+ (long unsigned int)addr, size);
+
+ return addr;
+#else
+ return NULL;
+#endif
+}
+EXPORT_SYMBOL(l1_data_B_sram_alloc);
+
+int l1_data_B_sram_free(const void *addr)
+{
+#if L1_DATA_B_LENGTH != 0
+ unsigned flags;
+ int ret;
+
+ /* add mutex operation */
+ spin_lock_irqsave(&l1_data_sram_lock, flags);
+
+ ret = _l1_sram_free(addr, l1_data_B_sram, ARRAY_SIZE(l1_data_B_sram));
+
+ /* add mutex operation */
+ spin_unlock_irqrestore(&l1_data_sram_lock, flags);
+
+ return ret;
+#else
+ return -1;
+#endif
+}
+EXPORT_SYMBOL(l1_data_B_sram_free);
+
+void *l1_data_sram_alloc(size_t size)
+{
+ void *addr = l1_data_A_sram_alloc(size);
+
+ if (!addr)
+ addr = l1_data_B_sram_alloc(size);
+
+ return addr;
+}
+EXPORT_SYMBOL(l1_data_sram_alloc);
+
+void *l1_data_sram_zalloc(size_t size)
+{
+ void *addr = l1_data_sram_alloc(size);
+
+ if (addr)
+ memset(addr, 0x00, size);
+
+ return addr;
+}
+EXPORT_SYMBOL(l1_data_sram_zalloc);
+
+int l1_data_sram_free(const void *addr)
+{
+ int ret;
+ ret = l1_data_A_sram_free(addr);
+ if (ret == -1)
+ ret = l1_data_B_sram_free(addr);
+ return ret;
+}
+EXPORT_SYMBOL(l1_data_sram_free);
+
+void *l1_inst_sram_alloc(size_t size)
+{
+#if L1_DATA_A_LENGTH != 0
+ unsigned flags;
+ void *addr;
+
+ /* add mutex operation */
+ spin_lock_irqsave(&l1_inst_sram_lock, flags);
+
+ addr = _l1_sram_alloc(size, l1_inst_sram, ARRAY_SIZE(l1_inst_sram));
+
+ /* add mutex operation */
+ spin_unlock_irqrestore(&l1_inst_sram_lock, flags);
+
+ pr_debug("Allocated address in l1_inst_sram_alloc is 0x%lx+0x%lx\n",
+ (long unsigned int)addr, size);
+
+ return addr;
+#else
+ return NULL;
+#endif
+}
+EXPORT_SYMBOL(l1_inst_sram_alloc);
+
+int l1_inst_sram_free(const void *addr)
+{
+#if L1_CODE_LENGTH != 0
+ unsigned flags;
+ int ret;
+
+ /* add mutex operation */
+ spin_lock_irqsave(&l1_inst_sram_lock, flags);
+
+ ret = _l1_sram_free(addr, l1_inst_sram, ARRAY_SIZE(l1_inst_sram));
+
+ /* add mutex operation */
+ spin_unlock_irqrestore(&l1_inst_sram_lock, flags);
+
+ return ret;
+#else
+ return -1;
+#endif
+}
+EXPORT_SYMBOL(l1_inst_sram_free);
+
+/* L1 Scratchpad memory allocate function */
+void *l1sram_alloc(size_t size)
+{
+ unsigned flags;
+ void *addr;
+
+ /* add mutex operation */
+ spin_lock_irqsave(&l1sram_lock, flags);
+
+ addr = _l1_sram_alloc(size, l1_ssram, ARRAY_SIZE(l1_ssram));
+
+ /* add mutex operation */
+ spin_unlock_irqrestore(&l1sram_lock, flags);
+
+ return addr;
+}
+
+/* L1 Scratchpad memory allocate function */
+void *l1sram_alloc_max(size_t *psize)
+{
+ unsigned flags;
+ void *addr;
+
+ /* add mutex operation */
+ spin_lock_irqsave(&l1sram_lock, flags);
+
+ addr = _l1_sram_alloc_max(l1_ssram, ARRAY_SIZE(l1_ssram), psize);
+
+ /* add mutex operation */
+ spin_unlock_irqrestore(&l1sram_lock, flags);
+
+ return addr;
+}
+
+/* L1 Scratchpad memory free function */
+int l1sram_free(const void *addr)
+{
+ unsigned flags;
+ int ret;
+
+ /* add mutex operation */
+ spin_lock_irqsave(&l1sram_lock, flags);
+
+ ret = _l1_sram_free(addr, l1_ssram, ARRAY_SIZE(l1_ssram));
+
+ /* add mutex operation */
+ spin_unlock_irqrestore(&l1sram_lock, flags);
+
+ return ret;
+}
+
+int sram_free_with_lsl(const void *addr)
+{
+ struct sram_list_struct *lsl, **tmp;
+ struct mm_struct *mm = current->mm;
+
+ for (tmp = &mm->context.sram_list; *tmp; tmp = &(*tmp)->next)
+ if ((*tmp)->addr == addr)
+ goto found;
+ return -1;
+found:
+ lsl = *tmp;
+ sram_free(addr);
+ *tmp = lsl->next;
+ kfree(lsl);
+
+ return 0;
+}
+EXPORT_SYMBOL(sram_free_with_lsl);
+
+void *sram_alloc_with_lsl(size_t size, unsigned long flags)
+{
+ void *addr = NULL;
+ struct sram_list_struct *lsl = NULL;
+ struct mm_struct *mm = current->mm;
+
+ lsl = kmalloc(sizeof(struct sram_list_struct), GFP_KERNEL);
+ if (!lsl)
+ return NULL;
+ memset(lsl, 0, sizeof(*lsl));
+
+ if (flags & L1_INST_SRAM)
+ addr = l1_inst_sram_alloc(size);
+
+ if (addr == NULL && (flags & L1_DATA_A_SRAM))
+ addr = l1_data_A_sram_alloc(size);
+
+ if (addr == NULL && (flags & L1_DATA_B_SRAM))
+ addr = l1_data_B_sram_alloc(size);
+
+ if (addr == NULL) {
+ kfree(lsl);
+ return NULL;
+ }
+ lsl->addr = addr;
+ lsl->length = size;
+ lsl->next = mm->context.sram_list;
+ mm->context.sram_list = lsl;
+ return addr;
+}
+EXPORT_SYMBOL(sram_alloc_with_lsl);
diff --git a/arch/blackfin/mm/blackfin_sram.h b/arch/blackfin/mm/blackfin_sram.h
new file mode 100644
index 00000000000..0fb73b78dd6
--- /dev/null
+++ b/arch/blackfin/mm/blackfin_sram.h
@@ -0,0 +1,38 @@
+/*
+ * File: arch/blackfin/mm/blackfin_sram.h
+ * Based on: arch/blackfin/mm/blackfin_sram.c
+ * Author: Mike Frysinger
+ *
+ * Created: Aug 2006
+ * Description: Local prototypes meant for internal use only
+ *
+ * Modified:
+ * Copyright 2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __BLACKFIN_SRAM_H__
+#define __BLACKFIN_SRAM_H__
+
+extern void l1sram_init(void);
+extern void l1_inst_sram_init(void);
+extern void l1_data_sram_init(void);
+extern void *l1sram_alloc(size_t);
+
+#endif
diff --git a/arch/blackfin/mm/init.c b/arch/blackfin/mm/init.c
new file mode 100644
index 00000000000..73f72abed43
--- /dev/null
+++ b/arch/blackfin/mm/init.c
@@ -0,0 +1,208 @@
+/*
+ * File: arch/blackfin/mm/init.c
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/swap.h>
+#include <linux/bootmem.h>
+#include <asm/bfin-global.h>
+#include <asm/uaccess.h>
+#include <asm/l1layout.h>
+#include "blackfin_sram.h"
+
+/*
+ * BAD_PAGE is the page that is used for page faults when linux
+ * is out-of-memory. Older versions of linux just did a
+ * do_exit(), but using this instead means there is less risk
+ * for a process dying in kernel mode, possibly leaving a inode
+ * unused etc..
+ *
+ * BAD_PAGETABLE is the accompanying page-table: it is initialized
+ * to point to BAD_PAGE entries.
+ *
+ * ZERO_PAGE is a special page that is used for zero-initialized
+ * data and COW.
+ */
+static unsigned long empty_bad_page_table;
+
+static unsigned long empty_bad_page;
+
+unsigned long empty_zero_page;
+
+void show_mem(void)
+{
+ unsigned long i;
+ int free = 0, total = 0, reserved = 0, shared = 0;
+
+ int cached = 0;
+ printk(KERN_INFO "Mem-info:\n");
+ show_free_areas();
+ i = max_mapnr;
+ while (i-- > 0) {
+ total++;
+ if (PageReserved(mem_map + i))
+ reserved++;
+ else if (PageSwapCache(mem_map + i))
+ cached++;
+ else if (!page_count(mem_map + i))
+ free++;
+ else
+ shared += page_count(mem_map + i) - 1;
+ }
+ printk(KERN_INFO "%d pages of RAM\n", total);
+ printk(KERN_INFO "%d free pages\n", free);
+ printk(KERN_INFO "%d reserved pages\n", reserved);
+ printk(KERN_INFO "%d pages shared\n", shared);
+ printk(KERN_INFO "%d pages swap cached\n", cached);
+}
+
+/*
+ * paging_init() continues the virtual memory environment setup which
+ * was begun by the code in arch/head.S.
+ * The parameters are pointers to where to stick the starting and ending
+ * addresses of available kernel virtual memory.
+ */
+void paging_init(void)
+{
+ /*
+ * make sure start_mem is page aligned, otherwise bootmem and
+ * page_alloc get different views og the world
+ */
+ unsigned long end_mem = memory_end & PAGE_MASK;
+
+ pr_debug("start_mem is %#lx virtual_end is %#lx\n", PAGE_ALIGN(memory_start), end_mem);
+
+ /*
+ * initialize the bad page table and bad page to point
+ * to a couple of allocated pages
+ */
+ empty_bad_page_table = (unsigned long)alloc_bootmem_pages(PAGE_SIZE);
+ empty_bad_page = (unsigned long)alloc_bootmem_pages(PAGE_SIZE);
+ empty_zero_page = (unsigned long)alloc_bootmem_pages(PAGE_SIZE);
+ memset((void *)empty_zero_page, 0, PAGE_SIZE);
+
+ /*
+ * Set up SFC/DFC registers (user data space)
+ */
+ set_fs(KERNEL_DS);
+
+ pr_debug("free_area_init -> start_mem is %#lx virtual_end is %#lx\n",
+ PAGE_ALIGN(memory_start), end_mem);
+
+ {
+ unsigned long zones_size[MAX_NR_ZONES] = { 0, };
+
+ zones_size[ZONE_NORMAL] = (end_mem - PAGE_OFFSET) >> PAGE_SHIFT;
+#ifdef CONFIG_HIGHMEM
+ zones_size[ZONE_HIGHMEM] = 0;
+#endif
+ free_area_init(zones_size);
+ }
+}
+
+void mem_init(void)
+{
+ unsigned int codek = 0, datak = 0, initk = 0;
+ unsigned long tmp;
+ unsigned int len = _ramend - _rambase;
+ unsigned long start_mem = memory_start;
+ unsigned long end_mem = memory_end;
+
+ end_mem &= PAGE_MASK;
+ high_memory = (void *)end_mem;
+
+ start_mem = PAGE_ALIGN(start_mem);
+ max_mapnr = num_physpages = MAP_NR(high_memory);
+ printk(KERN_INFO "Physical pages: %lx\n", num_physpages);
+
+ /* This will put all memory onto the freelists. */
+ totalram_pages = free_all_bootmem();
+
+ codek = (_etext - _stext) >> 10;
+ datak = (__bss_stop - __bss_start) >> 10;
+ initk = (__init_end - __init_begin) >> 10;
+
+ tmp = nr_free_pages() << PAGE_SHIFT;
+ printk(KERN_INFO
+ "Memory available: %luk/%uk RAM, (%uk init code, %uk kernel code, %uk data, %uk dma)\n",
+ tmp >> 10, len >> 10, initk, codek, datak, DMA_UNCACHED_REGION >> 10);
+
+ /* Initialize the blackfin L1 Memory. */
+ l1sram_init();
+ l1_data_sram_init();
+ l1_inst_sram_init();
+
+ /* Allocate this once; never free it. We assume this gives us a
+ pointer to the start of L1 scratchpad memory; panic if it
+ doesn't. */
+ tmp = (unsigned long)l1sram_alloc(sizeof(struct l1_scratch_task_info));
+ if (tmp != (unsigned long)L1_SCRATCH_TASK_INFO) {
+ printk(KERN_EMERG "mem_init(): Did not get the right address from l1sram_alloc: %08lx != %08lx\n",
+ tmp, (unsigned long)L1_SCRATCH_TASK_INFO);
+ panic("No L1, time to give up\n");
+ }
+}
+
+#ifdef CONFIG_BLK_DEV_INITRD
+void free_initrd_mem(unsigned long start, unsigned long end)
+{
+ int pages = 0;
+ for (; start < end; start += PAGE_SIZE) {
+ ClearPageReserved(virt_to_page(start));
+ init_page_count(virt_to_page(start));
+ free_page(start);
+ totalram_pages++;
+ pages++;
+ }
+ printk(KERN_NOTICE "Freeing initrd memory: %dk freed\n", pages);
+}
+#endif
+
+void free_initmem(void)
+{
+#ifdef CONFIG_RAMKERNEL
+ unsigned long addr;
+/*
+ * the following code should be cool even if these sections
+ * are not page aligned.
+ */
+ addr = PAGE_ALIGN((unsigned long)(__init_begin));
+ /* next to check that the page we free is not a partial page */
+ for (; addr + PAGE_SIZE < (unsigned long)(__init_end);
+ addr += PAGE_SIZE) {
+ ClearPageReserved(virt_to_page(addr));
+ init_page_count(virt_to_page(addr));
+ free_page(addr);
+ totalram_pages++;
+ }
+ printk(KERN_NOTICE
+ "Freeing unused kernel memory: %ldk freed (0x%x - 0x%x)\n",
+ (addr - PAGE_ALIGN((long)__init_begin)) >> 10,
+ (int)(PAGE_ALIGN((unsigned long)(__init_begin))),
+ (int)(addr - PAGE_SIZE));
+#endif
+}
diff --git a/arch/blackfin/oprofile/Kconfig b/arch/blackfin/oprofile/Kconfig
new file mode 100644
index 00000000000..0a2fd999c94
--- /dev/null
+++ b/arch/blackfin/oprofile/Kconfig
@@ -0,0 +1,29 @@
+menu "Profiling support"
+depends on EXPERIMENTAL
+
+config PROFILING
+ bool "Profiling support (EXPERIMENTAL)"
+ help
+ Say Y here to enable the extended profiling support mechanisms used
+ by profilers such as OProfile.
+
+config OPROFILE
+ tristate "OProfile system profiling (EXPERIMENTAL)"
+ depends on PROFILING
+ help
+ OProfile is a profiling system capable of profiling the
+ whole system, include the kernel, kernel modules, libraries,
+ and applications.
+
+ If unsure, say N.
+
+config HARDWARE_PM
+ tristate "Hardware Performance Monitor Profiling"
+ depends on PROFILING
+ help
+ take use of hardware performance monitor to profiling the kernel
+ and application.
+
+ If unsure, say N.
+
+endmenu
diff --git a/arch/blackfin/oprofile/Makefile b/arch/blackfin/oprofile/Makefile
new file mode 100644
index 00000000000..634e300d67e
--- /dev/null
+++ b/arch/blackfin/oprofile/Makefile
@@ -0,0 +1,14 @@
+#
+# arch/blackfin/oprofile/Makefile
+#
+
+obj-$(CONFIG_OPROFILE) += oprofile.o
+
+DRIVER_OBJS := $(addprefix ../../../drivers/oprofile/, \
+ oprof.o cpu_buffer.o buffer_sync.o \
+ event_buffer.o oprofile_files.o \
+ oprofilefs.o oprofile_stats.o \
+ timer_int.o )
+
+oprofile-y := $(DRIVER_OBJS) common.o
+oprofile-$(CONFIG_HARDWARE_PM) += op_model_bf533.o
diff --git a/arch/blackfin/oprofile/common.c b/arch/blackfin/oprofile/common.c
new file mode 100644
index 00000000000..009a1700c85
--- /dev/null
+++ b/arch/blackfin/oprofile/common.c
@@ -0,0 +1,168 @@
+/*
+ * File: arch/blackfin/oprofile/common.c
+ * Based on: arch/alpha/oprofile/common.c
+ * Author: Anton Blanchard <anton@au.ibm.com>
+ *
+ * Created:
+ * Description:
+ *
+ * Modified:
+ * Copyright (C) 2004 Anton Blanchard <anton@au.ibm.com>, IBM
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/oprofile.h>
+#include <linux/init.h>
+#include <linux/smp.h>
+#include <linux/errno.h>
+#include <linux/mutex.h>
+
+#include <asm/ptrace.h>
+#include <asm/system.h>
+#include <asm/blackfin.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+
+#include "op_blackfin.h"
+
+#define BFIN_533_ID 0xE5040003
+#define BFIN_537_ID 0xE5040002
+
+static int pfmon_enabled;
+static struct mutex pfmon_lock;
+
+struct op_bfin533_model *model;
+
+struct op_counter_config ctr[OP_MAX_COUNTER];
+
+static int op_bfin_setup(void)
+{
+ int ret;
+
+ /* Pre-compute the values to stuff in the hardware registers. */
+ spin_lock(&oprofilefs_lock);
+ ret = model->reg_setup(ctr);
+ spin_unlock(&oprofilefs_lock);
+
+ return ret;
+}
+
+static void op_bfin_shutdown(void)
+{
+#if 0
+ /* what is the difference between shutdown and stop? */
+#endif
+}
+
+static int op_bfin_start(void)
+{
+ int ret = -EBUSY;
+
+ printk(KERN_INFO "KSDBG:in %s\n", __FUNCTION__);
+ mutex_lock(&pfmon_lock);
+ if (!pfmon_enabled) {
+ ret = model->start(ctr);
+ pfmon_enabled = !ret;
+ }
+ mutex_unlock(&pfmon_lock);
+
+ return ret;
+}
+
+static void op_bfin_stop(void)
+{
+ mutex_lock(&pfmon_lock);
+ if (pfmon_enabled) {
+ model->stop();
+ pfmon_enabled = 0;
+ }
+ mutex_unlock(&pfmon_lock);
+}
+
+static int op_bfin_create_files(struct super_block *sb, struct dentry *root)
+{
+ int i;
+
+ for (i = 0; i < model->num_counters; ++i) {
+ struct dentry *dir;
+ char buf[3];
+ printk(KERN_INFO "Oprofile: creating files... \n");
+
+ snprintf(buf, sizeof buf, "%d", i);
+ dir = oprofilefs_mkdir(sb, root, buf);
+
+ oprofilefs_create_ulong(sb, dir, "enabled", &ctr[i].enabled);
+ oprofilefs_create_ulong(sb, dir, "event", &ctr[i].event);
+ oprofilefs_create_ulong(sb, dir, "count", &ctr[i].count);
+ /*
+ * We dont support per counter user/kernel selection, but
+ * we leave the entries because userspace expects them
+ */
+ oprofilefs_create_ulong(sb, dir, "kernel", &ctr[i].kernel);
+ oprofilefs_create_ulong(sb, dir, "user", &ctr[i].user);
+ oprofilefs_create_ulong(sb, dir, "unit_mask",
+ &ctr[i].unit_mask);
+ }
+
+ return 0;
+}
+int __init oprofile_arch_init(struct oprofile_operations *ops)
+{
+#ifdef CONFIG_HARDWARE_PM
+ unsigned int dspid;
+
+ mutex_init(&pfmon_lock);
+
+ dspid = bfin_read_DSPID();
+
+ printk(KERN_INFO "Oprofile got the cpu id is 0x%x. \n", dspid);
+
+ switch (dspid) {
+ case BFIN_533_ID:
+ model = &op_model_bfin533;
+ model->num_counters = 2;
+ break;
+ case BFIN_537_ID:
+ model = &op_model_bfin533;
+ model->num_counters = 2;
+ break;
+ default:
+ return -ENODEV;
+ }
+
+ ops->cpu_type = model->name;
+ ops->create_files = op_bfin_create_files;
+ ops->setup = op_bfin_setup;
+ ops->shutdown = op_bfin_shutdown;
+ ops->start = op_bfin_start;
+ ops->stop = op_bfin_stop;
+
+ printk(KERN_INFO "oprofile: using %s performance monitoring.\n",
+ ops->cpu_type);
+
+ return 0;
+#else
+ return -1;
+#endif
+}
+
+void oprofile_arch_exit(void)
+{
+}
diff --git a/arch/blackfin/oprofile/op_blackfin.h b/arch/blackfin/oprofile/op_blackfin.h
new file mode 100644
index 00000000000..f88f446c814
--- /dev/null
+++ b/arch/blackfin/oprofile/op_blackfin.h
@@ -0,0 +1,98 @@
+/*
+ * File: arch/blackfin/oprofile/op_blackfin.h
+ * Based on:
+ * Author: Anton Blanchard <anton@au.ibm.com>
+ *
+ * Created:
+ * Description:
+ *
+ * Modified:
+ * Copyright (C) 2004 Anton Blanchard <anton@au.ibm.com>, IBM
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef OP_BLACKFIN_H
+#define OP_BLACKFIN_H 1
+
+#define OP_MAX_COUNTER 2
+
+#include <asm/blackfin.h>
+
+/* Per-counter configuration as set via oprofilefs. */
+struct op_counter_config {
+ unsigned long valid;
+ unsigned long enabled;
+ unsigned long event;
+ unsigned long count;
+ unsigned long kernel;
+ unsigned long user;
+ unsigned long unit_mask;
+};
+
+/* System-wide configuration as set via oprofilefs. */
+struct op_system_config {
+ unsigned long enable_kernel;
+ unsigned long enable_user;
+};
+
+/* Per-arch configuration */
+struct op_bfin533_model {
+ int (*reg_setup) (struct op_counter_config *);
+ int (*start) (struct op_counter_config *);
+ void (*stop) (void);
+ int num_counters;
+ char *name;
+};
+
+extern struct op_bfin533_model op_model_bfin533;
+
+static inline unsigned int ctr_read(void)
+{
+ unsigned int tmp;
+
+ tmp = bfin_read_PFCTL();
+ __builtin_bfin_csync();
+
+ return tmp;
+}
+
+static inline void ctr_write(unsigned int val)
+{
+ bfin_write_PFCTL(val);
+ __builtin_bfin_csync();
+}
+
+static inline void count_read(unsigned int *count)
+{
+ count[0] = bfin_read_PFCNTR0();
+ count[1] = bfin_read_PFCNTR1();
+ __builtin_bfin_csync();
+}
+
+static inline void count_write(unsigned int *count)
+{
+ bfin_write_PFCNTR0(count[0]);
+ bfin_write_PFCNTR1(count[1]);
+ __builtin_bfin_csync();
+}
+
+extern int pm_overflow_handler(int irq, struct pt_regs *regs);
+
+#endif
diff --git a/arch/blackfin/oprofile/op_model_bf533.c b/arch/blackfin/oprofile/op_model_bf533.c
new file mode 100644
index 00000000000..b7a20a006b4
--- /dev/null
+++ b/arch/blackfin/oprofile/op_model_bf533.c
@@ -0,0 +1,161 @@
+/*
+ * File: arch/blackfin/oprofile/op_model_bf533.c
+ * Based on:
+ * Author: Anton Blanchard <anton@au.ibm.com>
+ *
+ * Created:
+ * Description:
+ *
+ * Modified:
+ * Copyright (C) 2004 Anton Blanchard <anton@au.ibm.com>, IBM
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/oprofile.h>
+#include <linux/init.h>
+#include <linux/smp.h>
+#include <linux/interrupt.h>
+#include <asm/ptrace.h>
+#include <asm/system.h>
+#include <asm/processor.h>
+#include <asm/blackfin.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+
+#include "op_blackfin.h"
+
+#define PM_ENABLE 0x01;
+#define PM_CTL1_ENABLE 0x18
+#define PM_CTL0_ENABLE 0xC000
+#define COUNT_EDGE_ONLY 0x3000000
+
+static int oprofile_running;
+
+static unsigned curr_pfctl, curr_count[2];
+
+static int bfin533_reg_setup(struct op_counter_config *ctr)
+{
+ unsigned int pfctl = ctr_read();
+ unsigned int count[2];
+
+ /* set Blackfin perf monitor regs with ctr */
+ if (ctr[0].enabled) {
+ pfctl |= (PM_CTL0_ENABLE | ((char)ctr[0].event << 5));
+ count[0] = 0xFFFFFFFF - ctr[0].count;
+ curr_count[0] = count[0];
+ }
+ if (ctr[1].enabled) {
+ pfctl |= (PM_CTL1_ENABLE | ((char)ctr[1].event << 16));
+ count[1] = 0xFFFFFFFF - ctr[1].count;
+ curr_count[1] = count[1];
+ }
+
+ pr_debug("ctr[0].enabled=%d,ctr[1].enabled=%d,ctr[0].event<<5=0x%x,ctr[1].event<<16=0x%x\n", ctr[0].enabled, ctr[1].enabled, ctr[0].event << 5, ctr[1].event << 16);
+ pfctl |= COUNT_EDGE_ONLY;
+ curr_pfctl = pfctl;
+
+ pr_debug("write 0x%x to pfctl\n", pfctl);
+ ctr_write(pfctl);
+ count_write(count);
+
+ return 0;
+}
+
+static int bfin533_start(struct op_counter_config *ctr)
+{
+ unsigned int pfctl = ctr_read();
+
+ pfctl |= PM_ENABLE;
+ curr_pfctl = pfctl;
+
+ ctr_write(pfctl);
+
+ oprofile_running = 1;
+ pr_debug("start oprofile counter \n");
+
+ return 0;
+}
+
+static void bfin533_stop(void)
+{
+ int pfctl;
+
+ pfctl = ctr_read();
+ pfctl &= ~PM_ENABLE;
+ /* freeze counters */
+ ctr_write(pfctl);
+
+ oprofile_running = 0;
+ pr_debug("stop oprofile counter \n");
+}
+
+static int get_kernel(void)
+{
+ int ipend, is_kernel;
+
+ ipend = bfin_read_IPEND();
+
+ /* test bit 15 */
+ is_kernel = ((ipend & 0x8000) != 0);
+
+ return is_kernel;
+}
+
+int pm_overflow_handler(int irq, struct pt_regs *regs)
+{
+ int is_kernel;
+ int i, cpu;
+ unsigned int pc, pfctl;
+ unsigned int count[2];
+
+ pr_debug("get interrupt in %s\n", __FUNCTION__);
+ if (oprofile_running == 0) {
+ pr_debug("error: entering interrupt when oprofile is stopped.\n\r");
+ return -1;
+ }
+
+ is_kernel = get_kernel();
+ cpu = smp_processor_id();
+ pc = regs->pc;
+ pfctl = ctr_read();
+
+ /* read the two event counter regs */
+ count_read(count);
+
+ /* if the counter overflows, add sample to oprofile buffer */
+ for (i = 0; i < 2; ++i) {
+ if (oprofile_running) {
+ oprofile_add_sample(regs, i);
+ }
+ }
+
+ /* reset the perfmon counter */
+ ctr_write(curr_pfctl);
+ count_write(curr_count);
+ return 0;
+}
+
+struct op_bfin533_model op_model_bfin533 = {
+ .reg_setup = bfin533_reg_setup,
+ .start = bfin533_start,
+ .stop = bfin533_stop,
+ .num_counters = 2,
+ .name = "blackfin/bf533"
+};
diff --git a/arch/blackfin/oprofile/timer_int.c b/arch/blackfin/oprofile/timer_int.c
new file mode 100644
index 00000000000..8fba16c846c
--- /dev/null
+++ b/arch/blackfin/oprofile/timer_int.c
@@ -0,0 +1,74 @@
+/*
+ * File: arch/blackfin/oprofile/timer_int.c
+ * Based on:
+ * Author: Michael Kang
+ *
+ * Created:
+ * Description:
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/init.h>
+#include <linux/smp.h>
+#include <linux/irq.h>
+#include <linux/oprofile.h>
+
+#include <asm/ptrace.h>
+
+static void enable_sys_timer0()
+{
+}
+static void disable_sys_timer0()
+{
+}
+
+static irqreturn_t sys_timer0_int_handler(int irq, void *dev_id,
+ struct pt_regs *regs)
+{
+ oprofile_add_sample(regs, 0);
+ return IRQ_HANDLED;
+}
+
+static int sys_timer0_start(void)
+{
+ enable_sys_timer0();
+ return request_irq(IVG11, sys_timer0_int_handler, 0, "sys_timer0", NULL);
+}
+
+static void sys_timer0_stop(void)
+{
+ disable_sys_timer();
+}
+
+int __init sys_timer0_init(struct oprofile_operations *ops)
+{
+ extern int nmi_active;
+
+ if (nmi_active <= 0)
+ return -ENODEV;
+
+ ops->start = timer_start;
+ ops->stop = timer_stop;
+ ops->cpu_type = "timer";
+ printk(KERN_INFO "oprofile: using NMI timer interrupt.\n");
+ return 0;
+}
diff --git a/arch/cris/arch-v32/kernel/fasttimer.c b/arch/cris/arch-v32/kernel/fasttimer.c
index 5daeb6f7f3b..79e1e4c2ca1 100644
--- a/arch/cris/arch-v32/kernel/fasttimer.c
+++ b/arch/cris/arch-v32/kernel/fasttimer.c
@@ -603,23 +603,8 @@ void schedule_usleep(unsigned long us)
#ifdef CONFIG_PROC_FS
static int proc_fasttimer_read(char *buf, char **start, off_t offset, int len
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
- ,int *eof, void *data_unused
-#else
- ,int unused
-#endif
- );
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
+ ,int *eof, void *data_unused);
static struct proc_dir_entry *fasttimer_proc_entry;
-#else
-static struct proc_dir_entry fasttimer_proc_entry =
-{
- 0, 9, "fasttimer",
- S_IFREG | S_IRUGO, 1, 0, 0,
- 0, NULL /* ops -- default to array */,
- &proc_fasttimer_read /* get_info */,
-};
-#endif
#endif /* CONFIG_PROC_FS */
#ifdef CONFIG_PROC_FS
@@ -628,12 +613,7 @@ static struct proc_dir_entry fasttimer_proc_entry =
#define BIG_BUF_SIZE (500 + NUM_TIMER_STATS * 300)
static int proc_fasttimer_read(char *buf, char **start, off_t offset, int len
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
- ,int *eof, void *data_unused
-#else
- ,int unused
-#endif
- )
+ ,int *eof, void *data_unused)
{
unsigned long flags;
int i = 0;
@@ -808,9 +788,7 @@ static int proc_fasttimer_read(char *buf, char **start, off_t offset, int len
memcpy(buf, bigbuf + offset, len);
*start = buf;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
*eof = 1;
-#endif
return len;
}
@@ -974,12 +952,8 @@ void fast_timer_init(void)
printk("fast_timer_init()\n");
#ifdef CONFIG_PROC_FS
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
if ((fasttimer_proc_entry = create_proc_entry( "fasttimer", 0, 0 )))
fasttimer_proc_entry->read_proc = proc_fasttimer_read;
-#else
- proc_register_dynamic(&proc_root, &fasttimer_proc_entry);
-#endif
#endif /* PROC_FS */
if(request_irq(TIMER_INTR_VECT, timer_trig_interrupt, IRQF_DISABLED,
"fast timer int", NULL))
diff --git a/arch/cris/kernel/profile.c b/arch/cris/kernel/profile.c
index 4cfcae62050..aad0a9e5991 100644
--- a/arch/cris/kernel/profile.c
+++ b/arch/cris/kernel/profile.c
@@ -15,39 +15,47 @@ static int prof_running = 0;
void
cris_profile_sample(struct pt_regs* regs)
{
- if (!prof_running)
- return;
- if (user_mode(regs))
- *(unsigned int*)sample_buffer_pos = current->pid;
- else
- *(unsigned int*)sample_buffer_pos = 0;
- *(unsigned int*)(sample_buffer_pos + 4) = instruction_pointer(regs);
- sample_buffer_pos += 8;
- if (sample_buffer_pos == sample_buffer + SAMPLE_BUFFER_SIZE)
- sample_buffer_pos = sample_buffer;
+ if (!prof_running)
+ return;
+
+ if (user_mode(regs))
+ *(unsigned int*)sample_buffer_pos = current->pid;
+ else
+ *(unsigned int*)sample_buffer_pos = 0;
+
+ *(unsigned int*)(sample_buffer_pos + 4) = instruction_pointer(regs);
+ sample_buffer_pos += 8;
+
+ if (sample_buffer_pos == sample_buffer + SAMPLE_BUFFER_SIZE)
+ sample_buffer_pos = sample_buffer;
}
static ssize_t
-read_cris_profile(struct file *file, char __user *buf, size_t count, loff_t *ppos)
+read_cris_profile(struct file *file, char __user *buf,
+ size_t count, loff_t *ppos)
{
- unsigned long p = *ppos;
- if (p > SAMPLE_BUFFER_SIZE)
- return 0;
- if (p + count > SAMPLE_BUFFER_SIZE)
- count = SAMPLE_BUFFER_SIZE - p;
- if (copy_to_user(buf, sample_buffer + p,count))
+ unsigned long p = *ppos;
+
+ if (p > SAMPLE_BUFFER_SIZE)
+ return 0;
+
+ if (p + count > SAMPLE_BUFFER_SIZE)
+ count = SAMPLE_BUFFER_SIZE - p;
+ if (copy_to_user(buf, sample_buffer + p,count))
return -EFAULT;
- memset(sample_buffer + p, 0, count);
- *ppos += count;
- return count;
+
+ memset(sample_buffer + p, 0, count);
+ *ppos += count;
+
+ return count;
}
static ssize_t
write_cris_profile(struct file *file, const char __user *buf,
- size_t count, loff_t *ppos)
+ size_t count, loff_t *ppos)
{
- sample_buffer_pos = sample_buffer;
- memset(sample_buffer, 0, SAMPLE_BUFFER_SIZE);
+ sample_buffer_pos = sample_buffer;
+ memset(sample_buffer, 0, SAMPLE_BUFFER_SIZE);
}
static const struct file_operations cris_proc_profile_operations = {
@@ -58,16 +66,23 @@ static const struct file_operations cris_proc_profile_operations = {
static int
__init init_cris_profile(void)
{
- struct proc_dir_entry *entry;
- sample_buffer = kmalloc(SAMPLE_BUFFER_SIZE, GFP_KERNEL);
- sample_buffer_pos = sample_buffer;
- entry = create_proc_entry("system_profile", S_IWUSR | S_IRUGO, NULL);
- if (entry) {
- entry->proc_fops = &cris_proc_profile_operations;
- entry->size = SAMPLE_BUFFER_SIZE;
- }
- prof_running = 1;
- return 0;
+ struct proc_dir_entry *entry;
+
+ sample_buffer = kmalloc(SAMPLE_BUFFER_SIZE, GFP_KERNEL);
+ if (!sample_buffer) {
+ return -ENOMEM;
+ }
+
+ sample_buffer_pos = sample_buffer;
+
+ entry = create_proc_entry("system_profile", S_IWUSR | S_IRUGO, NULL);
+ if (entry) {
+ entry->proc_fops = &cris_proc_profile_operations;
+ entry->size = SAMPLE_BUFFER_SIZE;
+ }
+ prof_running = 1;
+
+ return 0;
}
__initcall(init_cris_profile);
diff --git a/arch/frv/Kconfig b/arch/frv/Kconfig
index cea237413aa..eed694312a7 100644
--- a/arch/frv/Kconfig
+++ b/arch/frv/Kconfig
@@ -53,6 +53,10 @@ config ARCH_HAS_ILOG2_U64
bool
default y
+config ARCH_USES_SLAB_PAGE_STRUCT
+ bool
+ default y
+
mainmenu "Fujitsu FR-V Kernel Configuration"
source "init/Kconfig"
diff --git a/arch/frv/mm/elf-fdpic.c b/arch/frv/mm/elf-fdpic.c
index 9477ccce070..cac2c01a3a5 100644
--- a/arch/frv/mm/elf-fdpic.c
+++ b/arch/frv/mm/elf-fdpic.c
@@ -64,6 +64,10 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi
if (len > TASK_SIZE)
return -ENOMEM;
+ /* handle MAP_FIXED */
+ if (flags & MAP_FIXED)
+ return addr;
+
/* only honour a hint if we're not going to clobber something doing so */
if (addr) {
addr = PAGE_ALIGN(addr);
diff --git a/arch/h8300/Kconfig b/arch/h8300/Kconfig
index 1734d96422c..618dbad696f 100644
--- a/arch/h8300/Kconfig
+++ b/arch/h8300/Kconfig
@@ -49,10 +49,18 @@ config GENERIC_HWEIGHT
bool
default y
+config GENERIC_HARDIRQS
+ bool
+ default y
+
config GENERIC_CALIBRATE_DELAY
bool
default y
+config GENERIC_TIME
+ bool
+ default y
+
config TIME_LOW_RES
bool
default y
diff --git a/arch/h8300/Makefile b/arch/h8300/Makefile
index 40b3f56f366..b2d896a7e59 100644
--- a/arch/h8300/Makefile
+++ b/arch/h8300/Makefile
@@ -41,7 +41,7 @@ LDFLAGS += $(ldflags-y)
CROSS_COMPILE = h8300-elf-
LIBGCC := $(shell $(CROSS-COMPILE)$(CC) $(CFLAGS) -print-libgcc-file-name)
-head-y := arch/$(ARCH)/platform/$(platform-y)/$(board-y)/crt0_$(model-y).o
+head-y := arch/$(ARCH)/platform/$(PLATFORM)/$(BOARD)/crt0_$(MODEL).o
core-y += arch/$(ARCH)/kernel/ \
arch/$(ARCH)/mm/
diff --git a/arch/h8300/boot/Makefile b/arch/h8300/boot/Makefile
index 65086d925ca..0bb62e064ee 100644
--- a/arch/h8300/boot/Makefile
+++ b/arch/h8300/boot/Makefile
@@ -1,12 +1,22 @@
# arch/h8300/boot/Makefile
-targets := vmlinux.srec vmlinux.bin
+targets := vmlinux.srec vmlinux.bin zImage
+subdir- := compressed
OBJCOPYFLAGS_vmlinux.srec := -Osrec
OBJCOPYFLAGS_vmlinux.bin := -Obinary
+OBJCOPYFLAGS_zImage := -O binary -R .note -R .comment -R .stab -R .stabstr -S
$(obj)/vmlinux.srec $(obj)/vmlinux.bin: vmlinux FORCE
$(call if_changed,objcopy)
@echo ' Kernel: $@ is ready'
+$(obj)/zImage: $(obj)/compressed/vmlinux FORCE
+ $(call if_changed,objcopy)
+ @echo 'Kernel: $@ is ready'
+
+$(obj)/compressed/vmlinux: FORCE
+ $(Q)$(MAKE) $(build)=$(obj)/compressed $@
+
CLEAN_FILES += arch/$(ARCH)/vmlinux.bin arch/$(ARCH)/vmlinux.srec
+
diff --git a/arch/h8300/boot/compressed/Makefile b/arch/h8300/boot/compressed/Makefile
new file mode 100644
index 00000000000..71aac82a8ae
--- /dev/null
+++ b/arch/h8300/boot/compressed/Makefile
@@ -0,0 +1,37 @@
+#
+# linux/arch/sh/boot/compressed/Makefile
+#
+# create a compressed vmlinux image from the original vmlinux
+#
+
+targets := vmlinux vmlinux.bin vmlinux.bin.gz head.o misc.o piggy.o
+EXTRA_AFLAGS := -traditional
+
+OBJECTS = $(obj)/head.o $(obj)/misc.o
+
+#
+# IMAGE_OFFSET is the load offset of the compression loader
+# Assign dummy values if these 2 variables are not defined,
+# in order to suppress error message.
+#
+CONFIG_MEMORY_START ?= 0x00400000
+CONFIG_BOOT_LINK_OFFSET ?= 0x00400000
+IMAGE_OFFSET := $(shell printf "0x%08x" $$[$(CONFIG_MEMORY_START)+$(CONFIG_BOOT_LINK_OFFSET)])
+
+LDFLAGS_vmlinux := -T $(obj)/vmlinux.lds
+
+$(obj)/vmlinux: $(OBJECTS) $(obj)/piggy.o FORCE
+ $(call if_changed,ld)
+ @:
+
+$(obj)/vmlinux.bin: vmlinux FORCE
+ $(call if_changed,objcopy)
+
+$(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE
+ $(call if_changed,gzip)
+
+LDFLAGS_piggy.o := -r --format binary --oformat elf32-h8300 -T
+OBJCOPYFLAGS := -O binary
+
+$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.gz FORCE
+ $(call if_changed,ld)
diff --git a/arch/h8300/boot/compressed/head.S b/arch/h8300/boot/compressed/head.S
new file mode 100644
index 00000000000..b8e90d12d19
--- /dev/null
+++ b/arch/h8300/boot/compressed/head.S
@@ -0,0 +1,47 @@
+/*
+ * linux/arch/h8300/boot/compressed/head.S
+ *
+ * Copyright (C) 2006 Yoshinori Sato
+ */
+
+.h8300h
+#include <linux/linkage.h>
+
+#define SRAM_START 0xff4000
+
+ .section .text.startup
+ .global startup
+startup:
+ mov.l #SRAM_START+0x8000, sp
+ mov.l #__sbss, er0
+ mov.l #__ebss, er1
+ sub.l er0, er1
+ shlr er1
+ shlr er1
+ sub.l er2, er2
+1:
+ mov.l er2, @er0
+ adds #4, er0
+ dec.l #1, er1
+ bne 1b
+ jsr @_decompress_kernel
+ jmp @0x400000
+
+ .align 9
+fake_headers_as_bzImage:
+ .word 0
+ .ascii "HdrS" ; header signature
+ .word 0x0202 ; header version number (>= 0x0105)
+ ; or else old loadlin-1.5 will fail)
+ .word 0 ; default_switch
+ .word 0 ; SETUPSEG
+ .word 0x1000
+ .word 0 ; pointing to kernel version string
+ .byte 0 ; = 0, old one (LILO, Loadlin,
+ ; 0xTV: T=0 for LILO
+ ; V = version
+ .byte 1 ; Load flags bzImage=1
+ .word 0x8000 ; size to move, when setup is not
+ .long 0x100000 ; 0x100000 = default for big kernel
+ .long 0 ; address of loaded ramdisk image
+ .long 0 ; its size in bytes
diff --git a/arch/h8300/boot/compressed/misc.c b/arch/h8300/boot/compressed/misc.c
new file mode 100644
index 00000000000..845074588af
--- /dev/null
+++ b/arch/h8300/boot/compressed/misc.c
@@ -0,0 +1,219 @@
+/*
+ * arch/h8300/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 h8300 by Yoshinori Sato 2006
+ */
+
+#include <asm/uaccess.h>
+
+/*
+ * 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);
+static void gzip_mark(void **);
+static void gzip_release(void **);
+
+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 *malloc(int size);
+static void free(void *where);
+static void error(char *m);
+static void gzip_mark(void **);
+static void gzip_release(void **);
+
+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"
+
+#define SCR *((volatile unsigned char *)0xffff8a)
+#define TDR *((volatile unsigned char *)0xffff8b)
+#define SSR *((volatile unsigned char *)0xffff8c)
+
+static void *malloc(int size)
+{
+ void *p;
+
+ if (size <0) error("Malloc error");
+ if (free_mem_ptr == 0) error("Memory error");
+
+ free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */
+
+ p = (void *)free_mem_ptr;
+ free_mem_ptr += size;
+
+ if (free_mem_ptr >= free_mem_end_ptr)
+ error("Out of memory");
+
+ return p;
+}
+
+static void free(void *where)
+{ /* Don't care */
+}
+
+static void gzip_mark(void **ptr)
+{
+ *ptr = (void *) free_mem_ptr;
+}
+
+static void gzip_release(void **ptr)
+{
+ free_mem_ptr = (long) *ptr;
+}
+
+int puts(const char *s)
+{
+ return 0;
+}
+
+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 = 0;
+ output_ptr = (unsigned long)0x400000;
+ 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/h8300/kernel/Makefile b/arch/h8300/kernel/Makefile
index 4edbc2ef6ca..ccc1a7fbf94 100644
--- a/arch/h8300/kernel/Makefile
+++ b/arch/h8300/kernel/Makefile
@@ -4,10 +4,8 @@
extra-y := vmlinux.lds
-obj-y := process.o traps.o ptrace.o ints.o \
+obj-y := process.o traps.o ptrace.o irq.o \
sys_h8300.o time.o semaphore.o signal.o \
- setup.o gpio.o init_task.o syscalls.o devres.o
-
-devres-y = ../../../kernel/irq/devres.o
+ setup.o gpio.o init_task.o syscalls.o
obj-$(CONFIG_MODULES) += module.o h8300_ksyms.o
diff --git a/arch/h8300/kernel/irq.c b/arch/h8300/kernel/irq.c
new file mode 100644
index 00000000000..43d21e93f41
--- /dev/null
+++ b/arch/h8300/kernel/irq.c
@@ -0,0 +1,211 @@
+/*
+ * linux/arch/h8300/kernel/irq.c
+ *
+ * Copyright 2007 Yoshinori Sato <ysato@users.sourceforge.jp>
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/kernel_stat.h>
+#include <linux/seq_file.h>
+#include <linux/init.h>
+#include <linux/random.h>
+#include <linux/bootmem.h>
+#include <linux/irq.h>
+
+#include <asm/system.h>
+#include <asm/traps.h>
+#include <asm/io.h>
+#include <asm/setup.h>
+#include <asm/errno.h>
+
+/*#define DEBUG*/
+
+extern unsigned long *interrupt_redirect_table;
+extern const int h8300_saved_vectors[];
+extern const unsigned long h8300_trap_table[];
+int h8300_enable_irq_pin(unsigned int irq);
+void h8300_disable_irq_pin(unsigned int irq);
+
+#define CPU_VECTOR ((unsigned long *)0x000000)
+#define ADDR_MASK (0xffffff)
+
+static inline int is_ext_irq(unsigned int irq)
+{
+ return (irq >= EXT_IRQ0 && irq <= (EXT_IRQ0 + EXT_IRQS));
+}
+
+static void h8300_enable_irq(unsigned int irq)
+{
+ if (is_ext_irq(irq))
+ IER_REGS |= 1 << (irq - EXT_IRQ0);
+}
+
+static void h8300_disable_irq(unsigned int irq)
+{
+ if (is_ext_irq(irq))
+ IER_REGS &= ~(1 << (irq - EXT_IRQ0));
+}
+
+static void h8300_end_irq(unsigned int irq)
+{
+}
+
+static unsigned int h8300_startup_irq(unsigned int irq)
+{
+ if (is_ext_irq(irq))
+ return h8300_enable_irq_pin(irq);
+ else
+ return 0;
+}
+
+static void h8300_shutdown_irq(unsigned int irq)
+{
+ if (is_ext_irq(irq))
+ h8300_disable_irq_pin(irq);
+}
+
+/*
+ * h8300 interrupt controler implementation
+ */
+struct irq_chip h8300irq_chip = {
+ .name = "H8300-INTC",
+ .startup = h8300_startup_irq,
+ .shutdown = h8300_shutdown_irq,
+ .enable = h8300_enable_irq,
+ .disable = h8300_disable_irq,
+ .ack = NULL,
+ .end = h8300_end_irq,
+};
+
+void ack_bad_irq(unsigned int irq)
+{
+ printk("unexpected IRQ trap at vector %02x\n", irq);
+}
+
+#if defined(CONFIG_RAMKERNEL)
+static unsigned long __init *get_vector_address(void)
+{
+ unsigned long *rom_vector = CPU_VECTOR;
+ unsigned long base,tmp;
+ int vec_no;
+
+ base = rom_vector[EXT_IRQ0] & ADDR_MASK;
+
+ /* check romvector format */
+ for (vec_no = EXT_IRQ1; vec_no <= EXT_IRQ0+EXT_IRQS; vec_no++) {
+ if ((base+(vec_no - EXT_IRQ0)*4) != (rom_vector[vec_no] & ADDR_MASK))
+ return NULL;
+ }
+
+ /* ramvector base address */
+ base -= EXT_IRQ0*4;
+
+ /* writerble check */
+ tmp = ~(*(volatile unsigned long *)base);
+ (*(volatile unsigned long *)base) = tmp;
+ if ((*(volatile unsigned long *)base) != tmp)
+ return NULL;
+ return (unsigned long *)base;
+}
+
+static void __init setup_vector(void)
+{
+ int i;
+ unsigned long *ramvec,*ramvec_p;
+ const unsigned long *trap_entry;
+ const int *saved_vector;
+
+ ramvec = get_vector_address();
+ if (ramvec == NULL)
+ panic("interrupt vector serup failed.");
+ else
+ printk(KERN_INFO "virtual vector at 0x%08lx\n",(unsigned long)ramvec);
+
+ /* create redirect table */
+ ramvec_p = ramvec;
+ trap_entry = h8300_trap_table;
+ saved_vector = h8300_saved_vectors;
+ for ( i = 0; i < NR_IRQS; i++) {
+ if (i == *saved_vector) {
+ ramvec_p++;
+ saved_vector++;
+ } else {
+ if ( i < NR_TRAPS ) {
+ if (*trap_entry)
+ *ramvec_p = VECTOR(*trap_entry);
+ ramvec_p++;
+ trap_entry++;
+ } else
+ *ramvec_p++ = REDIRECT(interrupt_entry);
+ }
+ }
+ interrupt_redirect_table = ramvec;
+#ifdef DEBUG
+ ramvec_p = ramvec;
+ for (i = 0; i < NR_IRQS; i++) {
+ if ((i % 8) == 0)
+ printk(KERN_DEBUG "\n%p: ",ramvec_p);
+ printk(KERN_DEBUG "%p ",*ramvec_p);
+ ramvec_p++;
+ }
+ printk(KERN_DEBUG "\n");
+#endif
+}
+#else
+#define setup_vector() do { } while(0)
+#endif
+
+void __init init_IRQ(void)
+{
+ int c;
+
+ setup_vector();
+
+ for (c = 0; c < NR_IRQS; c++) {
+ irq_desc[c].status = IRQ_DISABLED;
+ irq_desc[c].action = NULL;
+ irq_desc[c].depth = 1;
+ irq_desc[c].chip = &h8300irq_chip;
+ }
+}
+
+asmlinkage void do_IRQ(int irq)
+{
+ irq_enter();
+ __do_IRQ(irq);
+ irq_exit();
+}
+
+#if defined(CONFIG_PROC_FS)
+int show_interrupts(struct seq_file *p, void *v)
+{
+ int i = *(loff_t *) v, j;
+ struct irqaction * action;
+ unsigned long flags;
+
+ if (i == 0)
+ seq_puts(p, " CPU0");
+
+ if (i < NR_IRQS) {
+ spin_lock_irqsave(&irq_desc[i].lock, flags);
+ action = irq_desc[i].action;
+ if (!action)
+ goto unlock;
+ seq_printf(p, "%3d: ",i);
+ seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
+ seq_printf(p, " %14s", irq_desc[i].chip->name);
+ seq_printf(p, "-%-8s", irq_desc[i].name);
+ seq_printf(p, " %s", action->name);
+
+ for (action=action->next; action; action = action->next)
+ seq_printf(p, ", %s", action->name);
+ seq_putc(p, '\n');
+unlock:
+ spin_unlock_irqrestore(&irq_desc[i].lock, flags);
+ }
+ return 0;
+}
+#endif
diff --git a/arch/h8300/kernel/setup.c b/arch/h8300/kernel/setup.c
index 313cd808104..b2e86d0255e 100644
--- a/arch/h8300/kernel/setup.c
+++ b/arch/h8300/kernel/setup.c
@@ -33,10 +33,7 @@
#include <asm/setup.h>
#include <asm/irq.h>
-
-#ifdef CONFIG_BLK_DEV_INITRD
#include <asm/pgtable.h>
-#endif
#if defined(__H8300H__)
#define CPU "H8/300H"
diff --git a/arch/h8300/kernel/time.c b/arch/h8300/kernel/time.c
index d1ef615ba89..330638220a2 100644
--- a/arch/h8300/kernel/time.c
+++ b/arch/h8300/kernel/time.c
@@ -44,7 +44,7 @@ static void timer_interrupt(int irq, void *dummy, struct pt_regs * regs)
#ifndef CONFIG_SMP
update_process_times(user_mode(regs));
#endif
- profile_tick(CPU_PROFILING, regs);
+ profile_tick(CPU_PROFILING);
}
void time_init(void)
@@ -66,55 +66,3 @@ void time_init(void)
platform_timer_setup(timer_interrupt);
}
-
-/*
- * This version of gettimeofday has near microsecond resolution.
- */
-void do_gettimeofday(struct timeval *tv)
-{
- unsigned long flags;
- unsigned long usec, sec;
-
- read_lock_irqsave(&xtime_lock, flags);
- usec = 0;
- sec = xtime.tv_sec;
- usec += (xtime.tv_nsec / 1000);
- read_unlock_irqrestore(&xtime_lock, flags);
-
- while (usec >= 1000000) {
- usec -= 1000000;
- sec++;
- }
-
- tv->tv_sec = sec;
- tv->tv_usec = usec;
-}
-
-EXPORT_SYMBOL(do_gettimeofday);
-
-int do_settimeofday(struct timespec *tv)
-{
- if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
- return -EINVAL;
-
- write_lock_irq(&xtime_lock);
- /* This is revolting. We need to set the xtime.tv_usec
- * correctly. However, the value in this location is
- * is value at the last tick.
- * Discover what correction gettimeofday
- * would have done, and then undo it!
- */
- while (tv->tv_nsec < 0) {
- tv->tv_nsec += NSEC_PER_SEC;
- tv->tv_sec--;
- }
-
- xtime.tv_sec = tv->tv_sec;
- xtime.tv_nsec = tv->tv_nsec;
- ntp_clear();
- write_sequnlock_irq(&xtime_lock);
- clock_was_set();
- return 0;
-}
-
-EXPORT_SYMBOL(do_settimeofday);
diff --git a/arch/h8300/mm/kmap.c b/arch/h8300/mm/kmap.c
index 26ab17286a5..5c7af09ae8d 100644
--- a/arch/h8300/mm/kmap.c
+++ b/arch/h8300/mm/kmap.c
@@ -24,12 +24,14 @@
#undef DEBUG
+#define VIRT_OFFSET (0x01000000)
+
/*
* Map some physical address range into the kernel address space.
*/
void *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag)
{
- return (void *)physaddr;
+ return (void *)(physaddr + VIRT_OFFSET);
}
/*
diff --git a/arch/h8300/platform/h8300h/Makefile b/arch/h8300/platform/h8300h/Makefile
index 5d42c772f75..b24ea08aa0a 100644
--- a/arch/h8300/platform/h8300h/Makefile
+++ b/arch/h8300/platform/h8300h/Makefile
@@ -4,4 +4,4 @@
# Reuse any files we can from the H8/300H
#
-obj-y := entry.o ints_h8300h.o ptrace_h8300h.o
+obj-y := entry.o irq_pin.o ptrace_h8300h.o
diff --git a/arch/h8300/platform/h8300h/entry.S b/arch/h8300/platform/h8300h/entry.S
index d2dea2432fb..f86ac3b5d4d 100644
--- a/arch/h8300/platform/h8300h/entry.S
+++ b/arch/h8300/platform/h8300h/entry.S
@@ -30,12 +30,12 @@
mov.l er0,@-sp
stc ccr,r0l /* check kernel mode */
- orc #0x10,ccr
btst #4,r0l
bne 5f
mov.l sp,@SYMBOL_NAME(sw_usp) /* user mode */
mov.l @sp,er0
+ orc #0x10,ccr
mov.l @SYMBOL_NAME(sw_ksp),sp
sub.l #(LRET-LORIG),sp /* allocate LORIG - LRET */
mov.l er0,@-sp
@@ -165,7 +165,7 @@ SYMBOL_NAME_LABEL(interrupt_entry)
dec.l #1,er0
mov.l sp,er1
subs #4,er1 /* adjust ret_pc */
- jsr @SYMBOL_NAME(process_int)
+ jsr @SYMBOL_NAME(do_IRQ)
mov.l @SYMBOL_NAME(irq_stat)+CPUSTAT_SOFTIRQ_PENDING,er0
beq 1f
jsr @SYMBOL_NAME(do_softirq)
diff --git a/arch/h8300/platform/h8300h/generic/Makefile b/arch/h8300/platform/h8300h/generic/Makefile
index b6ea7688a61..32b964a9010 100644
--- a/arch/h8300/platform/h8300h/generic/Makefile
+++ b/arch/h8300/platform/h8300h/generic/Makefile
@@ -2,5 +2,5 @@
# Makefile for the linux kernel.
#
+extra-y := crt0_$(MODEL).o
obj-y := timer.o
-extra-y = crt0_$(MODEL).o
diff --git a/arch/h8300/platform/h8300h/ints_h8300h.c b/arch/h8300/platform/h8300h/ints_h8300h.c
deleted file mode 100644
index f1777119b87..00000000000
--- a/arch/h8300/platform/h8300h/ints_h8300h.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * linux/arch/h8300/platform/h8300h/ints_h8300h.c
- * Interrupt handling CPU variants
- *
- * Yoshinori Sato <ysato@users.sourceforge.jp>
- *
- */
-
-#include <linux/init.h>
-#include <linux/errno.h>
-
-#include <asm/ptrace.h>
-#include <asm/traps.h>
-#include <asm/irq.h>
-#include <asm/io.h>
-#include <asm/gpio.h>
-#include <asm/regs306x.h>
-
-/* saved vector list */
-const int __initdata h8300_saved_vectors[]={
-#if defined(CONFIG_GDB_DEBUG)
- TRAP3_VEC,
-#endif
- -1
-};
-
-/* trap entry table */
-const unsigned long __initdata h8300_trap_table[NR_TRAPS]={
- 0,0,0,0,0,0,0,0,
- (unsigned long)system_call, /* TRAPA #0 */
- 0,0,
- (unsigned long)trace_break, /* TRAPA #3 */
-};
-
-int h8300_enable_irq_pin(unsigned int irq)
-{
- int bitmask;
- if (irq < EXT_IRQ0 || irq > EXT_IRQ5)
- return 0;
-
- /* initialize IRQ pin */
- bitmask = 1 << (irq - EXT_IRQ0);
- switch(irq) {
- case EXT_IRQ0:
- case EXT_IRQ1:
- case EXT_IRQ2:
- case EXT_IRQ3:
- if (H8300_GPIO_RESERVE(H8300_GPIO_P8, bitmask) == 0)
- return -EBUSY;
- H8300_GPIO_DDR(H8300_GPIO_P8, bitmask, H8300_GPIO_INPUT);
- break;
- case EXT_IRQ4:
- case EXT_IRQ5:
- if (H8300_GPIO_RESERVE(H8300_GPIO_P9, bitmask) == 0)
- return -EBUSY;
- H8300_GPIO_DDR(H8300_GPIO_P9, bitmask, H8300_GPIO_INPUT);
- break;
- }
-
- return 0;
-}
-
-void h8300_disable_irq_pin(unsigned int irq)
-{
- int bitmask;
- if (irq < EXT_IRQ0 || irq > EXT_IRQ5)
- return;
-
- /* disable interrupt & release IRQ pin */
- bitmask = 1 << (irq - EXT_IRQ0);
- switch(irq) {
- case EXT_IRQ0:
- case EXT_IRQ1:
- case EXT_IRQ2:
- case EXT_IRQ3:
- *(volatile unsigned char *)IER &= ~bitmask;
- H8300_GPIO_FREE(H8300_GPIO_P8, bitmask);
- break ;
- case EXT_IRQ4:
- case EXT_IRQ5:
- *(volatile unsigned char *)IER &= ~bitmask;
- H8300_GPIO_FREE(H8300_GPIO_P9, bitmask);
- break;
- }
-}
diff --git a/arch/h8300/platform/h8s/entry.S b/arch/h8300/platform/h8s/entry.S
index aeb2e9faa9b..f3d6b8e8f95 100644
--- a/arch/h8300/platform/h8s/entry.S
+++ b/arch/h8300/platform/h8s/entry.S
@@ -31,12 +31,13 @@
mov.l er0,@-sp
stc ccr,r0l /* check kernel mode */
- orc #0x10,ccr
btst #4,r0l
bne 5f
- mov.l sp,@SYMBOL_NAME(sw_usp) /* user mode */
- mov.l @sp,er0
+ /* user mode */
+ mov.l sp,@SYMBOL_NAME(sw_usp)
+ mov.l @sp,er0 /* restore saved er0 */
+ orc #0x10,ccr /* switch kernel stack */
mov.l @SYMBOL_NAME(sw_ksp),sp
sub.l #(LRET-LORIG),sp /* allocate LORIG - LRET */
stm.l er0-er3,@-sp
@@ -55,8 +56,9 @@
mov.l er0,@(LER0-LER3:16,sp) /* copy ER0 */
bra 6f
5:
- mov.l @sp,er0 /* kernel mode */
- subs #2,sp /* dummy ccr */
+ /* kernel mode */
+ mov.l @sp,er0 /* restore saved er0 */
+ subs #2,sp /* set dummy ccr */
stm.l er0-er3,@-sp
mov.w @(LRET-LER3:16,sp),r1 /* copy old ccr */
mov.b r1h,r1l
@@ -94,6 +96,7 @@
mov.l @sp+,er1
add.l #(LRET-LER1),sp /* remove LORIG - LRET */
mov.l sp,@SYMBOL_NAME(sw_ksp)
+ andc #0xef,ccr /* switch to user mode */
mov.l er0,sp
bra 8f
7:
@@ -173,9 +176,6 @@ SYMBOL_NAME_LABEL(interrupt_entry)
SYMBOL_NAME_LABEL(system_call)
subs #4,sp /* dummy LVEC */
SAVE_ALL
- mov.w @(LCCR:16,sp),r1
- bset #4,r1l
- ldc r1l,ccr /* restore ccr */
mov.l er0,er4
mov.l #-ENOSYS,er0
mov.l er0,@(LER0:16,sp)
@@ -198,6 +198,7 @@ SYMBOL_NAME_LABEL(system_call)
mov.l @(LER1:16,sp),er0
mov.l @(LER2:16,sp),er1
mov.l @(LER3:16,sp),er2
+ andc #0x7f,ccr
jsr @er4
mov.l er0,@(LER0:16,sp) /* save the return value */
#if defined(CONFIG_SYSCALL_PRINT)
diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig
index a9af760c7e5..64ad10f984a 100644
--- a/arch/i386/Kconfig
+++ b/arch/i386/Kconfig
@@ -79,6 +79,10 @@ config ARCH_MAY_HAVE_PC_FDC
bool
default y
+config ARCH_USES_SLAB_PAGE_STRUCT
+ bool
+ default y
+
config DMI
bool
default y
diff --git a/arch/i386/kernel/alternative.c b/arch/i386/kernel/alternative.c
index e5cec6685cc..d8cda14fff8 100644
--- a/arch/i386/kernel/alternative.c
+++ b/arch/i386/kernel/alternative.c
@@ -390,8 +390,8 @@ void __init alternative_instructions(void)
_text, _etext);
}
free_init_pages("SMP alternatives",
- __pa_symbol(&__smp_locks),
- __pa_symbol(&__smp_locks_end));
+ (unsigned long)__smp_locks,
+ (unsigned long)__smp_locks_end);
} else {
alternatives_smp_module_add(NULL, "core kernel",
__smp_locks, __smp_locks_end,
diff --git a/arch/i386/mm/hugetlbpage.c b/arch/i386/mm/hugetlbpage.c
index 34728e4afe4..6272a4fd9e7 100644
--- a/arch/i386/mm/hugetlbpage.c
+++ b/arch/i386/mm/hugetlbpage.c
@@ -367,6 +367,12 @@ hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
if (len > TASK_SIZE)
return -ENOMEM;
+ if (flags & MAP_FIXED) {
+ if (prepare_hugepage_range(addr, len, pgoff))
+ return -EINVAL;
+ return addr;
+ }
+
if (addr) {
addr = ALIGN(addr, HPAGE_SIZE);
vma = find_vma(mm, addr);
diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c
index dbe16f63a56..1a7197e89eb 100644
--- a/arch/i386/mm/init.c
+++ b/arch/i386/mm/init.c
@@ -843,11 +843,10 @@ void free_init_pages(char *what, unsigned long begin, unsigned long end)
unsigned long addr;
for (addr = begin; addr < end; addr += PAGE_SIZE) {
- struct page *page = pfn_to_page(addr >> PAGE_SHIFT);
- ClearPageReserved(page);
- init_page_count(page);
- memset(page_address(page), POISON_FREE_INITMEM, PAGE_SIZE);
- __free_page(page);
+ ClearPageReserved(virt_to_page(addr));
+ init_page_count(virt_to_page(addr));
+ memset((void *)addr, POISON_FREE_INITMEM, PAGE_SIZE);
+ free_page(addr);
totalram_pages++;
}
printk(KERN_INFO "Freeing %s: %luk freed\n", what, (end - begin) >> 10);
@@ -856,14 +855,14 @@ void free_init_pages(char *what, unsigned long begin, unsigned long end)
void free_initmem(void)
{
free_init_pages("unused kernel memory",
- __pa_symbol(&__init_begin),
- __pa_symbol(&__init_end));
+ (unsigned long)(&__init_begin),
+ (unsigned long)(&__init_end));
}
#ifdef CONFIG_BLK_DEV_INITRD
void free_initrd_mem(unsigned long start, unsigned long end)
{
- free_init_pages("initrd memory", __pa(start), __pa(end));
+ free_init_pages("initrd memory", start, end);
}
#endif
diff --git a/arch/ia64/kernel/sys_ia64.c b/arch/ia64/kernel/sys_ia64.c
index 9ef62a3fbfa..2fcaa2051aa 100644
--- a/arch/ia64/kernel/sys_ia64.c
+++ b/arch/ia64/kernel/sys_ia64.c
@@ -33,6 +33,13 @@ arch_get_unmapped_area (struct file *filp, unsigned long addr, unsigned long len
if (len > RGN_MAP_LIMIT)
return -ENOMEM;
+ /* handle fixed mapping: prevent overlap with huge pages */
+ if (flags & MAP_FIXED) {
+ if (is_hugepage_only_range(mm, addr, len))
+ return -EINVAL;
+ return addr;
+ }
+
#ifdef CONFIG_HUGETLB_PAGE
if (REGION_NUMBER(addr) == RGN_HPAGE)
addr = 0;
diff --git a/arch/ia64/mm/hugetlbpage.c b/arch/ia64/mm/hugetlbpage.c
index 0c7e94edc20..c7c90f4f429 100644
--- a/arch/ia64/mm/hugetlbpage.c
+++ b/arch/ia64/mm/hugetlbpage.c
@@ -148,6 +148,14 @@ unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr, u
return -ENOMEM;
if (len & ~HPAGE_MASK)
return -EINVAL;
+
+ /* Handle MAP_FIXED */
+ if (flags & MAP_FIXED) {
+ if (prepare_hugepage_range(addr, len, pgoff))
+ return -EINVAL;
+ return addr;
+ }
+
/* This code assumes that RGN_HPAGE != 0. */
if ((REGION_NUMBER(addr) != RGN_HPAGE) || (addr & (HPAGE_SIZE - 1)))
addr = HPAGE_REGION_BASE;
diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c
index 4f36987eea7..2da84111072 100644
--- a/arch/ia64/mm/init.c
+++ b/arch/ia64/mm/init.c
@@ -121,7 +121,7 @@ lazy_mmu_prot_update (pte_t pte)
return; /* i-cache is already coherent with d-cache */
if (PageCompound(page)) {
- order = (unsigned long) (page[1].lru.prev);
+ order = compound_order(page);
flush_icache_range(addr, addr + (1UL << order << PAGE_SHIFT));
}
else
diff --git a/arch/m68k/amiga/amiints.c b/arch/m68k/amiga/amiints.c
index 28d95cfe8ac..907a5533c84 100644
--- a/arch/m68k/amiga/amiints.c
+++ b/arch/m68k/amiga/amiints.c
@@ -54,7 +54,7 @@ static irqreturn_t ami_int5(int irq, void *dev_id);
static struct irq_controller amiga_irq_controller = {
.name = "amiga",
- .lock = SPIN_LOCK_UNLOCKED,
+ .lock = __SPIN_LOCK_UNLOCKED(amiga_irq_controller.lock),
.enable = amiga_enable_irq,
.disable = amiga_disable_irq,
};
diff --git a/arch/m68k/amiga/cia.c b/arch/m68k/amiga/cia.c
index 7a20058eb38..c4a4ffd45bc 100644
--- a/arch/m68k/amiga/cia.c
+++ b/arch/m68k/amiga/cia.c
@@ -123,7 +123,7 @@ static void cia_disable_irq(unsigned int irq)
static struct irq_controller cia_irq_controller = {
.name = "cia",
- .lock = SPIN_LOCK_UNLOCKED,
+ .lock = __SPIN_LOCK_UNLOCKED(cia_irq_controller.lock),
.enable = cia_enable_irq,
.disable = cia_disable_irq,
};
@@ -160,7 +160,7 @@ static void auto_disable_irq(unsigned int irq)
static struct irq_controller auto_irq_controller = {
.name = "auto",
- .lock = SPIN_LOCK_UNLOCKED,
+ .lock = __SPIN_LOCK_UNLOCKED(auto_irq_controller.lock),
.enable = auto_enable_irq,
.disable = auto_disable_irq,
};
diff --git a/arch/m68k/apollo/dn_ints.c b/arch/m68k/apollo/dn_ints.c
index 4274af12599..13bd41bed28 100644
--- a/arch/m68k/apollo/dn_ints.c
+++ b/arch/m68k/apollo/dn_ints.c
@@ -31,7 +31,7 @@ void apollo_irq_shutdown(unsigned int irq)
static struct irq_controller apollo_irq_controller = {
.name = "apollo",
- .lock = SPIN_LOCK_UNLOCKED,
+ .lock = __SPIN_LOCK_UNLOCKED(apollo_irq_controller.lock),
.startup = apollo_irq_startup,
.shutdown = apollo_irq_shutdown,
};
diff --git a/arch/m68k/atari/ataints.c b/arch/m68k/atari/ataints.c
index 7f812641790..b85ca22024c 100644
--- a/arch/m68k/atari/ataints.c
+++ b/arch/m68k/atari/ataints.c
@@ -339,7 +339,7 @@ static void atari_shutdown_irq(unsigned int irq)
static struct irq_controller atari_irq_controller = {
.name = "atari",
- .lock = SPIN_LOCK_UNLOCKED,
+ .lock = __SPIN_LOCK_UNLOCKED(atari_irq_controller.lock),
.startup = atari_startup_irq,
.shutdown = atari_shutdown_irq,
.enable = atari_enable_irq,
diff --git a/arch/m68k/atari/atasound.h b/arch/m68k/atari/atasound.h
deleted file mode 100644
index 1362762b8c0..00000000000
--- a/arch/m68k/atari/atasound.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Minor numbers for the sound driver.
- *
- * Unfortunately Creative called the codec chip of SB as a DSP. For this
- * reason the /dev/dsp is reserved for digitized audio use. There is a
- * device for true DSP processors but it will be called something else.
- * In v3.0 it's /dev/sndproc but this could be a temporary solution.
- */
-
-#define SND_NDEVS 256 /* Number of supported devices */
-#define SND_DEV_CTL 0 /* Control port /dev/mixer */
-#define SND_DEV_SEQ 1 /* Sequencer output /dev/sequencer (FM
- synthesizer and MIDI output) */
-#define SND_DEV_MIDIN 2 /* Raw midi access */
-#define SND_DEV_DSP 3 /* Digitized voice /dev/dsp */
-#define SND_DEV_AUDIO 4 /* Sparc compatible /dev/audio */
-#define SND_DEV_DSP16 5 /* Like /dev/dsp but 16 bits/sample */
-#define SND_DEV_STATUS 6 /* /dev/sndstat */
-/* #7 not in use now. Was in 2.4. Free for use after v3.0. */
-#define SND_DEV_SEQ2 8 /* /dev/sequencer, level 2 interface */
-#define SND_DEV_SNDPROC 9 /* /dev/sndproc for programmable devices */
-#define SND_DEV_PSS SND_DEV_SNDPROC
-
-#define DSP_DEFAULT_SPEED 8000
-
-#define ON 1
-#define OFF 0
-
-#define MAX_AUDIO_DEV 5
-#define MAX_MIXER_DEV 2
-#define MAX_SYNTH_DEV 3
-#define MAX_MIDI_DEV 6
-#define MAX_TIMER_DEV 3
diff --git a/arch/m68k/kernel/ints.c b/arch/m68k/kernel/ints.c
index b66c97c904b..60d4d75f579 100644
--- a/arch/m68k/kernel/ints.c
+++ b/arch/m68k/kernel/ints.c
@@ -59,14 +59,14 @@ static int m68k_first_user_vec;
static struct irq_controller auto_irq_controller = {
.name = "auto",
- .lock = SPIN_LOCK_UNLOCKED,
+ .lock = __SPIN_LOCK_UNLOCKED(auto_irq_controller.lock),
.startup = m68k_irq_startup,
.shutdown = m68k_irq_shutdown,
};
static struct irq_controller user_irq_controller = {
.name = "user",
- .lock = SPIN_LOCK_UNLOCKED,
+ .lock = __SPIN_LOCK_UNLOCKED(user_irq_controller.lock),
.startup = m68k_irq_startup,
.shutdown = m68k_irq_shutdown,
};
diff --git a/arch/m68k/mac/macints.c b/arch/m68k/mac/macints.c
index f6fcd754d8f..0fc72d8f786 100644
--- a/arch/m68k/mac/macints.c
+++ b/arch/m68k/mac/macints.c
@@ -219,7 +219,7 @@ static void mac_disable_irq(unsigned int irq);
static struct irq_controller mac_irq_controller = {
.name = "mac",
- .lock = SPIN_LOCK_UNLOCKED,
+ .lock = __SPIN_LOCK_UNLOCKED(mac_irq_controller.lock),
.enable = mac_enable_irq,
.disable = mac_disable_irq,
};
diff --git a/arch/m68k/q40/q40ints.c b/arch/m68k/q40/q40ints.c
index 31cc07d8cec..2fb25ae46a8 100644
--- a/arch/m68k/q40/q40ints.c
+++ b/arch/m68k/q40/q40ints.c
@@ -59,7 +59,7 @@ static void q40_irq_shutdown(unsigned int irq)
static struct irq_controller q40_irq_controller = {
.name = "q40",
- .lock = SPIN_LOCK_UNLOCKED,
+ .lock = __SPIN_LOCK_UNLOCKED(q40_irq_controller.lock),
.startup = q40_irq_startup,
.shutdown = q40_irq_shutdown,
.enable = q40_enable_irq,
diff --git a/arch/m68k/sun3/sun3ints.c b/arch/m68k/sun3/sun3ints.c
index 4232a2c2fae..50df34bf80e 100644
--- a/arch/m68k/sun3/sun3ints.c
+++ b/arch/m68k/sun3/sun3ints.c
@@ -90,7 +90,7 @@ static void sun3_inthandle(unsigned int irq, struct pt_regs *fp)
static struct irq_controller sun3_irq_controller = {
.name = "sun3",
- .lock = SPIN_LOCK_UNLOCKED,
+ .lock = __SPIN_LOCK_UNLOCKED(sun3_irq_controller.lock),
.startup = m68k_irq_startup,
.shutdown = m68k_irq_shutdown,
.enable = sun3_enable_irq,
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 130d825e543..7441a2cf523 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -1042,6 +1042,9 @@ config SOC_AU1X00
select SYS_SUPPORTS_APM_EMULATION
select SYS_SUPPORTS_KGDB
+config SERIAL_RM9000
+ bool
+
config PNX8550
bool
select SOC_PNX8550
diff --git a/arch/mips/pmc-sierra/msp71xx/msp_serial.c b/arch/mips/pmc-sierra/msp71xx/msp_serial.c
new file mode 100644
index 00000000000..c41b53faa8f
--- /dev/null
+++ b/arch/mips/pmc-sierra/msp71xx/msp_serial.c
@@ -0,0 +1,165 @@
+/*
+ * The setup file for serial related hardware on PMC-Sierra MSP processors.
+ *
+ * Copyright 2005 PMC-Sierra, Inc.
+ *
+ * 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, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/serial.h>
+#include <linux/serial_core.h>
+#include <linux/serial_reg.h>
+
+#include <asm/bootinfo.h>
+#include <asm/io.h>
+#include <asm/processor.h>
+#include <asm/serial.h>
+
+#include <msp_prom.h>
+#include <msp_int.h>
+#include <msp_regs.h>
+
+#ifdef CONFIG_KGDB
+/*
+ * kgdb uses serial port 1 so the console can remain on port 0.
+ * To use port 0 change the definition to read as follows:
+ * #define DEBUG_PORT_BASE KSEG1ADDR(MSP_UART0_BASE)
+ */
+#define DEBUG_PORT_BASE KSEG1ADDR(MSP_UART1_BASE)
+
+int putDebugChar(char c)
+{
+ volatile uint32_t *uart = (volatile uint32_t *)DEBUG_PORT_BASE;
+ uint32_t val = (uint32_t)c;
+
+ local_irq_disable();
+ while( !(uart[5] & 0x20) ); /* Wait for TXRDY */
+ uart[0] = val;
+ while( !(uart[5] & 0x20) ); /* Wait for TXRDY */
+ local_irq_enable();
+
+ return 1;
+}
+
+char getDebugChar(void)
+{
+ volatile uint32_t *uart = (volatile uint32_t *)DEBUG_PORT_BASE;
+ uint32_t val;
+
+ while( !(uart[5] & 0x01) ); /* Wait for RXRDY */
+ val = uart[0];
+
+ return (char)val;
+}
+
+void initDebugPort(unsigned int uartclk, unsigned int baudrate)
+{
+ unsigned int baud_divisor = (uartclk + 8 * baudrate)/(16 * baudrate);
+
+ /* Enable FIFOs */
+ writeb(UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR |
+ UART_FCR_CLEAR_XMIT | UART_FCR_TRIGGER_4,
+ (char *)DEBUG_PORT_BASE + (UART_FCR * 4));
+
+ /* Select brtc divisor */
+ writeb(UART_LCR_DLAB, (char *)DEBUG_PORT_BASE + (UART_LCR * 4));
+
+ /* Store divisor lsb */
+ writeb(baud_divisor, (char *)DEBUG_PORT_BASE + (UART_TX * 4));
+
+ /* Store divisor msb */
+ writeb(baud_divisor >> 8, (char *)DEBUG_PORT_BASE + (UART_IER * 4));
+
+ /* Set 8N1 mode */
+ writeb(UART_LCR_WLEN8, (char *)DEBUG_PORT_BASE + (UART_LCR * 4));
+
+ /* Disable flow control */
+ writeb(0, (char *)DEBUG_PORT_BASE + (UART_MCR * 4));
+
+ /* Disable receive interrupt(!) */
+ writeb(0, (char *)DEBUG_PORT_BASE + (UART_IER * 4));
+}
+#endif
+
+void __init msp_serial_setup(void)
+{
+ char *s;
+ char *endp;
+ struct uart_port up;
+ unsigned int uartclk;
+
+ memset(&up, 0, sizeof(up));
+
+ /* Check if clock was specified in environment */
+ s = prom_getenv("uartfreqhz");
+ if(!(s && *s && (uartclk = simple_strtoul(s, &endp, 10)) && *endp == 0))
+ uartclk = MSP_BASE_BAUD;
+ ppfinit("UART clock set to %d\n", uartclk);
+
+ /* Initialize first serial port */
+ up.mapbase = MSP_UART0_BASE;
+ up.membase = ioremap_nocache(up.mapbase,MSP_UART_REG_LEN);
+ up.irq = MSP_INT_UART0;
+ up.uartclk = uartclk;
+ up.regshift = 2;
+ up.iotype = UPIO_DWAPB; /* UPIO_MEM like */
+ up.flags = STD_COM_FLAGS;
+ up.type = PORT_16550A;
+ up.line = 0;
+ up.private_data = (void*)UART0_STATUS_REG;
+ if (early_serial_setup(&up))
+ printk(KERN_ERR "Early serial init of port 0 failed\n");
+
+ /* Initialize the second serial port, if one exists */
+ switch (mips_machtype) {
+ case MACH_MSP4200_EVAL:
+ case MACH_MSP4200_GW:
+ case MACH_MSP4200_FPGA:
+ case MACH_MSP7120_EVAL:
+ case MACH_MSP7120_GW:
+ case MACH_MSP7120_FPGA:
+ /* Enable UART1 on MSP4200 and MSP7120 */
+ *GPIO_CFG2_REG = 0x00002299;
+
+#ifdef CONFIG_KGDB
+ /* Initialize UART1 for kgdb since PMON doesn't */
+ if( DEBUG_PORT_BASE == KSEG1ADDR(MSP_UART1_BASE) ) {
+ if( mips_machtype == MACH_MSP4200_FPGA
+ || mips_machtype == MACH_MSP7120_FPGA )
+ initDebugPort(uartclk,19200);
+ else
+ initDebugPort(uartclk,57600);
+ }
+#endif
+ break;
+
+ default:
+ return; /* No second serial port, good-bye. */
+ }
+
+ up.mapbase = MSP_UART1_BASE;
+ up.membase = ioremap_nocache(up.mapbase,MSP_UART_REG_LEN);
+ up.irq = MSP_INT_UART1;
+ up.line = 1;
+ up.private_data = (void*)UART1_STATUS_REG;
+ if (early_serial_setup(&up))
+ printk(KERN_ERR "Early serial init of port 1 failed\n");
+}
diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c
index 512642d8f70..6fed0803c59 100644
--- a/arch/parisc/kernel/sys_parisc.c
+++ b/arch/parisc/kernel/sys_parisc.c
@@ -106,6 +106,11 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
{
if (len > TASK_SIZE)
return -ENOMEM;
+ /* Might want to check for cache aliasing issues for MAP_FIXED case
+ * like ARM or MIPS ??? --BenH.
+ */
+ if (flags & MAP_FIXED)
+ return addr;
if (!addr)
addr = TASK_UNMAPPED_BASE;
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index a54a9a2e36f..8de5f9ff4ad 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -117,6 +117,19 @@ config GENERIC_BUG
default y
depends on BUG
+#
+# Powerpc uses the slab allocator to manage its ptes and the
+# page structs of ptes are used for splitting the page table
+# lock for configurations supporting more than SPLIT_PTLOCK_CPUS.
+#
+# In that special configuration the page structs of slabs are modified.
+# This setting disables the selection of SLUB as a slab allocator.
+#
+config ARCH_USES_SLAB_PAGE_STRUCT
+ bool
+ default y
+ depends on SPLIT_PTLOCK_CPUS <= NR_CPUS
+
config DEFAULT_UIMAGE
bool
help
diff --git a/arch/powerpc/kernel/legacy_serial.c b/arch/powerpc/kernel/legacy_serial.c
index 63dd2c3ad95..ae4836ea744 100644
--- a/arch/powerpc/kernel/legacy_serial.c
+++ b/arch/powerpc/kernel/legacy_serial.c
@@ -115,7 +115,8 @@ static int __init add_legacy_soc_port(struct device_node *np,
{
u64 addr;
const u32 *addrp;
- upf_t flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ;
+ upf_t flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ
+ | UPF_FIXED_PORT;
struct device_node *tsi = of_get_parent(np);
/* We only support ports that have a clock frequency properly
diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c
index 8508f973d9c..1f07f70ac89 100644
--- a/arch/powerpc/mm/hugetlbpage.c
+++ b/arch/powerpc/mm/hugetlbpage.c
@@ -566,6 +566,13 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
if (len > TASK_SIZE)
return -ENOMEM;
+ /* handle fixed mapping: prevent overlap with huge pages */
+ if (flags & MAP_FIXED) {
+ if (is_hugepage_only_range(mm, addr, len))
+ return -EINVAL;
+ return addr;
+ }
+
if (addr) {
addr = PAGE_ALIGN(addr);
vma = find_vma(mm, addr);
@@ -641,6 +648,13 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
if (len > TASK_SIZE)
return -ENOMEM;
+ /* handle fixed mapping: prevent overlap with huge pages */
+ if (flags & MAP_FIXED) {
+ if (is_hugepage_only_range(mm, addr, len))
+ return -EINVAL;
+ return addr;
+ }
+
/* dont allow allocations above current base */
if (mm->free_area_cache > base)
mm->free_area_cache = base;
@@ -823,6 +837,13 @@ unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
/* Paranoia, caller should have dealt with this */
BUG_ON((addr + len) < addr);
+ /* Handle MAP_FIXED */
+ if (flags & MAP_FIXED) {
+ if (prepare_hugepage_range(addr, len, pgoff))
+ return -EINVAL;
+ return addr;
+ }
+
if (test_thread_flag(TIF_32BIT)) {
curareas = current->mm->context.low_htlb_areas;
@@ -1057,8 +1078,7 @@ static int __init hugetlbpage_init(void)
huge_pgtable_cache = kmem_cache_create("hugepte_cache",
HUGEPTE_TABLE_SIZE,
HUGEPTE_TABLE_SIZE,
- SLAB_HWCACHE_ALIGN |
- SLAB_MUST_HWCACHE_ALIGN,
+ 0,
zero_ctor, NULL);
if (! huge_pgtable_cache)
panic("hugetlbpage_init(): could not create hugepte cache\n");
diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c
index d12a87ec5ae..4416d5140c5 100644
--- a/arch/powerpc/mm/init_64.c
+++ b/arch/powerpc/mm/init_64.c
@@ -183,8 +183,7 @@ void pgtable_cache_init(void)
"for size: %08x...\n", name, i, size);
pgtable_cache[i] = kmem_cache_create(name,
size, size,
- SLAB_HWCACHE_ALIGN |
- SLAB_MUST_HWCACHE_ALIGN,
+ 0,
zero_ctor,
NULL);
if (! pgtable_cache[i])
diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c
index 13e4f70ec8c..a93f328a731 100644
--- a/arch/powerpc/platforms/cell/spufs/inode.c
+++ b/arch/powerpc/platforms/cell/spufs/inode.c
@@ -71,8 +71,7 @@ spufs_init_once(void *p, struct kmem_cache * cachep, unsigned long flags)
{
struct spufs_inode_info *ei = p;
- if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
- SLAB_CTOR_CONSTRUCTOR) {
+ if (flags & SLAB_CTOR_CONSTRUCTOR) {
inode_init_once(&ei->vfs_inode);
}
}
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index e6ec418093e..1a84719be26 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -49,6 +49,9 @@ config GENERIC_BUG
config NO_IOMEM
def_bool y
+config NO_DMA
+ def_bool y
+
mainmenu "Linux Kernel Configuration"
config S390
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index 4d16d891707..d74eb120a9c 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -22,6 +22,10 @@ config RWSEM_GENERIC_SPINLOCK
config RWSEM_XCHGADD_ALGORITHM
bool
+config GENERIC_BUG
+ def_bool y
+ depends on BUG
+
config GENERIC_FIND_NEXT_BIT
bool
default y
@@ -88,6 +92,14 @@ config SH_SOLUTION_ENGINE
Select SolutionEngine if configuring for a Hitachi SH7709
or SH7750 evaluation board.
+config SH_7722_SOLUTION_ENGINE
+ bool "SolutionEngine7722"
+ select SOLUTION_ENGINE
+ select CPU_SUBTYPE_SH7722
+ help
+ Select 7722 SolutionEngine if configuring for a Hitachi SH772
+ evaluation board.
+
config SH_7751_SOLUTION_ENGINE
bool "SolutionEngine7751"
select SOLUTION_ENGINE
@@ -95,6 +107,14 @@ config SH_7751_SOLUTION_ENGINE
help
Select 7751 SolutionEngine if configuring for a Hitachi SH7751
evaluation board.
+
+config SH_7780_SOLUTION_ENGINE
+ bool "SolutionEngine7780"
+ select SOLUTION_ENGINE
+ select CPU_SUBTYPE_SH7780
+ help
+ Select 7780 SolutionEngine if configuring for a Renesas SH7780
+ evaluation board.
config SH_7300_SOLUTION_ENGINE
bool "SolutionEngine7300"
@@ -193,12 +213,8 @@ config SH_RTS7751R2D
Select RTS7751R2D if configuring for a Renesas Technology
Sales SH-Graphics board.
-config SH_R7780RP
- bool "R7780RP-1"
- select CPU_SUBTYPE_SH7780
- help
- Select R7780RP-1 if configuring for a Renesas Solutions
- HIGHLANDER board.
+config SH_HIGHLANDER
+ bool "Highlander"
config SH_EDOSK7705
bool "EDOSK7705"
@@ -243,6 +259,12 @@ config SH_7619_SOLUTION_ENGINE
help
Select 7619 SolutionEngine if configuring for a Hitachi SH7619
evaluation board.
+
+config SH_LBOX_RE2
+ bool "L-BOX RE2"
+ select CPU_SUBTYPE_SH7751R
+ help
+ Select L-BOX RE2 if configuring for the NTT COMWARE L-BOX RE2.
config SH_UNKNOWN
bool "BareCPU"
@@ -258,6 +280,10 @@ config SH_UNKNOWN
endchoice
+source "arch/sh/boards/renesas/hs7751rvoip/Kconfig"
+source "arch/sh/boards/renesas/rts7751r2d/Kconfig"
+source "arch/sh/boards/renesas/r7780rp/Kconfig"
+
source "arch/sh/mm/Kconfig"
config CF_ENABLER
@@ -366,6 +392,16 @@ config SH_STORE_QUEUES
Selecting this option will enable an in-kernel API for manipulating
the store queues integrated in the SH-4 processors.
+config SPECULATIVE_EXECUTION
+ bool "Speculative subroutine return"
+ depends on CPU_SUBTYPE_SH7780 && EXPERIMENTAL
+ help
+ This enables support for a speculative instruction fetch for
+ subroutine return. There are various pitfalls associated with
+ this, as outlined in the SH7780 hardware manual.
+
+ If unsure, say N.
+
config CPU_HAS_INTEVT
bool
@@ -398,8 +434,9 @@ config CPU_HAS_PTEA
endmenu
-menu "Timer support"
-depends on !GENERIC_TIME
+menu "Timer and clock configuration"
+
+if !GENERIC_TIME
config SH_TMU
bool "TMU timer support"
@@ -422,17 +459,11 @@ config SH_MTU2
help
This enables the use of the MTU2 as the system timer.
-endmenu
-
-source "arch/sh/boards/renesas/hs7751rvoip/Kconfig"
-
-source "arch/sh/boards/renesas/rts7751r2d/Kconfig"
-
-source "arch/sh/boards/renesas/r7780rp/Kconfig"
+endif
config SH_TIMER_IRQ
int
- default "28" if CPU_SUBTYPE_SH7780
+ default "28" if CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7785
default "86" if CPU_SUBTYPE_SH7619
default "140" if CPU_SUBTYPE_SH7206
default "16"
@@ -462,7 +493,8 @@ config SH_PCLK_FREQ
default "33333333" if CPU_SUBTYPE_SH7300 || CPU_SUBTYPE_SH7770 || \
CPU_SUBTYPE_SH7760 || CPU_SUBTYPE_SH7705 || \
CPU_SUBTYPE_SH7206
- default "50000000" if CPU_SUBTYPE_SH7750 || CPU_SUBTYPE_SH7780
+ default "50000000" if CPU_SUBTYPE_SH7750 || CPU_SUBTYPE_SH7780 || \
+ CPU_SUBTYPE_SH7785
default "60000000" if CPU_SUBTYPE_SH7751
default "66000000" if CPU_SUBTYPE_SH4_202
help
@@ -477,6 +509,8 @@ config SH_CLK_MD
help
MD2 - MD0 pin setting.
+endmenu
+
menu "CPU Frequency scaling"
source "drivers/cpufreq/Kconfig"
@@ -495,21 +529,6 @@ config SH_CPU_FREQ
endmenu
-source "arch/sh/drivers/dma/Kconfig"
-
-source "arch/sh/cchips/Kconfig"
-
-config HEARTBEAT
- bool "Heartbeat LED"
- depends on SH_MPC1211 || SH_SH03 || \
- SOLUTION_ENGINE || \
- SH_RTS7751R2D || SH_SH4202_MICRODEV || SH_LANDISK || \
- SH_R7780RP
- help
- Use the power-on LED on your machine as a load meter. The exact
- behavior is platform-dependent, but normally the flash frequency is
- a hyperbolic function of the 5-minute load average.
-
source "arch/sh/drivers/Kconfig"
endmenu
@@ -540,6 +559,20 @@ config KEXEC
support. As of this writing the exact hardware interface is
strongly in flux, so no good recommendation can be made.
+config CRASH_DUMP
+ bool "kernel crash dumps (EXPERIMENTAL)"
+ depends on EXPERIMENTAL
+ help
+ Generate crash dump after being started by kexec.
+ This should be normally only set in special crash dump kernels
+ which are loaded in the main kernel with kexec-tools into
+ a specially reserved region and then later executed after
+ a crash by kdump/kexec. The crash dump kernel must be compiled
+ to a memory address not used by the main kernel using
+ MEMORY_START.
+
+ For more details see Documentation/kdump/kdump.txt
+
config SMP
bool "Symmetric multi-processing support"
---help---
diff --git a/arch/sh/Kconfig.debug b/arch/sh/Kconfig.debug
index 87902e0298e..b56307294b6 100644
--- a/arch/sh/Kconfig.debug
+++ b/arch/sh/Kconfig.debug
@@ -33,6 +33,7 @@ config EARLY_SCIF_CONSOLE_PORT
default "0xffe00000" if CPU_SUBTYPE_SH7780
default "0xfffe9800" if CPU_SUBTYPE_SH7206
default "0xf8420000" if CPU_SUBTYPE_SH7619
+ default "0xa4400000" if CPU_SUBTYPE_SH7712 || CPU_SUBTYPE_SH7705
default "0xffe80000" if CPU_SH4
config EARLY_PRINTK
@@ -77,16 +78,17 @@ config 4KSTACKS
on the VM subsystem for higher order allocations. This option
will also use IRQ stacks to compensate for the reduced stackspace.
-config KGDB
+config SH_KGDB
bool "Include KGDB kernel debugger"
select FRAME_POINTER
+ select DEBUG_INFO
help
Include in-kernel hooks for kgdb, the Linux kernel source level
debugger. See <http://kgdb.sourceforge.net/> for more information.
Unless you are intending to debug the kernel, say N here.
menu "KGDB configuration options"
- depends on KGDB
+ depends on SH_KGDB
config MORE_COMPILE_OPTIONS
bool "Add any additional compile options"
@@ -103,22 +105,16 @@ config KGDB_NMI
bool "Enter KGDB on NMI"
default n
-config KGDB_THREAD
- bool "Include KGDB thread support"
- default y
-
config SH_KGDB_CONSOLE
bool "Console messages through GDB"
+ depends on !SERIAL_SH_SCI_CONSOLE
+ select SERIAL_CORE_CONSOLE
default n
config KGDB_SYSRQ
bool "Allow SysRq 'G' to enter KGDB"
default y
-config KGDB_KERNEL_ASSERTS
- bool "Include KGDB kernel assertions"
- default n
-
comment "Serial port setup"
config KGDB_DEFPORT
@@ -131,7 +127,7 @@ config KGDB_DEFBAUD
choice
prompt "Parity"
- depends on KGDB
+ depends on SH_KGDB
default KGDB_DEFPARITY_N
config KGDB_DEFPARITY_N
@@ -147,7 +143,7 @@ endchoice
choice
prompt "Data bits"
- depends on KGDB
+ depends on SH_KGDB
default KGDB_DEFBITS_8
config KGDB_DEFBITS_8
diff --git a/arch/sh/Makefile b/arch/sh/Makefile
index bd9b1729f8b..7b112241705 100644
--- a/arch/sh/Makefile
+++ b/arch/sh/Makefile
@@ -47,7 +47,6 @@ cflags-$(CONFIG_CPU_LITTLE_ENDIAN) += -ml
cflags-y += $(call as-option,-Wa$(comma)-isa=$(isa-y),) -ffreestanding
cflags-$(CONFIG_SH_DSP) += -Wa,-dsp
-cflags-$(CONFIG_SH_KGDB) += -g
cflags-$(CONFIG_MORE_COMPILE_OPTIONS) += \
$(shell echo $(CONFIG_COMPILE_OPTIONS) | sed -e 's/"//g')
@@ -89,7 +88,9 @@ core-$(CONFIG_SH_FPU_EMU) += arch/sh/math-emu/
# Boards
machdir-$(CONFIG_SH_SOLUTION_ENGINE) := se/770x
+machdir-$(CONFIG_SH_7722_SOLUTION_ENGINE) := se/7722
machdir-$(CONFIG_SH_7751_SOLUTION_ENGINE) := se/7751
+machdir-$(CONFIG_SH_7780_SOLUTION_ENGINE) := se/7780
machdir-$(CONFIG_SH_7300_SOLUTION_ENGINE) := se/7300
machdir-$(CONFIG_SH_7343_SOLUTION_ENGINE) := se/7343
machdir-$(CONFIG_SH_73180_SOLUTION_ENGINE) := se/73180
@@ -103,7 +104,7 @@ machdir-$(CONFIG_SH_HS7751RVOIP) := renesas/hs7751rvoip
machdir-$(CONFIG_SH_RTS7751R2D) := renesas/rts7751r2d
machdir-$(CONFIG_SH_7751_SYSTEMH) := renesas/systemh
machdir-$(CONFIG_SH_EDOSK7705) := renesas/edosk7705
-machdir-$(CONFIG_SH_R7780RP) := renesas/r7780rp
+machdir-$(CONFIG_SH_HIGHLANDER) := renesas/r7780rp
machdir-$(CONFIG_SH_7710VOIPGW) := renesas/sh7710voipgw
machdir-$(CONFIG_SH_SH4202_MICRODEV) := superh/microdev
machdir-$(CONFIG_SH_LANDISK) := landisk
@@ -111,6 +112,7 @@ machdir-$(CONFIG_SH_TITAN) := titan
machdir-$(CONFIG_SH_SHMIN) := shmin
machdir-$(CONFIG_SH_7206_SOLUTION_ENGINE) := se/7206
machdir-$(CONFIG_SH_7619_SOLUTION_ENGINE) := se/7619
+machdir-$(CONFIG_SH_LBOX_RE2) := lboxre2
machdir-$(CONFIG_SH_UNKNOWN) := unknown
incdir-y := $(notdir $(machdir-y))
diff --git a/arch/sh/boards/hp6xx/Makefile b/arch/sh/boards/hp6xx/Makefile
index ff1b7f5b4e9..b3124278247 100644
--- a/arch/sh/boards/hp6xx/Makefile
+++ b/arch/sh/boards/hp6xx/Makefile
@@ -2,6 +2,6 @@
# Makefile for the HP6xx specific parts of the kernel
#
-obj-y := setup.o
+obj-y := setup.o
obj-$(CONFIG_PM) += pm.o pm_wakeup.o
-obj-$(CONFIG_APM) += hp6xx_apm.o
+obj-$(CONFIG_APM_EMULATION) += hp6xx_apm.o
diff --git a/arch/sh/boards/hp6xx/setup.c b/arch/sh/boards/hp6xx/setup.c
index b5a96649ed2..6aeee85c978 100644
--- a/arch/sh/boards/hp6xx/setup.c
+++ b/arch/sh/boards/hp6xx/setup.c
@@ -2,6 +2,7 @@
* linux/arch/sh/boards/hp6xx/setup.c
*
* Copyright (C) 2002 Andriy Skulysh
+ * Copyright (C) 2007 Kristoffer Ericson <Kristoffer_e1@hotmail.com>
*
* May be copied or modified under the terms of the GNU General Public
* License. See linux/COPYING for more information.
@@ -10,6 +11,7 @@
*/
#include <linux/types.h>
#include <linux/init.h>
+#include <linux/platform_device.h>
#include <asm/hd64461.h>
#include <asm/io.h>
#include <asm/irq.h>
@@ -19,6 +21,40 @@
#define SCPCR 0xa4000116
#define SCPDR 0xa4000136
+/* CF Slot */
+static struct resource cf_ide_resources[] = {
+ [0] = {
+ .start = 0x15000000 + 0x1f0,
+ .end = 0x15000000 + 0x1f0 + 0x08 - 0x01,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 0x15000000 + 0x1fe,
+ .end = 0x15000000 + 0x1fe + 0x01,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = {
+ .start = 93,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device cf_ide_device = {
+ .name = "pata_platform",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(cf_ide_resources),
+ .resource = cf_ide_resources,
+};
+
+static struct platform_device *hp6xx_devices[] __initdata = {
+ &cf_ide_device,
+};
+
+static int __init hp6xx_devices_setup(void)
+{
+ return platform_add_devices(hp6xx_devices, ARRAY_SIZE(hp6xx_devices));
+}
+
static void __init hp6xx_setup(char **cmdline_p)
{
u8 v8;
@@ -60,41 +96,12 @@ static void __init hp6xx_setup(char **cmdline_p)
v |= SCPCR_TS_ENABLE;
ctrl_outw(v, SCPCR);
}
+device_initcall(hp6xx_devices_setup);
-/*
- * XXX: This is stupid, we should have a generic machine vector for the cchips
- * and just wrap the platform setup code in to this, as it's the only thing
- * that ends up being different.
- */
struct sh_machine_vector mv_hp6xx __initmv = {
.mv_name = "hp6xx",
.mv_setup = hp6xx_setup,
.mv_nr_irqs = HD64461_IRQBASE + HD64461_IRQ_NUM,
-
- .mv_inb = hd64461_inb,
- .mv_inw = hd64461_inw,
- .mv_inl = hd64461_inl,
- .mv_outb = hd64461_outb,
- .mv_outw = hd64461_outw,
- .mv_outl = hd64461_outl,
-
- .mv_inb_p = hd64461_inb_p,
- .mv_inw_p = hd64461_inw,
- .mv_inl_p = hd64461_inl,
- .mv_outb_p = hd64461_outb_p,
- .mv_outw_p = hd64461_outw,
- .mv_outl_p = hd64461_outl,
-
- .mv_insb = hd64461_insb,
- .mv_insw = hd64461_insw,
- .mv_insl = hd64461_insl,
- .mv_outsb = hd64461_outsb,
- .mv_outsw = hd64461_outsw,
- .mv_outsl = hd64461_outsl,
-
- .mv_readw = hd64461_readw,
- .mv_writew = hd64461_writew,
-
.mv_irq_demux = hd64461_irq_demux,
};
ALIAS_MV(hp6xx)
diff --git a/arch/sh/boards/landisk/Makefile b/arch/sh/boards/landisk/Makefile
index 89e4beb2ad4..a696b4277fa 100644
--- a/arch/sh/boards/landisk/Makefile
+++ b/arch/sh/boards/landisk/Makefile
@@ -2,4 +2,4 @@
# Makefile for I-O DATA DEVICE, INC. "LANDISK Series"
#
-obj-y := setup.o io.o irq.o rtc.o landisk_pwb.o
+obj-y := setup.o irq.o psw.o gio.o
diff --git a/arch/sh/boards/landisk/gio.c b/arch/sh/boards/landisk/gio.c
new file mode 100644
index 00000000000..50d38be62f0
--- /dev/null
+++ b/arch/sh/boards/landisk/gio.c
@@ -0,0 +1,167 @@
+/*
+ * arch/sh/boards/landisk/gio.c - driver for landisk
+ *
+ * This driver will also support the I-O DATA Device, Inc. LANDISK Board.
+ * LANDISK and USL-5P Button, LED and GIO driver drive function.
+ *
+ * Copylight (C) 2006 kogiidena
+ * Copylight (C) 2002 Atom Create Engineering Co., Ltd. *
+ *
+ * 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/module.h>
+#include <linux/init.h>
+#include <linux/kdev_t.h>
+#include <linux/cdev.h>
+#include <linux/fs.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/landisk/gio.h>
+#include <asm/landisk/iodata_landisk.h>
+
+#define DEVCOUNT 4
+#define GIO_MINOR 2 /* GIO minor no. */
+
+static dev_t dev;
+static struct cdev *cdev_p;
+static int openCnt;
+
+static int gio_open(struct inode *inode, struct file *filp)
+{
+ int minor;
+
+ minor = MINOR(inode->i_rdev);
+ if (minor < DEVCOUNT) {
+ if (openCnt > 0) {
+ return -EALREADY;
+ } else {
+ openCnt++;
+ return 0;
+ }
+ }
+ return -ENOENT;
+}
+
+static int gio_close(struct inode *inode, struct file *filp)
+{
+ int minor;
+
+ minor = MINOR(inode->i_rdev);
+ if (minor < DEVCOUNT) {
+ openCnt--;
+ }
+ return 0;
+}
+
+static int gio_ioctl(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
+{
+ unsigned int data;
+ static unsigned int addr = 0;
+
+ if (cmd & 0x01) { /* write */
+ if (copy_from_user(&data, (int *)arg, sizeof(int))) {
+ return -EFAULT;
+ }
+ }
+
+ switch (cmd) {
+ case GIODRV_IOCSGIOSETADDR: /* addres set */
+ addr = data;
+ break;
+
+ case GIODRV_IOCSGIODATA1: /* write byte */
+ ctrl_outb((unsigned char)(0x0ff & data), addr);
+ break;
+
+ case GIODRV_IOCSGIODATA2: /* write word */
+ if (addr & 0x01) {
+ return -EFAULT;
+ }
+ ctrl_outw((unsigned short int)(0x0ffff & data), addr);
+ break;
+
+ case GIODRV_IOCSGIODATA4: /* write long */
+ if (addr & 0x03) {
+ return -EFAULT;
+ }
+ ctrl_outl(data, addr);
+ break;
+
+ case GIODRV_IOCGGIODATA1: /* read byte */
+ data = ctrl_inb(addr);
+ break;
+
+ case GIODRV_IOCGGIODATA2: /* read word */
+ if (addr & 0x01) {
+ return -EFAULT;
+ }
+ data = ctrl_inw(addr);
+ break;
+
+ case GIODRV_IOCGGIODATA4: /* read long */
+ if (addr & 0x03) {
+ return -EFAULT;
+ }
+ data = ctrl_inl(addr);
+ break;
+ default:
+ return -EFAULT;
+ break;
+ }
+
+ if ((cmd & 0x01) == 0) { /* read */
+ if (copy_to_user((int *)arg, &data, sizeof(int))) {
+ return -EFAULT;
+ }
+ }
+ return 0;
+}
+
+static struct file_operations gio_fops = {
+ .owner = THIS_MODULE,
+ .open = gio_open, /* open */
+ .release = gio_close, /* release */
+ .ioctl = gio_ioctl, /* ioctl */
+};
+
+static int __init gio_init(void)
+{
+ int error;
+
+ printk(KERN_INFO "gio: driver initialized\n");
+
+ openCnt = 0;
+
+ if ((error = alloc_chrdev_region(&dev, 0, DEVCOUNT, "gio")) < 0) {
+ printk(KERN_ERR
+ "gio: Couldn't alloc_chrdev_region, error=%d\n",
+ error);
+ return 1;
+ }
+
+ cdev_p = cdev_alloc();
+ cdev_p->ops = &gio_fops;
+ error = cdev_add(cdev_p, dev, DEVCOUNT);
+ if (error) {
+ printk(KERN_ERR
+ "gio: Couldn't cdev_add, error=%d\n", error);
+ return 1;
+ }
+
+ return 0;
+}
+
+static void __exit gio_exit(void)
+{
+ cdev_del(cdev_p);
+ unregister_chrdev_region(dev, DEVCOUNT);
+}
+
+module_init(gio_init);
+module_exit(gio_exit);
+
+MODULE_LICENSE("GPL");
diff --git a/arch/sh/boards/landisk/io.c b/arch/sh/boards/landisk/io.c
deleted file mode 100644
index 92498b4947d..00000000000
--- a/arch/sh/boards/landisk/io.c
+++ /dev/null
@@ -1,250 +0,0 @@
-/*
- * arch/sh/boards/landisk/io.c
- *
- * Copyright (C) 2001 Ian da Silva, Jeremy Siegel
- * Based largely on io_se.c.
- *
- * I/O routine for I-O Data Device, Inc. LANDISK.
- *
- * Initial version only to support LAN access; some
- * placeholder code from io_landisk.c left in with the
- * expectation of later SuperIO and PCMCIA access.
- */
-/*
- * modifed by kogiidena
- * 2005.03.03
- */
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <asm/landisk/iodata_landisk.h>
-#include <asm/addrspace.h>
-#include <asm/io.h>
-
-extern void *area5_io_base; /* Area 5 I/O Base address */
-extern void *area6_io_base; /* Area 6 I/O Base address */
-
-static inline unsigned long port2adr(unsigned int port)
-{
- if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6)
- if (port == 0x3f6)
- return ((unsigned long)area5_io_base + 0x2c);
- else
- return ((unsigned long)area5_io_base + PA_PIDE_OFFSET +
- ((port - 0x1f0) << 1));
- else if ((0x170 <= port && port < 0x178) || port == 0x376)
- if (port == 0x376)
- return ((unsigned long)area6_io_base + 0x2c);
- else
- return ((unsigned long)area6_io_base + PA_SIDE_OFFSET +
- ((port - 0x170) << 1));
- else
- maybebadio((unsigned long)port);
-
- return port;
-}
-
-/*
- * General outline: remap really low stuff [eventually] to SuperIO,
- * stuff in PCI IO space (at or above window at pci.h:PCIBIOS_MIN_IO)
- * is mapped through the PCI IO window. Stuff with high bits (PXSEG)
- * should be way beyond the window, and is used w/o translation for
- * compatibility.
- */
-u8 landisk_inb(unsigned long port)
-{
- if (PXSEG(port))
- return ctrl_inb(port);
- else if (is_pci_ioaddr(port))
- return ctrl_inb(pci_ioaddr(port));
-
- return ctrl_inw(port2adr(port)) & 0xff;
-}
-
-u8 landisk_inb_p(unsigned long port)
-{
- u8 v;
-
- if (PXSEG(port))
- v = ctrl_inb(port);
- else if (is_pci_ioaddr(port))
- v = ctrl_inb(pci_ioaddr(port));
- else
- v = ctrl_inw(port2adr(port)) & 0xff;
-
- ctrl_delay();
-
- return v;
-}
-
-u16 landisk_inw(unsigned long port)
-{
- if (PXSEG(port))
- return ctrl_inw(port);
- else if (is_pci_ioaddr(port))
- return ctrl_inw(pci_ioaddr(port));
- else
- maybebadio(port);
-
- return 0;
-}
-
-u32 landisk_inl(unsigned long port)
-{
- if (PXSEG(port))
- return ctrl_inl(port);
- else if (is_pci_ioaddr(port))
- return ctrl_inl(pci_ioaddr(port));
- else
- maybebadio(port);
-
- return 0;
-}
-
-void landisk_outb(u8 value, unsigned long port)
-{
- if (PXSEG(port))
- ctrl_outb(value, port);
- else if (is_pci_ioaddr(port))
- ctrl_outb(value, pci_ioaddr(port));
- else
- ctrl_outw(value, port2adr(port));
-}
-
-void landisk_outb_p(u8 value, unsigned long port)
-{
- if (PXSEG(port))
- ctrl_outb(value, port);
- else if (is_pci_ioaddr(port))
- ctrl_outb(value, pci_ioaddr(port));
- else
- ctrl_outw(value, port2adr(port));
- ctrl_delay();
-}
-
-void landisk_outw(u16 value, unsigned long port)
-{
- if (PXSEG(port))
- ctrl_outw(value, port);
- else if (is_pci_ioaddr(port))
- ctrl_outw(value, pci_ioaddr(port));
- else
- maybebadio(port);
-}
-
-void landisk_outl(u32 value, unsigned long port)
-{
- if (PXSEG(port))
- ctrl_outl(value, port);
- else if (is_pci_ioaddr(port))
- ctrl_outl(value, pci_ioaddr(port));
- else
- maybebadio(port);
-}
-
-void landisk_insb(unsigned long port, void *dst, unsigned long count)
-{
- volatile u16 *p;
- u8 *buf = dst;
-
- if (PXSEG(port)) {
- while (count--)
- *buf++ = *(volatile u8 *)port;
- } else if (is_pci_ioaddr(port)) {
- volatile u8 *bp = (volatile u8 *)pci_ioaddr(port);
-
- while (count--)
- *buf++ = *bp;
- } else {
- p = (volatile u16 *)port2adr(port);
- while (count--)
- *buf++ = *p & 0xff;
- }
-}
-
-void landisk_insw(unsigned long port, void *dst, unsigned long count)
-{
- volatile u16 *p;
- u16 *buf = dst;
-
- if (PXSEG(port))
- p = (volatile u16 *)port;
- else if (is_pci_ioaddr(port))
- p = (volatile u16 *)pci_ioaddr(port);
- else
- p = (volatile u16 *)port2adr(port);
- while (count--)
- *buf++ = *p;
-}
-
-void landisk_insl(unsigned long port, void *dst, unsigned long count)
-{
- u32 *buf = dst;
-
- if (is_pci_ioaddr(port)) {
- volatile u32 *p = (volatile u32 *)pci_ioaddr(port);
-
- while (count--)
- *buf++ = *p;
- } else
- maybebadio(port);
-}
-
-void landisk_outsb(unsigned long port, const void *src, unsigned long count)
-{
- volatile u16 *p;
- const u8 *buf = src;
-
- if (PXSEG(port))
- while (count--)
- ctrl_outb(*buf++, port);
- else if (is_pci_ioaddr(port)) {
- volatile u8 *bp = (volatile u8 *)pci_ioaddr(port);
-
- while (count--)
- *bp = *buf++;
- } else {
- p = (volatile u16 *)port2adr(port);
- while (count--)
- *p = *buf++;
- }
-}
-
-void landisk_outsw(unsigned long port, const void *src, unsigned long count)
-{
- volatile u16 *p;
- const u16 *buf = src;
-
- if (PXSEG(port))
- p = (volatile u16 *)port;
- else if (is_pci_ioaddr(port))
- p = (volatile u16 *)pci_ioaddr(port);
- else
- p = (volatile u16 *)port2adr(port);
-
- while (count--)
- *p = *buf++;
-}
-
-void landisk_outsl(unsigned long port, const void *src, unsigned long count)
-{
- const u32 *buf = src;
-
- if (is_pci_ioaddr(port)) {
- volatile u32 *p = (volatile u32 *)pci_ioaddr(port);
-
- while (count--)
- *p = *buf++;
- } else
- maybebadio(port);
-}
-
-void __iomem *landisk_ioport_map(unsigned long port, unsigned int size)
-{
- if (PXSEG(port))
- return (void __iomem *)port;
- else if (is_pci_ioaddr(port))
- return (void __iomem *)pci_ioaddr(port);
-
- return (void __iomem *)port2adr(port);
-}
diff --git a/arch/sh/boards/landisk/irq.c b/arch/sh/boards/landisk/irq.c
index 3eba6d086d7..258649491d4 100644
--- a/arch/sh/boards/landisk/irq.c
+++ b/arch/sh/boards/landisk/irq.c
@@ -1,18 +1,16 @@
/*
* arch/sh/boards/landisk/irq.c
*
+ * I-O DATA Device, Inc. LANDISK Support
+ *
+ * Copyright (C) 2005-2007 kogiidena
+ *
* Copyright (C) 2001 Ian da Silva, Jeremy Siegel
* Based largely on io_se.c.
*
- * I/O routine for I-O Data Device, Inc. LANDISK.
- *
- * Initial version only to support LAN access; some
- * placeholder code from io_landisk.c left in with the
- * expectation of later SuperIO and PCMCIA access.
- */
-/*
- * modified by kogiidena
- * 2005.03.03
+ * 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/irq.h>
@@ -20,71 +18,27 @@
#include <linux/io.h>
#include <asm/landisk/iodata_landisk.h>
-static void enable_landisk_irq(unsigned int irq);
-static void disable_landisk_irq(unsigned int irq);
-
-/* shutdown is same as "disable" */
-#define shutdown_landisk_irq disable_landisk_irq
-
-static void ack_landisk_irq(unsigned int irq);
-static void end_landisk_irq(unsigned int irq);
-
-static unsigned int startup_landisk_irq(unsigned int irq)
-{
- enable_landisk_irq(irq);
- return 0; /* never anything pending */
-}
-
static void disable_landisk_irq(unsigned int irq)
{
- unsigned char val;
unsigned char mask = 0xff ^ (0x01 << (irq - 5));
- /* Set the priority in IPR to 0 */
- val = ctrl_inb(PA_IMASK);
- val &= mask;
- ctrl_outb(val, PA_IMASK);
+ ctrl_outb(ctrl_inb(PA_IMASK) & mask, PA_IMASK);
}
static void enable_landisk_irq(unsigned int irq)
{
- unsigned char val;
unsigned char value = (0x01 << (irq - 5));
- /* Set priority in IPR back to original value */
- val = ctrl_inb(PA_IMASK);
- val |= value;
- ctrl_outb(val, PA_IMASK);
-}
-
-static void ack_landisk_irq(unsigned int irq)
-{
- disable_landisk_irq(irq);
-}
-
-static void end_landisk_irq(unsigned int irq)
-{
- if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
- enable_landisk_irq(irq);
+ ctrl_outb(ctrl_inb(PA_IMASK) | value, PA_IMASK);
}
-static struct hw_interrupt_type landisk_irq_type = {
- .typename = "LANDISK IRQ",
- .startup = startup_landisk_irq,
- .shutdown = shutdown_landisk_irq,
- .enable = enable_landisk_irq,
- .disable = disable_landisk_irq,
- .ack = ack_landisk_irq,
- .end = end_landisk_irq
+static struct irq_chip landisk_irq_chip __read_mostly = {
+ .name = "LANDISK",
+ .mask = disable_landisk_irq,
+ .unmask = enable_landisk_irq,
+ .mask_ack = disable_landisk_irq,
};
-static void make_landisk_irq(unsigned int irq)
-{
- disable_irq_nosync(irq);
- irq_desc[irq].chip = &landisk_irq_type;
- disable_landisk_irq(irq);
-}
-
/*
* Initialize IRQ setting
*/
@@ -92,6 +46,11 @@ void __init init_landisk_IRQ(void)
{
int i;
- for (i = 5; i < 14; i++)
- make_landisk_irq(i);
+ for (i = 5; i < 14; i++) {
+ disable_irq_nosync(i);
+ set_irq_chip_and_handler_name(i, &landisk_irq_chip,
+ handle_level_irq, "level");
+ enable_landisk_irq(i);
+ }
+ ctrl_outb(0x00, PA_PWRINT_CLR);
}
diff --git a/arch/sh/boards/landisk/landisk_pwb.c b/arch/sh/boards/landisk/landisk_pwb.c
deleted file mode 100644
index 47a63c6617e..00000000000
--- a/arch/sh/boards/landisk/landisk_pwb.c
+++ /dev/null
@@ -1,346 +0,0 @@
-/*
- * arch/sh/boards/landisk/landisk_pwb.c -- driver for the Power control switch.
- *
- * This driver will also support the I-O DATA Device, Inc. LANDISK Board.
- *
- * 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.
- *
- * Copylight (C) 2002 Atom Create Engineering Co., Ltd.
- *
- * LED control drive function added by kogiidena
- */
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/signal.h>
-#include <linux/major.h>
-#include <linux/poll.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/sched.h>
-#include <linux/timer.h>
-#include <linux/interrupt.h>
-
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/uaccess.h>
-#include <asm/landisk/iodata_landisk.h>
-
-#define SHUTDOWN_BTN_MINOR 1 /* Shutdown button device minor no. */
-#define LED_MINOR 21 /* LED minor no. */
-#define BTN_MINOR 22 /* BUTTON minor no. */
-#define GIO_MINOR 40 /* GIO minor no. */
-
-static int openCnt;
-static int openCntLED;
-static int openCntGio;
-static int openCntBtn;
-static int landisk_btn;
-static int landisk_btnctrlpid;
-/*
- * Functions prototypes
- */
-
-static int gio_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
- unsigned long arg);
-
-static int swdrv_open(struct inode *inode, struct file *filp)
-{
- int minor;
-
- minor = MINOR(inode->i_rdev);
- filp->private_data = (void *)minor;
-
- if (minor == SHUTDOWN_BTN_MINOR) {
- if (openCnt > 0) {
- return -EALREADY;
- } else {
- openCnt++;
- return 0;
- }
- } else if (minor == LED_MINOR) {
- if (openCntLED > 0) {
- return -EALREADY;
- } else {
- openCntLED++;
- return 0;
- }
- } else if (minor == BTN_MINOR) {
- if (openCntBtn > 0) {
- return -EALREADY;
- } else {
- openCntBtn++;
- return 0;
- }
- } else if (minor == GIO_MINOR) {
- if (openCntGio > 0) {
- return -EALREADY;
- } else {
- openCntGio++;
- return 0;
- }
- }
- return -ENOENT;
-
-}
-
-static int swdrv_close(struct inode *inode, struct file *filp)
-{
- int minor;
-
- minor = MINOR(inode->i_rdev);
- if (minor == SHUTDOWN_BTN_MINOR) {
- openCnt--;
- } else if (minor == LED_MINOR) {
- openCntLED--;
- } else if (minor == BTN_MINOR) {
- openCntBtn--;
- } else if (minor == GIO_MINOR) {
- openCntGio--;
- }
- return 0;
-}
-
-static int swdrv_read(struct file *filp, char *buff, size_t count,
- loff_t * ppos)
-{
- int minor;
- minor = (int)(filp->private_data);
-
- if (!access_ok(VERIFY_WRITE, (void *)buff, count))
- return -EFAULT;
-
- if (minor == SHUTDOWN_BTN_MINOR) {
- if (landisk_btn & 0x10) {
- put_user(1, buff);
- return 1;
- } else {
- return 0;
- }
- }
- return 0;
-}
-
-static int swdrv_write(struct file *filp, const char *buff, size_t count,
- loff_t * ppos)
-{
- int minor;
- minor = (int)(filp->private_data);
-
- if (minor == SHUTDOWN_BTN_MINOR) {
- return count;
- }
- return count;
-}
-
-static irqreturn_t sw_interrupt(int irq, void *dev_id)
-{
- landisk_btn = (0x0ff & (~ctrl_inb(PA_STATUS)));
- disable_irq(IRQ_BUTTON);
- disable_irq(IRQ_POWER);
- ctrl_outb(0x00, PA_PWRINT_CLR);
-
- if (landisk_btnctrlpid != 0) {
- kill_proc(landisk_btnctrlpid, SIGUSR1, 1);
- landisk_btnctrlpid = 0;
- }
-
- return IRQ_HANDLED;
-}
-
-static const struct file_operations swdrv_fops = {
- .read = swdrv_read, /* read */
- .write = swdrv_write, /* write */
- .open = swdrv_open, /* open */
- .release = swdrv_close, /* release */
- .ioctl = gio_ioctl, /* ioctl */
-
-};
-
-static char banner[] __initdata =
- KERN_INFO "LANDISK and USL-5P Button, LED and GIO driver initialized\n";
-
-int __init swdrv_init(void)
-{
- int error;
-
- printk("%s", banner);
-
- openCnt = 0;
- openCntLED = 0;
- openCntBtn = 0;
- openCntGio = 0;
- landisk_btn = 0;
- landisk_btnctrlpid = 0;
-
- if ((error = register_chrdev(SHUTDOWN_BTN_MAJOR, "swdrv", &swdrv_fops))) {
- printk(KERN_ERR
- "Button, LED and GIO driver:Couldn't register driver, error=%d\n",
- error);
- return 1;
- }
-
- if (request_irq(IRQ_POWER, sw_interrupt, 0, "SHUTDOWNSWITCH", NULL)) {
- printk(KERN_ERR "Unable to get IRQ 11.\n");
- return 1;
- }
- if (request_irq(IRQ_BUTTON, sw_interrupt, 0, "USL-5P BUTTON", NULL)) {
- printk(KERN_ERR "Unable to get IRQ 12.\n");
- return 1;
- }
- ctrl_outb(0x00, PA_PWRINT_CLR);
-
- return 0;
-}
-
-module_init(swdrv_init);
-
-/*
- * gio driver
- *
- */
-
-#include <asm/landisk/gio.h>
-
-static int gio_ioctl(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
-{
- int minor;
- unsigned int data, mask;
- static unsigned int addr = 0;
-
- minor = (int)(filp->private_data);
-
- /* access control */
- if (minor == GIO_MINOR) {
- ;
- } else if (minor == LED_MINOR) {
- if (((cmd & 0x0ff) >= 9) && ((cmd & 0x0ff) < 20)) {
- ;
- } else {
- return -EINVAL;
- }
- } else if (minor == BTN_MINOR) {
- if (((cmd & 0x0ff) >= 20) && ((cmd & 0x0ff) < 30)) {
- ;
- } else {
- return -EINVAL;
- }
- } else {
- return -EINVAL;
- }
-
- if (cmd & 0x01) { /* write */
- if (copy_from_user(&data, (int *)arg, sizeof(int))) {
- return -EFAULT;
- }
- }
-
- switch (cmd) {
- case GIODRV_IOCSGIOSETADDR: /* addres set */
- addr = data;
- break;
-
- case GIODRV_IOCSGIODATA1: /* write byte */
- ctrl_outb((unsigned char)(0x0ff & data), addr);
- break;
-
- case GIODRV_IOCSGIODATA2: /* write word */
- if (addr & 0x01) {
- return -EFAULT;
- }
- ctrl_outw((unsigned short int)(0x0ffff & data), addr);
- break;
-
- case GIODRV_IOCSGIODATA4: /* write long */
- if (addr & 0x03) {
- return -EFAULT;
- }
- ctrl_outl(data, addr);
- break;
-
- case GIODRV_IOCGGIODATA1: /* read byte */
- data = ctrl_inb(addr);
- break;
-
- case GIODRV_IOCGGIODATA2: /* read word */
- if (addr & 0x01) {
- return -EFAULT;
- }
- data = ctrl_inw(addr);
- break;
-
- case GIODRV_IOCGGIODATA4: /* read long */
- if (addr & 0x03) {
- return -EFAULT;
- }
- data = ctrl_inl(addr);
- break;
- case GIODRV_IOCSGIO_LED: /* write */
- mask = ((data & 0x00ffffff) << 8)
- | ((data & 0x0000ffff) << 16)
- | ((data & 0x000000ff) << 24);
- landisk_ledparam = data & (~mask);
- if (landisk_arch == 0) { /* arch == landisk */
- landisk_ledparam &= 0x03030303;
- mask = (~(landisk_ledparam >> 22)) & 0x000c;
- landisk_ledparam |= mask;
- } else { /* arch == usl-5p */
- mask = (landisk_ledparam >> 24) & 0x0001;
- landisk_ledparam |= mask;
- landisk_ledparam &= 0x007f7f7f;
- }
- landisk_ledparam |= 0x80;
- break;
- case GIODRV_IOCGGIO_LED: /* read */
- data = landisk_ledparam;
- if (landisk_arch == 0) { /* arch == landisk */
- data &= 0x03030303;
- } else { /* arch == usl-5p */
- ;
- }
- data &= (~0x080);
- break;
- case GIODRV_IOCSGIO_BUZZER: /* write */
- landisk_buzzerparam = data;
- landisk_ledparam |= 0x80;
- break;
- case GIODRV_IOCGGIO_LANDISK: /* read */
- data = landisk_arch & 0x01;
- break;
- case GIODRV_IOCGGIO_BTN: /* read */
- data = (0x0ff & ctrl_inb(PA_PWRINT_CLR));
- data <<= 8;
- data |= (0x0ff & ctrl_inb(PA_IMASK));
- data <<= 8;
- data |= (0x0ff & landisk_btn);
- data <<= 8;
- data |= (0x0ff & (~ctrl_inb(PA_STATUS)));
- break;
- case GIODRV_IOCSGIO_BTNPID: /* write */
- landisk_btnctrlpid = data;
- landisk_btn = 0;
- if (irq_desc[IRQ_BUTTON].depth) {
- enable_irq(IRQ_BUTTON);
- }
- if (irq_desc[IRQ_POWER].depth) {
- enable_irq(IRQ_POWER);
- }
- break;
- case GIODRV_IOCGGIO_BTNPID: /* read */
- data = landisk_btnctrlpid;
- break;
- default:
- return -EFAULT;
- break;
- }
-
- if ((cmd & 0x01) == 0) { /* read */
- if (copy_to_user((int *)arg, &data, sizeof(int))) {
- return -EFAULT;
- }
- }
- return 0;
-}
diff --git a/arch/sh/boards/landisk/psw.c b/arch/sh/boards/landisk/psw.c
new file mode 100644
index 00000000000..5a9b70b5dec
--- /dev/null
+++ b/arch/sh/boards/landisk/psw.c
@@ -0,0 +1,143 @@
+/*
+ * arch/sh/boards/landisk/psw.c
+ *
+ * push switch support for LANDISK and USL-5P
+ *
+ * Copyright (C) 2006-2007 Paul Mundt
+ * Copyright (C) 2007 kogiidena
+ *
+ * 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/io.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <asm/landisk/iodata_landisk.h>
+#include <asm/push-switch.h>
+
+static irqreturn_t psw_irq_handler(int irq, void *arg)
+{
+ struct platform_device *pdev = arg;
+ struct push_switch *psw = platform_get_drvdata(pdev);
+ struct push_switch_platform_info *psw_info = pdev->dev.platform_data;
+ unsigned int sw_value;
+ int ret = 0;
+
+ sw_value = (0x0ff & (~ctrl_inb(PA_STATUS)));
+
+ /* Nothing to do if there's no state change */
+ if (psw->state) {
+ ret = 1;
+ goto out;
+ }
+
+ /* Figure out who raised it */
+ if (sw_value & (1 << psw_info->bit)) {
+ psw->state = 1;
+ mod_timer(&psw->debounce, jiffies + 50);
+ ret = 1;
+ }
+
+out:
+ /* Clear the switch IRQs */
+ ctrl_outb(0x00, PA_PWRINT_CLR);
+
+ return IRQ_RETVAL(ret);
+}
+
+static struct resource psw_power_resources[] = {
+ [0] = {
+ .start = IRQ_POWER,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource psw_usl5p_resources[] = {
+ [0] = {
+ .start = IRQ_BUTTON,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct push_switch_platform_info psw_power_platform_data = {
+ .name = "psw_power",
+ .bit = 4,
+ .irq_flags = IRQF_SHARED,
+ .irq_handler = psw_irq_handler,
+};
+
+static struct push_switch_platform_info psw1_platform_data = {
+ .name = "psw1",
+ .bit = 0,
+ .irq_flags = IRQF_SHARED,
+ .irq_handler = psw_irq_handler,
+};
+
+static struct push_switch_platform_info psw2_platform_data = {
+ .name = "psw2",
+ .bit = 2,
+ .irq_flags = IRQF_SHARED,
+ .irq_handler = psw_irq_handler,
+};
+
+static struct push_switch_platform_info psw3_platform_data = {
+ .name = "psw3",
+ .bit = 1,
+ .irq_flags = IRQF_SHARED,
+ .irq_handler = psw_irq_handler,
+};
+
+static struct platform_device psw_power_switch_device = {
+ .name = "push-switch",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(psw_power_resources),
+ .resource = psw_power_resources,
+ .dev = {
+ .platform_data = &psw_power_platform_data,
+ },
+};
+
+static struct platform_device psw1_switch_device = {
+ .name = "push-switch",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(psw_usl5p_resources),
+ .resource = psw_usl5p_resources,
+ .dev = {
+ .platform_data = &psw1_platform_data,
+ },
+};
+
+static struct platform_device psw2_switch_device = {
+ .name = "push-switch",
+ .id = 2,
+ .num_resources = ARRAY_SIZE(psw_usl5p_resources),
+ .resource = psw_usl5p_resources,
+ .dev = {
+ .platform_data = &psw2_platform_data,
+ },
+};
+
+static struct platform_device psw3_switch_device = {
+ .name = "push-switch",
+ .id = 3,
+ .num_resources = ARRAY_SIZE(psw_usl5p_resources),
+ .resource = psw_usl5p_resources,
+ .dev = {
+ .platform_data = &psw3_platform_data,
+ },
+};
+
+static struct platform_device *psw_devices[] = {
+ &psw_power_switch_device,
+ &psw1_switch_device,
+ &psw2_switch_device,
+ &psw3_switch_device,
+};
+
+static int __init psw_init(void)
+{
+ return platform_add_devices(psw_devices, ARRAY_SIZE(psw_devices));
+}
+module_init(psw_init);
diff --git a/arch/sh/boards/landisk/rtc.c b/arch/sh/boards/landisk/rtc.c
deleted file mode 100644
index 0a9a2a2ad05..00000000000
--- a/arch/sh/boards/landisk/rtc.c
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * arch/sh/boards/landisk/rtc.c -- RTC support
- *
- * Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
- * Copyright (C) 1999 Tetsuya Okada & Niibe Yutaka
- */
-/*
- * modifed by kogiidena
- * 2005.09.16
- */
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/time.h>
-#include <linux/delay.h>
-#include <linux/spinlock.h>
-#include <linux/bcd.h>
-#include <asm/rtc.h>
-
-extern spinlock_t rtc_lock;
-
-extern void
-rs5c313_set_cmos_time(unsigned int BCD_yr, unsigned int BCD_mon,
- unsigned int BCD_day, unsigned int BCD_hr,
- unsigned int BCD_min, unsigned int BCD_sec);
-
-extern unsigned long
-rs5c313_get_cmos_time(unsigned int *BCD_yr, unsigned int *BCD_mon,
- unsigned int *BCD_day, unsigned int *BCD_hr,
- unsigned int *BCD_min, unsigned int *BCD_sec);
-
-void landisk_rtc_gettimeofday(struct timespec *tv)
-{
- unsigned int BCD_yr, BCD_mon, BCD_day, BCD_hr, BCD_min, BCD_sec;
- unsigned long flags;
-
- spin_lock_irqsave(&rtc_lock, flags);
- tv->tv_sec = rs5c313_get_cmos_time
- (&BCD_yr, &BCD_mon, &BCD_day, &BCD_hr, &BCD_min, &BCD_sec);
- tv->tv_nsec = 0;
- spin_unlock_irqrestore(&rtc_lock, flags);
-}
-
-int landisk_rtc_settimeofday(const time_t secs)
-{
- int retval = 0;
- int real_seconds, real_minutes, cmos_minutes;
- unsigned long flags;
- unsigned long nowtime = secs;
- unsigned int BCD_yr, BCD_mon, BCD_day, BCD_hr, BCD_min, BCD_sec;
-
- spin_lock_irqsave(&rtc_lock, flags);
-
- rs5c313_get_cmos_time
- (&BCD_yr, &BCD_mon, &BCD_day, &BCD_hr, &BCD_min, &BCD_sec);
- cmos_minutes = BCD_min;
- BCD_TO_BIN(cmos_minutes);
-
- /*
- * since we're only adjusting minutes and seconds,
- * don't interfere with hour overflow. This avoids
- * messing with unknown time zones but requires your
- * RTC not to be off by more than 15 minutes
- */
- real_seconds = nowtime % 60;
- real_minutes = nowtime / 60;
- if (((abs(real_minutes - cmos_minutes) + 15) / 30) & 1)
- real_minutes += 30; /* correct for half hour time zone */
- real_minutes %= 60;
-
- if (abs(real_minutes - cmos_minutes) < 30) {
- BIN_TO_BCD(real_seconds);
- BIN_TO_BCD(real_minutes);
- rs5c313_set_cmos_time(BCD_yr, BCD_mon, BCD_day, BCD_hr,
- real_minutes, real_seconds);
- } else {
- printk(KERN_WARNING
- "set_rtc_time: can't update from %d to %d\n",
- cmos_minutes, real_minutes);
- retval = -1;
- }
-
- spin_unlock_irqrestore(&rtc_lock, flags);
- return retval;
-}
-
-void landisk_time_init(void)
-{
- rtc_sh_get_time = landisk_rtc_gettimeofday;
- rtc_sh_set_time = landisk_rtc_settimeofday;
-}
diff --git a/arch/sh/boards/landisk/setup.c b/arch/sh/boards/landisk/setup.c
index 122d6996263..a83a5d9587b 100644
--- a/arch/sh/boards/landisk/setup.c
+++ b/arch/sh/boards/landisk/setup.c
@@ -1,144 +1,90 @@
/*
* arch/sh/boards/landisk/setup.c
*
- * Copyright (C) 2000 Kazumoto Kojima
- * Copyright (C) 2002 Paul Mundt
- *
* I-O DATA Device, Inc. LANDISK Support.
*
- * Modified for LANDISK by
- * Atom Create Engineering Co., Ltd. 2002.
- *
- * modifed by kogiidena
- * 2005.09.16
+ * Copyright (C) 2000 Kazumoto Kojima
+ * Copyright (C) 2002 Paul Mundt
+ * Copylight (C) 2002 Atom Create Engineering Co., Ltd.
+ * Copyright (C) 2005-2007 kogiidena
*
* 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/pata_platform.h>
#include <linux/pm.h>
#include <linux/mm.h>
#include <asm/machvec.h>
-#include <asm/rtc.h>
#include <asm/landisk/iodata_landisk.h>
#include <asm/io.h>
-void landisk_time_init(void);
void init_landisk_IRQ(void);
-int landisk_ledparam;
-int landisk_buzzerparam;
-int landisk_arch;
-
-/* cycle the led's in the clasic knightrider/sun pattern */
-static void heartbeat_landisk(void)
-{
- static unsigned int cnt = 0, blink = 0x00, period = 25;
- volatile u8 *p = (volatile u8 *)PA_LED;
- char data;
-
- if ((landisk_ledparam & 0x080) == 0)
- return;
-
- cnt += 1;
-
- if (cnt < period)
- return;
-
- cnt = 0;
- blink++;
-
- data = (blink & 0x01) ? (landisk_ledparam >> 16) : 0;
- data |= (blink & 0x02) ? (landisk_ledparam >> 8) : 0;
- data |= landisk_ledparam;
-
- /* buzzer */
- if (landisk_buzzerparam & 0x1) {
- data |= 0x80;
- } else {
- data &= 0x7f;
- }
- *p = data;
-
- if (((landisk_ledparam & 0x007f7f00) == 0) &&
- (landisk_buzzerparam == 0))
- landisk_ledparam &= (~0x0080);
-
- landisk_buzzerparam >>= 1;
-}
-
static void landisk_power_off(void)
{
ctrl_outb(0x01, PA_SHUTDOWN);
}
-static void check_usl5p(void)
-{
- volatile u8 *p = (volatile u8 *)PA_LED;
- u8 tmp1, tmp2;
+static struct resource cf_ide_resources[3];
- tmp1 = *p;
- *p = 0x40;
- tmp2 = *p;
- *p = tmp1;
+static struct pata_platform_info pata_info = {
+ .ioport_shift = 1,
+};
- landisk_arch = (tmp2 == 0x40);
- if (landisk_arch == 1) {
- /* arch == usl-5p */
- landisk_ledparam = 0x00000380;
- landisk_ledparam |= (tmp1 & 0x07c);
- } else {
- /* arch == landisk */
- landisk_ledparam = 0x02000180;
- landisk_ledparam |= 0x04;
- }
-}
+static struct platform_device cf_ide_device = {
+ .name = "pata_platform",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(cf_ide_resources),
+ .resource = cf_ide_resources,
+ .dev = {
+ .platform_data = &pata_info,
+ },
+};
-void *area5_io_base;
-void *area6_io_base;
+static struct platform_device *landisk_devices[] __initdata = {
+ &cf_ide_device,
+};
-static int __init landisk_cf_init(void)
+static int __init landisk_devices_setup(void)
{
pgprot_t prot;
- unsigned long paddrbase, psize;
+ unsigned long paddrbase;
+ void *cf_ide_base;
/* open I/O area window */
paddrbase = virt_to_phys((void *)PA_AREA5_IO);
- psize = PAGE_SIZE;
prot = PAGE_KERNEL_PCC(1, _PAGE_PCC_IO16);
- area5_io_base = p3_ioremap(paddrbase, psize, prot.pgprot);
- if (!area5_io_base) {
+ cf_ide_base = p3_ioremap(paddrbase, PAGE_SIZE, prot.pgprot);
+ if (!cf_ide_base) {
printk("allocate_cf_area : can't open CF I/O window!\n");
return -ENOMEM;
}
- paddrbase = virt_to_phys((void *)PA_AREA6_IO);
- psize = PAGE_SIZE;
- prot = PAGE_KERNEL_PCC(0, _PAGE_PCC_IO16);
- area6_io_base = p3_ioremap(paddrbase, psize, prot.pgprot);
- if (!area6_io_base) {
- printk("allocate_cf_area : can't open HDD I/O window!\n");
- return -ENOMEM;
- }
-
- printk(KERN_INFO "Allocate Area5/6 success.\n");
-
- /* XXX : do we need attribute and common-memory area also? */
-
- return 0;
+ /* IDE cmd address : 0x1f0-0x1f7 and 0x3f6 */
+ cf_ide_resources[0].start = (unsigned long)cf_ide_base + 0x40;
+ cf_ide_resources[0].end = (unsigned long)cf_ide_base + 0x40 + 0x0f;
+ cf_ide_resources[0].flags = IORESOURCE_IO;
+ cf_ide_resources[1].start = (unsigned long)cf_ide_base + 0x2c;
+ cf_ide_resources[1].end = (unsigned long)cf_ide_base + 0x2c + 0x03;
+ cf_ide_resources[1].flags = IORESOURCE_IO;
+ cf_ide_resources[2].start = IRQ_FATA;
+ cf_ide_resources[2].flags = IORESOURCE_IRQ;
+
+ return platform_add_devices(landisk_devices,
+ ARRAY_SIZE(landisk_devices));
}
+__initcall(landisk_devices_setup);
+
static void __init landisk_setup(char **cmdline_p)
{
- device_initcall(landisk_cf_init);
-
- landisk_buzzerparam = 0;
- check_usl5p();
+ /* LED ON */
+ ctrl_outb(ctrl_inb(PA_LED) | 0x03, PA_LED);
printk(KERN_INFO "I-O DATA DEVICE, INC. \"LANDISK Series\" support.\n");
-
- board_time_init = landisk_time_init;
pm_power_off = landisk_power_off;
}
@@ -148,29 +94,6 @@ static void __init landisk_setup(char **cmdline_p)
struct sh_machine_vector mv_landisk __initmv = {
.mv_name = "LANDISK",
.mv_setup = landisk_setup,
- .mv_nr_irqs = 72,
- .mv_inb = landisk_inb,
- .mv_inw = landisk_inw,
- .mv_inl = landisk_inl,
- .mv_outb = landisk_outb,
- .mv_outw = landisk_outw,
- .mv_outl = landisk_outl,
- .mv_inb_p = landisk_inb_p,
- .mv_inw_p = landisk_inw,
- .mv_inl_p = landisk_inl,
- .mv_outb_p = landisk_outb_p,
- .mv_outw_p = landisk_outw,
- .mv_outl_p = landisk_outl,
- .mv_insb = landisk_insb,
- .mv_insw = landisk_insw,
- .mv_insl = landisk_insl,
- .mv_outsb = landisk_outsb,
- .mv_outsw = landisk_outsw,
- .mv_outsl = landisk_outsl,
- .mv_ioport_map = landisk_ioport_map,
.mv_init_irq = init_landisk_IRQ,
-#ifdef CONFIG_HEARTBEAT
- .mv_heartbeat = heartbeat_landisk,
-#endif
};
ALIAS_MV(landisk)
diff --git a/arch/sh/boards/lboxre2/Makefile b/arch/sh/boards/lboxre2/Makefile
new file mode 100644
index 00000000000..e9ed140c06f
--- /dev/null
+++ b/arch/sh/boards/lboxre2/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for the L-BOX RE2 specific parts of the kernel
+# Copyright (c) 2007 Nobuhiro Iwamatsu
+
+obj-y := setup.o irq.o
diff --git a/arch/sh/boards/lboxre2/irq.c b/arch/sh/boards/lboxre2/irq.c
new file mode 100644
index 00000000000..5a1c3bbe7b5
--- /dev/null
+++ b/arch/sh/boards/lboxre2/irq.c
@@ -0,0 +1,31 @@
+/*
+ * linux/arch/sh/boards/lboxre2/irq.c
+ *
+ * Copyright (C) 2007 Nobuhiro Iwamatsu
+ *
+ * NTT COMWARE L-BOX RE2 Support.
+ *
+ * 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/interrupt.h>
+#include <linux/irq.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <asm/lboxre2.h>
+
+/*
+ * Initialize IRQ setting
+ */
+void __init init_lboxre2_IRQ(void)
+{
+ make_imask_irq(IRQ_CF1);
+ make_imask_irq(IRQ_CF0);
+ make_imask_irq(IRQ_INTD);
+ make_imask_irq(IRQ_ETH1);
+ make_imask_irq(IRQ_ETH0);
+ make_imask_irq(IRQ_INTA);
+}
diff --git a/arch/sh/boards/lboxre2/setup.c b/arch/sh/boards/lboxre2/setup.c
new file mode 100644
index 00000000000..4e20f7c63bf
--- /dev/null
+++ b/arch/sh/boards/lboxre2/setup.c
@@ -0,0 +1,85 @@
+/*
+ * linux/arch/sh/boards/lbox/setup.c
+ *
+ * Copyright (C) 2007 Nobuhiro Iwamatsu
+ *
+ * NTT COMWARE L-BOX RE2 Support
+ *
+ * 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/pata_platform.h>
+#include <asm/machvec.h>
+#include <asm/addrspace.h>
+#include <asm/lboxre2.h>
+#include <asm/io.h>
+
+static struct resource cf_ide_resources[] = {
+ [0] = {
+ .start = 0x1f0,
+ .end = 0x1f0 + 8 ,
+ .flags = IORESOURCE_IO,
+ },
+ [1] = {
+ .start = 0x1f0 + 0x206,
+ .end = 0x1f0 +8 + 0x206 + 8,
+ .flags = IORESOURCE_IO,
+ },
+ [2] = {
+ .start = IRQ_CF0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device cf_ide_device = {
+ .name = "pata_platform",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(cf_ide_resources),
+ .resource = cf_ide_resources,
+};
+
+static struct platform_device *lboxre2_devices[] __initdata = {
+ &cf_ide_device,
+};
+
+static int __init lboxre2_devices_setup(void)
+{
+ u32 cf0_io_base; /* Boot CF base address */
+ pgprot_t prot;
+ unsigned long paddrbase, psize;
+
+ /* open I/O area window */
+ paddrbase = virt_to_phys((void*)PA_AREA5_IO);
+ psize = PAGE_SIZE;
+ prot = PAGE_KERNEL_PCC( 1 , _PAGE_PCC_IO16);
+ cf0_io_base = (u32)p3_ioremap(paddrbase, psize, prot.pgprot);
+ if (!cf0_io_base) {
+ printk(KERN_ERR "%s : can't open CF I/O window!\n" , __func__ );
+ return -ENOMEM;
+ }
+
+ cf_ide_resources[0].start += cf0_io_base ;
+ cf_ide_resources[0].end += cf0_io_base ;
+ cf_ide_resources[1].start += cf0_io_base ;
+ cf_ide_resources[1].end += cf0_io_base ;
+
+ return platform_add_devices(lboxre2_devices,
+ ARRAY_SIZE(lboxre2_devices));
+
+}
+device_initcall(lboxre2_devices_setup);
+
+/*
+ * The Machine Vector
+ */
+struct sh_machine_vector mv_lboxre2 __initmv = {
+ .mv_name = "L-BOX RE2",
+ .mv_nr_irqs = 72,
+ .mv_init_irq = init_lboxre2_IRQ,
+};
+ALIAS_MV(lboxre2)
diff --git a/arch/sh/boards/renesas/r7780rp/Kconfig b/arch/sh/boards/renesas/r7780rp/Kconfig
index c26d9813d23..9fb11641fe1 100644
--- a/arch/sh/boards/renesas/r7780rp/Kconfig
+++ b/arch/sh/boards/renesas/r7780rp/Kconfig
@@ -1,14 +1,24 @@
-if SH_R7780RP
+if SH_HIGHLANDER
-menu "R7780RP options"
+choice
+ prompt "Highlander options"
+ default SH_R7780MP
+
+config SH_R7780RP
+ bool "R7780RP-1 board support"
+ select CPU_SUBTYPE_SH7780
config SH_R7780MP
bool "R7780MP board support"
- default y
+ select CPU_SUBTYPE_SH7780
help
Selecting this option will enable support for the mass-production
version of the R7780RP. If in doubt, say Y.
-endmenu
+config SH_R7785RP
+ bool "R7785RP board support"
+ select CPU_SUBTYPE_SH7785
+
+endchoice
endif
diff --git a/arch/sh/boards/renesas/r7780rp/Makefile b/arch/sh/boards/renesas/r7780rp/Makefile
index ed5f5a9a3b3..609e5d50dde 100644
--- a/arch/sh/boards/renesas/r7780rp/Makefile
+++ b/arch/sh/boards/renesas/r7780rp/Makefile
@@ -1,7 +1,7 @@
#
# Makefile for the R7780RP-1 specific parts of the kernel
#
-
-obj-y := setup.o irq.o
-
+irqinit-y := irq-r7780rp.o
+irqinit-$(CONFIG_SH_R7785RP) := irq-r7785rp.o
obj-$(CONFIG_PUSH_SWITCH) += psw.o
+obj-y := setup.o irq.o $(irqinit-y)
diff --git a/arch/sh/boards/renesas/r7780rp/irq-r7780rp.c b/arch/sh/boards/renesas/r7780rp/irq-r7780rp.c
new file mode 100644
index 00000000000..f5f358746c9
--- /dev/null
+++ b/arch/sh/boards/renesas/r7780rp/irq-r7780rp.c
@@ -0,0 +1,21 @@
+/*
+ * Renesas Solutions Highlander R7780RP-1 Support.
+ *
+ * Copyright (C) 2002 Atom Create Engineering Co., Ltd.
+ * Copyright (C) 2006 Paul Mundt
+ *
+ * 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 <asm/io.h>
+#include <asm/r7780rp.h>
+
+void __init highlander_init_irq(void)
+{
+ int i;
+
+ for (i = 0; i < 15; i++)
+ make_r7780rp_irq(i);
+}
diff --git a/arch/sh/boards/renesas/r7780rp/irq-r7785rp.c b/arch/sh/boards/renesas/r7780rp/irq-r7785rp.c
new file mode 100644
index 00000000000..dd6ec4ce44d
--- /dev/null
+++ b/arch/sh/boards/renesas/r7780rp/irq-r7785rp.c
@@ -0,0 +1,29 @@
+/*
+ * Renesas Solutions Highlander R7780RP-1 Support.
+ *
+ * Copyright (C) 2002 Atom Create Engineering Co., Ltd.
+ * Copyright (C) 2006 Paul Mundt
+ *
+ * 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 <asm/io.h>
+#include <asm/r7780rp.h>
+
+void __init highlander_init_irq(void)
+{
+ ctrl_outw(0x0000, PA_IRLSSR1); /* FPGA IRLSSR1(CF_CD clear) */
+
+ /* Setup the FPGA IRL */
+ ctrl_outw(0x0000, PA_IRLPRA); /* FPGA IRLA */
+ ctrl_outw(0xe598, PA_IRLPRB); /* FPGA IRLB */
+ ctrl_outw(0x7060, PA_IRLPRC); /* FPGA IRLC */
+ ctrl_outw(0x0000, PA_IRLPRD); /* FPGA IRLD */
+ ctrl_outw(0x4321, PA_IRLPRE); /* FPGA IRLE */
+ ctrl_outw(0x0000, PA_IRLPRF); /* FPGA IRLF */
+
+ make_r7780rp_irq(1); /* CF card */
+ make_r7780rp_irq(10); /* On-board ethernet */
+}
diff --git a/arch/sh/boards/renesas/r7780rp/irq.c b/arch/sh/boards/renesas/r7780rp/irq.c
index cc381e19778..e0b8eb52f37 100644
--- a/arch/sh/boards/renesas/r7780rp/irq.c
+++ b/arch/sh/boards/renesas/r7780rp/irq.c
@@ -14,10 +14,12 @@
#include <linux/io.h>
#include <asm/r7780rp.h>
-#ifdef CONFIG_SH_R7780MP
-static int mask_pos[] = {12, 11, 9, 14, 15, 8, 13, 6, 5, 4, 3, 2, 0, 0, 1, 0};
-#else
+#ifdef CONFIG_SH_R7780RP
static int mask_pos[] = {15, 14, 13, 12, 11, 10, 9, 8, 7, 5, 6, 4, 0, 1, 2, 0};
+#elif defined(CONFIG_SH_R7780MP)
+static int mask_pos[] = {12, 11, 9, 14, 15, 8, 13, 6, 5, 4, 3, 2, 0, 0, 1, 0};
+#elif defined(CONFIG_SH_R7785RP)
+static int mask_pos[] = {2, 11, 2, 2, 2, 2, 9, 8, 7, 5, 10, 2, 2, 2, 2, 2};
#endif
static void enable_r7780rp_irq(unsigned int irq)
@@ -40,17 +42,10 @@ static struct irq_chip r7780rp_irq_chip __read_mostly = {
.mask_ack = disable_r7780rp_irq,
};
-/*
- * Initialize IRQ setting
- */
-void __init init_r7780rp_IRQ(void)
+void make_r7780rp_irq(unsigned int irq)
{
- int i;
-
- for (i = 0; i < 15; i++) {
- disable_irq_nosync(i);
- set_irq_chip_and_handler_name(i, &r7780rp_irq_chip,
- handle_level_irq, "level");
- enable_r7780rp_irq(i);
- }
+ disable_irq_nosync(irq);
+ set_irq_chip_and_handler_name(irq, &r7780rp_irq_chip,
+ handle_level_irq, "level");
+ enable_r7780rp_irq(irq);
}
diff --git a/arch/sh/boards/renesas/r7780rp/setup.c b/arch/sh/boards/renesas/r7780rp/setup.c
index 2faba6679e6..0727ef92f2b 100644
--- a/arch/sh/boards/renesas/r7780rp/setup.c
+++ b/arch/sh/boards/renesas/r7780rp/setup.c
@@ -1,10 +1,13 @@
/*
* arch/sh/boards/renesas/r7780rp/setup.c
*
+ * Renesas Solutions Highlander Support.
+ *
* Copyright (C) 2002 Atom Create Engineering Co., Ltd.
* Copyright (C) 2005 - 2007 Paul Mundt
*
- * Renesas Solutions Highlander R7780RP-1 Support.
+ * This contains support for the R7780RP-1, R7780MP, and R7785RP
+ * Highlander modules.
*
* 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
@@ -18,32 +21,6 @@
#include <asm/clock.h>
#include <asm/io.h>
-extern void init_r7780rp_IRQ(void);
-
-static struct resource m66596_usb_host_resources[] = {
- [0] = {
- .start = 0xa4800000,
- .end = 0xa4ffffff,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = 6, /* irq number */
- .end = 6,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct platform_device m66596_usb_host_device = {
- .name = "m66596-hcd",
- .id = 0,
- .dev = {
- .dma_mask = NULL, /* don't use dma */
- .coherent_dma_mask = 0xffffffff,
- },
- .num_resources = ARRAY_SIZE(m66596_usb_host_resources),
- .resource = m66596_usb_host_resources,
-};
-
static struct resource cf_ide_resources[] = {
[0] = {
.start = PA_AREA5_IO + 0x1000,
@@ -56,10 +33,10 @@ static struct resource cf_ide_resources[] = {
.flags = IORESOURCE_MEM,
},
[2] = {
-#ifdef CONFIG_SH_R7780MP
- .start = 1,
-#else
+#ifdef CONFIG_SH_R7780RP
.start = 4,
+#else
+ .start = 1,
#endif
.flags = IORESOURCE_IRQ,
},
@@ -92,15 +69,18 @@ static struct resource heartbeat_resources[] = {
static struct platform_device heartbeat_device = {
.name = "heartbeat",
.id = -1,
+
+ /* R7785RP has a slightly more sensible FPGA.. */
+#ifndef CONFIG_SH_R7785RP
.dev = {
.platform_data = heartbeat_bit_pos,
},
+#endif
.num_resources = ARRAY_SIZE(heartbeat_resources),
.resource = heartbeat_resources,
};
static struct platform_device *r7780rp_devices[] __initdata = {
- &m66596_usb_host_device,
&cf_ide_device,
&heartbeat_device,
};
@@ -110,18 +90,19 @@ static int __init r7780rp_devices_setup(void)
return platform_add_devices(r7780rp_devices,
ARRAY_SIZE(r7780rp_devices));
}
+device_initcall(r7780rp_devices_setup);
/*
* Platform specific clocks
*/
static void ivdr_clk_enable(struct clk *clk)
{
- ctrl_outw(ctrl_inw(PA_IVDRCTL) | (1 << 8), PA_IVDRCTL);
+ ctrl_outw(ctrl_inw(PA_IVDRCTL) | (1 << IVDR_CK_ON), PA_IVDRCTL);
}
static void ivdr_clk_disable(struct clk *clk)
{
- ctrl_outw(ctrl_inw(PA_IVDRCTL) & ~(1 << 8), PA_IVDRCTL);
+ ctrl_outw(ctrl_inw(PA_IVDRCTL) & ~(1 << IVDR_CK_ON), PA_IVDRCTL);
}
static struct clk_ops ivdr_clk_ops = {
@@ -140,22 +121,22 @@ static struct clk *r7780rp_clocks[] = {
static void r7780rp_power_off(void)
{
-#ifdef CONFIG_SH_R7780MP
- ctrl_outw(0x0001, PA_POFF);
-#endif
+ if (mach_is_r7780mp() || mach_is_r7785rp())
+ ctrl_outw(0x0001, PA_POFF);
}
/*
* Initialize the board
*/
-static void __init r7780rp_setup(char **cmdline_p)
+static void __init highlander_setup(char **cmdline_p)
{
u16 ver = ctrl_inw(PA_VERREG);
int i;
- device_initcall(r7780rp_devices_setup);
-
- printk(KERN_INFO "Renesas Solutions Highlander R7780RP-1 support.\n");
+ printk(KERN_INFO "Renesas Solutions Highlander %s support.\n",
+ mach_is_r7780rp() ? "R7780RP-1" :
+ mach_is_r7780mp() ? "R7780MP" :
+ "R7785RP");
printk(KERN_INFO "Board version: %d (revision %d), "
"FPGA version: %d (revision %d)\n",
@@ -173,9 +154,10 @@ static void __init r7780rp_setup(char **cmdline_p)
}
ctrl_outw(0x0000, PA_OBLED); /* Clear LED. */
-#ifndef CONFIG_SH_R7780MP
- ctrl_outw(0x0001, PA_SDPOW); /* SD Power ON */
-#endif
+
+ if (mach_is_r7780rp())
+ ctrl_outw(0x0001, PA_SDPOW); /* SD Power ON */
+
ctrl_outw(ctrl_inw(PA_IVDRCTL) | 0x01, PA_IVDRCTL); /* Si13112 */
pm_power_off = r7780rp_power_off;
@@ -184,10 +166,10 @@ static void __init r7780rp_setup(char **cmdline_p)
/*
* The Machine Vector
*/
-struct sh_machine_vector mv_r7780rp __initmv = {
- .mv_name = "Highlander R7780RP-1",
- .mv_setup = r7780rp_setup,
+struct sh_machine_vector mv_highlander __initmv = {
+ .mv_name = "Highlander",
.mv_nr_irqs = 109,
- .mv_init_irq = init_r7780rp_IRQ,
+ .mv_setup = highlander_setup,
+ .mv_init_irq = highlander_init_irq,
};
-ALIAS_MV(r7780rp)
+ALIAS_MV(highlander)
diff --git a/arch/sh/boards/se/770x/io.c b/arch/sh/boards/se/770x/io.c
index 9941949331a..c4550473d4c 100644
--- a/arch/sh/boards/se/770x/io.c
+++ b/arch/sh/boards/se/770x/io.c
@@ -27,6 +27,8 @@ int sh_pcic_io_dummy;
static inline volatile __u16 *
port2adr(unsigned int port)
{
+ if (port & 0xff000000)
+ return ( volatile __u16 *) port;
if (port >= 0x2000)
return (volatile __u16 *) (PA_MRSHPC + (port - 0x2000));
else if (port >= 0x1000)
diff --git a/arch/sh/boards/se/770x/irq.c b/arch/sh/boards/se/770x/irq.c
index 307ca5da623..c8eccff77a0 100644
--- a/arch/sh/boards/se/770x/irq.c
+++ b/arch/sh/boards/se/770x/irq.c
@@ -55,23 +55,34 @@ void make_se770x_irq(struct ipr_data *table, unsigned int nr_irqs)
}
static struct ipr_data se770x_ipr_map[] = {
+ /*
+ * Super I/O (Just mimic PC):
+ * 1: keyboard
+ * 3: serial 0
+ * 4: serial 1
+ * 5: printer
+ * 6: floppy
+ * 8: rtc
+ * 12: mouse
+ * 14: ide0
+ */
#if defined(CONFIG_CPU_SUBTYPE_SH7705)
/* This is default value */
- { 0xf-0x2, 0, 8, 0x2 , BCR_ILCRA},
- { 0xf-0xa, 0, 4, 0xa , BCR_ILCRA},
- { 0xf-0x5, 0, 0, 0x5 , BCR_ILCRB},
- { 0xf-0x8, 0, 4, 0x8 , BCR_ILCRC},
- { 0xf-0xc, 0, 0, 0xc , BCR_ILCRC},
- { 0xf-0xe, 0, 12, 0xe , BCR_ILCRD},
- { 0xf-0x3, 0, 4, 0x3 , BCR_ILCRD}, /* LAN */
- { 0xf-0xd, 0, 8, 0xd , BCR_ILCRE},
- { 0xf-0x9, 0, 4, 0x9 , BCR_ILCRE},
- { 0xf-0x1, 0, 0, 0x1 , BCR_ILCRE},
- { 0xf-0xf, 0, 12, 0xf , BCR_ILCRF},
- { 0xf-0xb, 0, 4, 0xb , BCR_ILCRF},
- { 0xf-0x7, 0, 12, 0x7 , BCR_ILCRG},
- { 0xf-0x6, 0, 8, 0x6 , BCR_ILCRG},
- { 0xf-0x4, 0, 4, 0x4 , BCR_ILCRG},
+ { 13, 0, 8, 0x0f-13 ,BCR_ILCRA},
+ { 5 , 0, 4, 0x0f- 5 ,BCR_ILCRA},
+ { 10, 0, 0, 0x0f-10, BCR_ILCRB},
+ { 7 , 0, 4, 0x0f- 7, BCR_ILCRC},
+ { 3 , 0, 0, 0x0f- 3, BCR_ILCRC},
+ { 1 , 0, 12, 0x0f- 1, BCR_ILCRD},
+ { 12, 0, 4, 0x0f-12, BCR_ILCRD}, /* LAN */
+ { 2 , 0, 8, 0x0f- 2, BCR_ILCRE}, /* PCIRQ2 */
+ { 6 , 0, 4, 0x0f- 6, BCR_ILCRE}, /* PCIRQ1 */
+ { 14, 0, 0, 0x0f-14, BCR_ILCRE}, /* PCIRQ0 */
+ { 0 , 0, 12, 0x0f , BCR_ILCRF},
+ { 4 , 0, 4, 0x0f- 4, BCR_ILCRF},
+ { 8 , 0, 12, 0x0f- 8, BCR_ILCRG},
+ { 9 , 0, 8, 0x0f- 9, BCR_ILCRG},
+ { 11, 0, 4, 0x0f-11, BCR_ILCRG},
#else
{ 14, 0, 8, 0x0f-14 ,BCR_ILCRA},
{ 12, 0, 4, 0x0f-12 ,BCR_ILCRA},
@@ -81,8 +92,10 @@ static struct ipr_data se770x_ipr_map[] = {
{ 4, 0, 4, 0x0f- 4 ,BCR_ILCRC},
{ 3, 0, 0, 0x0f- 3 ,BCR_ILCRC},
{ 1, 0, 12, 0x0f- 1 ,BCR_ILCRD},
+#if defined(CONFIG_STNIC)
/* ST NIC */
{ 10, 0, 4, 0x0f-10 ,BCR_ILCRD}, /* LAN */
+#endif
/* MRSHPC IRQs setting */
{ 0, 0, 12, 0x0f- 0 ,BCR_ILCRE}, /* PCIRQ3 */
{ 11, 0, 8, 0x0f-11 ,BCR_ILCRE}, /* PCIRQ2 */
@@ -100,18 +113,6 @@ static struct ipr_data se770x_ipr_map[] = {
*/
void __init init_se_IRQ(void)
{
- /*
- * Super I/O (Just mimic PC):
- * 1: keyboard
- * 3: serial 0
- * 4: serial 1
- * 5: printer
- * 6: floppy
- * 8: rtc
- * 12: mouse
- * 14: ide0
- */
-#if defined(CONFIG_CPU_SUBTYPE_SH7705)
/* Disable all interrupts */
ctrl_outw(0, BCR_ILCRA);
ctrl_outw(0, BCR_ILCRB);
@@ -120,6 +121,6 @@ void __init init_se_IRQ(void)
ctrl_outw(0, BCR_ILCRE);
ctrl_outw(0, BCR_ILCRF);
ctrl_outw(0, BCR_ILCRG);
-#endif
+
make_se770x_irq(se770x_ipr_map, ARRAY_SIZE(se770x_ipr_map));
}
diff --git a/arch/sh/boards/se/770x/setup.c b/arch/sh/boards/se/770x/setup.c
index 45cbc36b9fb..17a2631de3b 100644
--- a/arch/sh/boards/se/770x/setup.c
+++ b/arch/sh/boards/se/770x/setup.c
@@ -63,6 +63,31 @@ static void __init smsc_setup(char **cmdline_p)
outb_p(CONFIG_EXIT, CONFIG_PORT);
}
+
+static struct resource cf_ide_resources[] = {
+ [0] = {
+ .start = PA_MRSHPC_IO + 0x1f0,
+ .end = PA_MRSHPC_IO + 0x1f0 + 8,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = PA_MRSHPC_IO + 0x1f0 + 0x206,
+ .end = PA_MRSHPC_IO + 0x1f0 +8 + 0x206 + 8,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = {
+ .start = IRQ_CFCARD,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device cf_ide_device = {
+ .name = "pata_platform",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(cf_ide_resources),
+ .resource = cf_ide_resources,
+};
+
static unsigned char heartbeat_bit_pos[] = { 8, 9, 10, 11, 12, 13, 14, 15 };
static struct resource heartbeat_resources[] = {
@@ -85,13 +110,14 @@ static struct platform_device heartbeat_device = {
static struct platform_device *se_devices[] __initdata = {
&heartbeat_device,
+ &cf_ide_device,
};
static int __init se_devices_setup(void)
{
return platform_add_devices(se_devices, ARRAY_SIZE(se_devices));
}
-__initcall(se_devices_setup);
+device_initcall(se_devices_setup);
/*
* The Machine Vector
@@ -107,6 +133,8 @@ struct sh_machine_vector mv_se __initmv = {
.mv_nr_irqs = 61,
#elif defined(CONFIG_CPU_SUBTYPE_SH7705)
.mv_nr_irqs = 86,
+#elif defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712)
+ .mv_nr_irqs = 104,
#endif
.mv_inb = se_inb,
diff --git a/arch/sh/boards/se/7722/Makefile b/arch/sh/boards/se/7722/Makefile
new file mode 100644
index 00000000000..8694373389e
--- /dev/null
+++ b/arch/sh/boards/se/7722/Makefile
@@ -0,0 +1,10 @@
+#
+# Makefile for the HITACHI UL SolutionEngine 7722 specific parts of the kernel
+#
+# 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.
+#
+#
+
+obj-y := setup.o irq.o
diff --git a/arch/sh/boards/se/7722/irq.c b/arch/sh/boards/se/7722/irq.c
new file mode 100644
index 00000000000..099e5deb77f
--- /dev/null
+++ b/arch/sh/boards/se/7722/irq.c
@@ -0,0 +1,101 @@
+/*
+ * linux/arch/sh/boards/se/7722/irq.c
+ *
+ * Copyright (C) 2007 Nobuhiro Iwamatsu
+ *
+ * Hitachi UL SolutionEngine 7722 Support.
+ *
+ * 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/irq.h>
+#include <linux/interrupt.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <asm/se7722.h>
+
+#define INTC_INTMSK0 0xFFD00044
+#define INTC_INTMSKCLR0 0xFFD00064
+
+static void disable_se7722_irq(unsigned int irq)
+{
+ struct ipr_data *p = get_irq_chip_data(irq);
+ ctrl_outw( ctrl_inw( p->addr ) | p->priority , p->addr );
+}
+
+static void enable_se7722_irq(unsigned int irq)
+{
+ struct ipr_data *p = get_irq_chip_data(irq);
+ ctrl_outw( ctrl_inw( p->addr ) & ~p->priority , p->addr );
+}
+
+static struct irq_chip se7722_irq_chip __read_mostly = {
+ .name = "SE7722",
+ .mask = disable_se7722_irq,
+ .unmask = enable_se7722_irq,
+ .mask_ack = disable_se7722_irq,
+};
+
+static struct ipr_data ipr_irq_table[] = {
+ /* irq ,idx,sft, priority , addr */
+ { MRSHPC_IRQ0 , 0 , 0 , MRSHPC_BIT0 , IRQ01_MASK } ,
+ { MRSHPC_IRQ1 , 0 , 0 , MRSHPC_BIT1 , IRQ01_MASK } ,
+ { MRSHPC_IRQ2 , 0 , 0 , MRSHPC_BIT2 , IRQ01_MASK } ,
+ { MRSHPC_IRQ3 , 0 , 0 , MRSHPC_BIT3 , IRQ01_MASK } ,
+ { SMC_IRQ , 0 , 0 , SMC_BIT , IRQ01_MASK } ,
+ { EXT_IRQ , 0 , 0 , EXT_BIT , IRQ01_MASK } ,
+};
+
+int se7722_irq_demux(int irq)
+{
+
+ if ((irq == IRQ0_IRQ)||(irq == IRQ1_IRQ)) {
+ volatile unsigned short intv =
+ *(volatile unsigned short *)IRQ01_STS;
+ if (irq == IRQ0_IRQ){
+ if(intv & SMC_BIT ) {
+ return SMC_IRQ;
+ } else if(intv & USB_BIT) {
+ return USB_IRQ;
+ } else {
+ printk("intv =%04x\n", intv);
+ return SMC_IRQ;
+ }
+ } else if(irq == IRQ1_IRQ){
+ if(intv & MRSHPC_BIT0) {
+ return MRSHPC_IRQ0;
+ } else if(intv & MRSHPC_BIT1) {
+ return MRSHPC_IRQ1;
+ } else if(intv & MRSHPC_BIT2) {
+ return MRSHPC_IRQ2;
+ } else if(intv & MRSHPC_BIT3) {
+ return MRSHPC_IRQ3;
+ } else {
+ printk("BIT_EXTENTION =%04x\n", intv);
+ return EXT_IRQ;
+ }
+ }
+ }
+ return irq;
+
+}
+/*
+ * Initialize IRQ setting
+ */
+void __init init_se7722_IRQ(void)
+{
+ int i = 0;
+ ctrl_outw(0x2000, 0xb03fffec); /* mrshpc irq enable */
+ ctrl_outl((3 << ((7 - 0) * 4))|(3 << ((7 - 1) * 4)), INTC_INTPRI0); /* irq0 pri=3,irq1,pri=3 */
+ ctrl_outw((2 << ((7 - 0) * 2))|(2 << ((7 - 1) * 2)), INTC_ICR1); /* irq0,1 low-level irq */
+
+ for (i = 0; i < ARRAY_SIZE(ipr_irq_table); i++) {
+ disable_irq_nosync(ipr_irq_table[i].irq);
+ set_irq_chip_and_handler_name( ipr_irq_table[i].irq, &se7722_irq_chip,
+ handle_level_irq, "level");
+ set_irq_chip_data( ipr_irq_table[i].irq, &ipr_irq_table[i] );
+ disable_se7722_irq(ipr_irq_table[i].irq);
+ }
+}
diff --git a/arch/sh/boards/se/7722/setup.c b/arch/sh/boards/se/7722/setup.c
new file mode 100644
index 00000000000..636ca6c987e
--- /dev/null
+++ b/arch/sh/boards/se/7722/setup.c
@@ -0,0 +1,148 @@
+/*
+ * linux/arch/sh/boards/se/7722/setup.c
+ *
+ * Copyright (C) 2007 Nobuhiro Iwamatsu
+ *
+ * Hitachi UL SolutionEngine 7722 Support.
+ *
+ * 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/pata_platform.h>
+#include <asm/machvec.h>
+#include <asm/se7722.h>
+#include <asm/io.h>
+
+/* Heartbeat */
+static unsigned char heartbeat_bit_pos[] = { 0, 1, 2, 3, 4, 5, 6, 7 };
+
+static struct resource heartbeat_resources[] = {
+ [0] = {
+ .start = PA_LED,
+ .end = PA_LED + ARRAY_SIZE(heartbeat_bit_pos) - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device heartbeat_device = {
+ .name = "heartbeat",
+ .id = -1,
+ .dev = {
+ .platform_data = heartbeat_bit_pos,
+ },
+ .num_resources = ARRAY_SIZE(heartbeat_resources),
+ .resource = heartbeat_resources,
+};
+
+/* SMC91x */
+static struct resource smc91x_eth_resources[] = {
+ [0] = {
+ .name = "smc91x-regs" ,
+ .start = PA_LAN + 0x300,
+ .end = PA_LAN + 0x300 + 0x10 ,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = SMC_IRQ,
+ .end = SMC_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device smc91x_eth_device = {
+ .name = "smc91x",
+ .id = 0,
+ .dev = {
+ .dma_mask = NULL, /* don't use dma */
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(smc91x_eth_resources),
+ .resource = smc91x_eth_resources,
+};
+
+static struct resource cf_ide_resources[] = {
+ [0] = {
+ .start = PA_MRSHPC_IO + 0x1f0,
+ .end = PA_MRSHPC_IO + 0x1f0 + 8 ,
+ .flags = IORESOURCE_IO,
+ },
+ [1] = {
+ .start = PA_MRSHPC_IO + 0x1f0 + 0x206,
+ .end = PA_MRSHPC_IO + 0x1f0 +8 + 0x206 + 8,
+ .flags = IORESOURCE_IO,
+ },
+ [2] = {
+ .start = MRSHPC_IRQ0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device cf_ide_device = {
+ .name = "pata_platform",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(cf_ide_resources),
+ .resource = cf_ide_resources,
+};
+
+static struct platform_device *se7722_devices[] __initdata = {
+ &heartbeat_device,
+ &smc91x_eth_device,
+ &cf_ide_device,
+};
+
+static int __init se7722_devices_setup(void)
+{
+ return platform_add_devices(se7722_devices,
+ ARRAY_SIZE(se7722_devices));
+}
+device_initcall(se7722_devices_setup);
+
+static void __init se7722_setup(char **cmdline_p)
+{
+ ctrl_outw(0x010D, FPGA_OUT); /* FPGA */
+
+ ctrl_outl(0x00051001, MSTPCR0);
+ ctrl_outl(0x00000000, MSTPCR1);
+ /* KEYSC, VOU, BEU, CEU, VEU, VPU, LCDC */
+ ctrl_outl(0xffffbfC0, MSTPCR2);
+
+ ctrl_outw(0x0000, PORT_PECR); /* PORT E 1 = IRQ5 ,E 0 = BS */
+ ctrl_outw(0x1000, PORT_PJCR); /* PORT J 1 = IRQ1,J 0 =IRQ0 */
+
+ /* LCDC I/O */
+ ctrl_outw(0x0020, PORT_PSELD);
+
+ /* SIOF1*/
+ ctrl_outw(0x0003, PORT_PSELB);
+ ctrl_outw(0xe000, PORT_PSELC);
+ ctrl_outw(0x0000, PORT_PKCR);
+
+ /* LCDC */
+ ctrl_outw(0x4020, PORT_PHCR);
+ ctrl_outw(0x0000, PORT_PLCR);
+ ctrl_outw(0x0000, PORT_PMCR);
+ ctrl_outw(0x0002, PORT_PRCR);
+ ctrl_outw(0x0000, PORT_PXCR); /* LCDC,CS6A */
+
+ /* KEYSC */
+ ctrl_outw(0x0A10, PORT_PSELA); /* BS,SHHID2 */
+ ctrl_outw(0x0000, PORT_PYCR);
+ ctrl_outw(0x0000, PORT_PZCR);
+}
+
+/*
+ * The Machine Vector
+ */
+struct sh_machine_vector mv_se7722 __initmv = {
+ .mv_name = "Solution Engine 7722" ,
+ .mv_setup = se7722_setup ,
+ .mv_nr_irqs = 109 ,
+ .mv_init_irq = init_se7722_IRQ,
+ .mv_irq_demux = se7722_irq_demux,
+
+};
+ALIAS_MV(se7722)
diff --git a/arch/sh/boards/se/7751/setup.c b/arch/sh/boards/se/7751/setup.c
index e3feae6ec0b..770defed9c4 100644
--- a/arch/sh/boards/se/7751/setup.c
+++ b/arch/sh/boards/se/7751/setup.c
@@ -14,153 +14,6 @@
#include <asm/se7751.h>
#include <asm/io.h>
-void init_7751se_IRQ(void);
-
-#ifdef CONFIG_SH_KGDB
-#include <asm/kgdb.h>
-static int kgdb_uart_setup(void);
-static struct kgdb_sermap kgdb_uart_sermap =
-{ "ttyS", 0, kgdb_uart_setup, NULL };
-#endif
-
-/*
- * Initialize the board
- */
-static void __init sh7751se_setup(char **cmdline_p)
-{
- /* Call init_smsc() replacement to set up SuperIO. */
- /* XXX: RTC setting comes here */
-#ifdef CONFIG_SH_KGDB
- kgdb_register_sermap(&kgdb_uart_sermap);
-#endif
-}
-
-/*********************************************************************
- * Currently a hack (e.g. does not interact well w/serial.c, lots of *
- * hardcoded stuff) but may be useful if SCI/F needs debugging. *
- * Mostly copied from x86 code (see files asm-i386/kgdb_local.h and *
- * arch/i386/lib/kgdb_serial.c). *
- *********************************************************************/
-
-#ifdef CONFIG_SH_KGDB
-#include <linux/types.h>
-#include <linux/serial.h>
-#include <linux/serialP.h>
-#include <linux/serial_reg.h>
-
-#define COM1_PORT 0x3f8 /* Base I/O address */
-#define COM1_IRQ 4 /* IRQ not used yet */
-#define COM2_PORT 0x2f8 /* Base I/O address */
-#define COM2_IRQ 3 /* IRQ not used yet */
-
-#define SB_CLOCK 1843200 /* Serial baud clock */
-#define SB_BASE (SB_CLOCK/16)
-#define SB_MCR UART_MCR_OUT2 | UART_MCR_DTR | UART_MCR_RTS
-
-struct uart_port {
- int base;
-};
-#define UART_NPORTS 2
-struct uart_port uart_ports[] = {
- { COM1_PORT },
- { COM2_PORT },
-};
-struct uart_port *kgdb_uart_port;
-
-#define UART_IN(reg) inb_p(kgdb_uart_port->base + reg)
-#define UART_OUT(reg,v) outb_p((v), kgdb_uart_port->base + reg)
-
-/* Basic read/write functions for the UART */
-#define UART_LSR_RXCERR (UART_LSR_BI | UART_LSR_FE | UART_LSR_PE)
-static int kgdb_uart_getchar(void)
-{
- int lsr;
- int c = -1;
-
- while (c == -1) {
- lsr = UART_IN(UART_LSR);
- if (lsr & UART_LSR_DR)
- c = UART_IN(UART_RX);
- if ((lsr & UART_LSR_RXCERR))
- c = -1;
- }
- return c;
-}
-
-static void kgdb_uart_putchar(int c)
-{
- while ((UART_IN(UART_LSR) & UART_LSR_THRE) == 0)
- ;
- UART_OUT(UART_TX, c);
-}
-
-/*
- * Initialize UART to configured/requested values.
- * (But we don't interrupts yet, or interact w/serial.c)
- */
-static int kgdb_uart_setup(void)
-{
- int port;
- int lcr = 0;
- int bdiv = 0;
-
- if (kgdb_portnum >= UART_NPORTS) {
- KGDB_PRINTK("uart port %d invalid.\n", kgdb_portnum);
- return -1;
- }
-
- kgdb_uart_port = &uart_ports[kgdb_portnum];
-
- /* Init sequence from gdb_hook_interrupt */
- UART_IN(UART_RX);
- UART_OUT(UART_IER, 0);
-
- UART_IN(UART_RX); /* Serial driver comments say */
- UART_IN(UART_IIR); /* this clears interrupt regs */
- UART_IN(UART_MSR);
-
- /* Figure basic LCR values */
- switch (kgdb_bits) {
- case '7':
- lcr |= UART_LCR_WLEN7;
- break;
- default: case '8':
- lcr |= UART_LCR_WLEN8;
- break;
- }
- switch (kgdb_parity) {
- case 'O':
- lcr |= UART_LCR_PARITY;
- break;
- case 'E':
- lcr |= (UART_LCR_PARITY | UART_LCR_EPAR);
- break;
- default: break;
- }
-
- /* Figure the baud rate divisor */
- bdiv = (SB_BASE/kgdb_baud);
-
- /* Set the baud rate and LCR values */
- UART_OUT(UART_LCR, (lcr | UART_LCR_DLAB));
- UART_OUT(UART_DLL, (bdiv & 0xff));
- UART_OUT(UART_DLM, ((bdiv >> 8) & 0xff));
- UART_OUT(UART_LCR, lcr);
-
- /* Set the MCR */
- UART_OUT(UART_MCR, SB_MCR);
-
- /* Turn off FIFOs for now */
- UART_OUT(UART_FCR, 0);
-
- /* Setup complete: initialize function pointers */
- kgdb_getchar = kgdb_uart_getchar;
- kgdb_putchar = kgdb_uart_putchar;
-
- return 0;
-}
-#endif /* CONFIG_SH_KGDB */
-
static unsigned char heartbeat_bit_pos[] = { 8, 9, 10, 11, 12, 13, 14, 15 };
static struct resource heartbeat_resources[] = {
@@ -197,7 +50,6 @@ __initcall(se7751_devices_setup);
*/
struct sh_machine_vector mv_7751se __initmv = {
.mv_name = "7751 SolutionEngine",
- .mv_setup = sh7751se_setup,
.mv_nr_irqs = 72,
.mv_inb = sh7751se_inb,
diff --git a/arch/sh/boards/se/7780/Makefile b/arch/sh/boards/se/7780/Makefile
new file mode 100644
index 00000000000..6b88adae3ec
--- /dev/null
+++ b/arch/sh/boards/se/7780/Makefile
@@ -0,0 +1,10 @@
+#
+# Makefile for the HITACHI UL SolutionEngine 7780 specific parts of the kernel
+#
+# 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.
+#
+#
+
+obj-y := setup.o irq.o
diff --git a/arch/sh/boards/se/7780/irq.c b/arch/sh/boards/se/7780/irq.c
new file mode 100644
index 00000000000..3d0625c2d07
--- /dev/null
+++ b/arch/sh/boards/se/7780/irq.c
@@ -0,0 +1,89 @@
+/*
+ * linux/arch/sh/boards/se/7780/irq.c
+ *
+ * Copyright (C) 2006,2007 Nobuhiro Iwamatsu
+ *
+ * Hitachi UL SolutionEngine 7780 Support.
+ *
+ * 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/irq.h>
+#include <linux/interrupt.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <asm/se7780.h>
+
+#define INTC_INTMSK0 0xFFD00044
+#define INTC_INTMSKCLR0 0xFFD00064
+
+static void disable_se7780_irq(unsigned int irq)
+{
+ struct intc2_data *p = get_irq_chip_data(irq);
+ ctrl_outl(1 << p->msk_shift, INTC_INTMSK0 + p->msk_offset);
+}
+
+static void enable_se7780_irq(unsigned int irq)
+{
+ struct intc2_data *p = get_irq_chip_data(irq);
+ ctrl_outl(1 << p->msk_shift, INTC_INTMSKCLR0 + p->msk_offset);
+}
+
+static struct irq_chip se7780_irq_chip __read_mostly = {
+ .name = "SE7780",
+ .mask = disable_se7780_irq,
+ .unmask = enable_se7780_irq,
+ .mask_ack = disable_se7780_irq,
+};
+
+static struct intc2_data intc2_irq_table[] = {
+ { 2, 0, 31, 0, 31, 3 }, /* daughter board EXTINT1 */
+ { 4, 0, 30, 0, 30, 3 }, /* daughter board EXTINT2 */
+ { 6, 0, 29, 0, 29, 3 }, /* daughter board EXTINT3 */
+ { 8, 0, 28, 0, 28, 3 }, /* SMC 91C111 (LAN) */
+ { 10, 0, 27, 0, 27, 3 }, /* daughter board EXTINT4 */
+ { 4, 0, 30, 0, 30, 3 }, /* daughter board EXTINT5 */
+ { 2, 0, 31, 0, 31, 3 }, /* daughter board EXTINT6 */
+ { 2, 0, 31, 0, 31, 3 }, /* daughter board EXTINT7 */
+ { 2, 0, 31, 0, 31, 3 }, /* daughter board EXTINT8 */
+ { 0 , 0, 24, 0, 24, 3 }, /* SM501 */
+};
+
+/*
+ * Initialize IRQ setting
+ */
+void __init init_se7780_IRQ(void)
+{
+ int i ;
+
+ /* enable all interrupt at FPGA */
+ ctrl_outw(0, FPGA_INTMSK1);
+ /* mask SM501 interrupt */
+ ctrl_outw((ctrl_inw(FPGA_INTMSK1) | 0x0002), FPGA_INTMSK1);
+ /* enable all interrupt at FPGA */
+ ctrl_outw(0, FPGA_INTMSK2);
+
+ /* set FPGA INTSEL register */
+ /* FPGA + 0x06 */
+ ctrl_outw( ((IRQPIN_SM501 << IRQPOS_SM501) |
+ (IRQPIN_SMC91CX << IRQPOS_SMC91CX)), FPGA_INTSEL1);
+
+ /* FPGA + 0x08 */
+ ctrl_outw(((IRQPIN_EXTINT4 << IRQPOS_EXTINT4) |
+ (IRQPIN_EXTINT3 << IRQPOS_EXTINT3) |
+ (IRQPIN_EXTINT2 << IRQPOS_EXTINT2) |
+ (IRQPIN_EXTINT1 << IRQPOS_EXTINT1)), FPGA_INTSEL2);
+
+ /* FPGA + 0x0A */
+ ctrl_outw((IRQPIN_PCCPW << IRQPOS_PCCPW), FPGA_INTSEL3);
+
+ for (i = 0; i < ARRAY_SIZE(intc2_irq_table); i++) {
+ disable_irq_nosync(intc2_irq_table[i].irq);
+ set_irq_chip_and_handler_name( intc2_irq_table[i].irq, &se7780_irq_chip,
+ handle_level_irq, "level");
+ set_irq_chip_data( intc2_irq_table[i].irq, &intc2_irq_table[i] );
+ disable_se7780_irq(intc2_irq_table[i].irq);
+ }
+}
diff --git a/arch/sh/boards/se/7780/setup.c b/arch/sh/boards/se/7780/setup.c
new file mode 100644
index 00000000000..df7d08a24c9
--- /dev/null
+++ b/arch/sh/boards/se/7780/setup.c
@@ -0,0 +1,122 @@
+/*
+ * linux/arch/sh/boards/se/7780/setup.c
+ *
+ * Copyright (C) 2006,2007 Nobuhiro Iwamatsu
+ *
+ * Hitachi UL SolutionEngine 7780 Support.
+ *
+ * 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 <asm/machvec.h>
+#include <asm/se7780.h>
+#include <asm/io.h>
+
+/* Heartbeat */
+static unsigned char heartbeat_bit_pos[] = { 0, 1, 2, 3, 4, 5, 6, 7 };
+
+static struct resource heartbeat_resources[] = {
+ [0] = {
+ .start = PA_LED,
+ .end = PA_LED + ARRAY_SIZE(heartbeat_bit_pos) - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device heartbeat_device = {
+ .name = "heartbeat",
+ .id = -1,
+ .dev = {
+ .platform_data = heartbeat_bit_pos,
+ },
+ .num_resources = ARRAY_SIZE(heartbeat_resources),
+ .resource = heartbeat_resources,
+};
+
+/* SMC91x */
+static struct resource smc91x_eth_resources[] = {
+ [0] = {
+ .name = "smc91x-regs" ,
+ .start = PA_LAN + 0x300,
+ .end = PA_LAN + 0x300 + 0x10 ,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = SMC_IRQ,
+ .end = SMC_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device smc91x_eth_device = {
+ .name = "smc91x",
+ .id = 0,
+ .dev = {
+ .dma_mask = NULL, /* don't use dma */
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(smc91x_eth_resources),
+ .resource = smc91x_eth_resources,
+};
+
+static struct platform_device *se7780_devices[] __initdata = {
+ &heartbeat_device,
+ &smc91x_eth_device,
+};
+
+static int __init se7780_devices_setup(void)
+{
+ return platform_add_devices(se7780_devices,
+ ARRAY_SIZE(se7780_devices));
+}
+device_initcall(se7780_devices_setup);
+
+#define GPIO_PHCR 0xFFEA000E
+#define GPIO_PMSELR 0xFFEA0080
+#define GPIO_PECR 0xFFEA0008
+
+static void __init se7780_setup(char **cmdline_p)
+{
+ /* "SH-Linux" on LED Display */
+ ctrl_outw( 'S' , PA_LED_DISP + (DISP_SEL0_ADDR << 1) );
+ ctrl_outw( 'H' , PA_LED_DISP + (DISP_SEL1_ADDR << 1) );
+ ctrl_outw( '-' , PA_LED_DISP + (DISP_SEL2_ADDR << 1) );
+ ctrl_outw( 'L' , PA_LED_DISP + (DISP_SEL3_ADDR << 1) );
+ ctrl_outw( 'i' , PA_LED_DISP + (DISP_SEL4_ADDR << 1) );
+ ctrl_outw( 'n' , PA_LED_DISP + (DISP_SEL5_ADDR << 1) );
+ ctrl_outw( 'u' , PA_LED_DISP + (DISP_SEL6_ADDR << 1) );
+ ctrl_outw( 'x' , PA_LED_DISP + (DISP_SEL7_ADDR << 1) );
+
+ printk(KERN_INFO "Hitachi UL Solutions Engine 7780SE03 support.\n");
+
+ /*
+ * PCI REQ/GNT setting
+ * REQ0/GNT0 -> USB
+ * REQ1/GNT1 -> PC Card
+ * REQ2/GNT2 -> Serial ATA
+ * REQ3/GNT3 -> PCI slot
+ */
+ ctrl_outw(0x0213, FPGA_REQSEL);
+
+ /* GPIO setting */
+ ctrl_outw(0x0000, GPIO_PECR);
+ ctrl_outw(ctrl_inw(GPIO_PHCR)&0xfff3, GPIO_PHCR);
+ ctrl_outw(0x0c00, GPIO_PMSELR);
+
+ /* iVDR Power ON */
+ ctrl_outw(0x0001, FPGA_IVDRPW);
+}
+
+/*
+ * The Machine Vector
+ */
+struct sh_machine_vector mv_se7780 __initmv = {
+ .mv_name = "Solution Engine 7780" ,
+ .mv_setup = se7780_setup ,
+ .mv_nr_irqs = 111 ,
+ .mv_init_irq = init_se7780_IRQ,
+};
+ALIAS_MV(se7780)
diff --git a/arch/sh/configs/lboxre2_defconfig b/arch/sh/configs/lboxre2_defconfig
new file mode 100644
index 00000000000..be86414dcc8
--- /dev/null
+++ b/arch/sh/configs/lboxre2_defconfig
@@ -0,0 +1,1271 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.21-rc4
+# Sat Mar 24 22:04:27 2007
+#
+CONFIG_SUPERH=y
+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_IRQ_PROBE=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+# CONFIG_GENERIC_TIME is not set
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_SYSFS_DEPRECATED=y
+# CONFIG_RELAY is not set
+# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
+CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_EXTRA_PASS=y
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SHMEM=y
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+
+#
+# Block layer
+#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
+# System type
+#
+# CONFIG_SH_SOLUTION_ENGINE is not set
+# CONFIG_SH_7751_SOLUTION_ENGINE is not set
+# CONFIG_SH_7300_SOLUTION_ENGINE is not set
+# CONFIG_SH_7343_SOLUTION_ENGINE is not set
+# CONFIG_SH_73180_SOLUTION_ENGINE is not set
+# CONFIG_SH_7751_SYSTEMH is not set
+# CONFIG_SH_HP6XX is not set
+# CONFIG_SH_SATURN is not set
+# CONFIG_SH_DREAMCAST is not set
+# CONFIG_SH_MPC1211 is not set
+# CONFIG_SH_SH03 is not set
+# CONFIG_SH_SECUREEDGE5410 is not set
+# CONFIG_SH_HS7751RVOIP is not set
+# CONFIG_SH_7710VOIPGW is not set
+# CONFIG_SH_RTS7751R2D is not set
+# CONFIG_SH_HIGHLANDER is not set
+# CONFIG_SH_EDOSK7705 is not set
+# CONFIG_SH_SH4202_MICRODEV is not set
+# CONFIG_SH_LANDISK is not set
+# CONFIG_SH_TITAN is not set
+# CONFIG_SH_SHMIN is not set
+# CONFIG_SH_7206_SOLUTION_ENGINE is not set
+# CONFIG_SH_7619_SOLUTION_ENGINE is not set
+CONFIG_SH_LBOX_RE2=y
+# CONFIG_SH_UNKNOWN is not set
+
+#
+# Processor selection
+#
+CONFIG_CPU_SH4=y
+
+#
+# SH-2 Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7604 is not set
+# CONFIG_CPU_SUBTYPE_SH7619 is not set
+
+#
+# SH-2A Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7206 is not set
+
+#
+# SH-3 Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7300 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
+
+#
+# SH-4 Processor Support
+#
+# 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=y
+CONFIG_CPU_SUBTYPE_SH7751R=y
+# CONFIG_CPU_SUBTYPE_SH7760 is not set
+# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+
+#
+# ST40 Processor Support
+#
+# CONFIG_CPU_SUBTYPE_ST40STB1 is not set
+# CONFIG_CPU_SUBTYPE_ST40GX1 is not set
+
+#
+# SH-4A Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7770 is not set
+# CONFIG_CPU_SUBTYPE_SH7780 is not set
+# CONFIG_CPU_SUBTYPE_SH7785 is not set
+
+#
+# SH4AL-DSP Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+# CONFIG_CPU_SUBTYPE_SH7722 is not set
+
+#
+# Memory management options
+#
+CONFIG_MMU=y
+CONFIG_PAGE_OFFSET=0x80000000
+CONFIG_MEMORY_START=0x0c000000
+CONFIG_MEMORY_SIZE=0x04000000
+CONFIG_VSYSCALL=y
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB 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 is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+
+#
+# Cache configuration
+#
+# CONFIG_SH_DIRECT_MAPPED is not set
+# CONFIG_SH_WRITETHROUGH is not set
+# CONFIG_SH_OCRAM is not set
+
+#
+# Processor features
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_CPU_BIG_ENDIAN is not set
+CONFIG_SH_FPU=y
+# CONFIG_SH_DSP is not set
+# CONFIG_SH_STORE_QUEUES is not set
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_IPR_IRQ=y
+CONFIG_CPU_HAS_SR_RB=y
+CONFIG_CPU_HAS_PTEA=y
+
+#
+# Timer and clock configuration
+#
+CONFIG_SH_TMU=y
+CONFIG_SH_TIMER_IRQ=16
+# CONFIG_NO_IDLE_HZ is not set
+CONFIG_SH_PCLK_FREQ=40000000
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+
+#
+# DMA support
+#
+# CONFIG_SH_DMA is not set
+
+#
+# Companion Chips
+#
+# CONFIG_HD6446X_SERIES is not set
+
+#
+# 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=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_KEXEC=y
+# CONFIG_SMP is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+
+#
+# Boot options
+#
+CONFIG_ZERO_PAGE_OFFSET=0x00001000
+CONFIG_BOOT_LINK_OFFSET=0x00800000
+# CONFIG_UBC_WAKEUP is not set
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=ttySC1,115200 root=/dev/sda1"
+
+#
+# Bus options
+#
+CONFIG_ISA=y
+CONFIG_PCI=y
+CONFIG_SH_PCIDMA_NONCOHERENT=y
+CONFIG_PCI_AUTO=y
+CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+CONFIG_PCCARD=y
+CONFIG_PCMCIA_DEBUG=y
+CONFIG_PCMCIA=y
+CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_IOCTL=y
+CONFIG_CARDBUS=y
+
+#
+# PC-card bridges
+#
+CONFIG_YENTA=y
+CONFIG_YENTA_O2=y
+# CONFIG_YENTA_RICOH is not set
+# CONFIG_YENTA_TI is not set
+# CONFIG_YENTA_TOSHIBA is not set
+# CONFIG_PD6729 is not set
+# CONFIG_I82092 is not set
+# CONFIG_I82365 is not set
+# CONFIG_TCIC is not set
+CONFIG_PCMCIA_PROBE=y
+CONFIG_PCCARD_NONSTATIC=y
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_FLAT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options (EXPERIMENTAL)
+#
+# CONFIG_PM is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_ASK_IP_FIB_HASH=y
+# CONFIG_IP_FIB_TRIE is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_MULTIPLE_TABLES is not set
+# CONFIG_IP_ROUTE_MULTIPATH is not set
+# CONFIG_IP_ROUTE_VERBOSE is not set
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP 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=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+
+#
+# Core Netfilter Configuration
+#
+# CONFIG_NETFILTER_NETLINK is not set
+# CONFIG_NF_CONNTRACK_ENABLED is not set
+# CONFIG_NETFILTER_XTABLES is not set
+
+#
+# IP: Netfilter Configuration
+#
+# CONFIG_IP_NF_QUEUE is not set
+# CONFIG_IP_NF_IPTABLES is not set
+# CONFIG_IP_NF_ARPTABLES is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE 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
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+# CONFIG_PNP is not set
+# CONFIG_PNPACPI is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# Misc devices
+#
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AHA152X is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
+# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_IN2000 is not set
+# CONFIG_SCSI_ARCMSR is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_HPTIOP is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_DTC3280 is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_GENERIC_NCR5380 is not set
+# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_NCR53C406A is not set
+# CONFIG_SCSI_STEX is not set
+# CONFIG_SCSI_SYM53C8XX_2 is not set
+# CONFIG_SCSI_IPR is not set
+# CONFIG_SCSI_PAS16 is not set
+# CONFIG_SCSI_PSI240I is not set
+# CONFIG_SCSI_QLOGIC_FAS is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI is not set
+# CONFIG_SCSI_LPFC is not set
+# CONFIG_SCSI_SYM53C416 is not set
+# CONFIG_SCSI_DC395x is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_NSP32 is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_SRP is not set
+
+#
+# PCMCIA SCSI adapter support
+#
+# CONFIG_PCMCIA_AHA152X is not set
+# CONFIG_PCMCIA_FDOMAIN is not set
+# CONFIG_PCMCIA_NINJA_SCSI is not set
+# CONFIG_PCMCIA_QLOGIC is not set
+# CONFIG_PCMCIA_SYM53C500 is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+CONFIG_ATA=y
+# CONFIG_ATA_NONSTANDARD is not set
+# CONFIG_SATA_AHCI is not set
+# CONFIG_SATA_SVW is not set
+# CONFIG_ATA_PIIX is not set
+# CONFIG_SATA_MV is not set
+# CONFIG_SATA_NV is not set
+# CONFIG_PDC_ADMA is not set
+# CONFIG_SATA_QSTOR is not set
+# CONFIG_SATA_PROMISE is not set
+# CONFIG_SATA_SX4 is not set
+# CONFIG_SATA_SIL is not set
+# CONFIG_SATA_SIL24 is not set
+# CONFIG_SATA_SIS is not set
+# CONFIG_SATA_ULI is not set
+# CONFIG_SATA_VIA is not set
+# CONFIG_SATA_VITESSE is not set
+# CONFIG_SATA_INIC162X is not set
+# CONFIG_PATA_ALI is not set
+# CONFIG_PATA_AMD is not set
+# CONFIG_PATA_ARTOP is not set
+# CONFIG_PATA_ATIIXP is not set
+# CONFIG_PATA_CMD64X is not set
+# CONFIG_PATA_CS5520 is not set
+# CONFIG_PATA_CS5530 is not set
+# CONFIG_PATA_CYPRESS is not set
+# CONFIG_PATA_EFAR is not set
+# CONFIG_ATA_GENERIC is not set
+# CONFIG_PATA_HPT366 is not set
+# CONFIG_PATA_HPT37X is not set
+# CONFIG_PATA_HPT3X2N is not set
+# CONFIG_PATA_HPT3X3 is not set
+# CONFIG_PATA_IT821X is not set
+# CONFIG_PATA_IT8213 is not set
+# CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_LEGACY is not set
+# CONFIG_PATA_TRIFLEX is not set
+# CONFIG_PATA_MARVELL is not set
+# CONFIG_PATA_MPIIX is not set
+# CONFIG_PATA_OLDPIIX is not set
+# CONFIG_PATA_NETCELL is not set
+# CONFIG_PATA_NS87410 is not set
+# CONFIG_PATA_OPTI is not set
+# CONFIG_PATA_OPTIDMA is not set
+# CONFIG_PATA_PCMCIA is not set
+# CONFIG_PATA_PDC_OLD is not set
+# CONFIG_PATA_QDI is not set
+# CONFIG_PATA_RADISYS is not set
+# CONFIG_PATA_RZ1000 is not set
+# CONFIG_PATA_SC1200 is not set
+# CONFIG_PATA_SERVERWORKS is not set
+# CONFIG_PATA_PDC2027X is not set
+# CONFIG_PATA_SIL680 is not set
+# CONFIG_PATA_SIS is not set
+# CONFIG_PATA_VIA is not set
+# CONFIG_PATA_WINBOND is not set
+# CONFIG_PATA_WINBOND_VLB is not set
+CONFIG_PATA_PLATFORM=y
+
+#
+# Old CD-ROM drivers (not SCSI, not IDE)
+#
+# CONFIG_CD_NO_IDESCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+# CONFIG_FUSION_SPI is not set
+# CONFIG_FUSION_FC is not set
+# CONFIG_FUSION_SAS is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_STNIC is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_SMC91X is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_AT1700 is not set
+# CONFIG_DEPCA is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_ISA is not set
+CONFIG_NET_PCI=y
+# CONFIG_PCNET32 is not set
+# CONFIG_AMD8111_ETH is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_AC3200 is not set
+# CONFIG_APRICOT is not set
+# CONFIG_B44 is not set
+# CONFIG_FORCEDETH is not set
+# CONFIG_CS89x0 is not set
+# CONFIG_DGRS is not set
+# CONFIG_EEPRO100 is not set
+# CONFIG_E100 is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+CONFIG_NE2K_PCI=y
+# CONFIG_8139CP is not set
+CONFIG_8139TOO=y
+CONFIG_8139TOO_PIO=y
+CONFIG_8139TOO_TUNE_TWISTER=y
+# CONFIG_8139TOO_8129 is not set
+# CONFIG_8139_OLD_RX_RESET is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_TLAN is not set
+# CONFIG_VIA_RHINE is not set
+# CONFIG_SC92031 is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_VIA_VELOCITY is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+# CONFIG_QLA3XXX is not set
+# CONFIG_ATL1 is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_CHELSIO_T1 is not set
+# CONFIG_CHELSIO_T3 is not set
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+# CONFIG_MYRI10GE is not set
+# CONFIG_NETXEN_NIC is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# PCMCIA network device support
+#
+CONFIG_NET_PCMCIA=y
+# CONFIG_PCMCIA_3C589 is not set
+# CONFIG_PCMCIA_3C574 is not set
+# CONFIG_PCMCIA_FMVJ18X is not set
+CONFIG_PCMCIA_PCNET=y
+# CONFIG_PCMCIA_NMCLAN is not set
+# CONFIG_PCMCIA_SMC91C92 is not set
+# CONFIG_PCMCIA_XIRC2PS is not set
+# CONFIG_PCMCIA_AXNET is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NET_FC is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK 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_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+# 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=2
+CONFIG_SERIAL_SH_SCI_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_DRM is not set
+
+#
+# PCMCIA character devices
+#
+# CONFIG_SYNCLINK_CS is not set
+# CONFIG_CARDMAN_4000 is not set
+# CONFIG_CARDMAN_4040 is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+# CONFIG_FB is not set
+
+#
+# Console display driver support
+#
+# CONFIG_MDA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# HID Devices
+#
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+# CONFIG_USB is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+
+#
+# RTC drivers
+#
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_SH is not set
+# CONFIG_RTC_DRV_TEST is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
+# Auxiliary Display support
+#
+
+#
+# Virtualization
+#
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4DEV_FS is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# 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_MINIX_FS is not set
+CONFIG_ROMFS_FS=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+# CONFIG_PROC_KCORE is not set
+CONFIG_PROC_SYSCTL=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_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+# CONFIG_NFS_FS is not set
+# CONFIG_NFSD is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Distributed Lock Manager
+#
+# CONFIG_DLM is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_SH_STANDARD_BIOS=y
+# CONFIG_EARLY_SCIF_CONSOLE is not set
+# CONFIG_EARLY_PRINTK is not set
+# CONFIG_SH_KGDB is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
diff --git a/arch/sh/configs/r7780rp_defconfig b/arch/sh/configs/r7780rp_defconfig
index 2b75b4896ba..48c6a2194c9 100644
--- a/arch/sh/configs/r7780rp_defconfig
+++ b/arch/sh/configs/r7780rp_defconfig
@@ -1,10 +1,11 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.19
-# Wed Dec 6 11:59:38 2006
+# Linux kernel version: 2.6.21-rc7
+# Tue May 1 12:28:39 2007
#
CONFIG_SUPERH=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_BUG=y
CONFIG_GENERIC_FIND_NEXT_BIT=y
CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_HARDIRQS=y
@@ -13,6 +14,8 @@ CONFIG_GENERIC_CALIBRATE_DELAY=y
# CONFIG_GENERIC_TIME is not set
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -31,6 +34,7 @@ CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
# CONFIG_POSIX_MQUEUE is not set
CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
@@ -41,7 +45,7 @@ CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
# CONFIG_SYSFS_DEPRECATED is not set
# CONFIG_RELAY is not set
-CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_BLK_DEV_INITRD is not set
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
CONFIG_EMBEDDED=y
@@ -99,23 +103,23 @@ CONFIG_DEFAULT_IOSCHED="noop"
# System type
#
# CONFIG_SH_SOLUTION_ENGINE is not set
+# CONFIG_SH_7722_SOLUTION_ENGINE is not set
# CONFIG_SH_7751_SOLUTION_ENGINE is not set
+# CONFIG_SH_7780_SOLUTION_ENGINE is not set
# CONFIG_SH_7300_SOLUTION_ENGINE is not set
# CONFIG_SH_7343_SOLUTION_ENGINE is not set
# CONFIG_SH_73180_SOLUTION_ENGINE is not set
# CONFIG_SH_7751_SYSTEMH is not set
# CONFIG_SH_HP6XX is not set
-# CONFIG_SH_EC3104 is not set
# CONFIG_SH_SATURN is not set
# CONFIG_SH_DREAMCAST is not set
-# CONFIG_SH_BIGSUR is not set
# CONFIG_SH_MPC1211 is not set
# CONFIG_SH_SH03 is not set
# CONFIG_SH_SECUREEDGE5410 is not set
# CONFIG_SH_HS7751RVOIP is not set
# CONFIG_SH_7710VOIPGW is not set
# CONFIG_SH_RTS7751R2D is not set
-CONFIG_SH_R7780RP=y
+CONFIG_SH_HIGHLANDER=y
# CONFIG_SH_EDOSK7705 is not set
# CONFIG_SH_SH4202_MICRODEV is not set
# CONFIG_SH_LANDISK is not set
@@ -123,7 +127,11 @@ CONFIG_SH_R7780RP=y
# CONFIG_SH_SHMIN is not set
# CONFIG_SH_7206_SOLUTION_ENGINE is not set
# CONFIG_SH_7619_SOLUTION_ENGINE is not set
+# CONFIG_SH_LBOX_RE2 is not set
# CONFIG_SH_UNKNOWN is not set
+CONFIG_SH_R7780RP=y
+# CONFIG_SH_R7780MP is not set
+# CONFIG_SH_R7785RP is not set
#
# Processor selection
@@ -152,6 +160,7 @@ CONFIG_CPU_SH4A=y
# 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
#
# SH-4 Processor Support
@@ -183,6 +192,7 @@ CONFIG_CPU_SUBTYPE_SH7780=y
#
# CONFIG_CPU_SUBTYPE_SH73180 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
+# CONFIG_CPU_SUBTYPE_SH7722 is not set
#
# Memory management options
@@ -193,6 +203,8 @@ CONFIG_MEMORY_START=0x08000000
CONFIG_MEMORY_SIZE=0x08000000
# CONFIG_32BIT is not set
CONFIG_VSYSCALL=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_PAGE_SIZE_4KB=y
# CONFIG_PAGE_SIZE_8KB is not set
# CONFIG_PAGE_SIZE_64KB is not set
@@ -210,6 +222,7 @@ CONFIG_FLAT_NODE_MEM_MAP=y
# CONFIG_SPARSEMEM_STATIC is not set
CONFIG_SPLIT_PTLOCK_CPUS=4
# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
#
# Cache configuration
@@ -226,20 +239,15 @@ CONFIG_CPU_LITTLE_ENDIAN=y
CONFIG_SH_FPU=y
# CONFIG_SH_DSP is not set
CONFIG_SH_STORE_QUEUES=y
+CONFIG_SPECULATIVE_EXECUTION=y
CONFIG_CPU_HAS_INTEVT=y
CONFIG_CPU_HAS_INTC2_IRQ=y
CONFIG_CPU_HAS_SR_RB=y
-CONFIG_CPU_HAS_PTEA=y
#
-# Timer support
+# Timer and clock configuration
#
CONFIG_SH_TMU=y
-
-#
-# R7780RP options
-#
-CONFIG_SH_R7780MP=y
CONFIG_SH_TIMER_IRQ=28
CONFIG_NO_IDLE_HZ=y
CONFIG_SH_PCLK_FREQ=32000000
@@ -262,6 +270,7 @@ CONFIG_SH_PCLK_FREQ=32000000
#
# Additional SuperH Device Drivers
#
+# CONFIG_HEARTBEAT is not set
CONFIG_PUSH_SWITCH=y
#
@@ -269,9 +278,11 @@ CONFIG_PUSH_SWITCH=y
#
# CONFIG_HZ_100 is not set
CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
# CONFIG_HZ_1000 is not set
CONFIG_HZ=250
CONFIG_KEXEC=y
+# CONFIG_CRASH_DUMP is not set
# CONFIG_SMP is not set
# CONFIG_PREEMPT_NONE is not set
# CONFIG_PREEMPT_VOLUNTARY is not set
@@ -294,7 +305,6 @@ CONFIG_PCI=y
CONFIG_SH_PCIDMA_NONCOHERENT=y
CONFIG_PCI_AUTO=y
CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
-# CONFIG_PCI_MULTITHREAD_PROBE is not set
# CONFIG_PCI_DEBUG is not set
#
@@ -334,6 +344,7 @@ CONFIG_UNIX=y
CONFIG_XFRM=y
# CONFIG_XFRM_USER is not set
# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
# CONFIG_NET_KEY is not set
CONFIG_INET=y
# CONFIG_IP_MULTICAST is not set
@@ -425,6 +436,7 @@ CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
CONFIG_FW_LOADER=m
# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
# CONFIG_SYS_HYPERVISOR is not set
#
@@ -445,6 +457,7 @@ CONFIG_FW_LOADER=m
#
# Plug and Play support
#
+# CONFIG_PNPACPI is not set
#
# Block devices
@@ -461,7 +474,6 @@ CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=4096
CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
-# CONFIG_BLK_DEV_INITRD is not set
# CONFIG_CDROM_PKTCDVD is not set
# CONFIG_ATA_OVER_ETH is not set
@@ -481,6 +493,7 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
#
# CONFIG_RAID_ATTRS is not set
CONFIG_SCSI=y
+# CONFIG_SCSI_TGT is not set
# CONFIG_SCSI_NETLINK is not set
CONFIG_SCSI_PROC_FS=y
@@ -500,6 +513,7 @@ CONFIG_CHR_DEV_SG=m
# CONFIG_SCSI_MULTI_LUN is not set
# CONFIG_SCSI_CONSTANTS is not set
# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
#
# SCSI Transports
@@ -544,11 +558,13 @@ CONFIG_CHR_DEV_SG=m
# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_NSP32 is not set
# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_SRP is not set
#
# Serial ATA (prod) and Parallel ATA (experimental) drivers
#
CONFIG_ATA=y
+# CONFIG_ATA_NONSTANDARD is not set
# CONFIG_SATA_AHCI is not set
# CONFIG_SATA_SVW is not set
# CONFIG_ATA_PIIX is not set
@@ -564,6 +580,7 @@ CONFIG_SATA_SIL=y
# CONFIG_SATA_ULI is not set
# CONFIG_SATA_VIA is not set
# CONFIG_SATA_VITESSE is not set
+# CONFIG_SATA_INIC162X is not set
# CONFIG_PATA_ALI is not set
# CONFIG_PATA_AMD is not set
# CONFIG_PATA_ARTOP is not set
@@ -579,6 +596,7 @@ CONFIG_SATA_SIL=y
# CONFIG_PATA_HPT3X2N is not set
# CONFIG_PATA_HPT3X3 is not set
# CONFIG_PATA_IT821X is not set
+# CONFIG_PATA_IT8213 is not set
# CONFIG_PATA_JMICRON is not set
# CONFIG_PATA_TRIFLEX is not set
# CONFIG_PATA_MARVELL is not set
@@ -685,6 +703,7 @@ CONFIG_8139TOO_8129=y
CONFIG_VIA_RHINE=m
CONFIG_VIA_RHINE_MMIO=y
# CONFIG_VIA_RHINE_NAPI is not set
+# CONFIG_SC92031 is not set
#
# Ethernet (1000 Mbit)
@@ -707,11 +726,13 @@ CONFIG_R8169=y
# CONFIG_TIGON3 is not set
# CONFIG_BNX2 is not set
# CONFIG_QLA3XXX is not set
+# CONFIG_ATL1 is not set
#
# Ethernet (10000 Mbit)
#
# CONFIG_CHELSIO_T1 is not set
+# CONFIG_CHELSIO_T3 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
# CONFIG_MYRI10GE is not set
@@ -889,10 +910,16 @@ CONFIG_HWMON=y
# CONFIG_HWMON_VID is not set
# CONFIG_SENSORS_ABITUGURU is not set
# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_PC87427 is not set
# CONFIG_SENSORS_VT1211 is not set
# CONFIG_HWMON_DEBUG_CHIP is not set
#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -905,9 +932,8 @@ CONFIG_HWMON=y
#
# Graphics support
#
-CONFIG_FIRMWARE_EDID=y
-# CONFIG_FB is not set
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+# CONFIG_FB is not set
#
# Sound
@@ -923,9 +949,8 @@ CONFIG_SOUND=m
# Open Sound System
#
CONFIG_SOUND_PRIME=m
-# CONFIG_OSS_OBSOLETE_DRIVER is not set
+# CONFIG_OBSOLETE_OSS is not set
# CONFIG_SOUND_BT878 is not set
-# CONFIG_SOUND_ES1371 is not set
# CONFIG_SOUND_ICH is not set
# CONFIG_SOUND_TRIDENT is not set
# CONFIG_SOUND_MSNDCLAS is not set
@@ -933,6 +958,12 @@ CONFIG_SOUND_PRIME=m
# CONFIG_SOUND_VIA82CXXX is not set
#
+# HID Devices
+#
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+
+#
# USB support
#
CONFIG_USB_ARCH_HAS_HCD=y
@@ -1017,6 +1048,14 @@ CONFIG_RTC_DRV_SH=y
#
#
+# Auxiliary Display support
+#
+
+#
+# Virtualization
+#
+
+#
# File systems
#
CONFIG_EXT2_FS=y
@@ -1175,6 +1214,11 @@ CONFIG_NLS_ISO8859_1=y
# CONFIG_NLS_UTF8 is not set
#
+# Distributed Lock Manager
+#
+# CONFIG_DLM is not set
+
+#
# Profiling support
#
CONFIG_PROFILING=y
@@ -1184,19 +1228,22 @@ CONFIG_OPROFILE=m
# Kernel hacking
#
CONFIG_TRACE_IRQFLAGS_SUPPORT=y
-CONFIG_PRINTK_TIME=y
+# CONFIG_PRINTK_TIME is not set
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_MAGIC_SYSRQ=y
# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
CONFIG_LOG_BUF_SHIFT=14
CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
# CONFIG_DEBUG_SLAB is not set
# CONFIG_DEBUG_PREEMPT is not set
# CONFIG_DEBUG_SPINLOCK is not set
# CONFIG_DEBUG_MUTEXES is not set
-# CONFIG_DEBUG_RWSEMS is not set
# CONFIG_DEBUG_LOCK_ALLOC is not set
# CONFIG_PROVE_LOCKING is not set
# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
@@ -1204,19 +1251,19 @@ CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_DEBUG_KOBJECT is not set
CONFIG_DEBUG_BUGVERBOSE=y
CONFIG_DEBUG_INFO=y
-CONFIG_DEBUG_FS=y
# CONFIG_DEBUG_VM is not set
# CONFIG_DEBUG_LIST is not set
-CONFIG_FRAME_POINTER=y
+# CONFIG_FRAME_POINTER is not set
CONFIG_FORCED_INLINING=y
-# CONFIG_HEADERS_CHECK is not set
# CONFIG_RCU_TORTURE_TEST is not set
-# CONFIG_SH_STANDARD_BIOS is not set
+# CONFIG_FAULT_INJECTION is not set
+CONFIG_SH_STANDARD_BIOS=y
# CONFIG_EARLY_SCIF_CONSOLE is not set
+CONFIG_EARLY_PRINTK=y
CONFIG_DEBUG_STACKOVERFLOW=y
# CONFIG_DEBUG_STACK_USAGE is not set
# CONFIG_4KSTACKS is not set
-# CONFIG_KGDB is not set
+# CONFIG_SH_KGDB is not set
#
# Security options
@@ -1233,6 +1280,7 @@ CONFIG_CRYPTO_BLKCIPHER=y
CONFIG_CRYPTO_HASH=y
CONFIG_CRYPTO_MANAGER=y
CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_XCBC is not set
# CONFIG_CRYPTO_NULL is not set
# CONFIG_CRYPTO_MD4 is not set
CONFIG_CRYPTO_MD5=y
@@ -1241,9 +1289,13 @@ CONFIG_CRYPTO_MD5=y
# CONFIG_CRYPTO_SHA512 is not set
# CONFIG_CRYPTO_WP512 is not set
# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
CONFIG_CRYPTO_ECB=m
CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_PCBC=m
+# CONFIG_CRYPTO_LRW is not set
CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
# CONFIG_CRYPTO_BLOWFISH is not set
# CONFIG_CRYPTO_TWOFISH is not set
# CONFIG_CRYPTO_SERPENT is not set
@@ -1257,6 +1309,7 @@ CONFIG_CRYPTO_DES=y
# CONFIG_CRYPTO_DEFLATE is not set
# CONFIG_CRYPTO_MICHAEL_MIC is not set
# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
# CONFIG_CRYPTO_TEST is not set
#
@@ -1266,7 +1319,10 @@ CONFIG_CRYPTO_DES=y
#
# Library routines
#
+CONFIG_BITREVERSE=y
# CONFIG_CRC_CCITT is not set
# CONFIG_CRC16 is not set
CONFIG_CRC32=y
# CONFIG_LIBCRC32C is not set
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
diff --git a/arch/sh/configs/r7785rp_defconfig b/arch/sh/configs/r7785rp_defconfig
new file mode 100644
index 00000000000..0f5ec649daf
--- /dev/null
+++ b/arch/sh/configs/r7785rp_defconfig
@@ -0,0 +1,1334 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.21-rc3
+# Mon Mar 12 14:26:33 2007
+#
+CONFIG_SUPERH=y
+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_IRQ_PROBE=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+# CONFIG_GENERIC_TIME is not set
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+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_UTS_NS is not set
+# CONFIG_AUDIT is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+# CONFIG_SYSFS_DEPRECATED is not set
+# CONFIG_RELAY is not set
+# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
+CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_ALL=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+# CONFIG_FUTEX is not set
+# CONFIG_EPOLL is not set
+CONFIG_SHMEM=y
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+
+#
+# Block layer
+#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF 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"
+
+#
+# System type
+#
+# CONFIG_SH_SOLUTION_ENGINE is not set
+# CONFIG_SH_7751_SOLUTION_ENGINE is not set
+# CONFIG_SH_7300_SOLUTION_ENGINE is not set
+# CONFIG_SH_7343_SOLUTION_ENGINE is not set
+# CONFIG_SH_73180_SOLUTION_ENGINE is not set
+# CONFIG_SH_7751_SYSTEMH is not set
+# CONFIG_SH_HP6XX is not set
+# CONFIG_SH_SATURN is not set
+# CONFIG_SH_DREAMCAST is not set
+# CONFIG_SH_MPC1211 is not set
+# CONFIG_SH_SH03 is not set
+# CONFIG_SH_SECUREEDGE5410 is not set
+# CONFIG_SH_HS7751RVOIP is not set
+# CONFIG_SH_7710VOIPGW is not set
+# CONFIG_SH_RTS7751R2D is not set
+CONFIG_SH_HIGHLANDER=y
+# CONFIG_SH_EDOSK7705 is not set
+# CONFIG_SH_SH4202_MICRODEV is not set
+# CONFIG_SH_LANDISK is not set
+# CONFIG_SH_TITAN is not set
+# CONFIG_SH_SHMIN is not set
+# CONFIG_SH_7206_SOLUTION_ENGINE is not set
+# CONFIG_SH_7619_SOLUTION_ENGINE is not set
+# CONFIG_SH_UNKNOWN is not set
+# CONFIG_SH_R7780RP is not set
+# CONFIG_SH_R7780MP is not set
+CONFIG_SH_R7785RP=y
+
+#
+# Processor selection
+#
+CONFIG_CPU_SH4=y
+CONFIG_CPU_SH4A=y
+CONFIG_CPU_SHX2=y
+
+#
+# SH-2 Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7604 is not set
+# CONFIG_CPU_SUBTYPE_SH7619 is not set
+
+#
+# SH-2A Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7206 is not set
+
+#
+# SH-3 Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7300 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
+
+#
+# SH-4 Processor Support
+#
+# 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
+
+#
+# ST40 Processor Support
+#
+# CONFIG_CPU_SUBTYPE_ST40STB1 is not set
+# CONFIG_CPU_SUBTYPE_ST40GX1 is not set
+
+#
+# SH-4A Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7770 is not set
+# CONFIG_CPU_SUBTYPE_SH7780 is not set
+CONFIG_CPU_SUBTYPE_SH7785=y
+
+#
+# SH4AL-DSP Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+# CONFIG_CPU_SUBTYPE_SH7722 is not set
+
+#
+# Memory management options
+#
+CONFIG_MMU=y
+CONFIG_PAGE_OFFSET=0x80000000
+CONFIG_MEMORY_START=0x08000000
+CONFIG_MEMORY_SIZE=0x08000000
+CONFIG_32BIT=y
+# CONFIG_X2TLB is not set
+CONFIG_VSYSCALL=y
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+# CONFIG_HUGETLB_PAGE_SIZE_64K is not set
+# CONFIG_HUGETLB_PAGE_SIZE_256K is not set
+CONFIG_HUGETLB_PAGE_SIZE_1MB=y
+# CONFIG_HUGETLB_PAGE_SIZE_4MB is not set
+# CONFIG_HUGETLB_PAGE_SIZE_64MB 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 is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+
+#
+# Cache configuration
+#
+# CONFIG_SH_DIRECT_MAPPED is not set
+# CONFIG_SH_WRITETHROUGH is not set
+# CONFIG_SH_OCRAM is not set
+
+#
+# Processor features
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_CPU_BIG_ENDIAN is not set
+CONFIG_SH_FPU=y
+# CONFIG_SH_DSP is not set
+CONFIG_SH_STORE_QUEUES=y
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_INTC2_IRQ=y
+CONFIG_CPU_HAS_SR_RB=y
+CONFIG_CPU_HAS_PTEA=y
+
+#
+# Timer and clock configuration
+#
+CONFIG_SH_TMU=y
+CONFIG_SH_TIMER_IRQ=28
+CONFIG_NO_IDLE_HZ=y
+CONFIG_SH_PCLK_FREQ=50000000
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+
+#
+# DMA support
+#
+# CONFIG_SH_DMA is not set
+
+#
+# Companion Chips
+#
+# CONFIG_HD6446X_SERIES is not set
+
+#
+# Additional SuperH Device Drivers
+#
+CONFIG_HEARTBEAT=y
+CONFIG_PUSH_SWITCH=y
+
+#
+# Kernel features
+#
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_KEXEC=y
+# CONFIG_SMP is not set
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_PREEMPT_BKL=y
+
+#
+# Boot options
+#
+CONFIG_ZERO_PAGE_OFFSET=0x00001000
+CONFIG_BOOT_LINK_OFFSET=0x00800000
+# CONFIG_UBC_WAKEUP is not set
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=ttySC0,115200 root=/dev/sda1"
+
+#
+# Bus options
+#
+CONFIG_PCI=y
+CONFIG_SH_PCIDMA_NONCOHERENT=y
+CONFIG_PCI_AUTO=y
+CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
+# CONFIG_PCI_DEBUG is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_FLAT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options (EXPERIMENTAL)
+#
+# CONFIG_PM is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_ASK_IP_FIB_HASH=y
+# CONFIG_IP_FIB_TRIE is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_MULTIPLE_TABLES is not set
+# CONFIG_IP_ROUTE_MULTIPATH is not set
+# CONFIG_IP_ROUTE_VERBOSE is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP 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=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# 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_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+CONFIG_BRIDGE=m
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+CONFIG_LLC=m
+# 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
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+CONFIG_WIRELESS_EXT=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=m
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+# CONFIG_PNPACPI is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# 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_SX8 is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# Misc devices
+#
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+CONFIG_CHR_DEV_SG=m
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
+# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_ARCMSR is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_HPTIOP is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_STEX is not set
+# CONFIG_SCSI_SYM53C8XX_2 is not set
+# CONFIG_SCSI_IPR is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI is not set
+# CONFIG_SCSI_LPFC is not set
+# CONFIG_SCSI_DC395x is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_NSP32 is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_SRP is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+CONFIG_ATA=y
+# CONFIG_ATA_NONSTANDARD is not set
+# CONFIG_SATA_AHCI is not set
+# CONFIG_SATA_SVW is not set
+# CONFIG_ATA_PIIX is not set
+# CONFIG_SATA_MV is not set
+# CONFIG_SATA_NV is not set
+# CONFIG_PDC_ADMA is not set
+# CONFIG_SATA_QSTOR is not set
+# CONFIG_SATA_PROMISE is not set
+# CONFIG_SATA_SX4 is not set
+CONFIG_SATA_SIL=y
+# CONFIG_SATA_SIL24 is not set
+# CONFIG_SATA_SIS is not set
+# CONFIG_SATA_ULI is not set
+# CONFIG_SATA_VIA is not set
+# CONFIG_SATA_VITESSE is not set
+# CONFIG_SATA_INIC162X is not set
+# CONFIG_PATA_ALI is not set
+# CONFIG_PATA_AMD is not set
+# CONFIG_PATA_ARTOP is not set
+# CONFIG_PATA_ATIIXP is not set
+# CONFIG_PATA_CMD64X is not set
+# CONFIG_PATA_CS5520 is not set
+# CONFIG_PATA_CS5530 is not set
+# CONFIG_PATA_CYPRESS is not set
+# CONFIG_PATA_EFAR is not set
+# CONFIG_ATA_GENERIC is not set
+# CONFIG_PATA_HPT366 is not set
+# CONFIG_PATA_HPT37X is not set
+# CONFIG_PATA_HPT3X2N is not set
+# CONFIG_PATA_HPT3X3 is not set
+# CONFIG_PATA_IT821X is not set
+# CONFIG_PATA_IT8213 is not set
+# CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_TRIFLEX is not set
+# CONFIG_PATA_MARVELL is not set
+# CONFIG_PATA_MPIIX is not set
+# CONFIG_PATA_OLDPIIX is not set
+# CONFIG_PATA_NETCELL is not set
+# CONFIG_PATA_NS87410 is not set
+# CONFIG_PATA_OPTI is not set
+# CONFIG_PATA_OPTIDMA is not set
+# CONFIG_PATA_PDC_OLD is not set
+# CONFIG_PATA_RADISYS is not set
+# CONFIG_PATA_RZ1000 is not set
+# CONFIG_PATA_SC1200 is not set
+# CONFIG_PATA_SERVERWORKS is not set
+# CONFIG_PATA_PDC2027X is not set
+# CONFIG_PATA_SIL680 is not set
+# CONFIG_PATA_SIS is not set
+# CONFIG_PATA_VIA is not set
+# CONFIG_PATA_WINBOND is not set
+CONFIG_PATA_PLATFORM=y
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+# CONFIG_FUSION_SPI is not set
+# CONFIG_FUSION_FC is not set
+# CONFIG_FUSION_SAS is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_STNIC is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_SMC91X is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_PCI is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+CONFIG_R8169=y
+# CONFIG_R8169_NAPI is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+# CONFIG_QLA3XXX is not set
+# CONFIG_ATL1 is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_CHELSIO_T1 is not set
+# CONFIG_CHELSIO_T3 is not set
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+# CONFIG_MYRI10GE is not set
+# CONFIG_NETXEN_NIC is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+CONFIG_NET_RADIO=y
+# CONFIG_NET_WIRELESS_RTNETLINK is not set
+
+#
+# Obsolete Wireless cards support (pre-802.11)
+#
+# CONFIG_STRIP is not set
+
+#
+# Wireless 802.11b ISA/PCI cards support
+#
+# CONFIG_IPW2100 is not set
+# CONFIG_IPW2200 is not set
+# CONFIG_HERMES is not set
+# CONFIG_ATMEL is not set
+
+#
+# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
+#
+# CONFIG_PRISM54 is not set
+# CONFIG_HOSTAP is not set
+CONFIG_NET_WIRELESS=y
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NET_FC is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+# CONFIG_SERIO_SERPORT is not set
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# 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_SERIAL_JSM is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_CFB_FILLRECT is not set
+# CONFIG_FB_CFB_COPYAREA is not set
+# CONFIG_FB_CFB_IMAGEBLIT is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frambuffer hardware drivers
+#
+# CONFIG_FB_CIRRUS is not set
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+# CONFIG_FB_EPSON1355 is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_NVIDIA is not set
+# CONFIG_FB_RIVA is not set
+# CONFIG_FB_MATROX is not set
+# CONFIG_FB_RADEON is not set
+# CONFIG_FB_ATY128 is not set
+# CONFIG_FB_ATY is not set
+# CONFIG_FB_S3 is not set
+# CONFIG_FB_SAVAGE is not set
+# CONFIG_FB_SIS is not set
+# CONFIG_FB_NEOMAGIC is not set
+# CONFIG_FB_KYRO is not set
+# CONFIG_FB_3DFX is not set
+# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_VIRTUAL is not set
+
+#
+# Logo configuration
+#
+# CONFIG_LOGO is not set
+
+#
+# Sound
+#
+CONFIG_SOUND=m
+
+#
+# Advanced Linux Sound Architecture
+#
+# CONFIG_SND is not set
+
+#
+# Open Sound System
+#
+CONFIG_SOUND_PRIME=m
+# CONFIG_OBSOLETE_OSS is not set
+# CONFIG_SOUND_BT878 is not set
+# CONFIG_SOUND_ICH is not set
+# CONFIG_SOUND_TRIDENT is not set
+# CONFIG_SOUND_MSNDCLAS is not set
+# CONFIG_SOUND_MSNDPIN is not set
+# CONFIG_SOUND_VIA82CXXX is not set
+
+#
+# HID Devices
+#
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+# CONFIG_USB is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+
+#
+# RTC drivers
+#
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+CONFIG_RTC_DRV_SH=y
+# CONFIG_RTC_DRV_TEST is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
+# Auxiliary Display support
+#
+
+#
+# Virtualization
+#
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4DEV_FS is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+CONFIG_MINIX_FS=y
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=m
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+CONFIG_NTFS_FS=y
+# CONFIG_NTFS_DEBUG is not set
+CONFIG_NTFS_RW=y
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+CONFIG_HUGETLBFS=y
+CONFIG_HUGETLB_PAGE=y
+CONFIG_RAMFS=y
+CONFIG_CONFIGFS_FS=m
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+CONFIG_NFS_V4=y
+# CONFIG_NFS_DIRECTIO is not set
+CONFIG_NFSD=y
+CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
+CONFIG_NFSD_V4=y
+CONFIG_NFSD_TCP=y
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+CONFIG_RPCSEC_GSS_KRB5=y
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+CONFIG_NLS_CODEPAGE_932=y
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Distributed Lock Manager
+#
+# CONFIG_DLM is not set
+
+#
+# Profiling support
+#
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=m
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_DETECT_SOFTLOCKUP is not set
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_PREEMPT is not set
+CONFIG_DEBUG_SPINLOCK=y
+CONFIG_DEBUG_MUTEXES=y
+CONFIG_DEBUG_LOCK_ALLOC=y
+# CONFIG_PROVE_LOCKING is not set
+CONFIG_LOCKDEP=y
+# CONFIG_DEBUG_LOCKDEP is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+CONFIG_DEBUG_LOCKING_API_SELFTESTS=y
+CONFIG_STACKTRACE=y
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
+CONFIG_FRAME_POINTER=y
+CONFIG_FORCED_INLINING=y
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_FAULT_INJECTION is not set
+CONFIG_SH_STANDARD_BIOS=y
+# CONFIG_EARLY_SCIF_CONSOLE is not set
+CONFIG_EARLY_PRINTK=y
+CONFIG_DEBUG_STACKOVERFLOW=y
+CONFIG_DEBUG_STACK_USAGE=y
+# CONFIG_4KSTACKS is not set
+# CONFIG_SH_KGDB is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_WP512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_PCBC=m
+# CONFIG_CRYPTO_LRW is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
diff --git a/arch/sh/configs/se7705_defconfig b/arch/sh/configs/se7705_defconfig
index 06ebd6ec0cd..87ae5c1f862 100644
--- a/arch/sh/configs/se7705_defconfig
+++ b/arch/sh/configs/se7705_defconfig
@@ -1,15 +1,21 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18
-# Tue Oct 3 12:03:04 2006
+# Linux kernel version: 2.6.21-rc5
+# Thu Apr 26 09:16:31 2007
#
CONFIG_SUPERH=y
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_IRQ_PROBE=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
+# CONFIG_GENERIC_TIME is not set
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -33,7 +39,9 @@ CONFIG_LOCALVERSION_AUTO=y
# CONFIG_UTS_NS is not set
# CONFIG_AUDIT is not set
# CONFIG_IKCONFIG is not set
+CONFIG_SYSFS_DEPRECATED=y
# CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
@@ -91,27 +99,30 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
CONFIG_SOLUTION_ENGINE=y
CONFIG_SH_SOLUTION_ENGINE=y
# CONFIG_SH_7751_SOLUTION_ENGINE is not set
+# CONFIG_SH_7780_SOLUTION_ENGINE is not set
# CONFIG_SH_7300_SOLUTION_ENGINE is not set
# CONFIG_SH_7343_SOLUTION_ENGINE is not set
# CONFIG_SH_73180_SOLUTION_ENGINE is not set
+# CONFIG_SH_7722_SOLUTION_ENGINE is not set
# CONFIG_SH_7751_SYSTEMH is not set
# CONFIG_SH_HP6XX is not set
-# CONFIG_SH_EC3104 is not set
# CONFIG_SH_SATURN is not set
# CONFIG_SH_DREAMCAST is not set
-# CONFIG_SH_BIGSUR is not set
# CONFIG_SH_MPC1211 is not set
# CONFIG_SH_SH03 is not set
# CONFIG_SH_SECUREEDGE5410 is not set
# CONFIG_SH_HS7751RVOIP is not set
# CONFIG_SH_7710VOIPGW is not set
# CONFIG_SH_RTS7751R2D is not set
-# CONFIG_SH_R7780RP is not set
+# CONFIG_SH_HIGHLANDER is not set
# CONFIG_SH_EDOSK7705 is not set
# CONFIG_SH_SH4202_MICRODEV is not set
# CONFIG_SH_LANDISK is not set
# CONFIG_SH_TITAN is not set
# CONFIG_SH_SHMIN is not set
+# CONFIG_SH_7206_SOLUTION_ENGINE is not set
+# CONFIG_SH_7619_SOLUTION_ENGINE is not set
+# CONFIG_SH_LBOX_RE2 is not set
# CONFIG_SH_UNKNOWN is not set
#
@@ -123,6 +134,12 @@ CONFIG_CPU_SH3=y
# SH-2 Processor Support
#
# CONFIG_CPU_SUBTYPE_SH7604 is not set
+# CONFIG_CPU_SUBTYPE_SH7619 is not set
+
+#
+# SH-2A Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7206 is not set
#
# SH-3 Processor Support
@@ -134,6 +151,7 @@ CONFIG_CPU_SUBTYPE_SH7705=y
# 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
#
# SH-4 Processor Support
@@ -158,12 +176,14 @@ CONFIG_CPU_SUBTYPE_SH7705=y
#
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
+# CONFIG_CPU_SUBTYPE_SH7785 is not set
#
# SH4AL-DSP Processor Support
#
# CONFIG_CPU_SUBTYPE_SH73180 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
+# CONFIG_CPU_SUBTYPE_SH7722 is not set
#
# Memory management options
@@ -173,6 +193,11 @@ CONFIG_PAGE_OFFSET=0x80000000
CONFIG_MEMORY_START=0x0c000000
CONFIG_MEMORY_SIZE=0x02000000
CONFIG_VSYSCALL=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB 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
@@ -182,6 +207,7 @@ CONFIG_FLAT_NODE_MEM_MAP=y
# CONFIG_SPARSEMEM_STATIC is not set
CONFIG_SPLIT_PTLOCK_CPUS=4
# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
#
# Cache configuration
@@ -190,23 +216,31 @@ CONFIG_SH7705_CACHE_32KB=y
# CONFIG_SH_DIRECT_MAPPED is not set
# CONFIG_SH_WRITETHROUGH is not set
# CONFIG_SH_OCRAM is not set
-# CONFIG_CF_ENABLER is not set
+CONFIG_CF_ENABLER=y
+# CONFIG_CF_AREA5 is not set
+CONFIG_CF_AREA6=y
+# CONFIG_CF_AREA4 is not set
+CONFIG_CF_BASE_ADDR=0xb8000000
#
# Processor features
#
CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_CPU_BIG_ENDIAN is not set
# CONFIG_SH_FPU_EMU is not set
# CONFIG_SH_DSP is not set
# CONFIG_SH_ADC is not set
CONFIG_CPU_HAS_INTEVT=y
CONFIG_CPU_HAS_PINT_IRQ=y
+CONFIG_CPU_HAS_IPR_IRQ=y
CONFIG_CPU_HAS_SR_RB=y
#
-# Timer support
+# Timer and clock configuration
#
CONFIG_SH_TMU=y
+CONFIG_SH_TIMER_IRQ=16
+# CONFIG_NO_IDLE_HZ is not set
CONFIG_SH_PCLK_FREQ=33333333
#
@@ -223,13 +257,19 @@ CONFIG_SH_PCLK_FREQ=33333333
# Companion Chips
#
# CONFIG_HD6446X_SERIES is not set
+
+#
+# Additional SuperH Device Drivers
+#
CONFIG_HEARTBEAT=y
+# CONFIG_PUSH_SWITCH is not set
#
# Kernel features
#
# CONFIG_HZ_100 is not set
CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
# CONFIG_HZ_1000 is not set
CONFIG_HZ=250
# CONFIG_KEXEC is not set
@@ -287,6 +327,7 @@ CONFIG_UNIX=y
CONFIG_XFRM=y
# CONFIG_XFRM_USER is not set
# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
# CONFIG_NET_KEY is not set
CONFIG_INET=y
# CONFIG_IP_MULTICAST is not set
@@ -307,11 +348,13 @@ CONFIG_IP_PNP_RARP=y
# CONFIG_INET_TUNNEL is not set
CONFIG_INET_XFRM_MODE_TRANSPORT=y
CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
CONFIG_INET_DIAG=y
CONFIG_INET_TCP_DIAG=y
# 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_INET6_XFRM_TUNNEL is not set
# CONFIG_INET6_TUNNEL is not set
@@ -388,6 +431,7 @@ CONFIG_MTD_PARTITIONS=y
# 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
@@ -461,6 +505,7 @@ CONFIG_MTD_CFI_UTIL=y
#
# Plug and Play support
#
+# CONFIG_PNPACPI is not set
#
# Block devices
@@ -472,11 +517,14 @@ CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=8192
CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
-CONFIG_BLK_DEV_INITRD=y
# CONFIG_CDROM_PKTCDVD is not set
# CONFIG_ATA_OVER_ETH is not set
#
+# Misc devices
+#
+
+#
# ATA/ATAPI/MFM/RLL support
#
# CONFIG_IDE is not set
@@ -649,17 +697,12 @@ CONFIG_HW_RANDOM=y
# CONFIG_GEN_RTC is not set
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
-
-#
-# Ftape, the floppy tape device driver
-#
# CONFIG_RAW_DRIVER is not set
#
# TPM devices
#
# CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
#
# I2C support
@@ -675,6 +718,7 @@ CONFIG_HW_RANDOM=y
#
# Dallas's 1-wire bus
#
+# CONFIG_W1 is not set
#
# Hardware Monitoring support
@@ -683,18 +727,19 @@ CONFIG_HWMON=y
# CONFIG_HWMON_VID is not set
# CONFIG_SENSORS_ABITUGURU is not set
# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_PC87427 is not set
# CONFIG_SENSORS_VT1211 is not set
# CONFIG_HWMON_DEBUG_CHIP is not set
#
-# Misc devices
+# Multifunction device drivers
#
+# CONFIG_MFD_SM501 is not set
#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
#
# Digital Video Broadcasting Devices
@@ -704,7 +749,7 @@ CONFIG_VIDEO_V4L2=y
#
# Graphics support
#
-CONFIG_FIRMWARE_EDID=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
# CONFIG_FB is not set
#
@@ -713,6 +758,12 @@ CONFIG_FIRMWARE_EDID=y
# CONFIG_SOUND is not set
#
+# HID Devices
+#
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+
+#
# USB support
#
# CONFIG_USB_ARCH_HAS_HCD is not set
@@ -773,16 +824,26 @@ CONFIG_FIRMWARE_EDID=y
#
#
+# Auxiliary Display support
+#
+
+#
+# Virtualization
+#
+
+#
# File systems
#
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
# CONFIG_EXT2_FS_XIP is not set
# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4DEV_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_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
CONFIG_INOTIFY=y
@@ -828,7 +889,6 @@ CONFIG_RAMFS=y
# CONFIG_BEFS_FS is not set
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
-# CONFIG_JFFS_FS is not set
CONFIG_JFFS2_FS=y
CONFIG_JFFS2_FS_DEBUG=0
CONFIG_JFFS2_FS_WRITEBUFFER=y
@@ -878,6 +938,10 @@ CONFIG_MSDOS_PARTITION=y
# CONFIG_NLS is not set
#
+# Distributed Lock Manager
+#
+
+#
# Profiling support
#
# CONFIG_PROFILING is not set
@@ -885,15 +949,18 @@ CONFIG_MSDOS_PARTITION=y
#
# Kernel hacking
#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
# CONFIG_PRINTK_TIME is not set
CONFIG_ENABLE_MUST_CHECK=y
# CONFIG_MAGIC_SYSRQ is not set
# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_HEADERS_CHECK is not set
# CONFIG_DEBUG_KERNEL is not set
CONFIG_LOG_BUF_SHIFT=14
# CONFIG_DEBUG_BUGVERBOSE is not set
# CONFIG_SH_STANDARD_BIOS is not set
-# CONFIG_KGDB is not set
+# CONFIG_EARLY_SCIF_CONSOLE is not set
+# CONFIG_SH_KGDB is not set
#
# Security options
@@ -908,6 +975,7 @@ CONFIG_LOG_BUF_SHIFT=14
#
# Library routines
#
+CONFIG_BITREVERSE=y
CONFIG_CRC_CCITT=y
# CONFIG_CRC16 is not set
CONFIG_CRC32=y
@@ -915,3 +983,5 @@ CONFIG_CRC32=y
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=y
CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
diff --git a/arch/sh/configs/se7712_defconfig b/arch/sh/configs/se7712_defconfig
new file mode 100644
index 00000000000..a5e37dbc535
--- /dev/null
+++ b/arch/sh/configs/se7712_defconfig
@@ -0,0 +1,1088 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.21-rc4
+# Wed Mar 28 10:19:02 2007
+#
+CONFIG_SUPERH=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+# CONFIG_GENERIC_TIME is not set
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_SYSFS_DEPRECATED=y
+# CONFIG_RELAY is not set
+# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_ALL=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+# CONFIG_BUG is not set
+CONFIG_ELF_CORE=y
+# CONFIG_BASE_FULL is not set
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_SHMEM is not set
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
+CONFIG_TINY_SHMEM=y
+CONFIG_BASE_SMALL=1
+# CONFIG_SLOB is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODULE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+# CONFIG_KMOD is not set
+
+#
+# Block layer
+#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF 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"
+
+#
+# System type
+#
+CONFIG_SOLUTION_ENGINE=y
+CONFIG_SH_SOLUTION_ENGINE=y
+# CONFIG_SH_7751_SOLUTION_ENGINE is not set
+# CONFIG_SH_7300_SOLUTION_ENGINE is not set
+# CONFIG_SH_7343_SOLUTION_ENGINE is not set
+# CONFIG_SH_73180_SOLUTION_ENGINE is not set
+# CONFIG_SH_7751_SYSTEMH is not set
+# CONFIG_SH_HP6XX is not set
+# CONFIG_SH_SATURN is not set
+# CONFIG_SH_DREAMCAST is not set
+# CONFIG_SH_MPC1211 is not set
+# CONFIG_SH_SH03 is not set
+# CONFIG_SH_SECUREEDGE5410 is not set
+# CONFIG_SH_HS7751RVOIP is not set
+# CONFIG_SH_7710VOIPGW is not set
+# CONFIG_SH_RTS7751R2D is not set
+# CONFIG_SH_HIGHLANDER is not set
+# CONFIG_SH_EDOSK7705 is not set
+# CONFIG_SH_SH4202_MICRODEV is not set
+# CONFIG_SH_LANDISK is not set
+# CONFIG_SH_TITAN is not set
+# CONFIG_SH_SHMIN is not set
+# CONFIG_SH_7206_SOLUTION_ENGINE is not set
+# CONFIG_SH_7619_SOLUTION_ENGINE is not set
+# CONFIG_SH_LBOX_RE2 is not set
+# CONFIG_SH_UNKNOWN is not set
+
+#
+# Processor selection
+#
+CONFIG_CPU_SH3=y
+
+#
+# SH-2 Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7604 is not set
+# CONFIG_CPU_SUBTYPE_SH7619 is not set
+
+#
+# SH-2A Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7206 is not set
+
+#
+# SH-3 Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7300 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=y
+
+#
+# SH-4 Processor Support
+#
+# 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
+
+#
+# ST40 Processor Support
+#
+# CONFIG_CPU_SUBTYPE_ST40STB1 is not set
+# CONFIG_CPU_SUBTYPE_ST40GX1 is not set
+
+#
+# SH-4A Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7770 is not set
+# CONFIG_CPU_SUBTYPE_SH7780 is not set
+# CONFIG_CPU_SUBTYPE_SH7785 is not set
+
+#
+# SH4AL-DSP Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+# CONFIG_CPU_SUBTYPE_SH7722 is not set
+
+#
+# Memory management options
+#
+CONFIG_MMU=y
+CONFIG_PAGE_OFFSET=0x80000000
+CONFIG_MEMORY_START=0x0c000000
+CONFIG_MEMORY_SIZE=0x02000000
+CONFIG_VSYSCALL=y
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB 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 is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+
+#
+# Cache configuration
+#
+# CONFIG_SH_DIRECT_MAPPED is not set
+# CONFIG_SH_WRITETHROUGH is not set
+# CONFIG_SH_OCRAM is not set
+CONFIG_CF_ENABLER=y
+# CONFIG_CF_AREA5 is not set
+CONFIG_CF_AREA6=y
+CONFIG_CF_BASE_ADDR=0xb8000000
+
+#
+# Processor features
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_CPU_BIG_ENDIAN is not set
+# CONFIG_SH_FPU_EMU is not set
+# CONFIG_SH_DSP is not set
+# CONFIG_SH_ADC is not set
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_IPR_IRQ=y
+CONFIG_CPU_HAS_SR_RB=y
+
+#
+# Timer and clock configuration
+#
+CONFIG_SH_TMU=y
+CONFIG_SH_TIMER_IRQ=16
+# CONFIG_NO_IDLE_HZ is not set
+CONFIG_SH_PCLK_FREQ=33333333
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+
+#
+# DMA support
+#
+# CONFIG_SH_DMA is not set
+
+#
+# Companion Chips
+#
+# CONFIG_HD6446X_SERIES is not set
+
+#
+# Additional SuperH Device Drivers
+#
+CONFIG_HEARTBEAT=y
+# CONFIG_PUSH_SWITCH is not set
+
+#
+# Kernel features
+#
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+# CONFIG_KEXEC is not set
+# CONFIG_SMP is not set
+# CONFIG_PREEMPT_NONE is not set
+CONFIG_PREEMPT_VOLUNTARY=y
+# CONFIG_PREEMPT is not set
+
+#
+# Boot options
+#
+CONFIG_ZERO_PAGE_OFFSET=0x00001000
+CONFIG_BOOT_LINK_OFFSET=0x00800000
+# CONFIG_UBC_WAKEUP is not set
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=ttySC0,115200 root=/dev/sda1"
+
+#
+# Bus options
+#
+# CONFIG_PCI is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PCI Hotplug Support
+#
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_FLAT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options (EXPERIMENTAL)
+#
+# CONFIG_PM is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+CONFIG_NET_KEY=y
+# CONFIG_NET_KEY_MIGRATE is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_ASK_IP_FIB_HASH=y
+# CONFIG_IP_FIB_TRIE is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+# CONFIG_IP_ROUTE_MULTIPATH_CACHED is not set
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=y
+CONFIG_INET_ESP=y
+CONFIG_INET_IPCOMP=y
+CONFIG_INET_XFRM_TUNNEL=y
+CONFIG_INET_TUNNEL=y
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# 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_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE 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
+
+#
+# QoS and/or fair queueing
+#
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_FIFO=y
+CONFIG_NET_SCH_CLK_JIFFIES=y
+# CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set
+# CONFIG_NET_SCH_CLK_CPU is not set
+
+#
+# Queueing/Scheduling
+#
+CONFIG_NET_SCH_CBQ=y
+CONFIG_NET_SCH_HTB=y
+CONFIG_NET_SCH_HFSC=y
+CONFIG_NET_SCH_PRIO=y
+CONFIG_NET_SCH_RED=y
+CONFIG_NET_SCH_SFQ=y
+CONFIG_NET_SCH_TEQL=y
+CONFIG_NET_SCH_TBF=y
+CONFIG_NET_SCH_GRED=y
+CONFIG_NET_SCH_DSMARK=y
+CONFIG_NET_SCH_NETEM=y
+CONFIG_NET_SCH_INGRESS=y
+
+#
+# Classification
+#
+CONFIG_NET_CLS=y
+# CONFIG_NET_CLS_BASIC is not set
+CONFIG_NET_CLS_TCINDEX=y
+CONFIG_NET_CLS_ROUTE4=y
+CONFIG_NET_CLS_ROUTE=y
+CONFIG_NET_CLS_FW=y
+# CONFIG_NET_CLS_U32 is not set
+# CONFIG_NET_CLS_RSVP is not set
+# CONFIG_NET_CLS_RSVP6 is not set
+# CONFIG_NET_EMATCH is not set
+# CONFIG_NET_CLS_ACT is not set
+# CONFIG_NET_CLS_POLICE is not set
+CONFIG_NET_CLS_IND=y
+CONFIG_NET_ESTIMATOR=y
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+CONFIG_FIB_RULES=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+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 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
+
+#
+# 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 is not set
+CONFIG_MTD_CFI_AMDSTD=y
+# 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
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PHYSMAP 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
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# OneNAND Flash Device Drivers
+#
+# CONFIG_MTD_ONENAND is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+# CONFIG_PNPACPI is not set
+
+#
+# Block devices
+#
+# 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
+
+#
+# Misc devices
+#
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+CONFIG_ATA=y
+# CONFIG_ATA_NONSTANDARD is not set
+CONFIG_PATA_PLATFORM=y
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# I2O device support
+#
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# PHY device support
+#
+
+#
+# Ethernet (10 or 100Mbit)
+#
+# CONFIG_NET_ETHERNET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+
+#
+# Ethernet (10000 Mbit)
+#
+
+#
+# Token Ring devices
+#
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+# CONFIG_INPUT is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# 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=2
+CONFIG_SERIAL_SH_SCI_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+CONFIG_HW_RANDOM=m
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+# CONFIG_FB is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB_ARCH_HAS_HCD is not set
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# LED devices
+#
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+# CONFIG_LEDS_TRIGGER_TIMER is not set
+# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
+
+#
+# InfiniBand support
+#
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
+# Auxiliary Display support
+#
+
+#
+# Virtualization
+#
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4DEV_FS is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_INOTIFY is not set
+# CONFIG_QUOTA is not set
+# CONFIG_DNOTIFY is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS 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 is not set
+CONFIG_PROC_SYSCTL=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_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+CONFIG_CRAMFS=y
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+# CONFIG_NFS_FS is not set
+# CONFIG_NFSD is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+
+#
+# Distributed Lock Manager
+#
+# CONFIG_DLM is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_DETECT_SOFTLOCKUP is not set
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_FORCED_INLINING is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_SH_STANDARD_BIOS is not set
+# CONFIG_EARLY_SCIF_CONSOLE is not set
+# CONFIG_DEBUG_STACKOVERFLOW is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_4KSTACKS is not set
+# CONFIG_SH_KGDB is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_SHA1=y
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_WP512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_PCBC=m
+# CONFIG_CRYPTO_LRW is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+CONFIG_CRYPTO_DEFLATE=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_CRC_CCITT=y
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
diff --git a/arch/sh/configs/se7722_defconfig b/arch/sh/configs/se7722_defconfig
new file mode 100644
index 00000000000..ca4c663dfa3
--- /dev/null
+++ b/arch/sh/configs/se7722_defconfig
@@ -0,0 +1,980 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.21-rc7
+# Fri Apr 27 16:30:30 2007
+#
+CONFIG_SUPERH=y
+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_IRQ_PROBE=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+# CONFIG_GENERIC_TIME is not set
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+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_UTS_NS is not set
+# CONFIG_AUDIT is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+# CONFIG_SYSFS_DEPRECATED is not set
+# CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS 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_SHMEM=y
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+
+#
+# Block layer
+#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF 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"
+
+#
+# System type
+#
+CONFIG_SOLUTION_ENGINE=y
+# CONFIG_SH_SOLUTION_ENGINE is not set
+CONFIG_SH_7722_SOLUTION_ENGINE=y
+# CONFIG_SH_7751_SOLUTION_ENGINE is not set
+# CONFIG_SH_7780_SOLUTION_ENGINE is not set
+# CONFIG_SH_7300_SOLUTION_ENGINE is not set
+# CONFIG_SH_7343_SOLUTION_ENGINE is not set
+# CONFIG_SH_73180_SOLUTION_ENGINE is not set
+# CONFIG_SH_7751_SYSTEMH is not set
+# CONFIG_SH_HP6XX is not set
+# CONFIG_SH_SATURN is not set
+# CONFIG_SH_DREAMCAST is not set
+# CONFIG_SH_MPC1211 is not set
+# CONFIG_SH_SH03 is not set
+# CONFIG_SH_SECUREEDGE5410 is not set
+# CONFIG_SH_HS7751RVOIP is not set
+# CONFIG_SH_7710VOIPGW is not set
+# CONFIG_SH_RTS7751R2D is not set
+# CONFIG_SH_HIGHLANDER is not set
+# CONFIG_SH_EDOSK7705 is not set
+# CONFIG_SH_SH4202_MICRODEV is not set
+# CONFIG_SH_LANDISK is not set
+# CONFIG_SH_TITAN is not set
+# CONFIG_SH_SHMIN is not set
+# CONFIG_SH_7206_SOLUTION_ENGINE is not set
+# CONFIG_SH_7619_SOLUTION_ENGINE is not set
+# CONFIG_SH_LBOX_RE2 is not set
+# CONFIG_SH_UNKNOWN is not set
+
+#
+# Processor selection
+#
+CONFIG_CPU_SH4=y
+CONFIG_CPU_SH4A=y
+CONFIG_CPU_SH4AL_DSP=y
+CONFIG_CPU_SHX2=y
+
+#
+# SH-2 Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7604 is not set
+# CONFIG_CPU_SUBTYPE_SH7619 is not set
+
+#
+# SH-2A Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7206 is not set
+
+#
+# SH-3 Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7300 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
+
+#
+# SH-4 Processor Support
+#
+# 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
+
+#
+# ST40 Processor Support
+#
+# CONFIG_CPU_SUBTYPE_ST40STB1 is not set
+# CONFIG_CPU_SUBTYPE_ST40GX1 is not set
+
+#
+# SH-4A Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7770 is not set
+# CONFIG_CPU_SUBTYPE_SH7780 is not set
+# CONFIG_CPU_SUBTYPE_SH7785 is not set
+
+#
+# SH4AL-DSP Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+CONFIG_CPU_SUBTYPE_SH7722=y
+
+#
+# Memory management options
+#
+CONFIG_MMU=y
+CONFIG_PAGE_OFFSET=0x80000000
+CONFIG_MEMORY_START=0x0c000000
+CONFIG_MEMORY_SIZE=0x04000000
+# CONFIG_32BIT is not set
+# CONFIG_X2TLB is not set
+CONFIG_VSYSCALL=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_HUGETLB_PAGE_SIZE_64K=y
+# CONFIG_HUGETLB_PAGE_SIZE_256K is not set
+# CONFIG_HUGETLB_PAGE_SIZE_1MB is not set
+# CONFIG_HUGETLB_PAGE_SIZE_4MB is not set
+# CONFIG_HUGETLB_PAGE_SIZE_64MB 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 is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+
+#
+# Cache configuration
+#
+# CONFIG_SH_DIRECT_MAPPED is not set
+# CONFIG_SH_WRITETHROUGH is not set
+# CONFIG_SH_OCRAM is not set
+CONFIG_CF_ENABLER=y
+# CONFIG_CF_AREA5 is not set
+CONFIG_CF_AREA6=y
+CONFIG_CF_BASE_ADDR=0xb8000000
+
+#
+# Processor features
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_CPU_BIG_ENDIAN is not set
+# CONFIG_SH_FPU is not set
+# CONFIG_SH_FPU_EMU is not set
+CONFIG_SH_DSP=y
+CONFIG_SH_STORE_QUEUES=y
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_IPR_IRQ=y
+CONFIG_CPU_HAS_SR_RB=y
+CONFIG_CPU_HAS_PTEA=y
+
+#
+# Timer and clock configuration
+#
+CONFIG_SH_TMU=y
+CONFIG_SH_TIMER_IRQ=16
+CONFIG_NO_IDLE_HZ=y
+CONFIG_SH_PCLK_FREQ=33333333
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+
+#
+# DMA support
+#
+# CONFIG_SH_DMA is not set
+
+#
+# Companion Chips
+#
+# CONFIG_HD6446X_SERIES is not set
+
+#
+# Additional SuperH Device Drivers
+#
+CONFIG_HEARTBEAT=y
+# CONFIG_PUSH_SWITCH is not set
+
+#
+# Kernel features
+#
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_KEXEC=y
+# CONFIG_CRASH_DUMP is not set
+# CONFIG_SMP is not set
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_PREEMPT_BKL=y
+
+#
+# Boot options
+#
+CONFIG_ZERO_PAGE_OFFSET=0x00001000
+CONFIG_BOOT_LINK_OFFSET=0x00800000
+# CONFIG_UBC_WAKEUP is not set
+# CONFIG_CMDLINE_BOOL is not set
+
+#
+# Bus options
+#
+# CONFIG_PCI is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PCI Hotplug Support
+#
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_FLAT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options (EXPERIMENTAL)
+#
+# CONFIG_PM is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# 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=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# 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_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE 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
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+# CONFIG_PNPACPI is not set
+
+#
+# Block devices
+#
+# 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=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# Misc devices
+#
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+CONFIG_ATA=y
+# CONFIG_ATA_NONSTANDARD is not set
+CONFIG_PATA_PLATFORM=y
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# I2O device support
+#
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_STNIC is not set
+CONFIG_SMC91X=y
+
+#
+# Ethernet (1000 Mbit)
+#
+
+#
+# Ethernet (10000 Mbit)
+#
+
+#
+# Token Ring devices
+#
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+# CONFIG_SERIO_SERPORT is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# 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=2
+CONFIG_SERIAL_SH_SCI_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+# CONFIG_FB is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# HID Devices
+#
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+
+#
+# USB support
+#
+# CONFIG_USB_ARCH_HAS_HCD is not set
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
+# InfiniBand support
+#
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+
+#
+# RTC drivers
+#
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+CONFIG_RTC_DRV_SH=y
+# CONFIG_RTC_DRV_TEST is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
+# Auxiliary Display support
+#
+
+#
+# Virtualization
+#
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4DEV_FS is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# 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_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS 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_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+CONFIG_HUGETLBFS=y
+CONFIG_HUGETLB_PAGE=y
+CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+# CONFIG_NFS_FS is not set
+# CONFIG_NFSD is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+
+#
+# Distributed Lock Manager
+#
+# CONFIG_DLM is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+# CONFIG_PRINTK_TIME is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_SH_STANDARD_BIOS is not set
+# CONFIG_EARLY_SCIF_CONSOLE is not set
+# CONFIG_SH_KGDB is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
diff --git a/arch/sh/configs/se7780_defconfig b/arch/sh/configs/se7780_defconfig
new file mode 100644
index 00000000000..538661e9879
--- /dev/null
+++ b/arch/sh/configs/se7780_defconfig
@@ -0,0 +1,1309 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.21-rc3
+# Thu Mar 15 14:06:20 2007
+#
+CONFIG_SUPERH=y
+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_IRQ_PROBE=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+# CONFIG_GENERIC_TIME is not set
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# Code maturity level options
+#
+# CONFIG_EXPERIMENTAL is not set
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
+# CONFIG_AUDIT is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_SYSFS_DEPRECATED=y
+# CONFIG_RELAY is not set
+# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+# CONFIG_KALLSYMS is not set
+# CONFIG_HOTPLUG is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+# CONFIG_EPOLL is not set
+CONFIG_SHMEM=y
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+
+#
+# Block layer
+#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_AS is not set
+CONFIG_IOSCHED_DEADLINE=y
+# CONFIG_IOSCHED_CFQ is not set
+# CONFIG_DEFAULT_AS is not set
+CONFIG_DEFAULT_DEADLINE=y
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="deadline"
+
+#
+# System type
+#
+CONFIG_SOLUTION_ENGINE=y
+# CONFIG_SH_SOLUTION_ENGINE is not set
+# CONFIG_SH_7751_SOLUTION_ENGINE is not set
+CONFIG_SH_7780_SOLUTION_ENGINE=y
+# CONFIG_SH_7300_SOLUTION_ENGINE is not set
+# CONFIG_SH_7343_SOLUTION_ENGINE is not set
+# CONFIG_SH_73180_SOLUTION_ENGINE is not set
+# CONFIG_SH_7751_SYSTEMH is not set
+# CONFIG_SH_HP6XX is not set
+# CONFIG_SH_SATURN is not set
+# CONFIG_SH_DREAMCAST is not set
+# CONFIG_SH_MPC1211 is not set
+# CONFIG_SH_SH03 is not set
+# CONFIG_SH_SECUREEDGE5410 is not set
+# CONFIG_SH_HS7751RVOIP is not set
+# CONFIG_SH_7710VOIPGW is not set
+# CONFIG_SH_RTS7751R2D is not set
+# CONFIG_SH_HIGHLANDER is not set
+# CONFIG_SH_EDOSK7705 is not set
+# CONFIG_SH_SH4202_MICRODEV is not set
+# CONFIG_SH_LANDISK is not set
+# CONFIG_SH_TITAN is not set
+# CONFIG_SH_SHMIN is not set
+# CONFIG_SH_7206_SOLUTION_ENGINE is not set
+# CONFIG_SH_7619_SOLUTION_ENGINE is not set
+# CONFIG_SH_UNKNOWN is not set
+
+#
+# Processor selection
+#
+CONFIG_CPU_SH4=y
+CONFIG_CPU_SH4A=y
+
+#
+# SH-2 Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7604 is not set
+# CONFIG_CPU_SUBTYPE_SH7619 is not set
+
+#
+# SH-2A Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7206 is not set
+
+#
+# SH-3 Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7300 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
+
+#
+# SH-4 Processor Support
+#
+# 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
+
+#
+# ST40 Processor Support
+#
+# CONFIG_CPU_SUBTYPE_ST40STB1 is not set
+# CONFIG_CPU_SUBTYPE_ST40GX1 is not set
+
+#
+# SH-4A Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7770 is not set
+CONFIG_CPU_SUBTYPE_SH7780=y
+# CONFIG_CPU_SUBTYPE_SH7785 is not set
+
+#
+# SH4AL-DSP Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+# CONFIG_CPU_SUBTYPE_SH7722 is not set
+
+#
+# Memory management options
+#
+CONFIG_MMU=y
+CONFIG_PAGE_OFFSET=0x80000000
+CONFIG_MEMORY_START=0x08000000
+CONFIG_MEMORY_SIZE=0x08000000
+CONFIG_32BIT=y
+CONFIG_VSYSCALL=y
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+
+#
+# Cache configuration
+#
+# CONFIG_SH_DIRECT_MAPPED is not set
+# CONFIG_SH_WRITETHROUGH is not set
+# CONFIG_SH_OCRAM is not set
+
+#
+# Processor features
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_CPU_BIG_ENDIAN is not set
+CONFIG_SH_FPU=y
+# CONFIG_SH_DSP is not set
+# CONFIG_SH_STORE_QUEUES is not set
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_INTC2_IRQ=y
+CONFIG_CPU_HAS_SR_RB=y
+
+#
+# Timer and clock configuration
+#
+CONFIG_SH_TMU=y
+CONFIG_SH_TIMER_IRQ=28
+# CONFIG_NO_IDLE_HZ is not set
+CONFIG_SH_PCLK_FREQ=33333333
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+
+#
+# DMA support
+#
+# CONFIG_SH_DMA is not set
+
+#
+# Companion Chips
+#
+# CONFIG_HD6446X_SERIES is not set
+
+#
+# Additional SuperH Device Drivers
+#
+CONFIG_HEARTBEAT=y
+# CONFIG_PUSH_SWITCH is not set
+
+#
+# Kernel features
+#
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+# CONFIG_SMP is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+
+#
+# Boot options
+#
+CONFIG_ZERO_PAGE_OFFSET=0x00001000
+CONFIG_BOOT_LINK_OFFSET=0x00810000
+# CONFIG_UBC_WAKEUP is not set
+# CONFIG_CMDLINE_BOOL is not set
+
+#
+# Bus options
+#
+CONFIG_PCI=y
+CONFIG_SH_PCIDMA_NONCOHERENT=y
+CONFIG_PCI_AUTO=y
+CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+
+#
+# PCI Hotplug Support
+#
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_FLAT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE 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=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+CONFIG_IPV6=y
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET6_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET6_XFRM_MODE_BEET is not set
+# CONFIG_IPV6_SIT is not set
+# CONFIG_IPV6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_BRIDGE 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
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_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
+
+#
+# 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=y
+CONFIG_MTD_CFI_NOSWAP=y
+# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
+# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
+CONFIG_MTD_CFI_GEOMETRY=y
+# CONFIG_MTD_MAP_BANK_WIDTH_1 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_2 is not set
+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 is not set
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_OTP is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+CONFIG_MTD_ROM=y
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# 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
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# OneNAND Flash Device Drivers
+#
+# CONFIG_MTD_ONENAND is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+# CONFIG_PNPACPI is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_UB is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# Misc devices
+#
+# CONFIG_SGI_IOC4 is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+CONFIG_CHR_DEV_SG=y
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
+# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_ARCMSR is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_HPTIOP is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_STEX is not set
+# CONFIG_SCSI_SYM53C8XX_2 is not set
+# CONFIG_SCSI_IPR is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI is not set
+# CONFIG_SCSI_LPFC is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_NSP32 is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_SRP is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+CONFIG_ATA=y
+# CONFIG_ATA_NONSTANDARD is not set
+# CONFIG_SATA_AHCI is not set
+# CONFIG_SATA_SVW is not set
+# CONFIG_ATA_PIIX is not set
+# CONFIG_SATA_NV is not set
+# CONFIG_PDC_ADMA is not set
+# CONFIG_SATA_QSTOR is not set
+# CONFIG_SATA_PROMISE is not set
+CONFIG_SATA_SIL=y
+# CONFIG_SATA_SIL24 is not set
+# CONFIG_SATA_SIS is not set
+# CONFIG_SATA_ULI is not set
+# CONFIG_SATA_VIA is not set
+# CONFIG_SATA_VITESSE is not set
+# CONFIG_PATA_AMD is not set
+# CONFIG_PATA_CS5520 is not set
+# CONFIG_PATA_EFAR is not set
+# CONFIG_ATA_GENERIC is not set
+# CONFIG_PATA_HPT3X3 is not set
+# CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_TRIFLEX is not set
+# CONFIG_PATA_MARVELL is not set
+# CONFIG_PATA_MPIIX is not set
+# CONFIG_PATA_NETCELL is not set
+# CONFIG_PATA_RZ1000 is not set
+# CONFIG_PATA_PDC2027X is not set
+# CONFIG_PATA_SIL680 is not set
+# CONFIG_PATA_VIA is not set
+# CONFIG_PATA_WINBOND is not set
+# CONFIG_PATA_PLATFORM is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+# CONFIG_FUSION_SPI is not set
+# CONFIG_FUSION_FC is not set
+# CONFIG_FUSION_SAS is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# PHY device support
+#
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+CONFIG_SMSC_PHY=y
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_FIXED_PHY is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_STNIC is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
+# CONFIG_NET_VENDOR_3COM is not set
+CONFIG_SMC91X=y
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+CONFIG_NET_PCI=y
+# CONFIG_PCNET32 is not set
+# CONFIG_AMD8111_ETH is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_B44 is not set
+# CONFIG_FORCEDETH is not set
+# CONFIG_DGRS is not set
+# CONFIG_EEPRO100 is not set
+# CONFIG_E100 is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_8139TOO is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_TLAN is not set
+# CONFIG_VIA_RHINE is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_VIA_VELOCITY is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+# CONFIG_QLA3XXX is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_CHELSIO_T1 is not set
+# CONFIG_CHELSIO_T3 is not set
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+# CONFIG_MYRI10GE is not set
+# CONFIG_NETXEN_NIC is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NET_FC is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK 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_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+# 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=2
+CONFIG_SERIAL_SH_SCI_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+# CONFIG_USB_DABUSB is not set
+
+#
+# Graphics support
+#
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+CONFIG_FB=y
+CONFIG_FIRMWARE_EDID=y
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_CFB_FILLRECT is not set
+# CONFIG_FB_CFB_COPYAREA is not set
+# CONFIG_FB_CFB_IMAGEBLIT is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frambuffer hardware drivers
+#
+# CONFIG_FB_CIRRUS is not set
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+# CONFIG_FB_EPSON1355 is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_NVIDIA is not set
+# CONFIG_FB_RIVA is not set
+# CONFIG_FB_MATROX is not set
+# CONFIG_FB_RADEON is not set
+# CONFIG_FB_ATY128 is not set
+# CONFIG_FB_ATY is not set
+# CONFIG_FB_S3 is not set
+# CONFIG_FB_SIS is not set
+# CONFIG_FB_NEOMAGIC is not set
+# CONFIG_FB_KYRO is not set
+# CONFIG_FB_3DFX is not set
+# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_VIRTUAL is not set
+
+#
+# Console display driver support
+#
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+
+#
+# Logo configuration
+#
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_LOGO_LINUX_CLUT224=y
+# CONFIG_LOGO_SUPERH_MONO is not set
+# CONFIG_LOGO_SUPERH_VGA16 is not set
+CONFIG_LOGO_SUPERH_CLUT224=y
+
+#
+# Sound
+#
+CONFIG_SOUND=y
+
+#
+# Advanced Linux Sound Architecture
+#
+# CONFIG_SND is not set
+
+#
+# Open Sound System
+#
+CONFIG_SOUND_PRIME=y
+# CONFIG_OBSOLETE_OSS is not set
+# CONFIG_SOUND_BT878 is not set
+# CONFIG_SOUND_ICH is not set
+# CONFIG_SOUND_TRIDENT is not set
+# CONFIG_SOUND_MSNDCLAS is not set
+# CONFIG_SOUND_MSNDPIN is not set
+# CONFIG_SOUND_VIA82CXXX is not set
+
+#
+# HID Devices
+#
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+CONFIG_USB_DEBUG=y
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+
+#
+# USB Host Controller Drivers
+#
+CONFIG_USB_EHCI_HCD=y
+# CONFIG_USB_EHCI_BIG_ENDIAN_MMIO is not set
+# CONFIG_USB_ISP116X_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_UHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+# CONFIG_USB_HIDINPUT_POWERBOOK is not set
+# CONFIG_USB_HIDDEV is not set
+# CONFIG_USB_AIPTEK is not set
+# CONFIG_USB_WACOM is not set
+# CONFIG_USB_ACECAD is not set
+# CONFIG_USB_KBTAB is not set
+# CONFIG_USB_POWERMATE is not set
+# CONFIG_USB_TOUCHSCREEN is not set
+# CONFIG_USB_XPAD is not set
+# CONFIG_USB_ATI_REMOTE is not set
+# CONFIG_USB_ATI_REMOTE2 is not set
+# CONFIG_USB_APPLETOUCH is not set
+# CONFIG_USB_GTCO is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_USBNET_MII is not set
+# CONFIG_USB_USBNET is not set
+CONFIG_USB_MON=y
+
+#
+# USB port drivers
+#
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGET is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+
+#
+# USB DSL modem support
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
+# Auxiliary Display support
+#
+
+#
+# Virtualization
+#
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_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_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_DNOTIFY is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+# CONFIG_PROC_KCORE is not set
+CONFIG_PROC_SYSCTL=y
+# CONFIG_SYSFS is not set
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLBFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_JFFS2_FS is not set
+CONFIG_CRAMFS=y
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_SH_STANDARD_BIOS is not set
+# CONFIG_EARLY_SCIF_CONSOLE is not set
+# CONFIG_SH_KGDB is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
diff --git a/arch/sh/drivers/Kconfig b/arch/sh/drivers/Kconfig
index c54c758e624..420c6b2f33a 100644
--- a/arch/sh/drivers/Kconfig
+++ b/arch/sh/drivers/Kconfig
@@ -1,5 +1,15 @@
+source "arch/sh/drivers/dma/Kconfig"
+source "arch/sh/cchips/Kconfig"
+
menu "Additional SuperH Device Drivers"
+config HEARTBEAT
+ bool "Heartbeat LED"
+ help
+ Use the power-on LED on your machine as a load meter. The exact
+ behavior is platform-dependent, but normally the flash frequency is
+ a hyperbolic function of the 5-minute load average.
+
config PUSH_SWITCH
tristate "Push switch support"
help
diff --git a/arch/sh/drivers/heartbeat.c b/arch/sh/drivers/heartbeat.c
index bc59cb6cd78..23dd6080422 100644
--- a/arch/sh/drivers/heartbeat.c
+++ b/arch/sh/drivers/heartbeat.c
@@ -40,16 +40,9 @@ static void heartbeat_timer(unsigned long data)
static unsigned bit = 0, up = 1;
ctrl_outw(1 << hd->bit_pos[bit], (unsigned long)hd->base);
- if (up)
- if (bit == (ARRAY_SIZE(hd->bit_pos) - 1)) {
- bit--;
- up = 0;
- } else
- bit++;
- else if (bit == 0)
- up = 1;
- else
- bit--;
+ bit += up;
+ if ((bit == 0) || (bit == ARRAY_SIZE(hd->bit_pos)-1))
+ up = -up;
mod_timer(&hd->timer, jiffies + (110 - ((300 << FSHIFT) /
((avenrun[0] / 5) + (3 << FSHIFT)))));
diff --git a/arch/sh/drivers/pci/Makefile b/arch/sh/drivers/pci/Makefile
index cc8d0d0b142..0e9b532b9fb 100644
--- a/arch/sh/drivers/pci/Makefile
+++ b/arch/sh/drivers/pci/Makefile
@@ -8,12 +8,15 @@ obj-$(CONFIG_PCI_AUTO) += pci-auto.o
obj-$(CONFIG_CPU_SUBTYPE_ST40STB1) += pci-st40.o
obj-$(CONFIG_CPU_SUBTYPE_SH7751) += pci-sh7751.o ops-sh4.o
obj-$(CONFIG_CPU_SUBTYPE_SH7780) += pci-sh7780.o ops-sh4.o
+obj-$(CONFIG_CPU_SUBTYPE_SH7785) += pci-sh7780.o ops-sh4.o
obj-$(CONFIG_SH_DREAMCAST) += ops-dreamcast.o fixups-dreamcast.o \
dma-dreamcast.o
obj-$(CONFIG_SH_SECUREEDGE5410) += ops-snapgear.o
obj-$(CONFIG_SH_RTS7751R2D) += ops-rts7751r2d.o fixups-rts7751r2d.o
obj-$(CONFIG_SH_SH03) += ops-sh03.o fixups-sh03.o
-obj-$(CONFIG_SH_R7780RP) += ops-r7780rp.o fixups-r7780rp.o
+obj-$(CONFIG_SH_HIGHLANDER) += ops-r7780rp.o fixups-r7780rp.o
obj-$(CONFIG_SH_TITAN) += ops-titan.o
obj-$(CONFIG_SH_LANDISK) += ops-landisk.o
+obj-$(CONFIG_SH_LBOX_RE2) += ops-lboxre2.o fixups-lboxre2.o
+obj-$(CONFIG_SH_7780_SOLUTION_ENGINE) += ops-se7780.o fixups-se7780.o
diff --git a/arch/sh/drivers/pci/fixups-lboxre2.c b/arch/sh/drivers/pci/fixups-lboxre2.c
new file mode 100644
index 00000000000..40b19bdfb89
--- /dev/null
+++ b/arch/sh/drivers/pci/fixups-lboxre2.c
@@ -0,0 +1,41 @@
+/*
+ * arch/sh/drivers/pci/fixups-lboxre2.c
+ *
+ * L-BOX RE2 PCI fixups
+ *
+ * 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 "pci-sh4.h"
+
+#define PCIMCR_MRSET_OFF 0xBFFFFFFF
+#define PCIMCR_RFSH_OFF 0xFFFFFFFB
+
+int pci_fixup_pcic(void)
+{
+ unsigned long bcr1, mcr;
+
+ bcr1 = inl(SH7751_BCR1);
+ bcr1 |= 0x40080000; /* Enable Bit 19 BREQEN, set PCIC to slave */
+ pci_write_reg(bcr1, SH4_PCIBCR1);
+
+ /* Enable all interrupts, so we known what to fix */
+ pci_write_reg(0x0000c3ff, SH4_PCIINTM);
+ pci_write_reg(0x0000380f, SH4_PCIAINTM);
+ pci_write_reg(0xfb900047, SH7751_PCICONF1);
+ pci_write_reg(0xab000001, SH7751_PCICONF4);
+
+ mcr = inl(SH7751_MCR);
+ mcr = (mcr & PCIMCR_MRSET_OFF) & PCIMCR_RFSH_OFF;
+ pci_write_reg(mcr, SH4_PCIMCR);
+
+ pci_write_reg(0x0c000000, SH7751_PCICONF5);
+ pci_write_reg(0xd0000000, SH7751_PCICONF6);
+ pci_write_reg(0x0c000000, SH4_PCILAR0);
+ pci_write_reg(0x00000000, SH4_PCILAR1);
+
+ return 0;
+}
diff --git a/arch/sh/drivers/pci/fixups-se7780.c b/arch/sh/drivers/pci/fixups-se7780.c
new file mode 100644
index 00000000000..880cea1c0d8
--- /dev/null
+++ b/arch/sh/drivers/pci/fixups-se7780.c
@@ -0,0 +1,60 @@
+/*
+ * arch/sh/drivers/pci/fixups-se7780.c
+ *
+ * HITACHI UL Solution Engine 7780 PCI fixups
+ *
+ * Copyright (C) 2003 Lineo uSolutions, Inc.
+ * Copyright (C) 2004 - 2006 Paul Mundt
+ * Copyright (C) 2006 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 <linux/pci.h>
+#include "pci-sh4.h"
+#include <asm/io.h>
+
+int pci_fixup_pcic(void)
+{
+ ctrl_outl(0x00000001, SH7780_PCI_VCR2);
+
+ /* Enable all interrupts, so we know what to fix */
+ pci_write_reg(0x0000C3FF, SH7780_PCIIMR);
+ pci_write_reg(0x0000380F, SH7780_PCIAINTM);
+
+ /* Set up standard PCI config registers */
+ ctrl_outw(0xFB00, PCI_REG(SH7780_PCISTATUS));
+ ctrl_outw(0x0047, PCI_REG(SH7780_PCICMD));
+ ctrl_outb( 0x00, PCI_REG(SH7780_PCIPIF));
+ ctrl_outb( 0x00, PCI_REG(SH7780_PCISUB));
+ ctrl_outb( 0x06, PCI_REG(SH7780_PCIBCC));
+ ctrl_outw(0x1912, PCI_REG(SH7780_PCISVID));
+ ctrl_outw(0x0001, PCI_REG(SH7780_PCISID));
+
+ pci_write_reg(0x08000000, SH7780_PCIMBAR0); /* PCI */
+ pci_write_reg(0x08000000, SH7780_PCILAR0); /* SHwy */
+ pci_write_reg(0x07F00001, SH7780_PCILSR); /* size 128M w/ MBAR */
+
+ pci_write_reg(0x00000000, SH7780_PCIMBAR1);
+ pci_write_reg(0x00000000, SH7780_PCILAR1);
+ pci_write_reg(0x00000000, SH7780_PCILSR1);
+
+ pci_write_reg(0xAB000801, SH7780_PCIIBAR);
+
+ /*
+ * Set the MBR so PCI address is one-to-one with window,
+ * meaning all calls go straight through... use ifdef to
+ * catch erroneous assumption.
+ */
+ pci_write_reg(0xFD000000 , SH7780_PCIMBR0);
+ pci_write_reg(0x00FC0000 , SH7780_PCIMBMR0); /* 16M */
+
+ /* Set IOBR for window containing area specified in pci.h */
+ pci_write_reg(PCIBIOS_MIN_IO & ~(SH7780_PCI_IO_SIZE-1), SH7780_PCIIOBR);
+ pci_write_reg((SH7780_PCI_IO_SIZE-1) & (7 << 18), SH7780_PCIIOBMR);
+
+ pci_write_reg(0xA5000C01, SH7780_PCICR);
+
+ return 0;
+}
diff --git a/arch/sh/drivers/pci/ops-landisk.c b/arch/sh/drivers/pci/ops-landisk.c
index d06030815a9..bff09ecf341 100644
--- a/arch/sh/drivers/pci/ops-landisk.c
+++ b/arch/sh/drivers/pci/ops-landisk.c
@@ -17,8 +17,8 @@
static struct resource sh7751_io_resource = {
.name = "SH7751 IO",
- .start = 0x4000,
- .end = 0x4000 + SH7751_PCI_IO_SIZE - 1,
+ .start = SH7751_PCI_IO_BASE,
+ .end = SH7751_PCI_IO_BASE + SH7751_PCI_IO_SIZE - 1,
.flags = IORESOURCE_IO
};
diff --git a/arch/sh/drivers/pci/ops-lboxre2.c b/arch/sh/drivers/pci/ops-lboxre2.c
new file mode 100644
index 00000000000..a13cb764b0b
--- /dev/null
+++ b/arch/sh/drivers/pci/ops-lboxre2.c
@@ -0,0 +1,63 @@
+/*
+ * linux/arch/sh/drivers/pci/ops-lboxre2.c
+ *
+ * Copyright (C) 2007 Nobuhiro Iwamatsu
+ *
+ * PCI initialization for the NTT COMWARE L-BOX RE2
+ */
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/io.h>
+#include <asm/lboxre2.h>
+#include "pci-sh4.h"
+
+static char lboxre2_irq_tab[] __initdata = {
+ IRQ_ETH0, IRQ_ETH1, IRQ_INTA, IRQ_INTD,
+};
+
+int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin)
+{
+ return lboxre2_irq_tab[slot];
+}
+
+static struct resource sh7751_io_resource = {
+ .name = "SH7751_IO",
+ .start = SH7751_PCI_IO_BASE ,
+ .end = SH7751_PCI_IO_BASE + SH7751_PCI_IO_SIZE - 1,
+ .flags = IORESOURCE_IO
+};
+
+static struct resource sh7751_mem_resource = {
+ .name = "SH7751_mem",
+ .start = SH7751_PCI_MEMORY_BASE,
+ .end = SH7751_PCI_MEMORY_BASE + SH7751_PCI_MEM_SIZE - 1,
+ .flags = IORESOURCE_MEM
+};
+
+extern struct pci_ops sh7751_pci_ops;
+
+struct pci_channel board_pci_channels[] = {
+ { &sh4_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff },
+ { NULL, NULL, NULL, 0, 0 },
+};
+
+EXPORT_SYMBOL(board_pci_channels);
+
+static struct sh4_pci_address_map sh7751_pci_map = {
+ .window0 = {
+ .base = SH7751_CS3_BASE_ADDR,
+ .size = 0x04000000,
+ },
+ .window1 = {
+ .base = 0x00000000, /* Unused */
+ .size = 0x00000000, /* Unused */
+ },
+ .flags = SH4_PCIC_NO_RESET,
+};
+
+int __init pcibios_init_platform(void)
+{
+ return sh7751_pcic_init(&sh7751_pci_map);
+}
diff --git a/arch/sh/drivers/pci/ops-r7780rp.c b/arch/sh/drivers/pci/ops-r7780rp.c
index eeea1577e11..f2216081ab8 100644
--- a/arch/sh/drivers/pci/ops-r7780rp.c
+++ b/arch/sh/drivers/pci/ops-r7780rp.c
@@ -17,18 +17,25 @@
#include <asm/io.h>
#include "pci-sh4.h"
+static char r7780rp_irq_tab[] __initdata = {
+ 0, 1, 2, 3,
+};
+
+static char r7780mp_irq_tab[] __initdata = {
+ 65, 66, 67, 68,
+};
+
int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin)
{
- switch (slot) {
- case 0: return IRQ_PCISLOT1; /* PCI Interrupt #1 */
- case 1: return IRQ_PCISLOT2; /* PCI Interrupt #2 */
- case 2: return IRQ_PCISLOT3; /* PCI Interrupt #3 */
- case 3: return IRQ_PCISLOT4; /* PCI Interrupt E4 */
- default:
- printk(KERN_ERR "PCI: Bad IRQ mapping "
- "request for slot %d, func %d\n", slot, pin-1);
- return -1;
- }
+ if (mach_is_r7780rp())
+ return r7780rp_irq_tab[slot];
+ if (mach_is_r7780mp() || mach_is_r7785rp())
+ return r7780mp_irq_tab[slot];
+
+ printk(KERN_ERR "PCI: Bad IRQ mapping "
+ "request for slot %d, func %d\n", slot, pin-1);
+
+ return -1;
}
static struct resource sh7780_io_resource = {
diff --git a/arch/sh/drivers/pci/ops-se7780.c b/arch/sh/drivers/pci/ops-se7780.c
new file mode 100644
index 00000000000..212674df5e1
--- /dev/null
+++ b/arch/sh/drivers/pci/ops-se7780.c
@@ -0,0 +1,96 @@
+/*
+ * linux/arch/sh/drivers/pci/ops-se7780.c
+ *
+ * Copyright (C) 2006 Nobuhiro Iwamatsu
+ *
+ * PCI initialization for the Hitachi UL Solution Engine 7780SE03
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License. See linux/COPYING for more information.
+ */
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/pci.h>
+#include <asm/se7780.h>
+#include <asm/io.h>
+#include "pci-sh4.h"
+
+/*
+ * IDSEL = AD16 PCI slot
+ * IDSEL = AD17 PCI slot
+ * IDSEL = AD18 Serial ATA Controller (Silicon Image SiL3512A)
+ * IDSEL = AD19 USB Host Controller (NEC uPD7210100A)
+ */
+
+/* IDSEL [16][17][18][19][20][21][22][23][24][25][26][27][28][29][30][31] */
+static char se7780_irq_tab[4][16] __initdata = {
+ /* INTA */
+ { 65, 68, 67, 68, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+ /* INTB */
+ { 66, 65, -1, 65, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+ /* INTC */
+ { 67, 66, -1, 66, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+ /* INTD */
+ { 68, 67, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+};
+
+int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin)
+{
+ return se7780_irq_tab[pin-1][slot];
+}
+
+static struct resource se7780_io_resource = {
+ .name = "SH7780_IO",
+ .start = 0x2000,
+ .end = 0x2000 + SH7780_PCI_IO_SIZE - 1,
+ .flags = IORESOURCE_IO
+};
+
+static struct resource se7780_mem_resource = {
+ .name = "SH7780_mem",
+ .start = SH7780_PCI_MEMORY_BASE,
+ .end = SH7780_PCI_MEMORY_BASE + SH7780_PCI_MEM_SIZE - 1,
+ .flags = IORESOURCE_MEM
+};
+
+extern struct pci_ops se7780_pci_ops;
+
+struct pci_channel board_pci_channels[] = {
+ { &sh4_pci_ops, &se7780_io_resource, &se7780_mem_resource, 0, 0xff },
+ { NULL, NULL, NULL, 0, 0 },
+};
+EXPORT_SYMBOL(board_pci_channels);
+
+static struct sh4_pci_address_map se7780_pci_map = {
+ .window0 = {
+ .base = SH7780_CS2_BASE_ADDR,
+ .size = 0x04000000,
+ },
+ .flags = SH4_PCIC_NO_RESET,
+};
+
+int __init pcibios_init_platform(void)
+{
+ printk("SH7780 PCI: Finished initialization of the PCI controller\n");
+
+ /*
+ * FPGA PCISEL register initialize
+ *
+ * CPU || SLOT1 | SLOT2 | S-ATA | USB
+ * -------------------------------------
+ * INTA || INTA | INTD | -- | INTB
+ * -------------------------------------
+ * INTB || INTB | INTA | -- | INTC
+ * -------------------------------------
+ * INTC || INTC | INTB | INTA | --
+ * -------------------------------------
+ * INTD || INTD | INTC | -- | INTA
+ * -------------------------------------
+ */
+ ctrl_outw(0x0013, FPGA_PCI_INTSEL1);
+ ctrl_outw(0xE402, FPGA_PCI_INTSEL2);
+
+ return sh7780_pcic_init(&se7780_pci_map);
+}
diff --git a/arch/sh/drivers/pci/ops-sh4.c b/arch/sh/drivers/pci/ops-sh4.c
index 2d4371009a5..54232f13e40 100644
--- a/arch/sh/drivers/pci/ops-sh4.c
+++ b/arch/sh/drivers/pci/ops-sh4.c
@@ -162,3 +162,9 @@ char * __init pcibios_setup(char *str)
return str;
}
+
+int __attribute__((weak)) pci_fixup_pcic(void)
+{
+ /* Nothing to do. */
+ return 0;
+}
diff --git a/arch/sh/drivers/pci/pci-sh4.h b/arch/sh/drivers/pci/pci-sh4.h
index 5a61d6041f2..1901c33cde6 100644
--- a/arch/sh/drivers/pci/pci-sh4.h
+++ b/arch/sh/drivers/pci/pci-sh4.h
@@ -1,7 +1,7 @@
#ifndef __PCI_SH4_H
#define __PCI_SH4_H
-#ifdef CONFIG_CPU_SUBTYPE_SH7780
+#if defined(CONFIG_CPU_SUBTYPE_SH7780) || defined(CONFIG_CPU_SUBTYPE_SH7785)
#include "pci-sh7780.h"
#else
#include "pci-sh7751.h"
diff --git a/arch/sh/drivers/pci/pci-sh7751.c b/arch/sh/drivers/pci/pci-sh7751.c
index 9ddff760d3c..1aca7fe5783 100644
--- a/arch/sh/drivers/pci/pci-sh7751.c
+++ b/arch/sh/drivers/pci/pci-sh7751.c
@@ -12,7 +12,6 @@
* License. See linux/COPYING for more information.
*
*/
-
#undef DEBUG
#include <linux/init.h>
@@ -28,7 +27,7 @@
* Initialization. Try all known PCI access methods. Note that we support
* using both PCI BIOS and direct access: in such cases, we use I/O ports
* to access config space.
- *
+ *
* Note that the platform specific initialization (BSC registers, and memory
* space mapping) will be called via the platform defined function
* pcibios_init_platform().
@@ -115,7 +114,7 @@ int __init sh7751_pcic_init(struct sh4_pci_address_map *map)
* Wait Cycle Control + Parity Enable + Bus Master +
* Mem space enable
*/
- word = SH7751_PCICONF1_WCC | SH7751_PCICONF1_PER |
+ word = SH7751_PCICONF1_WCC | SH7751_PCICONF1_PER |
SH7751_PCICONF1_BUM | SH7751_PCICONF1_MES;
pci_write_reg(word, SH7751_PCICONF1);
@@ -123,10 +122,10 @@ int __init sh7751_pcic_init(struct sh4_pci_address_map *map)
word = PCI_BASE_CLASS_BRIDGE << 24;
pci_write_reg(word, SH7751_PCICONF2);
- /* Set IO and Mem windows to local address
- * Make PCI and local address the same for easy 1 to 1 mapping
+ /* Set IO and Mem windows to local address
+ * Make PCI and local address the same for easy 1 to 1 mapping
* Window0 = map->window0.size @ non-cached area base = SDRAM
- * Window1 = map->window1.size @ cached area base = SDRAM
+ * Window1 = map->window1.size @ cached area base = SDRAM
*/
word = map->window0.size - 1;
pci_write_reg(word, SH4_PCILSR0);
@@ -175,7 +174,7 @@ int __init sh7751_pcic_init(struct sh4_pci_address_map *map)
case SH7751_CS5_BASE_ADDR: word = __area_sdram_check(5); break;
case SH7751_CS6_BASE_ADDR: word = __area_sdram_check(6); break;
}
-
+
if (!word)
return 0;
@@ -194,9 +193,7 @@ int __init sh7751_pcic_init(struct sh4_pci_address_map *map)
* DMA interrupts...
*/
-#ifdef CONFIG_SH_RTS7751R2D
pci_fixup_pcic();
-#endif
/* SH7751 init done, set central function init complete */
/* use round robin mode to stop a device starving/overruning */
diff --git a/arch/sh/drivers/pci/pci-sh7780.c b/arch/sh/drivers/pci/pci-sh7780.c
index 602b644c35a..5508e45d483 100644
--- a/arch/sh/drivers/pci/pci-sh7780.c
+++ b/arch/sh/drivers/pci/pci-sh7780.c
@@ -48,7 +48,7 @@
static int __init sh7780_pci_init(void)
{
unsigned int id;
- int ret;
+ int ret, match = 0;
pr_debug("PCI: Starting intialization.\n");
@@ -56,19 +56,43 @@ static int __init sh7780_pci_init(void)
/* check for SH7780/SH7780R hardware */
id = pci_read_reg(SH7780_PCIVID);
- if ((id != ((SH7780_DEVICE_ID << 16) | SH7780_VENDOR_ID)) &&
- (id != ((SH7781_DEVICE_ID << 16) | SH7780_VENDOR_ID))) {
+ if ((id & 0xffff) == SH7780_VENDOR_ID) {
+ switch ((id >> 16) & 0xffff) {
+ case SH7780_DEVICE_ID:
+ case SH7781_DEVICE_ID:
+ case SH7785_DEVICE_ID:
+ match = 1;
+ break;
+ }
+ }
+
+ if (unlikely(!match)) {
printk(KERN_ERR "PCI: This is not an SH7780 (%x)\n", id);
return -ENODEV;
}
/* Setup the INTC */
- ctrl_outl(0x00200000, INTC_ICR0); /* INTC SH-4 Mode */
- ctrl_outl(0x00078000, INTC_INT2MSKCR); /* enable PCIINTA - PCIINTD */
- ctrl_outl(0x40000000, INTC_INTMSK1); /* disable IRL4-7 Interrupt */
- ctrl_outl(0x0000fffe, INTC_INTMSK2); /* disable IRL4-7 Interrupt */
- ctrl_outl(0x80000000, INTC_INTMSKCLR1); /* enable IRL0-3 Interrupt */
- ctrl_outl(0xfffe0000, INTC_INTMSKCLR2); /* enable IRL0-3 Interrupt */
+ if (mach_is_7780se()) {
+ /* ICR0: IRL=use separately */
+ ctrl_outl(0x00C00020, INTC_ICR0);
+ /* ICR1: detect low level(for 2ndcut) */
+ ctrl_outl(0xAAAA0000, INTC_ICR1);
+ /* INTPRI: priority=3(all) */
+ ctrl_outl(0x33333333, INTC_INTPRI);
+ } else {
+ /* INTC SH-4 Mode */
+ ctrl_outl(0x00200000, INTC_ICR0);
+ /* enable PCIINTA - PCIINTD */
+ ctrl_outl(0x00078000, INTC_INT2MSKCR);
+ /* disable IRL4-7 Interrupt */
+ ctrl_outl(0x40000000, INTC_INTMSK1);
+ /* disable IRL4-7 Interrupt */
+ ctrl_outl(0x0000fffe, INTC_INTMSK2);
+ /* enable IRL0-3 Interrupt */
+ ctrl_outl(0x80000000, INTC_INTMSKCLR1);
+ /* enable IRL0-3 Interrupt */
+ ctrl_outl(0xfffe0000, INTC_INTMSKCLR2);
+ }
if ((ret = sh4_pci_check_direct()) != 0)
return ret;
@@ -138,9 +162,8 @@ int __init sh7780_pcic_init(struct sh4_pci_address_map *map)
* DMA interrupts...
*/
-#ifdef CONFIG_SH_R7780RP
+ /* Apply any last-minute PCIC fixups */
pci_fixup_pcic();
-#endif
/* SH7780 init done, set central function init complete */
/* use round robin mode to stop a device starving/overruning */
diff --git a/arch/sh/drivers/pci/pci-sh7780.h b/arch/sh/drivers/pci/pci-sh7780.h
index f02d2180a4b..00d12d0f8c1 100644
--- a/arch/sh/drivers/pci/pci-sh7780.h
+++ b/arch/sh/drivers/pci/pci-sh7780.h
@@ -14,8 +14,9 @@
/* Platform Specific Values */
#define SH7780_VENDOR_ID 0x1912
-#define SH7780_DEVICE_ID 0x0002
#define SH7781_DEVICE_ID 0x0001
+#define SH7780_DEVICE_ID 0x0002
+#define SH7785_DEVICE_ID 0x0007
/* SH7780 Control Registers */
#define SH7780_PCI_VCR0 0xFE000000
@@ -65,6 +66,22 @@
#define SH7780_PCIPMCSR_BSE 0x046
#define SH7780_PCICDD 0x047
+#define SH7780_PCICR 0x100 /* PCI Control Register */
+#define SH7780_PCILSR 0x104 /* PCI Local Space Register0 */
+#define SH7780_PCILSR1 0x108 /* PCI Local Space Register1 */
+#define SH7780_PCILAR0 0x10C /* PCI Local Address Register1 */
+#define SH7780_PCILAR1 0x110 /* PCI Local Address Register1 */
+#define SH7780_PCIIR 0x114 /* PCI Interrupt Register */
+#define SH7780_PCIIMR 0x118 /* PCI Interrupt Mask Register */
+#define SH7780_PCIAIR 0x11C /* Error Address Register */
+#define SH7780_PCICIR 0x120 /* Error Command/Data Register */
+#define SH7780_PCIAINT 0x130 /* Arbiter Interrupt Register */
+#define SH7780_PCIAINTM 0x134 /* Arbiter Int. Mask Register */
+#define SH7780_PCIBMIR 0x138 /* Error Bus Master Register */
+#define SH7780_PCIPAR 0x1C0 /* PIO Address Register */
+#define SH7780_PCIPINT 0x1CC /* Power Mgmnt Int. Register */
+#define SH7780_PCIPINTM 0x1D0 /* Power Mgmnt Mask Register */
+
#define SH7780_PCIMBR0 0x1E0
#define SH7780_PCIMBMR0 0x1E4
#define SH7780_PCIMBR2 0x1F0
diff --git a/arch/sh/kernel/Makefile b/arch/sh/kernel/Makefile
index ff30d7f5804..9104b625764 100644
--- a/arch/sh/kernel/Makefile
+++ b/arch/sh/kernel/Makefile
@@ -20,5 +20,6 @@ obj-$(CONFIG_SH_CPU_FREQ) += cpufreq.o
obj-$(CONFIG_MODULES) += module.o
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
+obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
obj-$(CONFIG_PM) += pm.o
obj-$(CONFIG_STACKTRACE) += stacktrace.o
diff --git a/arch/sh/kernel/cf-enabler.c b/arch/sh/kernel/cf-enabler.c
index 3e5fa1e24df..0758d48147a 100644
--- a/arch/sh/kernel/cf-enabler.c
+++ b/arch/sh/kernel/cf-enabler.c
@@ -29,7 +29,7 @@
* 0xB8001000 : Common Memory
* 0xBA000000 : I/O
*/
-#if defined(CONFIG_IDE) && defined(CONFIG_CPU_SH4)
+#if defined(CONFIG_CPU_SH4)
/* SH4 can't access PCMCIA interface through P2 area.
* we must remap it with appropreate attribute bit of the page set.
* this part is based on Greg Banks' hd64465_ss.c implementation - Masahiro Abe */
@@ -71,7 +71,7 @@ static int __init cf_init_default(void)
/* You must have enabled the card, and set the level interrupt
* before reaching this point. Possibly in boot ROM or boot loader.
*/
-#if defined(CONFIG_IDE) && defined(CONFIG_CPU_SH4)
+#if defined(CONFIG_CPU_SH4)
allocate_cf_area();
#endif
#if defined(CONFIG_SH_UNKNOWN)
@@ -84,15 +84,25 @@ static int __init cf_init_default(void)
#if defined(CONFIG_SH_SOLUTION_ENGINE)
#include <asm/se.h>
+#elif defined(CONFIG_SH_7722_SOLUTION_ENGINE)
+#include <asm/se7722.h>
+#endif
/*
- * SolutionEngine
+ * SolutionEngine Seriese
*
+ * about MS770xSE
* 0xB8400000 : Common Memory
* 0xB8500000 : Attribute
* 0xB8600000 : I/O
+ *
+ * about MS7722SE
+ * 0xB0400000 : Common Memory
+ * 0xB0500000 : Attribute
+ * 0xB0600000 : I/O
*/
+#if defined(CONFIG_SH_SOLUTION_ENGINE) || defined(CONFIG_SH_7722_SOLUTION_ENGINE)
static int __init cf_init_se(void)
{
if ((ctrl_inw(MRSHPC_CSR) & 0x000c) != 0)
@@ -109,7 +119,7 @@ static int __init cf_init_se(void)
* flag == COMMON/ATTRIBUTE/IO
*/
/* common window open */
- ctrl_outw(0x8a84, MRSHPC_MW0CR1);/* window 0xb8400000 */
+ ctrl_outw(0x8a84, MRSHPC_MW0CR1);
if((ctrl_inw(MRSHPC_CSR) & 0x4000) != 0)
/* common mode & bus width 16bit SWAP = 1*/
ctrl_outw(0x0b00, MRSHPC_MW0CR2);
@@ -118,7 +128,7 @@ static int __init cf_init_se(void)
ctrl_outw(0x0300, MRSHPC_MW0CR2);
/* attribute window open */
- ctrl_outw(0x8a85, MRSHPC_MW1CR1);/* window 0xb8500000 */
+ ctrl_outw(0x8a85, MRSHPC_MW1CR1);
if ((ctrl_inw(MRSHPC_CSR) & 0x4000) != 0)
/* attribute mode & bus width 16bit SWAP = 1*/
ctrl_outw(0x0a00, MRSHPC_MW1CR2);
@@ -127,7 +137,7 @@ static int __init cf_init_se(void)
ctrl_outw(0x0200, MRSHPC_MW1CR2);
/* I/O window open */
- ctrl_outw(0x8a86, MRSHPC_IOWCR1);/* I/O window 0xb8600000 */
+ ctrl_outw(0x8a86, MRSHPC_IOWCR1);
ctrl_outw(0x0008, MRSHPC_CDCR); /* I/O card mode */
if ((ctrl_inw(MRSHPC_CSR) & 0x4000) != 0)
ctrl_outw(0x0a00, MRSHPC_IOWCR2); /* bus width 16bit SWAP = 1*/
@@ -143,10 +153,10 @@ static int __init cf_init_se(void)
int __init cf_init(void)
{
-#if defined(CONFIG_SH_SOLUTION_ENGINE)
- if (MACH_SE)
+ if( mach_is_se() || mach_is_7722se() ){
return cf_init_se();
-#endif
+ }
+
return cf_init_default();
}
diff --git a/arch/sh/kernel/cpu/clock.c b/arch/sh/kernel/cpu/clock.c
index abb586b1256..014f318f5a0 100644
--- a/arch/sh/kernel/cpu/clock.c
+++ b/arch/sh/kernel/cpu/clock.c
@@ -1,7 +1,7 @@
/*
* arch/sh/kernel/cpu/clock.c - SuperH clock framework
*
- * Copyright (C) 2005, 2006 Paul Mundt
+ * Copyright (C) 2005, 2006, 2007 Paul Mundt
*
* This clock framework is derived from the OMAP version by:
*
@@ -23,6 +23,7 @@
#include <linux/seq_file.h>
#include <linux/err.h>
#include <linux/platform_device.h>
+#include <linux/proc_fs.h>
#include <asm/clock.h>
#include <asm/timer.h>
@@ -98,15 +99,17 @@ int __clk_enable(struct clk *clk)
if (clk->ops && clk->ops->init)
clk->ops->init(clk);
+ kref_get(&clk->kref);
+
if (clk->flags & CLK_ALWAYS_ENABLED)
return 0;
if (likely(clk->ops && clk->ops->enable))
clk->ops->enable(clk);
- kref_get(&clk->kref);
return 0;
}
+EXPORT_SYMBOL_GPL(__clk_enable);
int clk_enable(struct clk *clk)
{
@@ -119,6 +122,7 @@ int clk_enable(struct clk *clk)
return ret;
}
+EXPORT_SYMBOL_GPL(clk_enable);
static void clk_kref_release(struct kref *kref)
{
@@ -127,11 +131,17 @@ static void clk_kref_release(struct kref *kref)
void __clk_disable(struct clk *clk)
{
+ int count = kref_put(&clk->kref, clk_kref_release);
+
if (clk->flags & CLK_ALWAYS_ENABLED)
return;
- kref_put(&clk->kref, clk_kref_release);
+ if (!count) { /* count reaches zero, disable the clock */
+ if (likely(clk->ops && clk->ops->disable))
+ clk->ops->disable(clk);
+ }
}
+EXPORT_SYMBOL_GPL(__clk_disable);
void clk_disable(struct clk *clk)
{
@@ -141,6 +151,7 @@ void clk_disable(struct clk *clk)
__clk_disable(clk);
spin_unlock_irqrestore(&clock_lock, flags);
}
+EXPORT_SYMBOL_GPL(clk_disable);
int clk_register(struct clk *clk)
{
@@ -151,8 +162,18 @@ int clk_register(struct clk *clk)
mutex_unlock(&clock_list_sem);
+ if (clk->flags & CLK_ALWAYS_ENABLED) {
+ pr_debug( "Clock '%s' is ALWAYS_ENABLED\n", clk->name);
+ if (clk->ops && clk->ops->init)
+ clk->ops->init(clk);
+ if (clk->ops && clk->ops->enable)
+ clk->ops->enable(clk);
+ pr_debug( "Enabled.");
+ }
+
return 0;
}
+EXPORT_SYMBOL_GPL(clk_register);
void clk_unregister(struct clk *clk)
{
@@ -160,21 +181,29 @@ void clk_unregister(struct clk *clk)
list_del(&clk->node);
mutex_unlock(&clock_list_sem);
}
+EXPORT_SYMBOL_GPL(clk_unregister);
-inline unsigned long clk_get_rate(struct clk *clk)
+unsigned long clk_get_rate(struct clk *clk)
{
return clk->rate;
}
+EXPORT_SYMBOL_GPL(clk_get_rate);
int clk_set_rate(struct clk *clk, unsigned long rate)
{
+ return clk_set_rate_ex(clk, rate, 0);
+}
+EXPORT_SYMBOL_GPL(clk_set_rate);
+
+int clk_set_rate_ex(struct clk *clk, unsigned long rate, int algo_id)
+{
int ret = -EOPNOTSUPP;
if (likely(clk->ops && clk->ops->set_rate)) {
unsigned long flags;
spin_lock_irqsave(&clock_lock, flags);
- ret = clk->ops->set_rate(clk, rate);
+ ret = clk->ops->set_rate(clk, rate, algo_id);
spin_unlock_irqrestore(&clock_lock, flags);
}
@@ -183,6 +212,7 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
return ret;
}
+EXPORT_SYMBOL_GPL(clk_set_rate_ex);
void clk_recalc_rate(struct clk *clk)
{
@@ -197,6 +227,7 @@ void clk_recalc_rate(struct clk *clk)
if (unlikely(clk->flags & CLK_RATE_PROPAGATES))
propagate_rate(clk);
}
+EXPORT_SYMBOL_GPL(clk_recalc_rate);
/*
* Returns a clock. Note that we first try to use device id on the bus
@@ -233,18 +264,43 @@ found:
return clk;
}
+EXPORT_SYMBOL_GPL(clk_get);
void clk_put(struct clk *clk)
{
if (clk && !IS_ERR(clk))
module_put(clk->owner);
}
+EXPORT_SYMBOL_GPL(clk_put);
void __init __attribute__ ((weak))
arch_init_clk_ops(struct clk_ops **ops, int type)
{
}
+static int show_clocks(char *buf, char **start, off_t off,
+ int len, int *eof, void *data)
+{
+ struct clk *clk;
+ char *p = buf;
+
+ list_for_each_entry_reverse(clk, &clock_list, node) {
+ unsigned long rate = clk_get_rate(clk);
+
+ /*
+ * Don't bother listing dummy clocks with no ancestry
+ * that only support enable and disable ops.
+ */
+ if (unlikely(!rate && !clk->parent))
+ continue;
+
+ p += sprintf(p, "%-12s\t: %ld.%02ldMHz\n", clk->name,
+ rate / 1000000, (rate % 1000000) / 10000);
+ }
+
+ return p - buf;
+}
+
int __init clk_init(void)
{
int i, ret = 0;
@@ -256,7 +312,6 @@ int __init clk_init(void)
arch_init_clk_ops(&clk->ops, i);
ret |= clk_register(clk);
- clk_enable(clk);
}
/* Kick the child clocks.. */
@@ -266,35 +321,14 @@ int __init clk_init(void)
return ret;
}
-int show_clocks(struct seq_file *m)
+static int __init clk_proc_init(void)
{
- struct clk *clk;
-
- list_for_each_entry_reverse(clk, &clock_list, node) {
- unsigned long rate = clk_get_rate(clk);
-
- /*
- * Don't bother listing dummy clocks with no ancestry
- * that only support enable and disable ops.
- */
- if (unlikely(!rate && !clk->parent))
- continue;
-
- seq_printf(m, "%-12s\t: %ld.%02ldMHz\n", clk->name,
- rate / 1000000, (rate % 1000000) / 10000);
- }
+ struct proc_dir_entry *p;
+ p = create_proc_read_entry("clocks", S_IRUSR, NULL,
+ show_clocks, NULL);
+ if (unlikely(!p))
+ return -EINVAL;
return 0;
}
-
-EXPORT_SYMBOL_GPL(clk_register);
-EXPORT_SYMBOL_GPL(clk_unregister);
-EXPORT_SYMBOL_GPL(clk_get);
-EXPORT_SYMBOL_GPL(clk_put);
-EXPORT_SYMBOL_GPL(clk_enable);
-EXPORT_SYMBOL_GPL(clk_disable);
-EXPORT_SYMBOL_GPL(__clk_enable);
-EXPORT_SYMBOL_GPL(__clk_disable);
-EXPORT_SYMBOL_GPL(clk_get_rate);
-EXPORT_SYMBOL_GPL(clk_set_rate);
-EXPORT_SYMBOL_GPL(clk_recalc_rate);
+subsys_initcall(clk_proc_init);
diff --git a/arch/sh/kernel/cpu/init.c b/arch/sh/kernel/cpu/init.c
index 726acfcb9b7..6451ad63017 100644
--- a/arch/sh/kernel/cpu/init.c
+++ b/arch/sh/kernel/cpu/init.c
@@ -41,6 +41,23 @@ __setup("no" __stringify(x), x##_setup);
onchip_setup(fpu);
onchip_setup(dsp);
+#ifdef CONFIG_SPECULATIVE_EXECUTION
+#define CPUOPM 0xff2f0000
+#define CPUOPM_RABD (1 << 5)
+
+static void __init speculative_execution_init(void)
+{
+ /* Clear RABD */
+ ctrl_outl(ctrl_inl(CPUOPM) & ~CPUOPM_RABD, CPUOPM);
+
+ /* Flush the update */
+ (void)ctrl_inl(CPUOPM);
+ ctrl_barrier();
+}
+#else
+#define speculative_execution_init() do { } while (0)
+#endif
+
/*
* Generic first-level cache init
*/
@@ -261,4 +278,6 @@ asmlinkage void __init sh_cpu_init(void)
*/
ubc_wakeup();
#endif
+
+ speculative_execution_init();
}
diff --git a/arch/sh/kernel/cpu/irq/Makefile b/arch/sh/kernel/cpu/irq/Makefile
index 0049d217561..1c23308cfc2 100644
--- a/arch/sh/kernel/cpu/irq/Makefile
+++ b/arch/sh/kernel/cpu/irq/Makefile
@@ -4,6 +4,6 @@
obj-y += imask.o
obj-$(CONFIG_CPU_HAS_IPR_IRQ) += ipr.o
-obj-$(CONFIG_CPU_HAS_PINT_IRQ) += pint.o
+obj-$(CONFIG_CPU_HAS_PINT_IRQ) += pint.o
obj-$(CONFIG_CPU_HAS_MASKREG_IRQ) += maskreg.o
obj-$(CONFIG_CPU_HAS_INTC2_IRQ) += intc2.o
diff --git a/arch/sh/kernel/cpu/irq/intc2.c b/arch/sh/kernel/cpu/irq/intc2.c
index 74defe76a05..d8e22f4ff0f 100644
--- a/arch/sh/kernel/cpu/irq/intc2.c
+++ b/arch/sh/kernel/cpu/irq/intc2.c
@@ -18,7 +18,8 @@
#define INTC2_BASE 0xfe080000
#define INTC2_INTMSK (INTC2_BASE + 0x40)
#define INTC2_INTMSKCLR (INTC2_BASE + 0x60)
-#elif defined(CONFIG_CPU_SUBTYPE_SH7780)
+#elif defined(CONFIG_CPU_SUBTYPE_SH7780) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7785)
#define INTC2_BASE 0xffd40000
#define INTC2_INTMSK (INTC2_BASE + 0x38)
#define INTC2_INTMSKCLR (INTC2_BASE + 0x3c)
diff --git a/arch/sh/kernel/cpu/irq/pint.c b/arch/sh/kernel/cpu/irq/pint.c
index f60007783a2..67602685df1 100644
--- a/arch/sh/kernel/cpu/irq/pint.c
+++ b/arch/sh/kernel/cpu/irq/pint.c
@@ -18,6 +18,58 @@
#include <asm/io.h>
#include <asm/machvec.h>
+#if defined(CONFIG_CPU_SUBTYPE_SH7705)
+#define INTC_INTER 0xA4000014UL
+#define INTC_IPRD 0xA4000018UL
+#define INTC_ICR2 0xA4000012UL
+
+/* PFC */
+#define PORT_PACR 0xA4000100UL
+#define PORT_PBCR 0xA4000102UL
+#define PORT_PCCR 0xA4000104UL
+#define PORT_PDCR 0xA4000106UL
+#define PORT_PECR 0xA4000108UL
+#define PORT_PFCR 0xA400010AUL
+#define PORT_PGCR 0xA400010CUL
+#define PORT_PHCR 0xA400010EUL
+#define PORT_PJCR 0xA4000110UL
+#define PORT_PKCR 0xA4000112UL
+#define PORT_PLCR 0xA4000114UL
+#define PORT_PMCR 0xA4000118UL
+#define PORT_PNCR 0xA400011AUL
+#define PORT_PECR2 0xA4050148UL
+#define PORT_PFCR2 0xA405014AUL
+#define PORT_PNCR2 0xA405015AUL
+
+/* I/O port */
+#define PORT_PADR 0xA4000120UL
+#define PORT_PBDR 0xA4000122UL
+#define PORT_PCDR 0xA4000124UL
+#define PORT_PDDR 0xA4000126UL
+#define PORT_PEDR 0xA4000128UL
+#define PORT_PFDR 0xA400012AUL
+#define PORT_PGDR 0xA400012CUL
+#define PORT_PHDR 0xA400012EUL
+#define PORT_PJDR 0xA4000130UL
+#define PORT_PKDR 0xA4000132UL
+#define PORT_PLDR 0xA4000134UL
+#define PORT_PMDR 0xA4000138UL
+#define PORT_PNDR 0xA400013AUL
+
+#define PINT0_IRQ 40
+#define PINT8_IRQ 41
+#define PINT_IRQ_BASE 86
+
+#define PINT0_IPR_ADDR INTC_IPRD
+#define PINT0_IPR_POS 3
+#define PINT0_PRIORITY 2
+
+#define PINT8_IPR_ADDR INTC_IPRD
+#define PINT8_IPR_POS 2
+#define PINT8_PRIORITY 2
+
+#endif /* CONFIG_CPU_SUBTYPE_SH7705 */
+
static unsigned char pint_map[256];
static unsigned long portcr_mask;
@@ -126,7 +178,7 @@ int ipr_irq_demux(int irq)
unsigned long creg, dreg, d, sav;
if (irq == PINT0_IRQ) {
-#if defined(CONFIG_CPU_SUBTYPE_SH7707)
+#if defined(CONFIG_CPU_SUBTYPE_SH7705) || defined(CONFIG_CPU_SUBTYPE_SH7707)
creg = PORT_PACR;
dreg = PORT_PADR;
#else
@@ -144,7 +196,7 @@ int ipr_irq_demux(int irq)
return PINT_IRQ_BASE + pint_map[d];
} else if (irq == PINT8_IRQ) {
-#if defined(CONFIG_CPU_SUBTYPE_SH7707)
+#if defined(CONFIG_CPU_SUBTYPE_SH7705) || defined(CONFIG_CPU_SUBTYPE_SH7707)
creg = PORT_PBCR;
dreg = PORT_PBDR;
#else
diff --git a/arch/sh/kernel/cpu/sh3/Makefile b/arch/sh/kernel/cpu/sh3/Makefile
index 83905e4e438..09faa056cd4 100644
--- a/arch/sh/kernel/cpu/sh3/Makefile
+++ b/arch/sh/kernel/cpu/sh3/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_CPU_SUBTYPE_SH7708) += setup-sh7708.o
obj-$(CONFIG_CPU_SUBTYPE_SH7709) += setup-sh7709.o
obj-$(CONFIG_CPU_SUBTYPE_SH7300) += setup-sh7300.o
obj-$(CONFIG_CPU_SUBTYPE_SH7710) += setup-sh7710.o
+obj-$(CONFIG_CPU_SUBTYPE_SH7712) += setup-sh7710.o
# Primary on-chip clocks (common)
clock-$(CONFIG_CPU_SH3) := clock-sh3.o
diff --git a/arch/sh/kernel/cpu/sh3/probe.c b/arch/sh/kernel/cpu/sh3/probe.c
index 821b0ab7b52..647623b22ed 100644
--- a/arch/sh/kernel/cpu/sh3/probe.c
+++ b/arch/sh/kernel/cpu/sh3/probe.c
@@ -78,6 +78,9 @@ int __init detect_cpu_and_cache_system(void)
#if defined(CONFIG_CPU_SUBTYPE_SH7710)
current_cpu_data.type = CPU_SH7710;
#endif
+#if defined(CONFIG_CPU_SUBTYPE_SH7712)
+ current_cpu_data.type = CPU_SH7712;
+#endif
#if defined(CONFIG_CPU_SUBTYPE_SH7705)
current_cpu_data.type = CPU_SH7705;
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7705.c b/arch/sh/kernel/cpu/sh3/setup-sh7705.c
index a8e41c5241f..1983fb7ad6e 100644
--- a/arch/sh/kernel/cpu/sh3/setup-sh7705.c
+++ b/arch/sh/kernel/cpu/sh3/setup-sh7705.c
@@ -2,6 +2,7 @@
* SH7705 Setup
*
* Copyright (C) 2006 Paul Mundt
+ * 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
@@ -14,15 +15,15 @@
static struct plat_sci_port sci_platform_data[] = {
{
- .mapbase = 0xa4400000,
+ .mapbase = 0xa4410000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIF,
- .irqs = { 52, 53, 55, 54 },
+ .irqs = { 56, 57, 59 },
}, {
- .mapbase = 0xa4410000,
+ .mapbase = 0xa4400000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIF,
- .irqs = { 56, 57, 59, 58 },
+ .irqs = { 52, 53, 55 },
}, {
.flags = 0,
}
@@ -46,3 +47,48 @@ static int __init sh7705_devices_setup(void)
ARRAY_SIZE(sh7705_devices));
}
__initcall(sh7705_devices_setup);
+
+static struct ipr_data sh7705_ipr_map[] = {
+ /* IRQ, IPR-idx, shift, priority */
+ { 16, 0, 12, 2 }, /* TMU0 TUNI*/
+ { 17, 0, 8, 2 }, /* TMU1 TUNI */
+ { 18, 0, 4, 2 }, /* TMU2 TUNI */
+ { 27, 1, 12, 2 }, /* WDT ITI */
+ { 20, 0, 0, 2 }, /* RTC ATI (alarm) */
+ { 21, 0, 0, 2 }, /* RTC PRI (period) */
+ { 22, 0, 0, 2 }, /* RTC CUI (carry) */
+ { 48, 4, 12, 7 }, /* DMAC DMTE0 */
+ { 49, 4, 12, 7 }, /* DMAC DMTE1 */
+ { 50, 4, 12, 7 }, /* DMAC DMTE2 */
+ { 51, 4, 12, 7 }, /* DMAC DMTE3 */
+ { 52, 4, 8, 3 }, /* SCIF0 ERI */
+ { 53, 4, 8, 3 }, /* SCIF0 RXI */
+ { 55, 4, 8, 3 }, /* SCIF0 TXI */
+ { 56, 4, 4, 3 }, /* SCIF1 ERI */
+ { 57, 4, 4, 3 }, /* SCIF1 RXI */
+ { 59, 4, 4, 3 }, /* SCIF1 TXI */
+};
+
+static unsigned long ipr_offsets[] = {
+ 0xFFFFFEE2 /* 0: IPRA */
+, 0xFFFFFEE4 /* 1: IPRB */
+, 0xA4000016 /* 2: IPRC */
+, 0xA4000018 /* 3: IPRD */
+, 0xA400001A /* 4: IPRE */
+, 0xA4080000 /* 5: IPRF */
+, 0xA4080002 /* 6: IPRG */
+, 0xA4080004 /* 7: IPRH */
+};
+
+/* given the IPR index return the address of the IPR register */
+unsigned int map_ipridx_to_addr(int idx)
+{
+ if (idx >= ARRAY_SIZE(ipr_offsets))
+ return 0;
+ return ipr_offsets[idx];
+}
+
+void __init init_IRQ_ipr()
+{
+ make_ipr_irq(sh7705_ipr_map, ARRAY_SIZE(sh7705_ipr_map));
+}
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7709.c b/arch/sh/kernel/cpu/sh3/setup-sh7709.c
index dc9b211cf87..c7d7c35fc83 100644
--- a/arch/sh/kernel/cpu/sh3/setup-sh7709.c
+++ b/arch/sh/kernel/cpu/sh3/setup-sh7709.c
@@ -48,24 +48,33 @@ static struct platform_device *sh7709_devices[] __initdata = {
static int __init sh7709_devices_setup(void)
{
return platform_add_devices(sh7709_devices,
- ARRAY_SIZE(sh7709_devices));
+ ARRAY_SIZE(sh7709_devices));
}
__initcall(sh7709_devices_setup);
-#define IPRx(A,N) .addr=A, .shift=0*N*-1
+#define IPRx(A,N) .addr=A, .shift=N
#define IPRA(N) IPRx(0xfffffee2UL,N)
#define IPRB(N) IPRx(0xfffffee4UL,N)
+#define IPRC(N) IPRx(0xa4000016UL,N)
+#define IPRD(N) IPRx(0xa4000018UL,N)
#define IPRE(N) IPRx(0xa400001aUL,N)
static struct ipr_data sh7709_ipr_map[] = {
- [16] = { IPRA(15-12), 2 }, /* TMU TUNI0 */
- [17] = { IPRA(11-8), 4 }, /* TMU TUNI1 */
- [22] = { IPRA(3-0), 2 }, /* RTC CUI */
- [23 ... 26] = { IPRB(7-4), 3 }, /* SCI */
- [27] = { IPRB(15-12), 2 }, /* WDT ITI */
- [48 ... 51] = { IPRE(15-12), 7 }, /* DMA */
- [52 ... 55] = { IPRE(11-8), 3 }, /* IRDA */
- [56 ... 59] = { IPRE(7-4), 3 }, /* SCIF */
+ [16] = { IPRA(12), 2 }, /* TMU TUNI0 */
+ [17] = { IPRA(8), 4 }, /* TMU TUNI1 */
+ [18 ... 19] = { IPRA(4), 1 }, /* TMU TUNI1 */
+ [20 ... 22] = { IPRA(0), 2 }, /* RTC CUI */
+ [23 ... 26] = { IPRB(4), 3 }, /* SCI */
+ [27] = { IPRB(12), 2 }, /* WDT ITI */
+ [32] = { IPRC(0), 1 }, /* IRQ 0 */
+ [33] = { IPRC(4), 1 }, /* IRQ 1 */
+ [34] = { IPRC(8), 1 }, /* IRQ 2 APM */
+ [35] = { IPRC(12), 1 }, /* IRQ 3 TOUCHSCREEN */
+ [36] = { IPRD(0), 1 }, /* IRQ 4 */
+ [37] = { IPRD(4), 1 }, /* IRQ 5 */
+ [48 ... 51] = { IPRE(12), 7 }, /* DMA */
+ [52 ... 55] = { IPRE(8), 3 }, /* IRDA */
+ [56 ... 59] = { IPRE(4), 3 }, /* SCIF */
};
void __init init_IRQ_ipr()
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7710.c b/arch/sh/kernel/cpu/sh3/setup-sh7710.c
index 895f99ee6a9..51760a7e7f1 100644
--- a/arch/sh/kernel/cpu/sh3/setup-sh7710.c
+++ b/arch/sh/kernel/cpu/sh3/setup-sh7710.c
@@ -2,6 +2,7 @@
* SH7710 Setup
*
* Copyright (C) 2006 Paul Mundt
+ * 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
@@ -19,6 +20,12 @@ static struct plat_sci_port sci_platform_data[] = {
.type = PORT_SCIF,
.irqs = { 52, 53, 55, 54 },
}, {
+ .mapbase = 0xa4420000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .type = PORT_SCIF,
+ .irqs = { 56, 57, 59, 58 },
+ }, {
+
.flags = 0,
}
};
@@ -41,3 +48,56 @@ static int __init sh7710_devices_setup(void)
ARRAY_SIZE(sh7710_devices));
}
__initcall(sh7710_devices_setup);
+
+static struct ipr_data sh7710_ipr_map[] = {
+ /* IRQ, IPR-idx, shift, priority */
+ { 16, 0, 12, 2 }, /* TMU0 TUNI*/
+ { 17, 0, 8, 2 }, /* TMU1 TUNI */
+ { 18, 0, 4, 2 }, /* TMU2 TUNI */
+ { 27, 1, 12, 2 }, /* WDT ITI */
+ { 20, 0, 0, 2 }, /* RTC ATI (alarm) */
+ { 21, 0, 0, 2 }, /* RTC PRI (period) */
+ { 22, 0, 0, 2 }, /* RTC CUI (carry) */
+ { 48, 4, 12, 7 }, /* DMAC DMTE0 */
+ { 49, 4, 12, 7 }, /* DMAC DMTE1 */
+ { 50, 4, 12, 7 }, /* DMAC DMTE2 */
+ { 51, 4, 12, 7 }, /* DMAC DMTE3 */
+ { 52, 4, 8, 3 }, /* SCIF0 ERI */
+ { 53, 4, 8, 3 }, /* SCIF0 RXI */
+ { 54, 4, 8, 3 }, /* SCIF0 BRI */
+ { 55, 4, 8, 3 }, /* SCIF0 TXI */
+ { 56, 4, 4, 3 }, /* SCIF1 ERI */
+ { 57, 4, 4, 3 }, /* SCIF1 RXI */
+ { 58, 4, 4, 3 }, /* SCIF1 BRI */
+ { 59, 4, 4, 3 }, /* SCIF1 TXI */
+ { 76, 5, 8, 7 }, /* DMAC DMTE4 */
+ { 77, 5, 8, 7 }, /* DMAC DMTE5 */
+ { 80, 6, 12, 5 }, /* EDMAC EINT0 */
+ { 81, 6, 8, 5 }, /* EDMAC EINT1 */
+ { 82, 6, 4, 5 }, /* EDMAC EINT2 */
+};
+
+static unsigned long ipr_offsets[] = {
+ 0xA414FEE2 /* 0: IPRA */
+, 0xA414FEE4 /* 1: IPRB */
+, 0xA4140016 /* 2: IPRC */
+, 0xA4140018 /* 3: IPRD */
+, 0xA414001A /* 4: IPRE */
+, 0xA4080000 /* 5: IPRF */
+, 0xA4080002 /* 6: IPRG */
+, 0xA4080004 /* 7: IPRH */
+, 0xA4080006 /* 8: IPRI */
+};
+
+/* given the IPR index return the address of the IPR register */
+unsigned int map_ipridx_to_addr(int idx)
+{
+ if (idx >= ARRAY_SIZE(ipr_offsets))
+ return 0;
+ return ipr_offsets[idx];
+}
+
+void __init init_IRQ_ipr()
+{
+ make_ipr_irq(sh7710_ipr_map, ARRAY_SIZE(sh7710_ipr_map));
+}
diff --git a/arch/sh/kernel/cpu/sh4/clock-sh4-202.c b/arch/sh/kernel/cpu/sh4/clock-sh4-202.c
index fa2019aabd7..fcb2c41bc34 100644
--- a/arch/sh/kernel/cpu/sh4/clock-sh4-202.c
+++ b/arch/sh/kernel/cpu/sh4/clock-sh4-202.c
@@ -82,7 +82,8 @@ static void shoc_clk_init(struct clk *clk)
for (i = 0; i < ARRAY_SIZE(frqcr3_divisors); i++) {
int divisor = frqcr3_divisors[i];
- if (clk->ops->set_rate(clk, clk->parent->rate / divisor) == 0)
+ if (clk->ops->set_rate(clk, clk->parent->rate /
+ divisor, 0) == 0)
break;
}
diff --git a/arch/sh/kernel/cpu/sh4/probe.c b/arch/sh/kernel/cpu/sh4/probe.c
index 58950de2696..8cd04904c77 100644
--- a/arch/sh/kernel/cpu/sh4/probe.c
+++ b/arch/sh/kernel/cpu/sh4/probe.c
@@ -124,6 +124,14 @@ int __init detect_cpu_and_cache_system(void)
current_cpu_data.dcache.ways = 4;
current_cpu_data.flags |= CPU_HAS_LLSC;
break;
+ case 0x3004:
+ case 0x3007:
+ current_cpu_data.type = CPU_SH7785;
+ current_cpu_data.icache.ways = 4;
+ current_cpu_data.dcache.ways = 4;
+ current_cpu_data.flags |= CPU_HAS_FPU | CPU_HAS_PERF_COUNTER |
+ CPU_HAS_LLSC;
+ break;
case 0x3008:
if (prr == 0xa0) {
current_cpu_data.type = CPU_SH7722;
diff --git a/arch/sh/kernel/cpu/sh4a/Makefile b/arch/sh/kernel/cpu/sh4a/Makefile
index a8f493f2f21..ab7422f8f82 100644
--- a/arch/sh/kernel/cpu/sh4a/Makefile
+++ b/arch/sh/kernel/cpu/sh4a/Makefile
@@ -5,6 +5,7 @@
# CPU subtype setup
obj-$(CONFIG_CPU_SUBTYPE_SH7770) += setup-sh7770.o
obj-$(CONFIG_CPU_SUBTYPE_SH7780) += setup-sh7780.o
+obj-$(CONFIG_CPU_SUBTYPE_SH7785) += setup-sh7785.o
obj-$(CONFIG_CPU_SUBTYPE_SH73180) += setup-sh73180.o
obj-$(CONFIG_CPU_SUBTYPE_SH7343) += setup-sh7343.o
obj-$(CONFIG_CPU_SUBTYPE_SH7722) += setup-sh7722.o
@@ -13,7 +14,8 @@ obj-$(CONFIG_CPU_SUBTYPE_SH7722) += setup-sh7722.o
clock-$(CONFIG_CPU_SUBTYPE_SH73180) := clock-sh73180.o
clock-$(CONFIG_CPU_SUBTYPE_SH7770) := clock-sh7770.o
clock-$(CONFIG_CPU_SUBTYPE_SH7780) := clock-sh7780.o
+clock-$(CONFIG_CPU_SUBTYPE_SH7785) := clock-sh7785.o
clock-$(CONFIG_CPU_SUBTYPE_SH7343) := clock-sh7343.o
-clock-$(CONFIG_CPU_SUBTYPE_SH7722) := clock-sh7343.o
+clock-$(CONFIG_CPU_SUBTYPE_SH7722) := clock-sh7722.o
obj-y += $(clock-y)
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c
new file mode 100644
index 00000000000..29090035bc5
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c
@@ -0,0 +1,600 @@
+/*
+ * arch/sh/kernel/cpu/sh4a/clock-sh7722.c
+ *
+ * SH7722 support for the clock framework
+ *
+ * Copyright (c) 2006-2007 Nomad Global Solutions Inc
+ * Based on code for sh7343 by Paul Mundt
+ *
+ * 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/errno.h>
+#include <asm/clock.h>
+#include <asm/freq.h>
+
+#define SH7722_PLL_FREQ (32000000/8)
+#define N (-1)
+#define NM (-2)
+#define ROUND_NEAREST 0
+#define ROUND_DOWN -1
+#define ROUND_UP +1
+
+static int adjust_algos[][3] = {
+ {}, /* NO_CHANGE */
+ { NM, N, 1 }, /* N:1, N:1 */
+ { 3, 2, 2 }, /* 3:2:2 */
+ { 5, 2, 2 }, /* 5:2:2 */
+ { N, 1, 1 }, /* N:1:1 */
+
+ { N, 1 }, /* N:1 */
+
+ { N, 1 }, /* N:1 */
+ { 3, 2 },
+ { 4, 3 },
+ { 5, 4 },
+
+ { N, 1 }
+};
+
+static unsigned long adjust_pair_of_clocks(unsigned long r1, unsigned long r2,
+ int m1, int m2, int round_flag)
+{
+ unsigned long rem, div;
+ int the_one = 0;
+
+ pr_debug( "Actual values: r1 = %ld\n", r1);
+ pr_debug( "...............r2 = %ld\n", r2);
+
+ if (m1 == m2) {
+ r2 = r1;
+ pr_debug( "setting equal rates: r2 now %ld\n", r2);
+ } else if ((m2 == N && m1 == 1) ||
+ (m2 == NM && m1 == N)) { /* N:1 or NM:N */
+ pr_debug( "Setting rates as 1:N (N:N*M)\n");
+ rem = r2 % r1;
+ pr_debug( "...remainder = %ld\n", rem);
+ if (rem) {
+ div = r2 / r1;
+ pr_debug( "...div = %ld\n", div);
+ switch (round_flag) {
+ case ROUND_NEAREST:
+ the_one = rem >= r1/2 ? 1 : 0; break;
+ case ROUND_UP:
+ the_one = 1; break;
+ case ROUND_DOWN:
+ the_one = 0; break;
+ }
+
+ r2 = r1 * (div + the_one);
+ pr_debug( "...setting r2 to %ld\n", r2);
+ }
+ } else if ((m2 == 1 && m1 == N) ||
+ (m2 == N && m1 == NM)) { /* 1:N or N:NM */
+ pr_debug( "Setting rates as N:1 (N*M:N)\n");
+ rem = r1 % r2;
+ pr_debug( "...remainder = %ld\n", rem);
+ if (rem) {
+ div = r1 / r2;
+ pr_debug( "...div = %ld\n", div);
+ switch (round_flag) {
+ case ROUND_NEAREST:
+ the_one = rem > r2/2 ? 1 : 0; break;
+ case ROUND_UP:
+ the_one = 0; break;
+ case ROUND_DOWN:
+ the_one = 1; break;
+ }
+
+ r2 = r1 / (div + the_one);
+ pr_debug( "...setting r2 to %ld\n", r2);
+ }
+ } else { /* value:value */
+ pr_debug( "Setting rates as %d:%d\n", m1, m2);
+ div = r1 / m1;
+ r2 = div * m2;
+ pr_debug( "...div = %ld\n", div);
+ pr_debug( "...setting r2 to %ld\n", r2);
+ }
+
+ return r2;
+}
+
+static void adjust_clocks(int originate, int *l, unsigned long v[],
+ int n_in_line)
+{
+ int x;
+
+ pr_debug( "Go down from %d...\n", originate);
+ /* go up recalculation clocks */
+ for (x = originate; x>0; x -- )
+ v[x-1] = adjust_pair_of_clocks(v[x], v[x-1],
+ l[x], l[x-1],
+ ROUND_UP);
+
+ pr_debug( "Go up from %d...\n", originate);
+ /* go down recalculation clocks */
+ for (x = originate; x<n_in_line - 1; x ++ )
+ v[x+1] = adjust_pair_of_clocks(v[x], v[x+1],
+ l[x], l[x+1],
+ ROUND_UP);
+}
+
+
+/*
+ * SH7722 uses a common set of multipliers and divisors, so this
+ * is quite simple..
+ */
+
+/*
+ * Instead of having two separate multipliers/divisors set, like this:
+ *
+ * static int multipliers[] = { 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
+ * static int divisors[] = { 1, 3, 2, 5, 3, 4, 5, 6, 8, 10, 12, 16, 20 };
+ *
+ * I created the divisors2 array, which is used to calculate rate like
+ * rate = parent * 2 / divisors2[ divisor ];
+*/
+static int divisors2[] = { 2, 3, 4, 5, 6, 8, 10, 12, 16, 20, 24, 32, 40 };
+
+static void master_clk_init(struct clk *clk)
+{
+ clk_set_rate(clk, clk_get_rate(clk));
+}
+
+static void master_clk_recalc(struct clk *clk)
+{
+ unsigned long frqcr = ctrl_inl(FRQCR);
+
+ clk->rate = CONFIG_SH_PCLK_FREQ * (1 + (frqcr >> 24 & 0xF));
+}
+
+static int master_clk_setrate(struct clk *clk, unsigned long rate, int id)
+{
+ int div = rate / SH7722_PLL_FREQ;
+ int master_divs[] = { 2, 3, 4, 6, 8, 16 };
+ int index;
+ unsigned long frqcr;
+
+ if (rate < SH7722_PLL_FREQ * 2)
+ return -EINVAL;
+
+ for (index = 1; index < ARRAY_SIZE(master_divs); index++)
+ if (div >= master_divs[index - 1] && div < master_divs[index])
+ break;
+
+ if (index >= ARRAY_SIZE(master_divs))
+ index = ARRAY_SIZE(master_divs);
+ div = master_divs[index - 1];
+
+ frqcr = ctrl_inl(FRQCR);
+ frqcr &= ~(0xF << 24);
+ frqcr |= ( (div-1) << 24);
+ ctrl_outl(frqcr, FRQCR);
+
+ return 0;
+}
+
+static struct clk_ops sh7722_master_clk_ops = {
+ .init = master_clk_init,
+ .recalc = master_clk_recalc,
+ .set_rate = master_clk_setrate,
+};
+
+struct frqcr_context {
+ unsigned mask;
+ unsigned shift;
+};
+
+struct frqcr_context sh7722_get_clk_context(const char *name)
+{
+ struct frqcr_context ctx = { 0, };
+
+ if (!strcmp(name, "peripheral_clk")) {
+ ctx.shift = 0;
+ ctx.mask = 0xF;
+ } else if (!strcmp(name, "sdram_clk")) {
+ ctx.shift = 4;
+ ctx.mask = 0xF;
+ } else if (!strcmp(name, "bus_clk")) {
+ ctx.shift = 8;
+ ctx.mask = 0xF;
+ } else if (!strcmp(name, "sh_clk")) {
+ ctx.shift = 12;
+ ctx.mask = 0xF;
+ } else if (!strcmp(name, "umem_clk")) {
+ ctx.shift = 16;
+ ctx.mask = 0xF;
+ } else if (!strcmp(name, "cpu_clk")) {
+ ctx.shift = 20;
+ ctx.mask = 7;
+ }
+ return ctx;
+}
+
+/**
+ * sh7722_find_divisors - find divisor for setting rate
+ *
+ * All sh7722 clocks use the same set of multipliers/divisors. This function
+ * chooses correct divisor to set the rate of clock with parent clock that
+ * generates frequency of 'parent_rate'
+ *
+ * @parent_rate: rate of parent clock
+ * @rate: requested rate to be set
+ */
+static int sh7722_find_divisors(unsigned long parent_rate, unsigned rate)
+{
+ unsigned div2 = parent_rate * 2 / rate;
+ int index;
+
+ if (rate > parent_rate)
+ return -EINVAL;
+
+ for (index = 1; index < ARRAY_SIZE(divisors2); index++) {
+ if (div2 > divisors2[index] && div2 <= divisors2[index])
+ break;
+ }
+ if (index >= ARRAY_SIZE(divisors2))
+ index = ARRAY_SIZE(divisors2) - 1;
+ return divisors2[index];
+}
+
+static void sh7722_frqcr_recalc(struct clk *clk)
+{
+ struct frqcr_context ctx = sh7722_get_clk_context(clk->name);
+ unsigned long frqcr = ctrl_inl(FRQCR);
+ int index;
+
+ index = (frqcr >> ctx.shift) & ctx.mask;
+ clk->rate = clk->parent->rate * 2 / divisors2[index];
+}
+
+static int sh7722_frqcr_set_rate(struct clk *clk, unsigned long rate,
+ int algo_id)
+{
+ struct frqcr_context ctx = sh7722_get_clk_context(clk->name);
+ unsigned long parent_rate = clk->parent->rate;
+ int div;
+ unsigned long frqcr;
+ int err = 0;
+
+ /* pretty invalid */
+ if (parent_rate < rate)
+ return -EINVAL;
+
+ /* look for multiplier/divisor pair */
+ div = sh7722_find_divisors(parent_rate, rate);
+ if (div<0)
+ return div;
+
+ /* calculate new value of clock rate */
+ clk->rate = parent_rate * 2 / div;
+ frqcr = ctrl_inl(FRQCR);
+
+ /* FIXME: adjust as algo_id specifies */
+ if (algo_id != NO_CHANGE) {
+ int originator;
+ char *algo_group_1[] = { "cpu_clk", "umem_clk", "sh_clk" };
+ char *algo_group_2[] = { "sh_clk", "bus_clk" };
+ char *algo_group_3[] = { "sh_clk", "sdram_clk" };
+ char *algo_group_4[] = { "bus_clk", "peripheral_clk" };
+ char *algo_group_5[] = { "cpu_clk", "peripheral_clk" };
+ char **algo_current = NULL;
+ /* 3 is the maximum number of clocks in relation */
+ struct clk *ck[3];
+ unsigned long values[3]; /* the same comment as above */
+ int part_length = -1;
+ int i;
+
+ /*
+ * all the steps below only required if adjustion was
+ * requested
+ */
+ if (algo_id == IUS_N1_N1 ||
+ algo_id == IUS_322 ||
+ algo_id == IUS_522 ||
+ algo_id == IUS_N11) {
+ algo_current = algo_group_1;
+ part_length = 3;
+ }
+ if (algo_id == SB_N1) {
+ algo_current = algo_group_2;
+ part_length = 2;
+ }
+ if (algo_id == SB3_N1 ||
+ algo_id == SB3_32 ||
+ algo_id == SB3_43 ||
+ algo_id == SB3_54) {
+ algo_current = algo_group_3;
+ part_length = 2;
+ }
+ if (algo_id == BP_N1) {
+ algo_current = algo_group_4;
+ part_length = 2;
+ }
+ if (algo_id == IP_N1) {
+ algo_current = algo_group_5;
+ part_length = 2;
+ }
+ if (!algo_current)
+ goto incorrect_algo_id;
+
+ originator = -1;
+ for (i = 0; i < part_length; i ++ ) {
+ if (originator >= 0 && !strcmp(clk->name,
+ algo_current[i]))
+ originator = i;
+ ck[i] = clk_get(NULL, algo_current[i]);
+ values[i] = clk_get_rate(ck[i]);
+ }
+
+ if (originator >= 0)
+ adjust_clocks(originator, adjust_algos[algo_id],
+ values, part_length);
+
+ for (i = 0; i < part_length; i ++ ) {
+ struct frqcr_context part_ctx;
+ int part_div;
+
+ if (likely(!err)) {
+ part_div = sh7722_find_divisors(parent_rate,
+ rate);
+ if (part_div > 0) {
+ part_ctx = sh7722_get_clk_context(
+ ck[i]->name);
+ frqcr &= ~(part_ctx.mask <<
+ part_ctx.shift);
+ frqcr |= part_div << part_ctx.shift;
+ } else
+ err = part_div;
+ }
+
+ ck[i]->ops->recalc(ck[i]);
+ clk_put(ck[i]);
+ }
+ }
+
+ /* was there any error during recalculation ? If so, bail out.. */
+ if (unlikely(err!=0))
+ goto out_err;
+
+ /* clear FRQCR bits */
+ frqcr &= ~(ctx.mask << ctx.shift);
+ frqcr |= div << ctx.shift;
+
+ /* ...and perform actual change */
+ ctrl_outl(frqcr, FRQCR);
+ return 0;
+
+incorrect_algo_id:
+ return -EINVAL;
+out_err:
+ return err;
+}
+
+static struct clk_ops sh7722_frqcr_clk_ops = {
+ .recalc = sh7722_frqcr_recalc,
+ .set_rate = sh7722_frqcr_set_rate,
+};
+
+/*
+ * clock ops methods for SIU A/B and IrDA clock
+ *
+ */
+static int sh7722_siu_which(struct clk *clk)
+{
+ if (!strcmp(clk->name, "siu_a_clk"))
+ return 0;
+ if (!strcmp(clk->name, "siu_b_clk"))
+ return 1;
+ if (!strcmp(clk->name, "irda_clk"))
+ return 2;
+ return -EINVAL;
+}
+
+static unsigned long sh7722_siu_regs[] = {
+ [0] = SCLKACR,
+ [1] = SCLKBCR,
+ [2] = IrDACLKCR,
+};
+
+static int sh7722_siu_start_stop(struct clk *clk, int enable)
+{
+ int siu = sh7722_siu_which(clk);
+ unsigned long r;
+
+ if (siu < 0)
+ return siu;
+ BUG_ON(siu > 2);
+ r = ctrl_inl(sh7722_siu_regs[siu]);
+ if (enable)
+ ctrl_outl(r & ~(1 << 8), sh7722_siu_regs[siu]);
+ else
+ ctrl_outl(r | (1 << 8), sh7722_siu_regs[siu]);
+ return 0;
+}
+
+static void sh7722_siu_enable(struct clk *clk)
+{
+ sh7722_siu_start_stop(clk, 1);
+}
+
+static void sh7722_siu_disable(struct clk *clk)
+{
+ sh7722_siu_start_stop(clk, 0);
+}
+
+static void sh7722_video_enable(struct clk *clk)
+{
+ unsigned long r;
+
+ r = ctrl_inl(VCLKCR);
+ ctrl_outl( r & ~(1<<8), VCLKCR);
+}
+
+static void sh7722_video_disable(struct clk *clk)
+{
+ unsigned long r;
+
+ r = ctrl_inl(VCLKCR);
+ ctrl_outl( r | (1<<8), VCLKCR);
+}
+
+static int sh7722_video_set_rate(struct clk *clk, unsigned long rate,
+ int algo_id)
+{
+ unsigned long r;
+
+ r = ctrl_inl(VCLKCR);
+ r &= ~0x3F;
+ r |= ((clk->parent->rate / rate - 1) & 0x3F);
+ ctrl_outl(r, VCLKCR);
+ return 0;
+}
+
+static void sh7722_video_recalc(struct clk *clk)
+{
+ unsigned long r;
+
+ r = ctrl_inl(VCLKCR);
+ clk->rate = clk->parent->rate / ((r & 0x3F) + 1);
+}
+
+static int sh7722_siu_set_rate(struct clk *clk, unsigned long rate, int algo_id)
+{
+ int siu = sh7722_siu_which(clk);
+ unsigned long r;
+ int div;
+
+ if (siu < 0)
+ return siu;
+ BUG_ON(siu > 2);
+ r = ctrl_inl(sh7722_siu_regs[siu]);
+ div = sh7722_find_divisors(clk->parent->rate, rate);
+ if (div < 0)
+ return div;
+ r = (r & ~0xF) | div;
+ ctrl_outl(r, sh7722_siu_regs[siu]);
+ return 0;
+}
+
+static void sh7722_siu_recalc(struct clk *clk)
+{
+ int siu = sh7722_siu_which(clk);
+ unsigned long r;
+
+ if (siu < 0)
+ return /* siu */ ;
+ BUG_ON(siu > 1);
+ r = ctrl_inl(sh7722_siu_regs[siu]);
+ clk->rate = clk->parent->rate * 2 / divisors2[r & 0xF];
+}
+
+static struct clk_ops sh7722_siu_clk_ops = {
+ .recalc = sh7722_siu_recalc,
+ .set_rate = sh7722_siu_set_rate,
+ .enable = sh7722_siu_enable,
+ .disable = sh7722_siu_disable,
+};
+
+static struct clk_ops sh7722_video_clk_ops = {
+ .recalc = sh7722_video_recalc,
+ .set_rate = sh7722_video_set_rate,
+ .enable = sh7722_video_enable,
+ .disable = sh7722_video_disable,
+};
+/*
+ * and at last, clock definitions themselves
+ */
+static struct clk sh7722_umem_clock = {
+ .name = "umem_clk",
+ .ops = &sh7722_frqcr_clk_ops,
+};
+
+static struct clk sh7722_sh_clock = {
+ .name = "sh_clk",
+ .ops = &sh7722_frqcr_clk_ops,
+};
+
+static struct clk sh7722_peripheral_clock = {
+ .name = "peripheral_clk",
+ .ops = &sh7722_frqcr_clk_ops,
+};
+
+static struct clk sh7722_sdram_clock = {
+ .name = "sdram_clk",
+ .ops = &sh7722_frqcr_clk_ops,
+};
+
+/*
+ * these three clocks - SIU A, SIU B, IrDA - share the same clk_ops
+ * methods of clk_ops determine which register they should access by
+ * examining clk->name field
+ */
+static struct clk sh7722_siu_a_clock = {
+ .name = "siu_a_clk",
+ .ops = &sh7722_siu_clk_ops,
+};
+
+static struct clk sh7722_siu_b_clock = {
+ .name = "siu_b_clk",
+ .ops = &sh7722_siu_clk_ops,
+};
+
+static struct clk sh7722_irda_clock = {
+ .name = "irda_clk",
+ .ops = &sh7722_siu_clk_ops,
+};
+
+static struct clk sh7722_video_clock = {
+ .name = "video_clk",
+ .ops = &sh7722_video_clk_ops,
+};
+
+static struct clk *sh7722_clocks[] = {
+ &sh7722_umem_clock,
+ &sh7722_sh_clock,
+ &sh7722_peripheral_clock,
+ &sh7722_sdram_clock,
+ &sh7722_siu_a_clock,
+ &sh7722_siu_b_clock,
+ &sh7722_irda_clock,
+ &sh7722_video_clock,
+};
+
+/*
+ * init in order: master, module, bus, cpu
+ */
+struct clk_ops *onchip_ops[] = {
+ &sh7722_master_clk_ops,
+ &sh7722_frqcr_clk_ops,
+ &sh7722_frqcr_clk_ops,
+ &sh7722_frqcr_clk_ops,
+};
+
+void __init
+arch_init_clk_ops(struct clk_ops **ops, int type)
+{
+ BUG_ON(type < 0 || type > ARRAY_SIZE(onchip_ops));
+ *ops = onchip_ops[type];
+}
+
+int __init sh7722_clock_init(void)
+{
+ struct clk *master;
+ int i;
+
+ master = clk_get(NULL, "master_clk");
+ for (i = 0; i < ARRAY_SIZE(sh7722_clocks); i++) {
+ pr_debug( "Registering clock '%s'\n", sh7722_clocks[i]->name);
+ sh7722_clocks[i]->parent = master;
+ clk_register(sh7722_clocks[i]);
+ }
+ clk_put(master);
+ return 0;
+}
+arch_initcall(sh7722_clock_init);
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7785.c b/arch/sh/kernel/cpu/sh4a/clock-sh7785.c
new file mode 100644
index 00000000000..805535aa505
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7785.c
@@ -0,0 +1,162 @@
+/*
+ * arch/sh/kernel/cpu/sh4a/clock-sh7785.c
+ *
+ * SH7785 support for the clock framework
+ *
+ * Copyright (C) 2007 Paul Mundt
+ *
+ * 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 <asm/clock.h>
+#include <asm/freq.h>
+#include <asm/io.h>
+
+static int ifc_divisors[] = { 1, 2, 4, 6 };
+static int ufc_divisors[] = { 1, 1, 4, 6 };
+static int sfc_divisors[] = { 1, 1, 4, 6 };
+static int bfc_divisors[] = { 1, 1, 1, 1, 1, 12, 16, 18,
+ 24, 32, 36, 48, 1, 1, 1, 1 };
+static int mfc_divisors[] = { 1, 1, 4, 6 };
+static int pfc_divisors[] = { 1, 1, 1, 1, 1, 1, 1, 18,
+ 24, 32, 36, 48, 1, 1, 1, 1 };
+
+static void master_clk_init(struct clk *clk)
+{
+ clk->rate *= 36;
+}
+
+static struct clk_ops sh7785_master_clk_ops = {
+ .init = master_clk_init,
+};
+
+static void module_clk_recalc(struct clk *clk)
+{
+ int idx = (ctrl_inl(FRQMR1) & 0x000f);
+ clk->rate = clk->parent->rate / pfc_divisors[idx];
+}
+
+static struct clk_ops sh7785_module_clk_ops = {
+ .recalc = module_clk_recalc,
+};
+
+static void bus_clk_recalc(struct clk *clk)
+{
+ int idx = ((ctrl_inl(FRQMR1) >> 16) & 0x000f);
+ clk->rate = clk->parent->rate / bfc_divisors[idx];
+}
+
+static struct clk_ops sh7785_bus_clk_ops = {
+ .recalc = bus_clk_recalc,
+};
+
+static void cpu_clk_recalc(struct clk *clk)
+{
+ int idx = ((ctrl_inl(FRQMR1) >> 28) & 0x0003);
+ clk->rate = clk->parent->rate / ifc_divisors[idx];
+}
+
+static struct clk_ops sh7785_cpu_clk_ops = {
+ .recalc = cpu_clk_recalc,
+};
+
+static struct clk_ops *sh7785_clk_ops[] = {
+ &sh7785_master_clk_ops,
+ &sh7785_module_clk_ops,
+ &sh7785_bus_clk_ops,
+ &sh7785_cpu_clk_ops,
+};
+
+void __init arch_init_clk_ops(struct clk_ops **ops, int idx)
+{
+ if (idx < ARRAY_SIZE(sh7785_clk_ops))
+ *ops = sh7785_clk_ops[idx];
+}
+
+static void shyway_clk_recalc(struct clk *clk)
+{
+ int idx = ((ctrl_inl(FRQMR1) >> 20) & 0x0003);
+ clk->rate = clk->parent->rate / sfc_divisors[idx];
+}
+
+static struct clk_ops sh7785_shyway_clk_ops = {
+ .recalc = shyway_clk_recalc,
+};
+
+static struct clk sh7785_shyway_clk = {
+ .name = "shyway_clk",
+ .flags = CLK_ALWAYS_ENABLED,
+ .ops = &sh7785_shyway_clk_ops,
+};
+
+static void ddr_clk_recalc(struct clk *clk)
+{
+ int idx = ((ctrl_inl(FRQMR1) >> 12) & 0x0003);
+ clk->rate = clk->parent->rate / mfc_divisors[idx];
+}
+
+static struct clk_ops sh7785_ddr_clk_ops = {
+ .recalc = ddr_clk_recalc,
+};
+
+static struct clk sh7785_ddr_clk = {
+ .name = "ddr_clk",
+ .flags = CLK_ALWAYS_ENABLED,
+ .ops = &sh7785_ddr_clk_ops,
+};
+
+static void ram_clk_recalc(struct clk *clk)
+{
+ int idx = ((ctrl_inl(FRQMR1) >> 24) & 0x0003);
+ clk->rate = clk->parent->rate / ufc_divisors[idx];
+}
+
+static struct clk_ops sh7785_ram_clk_ops = {
+ .recalc = ram_clk_recalc,
+};
+
+static struct clk sh7785_ram_clk = {
+ .name = "ram_clk",
+ .flags = CLK_ALWAYS_ENABLED,
+ .ops = &sh7785_ram_clk_ops,
+};
+
+/*
+ * Additional SH7785-specific on-chip clocks that aren't already part of the
+ * clock framework
+ */
+static struct clk *sh7785_onchip_clocks[] = {
+ &sh7785_shyway_clk,
+ &sh7785_ddr_clk,
+ &sh7785_ram_clk,
+};
+
+static int __init sh7785_clk_init(void)
+{
+ struct clk *clk = clk_get(NULL, "master_clk");
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(sh7785_onchip_clocks); i++) {
+ struct clk *clkp = sh7785_onchip_clocks[i];
+
+ clkp->parent = clk;
+ clk_register(clkp);
+ clk_enable(clkp);
+ }
+
+ /*
+ * Now that we have the rest of the clocks registered, we need to
+ * force the parent clock to propagate so that these clocks will
+ * automatically figure out their rate. We cheat by handing the
+ * parent clock its current rate and forcing child propagation.
+ */
+ clk_set_rate(clk, clk_get_rate(clk));
+
+ clk_put(clk);
+
+ return 0;
+}
+arch_initcall(sh7785_clk_init);
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c
new file mode 100644
index 00000000000..07b0de82cfe
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c
@@ -0,0 +1,103 @@
+/*
+ * SH7785 Setup
+ *
+ * Copyright (C) 2007 Paul Mundt
+ *
+ * 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/platform_device.h>
+#include <linux/init.h>
+#include <linux/serial.h>
+#include <asm/sci.h>
+
+static struct plat_sci_port sci_platform_data[] = {
+ {
+ .mapbase = 0xffea0000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .type = PORT_SCIF,
+ .irqs = { 40, 41, 43, 42 },
+ }, {
+ .mapbase = 0xffeb0000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .type = PORT_SCIF,
+ .irqs = { 44, 45, 47, 46 },
+ },
+
+ /*
+ * The rest of these all have multiplexed IRQs
+ */
+ {
+ .mapbase = 0xffec0000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .type = PORT_SCIF,
+ .irqs = { 60, 60, 60, 60 },
+ }, {
+ .mapbase = 0xffed0000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .type = PORT_SCIF,
+ .irqs = { 61, 61, 61, 61 },
+ }, {
+ .mapbase = 0xffee0000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .type = PORT_SCIF,
+ .irqs = { 62, 62, 62, 62 },
+ }, {
+ .mapbase = 0xffef0000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .type = PORT_SCIF,
+ .irqs = { 63, 63, 63, 63 },
+ }, {
+ .flags = 0,
+ }
+};
+
+static struct platform_device sci_device = {
+ .name = "sh-sci",
+ .id = -1,
+ .dev = {
+ .platform_data = sci_platform_data,
+ },
+};
+
+static struct platform_device *sh7785_devices[] __initdata = {
+ &sci_device,
+};
+
+static int __init sh7785_devices_setup(void)
+{
+ return platform_add_devices(sh7785_devices,
+ ARRAY_SIZE(sh7785_devices));
+}
+__initcall(sh7785_devices_setup);
+
+static struct intc2_data intc2_irq_table[] = {
+ { 28, 0, 24, 0, 0, 2 }, /* TMU0 */
+
+ { 40, 8, 24, 0, 2, 3 }, /* SCIF0 ERI */
+ { 41, 8, 24, 0, 2, 3 }, /* SCIF0 RXI */
+ { 42, 8, 24, 0, 2, 3 }, /* SCIF0 BRI */
+ { 43, 8, 24, 0, 2, 3 }, /* SCIF0 TXI */
+
+ { 44, 8, 16, 0, 3, 3 }, /* SCIF1 ERI */
+ { 45, 8, 16, 0, 3, 3 }, /* SCIF1 RXI */
+ { 46, 8, 16, 0, 3, 3 }, /* SCIF1 BRI */
+ { 47, 8, 16, 0, 3, 3 }, /* SCIF1 TXI */
+
+ { 64, 0x14, 8, 0, 14, 2 }, /* PCIC0 */
+ { 65, 0x14, 0, 0, 15, 2 }, /* PCIC1 */
+ { 66, 0x18, 24, 0, 16, 2 }, /* PCIC2 */
+ { 67, 0x18, 16, 0, 17, 2 }, /* PCIC3 */
+ { 68, 0x18, 8, 0, 18, 2 }, /* PCIC4 */
+
+ { 60, 8, 8, 0, 4, 3 }, /* SCIF2 ERI, RXI, BRI, TXI */
+ { 60, 8, 0, 0, 5, 3 }, /* SCIF3 ERI, RXI, BRI, TXI */
+ { 60, 12, 24, 0, 6, 3 }, /* SCIF4 ERI, RXI, BRI, TXI */
+ { 60, 12, 16, 0, 7, 3 }, /* SCIF5 ERI, RXI, BRI, TXI */
+};
+
+void __init init_IRQ_intc2(void)
+{
+ make_intc2_irq(intc2_irq_table, ARRAY_SIZE(intc2_irq_table));
+}
diff --git a/arch/sh/kernel/crash_dump.c b/arch/sh/kernel/crash_dump.c
new file mode 100644
index 00000000000..4a2ecbe27d8
--- /dev/null
+++ b/arch/sh/kernel/crash_dump.c
@@ -0,0 +1,46 @@
+/*
+ * crash_dump.c - Memory preserving reboot related code.
+ *
+ * Created by: Hariprasad Nellitheertha (hari@in.ibm.com)
+ * Copyright (C) IBM Corporation, 2004. All rights reserved
+ */
+
+#include <linux/errno.h>
+#include <linux/crash_dump.h>
+#include <linux/io.h>
+#include <asm/uaccess.h>
+
+/**
+ * copy_oldmem_page - copy one page from "oldmem"
+ * @pfn: page frame number to be copied
+ * @buf: target memory address for the copy; this can be in kernel address
+ * space or user address space (see @userbuf)
+ * @csize: number of bytes to copy
+ * @offset: offset in bytes into the page (based on pfn) to begin the copy
+ * @userbuf: if set, @buf is in user address space, use copy_to_user(),
+ * otherwise @buf is in kernel address space, use memcpy().
+ *
+ * Copy a page from "oldmem". For this page, there is no pte mapped
+ * in the current kernel. We stitch up a pte, similar to kmap_atomic.
+ */
+ssize_t copy_oldmem_page(unsigned long pfn, char *buf,
+ size_t csize, unsigned long offset, int userbuf)
+{
+ void *vaddr;
+
+ if (!csize)
+ return 0;
+
+ vaddr = ioremap(pfn << PAGE_SHIFT, PAGE_SIZE);
+
+ if (userbuf) {
+ if (copy_to_user(buf, (vaddr + offset), csize)) {
+ iounmap(vaddr);
+ return -EFAULT;
+ }
+ } else
+ memcpy(buf, (vaddr + offset), csize);
+
+ iounmap(vaddr);
+ return csize;
+}
diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c
index 9bdd8a00cd4..27b923c45b3 100644
--- a/arch/sh/kernel/irq.c
+++ b/arch/sh/kernel/irq.c
@@ -13,6 +13,7 @@
#include <linux/seq_file.h>
#include <linux/irq.h>
#include <asm/processor.h>
+#include <asm/machvec.h>
#include <asm/uaccess.h>
#include <asm/thread_info.h>
#include <asm/cpu/mmu_context.h>
@@ -44,7 +45,7 @@ int show_interrupts(struct seq_file *p, void *v)
seq_putc(p, '\n');
}
- if (i < NR_IRQS) {
+ if (i < sh_mv.mv_nr_irqs) {
spin_lock_irqsave(&irq_desc[i].lock, flags);
action = irq_desc[i].action;
if (!action)
@@ -61,7 +62,7 @@ int show_interrupts(struct seq_file *p, void *v)
seq_putc(p, '\n');
unlock:
spin_unlock_irqrestore(&irq_desc[i].lock, flags);
- } else if (i == NR_IRQS)
+ } else if (i == sh_mv.mv_nr_irqs)
seq_printf(p, "Err: %10u\n", atomic_read(&irq_err_count));
return 0;
diff --git a/arch/sh/kernel/kgdb_stub.c b/arch/sh/kernel/kgdb_stub.c
index d8927d85492..a5323364cbc 100644
--- a/arch/sh/kernel/kgdb_stub.c
+++ b/arch/sh/kernel/kgdb_stub.c
@@ -6,11 +6,11 @@
* David Grothe <dave@gcom.com>, Tigran Aivazian <tigran@sco.com>,
* Amit S. Kale <akale@veritas.com>, William Gatliff <bgat@open-widgets.com>,
* Ben Lee, Steve Chamberlain and Benoit Miller <fulg@iname.com>.
- *
+ *
* This version by Henry Bell <henry.bell@st.com>
* Minor modifications by Jeremy Siegel <jsiegel@mvista.com>
- *
- * Contains low-level support for remote debug using GDB.
+ *
+ * Contains low-level support for remote debug using GDB.
*
* To enable debugger support, two things need to happen. A call to
* set_debug_traps() is necessary in order to allow any breakpoints
@@ -48,7 +48,7 @@
* k kill (Detach GDB)
*
* d Toggle debug flag
- * D Detach GDB
+ * D Detach GDB
*
* Hct Set thread t for operations, OK or ENN
* c = 'c' (step, cont), c = 'g' (other
@@ -58,7 +58,7 @@
* qfThreadInfo Get list of current threads (first) m<id>
* qsThreadInfo " " " " " (subsequent)
* qOffsets Get section offsets Text=x;Data=y;Bss=z
- *
+ *
* TXX Find if thread XX is alive OK or ENN
* ? What was the last sigval ? SNN (signal NN)
* O Output to GDB console
@@ -74,7 +74,7 @@
* '$' or '#'. If <data> starts with two characters followed by
* ':', then the existing stubs interpret this as a sequence number.
*
- * CSUM1 and CSUM2 are ascii hex representation of an 8-bit
+ * CSUM1 and CSUM2 are ascii hex representation of an 8-bit
* checksum of <data>, the most significant nibble is sent first.
* the hex digits 0-9,a-f are used.
*
@@ -86,8 +86,8 @@
* Responses can be run-length encoded to save space. A '*' means that
* the next character is an ASCII encoding giving a repeat count which
* stands for that many repititions of the character preceding the '*'.
- * The encoding is n+29, yielding a printable character where n >=3
- * (which is where RLE starts to win). Don't use an n > 126.
+ * The encoding is n+29, yielding a printable character where n >=3
+ * (which is where RLE starts to win). Don't use an n > 126.
*
* So "0* " means the same as "0000".
*/
@@ -100,12 +100,10 @@
#include <linux/delay.h>
#include <linux/linkage.h>
#include <linux/init.h>
-
-#ifdef CONFIG_SH_KGDB_CONSOLE
#include <linux/console.h>
-#endif
-
+#include <linux/sysrq.h>
#include <asm/system.h>
+#include <asm/cacheflush.h>
#include <asm/current.h>
#include <asm/signal.h>
#include <asm/pgtable.h>
@@ -153,7 +151,6 @@ char kgdb_in_gdb_mode;
char in_nmi; /* Set during NMI to prevent reentry */
int kgdb_nofault; /* Boolean to ignore bus errs (i.e. in GDB) */
int kgdb_enabled = 1; /* Default to enabled, cmdline can disable */
-int kgdb_halt;
/* Exposed for user access */
struct task_struct *kgdb_current;
@@ -246,14 +243,6 @@ static char out_buffer[OUTBUFMAX];
static void kgdb_to_gdb(const char *s);
-#ifdef CONFIG_KGDB_THREAD
-static struct task_struct *trapped_thread;
-static struct task_struct *current_thread;
-typedef unsigned char threadref[8];
-#define BUF_THREAD_ID_SIZE 16
-#endif
-
-
/* Convert ch to hex */
static int hex(const char ch)
{
@@ -328,7 +317,7 @@ static int hex_to_int(char **ptr, int *int_value)
}
/* Copy the binary array pointed to by buf into mem. Fix $, #,
- and 0x7d escaped with 0x7d. Return a pointer to the character
+ and 0x7d escaped with 0x7d. Return a pointer to the character
after the last byte written. */
static char *ebin_to_mem(const char *buf, char *mem, int count)
{
@@ -349,66 +338,6 @@ static char *pack_hex_byte(char *pkt, int byte)
return pkt;
}
-#ifdef CONFIG_KGDB_THREAD
-
-/* Pack a thread ID */
-static char *pack_threadid(char *pkt, threadref * id)
-{
- char *limit;
- unsigned char *altid;
-
- altid = (unsigned char *) id;
-
- limit = pkt + BUF_THREAD_ID_SIZE;
- while (pkt < limit)
- pkt = pack_hex_byte(pkt, *altid++);
- return pkt;
-}
-
-/* Convert an integer into our threadref */
-static void int_to_threadref(threadref * id, const int value)
-{
- unsigned char *scan = (unsigned char *) id;
- int i = 4;
-
- while (i--)
- *scan++ = 0;
-
- *scan++ = (value >> 24) & 0xff;
- *scan++ = (value >> 16) & 0xff;
- *scan++ = (value >> 8) & 0xff;
- *scan++ = (value & 0xff);
-}
-
-/* Return a task structure ptr for a particular pid */
-static struct task_struct *get_thread(int pid)
-{
- struct task_struct *thread;
-
- /* Use PID_MAX w/gdb for pid 0 */
- if (pid == PID_MAX) pid = 0;
-
- /* First check via PID */
- thread = find_task_by_pid(pid);
-
- if (thread)
- return thread;
-
- /* Start at the start */
- thread = init_tasks[0];
-
- /* Walk along the linked list of tasks */
- do {
- if (thread->pid == pid)
- return thread;
- thread = thread->next_task;
- } while (thread != init_tasks[0]);
-
- return NULL;
-}
-
-#endif /* CONFIG_KGDB_THREAD */
-
/* Scan for the start char '$', read the packet and check the checksum */
static void get_packet(char *buffer, int buflen)
{
@@ -452,7 +381,7 @@ static void get_packet(char *buffer, int buflen)
/* Ack successful transfer */
put_debug_char('+');
- /* If a sequence char is present, reply
+ /* If a sequence char is present, reply
the sequence ID */
if (buffer[2] == ':') {
put_debug_char(buffer[0]);
@@ -611,74 +540,6 @@ static void gdb_regs_to_kgdb_regs(const int *gdb_regs,
regs->vbr = gdb_regs[VBR];
}
-#ifdef CONFIG_KGDB_THREAD
-/* Make a local copy of registers from the specified thread */
-asmlinkage void ret_from_fork(void);
-static void thread_regs_to_gdb_regs(const struct task_struct *thread,
- int *gdb_regs)
-{
- int regno;
- int *tregs;
-
- /* Initialize to zero */
- for (regno = 0; regno < MAXREG; regno++)
- gdb_regs[regno] = 0;
-
- /* Just making sure... */
- if (thread == NULL)
- return;
-
- /* A new fork has pt_regs on the stack from a fork() call */
- if (thread->thread.pc == (unsigned long)ret_from_fork) {
-
- int vbr_val;
- struct pt_regs *kregs;
- kregs = (struct pt_regs*)thread->thread.sp;
-
- gdb_regs[R0] = kregs->regs[R0];
- gdb_regs[R1] = kregs->regs[R1];
- gdb_regs[R2] = kregs->regs[R2];
- gdb_regs[R3] = kregs->regs[R3];
- gdb_regs[R4] = kregs->regs[R4];
- gdb_regs[R5] = kregs->regs[R5];
- gdb_regs[R6] = kregs->regs[R6];
- gdb_regs[R7] = kregs->regs[R7];
- gdb_regs[R8] = kregs->regs[R8];
- gdb_regs[R9] = kregs->regs[R9];
- gdb_regs[R10] = kregs->regs[R10];
- gdb_regs[R11] = kregs->regs[R11];
- gdb_regs[R12] = kregs->regs[R12];
- gdb_regs[R13] = kregs->regs[R13];
- gdb_regs[R14] = kregs->regs[R14];
- gdb_regs[R15] = kregs->regs[R15];
- gdb_regs[PC] = kregs->pc;
- gdb_regs[PR] = kregs->pr;
- gdb_regs[GBR] = kregs->gbr;
- gdb_regs[MACH] = kregs->mach;
- gdb_regs[MACL] = kregs->macl;
- gdb_regs[SR] = kregs->sr;
-
- asm("stc vbr, %0":"=r"(vbr_val));
- gdb_regs[VBR] = vbr_val;
- return;
- }
-
- /* Otherwise, we have only some registers from switch_to() */
- tregs = (int *)thread->thread.sp;
- gdb_regs[R15] = (int)tregs;
- gdb_regs[R14] = *tregs++;
- gdb_regs[R13] = *tregs++;
- gdb_regs[R12] = *tregs++;
- gdb_regs[R11] = *tregs++;
- gdb_regs[R10] = *tregs++;
- gdb_regs[R9] = *tregs++;
- gdb_regs[R8] = *tregs++;
- gdb_regs[PR] = *tregs++;
- gdb_regs[GBR] = *tregs++;
- gdb_regs[PC] = thread->thread.pc;
-}
-#endif /* CONFIG_KGDB_THREAD */
-
/* Calculate the new address for after a step */
static short *get_step_address(void)
{
@@ -759,7 +620,7 @@ static short *get_step_address(void)
return (short *) addr;
}
-/* Set up a single-step. Replace the instruction immediately after the
+/* Set up a single-step. Replace the instruction immediately after the
current instruction (i.e. next in the expected flow of control) with a
trap instruction, so that returning will cause only a single instruction
to be executed. Note that this model is slightly broken for instructions
@@ -797,37 +658,11 @@ static void undo_single_step(void)
/* Send a signal message */
static void send_signal_msg(const int signum)
{
-#ifndef CONFIG_KGDB_THREAD
out_buffer[0] = 'S';
out_buffer[1] = highhex(signum);
out_buffer[2] = lowhex(signum);
out_buffer[3] = 0;
put_packet(out_buffer);
-#else /* CONFIG_KGDB_THREAD */
- int threadid;
- threadref thref;
- char *out = out_buffer;
- const char *tstring = "thread";
-
- *out++ = 'T';
- *out++ = highhex(signum);
- *out++ = lowhex(signum);
-
- while (*tstring) {
- *out++ = *tstring++;
- }
- *out++ = ':';
-
- threadid = trapped_thread->pid;
- if (threadid == 0) threadid = PID_MAX;
- int_to_threadref(&thref, threadid);
- pack_threadid(out, &thref);
- out += BUF_THREAD_ID_SIZE;
- *out++ = ';';
-
- *out = 0;
- put_packet(out_buffer);
-#endif /* CONFIG_KGDB_THREAD */
}
/* Reply that all was well */
@@ -962,15 +797,7 @@ static void step_with_sig_msg(void)
/* Send register contents */
static void send_regs_msg(void)
{
-#ifdef CONFIG_KGDB_THREAD
- if (!current_thread)
- kgdb_regs_to_gdb_regs(&trap_registers, registers);
- else
- thread_regs_to_gdb_regs(current_thread, registers);
-#else
kgdb_regs_to_gdb_regs(&trap_registers, registers);
-#endif
-
mem_to_hex((char *) registers, out_buffer, NUMREGBYTES);
put_packet(out_buffer);
}
@@ -978,201 +805,13 @@ static void send_regs_msg(void)
/* Set register contents - currently can't set other thread's registers */
static void set_regs_msg(void)
{
-#ifdef CONFIG_KGDB_THREAD
- if (!current_thread) {
-#endif
- kgdb_regs_to_gdb_regs(&trap_registers, registers);
- hex_to_mem(&in_buffer[1], (char *) registers, NUMREGBYTES);
- gdb_regs_to_kgdb_regs(registers, &trap_registers);
- send_ok_msg();
-#ifdef CONFIG_KGDB_THREAD
- } else
- send_err_msg();
-#endif
-}
-
-
-#ifdef CONFIG_KGDB_THREAD
-
-/* Set the status for a thread */
-void set_thread_msg(void)
-{
- int threadid;
- struct task_struct *thread = NULL;
- char *ptr;
-
- switch (in_buffer[1]) {
-
- /* To select which thread for gG etc messages, i.e. supported */
- case 'g':
-
- ptr = &in_buffer[2];
- hex_to_int(&ptr, &threadid);
- thread = get_thread(threadid);
-
- /* If we haven't found it */
- if (!thread) {
- send_err_msg();
- break;
- }
-
- /* Set current_thread (or not) */
- if (thread == trapped_thread)
- current_thread = NULL;
- else
- current_thread = thread;
- send_ok_msg();
- break;
-
- /* To select which thread for cCsS messages, i.e. unsupported */
- case 'c':
- send_ok_msg();
- break;
-
- default:
- send_empty_msg();
- break;
- }
-}
-
-/* Is a thread alive? */
-static void thread_status_msg(void)
-{
- char *ptr;
- int threadid;
- struct task_struct *thread = NULL;
-
- ptr = &in_buffer[1];
- hex_to_int(&ptr, &threadid);
- thread = get_thread(threadid);
- if (thread)
- send_ok_msg();
- else
- send_err_msg();
-}
-/* Send the current thread ID */
-static void thread_id_msg(void)
-{
- int threadid;
- threadref thref;
-
- out_buffer[0] = 'Q';
- out_buffer[1] = 'C';
-
- if (current_thread)
- threadid = current_thread->pid;
- else if (trapped_thread)
- threadid = trapped_thread->pid;
- else /* Impossible, but just in case! */
- {
- send_err_msg();
- return;
- }
-
- /* Translate pid 0 to PID_MAX for gdb */
- if (threadid == 0) threadid = PID_MAX;
-
- int_to_threadref(&thref, threadid);
- pack_threadid(out_buffer + 2, &thref);
- out_buffer[2 + BUF_THREAD_ID_SIZE] = '\0';
- put_packet(out_buffer);
-}
-
-/* Send thread info */
-static void thread_info_msg(void)
-{
- struct task_struct *thread = NULL;
- int threadid;
- char *pos;
- threadref thref;
-
- /* Start with 'm' */
- out_buffer[0] = 'm';
- pos = &out_buffer[1];
-
- /* For all possible thread IDs - this will overrun if > 44 threads! */
- /* Start at 1 and include PID_MAX (since GDB won't use pid 0...) */
- for (threadid = 1; threadid <= PID_MAX; threadid++) {
-
- read_lock(&tasklist_lock);
- thread = get_thread(threadid);
- read_unlock(&tasklist_lock);
-
- /* If it's a valid thread */
- if (thread) {
- int_to_threadref(&thref, threadid);
- pack_threadid(pos, &thref);
- pos += BUF_THREAD_ID_SIZE;
- *pos++ = ',';
- }
- }
- *--pos = 0; /* Lose final comma */
- put_packet(out_buffer);
-
-}
-
-/* Return printable info for gdb's 'info threads' command */
-static void thread_extra_info_msg(void)
-{
- int threadid;
- struct task_struct *thread = NULL;
- char buffer[20], *ptr;
- int i;
-
- /* Extract thread ID */
- ptr = &in_buffer[17];
- hex_to_int(&ptr, &threadid);
- thread = get_thread(threadid);
-
- /* If we don't recognise it, say so */
- if (thread == NULL)
- strcpy(buffer, "(unknown)");
- else
- strcpy(buffer, thread->comm);
-
- /* Construct packet */
- for (i = 0, ptr = out_buffer; buffer[i]; i++)
- ptr = pack_hex_byte(ptr, buffer[i]);
-
- if (thread->thread.pc == (unsigned long)ret_from_fork) {
- strcpy(buffer, "<new fork>");
- for (i = 0; buffer[i]; i++)
- ptr = pack_hex_byte(ptr, buffer[i]);
- }
-
- *ptr = '\0';
- put_packet(out_buffer);
-}
-
-/* Handle all qFooBarBaz messages - have to use an if statement as
- opposed to a switch because q messages can have > 1 char id. */
-static void query_msg(void)
-{
- const char *q_start = &in_buffer[1];
-
- /* qC = return current thread ID */
- if (strncmp(q_start, "C", 1) == 0)
- thread_id_msg();
-
- /* qfThreadInfo = query all threads (first) */
- else if (strncmp(q_start, "fThreadInfo", 11) == 0)
- thread_info_msg();
-
- /* qsThreadInfo = query all threads (subsequent). We know we have sent
- them all after the qfThreadInfo message, so there are no to send */
- else if (strncmp(q_start, "sThreadInfo", 11) == 0)
- put_packet("l"); /* el = last */
-
- /* qThreadExtraInfo = supply printable information per thread */
- else if (strncmp(q_start, "ThreadExtraInfo", 15) == 0)
- thread_extra_info_msg();
-
- /* Unsupported - empty message as per spec */
- else
- send_empty_msg();
+ kgdb_regs_to_gdb_regs(&trap_registers, registers);
+ hex_to_mem(&in_buffer[1], (char *) registers, NUMREGBYTES);
+ gdb_regs_to_kgdb_regs(registers, &trap_registers);
+ send_ok_msg();
}
-#endif /* CONFIG_KGDB_THREAD */
+#ifdef CONFIG_SH_KGDB_CONSOLE
/*
* Bring up the ports..
*/
@@ -1185,6 +824,9 @@ static int kgdb_serial_setup(void)
return 0;
}
+#else
+#define kgdb_serial_setup() 0
+#endif
/* The command loop, read and act on requests */
static void kgdb_command_loop(const int excep_code, const int trapa_value)
@@ -1193,7 +835,7 @@ static void kgdb_command_loop(const int excep_code, const int trapa_value)
if (excep_code == NMI_VEC) {
#ifndef CONFIG_KGDB_NMI
- KGDB_PRINTK("Ignoring unexpected NMI?\n");
+ printk(KERN_NOTICE "KGDB: Ignoring unexpected NMI?\n");
return;
#else /* CONFIG_KGDB_NMI */
if (!kgdb_enabled) {
@@ -1207,19 +849,10 @@ static void kgdb_command_loop(const int excep_code, const int trapa_value)
if (!kgdb_enabled)
return;
-#ifdef CONFIG_KGDB_THREAD
- /* Until GDB specifies a thread */
- current_thread = NULL;
- trapped_thread = current;
-#endif
-
/* Enter GDB mode (e.g. after detach) */
if (!kgdb_in_gdb_mode) {
/* Do serial setup, notify user, issue preemptive ack */
- kgdb_serial_setup();
- KGDB_PRINTK("Waiting for GDB (on %s%d at %d baud)\n",
- (kgdb_porttype ? kgdb_porttype->name : ""),
- kgdb_portnum, kgdb_baud);
+ printk(KERN_NOTICE "KGDB: Waiting for GDB\n");
kgdb_in_gdb_mode = 1;
put_debug_char('+');
}
@@ -1233,21 +866,18 @@ static void kgdb_command_loop(const int excep_code, const int trapa_value)
will later be replaced by its original one. Do NOT do this for
trap 0xff, since that indicates a compiled-in breakpoint which
will not be replaced (and we would retake the trap forever) */
- if ((excep_code == TRAP_VEC) && (trapa_value != (0xff << 2))) {
+ if ((excep_code == TRAP_VEC) && (trapa_value != (0x3c << 2)))
trap_registers.pc -= 2;
- }
/* Undo any stepping we may have done */
undo_single_step();
while (1) {
-
out_buffer[0] = 0;
get_packet(in_buffer, BUFMAX);
/* Examine first char of buffer to see what we need to do */
switch (in_buffer[0]) {
-
case '?': /* Send which signal we've received */
send_signal_msg(sigval);
break;
@@ -1291,21 +921,6 @@ static void kgdb_command_loop(const int excep_code, const int trapa_value)
step_msg();
return;
-#ifdef CONFIG_KGDB_THREAD
-
- case 'H': /* Task related */
- set_thread_msg();
- break;
-
- case 'T': /* Query thread status */
- thread_status_msg();
- break;
-
- case 'q': /* Handle query - currently thread-related */
- query_msg();
- break;
-#endif
-
case 'k': /* 'Kill the program' with a kernel ? */
break;
@@ -1323,11 +938,8 @@ static void kgdb_command_loop(const int excep_code, const int trapa_value)
}
/* There has been an exception, most likely a breakpoint. */
-asmlinkage void kgdb_handle_exception(unsigned long r4, unsigned long r5,
- unsigned long r6, unsigned long r7,
- struct pt_regs __regs)
+static void handle_exception(struct pt_regs *regs)
{
- struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
int excep_code, vbr_val;
int count;
int trapa_value = ctrl_inl(TRA);
@@ -1355,7 +967,7 @@ asmlinkage void kgdb_handle_exception(unsigned long r4, unsigned long r5,
kgdb_trapa_val = trapa_value;
/* Act on the exception */
- kgdb_command_loop(excep_code >> 5, trapa_value);
+ kgdb_command_loop(excep_code, trapa_value);
kgdb_current = NULL;
@@ -1373,14 +985,12 @@ asmlinkage void kgdb_handle_exception(unsigned long r4, unsigned long r5,
asm("ldc %0, vbr": :"r"(vbr_val));
}
-/* Trigger a breakpoint by function */
-void breakpoint(void)
+asmlinkage void kgdb_handle_exception(unsigned long r4, unsigned long r5,
+ unsigned long r6, unsigned long r7,
+ struct pt_regs __regs)
{
- if (!kgdb_enabled) {
- kgdb_enabled = 1;
- kgdb_init();
- }
- BREAKPOINT();
+ struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
+ handle_exception(regs);
}
/* Initialise the KGDB data structures and serial configuration */
@@ -1395,24 +1005,16 @@ int kgdb_init(void)
kgdb_in_gdb_mode = 0;
if (kgdb_serial_setup() != 0) {
- KGDB_PRINTK("serial setup error\n");
+ printk(KERN_NOTICE "KGDB: serial setup error\n");
return -1;
}
/* Init ptr to exception handler */
- kgdb_debug_hook = kgdb_handle_exception;
+ kgdb_debug_hook = handle_exception;
kgdb_bus_err_hook = kgdb_handle_bus_error;
/* Enter kgdb now if requested, or just report init done */
- if (kgdb_halt) {
- kgdb_in_gdb_mode = 1;
- put_debug_char('+');
- breakpoint();
- }
- else
- {
- KGDB_PRINTK("stub is initialized.\n");
- }
+ printk(KERN_NOTICE "KGDB: stub is initialized.\n");
return 0;
}
@@ -1437,7 +1039,7 @@ static void kgdb_msg_write(const char *s, unsigned count)
/* Calculate how many this time */
wcount = (count > MAXOUT) ? MAXOUT : count;
-
+
/* Pack in hex chars */
for (i = 0; i < wcount; i++)
bufptr = pack_hex_byte(bufptr, s[i]);
@@ -1467,3 +1069,25 @@ void kgdb_console_write(struct console *co, const char *s, unsigned count)
kgdb_msg_write(s, count);
}
#endif
+
+#ifdef CONFIG_KGDB_SYSRQ
+static void sysrq_handle_gdb(int key, struct tty_struct *tty)
+{
+ printk("Entering GDB stub\n");
+ breakpoint();
+}
+
+static struct sysrq_key_op sysrq_gdb_op = {
+ .handler = sysrq_handle_gdb,
+ .help_msg = "Gdb",
+ .action_msg = "GDB",
+};
+
+static int gdb_register_sysrq(void)
+{
+ printk("Registering GDB sysrq handler\n");
+ register_sysrq_key('g', &sysrq_gdb_op);
+ return 0;
+}
+module_init(gdb_register_sysrq);
+#endif
diff --git a/arch/sh/kernel/machine_kexec.c b/arch/sh/kernel/machine_kexec.c
index 08587cdb64d..790ed69b866 100644
--- a/arch/sh/kernel/machine_kexec.c
+++ b/arch/sh/kernel/machine_kexec.c
@@ -59,13 +59,13 @@ static void kexec_info(struct kimage *image)
printk(" segment[%d]: 0x%08x - 0x%08x (0x%08x)\n",
i,
(unsigned int)image->segment[i].mem,
- (unsigned int)image->segment[i].mem + image->segment[i].memsz,
+ (unsigned int)image->segment[i].mem +
+ image->segment[i].memsz,
(unsigned int)image->segment[i].memsz);
- }
+ }
printk(" start : 0x%08x\n\n", (unsigned int)image->start);
}
-
/*
* Do not allocate memory (or fail in any way) in machine_kexec().
* We are past the point of no return, committed to rebooting now.
@@ -101,6 +101,27 @@ NORET_TYPE void machine_kexec(struct kimage *image)
/* now call it */
rnk = (relocate_new_kernel_t) reboot_code_buffer;
- (*rnk)(page_list, reboot_code_buffer, image->start, vbr_reg);
+ (*rnk)(page_list, reboot_code_buffer, image->start, vbr_reg);
}
+/* crashkernel=size@addr specifies the location to reserve for
+ * a crash kernel. By reserving this memory we guarantee
+ * that linux never sets it up as a DMA target.
+ * Useful for holding code to do something appropriate
+ * after a kernel panic.
+ */
+static int __init parse_crashkernel(char *arg)
+{
+ unsigned long size, base;
+ size = memparse(arg, &arg);
+ if (*arg == '@') {
+ base = memparse(arg+1, &arg);
+ /* FIXME: Do I want a sanity check
+ * to validate the memory range?
+ */
+ crashk_res.start = base;
+ crashk_res.end = base + size - 1;
+ }
+ return 0;
+}
+early_param("crashkernel", parse_crashkernel);
diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c
index e7607366ac4..329b3f3051d 100644
--- a/arch/sh/kernel/process.c
+++ b/arch/sh/kernel/process.c
@@ -7,7 +7,7 @@
*
* SuperH version: Copyright (C) 1999, 2000 Niibe Yutaka & Kaz Kojima
* Copyright (C) 2006 Lineo Solutions Inc. support SH4A UBC
- * Copyright (C) 2002 - 2006 Paul Mundt
+ * Copyright (C) 2002 - 2007 Paul Mundt
*/
#include <linux/module.h>
#include <linux/mm.h>
@@ -15,6 +15,7 @@
#include <linux/pm.h>
#include <linux/kallsyms.h>
#include <linux/kexec.h>
+#include <asm/kdebug.h>
#include <asm/uaccess.h>
#include <asm/mmu_context.h>
#include <asm/ubc.h>
@@ -299,7 +300,8 @@ static void ubc_set_tracing(int asid, unsigned long pc)
ctrl_outl(0, UBC_BAMRA);
if (current_cpu_data.type == CPU_SH7729 ||
- current_cpu_data.type == CPU_SH7710) {
+ current_cpu_data.type == CPU_SH7710 ||
+ current_cpu_data.type == CPU_SH7712) {
ctrl_outw(BBR_INST | BBR_READ | BBR_CPU, UBC_BBRA);
ctrl_outl(BRCR_PCBA | BRCR_PCTE, UBC_BRCR);
} else {
@@ -495,6 +497,10 @@ asmlinkage void debug_trap_handler(unsigned long r4, unsigned long r5,
/* Rewind */
regs->pc -= 2;
+ if (notify_die(DIE_TRAP, regs, regs->tra & 0xff,
+ SIGTRAP) == NOTIFY_STOP)
+ return;
+
force_sig(SIGTRAP, current);
}
@@ -510,6 +516,10 @@ asmlinkage void bug_trap_handler(unsigned long r4, unsigned long r5,
/* Rewind */
regs->pc -= 2;
+ if (notify_die(DIE_TRAP, regs, TRAPA_BUG_OPCODE & 0xff,
+ SIGTRAP) == NOTIFY_STOP)
+ return;
+
#ifdef CONFIG_BUG
if (__kernel_text_address(instruction_pointer(regs))) {
u16 insn = *(u16 *)instruction_pointer(regs);
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index 98802ab2821..477d2a854fc 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -4,7 +4,7 @@
* This file handles the architecture-dependent parts of initialization
*
* Copyright (C) 1999 Niibe Yutaka
- * Copyright (C) 2002 - 2006 Paul Mundt
+ * Copyright (C) 2002 - 2007 Paul Mundt
*/
#include <linux/screen_info.h>
#include <linux/ioport.h>
@@ -15,21 +15,22 @@
#include <linux/seq_file.h>
#include <linux/root_dev.h>
#include <linux/utsname.h>
+#include <linux/nodemask.h>
#include <linux/cpu.h>
#include <linux/pfn.h>
#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/kexec.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <asm/sections.h>
#include <asm/irq.h>
#include <asm/setup.h>
#include <asm/clock.h>
+#include <asm/mmu_context.h>
-#ifdef CONFIG_SH_KGDB
-#include <asm/kgdb.h>
-static int kgdb_parse_options(char *options);
-#endif
extern void * __rd_start, * __rd_end;
+
/*
* Machine setup..
*/
@@ -205,53 +206,33 @@ static int __init sh_mv_setup(char **cmdline_p)
return 0;
}
-void __init setup_arch(char **cmdline_p)
+/*
+ * Register fully available low RAM pages with the bootmem allocator.
+ */
+static void __init register_bootmem_low_pages(void)
{
- unsigned long bootmap_size;
- unsigned long start_pfn, max_pfn, max_low_pfn;
-
-#ifdef CONFIG_CMDLINE_BOOL
- strcpy(COMMAND_LINE, CONFIG_CMDLINE);
-#endif
-
- ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV);
-
-#ifdef CONFIG_BLK_DEV_RAM
- rd_image_start = RAMDISK_FLAGS & RAMDISK_IMAGE_START_MASK;
- rd_prompt = ((RAMDISK_FLAGS & RAMDISK_PROMPT_FLAG) != 0);
- rd_doload = ((RAMDISK_FLAGS & RAMDISK_LOAD_FLAG) != 0);
-#endif
-
- if (!MOUNT_ROOT_RDONLY)
- root_mountflags &= ~MS_RDONLY;
- init_mm.start_code = (unsigned long) _text;
- init_mm.end_code = (unsigned long) _etext;
- init_mm.end_data = (unsigned long) _edata;
- init_mm.brk = (unsigned long) _end;
-
- code_resource.start = (unsigned long)virt_to_phys(_text);
- code_resource.end = (unsigned long)virt_to_phys(_etext)-1;
- data_resource.start = (unsigned long)virt_to_phys(_etext);
- data_resource.end = (unsigned long)virt_to_phys(_edata)-1;
-
- sh_mv_setup(cmdline_p);
-
+ unsigned long curr_pfn, last_pfn, pages;
/*
- * Find the highest page frame number we have available
+ * We are rounding up the start address of usable memory:
*/
- max_pfn = PFN_DOWN(__pa(memory_end));
+ curr_pfn = PFN_UP(__MEMORY_START);
/*
- * Determine low and high memory ranges:
+ * ... and at the end of the usable range downwards:
*/
- max_low_pfn = max_pfn;
+ last_pfn = PFN_DOWN(__pa(memory_end));
- /*
- * Partially used pages are not usable - thus
- * we are rounding upwards:
- */
- start_pfn = PFN_UP(__pa(_end));
+ if (last_pfn > max_low_pfn)
+ last_pfn = max_low_pfn;
+
+ pages = last_pfn - curr_pfn;
+ free_bootmem(PFN_PHYS(curr_pfn), PFN_PHYS(pages));
+}
+
+void __init setup_bootmem_allocator(unsigned long start_pfn)
+{
+ unsigned long bootmap_size;
/*
* Find a proper area for the bootmem bitmap. After this
@@ -259,31 +240,11 @@ void __init setup_arch(char **cmdline_p)
* is intact) must be done via bootmem_alloc().
*/
bootmap_size = init_bootmem_node(NODE_DATA(0), start_pfn,
- __MEMORY_START>>PAGE_SHIFT,
- max_low_pfn);
- /*
- * Register fully available low RAM pages with the bootmem allocator.
- */
- {
- unsigned long curr_pfn, last_pfn, pages;
-
- /*
- * We are rounding up the start address of usable memory:
- */
- curr_pfn = PFN_UP(__MEMORY_START);
- /*
- * ... and at the end of the usable range downwards:
- */
- last_pfn = PFN_DOWN(__pa(memory_end));
+ min_low_pfn, max_low_pfn);
- if (last_pfn > max_low_pfn)
- last_pfn = max_low_pfn;
-
- pages = last_pfn - curr_pfn;
- free_bootmem_node(NODE_DATA(0), PFN_PHYS(curr_pfn),
- PFN_PHYS(pages));
- }
+ register_bootmem_low_pages();
+ node_set_online(0);
/*
* Reserve the kernel text and
@@ -292,14 +253,14 @@ void __init setup_arch(char **cmdline_p)
* case of us accidentally initializing the bootmem allocator with
* an invalid RAM area.
*/
- reserve_bootmem_node(NODE_DATA(0), __MEMORY_START+PAGE_SIZE,
+ reserve_bootmem(__MEMORY_START+PAGE_SIZE,
(PFN_PHYS(start_pfn)+bootmap_size+PAGE_SIZE-1)-__MEMORY_START);
/*
* reserve physical page 0 - it's a special BIOS page on many boxes,
* enabling clean reboots, SMP operation, laptop functions.
*/
- reserve_bootmem_node(NODE_DATA(0), __MEMORY_START, PAGE_SIZE);
+ reserve_bootmem(__MEMORY_START, PAGE_SIZE);
#ifdef CONFIG_BLK_DEV_INITRD
ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
@@ -313,8 +274,8 @@ void __init setup_arch(char **cmdline_p)
if (LOADER_TYPE && INITRD_START) {
if (INITRD_START + INITRD_SIZE <= (max_low_pfn << PAGE_SHIFT)) {
- reserve_bootmem_node(NODE_DATA(0), INITRD_START +
- __MEMORY_START, INITRD_SIZE);
+ reserve_bootmem(INITRD_START + __MEMORY_START,
+ INITRD_SIZE);
initrd_start = INITRD_START + PAGE_OFFSET +
__MEMORY_START;
initrd_end = initrd_start + INITRD_SIZE;
@@ -327,6 +288,76 @@ void __init setup_arch(char **cmdline_p)
}
}
#endif
+#ifdef CONFIG_KEXEC
+ if (crashk_res.start != crashk_res.end)
+ reserve_bootmem(crashk_res.start,
+ crashk_res.end - crashk_res.start + 1);
+#endif
+}
+
+#ifndef CONFIG_NEED_MULTIPLE_NODES
+static void __init setup_memory(void)
+{
+ unsigned long start_pfn;
+
+ /*
+ * Partially used pages are not usable - thus
+ * we are rounding upwards:
+ */
+ start_pfn = PFN_UP(__pa(_end));
+ setup_bootmem_allocator(start_pfn);
+}
+#else
+extern void __init setup_memory(void);
+#endif
+
+void __init setup_arch(char **cmdline_p)
+{
+ enable_mmu();
+
+#ifdef CONFIG_CMDLINE_BOOL
+ strcpy(COMMAND_LINE, CONFIG_CMDLINE);
+#endif
+
+ ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV);
+
+#ifdef CONFIG_BLK_DEV_RAM
+ rd_image_start = RAMDISK_FLAGS & RAMDISK_IMAGE_START_MASK;
+ rd_prompt = ((RAMDISK_FLAGS & RAMDISK_PROMPT_FLAG) != 0);
+ rd_doload = ((RAMDISK_FLAGS & RAMDISK_LOAD_FLAG) != 0);
+#endif
+
+ if (!MOUNT_ROOT_RDONLY)
+ root_mountflags &= ~MS_RDONLY;
+ init_mm.start_code = (unsigned long) _text;
+ init_mm.end_code = (unsigned long) _etext;
+ init_mm.end_data = (unsigned long) _edata;
+ init_mm.brk = (unsigned long) _end;
+
+ code_resource.start = virt_to_phys(_text);
+ code_resource.end = virt_to_phys(_etext)-1;
+ data_resource.start = virt_to_phys(_etext);
+ data_resource.end = virt_to_phys(_edata)-1;
+
+ parse_early_param();
+
+ sh_mv_setup(cmdline_p);
+
+ /*
+ * Find the highest page frame number we have available
+ */
+ max_pfn = PFN_DOWN(__pa(memory_end));
+
+ /*
+ * Determine low and high memory ranges:
+ */
+ max_low_pfn = max_pfn;
+ min_low_pfn = __MEMORY_START >> PAGE_SHIFT;
+
+ nodes_clear(node_online_map);
+ setup_memory();
+ paging_init();
+ sparse_init();
#ifdef CONFIG_DUMMY_CONSOLE
conswitchp = &dummy_con;
@@ -335,8 +366,6 @@ void __init setup_arch(char **cmdline_p)
/* Perform the machine specific initialisation */
if (likely(sh_mv.mv_setup))
sh_mv.mv_setup(cmdline_p);
-
- paging_init();
}
struct sh_machine_vector* __init get_mv_byname(const char* name)
@@ -380,6 +409,7 @@ static const char *cpu_name[] = {
[CPU_SH7705] = "SH7705", [CPU_SH7706] = "SH7706",
[CPU_SH7707] = "SH7707", [CPU_SH7708] = "SH7708",
[CPU_SH7709] = "SH7709", [CPU_SH7710] = "SH7710",
+ [CPU_SH7712] = "SH7712",
[CPU_SH7729] = "SH7729", [CPU_SH7750] = "SH7750",
[CPU_SH7750S] = "SH7750S", [CPU_SH7750R] = "SH7750R",
[CPU_SH7751] = "SH7751", [CPU_SH7751R] = "SH7751R",
@@ -477,7 +507,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
c->loops_per_jiffy/(500000/HZ),
(c->loops_per_jiffy/(5000/HZ)) % 100);
- return show_clocks(m);
+ return 0;
}
static void *c_start(struct seq_file *m, loff_t *pos)
@@ -499,92 +529,3 @@ struct seq_operations cpuinfo_op = {
.show = show_cpuinfo,
};
#endif /* CONFIG_PROC_FS */
-
-#ifdef CONFIG_SH_KGDB
-/*
- * Parse command-line kgdb options. By default KGDB is enabled,
- * entered on error (or other action) using default serial info.
- * The command-line option can include a serial port specification
- * and an action to override default or configured behavior.
- */
-struct kgdb_sermap kgdb_sci_sermap =
-{ "ttySC", 5, kgdb_sci_setup, NULL };
-
-struct kgdb_sermap *kgdb_serlist = &kgdb_sci_sermap;
-struct kgdb_sermap *kgdb_porttype = &kgdb_sci_sermap;
-
-void kgdb_register_sermap(struct kgdb_sermap *map)
-{
- struct kgdb_sermap *last;
-
- for (last = kgdb_serlist; last->next; last = last->next)
- ;
- last->next = map;
- if (!map->namelen) {
- map->namelen = strlen(map->name);
- }
-}
-
-static int __init kgdb_parse_options(char *options)
-{
- char c;
- int baud;
-
- /* Check for port spec (or use default) */
-
- /* Determine port type and instance */
- if (!memcmp(options, "tty", 3)) {
- struct kgdb_sermap *map = kgdb_serlist;
-
- while (map && memcmp(options, map->name, map->namelen))
- map = map->next;
-
- if (!map) {
- KGDB_PRINTK("unknown port spec in %s\n", options);
- return -1;
- }
-
- kgdb_porttype = map;
- kgdb_serial_setup = map->setup_fn;
- kgdb_portnum = options[map->namelen] - '0';
- options += map->namelen + 1;
-
- options = (*options == ',') ? options+1 : options;
-
- /* Read optional parameters (baud/parity/bits) */
- baud = simple_strtoul(options, &options, 10);
- if (baud != 0) {
- kgdb_baud = baud;
-
- c = toupper(*options);
- if (c == 'E' || c == 'O' || c == 'N') {
- kgdb_parity = c;
- options++;
- }
-
- c = *options;
- if (c == '7' || c == '8') {
- kgdb_bits = c;
- options++;
- }
- options = (*options == ',') ? options+1 : options;
- }
- }
-
- /* Check for action specification */
- if (!memcmp(options, "halt", 4)) {
- kgdb_halt = 1;
- options += 4;
- } else if (!memcmp(options, "disabled", 8)) {
- kgdb_enabled = 0;
- options += 8;
- }
-
- if (*options) {
- KGDB_PRINTK("ignored unknown options: %s\n", options);
- return 0;
- }
- return 1;
-}
-__setup("kgdb=", kgdb_parse_options);
-#endif /* CONFIG_SH_KGDB */
diff --git a/arch/sh/kernel/sh_ksyms.c b/arch/sh/kernel/sh_ksyms.c
index 6e0d10fac4a..17f0b50c567 100644
--- a/arch/sh/kernel/sh_ksyms.c
+++ b/arch/sh/kernel/sh_ksyms.c
@@ -65,7 +65,6 @@ EXPORT_SYMBOL(__div64_32);
/* These symbols are generated by the compiler itself */
DECLARE_EXPORT(__udivsi3);
-DECLARE_EXPORT(__udivdi3);
DECLARE_EXPORT(__sdivsi3);
DECLARE_EXPORT(__ashrdi3);
DECLARE_EXPORT(__ashldi3);
diff --git a/arch/sh/kernel/timers/timer-tmu.c b/arch/sh/kernel/timers/timer-tmu.c
index e060e71d078..ad1ede52fc9 100644
--- a/arch/sh/kernel/timers/timer-tmu.c
+++ b/arch/sh/kernel/timers/timer-tmu.c
@@ -148,7 +148,9 @@ static int tmu_timer_init(void)
/* Start TMU0 */
tmu_timer_stop();
-#if !defined(CONFIG_CPU_SUBTYPE_SH7300) && !defined(CONFIG_CPU_SUBTYPE_SH7760)
+#if !defined(CONFIG_CPU_SUBTYPE_SH7300) && \
+ !defined(CONFIG_CPU_SUBTYPE_SH7760) && \
+ !defined(CONFIG_CPU_SUBTYPE_SH7785)
ctrl_outb(TMU_TOCR_INIT, TMU_TOCR);
#endif
diff --git a/arch/sh/kernel/traps.c b/arch/sh/kernel/traps.c
index e9f168f60f9..7b40f0ff3df 100644
--- a/arch/sh/kernel/traps.c
+++ b/arch/sh/kernel/traps.c
@@ -5,7 +5,7 @@
* SuperH version: Copyright (C) 1999 Niibe Yutaka
* Copyright (C) 2000 Philipp Rumpf
* Copyright (C) 2000 David Howells
- * Copyright (C) 2002 - 2006 Paul Mundt
+ * Copyright (C) 2002 - 2007 Paul Mundt
*
* 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
@@ -18,10 +18,12 @@
#include <linux/module.h>
#include <linux/kallsyms.h>
#include <linux/io.h>
+#include <linux/bug.h>
#include <linux/debug_locks.h>
#include <linux/limits.h>
#include <asm/system.h>
#include <asm/uaccess.h>
+#include <asm/kdebug.h>
#ifdef CONFIG_SH_KGDB
#include <asm/kgdb.h>
@@ -74,7 +76,21 @@ static void dump_mem(const char *str, unsigned long bottom, unsigned long top)
}
}
-DEFINE_SPINLOCK(die_lock);
+ATOMIC_NOTIFIER_HEAD(shdie_chain);
+
+int register_die_notifier(struct notifier_block *nb)
+{
+ return atomic_notifier_chain_register(&shdie_chain, nb);
+}
+EXPORT_SYMBOL(register_die_notifier);
+
+int unregister_die_notifier(struct notifier_block *nb)
+{
+ return atomic_notifier_chain_unregister(&shdie_chain, nb);
+}
+EXPORT_SYMBOL(unregister_die_notifier);
+
+static DEFINE_SPINLOCK(die_lock);
void die(const char * str, struct pt_regs * regs, long err)
{
@@ -130,40 +146,6 @@ static int die_if_no_fixup(const char * str, struct pt_regs * regs, long err)
return -EFAULT;
}
-#ifdef CONFIG_BUG
-#ifdef CONFIG_DEBUG_BUGVERBOSE
-static inline void do_bug_verbose(struct pt_regs *regs)
-{
- struct bug_frame f;
- long len;
-
- if (__copy_from_user(&f, (const void __user *)regs->pc,
- sizeof(struct bug_frame)))
- return;
-
- len = __strnlen_user(f.file, PATH_MAX) - 1;
- if (unlikely(len < 0 || len >= PATH_MAX))
- f.file = "<bad filename>";
- len = __strnlen_user(f.func, PATH_MAX) - 1;
- if (unlikely(len < 0 || len >= PATH_MAX))
- f.func = "<bad function>";
-
- printk(KERN_ALERT "kernel BUG in %s() at %s:%d!\n",
- f.func, f.file, f.line);
-}
-#else
-static inline void do_bug_verbose(struct pt_regs *regs)
-{
-}
-#endif /* CONFIG_DEBUG_BUGVERBOSE */
-
-void handle_BUG(struct pt_regs *regs)
-{
- do_bug_verbose(regs);
- die("Kernel BUG", regs, TRAPA_BUG_OPCODE & 0xff);
-}
-#endif /* CONFIG_BUG */
-
/*
* handle an instruction that does an unaligned memory access by emulating the
* desired behaviour
@@ -888,6 +870,25 @@ void __init trap_init(void)
per_cpu_trap_init();
}
+#ifdef CONFIG_BUG
+void handle_BUG(struct pt_regs *regs)
+{
+ enum bug_trap_type tt;
+ tt = report_bug(regs->pc);
+ if (tt == BUG_TRAP_TYPE_WARN) {
+ regs->pc += 2;
+ return;
+ }
+
+ die("Kernel BUG", regs, TRAPA_BUG_OPCODE & 0xff);
+}
+
+int is_valid_bugaddr(unsigned long addr)
+{
+ return addr >= PAGE_OFFSET;
+}
+#endif
+
void show_trace(struct task_struct *tsk, unsigned long *sp,
struct pt_regs *regs)
{
diff --git a/arch/sh/kernel/vmlinux.lds.S b/arch/sh/kernel/vmlinux.lds.S
index 2f606d0ce1f..d83143cc5ca 100644
--- a/arch/sh/kernel/vmlinux.lds.S
+++ b/arch/sh/kernel/vmlinux.lds.S
@@ -34,9 +34,11 @@ SECTIONS
__ex_table : { *(__ex_table) }
__stop___ex_table = .;
+ _etext = .; /* End of text section */
+
RODATA
- _etext = .; /* End of text section */
+ BUG_TABLE
.data : { /* Data */
*(.data)
@@ -53,6 +55,10 @@ SECTIONS
. = ALIGN(PAGE_SIZE);
.data.page_aligned : { *(.data.page_aligned) }
+ __nosave_begin = .;
+ .data_nosave : { *(.data.nosave) }
+ . = ALIGN(PAGE_SIZE);
+ __nosave_end = .;
. = ALIGN(PAGE_SIZE);
__per_cpu_start = .;
@@ -110,43 +116,10 @@ SECTIONS
* it's a module.
*/
/DISCARD/ : {
- *(.exit.text)
- *(.exit.data)
*(.exitcall.exit)
}
- /* Stabs debugging sections. */
- .stab 0 : { *(.stab) }
- .stabstr 0 : { *(.stabstr) }
- .stab.excl 0 : { *(.stab.excl) }
- .stab.exclstr 0 : { *(.stab.exclstr) }
- .stab.index 0 : { *(.stab.index) }
- .stab.indexstr 0 : { *(.stab.indexstr) }
- .comment 0 : { *(.comment) }
- /* DWARF debug sections.
- Symbols in the DWARF debugging section are relative to the beginning
- of the section so we begin .debug at 0. */
- /* DWARF 1 */
- .debug 0 : { *(.debug) }
- .line 0 : { *(.line) }
- /* GNU DWARF 1 extensions */
- .debug_srcinfo 0 : { *(.debug_srcinfo) }
- .debug_sfnames 0 : { *(.debug_sfnames) }
- /* DWARF 1.1 and DWARF 2 */
- .debug_aranges 0 : { *(.debug_aranges) }
- .debug_pubnames 0 : { *(.debug_pubnames) }
- /* DWARF 2 */
- .debug_info 0 : { *(.debug_info) }
- .debug_abbrev 0 : { *(.debug_abbrev) }
- .debug_line 0 : { *(.debug_line) }
- .debug_frame 0 : { *(.debug_frame) }
- .debug_str 0 : { *(.debug_str) }
- .debug_loc 0 : { *(.debug_loc) }
- .debug_macinfo 0 : { *(.debug_macinfo) }
- /* SGI/MIPS DWARF 2 extensions */
- .debug_weaknames 0 : { *(.debug_weaknames) }
- .debug_funcnames 0 : { *(.debug_funcnames) }
- .debug_typenames 0 : { *(.debug_typenames) }
- .debug_varnames 0 : { *(.debug_varnames) }
- /* These must appear regardless of . */
+ STABS_DEBUG
+
+ DWARF_DEBUG
}
diff --git a/arch/sh/lib/Makefile b/arch/sh/lib/Makefile
index 0b9cca5c7cb..e23dd1a3fcc 100644
--- a/arch/sh/lib/Makefile
+++ b/arch/sh/lib/Makefile
@@ -3,11 +3,9 @@
#
lib-y = delay.o memset.o memmove.o memchr.o \
- checksum.o strlen.o div64.o udivdi3.o \
- div64-generic.o
+ checksum.o strlen.o div64.o div64-generic.o
memcpy-y := memcpy.o
memcpy-$(CONFIG_CPU_SH4) := memcpy-sh4.o
lib-y += $(memcpy-y)
-
diff --git a/arch/sh/lib/udivdi3.c b/arch/sh/lib/udivdi3.c
deleted file mode 100644
index 68f038bf3c5..00000000000
--- a/arch/sh/lib/udivdi3.c
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * Simple __udivdi3 function which doesn't use FPU.
- */
-
-#include <linux/types.h>
-
-extern u64 __xdiv64_32(u64 n, u32 d);
-extern void panic(const char * fmt, ...);
-
-u64 __udivdi3(u64 n, u64 d)
-{
- if (d & ~0xffffffff)
- panic("Need true 64-bit/64-bit division");
- return __xdiv64_32(n, (u32)d);
-}
-
diff --git a/arch/sh/mm/Kconfig b/arch/sh/mm/Kconfig
index 6b0d28ac924..12f3d394dc2 100644
--- a/arch/sh/mm/Kconfig
+++ b/arch/sh/mm/Kconfig
@@ -67,6 +67,7 @@ config CPU_SUBTYPE_SH7300
config CPU_SUBTYPE_SH7705
bool "Support SH7705 processor"
select CPU_SH3
+ select CPU_HAS_IPR_IRQ
select CPU_HAS_PINT_IRQ
config CPU_SUBTYPE_SH7706
@@ -101,9 +102,17 @@ config CPU_SUBTYPE_SH7709
config CPU_SUBTYPE_SH7710
bool "Support SH7710 processor"
select CPU_SH3
+ select CPU_HAS_IPR_IRQ
help
Select SH7710 if you have a SH3-DSP SH7710 CPU.
+config CPU_SUBTYPE_SH7712
+ bool "Support SH7712 processor"
+ select CPU_SH3
+ select CPU_HAS_IPR_IRQ
+ help
+ Select SH7712 if you have a SH3-DSP SH7712 CPU.
+
comment "SH-4 Processor Support"
config CPU_SUBTYPE_SH7750
@@ -283,6 +292,17 @@ config VSYSCALL
For systems with an MMU that can afford to give up a page,
(the default value) say Y.
+config NODES_SHIFT
+ int
+ default "1"
+ depends on NEED_MULTIPLE_NODES
+
+config ARCH_FLATMEM_ENABLE
+ def_bool y
+
+config ARCH_POPULATES_NODE_MAP
+ def_bool y
+
choice
prompt "Kernel page size"
default PAGE_SIZE_4KB
diff --git a/arch/sh/mm/fault.c b/arch/sh/mm/fault.c
index fa5d7f0b9f1..0ecc117cade 100644
--- a/arch/sh/mm/fault.c
+++ b/arch/sh/mm/fault.c
@@ -2,7 +2,7 @@
* Page fault handler for SH with an MMU.
*
* Copyright (C) 1999 Niibe Yutaka
- * Copyright (C) 2003 Paul Mundt
+ * Copyright (C) 2003 - 2007 Paul Mundt
*
* Based on linux/arch/i386/mm/fault.c:
* Copyright (C) 1995 Linus Torvalds
@@ -15,12 +15,42 @@
#include <linux/mm.h>
#include <linux/hardirq.h>
#include <linux/kprobes.h>
+#include <asm/kdebug.h>
#include <asm/system.h>
#include <asm/mmu_context.h>
#include <asm/tlbflush.h>
#include <asm/kgdb.h>
-extern void die(const char *,struct pt_regs *,long);
+#ifdef CONFIG_KPROBES
+ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain);
+
+/* Hook to register for page fault notifications */
+int register_page_fault_notifier(struct notifier_block *nb)
+{
+ return atomic_notifier_chain_register(&notify_page_fault_chain, nb);
+}
+
+int unregister_page_fault_notifier(struct notifier_block *nb)
+{
+ return atomic_notifier_chain_unregister(&notify_page_fault_chain, nb);
+}
+
+static inline int notify_page_fault(enum die_val val, struct pt_regs *regs,
+ int trap, int sig)
+{
+ struct die_args args = {
+ .regs = regs,
+ .trapnr = trap,
+ };
+ return atomic_notifier_call_chain(&notify_page_fault_chain, val, &args);
+}
+#else
+static inline int notify_page_fault(enum die_val val, struct pt_regs *regs,
+ int trap, int sig)
+{
+ return NOTIFY_DONE;
+}
+#endif
/*
* This routine handles page faults. It determines the address,
@@ -39,6 +69,11 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs,
siginfo_t info;
trace_hardirqs_on();
+
+ if (notify_page_fault(DIE_PAGE_FAULT, regs,
+ writeaccess, SIGSEGV) == NOTIFY_STOP)
+ return;
+
local_irq_enable();
#ifdef CONFIG_SH_KGDB
diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c
index ae957a93237..4d030988b36 100644
--- a/arch/sh/mm/init.c
+++ b/arch/sh/mm/init.c
@@ -1,37 +1,20 @@
-/* $Id: init.c,v 1.19 2004/02/21 04:42:16 kkojima Exp $
- *
- * linux/arch/sh/mm/init.c
+/*
+ * linux/arch/sh/mm/init.c
*
* Copyright (C) 1999 Niibe Yutaka
- * Copyright (C) 2002, 2004 Paul Mundt
+ * Copyright (C) 2002 - 2007 Paul Mundt
*
* Based on linux/arch/i386/mm/init.c:
* Copyright (C) 1995 Linus Torvalds
*/
-
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/types.h>
-#include <linux/ptrace.h>
-#include <linux/mman.h>
#include <linux/mm.h>
#include <linux/swap.h>
-#include <linux/smp.h>
#include <linux/init.h>
-#include <linux/highmem.h>
#include <linux/bootmem.h>
-#include <linux/pagemap.h>
#include <linux/proc_fs.h>
-#include <asm/processor.h>
-#include <asm/system.h>
-#include <asm/uaccess.h>
-#include <asm/pgtable.h>
-#include <asm/pgalloc.h>
+#include <linux/percpu.h>
+#include <linux/io.h>
#include <asm/mmu_context.h>
-#include <asm/io.h>
#include <asm/tlb.h>
#include <asm/cacheflush.h>
#include <asm/cache.h>
@@ -39,37 +22,51 @@
DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
pgd_t swapper_pg_dir[PTRS_PER_PGD];
-#ifdef CONFIG_MMU
-/* It'd be good if these lines were in the standard header file. */
-#define START_PFN (NODE_DATA(0)->bdata->node_boot_start >> PAGE_SHIFT)
-#define MAX_LOW_PFN (NODE_DATA(0)->bdata->node_low_pfn)
-#endif
-
void (*copy_page)(void *from, void *to);
void (*clear_page)(void *to);
void show_mem(void)
{
- int i, total = 0, reserved = 0;
- int shared = 0, cached = 0;
+ int total = 0, reserved = 0, free = 0;
+ int shared = 0, cached = 0, slab = 0;
+ pg_data_t *pgdat;
printk("Mem-info:\n");
show_free_areas();
- printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
- i = max_mapnr;
- while (i-- > 0) {
- total++;
- if (PageReserved(mem_map+i))
- reserved++;
- else if (PageSwapCache(mem_map+i))
- cached++;
- else if (page_count(mem_map+i))
- shared += page_count(mem_map+i) - 1;
+
+ for_each_online_pgdat(pgdat) {
+ struct page *page, *end;
+ unsigned long flags;
+
+ pgdat_resize_lock(pgdat, &flags);
+ page = pgdat->node_mem_map;
+ end = page + pgdat->node_spanned_pages;
+
+ do {
+ total++;
+ if (PageReserved(page))
+ reserved++;
+ else if (PageSwapCache(page))
+ cached++;
+ else if (PageSlab(page))
+ slab++;
+ else if (!page_count(page))
+ free++;
+ else
+ shared += page_count(page) - 1;
+ page++;
+ } while (page < end);
+
+ pgdat_resize_unlock(pgdat, &flags);
}
- printk("%d pages of RAM\n",total);
- printk("%d reserved pages\n",reserved);
- printk("%d pages shared\n",shared);
- printk("%d pages swap cached\n",cached);
+
+ printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
+ printk("%d pages of RAM\n", total);
+ printk("%d free pages\n", free);
+ printk("%d reserved pages\n", reserved);
+ printk("%d slab pages\n", slab);
+ printk("%d pages shared\n", shared);
+ printk("%d pages swap cached\n", cached);
}
#ifdef CONFIG_MMU
@@ -147,52 +144,38 @@ extern char __init_begin, __init_end;
*/
void __init paging_init(void)
{
- unsigned long zones_size[MAX_NR_ZONES] = { 0, };
+ int nid;
- /*
- * Setup some defaults for the zone sizes.. these should be safe
- * regardless of distcontiguous memory or MMU settings.
- */
- zones_size[ZONE_NORMAL] = __MEMORY_SIZE >> PAGE_SHIFT;
-#ifdef CONFIG_HIGHMEM
- zones_size[ZONE_HIGHMEM] = 0 >> PAGE_SHIFT;
-#endif
-
-#ifdef CONFIG_MMU
- /*
- * If we have an MMU, and want to be using it .. we need to adjust
- * the zone sizes accordingly, in addition to turning it on.
- */
- {
- /* We don't need to map the kernel through the TLB, as
- * it is permanatly mapped using P1. So clear the
- * entire pgd. */
- memset(swapper_pg_dir, 0, sizeof(swapper_pg_dir));
-
- /* Turn on the MMU */
- enable_mmu();
- zones_size[ZONE_NORMAL] = MAX_LOW_PFN - START_PFN;
- }
+ /* We don't need to map the kernel through the TLB, as
+ * it is permanatly mapped using P1. So clear the
+ * entire pgd. */
+ memset(swapper_pg_dir, 0, sizeof(swapper_pg_dir));
/* Set an initial value for the MMU.TTB so we don't have to
* check for a null value. */
set_TTB(swapper_pg_dir);
-#elif defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4)
- /*
- * If we don't have CONFIG_MMU set and the processor in question
- * still has an MMU, care needs to be taken to make sure it doesn't
- * stay on.. Since the boot loader could have potentially already
- * turned it on, and we clearly don't want it, we simply turn it off.
- *
- * We don't need to do anything special for the zone sizes, since the
- * default values that were already configured up above should be
- * satisfactory.
- */
- disable_mmu();
-#endif
- NODE_DATA(0)->node_mem_map = NULL;
- free_area_init_node(0, NODE_DATA(0), zones_size, __MEMORY_START >> PAGE_SHIFT, 0);
+ for_each_online_node(nid) {
+ pg_data_t *pgdat = NODE_DATA(nid);
+ unsigned long max_zone_pfns[MAX_NR_ZONES];
+ unsigned long low, start_pfn;
+
+ memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
+
+ start_pfn = pgdat->bdata->node_boot_start >> PAGE_SHIFT;
+ low = pgdat->bdata->node_low_pfn;
+
+ max_zone_pfns[ZONE_NORMAL] = low;
+ add_active_range(nid, start_pfn, low);
+
+ printk("Node %u: start_pfn = 0x%lx, low = 0x%lx\n",
+ nid, start_pfn, low);
+
+ free_area_init_nodes(max_zone_pfns);
+
+ printk("Node %u: mem_map starts at %p\n",
+ pgdat->node_id, pgdat->node_mem_map);
+ }
}
static struct kcore_list kcore_mem, kcore_vmalloc;
@@ -200,18 +183,33 @@ static struct kcore_list kcore_mem, kcore_vmalloc;
void __init mem_init(void)
{
int codesize, reservedpages, datasize, initsize;
- int tmp;
- extern unsigned long memory_start;
+ int nid;
-#ifdef CONFIG_MMU
- high_memory = (void *)__va(MAX_LOW_PFN * PAGE_SIZE);
-#else
- extern unsigned long memory_end;
+ reservedpages = 0;
- high_memory = (void *)(memory_end & PAGE_MASK);
-#endif
+ for_each_online_node(nid) {
+ pg_data_t *pgdat = NODE_DATA(nid);
+ unsigned long node_pages = 0;
+ void *node_high_memory;
+ int i;
+
+ num_physpages += pgdat->node_present_pages;
+
+ if (pgdat->node_spanned_pages)
+ node_pages = free_all_bootmem_node(pgdat);
+
+ totalram_pages += node_pages;
- max_mapnr = num_physpages = MAP_NR(high_memory) - MAP_NR(memory_start);
+ for (i = 0; i < node_pages; i++)
+ if (PageReserved(pgdat->node_mem_map + i))
+ reservedpages++;
+
+ node_high_memory = (void *)((pgdat->node_start_pfn +
+ pgdat->node_spanned_pages) <<
+ PAGE_SHIFT);
+ if (node_high_memory > high_memory)
+ high_memory = node_high_memory;
+ }
/* clear the zero-page */
memset(empty_zero_page, 0, PAGE_SIZE);
@@ -229,16 +227,6 @@ void __init mem_init(void)
clear_page = clear_page_nommu;
#endif
- /* this will put all low memory onto the freelists */
- totalram_pages += free_all_bootmem_node(NODE_DATA(0));
- reservedpages = 0;
- for (tmp = 0; tmp < num_physpages; tmp++)
- /*
- * Only count reserved RAM pages
- */
- if (PageReserved(mem_map+tmp))
- reservedpages++;
-
codesize = (unsigned long) &_etext - (unsigned long) &_text;
datasize = (unsigned long) &_edata - (unsigned long) &_etext;
initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin;
@@ -250,7 +238,7 @@ void __init mem_init(void)
printk(KERN_INFO "Memory: %luk/%luk available (%dk kernel code, "
"%dk reserved, %dk data, %dk init)\n",
(unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
- max_mapnr << (PAGE_SHIFT-10),
+ totalram_pages << (PAGE_SHIFT-10),
codesize >> 10,
reservedpages << (PAGE_SHIFT-10),
datasize >> 10,
@@ -289,4 +277,3 @@ void free_initrd_mem(unsigned long start, unsigned long end)
printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
}
#endif
-
diff --git a/arch/sh/tools/mach-types b/arch/sh/tools/mach-types
index 4fe0f94cbf4..554f801db67 100644
--- a/arch/sh/tools/mach-types
+++ b/arch/sh/tools/mach-types
@@ -9,6 +9,7 @@ SE SH_SOLUTION_ENGINE
7751SE SH_7751_SOLUTION_ENGINE
7300SE SH_7300_SOLUTION_ENGINE
7343SE SH_7343_SOLUTION_ENGINE
+7780SE SH_7780_SOLUTION_ENGINE
73180SE SH_73180_SOLUTION_ENGINE
7751SYSTEMH SH_7751_SYSTEMH
HP6XX SH_HP6XX
@@ -26,6 +27,7 @@ SH03 SH_SH03
LANDISK SH_LANDISK
R7780RP SH_R7780RP
R7780MP SH_R7780MP
+R7785RP SH_R7785RP
TITAN SH_TITAN
SHMIN SH_SHMIN
7710VOIPGW SH_7710VOIPGW
diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig
index be9e10b94ef..ad8d6b256a7 100644
--- a/arch/sparc64/Kconfig
+++ b/arch/sparc64/Kconfig
@@ -34,6 +34,10 @@ config MMU
bool
default y
+config QUICKLIST
+ bool
+ default y
+
config STACKTRACE_SUPPORT
bool
default y
diff --git a/arch/sparc64/mm/hugetlbpage.c b/arch/sparc64/mm/hugetlbpage.c
index 00677b5e1d7..e224a94e6a1 100644
--- a/arch/sparc64/mm/hugetlbpage.c
+++ b/arch/sparc64/mm/hugetlbpage.c
@@ -175,6 +175,12 @@ hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
if (len > task_size)
return -ENOMEM;
+ if (flags & MAP_FIXED) {
+ if (prepare_hugepage_range(addr, len, pgoff))
+ return -EINVAL;
+ return addr;
+ }
+
if (addr) {
addr = ALIGN(addr, HPAGE_SIZE);
vma = find_vma(mm, addr);
diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c
index 8c7af7e13ff..d7004eaf1c8 100644
--- a/arch/sparc64/mm/init.c
+++ b/arch/sparc64/mm/init.c
@@ -164,30 +164,6 @@ unsigned long sparc64_kern_sec_context __read_mostly;
int bigkernel = 0;
-struct kmem_cache *pgtable_cache __read_mostly;
-
-static void zero_ctor(void *addr, struct kmem_cache *cache, unsigned long flags)
-{
- clear_page(addr);
-}
-
-extern void tsb_cache_init(void);
-
-void __init pgtable_cache_init(void)
-{
- pgtable_cache = kmem_cache_create("pgtable_cache",
- PAGE_SIZE, PAGE_SIZE,
- SLAB_HWCACHE_ALIGN |
- SLAB_MUST_HWCACHE_ALIGN,
- zero_ctor,
- NULL);
- if (!pgtable_cache) {
- prom_printf("Could not create pgtable_cache\n");
- prom_halt();
- }
- tsb_cache_init();
-}
-
#ifdef CONFIG_DEBUG_DCFLUSH
atomic_t dcpage_flushes = ATOMIC_INIT(0);
#ifdef CONFIG_SMP
diff --git a/arch/sparc64/mm/tsb.c b/arch/sparc64/mm/tsb.c
index 236d02f41a0..8eb8a7c76ec 100644
--- a/arch/sparc64/mm/tsb.c
+++ b/arch/sparc64/mm/tsb.c
@@ -252,7 +252,7 @@ static const char *tsb_cache_names[8] = {
"tsb_1MB",
};
-void __init tsb_cache_init(void)
+void __init pgtable_cache_init(void)
{
unsigned long i;
@@ -262,8 +262,7 @@ void __init tsb_cache_init(void)
tsb_caches[i] = kmem_cache_create(name,
size, size,
- SLAB_HWCACHE_ALIGN |
- SLAB_MUST_HWCACHE_ALIGN,
+ 0,
NULL, NULL);
if (!tsb_caches[i]) {
prom_printf("Could not create %s cache\n", name);
diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c
index 9fdfad64953..3aa35161176 100644
--- a/arch/um/drivers/chan_kern.c
+++ b/arch/um/drivers/chan_kern.c
@@ -12,7 +12,6 @@
#include <linux/tty_flip.h>
#include <asm/irq.h>
#include "chan_kern.h"
-#include "user_util.h"
#include "kern.h"
#include "irq_user.h"
#include "sigio.h"
diff --git a/arch/um/drivers/chan_user.c b/arch/um/drivers/chan_user.c
index 0cad3546cb8..13f0bf852b2 100644
--- a/arch/um/drivers/chan_user.c
+++ b/arch/um/drivers/chan_user.c
@@ -14,7 +14,6 @@
#include <sys/ioctl.h>
#include <sys/socket.h>
#include "kern_util.h"
-#include "user_util.h"
#include "chan_user.h"
#include "user.h"
#include "os.h"
@@ -158,7 +157,7 @@ static int winch_tramp(int fd, struct tty_struct *tty, int *fd_out)
*/
err = run_helper_thread(winch_thread, &data, CLONE_FILES, &stack, 0);
if(err < 0){
- printk("fork of winch_thread failed - errno = %d\n", errno);
+ printk("fork of winch_thread failed - errno = %d\n", -err);
goto out_close;
}
@@ -204,14 +203,3 @@ void register_winch(int fd, struct tty_struct *tty)
}
}
}
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/drivers/cow_sys.h b/arch/um/drivers/cow_sys.h
index c6a308464ac..15453845d2b 100644
--- a/arch/um/drivers/cow_sys.h
+++ b/arch/um/drivers/cow_sys.h
@@ -2,14 +2,13 @@
#define __COW_SYS_H__
#include "kern_util.h"
-#include "user_util.h"
#include "os.h"
#include "user.h"
#include "um_malloc.h"
static inline void *cow_malloc(int size)
{
- return(um_kmalloc(size));
+ return um_kmalloc(size);
}
static inline void cow_free(void *ptr)
@@ -21,29 +20,22 @@ static inline void cow_free(void *ptr)
static inline char *cow_strdup(char *str)
{
- return(uml_strdup(str));
+ return uml_strdup(str);
}
static inline int cow_seek_file(int fd, __u64 offset)
{
- return(os_seek_file(fd, offset));
+ return os_seek_file(fd, offset);
}
static inline int cow_file_size(char *file, unsigned long long *size_out)
{
- return(os_file_size(file, size_out));
+ return os_file_size(file, size_out);
}
static inline int cow_write_file(int fd, void *buf, int size)
{
- return(os_write_file(fd, buf, size));
+ return os_write_file(fd, buf, size);
}
#endif
-
-/*
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/drivers/daemon_user.c b/arch/um/drivers/daemon_user.c
index 021b82c7a75..b869e389968 100644
--- a/arch/um/drivers/daemon_user.c
+++ b/arch/um/drivers/daemon_user.c
@@ -14,7 +14,6 @@
#include "net_user.h"
#include "daemon.h"
#include "kern_util.h"
-#include "user_util.h"
#include "user.h"
#include "os.h"
#include "um_malloc.h"
@@ -39,11 +38,11 @@ static struct sockaddr_un *new_addr(void *name, int len)
sun = um_kmalloc(sizeof(struct sockaddr_un));
if(sun == NULL){
printk("new_addr: allocation of sockaddr_un failed\n");
- return(NULL);
+ return NULL;
}
sun->sun_family = AF_UNIX;
memcpy(sun->sun_path, name, len);
- return(sun);
+ return sun;
}
static int connect_to_switch(struct daemon_data *pri)
@@ -112,7 +111,7 @@ static int connect_to_switch(struct daemon_data *pri)
}
pri->data_addr = sun;
- return(fd);
+ return fd;
out_free:
kfree(sun);
@@ -120,10 +119,10 @@ static int connect_to_switch(struct daemon_data *pri)
os_close_file(fd);
out:
os_close_file(pri->control);
- return(err);
+ return err;
}
-static void daemon_user_init(void *data, void *dev)
+static int daemon_user_init(void *data, void *dev)
{
struct daemon_data *pri = data;
struct timeval tv;
@@ -146,13 +145,16 @@ static void daemon_user_init(void *data, void *dev)
if(pri->fd < 0){
kfree(pri->local_addr);
pri->local_addr = NULL;
+ return pri->fd;
}
+
+ return 0;
}
static int daemon_open(void *data)
{
struct daemon_data *pri = data;
- return(pri->fd);
+ return pri->fd;
}
static void daemon_remove(void *data)
@@ -176,12 +178,12 @@ int daemon_user_write(int fd, void *buf, int len, struct daemon_data *pri)
{
struct sockaddr_un *data_addr = pri->data_addr;
- return(net_sendto(fd, buf, len, data_addr, sizeof(*data_addr)));
+ return net_sendto(fd, buf, len, data_addr, sizeof(*data_addr));
}
static int daemon_set_mtu(int mtu, void *data)
{
- return(mtu);
+ return mtu;
}
const struct net_user_info daemon_user_info = {
@@ -194,14 +196,3 @@ const struct net_user_info daemon_user_info = {
.delete_address = NULL,
.max_packet = MAX_PACKET - ETH_HEADER_OTHER
};
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/drivers/fd.c b/arch/um/drivers/fd.c
index 218aa0e9b79..7f083ec47a4 100644
--- a/arch/um/drivers/fd.c
+++ b/arch/um/drivers/fd.c
@@ -9,7 +9,6 @@
#include <termios.h>
#include <errno.h>
#include "user.h"
-#include "user_util.h"
#include "chan_user.h"
#include "os.h"
#include "um_malloc.h"
diff --git a/arch/um/drivers/harddog_user.c b/arch/um/drivers/harddog_user.c
index c495ecf263b..5eeecf8917c 100644
--- a/arch/um/drivers/harddog_user.c
+++ b/arch/um/drivers/harddog_user.c
@@ -6,7 +6,6 @@
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
-#include "user_util.h"
#include "user.h"
#include "mconsole.h"
#include "os.h"
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c
index f75d7b05c48..ced99106f79 100644
--- a/arch/um/drivers/line.c
+++ b/arch/um/drivers/line.c
@@ -13,7 +13,6 @@
#include "irq_user.h"
#include "line.h"
#include "kern.h"
-#include "user_util.h"
#include "kern_util.h"
#include "os.h"
#include "irq_kern.h"
diff --git a/arch/um/drivers/mcast_user.c b/arch/um/drivers/mcast_user.c
index b827e82884c..d319db16d4e 100644
--- a/arch/um/drivers/mcast_user.c
+++ b/arch/um/drivers/mcast_user.c
@@ -20,7 +20,6 @@
#include "net_user.h"
#include "mcast.h"
#include "kern_util.h"
-#include "user_util.h"
#include "user.h"
#include "os.h"
#include "um_malloc.h"
@@ -34,20 +33,21 @@ static struct sockaddr_in *new_addr(char *addr, unsigned short port)
sin = um_kmalloc(sizeof(struct sockaddr_in));
if(sin == NULL){
printk("new_addr: allocation of sockaddr_in failed\n");
- return(NULL);
+ return NULL;
}
sin->sin_family = AF_INET;
sin->sin_addr.s_addr = in_aton(addr);
sin->sin_port = htons(port);
- return(sin);
+ return sin;
}
-static void mcast_user_init(void *data, void *dev)
+static int mcast_user_init(void *data, void *dev)
{
struct mcast_data *pri = data;
pri->mcast_addr = new_addr(pri->addr, pri->port);
pri->dev = dev;
+ return 0;
}
static void mcast_remove(void *data)
@@ -107,8 +107,8 @@ static int mcast_open(void *data)
err = -errno;
printk("mcast_open : data bind failed, errno = %d\n", errno);
goto out_close;
- }
-
+ }
+
/* subscribe to the multicast group */
mreq.imr_multiaddr.s_addr = sin->sin_addr.s_addr;
mreq.imr_interface.s_addr = 0;
@@ -153,12 +153,12 @@ int mcast_user_write(int fd, void *buf, int len, struct mcast_data *pri)
{
struct sockaddr_in *data_addr = pri->mcast_addr;
- return(net_sendto(fd, buf, len, data_addr, sizeof(*data_addr)));
+ return net_sendto(fd, buf, len, data_addr, sizeof(*data_addr));
}
static int mcast_set_mtu(int mtu, void *data)
{
- return(mtu);
+ return mtu;
}
const struct net_user_info mcast_user_info = {
diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c
index 65ad2932672..542c9ef858f 100644
--- a/arch/um/drivers/mconsole_kern.c
+++ b/arch/um/drivers/mconsole_kern.c
@@ -25,7 +25,6 @@
#include "linux/console.h"
#include "asm/irq.h"
#include "asm/uaccess.h"
-#include "user_util.h"
#include "kern_util.h"
#include "kern.h"
#include "mconsole.h"
diff --git a/arch/um/drivers/mconsole_user.c b/arch/um/drivers/mconsole_user.c
index f02634fbf32..62e5ad63181 100644
--- a/arch/um/drivers/mconsole_user.c
+++ b/arch/um/drivers/mconsole_user.c
@@ -17,7 +17,6 @@
#include "sysdep/ptrace.h"
#include "mconsole.h"
#include "os.h"
-#include "user_util.h"
static struct mconsole_command commands[] = {
/* With uts namespaces, uts information becomes process-specific, so
diff --git a/arch/um/drivers/mmapper_kern.c b/arch/um/drivers/mmapper_kern.c
index df3516e47d4..e41a08f0469 100644
--- a/arch/um/drivers/mmapper_kern.c
+++ b/arch/um/drivers/mmapper_kern.c
@@ -15,7 +15,6 @@
#include <linux/miscdevice.h>
#include <asm/uaccess.h>
#include "mem_user.h"
-#include "user_util.h"
/* These are set in mmapper_init, which is called at boot time */
static unsigned long mmapper_size;
diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c
index 859303730b2..baac4ad5e68 100644
--- a/arch/um/drivers/net_kern.c
+++ b/arch/um/drivers/net_kern.c
@@ -21,7 +21,6 @@
#include "linux/ethtool.h"
#include "linux/platform_device.h"
#include "asm/uaccess.h"
-#include "user_util.h"
#include "kern_util.h"
#include "net_kern.h"
#include "net_user.h"
@@ -284,7 +283,7 @@ void uml_net_user_timer_expire(unsigned long _conn)
#endif
}
-static void setup_etheraddr(char *str, unsigned char *addr)
+static void setup_etheraddr(char *str, unsigned char *addr, char *name)
{
char *end;
int i;
@@ -303,15 +302,32 @@ static void setup_etheraddr(char *str, unsigned char *addr)
}
str = end + 1;
}
- if(addr[0] & 1){
+ if (is_multicast_ether_addr(addr)) {
printk(KERN_ERR
- "Attempt to assign a broadcast ethernet address to a "
+ "Attempt to assign a multicast ethernet address to a "
"device disallowed\n");
goto random;
}
+ if (!is_valid_ether_addr(addr)) {
+ printk(KERN_ERR
+ "Attempt to assign an invalid ethernet address to a "
+ "device disallowed\n");
+ goto random;
+ }
+ if (!is_local_ether_addr(addr)) {
+ printk(KERN_WARNING
+ "Warning: attempt to assign a globally valid ethernet address to a "
+ "device\n");
+ printk(KERN_WARNING "You should better enable the 2nd rightmost bit "
+ "in the first byte of the MAC, i.e. "
+ "%02x:%02x:%02x:%02x:%02x:%02x\n",
+ addr[0] | 0x02, addr[1], addr[2], addr[3], addr[4], addr[5]);
+ }
return;
random:
+ printk(KERN_INFO
+ "Choosing a random ethernet address for device %s\n", name);
random_ether_addr(addr);
}
@@ -325,31 +341,53 @@ static struct platform_driver uml_net_driver = {
};
static int driver_registered;
-static int eth_configure(int n, void *init, char *mac,
- struct transport *transport)
+static void net_device_release(struct device *dev)
+{
+ struct uml_net *device = dev->driver_data;
+ struct net_device *netdev = device->dev;
+ struct uml_net_private *lp = netdev->priv;
+
+ if(lp->remove != NULL)
+ (*lp->remove)(&lp->user);
+ list_del(&device->list);
+ kfree(device);
+ free_netdev(netdev);
+}
+
+static void eth_configure(int n, void *init, char *mac,
+ struct transport *transport)
{
struct uml_net *device;
struct net_device *dev;
struct uml_net_private *lp;
- int save, err, size;
+ int err, size;
- size = transport->private_size + sizeof(struct uml_net_private) +
- sizeof(((struct uml_net_private *) 0)->user);
+ size = transport->private_size + sizeof(struct uml_net_private);
device = kzalloc(sizeof(*device), GFP_KERNEL);
if (device == NULL) {
- printk(KERN_ERR "eth_configure failed to allocate uml_net\n");
- return(1);
+ printk(KERN_ERR "eth_configure failed to allocate struct "
+ "uml_net\n");
+ return;
+ }
+
+ dev = alloc_etherdev(size);
+ if (dev == NULL) {
+ printk(KERN_ERR "eth_configure: failed to allocate struct "
+ "net_device for eth%d\n", n);
+ goto out_free_device;
}
INIT_LIST_HEAD(&device->list);
device->index = n;
- spin_lock(&devices_lock);
- list_add(&device->list, &devices);
- spin_unlock(&devices_lock);
+ /* If this name ends up conflicting with an existing registered
+ * netdevice, that is OK, register_netdev{,ice}() will notice this
+ * and fail.
+ */
+ snprintf(dev->name, sizeof(dev->name), "eth%d", n);
- setup_etheraddr(mac, device->mac);
+ setup_etheraddr(mac, device->mac, dev->name);
printk(KERN_INFO "Netdevice %d ", n);
printk("(%02x:%02x:%02x:%02x:%02x:%02x) ",
@@ -357,11 +395,6 @@ static int eth_configure(int n, void *init, char *mac,
device->mac[2], device->mac[3],
device->mac[4], device->mac[5]);
printk(": ");
- dev = alloc_etherdev(size);
- if (dev == NULL) {
- printk(KERN_ERR "eth_configure: failed to allocate device\n");
- return 1;
- }
lp = dev->priv;
/* This points to the transport private data. It's still clear, but we
@@ -376,47 +409,20 @@ static int eth_configure(int n, void *init, char *mac,
}
device->pdev.id = n;
device->pdev.name = DRIVER_NAME;
- platform_device_register(&device->pdev);
+ device->pdev.dev.release = net_device_release;
+ device->pdev.dev.driver_data = device;
+ if(platform_device_register(&device->pdev))
+ goto out_free_netdev;
SET_NETDEV_DEV(dev,&device->pdev.dev);
- /* If this name ends up conflicting with an existing registered
- * netdevice, that is OK, register_netdev{,ice}() will notice this
- * and fail.
- */
- snprintf(dev->name, sizeof(dev->name), "eth%d", n);
device->dev = dev;
+ /*
+ * These just fill in a data structure, so there's no failure
+ * to be worried about.
+ */
(*transport->kern->init)(dev, init);
- dev->mtu = transport->user->max_packet;
- dev->open = uml_net_open;
- dev->hard_start_xmit = uml_net_start_xmit;
- dev->stop = uml_net_close;
- dev->get_stats = uml_net_get_stats;
- dev->set_multicast_list = uml_net_set_multicast_list;
- dev->tx_timeout = uml_net_tx_timeout;
- dev->set_mac_address = uml_net_set_mac;
- dev->change_mtu = uml_net_change_mtu;
- dev->ethtool_ops = &uml_net_ethtool_ops;
- dev->watchdog_timeo = (HZ >> 1);
- dev->irq = UM_ETH_IRQ;
-
- rtnl_lock();
- err = register_netdevice(dev);
- rtnl_unlock();
- if (err) {
- device->dev = NULL;
- /* XXX: should we call ->remove() here? */
- free_netdev(dev);
- return 1;
- }
-
- /* lp.user is the first four bytes of the transport data, which
- * has already been initialized. This structure assignment will
- * overwrite that, so we make sure that .user gets overwritten with
- * what it already has.
- */
- save = lp->user[0];
*lp = ((struct uml_net_private)
{ .list = LIST_HEAD_INIT(lp->list),
.dev = dev,
@@ -430,20 +436,52 @@ static int eth_configure(int n, void *init, char *mac,
.write = transport->kern->write,
.add_address = transport->user->add_address,
.delete_address = transport->user->delete_address,
- .set_mtu = transport->user->set_mtu,
- .user = { save } });
+ .set_mtu = transport->user->set_mtu });
init_timer(&lp->tl);
spin_lock_init(&lp->lock);
lp->tl.function = uml_net_user_timer_expire;
memcpy(lp->mac, device->mac, sizeof(lp->mac));
- if (transport->user->init)
- (*transport->user->init)(&lp->user, dev);
+ if ((transport->user->init != NULL) &&
+ ((*transport->user->init)(&lp->user, dev) != 0))
+ goto out_unregister;
set_ether_mac(dev, device->mac);
+ dev->mtu = transport->user->max_packet;
+ dev->open = uml_net_open;
+ dev->hard_start_xmit = uml_net_start_xmit;
+ dev->stop = uml_net_close;
+ dev->get_stats = uml_net_get_stats;
+ dev->set_multicast_list = uml_net_set_multicast_list;
+ dev->tx_timeout = uml_net_tx_timeout;
+ dev->set_mac_address = uml_net_set_mac;
+ dev->change_mtu = uml_net_change_mtu;
+ dev->ethtool_ops = &uml_net_ethtool_ops;
+ dev->watchdog_timeo = (HZ >> 1);
+ dev->irq = UM_ETH_IRQ;
- return 0;
+ rtnl_lock();
+ err = register_netdevice(dev);
+ rtnl_unlock();
+ if (err)
+ goto out_undo_user_init;
+
+ spin_lock(&devices_lock);
+ list_add(&device->list, &devices);
+ spin_unlock(&devices_lock);
+
+ return;
+
+out_undo_user_init:
+ if (transport->user->remove != NULL)
+ (*transport->user->remove)(&lp->user);
+out_unregister:
+ platform_device_unregister(&device->pdev);
+out_free_netdev:
+ free_netdev(dev);
+out_free_device:
+ kfree(device);
}
static struct uml_net *find_device(int n)
@@ -666,13 +704,9 @@ static int net_remove(int n, char **error_out)
lp = dev->priv;
if(lp->fd > 0)
return -EBUSY;
- if(lp->remove != NULL) (*lp->remove)(&lp->user);
unregister_netdev(dev);
platform_device_unregister(&device->pdev);
- list_del(&device->list);
- kfree(device);
- free_netdev(dev);
return 0;
}
diff --git a/arch/um/drivers/net_user.c b/arch/um/drivers/net_user.c
index 0ffd7ac295d..3503cff867c 100644
--- a/arch/um/drivers/net_user.c
+++ b/arch/um/drivers/net_user.c
@@ -14,11 +14,11 @@
#include <sys/wait.h>
#include <sys/time.h>
#include "user.h"
-#include "user_util.h"
#include "kern_util.h"
#include "net_user.h"
#include "os.h"
#include "um_malloc.h"
+#include "kern_constants.h"
int tap_open_common(void *dev, char *gate_addr)
{
@@ -216,7 +216,7 @@ static void change(char *dev, char *what, unsigned char *addr,
sprintf(netmask_buf, "%d.%d.%d.%d", netmask[0], netmask[1],
netmask[2], netmask[3]);
- output_len = page_size();
+ output_len = UM_KERN_PAGE_SIZE;
output = um_kmalloc(output_len);
if(output == NULL)
printk("change : failed to allocate output buffer\n");
diff --git a/arch/um/drivers/pcap_user.c b/arch/um/drivers/pcap_user.c
index 11921a7baa7..dc0a903ef9a 100644
--- a/arch/um/drivers/pcap_user.c
+++ b/arch/um/drivers/pcap_user.c
@@ -18,7 +18,7 @@
#define PCAP_FD(p) (*(int *)(p))
-static void pcap_user_init(void *data, void *dev)
+static int pcap_user_init(void *data, void *dev)
{
struct pcap_data *pri = data;
pcap_t *p;
@@ -28,11 +28,12 @@ static void pcap_user_init(void *data, void *dev)
if(p == NULL){
printk("pcap_user_init : pcap_open_live failed - '%s'\n",
errors);
- return;
+ return -EINVAL;
}
pri->dev = dev;
pri->pcap = p;
+ return 0;
}
static int pcap_open(void *data)
@@ -42,39 +43,39 @@ static int pcap_open(void *data)
int err;
if(pri->pcap == NULL)
- return(-ENODEV);
+ return -ENODEV;
if(pri->filter != NULL){
err = dev_netmask(pri->dev, &netmask);
if(err < 0){
printk("pcap_open : dev_netmask failed\n");
- return(-EIO);
+ return -EIO;
}
pri->compiled = um_kmalloc(sizeof(struct bpf_program));
if(pri->compiled == NULL){
printk("pcap_open : kmalloc failed\n");
- return(-ENOMEM);
+ return -ENOMEM;
}
-
+
err = pcap_compile(pri->pcap,
(struct bpf_program *) pri->compiled,
pri->filter, pri->optimize, netmask);
if(err < 0){
printk("pcap_open : pcap_compile failed - '%s'\n",
pcap_geterr(pri->pcap));
- return(-EIO);
+ return -EIO;
}
err = pcap_setfilter(pri->pcap, pri->compiled);
if(err < 0){
printk("pcap_open : pcap_setfilter failed - '%s'\n",
pcap_geterr(pri->pcap));
- return(-EIO);
+ return -EIO;
}
}
-
- return(PCAP_FD(pri->pcap));
+
+ return PCAP_FD(pri->pcap);
}
static void pcap_remove(void *data)
@@ -114,11 +115,11 @@ int pcap_user_read(int fd, void *buffer, int len, struct pcap_data *pri)
n = pcap_dispatch(pri->pcap, 1, handler, (u_char *) &hdata);
if(n < 0){
printk("pcap_dispatch failed - %s\n", pcap_geterr(pri->pcap));
- return(-EIO);
+ return -EIO;
}
else if(n == 0)
- return(0);
- return(hdata.len);
+ return 0;
+ return hdata.len;
}
const struct net_user_info pcap_user_info = {
@@ -131,14 +132,3 @@ const struct net_user_info pcap_user_info = {
.delete_address = NULL,
.max_packet = MAX_PACKET - ETH_HEADER_OTHER
};
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/drivers/port_user.c b/arch/um/drivers/port_user.c
index 80508023054..3f6357d24be 100644
--- a/arch/um/drivers/port_user.c
+++ b/arch/um/drivers/port_user.c
@@ -13,7 +13,6 @@
#include <sys/socket.h>
#include <sys/un.h>
#include <netinet/in.h>
-#include "user_util.h"
#include "kern_util.h"
#include "user.h"
#include "chan_user.h"
diff --git a/arch/um/drivers/pty.c b/arch/um/drivers/pty.c
index 829a5eca8c0..df4976c9eef 100644
--- a/arch/um/drivers/pty.c
+++ b/arch/um/drivers/pty.c
@@ -4,13 +4,13 @@
*/
#include <stdio.h>
+#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <termios.h>
#include "chan_user.h"
#include "user.h"
-#include "user_util.h"
#include "kern_util.h"
#include "os.h"
#include "um_malloc.h"
diff --git a/arch/um/drivers/slip_user.c b/arch/um/drivers/slip_user.c
index 7eddacc53b6..78f0e515da8 100644
--- a/arch/um/drivers/slip_user.c
+++ b/arch/um/drivers/slip_user.c
@@ -8,7 +8,6 @@
#include <sys/termios.h>
#include <sys/wait.h>
#include <sys/signal.h>
-#include "user_util.h"
#include "kern_util.h"
#include "user.h"
#include "net_user.h"
@@ -16,12 +15,14 @@
#include "slip_common.h"
#include "os.h"
#include "um_malloc.h"
+#include "kern_constants.h"
-void slip_user_init(void *data, void *dev)
+static int slip_user_init(void *data, void *dev)
{
struct slip_data *pri = data;
pri->dev = dev;
+ return 0;
}
static int set_up_tty(int fd)
@@ -89,7 +90,7 @@ static int slip_tramp(char **argv, int fd)
goto out_close;
pid = err;
- output_len = page_size();
+ output_len = UM_KERN_PAGE_SIZE;
output = um_kmalloc(output_len);
if(output == NULL){
printk("slip_tramp : failed to allocate output buffer\n");
diff --git a/arch/um/drivers/slirp_user.c b/arch/um/drivers/slirp_user.c
index ce5e85d1de3..39f889fe994 100644
--- a/arch/um/drivers/slirp_user.c
+++ b/arch/um/drivers/slirp_user.c
@@ -7,7 +7,6 @@
#include <errno.h>
#include <sys/wait.h>
#include <sys/signal.h>
-#include "user_util.h"
#include "kern_util.h"
#include "user.h"
#include "net_user.h"
@@ -15,11 +14,12 @@
#include "slip_common.h"
#include "os.h"
-void slirp_user_init(void *data, void *dev)
+static int slirp_user_init(void *data, void *dev)
{
struct slirp_data *pri = data;
pri->dev = dev;
+ return 0;
}
struct slirp_pre_exec_data {
diff --git a/arch/um/drivers/ssl.c b/arch/um/drivers/ssl.c
index 4b382a6e710..fd09ad9e9c0 100644
--- a/arch/um/drivers/ssl.c
+++ b/arch/um/drivers/ssl.c
@@ -15,7 +15,6 @@
#include "line.h"
#include "ssl.h"
#include "chan_kern.h"
-#include "user_util.h"
#include "kern_util.h"
#include "kern.h"
#include "init.h"
@@ -192,12 +191,12 @@ static int ssl_init(void)
ssl_driver = register_lines(&driver, &ssl_ops, serial_lines,
ARRAY_SIZE(serial_lines));
- lines_init(serial_lines, ARRAY_SIZE(serial_lines), &opts);
-
new_title = add_xterm_umid(opts.xterm_title);
if (new_title != NULL)
opts.xterm_title = new_title;
+ lines_init(serial_lines, ARRAY_SIZE(serial_lines), &opts);
+
ssl_init_done = 1;
register_console(&ssl_cons);
return 0;
diff --git a/arch/um/drivers/stdio_console.c b/arch/um/drivers/stdio_console.c
index 76d1f1c980e..2bb4193ac1a 100644
--- a/arch/um/drivers/stdio_console.c
+++ b/arch/um/drivers/stdio_console.c
@@ -22,7 +22,6 @@
#include "stdio_console.h"
#include "line.h"
#include "chan_kern.h"
-#include "user_util.h"
#include "kern_util.h"
#include "irq_user.h"
#include "mconsole_kern.h"
@@ -167,12 +166,12 @@ int stdio_init(void)
return -1;
printk(KERN_INFO "Initialized stdio console driver\n");
- lines_init(vts, ARRAY_SIZE(vts), &opts);
-
new_title = add_xterm_umid(opts.xterm_title);
if(new_title != NULL)
opts.xterm_title = new_title;
+ lines_init(vts, ARRAY_SIZE(vts), &opts);
+
con_init_done = 1;
register_console(&stdiocons);
return 0;
diff --git a/arch/um/drivers/tty.c b/arch/um/drivers/tty.c
index d95d64309ea..c07d0d56278 100644
--- a/arch/um/drivers/tty.c
+++ b/arch/um/drivers/tty.c
@@ -8,7 +8,6 @@
#include <errno.h>
#include <unistd.h>
#include "chan_user.h"
-#include "user_util.h"
#include "user.h"
#include "os.h"
#include "um_malloc.h"
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index 8bd9204ac1a..70509ddaac0 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -39,7 +39,6 @@
#include "asm/irq.h"
#include "asm/types.h"
#include "asm/tlbflush.h"
-#include "user_util.h"
#include "mem_user.h"
#include "kern_util.h"
#include "kern.h"
@@ -90,7 +89,7 @@ static inline int ubd_test_bit(__u64 bit, unsigned char *data)
bits = sizeof(data[0]) * 8;
n = bit / bits;
off = bit % bits;
- return((data[n] & (1 << off)) != 0);
+ return (data[n] & (1 << off)) != 0;
}
static inline void ubd_set_bit(__u64 bit, unsigned char *data)
@@ -147,10 +146,13 @@ struct cow {
unsigned long *bitmap;
unsigned long bitmap_len;
int bitmap_offset;
- int data_offset;
+ int data_offset;
};
+#define MAX_SG 64
+
struct ubd {
+ struct list_head restart;
/* name (and fd, below) of the file opened for writing, either the
* backing or the cow file. */
char *file;
@@ -165,15 +167,17 @@ struct ubd {
struct platform_device pdev;
struct request_queue *queue;
spinlock_t lock;
- int active;
+ struct scatterlist sg[MAX_SG];
+ struct request *request;
+ int start_sg, end_sg;
};
#define DEFAULT_COW { \
.file = NULL, \
- .fd = -1, \
- .bitmap = NULL, \
+ .fd = -1, \
+ .bitmap = NULL, \
.bitmap_offset = 0, \
- .data_offset = 0, \
+ .data_offset = 0, \
}
#define DEFAULT_UBD { \
@@ -183,11 +187,13 @@ struct ubd {
.size = -1, \
.boot_openflags = OPEN_FLAGS, \
.openflags = OPEN_FLAGS, \
- .no_cow = 0, \
+ .no_cow = 0, \
.shared = 0, \
- .cow = DEFAULT_COW, \
+ .cow = DEFAULT_COW, \
.lock = SPIN_LOCK_UNLOCKED, \
- .active = 0, \
+ .request = NULL, \
+ .start_sg = 0, \
+ .end_sg = 0, \
}
/* Protected by ubd_lock */
@@ -243,7 +249,7 @@ static void make_ide_entries(char *dev_name)
static int fake_ide_setup(char *str)
{
fake_ide = 1;
- return(1);
+ return 1;
}
__setup("fake_ide", fake_ide_setup);
@@ -261,7 +267,7 @@ static int parse_unit(char **ptr)
if(isdigit(*str)) {
n = simple_strtoul(str, &end, 0);
if(end == str)
- return(-1);
+ return -1;
*ptr = end;
}
else if (('a' <= *str) && (*str <= 'z')) {
@@ -269,7 +275,7 @@ static int parse_unit(char **ptr)
str++;
*ptr = str;
}
- return(n);
+ return n;
}
/* If *index_out == -1 at exit, the passed option was a general one;
@@ -436,7 +442,7 @@ static int udb_setup(char *str)
{
printk("udb%s specified on command line is almost certainly a ubd -> "
"udb TYPO\n", str);
- return(1);
+ return 1;
}
__setup("udb", udb_setup);
@@ -467,66 +473,75 @@ static void do_ubd_request(request_queue_t * q);
/* Only changed by ubd_init, which is an initcall. */
int thread_fd = -1;
-/* call ubd_finish if you need to serialize */
-static void __ubd_finish(struct request *req, int error)
+static void ubd_end_request(struct request *req, int bytes, int uptodate)
{
- int nsect;
-
- if(error){
- end_request(req, 0);
- return;
+ if (!end_that_request_first(req, uptodate, bytes >> 9)) {
+ struct ubd *dev = req->rq_disk->private_data;
+ unsigned long flags;
+
+ add_disk_randomness(req->rq_disk);
+ spin_lock_irqsave(&dev->lock, flags);
+ end_that_request_last(req, uptodate);
+ spin_unlock_irqrestore(&dev->lock, flags);
}
- nsect = req->current_nr_sectors;
- req->sector += nsect;
- req->buffer += nsect << 9;
- req->errors = 0;
- req->nr_sectors -= nsect;
- req->current_nr_sectors = 0;
- end_request(req, 1);
}
/* Callable only from interrupt context - otherwise you need to do
* spin_lock_irq()/spin_lock_irqsave() */
-static inline void ubd_finish(struct request *req, int error)
+static inline void ubd_finish(struct request *req, int bytes)
{
- struct ubd *dev = req->rq_disk->private_data;
-
- spin_lock(&dev->lock);
- __ubd_finish(req, error);
- spin_unlock(&dev->lock);
+ if(bytes < 0){
+ ubd_end_request(req, 0, 0);
+ return;
+ }
+ ubd_end_request(req, bytes, 1);
}
+static LIST_HEAD(restart);
+
/* XXX - move this inside ubd_intr. */
/* Called without dev->lock held, and only in interrupt context. */
static void ubd_handler(void)
{
- struct io_thread_req req;
+ struct io_thread_req *req;
struct request *rq;
- struct ubd *dev;
+ struct ubd *ubd;
+ struct list_head *list, *next_ele;
+ unsigned long flags;
int n;
- n = os_read_file(thread_fd, &req, sizeof(req));
- if(n != sizeof(req)){
- printk(KERN_ERR "Pid %d - spurious interrupt in ubd_handler, "
- "err = %d\n", os_getpid(), -n);
- return;
- }
-
- rq = req.req;
- dev = rq->rq_disk->private_data;
- dev->active = 0;
+ while(1){
+ n = os_read_file(thread_fd, &req,
+ sizeof(struct io_thread_req *));
+ if(n != sizeof(req)){
+ if(n == -EAGAIN)
+ break;
+ printk(KERN_ERR "spurious interrupt in ubd_handler, "
+ "err = %d\n", -n);
+ return;
+ }
- ubd_finish(rq, req.error);
+ rq = req->req;
+ rq->nr_sectors -= req->length >> 9;
+ if(rq->nr_sectors == 0)
+ ubd_finish(rq, rq->hard_nr_sectors << 9);
+ kfree(req);
+ }
reactivate_fd(thread_fd, UBD_IRQ);
- spin_lock(&dev->lock);
- do_ubd_request(dev->queue);
- spin_unlock(&dev->lock);
+
+ list_for_each_safe(list, next_ele, &restart){
+ ubd = container_of(list, struct ubd, restart);
+ list_del_init(&ubd->restart);
+ spin_lock_irqsave(&ubd->lock, flags);
+ do_ubd_request(ubd->queue);
+ spin_unlock_irqrestore(&ubd->lock, flags);
+ }
}
static irqreturn_t ubd_intr(int irq, void *dev)
{
ubd_handler();
- return(IRQ_HANDLED);
+ return IRQ_HANDLED;
}
/* Only changed by ubd_init, which is an initcall. */
@@ -545,7 +560,7 @@ static inline int ubd_file_size(struct ubd *ubd_dev, __u64 *size_out)
char *file;
file = ubd_dev->cow.file ? ubd_dev->cow.file : ubd_dev->file;
- return(os_file_size(file, size_out));
+ return os_file_size(file, size_out);
}
static void ubd_close_dev(struct ubd *ubd_dev)
@@ -617,10 +632,18 @@ static int ubd_open_dev(struct ubd *ubd_dev)
if(err < 0) goto error;
ubd_dev->cow.fd = err;
}
- return(0);
+ return 0;
error:
os_close_file(ubd_dev->fd);
- return(err);
+ return err;
+}
+
+static void ubd_device_release(struct device *dev)
+{
+ struct ubd *ubd_dev = dev->driver_data;
+
+ blk_cleanup_queue(ubd_dev->queue);
+ *ubd_dev = ((struct ubd) DEFAULT_UBD);
}
static int ubd_disk_register(int major, u64 size, int unit,
@@ -630,7 +653,7 @@ static int ubd_disk_register(int major, u64 size, int unit,
disk = alloc_disk(1 << UBD_SHIFT);
if(disk == NULL)
- return(-ENOMEM);
+ return -ENOMEM;
disk->major = major;
disk->first_minor = unit << UBD_SHIFT;
@@ -645,6 +668,8 @@ static int ubd_disk_register(int major, u64 size, int unit,
if (major == MAJOR_NR) {
ubd_devs[unit].pdev.id = unit;
ubd_devs[unit].pdev.name = DRIVER_NAME;
+ ubd_devs[unit].pdev.dev.release = ubd_device_release;
+ ubd_devs[unit].pdev.dev.driver_data = &ubd_devs[unit];
platform_device_register(&ubd_devs[unit].pdev);
disk->driverfs_dev = &ubd_devs[unit].pdev.dev;
}
@@ -675,6 +700,8 @@ static int ubd_add(int n, char **error_out)
ubd_dev->size = ROUND_BLOCK(ubd_dev->size);
+ INIT_LIST_HEAD(&ubd_dev->restart);
+
err = -ENOMEM;
ubd_dev->queue = blk_init_queue(do_ubd_request, &ubd_dev->lock);
if (ubd_dev->queue == NULL) {
@@ -683,6 +710,7 @@ static int ubd_add(int n, char **error_out)
}
ubd_dev->queue->queuedata = ubd_dev;
+ blk_queue_max_hw_segments(ubd_dev->queue, MAX_SG);
err = ubd_disk_register(MAJOR_NR, ubd_dev->size, n, &ubd_gendisk[n]);
if(err){
*error_out = "Failed to register device";
@@ -730,14 +758,14 @@ static int ubd_config(char *str, char **error_out)
goto err_free;
}
- mutex_lock(&ubd_lock);
+ mutex_lock(&ubd_lock);
ret = ubd_add(n, error_out);
if (ret)
ubd_devs[n].file = NULL;
- mutex_unlock(&ubd_lock);
+ mutex_unlock(&ubd_lock);
out:
- return ret;
+ return ret;
err_free:
kfree(str);
@@ -752,7 +780,7 @@ static int ubd_get_config(char *name, char *str, int size, char **error_out)
n = parse_unit(&name);
if((n >= MAX_DEV) || (n < 0)){
*error_out = "ubd_get_config : device number out of range";
- return(-1);
+ return -1;
}
ubd_dev = &ubd_devs[n];
@@ -773,29 +801,27 @@ static int ubd_get_config(char *name, char *str, int size, char **error_out)
out:
mutex_unlock(&ubd_lock);
- return(len);
+ return len;
}
static int ubd_id(char **str, int *start_out, int *end_out)
{
- int n;
+ int n;
n = parse_unit(str);
- *start_out = 0;
- *end_out = MAX_DEV - 1;
- return n;
+ *start_out = 0;
+ *end_out = MAX_DEV - 1;
+ return n;
}
static int ubd_remove(int n, char **error_out)
{
+ struct gendisk *disk = ubd_gendisk[n];
struct ubd *ubd_dev;
int err = -ENODEV;
mutex_lock(&ubd_lock);
- if(ubd_gendisk[n] == NULL)
- goto out;
-
ubd_dev = &ubd_devs[n];
if(ubd_dev->file == NULL)
@@ -806,9 +832,11 @@ static int ubd_remove(int n, char **error_out)
if(ubd_dev->count > 0)
goto out;
- del_gendisk(ubd_gendisk[n]);
- put_disk(ubd_gendisk[n]);
ubd_gendisk[n] = NULL;
+ if(disk != NULL){
+ del_gendisk(disk);
+ put_disk(disk);
+ }
if(fake_gendisk[n] != NULL){
del_gendisk(fake_gendisk[n]);
@@ -816,10 +844,8 @@ static int ubd_remove(int n, char **error_out)
fake_gendisk[n] = NULL;
}
- blk_cleanup_queue(ubd_dev->queue);
- platform_device_unregister(&ubd_dev->pdev);
- *ubd_dev = ((struct ubd) DEFAULT_UBD);
err = 0;
+ platform_device_unregister(&ubd_dev->pdev);
out:
mutex_unlock(&ubd_lock);
return err;
@@ -832,7 +858,7 @@ static struct mc_device ubd_mc = {
.list = LIST_HEAD_INIT(ubd_mc.list),
.name = "ubd",
.config = ubd_config,
- .get_config = ubd_get_config,
+ .get_config = ubd_get_config,
.id = ubd_id,
.remove = ubd_remove,
};
@@ -854,7 +880,7 @@ static int __init ubd0_init(void)
ubd_dev->file = "root_fs";
mutex_unlock(&ubd_lock);
- return(0);
+ return 0;
}
__initcall(ubd0_init);
@@ -882,14 +908,14 @@ static int __init ubd_init(void)
return -1;
}
platform_driver_register(&ubd_driver);
- mutex_lock(&ubd_lock);
+ mutex_lock(&ubd_lock);
for (i = 0; i < MAX_DEV; i++){
err = ubd_add(i, &error);
if(err)
printk(KERN_ERR "Failed to initialize ubd device %d :"
"%s\n", i, error);
}
- mutex_unlock(&ubd_lock);
+ mutex_unlock(&ubd_lock);
return 0;
}
@@ -913,7 +939,7 @@ static int __init ubd_driver_init(void){
"ubd : Failed to start I/O thread (errno = %d) - "
"falling back to synchronous I/O\n", -io_pid);
io_pid = -1;
- return(0);
+ return 0;
}
err = um_request_irq(UBD_IRQ, thread_fd, IRQ_READ, ubd_intr,
IRQF_DISABLED, "ubd", ubd_devs);
@@ -948,7 +974,7 @@ static int ubd_open(struct inode *inode, struct file *filp)
err = -EROFS;
}*/
out:
- return(err);
+ return err;
}
static int ubd_release(struct inode * inode, struct file * file)
@@ -958,7 +984,7 @@ static int ubd_release(struct inode * inode, struct file * file)
if(--ubd_dev->count == 0)
ubd_close_dev(ubd_dev);
- return(0);
+ return 0;
}
static void cowify_bitmap(__u64 io_offset, int length, unsigned long *cow_mask,
@@ -1014,7 +1040,7 @@ static void cowify_req(struct io_thread_req *req, unsigned long *bitmap,
if(ubd_test_bit(sector + i, (unsigned char *) bitmap))
ubd_set_bit(i, (unsigned char *)
&req->sector_mask);
- }
+ }
}
else cowify_bitmap(req->offset, req->length, &req->sector_mask,
&req->cow_offset, bitmap, bitmap_offset,
@@ -1022,26 +1048,16 @@ static void cowify_req(struct io_thread_req *req, unsigned long *bitmap,
}
/* Called with dev->lock held */
-static int prepare_request(struct request *req, struct io_thread_req *io_req)
+static void prepare_request(struct request *req, struct io_thread_req *io_req,
+ unsigned long long offset, int page_offset,
+ int len, struct page *page)
{
struct gendisk *disk = req->rq_disk;
struct ubd *ubd_dev = disk->private_data;
- __u64 offset;
- int len;
-
- /* This should be impossible now */
- if((rq_data_dir(req) == WRITE) && !ubd_dev->openflags.w){
- printk("Write attempted on readonly ubd device %s\n",
- disk->disk_name);
- end_request(req, 0);
- return(1);
- }
-
- offset = ((__u64) req->sector) << 9;
- len = req->current_nr_sectors << 9;
io_req->req = req;
- io_req->fds[0] = (ubd_dev->cow.file != NULL) ? ubd_dev->cow.fd : ubd_dev->fd;
+ io_req->fds[0] = (ubd_dev->cow.file != NULL) ? ubd_dev->cow.fd :
+ ubd_dev->fd;
io_req->fds[1] = ubd_dev->fd;
io_req->cow_offset = -1;
io_req->offset = offset;
@@ -1052,45 +1068,66 @@ static int prepare_request(struct request *req, struct io_thread_req *io_req)
io_req->op = (rq_data_dir(req) == READ) ? UBD_READ : UBD_WRITE;
io_req->offsets[0] = 0;
io_req->offsets[1] = ubd_dev->cow.data_offset;
- io_req->buffer = req->buffer;
+ io_req->buffer = page_address(page) + page_offset;
io_req->sectorsize = 1 << 9;
if(ubd_dev->cow.file != NULL)
- cowify_req(io_req, ubd_dev->cow.bitmap, ubd_dev->cow.bitmap_offset,
- ubd_dev->cow.bitmap_len);
+ cowify_req(io_req, ubd_dev->cow.bitmap,
+ ubd_dev->cow.bitmap_offset, ubd_dev->cow.bitmap_len);
- return(0);
}
/* Called with dev->lock held */
static void do_ubd_request(request_queue_t *q)
{
- struct io_thread_req io_req;
+ struct io_thread_req *io_req;
struct request *req;
- int err, n;
-
- if(thread_fd == -1){
- while((req = elv_next_request(q)) != NULL){
- err = prepare_request(req, &io_req);
- if(!err){
- do_io(&io_req);
- __ubd_finish(req, io_req.error);
- }
- }
- }
- else {
+ int n;
+
+ while(1){
struct ubd *dev = q->queuedata;
- if(dev->active || (req = elv_next_request(q)) == NULL)
- return;
- err = prepare_request(req, &io_req);
- if(!err){
- dev->active = 1;
- n = os_write_file(thread_fd, (char *) &io_req,
- sizeof(io_req));
- if(n != sizeof(io_req))
- printk("write to io thread failed, "
- "errno = %d\n", -n);
+ if(dev->end_sg == 0){
+ struct request *req = elv_next_request(q);
+ if(req == NULL)
+ return;
+
+ dev->request = req;
+ blkdev_dequeue_request(req);
+ dev->start_sg = 0;
+ dev->end_sg = blk_rq_map_sg(q, req, dev->sg);
}
+
+ req = dev->request;
+ while(dev->start_sg < dev->end_sg){
+ struct scatterlist *sg = &dev->sg[dev->start_sg];
+
+ io_req = kmalloc(sizeof(struct io_thread_req),
+ GFP_ATOMIC);
+ if(io_req == NULL){
+ if(list_empty(&dev->restart))
+ list_add(&dev->restart, &restart);
+ return;
+ }
+ prepare_request(req, io_req,
+ (unsigned long long) req->sector << 9,
+ sg->offset, sg->length, sg->page);
+
+ n = os_write_file(thread_fd, &io_req,
+ sizeof(struct io_thread_req *));
+ if(n != sizeof(struct io_thread_req *)){
+ if(n != -EAGAIN)
+ printk("write to io thread failed, "
+ "errno = %d\n", -n);
+ else if(list_empty(&dev->restart))
+ list_add(&dev->restart, &restart);
+ return;
+ }
+
+ req->sector += sg->length >> 9;
+ dev->start_sg++;
+ }
+ dev->end_sg = 0;
+ dev->request = NULL;
}
}
@@ -1120,21 +1157,21 @@ static int ubd_ioctl(struct inode * inode, struct file * file,
ubd_id.cyls = ubd_dev->size / (128 * 32 * 512);
if(copy_to_user((char __user *) arg, (char *) &ubd_id,
sizeof(ubd_id)))
- return(-EFAULT);
- return(0);
+ return -EFAULT;
+ return 0;
case CDROMVOLREAD:
if(copy_from_user(&volume, (char __user *) arg, sizeof(volume)))
- return(-EFAULT);
+ return -EFAULT;
volume.channel0 = 255;
volume.channel1 = 255;
volume.channel2 = 255;
volume.channel3 = 255;
if(copy_to_user((char __user *) arg, &volume, sizeof(volume)))
- return(-EFAULT);
- return(0);
+ return -EFAULT;
+ return 0;
}
- return(-EINVAL);
+ return -EINVAL;
}
static int path_requires_switch(char *from_cmdline, char *from_cow, char *cow)
@@ -1176,29 +1213,29 @@ static int backing_file_mismatch(char *file, __u64 size, time_t mtime)
if(err < 0){
printk("Failed to get modification time of backing file "
"\"%s\", err = %d\n", file, -err);
- return(err);
+ return err;
}
err = os_file_size(file, &actual);
if(err < 0){
printk("Failed to get size of backing file \"%s\", "
"err = %d\n", file, -err);
- return(err);
+ return err;
}
- if(actual != size){
+ if(actual != size){
/*__u64 can be a long on AMD64 and with %lu GCC complains; so
* the typecast.*/
printk("Size mismatch (%llu vs %llu) of COW header vs backing "
"file\n", (unsigned long long) size, actual);
- return(-EINVAL);
+ return -EINVAL;
}
if(modtime != mtime){
printk("mtime mismatch (%ld vs %ld) of COW header vs backing "
"file\n", mtime, modtime);
- return(-EINVAL);
+ return -EINVAL;
}
- return(0);
+ return 0;
}
int read_cow_bitmap(int fd, void *buf, int offset, int len)
@@ -1207,13 +1244,13 @@ int read_cow_bitmap(int fd, void *buf, int offset, int len)
err = os_seek_file(fd, offset);
if(err < 0)
- return(err);
+ return err;
err = os_read_file(fd, buf, len);
if(err < 0)
- return(err);
+ return err;
- return(0);
+ return 0;
}
int open_ubd_file(char *file, struct openflags *openflags, int shared,
@@ -1231,14 +1268,14 @@ int open_ubd_file(char *file, struct openflags *openflags, int shared,
if (fd < 0) {
if ((fd == -ENOENT) && (create_cow_out != NULL))
*create_cow_out = 1;
- if (!openflags->w ||
- ((fd != -EROFS) && (fd != -EACCES)))
+ if (!openflags->w ||
+ ((fd != -EROFS) && (fd != -EACCES)))
return fd;
openflags->w = 0;
fd = os_open_file(file, *openflags, mode);
if (fd < 0)
return fd;
- }
+ }
if(shared)
printk("Not locking \"%s\" on the host\n", file);
@@ -1252,7 +1289,7 @@ int open_ubd_file(char *file, struct openflags *openflags, int shared,
/* Successful return case! */
if(backing_file_out == NULL)
- return(fd);
+ return fd;
err = read_cow_header(file_reader, &fd, &version, &backing_file, &mtime,
&size, &sectorsize, &align, bitmap_offset_out);
@@ -1262,7 +1299,7 @@ int open_ubd_file(char *file, struct openflags *openflags, int shared,
goto out_close;
}
if(err)
- return(fd);
+ return fd;
asked_switch = path_requires_switch(*backing_file_out, backing_file, file);
@@ -1285,7 +1322,7 @@ int open_ubd_file(char *file, struct openflags *openflags, int shared,
cow_sizes(version, size, sectorsize, align, *bitmap_offset_out,
bitmap_len_out, data_offset_out);
- return fd;
+ return fd;
out_close:
os_close_file(fd);
return err;
@@ -1310,10 +1347,10 @@ int create_cow_file(char *cow_file, char *backing_file, struct openflags flags,
bitmap_offset_out, bitmap_len_out,
data_offset_out);
if(!err)
- return(fd);
+ return fd;
os_close_file(fd);
out:
- return(err);
+ return err;
}
static int update_bitmap(struct io_thread_req *req)
@@ -1321,23 +1358,23 @@ static int update_bitmap(struct io_thread_req *req)
int n;
if(req->cow_offset == -1)
- return(0);
+ return 0;
n = os_seek_file(req->fds[1], req->cow_offset);
if(n < 0){
printk("do_io - bitmap lseek failed : err = %d\n", -n);
- return(1);
+ return 1;
}
n = os_write_file(req->fds[1], &req->bitmap_words,
- sizeof(req->bitmap_words));
+ sizeof(req->bitmap_words));
if(n != sizeof(req->bitmap_words)){
printk("do_io - bitmap update failed, err = %d fd = %d\n", -n,
req->fds[1]);
- return(1);
+ return 1;
}
- return(0);
+ return 0;
}
void do_io(struct io_thread_req *req)
@@ -1409,13 +1446,14 @@ static int io_count = 0;
int io_thread(void *arg)
{
- struct io_thread_req req;
+ struct io_thread_req *req;
int n;
ignore_sigwinch_sig();
while(1){
- n = os_read_file(kernel_fd, &req, sizeof(req));
- if(n != sizeof(req)){
+ n = os_read_file(kernel_fd, &req,
+ sizeof(struct io_thread_req *));
+ if(n != sizeof(struct io_thread_req *)){
if(n < 0)
printk("io_thread - read failed, fd = %d, "
"err = %d\n", kernel_fd, -n);
@@ -1426,9 +1464,10 @@ int io_thread(void *arg)
continue;
}
io_count++;
- do_io(&req);
- n = os_write_file(kernel_fd, &req, sizeof(req));
- if(n != sizeof(req))
+ do_io(req);
+ n = os_write_file(kernel_fd, &req,
+ sizeof(struct io_thread_req *));
+ if(n != sizeof(struct io_thread_req *))
printk("io_thread - write failed, fd = %d, err = %d\n",
kernel_fd, -n);
}
diff --git a/arch/um/drivers/ubd_user.c b/arch/um/drivers/ubd_user.c
index b94d2bc4fe0..4707b3f14c2 100644
--- a/arch/um/drivers/ubd_user.c
+++ b/arch/um/drivers/ubd_user.c
@@ -16,7 +16,6 @@
#include <sys/mman.h>
#include <sys/param.h>
#include "asm/types.h"
-#include "user_util.h"
#include "kern_util.h"
#include "user.h"
#include "ubd_user.h"
@@ -47,8 +46,8 @@ int start_io_thread(unsigned long sp, int *fd_out)
pid = clone(io_thread, (void *) sp, CLONE_FILES | CLONE_VM | SIGCHLD,
NULL);
if(pid < 0){
- printk("start_io_thread - clone failed : errno = %d\n", errno);
err = -errno;
+ printk("start_io_thread - clone failed : errno = %d\n", errno);
goto out_close;
}
@@ -60,16 +59,5 @@ int start_io_thread(unsigned long sp, int *fd_out)
kernel_fd = -1;
*fd_out = -1;
out:
- return(err);
+ return err;
}
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/drivers/xterm.c b/arch/um/drivers/xterm.c
index 850221d9b4c..571c2b3325d 100644
--- a/arch/um/drivers/xterm.c
+++ b/arch/um/drivers/xterm.c
@@ -14,7 +14,6 @@
#include <sys/socket.h>
#include "kern_util.h"
#include "chan_user.h"
-#include "user_util.h"
#include "user.h"
#include "os.h"
#include "xterm.h"
diff --git a/arch/um/include/arch.h b/arch/um/include/arch.h
new file mode 100644
index 00000000000..10ad52daa8c
--- /dev/null
+++ b/arch/um/include/arch.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __ARCH_H__
+#define __ARCH_H__
+
+#include "sysdep/ptrace.h"
+
+extern void arch_check_bugs(void);
+extern int arch_fixup(unsigned long address, union uml_pt_regs *regs);
+extern int arch_handle_signal(int sig, union uml_pt_regs *regs);
+
+#endif
diff --git a/arch/um/include/as-layout.h b/arch/um/include/as-layout.h
new file mode 100644
index 00000000000..fccf187bf4e
--- /dev/null
+++ b/arch/um/include/as-layout.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __START_H__
+#define __START_H__
+
+#include "sysdep/ptrace.h"
+
+struct cpu_task {
+ int pid;
+ void *task;
+};
+
+extern struct cpu_task cpu_tasks[];
+
+extern unsigned long low_physmem;
+extern unsigned long high_physmem;
+extern unsigned long uml_physmem;
+extern unsigned long uml_reserved;
+extern unsigned long end_vm;
+extern unsigned long start_vm;
+extern unsigned long long highmem;
+
+extern unsigned long _stext, _etext, _sdata, _edata, __bss_start, _end;
+extern unsigned long _unprotected_end;
+extern unsigned long brk_start;
+
+extern int linux_main(int argc, char **argv);
+extern void set_cmdline(char *cmd);
+
+extern void (*sig_info[])(int, union uml_pt_regs *);
+
+#endif
diff --git a/arch/um/include/common-offsets.h b/arch/um/include/common-offsets.h
index 461175f8b1d..5593a802708 100644
--- a/arch/um/include/common-offsets.h
+++ b/arch/um/include/common-offsets.h
@@ -24,5 +24,7 @@ DEFINE(UM_ELF_CLASS, ELF_CLASS);
DEFINE(UM_ELFCLASS32, ELFCLASS32);
DEFINE(UM_ELFCLASS64, ELFCLASS64);
+DEFINE(UM_NR_CPUS, NR_CPUS);
+
/* For crypto assembler code. */
DEFINE(crypto_tfm_ctx_offset, offsetof(struct crypto_tfm, __crt_ctx));
diff --git a/arch/um/include/kern_util.h b/arch/um/include/kern_util.h
index 173af029d12..50a49691e0e 100644
--- a/arch/um/include/kern_util.h
+++ b/arch/um/include/kern_util.h
@@ -8,6 +8,7 @@
#include "sysdep/ptrace.h"
#include "sysdep/faultinfo.h"
+#include "uml-config.h"
typedef void (*kern_hndl)(int, union uml_pt_regs *);
@@ -23,7 +24,6 @@ struct kern_handlers {
extern const struct kern_handlers handlinfo_kern;
extern int ncpus;
-extern char *linux_prog;
extern char *gdb_init;
extern int kmalloc_ok;
extern int jail;
@@ -34,7 +34,9 @@ extern int nsyscalls;
UML_ROUND_DOWN(((unsigned long) addr) + PAGE_SIZE - 1)
extern int kernel_fork(unsigned long flags, int (*fn)(void *), void * arg);
+#ifdef UML_CONFIG_MODE_TT
extern unsigned long stack_sp(unsigned long page);
+#endif
extern int kernel_thread_proc(void *data);
extern void syscall_segv(int sig);
extern int current_pid(void);
@@ -42,7 +44,7 @@ extern unsigned long alloc_stack(int order, int atomic);
extern int do_signal(void);
extern int is_stack_fault(unsigned long sp);
extern unsigned long segv(struct faultinfo fi, unsigned long ip,
- int is_user, void *sc);
+ int is_user, union uml_pt_regs *regs);
extern int handle_page_fault(unsigned long address, unsigned long ip,
int is_write, int is_user, int *code_out);
extern void syscall_ready(void);
@@ -50,7 +52,6 @@ extern void set_tracing(void *t, int tracing);
extern int is_tracing(void *task);
extern int segv_syscall(void);
extern void kern_finish_exec(void *task, int new_pid, unsigned long stack);
-extern int page_size(void);
extern unsigned long page_mask(void);
extern int need_finish_fork(void);
extern void free_stack(unsigned long stack, int order);
@@ -58,7 +59,6 @@ extern void add_input_request(int op, void (*proc)(int), void *arg);
extern char *current_cmd(void);
extern void timer_handler(int sig, union uml_pt_regs *regs);
extern int set_signals(int enable);
-extern void force_sigbus(void);
extern int pid_to_processor_id(int pid);
extern void deliver_signals(void *t);
extern int next_trap_index(int max);
@@ -70,7 +70,6 @@ extern void *syscall_sp(void *t);
extern void syscall_trace(union uml_pt_regs *regs, int entryexit);
extern int hz(void);
extern unsigned int do_IRQ(int irq, union uml_pt_regs *regs);
-extern int external_pid(void *t);
extern void interrupt_end(void);
extern void initial_thread_cb(void (*proc)(void *), void *arg);
extern int debugger_signal(int status, int pid);
@@ -81,7 +80,6 @@ extern int init_parent_proxy(int pid);
extern int singlestepping(void *t);
extern void check_stack_overflow(void *ptr);
extern void relay_signal(int sig, union uml_pt_regs *regs);
-extern void not_implemented(void);
extern int user_context(unsigned long sp);
extern void timer_irq(union uml_pt_regs *regs);
extern void unprotect_stack(unsigned long stack);
@@ -93,7 +91,6 @@ extern char *uml_strdup(char *string);
extern void unprotect_kernel_mem(void);
extern void protect_kernel_mem(void);
extern void uml_cleanup(void);
-extern void set_current(void *t);
extern void lock_signalled_task(void *t);
extern void IPI_handler(int cpu);
extern int jail_setup(char *line, int *add);
@@ -118,4 +115,6 @@ extern void time_init_kern(void);
extern int __cant_sleep(void);
extern void sigio_handler(int sig, union uml_pt_regs *regs);
+extern void copy_sc(union uml_pt_regs *regs, void *from);
+
#endif
diff --git a/arch/um/include/net_kern.h b/arch/um/include/net_kern.h
index 125ab42df18..9237056b910 100644
--- a/arch/um/include/net_kern.h
+++ b/arch/um/include/net_kern.h
@@ -40,7 +40,7 @@ struct uml_net_private {
void (*add_address)(unsigned char *, unsigned char *, void *);
void (*delete_address)(unsigned char *, unsigned char *, void *);
int (*set_mtu)(int mtu, void *);
- int user[1];
+ char user[0];
};
struct net_kern_info {
diff --git a/arch/um/include/net_user.h b/arch/um/include/net_user.h
index 19f207cd70f..cfe7c50634b 100644
--- a/arch/um/include/net_user.h
+++ b/arch/um/include/net_user.h
@@ -14,7 +14,7 @@
#define UML_NET_VERSION (4)
struct net_user_info {
- void (*init)(void *, void *);
+ int (*init)(void *, void *);
int (*open)(void *);
void (*close)(int, void *);
void (*remove)(void *);
diff --git a/arch/um/include/os.h b/arch/um/include/os.h
index 5c74da41045..688d181b5f8 100644
--- a/arch/um/include/os.h
+++ b/arch/um/include/os.h
@@ -16,6 +16,8 @@
#include "sysdep/tls.h"
#include "sysdep/archsetjmp.h"
+#define CATCH_EINTR(expr) while ((errno = 0, ((expr) < 0)) && (errno == EINTR))
+
#define OS_TYPE_FILE 1
#define OS_TYPE_DIR 2
#define OS_TYPE_SYMLINK 3
@@ -273,8 +275,9 @@ extern void stack_protections(unsigned long address);
extern void task_protections(unsigned long address);
extern int raw(int fd);
extern void setup_machinename(char *machine_out);
-extern void setup_hostinfo(void);
+extern void setup_hostinfo(char *buf, int len);
extern int setjmp_wrapper(void (*proc)(void *, void *), ...);
+extern void os_dump_core(void);
/* time.c */
#define BILLION (1000 * 1000 * 1000)
@@ -297,13 +300,12 @@ extern long syscall_stub_data(struct mm_id * mm_idp,
unsigned long *data, int data_count,
void **addr, void **stub_addr);
extern int map(struct mm_id * mm_idp, unsigned long virt,
- unsigned long len, int r, int w, int x, int phys_fd,
+ unsigned long len, int prot, int phys_fd,
unsigned long long offset, int done, void **data);
-extern int unmap(struct mm_id * mm_idp, void *addr, unsigned long len,
+extern int unmap(struct mm_id * mm_idp, unsigned long addr, unsigned long len,
int done, void **data);
extern int protect(struct mm_id * mm_idp, unsigned long addr,
- unsigned long len, int r, int w, int x, int done,
- void **data);
+ unsigned long len, unsigned int prot, int done, void **data);
/* skas/process.c */
extern int is_skas_winch(int pid, int fd, void *data);
@@ -339,8 +341,11 @@ extern void maybe_sigio_broken(int fd, int read);
/* skas/trap */
extern void sig_handler_common_skas(int sig, void *sc_ptr);
-extern void user_signal(int sig, union uml_pt_regs *regs, int pid);
+/* sys-x86_64/prctl.c */
extern int os_arch_prctl(int pid, int code, unsigned long *addr);
+/* tty.c */
+int get_pty(void);
+
#endif
diff --git a/arch/um/include/skas/mode_kern_skas.h b/arch/um/include/skas/mode_kern_skas.h
index 9cd9c6ec9a6..8ee6285dfac 100644
--- a/arch/um/include/skas/mode_kern_skas.h
+++ b/arch/um/include/skas/mode_kern_skas.h
@@ -33,6 +33,8 @@ extern unsigned long set_task_sizes_skas(unsigned long *task_size_out);
extern int start_uml_skas(void);
extern int external_pid_skas(struct task_struct *task);
extern int thread_pid_skas(struct task_struct *task);
+extern void flush_tlb_page_skas(struct vm_area_struct *vma,
+ unsigned long address);
#define kmem_end_skas (host_task_size - 1024 * 1024)
diff --git a/arch/um/include/tlb.h b/arch/um/include/tlb.h
index 8efc1e0f1b8..bcd1a4afb84 100644
--- a/arch/um/include/tlb.h
+++ b/arch/um/include/tlb.h
@@ -14,9 +14,7 @@ struct host_vm_op {
struct {
unsigned long addr;
unsigned long len;
- unsigned int r:1;
- unsigned int w:1;
- unsigned int x:1;
+ unsigned int prot;
int fd;
__u64 offset;
} mmap;
@@ -27,9 +25,7 @@ struct host_vm_op {
struct {
unsigned long addr;
unsigned long len;
- unsigned int r:1;
- unsigned int w:1;
- unsigned int x:1;
+ unsigned int prot;
} mprotect;
} u;
};
diff --git a/arch/um/include/tt/uaccess-tt.h b/arch/um/include/tt/uaccess-tt.h
index b19645f32f2..13a64f61fcf 100644
--- a/arch/um/include/tt/uaccess-tt.h
+++ b/arch/um/include/tt/uaccess-tt.h
@@ -27,8 +27,6 @@ extern unsigned long uml_physmem;
#define access_ok_tt(type, addr, size) \
(is_stack(addr, size))
-extern unsigned long get_fault_addr(void);
-
extern int __do_copy_from_user(void *to, const void *from, int n,
void **fault_addr, void **fault_catcher);
extern int __do_strncpy_from_user(char *dst, const char *src, size_t n,
diff --git a/arch/um/include/um_malloc.h b/arch/um/include/um_malloc.h
index 0363a9b53f8..e6d7c5aa3f4 100644
--- a/arch/um/include/um_malloc.h
+++ b/arch/um/include/um_malloc.h
@@ -11,7 +11,6 @@ extern void *um_kmalloc_atomic(int size);
extern void kfree(const void *ptr);
extern void *um_vmalloc(int size);
-extern void *um_vmalloc_atomic(int size);
extern void vfree(void *ptr);
#endif /* __UM_MALLOC_H__ */
diff --git a/arch/um/include/user.h b/arch/um/include/user.h
index acadce3f271..d380e6d91a9 100644
--- a/arch/um/include/user.h
+++ b/arch/um/include/user.h
@@ -6,6 +6,19 @@
#ifndef __USER_H__
#define __USER_H__
+/*
+ * The usual definition - copied here because the kernel provides its own,
+ * fancier, type-safe, definition. Using that one would require
+ * copying too much infrastructure for my taste, so userspace files
+ * get less checking than kernel files.
+ */
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+
+/*
+ * This will provide the size_t definition in both kernel and userspace builds
+ */
+#include <linux/types.h>
+
extern void panic(const char *fmt, ...)
__attribute__ ((format (printf, 1, 2)));
extern int printk(const char *fmt, ...)
@@ -13,19 +26,7 @@ extern int printk(const char *fmt, ...)
extern void schedule(void);
extern int in_aton(char *str);
extern int open_gdb_chan(void);
-/* These use size_t, however unsigned long is correct on both i386 and x86_64. */
-extern unsigned long strlcpy(char *, const char *, unsigned long);
-extern unsigned long strlcat(char *, const char *, unsigned long);
+extern size_t strlcpy(char *, const char *, size_t);
+extern size_t strlcat(char *, const char *, size_t);
#endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/include/user_util.h b/arch/um/include/user_util.h
deleted file mode 100644
index 023575f6734..00000000000
--- a/arch/um/include/user_util.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#ifndef __USER_UTIL_H__
-#define __USER_UTIL_H__
-
-#include "sysdep/ptrace.h"
-
-/* Copied from kernel.h */
-#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
-
-#define CATCH_EINTR(expr) while ((errno = 0, ((expr) < 0)) && (errno == EINTR))
-
-extern int mode_tt;
-
-extern int grantpt(int __fd);
-extern int unlockpt(int __fd);
-extern char *ptsname(int __fd);
-
-struct cpu_task {
- int pid;
- void *task;
-};
-
-extern struct cpu_task cpu_tasks[];
-
-extern void (*sig_info[])(int, union uml_pt_regs *);
-
-extern unsigned long low_physmem;
-extern unsigned long high_physmem;
-extern unsigned long uml_physmem;
-extern unsigned long uml_reserved;
-extern unsigned long end_vm;
-extern unsigned long start_vm;
-extern unsigned long long highmem;
-
-extern char host_info[];
-
-extern unsigned long _stext, _etext, _sdata, _edata, __bss_start, _end;
-extern unsigned long _unprotected_end;
-extern unsigned long brk_start;
-
-extern int pty_output_sigio;
-extern int pty_close_sigio;
-
-extern void *add_signal_handler(int sig, void (*handler)(int));
-extern int linux_main(int argc, char **argv);
-extern void set_cmdline(char *cmd);
-extern void input_cb(void (*proc)(void *), void *arg, int arg_len);
-extern int get_pty(void);
-extern int switcheroo(int fd, int prot, void *from, void *to, int size);
-extern void do_exec(int old_pid, int new_pid);
-extern void tracer_panic(char *msg, ...)
- __attribute__ ((format (printf, 1, 2)));
-extern int detach(int pid, int sig);
-extern int attach(int pid);
-extern void kill_child_dead(int pid);
-extern int cont(int pid);
-extern void check_sigio(void);
-extern void arch_check_bugs(void);
-extern int cpu_feature(char *what, char *buf, int len);
-extern int arch_handle_signal(int sig, union uml_pt_regs *regs);
-extern int arch_fixup(unsigned long address, void *sc_ptr);
-extern void arch_init_thread(void);
-extern int raw(int fd);
-
-#endif
diff --git a/arch/um/kernel/exec.c b/arch/um/kernel/exec.c
index 121166400e2..356e50f5aae 100644
--- a/arch/um/kernel/exec.c
+++ b/arch/um/kernel/exec.c
@@ -10,8 +10,8 @@
#include "asm/pgtable.h"
#include "asm/tlbflush.h"
#include "asm/uaccess.h"
-#include "user_util.h"
#include "kern_util.h"
+#include "as-layout.h"
#include "mem_user.h"
#include "kern.h"
#include "irq_user.h"
diff --git a/arch/um/kernel/init_task.c b/arch/um/kernel/init_task.c
index 8cde431348c..cda91aa8e70 100644
--- a/arch/um/kernel/init_task.c
+++ b/arch/um/kernel/init_task.c
@@ -10,7 +10,6 @@
#include "linux/mqueue.h"
#include "asm/uaccess.h"
#include "asm/pgtable.h"
-#include "user_util.h"
#include "mem_user.h"
#include "os.h"
diff --git a/arch/um/kernel/initrd.c b/arch/um/kernel/initrd.c
index 82ecf904b09..16dc43e9d94 100644
--- a/arch/um/kernel/initrd.c
+++ b/arch/um/kernel/initrd.c
@@ -7,7 +7,6 @@
#include "linux/bootmem.h"
#include "linux/initrd.h"
#include "asm/types.h"
-#include "user_util.h"
#include "kern_util.h"
#include "initrd.h"
#include "init.h"
@@ -22,12 +21,20 @@ static int __init read_initrd(void)
long long size;
int err;
- if(initrd == NULL) return 0;
+ if(initrd == NULL)
+ return 0;
+
err = os_file_size(initrd, &size);
- if(err) return 0;
+ if(err)
+ return 0;
+
area = alloc_bootmem(size);
- if(area == NULL) return 0;
- if(load_initrd(initrd, area, size) == -1) return 0;
+ if(area == NULL)
+ return 0;
+
+ if(load_initrd(initrd, area, size) == -1)
+ return 0;
+
initrd_start = (unsigned long) area;
initrd_end = initrd_start + size;
return 0;
@@ -54,25 +61,15 @@ int load_initrd(char *filename, void *buf, int size)
fd = os_open_file(filename, of_read(OPENFLAGS()), 0);
if(fd < 0){
printk("Opening '%s' failed - err = %d\n", filename, -fd);
- return(-1);
+ return -1;
}
n = os_read_file(fd, buf, size);
if(n != size){
printk("Read of %d bytes from '%s' failed, err = %d\n", size,
filename, -n);
- return(-1);
+ return -1;
}
os_close_file(fd);
- return(0);
+ return 0;
}
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c
index dbf2f5bc842..8f2ed369031 100644
--- a/arch/um/kernel/irq.c
+++ b/arch/um/kernel/irq.c
@@ -25,7 +25,6 @@
#include "asm/system.h"
#include "asm/errno.h"
#include "asm/uaccess.h"
-#include "user_util.h"
#include "kern_util.h"
#include "irq_user.h"
#include "irq_kern.h"
@@ -79,6 +78,14 @@ skip:
return 0;
}
+/*
+ * This list is accessed under irq_lock, except in sigio_handler,
+ * where it is safe from being modified. IRQ handlers won't change it -
+ * if an IRQ source has vanished, it will be freed by free_irqs just
+ * before returning from sigio_handler. That will process a separate
+ * list of irqs to free, with its own locking, coming back here to
+ * remove list elements, taking the irq_lock to do so.
+ */
static struct irq_fd *active_fds = NULL;
static struct irq_fd **last_irq_ptr = &active_fds;
@@ -244,6 +251,7 @@ void free_irq_by_fd(int fd)
free_irq_by_cb(same_fd, &fd);
}
+/* Must be called with irq_lock held */
static struct irq_fd *find_irq_by_fd(int fd, int irqnum, int *index_out)
{
struct irq_fd *irq;
@@ -309,6 +317,12 @@ void deactivate_fd(int fd, int irqnum)
ignore_sigio_fd(fd);
}
+/*
+ * Called just before shutdown in order to provide a clean exec
+ * environment in case the system is rebooting. No locking because
+ * that would cause a pointless shutdown hang if something hadn't
+ * released the lock.
+ */
int deactivate_all_fds(void)
{
struct irq_fd *irq;
diff --git a/arch/um/kernel/ksyms.c b/arch/um/kernel/ksyms.c
index 0e00cf93f90..7b3e53fb807 100644
--- a/arch/um/kernel/ksyms.c
+++ b/arch/um/kernel/ksyms.c
@@ -16,7 +16,7 @@
#include "asm/page.h"
#include "asm/tlbflush.h"
#include "kern_util.h"
-#include "user_util.h"
+#include "as-layout.h"
#include "mem_user.h"
#include "os.h"
diff --git a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c
index df7d662b98c..72ff85693a3 100644
--- a/arch/um/kernel/mem.c
+++ b/arch/um/kernel/mem.c
@@ -13,8 +13,8 @@
#include "asm/page.h"
#include "asm/fixmap.h"
#include "asm/pgalloc.h"
-#include "user_util.h"
#include "kern_util.h"
+#include "as-layout.h"
#include "kern.h"
#include "mem_user.h"
#include "uml_uaccess.h"
@@ -216,7 +216,7 @@ static void __init fixaddr_user_init( void)
#endif
}
-void paging_init(void)
+void __init paging_init(void)
{
unsigned long zones_size[MAX_NR_ZONES], vaddr;
int i;
diff --git a/arch/um/kernel/physmem.c b/arch/um/kernel/physmem.c
index 638f3b5f609..3ba6e4c841d 100644
--- a/arch/um/kernel/physmem.c
+++ b/arch/um/kernel/physmem.c
@@ -13,7 +13,7 @@
#include "asm/types.h"
#include "asm/pgtable.h"
#include "kern_util.h"
-#include "user_util.h"
+#include "as-layout.h"
#include "mode_kern.h"
#include "mem.h"
#include "mem_user.h"
@@ -21,229 +21,8 @@
#include "kern.h"
#include "init.h"
-struct phys_desc {
- struct rb_node rb;
- int fd;
- __u64 offset;
- void *virt;
- unsigned long phys;
- struct list_head list;
-};
-
-static struct rb_root phys_mappings = RB_ROOT;
-
-static struct rb_node **find_rb(void *virt)
-{
- struct rb_node **n = &phys_mappings.rb_node;
- struct phys_desc *d;
-
- while(*n != NULL){
- d = rb_entry(*n, struct phys_desc, rb);
- if(d->virt == virt)
- return n;
-
- if(d->virt > virt)
- n = &(*n)->rb_left;
- else
- n = &(*n)->rb_right;
- }
-
- return n;
-}
-
-static struct phys_desc *find_phys_mapping(void *virt)
-{
- struct rb_node **n = find_rb(virt);
-
- if(*n == NULL)
- return NULL;
-
- return rb_entry(*n, struct phys_desc, rb);
-}
-
-static void insert_phys_mapping(struct phys_desc *desc)
-{
- struct rb_node **n = find_rb(desc->virt);
-
- if(*n != NULL)
- panic("Physical remapping for %p already present",
- desc->virt);
-
- rb_link_node(&desc->rb, rb_parent(*n), n);
- rb_insert_color(&desc->rb, &phys_mappings);
-}
-
-LIST_HEAD(descriptor_mappings);
-
-struct desc_mapping {
- int fd;
- struct list_head list;
- struct list_head pages;
-};
-
-static struct desc_mapping *find_mapping(int fd)
-{
- struct desc_mapping *desc;
- struct list_head *ele;
-
- list_for_each(ele, &descriptor_mappings){
- desc = list_entry(ele, struct desc_mapping, list);
- if(desc->fd == fd)
- return desc;
- }
-
- return NULL;
-}
-
-static struct desc_mapping *descriptor_mapping(int fd)
-{
- struct desc_mapping *desc;
-
- desc = find_mapping(fd);
- if(desc != NULL)
- return desc;
-
- desc = kmalloc(sizeof(*desc), GFP_ATOMIC);
- if(desc == NULL)
- return NULL;
-
- *desc = ((struct desc_mapping)
- { .fd = fd,
- .list = LIST_HEAD_INIT(desc->list),
- .pages = LIST_HEAD_INIT(desc->pages) });
- list_add(&desc->list, &descriptor_mappings);
-
- return desc;
-}
-
-int physmem_subst_mapping(void *virt, int fd, __u64 offset, int w)
-{
- struct desc_mapping *fd_maps;
- struct phys_desc *desc;
- unsigned long phys;
- int err;
-
- fd_maps = descriptor_mapping(fd);
- if(fd_maps == NULL)
- return -ENOMEM;
-
- phys = __pa(virt);
- desc = find_phys_mapping(virt);
- if(desc != NULL)
- panic("Address 0x%p is already substituted\n", virt);
-
- err = -ENOMEM;
- desc = kmalloc(sizeof(*desc), GFP_ATOMIC);
- if(desc == NULL)
- goto out;
-
- *desc = ((struct phys_desc)
- { .fd = fd,
- .offset = offset,
- .virt = virt,
- .phys = __pa(virt),
- .list = LIST_HEAD_INIT(desc->list) });
- insert_phys_mapping(desc);
-
- list_add(&desc->list, &fd_maps->pages);
-
- virt = (void *) ((unsigned long) virt & PAGE_MASK);
- err = os_map_memory(virt, fd, offset, PAGE_SIZE, 1, w, 0);
- if(!err)
- goto out;
-
- rb_erase(&desc->rb, &phys_mappings);
- kfree(desc);
- out:
- return err;
-}
-
static int physmem_fd = -1;
-static void remove_mapping(struct phys_desc *desc)
-{
- void *virt = desc->virt;
- int err;
-
- rb_erase(&desc->rb, &phys_mappings);
- list_del(&desc->list);
- kfree(desc);
-
- err = os_map_memory(virt, physmem_fd, __pa(virt), PAGE_SIZE, 1, 1, 0);
- if(err)
- panic("Failed to unmap block device page from physical memory, "
- "errno = %d", -err);
-}
-
-int physmem_remove_mapping(void *virt)
-{
- struct phys_desc *desc;
-
- virt = (void *) ((unsigned long) virt & PAGE_MASK);
- desc = find_phys_mapping(virt);
- if(desc == NULL)
- return 0;
-
- remove_mapping(desc);
- return 1;
-}
-
-void physmem_forget_descriptor(int fd)
-{
- struct desc_mapping *desc;
- struct phys_desc *page;
- struct list_head *ele, *next;
- __u64 offset;
- void *addr;
- int err;
-
- desc = find_mapping(fd);
- if(desc == NULL)
- return;
-
- list_for_each_safe(ele, next, &desc->pages){
- page = list_entry(ele, struct phys_desc, list);
- offset = page->offset;
- addr = page->virt;
- remove_mapping(page);
- err = os_seek_file(fd, offset);
- if(err)
- panic("physmem_forget_descriptor - failed to seek "
- "to %lld in fd %d, error = %d\n",
- offset, fd, -err);
- err = os_read_file(fd, addr, PAGE_SIZE);
- if(err < 0)
- panic("physmem_forget_descriptor - failed to read "
- "from fd %d to 0x%p, error = %d\n",
- fd, addr, -err);
- }
-
- list_del(&desc->list);
- kfree(desc);
-}
-
-EXPORT_SYMBOL(physmem_forget_descriptor);
-EXPORT_SYMBOL(physmem_remove_mapping);
-EXPORT_SYMBOL(physmem_subst_mapping);
-
-void arch_free_page(struct page *page, int order)
-{
- void *virt;
- int i;
-
- for(i = 0; i < (1 << order); i++){
- virt = __va(page_to_phys(page + i));
- physmem_remove_mapping(virt);
- }
-}
-
-int is_remapped(void *virt)
-{
- struct phys_desc *desc = find_phys_mapping(virt);
-
- return desc != NULL;
-}
-
/* Changed during early boot */
unsigned long high_physmem;
@@ -350,14 +129,9 @@ void setup_physmem(unsigned long start, unsigned long reserve_end,
int phys_mapping(unsigned long phys, __u64 *offset_out)
{
- struct phys_desc *desc = find_phys_mapping(__va(phys & PAGE_MASK));
int fd = -1;
- if(desc != NULL){
- fd = desc->fd;
- *offset_out = desc->offset;
- }
- else if(phys < physmem_size){
+ if(phys < physmem_size){
fd = physmem_fd;
*offset_out = phys;
}
diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c
index 348b272bb76..8d2c5496532 100644
--- a/arch/um/kernel/process.c
+++ b/arch/um/kernel/process.c
@@ -32,8 +32,8 @@
#include "asm/tlbflush.h"
#include "asm/uaccess.h"
#include "asm/user.h"
-#include "user_util.h"
#include "kern_util.h"
+#include "as-layout.h"
#include "kern.h"
#include "signal_kern.h"
#include "init.h"
@@ -54,11 +54,9 @@
*/
struct cpu_task cpu_tasks[NR_CPUS] = { [0 ... NR_CPUS - 1] = { -1, NULL } };
-int external_pid(void *t)
+static inline int external_pid(struct task_struct *task)
{
- struct task_struct *task = t ? t : current;
-
- return(CHOOSE_MODE_PROC(external_pid_tt, external_pid_skas, task));
+ return CHOOSE_MODE_PROC(external_pid_tt, external_pid_skas, task);
}
int pid_to_processor_id(int pid)
@@ -66,9 +64,10 @@ int pid_to_processor_id(int pid)
int i;
for(i = 0; i < ncpus; i++){
- if(cpu_tasks[i].pid == pid) return(i);
+ if(cpu_tasks[i].pid == pid)
+ return i;
}
- return(-1);
+ return -1;
}
void free_stack(unsigned long stack, int order)
@@ -85,9 +84,9 @@ unsigned long alloc_stack(int order, int atomic)
flags = GFP_ATOMIC;
page = __get_free_pages(flags, order);
if(page == 0)
- return(0);
+ return 0;
stack_protections(page);
- return(page);
+ return page;
}
int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
@@ -98,15 +97,11 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
current->thread.request.u.thread.arg = arg;
pid = do_fork(CLONE_VM | CLONE_UNTRACED | flags, 0,
&current->thread.regs, 0, NULL, NULL);
- if(pid < 0)
- panic("do_fork failed in kernel_thread, errno = %d", pid);
- return(pid);
+ return pid;
}
-void set_current(void *t)
+static inline void set_current(struct task_struct *task)
{
- struct task_struct *task = t;
-
cpu_tasks[task_thread_info(task)->cpu] = ((struct cpu_task)
{ external_pid(task), task });
}
@@ -128,14 +123,16 @@ void *_switch_to(void *prev, void *next, void *last)
prev= current;
} while(current->thread.saved_task);
- return(current->thread.prev_sched);
+ return current->thread.prev_sched;
}
void interrupt_end(void)
{
- if(need_resched()) schedule();
- if(test_tsk_thread_flag(current, TIF_SIGPENDING)) do_signal();
+ if(need_resched())
+ schedule();
+ if(test_tsk_thread_flag(current, TIF_SIGPENDING))
+ do_signal();
}
void release_thread(struct task_struct *task)
@@ -150,7 +147,7 @@ void exit_thread(void)
void *get_current(void)
{
- return(current);
+ return current;
}
int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
@@ -188,15 +185,12 @@ void initial_thread_cb(void (*proc)(void *), void *arg)
kmalloc_ok = save_kmalloc_ok;
}
+#ifdef CONFIG_MODE_TT
unsigned long stack_sp(unsigned long page)
{
- return(page + PAGE_SIZE - sizeof(void *));
-}
-
-int current_pid(void)
-{
- return(current->pid);
+ return page + PAGE_SIZE - sizeof(void *);
}
+#endif
void default_idle(void)
{
@@ -221,11 +215,6 @@ void cpu_idle(void)
CHOOSE_MODE(init_idle_tt(), init_idle_skas());
}
-int page_size(void)
-{
- return(PAGE_SIZE);
-}
-
void *um_virt_to_phys(struct task_struct *task, unsigned long addr,
pte_t *pte_out)
{
@@ -236,68 +225,43 @@ void *um_virt_to_phys(struct task_struct *task, unsigned long addr,
pte_t ptent;
if(task->mm == NULL)
- return(ERR_PTR(-EINVAL));
+ return ERR_PTR(-EINVAL);
pgd = pgd_offset(task->mm, addr);
if(!pgd_present(*pgd))
- return(ERR_PTR(-EINVAL));
+ return ERR_PTR(-EINVAL);
pud = pud_offset(pgd, addr);
if(!pud_present(*pud))
- return(ERR_PTR(-EINVAL));
+ return ERR_PTR(-EINVAL);
pmd = pmd_offset(pud, addr);
if(!pmd_present(*pmd))
- return(ERR_PTR(-EINVAL));
+ return ERR_PTR(-EINVAL);
pte = pte_offset_kernel(pmd, addr);
ptent = *pte;
if(!pte_present(ptent))
- return(ERR_PTR(-EINVAL));
+ return ERR_PTR(-EINVAL);
if(pte_out != NULL)
*pte_out = ptent;
- return((void *) (pte_val(ptent) & PAGE_MASK) + (addr & ~PAGE_MASK));
+ return (void *) (pte_val(ptent) & PAGE_MASK) + (addr & ~PAGE_MASK);
}
char *current_cmd(void)
{
#if defined(CONFIG_SMP) || defined(CONFIG_HIGHMEM)
- return("(Unknown)");
+ return "(Unknown)";
#else
void *addr = um_virt_to_phys(current, current->mm->arg_start, NULL);
return IS_ERR(addr) ? "(Unknown)": __va((unsigned long) addr);
#endif
}
-void force_sigbus(void)
-{
- printk(KERN_ERR "Killing pid %d because of a lack of memory\n",
- current->pid);
- lock_kernel();
- sigaddset(&current->pending.signal, SIGBUS);
- recalc_sigpending();
- current->flags |= PF_SIGNALED;
- do_exit(SIGBUS | 0x80);
-}
-
void dump_thread(struct pt_regs *regs, struct user *u)
{
}
-void enable_hlt(void)
-{
- panic("enable_hlt");
-}
-
-EXPORT_SYMBOL(enable_hlt);
-
-void disable_hlt(void)
-{
- panic("disable_hlt");
-}
-
-EXPORT_SYMBOL(disable_hlt);
-
void *um_kmalloc(int size)
{
return kmalloc(size, GFP_KERNEL);
@@ -313,36 +277,17 @@ void *um_vmalloc(int size)
return vmalloc(size);
}
-void *um_vmalloc_atomic(int size)
-{
- return __vmalloc(size, GFP_ATOMIC | __GFP_HIGHMEM, PAGE_KERNEL);
-}
-
int __cant_sleep(void) {
return in_atomic() || irqs_disabled() || in_interrupt();
/* Is in_interrupt() really needed? */
}
-unsigned long get_fault_addr(void)
-{
- return((unsigned long) current->thread.fault_addr);
-}
-
-EXPORT_SYMBOL(get_fault_addr);
-
-void not_implemented(void)
-{
- printk(KERN_DEBUG "Something isn't implemented in here\n");
-}
-
-EXPORT_SYMBOL(not_implemented);
-
int user_context(unsigned long sp)
{
unsigned long stack;
stack = sp & (PAGE_MASK << CONFIG_KERNEL_STACK_ORDER);
- return(stack != (unsigned long) current_thread);
+ return stack != (unsigned long) current_thread;
}
extern exitcall_t __uml_exitcall_begin, __uml_exitcall_end;
@@ -363,22 +308,22 @@ char *uml_strdup(char *string)
int copy_to_user_proc(void __user *to, void *from, int size)
{
- return(copy_to_user(to, from, size));
+ return copy_to_user(to, from, size);
}
int copy_from_user_proc(void *to, void __user *from, int size)
{
- return(copy_from_user(to, from, size));
+ return copy_from_user(to, from, size);
}
int clear_user_proc(void __user *buf, int size)
{
- return(clear_user(buf, size));
+ return clear_user(buf, size);
}
int strlen_user_proc(char __user *str)
{
- return(strlen_user(str));
+ return strlen_user(str);
}
int smp_sigio_handler(void)
@@ -387,14 +332,14 @@ int smp_sigio_handler(void)
int cpu = current_thread->cpu;
IPI_handler(cpu);
if(cpu != 0)
- return(1);
+ return 1;
#endif
- return(0);
+ return 0;
}
int cpu(void)
{
- return(current_thread->cpu);
+ return current_thread->cpu;
}
static atomic_t using_sysemu = ATOMIC_INIT(0);
@@ -443,7 +388,7 @@ int __init make_proc_sysemu(void)
if (ent == NULL)
{
printk(KERN_WARNING "Failed to register /proc/sysemu\n");
- return(0);
+ return 0;
}
ent->read_proc = proc_read_sysemu;
diff --git a/arch/um/kernel/reboot.c b/arch/um/kernel/reboot.c
index f602623644a..7e4305a1fd3 100644
--- a/arch/um/kernel/reboot.c
+++ b/arch/um/kernel/reboot.c
@@ -6,7 +6,6 @@
#include "linux/module.h"
#include "linux/sched.h"
#include "asm/smp.h"
-#include "user_util.h"
#include "kern_util.h"
#include "kern.h"
#include "os.h"
diff --git a/arch/um/kernel/signal.c b/arch/um/kernel/signal.c
index 3c798cdde55..c4020c3d785 100644
--- a/arch/um/kernel/signal.c
+++ b/arch/um/kernel/signal.c
@@ -17,7 +17,6 @@
#include "asm/signal.h"
#include "asm/uaccess.h"
#include "asm/unistd.h"
-#include "user_util.h"
#include "asm/ucontext.h"
#include "kern_util.h"
#include "signal_kern.h"
diff --git a/arch/um/kernel/skas/exec.c b/arch/um/kernel/skas/exec.c
index 54b79595137..580eb646894 100644
--- a/arch/um/kernel/skas/exec.c
+++ b/arch/um/kernel/skas/exec.c
@@ -17,7 +17,17 @@
void flush_thread_skas(void)
{
- force_flush_all();
+ void *data = NULL;
+ unsigned long end = proc_mm ? task_size : CONFIG_STUB_START;
+ int ret;
+
+ ret = unmap(&current->mm->context.skas.id, 0, end, 1, &data);
+ if(ret){
+ printk("flush_thread_skas - clearing address space failed, "
+ "err = %d\n", ret);
+ force_sig(SIGKILL, current);
+ }
+
switch_mm_skas(&current->mm->context.skas.id);
}
diff --git a/arch/um/kernel/skas/process.c b/arch/um/kernel/skas/process.c
index ae4fa71d3b8..ef36facd8fe 100644
--- a/arch/um/kernel/skas/process.c
+++ b/arch/um/kernel/skas/process.c
@@ -13,9 +13,9 @@
#include "asm/uaccess.h"
#include "asm/atomic.h"
#include "kern_util.h"
+#include "as-layout.h"
#include "skas.h"
#include "os.h"
-#include "user_util.h"
#include "tlb.h"
#include "kern.h"
#include "mode.h"
diff --git a/arch/um/kernel/skas/tlb.c b/arch/um/kernel/skas/tlb.c
index 27eb29ce666..c0f0693743b 100644
--- a/arch/um/kernel/skas/tlb.c
+++ b/arch/um/kernel/skas/tlb.c
@@ -10,7 +10,6 @@
#include "asm/page.h"
#include "asm/pgtable.h"
#include "asm/mmu.h"
-#include "user_util.h"
#include "mem_user.h"
#include "mem.h"
#include "skas.h"
@@ -28,19 +27,17 @@ static int do_ops(union mm_context *mmu, struct host_vm_op *ops, int last,
switch(op->type){
case MMAP:
ret = map(&mmu->skas.id, op->u.mmap.addr,
- op->u.mmap.len, op->u.mmap.r, op->u.mmap.w,
- op->u.mmap.x, op->u.mmap.fd,
- op->u.mmap.offset, finished, flush);
+ op->u.mmap.len, op->u.mmap.prot,
+ op->u.mmap.fd, op->u.mmap.offset, finished,
+ flush);
break;
case MUNMAP:
- ret = unmap(&mmu->skas.id,
- (void *) op->u.munmap.addr,
+ ret = unmap(&mmu->skas.id, op->u.munmap.addr,
op->u.munmap.len, finished, flush);
break;
case MPROTECT:
ret = protect(&mmu->skas.id, op->u.mprotect.addr,
- op->u.mprotect.len, op->u.mprotect.r,
- op->u.mprotect.w, op->u.mprotect.x,
+ op->u.mprotect.len, op->u.mprotect.prot,
finished, flush);
break;
default:
@@ -92,6 +89,76 @@ void flush_tlb_mm_skas(struct mm_struct *mm)
void force_flush_all_skas(void)
{
- unsigned long end = proc_mm ? task_size : CONFIG_STUB_START;
- fix_range(current->mm, 0, end, 1);
+ struct mm_struct *mm = current->mm;
+ struct vm_area_struct *vma = mm->mmap;
+
+ while(vma != NULL) {
+ fix_range(mm, vma->vm_start, vma->vm_end, 1);
+ vma = vma->vm_next;
+ }
+}
+
+void flush_tlb_page_skas(struct vm_area_struct *vma, unsigned long address)
+{
+ pgd_t *pgd;
+ pud_t *pud;
+ pmd_t *pmd;
+ pte_t *pte;
+ struct mm_struct *mm = vma->vm_mm;
+ void *flush = NULL;
+ int r, w, x, prot, err = 0;
+ struct mm_id *mm_id;
+
+ pgd = pgd_offset(mm, address);
+ if(!pgd_present(*pgd))
+ goto kill;
+
+ pud = pud_offset(pgd, address);
+ if(!pud_present(*pud))
+ goto kill;
+
+ pmd = pmd_offset(pud, address);
+ if(!pmd_present(*pmd))
+ goto kill;
+
+ pte = pte_offset_kernel(pmd, address);
+
+ r = pte_read(*pte);
+ w = pte_write(*pte);
+ x = pte_exec(*pte);
+ if (!pte_young(*pte)) {
+ r = 0;
+ w = 0;
+ } else if (!pte_dirty(*pte)) {
+ w = 0;
+ }
+
+ mm_id = &mm->context.skas.id;
+ prot = ((r ? UM_PROT_READ : 0) | (w ? UM_PROT_WRITE : 0) |
+ (x ? UM_PROT_EXEC : 0));
+ if(pte_newpage(*pte)){
+ if(pte_present(*pte)){
+ unsigned long long offset;
+ int fd;
+
+ fd = phys_mapping(pte_val(*pte) & PAGE_MASK, &offset);
+ err = map(mm_id, address, PAGE_SIZE, prot, fd, offset,
+ 1, &flush);
+ }
+ else err = unmap(mm_id, address, PAGE_SIZE, 1, &flush);
+ }
+ else if(pte_newprot(*pte))
+ err = protect(mm_id, address, PAGE_SIZE, prot, 1, &flush);
+
+ if(err)
+ goto kill;
+
+ *pte = pte_mkuptodate(*pte);
+
+ return;
+
+kill:
+ printk("Failed to flush page for address 0x%lx\n", address);
+ force_sig(SIGKILL, current);
}
+
diff --git a/arch/um/kernel/smp.c b/arch/um/kernel/smp.c
index 759b0705316..e6a7778006a 100644
--- a/arch/um/kernel/smp.c
+++ b/arch/um/kernel/smp.c
@@ -21,7 +21,6 @@ DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
#include "asm/smp.h"
#include "asm/processor.h"
#include "asm/spinlock.h"
-#include "user_util.h"
#include "kern_util.h"
#include "kern.h"
#include "irq_user.h"
@@ -90,7 +89,7 @@ static int idle_proc(void *cpup)
cpu_set(cpu, cpu_online_map);
default_idle();
- return(0);
+ return 0;
}
static struct task_struct *idle_thread(int cpu)
@@ -98,8 +97,8 @@ static struct task_struct *idle_thread(int cpu)
struct task_struct *new_task;
unsigned char c;
- current->thread.request.u.thread.proc = idle_proc;
- current->thread.request.u.thread.arg = (void *) cpu;
+ current->thread.request.u.thread.proc = idle_proc;
+ current->thread.request.u.thread.arg = (void *) cpu;
new_task = fork_idle(cpu);
if(IS_ERR(new_task))
panic("copy_process failed in idle_thread, error = %ld",
@@ -110,9 +109,9 @@ static struct task_struct *idle_thread(int cpu)
.task = new_task } );
idle_threads[cpu] = new_task;
CHOOSE_MODE(os_write_file(new_task->thread.mode.tt.switch_pipe[1], &c,
- sizeof(c)),
+ sizeof(c)),
({ panic("skas mode doesn't support SMP"); }));
- return(new_task);
+ return new_task;
}
void smp_prepare_cpus(unsigned int maxcpus)
@@ -163,13 +162,13 @@ int __cpu_up(unsigned int cpu)
cpu_set(cpu, smp_commenced_mask);
while (!cpu_isset(cpu, cpu_online_map))
mb();
- return(0);
+ return 0;
}
int setup_profiling_timer(unsigned int multiplier)
{
printk(KERN_INFO "setup_profiling_timer\n");
- return(0);
+ return 0;
}
void smp_call_function_slave(int cpu);
@@ -205,7 +204,7 @@ void IPI_handler(int cpu)
int hard_smp_processor_id(void)
{
- return(pid_to_processor_id(os_getpid()));
+ return pid_to_processor_id(os_getpid());
}
static DEFINE_SPINLOCK(call_lock);
@@ -254,14 +253,3 @@ int smp_call_function(void (*_func)(void *info), void *_info, int nonatomic,
}
#endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/kernel/syscall.c b/arch/um/kernel/syscall.c
index 2828c528322..237c4eab7cf 100644
--- a/arch/um/kernel/syscall.c
+++ b/arch/um/kernel/syscall.c
@@ -18,7 +18,6 @@
#include "asm/mman.h"
#include "asm/uaccess.h"
#include "kern_util.h"
-#include "user_util.h"
#include "sysdep/syscalls.h"
#include "mode_kern.h"
#include "choose-mode.h"
diff --git a/arch/um/kernel/sysrq.c b/arch/um/kernel/sysrq.c
index f9e02b31a97..93263571d81 100644
--- a/arch/um/kernel/sysrq.c
+++ b/arch/um/kernel/sysrq.c
@@ -10,7 +10,6 @@
#include "asm/page.h"
#include "asm/processor.h"
#include "sysrq.h"
-#include "user_util.h"
/* Catch non-i386 SUBARCH's. */
#if !defined(CONFIG_UML_X86) || defined(CONFIG_64BIT)
diff --git a/arch/um/kernel/time.c b/arch/um/kernel/time.c
index b1f8b075241..cd7349de8ca 100644
--- a/arch/um/kernel/time.c
+++ b/arch/um/kernel/time.c
@@ -18,7 +18,6 @@
#include "asm/param.h"
#include "asm/current.h"
#include "kern_util.h"
-#include "user_util.h"
#include "mode.h"
#include "os.h"
@@ -35,8 +34,8 @@ unsigned long long sched_clock(void)
return (unsigned long long)jiffies_64 * (1000000000 / HZ);
}
-static unsigned long long prev_nsecs[NR_CPUS];
#ifdef CONFIG_UML_REAL_TIME_CLOCK
+static unsigned long long prev_nsecs[NR_CPUS];
static long long delta[NR_CPUS]; /* Deviation per interval */
#endif
@@ -95,7 +94,12 @@ irqreturn_t um_timer(int irq, void *dev)
do_timer(1);
+#ifdef CONFIG_UML_REAL_TIME_CLOCK
nsecs = get_time();
+#else
+ nsecs = (unsigned long long) xtime.tv_sec * BILLION + xtime.tv_nsec +
+ BILLION / HZ;
+#endif
xtime.tv_sec = nsecs / NSEC_PER_SEC;
xtime.tv_nsec = nsecs - xtime.tv_sec * NSEC_PER_SEC;
@@ -128,13 +132,18 @@ void time_init(void)
nsecs = os_nsecs();
set_normalized_timespec(&wall_to_monotonic, -nsecs / BILLION,
-nsecs % BILLION);
+ set_normalized_timespec(&xtime, nsecs / BILLION, nsecs % BILLION);
late_time_init = register_timer;
}
void do_gettimeofday(struct timeval *tv)
{
+#ifdef CONFIG_UML_REAL_TIME_CLOCK
unsigned long long nsecs = get_time();
-
+#else
+ unsigned long long nsecs = (unsigned long long) xtime.tv_sec * BILLION +
+ xtime.tv_nsec;
+#endif
tv->tv_sec = nsecs / NSEC_PER_SEC;
/* Careful about calculations here - this was originally done as
* (nsecs - tv->tv_sec * NSEC_PER_SEC) / NSEC_PER_USEC
diff --git a/arch/um/kernel/tlb.c b/arch/um/kernel/tlb.c
index 54a5ff25645..8a8d5285144 100644
--- a/arch/um/kernel/tlb.c
+++ b/arch/um/kernel/tlb.c
@@ -6,17 +6,18 @@
#include "linux/mm.h"
#include "asm/page.h"
#include "asm/pgalloc.h"
+#include "asm/pgtable.h"
#include "asm/tlbflush.h"
#include "choose-mode.h"
#include "mode_kern.h"
-#include "user_util.h"
+#include "as-layout.h"
#include "tlb.h"
#include "mem.h"
#include "mem_user.h"
#include "os.h"
static int add_mmap(unsigned long virt, unsigned long phys, unsigned long len,
- int r, int w, int x, struct host_vm_op *ops, int *index,
+ unsigned int prot, struct host_vm_op *ops, int *index,
int last_filled, union mm_context *mmu, void **flush,
int (*do_ops)(union mm_context *, struct host_vm_op *,
int, int, void **))
@@ -30,8 +31,7 @@ static int add_mmap(unsigned long virt, unsigned long phys, unsigned long len,
last = &ops[*index];
if((last->type == MMAP) &&
(last->u.mmap.addr + last->u.mmap.len == virt) &&
- (last->u.mmap.r == r) && (last->u.mmap.w == w) &&
- (last->u.mmap.x == x) && (last->u.mmap.fd == fd) &&
+ (last->u.mmap.prot == prot) && (last->u.mmap.fd == fd) &&
(last->u.mmap.offset + last->u.mmap.len == offset)){
last->u.mmap.len += len;
return 0;
@@ -47,9 +47,7 @@ static int add_mmap(unsigned long virt, unsigned long phys, unsigned long len,
.u = { .mmap = {
.addr = virt,
.len = len,
- .r = r,
- .w = w,
- .x = x,
+ .prot = prot,
.fd = fd,
.offset = offset }
} });
@@ -86,8 +84,8 @@ static int add_munmap(unsigned long addr, unsigned long len,
return ret;
}
-static int add_mprotect(unsigned long addr, unsigned long len, int r, int w,
- int x, struct host_vm_op *ops, int *index,
+static int add_mprotect(unsigned long addr, unsigned long len,
+ unsigned int prot, struct host_vm_op *ops, int *index,
int last_filled, union mm_context *mmu, void **flush,
int (*do_ops)(union mm_context *, struct host_vm_op *,
int, int, void **))
@@ -99,8 +97,7 @@ static int add_mprotect(unsigned long addr, unsigned long len, int r, int w,
last = &ops[*index];
if((last->type == MPROTECT) &&
(last->u.mprotect.addr + last->u.mprotect.len == addr) &&
- (last->u.mprotect.r == r) && (last->u.mprotect.w == w) &&
- (last->u.mprotect.x == x)){
+ (last->u.mprotect.prot == prot)){
last->u.mprotect.len += len;
return 0;
}
@@ -115,114 +112,145 @@ static int add_mprotect(unsigned long addr, unsigned long len, int r, int w,
.u = { .mprotect = {
.addr = addr,
.len = len,
- .r = r,
- .w = w,
- .x = x } } });
+ .prot = prot } } });
return ret;
}
#define ADD_ROUND(n, inc) (((n) + (inc)) & ~((inc) - 1))
+static inline int update_pte_range(pmd_t *pmd, unsigned long addr,
+ unsigned long end, struct host_vm_op *ops,
+ int last_op, int *op_index, int force,
+ union mm_context *mmu, void **flush,
+ int (*do_ops)(union mm_context *,
+ struct host_vm_op *, int, int,
+ void **))
+{
+ pte_t *pte;
+ int r, w, x, prot, ret = 0;
+
+ pte = pte_offset_kernel(pmd, addr);
+ do {
+ r = pte_read(*pte);
+ w = pte_write(*pte);
+ x = pte_exec(*pte);
+ if (!pte_young(*pte)) {
+ r = 0;
+ w = 0;
+ } else if (!pte_dirty(*pte)) {
+ w = 0;
+ }
+ prot = ((r ? UM_PROT_READ : 0) | (w ? UM_PROT_WRITE : 0) |
+ (x ? UM_PROT_EXEC : 0));
+ if(force || pte_newpage(*pte)){
+ if(pte_present(*pte))
+ ret = add_mmap(addr, pte_val(*pte) & PAGE_MASK,
+ PAGE_SIZE, prot, ops, op_index,
+ last_op, mmu, flush, do_ops);
+ else ret = add_munmap(addr, PAGE_SIZE, ops, op_index,
+ last_op, mmu, flush, do_ops);
+ }
+ else if(pte_newprot(*pte))
+ ret = add_mprotect(addr, PAGE_SIZE, prot, ops, op_index,
+ last_op, mmu, flush, do_ops);
+ *pte = pte_mkuptodate(*pte);
+ } while (pte++, addr += PAGE_SIZE, ((addr != end) && !ret));
+ return ret;
+}
+
+static inline int update_pmd_range(pud_t *pud, unsigned long addr,
+ unsigned long end, struct host_vm_op *ops,
+ int last_op, int *op_index, int force,
+ union mm_context *mmu, void **flush,
+ int (*do_ops)(union mm_context *,
+ struct host_vm_op *, int, int,
+ void **))
+{
+ pmd_t *pmd;
+ unsigned long next;
+ int ret = 0;
+
+ pmd = pmd_offset(pud, addr);
+ do {
+ next = pmd_addr_end(addr, end);
+ if(!pmd_present(*pmd)){
+ if(force || pmd_newpage(*pmd)){
+ ret = add_munmap(addr, next - addr, ops,
+ op_index, last_op, mmu,
+ flush, do_ops);
+ pmd_mkuptodate(*pmd);
+ }
+ }
+ else ret = update_pte_range(pmd, addr, next, ops, last_op,
+ op_index, force, mmu, flush,
+ do_ops);
+ } while (pmd++, addr = next, ((addr != end) && !ret));
+ return ret;
+}
+
+static inline int update_pud_range(pgd_t *pgd, unsigned long addr,
+ unsigned long end, struct host_vm_op *ops,
+ int last_op, int *op_index, int force,
+ union mm_context *mmu, void **flush,
+ int (*do_ops)(union mm_context *,
+ struct host_vm_op *, int, int,
+ void **))
+{
+ pud_t *pud;
+ unsigned long next;
+ int ret = 0;
+
+ pud = pud_offset(pgd, addr);
+ do {
+ next = pud_addr_end(addr, end);
+ if(!pud_present(*pud)){
+ if(force || pud_newpage(*pud)){
+ ret = add_munmap(addr, next - addr, ops,
+ op_index, last_op, mmu,
+ flush, do_ops);
+ pud_mkuptodate(*pud);
+ }
+ }
+ else ret = update_pmd_range(pud, addr, next, ops, last_op,
+ op_index, force, mmu, flush,
+ do_ops);
+ } while (pud++, addr = next, ((addr != end) && !ret));
+ return ret;
+}
+
void fix_range_common(struct mm_struct *mm, unsigned long start_addr,
unsigned long end_addr, int force,
int (*do_ops)(union mm_context *, struct host_vm_op *,
int, int, void **))
{
- pgd_t *npgd;
- pud_t *npud;
- pmd_t *npmd;
- pte_t *npte;
+ pgd_t *pgd;
union mm_context *mmu = &mm->context;
- unsigned long addr, end;
- int r, w, x;
struct host_vm_op ops[1];
+ unsigned long addr = start_addr, next;
+ int ret = 0, last_op = ARRAY_SIZE(ops) - 1, op_index = -1;
void *flush = NULL;
- int op_index = -1, last_op = ARRAY_SIZE(ops) - 1;
- int ret = 0;
-
- if(mm == NULL)
- return;
ops[0].type = NONE;
- for(addr = start_addr; addr < end_addr && !ret;){
- npgd = pgd_offset(mm, addr);
- if(!pgd_present(*npgd)){
- end = ADD_ROUND(addr, PGDIR_SIZE);
- if(end > end_addr)
- end = end_addr;
- if(force || pgd_newpage(*npgd)){
- ret = add_munmap(addr, end - addr, ops,
- &op_index, last_op, mmu,
- &flush, do_ops);
- pgd_mkuptodate(*npgd);
- }
- addr = end;
- continue;
- }
-
- npud = pud_offset(npgd, addr);
- if(!pud_present(*npud)){
- end = ADD_ROUND(addr, PUD_SIZE);
- if(end > end_addr)
- end = end_addr;
- if(force || pud_newpage(*npud)){
- ret = add_munmap(addr, end - addr, ops,
- &op_index, last_op, mmu,
- &flush, do_ops);
- pud_mkuptodate(*npud);
- }
- addr = end;
- continue;
- }
-
- npmd = pmd_offset(npud, addr);
- if(!pmd_present(*npmd)){
- end = ADD_ROUND(addr, PMD_SIZE);
- if(end > end_addr)
- end = end_addr;
- if(force || pmd_newpage(*npmd)){
- ret = add_munmap(addr, end - addr, ops,
+ pgd = pgd_offset(mm, addr);
+ do {
+ next = pgd_addr_end(addr, end_addr);
+ if(!pgd_present(*pgd)){
+ if (force || pgd_newpage(*pgd)){
+ ret = add_munmap(addr, next - addr, ops,
&op_index, last_op, mmu,
&flush, do_ops);
- pmd_mkuptodate(*npmd);
+ pgd_mkuptodate(*pgd);
}
- addr = end;
- continue;
- }
-
- npte = pte_offset_kernel(npmd, addr);
- r = pte_read(*npte);
- w = pte_write(*npte);
- x = pte_exec(*npte);
- if (!pte_young(*npte)) {
- r = 0;
- w = 0;
- } else if (!pte_dirty(*npte)) {
- w = 0;
- }
- if(force || pte_newpage(*npte)){
- if(pte_present(*npte))
- ret = add_mmap(addr,
- pte_val(*npte) & PAGE_MASK,
- PAGE_SIZE, r, w, x, ops,
- &op_index, last_op, mmu,
- &flush, do_ops);
- else ret = add_munmap(addr, PAGE_SIZE, ops,
- &op_index, last_op, mmu,
- &flush, do_ops);
}
- else if(pte_newprot(*npte))
- ret = add_mprotect(addr, PAGE_SIZE, r, w, x, ops,
- &op_index, last_op, mmu,
- &flush, do_ops);
+ else ret = update_pud_range(pgd, addr, next, ops, last_op,
+ &op_index, force, mmu, &flush,
+ do_ops);
+ } while (pgd++, addr = next, ((addr != end_addr) && !ret));
- *npte = pte_mkuptodate(*npte);
- addr += PAGE_SIZE;
- }
if(!ret)
ret = (*do_ops)(mmu, ops, op_index, 1, &flush);
-/* This is not an else because ret is modified above */
+ /* This is not an else because ret is modified above */
if(ret) {
printk("fix_range_common: failed, killing current process\n");
force_sig(SIGKILL, current);
@@ -343,12 +371,6 @@ pte_t *addr_pte(struct task_struct *task, unsigned long addr)
return(pte_offset_map(pmd, addr));
}
-void flush_tlb_page(struct vm_area_struct *vma, unsigned long address)
-{
- address &= PAGE_MASK;
- flush_tlb_range(vma, address, address + PAGE_SIZE);
-}
-
void flush_tlb_all(void)
{
flush_tlb_mm(current->mm);
diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c
index 26f15c45857..abab90c3803 100644
--- a/arch/um/kernel/trap.c
+++ b/arch/um/kernel/trap.c
@@ -18,8 +18,9 @@
#include "asm/current.h"
#include "asm/irq.h"
#include "sysdep/sigcontext.h"
-#include "user_util.h"
#include "kern_util.h"
+#include "as-layout.h"
+#include "arch.h"
#include "kern.h"
#include "chan_kern.h"
#include "mconsole_kern.h"
@@ -71,8 +72,8 @@ good_area:
goto out;
/* Don't require VM_READ|VM_EXEC for write faults! */
- if(!is_write && !(vma->vm_flags & (VM_READ | VM_EXEC)))
- goto out;
+ if(!is_write && !(vma->vm_flags & (VM_READ | VM_EXEC)))
+ goto out;
do {
survive:
@@ -156,20 +157,23 @@ static void segv_handler(int sig, union uml_pt_regs *regs)
* the info in the regs. A pointer to the info then would
* give us bad data!
*/
-unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, void *sc)
+unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user,
+ union uml_pt_regs *regs)
{
struct siginfo si;
void *catcher;
int err;
- int is_write = FAULT_WRITE(fi);
- unsigned long address = FAULT_ADDRESS(fi);
+ int is_write = FAULT_WRITE(fi);
+ unsigned long address = FAULT_ADDRESS(fi);
- if(!is_user && (address >= start_vm) && (address < end_vm)){
- flush_tlb_kernel_vm();
- return(0);
- }
- else if(current->mm == NULL)
- panic("Segfault with no mm");
+ if(!is_user && (address >= start_vm) && (address < end_vm)){
+ flush_tlb_kernel_vm();
+ return 0;
+ }
+ else if(current->mm == NULL) {
+ show_regs(container_of(regs, struct pt_regs, regs));
+ panic("Segfault with no mm");
+ }
if (SEGV_IS_FIXABLE(&fi) || SEGV_MAYBE_FIXABLE(&fi))
err = handle_page_fault(address, ip, is_write, is_user, &si.si_code);
@@ -182,26 +186,28 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, void *sc)
catcher = current->thread.fault_catcher;
if(!err)
- return(0);
+ return 0;
else if(catcher != NULL){
current->thread.fault_addr = (void *) address;
do_longjmp(catcher, 1);
}
else if(current->thread.fault_addr != NULL)
panic("fault_addr set but no fault catcher");
- else if(!is_user && arch_fixup(ip, sc))
- return(0);
+ else if(!is_user && arch_fixup(ip, regs))
+ return 0;
- if(!is_user)
+ if(!is_user) {
+ show_regs(container_of(regs, struct pt_regs, regs));
panic("Kernel mode fault at addr 0x%lx, ip 0x%lx",
address, ip);
+ }
if (err == -EACCES) {
si.si_signo = SIGBUS;
si.si_errno = 0;
si.si_code = BUS_ADRERR;
si.si_addr = (void __user *)address;
- current->thread.arch.faultinfo = fi;
+ current->thread.arch.faultinfo = fi;
force_sig_info(SIGBUS, &si, current);
} else if (err == -ENOMEM) {
printk("VM: killing process %s\n", current->comm);
@@ -210,10 +216,10 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, void *sc)
BUG_ON(err != -EFAULT);
si.si_signo = SIGSEGV;
si.si_addr = (void __user *) address;
- current->thread.arch.faultinfo = fi;
+ current->thread.arch.faultinfo = fi;
force_sig_info(SIGSEGV, &si, current);
}
- return(0);
+ return 0;
}
void relay_signal(int sig, union uml_pt_regs *regs)
@@ -223,12 +229,12 @@ void relay_signal(int sig, union uml_pt_regs *regs)
if(!UPT_IS_USER(regs)){
if(sig == SIGBUS)
- printk("Bus error - the /dev/shm or /tmp mount likely "
- "just ran out of space\n");
+ printk("Bus error - the host /dev/shm or /tmp mount "
+ "likely just ran out of space\n");
panic("Kernel mode signal %d", sig);
}
- current->thread.arch.faultinfo = *UPT_FAULTINFO(regs);
+ current->thread.arch.faultinfo = *UPT_FAULTINFO(regs);
force_sig(sig, current);
}
diff --git a/arch/um/kernel/tt/exec_kern.c b/arch/um/kernel/tt/exec_kern.c
index ad66df17d9d..98e21743e60 100644
--- a/arch/um/kernel/tt/exec_kern.c
+++ b/arch/um/kernel/tt/exec_kern.c
@@ -10,7 +10,6 @@
#include "asm/uaccess.h"
#include "asm/pgalloc.h"
#include "asm/tlbflush.h"
-#include "user_util.h"
#include "kern_util.h"
#include "irq_user.h"
#include "mem_user.h"
diff --git a/arch/um/kernel/tt/exec_user.c b/arch/um/kernel/tt/exec_user.c
index a92c02ff2ce..7b5f2181cf5 100644
--- a/arch/um/kernel/tt/exec_user.c
+++ b/arch/um/kernel/tt/exec_user.c
@@ -10,7 +10,6 @@
#include <errno.h>
#include <sys/wait.h>
#include <signal.h>
-#include "user_util.h"
#include "kern_util.h"
#include "user.h"
#include "ptrace_user.h"
diff --git a/arch/um/kernel/tt/gdb.c b/arch/um/kernel/tt/gdb.c
index 8eba8f7dca6..030e4658f36 100644
--- a/arch/um/kernel/tt/gdb.c
+++ b/arch/um/kernel/tt/gdb.c
@@ -17,7 +17,6 @@
#include "user.h"
#include "debug.h"
#include "kern_util.h"
-#include "user_util.h"
#include "tt.h"
#include "sysdep/thread.h"
#include "os.h"
@@ -115,6 +114,8 @@ struct gdb_data {
int err;
};
+extern char *linux_prog;
+
static void config_gdb_cb(void *arg)
{
struct gdb_data *data = arg;
diff --git a/arch/um/kernel/tt/include/mode_kern-tt.h b/arch/um/kernel/tt/include/mode_kern-tt.h
deleted file mode 100644
index 2a35b15c5fe..00000000000
--- a/arch/um/kernel/tt/include/mode_kern-tt.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#ifndef __TT_MODE_KERN_H__
-#define __TT_MODE_KERN_H__
-
-#include "linux/sched.h"
-#include "asm/page.h"
-#include "asm/ptrace.h"
-#include "asm/uaccess.h"
-
-extern void switch_to_tt(void *prev, void *next);
-extern void flush_thread_tt(void);
-extern void start_thread_tt(struct pt_regs *regs, unsigned long eip,
- unsigned long esp);
-extern int copy_thread_tt(int nr, unsigned long clone_flags, unsigned long sp,
- unsigned long stack_top, struct task_struct *p,
- struct pt_regs *regs);
-extern void release_thread_tt(struct task_struct *task);
-extern void initial_thread_cb_tt(void (*proc)(void *), void *arg);
-extern void init_idle_tt(void);
-extern void flush_tlb_kernel_range_tt(unsigned long start, unsigned long end);
-extern void flush_tlb_kernel_vm_tt(void);
-extern void __flush_tlb_one_tt(unsigned long addr);
-extern void flush_tlb_range_tt(struct vm_area_struct *vma,
- unsigned long start, unsigned long end);
-extern void flush_tlb_mm_tt(struct mm_struct *mm);
-extern void force_flush_all_tt(void);
-extern long execute_syscall_tt(void *r);
-extern void before_mem_tt(unsigned long brk_start);
-extern unsigned long set_task_sizes_tt(int arg, unsigned long *host_size_out,
- unsigned long *task_size_out);
-extern int start_uml_tt(void);
-extern int external_pid_tt(struct task_struct *task);
-extern int thread_pid_tt(struct task_struct *task);
-
-#define kmem_end_tt (host_task_size - ABOVE_KMEM)
-
-#endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/kernel/tt/mem.c b/arch/um/kernel/tt/mem.c
index 4d1929dfa28..d0c3c4975f2 100644
--- a/arch/um/kernel/tt/mem.c
+++ b/arch/um/kernel/tt/mem.c
@@ -8,7 +8,6 @@
#include "asm/uaccess.h"
#include "mem_user.h"
#include "kern_util.h"
-#include "user_util.h"
#include "kern.h"
#include "tt.h"
diff --git a/arch/um/kernel/tt/mem_user.c b/arch/um/kernel/tt/mem_user.c
index 03e58989538..9774f6360c3 100644
--- a/arch/um/kernel/tt/mem_user.c
+++ b/arch/um/kernel/tt/mem_user.c
@@ -11,7 +11,6 @@
#include <sys/mman.h>
#include "tt.h"
#include "mem_user.h"
-#include "user_util.h"
#include "os.h"
void remap_data(void *segment_start, void *segment_end, int w)
diff --git a/arch/um/kernel/tt/process_kern.c b/arch/um/kernel/tt/process_kern.c
index 1e86f0bfef7..c631303cb80 100644
--- a/arch/um/kernel/tt/process_kern.c
+++ b/arch/um/kernel/tt/process_kern.c
@@ -14,7 +14,6 @@
#include "asm/tlbflush.h"
#include "irq_user.h"
#include "kern_util.h"
-#include "user_util.h"
#include "os.h"
#include "kern.h"
#include "sigcontext.h"
@@ -65,7 +64,8 @@ void switch_to_tt(void *prev, void *next)
if(from->thread.mode.tt.switch_pipe[0] == -1)
os_kill_process(os_getpid(), 0);
- err = os_read_file(from->thread.mode.tt.switch_pipe[0], &c, sizeof(c));
+ err = os_read_file(from->thread.mode.tt.switch_pipe[0], &c,
+ sizeof(c));
if(err != sizeof(c))
panic("read of switch_pipe failed, errno = %d", -err);
diff --git a/arch/um/kernel/tt/ptproxy/proxy.c b/arch/um/kernel/tt/ptproxy/proxy.c
index 58800c50b10..420c23f311f 100644
--- a/arch/um/kernel/tt/ptproxy/proxy.c
+++ b/arch/um/kernel/tt/ptproxy/proxy.c
@@ -26,7 +26,6 @@ Jeff Dike (jdike@karaya.com) : Modified for integration into uml
#include "sysdep.h"
#include "wait.h"
-#include "user_util.h"
#include "user.h"
#include "os.h"
#include "tempfile.h"
@@ -339,11 +338,12 @@ int start_debugger(char *prog, int startup, int stop, int *fd_out)
"err = %d\n", -fd);
exit(1);
}
- os_write_file(fd, gdb_init_string, sizeof(gdb_init_string) - 1);
+ os_write_file(fd, gdb_init_string,
+ sizeof(gdb_init_string) - 1);
if(startup){
if(stop){
os_write_file(fd, "b start_kernel\n",
- strlen("b start_kernel\n"));
+ strlen("b start_kernel\n"));
}
os_write_file(fd, "c\n", strlen("c\n"));
}
diff --git a/arch/um/kernel/tt/ptproxy/ptrace.c b/arch/um/kernel/tt/ptproxy/ptrace.c
index 03774427d46..4b4f6179b21 100644
--- a/arch/um/kernel/tt/ptproxy/ptrace.c
+++ b/arch/um/kernel/tt/ptproxy/ptrace.c
@@ -16,7 +16,6 @@ Jeff Dike (jdike@karaya.com) : Modified for integration into uml
#include "ptproxy.h"
#include "debug.h"
-#include "user_util.h"
#include "kern_util.h"
#include "ptrace_user.h"
#include "tt.h"
diff --git a/arch/um/kernel/tt/ptproxy/sysdep.c b/arch/um/kernel/tt/ptproxy/sysdep.c
index 99f178319d0..e0e1ab0588a 100644
--- a/arch/um/kernel/tt/ptproxy/sysdep.c
+++ b/arch/um/kernel/tt/ptproxy/sysdep.c
@@ -13,7 +13,6 @@ terms and conditions.
#include <sys/types.h>
#include <linux/unistd.h>
#include "ptrace_user.h"
-#include "user_util.h"
#include "user.h"
#include "os.h"
diff --git a/arch/um/kernel/tt/ptproxy/wait.c b/arch/um/kernel/tt/ptproxy/wait.c
index 12f6319d8d7..bdd4af4b65f 100644
--- a/arch/um/kernel/tt/ptproxy/wait.c
+++ b/arch/um/kernel/tt/ptproxy/wait.c
@@ -13,7 +13,6 @@ terms and conditions.
#include "ptproxy.h"
#include "sysdep.h"
#include "wait.h"
-#include "user_util.h"
#include "ptrace_user.h"
#include "sysdep/ptrace.h"
#include "sysdep/sigcontext.h"
diff --git a/arch/um/kernel/tt/syscall_user.c b/arch/um/kernel/tt/syscall_user.c
index 902987bf379..f52b47aff1d 100644
--- a/arch/um/kernel/tt/syscall_user.c
+++ b/arch/um/kernel/tt/syscall_user.c
@@ -11,7 +11,6 @@
#include "sigcontext.h"
#include "ptrace_user.h"
#include "task.h"
-#include "user_util.h"
#include "kern_util.h"
#include "syscall.h"
#include "tt.h"
diff --git a/arch/um/kernel/tt/tlb.c b/arch/um/kernel/tt/tlb.c
index ae6217c8613..7caa24fe05d 100644
--- a/arch/um/kernel/tt/tlb.c
+++ b/arch/um/kernel/tt/tlb.c
@@ -12,7 +12,6 @@
#include "asm/pgtable.h"
#include "asm/uaccess.h"
#include "asm/tlbflush.h"
-#include "user_util.h"
#include "mem_user.h"
#include "os.h"
#include "tlb.h"
diff --git a/arch/um/kernel/tt/tracer.c b/arch/um/kernel/tt/tracer.c
index b9195355075..c23588393f6 100644
--- a/arch/um/kernel/tt/tracer.c
+++ b/arch/um/kernel/tt/tracer.c
@@ -19,7 +19,6 @@
#include "sigcontext.h"
#include "sysdep/sigcontext.h"
#include "os.h"
-#include "user_util.h"
#include "mem_user.h"
#include "process.h"
#include "kern_util.h"
diff --git a/arch/um/kernel/tt/trap_user.c b/arch/um/kernel/tt/trap_user.c
index b5d9d64d91e..3032eb5e246 100644
--- a/arch/um/kernel/tt/trap_user.c
+++ b/arch/um/kernel/tt/trap_user.c
@@ -8,7 +8,6 @@
#include <signal.h>
#include "sysdep/ptrace.h"
#include "sysdep/sigcontext.h"
-#include "user_util.h"
#include "kern_util.h"
#include "task.h"
#include "tt.h"
diff --git a/arch/um/kernel/tt/uaccess_user.c b/arch/um/kernel/tt/uaccess_user.c
index ed1abcf4d05..0e5c82c5e5b 100644
--- a/arch/um/kernel/tt/uaccess_user.c
+++ b/arch/um/kernel/tt/uaccess_user.c
@@ -5,7 +5,6 @@
*/
#include <string.h>
-#include "user_util.h"
#include "uml_uaccess.h"
#include "task.h"
#include "kern_util.h"
diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c
index 89c6dba731f..1cf954a47fd 100644
--- a/arch/um/kernel/um_arch.c
+++ b/arch/um/kernel/um_arch.c
@@ -17,6 +17,7 @@
#include "linux/seq_file.h"
#include "linux/delay.h"
#include "linux/module.h"
+#include "linux/utsname.h"
#include "asm/page.h"
#include "asm/pgtable.h"
#include "asm/ptrace.h"
@@ -25,8 +26,9 @@
#include "asm/setup.h"
#include "ubd_user.h"
#include "asm/current.h"
-#include "user_util.h"
#include "kern_util.h"
+#include "as-layout.h"
+#include "arch.h"
#include "kern.h"
#include "mem_user.h"
#include "mem.h"
@@ -42,7 +44,7 @@
#define DEFAULT_COMMAND_LINE "root=98:0"
-/* Changed in linux_main and setup_arch, which run before SMP is started */
+/* Changed in add_arg and setup_arch, which run before SMP is started */
static char __initdata command_line[COMMAND_LINE_SIZE] = { 0 };
static void __init add_arg(char *arg)
@@ -56,17 +58,25 @@ static void __init add_arg(char *arg)
strcat(command_line, arg);
}
-struct cpuinfo_um boot_cpu_data = {
+/*
+ * These fields are initialized at boot time and not changed.
+ * XXX This structure is used only in the non-SMP case. Maybe this
+ * should be moved to smp.c.
+ */
+struct cpuinfo_um boot_cpu_data = {
.loops_per_jiffy = 0,
.ipi_pipe = { -1, -1 }
};
unsigned long thread_saved_pc(struct task_struct *task)
{
- return(os_process_pc(CHOOSE_MODE_PROC(thread_pid_tt, thread_pid_skas,
- task)));
+ return os_process_pc(CHOOSE_MODE_PROC(thread_pid_tt, thread_pid_skas,
+ task));
}
+/* Changed in setup_arch, which is called in early boot */
+static char host_info[(__NEW_UTS_LEN + 1) * 5];
+
static int show_cpuinfo(struct seq_file *m, void *v)
{
int index = 0;
@@ -86,7 +96,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
loops_per_jiffy/(500000/HZ),
(loops_per_jiffy/(5000/HZ)) % 100);
- return(0);
+ return 0;
}
static void *c_start(struct seq_file *m, loff_t *pos)
@@ -114,14 +124,12 @@ const struct seq_operations cpuinfo_op = {
/* Set in linux_main */
unsigned long host_task_size;
unsigned long task_size;
-
-unsigned long uml_start;
-
-/* Set in early boot */
unsigned long uml_physmem;
-unsigned long uml_reserved;
+unsigned long uml_reserved; /* Also modified in mem_init */
unsigned long start_vm;
unsigned long end_vm;
+
+/* Set in uml_ncpus_setup */
int ncpus = 1;
#ifdef CONFIG_CMDLINE_ON_HOST
@@ -135,6 +143,8 @@ static char *argv1_end = NULL;
/* Set in early boot */
static int have_root __initdata = 0;
+
+/* Set in uml_mem_setup and modified in linux_main */
long long physmem_size = 32 * 1024 * 1024;
void set_cmdline(char *cmd)
@@ -212,12 +222,12 @@ __uml_setup("debug", no_skas_debug_setup,
#ifdef CONFIG_SMP
static int __init uml_ncpus_setup(char *line, int *add)
{
- if (!sscanf(line, "%d", &ncpus)) {
- printf("Couldn't parse [%s]\n", line);
- return -1;
- }
+ if (!sscanf(line, "%d", &ncpus)) {
+ printf("Couldn't parse [%s]\n", line);
+ return -1;
+ }
- return 0;
+ return 0;
}
__uml_setup("ncpus=", uml_ncpus_setup,
@@ -234,7 +244,7 @@ static int force_tt = 0;
static int __init mode_tt_setup(char *line, int *add)
{
force_tt = 1;
- return(0);
+ return 0;
}
#else
@@ -245,7 +255,7 @@ static int __init mode_tt_setup(char *line, int *add)
static int __init mode_tt_setup(char *line, int *add)
{
printf("CONFIG_MODE_TT disabled - 'mode=tt' ignored\n");
- return(0);
+ return 0;
}
#else
@@ -256,7 +266,7 @@ static int __init mode_tt_setup(char *line, int *add)
static int __init mode_tt_setup(char *line, int *add)
{
printf("CONFIG_MODE_SKAS disabled - 'mode=tt' redundant\n");
- return(0);
+ return 0;
}
#endif
@@ -274,16 +284,15 @@ int mode_tt = DEFAULT_TT;
static int __init Usage(char *line, int *add)
{
- const char **p;
+ const char **p;
printf(usage_string, init_utsname()->release);
- p = &__uml_help_start;
- while (p < &__uml_help_end) {
- printf("%s", *p);
- p++;
- }
+ p = &__uml_help_start;
+ while (p < &__uml_help_end) {
+ printf("%s", *p);
+ p++;
+ }
exit(0);
-
return 0;
}
@@ -374,13 +383,12 @@ int __init linux_main(int argc, char **argv)
printf("UML running in %s mode\n", mode);
- uml_start = (unsigned long) &__binary_start;
host_task_size = CHOOSE_MODE_PROC(set_task_sizes_tt,
set_task_sizes_skas, &task_size);
/*
- * Setting up handlers to 'sig_info' struct
- */
+ * Setting up handlers to 'sig_info' struct
+ */
os_fill_handlinfo(handlinfo_kern);
brk_start = (unsigned long) sbrk(0);
@@ -396,7 +404,7 @@ int __init linux_main(int argc, char **argv)
physmem_size += UML_ROUND_UP(brk_start) - UML_ROUND_UP(&_end);
}
- uml_physmem = uml_start & PAGE_MASK;
+ uml_physmem = (unsigned long) &__binary_start & PAGE_MASK;
/* Reserve up to 4M after the current brk */
uml_reserved = ROUND_4M(brk_start) + (1 << 22);
@@ -407,7 +415,7 @@ int __init linux_main(int argc, char **argv)
argv1_begin = argv[1];
argv1_end = &argv[1][strlen(argv[1])];
#endif
-
+
highmem = 0;
iomem_size = (iomem_size + PAGE_SIZE - 1) & PAGE_MASK;
max_physmem = get_kmem_end() - uml_physmem - iomem_size - MIN_VMALLOC;
@@ -449,12 +457,12 @@ int __init linux_main(int argc, char **argv)
printf("Kernel virtual memory size shrunk to %lu bytes\n",
virtmem_size);
- uml_postsetup();
+ uml_postsetup();
task_protections((unsigned long) &init_thread_info);
os_flush_stdout();
- return(CHOOSE_MODE(start_uml_tt(), start_uml_skas()));
+ return CHOOSE_MODE(start_uml_tt(), start_uml_skas());
}
extern int uml_exitcode;
@@ -466,8 +474,8 @@ static int panic_exit(struct notifier_block *self, unsigned long unused1,
show_regs(&(current->thread.regs));
bust_spinlocks(0);
uml_exitcode = 1;
- machine_halt();
- return(0);
+ os_dump_core();
+ return 0;
}
static struct notifier_block panic_exit_notifier = {
@@ -482,14 +490,14 @@ void __init setup_arch(char **cmdline_p)
&panic_exit_notifier);
paging_init();
strlcpy(boot_command_line, command_line, COMMAND_LINE_SIZE);
- *cmdline_p = command_line;
- setup_hostinfo();
+ *cmdline_p = command_line;
+ setup_hostinfo(host_info, sizeof host_info);
}
void __init check_bugs(void)
{
arch_check_bugs();
- os_check_bugs();
+ os_check_bugs();
}
void apply_alternatives(struct alt_instr *start, struct alt_instr *end)
diff --git a/arch/um/os-Linux/aio.c b/arch/um/os-Linux/aio.c
index 6ff12743a0b..9bf944f6a1d 100644
--- a/arch/um/os-Linux/aio.c
+++ b/arch/um/os-Linux/aio.c
@@ -132,10 +132,10 @@ static int aio_thread(void *arg)
{ .data = (void *) (long) event.data,
.err = event.res });
reply_fd = ((struct aio_context *) reply.data)->reply_fd;
- err = os_write_file(reply_fd, &reply, sizeof(reply));
+ err = write(reply_fd, &reply, sizeof(reply));
if(err != sizeof(reply))
printk("aio_thread - write failed, fd = %d, "
- "err = %d\n", reply_fd, -err);
+ "err = %d\n", reply_fd, errno);
}
}
return 0;
@@ -146,38 +146,31 @@ static int aio_thread(void *arg)
static int do_not_aio(struct aio_thread_req *req)
{
char c;
- int err;
+ unsigned long long actual;
+ int n;
+
+ actual = lseek64(req->io_fd, req->offset, SEEK_SET);
+ if(actual != req->offset)
+ return -errno;
switch(req->type){
case AIO_READ:
- err = os_seek_file(req->io_fd, req->offset);
- if(err)
- goto out;
-
- err = os_read_file(req->io_fd, req->buf, req->len);
+ n = read(req->io_fd, req->buf, req->len);
break;
case AIO_WRITE:
- err = os_seek_file(req->io_fd, req->offset);
- if(err)
- goto out;
-
- err = os_write_file(req->io_fd, req->buf, req->len);
+ n = write(req->io_fd, req->buf, req->len);
break;
case AIO_MMAP:
- err = os_seek_file(req->io_fd, req->offset);
- if(err)
- goto out;
-
- err = os_read_file(req->io_fd, &c, sizeof(c));
+ n = read(req->io_fd, &c, sizeof(c));
break;
default:
printk("do_not_aio - bad request type : %d\n", req->type);
- err = -EINVAL;
- break;
+ return -EINVAL;
}
-out:
- return err;
+ if(n < 0)
+ return -errno;
+ return 0;
}
/* These are initialized in initcalls and not changed */
@@ -193,12 +186,12 @@ static int not_aio_thread(void *arg)
signal(SIGWINCH, SIG_IGN);
while(1){
- err = os_read_file(aio_req_fd_r, &req, sizeof(req));
+ err = read(aio_req_fd_r, &req, sizeof(req));
if(err != sizeof(req)){
if(err < 0)
printk("not_aio_thread - read failed, "
"fd = %d, err = %d\n", aio_req_fd_r,
- -err);
+ errno);
else {
printk("not_aio_thread - short read, fd = %d, "
"length = %d\n", aio_req_fd_r, err);
@@ -207,11 +200,11 @@ static int not_aio_thread(void *arg)
}
err = do_not_aio(&req);
reply = ((struct aio_thread_reply) { .data = req.aio,
- .err = err });
- err = os_write_file(req.aio->reply_fd, &reply, sizeof(reply));
+ .err = err });
+ err = write(req.aio->reply_fd, &reply, sizeof(reply));
if(err != sizeof(reply))
printk("not_aio_thread - write failed, fd = %d, "
- "err = %d\n", req.aio->reply_fd, -err);
+ "err = %d\n", req.aio->reply_fd, errno);
}
return 0;
@@ -228,6 +221,11 @@ static int init_aio_24(void)
aio_req_fd_w = fds[0];
aio_req_fd_r = fds[1];
+
+ err = os_set_fd_block(aio_req_fd_w, 0);
+ if(err)
+ goto out_close_pipe;
+
err = run_helper_thread(not_aio_thread, NULL,
CLONE_FILES | CLONE_VM | SIGCHLD, &stack, 0);
if(err < 0)
@@ -285,10 +283,12 @@ static int submit_aio_26(enum aio_type type, int io_fd, char *buf, int len,
if(err){
reply = ((struct aio_thread_reply) { .data = aio,
.err = err });
- err = os_write_file(aio->reply_fd, &reply, sizeof(reply));
- if(err != sizeof(reply))
+ err = write(aio->reply_fd, &reply, sizeof(reply));
+ if(err != sizeof(reply)){
+ err = -errno;
printk("submit_aio_26 - write failed, "
"fd = %d, err = %d\n", aio->reply_fd, -err);
+ }
else err = 0;
}
@@ -383,9 +383,10 @@ static int submit_aio_24(enum aio_type type, int io_fd, char *buf, int len,
};
int err;
- err = os_write_file(aio_req_fd_w, &req, sizeof(req));
+ err = write(aio_req_fd_w, &req, sizeof(req));
if(err == sizeof(req))
err = 0;
+ else err = -errno;
return err;
}
diff --git a/arch/um/os-Linux/drivers/ethertap_user.c b/arch/um/os-Linux/drivers/ethertap_user.c
index 863981ba146..acba3016128 100644
--- a/arch/um/os-Linux/drivers/ethertap_user.c
+++ b/arch/um/os-Linux/drivers/ethertap_user.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
+ * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
* James Leu (jleu@mindspring.net).
* Copyright (C) 2001 by various other people who didn't put their name here.
* Licensed under the GPL.
@@ -16,19 +16,20 @@
#include <net/if.h>
#include "user.h"
#include "kern_util.h"
-#include "user_util.h"
#include "net_user.h"
#include "etap.h"
#include "os.h"
#include "um_malloc.h"
+#include "kern_constants.h"
#define MAX_PACKET ETH_MAX_PACKET
-void etap_user_init(void *data, void *dev)
+static int etap_user_init(void *data, void *dev)
{
struct ethertap_data *pri = data;
pri->dev = dev;
+ return 0;
}
struct addr_change {
@@ -47,13 +48,16 @@ static void etap_change(int op, unsigned char *addr, unsigned char *netmask,
change.what = op;
memcpy(change.addr, addr, sizeof(change.addr));
memcpy(change.netmask, netmask, sizeof(change.netmask));
- n = os_write_file(fd, &change, sizeof(change));
- if(n != sizeof(change))
- printk("etap_change - request failed, err = %d\n", -n);
- output = um_kmalloc(page_size());
+ CATCH_EINTR(n = write(fd, &change, sizeof(change)));
+ if(n != sizeof(change)){
+ printk("etap_change - request failed, err = %d\n", errno);
+ return;
+ }
+
+ output = um_kmalloc(UM_KERN_PAGE_SIZE);
if(output == NULL)
printk("etap_change : Failed to allocate output buffer\n");
- read_output(fd, output, page_size());
+ read_output(fd, output, UM_KERN_PAGE_SIZE);
if(output != NULL){
printk("%s", output);
kfree(output);
@@ -115,13 +119,15 @@ static int etap_tramp(char *dev, char *gate, int control_me,
pe_data.data_me = data_me;
pid = run_helper(etap_pre_exec, &pe_data, args, NULL);
- if(pid < 0) err = pid;
+ if(pid < 0)
+ err = pid;
os_close_file(data_remote);
os_close_file(control_remote);
- n = os_read_file(control_me, &c, sizeof(c));
+ CATCH_EINTR(n = read(control_me, &c, sizeof(c)));
if(n != sizeof(c)){
- printk("etap_tramp : read of status failed, err = %d\n", -n);
- return(-EINVAL);
+ err = -errno;
+ printk("etap_tramp : read of status failed, err = %d\n", -err);
+ return err;
}
if(c != 1){
printk("etap_tramp : uml_net failed\n");
@@ -132,7 +138,7 @@ static int etap_tramp(char *dev, char *gate, int control_me,
else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 1))
printk("uml_net didn't exit with status 1\n");
}
- return(err);
+ return err;
}
static int etap_open(void *data)
@@ -142,23 +148,24 @@ static int etap_open(void *data)
int data_fds[2], control_fds[2], err, output_len;
err = tap_open_common(pri->dev, pri->gate_addr);
- if(err) return(err);
+ if(err)
+ return err;
err = os_pipe(data_fds, 0, 0);
if(err < 0){
printk("data os_pipe failed - err = %d\n", -err);
- return(err);
+ return err;
}
err = os_pipe(control_fds, 1, 0);
if(err < 0){
printk("control os_pipe failed - err = %d\n", -err);
- return(err);
+ return err;
}
-
+
err = etap_tramp(pri->dev_name, pri->gate_addr, control_fds[0],
control_fds[1], data_fds[0], data_fds[1]);
- output_len = page_size();
+ output_len = UM_KERN_PAGE_SIZE;
output = um_kmalloc(output_len);
read_output(control_fds[0], output, output_len);
@@ -171,13 +178,13 @@ static int etap_open(void *data)
if(err < 0){
printk("etap_tramp failed - err = %d\n", -err);
- return(err);
+ return err;
}
pri->data_fd = data_fds[0];
pri->control_fd = control_fds[0];
iter_addresses(pri->dev, etap_open_addr, &pri->control_fd);
- return(data_fds[0]);
+ return data_fds[0];
}
static void etap_close(int fd, void *data)
@@ -195,7 +202,7 @@ static void etap_close(int fd, void *data)
static int etap_set_mtu(int mtu, void *data)
{
- return(mtu);
+ return mtu;
}
static void etap_add_addr(unsigned char *addr, unsigned char *netmask,
@@ -204,7 +211,8 @@ static void etap_add_addr(unsigned char *addr, unsigned char *netmask,
struct ethertap_data *pri = data;
tap_check_ips(pri->gate_addr, addr);
- if(pri->control_fd == -1) return;
+ if(pri->control_fd == -1)
+ return;
etap_open_addr(addr, netmask, &pri->control_fd);
}
@@ -213,7 +221,8 @@ static void etap_del_addr(unsigned char *addr, unsigned char *netmask,
{
struct ethertap_data *pri = data;
- if(pri->control_fd == -1) return;
+ if(pri->control_fd == -1)
+ return;
etap_close_addr(addr, netmask, &pri->control_fd);
}
@@ -227,14 +236,3 @@ const struct net_user_info ethertap_user_info = {
.delete_address = etap_del_addr,
.max_packet = MAX_PACKET - ETH_HEADER_ETHERTAP
};
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/os-Linux/drivers/tuntap_user.c b/arch/um/os-Linux/drivers/tuntap_user.c
index e846b23f755..11a9779dc9f 100644
--- a/arch/um/os-Linux/drivers/tuntap_user.c
+++ b/arch/um/os-Linux/drivers/tuntap_user.c
@@ -18,17 +18,17 @@
#include "net_user.h"
#include "tuntap.h"
#include "kern_util.h"
-#include "user_util.h"
#include "user.h"
#include "os.h"
#define MAX_PACKET ETH_MAX_PACKET
-void tuntap_user_init(void *data, void *dev)
+static int tuntap_user_init(void *data, void *dev)
{
struct tuntap_data *pri = data;
pri->dev = dev;
+ return 0;
}
static void tuntap_add_addr(unsigned char *addr, unsigned char *netmask,
@@ -37,7 +37,8 @@ static void tuntap_add_addr(unsigned char *addr, unsigned char *netmask,
struct tuntap_data *pri = data;
tap_check_ips(pri->gate_addr, addr);
- if((pri->fd == -1) || pri->fixed_config) return;
+ if((pri->fd == -1) || pri->fixed_config)
+ return;
open_addr(addr, netmask, pri->dev_name);
}
@@ -46,7 +47,8 @@ static void tuntap_del_addr(unsigned char *addr, unsigned char *netmask,
{
struct tuntap_data *pri = data;
- if((pri->fd == -1) || pri->fixed_config) return;
+ if((pri->fd == -1) || pri->fixed_config)
+ return;
close_addr(addr, netmask, pri->dev_name);
}
@@ -58,7 +60,7 @@ struct tuntap_pre_exec_data {
static void tuntap_pre_exec(void *arg)
{
struct tuntap_pre_exec_data *data = arg;
-
+
dup2(data->stdout, 1);
os_close_file(data->close_me);
}
@@ -83,7 +85,8 @@ static int tuntap_open_tramp(char *gate, int *fd_out, int me, int remote,
pid = run_helper(tuntap_pre_exec, &data, argv, NULL);
- if(pid < 0) return(-pid);
+ if(pid < 0)
+ return -pid;
os_close_file(remote);
@@ -114,16 +117,16 @@ static int tuntap_open_tramp(char *gate, int *fd_out, int me, int remote,
cmsg = CMSG_FIRSTHDR(&msg);
if(cmsg == NULL){
printk("tuntap_open_tramp : didn't receive a message\n");
- return(-EINVAL);
+ return -EINVAL;
}
if((cmsg->cmsg_level != SOL_SOCKET) ||
(cmsg->cmsg_type != SCM_RIGHTS)){
printk("tuntap_open_tramp : didn't receive a descriptor\n");
- return(-EINVAL);
+ return -EINVAL;
}
*fd_out = ((int *) CMSG_DATA(cmsg))[0];
os_set_exec_close(*fd_out, 1);
- return(0);
+ return 0;
}
static int tuntap_open(void *data)
@@ -135,7 +138,7 @@ static int tuntap_open(void *data)
err = tap_open_common(pri->dev, pri->gate_addr);
if(err < 0)
- return(err);
+ return err;
if(pri->fixed_config){
pri->fd = os_open_file("/dev/net/tun",
@@ -143,7 +146,7 @@ static int tuntap_open(void *data)
if(pri->fd < 0){
printk("Failed to open /dev/net/tun, err = %d\n",
-pri->fd);
- return(pri->fd);
+ return pri->fd;
}
memset(&ifr, 0, sizeof(ifr));
ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
@@ -160,7 +163,7 @@ static int tuntap_open(void *data)
if(err < 0){
printk("tuntap_open : os_pipe failed - err = %d\n",
-err);
- return(err);
+ return err;
}
buffer = get_output_buffer(&len);
@@ -175,7 +178,7 @@ static int tuntap_open(void *data)
printk("%s", output);
free_output_buffer(buffer);
printk("tuntap_open_tramp failed - err = %d\n", -err);
- return(err);
+ return err;
}
pri->dev_name = uml_strdup(buffer);
@@ -187,7 +190,7 @@ static int tuntap_open(void *data)
iter_addresses(pri->dev, open_addr, pri->dev_name);
}
- return(pri->fd);
+ return pri->fd;
}
static void tuntap_close(int fd, void *data)
@@ -202,7 +205,7 @@ static void tuntap_close(int fd, void *data)
static int tuntap_set_mtu(int mtu, void *data)
{
- return(mtu);
+ return mtu;
}
const struct net_user_info tuntap_user_info = {
@@ -215,14 +218,3 @@ const struct net_user_info tuntap_user_info = {
.delete_address = tuntap_del_addr,
.max_packet = MAX_PACKET
};
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/os-Linux/file.c b/arch/um/os-Linux/file.c
index 371b4335f46..6f92f732d25 100644
--- a/arch/um/os-Linux/file.c
+++ b/arch/um/os-Linux/file.c
@@ -18,7 +18,6 @@
#include "os.h"
#include "user.h"
#include "kern_util.h"
-#include "user_util.h"
static void copy_stat(struct uml_stat *dst, struct stat64 *src)
{
@@ -291,54 +290,22 @@ int os_seek_file(int fd, __u64 offset)
return 0;
}
-static int fault_buffer(void *start, int len,
- int (*copy_proc)(void *addr, void *buf, int len))
-{
- int page = getpagesize(), i;
- char c;
-
- for(i = 0; i < len; i += page){
- if((*copy_proc)(start + i, &c, sizeof(c)))
- return -EFAULT;
- }
- if((len % page) != 0){
- if((*copy_proc)(start + len - 1, &c, sizeof(c)))
- return -EFAULT;
- }
- return 0;
-}
-
-static int file_io(int fd, void *buf, int len,
- int (*io_proc)(int fd, void *buf, int len),
- int (*copy_user_proc)(void *addr, void *buf, int len))
+int os_read_file(int fd, void *buf, int len)
{
- int n, err;
-
- do {
- n = (*io_proc)(fd, buf, len);
- if((n < 0) && (errno == EFAULT)){
- err = fault_buffer(buf, len, copy_user_proc);
- if(err)
- return err;
- n = (*io_proc)(fd, buf, len);
- }
- } while((n < 0) && (errno == EINTR));
+ int n = read(fd, buf, len);
if(n < 0)
return -errno;
return n;
}
-int os_read_file(int fd, void *buf, int len)
-{
- return file_io(fd, buf, len, (int (*)(int, void *, int)) read,
- copy_from_user_proc);
-}
-
int os_write_file(int fd, const void *buf, int len)
{
- return file_io(fd, (void *) buf, len,
- (int (*)(int, void *, int)) write, copy_to_user_proc);
+ int n = write(fd, (void *) buf, len);
+
+ if(n < 0)
+ return -errno;
+ return n;
}
int os_file_size(char *file, unsigned long long *size_out)
diff --git a/arch/um/os-Linux/helper.c b/arch/um/os-Linux/helper.c
index c7ad6306e22..97bed16bf4c 100644
--- a/arch/um/os-Linux/helper.c
+++ b/arch/um/os-Linux/helper.c
@@ -13,9 +13,9 @@
#include <sys/wait.h>
#include "user.h"
#include "kern_util.h"
-#include "user_util.h"
#include "os.h"
#include "um_malloc.h"
+#include "kern_constants.h"
struct helper_data {
void (*pre_exec)(void*);
@@ -25,28 +25,18 @@ struct helper_data {
char *buf;
};
-/* Debugging aid, changed only from gdb */
-int helper_pause = 0;
-
-static void helper_hup(int sig)
-{
-}
-
static int helper_child(void *arg)
{
struct helper_data *data = arg;
char **argv = data->argv;
int errval;
- if (helper_pause){
- signal(SIGHUP, helper_hup);
- pause();
- }
if (data->pre_exec != NULL)
(*data->pre_exec)(data->pre_data);
errval = execvp_noalloc(data->buf, argv[0], argv);
- printk("helper_child - execvp of '%s' failed - errno = %d\n", argv[0], -errval);
- os_write_file(data->fd, &errval, sizeof(errval));
+ printk("helper_child - execvp of '%s' failed - errno = %d\n", argv[0],
+ -errval);
+ write(data->fd, &errval, sizeof(errval));
kill(os_getpid(), SIGKILL);
return 0;
}
@@ -81,7 +71,7 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv,
goto out_close;
}
- sp = stack + page_size() - sizeof(void *);
+ sp = stack + UM_KERN_PAGE_SIZE - sizeof(void *);
data.pre_exec = pre_exec;
data.pre_data = pre_data;
data.argv = argv;
@@ -98,13 +88,16 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv,
close(fds[1]);
fds[1] = -1;
- /* Read the errno value from the child, if the exec failed, or get 0 if
- * the exec succeeded because the pipe fd was set as close-on-exec. */
- n = os_read_file(fds[0], &ret, sizeof(ret));
+ /*
+ * Read the errno value from the child, if the exec failed, or get 0 if
+ * the exec succeeded because the pipe fd was set as close-on-exec.
+ */
+ n = read(fds[0], &ret, sizeof(ret));
if (n == 0) {
ret = pid;
} else {
if (n < 0) {
+ n = -errno;
printk("run_helper : read on pipe failed, ret = %d\n",
-n);
ret = n;
@@ -135,7 +128,7 @@ int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags,
if (stack == 0)
return -ENOMEM;
- sp = stack + (page_size() << stack_order) - sizeof(void *);
+ sp = stack + (UM_KERN_PAGE_SIZE << stack_order) - sizeof(void *);
pid = clone(proc, (void *) sp, flags | SIGCHLD, arg);
if (pid < 0) {
err = -errno;
diff --git a/arch/um/os-Linux/irq.c b/arch/um/os-Linux/irq.c
index d1b61d474e0..a633fa8e0a9 100644
--- a/arch/um/os-Linux/irq.c
+++ b/arch/um/os-Linux/irq.c
@@ -11,7 +11,6 @@
#include <sys/poll.h>
#include <sys/types.h>
#include <sys/time.h>
-#include "user_util.h"
#include "kern_util.h"
#include "user.h"
#include "process.h"
diff --git a/arch/um/os-Linux/main.c b/arch/um/os-Linux/main.c
index 685feaab65d..ea9a23696f3 100644
--- a/arch/um/os-Linux/main.c
+++ b/arch/um/os-Linux/main.c
@@ -13,8 +13,8 @@
#include <sys/mman.h>
#include <sys/user.h>
#include <asm/page.h>
-#include "user_util.h"
#include "kern_util.h"
+#include "as-layout.h"
#include "mem_user.h"
#include "irq_user.h"
#include "user.h"
@@ -25,12 +25,7 @@
#include "os.h"
#include "um_malloc.h"
-/* Set in set_stklim, which is called from main and __wrap_malloc.
- * __wrap_malloc only calls it if main hasn't started.
- */
-unsigned long stacksizelim;
-
-/* Set in main */
+/* Set in main, unchanged thereafter */
char *linux_prog;
#define PGD_BOUND (4 * 1024 * 1024)
@@ -52,7 +47,6 @@ static void set_stklim(void)
exit(1);
}
}
- stacksizelim = (lim.rlim_cur + PGD_BOUND - 1) & ~(PGD_BOUND - 1);
}
static __init void do_uml_initcalls(void)
@@ -126,7 +120,7 @@ extern int uml_exitcode;
extern void scan_elf_aux( char **envp);
-int main(int argc, char **argv, char **envp)
+int __init main(int argc, char **argv, char **envp)
{
char **new_argv;
int ret, i, err;
@@ -224,7 +218,7 @@ int main(int argc, char **argv, char **envp)
ret = 1;
}
printf("\n");
- return(uml_exitcode);
+ return uml_exitcode;
}
#define CAN_KMALLOC() \
@@ -237,7 +231,7 @@ void *__wrap_malloc(int size)
void *ret;
if(!CAN_KMALLOC())
- return(__real_malloc(size));
+ return __real_malloc(size);
else if(size <= PAGE_SIZE) /* finding contiguos pages can be hard*/
ret = um_kmalloc(size);
else ret = um_vmalloc(size);
@@ -248,16 +242,17 @@ void *__wrap_malloc(int size)
if(ret == NULL)
errno = ENOMEM;
- return(ret);
+ return ret;
}
void *__wrap_calloc(int n, int size)
{
void *ptr = __wrap_malloc(n * size);
- if(ptr == NULL) return(NULL);
+ if(ptr == NULL)
+ return NULL;
memset(ptr, 0, n * size);
- return(ptr);
+ return ptr;
}
extern void __real_free(void *);
diff --git a/arch/um/os-Linux/mem.c b/arch/um/os-Linux/mem.c
index f1ea169db85..c6378c6d10d 100644
--- a/arch/um/os-Linux/mem.c
+++ b/arch/um/os-Linux/mem.c
@@ -11,7 +11,6 @@
#include <sys/statfs.h>
#include "kern_util.h"
#include "user.h"
-#include "user_util.h"
#include "mem_user.h"
#include "init.h"
#include "os.h"
@@ -165,7 +164,8 @@ found:
* (file: kernel/tt/ptproxy/proxy.c, proc: start_debugger).
* So it isn't 'static' yet.
*/
-int make_tempfile(const char *template, char **out_tempname, int do_unlink)
+int __init make_tempfile(const char *template, char **out_tempname,
+ int do_unlink)
{
char *tempname;
int fd;
@@ -206,7 +206,7 @@ out:
* This proc is used in start_up.c
* So it isn't 'static'.
*/
-int create_tmp_file(unsigned long long len)
+int __init create_tmp_file(unsigned long long len)
{
int fd, err;
char zero;
@@ -232,17 +232,16 @@ int create_tmp_file(unsigned long long len)
zero = 0;
- err = os_write_file(fd, &zero, 1);
+ err = write(fd, &zero, 1);
if(err != 1){
- errno = -err;
- perror("os_write_file");
+ perror("write");
exit(1);
}
return fd;
}
-int create_mem_file(unsigned long long len)
+int __init create_mem_file(unsigned long long len)
{
int err, fd;
@@ -257,7 +256,7 @@ int create_mem_file(unsigned long long len)
}
-void check_tmpexec(void)
+void __init check_tmpexec(void)
{
void *addr;
int err, fd = create_tmp_file(UM_KERN_PAGE_SIZE);
diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c
index 76bdd671241..92a7b59120d 100644
--- a/arch/um/os-Linux/process.c
+++ b/arch/um/os-Linux/process.c
@@ -14,7 +14,6 @@
#include "ptrace_user.h"
#include "os.h"
#include "user.h"
-#include "user_util.h"
#include "process.h"
#include "irq_user.h"
#include "kern_util.h"
@@ -22,6 +21,7 @@
#include "skas_ptrace.h"
#include "kern_constants.h"
#include "uml-config.h"
+#include "init.h"
#define ARBITRARY_ADDR -1
#define FAILURE_PID -1
@@ -40,14 +40,14 @@ unsigned long os_process_pc(int pid)
if(fd < 0){
printk("os_process_pc - couldn't open '%s', err = %d\n",
proc_stat, -fd);
- return(ARBITRARY_ADDR);
+ return ARBITRARY_ADDR;
}
- err = os_read_file(fd, buf, sizeof(buf));
+ CATCH_EINTR(err = read(fd, buf, sizeof(buf)));
if(err < 0){
printk("os_process_pc - couldn't read '%s', err = %d\n",
- proc_stat, -err);
+ proc_stat, errno);
os_close_file(fd);
- return(ARBITRARY_ADDR);
+ return ARBITRARY_ADDR;
}
os_close_file(fd);
pc = ARBITRARY_ADDR;
@@ -56,7 +56,7 @@ unsigned long os_process_pc(int pid)
"%*d %*d %*d %*d %*d %lu", &pc) != 1){
printk("os_process_pc - couldn't find pc in '%s'\n", buf);
}
- return(pc);
+ return pc;
}
int os_process_parent(int pid)
@@ -65,21 +65,22 @@ int os_process_parent(int pid)
char data[256];
int parent, n, fd;
- if(pid == -1) return(-1);
+ if(pid == -1)
+ return -1;
snprintf(stat, sizeof(stat), "/proc/%d/stat", pid);
fd = os_open_file(stat, of_read(OPENFLAGS()), 0);
if(fd < 0){
printk("Couldn't open '%s', err = %d\n", stat, -fd);
- return(FAILURE_PID);
+ return FAILURE_PID;
}
- n = os_read_file(fd, data, sizeof(data));
+ CATCH_EINTR(n = read(fd, data, sizeof(data)));
os_close_file(fd);
if(n < 0){
- printk("Couldn't read '%s', err = %d\n", stat, -n);
- return(FAILURE_PID);
+ printk("Couldn't read '%s', err = %d\n", stat, errno);
+ return FAILURE_PID;
}
parent = FAILURE_PID;
@@ -87,7 +88,7 @@ int os_process_parent(int pid)
if(n != 1)
printk("Failed to scan '%s'\n", data);
- return(parent);
+ return parent;
}
void os_stop_process(int pid)
@@ -145,7 +146,7 @@ void os_usr1_process(int pid)
int os_getpid(void)
{
- return(syscall(__NR_getpid));
+ return syscall(__NR_getpid);
}
int os_getpgrp(void)
@@ -165,8 +166,8 @@ int os_map_memory(void *virt, int fd, unsigned long long off, unsigned long len,
loc = mmap64((void *) virt, len, prot, MAP_SHARED | MAP_FIXED,
fd, off);
if(loc == MAP_FAILED)
- return(-errno);
- return(0);
+ return -errno;
+ return 0;
}
int os_protect_memory(void *addr, unsigned long len, int r, int w, int x)
@@ -175,8 +176,8 @@ int os_protect_memory(void *addr, unsigned long len, int r, int w, int x)
(x ? PROT_EXEC : 0));
if(mprotect(addr, len, prot) < 0)
- return(-errno);
- return(0);
+ return -errno;
+ return 0;
}
int os_unmap_memory(void *addr, int len)
@@ -185,15 +186,15 @@ int os_unmap_memory(void *addr, int len)
err = munmap(addr, len);
if(err < 0)
- return(-errno);
- return(0);
+ return -errno;
+ return 0;
}
#ifndef MADV_REMOVE
#define MADV_REMOVE KERNEL_MADV_REMOVE
#endif
-int os_drop_memory(void *addr, int length)
+int __init os_drop_memory(void *addr, int length)
{
int err;
@@ -203,7 +204,7 @@ int os_drop_memory(void *addr, int length)
return err;
}
-int can_drop_memory(void)
+int __init can_drop_memory(void)
{
void *addr;
int fd, ok = 0;
@@ -244,7 +245,7 @@ void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int))
if(sig_stack != NULL){
pages = (1 << UML_CONFIG_KERNEL_STACK_ORDER);
- set_sigstack(sig_stack, pages * page_size());
+ set_sigstack(sig_stack, pages * UM_KERN_PAGE_SIZE);
flags = SA_ONSTACK;
}
if(usr1_handler){
diff --git a/arch/um/os-Linux/sigio.c b/arch/um/os-Linux/sigio.c
index 3fc43b33db6..8d4e0c6b8c9 100644
--- a/arch/um/os-Linux/sigio.c
+++ b/arch/um/os-Linux/sigio.c
@@ -8,6 +8,7 @@
#include <termios.h>
#include <pty.h>
#include <signal.h>
+#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <sched.h>
@@ -16,10 +17,10 @@
#include "init.h"
#include "user.h"
#include "kern_util.h"
-#include "user_util.h"
#include "sigio.h"
#include "os.h"
#include "um_malloc.h"
+#include "init.h"
/* Protected by sigio_lock(), also used by sigio_cleanup, which is an
* exitcall.
@@ -68,11 +69,12 @@ static int write_sigio_thread(void *unused)
p = &fds->poll[i];
if(p->revents == 0) continue;
if(p->fd == sigio_private[1]){
- n = os_read_file(sigio_private[1], &c, sizeof(c));
+ CATCH_EINTR(n = read(sigio_private[1], &c,
+ sizeof(c)));
if(n != sizeof(c))
printk("write_sigio_thread : "
"read on socket failed, "
- "err = %d\n", -n);
+ "err = %d\n", errno);
tmp = current_poll;
current_poll = next_poll;
next_poll = tmp;
@@ -85,10 +87,10 @@ static int write_sigio_thread(void *unused)
(fds->used - i) * sizeof(*fds->poll));
}
- n = os_write_file(respond_fd, &c, sizeof(c));
+ CATCH_EINTR(n = write(respond_fd, &c, sizeof(c)));
if(n != sizeof(c))
printk("write_sigio_thread : write on socket "
- "failed, err = %d\n", -n);
+ "failed, err = %d\n", errno);
}
}
@@ -126,15 +128,15 @@ static void update_thread(void)
char c;
flags = set_signals(0);
- n = os_write_file(sigio_private[0], &c, sizeof(c));
+ n = write(sigio_private[0], &c, sizeof(c));
if(n != sizeof(c)){
- printk("update_thread : write failed, err = %d\n", -n);
+ printk("update_thread : write failed, err = %d\n", errno);
goto fail;
}
- n = os_read_file(sigio_private[0], &c, sizeof(c));
+ CATCH_EINTR(n = read(sigio_private[0], &c, sizeof(c)));
if(n != sizeof(c)){
- printk("update_thread : read failed, err = %d\n", -n);
+ printk("update_thread : read failed, err = %d\n", errno);
goto fail;
}
@@ -320,6 +322,10 @@ out_close1:
close(l_write_sigio_fds[1]);
}
+/* Changed during early boot */
+static int pty_output_sigio = 0;
+static int pty_close_sigio = 0;
+
void maybe_sigio_broken(int fd, int read)
{
int err;
@@ -357,3 +363,143 @@ static void sigio_cleanup(void)
}
__uml_exitcall(sigio_cleanup);
+
+/* Used as a flag during SIGIO testing early in boot */
+static volatile int got_sigio = 0;
+
+static void __init handler(int sig)
+{
+ got_sigio = 1;
+}
+
+struct openpty_arg {
+ int master;
+ int slave;
+ int err;
+};
+
+static void openpty_cb(void *arg)
+{
+ struct openpty_arg *info = arg;
+
+ info->err = 0;
+ if(openpty(&info->master, &info->slave, NULL, NULL, NULL))
+ info->err = -errno;
+}
+
+static int async_pty(int master, int slave)
+{
+ int flags;
+
+ flags = fcntl(master, F_GETFL);
+ if(flags < 0)
+ return -errno;
+
+ if((fcntl(master, F_SETFL, flags | O_NONBLOCK | O_ASYNC) < 0) ||
+ (fcntl(master, F_SETOWN, os_getpid()) < 0))
+ return -errno;
+
+ if((fcntl(slave, F_SETFL, flags | O_NONBLOCK) < 0))
+ return -errno;
+
+ return(0);
+}
+
+static void __init check_one_sigio(void (*proc)(int, int))
+{
+ struct sigaction old, new;
+ struct openpty_arg pty = { .master = -1, .slave = -1 };
+ int master, slave, err;
+
+ initial_thread_cb(openpty_cb, &pty);
+ if(pty.err){
+ printk("openpty failed, errno = %d\n", -pty.err);
+ return;
+ }
+
+ master = pty.master;
+ slave = pty.slave;
+
+ if((master == -1) || (slave == -1)){
+ printk("openpty failed to allocate a pty\n");
+ return;
+ }
+
+ /* Not now, but complain so we now where we failed. */
+ err = raw(master);
+ if (err < 0)
+ panic("check_sigio : __raw failed, errno = %d\n", -err);
+
+ err = async_pty(master, slave);
+ if(err < 0)
+ panic("tty_fds : sigio_async failed, err = %d\n", -err);
+
+ if(sigaction(SIGIO, NULL, &old) < 0)
+ panic("check_sigio : sigaction 1 failed, errno = %d\n", errno);
+ new = old;
+ new.sa_handler = handler;
+ if(sigaction(SIGIO, &new, NULL) < 0)
+ panic("check_sigio : sigaction 2 failed, errno = %d\n", errno);
+
+ got_sigio = 0;
+ (*proc)(master, slave);
+
+ close(master);
+ close(slave);
+
+ if(sigaction(SIGIO, &old, NULL) < 0)
+ panic("check_sigio : sigaction 3 failed, errno = %d\n", errno);
+}
+
+static void tty_output(int master, int slave)
+{
+ int n;
+ char buf[512];
+
+ printk("Checking that host ptys support output SIGIO...");
+
+ memset(buf, 0, sizeof(buf));
+
+ while(write(master, buf, sizeof(buf)) > 0) ;
+ if(errno != EAGAIN)
+ panic("tty_output : write failed, errno = %d\n", errno);
+ while(((n = read(slave, buf, sizeof(buf))) > 0) && !got_sigio) ;
+
+ if(got_sigio){
+ printk("Yes\n");
+ pty_output_sigio = 1;
+ }
+ else if(n == -EAGAIN)
+ printk("No, enabling workaround\n");
+ else panic("tty_output : read failed, err = %d\n", n);
+}
+
+static void tty_close(int master, int slave)
+{
+ printk("Checking that host ptys support SIGIO on close...");
+
+ close(slave);
+ if(got_sigio){
+ printk("Yes\n");
+ pty_close_sigio = 1;
+ }
+ else printk("No, enabling workaround\n");
+}
+
+void __init check_sigio(void)
+{
+ if((os_access("/dev/ptmx", OS_ACC_R_OK) < 0) &&
+ (os_access("/dev/ptyp0", OS_ACC_R_OK) < 0)){
+ printk("No pseudo-terminals available - skipping pty SIGIO "
+ "check\n");
+ return;
+ }
+ check_one_sigio(tty_output);
+ check_one_sigio(tty_close);
+}
+
+/* Here because it only does the SIGIO testing for now */
+void __init os_check_bugs(void)
+{
+ check_sigio();
+}
diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c
index 266768629fe..48d49341530 100644
--- a/arch/um/os-Linux/signal.c
+++ b/arch/um/os-Linux/signal.c
@@ -11,7 +11,6 @@
#include <stdarg.h>
#include <string.h>
#include <sys/mman.h>
-#include "user_util.h"
#include "user.h"
#include "signal_kern.h"
#include "sysdep/sigcontext.h"
diff --git a/arch/um/os-Linux/skas/mem.c b/arch/um/os-Linux/skas/mem.c
index 9383e8751ae..8e490fff3d4 100644
--- a/arch/um/os-Linux/skas/mem.c
+++ b/arch/um/os-Linux/skas/mem.c
@@ -6,6 +6,7 @@
#include <signal.h>
#include <errno.h>
#include <string.h>
+#include <unistd.h>
#include <sys/mman.h>
#include <sys/wait.h>
#include <asm/page.h>
@@ -17,17 +18,17 @@
#include "os.h"
#include "proc_mm.h"
#include "ptrace_user.h"
-#include "user_util.h"
#include "kern_util.h"
#include "task.h"
#include "registers.h"
#include "uml-config.h"
#include "sysdep/ptrace.h"
#include "sysdep/stub.h"
+#include "init.h"
extern unsigned long batch_syscall_stub, __syscall_stub_start;
-extern void wait_stub_done(int pid, int sig, char * fname);
+extern void wait_stub_done(int pid);
static inline unsigned long *check_init_stack(struct mm_id * mm_idp,
unsigned long *stack)
@@ -39,6 +40,19 @@ static inline unsigned long *check_init_stack(struct mm_id * mm_idp,
return stack;
}
+static unsigned long syscall_regs[MAX_REG_NR];
+
+static int __init init_syscall_regs(void)
+{
+ get_safe_registers(syscall_regs, NULL);
+ syscall_regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE +
+ ((unsigned long) &batch_syscall_stub -
+ (unsigned long) &__syscall_stub_start);
+ return 0;
+}
+
+__initcall(init_syscall_regs);
+
extern int proc_mm;
int single_count = 0;
@@ -47,12 +61,11 @@ int multi_op_count = 0;
static inline long do_syscall_stub(struct mm_id * mm_idp, void **addr)
{
- unsigned long regs[MAX_REG_NR];
int n, i;
long ret, offset;
unsigned long * data;
unsigned long * syscall;
- int pid = mm_idp->u.pid;
+ int err, pid = mm_idp->u.pid;
if(proc_mm)
#warning Need to look up userspace_pid by cpu
@@ -60,21 +73,21 @@ static inline long do_syscall_stub(struct mm_id * mm_idp, void **addr)
multi_count++;
- get_safe_registers(regs, NULL);
- regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE +
- ((unsigned long) &batch_syscall_stub -
- (unsigned long) &__syscall_stub_start);
-
- n = ptrace_setregs(pid, regs);
+ n = ptrace_setregs(pid, syscall_regs);
if(n < 0){
printk("Registers - \n");
for(i = 0; i < MAX_REG_NR; i++)
- printk("\t%d\t0x%lx\n", i, regs[i]);
+ printk("\t%d\t0x%lx\n", i, syscall_regs[i]);
panic("do_syscall_stub : PTRACE_SETREGS failed, errno = %d\n",
-n);
}
- wait_stub_done(pid, 0, "do_syscall_stub");
+ err = ptrace(PTRACE_CONT, pid, 0, 0);
+ if(err)
+ panic("Failed to continue stub, pid = %d, errno = %d\n", pid,
+ errno);
+
+ wait_stub_done(pid);
/* When the stub stops, we find the following values on the
* beginning of the stack:
@@ -176,14 +189,10 @@ long syscall_stub_data(struct mm_id * mm_idp,
return 0;
}
-int map(struct mm_id * mm_idp, unsigned long virt, unsigned long len,
- int r, int w, int x, int phys_fd, unsigned long long offset,
- int done, void **data)
+int map(struct mm_id * mm_idp, unsigned long virt, unsigned long len, int prot,
+ int phys_fd, unsigned long long offset, int done, void **data)
{
- int prot, ret;
-
- prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) |
- (x ? PROT_EXEC : 0);
+ int ret;
if(proc_mm){
struct proc_mm_op map;
@@ -200,9 +209,11 @@ int map(struct mm_id * mm_idp, unsigned long virt, unsigned long len,
.fd = phys_fd,
.offset= offset
} } } );
- ret = os_write_file(fd, &map, sizeof(map));
- if(ret != sizeof(map))
+ CATCH_EINTR(ret = write(fd, &map, sizeof(map)));
+ if(ret != sizeof(map)){
+ ret = -errno;
printk("map : /proc/mm map failed, err = %d\n", -ret);
+ }
else ret = 0;
}
else {
@@ -217,8 +228,8 @@ int map(struct mm_id * mm_idp, unsigned long virt, unsigned long len,
return ret;
}
-int unmap(struct mm_id * mm_idp, void *addr, unsigned long len, int done,
- void **data)
+int unmap(struct mm_id * mm_idp, unsigned long addr, unsigned long len,
+ int done, void **data)
{
int ret;
@@ -232,9 +243,11 @@ int unmap(struct mm_id * mm_idp, void *addr, unsigned long len, int done,
{ .addr =
(unsigned long) addr,
.len = len } } } );
- ret = os_write_file(fd, &unmap, sizeof(unmap));
- if(ret != sizeof(unmap))
+ CATCH_EINTR(ret = write(fd, &unmap, sizeof(unmap)));
+ if(ret != sizeof(unmap)){
+ ret = -errno;
printk("unmap - proc_mm write returned %d\n", ret);
+ }
else ret = 0;
}
else {
@@ -249,13 +262,11 @@ int unmap(struct mm_id * mm_idp, void *addr, unsigned long len, int done,
}
int protect(struct mm_id * mm_idp, unsigned long addr, unsigned long len,
- int r, int w, int x, int done, void **data)
+ unsigned int prot, int done, void **data)
{
struct proc_mm_op protect;
- int prot, ret;
+ int ret;
- prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) |
- (x ? PROT_EXEC : 0);
if(proc_mm){
int fd = mm_idp->u.mm_fd;
@@ -267,9 +278,11 @@ int protect(struct mm_id * mm_idp, unsigned long addr, unsigned long len,
.len = len,
.prot = prot } } } );
- ret = os_write_file(fd, &protect, sizeof(protect));
- if(ret != sizeof(protect))
+ CATCH_EINTR(ret = write(fd, &protect, sizeof(protect)));
+ if(ret != sizeof(protect)){
+ ret = -errno;
printk("protect failed, err = %d", -ret);
+ }
else ret = 0;
}
else {
diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c
index 0564422c155..5c088a55396 100644
--- a/arch/um/os-Linux/skas/process.c
+++ b/arch/um/os-Linux/skas/process.c
@@ -18,7 +18,6 @@
#include <asm/types.h>
#include "user.h"
#include "sysdep/ptrace.h"
-#include "user_util.h"
#include "kern_util.h"
#include "skas.h"
#include "stub-data.h"
@@ -34,6 +33,8 @@
#include "uml-config.h"
#include "process.h"
#include "longjmp.h"
+#include "kern_constants.h"
+#include "as-layout.h"
int is_skas_winch(int pid, int fd, void *data)
{
@@ -44,45 +45,58 @@ int is_skas_winch(int pid, int fd, void *data)
return(1);
}
-void wait_stub_done(int pid, int sig, char * fname)
+static int ptrace_dump_regs(int pid)
{
- int n, status, err;
+ unsigned long regs[MAX_REG_NR];
+ int i;
+
+ if(ptrace(PTRACE_GETREGS, pid, 0, regs) < 0)
+ return -errno;
+ else {
+ printk("Stub registers -\n");
+ for(i = 0; i < ARRAY_SIZE(regs); i++)
+ printk("\t%d - %lx\n", i, regs[i]);
+ }
+
+ return 0;
+}
- do {
- if ( sig != -1 ) {
- err = ptrace(PTRACE_CONT, pid, 0, sig);
- if(err)
- panic("%s : continue failed, errno = %d\n",
- fname, errno);
- }
- sig = 0;
+/*
+ * Signals that are OK to receive in the stub - we'll just continue it.
+ * SIGWINCH will happen when UML is inside a detached screen.
+ */
+#define STUB_SIG_MASK ((1 << SIGVTALRM) | (1 << SIGWINCH))
+
+/* Signals that the stub will finish with - anything else is an error */
+#define STUB_DONE_MASK ((1 << SIGUSR1) | (1 << SIGTRAP))
+
+void wait_stub_done(int pid)
+{
+ int n, status, err;
+ while(1){
CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
- } while((n >= 0) && WIFSTOPPED(status) &&
- ((WSTOPSIG(status) == SIGVTALRM) ||
- /* running UML inside a detached screen can cause
- * SIGWINCHes
- */
- (WSTOPSIG(status) == SIGWINCH)));
-
- if((n < 0) || !WIFSTOPPED(status) ||
- (WSTOPSIG(status) != SIGUSR1 && WSTOPSIG(status) != SIGTRAP)){
- unsigned long regs[MAX_REG_NR];
-
- if(ptrace(PTRACE_GETREGS, pid, 0, regs) < 0)
- printk("Failed to get registers from stub, "
- "errno = %d\n", errno);
- else {
- int i;
-
- printk("Stub registers -\n");
- for(i = 0; i < ARRAY_SIZE(regs); i++)
- printk("\t%d - %lx\n", i, regs[i]);
- }
- panic("%s : failed to wait for SIGUSR1/SIGTRAP, "
- "pid = %d, n = %d, errno = %d, status = 0x%x\n",
- fname, pid, n, errno, status);
+ if((n < 0) || !WIFSTOPPED(status))
+ goto bad_wait;
+
+ if(((1 << WSTOPSIG(status)) & STUB_SIG_MASK) == 0)
+ break;
+
+ err = ptrace(PTRACE_CONT, pid, 0, 0);
+ if(err)
+ panic("wait_stub_done : continue failed, errno = %d\n",
+ errno);
}
+
+ if(((1 << WSTOPSIG(status)) & STUB_DONE_MASK) != 0)
+ return;
+
+bad_wait:
+ err = ptrace_dump_regs(pid);
+ if(err)
+ printk("Failed to get registers from stub, errno = %d\n", -err);
+ panic("wait_stub_done : failed to wait for SIGUSR1/SIGTRAP, pid = %d, "
+ "n = %d, errno = %d, status = 0x%x\n", pid, n, errno, status);
}
extern unsigned long current_stub_stack(void);
@@ -104,7 +118,11 @@ void get_skas_faultinfo(int pid, struct faultinfo * fi)
sizeof(struct ptrace_faultinfo));
}
else {
- wait_stub_done(pid, SIGSEGV, "get_skas_faultinfo");
+ err = ptrace(PTRACE_CONT, pid, 0, SIGSEGV);
+ if(err)
+ panic("Failed to continue stub, pid = %d, errno = %d\n",
+ pid, errno);
+ wait_stub_done(pid);
/* faultinfo is prepared by the stub-segv-handler at start of
* the stub stack page. We just have to copy it.
@@ -142,9 +160,14 @@ static void handle_trap(int pid, union uml_pt_regs *regs, int local_using_sysemu
CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED));
if((err < 0) || !WIFSTOPPED(status) ||
- (WSTOPSIG(status) != SIGTRAP + 0x80))
+ (WSTOPSIG(status) != SIGTRAP + 0x80)){
+ err = ptrace_dump_regs(pid);
+ if(err)
+ printk("Failed to get registers from process, "
+ "errno = %d\n", -err);
panic("handle_trap - failed to wait at end of syscall, "
"errno = %d, status = %d\n", errno, status);
+ }
}
handle_syscall(regs);
@@ -172,7 +195,7 @@ static int userspace_tramp(void *stack)
int fd;
__u64 offset;
fd = phys_mapping(to_phys(&__syscall_stub_start), &offset);
- addr = mmap64((void *) UML_CONFIG_STUB_CODE, page_size(),
+ addr = mmap64((void *) UML_CONFIG_STUB_CODE, UM_KERN_PAGE_SIZE,
PROT_EXEC, MAP_FIXED | MAP_PRIVATE, fd, offset);
if(addr == MAP_FAILED){
printk("mapping mmap stub failed, errno = %d\n",
@@ -182,8 +205,8 @@ static int userspace_tramp(void *stack)
if(stack != NULL){
fd = phys_mapping(to_phys(stack), &offset);
- addr = mmap((void *) UML_CONFIG_STUB_DATA, page_size(),
- PROT_READ | PROT_WRITE,
+ addr = mmap((void *) UML_CONFIG_STUB_DATA,
+ UM_KERN_PAGE_SIZE, PROT_READ | PROT_WRITE,
MAP_FIXED | MAP_SHARED, fd, offset);
if(addr == MAP_FAILED){
printk("mapping segfault stack failed, "
@@ -199,7 +222,7 @@ static int userspace_tramp(void *stack)
(unsigned long) stub_segv_handler -
(unsigned long) &__syscall_stub_start;
- set_sigstack((void *) UML_CONFIG_STUB_DATA, page_size());
+ set_sigstack((void *) UML_CONFIG_STUB_DATA, UM_KERN_PAGE_SIZE);
sigemptyset(&sa.sa_mask);
sigaddset(&sa.sa_mask, SIGIO);
sigaddset(&sa.sa_mask, SIGWINCH);
@@ -291,10 +314,13 @@ void userspace(union uml_pt_regs *regs)
UPT_SYSCALL_NR(regs) = -1; /* Assume: It's not a syscall */
if(WIFSTOPPED(status)){
- switch(WSTOPSIG(status)){
+ int sig = WSTOPSIG(status);
+ switch(sig){
case SIGSEGV:
- if(PTRACE_FULL_FAULTINFO || !ptrace_faultinfo)
- user_signal(SIGSEGV, regs, pid);
+ if(PTRACE_FULL_FAULTINFO || !ptrace_faultinfo){
+ get_skas_faultinfo(pid, &regs->skas.faultinfo);
+ (*sig_info[SIGSEGV])(SIGSEGV, regs);
+ }
else handle_segv(pid, regs);
break;
case SIGTRAP + 0x80:
@@ -309,11 +335,13 @@ void userspace(union uml_pt_regs *regs)
case SIGBUS:
case SIGFPE:
case SIGWINCH:
- user_signal(WSTOPSIG(status), regs, pid);
+ block_signals();
+ (*sig_info[sig])(sig, regs);
+ unblock_signals();
break;
default:
printk("userspace - child stopped with signal "
- "%d\n", WSTOPSIG(status));
+ "%d\n", sig);
}
pid = userspace_pid[0];
interrupt_end();
@@ -325,11 +353,29 @@ void userspace(union uml_pt_regs *regs)
}
}
+static unsigned long thread_regs[MAX_REG_NR];
+static unsigned long thread_fp_regs[HOST_FP_SIZE];
+
+static int __init init_thread_regs(void)
+{
+ get_safe_registers(thread_regs, thread_fp_regs);
+ /* Set parent's instruction pointer to start of clone-stub */
+ thread_regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE +
+ (unsigned long) stub_clone_handler -
+ (unsigned long) &__syscall_stub_start;
+ thread_regs[REGS_SP_INDEX] = UML_CONFIG_STUB_DATA + PAGE_SIZE -
+ sizeof(void *);
+#ifdef __SIGNAL_FRAMESIZE
+ thread_regs[REGS_SP_INDEX] -= __SIGNAL_FRAMESIZE;
+#endif
+ return 0;
+}
+
+__initcall(init_thread_regs);
+
int copy_context_skas0(unsigned long new_stack, int pid)
{
int err;
- unsigned long regs[MAX_REG_NR];
- unsigned long fp_regs[HOST_FP_SIZE];
unsigned long current_stack = current_stub_stack();
struct stub_data *data = (struct stub_data *) current_stack;
struct stub_data *child_data = (struct stub_data *) new_stack;
@@ -344,23 +390,12 @@ int copy_context_skas0(unsigned long new_stack, int pid)
.timer = ((struct itimerval)
{ { 0, 1000000 / hz() },
{ 0, 1000000 / hz() }})});
- get_safe_registers(regs, fp_regs);
-
- /* Set parent's instruction pointer to start of clone-stub */
- regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE +
- (unsigned long) stub_clone_handler -
- (unsigned long) &__syscall_stub_start;
- regs[REGS_SP_INDEX] = UML_CONFIG_STUB_DATA + PAGE_SIZE -
- sizeof(void *);
-#ifdef __SIGNAL_FRAMESIZE
- regs[REGS_SP_INDEX] -= __SIGNAL_FRAMESIZE;
-#endif
- err = ptrace_setregs(pid, regs);
+ err = ptrace_setregs(pid, thread_regs);
if(err < 0)
panic("copy_context_skas0 : PTRACE_SETREGS failed, "
"pid = %d, errno = %d\n", pid, -err);
- err = ptrace_setfpregs(pid, fp_regs);
+ err = ptrace_setfpregs(pid, thread_fp_regs);
if(err < 0)
panic("copy_context_skas0 : PTRACE_SETFPREGS failed, "
"pid = %d, errno = %d\n", pid, -err);
@@ -371,7 +406,11 @@ int copy_context_skas0(unsigned long new_stack, int pid)
/* Wait, until parent has finished its work: read child's pid from
* parent's stack, and check, if bad result.
*/
- wait_stub_done(pid, 0, "copy_context_skas0");
+ err = ptrace(PTRACE_CONT, pid, 0, 0);
+ if(err)
+ panic("Failed to continue new process, pid = %d, "
+ "errno = %d\n", pid, errno);
+ wait_stub_done(pid);
pid = data->err;
if(pid < 0)
@@ -381,7 +420,7 @@ int copy_context_skas0(unsigned long new_stack, int pid)
/* Wait, until child has finished too: read child's result from
* child's stack and check it.
*/
- wait_stub_done(pid, -1, "copy_context_skas0");
+ wait_stub_done(pid);
if (child_data->err != UML_CONFIG_STUB_DATA)
panic("copy_context_skas0 - stub-child reports error %ld\n",
child_data->err);
@@ -396,7 +435,7 @@ int copy_context_skas0(unsigned long new_stack, int pid)
/*
* This is used only, if stub pages are needed, while proc_mm is
- * availabl. Opening /proc/mm creates a new mm_context, which lacks
+ * available. Opening /proc/mm creates a new mm_context, which lacks
* the stub-pages. Thus, we map them using /proc/mm-fd
*/
void map_stub_pages(int fd, unsigned long code,
@@ -418,12 +457,13 @@ void map_stub_pages(int fd, unsigned long code,
.fd = code_fd,
.offset = code_offset
} } });
- n = os_write_file(fd, &mmop, sizeof(mmop));
+ CATCH_EINTR(n = write(fd, &mmop, sizeof(mmop)));
if(n != sizeof(mmop)){
+ n = errno;
printk("mmap args - addr = 0x%lx, fd = %d, offset = %llx\n",
code, code_fd, (unsigned long long) code_offset);
panic("map_stub_pages : /proc/mm map for code failed, "
- "err = %d\n", -n);
+ "err = %d\n", n);
}
if ( stack ) {
@@ -440,10 +480,10 @@ void map_stub_pages(int fd, unsigned long code,
.fd = map_fd,
.offset = map_offset
} } });
- n = os_write_file(fd, &mmop, sizeof(mmop));
+ CATCH_EINTR(n = write(fd, &mmop, sizeof(mmop)));
if(n != sizeof(mmop))
panic("map_stub_pages : /proc/mm map for data failed, "
- "err = %d\n", -n);
+ "err = %d\n", errno);
}
}
@@ -480,7 +520,15 @@ int start_idle_thread(void *stack, jmp_buf *switch_buf)
SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGALRM,
SIGVTALRM, -1);
- n = UML_SETJMP(&initial_jmpbuf);
+ /*
+ * Can't use UML_SETJMP or UML_LONGJMP here because they save
+ * and restore signals, with the possible side-effect of
+ * trying to handle any signals which came when they were
+ * blocked, which can't be done on this stack.
+ * Signals must be blocked when jumping back here and restored
+ * after returning to the jumper.
+ */
+ n = setjmp(initial_jmpbuf);
switch(n){
case INIT_JMP_NEW_THREAD:
(*switch_buf)[0].JB_IP = (unsigned long) new_thread_handler;
@@ -490,7 +538,7 @@ int start_idle_thread(void *stack, jmp_buf *switch_buf)
break;
case INIT_JMP_CALLBACK:
(*cb_proc)(cb_arg);
- UML_LONGJMP(cb_back, 1);
+ longjmp(*cb_back, 1);
break;
case INIT_JMP_HALT:
kmalloc_ok = 0;
@@ -501,7 +549,7 @@ int start_idle_thread(void *stack, jmp_buf *switch_buf)
default:
panic("Bad sigsetjmp return in start_idle_thread - %d\n", n);
}
- UML_LONGJMP(switch_buf, 1);
+ longjmp(*switch_buf, 1);
}
void initial_thread_cb_skas(void (*proc)(void *), void *arg)
diff --git a/arch/um/os-Linux/skas/trap.c b/arch/um/os-Linux/skas/trap.c
index 9ad5fbec459..3b600c2e63b 100644
--- a/arch/um/os-Linux/skas/trap.c
+++ b/arch/um/os-Linux/skas/trap.c
@@ -5,8 +5,8 @@
#include <signal.h>
#include <errno.h>
-#include "user_util.h"
#include "kern_util.h"
+#include "as-layout.h"
#include "task.h"
#include "sigcontext.h"
#include "skas.h"
@@ -15,29 +15,39 @@
#include "sysdep/ptrace_user.h"
#include "os.h"
+static union uml_pt_regs ksig_regs[UM_NR_CPUS];
+
void sig_handler_common_skas(int sig, void *sc_ptr)
{
struct sigcontext *sc = sc_ptr;
- struct skas_regs *r;
+ union uml_pt_regs *r;
void (*handler)(int, union uml_pt_regs *);
- int save_errno = errno;
- int save_user;
+ int save_user, save_errno = errno;
/* This is done because to allow SIGSEGV to be delivered inside a SEGV
* handler. This can happen in copy_user, and if SEGV is disabled,
* the process will die.
* XXX Figure out why this is better than SA_NODEFER
*/
- if(sig == SIGSEGV)
+ if(sig == SIGSEGV) {
change_sig(SIGSEGV, 1);
+ /* For segfaults, we want the data from the
+ * sigcontext. In this case, we don't want to mangle
+ * the process registers, so use a static set of
+ * registers. For other signals, the process
+ * registers are OK.
+ */
+ r = &ksig_regs[cpu()];
+ copy_sc(r, sc_ptr);
+ }
+ else r = TASK_REGS(get_current());
- r = &TASK_REGS(get_current())->skas;
- save_user = r->is_user;
- r->is_user = 0;
+ save_user = r->skas.is_user;
+ r->skas.is_user = 0;
if ( sig == SIGFPE || sig == SIGSEGV ||
sig == SIGBUS || sig == SIGILL ||
sig == SIGTRAP ) {
- GET_FAULTINFO_FROM_SC(r->faultinfo, sc);
+ GET_FAULTINFO_FROM_SC(r->skas.faultinfo, sc);
}
change_sig(SIGUSR1, 1);
@@ -49,25 +59,8 @@ void sig_handler_common_skas(int sig, void *sc_ptr)
sig != SIGVTALRM && sig != SIGALRM)
unblock_signals();
- handler(sig, (union uml_pt_regs *) r);
+ handler(sig, r);
errno = save_errno;
- r->is_user = save_user;
-}
-
-extern int ptrace_faultinfo;
-
-void user_signal(int sig, union uml_pt_regs *regs, int pid)
-{
- void (*handler)(int, union uml_pt_regs *);
- int segv = ((sig == SIGFPE) || (sig == SIGSEGV) || (sig == SIGBUS) ||
- (sig == SIGILL) || (sig == SIGTRAP));
-
- if (segv)
- get_skas_faultinfo(pid, &regs->skas.faultinfo);
-
- handler = sig_info[sig];
- handler(sig, (union uml_pt_regs *) regs);
-
- unblock_signals();
+ r->skas.is_user = save_user;
}
diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c
index 5178eba9afa..79471f85eb8 100644
--- a/arch/um/os-Linux/start_up.c
+++ b/arch/um/os-Linux/start_up.c
@@ -17,10 +17,10 @@
#include <sys/time.h>
#include <sys/wait.h>
#include <sys/mman.h>
+#include <sys/resource.h>
#include <asm/unistd.h>
#include <asm/page.h>
#include <sys/types.h>
-#include "user_util.h"
#include "kern_util.h"
#include "user.h"
#include "signal_kern.h"
@@ -329,8 +329,32 @@ static void __init check_ptrace(void)
extern void check_tmpexec(void);
-void os_early_checks(void)
+static void __init check_coredump_limit(void)
{
+ struct rlimit lim;
+ int err = getrlimit(RLIMIT_CORE, &lim);
+
+ if(err){
+ perror("Getting core dump limit");
+ return;
+ }
+
+ printf("Core dump limits :\n\tsoft - ");
+ if(lim.rlim_cur == RLIM_INFINITY)
+ printf("NONE\n");
+ else printf("%lu\n", lim.rlim_cur);
+
+ printf("\thard - ");
+ if(lim.rlim_max == RLIM_INFINITY)
+ printf("NONE\n");
+ else printf("%lu\n", lim.rlim_max);
+}
+
+void __init os_early_checks(void)
+{
+ /* Print out the core dump limits early */
+ check_coredump_limit();
+
check_ptrace();
/* Need to check this early because mmapping happens before the
@@ -528,148 +552,3 @@ int __init parse_iomem(char *str, int *add)
out:
return 1;
}
-
-
-/* Changed during early boot */
-int pty_output_sigio = 0;
-int pty_close_sigio = 0;
-
-/* Used as a flag during SIGIO testing early in boot */
-static volatile int got_sigio = 0;
-
-static void __init handler(int sig)
-{
- got_sigio = 1;
-}
-
-struct openpty_arg {
- int master;
- int slave;
- int err;
-};
-
-static void openpty_cb(void *arg)
-{
- struct openpty_arg *info = arg;
-
- info->err = 0;
- if(openpty(&info->master, &info->slave, NULL, NULL, NULL))
- info->err = -errno;
-}
-
-static int async_pty(int master, int slave)
-{
- int flags;
-
- flags = fcntl(master, F_GETFL);
- if(flags < 0)
- return -errno;
-
- if((fcntl(master, F_SETFL, flags | O_NONBLOCK | O_ASYNC) < 0) ||
- (fcntl(master, F_SETOWN, os_getpid()) < 0))
- return -errno;
-
- if((fcntl(slave, F_SETFL, flags | O_NONBLOCK) < 0))
- return -errno;
-
- return(0);
-}
-
-static void __init check_one_sigio(void (*proc)(int, int))
-{
- struct sigaction old, new;
- struct openpty_arg pty = { .master = -1, .slave = -1 };
- int master, slave, err;
-
- initial_thread_cb(openpty_cb, &pty);
- if(pty.err){
- printk("openpty failed, errno = %d\n", -pty.err);
- return;
- }
-
- master = pty.master;
- slave = pty.slave;
-
- if((master == -1) || (slave == -1)){
- printk("openpty failed to allocate a pty\n");
- return;
- }
-
- /* Not now, but complain so we now where we failed. */
- err = raw(master);
- if (err < 0)
- panic("check_sigio : __raw failed, errno = %d\n", -err);
-
- err = async_pty(master, slave);
- if(err < 0)
- panic("tty_fds : sigio_async failed, err = %d\n", -err);
-
- if(sigaction(SIGIO, NULL, &old) < 0)
- panic("check_sigio : sigaction 1 failed, errno = %d\n", errno);
- new = old;
- new.sa_handler = handler;
- if(sigaction(SIGIO, &new, NULL) < 0)
- panic("check_sigio : sigaction 2 failed, errno = %d\n", errno);
-
- got_sigio = 0;
- (*proc)(master, slave);
-
- close(master);
- close(slave);
-
- if(sigaction(SIGIO, &old, NULL) < 0)
- panic("check_sigio : sigaction 3 failed, errno = %d\n", errno);
-}
-
-static void tty_output(int master, int slave)
-{
- int n;
- char buf[512];
-
- printk("Checking that host ptys support output SIGIO...");
-
- memset(buf, 0, sizeof(buf));
-
- while(os_write_file(master, buf, sizeof(buf)) > 0) ;
- if(errno != EAGAIN)
- panic("check_sigio : write failed, errno = %d\n", errno);
- while(((n = os_read_file(slave, buf, sizeof(buf))) > 0) && !got_sigio) ;
-
- if(got_sigio){
- printk("Yes\n");
- pty_output_sigio = 1;
- }
- else if(n == -EAGAIN) printk("No, enabling workaround\n");
- else panic("check_sigio : read failed, err = %d\n", n);
-}
-
-static void tty_close(int master, int slave)
-{
- printk("Checking that host ptys support SIGIO on close...");
-
- close(slave);
- if(got_sigio){
- printk("Yes\n");
- pty_close_sigio = 1;
- }
- else printk("No, enabling workaround\n");
-}
-
-void __init check_sigio(void)
-{
- if((os_access("/dev/ptmx", OS_ACC_R_OK) < 0) &&
- (os_access("/dev/ptyp0", OS_ACC_R_OK) < 0)){
- printk("No pseudo-terminals available - skipping pty SIGIO "
- "check\n");
- return;
- }
- check_one_sigio(tty_output);
- check_one_sigio(tty_close);
-}
-
-void os_check_bugs(void)
-{
- check_ptrace();
- check_sigio();
-}
-
diff --git a/arch/um/os-Linux/sys-i386/tls.c b/arch/um/os-Linux/sys-i386/tls.c
index 256532034c6..32ed41ec1a3 100644
--- a/arch/um/os-Linux/sys-i386/tls.c
+++ b/arch/um/os-Linux/sys-i386/tls.c
@@ -5,7 +5,7 @@
#include <unistd.h>
#include "sysdep/tls.h"
-#include "user_util.h"
+#include "user.h"
/* Checks whether host supports TLS, and sets *tls_min according to the value
* valid on the host.
diff --git a/arch/um/os-Linux/time.c b/arch/um/os-Linux/time.c
index 2115b8beb54..5de169b168f 100644
--- a/arch/um/os-Linux/time.c
+++ b/arch/um/os-Linux/time.c
@@ -10,7 +10,6 @@
#include <sys/time.h>
#include <signal.h>
#include <errno.h>
-#include "user_util.h"
#include "kern_util.h"
#include "user.h"
#include "process.h"
diff --git a/arch/um/os-Linux/trap.c b/arch/um/os-Linux/trap.c
index d221214d2ed..295da657931 100644
--- a/arch/um/os-Linux/trap.c
+++ b/arch/um/os-Linux/trap.c
@@ -6,7 +6,6 @@
#include <stdlib.h>
#include <signal.h>
#include "kern_util.h"
-#include "user_util.h"
#include "os.h"
#include "mode.h"
#include "longjmp.h"
diff --git a/arch/um/os-Linux/tt.c b/arch/um/os-Linux/tt.c
index 3dc3a02d626..bcf9359c4e9 100644
--- a/arch/um/os-Linux/tt.c
+++ b/arch/um/os-Linux/tt.c
@@ -18,7 +18,6 @@
#include <asm/ptrace.h>
#include <asm/unistd.h>
#include <asm/page.h>
-#include "user_util.h"
#include "kern_util.h"
#include "user.h"
#include "signal_kern.h"
@@ -32,6 +31,7 @@
#include "choose-mode.h"
#include "mode.h"
#include "tempfile.h"
+#include "kern_constants.h"
int protect_memory(unsigned long addr, unsigned long len, int r, int w, int x,
int must_succeed)
@@ -143,7 +143,7 @@ int outer_tramp(void *arg)
int sig = sigkill;
t = arg;
- t->pid = clone(t->tramp, (void *) t->temp_stack + page_size()/2,
+ t->pid = clone(t->tramp, (void *) t->temp_stack + UM_KERN_PAGE_SIZE/2,
t->flags, t->tramp_data);
if(t->pid > 0) wait_for_stop(t->pid, SIGSTOP, PTRACE_CONT, NULL);
kill(os_getpid(), sig);
diff --git a/arch/um/os-Linux/tty_log.c b/arch/um/os-Linux/tty_log.c
index c6ba56c1560..d11a55baa6b 100644
--- a/arch/um/os-Linux/tty_log.c
+++ b/arch/um/os-Linux/tty_log.c
@@ -53,9 +53,9 @@ int open_tty_log(void *tty, void *current_tty)
.direction = 0,
.sec = tv.tv_sec,
.usec = tv.tv_usec } );
- os_write_file(tty_log_fd, &data, sizeof(data));
- os_write_file(tty_log_fd, &current_tty, data.len);
- return(tty_log_fd);
+ write(tty_log_fd, &data, sizeof(data));
+ write(tty_log_fd, &current_tty, data.len);
+ return tty_log_fd;
}
sprintf(buf, "%s/%0u-%0u", tty_log_dir, (unsigned int) tv.tv_sec,
@@ -67,7 +67,7 @@ int open_tty_log(void *tty, void *current_tty)
printk("open_tty_log : couldn't open '%s', errno = %d\n",
buf, -fd);
}
- return(fd);
+ return fd;
}
void close_tty_log(int fd, void *tty)
@@ -83,7 +83,7 @@ void close_tty_log(int fd, void *tty)
.direction = 0,
.sec = tv.tv_sec,
.usec = tv.tv_usec } );
- os_write_file(tty_log_fd, &data, sizeof(data));
+ write(tty_log_fd, &data, sizeof(data));
return;
}
os_close_file(fd);
@@ -98,21 +98,21 @@ static int log_chunk(int fd, const char *buf, int len)
try = (len > sizeof(chunk)) ? sizeof(chunk) : len;
missed = copy_from_user_proc(chunk, (char *) buf, try);
try -= missed;
- n = os_write_file(fd, chunk, try);
+ n = write(fd, chunk, try);
if(n != try) {
if(n < 0)
- return(n);
- return(-EIO);
+ return -errno;
+ return -EIO;
}
if(missed != 0)
- return(-EFAULT);
+ return -EFAULT;
len -= try;
total += try;
buf += try;
}
- return(total);
+ return total;
}
int write_tty_log(int fd, const char *buf, int len, void *tty, int is_read)
@@ -130,10 +130,10 @@ int write_tty_log(int fd, const char *buf, int len, void *tty, int is_read)
.direction = direction,
.sec = tv.tv_sec,
.usec = tv.tv_usec } );
- os_write_file(tty_log_fd, &data, sizeof(data));
+ write(tty_log_fd, &data, sizeof(data));
}
- return(log_chunk(fd, buf, len));
+ return log_chunk(fd, buf, len);
}
void log_exec(char **argv, void *tty)
@@ -161,7 +161,7 @@ void log_exec(char **argv, void *tty)
.direction = 0,
.sec = tv.tv_sec,
.usec = tv.tv_usec } );
- os_write_file(tty_log_fd, &data, sizeof(data));
+ write(tty_log_fd, &data, sizeof(data));
for(ptr = argv; ; ptr++){
if(copy_from_user_proc(&arg, ptr, sizeof(arg)))
@@ -179,7 +179,7 @@ extern void register_tty_logger(int (*opener)(void *, void *),
static int register_logger(void)
{
register_tty_logger(open_tty_log, write_tty_log, close_tty_log);
- return(0);
+ return 0;
}
__uml_initcall(register_logger);
diff --git a/arch/um/os-Linux/util.c b/arch/um/os-Linux/util.c
index 56b8a50e8bc..c307a89ed25 100644
--- a/arch/um/os-Linux/util.c
+++ b/arch/um/os-Linux/util.c
@@ -21,7 +21,6 @@
#include <sched.h>
#include <termios.h>
#include <string.h>
-#include "user_util.h"
#include "kern_util.h"
#include "user.h"
#include "mem_user.h"
@@ -30,28 +29,29 @@
#include "uml-config.h"
#include "os.h"
#include "longjmp.h"
+#include "kern_constants.h"
void stack_protections(unsigned long address)
{
int prot = PROT_READ | PROT_WRITE | PROT_EXEC;
- if(mprotect((void *) address, page_size(), prot) < 0)
+ if(mprotect((void *) address, UM_KERN_PAGE_SIZE, prot) < 0)
panic("protecting stack failed, errno = %d", errno);
}
void task_protections(unsigned long address)
{
- unsigned long guard = address + page_size();
- unsigned long stack = guard + page_size();
+ unsigned long guard = address + UM_KERN_PAGE_SIZE;
+ unsigned long stack = guard + UM_KERN_PAGE_SIZE;
int prot = 0, pages;
#ifdef notdef
- if(mprotect((void *) stack, page_size(), prot) < 0)
+ if(mprotect((void *) stack, UM_KERN_PAGE_SIZE, prot) < 0)
panic("protecting guard page failed, errno = %d", errno);
#endif
pages = (1 << UML_CONFIG_KERNEL_STACK_ORDER) - 2;
prot = PROT_READ | PROT_WRITE | PROT_EXEC;
- if(mprotect((void *) stack, pages * page_size(), prot) < 0)
+ if(mprotect((void *) stack, pages * UM_KERN_PAGE_SIZE, prot) < 0)
panic("protecting stack failed, errno = %d", errno);
}
@@ -96,15 +96,13 @@ void setup_machinename(char *machine_out)
strcpy(machine_out, host.machine);
}
-char host_info[(_UTSNAME_LENGTH + 1) * 4 + _UTSNAME_NODENAME_LENGTH + 1];
-
-void setup_hostinfo(void)
+void setup_hostinfo(char *buf, int len)
{
struct utsname host;
uname(&host);
- sprintf(host_info, "%s %s %s %s %s", host.sysname, host.nodename,
- host.release, host.version, host.machine);
+ snprintf(buf, len, "%s %s %s %s %s", host.sysname, host.nodename,
+ host.release, host.version, host.machine);
}
int setjmp_wrapper(void (*proc)(void *, void *), ...)
@@ -121,3 +119,9 @@ int setjmp_wrapper(void (*proc)(void *, void *), ...)
va_end(args);
return n;
}
+
+void os_dump_core(void)
+{
+ signal(SIGSEGV, SIG_DFL);
+ abort();
+}
diff --git a/arch/um/sys-i386/bugs.c b/arch/um/sys-i386/bugs.c
index f1bcd399ac9..0393e44813e 100644
--- a/arch/um/sys-i386/bugs.c
+++ b/arch/um/sys-i386/bugs.c
@@ -1,4 +1,4 @@
-/*
+/*
* Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
* Licensed under the GPL
*/
@@ -13,7 +13,6 @@
#include "sysdep/ptrace.h"
#include "task.h"
#include "os.h"
-#include "user_util.h"
#define MAXTOKEN 64
@@ -32,21 +31,21 @@ static char token(int fd, char *buf, int len, char stop)
n = os_read_file(fd, ptr, sizeof(*ptr));
c = *ptr++;
if(n != sizeof(*ptr)){
- if(n == 0) return(0);
+ if(n == 0)
+ return 0;
printk("Reading /proc/cpuinfo failed, err = %d\n", -n);
if(n < 0)
- return(n);
- else
- return(-EIO);
+ return n;
+ else return -EIO;
}
} while((c != '\n') && (c != stop) && (ptr < end));
if(ptr == end){
printk("Failed to find '%c' in /proc/cpuinfo\n", stop);
- return(-1);
+ return -1;
}
*(ptr - 1) = '\0';
- return(c);
+ return c;
}
static int find_cpuinfo_line(int fd, char *key, char *scratch, int len)
@@ -58,48 +57,25 @@ static int find_cpuinfo_line(int fd, char *key, char *scratch, int len)
while(1){
c = token(fd, scratch, len - 1, ':');
if(c <= 0)
- return(0);
+ return 0;
else if(c != ':'){
printk("Failed to find ':' in /proc/cpuinfo\n");
- return(0);
+ return 0;
}
if(!strncmp(scratch, key, strlen(key)))
- return(1);
+ return 1;
do {
n = os_read_file(fd, &c, sizeof(c));
if(n != sizeof(c)){
printk("Failed to find newline in "
"/proc/cpuinfo, err = %d\n", -n);
- return(0);
+ return 0;
}
} while(c != '\n');
}
- return(0);
-}
-
-int cpu_feature(char *what, char *buf, int len)
-{
- int fd, ret = 0;
-
- fd = os_open_file("/proc/cpuinfo", of_read(OPENFLAGS()), 0);
- if(fd < 0){
- printk("Couldn't open /proc/cpuinfo, err = %d\n", -fd);
- return(0);
- }
-
- if(!find_cpuinfo_line(fd, what, buf, len)){
- printk("Couldn't find '%s' line in /proc/cpuinfo\n", what);
- goto out_close;
- }
-
- token(fd, buf, len, '\n');
- ret = 1;
-
- out_close:
- os_close_file(fd);
- return(ret);
+ return 0;
}
static int check_cpu_flag(char *feature, int *have_it)
@@ -119,7 +95,8 @@ static int check_cpu_flag(char *feature, int *have_it)
goto out;
c = token(fd, buf, len - 1, ' ');
- if(c < 0) goto out;
+ if(c < 0)
+ goto out;
else if(c != ' '){
printk("Failed to find ' ' in /proc/cpuinfo\n");
goto out;
@@ -127,7 +104,8 @@ static int check_cpu_flag(char *feature, int *have_it)
while(1){
c = token(fd, buf, len - 1, ' ');
- if(c < 0) goto out;
+ if(c < 0)
+ goto out;
else if(c == '\n') break;
if(!strcmp(buf, feature)){
@@ -136,8 +114,10 @@ static int check_cpu_flag(char *feature, int *have_it)
}
}
out:
- if(*have_it == 0) printk("No\n");
- else if(*have_it == 1) printk("Yes\n");
+ if(*have_it == 0)
+ printk("No\n");
+ else if(*have_it == 1)
+ printk("Yes\n");
os_close_file(fd);
return 1;
}
@@ -189,12 +169,13 @@ int arch_handle_signal(int sig, union uml_pt_regs *regs)
/* This is testing for a cmov (0x0f 0x4x) instruction causing a
* SIGILL in init.
*/
- if((sig != SIGILL) || (TASK_PID(get_current()) != 1)) return(0);
+ if((sig != SIGILL) || (TASK_PID(get_current()) != 1))
+ return 0;
if (copy_from_user_proc(tmp, (void *) UPT_IP(regs), 2))
panic("SIGILL in init, could not read instructions!\n");
if((tmp[0] != 0x0f) || ((tmp[1] & 0xf0) != 0x40))
- return(0);
+ return 0;
if(host_has_cmov == 0)
panic("SIGILL caused by cmov, which this processor doesn't "
@@ -208,16 +189,5 @@ int arch_handle_signal(int sig, union uml_pt_regs *regs)
"implements it, boot a filesystem compiled for older "
"processors");
else panic("Bad value for host_has_cmov (%d)", host_has_cmov);
- return(0);
+ return 0;
}
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/sys-i386/fault.c b/arch/um/sys-i386/fault.c
index d0bbcdfdb53..745b4fd49e9 100644
--- a/arch/um/sys-i386/fault.c
+++ b/arch/um/sys-i386/fault.c
@@ -3,9 +3,7 @@
* Licensed under the GPL
*/
-#include <signal.h>
#include "sysdep/ptrace.h"
-#include "sysdep/sigcontext.h"
/* These two are from asm-um/uaccess.h and linux/module.h, check them. */
struct exception_table_entry
@@ -17,26 +15,14 @@ struct exception_table_entry
const struct exception_table_entry *search_exception_tables(unsigned long add);
/* Compare this to arch/i386/mm/extable.c:fixup_exception() */
-int arch_fixup(unsigned long address, void *sc_ptr)
+int arch_fixup(unsigned long address, union uml_pt_regs *regs)
{
- struct sigcontext *sc = sc_ptr;
const struct exception_table_entry *fixup;
fixup = search_exception_tables(address);
if(fixup != 0){
- sc->eip = fixup->fixup;
+ UPT_IP(regs) = fixup->fixup;
return(1);
}
return(0);
}
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/sys-i386/ptrace_user.c b/arch/um/sys-i386/ptrace_user.c
index 01212c88fcc..40ff0c831bd 100644
--- a/arch/um/sys-i386/ptrace_user.c
+++ b/arch/um/sys-i386/ptrace_user.c
@@ -1,4 +1,4 @@
-/*
+/*
* Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
* Licensed under the GPL
*/
@@ -15,7 +15,6 @@
#include "user.h"
#include "os.h"
#include "uml-config.h"
-#include "user_util.h"
int ptrace_getregs(long pid, unsigned long *regs_out)
{
@@ -45,7 +44,8 @@ int ptrace_setfpregs(long pid, unsigned long *regs)
return 0;
}
-/* All the below stuff is of interest for TT mode only */
+#ifdef UML_CONFIG_MODE_TT
+
static void write_debugregs(int pid, unsigned long *regs)
{
struct user *dummy;
@@ -128,13 +128,4 @@ void update_debugregs(int seq)
}
#endif
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
+#endif
diff --git a/arch/um/sys-i386/signal.c b/arch/um/sys-i386/signal.c
index 3f6acd66771..1cbf95f6858 100644
--- a/arch/um/sys-i386/signal.c
+++ b/arch/um/sys-i386/signal.c
@@ -18,6 +18,28 @@
#include "skas.h"
+void copy_sc(union uml_pt_regs *regs, void *from)
+{
+ struct sigcontext *sc = from;
+
+ REGS_GS(regs->skas.regs) = sc->gs;
+ REGS_FS(regs->skas.regs) = sc->fs;
+ REGS_ES(regs->skas.regs) = sc->es;
+ REGS_DS(regs->skas.regs) = sc->ds;
+ REGS_EDI(regs->skas.regs) = sc->edi;
+ REGS_ESI(regs->skas.regs) = sc->esi;
+ REGS_EBP(regs->skas.regs) = sc->ebp;
+ REGS_SP(regs->skas.regs) = sc->esp;
+ REGS_EBX(regs->skas.regs) = sc->ebx;
+ REGS_EDX(regs->skas.regs) = sc->edx;
+ REGS_ECX(regs->skas.regs) = sc->ecx;
+ REGS_EAX(regs->skas.regs) = sc->eax;
+ REGS_IP(regs->skas.regs) = sc->eip;
+ REGS_CS(regs->skas.regs) = sc->cs;
+ REGS_EFLAGS(regs->skas.regs) = sc->eflags;
+ REGS_SS(regs->skas.regs) = sc->ss;
+}
+
static int copy_sc_from_user_skas(struct pt_regs *regs,
struct sigcontext __user *from)
{
@@ -28,33 +50,18 @@ static int copy_sc_from_user_skas(struct pt_regs *regs,
err = copy_from_user(&sc, from, sizeof(sc));
err |= copy_from_user(fpregs, sc.fpstate, sizeof(fpregs));
if(err)
- return(err);
-
- REGS_GS(regs->regs.skas.regs) = sc.gs;
- REGS_FS(regs->regs.skas.regs) = sc.fs;
- REGS_ES(regs->regs.skas.regs) = sc.es;
- REGS_DS(regs->regs.skas.regs) = sc.ds;
- REGS_EDI(regs->regs.skas.regs) = sc.edi;
- REGS_ESI(regs->regs.skas.regs) = sc.esi;
- REGS_EBP(regs->regs.skas.regs) = sc.ebp;
- REGS_SP(regs->regs.skas.regs) = sc.esp;
- REGS_EBX(regs->regs.skas.regs) = sc.ebx;
- REGS_EDX(regs->regs.skas.regs) = sc.edx;
- REGS_ECX(regs->regs.skas.regs) = sc.ecx;
- REGS_EAX(regs->regs.skas.regs) = sc.eax;
- REGS_IP(regs->regs.skas.regs) = sc.eip;
- REGS_CS(regs->regs.skas.regs) = sc.cs;
- REGS_EFLAGS(regs->regs.skas.regs) = sc.eflags;
- REGS_SS(regs->regs.skas.regs) = sc.ss;
+ return err;
+
+ copy_sc(&regs->regs, &sc);
err = restore_fp_registers(userspace_pid[0], fpregs);
- if(err < 0){
+ if(err < 0) {
printk("copy_sc_from_user_skas - PTRACE_SETFPREGS failed, "
- "errno = %d\n", err);
- return(1);
+ "errno = %d\n", -err);
+ return err;
}
- return(0);
+ return 0;
}
int copy_sc_to_user_skas(struct sigcontext __user *to, struct _fpstate __user *to_fp,
@@ -90,16 +97,16 @@ int copy_sc_to_user_skas(struct sigcontext __user *to, struct _fpstate __user *t
if(err < 0){
printk("copy_sc_to_user_skas - PTRACE_GETFPREGS failed, "
"errno = %d\n", err);
- return(1);
+ return 1;
}
to_fp = (to_fp ? to_fp : (struct _fpstate __user *) (to + 1));
sc.fpstate = to_fp;
if(err)
- return(err);
+ return err;
- return(copy_to_user(to, &sc, sizeof(sc)) ||
- copy_to_user(to_fp, fpregs, sizeof(fpregs)));
+ return copy_to_user(to, &sc, sizeof(sc)) ||
+ copy_to_user(to_fp, fpregs, sizeof(fpregs));
}
#endif
@@ -129,7 +136,7 @@ int copy_sc_from_user_tt(struct sigcontext *to, struct sigcontext __user *from,
to->fpstate = to_fp;
if(to_fp != NULL)
err |= copy_from_user(to_fp, from_fp, fpsize);
- return(err);
+ return err;
}
int copy_sc_to_user_tt(struct sigcontext __user *to, struct _fpstate __user *fp,
@@ -164,15 +171,15 @@ static int copy_sc_from_user(struct pt_regs *to, void __user *from)
ret = CHOOSE_MODE(copy_sc_from_user_tt(UPT_SC(&to->regs), from,
sizeof(struct _fpstate)),
copy_sc_from_user_skas(to, from));
- return(ret);
+ return ret;
}
static int copy_sc_to_user(struct sigcontext __user *to, struct _fpstate __user *fp,
struct pt_regs *from, unsigned long sp)
{
- return(CHOOSE_MODE(copy_sc_to_user_tt(to, fp, UPT_SC(&from->regs),
+ return CHOOSE_MODE(copy_sc_to_user_tt(to, fp, UPT_SC(&from->regs),
sizeof(*fp), sp),
- copy_sc_to_user_skas(to, fp, from, sp)));
+ copy_sc_to_user_skas(to, fp, from, sp));
}
static int copy_ucontext_to_user(struct ucontext __user *uc, struct _fpstate __user *fp,
@@ -185,7 +192,7 @@ static int copy_ucontext_to_user(struct ucontext __user *uc, struct _fpstate __u
err |= put_user(current->sas_ss_size, &uc->uc_stack.ss_size);
err |= copy_sc_to_user(&uc->uc_mcontext, fp, &current->thread.regs, sp);
err |= copy_to_user(&uc->uc_sigmask, set, sizeof(*set));
- return(err);
+ return err;
}
struct sigframe
@@ -359,7 +366,7 @@ long sys_sigreturn(struct pt_regs regs)
/* Avoid ERESTART handling */
PT_REGS_SYSCALL_NR(&current->thread.regs) = -1;
- return(PT_REGS_SYSCALL_RET(&current->thread.regs));
+ return PT_REGS_SYSCALL_RET(&current->thread.regs);
segfault:
force_sig(SIGSEGV, current);
@@ -389,20 +396,9 @@ long sys_rt_sigreturn(struct pt_regs regs)
/* Avoid ERESTART handling */
PT_REGS_SYSCALL_NR(&current->thread.regs) = -1;
- return(PT_REGS_SYSCALL_RET(&current->thread.regs));
+ return PT_REGS_SYSCALL_RET(&current->thread.regs);
segfault:
force_sig(SIGSEGV, current);
return 0;
}
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/sys-i386/tls.c b/arch/um/sys-i386/tls.c
index 643dab58572..fea8e5e15cc 100644
--- a/arch/um/sys-i386/tls.c
+++ b/arch/um/sys-i386/tls.c
@@ -23,9 +23,13 @@
#include "skas.h"
#endif
-/* If needed we can detect when it's uninitialized. */
+/*
+ * If needed we can detect when it's uninitialized.
+ *
+ * These are initialized in an initcall and unchanged thereafter.
+ */
static int host_supports_tls = -1;
-int host_gdt_entry_tls_min = -1;
+int host_gdt_entry_tls_min;
#ifdef CONFIG_MODE_SKAS
int do_set_thread_area_skas(struct user_desc *info)
@@ -361,7 +365,8 @@ out:
/* XXX: This part is probably common to i386 and x86-64. Don't create a common
* file for now, do that when implementing x86-64 support.*/
-static int __init __setup_host_supports_tls(void) {
+static int __init __setup_host_supports_tls(void)
+{
check_host_supports_tls(&host_supports_tls, &host_gdt_entry_tls_min);
if (host_supports_tls) {
printk(KERN_INFO "Host TLS support detected\n");
diff --git a/arch/um/sys-i386/user-offsets.c b/arch/um/sys-i386/user-offsets.c
index 447306b20ae..29118cf5ff2 100644
--- a/arch/um/sys-i386/user-offsets.c
+++ b/arch/um/sys-i386/user-offsets.c
@@ -1,9 +1,10 @@
#include <stdio.h>
+#include <stddef.h>
#include <signal.h>
+#include <sys/poll.h>
+#include <sys/mman.h>
#include <asm/ptrace.h>
#include <asm/user.h>
-#include <stddef.h>
-#include <sys/poll.h>
#define DEFINE(sym, val) \
asm volatile("\n->" #sym " %0 " #val : : "i" (val))
@@ -47,7 +48,6 @@ void foo(void)
OFFSET(HOST_SC_FP_ST, _fpstate, _st);
OFFSET(HOST_SC_FXSR_ENV, _fpstate, _fxsr_env);
- DEFINE(HOST_FRAME_SIZE, FRAME_SIZE);
DEFINE_LONGS(HOST_FP_SIZE, sizeof(struct user_i387_struct));
DEFINE_LONGS(HOST_XFP_SIZE, sizeof(struct user_fxsr_struct));
@@ -73,4 +73,8 @@ void foo(void)
DEFINE(UM_POLLIN, POLLIN);
DEFINE(UM_POLLPRI, POLLPRI);
DEFINE(UM_POLLOUT, POLLOUT);
+
+ DEFINE(UM_PROT_READ, PROT_READ);
+ DEFINE(UM_PROT_WRITE, PROT_WRITE);
+ DEFINE(UM_PROT_EXEC, PROT_EXEC);
}
diff --git a/arch/um/sys-ppc/sigcontext.c b/arch/um/sys-ppc/sigcontext.c
index 5d430fc994a..4bdc15c89ed 100644
--- a/arch/um/sys-ppc/sigcontext.c
+++ b/arch/um/sys-ppc/sigcontext.c
@@ -1,7 +1,6 @@
#include "asm/ptrace.h"
#include "asm/sigcontext.h"
#include "sysdep/ptrace.h"
-#include "user_util.h"
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
diff --git a/arch/um/sys-x86_64/bugs.c b/arch/um/sys-x86_64/bugs.c
index fdce7ea98ca..09547889037 100644
--- a/arch/um/sys-x86_64/bugs.c
+++ b/arch/um/sys-x86_64/bugs.c
@@ -4,12 +4,7 @@
* Licensed under the GPL
*/
-#include "linux/sched.h"
-#include "linux/errno.h"
-#include "asm/system.h"
-#include "asm/pda.h"
#include "sysdep/ptrace.h"
-#include "os.h"
void arch_init_thread(void)
{
@@ -21,102 +16,5 @@ void arch_check_bugs(void)
int arch_handle_signal(int sig, union uml_pt_regs *regs)
{
- return(0);
+ return 0;
}
-
-#define MAXTOKEN 64
-
-/* Set during early boot */
-int host_has_cmov = 1;
-int host_has_xmm = 0;
-
-static char token(int fd, char *buf, int len, char stop)
-{
- int n;
- char *ptr, *end, c;
-
- ptr = buf;
- end = &buf[len];
- do {
- n = os_read_file(fd, ptr, sizeof(*ptr));
- c = *ptr++;
- if(n != sizeof(*ptr)){
- if(n == 0) return(0);
- printk("Reading /proc/cpuinfo failed, err = %d\n", -n);
- if(n < 0)
- return(n);
- else
- return(-EIO);
- }
- } while((c != '\n') && (c != stop) && (ptr < end));
-
- if(ptr == end){
- printk("Failed to find '%c' in /proc/cpuinfo\n", stop);
- return(-1);
- }
- *(ptr - 1) = '\0';
- return(c);
-}
-
-static int find_cpuinfo_line(int fd, char *key, char *scratch, int len)
-{
- int n;
- char c;
-
- scratch[len - 1] = '\0';
- while(1){
- c = token(fd, scratch, len - 1, ':');
- if(c <= 0)
- return(0);
- else if(c != ':'){
- printk("Failed to find ':' in /proc/cpuinfo\n");
- return(0);
- }
-
- if(!strncmp(scratch, key, strlen(key)))
- return(1);
-
- do {
- n = os_read_file(fd, &c, sizeof(c));
- if(n != sizeof(c)){
- printk("Failed to find newline in "
- "/proc/cpuinfo, err = %d\n", -n);
- return(0);
- }
- } while(c != '\n');
- }
- return(0);
-}
-
-int cpu_feature(char *what, char *buf, int len)
-{
- int fd, ret = 0;
-
- fd = os_open_file("/proc/cpuinfo", of_read(OPENFLAGS()), 0);
- if(fd < 0){
- printk("Couldn't open /proc/cpuinfo, err = %d\n", -fd);
- return(0);
- }
-
- if(!find_cpuinfo_line(fd, what, buf, len)){
- printk("Couldn't find '%s' line in /proc/cpuinfo\n", what);
- goto out_close;
- }
-
- token(fd, buf, len, '\n');
- ret = 1;
-
- out_close:
- os_close_file(fd);
- return(ret);
-}
-
-/* Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/sys-x86_64/fault.c b/arch/um/sys-x86_64/fault.c
index cee1513c5c3..4636b1465b6 100644
--- a/arch/um/sys-x86_64/fault.c
+++ b/arch/um/sys-x86_64/fault.c
@@ -4,20 +4,24 @@
* Licensed under the GPL
*/
-#include "user.h"
+#include "sysdep/ptrace.h"
-int arch_fixup(unsigned long address, void *sc_ptr)
+/* These two are from asm-um/uaccess.h and linux/module.h, check them. */
+struct exception_table_entry
{
- /* XXX search_exception_tables() */
+ unsigned long insn;
+ unsigned long fixup;
+};
+
+const struct exception_table_entry *search_exception_tables(unsigned long add);
+int arch_fixup(unsigned long address, union uml_pt_regs *regs)
+{
+ const struct exception_table_entry *fixup;
+
+ fixup = search_exception_tables(address);
+ if(fixup != 0){
+ UPT_IP(regs) = fixup->fixup;
+ return(1);
+ }
return(0);
}
-
-/* Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/sys-x86_64/signal.c b/arch/um/sys-x86_64/signal.c
index af2f017617b..fe8ec04d35b 100644
--- a/arch/um/sys-x86_64/signal.c
+++ b/arch/um/sys-x86_64/signal.c
@@ -20,6 +20,36 @@
#include "skas.h"
+void copy_sc(union uml_pt_regs *regs, void *from)
+{
+ struct sigcontext *sc = from;
+
+#define GETREG(regs, regno, sc, regname) \
+ (regs)->skas.regs[(regno) / sizeof(unsigned long)] = (sc)->regname
+
+ GETREG(regs, R8, sc, r8);
+ GETREG(regs, R9, sc, r9);
+ GETREG(regs, R10, sc, r10);
+ GETREG(regs, R11, sc, r11);
+ GETREG(regs, R12, sc, r12);
+ GETREG(regs, R13, sc, r13);
+ GETREG(regs, R14, sc, r14);
+ GETREG(regs, R15, sc, r15);
+ GETREG(regs, RDI, sc, rdi);
+ GETREG(regs, RSI, sc, rsi);
+ GETREG(regs, RBP, sc, rbp);
+ GETREG(regs, RBX, sc, rbx);
+ GETREG(regs, RDX, sc, rdx);
+ GETREG(regs, RAX, sc, rax);
+ GETREG(regs, RCX, sc, rcx);
+ GETREG(regs, RSP, sc, rsp);
+ GETREG(regs, RIP, sc, rip);
+ GETREG(regs, EFLAGS, sc, eflags);
+ GETREG(regs, CS, sc, cs);
+
+#undef GETREG
+}
+
static int copy_sc_from_user_skas(struct pt_regs *regs,
struct sigcontext __user *from)
{
@@ -51,7 +81,7 @@ static int copy_sc_from_user_skas(struct pt_regs *regs,
#undef GETREG
- return(err);
+ return err;
}
int copy_sc_to_user_skas(struct sigcontext __user *to,
diff --git a/arch/um/sys-x86_64/user-offsets.c b/arch/um/sys-x86_64/user-offsets.c
index 899cebb57c3..0d5fd764c21 100644
--- a/arch/um/sys-x86_64/user-offsets.c
+++ b/arch/um/sys-x86_64/user-offsets.c
@@ -2,6 +2,7 @@
#include <stddef.h>
#include <signal.h>
#include <sys/poll.h>
+#include <sys/mman.h>
#define __FRAME_OFFSETS
#include <asm/ptrace.h>
#include <asm/types.h>
@@ -57,7 +58,6 @@ void foo(void)
OFFSET(HOST_SC_SS, sigcontext, ss);
#endif
- DEFINE_LONGS(HOST_FRAME_SIZE, FRAME_SIZE);
DEFINE(HOST_FP_SIZE, sizeof(struct _fpstate) / sizeof(unsigned long));
DEFINE(HOST_XFP_SIZE, 0);
DEFINE_LONGS(HOST_RBX, RBX);
@@ -94,4 +94,8 @@ void foo(void)
DEFINE(UM_POLLIN, POLLIN);
DEFINE(UM_POLLPRI, POLLPRI);
DEFINE(UM_POLLOUT, POLLOUT);
+
+ DEFINE(UM_PROT_READ, PROT_READ);
+ DEFINE(UM_PROT_WRITE, PROT_WRITE);
+ DEFINE(UM_PROT_EXEC, PROT_EXEC);
}
diff --git a/arch/v850/Kconfig b/arch/v850/Kconfig
index 50ccc7f57cd..5f54c1236c1 100644
--- a/arch/v850/Kconfig
+++ b/arch/v850/Kconfig
@@ -37,6 +37,10 @@ config GENERIC_IRQ_PROBE
bool
default y
+config GENERIC_TIME
+ bool
+ default y
+
config TIME_LOW_RES
bool
default y
diff --git a/arch/v850/kernel/time.c b/arch/v850/kernel/time.c
index 486e3a441c8..f0905b03523 100644
--- a/arch/v850/kernel/time.c
+++ b/arch/v850/kernel/time.c
@@ -90,81 +90,6 @@ static irqreturn_t timer_interrupt (int irq, void *dummy, struct pt_regs *regs)
return IRQ_HANDLED;
}
-/*
- * This version of gettimeofday has near microsecond resolution.
- */
-void do_gettimeofday (struct timeval *tv)
-{
-#if 0 /* DAVIDM later if possible */
- extern volatile unsigned long lost_ticks;
- unsigned long lost;
-#endif
- unsigned long flags;
- unsigned long usec, sec;
- unsigned long seq;
-
- do {
- seq = read_seqbegin_irqsave(&xtime_lock, flags);
-
-#if 0
- usec = mach_gettimeoffset ? mach_gettimeoffset () : 0;
-#else
- usec = 0;
-#endif
-#if 0 /* DAVIDM later if possible */
- lost = lost_ticks;
- if (lost)
- usec += lost * (1000000/HZ);
-#endif
- sec = xtime.tv_sec;
- usec += xtime.tv_nsec / 1000;
- } while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
-
- while (usec >= 1000000) {
- usec -= 1000000;
- sec++;
- }
-
- tv->tv_sec = sec;
- tv->tv_usec = usec;
-}
-
-EXPORT_SYMBOL(do_gettimeofday);
-
-int do_settimeofday(struct timespec *tv)
-{
- if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
- return -EINVAL;
-
- write_seqlock_irq (&xtime_lock);
-
- /* This is revolting. We need to set the xtime.tv_nsec
- * correctly. However, the value in this location is
- * is value at the last tick.
- * Discover what correction gettimeofday
- * would have done, and then undo it!
- */
-#if 0
- tv->tv_nsec -= mach_gettimeoffset() * 1000;
-#endif
-
- while (tv->tv_nsec < 0) {
- tv->tv_nsec += NSEC_PER_SEC;
- tv->tv_sec--;
- }
-
- xtime.tv_sec = tv->tv_sec;
- xtime.tv_nsec = tv->tv_nsec;
-
- ntp_clear();
-
- write_sequnlock_irq (&xtime_lock);
- clock_was_set();
- return 0;
-}
-
-EXPORT_SYMBOL(do_settimeofday);
-
static int timer_dev_id;
static struct irqaction timer_irqaction = {
timer_interrupt,
diff --git a/arch/x86_64/kernel/e820.c b/arch/x86_64/kernel/e820.c
index be8965427a9..13c6c37610e 100644
--- a/arch/x86_64/kernel/e820.c
+++ b/arch/x86_64/kernel/e820.c
@@ -17,6 +17,8 @@
#include <linux/kexec.h>
#include <linux/module.h>
#include <linux/mm.h>
+#include <linux/suspend.h>
+#include <linux/pfn.h>
#include <asm/pgtable.h>
#include <asm/page.h>
@@ -256,22 +258,6 @@ void __init e820_reserve_resources(void)
}
}
-/* Mark pages corresponding to given address range as nosave */
-static void __init
-e820_mark_nosave_range(unsigned long start, unsigned long end)
-{
- unsigned long pfn, max_pfn;
-
- if (start >= end)
- return;
-
- printk("Nosave address range: %016lx - %016lx\n", start, end);
- max_pfn = end >> PAGE_SHIFT;
- for (pfn = start >> PAGE_SHIFT; pfn < max_pfn; pfn++)
- if (pfn_valid(pfn))
- SetPageNosave(pfn_to_page(pfn));
-}
-
/*
* Find the ranges of physical addresses that do not correspond to
* e820 RAM areas and mark the corresponding pages as nosave for software
@@ -290,13 +276,13 @@ void __init e820_mark_nosave_regions(void)
struct e820entry *ei = &e820.map[i];
if (paddr < ei->addr)
- e820_mark_nosave_range(paddr,
- round_up(ei->addr, PAGE_SIZE));
+ register_nosave_region(PFN_DOWN(paddr),
+ PFN_UP(ei->addr));
paddr = round_down(ei->addr + ei->size, PAGE_SIZE);
if (ei->type != E820_RAM)
- e820_mark_nosave_range(round_up(ei->addr, PAGE_SIZE),
- paddr);
+ register_nosave_region(PFN_UP(ei->addr),
+ PFN_DOWN(paddr));
if (paddr >= (end_pfn << PAGE_SHIFT))
break;
diff --git a/arch/x86_64/kernel/machine_kexec.c b/arch/x86_64/kernel/machine_kexec.c
index a8bb33c1a8f..c3a55470367 100644
--- a/arch/x86_64/kernel/machine_kexec.c
+++ b/arch/x86_64/kernel/machine_kexec.c
@@ -189,21 +189,21 @@ NORET_TYPE void machine_kexec(struct kimage *image)
control_page = page_address(image->control_code_page) + PAGE_SIZE;
memcpy(control_page, relocate_kernel, PAGE_SIZE);
- page_list[PA_CONTROL_PAGE] = __pa(control_page);
+ page_list[PA_CONTROL_PAGE] = virt_to_phys(control_page);
page_list[VA_CONTROL_PAGE] = (unsigned long)relocate_kernel;
- page_list[PA_PGD] = __pa_symbol(&kexec_pgd);
+ page_list[PA_PGD] = virt_to_phys(&kexec_pgd);
page_list[VA_PGD] = (unsigned long)kexec_pgd;
- page_list[PA_PUD_0] = __pa_symbol(&kexec_pud0);
+ page_list[PA_PUD_0] = virt_to_phys(&kexec_pud0);
page_list[VA_PUD_0] = (unsigned long)kexec_pud0;
- page_list[PA_PMD_0] = __pa_symbol(&kexec_pmd0);
+ page_list[PA_PMD_0] = virt_to_phys(&kexec_pmd0);
page_list[VA_PMD_0] = (unsigned long)kexec_pmd0;
- page_list[PA_PTE_0] = __pa_symbol(&kexec_pte0);
+ page_list[PA_PTE_0] = virt_to_phys(&kexec_pte0);
page_list[VA_PTE_0] = (unsigned long)kexec_pte0;
- page_list[PA_PUD_1] = __pa_symbol(&kexec_pud1);
+ page_list[PA_PUD_1] = virt_to_phys(&kexec_pud1);
page_list[VA_PUD_1] = (unsigned long)kexec_pud1;
- page_list[PA_PMD_1] = __pa_symbol(&kexec_pmd1);
+ page_list[PA_PMD_1] = virt_to_phys(&kexec_pmd1);
page_list[VA_PMD_1] = (unsigned long)kexec_pmd1;
- page_list[PA_PTE_1] = __pa_symbol(&kexec_pte1);
+ page_list[PA_PTE_1] = virt_to_phys(&kexec_pte1);
page_list[VA_PTE_1] = (unsigned long)kexec_pte1;
page_list[PA_TABLE_PAGE] =
diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c
index db30b5bcef6..db51577bda3 100644
--- a/arch/x86_64/kernel/setup.c
+++ b/arch/x86_64/kernel/setup.c
@@ -245,12 +245,11 @@ void __init setup_arch(char **cmdline_p)
init_mm.end_code = (unsigned long) &_etext;
init_mm.end_data = (unsigned long) &_edata;
init_mm.brk = (unsigned long) &_end;
- init_mm.pgd = __va(__pa_symbol(&init_level4_pgt));
- code_resource.start = __pa_symbol(&_text);
- code_resource.end = __pa_symbol(&_etext)-1;
- data_resource.start = __pa_symbol(&_etext);
- data_resource.end = __pa_symbol(&_edata)-1;
+ code_resource.start = virt_to_phys(&_text);
+ code_resource.end = virt_to_phys(&_etext)-1;
+ data_resource.start = virt_to_phys(&_etext);
+ data_resource.end = virt_to_phys(&_edata)-1;
early_identify_cpu(&boot_cpu_data);
diff --git a/arch/x86_64/kernel/smp.c b/arch/x86_64/kernel/smp.c
index 22abae4e9f3..bd1d123947c 100644
--- a/arch/x86_64/kernel/smp.c
+++ b/arch/x86_64/kernel/smp.c
@@ -76,7 +76,7 @@ static inline void leave_mm(int cpu)
if (read_pda(mmu_state) == TLBSTATE_OK)
BUG();
cpu_clear(cpu, read_pda(active_mm)->cpu_vm_mask);
- load_cr3(init_mm.pgd);
+ load_cr3(swapper_pg_dir);
}
/*
diff --git a/arch/x86_64/kernel/sys_x86_64.c b/arch/x86_64/kernel/sys_x86_64.c
index 76bf7c241fe..f891931eb75 100644
--- a/arch/x86_64/kernel/sys_x86_64.c
+++ b/arch/x86_64/kernel/sys_x86_64.c
@@ -93,6 +93,9 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
unsigned long start_addr;
unsigned long begin, end;
+ if (flags & MAP_FIXED)
+ return addr;
+
find_start_end(flags, &begin, &end);
if (len > end)
diff --git a/arch/x86_64/mm/init.c b/arch/x86_64/mm/init.c
index 282b0a8f00a..c0822683b91 100644
--- a/arch/x86_64/mm/init.c
+++ b/arch/x86_64/mm/init.c
@@ -572,13 +572,13 @@ void free_init_pages(char *what, unsigned long begin, unsigned long end)
printk(KERN_INFO "Freeing %s: %luk freed\n", what, (end - begin) >> 10);
for (addr = begin; addr < end; addr += PAGE_SIZE) {
- struct page *page = pfn_to_page(addr >> PAGE_SHIFT);
- ClearPageReserved(page);
- init_page_count(page);
- memset(page_address(page), POISON_FREE_INITMEM, PAGE_SIZE);
+ ClearPageReserved(virt_to_page(addr));
+ init_page_count(virt_to_page(addr));
+ memset((void *)(addr & ~(PAGE_SIZE-1)),
+ POISON_FREE_INITMEM, PAGE_SIZE);
if (addr >= __START_KERNEL_map)
change_page_attr_addr(addr, 1, __pgprot(0));
- __free_page(page);
+ free_page(addr);
totalram_pages++;
}
if (addr > __START_KERNEL_map)
@@ -588,26 +588,31 @@ void free_init_pages(char *what, unsigned long begin, unsigned long end)
void free_initmem(void)
{
free_init_pages("unused kernel memory",
- __pa_symbol(&__init_begin),
- __pa_symbol(&__init_end));
+ (unsigned long)(&__init_begin),
+ (unsigned long)(&__init_end));
}
#ifdef CONFIG_DEBUG_RODATA
void mark_rodata_ro(void)
{
- unsigned long start = PFN_ALIGN(__va(__pa_symbol(&_stext))), size;
+ unsigned long start = (unsigned long)_stext, end;
#ifdef CONFIG_HOTPLUG_CPU
/* It must still be possible to apply SMP alternatives. */
if (num_possible_cpus() > 1)
- start = PFN_ALIGN(__va(__pa_symbol(&_etext)));
+ start = (unsigned long)_etext;
#endif
- size = (unsigned long)__va(__pa_symbol(&__end_rodata)) - start;
- change_page_attr_addr(start, size >> PAGE_SHIFT, PAGE_KERNEL_RO);
+ end = (unsigned long)__end_rodata;
+ start = (start + PAGE_SIZE - 1) & PAGE_MASK;
+ end &= PAGE_MASK;
+ if (end <= start)
+ return;
+
+ change_page_attr_addr(start, (end - start) >> PAGE_SHIFT, PAGE_KERNEL_RO);
printk(KERN_INFO "Write protecting the kernel read-only data: %luk\n",
- size >> 10);
+ (end - start) >> 10);
/*
* change_page_attr_addr() requires a global_flush_tlb() call after it.
@@ -622,7 +627,7 @@ void mark_rodata_ro(void)
#ifdef CONFIG_BLK_DEV_INITRD
void free_initrd_mem(unsigned long start, unsigned long end)
{
- free_init_pages("initrd memory", __pa(start), __pa(end));
+ free_init_pages("initrd memory", start, end);
}
#endif
diff --git a/arch/x86_64/mm/ioremap.c b/arch/x86_64/mm/ioremap.c
index c6e5e8d401a..6cac90aa503 100644
--- a/arch/x86_64/mm/ioremap.c
+++ b/arch/x86_64/mm/ioremap.c
@@ -13,12 +13,21 @@
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/io.h>
+
#include <asm/pgalloc.h>
#include <asm/fixmap.h>
#include <asm/tlbflush.h>
#include <asm/cacheflush.h>
#include <asm/proto.h>
+unsigned long __phys_addr(unsigned long x)
+{
+ if (x >= __START_KERNEL_map)
+ return x - __START_KERNEL_map + phys_base;
+ return x - PAGE_OFFSET;
+}
+EXPORT_SYMBOL(__phys_addr);
+
#define ISA_START_ADDRESS 0xa0000
#define ISA_END_ADDRESS 0x100000
diff --git a/arch/x86_64/mm/pageattr.c b/arch/x86_64/mm/pageattr.c
index bf4aa8dd425..d653d0bf3df 100644
--- a/arch/x86_64/mm/pageattr.c
+++ b/arch/x86_64/mm/pageattr.c
@@ -51,6 +51,7 @@ static struct page *split_large_page(unsigned long address, pgprot_t prot,
SetPagePrivate(base);
page_private(base) = 0;
+ address = __pa(address);
addr = address & LARGE_PAGE_MASK;
pbase = (pte_t *)page_address(base);
for (i = 0; i < PTRS_PER_PTE; i++, addr += PAGE_SIZE) {
@@ -100,12 +101,13 @@ static inline void save_page(struct page *fpage)
* No more special protections in this 2/4MB area - revert to a
* large page again.
*/
-static void revert_page(unsigned long address, unsigned long pfn, pgprot_t ref_prot)
+static void revert_page(unsigned long address, pgprot_t ref_prot)
{
pgd_t *pgd;
pud_t *pud;
pmd_t *pmd;
pte_t large_pte;
+ unsigned long pfn;
pgd = pgd_offset_k(address);
BUG_ON(pgd_none(*pgd));
@@ -113,6 +115,7 @@ static void revert_page(unsigned long address, unsigned long pfn, pgprot_t ref_p
BUG_ON(pud_none(*pud));
pmd = pmd_offset(pud, address);
BUG_ON(pmd_val(*pmd) & _PAGE_PSE);
+ pfn = (__pa(address) & LARGE_PAGE_MASK) >> PAGE_SHIFT;
large_pte = pfn_pte(pfn, ref_prot);
large_pte = pte_mkhuge(large_pte);
set_pte((pte_t *)pmd, large_pte);
@@ -138,8 +141,7 @@ __change_page_attr(unsigned long address, unsigned long pfn, pgprot_t prot,
*/
struct page *split;
ref_prot2 = pte_pgprot(pte_clrhuge(*kpte));
- split = split_large_page(pfn << PAGE_SHIFT, prot,
- ref_prot2);
+ split = split_large_page(address, prot, ref_prot2);
if (!split)
return -ENOMEM;
set_pte(kpte, mk_pte(split, ref_prot2));
@@ -158,7 +160,7 @@ __change_page_attr(unsigned long address, unsigned long pfn, pgprot_t prot,
if (page_private(kpte_page) == 0) {
save_page(kpte_page);
- revert_page(address, pfn, ref_prot);
+ revert_page(address, ref_prot);
}
return 0;
}
@@ -178,7 +180,6 @@ __change_page_attr(unsigned long address, unsigned long pfn, pgprot_t prot,
*/
int change_page_attr_addr(unsigned long address, int numpages, pgprot_t prot)
{
- unsigned long phys_base_pfn = __pa_symbol(__START_KERNEL_map) >> PAGE_SHIFT;
int err = 0, kernel_map = 0;
int i;
@@ -199,11 +200,10 @@ int change_page_attr_addr(unsigned long address, int numpages, pgprot_t prot)
}
/* Handle kernel mapping too which aliases part of the
* lowmem */
- if ((pfn >= phys_base_pfn) &&
- ((pfn - phys_base_pfn) < (KERNEL_TEXT_SIZE >> PAGE_SHIFT))) {
+ if (__pa(address) < KERNEL_TEXT_SIZE) {
unsigned long addr2;
pgprot_t prot2;
- addr2 = __START_KERNEL_map + ((pfn - phys_base_pfn) << PAGE_SHIFT);
+ addr2 = __START_KERNEL_map + __pa(address);
/* Make sure the kernel mappings stay executable */
prot2 = pte_pgprot(pte_mkexec(pfn_pte(0, prot)));
err = __change_page_attr(addr2, pfn, prot2,
diff --git a/arch/xtensa/platform-iss/network.c b/arch/xtensa/platform-iss/network.c
index ab05bff4010..4bfe333be22 100644
--- a/arch/xtensa/platform-iss/network.c
+++ b/arch/xtensa/platform-iss/network.c
@@ -251,7 +251,7 @@ static int tuntap_open(struct iss_net_private *lp)
memset(&ifr, 0, sizeof ifr);
ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
- strlcpy(ifr.ifr_name, dev_name, sizeof ifr.ifr_name - 1);
+ strlcpy(ifr.ifr_name, dev_name, sizeof ifr.ifr_name);
if ((err = simc_ioctl(fd, TUNSETIFF, (void*) &ifr)) < 0) {
printk("Failed to set interface, returned %d "