summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/sh/Kconfig32
-rw-r--r--arch/sh/Kconfig.cpu3
-rw-r--r--arch/sh/Makefile10
-rw-r--r--arch/sh/boards/Kconfig8
-rw-r--r--arch/sh/boards/Makefile1
-rw-r--r--arch/sh/boards/board-magicpanelr2.c74
-rw-r--r--arch/sh/boards/board-polaris.c37
-rw-r--r--arch/sh/boards/board-sh7785lcr.c32
-rw-r--r--arch/sh/boards/board-shmin.c4
-rw-r--r--arch/sh/boards/board-titan.c (renamed from arch/sh/boards/mach-titan/setup.c)24
-rw-r--r--arch/sh/boards/board-urquell.c46
-rw-r--r--arch/sh/boards/mach-ap325rxa/setup.c20
-rw-r--r--arch/sh/boards/mach-cayman/irq.c16
-rw-r--r--arch/sh/boards/mach-dreamcast/irq.c27
-rw-r--r--arch/sh/boards/mach-dreamcast/rtc.c20
-rw-r--r--arch/sh/boards/mach-dreamcast/setup.c18
-rw-r--r--arch/sh/boards/mach-ecovec24/sdram.S59
-rw-r--r--arch/sh/boards/mach-ecovec24/setup.c87
-rw-r--r--arch/sh/boards/mach-highlander/irq-r7780mp.c2
-rw-r--r--arch/sh/boards/mach-highlander/irq-r7780rp.c2
-rw-r--r--arch/sh/boards/mach-highlander/irq-r7785rp.c16
-rw-r--r--arch/sh/boards/mach-highlander/psw.c4
-rw-r--r--arch/sh/boards/mach-highlander/setup.c14
-rw-r--r--arch/sh/boards/mach-hp6xx/hp6xx_apm.c2
-rw-r--r--arch/sh/boards/mach-hp6xx/pm.c38
-rw-r--r--arch/sh/boards/mach-hp6xx/setup.c12
-rw-r--r--arch/sh/boards/mach-kfr2r09/setup.c16
-rw-r--r--arch/sh/boards/mach-landisk/gio.c12
-rw-r--r--arch/sh/boards/mach-landisk/irq.c6
-rw-r--r--arch/sh/boards/mach-landisk/psw.c4
-rw-r--r--arch/sh/boards/mach-landisk/setup.c6
-rw-r--r--arch/sh/boards/mach-lboxre2/setup.c4
-rw-r--r--arch/sh/boards/mach-microdev/io.c4
-rw-r--r--arch/sh/boards/mach-microdev/irq.c10
-rw-r--r--arch/sh/boards/mach-migor/setup.c22
-rw-r--r--arch/sh/boards/mach-r2d/irq.c4
-rw-r--r--arch/sh/boards/mach-r2d/setup.c8
-rw-r--r--arch/sh/boards/mach-rsk/devices-rsk7203.c2
-rw-r--r--arch/sh/boards/mach-sdk7780/irq.c4
-rw-r--r--arch/sh/boards/mach-sdk7780/setup.c29
-rw-r--r--arch/sh/boards/mach-sdk7786/Makefile1
-rw-r--r--arch/sh/boards/mach-sdk7786/fpga.c72
-rw-r--r--arch/sh/boards/mach-sdk7786/irq.c48
-rw-r--r--arch/sh/boards/mach-sdk7786/setup.c189
-rw-r--r--arch/sh/boards/mach-se/7206/io.c2
-rw-r--r--arch/sh/boards/mach-se/7206/irq.c43
-rw-r--r--arch/sh/boards/mach-se/7206/setup.c15
-rw-r--r--arch/sh/boards/mach-se/7343/irq.c45
-rw-r--r--arch/sh/boards/mach-se/7343/setup.c43
-rw-r--r--arch/sh/boards/mach-se/770x/irq.c14
-rw-r--r--arch/sh/boards/mach-se/770x/setup.c15
-rw-r--r--arch/sh/boards/mach-se/7721/irq.c2
-rw-r--r--arch/sh/boards/mach-se/7721/setup.c23
-rw-r--r--arch/sh/boards/mach-se/7722/irq.c10
-rw-r--r--arch/sh/boards/mach-se/7722/setup.c55
-rw-r--r--arch/sh/boards/mach-se/7724/irq.c62
-rw-r--r--arch/sh/boards/mach-se/7724/sdram.S79
-rw-r--r--arch/sh/boards/mach-se/7724/setup.c114
-rw-r--r--arch/sh/boards/mach-se/7780/irq.c18
-rw-r--r--arch/sh/boards/mach-se/7780/setup.c47
-rw-r--r--arch/sh/boards/mach-sh03/rtc.c50
-rw-r--r--arch/sh/boards/mach-sh03/setup.c2
-rw-r--r--arch/sh/boards/mach-sh7763rdp/irq.c10
-rw-r--r--arch/sh/boards/mach-sh7763rdp/setup.c40
-rw-r--r--arch/sh/boards/mach-snapgear/setup.c2
-rw-r--r--arch/sh/boards/mach-systemh/irq.c12
-rw-r--r--arch/sh/boards/mach-titan/Makefile5
-rw-r--r--arch/sh/boards/mach-titan/io.c108
-rw-r--r--arch/sh/boards/mach-x3proto/ilsel.c8
-rw-r--r--arch/sh/boards/mach-x3proto/setup.c2
-rw-r--r--arch/sh/boot/Makefile30
-rw-r--r--arch/sh/boot/compressed/Makefile7
-rw-r--r--arch/sh/boot/compressed/misc.c23
-rw-r--r--arch/sh/cchips/hd6446x/hd64461.c36
-rw-r--r--arch/sh/configs/sdk7786_defconfig1754
-rw-r--r--arch/sh/drivers/dma/dma-pvr2.c10
-rw-r--r--arch/sh/drivers/dma/dma-sh.c31
-rw-r--r--arch/sh/drivers/dma/dmabrg.c22
-rw-r--r--arch/sh/drivers/heartbeat.c22
-rw-r--r--arch/sh/drivers/pci/Makefile5
-rw-r--r--arch/sh/drivers/pci/common.c162
-rw-r--r--arch/sh/drivers/pci/fixups-dreamcast.c2
-rw-r--r--arch/sh/drivers/pci/fixups-r7780rp.c12
-rw-r--r--arch/sh/drivers/pci/fixups-rts7751r2d.c4
-rw-r--r--arch/sh/drivers/pci/fixups-sdk7780.c19
-rw-r--r--arch/sh/drivers/pci/fixups-se7751.c6
-rw-r--r--arch/sh/drivers/pci/ops-sh4.c30
-rw-r--r--arch/sh/drivers/pci/pci-dreamcast.c32
-rw-r--r--arch/sh/drivers/pci/pci-sh4.h18
-rw-r--r--arch/sh/drivers/pci/pci-sh5.c19
-rw-r--r--arch/sh/drivers/pci/pci-sh5.h12
-rw-r--r--arch/sh/drivers/pci/pci-sh7751.c52
-rw-r--r--arch/sh/drivers/pci/pci-sh7780.c408
-rw-r--r--arch/sh/drivers/pci/pci-sh7780.h64
-rw-r--r--arch/sh/drivers/pci/pci.c167
-rw-r--r--arch/sh/drivers/pci/pcie-sh7786.c205
-rw-r--r--arch/sh/drivers/pci/pcie-sh7786.h74
-rw-r--r--arch/sh/drivers/superhyway/ops-sh4-202.c8
-rw-r--r--arch/sh/include/asm/Kbuild4
-rw-r--r--arch/sh/include/asm/addrspace.h18
-rw-r--r--arch/sh/include/asm/alignment.h21
-rw-r--r--arch/sh/include/asm/atomic-grb.h46
-rw-r--r--arch/sh/include/asm/atomic-llsc.h27
-rw-r--r--arch/sh/include/asm/atomic.h73
-rw-r--r--arch/sh/include/asm/clock.h11
-rw-r--r--arch/sh/include/asm/cmpxchg-grb.h7
-rw-r--r--arch/sh/include/asm/dma-mapping.h2
-rw-r--r--arch/sh/include/asm/dma-sh.h55
-rw-r--r--arch/sh/include/asm/dwarf.h19
-rw-r--r--arch/sh/include/asm/fixmap.h15
-rw-r--r--arch/sh/include/asm/fpu.h35
-rw-r--r--arch/sh/include/asm/hw_breakpoint.h67
-rw-r--r--arch/sh/include/asm/io.h169
-rw-r--r--arch/sh/include/asm/kdebug.h2
-rw-r--r--arch/sh/include/asm/mmu.h49
-rw-r--r--arch/sh/include/asm/mmu_context.h6
-rw-r--r--arch/sh/include/asm/mmu_context_32.h4
-rw-r--r--arch/sh/include/asm/module.h17
-rw-r--r--arch/sh/include/asm/page.h19
-rw-r--r--arch/sh/include/asm/pci.h59
-rw-r--r--arch/sh/include/asm/pgalloc.h32
-rw-r--r--arch/sh/include/asm/pgtable-2level.h23
-rw-r--r--arch/sh/include/asm/pgtable-3level.h56
-rw-r--r--arch/sh/include/asm/pgtable.h26
-rw-r--r--arch/sh/include/asm/pgtable_32.h4
-rw-r--r--arch/sh/include/asm/pgtable_64.h26
-rw-r--r--arch/sh/include/asm/processor.h21
-rw-r--r--arch/sh/include/asm/processor_32.h35
-rw-r--r--arch/sh/include/asm/processor_64.h23
-rw-r--r--arch/sh/include/asm/ptrace.h20
-rw-r--r--arch/sh/include/asm/reboot.h21
-rw-r--r--arch/sh/include/asm/setup.h1
-rw-r--r--arch/sh/include/asm/sh_bios.h15
-rw-r--r--arch/sh/include/asm/suspend.h1
-rw-r--r--arch/sh/include/asm/system.h9
-rw-r--r--arch/sh/include/asm/system_32.h15
-rw-r--r--arch/sh/include/asm/system_64.h10
-rw-r--r--arch/sh/include/asm/thread_info.h10
-rw-r--r--arch/sh/include/asm/tlb.h17
-rw-r--r--arch/sh/include/asm/ubc.h64
-rw-r--r--arch/sh/include/asm/uncached.h18
-rw-r--r--arch/sh/include/asm/vmlinux.lds.h8
-rw-r--r--arch/sh/include/asm/watchdog.h18
-rw-r--r--arch/sh/include/cpu-sh2/cpu/ubc.h32
-rw-r--r--arch/sh/include/cpu-sh2/cpu/watchdog.h4
-rw-r--r--arch/sh/include/cpu-sh3/cpu/dac.h12
-rw-r--r--arch/sh/include/cpu-sh3/cpu/dma.h20
-rw-r--r--arch/sh/include/cpu-sh3/cpu/ubc.h42
-rw-r--r--arch/sh/include/cpu-sh4/cpu/addrspace.h9
-rw-r--r--arch/sh/include/cpu-sh4/cpu/dma-sh4a.h108
-rw-r--r--arch/sh/include/cpu-sh4/cpu/dma.h35
-rw-r--r--arch/sh/include/cpu-sh4/cpu/mmu_context.h4
-rw-r--r--arch/sh/include/cpu-sh4/cpu/sq.h3
-rw-r--r--arch/sh/include/cpu-sh4/cpu/ubc.h64
-rw-r--r--arch/sh/include/mach-common/mach/magicpanelr2.h12
-rw-r--r--arch/sh/include/mach-dreamcast/mach/sysasic.h5
-rw-r--r--arch/sh/include/mach-sdk7786/mach/fpga.h114
-rw-r--r--arch/sh/include/mach-sdk7786/mach/irq.h7
-rw-r--r--arch/sh/include/mach-se/mach/se7343.h52
-rw-r--r--arch/sh/kernel/Makefile8
-rw-r--r--arch/sh/kernel/cpu/Makefile2
-rw-r--r--arch/sh/kernel/cpu/adc.c12
-rw-r--r--arch/sh/kernel/cpu/clock-cpg.c104
-rw-r--r--arch/sh/kernel/cpu/fpu.c84
-rw-r--r--arch/sh/kernel/cpu/init.c125
-rw-r--r--arch/sh/kernel/cpu/irq/intc-sh5.c14
-rw-r--r--arch/sh/kernel/cpu/sh2/clock-sh7619.c6
-rw-r--r--arch/sh/kernel/cpu/sh2a/clock-sh7201.c8
-rw-r--r--arch/sh/kernel/cpu/sh2a/clock-sh7203.c6
-rw-r--r--arch/sh/kernel/cpu/sh2a/clock-sh7206.c8
-rw-r--r--arch/sh/kernel/cpu/sh2a/fpu.c111
-rw-r--r--arch/sh/kernel/cpu/sh3/clock-sh3.c8
-rw-r--r--arch/sh/kernel/cpu/sh3/clock-sh7705.c8
-rw-r--r--arch/sh/kernel/cpu/sh3/clock-sh7706.c8
-rw-r--r--arch/sh/kernel/cpu/sh3/clock-sh7709.c8
-rw-r--r--arch/sh/kernel/cpu/sh3/clock-sh7710.c8
-rw-r--r--arch/sh/kernel/cpu/sh3/clock-sh7712.c6
-rw-r--r--arch/sh/kernel/cpu/sh3/ex.S2
-rw-r--r--arch/sh/kernel/cpu/sh3/probe.c28
-rw-r--r--arch/sh/kernel/cpu/sh3/setup-sh3.c2
-rw-r--r--arch/sh/kernel/cpu/sh4/clock-sh4-202.c10
-rw-r--r--arch/sh/kernel/cpu/sh4/clock-sh4.c8
-rw-r--r--arch/sh/kernel/cpu/sh4/fpu.c159
-rw-r--r--arch/sh/kernel/cpu/sh4/probe.c14
-rw-r--r--arch/sh/kernel/cpu/sh4/setup-sh4-202.c2
-rw-r--r--arch/sh/kernel/cpu/sh4/setup-sh7750.c2
-rw-r--r--arch/sh/kernel/cpu/sh4/setup-sh7760.c2
-rw-r--r--arch/sh/kernel/cpu/sh4/sq.c23
-rw-r--r--arch/sh/kernel/cpu/sh4a/Makefile9
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7343.c6
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7366.c6
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7722.c29
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7723.c30
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7724.c19
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7757.c8
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7763.c8
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7770.c8
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7780.c10
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7785.c6
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7786.c184
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-shx3.c10
-rw-r--r--arch/sh/kernel/cpu/sh4a/pinmux-sh7722.c21
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7722.c20
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7723.c39
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7724.c39
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7757.c26
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7763.c20
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7770.c24
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7780.c24
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7785.c26
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7786.c24
-rw-r--r--arch/sh/kernel/cpu/sh4a/smp-shx3.c5
-rw-r--r--arch/sh/kernel/cpu/sh4a/ubc.c133
-rw-r--r--arch/sh/kernel/cpu/sh5/clock-sh5.c8
-rw-r--r--arch/sh/kernel/cpu/sh5/entry.S6
-rw-r--r--arch/sh/kernel/cpu/sh5/fpu.c65
-rw-r--r--arch/sh/kernel/cpu/shmobile/pm.c3
-rw-r--r--arch/sh/kernel/cpu/shmobile/sleep.S121
-rw-r--r--arch/sh/kernel/debugtraps.S1
-rw-r--r--arch/sh/kernel/dwarf.c174
-rw-r--r--arch/sh/kernel/early_printk.c85
-rw-r--r--arch/sh/kernel/head_32.S221
-rw-r--r--arch/sh/kernel/head_64.S2
-rw-r--r--arch/sh/kernel/hw_breakpoint.c463
-rw-r--r--arch/sh/kernel/idle.c14
-rw-r--r--arch/sh/kernel/io_trapped.c18
-rw-r--r--arch/sh/kernel/kgdb.c46
-rw-r--r--arch/sh/kernel/machine_kexec.c16
-rw-r--r--arch/sh/kernel/process.c100
-rw-r--r--arch/sh/kernel/process_32.c164
-rw-r--r--arch/sh/kernel/process_64.c27
-rw-r--r--arch/sh/kernel/ptrace_32.c82
-rw-r--r--arch/sh/kernel/ptrace_64.c16
-rw-r--r--arch/sh/kernel/reboot.c98
-rw-r--r--arch/sh/kernel/setup.c12
-rw-r--r--arch/sh/kernel/sh_bios.c129
-rw-r--r--arch/sh/kernel/signal_32.c10
-rw-r--r--arch/sh/kernel/signal_64.c4
-rw-r--r--arch/sh/kernel/smp.c9
-rw-r--r--arch/sh/kernel/traps.c4
-rw-r--r--arch/sh/kernel/traps_32.c181
-rw-r--r--arch/sh/kernel/traps_64.c28
-rw-r--r--arch/sh/kernel/vmlinux.lds.S42
-rw-r--r--arch/sh/math-emu/math.c12
-rw-r--r--arch/sh/mm/Kconfig48
-rw-r--r--arch/sh/mm/Makefile12
-rw-r--r--arch/sh/mm/alignment.c189
-rw-r--r--arch/sh/mm/cache-debugfs.c7
-rw-r--r--arch/sh/mm/cache-sh2.c12
-rw-r--r--arch/sh/mm/cache-sh2a.c20
-rw-r--r--arch/sh/mm/cache-sh3.c6
-rw-r--r--arch/sh/mm/cache-sh4.c27
-rw-r--r--arch/sh/mm/cache-sh7705.c12
-rw-r--r--arch/sh/mm/cache.c13
-rw-r--r--arch/sh/mm/fault_32.c3
-rw-r--r--arch/sh/mm/init.c166
-rw-r--r--arch/sh/mm/ioremap.c (renamed from arch/sh/mm/ioremap_32.c)63
-rw-r--r--arch/sh/mm/ioremap_64.c326
-rw-r--r--arch/sh/mm/ioremap_fixed.c128
-rw-r--r--arch/sh/mm/nommu.c4
-rw-r--r--arch/sh/mm/pgtable.c56
-rw-r--r--arch/sh/mm/pmb.c586
-rw-r--r--arch/sh/mm/tlb-pteaex.c3
-rw-r--r--arch/sh/mm/tlb-sh3.c6
-rw-r--r--arch/sh/mm/tlb-sh4.c13
-rw-r--r--arch/sh/mm/tlb-sh5.c39
-rw-r--r--arch/sh/mm/tlb-urb.c81
-rw-r--r--arch/sh/mm/tlbflush_32.c4
-rw-r--r--arch/sh/mm/tlbflush_64.c2
-rw-r--r--arch/sh/mm/uncached.c34
-rw-r--r--arch/sh/tools/mach-types1
-rw-r--r--drivers/clocksource/sh_cmt.c32
-rw-r--r--drivers/clocksource/sh_mtu2.c6
-rw-r--r--drivers/clocksource/sh_tmu.c6
-rw-r--r--drivers/dma/shdma.c411
-rw-r--r--drivers/dma/shdma.h7
-rw-r--r--drivers/mtd/nand/Kconfig4
-rw-r--r--drivers/mtd/nand/sh_flctl.c69
-rw-r--r--drivers/serial/sh-sci.h220
-rw-r--r--drivers/sh/intc.c266
-rw-r--r--drivers/sh/pfc.c37
-rw-r--r--drivers/video/pvr2fb.c2
-rw-r--r--drivers/video/sh_mobile_lcdcfb.c88
-rw-r--r--include/linux/mtd/sh_flctl.h3
-rw-r--r--include/linux/sh_intc.h33
-rw-r--r--include/video/sh_mobile_lcdc.h2
-rw-r--r--lib/Kconfig.debug2
-rw-r--r--mm/Kconfig2
288 files changed, 9133 insertions, 4429 deletions
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index 2121fbb2ff4..05cef506129 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -13,7 +13,6 @@ config SUPERH
select HAVE_LMB
select HAVE_OPROFILE
select HAVE_GENERIC_DMA_COHERENT
- select HAVE_IOREMAP_PROT if MMU
select HAVE_ARCH_TRACEHOOK
select HAVE_DMA_API_DEBUG
select HAVE_DMA_ATTRS
@@ -22,6 +21,7 @@ config SUPERH
select HAVE_KERNEL_GZIP
select HAVE_KERNEL_BZIP2
select HAVE_KERNEL_LZMA
+ select HAVE_KERNEL_LZO
select HAVE_SYSCALL_TRACEPOINTS
select RTC_LIB
select GENERIC_ATOMIC64
@@ -35,6 +35,7 @@ config SUPERH32
def_bool ARCH = "sh"
select HAVE_KPROBES
select HAVE_KRETPROBES
+ select HAVE_IOREMAP_PROT if MMU && !X2TLB
select HAVE_FUNCTION_TRACER
select HAVE_FTRACE_MCOUNT_RECORD
select HAVE_DYNAMIC_FTRACE
@@ -42,6 +43,8 @@ config SUPERH32
select HAVE_FTRACE_NMI_ENTER if DYNAMIC_FTRACE
select HAVE_FUNCTION_GRAPH_TRACER
select HAVE_ARCH_KGDB
+ select HAVE_HW_BREAKPOINT
+ select PERF_EVENTS if HAVE_HW_BREAKPOINT
select ARCH_HIBERNATION_POSSIBLE if MMU
config SUPERH64
@@ -78,11 +81,12 @@ config GENERIC_HARDIRQS
config GENERIC_HARDIRQS_NO__DO_IRQ
def_bool y
-config GENERIC_IRQ_PROBE
+config IRQ_PER_CPU
def_bool y
-config IRQ_PER_CPU
+config SPARSE_IRQ
def_bool y
+ depends on SUPERH32
config GENERIC_GPIO
def_bool n
@@ -548,8 +552,7 @@ config SH_PCLK_FREQ
CPU_SUBTYPE_SH7203 || \
CPU_SUBTYPE_SH7206 || \
CPU_SUBTYPE_SH7263 || \
- CPU_SUBTYPE_MXG || \
- CPU_SUBTYPE_SH7786
+ CPU_SUBTYPE_MXG
default "60000000" if CPU_SUBTYPE_SH7751 || CPU_SUBTYPE_SH7751R
default "66000000" if CPU_SUBTYPE_SH4_202
default "50000000"
@@ -563,7 +566,8 @@ config SH_CLK_CPG
config SH_CLK_CPG_LEGACY
depends on SH_CLK_CPG
- def_bool y if !CPU_SUBTYPE_SH7785 && !ARCH_SHMOBILE
+ def_bool y if !CPU_SUBTYPE_SH7785 && !ARCH_SHMOBILE && \
+ !CPU_SUBTYPE_SH7786
config SH_CLK_MD
int "CPU Mode Pin Setting"
@@ -725,18 +729,6 @@ config GUSA_RB
LLSC, this should be more efficient than the other alternative of
disabling interrupts around the atomic sequence.
-config SPARSE_IRQ
- bool "Support sparse irq numbering"
- depends on EXPERIMENTAL
- help
- This enables support for sparse irqs. This is useful in general
- as most CPUs have a fairly sparse array of IRQ vectors, which
- the irq_desc then maps directly on to. Systems with a high
- number of off-chip IRQs will want to treat this as
- experimental until they have been independently verified.
-
- If you don't know what to do here, say N.
-
endmenu
menu "Boot options"
@@ -822,11 +814,15 @@ config MAPLE
config PCI
bool "PCI support"
depends on SYS_SUPPORTS_PCI
+ select PCI_DOMAINS
help
Find out whether you have a PCI motherboard. PCI is the name of a
bus system, i.e. the way the CPU talks to the other stuff inside
your box. If you have PCI, say Y, otherwise N.
+config PCI_DOMAINS
+ bool
+
source "drivers/pci/pcie/Kconfig"
source "drivers/pci/Kconfig"
diff --git a/arch/sh/Kconfig.cpu b/arch/sh/Kconfig.cpu
index cd6e3ea598d..ddf096c7d8b 100644
--- a/arch/sh/Kconfig.cpu
+++ b/arch/sh/Kconfig.cpu
@@ -68,7 +68,8 @@ config SH_STORE_QUEUES
config SPECULATIVE_EXECUTION
bool "Speculative subroutine return"
- depends on CPU_SUBTYPE_SH7780 && EXPERIMENTAL
+ depends on EXPERIMENTAL
+ depends on CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7785 || CPU_SUBTYPE_SH7786
help
This enables support for a speculative instruction fetch for
subroutine return. There are various pitfalls associated with
diff --git a/arch/sh/Makefile b/arch/sh/Makefile
index db91925c79d..588579ac2e3 100644
--- a/arch/sh/Makefile
+++ b/arch/sh/Makefile
@@ -83,6 +83,7 @@ defaultimage-$(CONFIG_SH_AP325RXA) := uImage
defaultimage-$(CONFIG_SH_7724_SOLUTION_ENGINE) := uImage
defaultimage-$(CONFIG_SH_7206_SOLUTION_ENGINE) := vmlinux
defaultimage-$(CONFIG_SH_7619_SOLUTION_ENGINE) := vmlinux
+defaultimage-$(CONFIG_SH_SDK7786) := vmlinux.bin
# Set some sensible Kbuild defaults
KBUILD_IMAGE := $(defaultimage-y)
@@ -143,11 +144,11 @@ machdir-$(CONFIG_SH_AP325RXA) += mach-ap325rxa
machdir-$(CONFIG_SH_KFR2R09) += mach-kfr2r09
machdir-$(CONFIG_SH_ECOVEC) += mach-ecovec24
machdir-$(CONFIG_SH_SDK7780) += mach-sdk7780
+machdir-$(CONFIG_SH_SDK7786) += mach-sdk7786
machdir-$(CONFIG_SH_X3PROTO) += mach-x3proto
machdir-$(CONFIG_SH_SH7763RDP) += mach-sh7763rdp
machdir-$(CONFIG_SH_SH4202_MICRODEV) += mach-microdev
machdir-$(CONFIG_SH_LANDISK) += mach-landisk
-machdir-$(CONFIG_SH_TITAN) += mach-titan
machdir-$(CONFIG_SH_LBOX_RE2) += mach-lboxre2
machdir-$(CONFIG_SH_CAYMAN) += mach-cayman
machdir-$(CONFIG_SH_RSK) += mach-rsk
@@ -203,8 +204,9 @@ endif
libs-$(CONFIG_SUPERH32) := arch/sh/lib/ $(libs-y)
libs-$(CONFIG_SUPERH64) := arch/sh/lib64/ $(libs-y)
-BOOT_TARGETS = uImage uImage.bz2 uImage.gz uImage.lzma uImage.srec uImage.bin \
- zImage vmlinux.srec romImage
+BOOT_TARGETS = uImage uImage.bz2 uImage.gz uImage.lzma uImage.lzo \
+ uImage.srec uImage.bin zImage vmlinux.bin vmlinux.srec \
+ romImage
PHONY += $(BOOT_TARGETS)
all: $(KBUILD_IMAGE)
@@ -225,10 +227,12 @@ define archhelp
@echo ' zImage - Compressed kernel image'
@echo ' romImage - Compressed ROM image, if supported'
@echo ' vmlinux.srec - Create an ELF S-record'
+ @echo ' vmlinux.bin - Create an uncompressed binary image'
@echo '* uImage - Alias to bootable U-Boot image'
@echo ' uImage.srec - Create an S-record for U-Boot'
@echo ' uImage.bin - Kernel-only image for U-Boot (bin)'
@echo '* uImage.gz - Kernel-only image for U-Boot (gzip)'
@echo ' uImage.bz2 - Kernel-only image for U-Boot (bzip2)'
@echo ' uImage.lzma - Kernel-only image for U-Boot (lzma)'
+ @echo ' uImage.lzo - Kernel-only image for U-Boot (lzo)'
endef
diff --git a/arch/sh/boards/Kconfig b/arch/sh/boards/Kconfig
index aedd9deb5de..938e87d5148 100644
--- a/arch/sh/boards/Kconfig
+++ b/arch/sh/boards/Kconfig
@@ -150,6 +150,14 @@ config SH_SDK7780
Select SDK7780 if configuring for a Renesas SH7780 SDK7780R3
evaluation board.
+config SH_SDK7786
+ bool "SDK7786"
+ depends on CPU_SUBTYPE_SH7786
+ select SYS_SUPPORTS_PCI
+ help
+ Select SDK7786 if configuring for a Renesas Technology Europe
+ SH7786-65nm board.
+
config SH_HIGHLANDER
bool "Highlander"
depends on CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7785
diff --git a/arch/sh/boards/Makefile b/arch/sh/boards/Makefile
index ce0f2638178..4f90f9b7a92 100644
--- a/arch/sh/boards/Makefile
+++ b/arch/sh/boards/Makefile
@@ -8,3 +8,4 @@ obj-$(CONFIG_SH_SHMIN) += board-shmin.o
obj-$(CONFIG_SH_EDOSK7760) += board-edosk7760.o
obj-$(CONFIG_SH_ESPT) += board-espt.o
obj-$(CONFIG_SH_POLARIS) += board-polaris.o
+obj-$(CONFIG_SH_TITAN) += board-titan.o
diff --git a/arch/sh/boards/board-magicpanelr2.c b/arch/sh/boards/board-magicpanelr2.c
index 99ffc5f1c0d..efba450a051 100644
--- a/arch/sh/boards/board-magicpanelr2.c
+++ b/arch/sh/boards/board-magicpanelr2.c
@@ -23,7 +23,7 @@
#include <asm/heartbeat.h>
#include <cpu/sh7720.h>
-#define LAN9115_READY (ctrl_inl(0xA8000084UL) & 0x00000001UL)
+#define LAN9115_READY (__raw_readl(0xA8000084UL) & 0x00000001UL)
/* Prefer cmdline over RedBoot */
static const char *probes[] = { "cmdlinepart", "RedBoot", NULL };
@@ -60,33 +60,33 @@ static void __init setup_chip_select(void)
{
/* CS2: LAN (0x08000000 - 0x0bffffff) */
/* no idle cycles, normal space, 8 bit data bus */
- ctrl_outl(0x36db0400, CS2BCR);
+ __raw_writel(0x36db0400, CS2BCR);
/* (SW:1.5 WR:3 HW:1.5), ext. wait */
- ctrl_outl(0x000003c0, CS2WCR);
+ __raw_writel(0x000003c0, CS2WCR);
/* CS4: CAN1 (0xb0000000 - 0xb3ffffff) */
/* no idle cycles, normal space, 8 bit data bus */
- ctrl_outl(0x00000200, CS4BCR);
+ __raw_writel(0x00000200, CS4BCR);
/* (SW:1.5 WR:3 HW:1.5), ext. wait */
- ctrl_outl(0x00100981, CS4WCR);
+ __raw_writel(0x00100981, CS4WCR);
/* CS5a: CAN2 (0xb4000000 - 0xb5ffffff) */
/* no idle cycles, normal space, 8 bit data bus */
- ctrl_outl(0x00000200, CS5ABCR);
+ __raw_writel(0x00000200, CS5ABCR);
/* (SW:1.5 WR:3 HW:1.5), ext. wait */
- ctrl_outl(0x00100981, CS5AWCR);
+ __raw_writel(0x00100981, CS5AWCR);
/* CS5b: CAN3 (0xb6000000 - 0xb7ffffff) */
/* no idle cycles, normal space, 8 bit data bus */
- ctrl_outl(0x00000200, CS5BBCR);
+ __raw_writel(0x00000200, CS5BBCR);
/* (SW:1.5 WR:3 HW:1.5), ext. wait */
- ctrl_outl(0x00100981, CS5BWCR);
+ __raw_writel(0x00100981, CS5BWCR);
/* CS6a: Rotary (0xb8000000 - 0xb9ffffff) */
/* no idle cycles, normal space, 8 bit data bus */
- ctrl_outl(0x00000200, CS6ABCR);
+ __raw_writel(0x00000200, CS6ABCR);
/* (SW:1.5 WR:3 HW:1.5), no ext. wait */
- ctrl_outl(0x001009C1, CS6AWCR);
+ __raw_writel(0x001009C1, CS6AWCR);
}
static void __init setup_port_multiplexing(void)
@@ -94,71 +94,71 @@ static void __init setup_port_multiplexing(void)
/* A7 GPO(LED8); A6 GPO(LED7); A5 GPO(LED6); A4 GPO(LED5);
* A3 GPO(LED4); A2 GPO(LED3); A1 GPO(LED2); A0 GPO(LED1);
*/
- ctrl_outw(0x5555, PORT_PACR); /* 01 01 01 01 01 01 01 01 */
+ __raw_writew(0x5555, PORT_PACR); /* 01 01 01 01 01 01 01 01 */
/* B7 GPO(RST4); B6 GPO(RST3); B5 GPO(RST2); B4 GPO(RST1);
* B3 GPO(PB3); B2 GPO(PB2); B1 GPO(PB1); B0 GPO(PB0);
*/
- ctrl_outw(0x5555, PORT_PBCR); /* 01 01 01 01 01 01 01 01 */
+ __raw_writew(0x5555, PORT_PBCR); /* 01 01 01 01 01 01 01 01 */
/* C7 GPO(PC7); C6 GPO(PC6); C5 GPO(PC5); C4 GPO(PC4);
* C3 LCD_DATA3; C2 LCD_DATA2; C1 LCD_DATA1; C0 LCD_DATA0;
*/
- ctrl_outw(0x5500, PORT_PCCR); /* 01 01 01 01 00 00 00 00 */
+ __raw_writew(0x5500, PORT_PCCR); /* 01 01 01 01 00 00 00 00 */
/* D7 GPO(PD7); D6 GPO(PD6); D5 GPO(PD5); D4 GPO(PD4);
* D3 GPO(PD3); D2 GPO(PD2); D1 GPO(PD1); D0 GPO(PD0);
*/
- ctrl_outw(0x5555, PORT_PDCR); /* 01 01 01 01 01 01 01 01 */
+ __raw_writew(0x5555, PORT_PDCR); /* 01 01 01 01 01 01 01 01 */
/* E7 (x); E6 GPI(nu); E5 GPI(nu); E4 LCD_M_DISP;
* E3 LCD_CL1; E2 LCD_CL2; E1 LCD_DON; E0 LCD_FLM;
*/
- ctrl_outw(0x3C00, PORT_PECR); /* 00 11 11 00 00 00 00 00 */
+ __raw_writew(0x3C00, PORT_PECR); /* 00 11 11 00 00 00 00 00 */
/* F7 (x); F6 DA1(VLCD); F5 DA0(nc); F4 AN3;
* F3 AN2(MID_AD); F2 AN1(EARTH_AD); F1 AN0(TEMP); F0 GPI+(nc);
*/
- ctrl_outw(0x0002, PORT_PFCR); /* 00 00 00 00 00 00 00 10 */
+ __raw_writew(0x0002, PORT_PFCR); /* 00 00 00 00 00 00 00 10 */
/* G7 (x); G6 IRQ5(TOUCH_BUSY); G5 IRQ4(TOUCH_IRQ); G4 GPI(KEY2);
* G3 GPI(KEY1); G2 GPO(LED11); G1 GPO(LED10); G0 GPO(LED9);
*/
- ctrl_outw(0x03D5, PORT_PGCR); /* 00 00 00 11 11 01 01 01 */
+ __raw_writew(0x03D5, PORT_PGCR); /* 00 00 00 11 11 01 01 01 */
/* H7 (x); H6 /RAS(BRAS); H5 /CAS(BCAS); H4 CKE(BCKE);
* H3 GPO(EARTH_OFF); H2 GPO(EARTH_TEST); H1 USB2_PWR; H0 USB1_PWR;
*/
- ctrl_outw(0x0050, PORT_PHCR); /* 00 00 00 00 01 01 00 00 */
+ __raw_writew(0x0050, PORT_PHCR); /* 00 00 00 00 01 01 00 00 */
/* J7 (x); J6 AUDCK; J5 ASEBRKAK; J4 AUDATA3;
* J3 AUDATA2; J2 AUDATA1; J1 AUDATA0; J0 AUDSYNC;
*/
- ctrl_outw(0x0000, PORT_PJCR); /* 00 00 00 00 00 00 00 00 */
+ __raw_writew(0x0000, PORT_PJCR); /* 00 00 00 00 00 00 00 00 */
/* K7 (x); K6 (x); K5 (x); K4 (x);
* K3 PINT7(/PWR2); K2 PINT6(/PWR1); K1 PINT5(nu); K0 PINT4(FLASH_READY)
*/
- ctrl_outw(0x00FF, PORT_PKCR); /* 00 00 00 00 11 11 11 11 */
+ __raw_writew(0x00FF, PORT_PKCR); /* 00 00 00 00 11 11 11 11 */
/* L7 TRST; L6 TMS; L5 TDO; L4 TDI;
* L3 TCK; L2 (x); L1 (x); L0 (x);
*/
- ctrl_outw(0x0000, PORT_PLCR); /* 00 00 00 00 00 00 00 00 */
+ __raw_writew(0x0000, PORT_PLCR); /* 00 00 00 00 00 00 00 00 */
/* M7 GPO(CURRENT_SINK); M6 GPO(PWR_SWITCH); M5 GPO(LAN_SPEED);
* M4 GPO(LAN_RESET); M3 GPO(BUZZER); M2 GPO(LCD_BL);
* M1 CS5B(CAN3_CS); M0 GPI+(nc);
*/
- ctrl_outw(0x5552, PORT_PMCR); /* 01 01 01 01 01 01 00 10 */
+ __raw_writew(0x5552, PORT_PMCR); /* 01 01 01 01 01 01 00 10 */
/* CURRENT_SINK=off, PWR_SWITCH=off, LAN_SPEED=100MBit,
* LAN_RESET=off, BUZZER=off, LCD_BL=off
*/
#if CONFIG_SH_MAGIC_PANEL_R2_VERSION == 2
- ctrl_outb(0x30, PORT_PMDR);
+ __raw_writeb(0x30, PORT_PMDR);
#elif CONFIG_SH_MAGIC_PANEL_R2_VERSION == 3
- ctrl_outb(0xF0, PORT_PMDR);
+ __raw_writeb(0xF0, PORT_PMDR);
#else
#error Unknown revision of PLATFORM_MP_R2
#endif
@@ -167,8 +167,8 @@ static void __init setup_port_multiplexing(void)
* P4 GPO(nu); P3 IRQ3(LAN_IRQ); P2 IRQ2(CAN3_IRQ);
* P1 IRQ1(CAN2_IRQ); P0 IRQ0(CAN1_IRQ)
*/
- ctrl_outw(0x0100, PORT_PPCR); /* 00 00 00 01 00 00 00 00 */
- ctrl_outb(0x10, PORT_PPDR);
+ __raw_writew(0x0100, PORT_PPCR); /* 00 00 00 01 00 00 00 00 */
+ __raw_writeb(0x10, PORT_PPDR);
/* R7 A25; R6 A24; R5 A23; R4 A22;
* R3 A21; R2 A20; R1 A19; R0 A0;
@@ -185,22 +185,22 @@ static void __init setup_port_multiplexing(void)
/* S7 (x); S6 (x); S5 (x); S4 GPO(EEPROM_CS2);
* S3 GPO(EEPROM_CS1); S2 SIOF0_TXD; S1 SIOF0_RXD; S0 SIOF0_SCK;
*/
- ctrl_outw(0x0140, PORT_PSCR); /* 00 00 00 01 01 00 00 00 */
+ __raw_writew(0x0140, PORT_PSCR); /* 00 00 00 01 01 00 00 00 */
/* T7 (x); T6 (x); T5 (x); T4 COM1_CTS;
* T3 COM1_RTS; T2 COM1_TXD; T1 COM1_RXD; T0 GPO(WDOG)
*/
- ctrl_outw(0x0001, PORT_PTCR); /* 00 00 00 00 00 00 00 01 */
+ __raw_writew(0x0001, PORT_PTCR); /* 00 00 00 00 00 00 00 01 */
/* U7 (x); U6 (x); U5 (x); U4 GPI+(/AC_FAULT);
* U3 GPO(TOUCH_CS); U2 TOUCH_TXD; U1 TOUCH_RXD; U0 TOUCH_SCK;
*/
- ctrl_outw(0x0240, PORT_PUCR); /* 00 00 00 10 01 00 00 00 */
+ __raw_writew(0x0240, PORT_PUCR); /* 00 00 00 10 01 00 00 00 */
/* V7 (x); V6 (x); V5 (x); V4 GPO(MID2);
* V3 GPO(MID1); V2 CARD_TxD; V1 CARD_RxD; V0 GPI+(/BAT_FAULT);
*/
- ctrl_outw(0x0142, PORT_PVCR); /* 00 00 00 01 01 00 00 10 */
+ __raw_writew(0x0142, PORT_PVCR); /* 00 00 00 01 01 00 00 10 */
}
static void __init mpr2_setup(char **cmdline_p)
@@ -209,24 +209,24 @@ static void __init mpr2_setup(char **cmdline_p)
* /PCC_CD1, /PCC_CD2, PCC_BVD1, PCC_BVD2,
* /IOIS16, IRQ4, IRQ5, USB1d_SUSPEND
*/
- ctrl_outw(0xAABC, PORT_PSELA);
+ __raw_writew(0xAABC, PORT_PSELA);
/* set Pin Select Register B:
* /SCIF0_RTS, /SCIF0_CTS, LCD_VCPWC,
* LCD_VEPWC, IIC_SDA, IIC_SCL, Reserved
*/
- ctrl_outw(0x3C00, PORT_PSELB);
+ __raw_writew(0x3C00, PORT_PSELB);
/* set Pin Select Register C:
* SIOF1_SCK, SIOF1_RxD, SCIF1_RxD, SCIF1_TxD, Reserved
*/
- ctrl_outw(0x0000, PORT_PSELC);
+ __raw_writew(0x0000, PORT_PSELC);
/* set Pin Select Register D: Reserved, SIOF1_TxD, Reserved, SIOF1_MCLK,
* Reserved, SIOF1_SYNC, Reserved, SCIF1_SCK, Reserved
*/
- ctrl_outw(0x0000, PORT_PSELD);
+ __raw_writew(0x0000, PORT_PSELD);
/* set USB TxRx Control: Reserved, DRV, Reserved, USB_TRANS, USB_SEL */
- ctrl_outw(0x0101, PORT_UTRCTL);
+ __raw_writew(0x0101, PORT_UTRCTL);
/* set USB Clock Control: USSCS, USSTB, Reserved (HighByte always A5) */
- ctrl_outw(0xA5C0, PORT_UCLKCR_W);
+ __raw_writew(0xA5C0, PORT_UCLKCR_W);
setup_chip_select();
diff --git a/arch/sh/boards/board-polaris.c b/arch/sh/boards/board-polaris.c
index 62607eb5100..594866356c2 100644
--- a/arch/sh/boards/board-polaris.c
+++ b/arch/sh/boards/board-polaris.c
@@ -59,15 +59,12 @@ static unsigned char heartbeat_bit_pos[] = { 0, 1, 2, 3 };
static struct heartbeat_data heartbeat_data = {
.bit_pos = heartbeat_bit_pos,
.nr_bits = ARRAY_SIZE(heartbeat_bit_pos),
- .regsize = 8,
};
-static struct resource heartbeat_resources[] = {
- [0] = {
- .start = PORT_PCDR,
- .end = PORT_PCDR,
- .flags = IORESOURCE_MEM,
- },
+static struct resource heartbeat_resource = {
+ .start = PORT_PCDR,
+ .end = PORT_PCDR,
+ .flags = IORESOURCE_MEM | IORESOURCE_MEM_8BIT,
};
static struct platform_device heartbeat_device = {
@@ -76,8 +73,8 @@ static struct platform_device heartbeat_device = {
.dev = {
.platform_data = &heartbeat_data,
},
- .num_resources = ARRAY_SIZE(heartbeat_resources),
- .resource = heartbeat_resources,
+ .num_resources = 1,
+ .resource = &heartbeat_resource,
};
static struct platform_device *polaris_devices[] __initdata = {
@@ -92,15 +89,15 @@ static int __init polaris_initialise(void)
printk(KERN_INFO "Configuring Polaris external bus\n");
/* Configure area 5 with 2 wait states */
- wcr = ctrl_inw(WCR2);
+ wcr = __raw_readw(WCR2);
wcr &= (~AREA5_WAIT_CTRL);
wcr |= (WAIT_STATES_10 << 10);
- ctrl_outw(wcr, WCR2);
+ __raw_writew(wcr, WCR2);
/* Configure area 5 for 32-bit access */
- bcr_mask = ctrl_inw(BCR2);
+ bcr_mask = __raw_readw(BCR2);
bcr_mask |= 1 << 10;
- ctrl_outw(bcr_mask, BCR2);
+ __raw_writew(bcr_mask, BCR2);
return platform_add_devices(polaris_devices,
ARRAY_SIZE(polaris_devices));
@@ -131,13 +128,13 @@ static struct ipr_desc ipr_irq_desc = {
static void __init init_polaris_irq(void)
{
/* Disable all interrupts */
- ctrl_outw(0, BCR_ILCRA);
- ctrl_outw(0, BCR_ILCRB);
- ctrl_outw(0, BCR_ILCRC);
- ctrl_outw(0, BCR_ILCRD);
- ctrl_outw(0, BCR_ILCRE);
- ctrl_outw(0, BCR_ILCRF);
- ctrl_outw(0, BCR_ILCRG);
+ __raw_writew(0, BCR_ILCRA);
+ __raw_writew(0, BCR_ILCRB);
+ __raw_writew(0, BCR_ILCRC);
+ __raw_writew(0, BCR_ILCRD);
+ __raw_writew(0, BCR_ILCRE);
+ __raw_writew(0, BCR_ILCRF);
+ __raw_writew(0, BCR_ILCRG);
register_ipr_controller(&ipr_irq_desc);
}
diff --git a/arch/sh/boards/board-sh7785lcr.c b/arch/sh/boards/board-sh7785lcr.c
index e5a8a2fde39..fe7e686c94a 100644
--- a/arch/sh/boards/board-sh7785lcr.c
+++ b/arch/sh/boards/board-sh7785lcr.c
@@ -21,6 +21,7 @@
#include <linux/i2c-algo-pca.h>
#include <linux/usb/r8a66597.h>
#include <linux/irq.h>
+#include <linux/io.h>
#include <linux/clk.h>
#include <linux/errno.h>
#include <mach/sh7785lcr.h>
@@ -32,26 +33,17 @@
* NOTE: This board has 2 physical memory maps.
* Please look at include/asm-sh/sh7785lcr.h or hardware manual.
*/
-static struct resource heartbeat_resources[] = {
- [0] = {
- .start = PLD_LEDCR,
- .end = PLD_LEDCR,
- .flags = IORESOURCE_MEM,
- },
-};
-
-static struct heartbeat_data heartbeat_data = {
- .regsize = 8,
+static struct resource heartbeat_resource = {
+ .start = PLD_LEDCR,
+ .end = PLD_LEDCR,
+ .flags = IORESOURCE_MEM | IORESOURCE_MEM_8BIT,
};
static struct platform_device heartbeat_device = {
.name = "heartbeat",
.id = -1,
- .dev = {
- .platform_data = &heartbeat_data,
- },
- .num_resources = ARRAY_SIZE(heartbeat_resources),
- .resource = heartbeat_resources,
+ .num_resources = 1,
+ .resource = &heartbeat_resource,
};
static struct mtd_partition nor_flash_partitions[] = {
@@ -341,8 +333,14 @@ static void __init sh7785lcr_setup(char **cmdline_p)
pm_power_off = sh7785lcr_power_off;
/* sm501 DRAM configuration */
- sm501_reg = (void __iomem *)0xb3e00000 + SM501_DRAM_CONTROL;
- writel(0x000307c2, sm501_reg);
+ sm501_reg = ioremap_nocache(SM107_REG_ADDR, SM501_DRAM_CONTROL);
+ if (!sm501_reg) {
+ printk(KERN_ERR "%s: ioremap error.\n", __func__);
+ return;
+ }
+
+ writel(0x000307c2, sm501_reg + SM501_DRAM_CONTROL);
+ iounmap(sm501_reg);
}
/* Return the board specific boot mode pin configuration */
diff --git a/arch/sh/boards/board-shmin.c b/arch/sh/boards/board-shmin.c
index b1dcbbc8918..325bed53b87 100644
--- a/arch/sh/boards/board-shmin.c
+++ b/arch/sh/boards/board-shmin.c
@@ -17,8 +17,8 @@
static void __init init_shmin_irq(void)
{
- ctrl_outw(0x2a00, PFC_PHCR); // IRQ0-3=IRQ
- ctrl_outw(0x0aaa, INTC_ICR1); // IRQ0-3=IRQ-mode,Low-active.
+ __raw_writew(0x2a00, PFC_PHCR); // IRQ0-3=IRQ
+ __raw_writew(0x0aaa, INTC_ICR1); // IRQ0-3=IRQ-mode,Low-active.
plat_irq_setup_pins(IRQ_MODE_IRQ);
}
diff --git a/arch/sh/boards/mach-titan/setup.c b/arch/sh/boards/board-titan.c
index 81e7e0f0386..94c36c7bc0b 100644
--- a/arch/sh/boards/mach-titan/setup.c
+++ b/arch/sh/boards/board-titan.c
@@ -19,26 +19,6 @@ static void __init init_titan_irq(void)
}
static struct sh_machine_vector mv_titan __initmv = {
- .mv_name = "Titan",
-
- .mv_inb = titan_inb,
- .mv_inw = titan_inw,
- .mv_inl = titan_inl,
- .mv_outb = titan_outb,
- .mv_outw = titan_outw,
- .mv_outl = titan_outl,
-
- .mv_inb_p = titan_inb_p,
- .mv_inw_p = titan_inw,
- .mv_inl_p = titan_inl,
- .mv_outb_p = titan_outb_p,
- .mv_outw_p = titan_outw,
- .mv_outl_p = titan_outl,
-
- .mv_insl = titan_insl,
- .mv_outsl = titan_outsl,
-
- .mv_ioport_map = titan_ioport_map,
-
- .mv_init_irq = init_titan_irq,
+ .mv_name = "Titan",
+ .mv_init_irq = init_titan_irq,
};
diff --git a/arch/sh/boards/board-urquell.c b/arch/sh/boards/board-urquell.c
index 36b8bac9b12..a9bd6e3ee10 100644
--- a/arch/sh/boards/board-urquell.c
+++ b/arch/sh/boards/board-urquell.c
@@ -2,7 +2,7 @@
* Renesas Technology Corp. SH7786 Urquell Support.
*
* Copyright (C) 2008 Kuninori Morimoto <morimoto.kuninori@renesas.com>
- * Copyright (C) 2009 Paul Mundt
+ * Copyright (C) 2009, 2010 Paul Mundt
*
* Based on board-sh7785lcr.c
* Copyright (C) 2008 Yoshihiro Shimoda
@@ -19,6 +19,7 @@
#include <linux/delay.h>
#include <linux/gpio.h>
#include <linux/irq.h>
+#include <linux/clk.h>
#include <mach/urquell.h>
#include <cpu/sh7786.h>
#include <asm/heartbeat.h>
@@ -50,26 +51,17 @@
*/
/* HeartBeat */
-static struct resource heartbeat_resources[] = {
- [0] = {
- .start = BOARDREG(SLEDR),
- .end = BOARDREG(SLEDR),
- .flags = IORESOURCE_MEM,
- },
-};
-
-static struct heartbeat_data heartbeat_data = {
- .regsize = 16,
+static struct resource heartbeat_resource = {
+ .start = BOARDREG(SLEDR),
+ .end = BOARDREG(SLEDR),
+ .flags = IORESOURCE_MEM | IORESOURCE_MEM_16BIT,
};
static struct platform_device heartbeat_device = {
.name = "heartbeat",
.id = -1,
- .dev = {
- .platform_data = &heartbeat_data,
- },
- .num_resources = ARRAY_SIZE(heartbeat_resources),
- .resource = heartbeat_resources,
+ .num_resources = 1,
+ .resource = &heartbeat_resource,
};
/* LAN91C111 */
@@ -184,6 +176,27 @@ static int urquell_mode_pins(void)
return __raw_readw(UBOARDREG(MDSWMR));
}
+static int urquell_clk_init(void)
+{
+ struct clk *clk;
+ int ret;
+
+ /*
+ * Only handle the EXTAL case, anyone interfacing a crystal
+ * resonator will need to provide their own input clock.
+ */
+ if (test_mode_pin(MODE_PIN9))
+ return -EINVAL;
+
+ clk = clk_get(NULL, "extal");
+ if (!clk || IS_ERR(clk))
+ return PTR_ERR(clk);
+ ret = clk_set_rate(clk, 33333333);
+ clk_put(clk);
+
+ return ret;
+}
+
/* Initialize the board */
static void __init urquell_setup(char **cmdline_p)
{
@@ -200,4 +213,5 @@ static struct sh_machine_vector mv_urquell __initmv = {
.mv_setup = urquell_setup,
.mv_init_irq = urquell_init_irq,
.mv_mode_pins = urquell_mode_pins,
+ .mv_clk_init = urquell_clk_init,
};
diff --git a/arch/sh/boards/mach-ap325rxa/setup.c b/arch/sh/boards/mach-ap325rxa/setup.c
index 1f5fa5c44f6..b5980696abb 100644
--- a/arch/sh/boards/mach-ap325rxa/setup.c
+++ b/arch/sh/boards/mach-ap325rxa/setup.c
@@ -159,21 +159,21 @@ static void ap320_wvga_power_on(void *board_data)
msleep(100);
/* ASD AP-320/325 LCD ON */
- ctrl_outw(FPGA_LCDREG_VAL, FPGA_LCDREG);
+ __raw_writew(FPGA_LCDREG_VAL, FPGA_LCDREG);
/* backlight */
gpio_set_value(GPIO_PTS3, 0);
- ctrl_outw(0x100, FPGA_BKLREG);
+ __raw_writew(0x100, FPGA_BKLREG);
}
static void ap320_wvga_power_off(void *board_data)
{
/* backlight */
- ctrl_outw(0, FPGA_BKLREG);
+ __raw_writew(0, FPGA_BKLREG);
gpio_set_value(GPIO_PTS3, 1);
/* ASD AP-320/325 LCD OFF */
- ctrl_outw(0, FPGA_LCDREG);
+ __raw_writew(0, FPGA_LCDREG);
}
static struct sh_mobile_lcdc_info lcdc_info = {
@@ -420,7 +420,7 @@ static struct resource sdhi0_cn3_resources[] = {
.flags = IORESOURCE_MEM,
},
[1] = {
- .start = 101,
+ .start = 100,
.flags = IORESOURCE_IRQ,
},
};
@@ -443,7 +443,7 @@ static struct resource sdhi1_cn7_resources[] = {
.flags = IORESOURCE_MEM,
},
[1] = {
- .start = 24,
+ .start = 23,
.flags = IORESOURCE_IRQ,
},
};
@@ -595,7 +595,7 @@ static int __init ap325rxa_devices_setup(void)
gpio_request(GPIO_PTZ4, NULL);
gpio_direction_output(GPIO_PTZ4, 0); /* SADDR */
- ctrl_outw(ctrl_inw(PORT_MSELCRB) & ~0x0001, PORT_MSELCRB);
+ __raw_writew(__raw_readw(PORT_MSELCRB) & ~0x0001, PORT_MSELCRB);
/* FLCTL */
gpio_request(GPIO_FN_FCE, NULL);
@@ -613,9 +613,9 @@ static int __init ap325rxa_devices_setup(void)
gpio_request(GPIO_FN_FWE, NULL);
gpio_request(GPIO_FN_FRB, NULL);
- ctrl_outw(0, PORT_HIZCRC);
- ctrl_outw(0xFFFF, PORT_DRVCRA);
- ctrl_outw(0xFFFF, PORT_DRVCRB);
+ __raw_writew(0, PORT_HIZCRC);
+ __raw_writew(0xFFFF, PORT_DRVCRA);
+ __raw_writew(0xFFFF, PORT_DRVCRB);
platform_resource_setup_memory(&ceu_device, "ceu", 4 << 20);
diff --git a/arch/sh/boards/mach-cayman/irq.c b/arch/sh/boards/mach-cayman/irq.c
index 33f77085631..1394b078db3 100644
--- a/arch/sh/boards/mach-cayman/irq.c
+++ b/arch/sh/boards/mach-cayman/irq.c
@@ -66,9 +66,9 @@ static void enable_cayman_irq(unsigned int irq)
reg = EPLD_MASK_BASE + ((irq / 8) << 2);
bit = 1<<(irq % 8);
local_irq_save(flags);
- mask = ctrl_inl(reg);
+ mask = __raw_readl(reg);
mask |= bit;
- ctrl_outl(mask, reg);
+ __raw_writel(mask, reg);
local_irq_restore(flags);
}
@@ -83,9 +83,9 @@ void disable_cayman_irq(unsigned int irq)
reg = EPLD_MASK_BASE + ((irq / 8) << 2);
bit = 1<<(irq % 8);
local_irq_save(flags);
- mask = ctrl_inl(reg);
+ mask = __raw_readl(reg);
mask &= ~bit;
- ctrl_outl(mask, reg);
+ __raw_writel(mask, reg);
local_irq_restore(flags);
}
@@ -109,8 +109,8 @@ int cayman_irq_demux(int evt)
unsigned long status;
int i;
- status = ctrl_inl(EPLD_STATUS_BASE) &
- ctrl_inl(EPLD_MASK_BASE) & 0xff;
+ status = __raw_readl(EPLD_STATUS_BASE) &
+ __raw_readl(EPLD_MASK_BASE) & 0xff;
if (status == 0) {
irq = -1;
} else {
@@ -126,8 +126,8 @@ int cayman_irq_demux(int evt)
unsigned long status;
int i;
- status = ctrl_inl(EPLD_STATUS_BASE + 3 * sizeof(u32)) &
- ctrl_inl(EPLD_MASK_BASE + 3 * sizeof(u32)) & 0xff;
+ status = __raw_readl(EPLD_STATUS_BASE + 3 * sizeof(u32)) &
+ __raw_readl(EPLD_MASK_BASE + 3 * sizeof(u32)) & 0xff;
if (status == 0) {
irq = -1;
} else {
diff --git a/arch/sh/boards/mach-dreamcast/irq.c b/arch/sh/boards/mach-dreamcast/irq.c
index f55fc8e795e..d932667410a 100644
--- a/arch/sh/boards/mach-dreamcast/irq.c
+++ b/arch/sh/boards/mach-dreamcast/irq.c
@@ -135,3 +135,30 @@ int systemasic_irq_demux(int irq)
/* Not reached */
return irq;
}
+
+void systemasic_irq_init(void)
+{
+ int i, nid = cpu_to_node(boot_cpu_data);
+
+ /* Assign all virtual IRQs to the System ASIC int. handler */
+ for (i = HW_EVENT_IRQ_BASE; i < HW_EVENT_IRQ_MAX; i++) {
+ unsigned int irq;
+
+ irq = create_irq_nr(i, nid);
+ if (unlikely(irq == 0)) {
+ pr_err("%s: failed hooking irq %d for systemasic\n",
+ __func__, i);
+ return;
+ }
+
+ if (unlikely(irq != i)) {
+ pr_err("%s: got irq %d but wanted %d, bailing.\n",
+ __func__, irq, i);
+ destroy_irq(irq);
+ return;
+ }
+
+ set_irq_chip_and_handler(i, &systemasic_int,
+ handle_level_irq);
+ }
+}
diff --git a/arch/sh/boards/mach-dreamcast/rtc.c b/arch/sh/boards/mach-dreamcast/rtc.c
index a7433685798..061d65714fc 100644
--- a/arch/sh/boards/mach-dreamcast/rtc.c
+++ b/arch/sh/boards/mach-dreamcast/rtc.c
@@ -35,11 +35,11 @@ static void aica_rtc_gettimeofday(struct timespec *ts)
unsigned long val1, val2;
do {
- val1 = ((ctrl_inl(AICA_RTC_SECS_H) & 0xffff) << 16) |
- (ctrl_inl(AICA_RTC_SECS_L) & 0xffff);
+ val1 = ((__raw_readl(AICA_RTC_SECS_H) & 0xffff) << 16) |
+ (__raw_readl(AICA_RTC_SECS_L) & 0xffff);
- val2 = ((ctrl_inl(AICA_RTC_SECS_H) & 0xffff) << 16) |
- (ctrl_inl(AICA_RTC_SECS_L) & 0xffff);
+ val2 = ((__raw_readl(AICA_RTC_SECS_H) & 0xffff) << 16) |
+ (__raw_readl(AICA_RTC_SECS_L) & 0xffff);
} while (val1 != val2);
ts->tv_sec = val1 - TWENTY_YEARS;
@@ -60,14 +60,14 @@ static int aica_rtc_settimeofday(const time_t secs)
unsigned long adj = secs + TWENTY_YEARS;
do {
- ctrl_outl((adj & 0xffff0000) >> 16, AICA_RTC_SECS_H);
- ctrl_outl((adj & 0xffff), AICA_RTC_SECS_L);
+ __raw_writel((adj & 0xffff0000) >> 16, AICA_RTC_SECS_H);
+ __raw_writel((adj & 0xffff), AICA_RTC_SECS_L);
- val1 = ((ctrl_inl(AICA_RTC_SECS_H) & 0xffff) << 16) |
- (ctrl_inl(AICA_RTC_SECS_L) & 0xffff);
+ val1 = ((__raw_readl(AICA_RTC_SECS_H) & 0xffff) << 16) |
+ (__raw_readl(AICA_RTC_SECS_L) & 0xffff);
- val2 = ((ctrl_inl(AICA_RTC_SECS_H) & 0xffff) << 16) |
- (ctrl_inl(AICA_RTC_SECS_L) & 0xffff);
+ val2 = ((__raw_readl(AICA_RTC_SECS_H) & 0xffff) << 16) |
+ (__raw_readl(AICA_RTC_SECS_L) & 0xffff);
} while (val1 != val2);
return 0;
diff --git a/arch/sh/boards/mach-dreamcast/setup.c b/arch/sh/boards/mach-dreamcast/setup.c
index a4b7402d617..ad1a4db72e0 100644
--- a/arch/sh/boards/mach-dreamcast/setup.c
+++ b/arch/sh/boards/mach-dreamcast/setup.c
@@ -28,25 +28,8 @@
#include <asm/machvec.h>
#include <mach/sysasic.h>
-extern struct irq_chip systemasic_int;
-extern void aica_time_init(void);
-extern int systemasic_irq_demux(int);
-
static void __init dreamcast_setup(char **cmdline_p)
{
- int i;
-
- /* Mask all hardware events */
- /* XXX */
-
- /* Acknowledge any previous events */
- /* XXX */
-
- /* Assign all virtual IRQs to the System ASIC int. handler */
- for (i = HW_EVENT_IRQ_BASE; i < HW_EVENT_IRQ_MAX; i++)
- set_irq_chip_and_handler(i, &systemasic_int,
- handle_level_irq);
-
board_time_init = aica_time_init;
}
@@ -54,4 +37,5 @@ static struct sh_machine_vector mv_dreamcast __initmv = {
.mv_name = "Sega Dreamcast",
.mv_setup = dreamcast_setup,
.mv_irq_demux = systemasic_irq_demux,
+ .mv_init_irq = systemasic_irq_init,
};
diff --git a/arch/sh/boards/mach-ecovec24/sdram.S b/arch/sh/boards/mach-ecovec24/sdram.S
index 83344004440..3963c6f23d5 100644
--- a/arch/sh/boards/mach-ecovec24/sdram.S
+++ b/arch/sh/boards/mach-ecovec24/sdram.S
@@ -37,6 +37,10 @@ ENTRY(ecovec24_sdram_enter_end)
.balign 4
ENTRY(ecovec24_sdram_leave_start)
+ mov.l @(SH_SLEEP_MODE, r5), r0
+ tst #SUSP_SH_RSTANDBY, r0
+ bf resume_rstandby
+
/* DBSC: put memory in auto-refresh mode */
ED 0xFD000040, 0x00000000 /* DBRFPDN0 */
@@ -49,4 +53,59 @@ ENTRY(ecovec24_sdram_leave_start)
rts
nop
+resume_rstandby:
+
+ /* DBSC: re-initialize and put in auto-refresh */
+
+ ED 0xFD000108, 0x00000181 /* DBPDCNT0 */
+ ED 0xFD000020, 0x015B0002 /* DBCONF */
+ ED 0xFD000030, 0x03071502 /* DBTR0 */
+ ED 0xFD000034, 0x02020102 /* DBTR1 */
+ ED 0xFD000038, 0x01090405 /* DBTR2 */
+ ED 0xFD00003C, 0x00000002 /* DBTR3 */
+ ED 0xFD000008, 0x00000005 /* DBKIND */
+ ED 0xFD000040, 0x00000001 /* DBRFPDN0 */
+ ED 0xFD000040, 0x00000000 /* DBRFPDN0 */
+ ED 0xFD000018, 0x00000001 /* DBCKECNT */
+
+ mov #100,r0
+WAIT_400NS:
+ dt r0
+ bf WAIT_400NS
+
+ ED 0xFD000014, 0x00000002 /* DBCMDCNT (PALL) */
+ ED 0xFD000060, 0x00020000 /* DBMRCNT (EMR2) */
+ ED 0xFD000060, 0x00030000 /* DBMRCNT (EMR3) */
+ ED 0xFD000060, 0x00010004 /* DBMRCNT (EMR) */
+ ED 0xFD000060, 0x00000532 /* DBMRCNT (MRS) */
+ ED 0xFD000014, 0x00000002 /* DBCMDCNT (PALL) */
+ ED 0xFD000014, 0x00000004 /* DBCMDCNT (REF) */
+ ED 0xFD000014, 0x00000004 /* DBCMDCNT (REF) */
+ ED 0xFD000060, 0x00000432 /* DBMRCNT (MRS) */
+ ED 0xFD000060, 0x000103c0 /* DBMRCNT (EMR) */
+ ED 0xFD000060, 0x00010040 /* DBMRCNT (EMR) */
+
+ mov #100,r0
+WAIT_400NS_2:
+ dt r0
+ bf WAIT_400NS_2
+
+ ED 0xFD000010, 0x00000001 /* DBEN */
+ ED 0xFD000044, 0x0000050f /* DBRFPDN1 */
+ ED 0xFD000048, 0x236800e6 /* DBRFPDN2 */
+
+ mov.l DUMMY,r0
+ mov.l @r0, r1 /* force single dummy read */
+
+ ED 0xFD000014, 0x00000002 /* DBCMDCNT (PALL) */
+ ED 0xFD000014, 0x00000004 /* DBCMDCNT (REF) */
+ ED 0xFD000108, 0x00000080 /* DBPDCNT0 */
+ ED 0xFD000040, 0x00010000 /* DBRFPDN0 */
+
+ rts
+ nop
+
+ .balign 4
+DUMMY: .long 0xac400000
+
ENTRY(ecovec24_sdram_leave_end)
diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c
index 5c246289b4f..39ed8722d11 100644
--- a/arch/sh/boards/mach-ecovec24/setup.c
+++ b/arch/sh/boards/mach-ecovec24/setup.c
@@ -64,18 +64,16 @@
/* Heartbeat */
static unsigned char led_pos[] = { 0, 1, 2, 3 };
+
static struct heartbeat_data heartbeat_data = {
- .regsize = 8,
.nr_bits = 4,
.bit_pos = led_pos,
};
-static struct resource heartbeat_resources[] = {
- [0] = {
- .start = 0xA405012C, /* PTG */
- .end = 0xA405012E - 1,
- .flags = IORESOURCE_MEM,
- },
+static struct resource heartbeat_resource = {
+ .start = 0xA405012C, /* PTG */
+ .end = 0xA405012E - 1,
+ .flags = IORESOURCE_MEM | IORESOURCE_MEM_8BIT,
};
static struct platform_device heartbeat_device = {
@@ -84,8 +82,8 @@ static struct platform_device heartbeat_device = {
.dev = {
.platform_data = &heartbeat_data,
},
- .num_resources = ARRAY_SIZE(heartbeat_resources),
- .resource = heartbeat_resources,
+ .num_resources = 1,
+ .resource = &heartbeat_resource,
};
/* MTD */
@@ -455,7 +453,7 @@ static struct resource sdhi0_resources[] = {
.flags = IORESOURCE_MEM,
},
[1] = {
- .start = 101,
+ .start = 100,
.flags = IORESOURCE_IRQ,
},
};
@@ -491,7 +489,7 @@ static struct resource sdhi1_resources[] = {
.flags = IORESOURCE_MEM,
},
[1] = {
- .start = 24,
+ .start = 23,
.flags = IORESOURCE_IRQ,
},
};
@@ -698,13 +696,13 @@ static struct platform_device camera_devices[] = {
#define FCLKBCR 0xa415000c
static void fsimck_init(struct clk *clk)
{
- u32 status = ctrl_inl(clk->enable_reg);
+ u32 status = __raw_readl(clk->enable_reg);
/* use external clock */
status &= ~0x000000ff;
status |= 0x00000080;
- ctrl_outl(status, clk->enable_reg);
+ __raw_writel(status, clk->enable_reg);
}
static struct clk_ops fsimck_clk_ops = {
@@ -753,6 +751,26 @@ static struct platform_device fsi_device = {
},
};
+/* IrDA */
+static struct resource irda_resources[] = {
+ [0] = {
+ .name = "IrDA",
+ .start = 0xA45D0000,
+ .end = 0xA45D0049,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 20,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device irda_device = {
+ .name = "sh_sir",
+ .num_resources = ARRAY_SIZE(irda_resources),
+ .resource = irda_resources,
+};
+
static struct platform_device *ecovec_devices[] __initdata = {
&heartbeat_device,
&nor_flash_device,
@@ -773,8 +791,10 @@ static struct platform_device *ecovec_devices[] __initdata = {
&camera_devices[1],
&camera_devices[2],
&fsi_device,
+ &irda_device,
};
+#ifdef CONFIG_I2C
#define EEPROM_ADDR 0x50
static u8 mac_read(struct i2c_adapter *a, u8 command)
{
@@ -817,6 +837,12 @@ static void __init sh_eth_init(struct sh_eth_plat_data *pd)
msleep(10);
}
}
+#else
+static void __init sh_eth_init(struct sh_eth_plat_data *pd)
+{
+ pr_err("unable to read sh_eth MAC address\n");
+}
+#endif
#define PORT_HIZA 0xA4050158
#define IODRIVEA 0xA405018A
@@ -831,7 +857,8 @@ static int __init arch_setup(void)
struct clk *clk;
/* register board specific self-refresh code */
- sh_mobile_register_self_refresh(SUSP_SH_STANDBY | SUSP_SH_SF,
+ sh_mobile_register_self_refresh(SUSP_SH_STANDBY | SUSP_SH_SF |
+ SUSP_SH_RSTANDBY,
&ecovec24_sdram_enter_start,
&ecovec24_sdram_enter_end,
&ecovec24_sdram_leave_start,
@@ -855,7 +882,7 @@ static int __init arch_setup(void)
gpio_direction_output(GPIO_PTG1, 0);
gpio_direction_output(GPIO_PTG2, 0);
gpio_direction_output(GPIO_PTG3, 0);
- ctrl_outw((ctrl_inw(PORT_HIZA) & ~(0x1 << 1)) , PORT_HIZA);
+ __raw_writew((__raw_readw(PORT_HIZA) & ~(0x1 << 1)) , PORT_HIZA);
/* enable SH-Eth */
gpio_request(GPIO_PTA1, NULL);
@@ -875,16 +902,16 @@ static int __init arch_setup(void)
gpio_request(GPIO_FN_LNKSTA, NULL);
/* enable USB */
- ctrl_outw(0x0000, 0xA4D80000);
- ctrl_outw(0x0000, 0xA4D90000);
+ __raw_writew(0x0000, 0xA4D80000);
+ __raw_writew(0x0000, 0xA4D90000);
gpio_request(GPIO_PTB3, NULL);
gpio_request(GPIO_PTB4, NULL);
gpio_request(GPIO_PTB5, NULL);
gpio_direction_input(GPIO_PTB3);
gpio_direction_output(GPIO_PTB4, 0);
gpio_direction_output(GPIO_PTB5, 0);
- ctrl_outw(0x0600, 0xa40501d4);
- ctrl_outw(0x0600, 0xa4050192);
+ __raw_writew(0x0600, 0xa40501d4);
+ __raw_writew(0x0600, 0xa4050192);
if (gpio_get_value(GPIO_PTB3)) {
printk(KERN_INFO "USB1 function is selected\n");
@@ -925,7 +952,7 @@ static int __init arch_setup(void)
gpio_request(GPIO_FN_LCDVSYN, NULL);
gpio_request(GPIO_FN_LCDDON, NULL);
gpio_request(GPIO_FN_LCDLCLK, NULL);
- ctrl_outw((ctrl_inw(PORT_HIZA) & ~0x0001), PORT_HIZA);
+ __raw_writew((__raw_readw(PORT_HIZA) & ~0x0001), PORT_HIZA);
gpio_request(GPIO_PTE6, NULL);
gpio_request(GPIO_PTU1, NULL);
@@ -937,7 +964,7 @@ static int __init arch_setup(void)
gpio_direction_output(GPIO_PTA2, 0);
/* I/O buffer drive ability is high */
- ctrl_outw((ctrl_inw(IODRIVEA) & ~0x00c0) | 0x0080 , IODRIVEA);
+ __raw_writew((__raw_readw(IODRIVEA) & ~0x00c0) | 0x0080 , IODRIVEA);
if (gpio_get_value(GPIO_PTE6)) {
/* DVI */
@@ -1069,7 +1096,7 @@ static int __init arch_setup(void)
gpio_direction_output(GPIO_PTB7, 0);
/* I/O buffer drive ability is high for SDHI1 */
- ctrl_outw((ctrl_inw(IODRIVEA) & ~0x3000) | 0x2000 , IODRIVEA);
+ __raw_writew((__raw_readw(IODRIVEA) & ~0x3000) | 0x2000 , IODRIVEA);
#else
/* enable MSIOF0 on CN11 (needs DS2.4 set to OFF) */
gpio_request(GPIO_FN_MSIOF0_TXD, NULL);
@@ -1107,6 +1134,11 @@ static int __init arch_setup(void)
gpio_request(GPIO_FN_FSIOBLRCK, NULL);
gpio_request(GPIO_FN_CLKAUDIOBO, NULL);
+ /* set SPU2 clock to 83.4 MHz */
+ clk = clk_get(NULL, "spu_clk");
+ clk_set_rate(clk, clk_round_rate(clk, 83333333));
+ clk_put(clk);
+
/* change parent of FSI B */
clk = clk_get(NULL, "fsib_clk");
clk_register(&fsimckb_clk);
@@ -1123,6 +1155,17 @@ static int __init arch_setup(void)
gpio_request(GPIO_FN_INTC_IRQ1, NULL);
gpio_direction_input(GPIO_FN_INTC_IRQ1);
+ /* set VPU clock to 166 MHz */
+ clk = clk_get(NULL, "vpu_clk");
+ clk_set_rate(clk, clk_round_rate(clk, 166000000));
+ clk_put(clk);
+
+ /* enable IrDA */
+ gpio_request(GPIO_FN_IRDA_OUT, NULL);
+ gpio_request(GPIO_FN_IRDA_IN, NULL);
+ gpio_request(GPIO_PTU5, NULL);
+ gpio_direction_output(GPIO_PTU5, 0);
+
/* enable I2C device */
i2c_register_board_info(0, i2c0_devices,
ARRAY_SIZE(i2c0_devices));
diff --git a/arch/sh/boards/mach-highlander/irq-r7780mp.c b/arch/sh/boards/mach-highlander/irq-r7780mp.c
index 83c28bcd4d2..9893fd3a135 100644
--- a/arch/sh/boards/mach-highlander/irq-r7780mp.c
+++ b/arch/sh/boards/mach-highlander/irq-r7780mp.c
@@ -64,7 +64,7 @@ static DECLARE_INTC_DESC(intc_desc, "r7780mp", vectors,
unsigned char * __init highlander_plat_irq_setup(void)
{
- if ((ctrl_inw(0xa4000700) & 0xf000) == 0x2000) {
+ if ((__raw_readw(0xa4000700) & 0xf000) == 0x2000) {
printk(KERN_INFO "Using r7780mp interrupt controller.\n");
register_intc_controller(&intc_desc);
return irl2irq;
diff --git a/arch/sh/boards/mach-highlander/irq-r7780rp.c b/arch/sh/boards/mach-highlander/irq-r7780rp.c
index b721e86b5af..0805b215145 100644
--- a/arch/sh/boards/mach-highlander/irq-r7780rp.c
+++ b/arch/sh/boards/mach-highlander/irq-r7780rp.c
@@ -57,7 +57,7 @@ static DECLARE_INTC_DESC(intc_desc, "r7780rp", vectors,
unsigned char * __init highlander_plat_irq_setup(void)
{
- if (ctrl_inw(0xa5000600)) {
+ if (__raw_readw(0xa5000600)) {
printk(KERN_INFO "Using r7780rp interrupt controller.\n");
register_intc_controller(&intc_desc);
return irl2irq;
diff --git a/arch/sh/boards/mach-highlander/irq-r7785rp.c b/arch/sh/boards/mach-highlander/irq-r7785rp.c
index 3811b060a39..558b2486277 100644
--- a/arch/sh/boards/mach-highlander/irq-r7785rp.c
+++ b/arch/sh/boards/mach-highlander/irq-r7785rp.c
@@ -66,20 +66,20 @@ static DECLARE_INTC_DESC(intc_desc, "r7785rp", vectors,
unsigned char * __init highlander_plat_irq_setup(void)
{
- if ((ctrl_inw(0xa4000158) & 0xf000) != 0x1000)
+ if ((__raw_readw(0xa4000158) & 0xf000) != 0x1000)
return NULL;
printk(KERN_INFO "Using r7785rp interrupt controller.\n");
- ctrl_outw(0x0000, PA_IRLSSR1); /* FPGA IRLSSR1(CF_CD clear) */
+ __raw_writew(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(0xdcba, PA_IRLPRF); /* FPGA IRLF */
+ __raw_writew(0x0000, PA_IRLPRA); /* FPGA IRLA */
+ __raw_writew(0xe598, PA_IRLPRB); /* FPGA IRLB */
+ __raw_writew(0x7060, PA_IRLPRC); /* FPGA IRLC */
+ __raw_writew(0x0000, PA_IRLPRD); /* FPGA IRLD */
+ __raw_writew(0x4321, PA_IRLPRE); /* FPGA IRLE */
+ __raw_writew(0xdcba, PA_IRLPRF); /* FPGA IRLF */
register_intc_controller(&intc_desc);
return irl2irq;
diff --git a/arch/sh/boards/mach-highlander/psw.c b/arch/sh/boards/mach-highlander/psw.c
index 37b1a2ee71a..522786318d3 100644
--- a/arch/sh/boards/mach-highlander/psw.c
+++ b/arch/sh/boards/mach-highlander/psw.c
@@ -24,7 +24,7 @@ static irqreturn_t psw_irq_handler(int irq, void *arg)
unsigned int l, mask;
int ret = 0;
- l = ctrl_inw(PA_DBSW);
+ l = __raw_readw(PA_DBSW);
/* Nothing to do if there's no state change */
if (psw->state) {
@@ -45,7 +45,7 @@ static irqreturn_t psw_irq_handler(int irq, void *arg)
out:
/* Clear the switch IRQs */
l |= (0x7 << 12);
- ctrl_outw(l, PA_DBSW);
+ __raw_writew(l, PA_DBSW);
return IRQ_RETVAL(ret);
}
diff --git a/arch/sh/boards/mach-highlander/setup.c b/arch/sh/boards/mach-highlander/setup.c
index f663c14d888..affd66747ba 100644
--- a/arch/sh/boards/mach-highlander/setup.c
+++ b/arch/sh/boards/mach-highlander/setup.c
@@ -311,13 +311,13 @@ device_initcall(r7780rp_devices_setup);
*/
static int ivdr_clk_enable(struct clk *clk)
{
- ctrl_outw(ctrl_inw(PA_IVDRCTL) | (1 << IVDR_CK_ON), PA_IVDRCTL);
+ __raw_writew(__raw_readw(PA_IVDRCTL) | (1 << IVDR_CK_ON), PA_IVDRCTL);
return 0;
}
static void ivdr_clk_disable(struct clk *clk)
{
- ctrl_outw(ctrl_inw(PA_IVDRCTL) & ~(1 << IVDR_CK_ON), PA_IVDRCTL);
+ __raw_writew(__raw_readw(PA_IVDRCTL) & ~(1 << IVDR_CK_ON), PA_IVDRCTL);
}
static struct clk_ops ivdr_clk_ops = {
@@ -337,7 +337,7 @@ static struct clk *r7780rp_clocks[] = {
static void r7780rp_power_off(void)
{
if (mach_is_r7780mp() || mach_is_r7785rp())
- ctrl_outw(0x0001, PA_POFF);
+ __raw_writew(0x0001, PA_POFF);
}
/*
@@ -345,7 +345,7 @@ static void r7780rp_power_off(void)
*/
static void __init highlander_setup(char **cmdline_p)
{
- u16 ver = ctrl_inw(PA_VERREG);
+ u16 ver = __raw_readw(PA_VERREG);
int i;
printk(KERN_INFO "Renesas Solutions Highlander %s support.\n",
@@ -370,12 +370,12 @@ static void __init highlander_setup(char **cmdline_p)
clk_enable(clk);
}
- ctrl_outw(0x0000, PA_OBLED); /* Clear LED. */
+ __raw_writew(0x0000, PA_OBLED); /* Clear LED. */
if (mach_is_r7780rp())
- ctrl_outw(0x0001, PA_SDPOW); /* SD Power ON */
+ __raw_writew(0x0001, PA_SDPOW); /* SD Power ON */
- ctrl_outw(ctrl_inw(PA_IVDRCTL) | 0x01, PA_IVDRCTL); /* Si13112 */
+ __raw_writew(__raw_readw(PA_IVDRCTL) | 0x01, PA_IVDRCTL); /* Si13112 */
pm_power_off = r7780rp_power_off;
}
diff --git a/arch/sh/boards/mach-hp6xx/hp6xx_apm.c b/arch/sh/boards/mach-hp6xx/hp6xx_apm.c
index e85212faf40..b49535c0ddd 100644
--- a/arch/sh/boards/mach-hp6xx/hp6xx_apm.c
+++ b/arch/sh/boards/mach-hp6xx/hp6xx_apm.c
@@ -53,7 +53,7 @@ static void hp6x0_apm_get_power_status(struct apm_power_info *info)
info->ac_line_status = (battery > HP680_BATTERY_AC_ON) ?
APM_AC_ONLINE : APM_AC_OFFLINE;
- pgdr = ctrl_inb(PGDR);
+ pgdr = __raw_readb(PGDR);
if (pgdr & PGDR_MAIN_BATTERY_OUT) {
info->battery_status = APM_BATTERY_STATUS_NOT_PRESENT;
info->battery_flag = 0x80;
diff --git a/arch/sh/boards/mach-hp6xx/pm.c b/arch/sh/boards/mach-hp6xx/pm.c
index d936c1af762..4499a3749d4 100644
--- a/arch/sh/boards/mach-hp6xx/pm.c
+++ b/arch/sh/boards/mach-hp6xx/pm.c
@@ -53,17 +53,17 @@ static void pm_enter(void)
sh_wdt_write_cnt(0);
/* disable PLL1 */
- frqcr = ctrl_inw(FRQCR);
+ frqcr = __raw_readw(FRQCR);
frqcr &= ~(FRQCR_PLLEN | FRQCR_PSTBY);
- ctrl_outw(frqcr, FRQCR);
+ __raw_writew(frqcr, FRQCR);
/* enable standby */
- stbcr = ctrl_inb(STBCR);
- ctrl_outb(stbcr | STBCR_STBY | STBCR_MSTP2, STBCR);
+ stbcr = __raw_readb(STBCR);
+ __raw_writeb(stbcr | STBCR_STBY | STBCR_MSTP2, STBCR);
/* set self-refresh */
- mcr = ctrl_inw(MCR);
- ctrl_outw(mcr & ~MCR_RFSH, MCR);
+ mcr = __raw_readw(MCR);
+ __raw_writew(mcr & ~MCR_RFSH, MCR);
/* set interrupt handler */
asm volatile("stc vbr, %0" : "=r" (vbr_old));
@@ -73,8 +73,8 @@ static void pm_enter(void)
&wakeup_start, &wakeup_end - &wakeup_start);
asm volatile("ldc %0, vbr" : : "r" (vbr_new));
- ctrl_outw(0, RTCNT);
- ctrl_outw(mcr | MCR_RFSH | MCR_RMODE, MCR);
+ __raw_writew(0, RTCNT);
+ __raw_writew(mcr | MCR_RFSH | MCR_RMODE, MCR);
cpu_sleep();
@@ -83,14 +83,14 @@ static void pm_enter(void)
free_page(vbr_new);
/* enable PLL1 */
- frqcr = ctrl_inw(FRQCR);
+ frqcr = __raw_readw(FRQCR);
frqcr |= FRQCR_PSTBY;
- ctrl_outw(frqcr, FRQCR);
+ __raw_writew(frqcr, FRQCR);
udelay(50);
frqcr |= FRQCR_PLLEN;
- ctrl_outw(frqcr, FRQCR);
+ __raw_writew(frqcr, FRQCR);
- ctrl_outb(stbcr, STBCR);
+ __raw_writeb(stbcr, STBCR);
clear_bl_bit();
}
@@ -115,21 +115,21 @@ static int hp6x0_pm_enter(suspend_state_t state)
outw(hd64461_stbcr, HD64461_STBCR);
#endif
- ctrl_outb(0x1f, DACR);
+ __raw_writeb(0x1f, DACR);
- stbcr = ctrl_inb(STBCR);
- ctrl_outb(0x01, STBCR);
+ stbcr = __raw_readb(STBCR);
+ __raw_writeb(0x01, STBCR);
- stbcr2 = ctrl_inb(STBCR2);
- ctrl_outb(0x7f , STBCR2);
+ stbcr2 = __raw_readb(STBCR2);
+ __raw_writeb(0x7f , STBCR2);
outw(0xf07f, HD64461_SCPUCR);
pm_enter();
outw(0, HD64461_SCPUCR);
- ctrl_outb(stbcr, STBCR);
- ctrl_outb(stbcr2, STBCR2);
+ __raw_writeb(stbcr, STBCR);
+ __raw_writeb(stbcr2, STBCR2);
#ifdef CONFIG_HD64461_ENABLER
hd64461_stbcr = inw(HD64461_STBCR);
diff --git a/arch/sh/boards/mach-hp6xx/setup.c b/arch/sh/boards/mach-hp6xx/setup.c
index e6dd5e96321..8c9add5f4cf 100644
--- a/arch/sh/boards/mach-hp6xx/setup.c
+++ b/arch/sh/boards/mach-hp6xx/setup.c
@@ -149,19 +149,19 @@ static void __init hp6xx_setup(char **cmdline_p)
sh_dac_output(0, DAC_SPEAKER_VOLUME);
sh_dac_disable(DAC_SPEAKER_VOLUME);
- v8 = ctrl_inb(DACR);
+ v8 = __raw_readb(DACR);
v8 &= ~DACR_DAE;
- ctrl_outb(v8,DACR);
+ __raw_writeb(v8,DACR);
- v8 = ctrl_inb(SCPDR);
+ v8 = __raw_readb(SCPDR);
v8 |= SCPDR_TS_SCAN_X | SCPDR_TS_SCAN_Y;
v8 &= ~SCPDR_TS_SCAN_ENABLE;
- ctrl_outb(v8, SCPDR);
+ __raw_writeb(v8, SCPDR);
- v = ctrl_inw(SCPCR);
+ v = __raw_readw(SCPCR);
v &= ~SCPCR_TS_MASK;
v |= SCPCR_TS_ENABLE;
- ctrl_outw(v, SCPCR);
+ __raw_writew(v, SCPCR);
}
device_initcall(hp6xx_devices_setup);
diff --git a/arch/sh/boards/mach-kfr2r09/setup.c b/arch/sh/boards/mach-kfr2r09/setup.c
index 5d7b5d92475..b2cd0ed8664 100644
--- a/arch/sh/boards/mach-kfr2r09/setup.c
+++ b/arch/sh/boards/mach-kfr2r09/setup.c
@@ -282,7 +282,7 @@ static int camera_power(struct device *dev, int mode)
* use 1.8 V for VccQ_VIO
* use 2.85V for VccQ_SR
*/
- ctrl_outw((ctrl_inw(DRVCRB) & ~0x0003) | 0x0001, DRVCRB);
+ __raw_writew((__raw_readw(DRVCRB) & ~0x0003) | 0x0001, DRVCRB);
/* reset clear */
ret = gpio_request(GPIO_PTB4, NULL);
@@ -351,7 +351,7 @@ static struct resource kfr2r09_sh_sdhi0_resources[] = {
.flags = IORESOURCE_MEM,
},
[1] = {
- .start = 101,
+ .start = 100,
.flags = IORESOURCE_IRQ,
},
};
@@ -492,13 +492,13 @@ static int kfr2r09_usb0_gadget_setup(void)
if (kfr2r09_usb0_gadget_i2c_setup() != 0)
return -ENODEV; /* unable to configure using i2c */
- ctrl_outw((ctrl_inw(PORT_MSELCRB) & ~0xc000) | 0x8000, PORT_MSELCRB);
+ __raw_writew((__raw_readw(PORT_MSELCRB) & ~0xc000) | 0x8000, PORT_MSELCRB);
gpio_request(GPIO_FN_PDSTATUS, NULL); /* R-standby disables USB clock */
gpio_request(GPIO_PTV6, NULL); /* USBCLK_ON */
gpio_direction_output(GPIO_PTV6, 1); /* USBCLK_ON = H */
msleep(20); /* wait 20ms to let the clock settle */
clk_enable(clk_get(NULL, "usb0"));
- ctrl_outw(0x0600, 0xa40501d4);
+ __raw_writew(0x0600, 0xa40501d4);
return 0;
}
@@ -526,12 +526,12 @@ static int __init kfr2r09_devices_setup(void)
gpio_direction_output(GPIO_PTG3, 1); /* HPON_ON = H */
/* setup NOR flash at CS0 */
- ctrl_outl(0x36db0400, BSC_CS0BCR);
- ctrl_outl(0x00000500, BSC_CS0WCR);
+ __raw_writel(0x36db0400, BSC_CS0BCR);
+ __raw_writel(0x00000500, BSC_CS0WCR);
/* setup NAND flash at CS4 */
- ctrl_outl(0x36db0400, BSC_CS4BCR);
- ctrl_outl(0x00000500, BSC_CS4WCR);
+ __raw_writel(0x36db0400, BSC_CS4BCR);
+ __raw_writel(0x00000500, BSC_CS4WCR);
/* setup KEYSC pins */
gpio_request(GPIO_FN_KEYOUT0, NULL);
diff --git a/arch/sh/boards/mach-landisk/gio.c b/arch/sh/boards/mach-landisk/gio.c
index 52801318819..01e6abb769b 100644
--- a/arch/sh/boards/mach-landisk/gio.c
+++ b/arch/sh/boards/mach-landisk/gio.c
@@ -76,39 +76,39 @@ static long gio_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
break;
case GIODRV_IOCSGIODATA1: /* write byte */
- ctrl_outb((unsigned char)(0x0ff & data), addr);
+ __raw_writeb((unsigned char)(0x0ff & data), addr);
break;
case GIODRV_IOCSGIODATA2: /* write word */
if (addr & 0x01) {
return -EFAULT;
}
- ctrl_outw((unsigned short int)(0x0ffff & data), addr);
+ __raw_writew((unsigned short int)(0x0ffff & data), addr);
break;
case GIODRV_IOCSGIODATA4: /* write long */
if (addr & 0x03) {
return -EFAULT;
}
- ctrl_outl(data, addr);
+ __raw_writel(data, addr);
break;
case GIODRV_IOCGGIODATA1: /* read byte */
- data = ctrl_inb(addr);
+ data = __raw_readb(addr);
break;
case GIODRV_IOCGGIODATA2: /* read word */
if (addr & 0x01) {
return -EFAULT;
}
- data = ctrl_inw(addr);
+ data = __raw_readw(addr);
break;
case GIODRV_IOCGGIODATA4: /* read long */
if (addr & 0x03) {
return -EFAULT;
}
- data = ctrl_inl(addr);
+ data = __raw_readl(addr);
break;
default:
return -EFAULT;
diff --git a/arch/sh/boards/mach-landisk/irq.c b/arch/sh/boards/mach-landisk/irq.c
index 7b284cde1f5..96f38a4187d 100644
--- a/arch/sh/boards/mach-landisk/irq.c
+++ b/arch/sh/boards/mach-landisk/irq.c
@@ -22,14 +22,14 @@ static void disable_landisk_irq(unsigned int irq)
{
unsigned char mask = 0xff ^ (0x01 << (irq - 5));
- ctrl_outb(ctrl_inb(PA_IMASK) & mask, PA_IMASK);
+ __raw_writeb(__raw_readb(PA_IMASK) & mask, PA_IMASK);
}
static void enable_landisk_irq(unsigned int irq)
{
unsigned char value = (0x01 << (irq - 5));
- ctrl_outb(ctrl_inb(PA_IMASK) | value, PA_IMASK);
+ __raw_writeb(__raw_readb(PA_IMASK) | value, PA_IMASK);
}
static struct irq_chip landisk_irq_chip __read_mostly = {
@@ -52,5 +52,5 @@ void __init init_landisk_IRQ(void)
handle_level_irq, "level");
enable_landisk_irq(i);
}
- ctrl_outb(0x00, PA_PWRINT_CLR);
+ __raw_writeb(0x00, PA_PWRINT_CLR);
}
diff --git a/arch/sh/boards/mach-landisk/psw.c b/arch/sh/boards/mach-landisk/psw.c
index e6b0efa098d..bef83522f95 100644
--- a/arch/sh/boards/mach-landisk/psw.c
+++ b/arch/sh/boards/mach-landisk/psw.c
@@ -25,7 +25,7 @@ static irqreturn_t psw_irq_handler(int irq, void *arg)
unsigned int sw_value;
int ret = 0;
- sw_value = (0x0ff & (~ctrl_inb(PA_STATUS)));
+ sw_value = (0x0ff & (~__raw_readb(PA_STATUS)));
/* Nothing to do if there's no state change */
if (psw->state) {
@@ -42,7 +42,7 @@ static irqreturn_t psw_irq_handler(int irq, void *arg)
out:
/* Clear the switch IRQs */
- ctrl_outb(0x00, PA_PWRINT_CLR);
+ __raw_writeb(0x00, PA_PWRINT_CLR);
return IRQ_RETVAL(ret);
}
diff --git a/arch/sh/boards/mach-landisk/setup.c b/arch/sh/boards/mach-landisk/setup.c
index db22ea2e6d4..50337acc18c 100644
--- a/arch/sh/boards/mach-landisk/setup.c
+++ b/arch/sh/boards/mach-landisk/setup.c
@@ -25,7 +25,7 @@ void init_landisk_IRQ(void);
static void landisk_power_off(void)
{
- ctrl_outb(0x01, PA_SHUTDOWN);
+ __raw_writeb(0x01, PA_SHUTDOWN);
}
static struct resource cf_ide_resources[3];
@@ -63,7 +63,7 @@ static int __init landisk_devices_setup(void)
/* open I/O area window */
paddrbase = virt_to_phys((void *)PA_AREA5_IO);
prot = PAGE_KERNEL_PCC(1, _PAGE_PCC_IO16);
- cf_ide_base = p3_ioremap(paddrbase, PAGE_SIZE, prot.pgprot);
+ cf_ide_base = ioremap_prot(paddrbase, PAGE_SIZE, pgprot_val(prot));
if (!cf_ide_base) {
printk("allocate_cf_area : can't open CF I/O window!\n");
return -ENOMEM;
@@ -88,7 +88,7 @@ __initcall(landisk_devices_setup);
static void __init landisk_setup(char **cmdline_p)
{
/* LED ON */
- ctrl_outb(ctrl_inb(PA_LED) | 0x03, PA_LED);
+ __raw_writeb(__raw_readb(PA_LED) | 0x03, PA_LED);
printk(KERN_INFO "I-O DATA DEVICE, INC. \"LANDISK Series\" support.\n");
pm_power_off = landisk_power_off;
diff --git a/arch/sh/boards/mach-lboxre2/setup.c b/arch/sh/boards/mach-lboxre2/setup.c
index 2b0b5818e1e..79b4e0d77b7 100644
--- a/arch/sh/boards/mach-lboxre2/setup.c
+++ b/arch/sh/boards/mach-lboxre2/setup.c
@@ -56,8 +56,8 @@ static int __init lboxre2_devices_setup(void)
/* 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);
+ prot = PAGE_KERNEL_PCC(1, _PAGE_PCC_IO16);
+ cf0_io_base = (u32)ioremap_prot(paddrbase, psize, pgprot_val(prot));
if (!cf0_io_base) {
printk(KERN_ERR "%s : can't open CF I/O window!\n" , __func__ );
return -ENOMEM;
diff --git a/arch/sh/boards/mach-microdev/io.c b/arch/sh/boards/mach-microdev/io.c
index 52dd748211c..2960c659020 100644
--- a/arch/sh/boards/mach-microdev/io.c
+++ b/arch/sh/boards/mach-microdev/io.c
@@ -141,10 +141,10 @@ static inline void delay(void)
#if defined(CONFIG_PCI)
/* System board present, just make a dummy SRAM access. (CS0 will be
mapped to PCI memory, probably good to avoid it.) */
- ctrl_inw(0xa6800000);
+ __raw_readw(0xa6800000);
#else
/* CS0 will be mapped to flash, ROM etc so safe to access it. */
- ctrl_inw(0xa0000000);
+ __raw_readw(0xa0000000);
#endif
}
diff --git a/arch/sh/boards/mach-microdev/irq.c b/arch/sh/boards/mach-microdev/irq.c
index b551963579c..a26d16669aa 100644
--- a/arch/sh/boards/mach-microdev/irq.c
+++ b/arch/sh/boards/mach-microdev/irq.c
@@ -88,7 +88,7 @@ static void disable_microdev_irq(unsigned int irq)
fpgaIrq = fpgaIrqTable[irq].fpgaIrq;
/* disable interrupts on the FPGA INTC register */
- ctrl_outl(MICRODEV_FPGA_INTC_MASK(fpgaIrq), MICRODEV_FPGA_INTDSB_REG);
+ __raw_writel(MICRODEV_FPGA_INTC_MASK(fpgaIrq), MICRODEV_FPGA_INTDSB_REG);
}
static void enable_microdev_irq(unsigned int irq)
@@ -107,13 +107,13 @@ static void enable_microdev_irq(unsigned int irq)
priorityReg = MICRODEV_FPGA_INTPRI_REG(fpgaIrq);
/* set priority for the interrupt */
- priorities = ctrl_inl(priorityReg);
+ priorities = __raw_readl(priorityReg);
priorities &= ~MICRODEV_FPGA_INTPRI_MASK(fpgaIrq);
priorities |= MICRODEV_FPGA_INTPRI_LEVEL(fpgaIrq, pri);
- ctrl_outl(priorities, priorityReg);
+ __raw_writel(priorities, priorityReg);
/* enable interrupts on the FPGA INTC register */
- ctrl_outl(MICRODEV_FPGA_INTC_MASK(fpgaIrq), MICRODEV_FPGA_INTENB_REG);
+ __raw_writel(MICRODEV_FPGA_INTC_MASK(fpgaIrq), MICRODEV_FPGA_INTENB_REG);
}
/* This function sets the desired irq handler to be a MicroDev type */
@@ -134,7 +134,7 @@ extern void __init init_microdev_irq(void)
int i;
/* disable interrupts on the FPGA INTC register */
- ctrl_outl(~0ul, MICRODEV_FPGA_INTDSB_REG);
+ __raw_writel(~0ul, MICRODEV_FPGA_INTDSB_REG);
for (i = 0; i < NUM_EXTERNAL_IRQS; i++)
make_microdev_irq(i);
diff --git a/arch/sh/boards/mach-migor/setup.c b/arch/sh/boards/mach-migor/setup.c
index 507c77be476..e08d5132bb1 100644
--- a/arch/sh/boards/mach-migor/setup.c
+++ b/arch/sh/boards/mach-migor/setup.c
@@ -397,7 +397,7 @@ static struct resource sdhi_cn9_resources[] = {
.flags = IORESOURCE_MEM,
},
[1] = {
- .start = 101,
+ .start = 100,
.flags = IORESOURCE_IRQ,
},
};
@@ -496,28 +496,16 @@ static int __init migor_devices_setup(void)
&migor_sdram_enter_end,
&migor_sdram_leave_start,
&migor_sdram_leave_end);
-#ifdef CONFIG_PM
/* Let D11 LED show STATUS0 */
gpio_request(GPIO_FN_STATUS0, NULL);
/* Lit D12 LED show PDSTATUS */
gpio_request(GPIO_FN_PDSTATUS, NULL);
-#else
- /* Lit D11 LED */
- gpio_request(GPIO_PTJ7, NULL);
- gpio_direction_output(GPIO_PTJ7, 1);
- gpio_export(GPIO_PTJ7, 0);
-
- /* Lit D12 LED */
- gpio_request(GPIO_PTJ5, NULL);
- gpio_direction_output(GPIO_PTJ5, 1);
- gpio_export(GPIO_PTJ5, 0);
-#endif
/* SMC91C111 - Enable IRQ0, Setup CS4 for 16-bit fast access */
gpio_request(GPIO_FN_IRQ0, NULL);
- ctrl_outl(0x00003400, BSC_CS4BCR);
- ctrl_outl(0x00110080, BSC_CS4WCR);
+ __raw_writel(0x00003400, BSC_CS4BCR);
+ __raw_writel(0x00110080, BSC_CS4WCR);
/* KEYSC */
gpio_request(GPIO_FN_KEYOUT0, NULL);
@@ -533,7 +521,7 @@ static int __init migor_devices_setup(void)
/* NAND Flash */
gpio_request(GPIO_FN_CS6A_CE2B, NULL);
- ctrl_outl((ctrl_inl(BSC_CS6ABCR) & ~0x0600) | 0x0200, BSC_CS6ABCR);
+ __raw_writel((__raw_readl(BSC_CS6ABCR) & ~0x0600) | 0x0200, BSC_CS6ABCR);
gpio_request(GPIO_PTA1, NULL);
gpio_direction_input(GPIO_PTA1);
@@ -627,7 +615,7 @@ static int __init migor_devices_setup(void)
#else
gpio_direction_output(GPIO_PTT0, 1);
#endif
- ctrl_outw(ctrl_inw(PORT_MSELCRB) | 0x2000, PORT_MSELCRB); /* D15->D8 */
+ __raw_writew(__raw_readw(PORT_MSELCRB) | 0x2000, PORT_MSELCRB); /* D15->D8 */
platform_resource_setup_memory(&migor_ceu_device, "ceu", 4 << 20);
diff --git a/arch/sh/boards/mach-r2d/irq.c b/arch/sh/boards/mach-r2d/irq.c
index 78d7b27c80d..574f009c3c3 100644
--- a/arch/sh/boards/mach-r2d/irq.c
+++ b/arch/sh/boards/mach-r2d/irq.c
@@ -129,7 +129,7 @@ void __init init_rts7751r2d_IRQ(void)
{
struct intc_desc *d;
- switch (ctrl_inw(PA_VERREG) & 0xf0) {
+ switch (__raw_readw(PA_VERREG) & 0xf0) {
#ifdef CONFIG_RTS7751R2D_PLUS
case 0x10:
printk(KERN_INFO "Using R2D-PLUS interrupt controller.\n");
@@ -147,7 +147,7 @@ void __init init_rts7751r2d_IRQ(void)
#endif
default:
printk(KERN_INFO "Unknown R2D interrupt controller 0x%04x\n",
- ctrl_inw(PA_VERREG));
+ __raw_readw(PA_VERREG));
return;
}
diff --git a/arch/sh/boards/mach-r2d/setup.c b/arch/sh/boards/mach-r2d/setup.c
index a625ecb93e4..b84df6a3a93 100644
--- a/arch/sh/boards/mach-r2d/setup.c
+++ b/arch/sh/boards/mach-r2d/setup.c
@@ -70,7 +70,7 @@ static struct spi_board_info spi_bus[] = {
static void r2d_chip_select(struct sh_spi_info *spi, int cs, int state)
{
BUG_ON(cs != 0); /* Single Epson RTC-9701JE attached on CS0 */
- ctrl_outw(state == BITBANG_CS_ACTIVE, PA_RTCCE);
+ __raw_writew(state == BITBANG_CS_ACTIVE, PA_RTCCE);
}
static struct sh_spi_info spi_info = {
@@ -262,7 +262,7 @@ __initcall(rts7751r2d_devices_setup);
static void rts7751r2d_power_off(void)
{
- ctrl_outw(0x0001, PA_POWOFF);
+ __raw_writew(0x0001, PA_POWOFF);
}
/*
@@ -271,14 +271,14 @@ static void rts7751r2d_power_off(void)
static void __init rts7751r2d_setup(char **cmdline_p)
{
void __iomem *sm501_reg;
- u16 ver = ctrl_inw(PA_VERREG);
+ u16 ver = __raw_readw(PA_VERREG);
printk(KERN_INFO "Renesas Technology Sales RTS7751R2D support.\n");
printk(KERN_INFO "FPGA version:%d (revision:%d)\n",
(ver >> 4) & 0xf, ver & 0xf);
- ctrl_outw(0x0000, PA_OUTPORT);
+ __raw_writew(0x0000, PA_OUTPORT);
pm_power_off = rts7751r2d_power_off;
/* sm501 dram configuration:
diff --git a/arch/sh/boards/mach-rsk/devices-rsk7203.c b/arch/sh/boards/mach-rsk/devices-rsk7203.c
index c37617e6322..4fa08ba1025 100644
--- a/arch/sh/boards/mach-rsk/devices-rsk7203.c
+++ b/arch/sh/boards/mach-rsk/devices-rsk7203.c
@@ -96,7 +96,7 @@ static int __init rsk7203_devices_setup(void)
gpio_request(GPIO_FN_RXD0, NULL);
/* Setup LAN9118: CS1 in 16-bit Big Endian Mode, IRQ0 at Port B */
- ctrl_outl(0x36db0400, 0xfffc0008); /* CS1BCR */
+ __raw_writel(0x36db0400, 0xfffc0008); /* CS1BCR */
gpio_request(GPIO_FN_IRQ0_PB, NULL);
return platform_add_devices(rsk7203_devices,
diff --git a/arch/sh/boards/mach-sdk7780/irq.c b/arch/sh/boards/mach-sdk7780/irq.c
index 855558163c5..e5f7564f251 100644
--- a/arch/sh/boards/mach-sdk7780/irq.c
+++ b/arch/sh/boards/mach-sdk7780/irq.c
@@ -37,9 +37,9 @@ void __init init_sdk7780_IRQ(void)
{
printk(KERN_INFO "Using SDK7780 interrupt controller.\n");
- ctrl_outw(0xFFFF, FPGA_IRQ0MR);
+ __raw_writew(0xFFFF, FPGA_IRQ0MR);
/* Setup IRL 0-3 */
- ctrl_outw(0x0003, FPGA_IMSR);
+ __raw_writew(0x0003, FPGA_IMSR);
plat_irq_setup_pins(IRQ_MODE_IRL3210);
register_intc_controller(&fpga_intc_desc);
diff --git a/arch/sh/boards/mach-sdk7780/setup.c b/arch/sh/boards/mach-sdk7780/setup.c
index aad94a78dc7..4da38db4b5f 100644
--- a/arch/sh/boards/mach-sdk7780/setup.c
+++ b/arch/sh/boards/mach-sdk7780/setup.c
@@ -20,27 +20,18 @@
#define GPIO_PECR 0xFFEA0008
-//* Heartbeat */
-static struct heartbeat_data heartbeat_data = {
- .regsize = 16,
-};
-
-static struct resource heartbeat_resources[] = {
- [0] = {
- .start = PA_LED,
- .end = PA_LED,
- .flags = IORESOURCE_MEM,
- },
+/* Heartbeat */
+static struct resource heartbeat_resource = {
+ .start = PA_LED,
+ .end = PA_LED,
+ .flags = IORESOURCE_MEM | IORESOURCE_MEM_16BIT,
};
static struct platform_device heartbeat_device = {
.name = "heartbeat",
.id = -1,
- .dev = {
- .platform_data = &heartbeat_data,
- },
- .num_resources = ARRAY_SIZE(heartbeat_resources),
- .resource = heartbeat_resources,
+ .num_resources = 1,
+ .resource = &heartbeat_resource,
};
/* SMC91x */
@@ -83,8 +74,8 @@ device_initcall(sdk7780_devices_setup);
static void __init sdk7780_setup(char **cmdline_p)
{
- u16 ver = ctrl_inw(FPGA_FPVERR);
- u16 dateStamp = ctrl_inw(FPGA_FPDATER);
+ u16 ver = __raw_readw(FPGA_FPVERR);
+ u16 dateStamp = __raw_readw(FPGA_FPDATER);
printk(KERN_INFO "Renesas Technology Europe SDK7780 support.\n");
printk(KERN_INFO "Board version: %d (revision %d), "
@@ -94,7 +85,7 @@ static void __init sdk7780_setup(char **cmdline_p)
dateStamp);
/* Setup pin mux'ing for PCIC */
- ctrl_outw(0x0000, GPIO_PECR);
+ __raw_writew(0x0000, GPIO_PECR);
}
/*
diff --git a/arch/sh/boards/mach-sdk7786/Makefile b/arch/sh/boards/mach-sdk7786/Makefile
new file mode 100644
index 00000000000..a29f19e85b6
--- /dev/null
+++ b/arch/sh/boards/mach-sdk7786/Makefile
@@ -0,0 +1 @@
+obj-y := setup.o fpga.o irq.o
diff --git a/arch/sh/boards/mach-sdk7786/fpga.c b/arch/sh/boards/mach-sdk7786/fpga.c
new file mode 100644
index 00000000000..3e4ec66a041
--- /dev/null
+++ b/arch/sh/boards/mach-sdk7786/fpga.c
@@ -0,0 +1,72 @@
+/*
+ * SDK7786 FPGA Support.
+ *
+ * Copyright (C) 2010 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/io.h>
+#include <linux/bcd.h>
+#include <mach/fpga.h>
+#include <asm/sizes.h>
+
+#define FPGA_REGS_OFFSET 0x03fff800
+#define FPGA_REGS_SIZE 0x490
+
+/*
+ * The FPGA can be mapped in any of the generally available areas,
+ * so we attempt to scan for it using the fixed SRSTR read magic.
+ *
+ * Once the FPGA is located, the rest of the mapping data for the other
+ * components can be determined dynamically from its section mapping
+ * registers.
+ */
+static void __iomem *sdk7786_fpga_probe(void)
+{
+ unsigned long area;
+ void __iomem *base;
+
+ /*
+ * Iterate over all of the areas where the FPGA could be mapped.
+ * The possible range is anywhere from area 0 through 6, area 7
+ * is reserved.
+ */
+ for (area = PA_AREA0; area < PA_AREA7; area += SZ_64M) {
+ base = ioremap_nocache(area + FPGA_REGS_OFFSET, FPGA_REGS_SIZE);
+ if (!base) {
+ /* Failed to remap this area, move along. */
+ continue;
+ }
+
+ if (ioread16(base + SRSTR) == SRSTR_MAGIC)
+ return base; /* Found it! */
+
+ iounmap(base);
+ }
+
+ return NULL;
+}
+
+void __iomem *sdk7786_fpga_base;
+
+void __init sdk7786_fpga_init(void)
+{
+ u16 version, date;
+
+ sdk7786_fpga_base = sdk7786_fpga_probe();
+ if (unlikely(!sdk7786_fpga_base)) {
+ panic("FPGA detection failed.\n");
+ return;
+ }
+
+ version = fpga_read_reg(FPGAVR);
+ date = fpga_read_reg(FPGADR);
+
+ pr_info("\tFPGA version:\t%d.%d (built on %d/%d/%d)\n",
+ bcd2bin(version >> 8) & 0xf, bcd2bin(version & 0xf),
+ ((date >> 12) & 0xf) + 2000,
+ (date >> 8) & 0xf, bcd2bin(date & 0xff));
+}
diff --git a/arch/sh/boards/mach-sdk7786/irq.c b/arch/sh/boards/mach-sdk7786/irq.c
new file mode 100644
index 00000000000..46943a0da5b
--- /dev/null
+++ b/arch/sh/boards/mach-sdk7786/irq.c
@@ -0,0 +1,48 @@
+/*
+ * SDK7786 FPGA IRQ Controller Support.
+ *
+ * Copyright (C) 2010 Matt Fleming
+ * Copyright (C) 2010 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/irq.h>
+#include <mach/fpga.h>
+#include <mach/irq.h>
+
+enum {
+ ATA_IRQ_BIT = 1,
+ SPI_BUSY_BIT = 2,
+ LIRQ5_BIT = 3,
+ LIRQ6_BIT = 4,
+ LIRQ7_BIT = 5,
+ LIRQ8_BIT = 6,
+ KEY_IRQ_BIT = 7,
+ PEN_IRQ_BIT = 8,
+ ETH_IRQ_BIT = 9,
+ RTC_ALARM_BIT = 10,
+ CRYSTAL_FAIL_BIT = 12,
+ ETH_PME_BIT = 14,
+};
+
+void __init sdk7786_init_irq(void)
+{
+ unsigned int tmp;
+
+ /* Enable priority encoding for all IRLs */
+ fpga_write_reg(fpga_read_reg(INTMSR) | 0x0303, INTMSR);
+
+ /* Clear FPGA interrupt status registers */
+ fpga_write_reg(0x0000, INTASR);
+ fpga_write_reg(0x0000, INTBSR);
+
+ /* Unmask FPGA interrupts */
+ tmp = fpga_read_reg(INTAMR);
+ tmp &= ~(1 << ETH_IRQ_BIT);
+ fpga_write_reg(tmp, INTAMR);
+
+ plat_irq_setup_pins(IRQ_MODE_IRL7654_MASK);
+ plat_irq_setup_pins(IRQ_MODE_IRL3210_MASK);
+}
diff --git a/arch/sh/boards/mach-sdk7786/setup.c b/arch/sh/boards/mach-sdk7786/setup.c
new file mode 100644
index 00000000000..f094ea2ee78
--- /dev/null
+++ b/arch/sh/boards/mach-sdk7786/setup.c
@@ -0,0 +1,189 @@
+/*
+ * Renesas Technology Europe SDK7786 Support.
+ *
+ * Copyright (C) 2010 Matt Fleming
+ * Copyright (C) 2010 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/platform_device.h>
+#include <linux/io.h>
+#include <linux/smsc911x.h>
+#include <linux/i2c.h>
+#include <linux/irq.h>
+#include <linux/clk.h>
+#include <mach/fpga.h>
+#include <mach/irq.h>
+#include <asm/machvec.h>
+#include <asm/heartbeat.h>
+#include <asm/sizes.h>
+#include <asm/reboot.h>
+
+static struct resource heartbeat_resource = {
+ .start = 0x07fff8b0,
+ .end = 0x07fff8b0 + sizeof(u16) - 1,
+ .flags = IORESOURCE_MEM | IORESOURCE_MEM_16BIT,
+};
+
+static struct platform_device heartbeat_device = {
+ .name = "heartbeat",
+ .id = -1,
+ .num_resources = 1,
+ .resource = &heartbeat_resource,
+};
+
+static struct resource smsc911x_resources[] = {
+ [0] = {
+ .name = "smsc911x-memory",
+ .start = 0x07ffff00,
+ .end = 0x07ffff00 + SZ_256 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .name = "smsc911x-irq",
+ .start = evt2irq(0x2c0),
+ .end = evt2irq(0x2c0),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct smsc911x_platform_config smsc911x_config = {
+ .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+ .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN,
+ .flags = SMSC911X_USE_32BIT,
+ .phy_interface = PHY_INTERFACE_MODE_MII,
+};
+
+static struct platform_device smsc911x_device = {
+ .name = "smsc911x",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(smsc911x_resources),
+ .resource = smsc911x_resources,
+ .dev = {
+ .platform_data = &smsc911x_config,
+ },
+};
+
+static struct resource smbus_fpga_resource = {
+ .start = 0x07fff9e0,
+ .end = 0x07fff9e0 + SZ_32 - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device smbus_fpga_device = {
+ .name = "i2c-sdk7786",
+ .id = 0,
+ .num_resources = 1,
+ .resource = &smbus_fpga_resource,
+};
+
+static struct resource smbus_pcie_resource = {
+ .start = 0x07fffc30,
+ .end = 0x07fffc30 + SZ_32 - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device smbus_pcie_device = {
+ .name = "i2c-sdk7786",
+ .id = 1,
+ .num_resources = 1,
+ .resource = &smbus_pcie_resource,
+};
+
+static struct i2c_board_info __initdata sdk7786_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("max6900", 0x68),
+ },
+};
+
+static struct platform_device *sh7786_devices[] __initdata = {
+ &heartbeat_device,
+ &smsc911x_device,
+ &smbus_fpga_device,
+ &smbus_pcie_device,
+};
+
+static int sdk7786_i2c_setup(void)
+{
+ unsigned int tmp;
+
+ /*
+ * Hand over I2C control to the FPGA.
+ */
+ tmp = fpga_read_reg(SBCR);
+ tmp &= ~SCBR_I2CCEN;
+ tmp |= SCBR_I2CMEN;
+ fpga_write_reg(tmp, SBCR);
+
+ return i2c_register_board_info(0, sdk7786_i2c_devices,
+ ARRAY_SIZE(sdk7786_i2c_devices));
+}
+
+static int __init sdk7786_devices_setup(void)
+{
+ int ret;
+
+ ret = platform_add_devices(sh7786_devices, ARRAY_SIZE(sh7786_devices));
+ if (unlikely(ret != 0))
+ return ret;
+
+ return sdk7786_i2c_setup();
+}
+__initcall(sdk7786_devices_setup);
+
+static int sdk7786_mode_pins(void)
+{
+ return fpga_read_reg(MODSWR);
+}
+
+static int sdk7786_clk_init(void)
+{
+ struct clk *clk;
+ int ret;
+
+ /*
+ * Only handle the EXTAL case, anyone interfacing a crystal
+ * resonator will need to provide their own input clock.
+ */
+ if (test_mode_pin(MODE_PIN9))
+ return -EINVAL;
+
+ clk = clk_get(NULL, "extal");
+ if (!clk || IS_ERR(clk))
+ return PTR_ERR(clk);
+ ret = clk_set_rate(clk, 33333333);
+ clk_put(clk);
+
+ return ret;
+}
+
+static void sdk7786_restart(char *cmd)
+{
+ fpga_write_reg(0xa5a5, SRSTR);
+}
+
+/* Initialize the board */
+static void __init sdk7786_setup(char **cmdline_p)
+{
+ pr_info("Renesas Technology Europe SDK7786 support:\n");
+
+ sdk7786_fpga_init();
+
+ pr_info("\tPCB revision:\t%d\n", fpga_read_reg(PCBRR) & 0xf);
+
+ machine_ops.restart = sdk7786_restart;
+}
+
+/*
+ * The Machine Vector
+ */
+static struct sh_machine_vector mv_sdk7786 __initmv = {
+ .mv_name = "SDK7786",
+ .mv_setup = sdk7786_setup,
+ .mv_mode_pins = sdk7786_mode_pins,
+ .mv_clk_init = sdk7786_clk_init,
+ .mv_init_irq = sdk7786_init_irq,
+};
diff --git a/arch/sh/boards/mach-se/7206/io.c b/arch/sh/boards/mach-se/7206/io.c
index 180455642a4..adadc77532e 100644
--- a/arch/sh/boards/mach-se/7206/io.c
+++ b/arch/sh/boards/mach-se/7206/io.c
@@ -16,7 +16,7 @@
static inline void delay(void)
{
- ctrl_inw(0x20000000); /* P2 ROM Area */
+ __raw_readw(0x20000000); /* P2 ROM Area */
}
/* MS7750 requires special versions of in*, out* routines, since
diff --git a/arch/sh/boards/mach-se/7206/irq.c b/arch/sh/boards/mach-se/7206/irq.c
index aef7f052851..8d82175d83a 100644
--- a/arch/sh/boards/mach-se/7206/irq.c
+++ b/arch/sh/boards/mach-se/7206/irq.c
@@ -32,12 +32,12 @@ static void disable_se7206_irq(unsigned int irq)
unsigned short msk0,msk1;
/* Set the priority in IPR to 0 */
- val = ctrl_inw(INTC_IPR01);
+ val = __raw_readw(INTC_IPR01);
val &= mask;
- ctrl_outw(val, INTC_IPR01);
+ __raw_writew(val, INTC_IPR01);
/* FPGA mask set */
- msk0 = ctrl_inw(INTMSK0);
- msk1 = ctrl_inw(INTMSK1);
+ msk0 = __raw_readw(INTMSK0);
+ msk1 = __raw_readw(INTMSK1);
switch (irq) {
case IRQ0_IRQ:
@@ -51,8 +51,8 @@ static void disable_se7206_irq(unsigned int irq)
msk1 |= 0x00ff;
break;
}
- ctrl_outw(msk0, INTMSK0);
- ctrl_outw(msk1, INTMSK1);
+ __raw_writew(msk0, INTMSK0);
+ __raw_writew(msk1, INTMSK1);
}
static void enable_se7206_irq(unsigned int irq)
@@ -62,13 +62,13 @@ static void enable_se7206_irq(unsigned int irq)
unsigned short msk0,msk1;
/* Set priority in IPR back to original value */
- val = ctrl_inw(INTC_IPR01);
+ val = __raw_readw(INTC_IPR01);
val |= value;
- ctrl_outw(val, INTC_IPR01);
+ __raw_writew(val, INTC_IPR01);
/* FPGA mask reset */
- msk0 = ctrl_inw(INTMSK0);
- msk1 = ctrl_inw(INTMSK1);
+ msk0 = __raw_readw(INTMSK0);
+ msk1 = __raw_readw(INTMSK1);
switch (irq) {
case IRQ0_IRQ:
@@ -82,19 +82,20 @@ static void enable_se7206_irq(unsigned int irq)
msk1 &= ~0x00ff;
break;
}
- ctrl_outw(msk0, INTMSK0);
- ctrl_outw(msk1, INTMSK1);
+ __raw_writew(msk0, INTMSK0);
+ __raw_writew(msk1, INTMSK1);
}
static void eoi_se7206_irq(unsigned int irq)
{
unsigned short sts0,sts1;
+ struct irq_desc *desc = irq_to_desc(irq);
- if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+ if (!(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)))
enable_se7206_irq(irq);
/* FPGA isr clear */
- sts0 = ctrl_inw(INTSTS0);
- sts1 = ctrl_inw(INTSTS1);
+ sts0 = __raw_readw(INTSTS0);
+ sts1 = __raw_readw(INTSTS1);
switch (irq) {
case IRQ0_IRQ:
@@ -108,8 +109,8 @@ static void eoi_se7206_irq(unsigned int irq)
sts1 &= ~0x00ff;
break;
}
- ctrl_outw(sts0, INTSTS0);
- ctrl_outw(sts1, INTSTS1);
+ __raw_writew(sts0, INTSTS0);
+ __raw_writew(sts1, INTSTS1);
}
static struct irq_chip se7206_irq_chip __read_mostly = {
@@ -136,11 +137,11 @@ void __init init_se7206_IRQ(void)
make_se7206_irq(IRQ0_IRQ); /* SMC91C111 */
make_se7206_irq(IRQ1_IRQ); /* ATA */
make_se7206_irq(IRQ3_IRQ); /* SLOT / PCM */
- ctrl_outw(inw(INTC_ICR1) | 0x000b ,INTC_ICR1 ) ; /* ICR1 */
+ __raw_writew(inw(INTC_ICR1) | 0x000b ,INTC_ICR1 ) ; /* ICR1 */
/* FPGA System register setup*/
- ctrl_outw(0x0000,INTSTS0); /* Clear INTSTS0 */
- ctrl_outw(0x0000,INTSTS1); /* Clear INTSTS1 */
+ __raw_writew(0x0000,INTSTS0); /* Clear INTSTS0 */
+ __raw_writew(0x0000,INTSTS1); /* Clear INTSTS1 */
/* IRQ0=LAN, IRQ1=ATA, IRQ3=SLT,PCM */
- ctrl_outw(0x0001,INTSEL);
+ __raw_writew(0x0001,INTSEL);
}
diff --git a/arch/sh/boards/mach-se/7206/setup.c b/arch/sh/boards/mach-se/7206/setup.c
index f5466384972..8f5c65d43d1 100644
--- a/arch/sh/boards/mach-se/7206/setup.c
+++ b/arch/sh/boards/mach-se/7206/setup.c
@@ -50,15 +50,12 @@ static unsigned char heartbeat_bit_pos[] = { 8, 9, 10, 11, 12, 13, 14, 15 };
static struct heartbeat_data heartbeat_data = {
.bit_pos = heartbeat_bit_pos,
.nr_bits = ARRAY_SIZE(heartbeat_bit_pos),
- .regsize = 32,
};
-static struct resource heartbeat_resources[] = {
- [0] = {
- .start = PA_LED,
- .end = PA_LED,
- .flags = IORESOURCE_MEM,
- },
+static struct resource heartbeat_resource = {
+ .start = PA_LED,
+ .end = PA_LED,
+ .flags = IORESOURCE_MEM | IORESOURCE_MEM_32BIT,
};
static struct platform_device heartbeat_device = {
@@ -67,8 +64,8 @@ static struct platform_device heartbeat_device = {
.dev = {
.platform_data = &heartbeat_data,
},
- .num_resources = ARRAY_SIZE(heartbeat_resources),
- .resource = heartbeat_resources,
+ .num_resources = 1,
+ .resource = &heartbeat_resource,
};
static struct platform_device *se7206_devices[] __initdata = {
diff --git a/arch/sh/boards/mach-se/7343/irq.c b/arch/sh/boards/mach-se/7343/irq.c
index 051c29d4eae..d4305c26e9f 100644
--- a/arch/sh/boards/mach-se/7343/irq.c
+++ b/arch/sh/boards/mach-se/7343/irq.c
@@ -16,16 +16,18 @@
#include <linux/io.h>
#include <mach-se/mach/se7343.h>
+unsigned int se7343_fpga_irq[SE7343_FPGA_IRQ_NR] = { 0, };
+
static void disable_se7343_irq(unsigned int irq)
{
- unsigned int bit = irq - SE7343_FPGA_IRQ_BASE;
- ctrl_outw(ctrl_inw(PA_CPLD_IMSK) | 1 << bit, PA_CPLD_IMSK);
+ unsigned int bit = (unsigned int)get_irq_chip_data(irq);
+ __raw_writew(__raw_readw(PA_CPLD_IMSK) | 1 << bit, PA_CPLD_IMSK);
}
static void enable_se7343_irq(unsigned int irq)
{
- unsigned int bit = irq - SE7343_FPGA_IRQ_BASE;
- ctrl_outw(ctrl_inw(PA_CPLD_IMSK) & ~(1 << bit), PA_CPLD_IMSK);
+ unsigned int bit = (unsigned int)get_irq_chip_data(irq);
+ __raw_writew(__raw_readw(PA_CPLD_IMSK) & ~(1 << bit), PA_CPLD_IMSK);
}
static struct irq_chip se7343_irq_chip __read_mostly = {
@@ -37,19 +39,16 @@ static struct irq_chip se7343_irq_chip __read_mostly = {
static void se7343_irq_demux(unsigned int irq, struct irq_desc *desc)
{
- unsigned short intv = ctrl_inw(PA_CPLD_ST);
- struct irq_desc *ext_desc;
- unsigned int ext_irq = SE7343_FPGA_IRQ_BASE;
+ unsigned short intv = __raw_readw(PA_CPLD_ST);
+ unsigned int ext_irq = 0;
intv &= (1 << SE7343_FPGA_IRQ_NR) - 1;
- while (intv) {
- if (intv & 1) {
- ext_desc = irq_desc + ext_irq;
- handle_level_irq(ext_irq, ext_desc);
- }
- intv >>= 1;
- ext_irq++;
+ for (; intv; intv >>= 1, ext_irq++) {
+ if (!(intv & 1))
+ continue;
+
+ generic_handle_irq(se7343_fpga_irq[ext_irq]);
}
}
@@ -58,16 +57,24 @@ static void se7343_irq_demux(unsigned int irq, struct irq_desc *desc)
*/
void __init init_7343se_IRQ(void)
{
- int i;
+ int i, irq;
+
+ __raw_writew(0, PA_CPLD_IMSK); /* disable all irqs */
+ __raw_writew(0x2000, 0xb03fffec); /* mrshpc irq enable */
- ctrl_outw(0, PA_CPLD_IMSK); /* disable all irqs */
- ctrl_outw(0x2000, 0xb03fffec); /* mrshpc irq enable */
+ for (i = 0; i < SE7343_FPGA_IRQ_NR; i++) {
+ irq = create_irq();
+ if (irq < 0)
+ return;
+ se7343_fpga_irq[i] = irq;
- for (i = 0; i < SE7343_FPGA_IRQ_NR; i++)
- set_irq_chip_and_handler_name(SE7343_FPGA_IRQ_BASE + i,
+ set_irq_chip_and_handler_name(se7343_fpga_irq[i],
&se7343_irq_chip,
handle_level_irq, "level");
+ set_irq_chip_data(se7343_fpga_irq[i], (void *)i);
+ }
+
set_irq_chained_handler(IRQ0_IRQ, se7343_irq_demux);
set_irq_type(IRQ0_IRQ, IRQ_TYPE_LEVEL_LOW);
set_irq_chained_handler(IRQ1_IRQ, se7343_irq_demux);
diff --git a/arch/sh/boards/mach-se/7343/setup.c b/arch/sh/boards/mach-se/7343/setup.c
index 4de56f35f41..d2370af56d7 100644
--- a/arch/sh/boards/mach-se/7343/setup.c
+++ b/arch/sh/boards/mach-se/7343/setup.c
@@ -11,26 +11,17 @@
#include <asm/irq.h>
#include <asm/io.h>
-static struct resource heartbeat_resources[] = {
- [0] = {
- .start = PA_LED,
- .end = PA_LED,
- .flags = IORESOURCE_MEM,
- },
-};
-
-static struct heartbeat_data heartbeat_data = {
- .regsize = 16,
+static struct resource heartbeat_resource = {
+ .start = PA_LED,
+ .end = PA_LED,
+ .flags = IORESOURCE_MEM | IORESOURCE_MEM_16BIT,
};
static struct platform_device heartbeat_device = {
.name = "heartbeat",
.id = -1,
- .dev = {
- .platform_data = &heartbeat_data,
- },
- .num_resources = ARRAY_SIZE(heartbeat_resources),
- .resource = heartbeat_resources,
+ .num_resources = 1,
+ .resource = &heartbeat_resource,
};
static struct mtd_partition nor_flash_partitions[] = {
@@ -82,7 +73,6 @@ static struct plat_serial8250_port serial_platform_data[] = {
.mapbase = 0x16000000,
.regshift = 1,
.flags = ST16C2550C_FLAGS,
- .irq = UARTA_IRQ,
.uartclk = 7372800,
},
[1] = {
@@ -90,7 +80,6 @@ static struct plat_serial8250_port serial_platform_data[] = {
.mapbase = 0x17000000,
.regshift = 1,
.flags = ST16C2550C_FLAGS,
- .irq = UARTB_IRQ,
.uartclk = 7372800,
},
{ },
@@ -121,7 +110,7 @@ static struct resource usb_resources[] = {
.flags = IORESOURCE_MEM,
},
[2] = {
- .start = USB_IRQ,
+ /* Filled in later */
.flags = IORESOURCE_IRQ,
},
};
@@ -138,8 +127,8 @@ static struct isp116x_platform_data usb_platform_data = {
static struct platform_device usb_device = {
.name = "isp116x-hcd",
.id = -1,
- .num_resources = ARRAY_SIZE(usb_resources),
- .resource = usb_resources,
+ .num_resources = ARRAY_SIZE(usb_resources),
+ .resource = usb_resources,
.dev = {
.platform_data = &usb_platform_data,
},
@@ -155,6 +144,13 @@ static struct platform_device *sh7343se_platform_devices[] __initdata = {
static int __init sh7343se_devices_setup(void)
{
+ /* Wire-up dynamic vectors */
+ serial_platform_data[0].irq = se7343_fpga_irq[SE7343_FPGA_IRQ_UARTA];
+ serial_platform_data[1].irq = se7343_fpga_irq[SE7343_FPGA_IRQ_UARTB];
+
+ usb_resources[2].start = usb_resources[2].end =
+ se7343_fpga_irq[SE7343_FPGA_IRQ_USB];
+
return platform_add_devices(sh7343se_platform_devices,
ARRAY_SIZE(sh7343se_platform_devices));
}
@@ -165,10 +161,10 @@ device_initcall(sh7343se_devices_setup);
*/
static void __init sh7343se_setup(char **cmdline_p)
{
- ctrl_outw(0xf900, FPGA_OUT); /* FPGA */
+ __raw_writew(0xf900, FPGA_OUT); /* FPGA */
- ctrl_outw(0x0002, PORT_PECR); /* PORT E 1 = IRQ5 */
- ctrl_outw(0x0020, PORT_PSELD);
+ __raw_writew(0x0002, PORT_PECR); /* PORT E 1 = IRQ5 */
+ __raw_writew(0x0020, PORT_PSELD);
printk(KERN_INFO "MS7343CP01 Setup...done\n");
}
@@ -179,6 +175,5 @@ static void __init sh7343se_setup(char **cmdline_p)
static struct sh_machine_vector mv_7343se __initmv = {
.mv_name = "SolutionEngine 7343",
.mv_setup = sh7343se_setup,
- .mv_nr_irqs = SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_NR,
.mv_init_irq = init_7343se_IRQ,
};
diff --git a/arch/sh/boards/mach-se/770x/irq.c b/arch/sh/boards/mach-se/770x/irq.c
index ec1fea571b5..1028c17b81b 100644
--- a/arch/sh/boards/mach-se/770x/irq.c
+++ b/arch/sh/boards/mach-se/770x/irq.c
@@ -96,13 +96,13 @@ static struct ipr_desc ipr_irq_desc = {
void __init init_se_IRQ(void)
{
/* Disable all interrupts */
- ctrl_outw(0, BCR_ILCRA);
- ctrl_outw(0, BCR_ILCRB);
- ctrl_outw(0, BCR_ILCRC);
- ctrl_outw(0, BCR_ILCRD);
- ctrl_outw(0, BCR_ILCRE);
- ctrl_outw(0, BCR_ILCRF);
- ctrl_outw(0, BCR_ILCRG);
+ __raw_writew(0, BCR_ILCRA);
+ __raw_writew(0, BCR_ILCRB);
+ __raw_writew(0, BCR_ILCRC);
+ __raw_writew(0, BCR_ILCRD);
+ __raw_writew(0, BCR_ILCRE);
+ __raw_writew(0, BCR_ILCRF);
+ __raw_writew(0, BCR_ILCRG);
register_ipr_controller(&ipr_irq_desc);
}
diff --git a/arch/sh/boards/mach-se/770x/setup.c b/arch/sh/boards/mach-se/770x/setup.c
index 527eb6b1261..66d39d1b090 100644
--- a/arch/sh/boards/mach-se/770x/setup.c
+++ b/arch/sh/boards/mach-se/770x/setup.c
@@ -93,15 +93,12 @@ static unsigned char heartbeat_bit_pos[] = { 8, 9, 10, 11, 12, 13, 14, 15 };
static struct heartbeat_data heartbeat_data = {
.bit_pos = heartbeat_bit_pos,
.nr_bits = ARRAY_SIZE(heartbeat_bit_pos),
- .regsize = 16,
};
-static struct resource heartbeat_resources[] = {
- [0] = {
- .start = PA_LED,
- .end = PA_LED,
- .flags = IORESOURCE_MEM,
- },
+static struct resource heartbeat_resource = {
+ .start = PA_LED,
+ .end = PA_LED,
+ .flags = IORESOURCE_MEM | IORESOURCE_MEM_16BIT,
};
static struct platform_device heartbeat_device = {
@@ -110,8 +107,8 @@ static struct platform_device heartbeat_device = {
.dev = {
.platform_data = &heartbeat_data,
},
- .num_resources = ARRAY_SIZE(heartbeat_resources),
- .resource = heartbeat_resources,
+ .num_resources = 1,
+ .resource = &heartbeat_resource,
};
#if defined(CONFIG_CPU_SUBTYPE_SH7710) ||\
diff --git a/arch/sh/boards/mach-se/7721/irq.c b/arch/sh/boards/mach-se/7721/irq.c
index b417acc4dad..d85022ea3f1 100644
--- a/arch/sh/boards/mach-se/7721/irq.c
+++ b/arch/sh/boards/mach-se/7721/irq.c
@@ -38,7 +38,7 @@ static DECLARE_INTC_DESC(intc_desc, "SE7721", vectors,
void __init init_se7721_IRQ(void)
{
/* PPCR */
- ctrl_outw(ctrl_inw(0xa4050118) & ~0x00ff, 0xa4050118);
+ __raw_writew(__raw_readw(0xa4050118) & ~0x00ff, 0xa4050118);
register_intc_controller(&intc_desc);
intc_set_priority(MRSHPC_IRQ0, 0xf - MRSHPC_IRQ0);
diff --git a/arch/sh/boards/mach-se/7721/setup.c b/arch/sh/boards/mach-se/7721/setup.c
index 55af4c36b43..7416ad7ee53 100644
--- a/arch/sh/boards/mach-se/7721/setup.c
+++ b/arch/sh/boards/mach-se/7721/setup.c
@@ -23,15 +23,12 @@ static unsigned char heartbeat_bit_pos[] = { 8, 9, 10, 11, 12, 13, 14, 15 };
static struct heartbeat_data heartbeat_data = {
.bit_pos = heartbeat_bit_pos,
.nr_bits = ARRAY_SIZE(heartbeat_bit_pos),
- .regsize = 16,
};
-static struct resource heartbeat_resources[] = {
- [0] = {
- .start = PA_LED,
- .end = PA_LED,
- .flags = IORESOURCE_MEM,
- },
+static struct resource heartbeat_resource = {
+ .start = PA_LED,
+ .end = PA_LED,
+ .flags = IORESOURCE_MEM | IORESOURCE_MEM_16BIT,
};
static struct platform_device heartbeat_device = {
@@ -40,8 +37,8 @@ static struct platform_device heartbeat_device = {
.dev = {
.platform_data = &heartbeat_data,
},
- .num_resources = ARRAY_SIZE(heartbeat_resources),
- .resource = heartbeat_resources,
+ .num_resources = 1,
+ .resource = &heartbeat_resource,
};
static struct resource cf_ide_resources[] = {
@@ -83,10 +80,10 @@ device_initcall(se7721_devices_setup);
static void __init se7721_setup(char **cmdline_p)
{
/* for USB */
- ctrl_outw(0x0000, 0xA405010C); /* PGCR */
- ctrl_outw(0x0000, 0xA405010E); /* PHCR */
- ctrl_outw(0x00AA, 0xA4050118); /* PPCR */
- ctrl_outw(0x0000, 0xA4050124); /* PSELA */
+ __raw_writew(0x0000, 0xA405010C); /* PGCR */
+ __raw_writew(0x0000, 0xA405010E); /* PHCR */
+ __raw_writew(0x00AA, 0xA4050118); /* PPCR */
+ __raw_writew(0x0000, 0xA4050124); /* PSELA */
}
/*
diff --git a/arch/sh/boards/mach-se/7722/irq.c b/arch/sh/boards/mach-se/7722/irq.c
index b221b6842b0..61605db04ee 100644
--- a/arch/sh/boards/mach-se/7722/irq.c
+++ b/arch/sh/boards/mach-se/7722/irq.c
@@ -21,13 +21,13 @@ unsigned int se7722_fpga_irq[SE7722_FPGA_IRQ_NR] = { 0, };
static void disable_se7722_irq(unsigned int irq)
{
unsigned int bit = (unsigned int)get_irq_chip_data(irq);
- ctrl_outw(ctrl_inw(IRQ01_MASK) | 1 << bit, IRQ01_MASK);
+ __raw_writew(__raw_readw(IRQ01_MASK) | 1 << bit, IRQ01_MASK);
}
static void enable_se7722_irq(unsigned int irq)
{
unsigned int bit = (unsigned int)get_irq_chip_data(irq);
- ctrl_outw(ctrl_inw(IRQ01_MASK) & ~(1 << bit), IRQ01_MASK);
+ __raw_writew(__raw_readw(IRQ01_MASK) & ~(1 << bit), IRQ01_MASK);
}
static struct irq_chip se7722_irq_chip __read_mostly = {
@@ -39,7 +39,7 @@ static struct irq_chip se7722_irq_chip __read_mostly = {
static void se7722_irq_demux(unsigned int irq, struct irq_desc *desc)
{
- unsigned short intv = ctrl_inw(IRQ01_STS);
+ unsigned short intv = __raw_readw(IRQ01_STS);
unsigned int ext_irq = 0;
intv &= (1 << SE7722_FPGA_IRQ_NR) - 1;
@@ -59,8 +59,8 @@ void __init init_se7722_IRQ(void)
{
int i, irq;
- ctrl_outw(0, IRQ01_MASK); /* disable all irqs */
- ctrl_outw(0x2000, 0xb03fffec); /* mrshpc irq enable */
+ __raw_writew(0, IRQ01_MASK); /* disable all irqs */
+ __raw_writew(0x2000, 0xb03fffec); /* mrshpc irq enable */
for (i = 0; i < SE7722_FPGA_IRQ_NR; i++) {
irq = create_irq();
diff --git a/arch/sh/boards/mach-se/7722/setup.c b/arch/sh/boards/mach-se/7722/setup.c
index b1cb9425b60..80a4e571b31 100644
--- a/arch/sh/boards/mach-se/7722/setup.c
+++ b/arch/sh/boards/mach-se/7722/setup.c
@@ -25,26 +25,17 @@
#include <cpu/sh7722.h>
/* Heartbeat */
-static struct heartbeat_data heartbeat_data = {
- .regsize = 16,
-};
-
-static struct resource heartbeat_resources[] = {
- [0] = {
- .start = PA_LED,
- .end = PA_LED,
- .flags = IORESOURCE_MEM,
- },
+static struct resource heartbeat_resource = {
+ .start = PA_LED,
+ .end = PA_LED,
+ .flags = IORESOURCE_MEM | IORESOURCE_MEM_16BIT,
};
static struct platform_device heartbeat_device = {
.name = "heartbeat",
.id = -1,
- .dev = {
- .platform_data = &heartbeat_data,
- },
- .num_resources = ARRAY_SIZE(heartbeat_resources),
- .resource = heartbeat_resources,
+ .num_resources = 1,
+ .resource = &heartbeat_resource,
};
/* SMC91x */
@@ -165,32 +156,32 @@ device_initcall(se7722_devices_setup);
static void __init se7722_setup(char **cmdline_p)
{
- ctrl_outw(0x010D, FPGA_OUT); /* FPGA */
+ __raw_writew(0x010D, FPGA_OUT); /* FPGA */
- ctrl_outw(0x0000, PORT_PECR); /* PORT E 1 = IRQ5 ,E 0 = BS */
- ctrl_outw(0x1000, PORT_PJCR); /* PORT J 1 = IRQ1,J 0 =IRQ0 */
+ __raw_writew(0x0000, PORT_PECR); /* PORT E 1 = IRQ5 ,E 0 = BS */
+ __raw_writew(0x1000, PORT_PJCR); /* PORT J 1 = IRQ1,J 0 =IRQ0 */
/* LCDC I/O */
- ctrl_outw(0x0020, PORT_PSELD);
+ __raw_writew(0x0020, PORT_PSELD);
/* SIOF1*/
- ctrl_outw(0x0003, PORT_PSELB);
- ctrl_outw(0xe000, PORT_PSELC);
- ctrl_outw(0x0000, PORT_PKCR);
+ __raw_writew(0x0003, PORT_PSELB);
+ __raw_writew(0xe000, PORT_PSELC);
+ __raw_writew(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 */
+ __raw_writew(0x4020, PORT_PHCR);
+ __raw_writew(0x0000, PORT_PLCR);
+ __raw_writew(0x0000, PORT_PMCR);
+ __raw_writew(0x0002, PORT_PRCR);
+ __raw_writew(0x0000, PORT_PXCR); /* LCDC,CS6A */
/* KEYSC */
- ctrl_outw(0x0A10, PORT_PSELA); /* BS,SHHID2 */
- ctrl_outw(0x0000, PORT_PYCR);
- ctrl_outw(0x0000, PORT_PZCR);
- ctrl_outw(ctrl_inw(PORT_HIZCRA) & ~0x4000, PORT_HIZCRA);
- ctrl_outw(ctrl_inw(PORT_HIZCRC) & ~0xc000, PORT_HIZCRC);
+ __raw_writew(0x0A10, PORT_PSELA); /* BS,SHHID2 */
+ __raw_writew(0x0000, PORT_PYCR);
+ __raw_writew(0x0000, PORT_PZCR);
+ __raw_writew(__raw_readw(PORT_HIZCRA) & ~0x4000, PORT_HIZCRA);
+ __raw_writew(__raw_readw(PORT_HIZCRC) & ~0xc000, PORT_HIZCRC);
}
/*
diff --git a/arch/sh/boards/mach-se/7724/irq.c b/arch/sh/boards/mach-se/7724/irq.c
index f76cf3b49f2..0942be2daef 100644
--- a/arch/sh/boards/mach-se/7724/irq.c
+++ b/arch/sh/boards/mach-se/7724/irq.c
@@ -72,14 +72,14 @@ static void disable_se7724_irq(unsigned int irq)
{
struct fpga_irq set = get_fpga_irq(fpga2irq(irq));
unsigned int bit = irq - set.base;
- ctrl_outw(ctrl_inw(set.mraddr) | 0x0001 << bit, set.mraddr);
+ __raw_writew(__raw_readw(set.mraddr) | 0x0001 << bit, set.mraddr);
}
static void enable_se7724_irq(unsigned int irq)
{
struct fpga_irq set = get_fpga_irq(fpga2irq(irq));
unsigned int bit = irq - set.base;
- ctrl_outw(ctrl_inw(set.mraddr) & ~(0x0001 << bit), set.mraddr);
+ __raw_writew(__raw_readw(set.mraddr) & ~(0x0001 << bit), set.mraddr);
}
static struct irq_chip se7724_irq_chip __read_mostly = {
@@ -92,19 +92,16 @@ static struct irq_chip se7724_irq_chip __read_mostly = {
static void se7724_irq_demux(unsigned int irq, struct irq_desc *desc)
{
struct fpga_irq set = get_fpga_irq(irq);
- unsigned short intv = ctrl_inw(set.sraddr);
- struct irq_desc *ext_desc;
+ unsigned short intv = __raw_readw(set.sraddr);
unsigned int ext_irq = set.base;
intv &= set.mask;
- while (intv) {
- if (intv & 0x0001) {
- ext_desc = irq_desc + ext_irq;
- handle_level_irq(ext_irq, ext_desc);
- }
- intv >>= 1;
- ext_irq++;
+ for (; intv; intv >>= 1, ext_irq++) {
+ if (!(intv & 1))
+ continue;
+
+ generic_handle_irq(ext_irq);
}
}
@@ -113,20 +110,39 @@ static void se7724_irq_demux(unsigned int irq, struct irq_desc *desc)
*/
void __init init_se7724_IRQ(void)
{
- int i;
-
- ctrl_outw(0xffff, IRQ0_MR); /* mask all */
- ctrl_outw(0xffff, IRQ1_MR); /* mask all */
- ctrl_outw(0xffff, IRQ2_MR); /* mask all */
- ctrl_outw(0x0000, IRQ0_SR); /* clear irq */
- ctrl_outw(0x0000, IRQ1_SR); /* clear irq */
- ctrl_outw(0x0000, IRQ2_SR); /* clear irq */
- ctrl_outw(0x002a, IRQ_MODE); /* set irq type */
-
- for (i = 0; i < SE7724_FPGA_IRQ_NR; i++)
- set_irq_chip_and_handler_name(SE7724_FPGA_IRQ_BASE + i,
+ int i, nid = cpu_to_node(boot_cpu_data);
+
+ __raw_writew(0xffff, IRQ0_MR); /* mask all */
+ __raw_writew(0xffff, IRQ1_MR); /* mask all */
+ __raw_writew(0xffff, IRQ2_MR); /* mask all */
+ __raw_writew(0x0000, IRQ0_SR); /* clear irq */
+ __raw_writew(0x0000, IRQ1_SR); /* clear irq */
+ __raw_writew(0x0000, IRQ2_SR); /* clear irq */
+ __raw_writew(0x002a, IRQ_MODE); /* set irq type */
+
+ for (i = 0; i < SE7724_FPGA_IRQ_NR; i++) {
+ int irq, wanted;
+
+ wanted = SE7724_FPGA_IRQ_BASE + i;
+
+ irq = create_irq_nr(wanted, nid);
+ if (unlikely(irq == 0)) {
+ pr_err("%s: failed hooking irq %d for FPGA\n",
+ __func__, wanted);
+ return;
+ }
+
+ if (unlikely(irq != wanted)) {
+ pr_err("%s: got irq %d but wanted %d, bailing.\n",
+ __func__, irq, wanted);
+ destroy_irq(irq);
+ return;
+ }
+
+ set_irq_chip_and_handler_name(irq,
&se7724_irq_chip,
handle_level_irq, "level");
+ }
set_irq_chained_handler(IRQ0_IRQ, se7724_irq_demux);
set_irq_type(IRQ0_IRQ, IRQ_TYPE_LEVEL_LOW);
diff --git a/arch/sh/boards/mach-se/7724/sdram.S b/arch/sh/boards/mach-se/7724/sdram.S
index 9040167d502..6fa4734d09c 100644
--- a/arch/sh/boards/mach-se/7724/sdram.S
+++ b/arch/sh/boards/mach-se/7724/sdram.S
@@ -39,6 +39,10 @@ ENTRY(ms7724se_sdram_leave_start)
/* DBSC: put memory in auto-refresh mode */
+ mov.l @(SH_SLEEP_MODE, r5), r0
+ tst #SUSP_SH_RSTANDBY, r0
+ bf resume_rstandby
+
ED 0xFD000040, 0x00000000 /* DBRFPDN0 */
WAIT 1
ED 0xFD000014, 0x00000002 /* DBCMDCNT (PALL) */
@@ -49,4 +53,79 @@ ENTRY(ms7724se_sdram_leave_start)
rts
nop
+resume_rstandby:
+
+ /* CPG: setup clocks before restarting external memory */
+
+ ED 0xA4150024, 0x00004000 /* PLLCR */
+
+ mov.l FRQCRA,r0
+ mov.l @r0,r3
+ mov.l KICK,r1
+ or r1, r3
+ mov.l r3, @r0
+
+ mov.l LSTATS,r0
+ mov #1,r1
+WAIT_LSTATS:
+ mov.l @r0,r3
+ tst r1,r3
+ bf WAIT_LSTATS
+
+ /* DBSC: re-initialize and put in auto-refresh */
+
+ ED 0xFD000108, 0x00000181 /* DBPDCNT0 */
+ ED 0xFD000020, 0x015B0002 /* DBCONF */
+ ED 0xFD000030, 0x03071502 /* DBTR0 */
+ ED 0xFD000034, 0x02020102 /* DBTR1 */
+ ED 0xFD000038, 0x01090405 /* DBTR2 */
+ ED 0xFD00003C, 0x00000002 /* DBTR3 */
+ ED 0xFD000008, 0x00000005 /* DBKIND */
+ ED 0xFD000040, 0x00000001 /* DBRFPDN0 */
+ ED 0xFD000040, 0x00000000 /* DBRFPDN0 */
+ ED 0xFD000018, 0x00000001 /* DBCKECNT */
+
+ mov #100,r0
+WAIT_400NS:
+ dt r0
+ bf WAIT_400NS
+
+ ED 0xFD000014, 0x00000002 /* DBCMDCNT (PALL) */
+ ED 0xFD000060, 0x00020000 /* DBMRCNT (EMR2) */
+ ED 0xFD000060, 0x00030000 /* DBMRCNT (EMR3) */
+ ED 0xFD000060, 0x00010004 /* DBMRCNT (EMR) */
+ ED 0xFD000060, 0x00000532 /* DBMRCNT (MRS) */
+ ED 0xFD000014, 0x00000002 /* DBCMDCNT (PALL) */
+ ED 0xFD000014, 0x00000004 /* DBCMDCNT (REF) */
+ ED 0xFD000014, 0x00000004 /* DBCMDCNT (REF) */
+ ED 0xFD000060, 0x00000432 /* DBMRCNT (MRS) */
+ ED 0xFD000060, 0x000103c0 /* DBMRCNT (EMR) */
+ ED 0xFD000060, 0x00010040 /* DBMRCNT (EMR) */
+
+ mov #100,r0
+WAIT_400NS_2:
+ dt r0
+ bf WAIT_400NS_2
+
+ ED 0xFD000010, 0x00000001 /* DBEN */
+ ED 0xFD000044, 0x0000050f /* DBRFPDN1 */
+ ED 0xFD000048, 0x236800e6 /* DBRFPDN2 */
+
+ mov.l DUMMY,r0
+ mov.l @r0, r1 /* force single dummy read */
+
+ ED 0xFD000014, 0x00000002 /* DBCMDCNT (PALL) */
+ ED 0xFD000014, 0x00000004 /* DBCMDCNT (REF) */
+ ED 0xFD000108, 0x00000080 /* DBPDCNT0 */
+ ED 0xFD000040, 0x00010000 /* DBRFPDN0 */
+
+ rts
+ nop
+
+ .balign 4
+DUMMY: .long 0xac400000
+FRQCRA: .long 0xa4150000
+KICK: .long 0x80000000
+LSTATS: .long 0xa4150060
+
ENTRY(ms7724se_sdram_leave_end)
diff --git a/arch/sh/boards/mach-se/7724/setup.c b/arch/sh/boards/mach-se/7724/setup.c
index 858ecb25d46..66cdbc3c7af 100644
--- a/arch/sh/boards/mach-se/7724/setup.c
+++ b/arch/sh/boards/mach-se/7724/setup.c
@@ -53,26 +53,17 @@
*/
/* Heartbeat */
-static struct heartbeat_data heartbeat_data = {
- .regsize = 16,
-};
-
-static struct resource heartbeat_resources[] = {
- [0] = {
- .start = PA_LED,
- .end = PA_LED,
- .flags = IORESOURCE_MEM,
- },
+static struct resource heartbeat_resource = {
+ .start = PA_LED,
+ .end = PA_LED,
+ .flags = IORESOURCE_MEM | IORESOURCE_MEM_16BIT,
};
static struct platform_device heartbeat_device = {
.name = "heartbeat",
.id = -1,
- .dev = {
- .platform_data = &heartbeat_data,
- },
- .num_resources = ARRAY_SIZE(heartbeat_resources),
- .resource = heartbeat_resources,
+ .num_resources = 1,
+ .resource = &heartbeat_resource,
};
/* LAN91C111 */
@@ -265,12 +256,12 @@ static struct platform_device ceu1_device = {
#define FCLKACR 0xa4150008
static void fsimck_init(struct clk *clk)
{
- u32 status = ctrl_inl(clk->enable_reg);
+ u32 status = __raw_readl(clk->enable_reg);
/* use external clock */
status &= ~0x000000ff;
status |= 0x00000080;
- ctrl_outl(status, clk->enable_reg);
+ __raw_writel(status, clk->enable_reg);
}
static struct clk_ops fsimck_clk_ops = {
@@ -322,7 +313,7 @@ static struct platform_device fsi_device = {
/* KEYSC in SoC (Needs SW33-2 set to ON) */
static struct sh_keysc_info keysc_info = {
.mode = SH_KEYSC_MODE_1,
- .scan_timing = 10,
+ .scan_timing = 3,
.delay = 50,
.keycodes = {
KEY_1, KEY_2, KEY_3, KEY_4, KEY_5,
@@ -460,7 +451,7 @@ static struct resource sdhi0_cn7_resources[] = {
.flags = IORESOURCE_MEM,
},
[1] = {
- .start = 101,
+ .start = 100,
.flags = IORESOURCE_IRQ,
},
};
@@ -483,7 +474,7 @@ static struct resource sdhi1_cn8_resources[] = {
.flags = IORESOURCE_MEM,
},
[1] = {
- .start = 24,
+ .start = 23,
.flags = IORESOURCE_IRQ,
},
};
@@ -498,6 +489,26 @@ static struct platform_device sdhi1_cn8_device = {
},
};
+/* IrDA */
+static struct resource irda_resources[] = {
+ [0] = {
+ .name = "IrDA",
+ .start = 0xA45D0000,
+ .end = 0xA45D0049,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 20,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device irda_device = {
+ .name = "sh_sir",
+ .num_resources = ARRAY_SIZE(irda_resources),
+ .resource = irda_resources,
+};
+
static struct platform_device *ms7724se_devices[] __initdata = {
&heartbeat_device,
&smc91x_eth_device,
@@ -512,6 +523,7 @@ static struct platform_device *ms7724se_devices[] __initdata = {
&fsi_device,
&sdhi0_cn7_device,
&sdhi1_cn8_device,
+ &irda_device,
};
/* I2C device */
@@ -531,7 +543,7 @@ static int __init sh_eth_is_eeprom_ready(void)
int t = 10000;
while (t--) {
- if (!ctrl_inw(EEPROM_STAT))
+ if (!__raw_readw(EEPROM_STAT))
return 1;
udelay(1);
}
@@ -551,13 +563,13 @@ static void __init sh_eth_init(void)
/* read MAC addr from EEPROM */
for (i = 0 ; i < 3 ; i++) {
- ctrl_outw(0x0, EEPROM_OP); /* read */
- ctrl_outw(i*2, EEPROM_ADR);
- ctrl_outw(0x1, EEPROM_STRT);
+ __raw_writew(0x0, EEPROM_OP); /* read */
+ __raw_writew(i*2, EEPROM_ADR);
+ __raw_writew(0x1, EEPROM_STRT);
if (!sh_eth_is_eeprom_ready())
return;
- mac = ctrl_inw(EEPROM_DATA);
+ mac = __raw_readw(EEPROM_DATA);
sh_eth_plat.mac_addr[i << 1] = mac & 0xff;
sh_eth_plat.mac_addr[(i << 1) + 1] = mac >> 8;
}
@@ -594,28 +606,29 @@ arch_initcall(arch_setup);
static int __init devices_setup(void)
{
- u16 sw = ctrl_inw(SW4140); /* select camera, monitor */
- struct clk *fsia_clk;
+ u16 sw = __raw_readw(SW4140); /* select camera, monitor */
+ struct clk *clk;
/* register board specific self-refresh code */
- sh_mobile_register_self_refresh(SUSP_SH_STANDBY | SUSP_SH_SF,
+ sh_mobile_register_self_refresh(SUSP_SH_STANDBY | SUSP_SH_SF |
+ SUSP_SH_RSTANDBY,
&ms7724se_sdram_enter_start,
&ms7724se_sdram_enter_end,
&ms7724se_sdram_leave_start,
&ms7724se_sdram_leave_end);
/* Reset Release */
- ctrl_outw(ctrl_inw(FPGA_OUT) &
+ __raw_writew(__raw_readw(FPGA_OUT) &
~((1 << 1) | /* LAN */
(1 << 6) | /* VIDEO DAC */
(1 << 7) | /* AK4643 */
+ (1 << 8) | /* IrDA */
(1 << 12) | /* USB0 */
(1 << 14)), /* RMII */
FPGA_OUT);
/* turn on USB clocks, use external clock */
- ctrl_outw((ctrl_inw(PORT_MSELCRB) & ~0xc000) | 0x8000, PORT_MSELCRB);
+ __raw_writew((__raw_readw(PORT_MSELCRB) & ~0xc000) | 0x8000, PORT_MSELCRB);
-#ifdef CONFIG_PM
/* Let LED9 show STATUS2 */
gpio_request(GPIO_FN_STATUS2, NULL);
@@ -624,28 +637,12 @@ static int __init devices_setup(void)
/* Lit LED11 show PDSTATUS */
gpio_request(GPIO_FN_PDSTATUS, NULL);
-#else
- /* Lit LED9 */
- gpio_request(GPIO_PTJ6, NULL);
- gpio_direction_output(GPIO_PTJ6, 1);
- gpio_export(GPIO_PTJ6, 0);
-
- /* Lit LED10 */
- gpio_request(GPIO_PTJ5, NULL);
- gpio_direction_output(GPIO_PTJ5, 1);
- gpio_export(GPIO_PTJ5, 0);
-
- /* Lit LED11 */
- gpio_request(GPIO_PTJ7, NULL);
- gpio_direction_output(GPIO_PTJ7, 1);
- gpio_export(GPIO_PTJ7, 0);
-#endif
/* enable USB0 port */
- ctrl_outw(0x0600, 0xa40501d4);
+ __raw_writew(0x0600, 0xa40501d4);
/* enable USB1 port */
- ctrl_outw(0x0600, 0xa4050192);
+ __raw_writew(0x0600, 0xa4050192);
/* enable IRQ 0,1,2 */
gpio_request(GPIO_FN_INTC_IRQ0, NULL);
@@ -693,7 +690,7 @@ static int __init devices_setup(void)
gpio_request(GPIO_FN_LCDVCPWC, NULL);
gpio_request(GPIO_FN_LCDRD, NULL);
gpio_request(GPIO_FN_LCDLCLK, NULL);
- ctrl_outw((ctrl_inw(PORT_HIZA) & ~0x0001), PORT_HIZA);
+ __raw_writew((__raw_readw(PORT_HIZA) & ~0x0001), PORT_HIZA);
/* enable CEU0 */
gpio_request(GPIO_FN_VIO0_D15, NULL);
@@ -764,13 +761,18 @@ static int __init devices_setup(void)
gpio_request(GPIO_FN_CLKAUDIOBO, NULL);
gpio_request(GPIO_FN_FSIIASD, NULL);
+ /* set SPU2 clock to 83.4 MHz */
+ clk = clk_get(NULL, "spu_clk");
+ clk_set_rate(clk, clk_round_rate(clk, 83333333));
+ clk_put(clk);
+
/* change parent of FSI A */
- fsia_clk = clk_get(NULL, "fsia_clk");
+ clk = clk_get(NULL, "fsia_clk");
clk_register(&fsimcka_clk);
- clk_set_parent(fsia_clk, &fsimcka_clk);
- clk_set_rate(fsia_clk, 11000);
+ clk_set_parent(clk, &fsimcka_clk);
+ clk_set_rate(clk, 11000);
clk_set_rate(&fsimcka_clk, 11000);
- clk_put(fsia_clk);
+ clk_put(clk);
/* SDHI0 connected to cn7 */
gpio_request(GPIO_FN_SDHI0CD, NULL);
@@ -792,6 +794,10 @@ static int __init devices_setup(void)
gpio_request(GPIO_FN_SDHI1CMD, NULL);
gpio_request(GPIO_FN_SDHI1CLK, NULL);
+ /* enable IrDA */
+ gpio_request(GPIO_FN_IRDA_OUT, NULL);
+ gpio_request(GPIO_FN_IRDA_IN, NULL);
+
/*
* enable SH-Eth
*
diff --git a/arch/sh/boards/mach-se/7780/irq.c b/arch/sh/boards/mach-se/7780/irq.c
index 121744c0871..d5c9edc172a 100644
--- a/arch/sh/boards/mach-se/7780/irq.c
+++ b/arch/sh/boards/mach-se/7780/irq.c
@@ -24,30 +24,30 @@
void __init init_se7780_IRQ(void)
{
/* enable all interrupt at FPGA */
- ctrl_outw(0, FPGA_INTMSK1);
+ __raw_writew(0, FPGA_INTMSK1);
/* mask SM501 interrupt */
- ctrl_outw((ctrl_inw(FPGA_INTMSK1) | 0x0002), FPGA_INTMSK1);
+ __raw_writew((__raw_readw(FPGA_INTMSK1) | 0x0002), FPGA_INTMSK1);
/* enable all interrupt at FPGA */
- ctrl_outw(0, FPGA_INTMSK2);
+ __raw_writew(0, FPGA_INTMSK2);
/* set FPGA INTSEL register */
/* FPGA + 0x06 */
- ctrl_outw( ((IRQPIN_SM501 << IRQPOS_SM501) |
+ __raw_writew( ((IRQPIN_SM501 << IRQPOS_SM501) |
(IRQPIN_SMC91CX << IRQPOS_SMC91CX)), FPGA_INTSEL1);
/* FPGA + 0x08 */
- ctrl_outw(((IRQPIN_EXTINT4 << IRQPOS_EXTINT4) |
+ __raw_writew(((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);
+ __raw_writew((IRQPIN_PCCPW << IRQPOS_PCCPW), FPGA_INTSEL3);
plat_irq_setup_pins(IRQ_MODE_IRQ); /* install handlers for IRQ0-7 */
/* ICR1: detect low level(for 2ndcut) */
- ctrl_outl(0xAAAA0000, INTC_ICR1);
+ __raw_writel(0xAAAA0000, INTC_ICR1);
/*
* FPGA PCISEL register initialize
@@ -63,6 +63,6 @@ void __init init_se7780_IRQ(void)
* INTD || INTD | INTC | -- | INTA
* -------------------------------------
*/
- ctrl_outw(0x0013, FPGA_PCI_INTSEL1);
- ctrl_outw(0xE402, FPGA_PCI_INTSEL2);
+ __raw_writew(0x0013, FPGA_PCI_INTSEL1);
+ __raw_writew(0xE402, FPGA_PCI_INTSEL2);
}
diff --git a/arch/sh/boards/mach-se/7780/setup.c b/arch/sh/boards/mach-se/7780/setup.c
index 1d3a867e94e..6f7c207138e 100644
--- a/arch/sh/boards/mach-se/7780/setup.c
+++ b/arch/sh/boards/mach-se/7780/setup.c
@@ -17,26 +17,17 @@
#include <asm/heartbeat.h>
/* Heartbeat */
-static struct heartbeat_data heartbeat_data = {
- .regsize = 16,
-};
-
-static struct resource heartbeat_resources[] = {
- [0] = {
- .start = PA_LED,
- .end = PA_LED,
- .flags = IORESOURCE_MEM,
- },
+static struct resource heartbeat_resource = {
+ .start = PA_LED,
+ .end = PA_LED,
+ .flags = IORESOURCE_MEM | IORESOURCE_MEM_16BIT,
};
static struct platform_device heartbeat_device = {
.name = "heartbeat",
.id = -1,
- .dev = {
- .platform_data = &heartbeat_data,
- },
- .num_resources = ARRAY_SIZE(heartbeat_resources),
- .resource = heartbeat_resources,
+ .num_resources = 1,
+ .resource = &heartbeat_resource,
};
/* SMC91x */
@@ -84,14 +75,14 @@ device_initcall(se7780_devices_setup);
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) );
+ __raw_writew( 'S' , PA_LED_DISP + (DISP_SEL0_ADDR << 1) );
+ __raw_writew( 'H' , PA_LED_DISP + (DISP_SEL1_ADDR << 1) );
+ __raw_writew( '-' , PA_LED_DISP + (DISP_SEL2_ADDR << 1) );
+ __raw_writew( 'L' , PA_LED_DISP + (DISP_SEL3_ADDR << 1) );
+ __raw_writew( 'i' , PA_LED_DISP + (DISP_SEL4_ADDR << 1) );
+ __raw_writew( 'n' , PA_LED_DISP + (DISP_SEL5_ADDR << 1) );
+ __raw_writew( 'u' , PA_LED_DISP + (DISP_SEL6_ADDR << 1) );
+ __raw_writew( 'x' , PA_LED_DISP + (DISP_SEL7_ADDR << 1) );
printk(KERN_INFO "Hitachi UL Solutions Engine 7780SE03 support.\n");
@@ -102,15 +93,15 @@ static void __init se7780_setup(char **cmdline_p)
* REQ2/GNT2 -> Serial ATA
* REQ3/GNT3 -> PCI slot
*/
- ctrl_outw(0x0213, FPGA_REQSEL);
+ __raw_writew(0x0213, FPGA_REQSEL);
/* GPIO setting */
- ctrl_outw(0x0000, GPIO_PECR);
- ctrl_outw(ctrl_inw(GPIO_PHCR)&0xfff3, GPIO_PHCR);
- ctrl_outw(0x0c00, GPIO_PMSELR);
+ __raw_writew(0x0000, GPIO_PECR);
+ __raw_writew(__raw_readw(GPIO_PHCR)&0xfff3, GPIO_PHCR);
+ __raw_writew(0x0c00, GPIO_PMSELR);
/* iVDR Power ON */
- ctrl_outw(0x0001, FPGA_IVDRPW);
+ __raw_writew(0x0001, FPGA_IVDRPW);
}
/*
diff --git a/arch/sh/boards/mach-sh03/rtc.c b/arch/sh/boards/mach-sh03/rtc.c
index a8b9f844ab5..1b200990500 100644
--- a/arch/sh/boards/mach-sh03/rtc.c
+++ b/arch/sh/boards/mach-sh03/rtc.c
@@ -44,15 +44,15 @@ unsigned long get_cmos_time(void)
spin_lock(&sh03_rtc_lock);
again:
do {
- sec = (ctrl_inb(RTC_SEC1) & 0xf) + (ctrl_inb(RTC_SEC10) & 0x7) * 10;
- min = (ctrl_inb(RTC_MIN1) & 0xf) + (ctrl_inb(RTC_MIN10) & 0xf) * 10;
- hour = (ctrl_inb(RTC_HOU1) & 0xf) + (ctrl_inb(RTC_HOU10) & 0xf) * 10;
- day = (ctrl_inb(RTC_DAY1) & 0xf) + (ctrl_inb(RTC_DAY10) & 0xf) * 10;
- mon = (ctrl_inb(RTC_MON1) & 0xf) + (ctrl_inb(RTC_MON10) & 0xf) * 10;
- year = (ctrl_inb(RTC_YEA1) & 0xf) + (ctrl_inb(RTC_YEA10) & 0xf) * 10
- + (ctrl_inb(RTC_YEA100 ) & 0xf) * 100
- + (ctrl_inb(RTC_YEA1000) & 0xf) * 1000;
- } while (sec != (ctrl_inb(RTC_SEC1) & 0xf) + (ctrl_inb(RTC_SEC10) & 0x7) * 10);
+ sec = (__raw_readb(RTC_SEC1) & 0xf) + (__raw_readb(RTC_SEC10) & 0x7) * 10;
+ min = (__raw_readb(RTC_MIN1) & 0xf) + (__raw_readb(RTC_MIN10) & 0xf) * 10;
+ hour = (__raw_readb(RTC_HOU1) & 0xf) + (__raw_readb(RTC_HOU10) & 0xf) * 10;
+ day = (__raw_readb(RTC_DAY1) & 0xf) + (__raw_readb(RTC_DAY10) & 0xf) * 10;
+ mon = (__raw_readb(RTC_MON1) & 0xf) + (__raw_readb(RTC_MON10) & 0xf) * 10;
+ year = (__raw_readb(RTC_YEA1) & 0xf) + (__raw_readb(RTC_YEA10) & 0xf) * 10
+ + (__raw_readb(RTC_YEA100 ) & 0xf) * 100
+ + (__raw_readb(RTC_YEA1000) & 0xf) * 1000;
+ } while (sec != (__raw_readb(RTC_SEC1) & 0xf) + (__raw_readb(RTC_SEC10) & 0x7) * 10);
if (year == 0 || mon < 1 || mon > 12 || day > 31 || day < 1 ||
hour > 23 || min > 59 || sec > 59) {
printk(KERN_ERR
@@ -60,16 +60,16 @@ unsigned long get_cmos_time(void)
printk("year=%d, mon=%d, day=%d, hour=%d, min=%d, sec=%d\n",
year, mon, day, hour, min, sec);
- ctrl_outb(0, RTC_SEC1); ctrl_outb(0, RTC_SEC10);
- ctrl_outb(0, RTC_MIN1); ctrl_outb(0, RTC_MIN10);
- ctrl_outb(0, RTC_HOU1); ctrl_outb(0, RTC_HOU10);
- ctrl_outb(6, RTC_WEE1);
- ctrl_outb(1, RTC_DAY1); ctrl_outb(0, RTC_DAY10);
- ctrl_outb(1, RTC_MON1); ctrl_outb(0, RTC_MON10);
- ctrl_outb(0, RTC_YEA1); ctrl_outb(0, RTC_YEA10);
- ctrl_outb(0, RTC_YEA100);
- ctrl_outb(2, RTC_YEA1000);
- ctrl_outb(0, RTC_CTL);
+ __raw_writeb(0, RTC_SEC1); __raw_writeb(0, RTC_SEC10);
+ __raw_writeb(0, RTC_MIN1); __raw_writeb(0, RTC_MIN10);
+ __raw_writeb(0, RTC_HOU1); __raw_writeb(0, RTC_HOU10);
+ __raw_writeb(6, RTC_WEE1);
+ __raw_writeb(1, RTC_DAY1); __raw_writeb(0, RTC_DAY10);
+ __raw_writeb(1, RTC_MON1); __raw_writeb(0, RTC_MON10);
+ __raw_writeb(0, RTC_YEA1); __raw_writeb(0, RTC_YEA10);
+ __raw_writeb(0, RTC_YEA100);
+ __raw_writeb(2, RTC_YEA1000);
+ __raw_writeb(0, RTC_CTL);
goto again;
}
@@ -93,9 +93,9 @@ static int set_rtc_mmss(unsigned long nowtime)
/* gets recalled with irq locally disabled */
spin_lock(&sh03_rtc_lock);
for (i = 0 ; i < 1000000 ; i++) /* may take up to 1 second... */
- if (!(ctrl_inb(RTC_CTL) & RTC_BUSY))
+ if (!(__raw_readb(RTC_CTL) & RTC_BUSY))
break;
- cmos_minutes = (ctrl_inb(RTC_MIN1) & 0xf) + (ctrl_inb(RTC_MIN10) & 0xf) * 10;
+ cmos_minutes = (__raw_readb(RTC_MIN1) & 0xf) + (__raw_readb(RTC_MIN10) & 0xf) * 10;
real_seconds = nowtime % 60;
real_minutes = nowtime / 60;
if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1)
@@ -103,10 +103,10 @@ static int set_rtc_mmss(unsigned long nowtime)
real_minutes %= 60;
if (abs(real_minutes - cmos_minutes) < 30) {
- ctrl_outb(real_seconds % 10, RTC_SEC1);
- ctrl_outb(real_seconds / 10, RTC_SEC10);
- ctrl_outb(real_minutes % 10, RTC_MIN1);
- ctrl_outb(real_minutes / 10, RTC_MIN10);
+ __raw_writeb(real_seconds % 10, RTC_SEC1);
+ __raw_writeb(real_seconds / 10, RTC_SEC10);
+ __raw_writeb(real_minutes % 10, RTC_MIN1);
+ __raw_writeb(real_minutes / 10, RTC_MIN10);
} else {
printk(KERN_WARNING
"set_rtc_mmss: can't update from %d to %d\n",
diff --git a/arch/sh/boards/mach-sh03/setup.c b/arch/sh/boards/mach-sh03/setup.c
index 74cfb4b8b03..af4a0c012a9 100644
--- a/arch/sh/boards/mach-sh03/setup.c
+++ b/arch/sh/boards/mach-sh03/setup.c
@@ -82,7 +82,7 @@ static int __init sh03_devices_setup(void)
/* open I/O area window */
paddrbase = virt_to_phys((void *)PA_AREA5_IO);
prot = PAGE_KERNEL_PCC(1, _PAGE_PCC_IO16);
- cf_ide_base = p3_ioremap(paddrbase, PAGE_SIZE, prot.pgprot);
+ cf_ide_base = ioremap_prot(paddrbase, PAGE_SIZE, pgprot_val(prot));
if (!cf_ide_base) {
printk("allocate_cf_area : can't open CF I/O window!\n");
return -ENOMEM;
diff --git a/arch/sh/boards/mach-sh7763rdp/irq.c b/arch/sh/boards/mach-sh7763rdp/irq.c
index d8ebfa7d8c7..add698c8f2b 100644
--- a/arch/sh/boards/mach-sh7763rdp/irq.c
+++ b/arch/sh/boards/mach-sh7763rdp/irq.c
@@ -28,18 +28,18 @@
void __init init_sh7763rdp_IRQ(void)
{
/* GPIO enabled */
- ctrl_outl(1 << 25, INTC_INT2MSKCR);
+ __raw_writel(1 << 25, INTC_INT2MSKCR);
/* enable GPIO interrupts */
- ctrl_outl((ctrl_inl(INTC_INT2PRI7) & 0xFF00FFFF) | 0x000F0000,
+ __raw_writel((__raw_readl(INTC_INT2PRI7) & 0xFF00FFFF) | 0x000F0000,
INTC_INT2PRI7);
/* USBH enabled */
- ctrl_outl(1 << 17, INTC_INT2MSKCR1);
+ __raw_writel(1 << 17, INTC_INT2MSKCR1);
/* GETHER enabled */
- ctrl_outl(1 << 16, INTC_INT2MSKCR1);
+ __raw_writel(1 << 16, INTC_INT2MSKCR1);
/* DMAC enabled */
- ctrl_outl(1 << 8, INTC_INT2MSKCR);
+ __raw_writel(1 << 8, INTC_INT2MSKCR);
}
diff --git a/arch/sh/boards/mach-sh7763rdp/setup.c b/arch/sh/boards/mach-sh7763rdp/setup.c
index 390534a0b35..f64a6918224 100644
--- a/arch/sh/boards/mach-sh7763rdp/setup.c
+++ b/arch/sh/boards/mach-sh7763rdp/setup.c
@@ -158,50 +158,50 @@ device_initcall(sh7763rdp_devices_setup);
static void __init sh7763rdp_setup(char **cmdline_p)
{
/* Board version check */
- if (ctrl_inw(CPLD_BOARD_ID_ERV_REG) == 0xECB1)
+ if (__raw_readw(CPLD_BOARD_ID_ERV_REG) == 0xECB1)
printk(KERN_INFO "RTE Standard Configuration\n");
else
printk(KERN_INFO "RTA Standard Configuration\n");
/* USB pin select bits (clear bit 5-2 to 0) */
- ctrl_outw((ctrl_inw(PORT_PSEL2) & 0xFFC3), PORT_PSEL2);
+ __raw_writew((__raw_readw(PORT_PSEL2) & 0xFFC3), PORT_PSEL2);
/* USBH setup port I controls to other (clear bits 4-9 to 0) */
- ctrl_outw(ctrl_inw(PORT_PICR) & 0xFC0F, PORT_PICR);
+ __raw_writew(__raw_readw(PORT_PICR) & 0xFC0F, PORT_PICR);
/* Select USB Host controller */
- ctrl_outw(0x00, USB_USBHSC);
+ __raw_writew(0x00, USB_USBHSC);
/* For LCD */
/* set PTJ7-1, bits 15-2 of PJCR to 0 */
- ctrl_outw(ctrl_inw(PORT_PJCR) & 0x0003, PORT_PJCR);
+ __raw_writew(__raw_readw(PORT_PJCR) & 0x0003, PORT_PJCR);
/* set PTI5, bits 11-10 of PICR to 0 */
- ctrl_outw(ctrl_inw(PORT_PICR) & 0xF3FF, PORT_PICR);
- ctrl_outw(0, PORT_PKCR);
- ctrl_outw(0, PORT_PLCR);
+ __raw_writew(__raw_readw(PORT_PICR) & 0xF3FF, PORT_PICR);
+ __raw_writew(0, PORT_PKCR);
+ __raw_writew(0, PORT_PLCR);
/* set PSEL2 bits 14-8, 5-4, of PSEL2 to 0 */
- ctrl_outw((ctrl_inw(PORT_PSEL2) & 0x00C0), PORT_PSEL2);
+ __raw_writew((__raw_readw(PORT_PSEL2) & 0x00C0), PORT_PSEL2);
/* set PSEL3 bits 14-12, 6-4, 2-0 of PSEL3 to 0 */
- ctrl_outw((ctrl_inw(PORT_PSEL3) & 0x0700), PORT_PSEL3);
+ __raw_writew((__raw_readw(PORT_PSEL3) & 0x0700), PORT_PSEL3);
/* For HAC */
/* bit3-0 0100:HAC & SSI1 enable */
- ctrl_outw((ctrl_inw(PORT_PSEL1) & 0xFFF0) | 0x0004, PORT_PSEL1);
+ __raw_writew((__raw_readw(PORT_PSEL1) & 0xFFF0) | 0x0004, PORT_PSEL1);
/* bit14 1:SSI_HAC_CLK enable */
- ctrl_outw(ctrl_inw(PORT_PSEL4) | 0x4000, PORT_PSEL4);
+ __raw_writew(__raw_readw(PORT_PSEL4) | 0x4000, PORT_PSEL4);
/* SH-Ether */
- ctrl_outw((ctrl_inw(PORT_PSEL1) & ~0xff00) | 0x2400, PORT_PSEL1);
- ctrl_outw(0x0, PORT_PFCR);
- ctrl_outw(0x0, PORT_PFCR);
- ctrl_outw(0x0, PORT_PFCR);
+ __raw_writew((__raw_readw(PORT_PSEL1) & ~0xff00) | 0x2400, PORT_PSEL1);
+ __raw_writew(0x0, PORT_PFCR);
+ __raw_writew(0x0, PORT_PFCR);
+ __raw_writew(0x0, PORT_PFCR);
/* MMC */
/*selects SCIF and MMC other functions */
- ctrl_outw(0x0001, PORT_PSEL0);
+ __raw_writew(0x0001, PORT_PSEL0);
/* MMC clock operates */
- ctrl_outl(ctrl_inl(MSTPCR1) & ~0x8, MSTPCR1);
- ctrl_outw(ctrl_inw(PORT_PACR) & ~0x3000, PORT_PACR);
- ctrl_outw(ctrl_inw(PORT_PCCR) & ~0xCFC3, PORT_PCCR);
+ __raw_writel(__raw_readl(MSTPCR1) & ~0x8, MSTPCR1);
+ __raw_writew(__raw_readw(PORT_PACR) & ~0x3000, PORT_PACR);
+ __raw_writew(__raw_readw(PORT_PCCR) & ~0xCFC3, PORT_PCCR);
}
static struct sh_machine_vector mv_sh7763rdp __initmv = {
diff --git a/arch/sh/boards/mach-snapgear/setup.c b/arch/sh/boards/mach-snapgear/setup.c
index a3277a23cf1..331745dee37 100644
--- a/arch/sh/boards/mach-snapgear/setup.c
+++ b/arch/sh/boards/mach-snapgear/setup.c
@@ -30,7 +30,7 @@
static irqreturn_t eraseconfig_interrupt(int irq, void *dev_id)
{
- (void)ctrl_inb(0xb8000000); /* dummy read */
+ (void)__raw_readb(0xb8000000); /* dummy read */
printk("SnapGear: erase switch interrupt!\n");
diff --git a/arch/sh/boards/mach-systemh/irq.c b/arch/sh/boards/mach-systemh/irq.c
index 986a0e71d22..523aea5dc94 100644
--- a/arch/sh/boards/mach-systemh/irq.c
+++ b/arch/sh/boards/mach-systemh/irq.c
@@ -41,13 +41,13 @@ static void disable_systemh_irq(unsigned int irq)
unsigned long val, mask = 0x01 << 1;
/* Clear the "irq"th bit in the mask and set it in the request */
- val = ctrl_inl((unsigned long)systemh_irq_mask_register);
+ val = __raw_readl((unsigned long)systemh_irq_mask_register);
val &= ~mask;
- ctrl_outl(val, (unsigned long)systemh_irq_mask_register);
+ __raw_writel(val, (unsigned long)systemh_irq_mask_register);
- val = ctrl_inl((unsigned long)systemh_irq_request_register);
+ val = __raw_readl((unsigned long)systemh_irq_request_register);
val |= mask;
- ctrl_outl(val, (unsigned long)systemh_irq_request_register);
+ __raw_writel(val, (unsigned long)systemh_irq_request_register);
}
}
@@ -57,9 +57,9 @@ static void enable_systemh_irq(unsigned int irq)
unsigned long val, mask = 0x01 << 1;
/* Set "irq"th bit in the mask register */
- val = ctrl_inl((unsigned long)systemh_irq_mask_register);
+ val = __raw_readl((unsigned long)systemh_irq_mask_register);
val |= mask;
- ctrl_outl(val, (unsigned long)systemh_irq_mask_register);
+ __raw_writel(val, (unsigned long)systemh_irq_mask_register);
}
}
diff --git a/arch/sh/boards/mach-titan/Makefile b/arch/sh/boards/mach-titan/Makefile
deleted file mode 100644
index 08d75370006..00000000000
--- a/arch/sh/boards/mach-titan/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
-#
-# Makefile for the Nimble Microsystems TITAN specific parts of the kernel
-#
-
-obj-y := setup.o io.o
diff --git a/arch/sh/boards/mach-titan/io.c b/arch/sh/boards/mach-titan/io.c
deleted file mode 100644
index 0130e9826ac..00000000000
--- a/arch/sh/boards/mach-titan/io.c
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * I/O routines for Titan
- */
-#include <linux/pci.h>
-#include <asm/machvec.h>
-#include <asm/addrspace.h>
-#include <mach/titan.h>
-#include <asm/io.h>
-
-static inline unsigned int port2adr(unsigned int port)
-{
- maybebadio((unsigned long)port);
- return port;
-}
-
-u8 titan_inb(unsigned long port)
-{
- if (PXSEG(port))
- return ctrl_inb(port);
- return ctrl_inw(port2adr(port)) & 0xff;
-}
-
-u8 titan_inb_p(unsigned long port)
-{
- u8 v;
-
- if (PXSEG(port))
- v = ctrl_inb(port);
- else
- v = ctrl_inw(port2adr(port)) & 0xff;
- ctrl_delay();
- return v;
-}
-
-u16 titan_inw(unsigned long port)
-{
- if (PXSEG(port))
- return ctrl_inw(port);
- else if (port >= 0x2000)
- return ctrl_inw(port2adr(port));
- else
- maybebadio(port);
- return 0;
-}
-
-u32 titan_inl(unsigned long port)
-{
- if (PXSEG(port))
- return ctrl_inl(port);
- else if (port >= 0x2000)
- return ctrl_inw(port2adr(port));
- else
- maybebadio(port);
- return 0;
-}
-
-void titan_outb(u8 value, unsigned long port)
-{
- if (PXSEG(port))
- ctrl_outb(value, port);
- else
- ctrl_outw(value, port2adr(port));
-}
-
-void titan_outb_p(u8 value, unsigned long port)
-{
- if (PXSEG(port))
- ctrl_outb(value, port);
- else
- ctrl_outw(value, port2adr(port));
- ctrl_delay();
-}
-
-void titan_outw(u16 value, unsigned long port)
-{
- if (PXSEG(port))
- ctrl_outw(value, port);
- else if (port >= 0x2000)
- ctrl_outw(value, port2adr(port));
- else
- maybebadio(port);
-}
-
-void titan_outl(u32 value, unsigned long port)
-{
- if (PXSEG(port))
- ctrl_outl(value, port);
- else
- maybebadio(port);
-}
-
-void titan_insl(unsigned long port, void *dst, unsigned long count)
-{
- maybebadio(port);
-}
-
-void titan_outsl(unsigned long port, const void *src, unsigned long count)
-{
- maybebadio(port);
-}
-
-void __iomem *titan_ioport_map(unsigned long port, unsigned int size)
-{
- if (PXSEG(port))
- return (void __iomem *)port;
-
- return (void __iomem *)port2adr(port);
-}
diff --git a/arch/sh/boards/mach-x3proto/ilsel.c b/arch/sh/boards/mach-x3proto/ilsel.c
index b5c673c3933..5c9842704c6 100644
--- a/arch/sh/boards/mach-x3proto/ilsel.c
+++ b/arch/sh/boards/mach-x3proto/ilsel.c
@@ -70,10 +70,10 @@ static void __ilsel_enable(ilsel_source_t set, unsigned int bit)
pr_debug("%s: bit#%d: addr - 0x%08lx (shift %d, set %d)\n",
__func__, bit, addr, shift, set);
- tmp = ctrl_inw(addr);
+ tmp = __raw_readw(addr);
tmp &= ~(0xf << shift);
tmp |= set << shift;
- ctrl_outw(tmp, addr);
+ __raw_writew(tmp, addr);
}
/**
@@ -142,9 +142,9 @@ void ilsel_disable(unsigned int irq)
addr = mk_ilsel_addr(irq);
- tmp = ctrl_inw(addr);
+ tmp = __raw_readw(addr);
tmp &= ~(0xf << mk_ilsel_shift(irq));
- ctrl_outw(tmp, addr);
+ __raw_writew(tmp, addr);
clear_bit(irq, &ilsel_level_map);
}
diff --git a/arch/sh/boards/mach-x3proto/setup.c b/arch/sh/boards/mach-x3proto/setup.c
index efe4cb9f8a7..e284592fd42 100644
--- a/arch/sh/boards/mach-x3proto/setup.c
+++ b/arch/sh/boards/mach-x3proto/setup.c
@@ -149,7 +149,7 @@ static void __init x3proto_init_irq(void)
plat_irq_setup_pins(IRQ_MODE_IRL3210);
/* Set ICR0.LVLMODE */
- ctrl_outl(ctrl_inl(0xfe410000) | (1 << 21), 0xfe410000);
+ __raw_writel(__raw_readl(0xfe410000) | (1 << 21), 0xfe410000);
}
static struct sh_machine_vector mv_x3proto __initmv = {
diff --git a/arch/sh/boot/Makefile b/arch/sh/boot/Makefile
index cb8cf5572e7..1ce63624c9b 100644
--- a/arch/sh/boot/Makefile
+++ b/arch/sh/boot/Makefile
@@ -21,12 +21,15 @@ CONFIG_ZERO_PAGE_OFFSET ?= 0x00001000
CONFIG_ENTRY_OFFSET ?= 0x00001000
suffix-y := bin
-suffix-$(CONFIG_KERNEL_GZIP) := gz
-suffix-$(CONFIG_KERNEL_BZIP2) := bz2
-suffix-$(CONFIG_KERNEL_LZMA) := lzma
-
-targets := zImage vmlinux.srec romImage uImage uImage.srec uImage.gz uImage.bz2 uImage.lzma uImage.bin
-extra-y += vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma
+suffix-$(CONFIG_KERNEL_GZIP) := gz
+suffix-$(CONFIG_KERNEL_BZIP2) := bz2
+suffix-$(CONFIG_KERNEL_LZMA) := lzma
+suffix-$(CONFIG_KERNEL_LZO) := lzo
+
+targets := zImage vmlinux.srec romImage uImage uImage.srec uImage.gz \
+ uImage.bz2 uImage.lzma uImage.lzo uImage.bin
+extra-y += vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma \
+ vmlinux.bin.lzo
subdir- := compressed romimage
$(obj)/zImage: $(obj)/compressed/vmlinux FORCE
@@ -43,15 +46,8 @@ $(obj)/romImage: $(obj)/romimage/vmlinux FORCE
$(obj)/romimage/vmlinux: $(obj)/zImage FORCE
$(Q)$(MAKE) $(build)=$(obj)/romimage $@
-KERNEL_MEMORY := 0x00000000
-ifeq ($(CONFIG_PMB_FIXED),y)
-KERNEL_MEMORY := $(shell /bin/bash -c 'printf "0x%08x" \
+KERNEL_MEMORY := $(shell /bin/bash -c 'printf "0x%08x" \
$$[$(CONFIG_MEMORY_START) & 0x1fffffff]')
-endif
-ifeq ($(CONFIG_29BIT),y)
-KERNEL_MEMORY := $(shell /bin/bash -c 'printf "0x%08x" \
- $$[$(CONFIG_MEMORY_START)]')
-endif
KERNEL_LOAD := $(shell /bin/bash -c 'printf "0x%08x" \
$$[$(CONFIG_PAGE_OFFSET) + \
@@ -80,6 +76,9 @@ $(obj)/vmlinux.bin.bz2: $(obj)/vmlinux.bin FORCE
$(obj)/vmlinux.bin.lzma: $(obj)/vmlinux.bin FORCE
$(call if_changed,lzma)
+$(obj)/vmlinux.bin.lzo: $(obj)/vmlinux.bin FORCE
+ $(call if_changed,lzo)
+
$(obj)/uImage.bz2: $(obj)/vmlinux.bin.bz2
$(call if_changed,uimage,bzip2)
@@ -89,6 +88,9 @@ $(obj)/uImage.gz: $(obj)/vmlinux.bin.gz
$(obj)/uImage.lzma: $(obj)/vmlinux.bin.lzma
$(call if_changed,uimage,lzma)
+$(obj)/uImage.lzo: $(obj)/vmlinux.bin.lzo
+ $(call if_changed,uimage,lzo)
+
$(obj)/uImage.bin: $(obj)/vmlinux.bin
$(call if_changed,uimage,none)
diff --git a/arch/sh/boot/compressed/Makefile b/arch/sh/boot/compressed/Makefile
index 6182eca5180..5d660b90943 100644
--- a/arch/sh/boot/compressed/Makefile
+++ b/arch/sh/boot/compressed/Makefile
@@ -6,14 +6,11 @@
targets := vmlinux vmlinux.bin vmlinux.bin.gz \
vmlinux.bin.bz2 vmlinux.bin.lzma \
+ vmlinux.bin.lzo \
head_$(BITS).o misc.o piggy.o
OBJECTS = $(obj)/head_$(BITS).o $(obj)/misc.o $(obj)/cache.o
-ifdef CONFIG_SH_STANDARD_BIOS
-OBJECTS += $(obj)/../../kernel/sh_bios.o
-endif
-
#
# IMAGE_OFFSET is the load offset of the compression loader
#
@@ -47,6 +44,8 @@ $(obj)/vmlinux.bin.bz2: $(vmlinux.bin.all-y) FORCE
$(call if_changed,bzip2)
$(obj)/vmlinux.bin.lzma: $(vmlinux.bin.all-y) FORCE
$(call if_changed,lzma)
+$(obj)/vmlinux.bin.lzo: $(vmlinux.bin.all-y) FORCE
+ $(call if_changed,lzo)
OBJCOPYFLAGS += -R .empty_zero_page
diff --git a/arch/sh/boot/compressed/misc.c b/arch/sh/boot/compressed/misc.c
index b51b1fc4baa..27140a6b365 100644
--- a/arch/sh/boot/compressed/misc.c
+++ b/arch/sh/boot/compressed/misc.c
@@ -14,7 +14,6 @@
#include <asm/uaccess.h>
#include <asm/addrspace.h>
#include <asm/page.h>
-#include <asm/sh_bios.h>
/*
* gzip declarations
@@ -62,29 +61,15 @@ static unsigned long free_mem_end_ptr;
#include "../../../../lib/decompress_unlzma.c"
#endif
-#ifdef CONFIG_SH_STANDARD_BIOS
-size_t strlen(const char *s)
-{
- int i = 0;
-
- while (*s++)
- i++;
- return i;
-}
+#ifdef CONFIG_KERNEL_LZO
+#include "../../../../lib/decompress_unlzo.c"
+#endif
int puts(const char *s)
{
- int len = strlen(s);
- sh_bios_console_write(s, len);
- return len;
-}
-#else
-int puts(const char *s)
-{
/* This should be updated to use the sh-sci routines */
return 0;
}
-#endif
void* memset(void* s, int c, size_t n)
{
@@ -132,7 +117,7 @@ void decompress_kernel(void)
output_addr = (CONFIG_MEMORY_START + 0x2000);
#else
output_addr = __pa((unsigned long)&_text+PAGE_SIZE);
-#ifdef CONFIG_29BIT
+#if defined(CONFIG_29BIT)
output_addr |= P2SEG;
#endif
#endif
diff --git a/arch/sh/cchips/hd6446x/hd64461.c b/arch/sh/cchips/hd6446x/hd64461.c
index 50aa0c1f76e..bcb31ae84a5 100644
--- a/arch/sh/cchips/hd6446x/hd64461.c
+++ b/arch/sh/cchips/hd6446x/hd64461.c
@@ -55,25 +55,22 @@ static struct irq_chip hd64461_irq_chip = {
static void hd64461_irq_demux(unsigned int irq, struct irq_desc *desc)
{
- unsigned short intv = ctrl_inw(HD64461_NIRR);
- struct irq_desc *ext_desc;
+ unsigned short intv = __raw_readw(HD64461_NIRR);
unsigned int ext_irq = HD64461_IRQBASE;
intv &= (1 << HD64461_IRQ_NUM) - 1;
- while (intv) {
- if (intv & 1) {
- ext_desc = irq_desc + ext_irq;
- handle_level_irq(ext_irq, ext_desc);
- }
- intv >>= 1;
- ext_irq++;
+ for (; intv; intv >>= 1, ext_irq++) {
+ if (!(intv & 1))
+ continue;
+
+ generic_handle_irq(ext_irq);
}
}
int __init setup_hd64461(void)
{
- int i;
+ int i, nid = cpu_to_node(boot_cpu_data);
if (!MACH_HD64461)
return 0;
@@ -90,9 +87,26 @@ int __init setup_hd64461(void)
__raw_writew(0xffff, HD64461_NIMR);
/* IRQ 80 -> 95 belongs to HD64461 */
- for (i = HD64461_IRQBASE; i < HD64461_IRQBASE + 16; i++)
+ for (i = HD64461_IRQBASE; i < HD64461_IRQBASE + 16; i++) {
+ unsigned int irq;
+
+ irq = create_irq_nr(i, nid);
+ if (unlikely(irq == 0)) {
+ pr_err("%s: failed hooking irq %d for HD64461\n",
+ __func__, i);
+ return -EBUSY;
+ }
+
+ if (unlikely(irq != i)) {
+ pr_err("%s: got irq %d but wanted %d, bailing.\n",
+ __func__, irq, i);
+ destroy_irq(irq);
+ return -EINVAL;
+ }
+
set_irq_chip_and_handler(i, &hd64461_irq_chip,
handle_level_irq);
+ }
set_irq_chained_handler(CONFIG_HD64461_IRQ, hd64461_irq_demux);
set_irq_type(CONFIG_HD64461_IRQ, IRQ_TYPE_LEVEL_LOW);
diff --git a/arch/sh/configs/sdk7786_defconfig b/arch/sh/configs/sdk7786_defconfig
new file mode 100644
index 00000000000..9b331eab968
--- /dev/null
+++ b/arch/sh/configs/sdk7786_defconfig
@@ -0,0 +1,1754 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.33-rc7
+# Tue Feb 9 15:27:06 2010
+#
+CONFIG_SUPERH=y
+CONFIG_SUPERH32=y
+# CONFIG_SUPERH64 is not set
+CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_IRQ_PER_CPU=y
+CONFIG_SPARSE_IRQ=y
+# CONFIG_GENERIC_GPIO is not set
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_SYS_SUPPORTS_HUGETLBFS=y
+CONFIG_SYS_SUPPORTS_SMP=y
+CONFIG_SYS_SUPPORTS_NUMA=y
+CONFIG_SYS_SUPPORTS_PCI=y
+CONFIG_SYS_SUPPORTS_TMU=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
+CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
+CONFIG_DMA_COHERENT=y
+# CONFIG_DMA_NONCOHERENT is not set
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_BZIP2=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
+CONFIG_RCU_TRACE=y
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+CONFIG_TREE_RCU_TRACE=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_GROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+CONFIG_RT_GROUP_SCHED=y
+CONFIG_USER_SCHED=y
+# CONFIG_CGROUP_SCHED is not set
+CONFIG_CGROUPS=y
+# CONFIG_CGROUP_DEBUG is not set
+CONFIG_CGROUP_NS=y
+CONFIG_CGROUP_FREEZER=y
+CONFIG_CGROUP_DEVICE=y
+# CONFIG_CPUSETS is not set
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_RESOURCE_COUNTERS=y
+CONFIG_CGROUP_MEM_RES_CTLR=y
+# CONFIG_CGROUP_MEM_RES_CTLR_SWAP is not set
+CONFIG_MM_OWNER=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
+# CONFIG_RELAY is not set
+CONFIG_NAMESPACES=y
+CONFIG_UTS_NS=y
+CONFIG_IPC_NS=y
+CONFIG_USER_NS=y
+CONFIG_PID_NS=y
+CONFIG_NET_NS=y
+# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=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=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_PERF_EVENTS=y
+CONFIG_EVENT_PROFILE=y
+# CONFIG_PERF_COUNTERS is not set
+# CONFIG_DEBUG_PERF_USE_VMALLOC is not set
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+CONFIG_PROFILING=y
+CONFIG_TRACEPOINTS=y
+# CONFIG_OPROFILE is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_HW_BREAKPOINT=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+# CONFIG_LBDAF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+CONFIG_BLK_CGROUP=y
+# CONFIG_DEBUG_BLK_CGROUP is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_CFQ_GROUP_IOSCHED=y
+# CONFIG_DEBUG_CFQ_IOSCHED is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_SPIN_UNLOCK is not set
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_READ_UNLOCK is not set
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_WRITE_UNLOCK is not set
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
+CONFIG_FREEZER=y
+
+#
+# System type
+#
+CONFIG_CPU_SH4=y
+CONFIG_CPU_SH4A=y
+CONFIG_CPU_SHX3=y
+# CONFIG_CPU_SUBTYPE_SH7619 is not set
+# CONFIG_CPU_SUBTYPE_SH7201 is not set
+# CONFIG_CPU_SUBTYPE_SH7203 is not set
+# CONFIG_CPU_SUBTYPE_SH7206 is not set
+# CONFIG_CPU_SUBTYPE_SH7263 is not set
+# CONFIG_CPU_SUBTYPE_MXG is not set
+# CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
+# CONFIG_CPU_SUBTYPE_SH7707 is not set
+# CONFIG_CPU_SUBTYPE_SH7708 is not set
+# CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
+# CONFIG_CPU_SUBTYPE_SH7712 is not set
+# CONFIG_CPU_SUBTYPE_SH7720 is not set
+# CONFIG_CPU_SUBTYPE_SH7721 is not set
+# CONFIG_CPU_SUBTYPE_SH7750 is not set
+# CONFIG_CPU_SUBTYPE_SH7091 is not set
+# CONFIG_CPU_SUBTYPE_SH7750R is not set
+# CONFIG_CPU_SUBTYPE_SH7750S is not set
+# CONFIG_CPU_SUBTYPE_SH7751 is not set
+# CONFIG_CPU_SUBTYPE_SH7751R is not set
+# CONFIG_CPU_SUBTYPE_SH7760 is not set
+# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+# CONFIG_CPU_SUBTYPE_SH7723 is not set
+# CONFIG_CPU_SUBTYPE_SH7724 is not set
+# CONFIG_CPU_SUBTYPE_SH7757 is not set
+# CONFIG_CPU_SUBTYPE_SH7763 is not set
+# CONFIG_CPU_SUBTYPE_SH7770 is not set
+# CONFIG_CPU_SUBTYPE_SH7780 is not set
+# CONFIG_CPU_SUBTYPE_SH7785 is not set
+CONFIG_CPU_SUBTYPE_SH7786=y
+# CONFIG_CPU_SUBTYPE_SHX3 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+# CONFIG_CPU_SUBTYPE_SH7722 is not set
+# CONFIG_CPU_SUBTYPE_SH7366 is not set
+
+#
+# Memory management options
+#
+CONFIG_QUICKLIST=y
+CONFIG_MMU=y
+CONFIG_PAGE_OFFSET=0x80000000
+CONFIG_FORCE_MAX_ZONEORDER=11
+CONFIG_MEMORY_START=0x60000000
+CONFIG_MEMORY_SIZE=0x20000000
+# CONFIG_29BIT is not set
+CONFIG_32BIT=y
+CONFIG_PMB=y
+# CONFIG_PMB_LEGACY is not set
+CONFIG_X2TLB=y
+CONFIG_VSYSCALL=y
+# CONFIG_NUMA is not set
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_DEFAULT=y
+CONFIG_MAX_ACTIVE_REGIONS=1
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_ARCH_MEMORY_PROBE=y
+CONFIG_IOREMAP_FIXED=y
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+# CONFIG_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_HUGETLB_PAGE_SIZE_512MB is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+# CONFIG_FLATMEM_MANUAL is not set
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+CONFIG_SPARSEMEM_MANUAL=y
+CONFIG_SPARSEMEM=y
+CONFIG_HAVE_MEMORY_PRESENT=y
+CONFIG_SPARSEMEM_STATIC=y
+CONFIG_MEMORY_HOTPLUG=y
+CONFIG_MEMORY_HOTPLUG_SPARSE=y
+CONFIG_MEMORY_HOTREMOVE=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_MIGRATION=y
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_NR_QUICK=1
+CONFIG_KSM=y
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+
+#
+# Cache configuration
+#
+CONFIG_CACHE_WRITEBACK=y
+# CONFIG_CACHE_WRITETHROUGH is not set
+# CONFIG_CACHE_OFF is not set
+
+#
+# Processor features
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_CPU_BIG_ENDIAN is not set
+CONFIG_SH_FPU=y
+CONFIG_SH_STORE_QUEUES=y
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_SR_RB=y
+CONFIG_CPU_HAS_PTEAEX=y
+CONFIG_CPU_HAS_FPU=y
+
+#
+# Board support
+#
+CONFIG_SH_SDK7786=y
+# CONFIG_SH_URQUELL is not set
+
+#
+# Timer and clock configuration
+#
+CONFIG_SH_TIMER_TMU=y
+CONFIG_SH_CLK_CPG=y
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+
+#
+# CPU Frequency scaling
+#
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=y
+# CONFIG_CPU_FREQ_DEBUG is not set
+CONFIG_CPU_FREQ_STAT=y
+# CONFIG_CPU_FREQ_STAT_DETAILS is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=m
+CONFIG_CPU_FREQ_GOV_USERSPACE=m
+CONFIG_CPU_FREQ_GOV_ONDEMAND=m
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
+CONFIG_SH_CPU_FREQ=y
+
+#
+# DMA support
+#
+# CONFIG_SH_DMA is not set
+
+#
+# Companion Chips
+#
+
+#
+# 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_SCHED_HRTICK=y
+CONFIG_KEXEC=y
+# CONFIG_CRASH_DUMP is not set
+CONFIG_SECCOMP=y
+# CONFIG_SMP is not set
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_GUSA=y
+
+#
+# Boot options
+#
+CONFIG_ZERO_PAGE_OFFSET=0x00001000
+CONFIG_BOOT_LINK_OFFSET=0x00800000
+CONFIG_ENTRY_OFFSET=0x00001000
+CONFIG_CMDLINE_OVERWRITE=y
+# CONFIG_CMDLINE_EXTEND is not set
+CONFIG_CMDLINE="console=ttySC1,115200 earlyprintk=sh-sci.1,115200 root=/dev/sda1 nmi_debug=state,debounce rootdelay=10"
+
+#
+# Bus options
+#
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCIEPORTBUS=y
+CONFIG_PCIEAER=y
+# CONFIG_PCIE_ECRC is not set
+CONFIG_PCIEAER_INJECT=y
+CONFIG_PCIEASPM=y
+CONFIG_PCIEASPM_DEBUG=y
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCI_LEGACY is not set
+CONFIG_PCI_DEBUG=y
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
+# CONFIG_PCCARD is not set
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
+CONFIG_BINFMT_MISC=y
+
+#
+# Power management options (EXPERIMENTAL)
+#
+CONFIG_PM=y
+CONFIG_PM_DEBUG=y
+CONFIG_PM_VERBOSE=y
+# CONFIG_HIBERNATION is not set
+CONFIG_PM_RUNTIME=y
+CONFIG_CPU_IDLE=y
+CONFIG_CPU_IDLE_GOV_LADDER=y
+CONFIG_CPU_IDLE_GOV_MENU=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+CONFIG_NET_KEY=y
+# CONFIG_NET_KEY_MIGRATE 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=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_LRO is not set
+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_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NET_DROP_MONITOR is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+# CONFIG_MTD is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# 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
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
+# 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=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_BLK_DEV_HD is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT is not set
+# CONFIG_PHANTOM is not set
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
+# CONFIG_ICS932S401 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_HP_ILO is not set
+# CONFIG_ISL29003 is not set
+# CONFIG_DS1682 is not set
+# CONFIG_TI_DAC7512 is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_AT25 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_CB710_CORE is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=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
+# 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
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# 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_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_SCSI_BNX2_ISCSI is not set
+# CONFIG_BE2ISCSI is not set
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_HPSA is not set
+# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_3W_SAS 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_MVSAS 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_MPT2SAS is not set
+# CONFIG_SCSI_HPTIOP is not set
+# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
+# CONFIG_FCOE 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_PMCRAID is not set
+# CONFIG_SCSI_PM8001 is not set
+# CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_BFA_FC is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+CONFIG_ATA=y
+# CONFIG_ATA_NONSTANDARD is not set
+CONFIG_ATA_VERBOSE_ERROR=y
+CONFIG_SATA_PMP=y
+# CONFIG_SATA_AHCI is not set
+CONFIG_SATA_SIL24=y
+CONFIG_ATA_SFF=y
+# 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_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_ATP867X is not set
+# CONFIG_PATA_ATIIXP is not set
+# CONFIG_PATA_CMD640_PCI 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_NINJA32 is not set
+# CONFIG_PATA_NS87410 is not set
+# CONFIG_PATA_NS87415 is not set
+# CONFIG_PATA_OPTI is not set
+# CONFIG_PATA_OPTIDMA is not set
+# CONFIG_PATA_PDC2027X is not set
+# CONFIG_PATA_PDC_OLD is not set
+# CONFIG_PATA_RADISYS is not set
+# CONFIG_PATA_RDC is not set
+# CONFIG_PATA_RZ1000 is not set
+# CONFIG_PATA_SC1200 is not set
+# CONFIG_PATA_SERVERWORKS is not set
+# CONFIG_PATA_SIL680 is not set
+# CONFIG_PATA_SIS is not set
+# CONFIG_PATA_TOSHIBA is not set
+# CONFIG_PATA_VIA is not set
+# CONFIG_PATA_WINBOND is not set
+CONFIG_PATA_PLATFORM=y
+# CONFIG_PATA_SCH is not set
+# CONFIG_MD is not set
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# You can enable one or both FireWire driver stacks.
+#
+
+#
+# The newer stack is recommended.
+#
+# CONFIG_FIREWIRE is not set
+# CONFIG_IEEE1394 is not set
+# CONFIG_I2O is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_ARCNET is not set
+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 is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_FIXED_PHY is not set
+CONFIG_MDIO_BITBANG=y
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_AX88796 is not set
+# 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
+# CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMC911X is not set
+CONFIG_SMSC911X=y
+# CONFIG_DNET is not set
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851 is not set
+# CONFIG_KS8851_MLL is not set
+# CONFIG_ATL2 is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_TR is not set
+CONFIG_WLAN=y
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_HOSTAP is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# 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_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ADP5588 is not set
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_QT2160 is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_MAX7359 is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_SH_KEYSC is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_PS2_ALPS=y
+CONFIG_MOUSE_PS2_LOGIPS2PP=y
+CONFIG_MOUSE_PS2_SYNAPTICS=y
+CONFIG_MOUSE_PS2_TRACKPOINT=y
+# CONFIG_MOUSE_PS2_ELANTECH is not set
+# CONFIG_MOUSE_PS2_SENTELIC is not set
+# CONFIG_MOUSE_PS2_TOUCHKIT is not set
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_APPLETOUCH is not set
+# CONFIG_MOUSE_BCM5974 is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_MOUSE_SYNAPTICS_I2C is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_SERIO_ALTERA_PS2 is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_NOZOMI is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_MAX3100 is not set
+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_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_DEVPORT=y
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+# CONFIG_I2C_COMPAT is not set
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# PC SMBus host controller drivers
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+# CONFIG_I2C_AMD8111 is not set
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_ISCH is not set
+# CONFIG_I2C_PIIX4 is not set
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_DESIGNWARE is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_SH_MOBILE is not set
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+CONFIG_SPI=y
+# CONFIG_SPI_DEBUG is not set
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+# CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_SH_MSIOF is not set
+# CONFIG_SPI_SH_SCI is not set
+# CONFIG_SPI_XILINX is not set
+# CONFIG_SPI_DESIGNWARE is not set
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_ALIM7101_WDT is not set
+# CONFIG_SH_WDT is not set
+
+#
+# PCI-based Watchdog Cards
+#
+# CONFIG_PCIPCWATCHDOG is not set
+# CONFIG_WDTPCI is not set
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_SH_MOBILE_SDHI is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_MC13783 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_EZX_PCAP is not set
+# CONFIG_MFD_88PM8607 is not set
+# CONFIG_AB4500_CORE is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+CONFIG_VGA_ARB=y
+# CONFIG_DRM is not set
+# CONFIG_VGASTATE is not set
+CONFIG_VIDEO_OUTPUT_CONTROL=m
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_SOUND is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+# CONFIG_HID_PID is not set
+# CONFIG_USB_HIDDEV is not set
+
+#
+# Special HID drivers
+#
+# CONFIG_HID_A4TECH is not set
+# CONFIG_HID_APPLE is not set
+# CONFIG_HID_BELKIN is not set
+# CONFIG_HID_CHERRY is not set
+# CONFIG_HID_CHICONY is not set
+# CONFIG_HID_CYPRESS is not set
+# CONFIG_HID_DRAGONRISE is not set
+# CONFIG_HID_EZKEY is not set
+# CONFIG_HID_KYE is not set
+# CONFIG_HID_GYRATION is not set
+# CONFIG_HID_TWINHAN is not set
+# CONFIG_HID_KENSINGTON is not set
+# CONFIG_HID_LOGITECH is not set
+# CONFIG_HID_MICROSOFT is not set
+# CONFIG_HID_MONTEREY is not set
+# CONFIG_HID_NTRIG is not set
+# CONFIG_HID_PANTHERLORD is not set
+# CONFIG_HID_PETALYNX is not set
+# CONFIG_HID_SAMSUNG is not set
+# CONFIG_HID_SONY is not set
+# CONFIG_HID_SUNPLUS is not set
+# CONFIG_HID_GREENASIA is not set
+# CONFIG_HID_SMARTJOYPLUS is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_HID_THRUSTMASTER is not set
+# CONFIG_HID_ZEROPLUS is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEVICEFS is not set
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_SUSPEND is not set
+# CONFIG_USB_OTG is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+CONFIG_USB_MON=y
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_XHCI_HCD is not set
+# CONFIG_USB_EHCI_HCD is not set
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_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
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_WHCI_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+# CONFIG_USB_GADGET_MUSB_HDRC is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# also be needed; see USB_STORAGE Help for more info
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER 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_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
+CONFIG_USB_GADGET=y
+# CONFIG_USB_GADGET_DEBUG is not set
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+# CONFIG_USB_GADGET_DEBUG_FS is not set
+CONFIG_USB_GADGET_VBUS_DRAW=2
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_AT91 is not set
+# CONFIG_USB_GADGET_ATMEL_USBA is not set
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+# CONFIG_USB_GADGET_PXA25X is not set
+# CONFIG_USB_GADGET_R8A66597 is not set
+# CONFIG_USB_GADGET_PXA27X is not set
+# CONFIG_USB_GADGET_S3C_HSOTG is not set
+# CONFIG_USB_GADGET_IMX is not set
+# CONFIG_USB_GADGET_S3C2410 is not set
+CONFIG_USB_GADGET_M66592=y
+CONFIG_USB_M66592=y
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_FSL_QE is not set
+# CONFIG_USB_GADGET_CI13XXX is not set
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LANGWELL is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+CONFIG_USB_GADGET_DUALSPEED=y
+# CONFIG_USB_ZERO is not set
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_ETH is not set
+# CONFIG_USB_GADGETFS is not set
+# CONFIG_USB_FILE_STORAGE is not set
+# CONFIG_USB_MASS_STORAGE is not set
+# CONFIG_USB_G_SERIAL is not set
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_PRINTER is not set
+# CONFIG_USB_CDC_COMPOSITE is not set
+# CONFIG_USB_G_MULTI is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_NOP_USB_XCEIV is not set
+# CONFIG_UWB is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_INFINIBAND is not set
+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
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+CONFIG_RTC_DRV_MAX6900=y
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+CONFIG_RTC_DRV_SH=y
+# CONFIG_RTC_DRV_GENERIC is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+CONFIG_UIO=m
+# CONFIG_UIO_CIF is not set
+# CONFIG_UIO_PDRV is not set
+# CONFIG_UIO_PDRV_GENIRQ is not set
+# CONFIG_UIO_SMX is not set
+# CONFIG_UIO_AEC is not set
+# CONFIG_UIO_SERCOS3 is not set
+# CONFIG_UIO_PCI_GENERIC is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# 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_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4_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_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+CONFIG_HUGETLBFS=y
+CONFIG_HUGETLB_PAGE=y
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# 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_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# 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
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+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
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_PRINTK_TIME=y
+CONFIG_ENABLE_WARN_DEPRECATED=y
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_SHIRQ=y
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_SLAB is not set
+CONFIG_DEBUG_PREEMPT=y
+# 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_LOCK_STAT is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+CONFIG_STACKTRACE=y
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_INFO is not set
+CONFIG_DEBUG_VM=y
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_NOP_TRACER=y
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
+CONFIG_RING_BUFFER=y
+CONFIG_EVENT_TRACING=y
+CONFIG_CONTEXT_SWITCH_TRACER=y
+CONFIG_TRACING=y
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_PREEMPT_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
+# CONFIG_FTRACE_SYSCALLS is not set
+# CONFIG_BOOT_TRACER is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+CONFIG_KSYM_TRACER=y
+# CONFIG_PROFILE_KSYM_TRACER is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_RING_BUFFER_BENCHMARK is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_DMA_API_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+# CONFIG_SH_STANDARD_BIOS is not set
+# CONFIG_STACK_DEBUG is not set
+CONFIG_DEBUG_STACK_USAGE=y
+# CONFIG_4KSTACKS is not set
+CONFIG_DUMP_CODE=y
+CONFIG_DWARF_UNWINDER=y
+# CONFIG_SH_NO_BSS_INIT is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_MANAGER is not set
+# CONFIG_CRYPTO_MANAGER2 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+# CONFIG_CRYPTO_CBC is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_HW=y
+# CONFIG_CRYPTO_DEV_HIFN_795X is not set
+CONFIG_BINARY_PRINTF=y
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_HAVE_LMB=y
+CONFIG_NLATTR=y
+CONFIG_GENERIC_ATOMIC64=y
diff --git a/arch/sh/drivers/dma/dma-pvr2.c b/arch/sh/drivers/dma/dma-pvr2.c
index 391cbe1c295..3cee58e7f1e 100644
--- a/arch/sh/drivers/dma/dma-pvr2.c
+++ b/arch/sh/drivers/dma/dma-pvr2.c
@@ -40,10 +40,10 @@ static irqreturn_t pvr2_dma_interrupt(int irq, void *dev_id)
static int pvr2_request_dma(struct dma_channel *chan)
{
- if (ctrl_inl(PVR2_DMA_MODE) != 0)
+ if (__raw_readl(PVR2_DMA_MODE) != 0)
return -EBUSY;
- ctrl_outl(0, PVR2_DMA_LMMODE0);
+ __raw_writel(0, PVR2_DMA_LMMODE0);
return 0;
}
@@ -60,9 +60,9 @@ static int pvr2_xfer_dma(struct dma_channel *chan)
xfer_complete = 0;
- ctrl_outl(chan->dar, PVR2_DMA_ADDR);
- ctrl_outl(chan->count, PVR2_DMA_COUNT);
- ctrl_outl(chan->mode & DMA_MODE_MASK, PVR2_DMA_MODE);
+ __raw_writel(chan->dar, PVR2_DMA_ADDR);
+ __raw_writel(chan->count, PVR2_DMA_COUNT);
+ __raw_writel(chan->mode & DMA_MODE_MASK, PVR2_DMA_MODE);
return 0;
}
diff --git a/arch/sh/drivers/dma/dma-sh.c b/arch/sh/drivers/dma/dma-sh.c
index 37fb5b8bbc3..827208781ed 100644
--- a/arch/sh/drivers/dma/dma-sh.c
+++ b/arch/sh/drivers/dma/dma-sh.c
@@ -52,11 +52,14 @@ static inline unsigned int get_dmte_irq(unsigned int chan)
*
* iterations to complete the transfer.
*/
+static unsigned int ts_shift[] = TS_SHIFT;
static inline unsigned int calc_xmit_shift(struct dma_channel *chan)
{
- u32 chcr = ctrl_inl(dma_base_addr[chan->chan] + CHCR);
+ u32 chcr = __raw_readl(dma_base_addr[chan->chan] + CHCR);
+ int cnt = ((chcr & CHCR_TS_LOW_MASK) >> CHCR_TS_LOW_SHIFT) |
+ ((chcr & CHCR_TS_HIGH_MASK) >> CHCR_TS_HIGH_SHIFT);
- return ts_shift[(chcr & CHCR_TS_MASK)>>CHCR_TS_SHIFT];
+ return ts_shift[cnt];
}
/*
@@ -70,13 +73,13 @@ static irqreturn_t dma_tei(int irq, void *dev_id)
struct dma_channel *chan = dev_id;
u32 chcr;
- chcr = ctrl_inl(dma_base_addr[chan->chan] + CHCR);
+ chcr = __raw_readl(dma_base_addr[chan->chan] + CHCR);
if (!(chcr & CHCR_TE))
return IRQ_NONE;
chcr &= ~(CHCR_IE | CHCR_DE);
- ctrl_outl(chcr, (dma_base_addr[chan->chan] + CHCR));
+ __raw_writel(chcr, (dma_base_addr[chan->chan] + CHCR));
wake_up(&chan->wait_queue);
@@ -115,7 +118,7 @@ sh_dmac_configure_channel(struct dma_channel *chan, unsigned long chcr)
chan->flags &= ~DMA_TEI_CAPABLE;
}
- ctrl_outl(chcr, (dma_base_addr[chan->chan] + CHCR));
+ __raw_writel(chcr, (dma_base_addr[chan->chan] + CHCR));
chan->flags |= DMA_CONFIGURED;
return 0;
@@ -126,13 +129,13 @@ static void sh_dmac_enable_dma(struct dma_channel *chan)
int irq;
u32 chcr;
- chcr = ctrl_inl(dma_base_addr[chan->chan] + CHCR);
+ chcr = __raw_readl(dma_base_addr[chan->chan] + CHCR);
chcr |= CHCR_DE;
if (chan->flags & DMA_TEI_CAPABLE)
chcr |= CHCR_IE;
- ctrl_outl(chcr, (dma_base_addr[chan->chan] + CHCR));
+ __raw_writel(chcr, (dma_base_addr[chan->chan] + CHCR));
if (chan->flags & DMA_TEI_CAPABLE) {
irq = get_dmte_irq(chan->chan);
@@ -150,9 +153,9 @@ static void sh_dmac_disable_dma(struct dma_channel *chan)
disable_irq(irq);
}
- chcr = ctrl_inl(dma_base_addr[chan->chan] + CHCR);
+ chcr = __raw_readl(dma_base_addr[chan->chan] + CHCR);
chcr &= ~(CHCR_DE | CHCR_TE | CHCR_IE);
- ctrl_outl(chcr, (dma_base_addr[chan->chan] + CHCR));
+ __raw_writel(chcr, (dma_base_addr[chan->chan] + CHCR));
}
static int sh_dmac_xfer_dma(struct dma_channel *chan)
@@ -183,12 +186,12 @@ static int sh_dmac_xfer_dma(struct dma_channel *chan)
*/
if (chan->sar || (mach_is_dreamcast() &&
chan->chan == PVR2_CASCADE_CHAN))
- ctrl_outl(chan->sar, (dma_base_addr[chan->chan]+SAR));
+ __raw_writel(chan->sar, (dma_base_addr[chan->chan]+SAR));
if (chan->dar || (mach_is_dreamcast() &&
chan->chan == PVR2_CASCADE_CHAN))
- ctrl_outl(chan->dar, (dma_base_addr[chan->chan] + DAR));
+ __raw_writel(chan->dar, (dma_base_addr[chan->chan] + DAR));
- ctrl_outl(chan->count >> calc_xmit_shift(chan),
+ __raw_writel(chan->count >> calc_xmit_shift(chan),
(dma_base_addr[chan->chan] + TCR));
sh_dmac_enable_dma(chan);
@@ -198,10 +201,10 @@ static int sh_dmac_xfer_dma(struct dma_channel *chan)
static int sh_dmac_get_dma_residue(struct dma_channel *chan)
{
- if (!(ctrl_inl(dma_base_addr[chan->chan] + CHCR) & CHCR_DE))
+ if (!(__raw_readl(dma_base_addr[chan->chan] + CHCR) & CHCR_DE))
return 0;
- return ctrl_inl(dma_base_addr[chan->chan] + TCR)
+ return __raw_readl(dma_base_addr[chan->chan] + TCR)
<< calc_xmit_shift(chan);
}
diff --git a/arch/sh/drivers/dma/dmabrg.c b/arch/sh/drivers/dma/dmabrg.c
index 5e22689c2fc..72622e30761 100644
--- a/arch/sh/drivers/dma/dmabrg.c
+++ b/arch/sh/drivers/dma/dmabrg.c
@@ -86,8 +86,8 @@ static irqreturn_t dmabrg_irq(int irq, void *data)
unsigned long dcr;
unsigned int i;
- dcr = ctrl_inl(DMABRGCR);
- ctrl_outl(dcr & ~0x00ff0003, DMABRGCR); /* ack all */
+ dcr = __raw_readl(DMABRGCR);
+ __raw_writel(dcr & ~0x00ff0003, DMABRGCR); /* ack all */
dcr &= dcr >> 8; /* ignore masked */
/* USB stuff, get it out of the way first */
@@ -109,17 +109,17 @@ static irqreturn_t dmabrg_irq(int irq, void *data)
static void dmabrg_disable_irq(unsigned int dmairq)
{
unsigned long dcr;
- dcr = ctrl_inl(DMABRGCR);
+ dcr = __raw_readl(DMABRGCR);
dcr &= ~(1 << ((dmairq > 1) ? dmairq + 22 : dmairq + 8));
- ctrl_outl(dcr, DMABRGCR);
+ __raw_writel(dcr, DMABRGCR);
}
static void dmabrg_enable_irq(unsigned int dmairq)
{
unsigned long dcr;
- dcr = ctrl_inl(DMABRGCR);
+ dcr = __raw_readl(DMABRGCR);
dcr |= (1 << ((dmairq > 1) ? dmairq + 22 : dmairq + 8));
- ctrl_outl(dcr, DMABRGCR);
+ __raw_writel(dcr, DMABRGCR);
}
int dmabrg_request_irq(unsigned int dmairq, void(*handler)(void*),
@@ -165,13 +165,13 @@ static int __init dmabrg_init(void)
printk(KERN_INFO "DMABRG: DMAC ch0 not reserved!\n");
#endif
- ctrl_outl(0, DMABRGCR);
- ctrl_outl(0, DMACHCR0);
- ctrl_outl(0x94000000, DMARSRA); /* enable DMABRG in DMAC 0 */
+ __raw_writel(0, DMABRGCR);
+ __raw_writel(0, DMACHCR0);
+ __raw_writel(0x94000000, DMARSRA); /* enable DMABRG in DMAC 0 */
/* enable DMABRG mode, enable the DMAC */
- or = ctrl_inl(DMAOR);
- ctrl_outl(or | DMAOR_BRG | DMAOR_DMEN, DMAOR);
+ or = __raw_readl(DMAOR);
+ __raw_writel(or | DMAOR_BRG | DMAOR_DMEN, DMAOR);
ret = request_irq(DMABRGI0, dmabrg_irq, IRQF_DISABLED,
"DMABRG USB address error", NULL);
diff --git a/arch/sh/drivers/heartbeat.c b/arch/sh/drivers/heartbeat.c
index a9339a6174f..2acbc793032 100644
--- a/arch/sh/drivers/heartbeat.c
+++ b/arch/sh/drivers/heartbeat.c
@@ -1,7 +1,7 @@
/*
* Generic heartbeat driver for regular LED banks
*
- * Copyright (C) 2007 Paul Mundt
+ * Copyright (C) 2007 - 2010 Paul Mundt
*
* Most SH reference boards include a number of individual LEDs that can
* be independently controlled (either via a pre-defined hardware
@@ -27,7 +27,7 @@
#include <asm/heartbeat.h>
#define DRV_NAME "heartbeat"
-#define DRV_VERSION "0.1.1"
+#define DRV_VERSION "0.1.2"
static unsigned char default_bit_pos[] = { 0, 1, 2, 3, 4, 5, 6, 7 };
@@ -98,7 +98,7 @@ static int heartbeat_drv_probe(struct platform_device *pdev)
return -ENOMEM;
}
- hd->base = ioremap_nocache(res->start, res->end - res->start + 1);
+ hd->base = ioremap_nocache(res->start, resource_size(res));
if (unlikely(!hd->base)) {
dev_err(&pdev->dev, "ioremap failed\n");
@@ -117,8 +117,20 @@ static int heartbeat_drv_probe(struct platform_device *pdev)
for (i = 0; i < hd->nr_bits; i++)
hd->mask |= (1 << hd->bit_pos[i]);
- if (!hd->regsize)
- hd->regsize = 8; /* default access size */
+ if (!hd->regsize) {
+ switch (res->flags & IORESOURCE_MEM_TYPE_MASK) {
+ case IORESOURCE_MEM_32BIT:
+ hd->regsize = 32;
+ break;
+ case IORESOURCE_MEM_16BIT:
+ hd->regsize = 16;
+ break;
+ case IORESOURCE_MEM_8BIT:
+ default:
+ hd->regsize = 8;
+ break;
+ }
+ }
setup_timer(&hd->timer, heartbeat_timer, (unsigned long)hd);
platform_set_drvdata(pdev, hd);
diff --git a/arch/sh/drivers/pci/Makefile b/arch/sh/drivers/pci/Makefile
index 08af1f45975..4a59e689087 100644
--- a/arch/sh/drivers/pci/Makefile
+++ b/arch/sh/drivers/pci/Makefile
@@ -1,14 +1,14 @@
#
# Makefile for the PCI specific kernel interface routines under Linux.
#
-obj-y += pci.o
+obj-y += common.o pci.o
obj-$(CONFIG_CPU_SUBTYPE_SH7751) += pci-sh7751.o ops-sh4.o
obj-$(CONFIG_CPU_SUBTYPE_SH7751R) += pci-sh7751.o ops-sh4.o
obj-$(CONFIG_CPU_SUBTYPE_SH7763) += pci-sh7780.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_CPU_SUBTYPE_SH7786) += ops-sh7786.o
+obj-$(CONFIG_CPU_SUBTYPE_SH7786) += pcie-sh7786.o ops-sh7786.o
obj-$(CONFIG_CPU_SH5) += pci-sh5.o ops-sh5.o
obj-$(CONFIG_SH_DREAMCAST) += ops-dreamcast.o fixups-dreamcast.o \
@@ -25,4 +25,3 @@ obj-$(CONFIG_SH_TITAN) += fixups-titan.o
obj-$(CONFIG_SH_LANDISK) += fixups-landisk.o
obj-$(CONFIG_SH_LBOX_RE2) += fixups-rts7751r2d.o
obj-$(CONFIG_SH_CAYMAN) += fixups-cayman.o
-obj-$(CONFIG_SH_URQUELL) += pcie-sh7786.o
diff --git a/arch/sh/drivers/pci/common.c b/arch/sh/drivers/pci/common.c
new file mode 100644
index 00000000000..dbf13819987
--- /dev/null
+++ b/arch/sh/drivers/pci/common.c
@@ -0,0 +1,162 @@
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/timer.h>
+#include <linux/kernel.h>
+
+/*
+ * These functions are used early on before PCI scanning is done
+ * and all of the pci_dev and pci_bus structures have been created.
+ */
+static struct pci_dev *fake_pci_dev(struct pci_channel *hose,
+ int top_bus, int busnr, int devfn)
+{
+ static struct pci_dev dev;
+ static struct pci_bus bus;
+
+ dev.bus = &bus;
+ dev.sysdata = hose;
+ dev.devfn = devfn;
+ bus.number = busnr;
+ bus.sysdata = hose;
+ bus.ops = hose->pci_ops;
+
+ if(busnr != top_bus)
+ /* Fake a parent bus structure. */
+ bus.parent = &bus;
+ else
+ bus.parent = NULL;
+
+ return &dev;
+}
+
+#define EARLY_PCI_OP(rw, size, type) \
+int __init early_##rw##_config_##size(struct pci_channel *hose, \
+ int top_bus, int bus, int devfn, int offset, type value) \
+{ \
+ return pci_##rw##_config_##size( \
+ fake_pci_dev(hose, top_bus, bus, devfn), \
+ offset, value); \
+}
+
+EARLY_PCI_OP(read, byte, u8 *)
+EARLY_PCI_OP(read, word, u16 *)
+EARLY_PCI_OP(read, dword, u32 *)
+EARLY_PCI_OP(write, byte, u8)
+EARLY_PCI_OP(write, word, u16)
+EARLY_PCI_OP(write, dword, u32)
+
+int __init pci_is_66mhz_capable(struct pci_channel *hose,
+ int top_bus, int current_bus)
+{
+ u32 pci_devfn;
+ unsigned short vid;
+ int cap66 = -1;
+ u16 stat;
+
+ printk(KERN_INFO "PCI: Checking 66MHz capabilities...\n");
+
+ for (pci_devfn = 0; pci_devfn < 0xff; pci_devfn++) {
+ if (PCI_FUNC(pci_devfn))
+ continue;
+ if (early_read_config_word(hose, top_bus, current_bus,
+ pci_devfn, PCI_VENDOR_ID, &vid) !=
+ PCIBIOS_SUCCESSFUL)
+ continue;
+ if (vid == 0xffff)
+ continue;
+
+ /* check 66MHz capability */
+ if (cap66 < 0)
+ cap66 = 1;
+ if (cap66) {
+ early_read_config_word(hose, top_bus, current_bus,
+ pci_devfn, PCI_STATUS, &stat);
+ if (!(stat & PCI_STATUS_66MHZ)) {
+ printk(KERN_DEBUG
+ "PCI: %02x:%02x not 66MHz capable.\n",
+ current_bus, pci_devfn);
+ cap66 = 0;
+ break;
+ }
+ }
+ }
+
+ return cap66 > 0;
+}
+
+static void pcibios_enable_err(unsigned long __data)
+{
+ struct pci_channel *hose = (struct pci_channel *)__data;
+
+ del_timer(&hose->err_timer);
+ printk(KERN_DEBUG "PCI: re-enabling error IRQ.\n");
+ enable_irq(hose->err_irq);
+}
+
+static void pcibios_enable_serr(unsigned long __data)
+{
+ struct pci_channel *hose = (struct pci_channel *)__data;
+
+ del_timer(&hose->serr_timer);
+ printk(KERN_DEBUG "PCI: re-enabling system error IRQ.\n");
+ enable_irq(hose->serr_irq);
+}
+
+void pcibios_enable_timers(struct pci_channel *hose)
+{
+ if (hose->err_irq) {
+ init_timer(&hose->err_timer);
+ hose->err_timer.data = (unsigned long)hose;
+ hose->err_timer.function = pcibios_enable_err;
+ }
+
+ if (hose->serr_irq) {
+ init_timer(&hose->serr_timer);
+ hose->serr_timer.data = (unsigned long)hose;
+ hose->serr_timer.function = pcibios_enable_serr;
+ }
+}
+
+/*
+ * A simple handler for the regular PCI status errors, called from IRQ
+ * context.
+ */
+unsigned int pcibios_handle_status_errors(unsigned long addr,
+ unsigned int status,
+ struct pci_channel *hose)
+{
+ unsigned int cmd = 0;
+
+ if (status & PCI_STATUS_REC_MASTER_ABORT) {
+ printk(KERN_DEBUG "PCI: master abort, pc=0x%08lx\n", addr);
+ cmd |= PCI_STATUS_REC_MASTER_ABORT;
+ }
+
+ if (status & PCI_STATUS_REC_TARGET_ABORT) {
+ printk(KERN_DEBUG "PCI: target abort: ");
+ pcibios_report_status(PCI_STATUS_REC_TARGET_ABORT |
+ PCI_STATUS_SIG_TARGET_ABORT |
+ PCI_STATUS_REC_MASTER_ABORT, 1);
+ printk("\n");
+
+ cmd |= PCI_STATUS_REC_TARGET_ABORT;
+ }
+
+ if (status & (PCI_STATUS_PARITY | PCI_STATUS_DETECTED_PARITY)) {
+ printk(KERN_DEBUG "PCI: parity error detected: ");
+ pcibios_report_status(PCI_STATUS_PARITY |
+ PCI_STATUS_DETECTED_PARITY, 1);
+ printk("\n");
+
+ cmd |= PCI_STATUS_PARITY | PCI_STATUS_DETECTED_PARITY;
+
+ /* Now back off of the IRQ for awhile */
+ if (hose->err_irq) {
+ disable_irq_nosync(hose->err_irq);
+ hose->err_timer.expires = jiffies + HZ;
+ add_timer(&hose->err_timer);
+ }
+ }
+
+ return cmd;
+}
diff --git a/arch/sh/drivers/pci/fixups-dreamcast.c b/arch/sh/drivers/pci/fixups-dreamcast.c
index ed7f489936f..942ef4f155f 100644
--- a/arch/sh/drivers/pci/fixups-dreamcast.c
+++ b/arch/sh/drivers/pci/fixups-dreamcast.c
@@ -39,7 +39,7 @@ static void __init gapspci_fixup_resources(struct pci_dev *dev)
/*
* We also assume that dev->devfn == 0
*/
- dev->resource[1].start = p->io_resource->start + 0x100;
+ dev->resource[1].start = p->resources[0].start + 0x100;
dev->resource[1].end = dev->resource[1].start + 0x200 - 1;
/*
diff --git a/arch/sh/drivers/pci/fixups-r7780rp.c b/arch/sh/drivers/pci/fixups-r7780rp.c
index 15ca65cb667..08b2d8658a0 100644
--- a/arch/sh/drivers/pci/fixups-r7780rp.c
+++ b/arch/sh/drivers/pci/fixups-r7780rp.c
@@ -22,15 +22,3 @@ int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin)
{
return irq_tab[slot];
}
-
-int pci_fixup_pcic(struct pci_channel *chan)
-{
- pci_write_reg(chan, 0x000043ff, SH4_PCIINTM);
- pci_write_reg(chan, 0x00000000, SH7780_PCIIBAR);
- pci_write_reg(chan, 0x08000000, SH7780_PCICSCR0);
- pci_write_reg(chan, 0x0000001b, SH7780_PCICSAR0);
- pci_write_reg(chan, 0xfd000000, SH7780_PCICSCR1);
- pci_write_reg(chan, 0x0000000f, SH7780_PCICSAR1);
-
- return 0;
-}
diff --git a/arch/sh/drivers/pci/fixups-rts7751r2d.c b/arch/sh/drivers/pci/fixups-rts7751r2d.c
index 7898f14d664..e248516118a 100644
--- a/arch/sh/drivers/pci/fixups-rts7751r2d.c
+++ b/arch/sh/drivers/pci/fixups-rts7751r2d.c
@@ -43,7 +43,7 @@ int pci_fixup_pcic(struct pci_channel *chan)
{
unsigned long bcr1, mcr;
- bcr1 = ctrl_inl(SH7751_BCR1);
+ bcr1 = __raw_readl(SH7751_BCR1);
bcr1 |= 0x40080000; /* Enable Bit 19 BREQEN, set PCIC to slave */
pci_write_reg(chan, bcr1, SH4_PCIBCR1);
@@ -54,7 +54,7 @@ int pci_fixup_pcic(struct pci_channel *chan)
pci_write_reg(chan, 0xfb900047, SH7751_PCICONF1);
pci_write_reg(chan, 0xab000001, SH7751_PCICONF4);
- mcr = ctrl_inl(SH7751_MCR);
+ mcr = __raw_readl(SH7751_MCR);
mcr = (mcr & PCIMCR_MRSET_OFF) & PCIMCR_RFSH_OFF;
pci_write_reg(chan, mcr, SH4_PCIMCR);
diff --git a/arch/sh/drivers/pci/fixups-sdk7780.c b/arch/sh/drivers/pci/fixups-sdk7780.c
index 250b0edd736..0930f988ac2 100644
--- a/arch/sh/drivers/pci/fixups-sdk7780.c
+++ b/arch/sh/drivers/pci/fixups-sdk7780.c
@@ -31,22 +31,3 @@ int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin)
{
return sdk7780_irq_tab[pin-1][slot];
}
-int pci_fixup_pcic(struct pci_channel *chan)
-{
- /* Enable all interrupts, so we know what to fix */
- pci_write_reg(chan, 0x0000C3FF, SH7780_PCIIMR);
-
- /* Set up standard PCI config registers */
- pci_write_reg(chan, 0x08000000, SH7780_PCIMBAR0); /* PCI */
- pci_write_reg(chan, 0x08000000, SH4_PCILAR0); /* SHwy */
- pci_write_reg(chan, 0x07F00001, SH4_PCILSR0); /* size 128M w/ MBAR */
-
- pci_write_reg(chan, 0x00000000, SH7780_PCIMBAR1);
- pci_write_reg(chan, 0x00000000, SH4_PCILAR1);
- pci_write_reg(chan, 0x00000000, SH4_PCILSR1);
-
- pci_write_reg(chan, 0xAB000801, SH7780_PCIIBAR);
- pci_write_reg(chan, 0xA5000C01, SH4_PCICR);
-
- return 0;
-}
diff --git a/arch/sh/drivers/pci/fixups-se7751.c b/arch/sh/drivers/pci/fixups-se7751.c
index 475fa9f0fe2..a4c7d3a4efc 100644
--- a/arch/sh/drivers/pci/fixups-se7751.c
+++ b/arch/sh/drivers/pci/fixups-se7751.c
@@ -97,12 +97,12 @@ int pci_fixup_pcic(struct pci_channel *chan)
* meaning all calls go straight through... use BUG_ON to
* catch erroneous assumption.
*/
- BUG_ON(chan->mem_resource->start != SH7751_PCI_MEMORY_BASE);
+ BUG_ON(chan->resources[1].start != SH7751_PCI_MEMORY_BASE);
- PCIC_WRITE(SH7751_PCIMBR, chan->mem_resource->start);
+ PCIC_WRITE(SH7751_PCIMBR, chan->resources[1].start);
/* Set IOBR for window containing area specified in pci.h */
- PCIC_WRITE(SH7751_PCIIOBR, (chan->io_resource->start & SH7751_PCIIOBR_MASK));
+ PCIC_WRITE(SH7751_PCIIOBR, (chan->resources[0].start & SH7751_PCIIOBR_MASK));
/* All done, may as well say so... */
printk("SH7751 PCI: Finished initialization of the PCI controller\n");
diff --git a/arch/sh/drivers/pci/ops-sh4.c b/arch/sh/drivers/pci/ops-sh4.c
index 78bebebdc99..0b81999fb88 100644
--- a/arch/sh/drivers/pci/ops-sh4.c
+++ b/arch/sh/drivers/pci/ops-sh4.c
@@ -16,7 +16,7 @@
* Direct access to PCI hardware...
*/
#define CONFIG_CMD(bus, devfn, where) \
- (P1SEG | (bus->number << 16) | (devfn << 8) | (where & ~3))
+ (0x80000000 | (bus->number << 16) | (devfn << 8) | (where & ~3))
static DEFINE_SPINLOCK(sh4_pci_lock);
@@ -102,34 +102,6 @@ struct pci_ops sh4_pci_ops = {
.write = sh4_pci_write,
};
-/*
- * Not really related to pci_ops, but it's common and not worth shoving
- * somewhere else for now..
- */
-int __init sh4_pci_check_direct(struct pci_channel *chan)
-{
- /*
- * Check if configuration works.
- */
- unsigned int tmp = pci_read_reg(chan, SH4_PCIPAR);
-
- pci_write_reg(chan, P1SEG, SH4_PCIPAR);
-
- if (pci_read_reg(chan, SH4_PCIPAR) == P1SEG) {
- pci_write_reg(chan, tmp, SH4_PCIPAR);
- printk(KERN_INFO "PCI: Using configuration type 1\n");
- request_region(chan->reg_base + SH4_PCIPAR, 8,
- "PCI conf1");
- return 0;
- }
-
- pci_write_reg(chan, tmp, SH4_PCIPAR);
-
- printk(KERN_ERR "PCI: %s failed\n", __func__);
-
- return -EINVAL;
-}
-
int __attribute__((weak)) pci_fixup_pcic(struct pci_channel *chan)
{
/* Nothing to do. */
diff --git a/arch/sh/drivers/pci/pci-dreamcast.c b/arch/sh/drivers/pci/pci-dreamcast.c
index 210f9d4af14..633694193af 100644
--- a/arch/sh/drivers/pci/pci-dreamcast.c
+++ b/arch/sh/drivers/pci/pci-dreamcast.c
@@ -25,25 +25,25 @@
#include <asm/irq.h>
#include <mach/pci.h>
-static struct resource gapspci_io_resource = {
- .name = "GAPSPCI IO",
- .start = GAPSPCI_BBA_CONFIG,
- .end = GAPSPCI_BBA_CONFIG + GAPSPCI_BBA_CONFIG_SIZE - 1,
- .flags = IORESOURCE_IO,
-};
-
-static struct resource gapspci_mem_resource = {
- .name = "GAPSPCI mem",
- .start = GAPSPCI_DMA_BASE,
- .end = GAPSPCI_DMA_BASE + GAPSPCI_DMA_SIZE - 1,
- .flags = IORESOURCE_MEM,
+static struct resource gapspci_resources[] = {
+ {
+ .name = "GAPSPCI IO",
+ .start = GAPSPCI_BBA_CONFIG,
+ .end = GAPSPCI_BBA_CONFIG + GAPSPCI_BBA_CONFIG_SIZE - 1,
+ .flags = IORESOURCE_IO,
+ }, {
+ .name = "GAPSPCI mem",
+ .start = GAPSPCI_DMA_BASE,
+ .end = GAPSPCI_DMA_BASE + GAPSPCI_DMA_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
};
static struct pci_channel dreamcast_pci_controller = {
.pci_ops = &gapspci_pci_ops,
- .io_resource = &gapspci_io_resource,
+ .resources = gapspci_resources,
+ .nr_resources = ARRAY_SIZE(gapspci_resources),
.io_offset = 0x00000000,
- .mem_resource = &gapspci_mem_resource,
.mem_offset = 0x00000000,
};
@@ -95,8 +95,6 @@ static int __init gapspci_init(void)
outl(0x00002001, GAPSPCI_BBA_CONFIG+0x10);
outl(0x01000000, GAPSPCI_BBA_CONFIG+0x14);
- register_pci_controller(&dreamcast_pci_controller);
-
- return 0;
+ return register_pci_controller(&dreamcast_pci_controller);
}
arch_initcall(gapspci_init);
diff --git a/arch/sh/drivers/pci/pci-sh4.h b/arch/sh/drivers/pci/pci-sh4.h
index 3d5296cde62..cbf763b3015 100644
--- a/arch/sh/drivers/pci/pci-sh4.h
+++ b/arch/sh/drivers/pci/pci-sh4.h
@@ -49,6 +49,17 @@
#define SH4_PCIINT_MWPD 0x00000002 /* Master Write PERR Detect */
#define SH4_PCIINT_MRPD 0x00000001 /* Master Read PERR Detect */
#define SH4_PCIINTM 0x118 /* PCI Interrupt Mask */
+ #define SH4_PCIINTM_TTADIM BIT(14) /* Target-target abort interrupt */
+ #define SH4_PCIINTM_TMTOIM BIT(9) /* Target retry timeout */
+ #define SH4_PCIINTM_MDEIM BIT(8) /* Master function disable error */
+ #define SH4_PCIINTM_APEDIM BIT(7) /* Address parity error detection */
+ #define SH4_PCIINTM_SDIM BIT(6) /* SERR detection */
+ #define SH4_PCIINTM_DPEITWM BIT(5) /* Data parity error for target write */
+ #define SH4_PCIINTM_PEDITRM BIT(4) /* PERR detection for target read */
+ #define SH4_PCIINTM_TADIMM BIT(3) /* Target abort for master */
+ #define SH4_PCIINTM_MADIMM BIT(2) /* Master abort for master */
+ #define SH4_PCIINTM_MWPDIM BIT(1) /* Master write data parity error */
+ #define SH4_PCIINTM_MRDPEIM BIT(0) /* Master read data parity error */
#define SH4_PCIALR 0x11C /* Error Address Register */
#define SH4_PCICLR 0x120 /* Error Command/Data */
#define SH4_PCICLR_MPIO 0x80000000
@@ -61,7 +72,7 @@
#define SH4_PCIAINT 0x130 /* Arbiter Interrupt Register */
#define SH4_PCIAINT_MBKN 0x00002000 /* Master Broken Interrupt */
#define SH4_PCIAINT_TBTO 0x00001000 /* Target Bus Time Out */
- #define SH4_PCIAINT_MBTO 0x00001000 /* Master Bus Time Out */
+ #define SH4_PCIAINT_MBTO 0x00000800 /* Master Bus Time Out */
#define SH4_PCIAINT_TABT 0x00000008 /* Target Abort */
#define SH4_PCIAINT_MABT 0x00000004 /* Master Abort */
#define SH4_PCIAINT_RDPE 0x00000002 /* Read Data Parity Error */
@@ -151,7 +162,6 @@
/* arch/sh/kernel/drivers/pci/ops-sh4.c */
extern struct pci_ops sh4_pci_ops;
-int sh4_pci_check_direct(struct pci_channel *chan);
int pci_fixup_pcic(struct pci_channel *chan);
struct sh4_pci_address_space {
@@ -167,13 +177,13 @@ struct sh4_pci_address_map {
static inline void pci_write_reg(struct pci_channel *chan,
unsigned long val, unsigned long reg)
{
- ctrl_outl(val, chan->reg_base + reg);
+ __raw_writel(val, chan->reg_base + reg);
}
static inline unsigned long pci_read_reg(struct pci_channel *chan,
unsigned long reg)
{
- return ctrl_inl(chan->reg_base + reg);
+ return __raw_readl(chan->reg_base + reg);
}
#endif /* __PCI_SH4_H */
diff --git a/arch/sh/drivers/pci/pci-sh5.c b/arch/sh/drivers/pci/pci-sh5.c
index 873ed2b4405..0bf296c7879 100644
--- a/arch/sh/drivers/pci/pci-sh5.c
+++ b/arch/sh/drivers/pci/pci-sh5.c
@@ -89,14 +89,13 @@ static irqreturn_t pcish5_serr_irq(int irq, void *dev_id)
return IRQ_NONE;
}
-static struct resource sh5_io_resource = { /* place holder */ };
-static struct resource sh5_mem_resource = { /* place holder */ };
+static struct resource sh5_pci_resources[2];
static struct pci_channel sh5pci_controller = {
.pci_ops = &sh5_pci_ops,
- .mem_resource = &sh5_mem_resource,
+ .resources = sh5_pci_resources,
+ .nr_resources = ARRAY_SIZE(sh5_pci_resources),
.mem_offset = 0x00000000,
- .io_resource = &sh5_io_resource,
.io_offset = 0x00000000,
};
@@ -210,14 +209,12 @@ static int __init sh5pci_init(void)
SH5PCI_WRITE(AINTM, ~0);
SH5PCI_WRITE(PINTM, ~0);
- sh5_io_resource.start = PCI_IO_AREA;
- sh5_io_resource.end = PCI_IO_AREA + 0x10000;
+ sh5_pci_resources[0].start = PCI_IO_AREA;
+ sh5_pci_resources[0].end = PCI_IO_AREA + 0x10000;
- sh5_mem_resource.start = memStart;
- sh5_mem_resource.end = memStart + memSize;
+ sh5_pci_resources[1].start = memStart;
+ sh5_pci_resources[1].end = memStart + memSize;
- register_pci_controller(&sh5pci_controller);
-
- return 0;
+ return register_pci_controller(&sh5pci_controller);
}
arch_initcall(sh5pci_init);
diff --git a/arch/sh/drivers/pci/pci-sh5.h b/arch/sh/drivers/pci/pci-sh5.h
index f277628221f..3f01decb430 100644
--- a/arch/sh/drivers/pci/pci-sh5.h
+++ b/arch/sh/drivers/pci/pci-sh5.h
@@ -86,14 +86,14 @@ extern unsigned long pcicr_virt;
/* #define PCISH5_VCR_REG(x) ( SH5PCI_VCR_BASE (PCISH5_VCR_##x)) */
/* Write I/O functions */
-#define SH5PCI_WRITE(reg,val) ctrl_outl((u32)(val),PCISH5_ICR_REG(reg))
-#define SH5PCI_WRITE_SHORT(reg,val) ctrl_outw((u16)(val),PCISH5_ICR_REG(reg))
-#define SH5PCI_WRITE_BYTE(reg,val) ctrl_outb((u8)(val),PCISH5_ICR_REG(reg))
+#define SH5PCI_WRITE(reg,val) __raw_writel((u32)(val),PCISH5_ICR_REG(reg))
+#define SH5PCI_WRITE_SHORT(reg,val) __raw_writew((u16)(val),PCISH5_ICR_REG(reg))
+#define SH5PCI_WRITE_BYTE(reg,val) __raw_writeb((u8)(val),PCISH5_ICR_REG(reg))
/* Read I/O functions */
-#define SH5PCI_READ(reg) ctrl_inl(PCISH5_ICR_REG(reg))
-#define SH5PCI_READ_SHORT(reg) ctrl_inw(PCISH5_ICR_REG(reg))
-#define SH5PCI_READ_BYTE(reg) ctrl_inb(PCISH5_ICR_REG(reg))
+#define SH5PCI_READ(reg) __raw_readl(PCISH5_ICR_REG(reg))
+#define SH5PCI_READ_SHORT(reg) __raw_readw(PCISH5_ICR_REG(reg))
+#define SH5PCI_READ_BYTE(reg) __raw_readb(PCISH5_ICR_REG(reg))
/* Set PCI config bits */
#define SET_CONFIG_BITS(bus,devfn,where) ((((bus) << 16) | ((devfn) << 8) | ((where) & ~3)) | 0x80000000)
diff --git a/arch/sh/drivers/pci/pci-sh7751.c b/arch/sh/drivers/pci/pci-sh7751.c
index 70c1999a0ec..17811e5d287 100644
--- a/arch/sh/drivers/pci/pci-sh7751.c
+++ b/arch/sh/drivers/pci/pci-sh7751.c
@@ -44,25 +44,25 @@ static int __init __area_sdram_check(struct pci_channel *chan,
return 1;
}
-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
+static struct resource sh7751_pci_resources[] = {
+ {
+ .name = "SH7751_IO",
+ .start = SH7751_PCI_IO_BASE,
+ .end = SH7751_PCI_IO_BASE + SH7751_PCI_IO_SIZE - 1,
+ .flags = IORESOURCE_IO
+ }, {
+ .name = "SH7751_mem",
+ .start = SH7751_PCI_MEMORY_BASE,
+ .end = SH7751_PCI_MEMORY_BASE + SH7751_PCI_MEM_SIZE - 1,
+ .flags = IORESOURCE_MEM
+ },
};
static struct pci_channel sh7751_pci_controller = {
.pci_ops = &sh4_pci_ops,
- .mem_resource = &sh7751_mem_resource,
+ .resources = sh7751_pci_resources,
+ .nr_resources = ARRAY_SIZE(sh7751_pci_resources),
.mem_offset = 0x00000000,
- .io_resource = &sh7751_io_resource,
.io_offset = 0x00000000,
.io_map_base = SH7751_PCI_IO_BASE,
};
@@ -79,7 +79,6 @@ static int __init sh7751_pci_init(void)
struct pci_channel *chan = &sh7751_pci_controller;
unsigned int id;
u32 word, reg;
- int ret;
printk(KERN_NOTICE "PCI: Starting intialization.\n");
@@ -93,13 +92,10 @@ static int __init sh7751_pci_init(void)
return -ENODEV;
}
- if ((ret = sh4_pci_check_direct(chan)) != 0)
- return ret;
-
/* Set the BCR's to enable PCI access */
- reg = ctrl_inl(SH7751_BCR1);
+ reg = __raw_readl(SH7751_BCR1);
reg |= 0x80000;
- ctrl_outl(reg, SH7751_BCR1);
+ __raw_writel(reg, SH7751_BCR1);
/* Turn the clocks back on (not done in reset)*/
pci_write_reg(chan, 0, SH4_PCICLKR);
@@ -132,13 +128,13 @@ static int __init sh7751_pci_init(void)
/* Set the local 16MB PCI memory space window to
* the lowest PCI mapped address
*/
- word = chan->mem_resource->start & SH4_PCIMBR_MASK;
+ word = chan->resources[1].start & SH4_PCIMBR_MASK;
pr_debug("PCI: Setting upper bits of Memory window to 0x%x\n", word);
pci_write_reg(chan, word , SH4_PCIMBR);
/* Make sure the MSB's of IO window are set to access PCI space
* correctly */
- word = chan->io_resource->start & SH4_PCIIOBR_MASK;
+ word = chan->resources[0].start & SH4_PCIIOBR_MASK;
pr_debug("PCI: Setting upper bits of IO window to 0x%x\n", word);
pci_write_reg(chan, word, SH4_PCIIOBR);
@@ -159,13 +155,13 @@ static int __init sh7751_pci_init(void)
return -1;
/* configure the wait control registers */
- word = ctrl_inl(SH7751_WCR1);
+ word = __raw_readl(SH7751_WCR1);
pci_write_reg(chan, word, SH4_PCIWCR1);
- word = ctrl_inl(SH7751_WCR2);
+ word = __raw_readl(SH7751_WCR2);
pci_write_reg(chan, word, SH4_PCIWCR2);
- word = ctrl_inl(SH7751_WCR3);
+ word = __raw_readl(SH7751_WCR3);
pci_write_reg(chan, word, SH4_PCIWCR3);
- word = ctrl_inl(SH7751_MCR);
+ word = __raw_readl(SH7751_MCR);
pci_write_reg(chan, word, SH4_PCIMCR);
/* NOTE: I'm ignoring the PCI error IRQs for now..
@@ -180,8 +176,6 @@ static int __init sh7751_pci_init(void)
word = SH4_PCICR_PREFIX | SH4_PCICR_CFIN | SH4_PCICR_ARBM;
pci_write_reg(chan, word, SH4_PCICR);
- register_pci_controller(chan);
-
- return 0;
+ return register_pci_controller(chan);
}
arch_initcall(sh7751_pci_init);
diff --git a/arch/sh/drivers/pci/pci-sh7780.c b/arch/sh/drivers/pci/pci-sh7780.c
index 323b92d565f..ffdcbf10b95 100644
--- a/arch/sh/drivers/pci/pci-sh7780.c
+++ b/arch/sh/drivers/pci/pci-sh7780.c
@@ -1,7 +1,7 @@
/*
* Low-Level PCI Support for the SH7780
*
- * Copyright (C) 2005 - 2009 Paul Mundt
+ * Copyright (C) 2005 - 2010 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
@@ -11,52 +11,240 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/timer.h>
+#include <linux/irq.h>
#include <linux/errno.h>
#include <linux/delay.h>
+#include <linux/log2.h>
#include "pci-sh4.h"
+#include <asm/mmu.h>
+#include <asm/sizes.h>
-static struct resource sh7785_io_resource = {
- .name = "SH7785_IO",
- .start = SH7780_PCI_IO_BASE,
- .end = SH7780_PCI_IO_BASE + SH7780_PCI_IO_SIZE - 1,
- .flags = IORESOURCE_IO
-};
-
-static struct resource sh7785_mem_resource = {
- .name = "SH7785_mem",
- .start = SH7780_PCI_MEMORY_BASE,
- .end = SH7780_PCI_MEMORY_BASE + SH7780_PCI_MEM_SIZE - 1,
- .flags = IORESOURCE_MEM
+static struct resource sh7785_pci_resources[] = {
+ {
+ .name = "PCI IO",
+ .start = 0x1000,
+ .end = SZ_4M - 1,
+ .flags = IORESOURCE_IO,
+ }, {
+ .name = "PCI MEM 0",
+ .start = 0xfd000000,
+ .end = 0xfd000000 + SZ_16M - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .name = "PCI MEM 1",
+ .start = 0x10000000,
+ .end = 0x10000000 + SZ_64M - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ /*
+ * 32-bit only resources must be last.
+ */
+ .name = "PCI MEM 2",
+ .start = 0xc0000000,
+ .end = 0xc0000000 + SZ_512M - 1,
+ .flags = IORESOURCE_MEM | IORESOURCE_MEM_32BIT,
+ },
};
static struct pci_channel sh7780_pci_controller = {
.pci_ops = &sh4_pci_ops,
- .mem_resource = &sh7785_mem_resource,
- .mem_offset = 0x00000000,
- .io_resource = &sh7785_io_resource,
- .io_offset = 0x00000000,
- .io_map_base = SH7780_PCI_IO_BASE,
+ .resources = sh7785_pci_resources,
+ .nr_resources = ARRAY_SIZE(sh7785_pci_resources),
+ .io_offset = 0,
+ .mem_offset = 0,
+ .io_map_base = 0xfe200000,
+ .serr_irq = evt2irq(0xa00),
+ .err_irq = evt2irq(0xaa0),
};
-static struct sh4_pci_address_map sh7780_pci_map = {
- .window0 = {
-#if defined(CONFIG_32BIT)
- .base = SH7780_32BIT_DDR_BASE_ADDR,
- .size = 0x40000000,
-#else
- .base = SH7780_CS0_BASE_ADDR,
- .size = 0x20000000,
-#endif
- },
+struct pci_errors {
+ unsigned int mask;
+ const char *str;
+} pci_arbiter_errors[] = {
+ { SH4_PCIAINT_MBKN, "master broken" },
+ { SH4_PCIAINT_TBTO, "target bus time out" },
+ { SH4_PCIAINT_MBTO, "master bus time out" },
+ { SH4_PCIAINT_TABT, "target abort" },
+ { SH4_PCIAINT_MABT, "master abort" },
+ { SH4_PCIAINT_RDPE, "read data parity error" },
+ { SH4_PCIAINT_WDPE, "write data parity error" },
+}, pci_interrupt_errors[] = {
+ { SH4_PCIINT_MLCK, "master lock error" },
+ { SH4_PCIINT_TABT, "target-target abort" },
+ { SH4_PCIINT_TRET, "target retry time out" },
+ { SH4_PCIINT_MFDE, "master function disable erorr" },
+ { SH4_PCIINT_PRTY, "address parity error" },
+ { SH4_PCIINT_SERR, "SERR" },
+ { SH4_PCIINT_TWDP, "data parity error for target write" },
+ { SH4_PCIINT_TRDP, "PERR detected for target read" },
+ { SH4_PCIINT_MTABT, "target abort for master" },
+ { SH4_PCIINT_MMABT, "master abort for master" },
+ { SH4_PCIINT_MWPD, "master write data parity error" },
+ { SH4_PCIINT_MRPD, "master read data parity error" },
};
+static irqreturn_t sh7780_pci_err_irq(int irq, void *dev_id)
+{
+ struct pci_channel *hose = dev_id;
+ unsigned long addr;
+ unsigned int status;
+ unsigned int cmd;
+ int i;
+
+ addr = __raw_readl(hose->reg_base + SH4_PCIALR);
+
+ /*
+ * Handle status errors.
+ */
+ status = __raw_readw(hose->reg_base + PCI_STATUS);
+ if (status & (PCI_STATUS_PARITY |
+ PCI_STATUS_DETECTED_PARITY |
+ PCI_STATUS_SIG_TARGET_ABORT |
+ PCI_STATUS_REC_TARGET_ABORT |
+ PCI_STATUS_REC_MASTER_ABORT)) {
+ cmd = pcibios_handle_status_errors(addr, status, hose);
+ if (likely(cmd))
+ __raw_writew(cmd, hose->reg_base + PCI_STATUS);
+ }
+
+ /*
+ * Handle arbiter errors.
+ */
+ status = __raw_readl(hose->reg_base + SH4_PCIAINT);
+ for (i = cmd = 0; i < ARRAY_SIZE(pci_arbiter_errors); i++) {
+ if (status & pci_arbiter_errors[i].mask) {
+ printk(KERN_DEBUG "PCI: %s, addr=%08lx\n",
+ pci_arbiter_errors[i].str, addr);
+ cmd |= pci_arbiter_errors[i].mask;
+ }
+ }
+ __raw_writel(cmd, hose->reg_base + SH4_PCIAINT);
+
+ /*
+ * Handle the remaining PCI errors.
+ */
+ status = __raw_readl(hose->reg_base + SH4_PCIINT);
+ for (i = cmd = 0; i < ARRAY_SIZE(pci_interrupt_errors); i++) {
+ if (status & pci_interrupt_errors[i].mask) {
+ printk(KERN_DEBUG "PCI: %s, addr=%08lx\n",
+ pci_interrupt_errors[i].str, addr);
+ cmd |= pci_interrupt_errors[i].mask;
+ }
+ }
+ __raw_writel(cmd, hose->reg_base + SH4_PCIINT);
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t sh7780_pci_serr_irq(int irq, void *dev_id)
+{
+ struct pci_channel *hose = dev_id;
+
+ printk(KERN_DEBUG "PCI: system error received: ");
+ pcibios_report_status(PCI_STATUS_SIG_SYSTEM_ERROR, 1);
+ printk("\n");
+
+ /* Deassert SERR */
+ __raw_writel(SH4_PCIINTM_SDIM, hose->reg_base + SH4_PCIINTM);
+
+ /* Back off the IRQ for awhile */
+ disable_irq_nosync(irq);
+ hose->serr_timer.expires = jiffies + HZ;
+ add_timer(&hose->serr_timer);
+
+ return IRQ_HANDLED;
+}
+
+static int __init sh7780_pci_setup_irqs(struct pci_channel *hose)
+{
+ int ret;
+
+ /* Clear out PCI arbiter IRQs */
+ __raw_writel(0, hose->reg_base + SH4_PCIAINT);
+
+ /* Clear all error conditions */
+ __raw_writew(PCI_STATUS_DETECTED_PARITY | \
+ PCI_STATUS_SIG_SYSTEM_ERROR | \
+ PCI_STATUS_REC_MASTER_ABORT | \
+ PCI_STATUS_REC_TARGET_ABORT | \
+ PCI_STATUS_SIG_TARGET_ABORT | \
+ PCI_STATUS_PARITY, hose->reg_base + PCI_STATUS);
+
+ ret = request_irq(hose->serr_irq, sh7780_pci_serr_irq, IRQF_DISABLED,
+ "PCI SERR interrupt", hose);
+ if (unlikely(ret)) {
+ printk(KERN_ERR "PCI: Failed hooking SERR IRQ\n");
+ return ret;
+ }
+
+ /*
+ * The PCI ERR IRQ needs to be IRQF_SHARED since all of the power
+ * down IRQ vectors are routed through the ERR IRQ vector. We
+ * only request_irq() once as there is only a single masking
+ * source for multiple events.
+ */
+ ret = request_irq(hose->err_irq, sh7780_pci_err_irq, IRQF_SHARED,
+ "PCI ERR interrupt", hose);
+ if (unlikely(ret)) {
+ free_irq(hose->serr_irq, hose);
+ return ret;
+ }
+
+ /* Unmask all of the arbiter IRQs. */
+ __raw_writel(SH4_PCIAINT_MBKN | SH4_PCIAINT_TBTO | SH4_PCIAINT_MBTO | \
+ SH4_PCIAINT_TABT | SH4_PCIAINT_MABT | SH4_PCIAINT_RDPE | \
+ SH4_PCIAINT_WDPE, hose->reg_base + SH4_PCIAINTM);
+
+ /* Unmask all of the PCI IRQs */
+ __raw_writel(SH4_PCIINTM_TTADIM | SH4_PCIINTM_TMTOIM | \
+ SH4_PCIINTM_MDEIM | SH4_PCIINTM_APEDIM | \
+ SH4_PCIINTM_SDIM | SH4_PCIINTM_DPEITWM | \
+ SH4_PCIINTM_PEDITRM | SH4_PCIINTM_TADIMM | \
+ SH4_PCIINTM_MADIMM | SH4_PCIINTM_MWPDIM | \
+ SH4_PCIINTM_MRDPEIM, hose->reg_base + SH4_PCIINTM);
+
+ return ret;
+}
+
+static inline void __init sh7780_pci_teardown_irqs(struct pci_channel *hose)
+{
+ free_irq(hose->err_irq, hose);
+ free_irq(hose->serr_irq, hose);
+}
+
+static void __init sh7780_pci66_init(struct pci_channel *hose)
+{
+ unsigned int tmp;
+
+ if (!pci_is_66mhz_capable(hose, 0, 0))
+ return;
+
+ /* Enable register access */
+ tmp = __raw_readl(hose->reg_base + SH4_PCICR);
+ tmp |= SH4_PCICR_PREFIX;
+ __raw_writel(tmp, hose->reg_base + SH4_PCICR);
+
+ /* Enable 66MHz operation */
+ tmp = __raw_readw(hose->reg_base + PCI_STATUS);
+ tmp |= PCI_STATUS_66MHZ;
+ __raw_writew(tmp, hose->reg_base + PCI_STATUS);
+
+ /* Done */
+ tmp = __raw_readl(hose->reg_base + SH4_PCICR);
+ tmp |= SH4_PCICR_PREFIX | SH4_PCICR_CFIN;
+ __raw_writel(tmp, hose->reg_base + SH4_PCICR);
+}
+
static int __init sh7780_pci_init(void)
{
struct pci_channel *chan = &sh7780_pci_controller;
+ phys_addr_t memphys;
+ size_t memsize;
unsigned int id;
- const char *type = NULL;
- int ret;
- u32 word;
+ const char *type;
+ int ret, i;
printk(KERN_NOTICE "PCI: Starting intialization.\n");
@@ -65,17 +253,28 @@ static int __init sh7780_pci_init(void)
/* Enable CPU access to the PCIC registers. */
__raw_writel(PCIECR_ENBL, PCIECR);
- id = __raw_readw(chan->reg_base + SH7780_PCIVID);
- if (id != SH7780_VENDOR_ID) {
+ /* Reset */
+ __raw_writel(SH4_PCICR_PREFIX | SH4_PCICR_PRST,
+ chan->reg_base + SH4_PCICR);
+
+ /*
+ * Wait for it to come back up. The spec says to allow for up to
+ * 1 second after toggling the reset pin, but in practice 100ms
+ * is more than enough.
+ */
+ mdelay(100);
+
+ id = __raw_readw(chan->reg_base + PCI_VENDOR_ID);
+ if (id != PCI_VENDOR_ID_RENESAS) {
printk(KERN_ERR "PCI: Unknown vendor ID 0x%04x.\n", id);
return -ENODEV;
}
- id = __raw_readw(chan->reg_base + SH7780_PCIDID);
- type = (id == SH7763_DEVICE_ID) ? "SH7763" :
- (id == SH7780_DEVICE_ID) ? "SH7780" :
- (id == SH7781_DEVICE_ID) ? "SH7781" :
- (id == SH7785_DEVICE_ID) ? "SH7785" :
+ id = __raw_readw(chan->reg_base + PCI_DEVICE_ID);
+ type = (id == PCI_DEVICE_ID_RENESAS_SH7763) ? "SH7763" :
+ (id == PCI_DEVICE_ID_RENESAS_SH7780) ? "SH7780" :
+ (id == PCI_DEVICE_ID_RENESAS_SH7781) ? "SH7781" :
+ (id == PCI_DEVICE_ID_RENESAS_SH7785) ? "SH7785" :
NULL;
if (unlikely(!type)) {
printk(KERN_ERR "PCI: Found an unsupported Renesas host "
@@ -85,62 +284,119 @@ static int __init sh7780_pci_init(void)
printk(KERN_NOTICE "PCI: Found a Renesas %s host "
"controller, revision %d.\n", type,
- __raw_readb(chan->reg_base + SH7780_PCIRID));
+ __raw_readb(chan->reg_base + PCI_REVISION_ID));
- if ((ret = sh4_pci_check_direct(chan)) != 0)
+ /*
+ * Now throw it in to register initialization mode and
+ * start the real work.
+ */
+ __raw_writel(SH4_PCICR_PREFIX, chan->reg_base + SH4_PCICR);
+
+ memphys = __pa(memory_start);
+ memsize = roundup_pow_of_two(memory_end - memory_start);
+
+ /*
+ * If there's more than 512MB of memory, we need to roll over to
+ * LAR1/LSR1.
+ */
+ if (memsize > SZ_512M) {
+ __raw_writel(memphys + SZ_512M, chan->reg_base + SH4_PCILAR1);
+ __raw_writel((((memsize - SZ_512M) - SZ_1M) & 0x1ff00000) | 1,
+ chan->reg_base + SH4_PCILSR1);
+ memsize = SZ_512M;
+ } else {
+ /*
+ * Otherwise just zero it out and disable it.
+ */
+ __raw_writel(0, chan->reg_base + SH4_PCILAR1);
+ __raw_writel(0, chan->reg_base + SH4_PCILSR1);
+ }
+
+ /*
+ * LAR0/LSR0 covers up to the first 512MB, which is enough to
+ * cover all of lowmem on most platforms.
+ */
+ __raw_writel(memphys, chan->reg_base + SH4_PCILAR0);
+ __raw_writel(((memsize - SZ_1M) & 0x1ff00000) | 1,
+ chan->reg_base + SH4_PCILSR0);
+
+ /*
+ * Hook up the ERR and SERR IRQs.
+ */
+ ret = sh7780_pci_setup_irqs(chan);
+ if (unlikely(ret))
return ret;
/*
- * Set the class and sub-class codes.
+ * Disable the cache snoop controller for non-coherent DMA.
*/
- __raw_writeb(PCI_CLASS_BRIDGE_HOST >> 8,
- chan->reg_base + SH7780_PCIBCC);
- __raw_writeb(PCI_CLASS_BRIDGE_HOST & 0xff,
- chan->reg_base + SH7780_PCISUB);
+ __raw_writel(0, chan->reg_base + SH7780_PCICSCR0);
+ __raw_writel(0, chan->reg_base + SH7780_PCICSAR0);
+ __raw_writel(0, chan->reg_base + SH7780_PCICSCR1);
+ __raw_writel(0, chan->reg_base + SH7780_PCICSAR1);
/*
- * Set IO and Mem windows to local address
- * Make PCI and local address the same for easy 1 to 1 mapping
+ * Setup the memory BARs
*/
- pci_write_reg(chan, sh7780_pci_map.window0.size - 0xfffff, SH4_PCILSR0);
- /* Set the values on window 0 PCI config registers */
- pci_write_reg(chan, sh7780_pci_map.window0.base, SH4_PCILAR0);
- pci_write_reg(chan, sh7780_pci_map.window0.base, SH7780_PCIMBAR0);
+ for (i = 1; i < chan->nr_resources; i++) {
+ struct resource *res = chan->resources + i;
+ resource_size_t size;
- pci_write_reg(chan, 0x0000380f, SH4_PCIAINTM);
+ if (unlikely(res->flags & IORESOURCE_IO))
+ continue;
- /* Set up standard PCI config registers */
- __raw_writew(0xFB00, chan->reg_base + SH7780_PCISTATUS);
- __raw_writew(0x0047, chan->reg_base + SH7780_PCICMD);
- __raw_writew(0x1912, chan->reg_base + SH7780_PCISVID);
- __raw_writew(0x0001, chan->reg_base + SH7780_PCISID);
+ /*
+ * Make sure we're in the right physical addressing mode
+ * for dealing with the resource.
+ */
+ if ((res->flags & IORESOURCE_MEM_32BIT) && __in_29bit_mode()) {
+ chan->nr_resources--;
+ continue;
+ }
- __raw_writeb(0x00, chan->reg_base + SH7780_PCIPIF);
+ size = resource_size(res);
+
+ /*
+ * The MBMR mask is calculated in units of 256kB, which
+ * keeps things pretty simple.
+ */
+ __raw_writel(((roundup_pow_of_two(size) / SZ_256K) - 1) << 18,
+ chan->reg_base + SH7780_PCIMBMR(i - 1));
+ __raw_writel(res->start, chan->reg_base + SH7780_PCIMBR(i - 1));
+ }
- /* Apply any last-minute PCIC fixups */
- pci_fixup_pcic(chan);
+ /*
+ * And I/O.
+ */
+ __raw_writel(0, chan->reg_base + PCI_BASE_ADDRESS_0);
+ __raw_writel(0, chan->reg_base + SH7780_PCIIOBR);
+ __raw_writel(0, chan->reg_base + SH7780_PCIIOBMR);
- pci_write_reg(chan, 0xfd000000, SH7780_PCIMBR0);
- pci_write_reg(chan, 0x00fc0000, SH7780_PCIMBMR0);
+ __raw_writew(PCI_COMMAND_SERR | PCI_COMMAND_WAIT | \
+ PCI_COMMAND_PARITY | PCI_COMMAND_MASTER | \
+ PCI_COMMAND_MEMORY, chan->reg_base + PCI_COMMAND);
-#ifdef CONFIG_32BIT
- pci_write_reg(chan, 0xc0000000, SH7780_PCIMBR2);
- pci_write_reg(chan, 0x20000000 - SH7780_PCI_IO_SIZE, SH7780_PCIMBMR2);
-#endif
+ /*
+ * Initialization mode complete, release the control register and
+ * enable round robin mode to stop device overruns/starvation.
+ */
+ __raw_writel(SH4_PCICR_PREFIX | SH4_PCICR_CFIN | SH4_PCICR_FTO,
+ chan->reg_base + SH4_PCICR);
- /* Set IOBR for windows containing area specified in pci.h */
- pci_write_reg(chan, chan->io_resource->start & ~(SH7780_PCI_IO_SIZE-1),
- SH7780_PCIIOBR);
- pci_write_reg(chan, ((SH7780_PCI_IO_SIZE-1) & (7<<18)),
- SH7780_PCIIOBMR);
+ ret = register_pci_controller(chan);
+ if (unlikely(ret))
+ goto err;
- /* SH7780 init done, set central function init complete */
- /* use round robin mode to stop a device starving/overruning */
- word = SH4_PCICR_PREFIX | SH4_PCICR_CFIN | SH4_PCICR_FTO;
- pci_write_reg(chan, word, SH4_PCICR);
+ sh7780_pci66_init(chan);
- register_pci_controller(chan);
+ printk(KERN_NOTICE "PCI: Running at %dMHz.\n",
+ (__raw_readw(chan->reg_base + PCI_STATUS) & PCI_STATUS_66MHZ) ?
+ 66 : 33);
return 0;
+
+err:
+ sh7780_pci_teardown_irqs(chan);
+ return ret;
}
arch_initcall(sh7780_pci_init);
diff --git a/arch/sh/drivers/pci/pci-sh7780.h b/arch/sh/drivers/pci/pci-sh7780.h
index 4a52478c97c..205dcbefe27 100644
--- a/arch/sh/drivers/pci/pci-sh7780.h
+++ b/arch/sh/drivers/pci/pci-sh7780.h
@@ -12,12 +12,11 @@
#ifndef _PCI_SH7780_H_
#define _PCI_SH7780_H_
-/* Platform Specific Values */
-#define SH7780_VENDOR_ID 0x1912
-#define SH7781_DEVICE_ID 0x0001
-#define SH7780_DEVICE_ID 0x0002
-#define SH7763_DEVICE_ID 0x0004
-#define SH7785_DEVICE_ID 0x0007
+#define PCI_VENDOR_ID_RENESAS 0x1912
+#define PCI_DEVICE_ID_RENESAS_SH7781 0x0001
+#define PCI_DEVICE_ID_RENESAS_SH7780 0x0002
+#define PCI_DEVICE_ID_RENESAS_SH7763 0x0004
+#define PCI_DEVICE_ID_RENESAS_SH7785 0x0007
/* SH7780 Control Registers */
#define PCIECR 0xFE000008
@@ -27,44 +26,9 @@
#define SH7780_PCI_CONFIG_BASE 0xFD000000 /* Config space base addr */
#define SH7780_PCI_CONFIG_SIZE 0x01000000 /* Config space size */
-#define SH7780_PCI_MEMORY_BASE 0xFD000000 /* Memory space base addr */
-#define SH7780_PCI_MEM_SIZE 0x01000000 /* Size of Memory window */
-
-#define SH7780_PCI_IO_BASE 0xFE200000 /* IO space base address */
-#define SH7780_PCI_IO_SIZE 0x00400000 /* Size of IO window */
-
#define SH7780_PCIREG_BASE 0xFE040000 /* PCI regs base address */
/* SH7780 PCI Config Registers */
-#define SH7780_PCIVID 0x000 /* Vendor ID */
-#define SH7780_PCIDID 0x002 /* Device ID */
-#define SH7780_PCICMD 0x004 /* Command */
-#define SH7780_PCISTATUS 0x006 /* Status */
-#define SH7780_PCIRID 0x008 /* Revision ID */
-#define SH7780_PCIPIF 0x009 /* Program Interface */
-#define SH7780_PCISUB 0x00a /* Sub class code */
-#define SH7780_PCIBCC 0x00b /* Base class code */
-#define SH7780_PCICLS 0x00c /* Cache line size */
-#define SH7780_PCILTM 0x00d /* latency timer */
-#define SH7780_PCIHDR 0x00e /* Header type */
-#define SH7780_PCIBIST 0x00f /* BIST */
-#define SH7780_PCIIBAR 0x010 /* IO Base address */
-#define SH7780_PCIMBAR0 0x014 /* Memory base address0 */
-#define SH7780_PCIMBAR1 0x018 /* Memory base address1 */
-#define SH7780_PCISVID 0x02c /* Sub system vendor ID */
-#define SH7780_PCISID 0x02e /* Sub system ID */
-#define SH7780_PCICP 0x034
-#define SH7780_PCIINTLINE 0x03c /* Interrupt line */
-#define SH7780_PCIINTPIN 0x03d /* Interrupt pin */
-#define SH7780_PCIMINGNT 0x03e /* Minumum grand */
-#define SH7780_PCIMAXLAT 0x03f /* Maxmum latency */
-#define SH7780_PCICID 0x040
-#define SH7780_PCINIP 0x041
-#define SH7780_PCIPMC 0x042
-#define SH7780_PCIPMCSR 0x044
-#define SH7780_PCIPMCSR_BSE 0x046
-#define SH7780_PCICDD 0x047
-
#define SH7780_PCIIR 0x114 /* PCI Interrupt Register */
#define SH7780_PCIIMR 0x118 /* PCI Interrupt Mask Register */
#define SH7780_PCIAIR 0x11C /* Error Address Register */
@@ -76,10 +40,8 @@
#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
-#define SH7780_PCIMBMR2 0x1F4
+#define SH7780_PCIMBR(x) (0x1E0 + ((x) * 8))
+#define SH7780_PCIMBMR(x) (0x1E4 + ((x) * 8))
#define SH7780_PCIIOBR 0x1F8
#define SH7780_PCIIOBMR 0x1FC
#define SH7780_PCICSCR0 0x210 /* Cache Snoop1 Cnt. Register */
@@ -87,16 +49,4 @@
#define SH7780_PCICSAR0 0x218 /* Cache Snoop1 Addr. Register */
#define SH7780_PCICSAR1 0x21C /* Cache Snoop2 Addr. Register */
-/* General Memory Config Addresses */
-#define SH7780_CS0_BASE_ADDR 0x0
-#define SH7780_MEM_REGION_SIZE 0x04000000
-#define SH7780_CS1_BASE_ADDR (SH7780_CS0_BASE_ADDR + SH7780_MEM_REGION_SIZE)
-#define SH7780_CS2_BASE_ADDR (SH7780_CS1_BASE_ADDR + SH7780_MEM_REGION_SIZE)
-#define SH7780_CS3_BASE_ADDR (SH7780_CS2_BASE_ADDR + SH7780_MEM_REGION_SIZE)
-#define SH7780_CS4_BASE_ADDR (SH7780_CS3_BASE_ADDR + SH7780_MEM_REGION_SIZE)
-#define SH7780_CS5_BASE_ADDR (SH7780_CS4_BASE_ADDR + SH7780_MEM_REGION_SIZE)
-#define SH7780_CS6_BASE_ADDR (SH7780_CS5_BASE_ADDR + SH7780_MEM_REGION_SIZE)
-
-#define SH7780_32BIT_DDR_BASE_ADDR 0x40000000
-
#endif /* _PCI_SH7780_H_ */
diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c
index 96213fd172c..953af139e23 100644
--- a/arch/sh/drivers/pci/pci.c
+++ b/arch/sh/drivers/pci/pci.c
@@ -33,15 +33,22 @@ static int pci_initialized;
static void __devinit pcibios_scanbus(struct pci_channel *hose)
{
static int next_busno;
+ static int need_domain_info;
struct pci_bus *bus;
bus = pci_scan_bus(next_busno, hose->pci_ops, hose);
+ hose->bus = bus;
+
+ need_domain_info = need_domain_info || hose->index;
+ hose->need_domain_info = need_domain_info;
if (bus) {
next_busno = bus->subordinate + 1;
/* Don't allow 8-bit bus number overflow inside the hose -
reserve some space for bridges. */
- if (next_busno > 224)
+ if (next_busno > 224) {
next_busno = 0;
+ need_domain_info = 1;
+ }
pci_bus_size_bridges(bus);
pci_bus_assign_resources(bus);
@@ -51,10 +58,21 @@ static void __devinit pcibios_scanbus(struct pci_channel *hose)
static DEFINE_MUTEX(pci_scan_mutex);
-void __devinit register_pci_controller(struct pci_channel *hose)
+int __devinit register_pci_controller(struct pci_channel *hose)
{
- request_resource(&iomem_resource, hose->mem_resource);
- request_resource(&ioport_resource, hose->io_resource);
+ int i;
+
+ for (i = 0; i < hose->nr_resources; i++) {
+ struct resource *res = hose->resources + i;
+
+ if (res->flags & IORESOURCE_IO) {
+ if (request_resource(&ioport_resource, res) < 0)
+ goto out;
+ } else {
+ if (request_resource(&iomem_resource, res) < 0)
+ goto out;
+ }
+ }
*hose_tail = hose;
hose_tail = &hose->next;
@@ -68,6 +86,11 @@ void __devinit register_pci_controller(struct pci_channel *hose)
}
/*
+ * Setup the ERR/PERR and SERR timers, if available.
+ */
+ pcibios_enable_timers(hose);
+
+ /*
* Scan the bus if it is register after the PCI subsystem
* initialization.
*/
@@ -76,6 +99,15 @@ void __devinit register_pci_controller(struct pci_channel *hose)
pcibios_scanbus(hose);
mutex_unlock(&pci_scan_mutex);
}
+
+ return 0;
+
+out:
+ for (--i; i >= 0; i--)
+ release_resource(&hose->resources[i]);
+
+ printk(KERN_WARNING "Skipping PCI bus scan due to resource conflict\n");
+ return -1;
}
static int __init pcibios_init(void)
@@ -127,11 +159,13 @@ void __devinit pcibios_fixup_bus(struct pci_bus *bus)
{
struct pci_dev *dev = bus->self;
struct list_head *ln;
- struct pci_channel *chan = bus->sysdata;
+ struct pci_channel *hose = bus->sysdata;
if (!dev) {
- bus->resource[0] = chan->io_resource;
- bus->resource[1] = chan->mem_resource;
+ int i;
+
+ for (i = 0; i < hose->nr_resources; i++)
+ bus->resource[i] = hose->resources + i;
}
for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) {
@@ -152,30 +186,25 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res,
resource_size_t size, resource_size_t align)
{
struct pci_dev *dev = data;
- struct pci_channel *chan = dev->sysdata;
+ struct pci_channel *hose = dev->sysdata;
resource_size_t start = res->start;
if (res->flags & IORESOURCE_IO) {
- if (start < PCIBIOS_MIN_IO + chan->io_resource->start)
- start = PCIBIOS_MIN_IO + chan->io_resource->start;
+ if (start < PCIBIOS_MIN_IO + hose->resources[0].start)
+ start = PCIBIOS_MIN_IO + hose->resources[0].start;
/*
* Put everything into 0x00-0xff region modulo 0x400.
*/
- if (start & 0x300) {
+ if (start & 0x300)
start = (start + 0x3ff) & ~0x3ff;
- res->start = start;
- }
- } else if (res->flags & IORESOURCE_MEM) {
- if (start < PCIBIOS_MIN_MEM + chan->mem_resource->start)
- start = PCIBIOS_MIN_MEM + chan->mem_resource->start;
}
return start;
}
void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
- struct resource *res)
+ struct resource *res)
{
struct pci_channel *hose = dev->sysdata;
unsigned long offset = 0;
@@ -189,9 +218,8 @@ void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
region->end = res->end - offset;
}
-void __devinit
-pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
- struct pci_bus_region *region)
+void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
+ struct pci_bus_region *region)
{
struct pci_channel *hose = dev->sysdata;
unsigned long offset = 0;
@@ -274,6 +302,86 @@ char * __devinit pcibios_setup(char *str)
return str;
}
+static void __init
+pcibios_bus_report_status_early(struct pci_channel *hose,
+ int top_bus, int current_bus,
+ unsigned int status_mask, int warn)
+{
+ unsigned int pci_devfn;
+ u16 status;
+ int ret;
+
+ for (pci_devfn = 0; pci_devfn < 0xff; pci_devfn++) {
+ if (PCI_FUNC(pci_devfn))
+ continue;
+ ret = early_read_config_word(hose, top_bus, current_bus,
+ pci_devfn, PCI_STATUS, &status);
+ if (ret != PCIBIOS_SUCCESSFUL)
+ continue;
+ if (status == 0xffff)
+ continue;
+
+ early_write_config_word(hose, top_bus, current_bus,
+ pci_devfn, PCI_STATUS,
+ status & status_mask);
+ if (warn)
+ printk("(%02x:%02x: %04X) ", current_bus,
+ pci_devfn, status);
+ }
+}
+
+/*
+ * We can't use pci_find_device() here since we are
+ * called from interrupt context.
+ */
+static void __init_refok
+pcibios_bus_report_status(struct pci_bus *bus, unsigned int status_mask,
+ int warn)
+{
+ struct pci_dev *dev;
+
+ list_for_each_entry(dev, &bus->devices, bus_list) {
+ u16 status;
+
+ /*
+ * ignore host bridge - we handle
+ * that separately
+ */
+ if (dev->bus->number == 0 && dev->devfn == 0)
+ continue;
+
+ pci_read_config_word(dev, PCI_STATUS, &status);
+ if (status == 0xffff)
+ continue;
+
+ if ((status & status_mask) == 0)
+ continue;
+
+ /* clear the status errors */
+ pci_write_config_word(dev, PCI_STATUS, status & status_mask);
+
+ if (warn)
+ printk("(%s: %04X) ", pci_name(dev), status);
+ }
+
+ list_for_each_entry(dev, &bus->devices, bus_list)
+ if (dev->subordinate)
+ pcibios_bus_report_status(dev->subordinate, status_mask, warn);
+}
+
+void __init_refok pcibios_report_status(unsigned int status_mask, int warn)
+{
+ struct pci_channel *hose;
+
+ for (hose = hose_head; hose; hose = hose->next) {
+ if (unlikely(!hose->bus))
+ pcibios_bus_report_status_early(hose, hose_head->index,
+ hose->index, status_mask, warn);
+ else
+ pcibios_bus_report_status(hose->bus, status_mask, warn);
+ }
+}
+
int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
enum pci_mmap_state mmap_state, int write_combine)
{
@@ -302,9 +410,15 @@ static void __iomem *ioport_map_pci(struct pci_dev *dev,
{
struct pci_channel *chan = dev->sysdata;
- if (!chan->io_map_base)
+ if (unlikely(!chan->io_map_base)) {
chan->io_map_base = generic_io_base;
+ if (pci_domains_supported)
+ panic("To avoid data corruption io_map_base MUST be "
+ "set with multiple PCI domains.");
+ }
+
+
return (void __iomem *)(chan->io_map_base + port);
}
@@ -321,20 +435,9 @@ void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen)
if (flags & IORESOURCE_IO)
return ioport_map_pci(dev, start, len);
-
- /*
- * Presently the IORESOURCE_MEM case is a bit special, most
- * SH7751 style PCI controllers have PCI memory at a fixed
- * location in the address space where no remapping is desired.
- * With the IORESOURCE_MEM case more care has to be taken
- * to inhibit page table mapping for legacy cores, but this is
- * punted off to __ioremap().
- * -- PFM.
- */
if (flags & IORESOURCE_MEM) {
if (flags & IORESOURCE_CACHEABLE)
return ioremap(start, len);
-
return ioremap_nocache(start, len);
}
diff --git a/arch/sh/drivers/pci/pcie-sh7786.c b/arch/sh/drivers/pci/pcie-sh7786.c
index ac37ee879ba..ae91a2dd918 100644
--- a/arch/sh/drivers/pci/pcie-sh7786.c
+++ b/arch/sh/drivers/pci/pcie-sh7786.c
@@ -1,7 +1,7 @@
/*
* Low-Level PCI Express Support for the SH7786
*
- * Copyright (C) 2009 Paul Mundt
+ * Copyright (C) 2009 - 2010 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
@@ -30,60 +30,84 @@ static struct sh7786_pcie_hwops {
int (*port_init_hw)(struct sh7786_pcie_port *port);
} *sh7786_pcie_hwops;
-static struct resource sh7786_pci_32bit_mem_resources[] = {
+static struct resource sh7786_pci0_resources[] = {
{
- .name = "pci0_mem",
- .start = SH4A_PCIMEM_BASEA,
- .end = SH4A_PCIMEM_BASEA + SZ_64M - 1,
- .flags = IORESOURCE_MEM,
+ .name = "PCIe0 IO",
+ .start = 0xfd000000,
+ .end = 0xfd000000 + SZ_8M - 1,
+ .flags = IORESOURCE_IO,
}, {
- .name = "pci1_mem",
- .start = SH4A_PCIMEM_BASEA1,
- .end = SH4A_PCIMEM_BASEA1 + SZ_64M - 1,
- .flags = IORESOURCE_MEM,
+ .name = "PCIe0 MEM 0",
+ .start = 0xc0000000,
+ .end = 0xc0000000 + SZ_512M - 1,
+ .flags = IORESOURCE_MEM | IORESOURCE_MEM_32BIT,
}, {
- .name = "pci2_mem",
- .start = SH4A_PCIMEM_BASEA2,
- .end = SH4A_PCIMEM_BASEA2 + SZ_64M - 1,
+ .name = "PCIe0 MEM 1",
+ .start = 0x10000000,
+ .end = 0x10000000 + SZ_64M - 1,
.flags = IORESOURCE_MEM,
+ }, {
+ .name = "PCIe0 MEM 2",
+ .start = 0xfe100000,
+ .end = 0xfe100000 + SZ_1M - 1,
},
};
-static struct resource sh7786_pci_29bit_mem_resource = {
- .start = SH4A_PCIMEM_BASE,
- .end = SH4A_PCIMEM_BASE + SZ_64M - 1,
- .flags = IORESOURCE_MEM,
+static struct resource sh7786_pci1_resources[] = {
+ {
+ .name = "PCIe1 IO",
+ .start = 0xfd800000,
+ .end = 0xfd800000 + SZ_8M - 1,
+ .flags = IORESOURCE_IO,
+ }, {
+ .name = "PCIe1 MEM 0",
+ .start = 0xa0000000,
+ .end = 0xa0000000 + SZ_512M - 1,
+ .flags = IORESOURCE_MEM | IORESOURCE_MEM_32BIT,
+ }, {
+ .name = "PCIe1 MEM 1",
+ .start = 0x30000000,
+ .end = 0x30000000 + SZ_256M - 1,
+ .flags = IORESOURCE_MEM | IORESOURCE_MEM_32BIT,
+ }, {
+ .name = "PCIe1 MEM 2",
+ .start = 0xfe300000,
+ .end = 0xfe300000 + SZ_1M - 1,
+ },
};
-static struct resource sh7786_pci_io_resources[] = {
+static struct resource sh7786_pci2_resources[] = {
{
- .name = "pci0_io",
- .start = SH4A_PCIIO_BASE,
- .end = SH4A_PCIIO_BASE + SZ_8M - 1,
- .flags = IORESOURCE_IO,
+ .name = "PCIe2 IO",
+ .start = 0xfc800000,
+ .end = 0xfc800000 + SZ_4M - 1,
}, {
- .name = "pci1_io",
- .start = SH4A_PCIIO_BASE1,
- .end = SH4A_PCIIO_BASE1 + SZ_8M - 1,
- .flags = IORESOURCE_IO,
+ .name = "PCIe2 MEM 0",
+ .start = 0x80000000,
+ .end = 0x80000000 + SZ_512M - 1,
+ .flags = IORESOURCE_MEM | IORESOURCE_MEM_32BIT,
}, {
- .name = "pci2_io",
- .start = SH4A_PCIIO_BASE2,
- .end = SH4A_PCIIO_BASE2 + SZ_4M - 1,
- .flags = IORESOURCE_IO,
+ .name = "PCIe2 MEM 1",
+ .start = 0x20000000,
+ .end = 0x20000000 + SZ_256M - 1,
+ .flags = IORESOURCE_MEM | IORESOURCE_MEM_32BIT,
+ }, {
+ .name = "PCIe2 MEM 2",
+ .start = 0xfcd00000,
+ .end = 0xfcd00000 + SZ_1M - 1,
},
};
extern struct pci_ops sh7786_pci_ops;
-#define DEFINE_CONTROLLER(start, idx) \
-{ \
- .pci_ops = &sh7786_pci_ops, \
- .reg_base = start, \
- /* mem_resource filled in at probe time */ \
- .mem_offset = 0, \
- .io_resource = &sh7786_pci_io_resources[idx], \
- .io_offset = 0, \
+#define DEFINE_CONTROLLER(start, idx) \
+{ \
+ .pci_ops = &sh7786_pci_ops, \
+ .resources = sh7786_pci##idx##_resources, \
+ .nr_resources = ARRAY_SIZE(sh7786_pci##idx##_resources), \
+ .reg_base = start, \
+ .mem_offset = 0, \
+ .io_offset = 0, \
}
static struct pci_channel sh7786_pci_channels[] = {
@@ -180,7 +204,9 @@ static int pcie_init(struct sh7786_pcie_port *port)
{
struct pci_channel *chan = port->hose;
unsigned int data;
- int ret;
+ phys_addr_t memphys;
+ size_t memsize;
+ int ret, i;
/* Begin initialization */
pci_write_reg(chan, 0, SH4A_PCIETCTLR);
@@ -203,15 +229,24 @@ static int pcie_init(struct sh7786_pcie_port *port)
data |= PCI_CAP_ID_EXP;
pci_write_reg(chan, data, SH4A_PCIEEXPCAP0);
- /* Enable x4 link width and extended sync. */
+ /* Enable data link layer active state reporting */
+ pci_write_reg(chan, PCI_EXP_LNKCAP_DLLLARC, SH4A_PCIEEXPCAP3);
+
+ /* Enable extended sync and ASPM L0s support */
data = pci_read_reg(chan, SH4A_PCIEEXPCAP4);
- data &= ~(PCI_EXP_LNKSTA_NLW << 16);
- data |= (1 << 22) | PCI_EXP_LNKCTL_ES;
+ data &= ~PCI_EXP_LNKCTL_ASPMC;
+ data |= PCI_EXP_LNKCTL_ES | 1;
pci_write_reg(chan, data, SH4A_PCIEEXPCAP4);
+ /* Write out the physical slot number */
+ data = pci_read_reg(chan, SH4A_PCIEEXPCAP5);
+ data &= ~PCI_EXP_SLTCAP_PSN;
+ data |= (port->index + 1) << 19;
+ pci_write_reg(chan, data, SH4A_PCIEEXPCAP5);
+
/* Set the completion timer timeout to the maximum 32ms. */
data = pci_read_reg(chan, SH4A_PCIETLCTLR);
- data &= ~0xffff;
+ data &= ~0x3f00;
data |= 0x32 << 8;
pci_write_reg(chan, data, SH4A_PCIETLCTLR);
@@ -224,6 +259,33 @@ static int pcie_init(struct sh7786_pcie_port *port)
data |= (0xff << 16);
pci_write_reg(chan, data, SH4A_PCIEMACCTLR);
+ memphys = __pa(memory_start);
+ memsize = roundup_pow_of_two(memory_end - memory_start);
+
+ /*
+ * If there's more than 512MB of memory, we need to roll over to
+ * LAR1/LAMR1.
+ */
+ if (memsize > SZ_512M) {
+ __raw_writel(memphys + SZ_512M, chan->reg_base + SH4A_PCIELAR1);
+ __raw_writel(((memsize - SZ_512M) - SZ_256) | 1,
+ chan->reg_base + SH4A_PCIELAMR1);
+ memsize = SZ_512M;
+ } else {
+ /*
+ * Otherwise just zero it out and disable it.
+ */
+ __raw_writel(0, chan->reg_base + SH4A_PCIELAR1);
+ __raw_writel(0, chan->reg_base + SH4A_PCIELAMR1);
+ }
+
+ /*
+ * LAR0/LAMR0 covers up to the first 512MB, which is enough to
+ * cover all of lowmem on most platforms.
+ */
+ __raw_writel(memphys, chan->reg_base + SH4A_PCIELAR0);
+ __raw_writel((memsize - SZ_256) | 1, chan->reg_base + SH4A_PCIELAMR0);
+
/* Finish initialization */
data = pci_read_reg(chan, SH4A_PCIETCTLR);
data |= 0x1;
@@ -243,10 +305,14 @@ static int pcie_init(struct sh7786_pcie_port *port)
if (unlikely(ret != 0))
return -ENODEV;
- pci_write_reg(chan, 0x00100007, SH4A_PCIEPCICONF1);
+ data = pci_read_reg(chan, SH4A_PCIEPCICONF1);
+ data &= ~(PCI_STATUS_DEVSEL_MASK << 16);
+ data |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
+ (PCI_STATUS_CAP_LIST | PCI_STATUS_DEVSEL_FAST) << 16;
+ pci_write_reg(chan, data, SH4A_PCIEPCICONF1);
+
pci_write_reg(chan, 0x80888000, SH4A_PCIETXVC0DCTLR);
pci_write_reg(chan, 0x00222000, SH4A_PCIERXVC0DCTLR);
- pci_write_reg(chan, 0x000050A0, SH4A_PCIEEXPCAP2);
wmb();
@@ -254,15 +320,32 @@ static int pcie_init(struct sh7786_pcie_port *port)
printk(KERN_NOTICE "PCI: PCIe#%d link width %d\n",
port->index, (data >> 20) & 0x3f);
- pci_write_reg(chan, 0x007c0000, SH4A_PCIEPAMR0);
- pci_write_reg(chan, 0x00000000, SH4A_PCIEPARH0);
- pci_write_reg(chan, 0x00000000, SH4A_PCIEPARL0);
- pci_write_reg(chan, 0x80000100, SH4A_PCIEPTCTLR0);
- pci_write_reg(chan, 0x03fc0000, SH4A_PCIEPAMR2);
- pci_write_reg(chan, 0x00000000, SH4A_PCIEPARH2);
- pci_write_reg(chan, 0x00000000, SH4A_PCIEPARL2);
- pci_write_reg(chan, 0x80000000, SH4A_PCIEPTCTLR2);
+ for (i = 0; i < chan->nr_resources; i++) {
+ struct resource *res = chan->resources + i;
+ resource_size_t size;
+ u32 enable_mask;
+
+ pci_write_reg(chan, 0x00000000, SH4A_PCIEPTCTLR(i));
+
+ size = resource_size(res);
+
+ /*
+ * The PAMR mask is calculated in units of 256kB, which
+ * keeps things pretty simple.
+ */
+ __raw_writel(((roundup_pow_of_two(size) / SZ_256K) - 1) << 18,
+ chan->reg_base + SH4A_PCIEPAMR(i));
+
+ pci_write_reg(chan, 0x00000000, SH4A_PCIEPARH(i));
+ pci_write_reg(chan, 0x00000000, SH4A_PCIEPARL(i));
+
+ enable_mask = MASK_PARE;
+ if (res->flags & IORESOURCE_IO)
+ enable_mask |= MASK_SPC;
+
+ pci_write_reg(chan, enable_mask, SH4A_PCIEPTCTLR(i));
+ }
return 0;
}
@@ -296,9 +379,7 @@ static int __devinit sh7786_pcie_init_hw(struct sh7786_pcie_port *port)
if (unlikely(ret < 0))
return ret;
- register_pci_controller(port->hose);
-
- return 0;
+ return register_pci_controller(port->hose);
}
static struct sh7786_pcie_hwops sh7786_65nm_pcie_hwops __initdata = {
@@ -332,17 +413,7 @@ static int __init sh7786_pcie_init(void)
port->index = i;
port->hose = sh7786_pci_channels + i;
- port->hose->io_map_base = port->hose->io_resource->start;
-
- /*
- * Check if we are booting in 29 or 32-bit mode
- *
- * 32-bit mode provides each controller with its own
- * memory window, while 29-bit mode uses a shared one.
- */
- port->hose->mem_resource = test_mode_pin(MODE_PIN10) ?
- &sh7786_pci_32bit_mem_resources[i] :
- &sh7786_pci_29bit_mem_resource;
+ port->hose->io_map_base = port->hose->resources[0].start;
ret |= sh7786_pcie_hwops->port_init_hw(port);
}
diff --git a/arch/sh/drivers/pci/pcie-sh7786.h b/arch/sh/drivers/pci/pcie-sh7786.h
index c655290a775..90a6992576b 100644
--- a/arch/sh/drivers/pci/pcie-sh7786.h
+++ b/arch/sh/drivers/pci/pcie-sh7786.h
@@ -30,47 +30,9 @@
* for other(Max Payload Size=4096B,PCIIO_SIZE=8M)
*/
-/* PCI0-0: PCI I/O space */
-#define SH4A_PCIIO_BASE 0xFD000000 /* PCI I/O for controller 0 */
-#define SH4A_PCIIO_BASE1 0xFD800000 /* PCI I/O for controller 1 (Rev1.14)*/
-#define SH4A_PCIIO_BASE2 0xFC800000 /* PCI I/O for controller 2 (Rev1.171)*/
-
-#define SH4A_PCIIO_SIZE64 0x00010000 /* PLX allows only 64K */
-#define SH4A_PCIIO_SIZE 0x00800000 /* 8M */
-#define SH4A_PCIIO_SIZE2 0x00400000 /* 4M (Rev1.171)*/
-
-/* PCI0-1: PCI memory space 29-bit address */
-#define SH4A_PCIMEM_BASE 0x10000000
-#define SH4A_PCIMEM_SIZE 0x04000000 /* 64M */
-
-/* PCI0-2: PCI memory space 32-bit address */
-#define SH4A_PCIMEM_BASEA 0xC0000000 /* for controller 0 */
-#define SH4A_PCIMEM_BASEA1 0xA0000000 /* for controller 1 (Rev1.14)*/
-#define SH4A_PCIMEM_BASEA2 0x80000000 /* for controller 2 (Rev1.171)*/
-#define SH4A_PCIMEM_SIZEA 0x20000000 /* 512M */
-
/* PCI0: PCI memory target transfer 32-bit address translation value(Rev1.11T)*/
#define SH4A_PCIBMSTR_TRANSLATION 0x20000000
-#define SH4A_PCI_DEVICE_ID 0x0002
-#define SH4A_PCI_VENDOR_ID 0x1912
-
-// PCI compatible 000-03f
-#define PCI_CMD 0x004
-#define PCI_RID 0x008
-#define PCI_IBAR 0x010
-#define PCI_MBAR0 0x014
-#define PCI_MBAR1 0x018
-
-/* PCI power management/MSI/capablity 040-0ff */
-/* PCIE extended 100-fff */
-
-/* SH7786 device identification */ // Rev1.171
-#define SH4A_PVR (0xFF000030)
-#define SH4A_PVR_SHX3 (0x10400000)
-#define SH4A_PRR (0xFF000044)
-#define SH4A_PRR_SH7786 (0x00000400) // Rev1.171
-
/* SPVCR0 */
#define SH4A_PCIEVCR0 (0x000000) /* R - 0x0000 0000 32 */
#define BITS_TOP_MB (24)
@@ -350,23 +312,23 @@
#define SH4A_PCIECSAR5 (0x0202B4) /* R/W R/W 0x0000 0000 32 */
#define SH4A_PCIESTCTLR5 (0x0202B8) /* R/W R/W 0x0000 0000 32 */
-/* PCIEPARL0 */
-#define SH4A_PCIEPARL0 (0x020400) /* R/W R/W 0x0000 0000 32 */
+/* PCIEPARL */
+#define SH4A_PCIEPARL(x) (0x020400 + ((x) * 0x20)) /* R/W R/W 0x0000 0000 32 */
#define BITS_PAL (18)
#define MASK_PAL (0x3fff<<BITS_PAL)
-/* PCIEPARH0 */
-#define SH4A_PCIEPARH0 (0x020404) /* R/W R/W 0x0000 0000 32 */
+/* PCIEPARH */
+#define SH4A_PCIEPARH(x) (0x020404 + ((x) * 0x20)) /* R/W R/W 0x0000 0000 32 */
#define BITS_PAH (0)
#define MASK_PAH (0xffffffff<<BITS_PAH)
-/* PCIEPAMR0 */
-#define SH4A_PCIEPAMR0 (0x020408) /* R/W R/W 0x0000 0000 32 */
+/* PCIEPAMR */
+#define SH4A_PCIEPAMR(x) (0x020408 + ((x) * 0x20)) /* R/W R/W 0x0000 0000 32 */
#define BITS_PAM (18)
#define MASK_PAM (0x3fff<<BITS_PAM)
-/* PCIEPTCTLR0 */
-#define SH4A_PCIEPTCTLR0 (0x02040C) /* R/W R/W 0x0000 0000 32 */
+/* PCIEPTCTLR */
+#define SH4A_PCIEPTCTLR(x) (0x02040C + ((x) * 0x20))
#define BITS_PARE (31)
#define MASK_PARE (0x1<<BITS_PARE)
#define BITS_TC (20)
@@ -378,26 +340,6 @@
#define BITS_SPC (8)
#define MASK_SPC (0x1<<BITS_SPC)
-#define SH4A_PCIEPARL1 (0x020420) /* R/W R/W 0x0000 0000 32 */
-#define SH4A_PCIEPARH1 (0x020424) /* R/W R/W 0x0000 0000 32 */
-#define SH4A_PCIEPAMR1 (0x020428) /* R/W R/W 0x0000 0000 32 */
-#define SH4A_PCIEPTCTLR1 (0x02042C) /* R/W R/W 0x0000 0000 32 */
-#define SH4A_PCIEPARL2 (0x020440) /* R/W R/W 0x0000 0000 32 */
-#define SH4A_PCIEPARH2 (0x020444) /* R/W R/W 0x0000 0000 32 */
-#define SH4A_PCIEPAMR2 (0x020448) /* R/W R/W 0x0000 0000 32 */
-#define SH4A_PCIEPTCTLR2 (0x02044C) /* R/W R/W 0x0000 0000 32 */
-#define SH4A_PCIEPARL3 (0x020460) /* R/W R/W 0x0000 0000 32 */
-#define SH4A_PCIEPARH3 (0x020464) /* R/W R/W 0x0000 0000 32 */
-#define SH4A_PCIEPAMR3 (0x020468) /* R/W R/W 0x0000 0000 32 */
-#define SH4A_PCIEPTCTLR3 (0x02046C) /* R/W R/W 0x0000 0000 32 */
-#define SH4A_PCIEPARL4 (0x020480) /* R/W R/W 0x0000 0000 32 */
-#define SH4A_PCIEPARH4 (0x020484) /* R/W R/W 0x0000 0000 32 */
-#define SH4A_PCIEPAMR4 (0x020488) /* R/W R/W 0x0000 0000 32 */
-#define SH4A_PCIEPTCTLR4 (0x02048C) /* R/W R/W 0x0000 0000 32 */
-#define SH4A_PCIEPARL5 (0x0204A0) /* R/W R/W 0x0000 0000 32 */
-#define SH4A_PCIEPARH5 (0x0204A4) /* R/W R/W 0x0000 0000 32 */
-#define SH4A_PCIEPAMR5 (0x0204A8) /* R/W R/W 0x0000 0000 32 */
-#define SH4A_PCIEPTCTLR5 (0x0204AC) /* R/W R/W 0x0000 0000 32 */
#define SH4A_PCIEDMAOR (0x021000) /* R/W R/W 0x0000 0000 32 */
#define SH4A_PCIEDMSAR0 (0x021100) /* R/W R/W 0x0000 0000 32 */
#define SH4A_PCIEDMSAHR0 (0x021104) /* R/W R/W 0x0000 0000 32 */
diff --git a/arch/sh/drivers/superhyway/ops-sh4-202.c b/arch/sh/drivers/superhyway/ops-sh4-202.c
index 3b14bf860db..6da62e9475c 100644
--- a/arch/sh/drivers/superhyway/ops-sh4-202.c
+++ b/arch/sh/drivers/superhyway/ops-sh4-202.c
@@ -134,8 +134,8 @@ static int sh4202_read_vcr(unsigned long base, struct superhyway_vcr_info *vcr)
*
* Do not trust the documentation, for it is evil.
*/
- vcrh = ctrl_inl(base);
- vcrl = ctrl_inl(base + sizeof(u32));
+ vcrh = __raw_readl(base);
+ vcrl = __raw_readl(base + sizeof(u32));
tmp = ((u64)vcrh << 32) | vcrl;
memcpy(vcr, &tmp, sizeof(u64));
@@ -147,8 +147,8 @@ static int sh4202_write_vcr(unsigned long base, struct superhyway_vcr_info vcr)
{
u64 tmp = *(u64 *)&vcr;
- ctrl_outl((tmp >> 32) & 0xffffffff, base);
- ctrl_outl(tmp & 0xffffffff, base + sizeof(u32));
+ __raw_writel((tmp >> 32) & 0xffffffff, base);
+ __raw_writel(tmp & 0xffffffff, base + sizeof(u32));
return 0;
}
diff --git a/arch/sh/include/asm/Kbuild b/arch/sh/include/asm/Kbuild
index e121c30f797..46cb93477bc 100644
--- a/arch/sh/include/asm/Kbuild
+++ b/arch/sh/include/asm/Kbuild
@@ -1,6 +1,8 @@
include include/asm-generic/Kbuild.asm
-header-y += cachectl.h cpu-features.h
+header-y += cachectl.h
+header-y += cpu-features.h
+header-y += hw_breakpoint.h
unifdef-y += unistd_32.h
unifdef-y += unistd_64.h
diff --git a/arch/sh/include/asm/addrspace.h b/arch/sh/include/asm/addrspace.h
index 99d6b3ecbe2..446b3831c21 100644
--- a/arch/sh/include/asm/addrspace.h
+++ b/arch/sh/include/asm/addrspace.h
@@ -28,7 +28,7 @@
/* Returns the privileged segment base of a given address */
#define PXSEG(a) (((unsigned long)(a)) & 0xe0000000)
-#if defined(CONFIG_29BIT) || defined(CONFIG_PMB_FIXED)
+#ifdef CONFIG_29BIT
/*
* Map an address to a certain privileged segment
*/
@@ -40,7 +40,15 @@
((__typeof__(a))(((unsigned long)(a) & 0x1fffffff) | P3SEG))
#define P4SEGADDR(a) \
((__typeof__(a))(((unsigned long)(a) & 0x1fffffff) | P4SEG))
-#endif /* 29BIT || PMB_FIXED */
+#else
+/*
+ * These will never work in 32-bit, don't even bother.
+ */
+#define P1SEGADDR(a) __futile_remapping_attempt
+#define P2SEGADDR(a) __futile_remapping_attempt
+#define P3SEGADDR(a) __futile_remapping_attempt
+#define P4SEGADDR(a) __futile_remapping_attempt
+#endif
#endif /* P1SEG */
/* Check if an address can be reached in 29 bits */
@@ -57,11 +65,5 @@
#define P3_ADDR_MAX P4SEG
#endif
-#ifndef __ASSEMBLY__
-#ifdef CONFIG_PMB
-extern int __in_29bit_mode(void);
-#endif /* CONFIG_PMB */
-#endif /* __ASSEMBLY__ */
-
#endif /* __KERNEL__ */
#endif /* __ASM_SH_ADDRSPACE_H */
diff --git a/arch/sh/include/asm/alignment.h b/arch/sh/include/asm/alignment.h
new file mode 100644
index 00000000000..b12efecf529
--- /dev/null
+++ b/arch/sh/include/asm/alignment.h
@@ -0,0 +1,21 @@
+#ifndef __ASM_SH_ALIGNMENT_H
+#define __ASM_SH_ALIGNMENT_H
+
+#include <linux/types.h>
+
+extern void inc_unaligned_byte_access(void);
+extern void inc_unaligned_word_access(void);
+extern void inc_unaligned_dword_access(void);
+extern void inc_unaligned_multi_access(void);
+extern void inc_unaligned_user_access(void);
+extern void inc_unaligned_kernel_access(void);
+
+#define UM_WARN (1 << 0)
+#define UM_FIXUP (1 << 1)
+#define UM_SIGNAL (1 << 2)
+
+extern unsigned int unaligned_user_action(void);
+
+extern void unaligned_fixups_notify(struct task_struct *, insn_size_t, struct pt_regs *);
+
+#endif /* __ASM_SH_ALIGNMENT_H */
diff --git a/arch/sh/include/asm/atomic-grb.h b/arch/sh/include/asm/atomic-grb.h
index 4c5b7dbfced..a273c88578f 100644
--- a/arch/sh/include/asm/atomic-grb.h
+++ b/arch/sh/include/asm/atomic-grb.h
@@ -120,50 +120,4 @@ static inline void atomic_set_mask(unsigned int mask, atomic_t *v)
: "memory" , "r0", "r1");
}
-static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
-{
- int ret;
-
- __asm__ __volatile__ (
- " .align 2 \n\t"
- " mova 1f, r0 \n\t"
- " nop \n\t"
- " mov r15, r1 \n\t"
- " mov #-8, r15 \n\t"
- " mov.l @%1, %0 \n\t"
- " cmp/eq %2, %0 \n\t"
- " bf 1f \n\t"
- " mov.l %3, @%1 \n\t"
- "1: mov r1, r15 \n\t"
- : "=&r" (ret)
- : "r" (v), "r" (old), "r" (new)
- : "memory" , "r0", "r1" , "t");
-
- return ret;
-}
-
-static inline int atomic_add_unless(atomic_t *v, int a, int u)
-{
- int ret;
- unsigned long tmp;
-
- __asm__ __volatile__ (
- " .align 2 \n\t"
- " mova 1f, r0 \n\t"
- " nop \n\t"
- " mov r15, r1 \n\t"
- " mov #-12, r15 \n\t"
- " mov.l @%2, %1 \n\t"
- " mov %1, %0 \n\t"
- " cmp/eq %4, %0 \n\t"
- " bt/s 1f \n\t"
- " add %3, %1 \n\t"
- " mov.l %1, @%2 \n\t"
- "1: mov r1, r15 \n\t"
- : "=&r" (ret), "=&r" (tmp)
- : "r" (v), "r" (a), "r" (u)
- : "memory" , "r0", "r1" , "t");
-
- return ret != u;
-}
#endif /* __ASM_SH_ATOMIC_GRB_H */
diff --git a/arch/sh/include/asm/atomic-llsc.h b/arch/sh/include/asm/atomic-llsc.h
index b040e1e0861..4b00b78e3f4 100644
--- a/arch/sh/include/asm/atomic-llsc.h
+++ b/arch/sh/include/asm/atomic-llsc.h
@@ -104,31 +104,4 @@ static inline void atomic_set_mask(unsigned int mask, atomic_t *v)
: "t");
}
-#define atomic_cmpxchg(v, o, n) (cmpxchg(&((v)->counter), (o), (n)))
-
-/**
- * atomic_add_unless - add unless the number is a given value
- * @v: pointer of type atomic_t
- * @a: the amount to add to v...
- * @u: ...unless v is equal to u.
- *
- * Atomically adds @a to @v, so long as it was not @u.
- * Returns non-zero if @v was not @u, and zero otherwise.
- */
-static inline int atomic_add_unless(atomic_t *v, int a, int u)
-{
- int c, old;
- c = atomic_read(v);
- for (;;) {
- if (unlikely(c == (u)))
- break;
- old = atomic_cmpxchg((v), c, c + (a));
- if (likely(old == c))
- break;
- c = old;
- }
-
- return c != (u);
-}
-
#endif /* __ASM_SH_ATOMIC_LLSC_H */
diff --git a/arch/sh/include/asm/atomic.h b/arch/sh/include/asm/atomic.h
index b16388d7195..275a448ae8c 100644
--- a/arch/sh/include/asm/atomic.h
+++ b/arch/sh/include/asm/atomic.h
@@ -25,58 +25,43 @@
#endif
#define atomic_add_negative(a, v) (atomic_add_return((a), (v)) < 0)
+#define atomic_dec_return(v) atomic_sub_return(1, (v))
+#define atomic_inc_return(v) atomic_add_return(1, (v))
+#define atomic_inc_and_test(v) (atomic_inc_return(v) == 0)
+#define atomic_sub_and_test(i,v) (atomic_sub_return((i), (v)) == 0)
+#define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0)
+#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
-#define atomic_dec_return(v) atomic_sub_return(1,(v))
-#define atomic_inc_return(v) atomic_add_return(1,(v))
+#define atomic_inc(v) atomic_add(1, (v))
+#define atomic_dec(v) atomic_sub(1, (v))
-/*
- * atomic_inc_and_test - increment and test
+#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
+#define atomic_cmpxchg(v, o, n) (cmpxchg(&((v)->counter), (o), (n)))
+
+/**
+ * atomic_add_unless - add unless the number is a given value
* @v: pointer of type atomic_t
+ * @a: the amount to add to v...
+ * @u: ...unless v is equal to u.
*
- * Atomically increments @v by 1
- * and returns true if the result is zero, or false for all
- * other cases.
+ * Atomically adds @a to @v, so long as it was not @u.
+ * Returns non-zero if @v was not @u, and zero otherwise.
*/
-#define atomic_inc_and_test(v) (atomic_inc_return(v) == 0)
-
-#define atomic_sub_and_test(i,v) (atomic_sub_return((i), (v)) == 0)
-#define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0)
-
-#define atomic_inc(v) atomic_add(1,(v))
-#define atomic_dec(v) atomic_sub(1,(v))
-
-#if !defined(CONFIG_GUSA_RB) && !defined(CONFIG_CPU_SH4A)
-static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
-{
- int ret;
- unsigned long flags;
-
- local_irq_save(flags);
- ret = v->counter;
- if (likely(ret == old))
- v->counter = new;
- local_irq_restore(flags);
-
- return ret;
-}
-
static inline int atomic_add_unless(atomic_t *v, int a, int u)
{
- int ret;
- unsigned long flags;
-
- local_irq_save(flags);
- ret = v->counter;
- if (ret != u)
- v->counter += a;
- local_irq_restore(flags);
-
- return ret != u;
+ int c, old;
+ c = atomic_read(v);
+ for (;;) {
+ if (unlikely(c == (u)))
+ break;
+ old = atomic_cmpxchg((v), c, c + (a));
+ if (likely(old == c))
+ break;
+ c = old;
+ }
+
+ return c != (u);
}
-#endif /* !CONFIG_GUSA_RB && !CONFIG_CPU_SH4A */
-
-#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
-#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
#define smp_mb__before_atomic_dec() smp_mb()
#define smp_mb__after_atomic_dec() smp_mb()
diff --git a/arch/sh/include/asm/clock.h b/arch/sh/include/asm/clock.h
index 9fe7d7f8af4..11da4c5beb6 100644
--- a/arch/sh/include/asm/clock.h
+++ b/arch/sh/include/asm/clock.h
@@ -146,8 +146,17 @@ int sh_clk_mstp32_register(struct clk *clks, int nr);
.flags = _flags, \
}
+struct clk_div4_table {
+ struct clk_div_mult_table *div_mult_table;
+ void (*kick)(struct clk *clk);
+};
+
int sh_clk_div4_register(struct clk *clks, int nr,
- struct clk_div_mult_table *table);
+ struct clk_div4_table *table);
+int sh_clk_div4_enable_register(struct clk *clks, int nr,
+ struct clk_div4_table *table);
+int sh_clk_div4_reparent_register(struct clk *clks, int nr,
+ struct clk_div4_table *table);
#define SH_CLK_DIV6(_name, _parent, _reg, _flags) \
{ \
diff --git a/arch/sh/include/asm/cmpxchg-grb.h b/arch/sh/include/asm/cmpxchg-grb.h
index e2681abe764..4676bf57693 100644
--- a/arch/sh/include/asm/cmpxchg-grb.h
+++ b/arch/sh/include/asm/cmpxchg-grb.h
@@ -57,11 +57,10 @@ static inline unsigned long __cmpxchg_u32(volatile int *m, unsigned long old,
" mov.l @%1, %0 \n\t" /* load old value */
" cmp/eq %0, %2 \n\t"
" bf 1f \n\t" /* if not equal */
- " mov.l %2, @%1 \n\t" /* store new value */
+ " mov.l %3, @%1 \n\t" /* store new value */
"1: mov r1, r15 \n\t" /* LOGOUT */
- : "=&r" (retval),
- "+r" (m)
- : "r" (new)
+ : "=&r" (retval)
+ : "r" (m), "r" (old), "r" (new)
: "memory" , "r0", "r1", "t");
return retval;
diff --git a/arch/sh/include/asm/dma-mapping.h b/arch/sh/include/asm/dma-mapping.h
index 87ced133a36..bea3337a426 100644
--- a/arch/sh/include/asm/dma-mapping.h
+++ b/arch/sh/include/asm/dma-mapping.h
@@ -89,8 +89,6 @@ static inline void dma_free_coherent(struct device *dev, size_t size,
{
struct dma_map_ops *ops = get_dma_ops(dev);
- WARN_ON(irqs_disabled()); /* for portability */
-
if (dma_release_from_coherent(dev, get_order(size), vaddr))
return;
diff --git a/arch/sh/include/asm/dma-sh.h b/arch/sh/include/asm/dma-sh.h
index 78eed3e0bdf..e934a2e6665 100644
--- a/arch/sh/include/asm/dma-sh.h
+++ b/arch/sh/include/asm/dma-sh.h
@@ -20,14 +20,14 @@
defined(CONFIG_CPU_SUBTYPE_SH7780) || \
defined(CONFIG_CPU_SUBTYPE_SH7785)
#define dmaor_read_reg(n) \
- (n ? ctrl_inw(SH_DMAC_BASE1 + DMAOR) \
- : ctrl_inw(SH_DMAC_BASE0 + DMAOR))
+ (n ? __raw_readw(SH_DMAC_BASE1 + DMAOR) \
+ : __raw_readw(SH_DMAC_BASE0 + DMAOR))
#define dmaor_write_reg(n, data) \
- (n ? ctrl_outw(data, SH_DMAC_BASE1 + DMAOR) \
- : ctrl_outw(data, SH_DMAC_BASE0 + DMAOR))
+ (n ? __raw_writew(data, SH_DMAC_BASE1 + DMAOR) \
+ : __raw_writew(data, SH_DMAC_BASE0 + DMAOR))
#else /* Other CPU */
-#define dmaor_read_reg(n) ctrl_inw(SH_DMAC_BASE0 + DMAOR)
-#define dmaor_write_reg(n, data) ctrl_outw(data, SH_DMAC_BASE0 + DMAOR)
+#define dmaor_read_reg(n) __raw_readw(SH_DMAC_BASE0 + DMAOR)
+#define dmaor_write_reg(n, data) __raw_writew(data, SH_DMAC_BASE0 + DMAOR)
#endif
static int dmte_irq_map[] __maybe_unused = {
@@ -64,8 +64,10 @@ static int dmte_irq_map[] __maybe_unused = {
#define ACK_L 0x00010000
#define DM_INC 0x00004000
#define DM_DEC 0x00008000
+#define DM_FIX 0x0000c000
#define SM_INC 0x00001000
#define SM_DEC 0x00002000
+#define SM_FIX 0x00003000
#define RS_IN 0x00000200
#define RS_OUT 0x00000300
#define TS_BLK 0x00000040
@@ -83,7 +85,7 @@ static int dmte_irq_map[] __maybe_unused = {
* Define the default configuration for dual address memory-memory transfer.
* The 0x400 value represents auto-request, external->external.
*/
-#define RS_DUAL (DM_INC | SM_INC | 0x400 | TS_32)
+#define RS_DUAL (DM_INC | SM_INC | 0x400 | TS_INDEX2VAL(XMIT_SZ_32BIT))
/* DMA base address */
static u32 dma_base_addr[] __maybe_unused = {
@@ -123,10 +125,47 @@ static u32 dma_base_addr[] __maybe_unused = {
*/
#define SHDMA_MIX_IRQ (1 << 1)
#define SHDMA_DMAOR1 (1 << 2)
-#define SHDMA_DMAE1 (1 << 3)
+#define SHDMA_DMAE1 (1 << 3)
+
+enum sh_dmae_slave_chan_id {
+ SHDMA_SLAVE_SCIF0_TX,
+ SHDMA_SLAVE_SCIF0_RX,
+ SHDMA_SLAVE_SCIF1_TX,
+ SHDMA_SLAVE_SCIF1_RX,
+ SHDMA_SLAVE_SCIF2_TX,
+ SHDMA_SLAVE_SCIF2_RX,
+ SHDMA_SLAVE_SCIF3_TX,
+ SHDMA_SLAVE_SCIF3_RX,
+ SHDMA_SLAVE_SCIF4_TX,
+ SHDMA_SLAVE_SCIF4_RX,
+ SHDMA_SLAVE_SCIF5_TX,
+ SHDMA_SLAVE_SCIF5_RX,
+ SHDMA_SLAVE_SIUA_TX,
+ SHDMA_SLAVE_SIUA_RX,
+ SHDMA_SLAVE_SIUB_TX,
+ SHDMA_SLAVE_SIUB_RX,
+ SHDMA_SLAVE_NUMBER, /* Must stay last */
+};
+
+struct sh_dmae_slave_config {
+ enum sh_dmae_slave_chan_id slave_id;
+ dma_addr_t addr;
+ u32 chcr;
+ char mid_rid;
+};
struct sh_dmae_pdata {
unsigned int mode;
+ struct sh_dmae_slave_config *config;
+ int config_num;
+};
+
+struct device;
+
+struct sh_dmae_slave {
+ enum sh_dmae_slave_chan_id slave_id; /* Set by the platform */
+ struct device *dma_dev; /* Set by the platform */
+ struct sh_dmae_slave_config *config; /* Set by the driver */
};
#endif /* __DMA_SH_H */
diff --git a/arch/sh/include/asm/dwarf.h b/arch/sh/include/asm/dwarf.h
index bdccbbfdc0b..d62abd1d0c0 100644
--- a/arch/sh/include/asm/dwarf.h
+++ b/arch/sh/include/asm/dwarf.h
@@ -243,16 +243,13 @@ struct dwarf_cie {
unsigned long cie_pointer;
- struct list_head link;
-
unsigned long flags;
#define DWARF_CIE_Z_AUGMENTATION (1 << 0)
- /*
- * 'mod' will be non-NULL if this CIE came from a module's
- * .eh_frame section.
- */
- struct module *mod;
+ /* linked-list entry if this CIE is from a module */
+ struct list_head link;
+
+ struct rb_node node;
};
/**
@@ -266,13 +263,11 @@ struct dwarf_fde {
unsigned long address_range;
unsigned char *instructions;
unsigned char *end;
+
+ /* linked-list entry if this FDE is from a module */
struct list_head link;
- /*
- * 'mod' will be non-NULL if this FDE came from a module's
- * .eh_frame section.
- */
- struct module *mod;
+ struct rb_node node;
};
/**
diff --git a/arch/sh/include/asm/fixmap.h b/arch/sh/include/asm/fixmap.h
index 5ac1e40a511..6e7cea45389 100644
--- a/arch/sh/include/asm/fixmap.h
+++ b/arch/sh/include/asm/fixmap.h
@@ -55,16 +55,29 @@ enum fixed_addresses {
#define FIX_N_COLOURS 8
FIX_CMAP_BEGIN,
FIX_CMAP_END = FIX_CMAP_BEGIN + (FIX_N_COLOURS * NR_CPUS) - 1,
- FIX_UNCACHED,
+
#ifdef CONFIG_HIGHMEM
FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */
FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
#endif
+
+#ifdef CONFIG_IOREMAP_FIXED
+ /*
+ * FIX_IOREMAP entries are useful for mapping physical address
+ * space before ioremap() is useable, e.g. really early in boot
+ * before kmalloc() is working.
+ */
+#define FIX_N_IOREMAPS 32
+ FIX_IOREMAP_BEGIN,
+ FIX_IOREMAP_END = FIX_IOREMAP_BEGIN + FIX_N_IOREMAPS,
+#endif
+
__end_of_fixed_addresses
};
extern void __set_fixmap(enum fixed_addresses idx,
unsigned long phys, pgprot_t flags);
+extern void __clear_fixmap(enum fixed_addresses idx, pgprot_t flags);
#define set_fixmap(idx, phys) \
__set_fixmap(idx, phys, PAGE_KERNEL)
diff --git a/arch/sh/include/asm/fpu.h b/arch/sh/include/asm/fpu.h
index fb6bbb9b1cc..06c4281aab6 100644
--- a/arch/sh/include/asm/fpu.h
+++ b/arch/sh/include/asm/fpu.h
@@ -2,8 +2,8 @@
#define __ASM_SH_FPU_H
#ifndef __ASSEMBLY__
-#include <linux/preempt.h>
-#include <asm/ptrace.h>
+
+struct task_struct;
#ifdef CONFIG_SH_FPU
static inline void release_fpu(struct pt_regs *regs)
@@ -16,22 +16,23 @@ static inline void grab_fpu(struct pt_regs *regs)
regs->sr &= ~SR_FD;
}
-struct task_struct;
-
extern void save_fpu(struct task_struct *__tsk);
-void fpu_state_restore(struct pt_regs *regs);
+extern void restore_fpu(struct task_struct *__tsk);
+extern void fpu_state_restore(struct pt_regs *regs);
+extern void __fpu_state_restore(void);
#else
-
-#define save_fpu(tsk) do { } while (0)
-#define release_fpu(regs) do { } while (0)
-#define grab_fpu(regs) do { } while (0)
-#define fpu_state_restore(regs) do { } while (0)
-
+#define save_fpu(tsk) do { } while (0)
+#define restore_fpu(tsk) do { } while (0)
+#define release_fpu(regs) do { } while (0)
+#define grab_fpu(regs) do { } while (0)
+#define fpu_state_restore(regs) do { } while (0)
+#define __fpu_state_restore(regs) do { } while (0)
#endif
struct user_regset;
extern int do_fpu_inst(unsigned short, struct pt_regs *);
+extern int init_fpu(struct task_struct *);
extern int fpregs_get(struct task_struct *target,
const struct user_regset *regset,
@@ -65,18 +66,6 @@ static inline void clear_fpu(struct task_struct *tsk, struct pt_regs *regs)
preempt_enable();
}
-static inline int init_fpu(struct task_struct *tsk)
-{
- if (tsk_used_math(tsk)) {
- if ((boot_cpu_data.flags & CPU_HAS_FPU) && tsk == current)
- unlazy_fpu(tsk, task_pt_regs(tsk));
- return 0;
- }
-
- set_stopped_child_used_math(tsk);
- return 0;
-}
-
#endif /* __ASSEMBLY__ */
#endif /* __ASM_SH_FPU_H */
diff --git a/arch/sh/include/asm/hw_breakpoint.h b/arch/sh/include/asm/hw_breakpoint.h
new file mode 100644
index 00000000000..965dd780d51
--- /dev/null
+++ b/arch/sh/include/asm/hw_breakpoint.h
@@ -0,0 +1,67 @@
+#ifndef __ASM_SH_HW_BREAKPOINT_H
+#define __ASM_SH_HW_BREAKPOINT_H
+
+#ifdef __KERNEL__
+#define __ARCH_HW_BREAKPOINT_H
+
+#include <linux/kdebug.h>
+#include <linux/types.h>
+
+struct arch_hw_breakpoint {
+ char *name; /* Contains name of the symbol to set bkpt */
+ unsigned long address;
+ u16 len;
+ u16 type;
+};
+
+enum {
+ SH_BREAKPOINT_READ = (1 << 1),
+ SH_BREAKPOINT_WRITE = (1 << 2),
+ SH_BREAKPOINT_RW = SH_BREAKPOINT_READ | SH_BREAKPOINT_WRITE,
+
+ SH_BREAKPOINT_LEN_1 = (1 << 12),
+ SH_BREAKPOINT_LEN_2 = (1 << 13),
+ SH_BREAKPOINT_LEN_4 = SH_BREAKPOINT_LEN_1 | SH_BREAKPOINT_LEN_2,
+ SH_BREAKPOINT_LEN_8 = (1 << 14),
+};
+
+struct sh_ubc {
+ const char *name;
+ unsigned int num_events;
+ unsigned int trap_nr;
+ void (*enable)(struct arch_hw_breakpoint *, int);
+ void (*disable)(struct arch_hw_breakpoint *, int);
+ void (*enable_all)(unsigned long);
+ void (*disable_all)(void);
+ unsigned long (*active_mask)(void);
+ unsigned long (*triggered_mask)(void);
+ void (*clear_triggered_mask)(unsigned long);
+ struct clk *clk; /* optional interface clock / MSTP bit */
+};
+
+struct perf_event;
+struct task_struct;
+struct pmu;
+
+/* Maximum number of UBC channels */
+#define HBP_NUM 2
+
+/* arch/sh/kernel/hw_breakpoint.c */
+extern int arch_check_va_in_userspace(unsigned long va, u16 hbp_len);
+extern int arch_validate_hwbkpt_settings(struct perf_event *bp,
+ struct task_struct *tsk);
+extern int hw_breakpoint_exceptions_notify(struct notifier_block *unused,
+ unsigned long val, void *data);
+
+int arch_install_hw_breakpoint(struct perf_event *bp);
+void arch_uninstall_hw_breakpoint(struct perf_event *bp);
+void hw_breakpoint_pmu_read(struct perf_event *bp);
+void hw_breakpoint_pmu_unthrottle(struct perf_event *bp);
+
+extern void arch_fill_perf_breakpoint(struct perf_event *bp);
+extern int register_sh_ubc(struct sh_ubc *);
+
+extern struct pmu perf_ops_bp;
+
+#endif /* __KERNEL__ */
+#endif /* __ASM_SH_HW_BREAKPOINT_H */
diff --git a/arch/sh/include/asm/io.h b/arch/sh/include/asm/io.h
index 026dd659a64..7dab7b23a5e 100644
--- a/arch/sh/include/asm/io.h
+++ b/arch/sh/include/asm/io.h
@@ -22,6 +22,7 @@
* for old compat code for I/O offseting to SuperIOs, all of which are
* better handled through the machvec ioport mapping routines these days.
*/
+#include <linux/errno.h>
#include <asm/cache.h>
#include <asm/system.h>
#include <asm/addrspace.h>
@@ -79,16 +80,51 @@
#define writel(v,a) ({ __raw_writel((v),(a)); mb(); })
#define writeq(v,a) ({ __raw_writeq((v),(a)); mb(); })
-/* SuperH on-chip I/O functions */
-#define ctrl_inb __raw_readb
-#define ctrl_inw __raw_readw
-#define ctrl_inl __raw_readl
-#define ctrl_inq __raw_readq
+/*
+ * Legacy SuperH on-chip I/O functions
+ *
+ * These are all deprecated, all new (and especially cross-platform) code
+ * should be using the __raw_xxx() routines directly.
+ */
+static inline u8 __deprecated ctrl_inb(unsigned long addr)
+{
+ return __raw_readb(addr);
+}
+
+static inline u16 __deprecated ctrl_inw(unsigned long addr)
+{
+ return __raw_readw(addr);
+}
+
+static inline u32 __deprecated ctrl_inl(unsigned long addr)
+{
+ return __raw_readl(addr);
+}
+
+static inline u64 __deprecated ctrl_inq(unsigned long addr)
+{
+ return __raw_readq(addr);
+}
+
+static inline void __deprecated ctrl_outb(u8 v, unsigned long addr)
+{
+ __raw_writeb(v, addr);
+}
+
+static inline void __deprecated ctrl_outw(u16 v, unsigned long addr)
+{
+ __raw_writew(v, addr);
+}
-#define ctrl_outb __raw_writeb
-#define ctrl_outw __raw_writew
-#define ctrl_outl __raw_writel
-#define ctrl_outq __raw_writeq
+static inline void __deprecated ctrl_outl(u32 v, unsigned long addr)
+{
+ __raw_writel(v, addr);
+}
+
+static inline void __deprecated ctrl_outq(u64 v, unsigned long addr)
+{
+ __raw_writeq(v, addr);
+}
extern unsigned long generic_io_base;
@@ -97,6 +133,28 @@ static inline void ctrl_delay(void)
__raw_readw(generic_io_base);
}
+#define __BUILD_UNCACHED_IO(bwlq, type) \
+static inline type read##bwlq##_uncached(unsigned long addr) \
+{ \
+ type ret; \
+ jump_to_uncached(); \
+ ret = __raw_read##bwlq(addr); \
+ back_to_cached(); \
+ return ret; \
+} \
+ \
+static inline void write##bwlq##_uncached(type v, unsigned long addr) \
+{ \
+ jump_to_uncached(); \
+ __raw_write##bwlq(v, addr); \
+ back_to_cached(); \
+}
+
+__BUILD_UNCACHED_IO(b, u8)
+__BUILD_UNCACHED_IO(w, u16)
+__BUILD_UNCACHED_IO(l, u32)
+__BUILD_UNCACHED_IO(q, u64)
+
#define __BUILD_MEMORY_STRING(bwlq, type) \
\
static inline void __raw_writes##bwlq(volatile void __iomem *mem, \
@@ -234,28 +292,21 @@ unsigned long long poke_real_address_q(unsigned long long addr,
*/
#ifdef CONFIG_MMU
void __iomem *__ioremap_caller(unsigned long offset, unsigned long size,
- unsigned long flags, void *caller);
+ pgprot_t prot, void *caller);
void __iounmap(void __iomem *addr);
static inline void __iomem *
-__ioremap(unsigned long offset, unsigned long size, unsigned long flags)
+__ioremap(unsigned long offset, unsigned long size, pgprot_t prot)
{
- return __ioremap_caller(offset, size, flags, __builtin_return_address(0));
+ return __ioremap_caller(offset, size, prot, __builtin_return_address(0));
}
static inline void __iomem *
-__ioremap_mode(unsigned long offset, unsigned long size, unsigned long flags)
+__ioremap_29bit(unsigned long offset, unsigned long size, pgprot_t prot)
{
-#if defined(CONFIG_SUPERH32) && !defined(CONFIG_PMB_FIXED) && !defined(CONFIG_PMB)
+#ifdef CONFIG_29BIT
unsigned long last_addr = offset + size - 1;
-#endif
- void __iomem *ret;
- ret = __ioremap_trapped(offset, size);
- if (ret)
- return ret;
-
-#if defined(CONFIG_SUPERH32) && !defined(CONFIG_PMB_FIXED) && !defined(CONFIG_PMB)
/*
* For P1 and P2 space this is trivial, as everything is already
* mapped. Uncached access for P1 addresses are done through P2.
@@ -263,7 +314,7 @@ __ioremap_mode(unsigned long offset, unsigned long size, unsigned long flags)
* mapping must be done by the PMB or by using page tables.
*/
if (likely(PXSEG(offset) < P3SEG && PXSEG(last_addr) < P3SEG)) {
- if (unlikely(flags & _PAGE_CACHABLE))
+ if (unlikely(pgprot_val(prot) & _PAGE_CACHABLE))
return (void __iomem *)P1SEGADDR(offset);
return (void __iomem *)P2SEGADDR(offset);
@@ -274,26 +325,70 @@ __ioremap_mode(unsigned long offset, unsigned long size, unsigned long flags)
return (void __iomem *)P4SEGADDR(offset);
#endif
- return __ioremap(offset, size, flags);
+ return NULL;
+}
+
+static inline void __iomem *
+__ioremap_mode(unsigned long offset, unsigned long size, pgprot_t prot)
+{
+ void __iomem *ret;
+
+ ret = __ioremap_trapped(offset, size);
+ if (ret)
+ return ret;
+
+ ret = __ioremap_29bit(offset, size, prot);
+ if (ret)
+ return ret;
+
+ return __ioremap(offset, size, prot);
}
#else
-#define __ioremap(offset, size, flags) ((void __iomem *)(offset))
-#define __ioremap_mode(offset, size, flags) ((void __iomem *)(offset))
+#define __ioremap(offset, size, prot) ((void __iomem *)(offset))
+#define __ioremap_mode(offset, size, prot) ((void __iomem *)(offset))
#define __iounmap(addr) do { } while (0)
#endif /* CONFIG_MMU */
-#define ioremap(offset, size) \
- __ioremap_mode((offset), (size), 0)
-#define ioremap_nocache(offset, size) \
- __ioremap_mode((offset), (size), 0)
-#define ioremap_cache(offset, size) \
- __ioremap_mode((offset), (size), _PAGE_CACHABLE)
-#define p3_ioremap(offset, size, flags) \
- __ioremap((offset), (size), (flags))
-#define ioremap_prot(offset, size, flags) \
- __ioremap_mode((offset), (size), (flags))
-#define iounmap(addr) \
- __iounmap((addr))
+static inline void __iomem *
+ioremap(unsigned long offset, unsigned long size)
+{
+ return __ioremap_mode(offset, size, PAGE_KERNEL_NOCACHE);
+}
+
+static inline void __iomem *
+ioremap_cache(unsigned long offset, unsigned long size)
+{
+ return __ioremap_mode(offset, size, PAGE_KERNEL);
+}
+
+#ifdef CONFIG_HAVE_IOREMAP_PROT
+static inline void __iomem *
+ioremap_prot(resource_size_t offset, unsigned long size, unsigned long flags)
+{
+ return __ioremap_mode(offset, size, __pgprot(flags));
+}
+#endif
+
+#ifdef CONFIG_IOREMAP_FIXED
+extern void __iomem *ioremap_fixed(resource_size_t, unsigned long,
+ unsigned long, pgprot_t);
+extern int iounmap_fixed(void __iomem *);
+extern void ioremap_fixed_init(void);
+#else
+static inline void __iomem *
+ioremap_fixed(resource_size_t phys_addr, unsigned long offset,
+ unsigned long size, pgprot_t prot)
+{
+ BUG();
+ return NULL;
+}
+
+static inline void ioremap_fixed_init(void) { }
+static inline int iounmap_fixed(void __iomem *addr) { return -EINVAL; }
+#endif
+
+#define ioremap_nocache ioremap
+#define iounmap __iounmap
#define maybebadio(port) \
printk(KERN_ERR "bad PC-like io %s:%u for port 0x%lx at 0x%08x\n", \
diff --git a/arch/sh/include/asm/kdebug.h b/arch/sh/include/asm/kdebug.h
index 985219f9759..5f6d2e9ccb7 100644
--- a/arch/sh/include/asm/kdebug.h
+++ b/arch/sh/include/asm/kdebug.h
@@ -6,6 +6,8 @@ enum die_val {
DIE_TRAP,
DIE_NMI,
DIE_OOPS,
+ DIE_BREAKPOINT,
+ DIE_SSTEP,
};
#endif /* __ASM_SH_KDEBUG_H */
diff --git a/arch/sh/include/asm/mmu.h b/arch/sh/include/asm/mmu.h
index c7426ad9926..15a05b615ba 100644
--- a/arch/sh/include/asm/mmu.h
+++ b/arch/sh/include/asm/mmu.h
@@ -11,7 +11,9 @@
#define PMB_ADDR 0xf6100000
#define PMB_DATA 0xf7100000
-#define PMB_ENTRY_MAX 16
+
+#define NR_PMB_ENTRIES 16
+
#define PMB_E_MASK 0x0000000f
#define PMB_E_SHIFT 8
@@ -25,11 +27,15 @@
#define PMB_C 0x00000008
#define PMB_WT 0x00000001
#define PMB_UB 0x00000200
+#define PMB_CACHE_MASK (PMB_C | PMB_WT | PMB_UB)
#define PMB_V 0x00000100
#define PMB_NO_ENTRY (-1)
#ifndef __ASSEMBLY__
+#include <linux/errno.h>
+#include <linux/threads.h>
+#include <asm/page.h>
/* Default "unsigned long" context */
typedef unsigned long mm_context_id_t[NR_CPUS];
@@ -47,29 +53,30 @@ typedef struct {
#endif
} mm_context_t;
-struct pmb_entry;
-
-struct pmb_entry {
- unsigned long vpn;
- unsigned long ppn;
- unsigned long flags;
-
- /*
- * 0 .. NR_PMB_ENTRIES for specific entry selection, or
- * PMB_NO_ENTRY to search for a free one
- */
- int entry;
-
- struct pmb_entry *next;
- /* Adjacent entry link for contiguous multi-entry mappings */
- struct pmb_entry *link;
-};
-
+#ifdef CONFIG_PMB
/* arch/sh/mm/pmb.c */
long pmb_remap(unsigned long virt, unsigned long phys,
- unsigned long size, unsigned long flags);
+ unsigned long size, pgprot_t prot);
void pmb_unmap(unsigned long addr);
-int pmb_init(void);
+void pmb_init(void);
+bool __in_29bit_mode(void);
+#else
+static inline long pmb_remap(unsigned long virt, unsigned long phys,
+ unsigned long size, pgprot_t prot)
+{
+ return -EINVAL;
+}
+
+#define pmb_unmap(addr) do { } while (0)
+#define pmb_init(addr) do { } while (0)
+
+#ifdef CONFIG_29BIT
+#define __in_29bit_mode() (1)
+#else
+#define __in_29bit_mode() (0)
+#endif
+
+#endif /* CONFIG_PMB */
#endif /* __ASSEMBLY__ */
#endif /* __MMU_H */
diff --git a/arch/sh/include/asm/mmu_context.h b/arch/sh/include/asm/mmu_context.h
index 41080b173a7..384c7471a37 100644
--- a/arch/sh/include/asm/mmu_context.h
+++ b/arch/sh/include/asm/mmu_context.h
@@ -158,7 +158,7 @@ static inline void enable_mmu(void)
unsigned int cpu = smp_processor_id();
/* Enable MMU */
- ctrl_outl(MMU_CONTROL_INIT, MMUCR);
+ __raw_writel(MMU_CONTROL_INIT, MMUCR);
ctrl_barrier();
if (asid_cache(cpu) == NO_CONTEXT)
@@ -171,9 +171,9 @@ static inline void disable_mmu(void)
{
unsigned long cr;
- cr = ctrl_inl(MMUCR);
+ cr = __raw_readl(MMUCR);
cr &= ~MMU_CONTROL_INIT;
- ctrl_outl(cr, MMUCR);
+ __raw_writel(cr, MMUCR);
ctrl_barrier();
}
diff --git a/arch/sh/include/asm/mmu_context_32.h b/arch/sh/include/asm/mmu_context_32.h
index 8ef800c549a..10e2e17210d 100644
--- a/arch/sh/include/asm/mmu_context_32.h
+++ b/arch/sh/include/asm/mmu_context_32.h
@@ -49,11 +49,11 @@ static inline unsigned long get_asid(void)
/* MMU_TTB is used for optimizing the fault handling. */
static inline void set_TTB(pgd_t *pgd)
{
- ctrl_outl((unsigned long)pgd, MMU_TTB);
+ __raw_writel((unsigned long)pgd, MMU_TTB);
}
static inline pgd_t *get_TTB(void)
{
- return (pgd_t *)ctrl_inl(MMU_TTB);
+ return (pgd_t *)__raw_readl(MMU_TTB);
}
#endif /* __ASM_SH_MMU_CONTEXT_32_H */
diff --git a/arch/sh/include/asm/module.h b/arch/sh/include/asm/module.h
index 068bf165975..b7927de86f9 100644
--- a/arch/sh/include/asm/module.h
+++ b/arch/sh/include/asm/module.h
@@ -1,7 +1,22 @@
#ifndef _ASM_SH_MODULE_H
#define _ASM_SH_MODULE_H
-#include <asm-generic/module.h>
+struct mod_arch_specific {
+#ifdef CONFIG_DWARF_UNWINDER
+ struct list_head fde_list;
+ struct list_head cie_list;
+#endif
+};
+
+#ifdef CONFIG_64BIT
+#define Elf_Shdr Elf64_Shdr
+#define Elf_Sym Elf64_Sym
+#define Elf_Ehdr Elf64_Ehdr
+#else
+#define Elf_Shdr Elf32_Shdr
+#define Elf_Sym Elf32_Sym
+#define Elf_Ehdr Elf32_Ehdr
+#endif
#ifdef CONFIG_CPU_LITTLE_ENDIAN
# ifdef CONFIG_CPU_SH2
diff --git a/arch/sh/include/asm/page.h b/arch/sh/include/asm/page.h
index 81bffc0d686..d71feb35930 100644
--- a/arch/sh/include/asm/page.h
+++ b/arch/sh/include/asm/page.h
@@ -45,6 +45,7 @@
#endif
#ifndef __ASSEMBLY__
+#include <asm/uncached.h>
extern unsigned long shm_align_mask;
extern unsigned long max_low_pfn, min_low_pfn;
@@ -56,7 +57,6 @@ pages_do_alias(unsigned long addr1, unsigned long addr2)
return (addr1 ^ addr2) & shm_align_mask;
}
-
#define clear_page(page) memset((void *)(page), 0, PAGE_SIZE)
extern void copy_page(void *to, void *from);
@@ -88,7 +88,7 @@ typedef struct { unsigned long pgd; } pgd_t;
#define __pte(x) ((pte_t) { (x) } )
#else
typedef struct { unsigned long long pte_low; } pte_t;
-typedef struct { unsigned long pgprot; } pgprot_t;
+typedef struct { unsigned long long pgprot; } pgprot_t;
typedef struct { unsigned long pgd; } pgd_t;
#define pte_val(x) ((x).pte_low)
#define __pte(x) ((pte_t) { (x) } )
@@ -127,12 +127,7 @@ typedef struct page *pgtable_t;
* is not visible (it is part of the PMB mapping) and so needs to be
* added or subtracted as required.
*/
-#if defined(CONFIG_PMB_FIXED)
-/* phys = virt - PAGE_OFFSET - (__MEMORY_START & 0xe0000000) */
-#define PMB_OFFSET (PAGE_OFFSET - PXSEG(__MEMORY_START))
-#define __pa(x) ((unsigned long)(x) - PMB_OFFSET)
-#define __va(x) ((void *)((unsigned long)(x) + PMB_OFFSET))
-#elif defined(CONFIG_32BIT)
+#ifdef CONFIG_PMB
#define __pa(x) ((unsigned long)(x)-PAGE_OFFSET+__MEMORY_START)
#define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET-__MEMORY_START))
#else
@@ -140,6 +135,14 @@ typedef struct page *pgtable_t;
#define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET))
#endif
+#ifdef CONFIG_UNCACHED_MAPPING
+#define UNCAC_ADDR(addr) ((addr) - PAGE_OFFSET + uncached_start)
+#define CAC_ADDR(addr) ((addr) - uncached_start + PAGE_OFFSET)
+#else
+#define UNCAC_ADDR(addr) ((addr))
+#define CAC_ADDR(addr) ((addr))
+#endif
+
#define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT)
#define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT)
diff --git a/arch/sh/include/asm/pci.h b/arch/sh/include/asm/pci.h
index 67f3999b544..1042f7f0a48 100644
--- a/arch/sh/include/asm/pci.h
+++ b/arch/sh/include/asm/pci.h
@@ -15,20 +15,49 @@
*/
struct pci_channel {
struct pci_channel *next;
+ struct pci_bus *bus;
struct pci_ops *pci_ops;
- struct resource *io_resource;
- struct resource *mem_resource;
+
+ struct resource *resources;
+ unsigned int nr_resources;
unsigned long io_offset;
unsigned long mem_offset;
unsigned long reg_base;
-
unsigned long io_map_base;
+
+ unsigned int index;
+ unsigned int need_domain_info;
+
+ /* Optional error handling */
+ struct timer_list err_timer, serr_timer;
+ unsigned int err_irq, serr_irq;
};
-extern void register_pci_controller(struct pci_channel *hose);
+/* arch/sh/drivers/pci/pci.c */
+extern int register_pci_controller(struct pci_channel *hose);
+extern void pcibios_report_status(unsigned int status_mask, int warn);
+
+/* arch/sh/drivers/pci/common.c */
+extern int early_read_config_byte(struct pci_channel *hose, int top_bus,
+ int bus, int devfn, int offset, u8 *value);
+extern int early_read_config_word(struct pci_channel *hose, int top_bus,
+ int bus, int devfn, int offset, u16 *value);
+extern int early_read_config_dword(struct pci_channel *hose, int top_bus,
+ int bus, int devfn, int offset, u32 *value);
+extern int early_write_config_byte(struct pci_channel *hose, int top_bus,
+ int bus, int devfn, int offset, u8 value);
+extern int early_write_config_word(struct pci_channel *hose, int top_bus,
+ int bus, int devfn, int offset, u16 value);
+extern int early_write_config_dword(struct pci_channel *hose, int top_bus,
+ int bus, int devfn, int offset, u32 value);
+extern void pcibios_enable_timers(struct pci_channel *hose);
+extern unsigned int pcibios_handle_status_errors(unsigned long addr,
+ unsigned int status, struct pci_channel *hose);
+extern int pci_is_66mhz_capable(struct pci_channel *hose,
+ int top_bus, int current_bus);
extern unsigned long PCIBIOS_MIN_IO, PCIBIOS_MIN_MEM;
@@ -99,20 +128,6 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev,
}
#endif
-#ifdef CONFIG_SUPERH32
-/*
- * If we're on an SH7751 or SH7780 PCI controller, PCI memory is mapped
- * at the end of the address space in a special non-translatable area.
- */
-#define PCI_MEM_FIXED_START 0xfd000000
-#define PCI_MEM_FIXED_END (PCI_MEM_FIXED_START + 0x01000000)
-
-#define is_pci_memory_fixed_range(s, e) \
- ((s) >= PCI_MEM_FIXED_START && (e) < PCI_MEM_FIXED_END)
-#else
-#define is_pci_memory_fixed_range(s, e) (0)
-#endif
-
/* Board-specific fixup routines. */
int pcibios_map_platform_irq(struct pci_dev *dev, u8 slot, u8 pin);
@@ -122,6 +137,14 @@ extern void pcibios_resource_to_bus(struct pci_dev *dev,
extern void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
struct pci_bus_region *region);
+#define pci_domain_nr(bus) ((struct pci_channel *)(bus)->sysdata)->index
+
+static inline int pci_proc_domain(struct pci_bus *bus)
+{
+ struct pci_channel *hose = bus->sysdata;
+ return hose->need_domain_info;
+}
+
/* Chances are this interrupt is wired PC-style ... */
static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
{
diff --git a/arch/sh/include/asm/pgalloc.h b/arch/sh/include/asm/pgalloc.h
index 63ca37bd9a9..8c00785c60d 100644
--- a/arch/sh/include/asm/pgalloc.h
+++ b/arch/sh/include/asm/pgalloc.h
@@ -4,8 +4,16 @@
#include <linux/quicklist.h>
#include <asm/page.h>
-#define QUICK_PGD 0 /* We preserve special mappings over free */
-#define QUICK_PT 1 /* Other page table pages that are zero on free */
+#define QUICK_PT 0 /* Other page table pages that are zero on free */
+
+extern pgd_t *pgd_alloc(struct mm_struct *);
+extern void pgd_free(struct mm_struct *mm, pgd_t *pgd);
+
+#if PAGETABLE_LEVELS > 2
+extern void pud_populate(struct mm_struct *mm, pud_t *pudp, pmd_t *pmd);
+extern pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address);
+extern void pmd_free(struct mm_struct *mm, pmd_t *pmd);
+#endif
static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd,
pte_t *pte)
@@ -20,28 +28,9 @@ static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd,
}
#define pmd_pgtable(pmd) pmd_page(pmd)
-static inline void pgd_ctor(void *x)
-{
- pgd_t *pgd = x;
-
- memcpy(pgd + USER_PTRS_PER_PGD,
- swapper_pg_dir + USER_PTRS_PER_PGD,
- (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
-}
-
/*
* Allocate and free page tables.
*/
-static inline pgd_t *pgd_alloc(struct mm_struct *mm)
-{
- return quicklist_alloc(QUICK_PGD, GFP_KERNEL | __GFP_REPEAT, pgd_ctor);
-}
-
-static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
-{
- quicklist_free(QUICK_PGD, NULL, pgd);
-}
-
static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
unsigned long address)
{
@@ -81,7 +70,6 @@ do { \
static inline void check_pgt_cache(void)
{
- quicklist_trim(QUICK_PGD, NULL, 25, 16);
quicklist_trim(QUICK_PT, NULL, 25, 16);
}
diff --git a/arch/sh/include/asm/pgtable-2level.h b/arch/sh/include/asm/pgtable-2level.h
new file mode 100644
index 00000000000..19bd89db17e
--- /dev/null
+++ b/arch/sh/include/asm/pgtable-2level.h
@@ -0,0 +1,23 @@
+#ifndef __ASM_SH_PGTABLE_2LEVEL_H
+#define __ASM_SH_PGTABLE_2LEVEL_H
+
+#include <asm-generic/pgtable-nopmd.h>
+
+/*
+ * traditional two-level paging structure
+ */
+#define PAGETABLE_LEVELS 2
+
+/* PTE bits */
+#define PTE_MAGNITUDE 2 /* 32-bit PTEs */
+
+#define PTE_SHIFT PAGE_SHIFT
+#define PTE_BITS (PTE_SHIFT - PTE_MAGNITUDE)
+
+/* PGD bits */
+#define PGDIR_SHIFT (PTE_SHIFT + PTE_BITS)
+
+#define PTRS_PER_PGD (PAGE_SIZE / (1 << PTE_MAGNITUDE))
+#define USER_PTRS_PER_PGD (TASK_SIZE/PGDIR_SIZE)
+
+#endif /* __ASM_SH_PGTABLE_2LEVEL_H */
diff --git a/arch/sh/include/asm/pgtable-3level.h b/arch/sh/include/asm/pgtable-3level.h
new file mode 100644
index 00000000000..249a985d964
--- /dev/null
+++ b/arch/sh/include/asm/pgtable-3level.h
@@ -0,0 +1,56 @@
+#ifndef __ASM_SH_PGTABLE_3LEVEL_H
+#define __ASM_SH_PGTABLE_3LEVEL_H
+
+#include <asm-generic/pgtable-nopud.h>
+
+/*
+ * Some cores need a 3-level page table layout, for example when using
+ * 64-bit PTEs and 4K pages.
+ */
+#define PAGETABLE_LEVELS 3
+
+#define PTE_MAGNITUDE 3 /* 64-bit PTEs on SH-X2 TLB */
+
+/* PGD bits */
+#define PGDIR_SHIFT 30
+
+#define PTRS_PER_PGD 4
+#define USER_PTRS_PER_PGD 2
+
+/* PMD bits */
+#define PMD_SHIFT (PAGE_SHIFT + (PAGE_SHIFT - PTE_MAGNITUDE))
+#define PMD_SIZE (1UL << PMD_SHIFT)
+#define PMD_MASK (~(PMD_SIZE-1))
+
+#define PTRS_PER_PMD ((1 << PGDIR_SHIFT) / PMD_SIZE)
+
+#define pmd_ERROR(e) \
+ printk("%s:%d: bad pmd %016llx.\n", __FILE__, __LINE__, pmd_val(e))
+
+typedef struct { unsigned long long pmd; } pmd_t;
+#define pmd_val(x) ((x).pmd)
+#define __pmd(x) ((pmd_t) { (x) } )
+
+static inline unsigned long pud_page_vaddr(pud_t pud)
+{
+ return pud_val(pud);
+}
+
+#define pmd_index(address) (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))
+static inline pmd_t *pmd_offset(pud_t *pud, unsigned long address)
+{
+ return (pmd_t *)pud_page_vaddr(*pud) + pmd_index(address);
+}
+
+#define pud_none(x) (!pud_val(x))
+#define pud_present(x) (pud_val(x))
+#define pud_clear(xp) do { set_pud(xp, __pud(0)); } while (0)
+#define pud_bad(x) (pud_val(x) & ~PAGE_MASK)
+
+/*
+ * (puds are folded into pgds so this doesn't get actually called,
+ * but the define is needed for a generic inline function.)
+ */
+#define set_pud(pudptr, pudval) do { *(pudptr) = (pudval); } while(0)
+
+#endif /* __ASM_SH_PGTABLE_3LEVEL_H */
diff --git a/arch/sh/include/asm/pgtable.h b/arch/sh/include/asm/pgtable.h
index ba3046e4f06..aab76528abb 100644
--- a/arch/sh/include/asm/pgtable.h
+++ b/arch/sh/include/asm/pgtable.h
@@ -12,7 +12,11 @@
#ifndef __ASM_SH_PGTABLE_H
#define __ASM_SH_PGTABLE_H
-#include <asm-generic/pgtable-nopmd.h>
+#ifdef CONFIG_X2TLB
+#include <asm/pgtable-3level.h>
+#else
+#include <asm/pgtable-2level.h>
+#endif
#include <asm/page.h>
#ifndef __ASSEMBLY__
@@ -51,28 +55,12 @@ static inline unsigned long long neff_sign_extend(unsigned long val)
#define NPHYS_SIGN (1LL << (NPHYS - 1))
#define NPHYS_MASK (-1LL << NPHYS)
-/*
- * traditional two-level paging structure
- */
-/* PTE bits */
-#if defined(CONFIG_X2TLB) || defined(CONFIG_SUPERH64)
-# define PTE_MAGNITUDE 3 /* 64-bit PTEs on extended mode SH-X2 TLB */
-#else
-# define PTE_MAGNITUDE 2 /* 32-bit PTEs */
-#endif
-#define PTE_SHIFT PAGE_SHIFT
-#define PTE_BITS (PTE_SHIFT - PTE_MAGNITUDE)
-
-/* PGD bits */
-#define PGDIR_SHIFT (PTE_SHIFT + PTE_BITS)
#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
#define PGDIR_MASK (~(PGDIR_SIZE-1))
/* Entries per level */
#define PTRS_PER_PTE (PAGE_SIZE / (1 << PTE_MAGNITUDE))
-#define PTRS_PER_PGD (PAGE_SIZE / sizeof(pgd_t))
-#define USER_PTRS_PER_PGD (TASK_SIZE/PGDIR_SIZE)
#define FIRST_USER_ADDRESS 0
#define PHYS_ADDR_MASK29 0x1fffffff
@@ -153,9 +141,9 @@ typedef pte_t *pte_addr_t;
#define pte_pfn(x) ((unsigned long)(((x).pte_low >> PAGE_SHIFT)))
/*
- * No page table caches to initialise
+ * Initialise the page table caches
*/
-#define pgtable_cache_init() do { } while (0)
+extern void pgtable_cache_init(void);
struct vm_area_struct;
diff --git a/arch/sh/include/asm/pgtable_32.h b/arch/sh/include/asm/pgtable_32.h
index 5003ee86f67..e172d696e52 100644
--- a/arch/sh/include/asm/pgtable_32.h
+++ b/arch/sh/include/asm/pgtable_32.h
@@ -71,6 +71,8 @@
#define _PAGE_EXT_KERN_WRITE 0x1000 /* EPR4-bit: Kernel space writable */
#define _PAGE_EXT_KERN_READ 0x2000 /* EPR5-bit: Kernel space readable */
+#define _PAGE_EXT_WIRED 0x4000 /* software: Wire TLB entry */
+
/* Wrapper for extended mode pgprot twiddling */
#define _PAGE_EXT(x) ((unsigned long long)(x) << 32)
@@ -141,12 +143,14 @@ static inline unsigned long copy_ptea_attributes(unsigned long x)
# elif defined(CONFIG_HUGETLB_PAGE_SIZE_64MB)
# define _PAGE_SZHUGE (_PAGE_EXT_ESZ2 | _PAGE_EXT_ESZ3)
# endif
+# define _PAGE_WIRED (_PAGE_EXT(_PAGE_EXT_WIRED))
#else
# if defined(CONFIG_HUGETLB_PAGE_SIZE_64K)
# define _PAGE_SZHUGE (_PAGE_SZ1)
# elif defined(CONFIG_HUGETLB_PAGE_SIZE_1MB)
# define _PAGE_SZHUGE (_PAGE_SZ0 | _PAGE_SZ1)
# endif
+# define _PAGE_WIRED (0)
#endif
/*
diff --git a/arch/sh/include/asm/pgtable_64.h b/arch/sh/include/asm/pgtable_64.h
index 17cdbecc3ad..0ee46776dad 100644
--- a/arch/sh/include/asm/pgtable_64.h
+++ b/arch/sh/include/asm/pgtable_64.h
@@ -43,11 +43,6 @@ static __inline__ void set_pte(pte_t *pteptr, pte_t pteval)
}
#define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval)
-static __inline__ void pmd_set(pmd_t *pmdp,pte_t *ptep)
-{
- pmd_val(*pmdp) = (unsigned long) ptep;
-}
-
/*
* PGD defines. Top level.
*/
@@ -128,8 +123,21 @@ static __inline__ void pmd_set(pmd_t *pmdp,pte_t *ptep)
#define _PAGE_DIRTY 0x400 /* software: page accessed in write */
#define _PAGE_ACCESSED 0x800 /* software: page referenced */
+/* Wrapper for extended mode pgprot twiddling */
+#define _PAGE_EXT(x) ((unsigned long long)(x) << 32)
+
+/*
+ * We can use the sign-extended bits in the PTEL to get 32 bits of
+ * software flags. This works for now because no implementations uses
+ * anything above the PPN field.
+ */
+#define _PAGE_WIRED _PAGE_EXT(0x001) /* software: wire the tlb entry */
+
+#define _PAGE_CLEAR_FLAGS (_PAGE_PRESENT | _PAGE_FILE | _PAGE_SHARED | \
+ _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_WIRED)
+
/* Mask which drops software flags */
-#define _PAGE_FLAGS_HARDWARE_MASK 0xfffffffffffff3dbLL
+#define _PAGE_FLAGS_HARDWARE_MASK (NEFF_MASK & ~(_PAGE_CLEAR_FLAGS))
/*
* HugeTLB support
@@ -203,12 +211,6 @@ static __inline__ void pmd_set(pmd_t *pmdp,pte_t *ptep)
#define pgprot_writecombine(prot) __pgprot(pgprot_val(prot) & ~_PAGE_CACHABLE)
/*
- * Handling allocation failures during page table setup.
- */
-extern void __handle_bad_pmd_kernel(pmd_t * pmd);
-#define __handle_bad_pmd(x) __handle_bad_pmd_kernel(x)
-
-/*
* PTE level access routines.
*
* Note1:
diff --git a/arch/sh/include/asm/processor.h b/arch/sh/include/asm/processor.h
index 017e0c1807b..9605e062840 100644
--- a/arch/sh/include/asm/processor.h
+++ b/arch/sh/include/asm/processor.h
@@ -98,13 +98,34 @@ extern struct sh_cpuinfo cpu_data[];
/* Forward decl */
struct seq_operations;
+struct task_struct;
extern struct pt_regs fake_swapper_regs;
+/* arch/sh/kernel/process.c */
+extern unsigned int xstate_size;
+extern void free_thread_xstate(struct task_struct *);
+extern struct kmem_cache *task_xstate_cachep;
+
+/* arch/sh/mm/alignment.c */
+extern int get_unalign_ctl(struct task_struct *, unsigned long addr);
+extern int set_unalign_ctl(struct task_struct *, unsigned int val);
+
+#define GET_UNALIGN_CTL(tsk, addr) get_unalign_ctl((tsk), (addr))
+#define SET_UNALIGN_CTL(tsk, val) set_unalign_ctl((tsk), (val))
+
+/* arch/sh/mm/init.c */
+extern unsigned int mem_init_done;
+
/* arch/sh/kernel/setup.c */
const char *get_cpu_subtype(struct sh_cpuinfo *c);
extern const struct seq_operations cpuinfo_op;
+/* thread_struct flags */
+#define SH_THREAD_UAC_NOPRINT (1 << 0)
+#define SH_THREAD_UAC_SIGBUS (1 << 1)
+#define SH_THREAD_UAC_MASK (SH_THREAD_UAC_NOPRINT | SH_THREAD_UAC_SIGBUS)
+
/* processor boot mode configuration */
#define MODE_PIN0 (1 << 0)
#define MODE_PIN1 (1 << 1)
diff --git a/arch/sh/include/asm/processor_32.h b/arch/sh/include/asm/processor_32.h
index 1f3d6fab660..572b4eb0949 100644
--- a/arch/sh/include/asm/processor_32.h
+++ b/arch/sh/include/asm/processor_32.h
@@ -14,6 +14,7 @@
#include <asm/page.h>
#include <asm/types.h>
#include <asm/ptrace.h>
+#include <asm/hw_breakpoint.h>
/*
* Default implementation of macro that returns current
@@ -90,9 +91,9 @@ struct sh_fpu_soft_struct {
unsigned long entry_pc;
};
-union sh_fpu_union {
- struct sh_fpu_hard_struct hard;
- struct sh_fpu_soft_struct soft;
+union thread_xstate {
+ struct sh_fpu_hard_struct hardfpu;
+ struct sh_fpu_soft_struct softfpu;
};
struct thread_struct {
@@ -100,38 +101,30 @@ struct thread_struct {
unsigned long sp;
unsigned long pc;
- /* Hardware debugging registers */
- unsigned long ubc_pc;
+ /* Various thread flags, see SH_THREAD_xxx */
+ unsigned long flags;
- /* floating point info */
- union sh_fpu_union fpu;
+ /* Save middle states of ptrace breakpoints */
+ struct perf_event *ptrace_bps[HBP_NUM];
#ifdef CONFIG_SH_DSP
/* Dsp status information */
struct sh_dsp_struct dsp_status;
#endif
-};
-/* Count of active tasks with UBC settings */
-extern int ubc_usercnt;
+ /* Extended processor state */
+ union thread_xstate *xstate;
+};
#define INIT_THREAD { \
.sp = sizeof(init_stack) + (long) &init_stack, \
+ .flags = 0, \
}
-/*
- * Do necessary setup to start up a newly executed thread.
- */
-#define start_thread(_regs, new_pc, new_sp) \
- set_fs(USER_DS); \
- _regs->pr = 0; \
- _regs->sr = SR_FD; /* User mode. */ \
- _regs->pc = new_pc; \
- _regs->regs[15] = new_sp
-
/* Forward declaration, a strange C thing */
struct task_struct;
-struct mm_struct;
+
+extern void start_thread(struct pt_regs *regs, unsigned long new_pc, unsigned long new_sp);
/* Free all resources held by a thread. */
extern void release_thread(struct task_struct *);
diff --git a/arch/sh/include/asm/processor_64.h b/arch/sh/include/asm/processor_64.h
index 5727d31b0cc..621bc4618c6 100644
--- a/arch/sh/include/asm/processor_64.h
+++ b/arch/sh/include/asm/processor_64.h
@@ -87,26 +87,31 @@ struct sh_fpu_hard_struct {
/* long status; * software status information */
};
-#if 0
/* Dummy fpu emulator */
struct sh_fpu_soft_struct {
- unsigned long long fp_regs[32];
+ unsigned long fp_regs[64];
unsigned int fpscr;
unsigned char lookahead;
unsigned long entry_pc;
};
-#endif
-union sh_fpu_union {
- struct sh_fpu_hard_struct hard;
- /* 'hard' itself only produces 32 bit alignment, yet we need
- to access it using 64 bit load/store as well. */
+union thread_xstate {
+ struct sh_fpu_hard_struct hardfpu;
+ struct sh_fpu_soft_struct softfpu;
+ /*
+ * The structure definitions only produce 32 bit alignment, yet we need
+ * to access them using 64 bit load/store as well.
+ */
unsigned long long alignment_dummy;
};
struct thread_struct {
unsigned long sp;
unsigned long pc;
+
+ /* Various thread flags, see SH_THREAD_xxx */
+ unsigned long flags;
+
/* This stores the address of the pt_regs built during a context
switch, or of the register save area built for a kernel mode
exception. It is used for backtracing the stack of a sleeping task
@@ -122,7 +127,7 @@ struct thread_struct {
/* Hardware debugging registers may come here */
/* floating point info */
- union sh_fpu_union fpu;
+ union thread_xstate *xstate;
};
#define INIT_MMAP \
@@ -137,7 +142,7 @@ struct thread_struct {
.trap_no = 0, \
.error_code = 0, \
.address = 0, \
- .fpu = { { { 0, } }, } \
+ .flags = 0, \
}
/*
diff --git a/arch/sh/include/asm/ptrace.h b/arch/sh/include/asm/ptrace.h
index 1dc12cb44a2..e11b14ea2c4 100644
--- a/arch/sh/include/asm/ptrace.h
+++ b/arch/sh/include/asm/ptrace.h
@@ -102,13 +102,15 @@ struct pt_dspregs {
#define PTRACE_GETDSPREGS 55 /* DSP registers */
#define PTRACE_SETDSPREGS 56
-#define PT_TEXT_END_ADDR 240
-#define PT_TEXT_ADDR 244 /* &(struct user)->start_code */
-#define PT_DATA_ADDR 248 /* &(struct user)->start_data */
+#define PT_TEXT_END_ADDR 240
+#define PT_TEXT_ADDR 244 /* &(struct user)->start_code */
+#define PT_DATA_ADDR 248 /* &(struct user)->start_data */
#define PT_TEXT_LEN 252
#ifdef __KERNEL__
#include <asm/addrspace.h>
+#include <asm/page.h>
+#include <asm/system.h>
#define user_mode(regs) (((regs)->sr & 0x40000000)==0)
#define instruction_pointer(regs) ((unsigned long)(regs)->pc)
@@ -124,6 +126,12 @@ struct task_struct;
extern void user_enable_single_step(struct task_struct *);
extern void user_disable_single_step(struct task_struct *);
+struct perf_event;
+struct perf_sample_data;
+
+extern void ptrace_triggered(struct perf_event *bp, int nmi,
+ struct perf_sample_data *data, struct pt_regs *regs);
+
#define task_pt_regs(task) \
((struct pt_regs *) (task_stack_page(task) + THREAD_SIZE) - 1)
@@ -131,10 +139,8 @@ static inline unsigned long profile_pc(struct pt_regs *regs)
{
unsigned long pc = instruction_pointer(regs);
-#ifdef P2SEG
- if (pc >= P2SEG && pc < P3SEG)
- pc -= 0x20000000;
-#endif
+ if (virt_addr_uncached(pc))
+ return CAC_ADDR(pc);
return pc;
}
diff --git a/arch/sh/include/asm/reboot.h b/arch/sh/include/asm/reboot.h
new file mode 100644
index 00000000000..b3da0c63fc3
--- /dev/null
+++ b/arch/sh/include/asm/reboot.h
@@ -0,0 +1,21 @@
+#ifndef __ASM_SH_REBOOT_H
+#define __ASM_SH_REBOOT_H
+
+#include <linux/kdebug.h>
+
+struct pt_regs;
+
+struct machine_ops {
+ void (*restart)(char *cmd);
+ void (*halt)(void);
+ void (*power_off)(void);
+ void (*shutdown)(void);
+ void (*crash_shutdown)(struct pt_regs *);
+};
+
+extern struct machine_ops machine_ops;
+
+/* arch/sh/kernel/machine_kexec.c */
+void native_machine_crash_shutdown(struct pt_regs *regs);
+
+#endif /* __ASM_SH_REBOOT_H */
diff --git a/arch/sh/include/asm/setup.h b/arch/sh/include/asm/setup.h
index ce3743599b2..4758325bb24 100644
--- a/arch/sh/include/asm/setup.h
+++ b/arch/sh/include/asm/setup.h
@@ -18,7 +18,6 @@
/* ... */
#define COMMAND_LINE ((char *) (PARAM+0x100))
-int setup_early_printk(char *);
void sh_mv_setup(void);
#endif /* __KERNEL__ */
diff --git a/arch/sh/include/asm/sh_bios.h b/arch/sh/include/asm/sh_bios.h
index d9c96d7cf6c..95714c28422 100644
--- a/arch/sh/include/asm/sh_bios.h
+++ b/arch/sh/include/asm/sh_bios.h
@@ -1,18 +1,27 @@
#ifndef __ASM_SH_BIOS_H
#define __ASM_SH_BIOS_H
+#ifdef CONFIG_SH_STANDARD_BIOS
+
/*
* Copyright (C) 2000 Greg Banks, Mitch Davis
* C API to interface to the standard LinuxSH BIOS
* usually from within the early stages of kernel boot.
*/
-
-
extern void sh_bios_console_write(const char *buf, unsigned int len);
-extern void sh_bios_char_out(char ch);
extern void sh_bios_gdb_detach(void);
extern void sh_bios_get_node_addr(unsigned char *node_addr);
extern void sh_bios_shutdown(unsigned int how);
+extern void sh_bios_vbr_init(void);
+extern void sh_bios_vbr_reload(void);
+
+#else
+
+static inline void sh_bios_vbr_init(void) { }
+static inline void sh_bios_vbr_reload(void) { }
+
+#endif /* CONFIG_SH_STANDARD_BIOS */
+
#endif /* __ASM_SH_BIOS_H */
diff --git a/arch/sh/include/asm/suspend.h b/arch/sh/include/asm/suspend.h
index fe9c2a1ad04..64eb41a063e 100644
--- a/arch/sh/include/asm/suspend.h
+++ b/arch/sh/include/asm/suspend.h
@@ -92,5 +92,6 @@ extern unsigned long sh_mobile_sleep_supported;
#define SUSP_SH_USTANDBY (1 << 3) /* SH-Mobile U-standby mode */
#define SUSP_SH_SF (1 << 4) /* Enable self-refresh */
#define SUSP_SH_MMU (1 << 5) /* Save/restore MMU and cache */
+#define SUSP_SH_REGS (1 << 6) /* Save/restore registers */
#endif /* _ASM_SH_SUSPEND_H */
diff --git a/arch/sh/include/asm/system.h b/arch/sh/include/asm/system.h
index c15415b4b16..0bd7a17d5e1 100644
--- a/arch/sh/include/asm/system.h
+++ b/arch/sh/include/asm/system.h
@@ -10,7 +10,6 @@
#include <linux/compiler.h>
#include <linux/linkage.h>
#include <asm/types.h>
-#include <asm/ptrace.h>
#define AT_VECTOR_SIZE_ARCH 5 /* entries in ARCH_DLINFO */
@@ -32,7 +31,7 @@
#define mb() __asm__ __volatile__ ("synco": : :"memory")
#define rmb() mb()
#define wmb() __asm__ __volatile__ ("synco": : :"memory")
-#define ctrl_barrier() __icbi(0xa8000000)
+#define ctrl_barrier() __icbi(PAGE_OFFSET)
#define read_barrier_depends() do { } while(0)
#else
#define mb() __asm__ __volatile__ ("": : :"memory")
@@ -114,6 +113,8 @@ static inline unsigned long __cmpxchg(volatile void * ptr, unsigned long old,
(unsigned long)_n_, sizeof(*(ptr))); \
})
+struct pt_regs;
+
extern void die(const char *str, struct pt_regs *regs, long err) __attribute__ ((noreturn));
void free_initmem(void);
void free_initrd_mem(unsigned long start, unsigned long end);
@@ -137,14 +138,14 @@ extern unsigned int instruction_size(unsigned int insn);
#endif
extern unsigned long cached_to_uncached;
+extern unsigned long uncached_size;
extern struct dentry *sh_debugfs_root;
void per_cpu_trap_init(void);
void default_idle(void);
void cpu_idle_wait(void);
-
-asmlinkage void break_point_trap(void);
+void stop_this_cpu(void *);
#ifdef CONFIG_SUPERH32
#define BUILD_TRAP_HANDLER(name) \
diff --git a/arch/sh/include/asm/system_32.h b/arch/sh/include/asm/system_32.h
index 06814f5b59c..51296b36770 100644
--- a/arch/sh/include/asm/system_32.h
+++ b/arch/sh/include/asm/system_32.h
@@ -2,6 +2,7 @@
#define __ASM_SH_SYSTEM_32_H
#include <linux/types.h>
+#include <asm/mmu.h>
#ifdef CONFIG_SH_DSP
@@ -144,9 +145,6 @@ do { \
__restore_dsp(prev); \
} while (0)
-#define __uses_jump_to_uncached \
- noinline __attribute__ ((__section__ (".uncached.text")))
-
/*
* Jump to uncached area.
* When handling TLB or caches, we need to do it from an uncached area.
@@ -216,6 +214,17 @@ static inline reg_size_t register_align(void *val)
int handle_unaligned_access(insn_size_t instruction, struct pt_regs *regs,
struct mem_access *ma, int);
+static inline void trigger_address_error(void)
+{
+ if (__in_29bit_mode())
+ __asm__ __volatile__ (
+ "ldc %0, sr\n\t"
+ "mov.l @%1, %0"
+ :
+ : "r" (0x10000000), "r" (0x80000001)
+ );
+}
+
asmlinkage void do_address_error(struct pt_regs *regs,
unsigned long writeaccess,
unsigned long address);
diff --git a/arch/sh/include/asm/system_64.h b/arch/sh/include/asm/system_64.h
index ab1dd917ea8..36338646dfc 100644
--- a/arch/sh/include/asm/system_64.h
+++ b/arch/sh/include/asm/system_64.h
@@ -18,6 +18,7 @@
/*
* switch_to() should switch tasks to task nr n, first
*/
+struct thread_struct;
struct task_struct *sh64_switch_to(struct task_struct *prev,
struct thread_struct *prev_thread,
struct task_struct *next,
@@ -33,8 +34,6 @@ do { \
&next->thread); \
} while (0)
-#define __uses_jump_to_uncached
-
#define jump_to_uncached() do { } while (0)
#define back_to_cached() do { } while (0)
@@ -48,6 +47,13 @@ static inline reg_size_t register_align(void *val)
return (unsigned long long)(signed long long)(signed long)val;
}
+extern void phys_stext(void);
+
+static inline void trigger_address_error(void)
+{
+ phys_stext();
+}
+
#define SR_BL_LL 0x0000000010000000LL
static inline void set_bl_bit(void)
diff --git a/arch/sh/include/asm/thread_info.h b/arch/sh/include/asm/thread_info.h
index 1f3d927e226..55a36fef687 100644
--- a/arch/sh/include/asm/thread_info.h
+++ b/arch/sh/include/asm/thread_info.h
@@ -93,14 +93,16 @@ static inline struct thread_info *current_thread_info(void)
#define THREAD_SIZE_ORDER (THREAD_SHIFT - PAGE_SHIFT)
-#else /* THREAD_SHIFT < PAGE_SHIFT */
-
-#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR
+#endif
extern struct thread_info *alloc_thread_info(struct task_struct *tsk);
extern void free_thread_info(struct thread_info *ti);
+extern void arch_task_cache_init(void);
+#define arch_task_cache_init arch_task_cache_init
+extern int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src);
+extern void init_thread_xstate(void);
-#endif /* THREAD_SHIFT < PAGE_SHIFT */
+#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR
#endif /* __ASSEMBLY__ */
diff --git a/arch/sh/include/asm/tlb.h b/arch/sh/include/asm/tlb.h
index da8fe7ab872..75abb38dffd 100644
--- a/arch/sh/include/asm/tlb.h
+++ b/arch/sh/include/asm/tlb.h
@@ -11,6 +11,7 @@
#ifdef CONFIG_MMU
#include <asm/pgalloc.h>
#include <asm/tlbflush.h>
+#include <asm/mmu_context.h>
/*
* TLB handling. This allows us to remove pages from the page
@@ -97,6 +98,22 @@ tlb_end_vma(struct mmu_gather *tlb, struct vm_area_struct *vma)
#define tlb_migrate_finish(mm) do { } while (0)
+#if defined(CONFIG_CPU_SH4) || defined(CONFIG_SUPERH64)
+extern void tlb_wire_entry(struct vm_area_struct *, unsigned long, pte_t);
+extern void tlb_unwire_entry(void);
+#else
+static inline void tlb_wire_entry(struct vm_area_struct *vma ,
+ unsigned long addr, pte_t pte)
+{
+ BUG();
+}
+
+static inline void tlb_unwire_entry(void)
+{
+ BUG();
+}
+#endif
+
#else /* CONFIG_MMU */
#define tlb_start_vma(tlb, vma) do { } while (0)
diff --git a/arch/sh/include/asm/ubc.h b/arch/sh/include/asm/ubc.h
deleted file mode 100644
index 9bf96168443..00000000000
--- a/arch/sh/include/asm/ubc.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * include/asm-sh/ubc.h
- *
- * Copyright (C) 1999 Niibe Yutaka
- * Copyright (C) 2002, 2003 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.
- */
-#ifndef __ASM_SH_UBC_H
-#define __ASM_SH_UBC_H
-#ifdef __KERNEL__
-
-#include <cpu/ubc.h>
-
-/* User Break Controller */
-#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709)
-#define UBC_TYPE_SH7729 (current_cpu_data.type == CPU_SH7729)
-#else
-#define UBC_TYPE_SH7729 0
-#endif
-
-#define BAMR_ASID (1 << 2)
-#define BAMR_NONE 0
-#define BAMR_10 0x1
-#define BAMR_12 0x2
-#define BAMR_ALL 0x3
-#define BAMR_16 0x8
-#define BAMR_20 0x9
-
-#define BBR_INST (1 << 4)
-#define BBR_DATA (2 << 4)
-#define BBR_READ (1 << 2)
-#define BBR_WRITE (2 << 2)
-#define BBR_BYTE 0x1
-#define BBR_HALF 0x2
-#define BBR_LONG 0x3
-#define BBR_QUAD (1 << 6) /* SH7750 */
-#define BBR_CPU (1 << 6) /* SH7709A,SH7729 */
-#define BBR_DMA (2 << 6) /* SH7709A,SH7729 */
-
-#define BRCR_CMFA (1 << 15)
-#define BRCR_CMFB (1 << 14)
-
-#if defined CONFIG_CPU_SH2A
-#define BRCR_CMFCA (1 << 15)
-#define BRCR_CMFCB (1 << 14)
-#define BRCR_CMFDA (1 << 13)
-#define BRCR_CMFDB (1 << 12)
-#define BRCR_PCBB (1 << 6) /* 1: after execution */
-#define BRCR_PCBA (1 << 5) /* 1: after execution */
-#define BRCR_PCTE 0
-#else
-#define BRCR_PCTE (1 << 11)
-#define BRCR_PCBA (1 << 10) /* 1: after execution */
-#define BRCR_DBEB (1 << 7)
-#define BRCR_PCBB (1 << 6)
-#define BRCR_SEQ (1 << 3)
-#define BRCR_UBDE (1 << 0)
-#endif
-
-#endif /* __KERNEL__ */
-#endif /* __ASM_SH_UBC_H */
diff --git a/arch/sh/include/asm/uncached.h b/arch/sh/include/asm/uncached.h
new file mode 100644
index 00000000000..e3419f96626
--- /dev/null
+++ b/arch/sh/include/asm/uncached.h
@@ -0,0 +1,18 @@
+#ifndef __ASM_SH_UNCACHED_H
+#define __ASM_SH_UNCACHED_H
+
+#include <linux/bug.h>
+
+#ifdef CONFIG_UNCACHED_MAPPING
+extern unsigned long uncached_start, uncached_end;
+
+extern int virt_addr_uncached(unsigned long kaddr);
+extern void uncached_init(void);
+extern void uncached_resize(unsigned long size);
+#else
+#define virt_addr_uncached(kaddr) (0)
+#define uncached_init() do { } while (0)
+#define uncached_resize(size) BUG()
+#endif
+
+#endif /* __ASM_SH_UNCACHED_H */
diff --git a/arch/sh/include/asm/vmlinux.lds.h b/arch/sh/include/asm/vmlinux.lds.h
index 244ec4ad9a7..d58ad493b3a 100644
--- a/arch/sh/include/asm/vmlinux.lds.h
+++ b/arch/sh/include/asm/vmlinux.lds.h
@@ -14,4 +14,12 @@
#define DWARF_EH_FRAME
#endif
+#ifdef CONFIG_SUPERH64
+#define EXTRA_TEXT \
+ *(.text64) \
+ *(.text..SHmedia32)
+#else
+#define EXTRA_TEXT
+#endif
+
#endif /* __ASM_SH_VMLINUX_LDS_H */
diff --git a/arch/sh/include/asm/watchdog.h b/arch/sh/include/asm/watchdog.h
index 19dfff5c851..85a7aca7fb8 100644
--- a/arch/sh/include/asm/watchdog.h
+++ b/arch/sh/include/asm/watchdog.h
@@ -70,7 +70,7 @@
*/
static inline __u32 sh_wdt_read_cnt(void)
{
- return ctrl_inl(WTCNT_R);
+ return __raw_readl(WTCNT_R);
}
/**
@@ -82,7 +82,7 @@ static inline __u32 sh_wdt_read_cnt(void)
*/
static inline void sh_wdt_write_cnt(__u32 val)
{
- ctrl_outl((WTCNT_HIGH << 24) | (__u32)val, WTCNT);
+ __raw_writel((WTCNT_HIGH << 24) | (__u32)val, WTCNT);
}
/**
@@ -94,7 +94,7 @@ static inline void sh_wdt_write_cnt(__u32 val)
*/
static inline void sh_wdt_write_bst(__u32 val)
{
- ctrl_outl((WTBST_HIGH << 24) | (__u32)val, WTBST);
+ __raw_writel((WTBST_HIGH << 24) | (__u32)val, WTBST);
}
/**
* sh_wdt_read_csr - Read from Control/Status Register
@@ -103,7 +103,7 @@ static inline void sh_wdt_write_bst(__u32 val)
*/
static inline __u32 sh_wdt_read_csr(void)
{
- return ctrl_inl(WTCSR_R);
+ return __raw_readl(WTCSR_R);
}
/**
@@ -115,7 +115,7 @@ static inline __u32 sh_wdt_read_csr(void)
*/
static inline void sh_wdt_write_csr(__u32 val)
{
- ctrl_outl((WTCSR_HIGH << 24) | (__u32)val, WTCSR);
+ __raw_writel((WTCSR_HIGH << 24) | (__u32)val, WTCSR);
}
#else
/**
@@ -124,7 +124,7 @@ static inline void sh_wdt_write_csr(__u32 val)
*/
static inline __u8 sh_wdt_read_cnt(void)
{
- return ctrl_inb(WTCNT_R);
+ return __raw_readb(WTCNT_R);
}
/**
@@ -136,7 +136,7 @@ static inline __u8 sh_wdt_read_cnt(void)
*/
static inline void sh_wdt_write_cnt(__u8 val)
{
- ctrl_outw((WTCNT_HIGH << 8) | (__u16)val, WTCNT);
+ __raw_writew((WTCNT_HIGH << 8) | (__u16)val, WTCNT);
}
/**
@@ -146,7 +146,7 @@ static inline void sh_wdt_write_cnt(__u8 val)
*/
static inline __u8 sh_wdt_read_csr(void)
{
- return ctrl_inb(WTCSR_R);
+ return __raw_readb(WTCSR_R);
}
/**
@@ -158,7 +158,7 @@ static inline __u8 sh_wdt_read_csr(void)
*/
static inline void sh_wdt_write_csr(__u8 val)
{
- ctrl_outw((WTCSR_HIGH << 8) | (__u16)val, WTCSR);
+ __raw_writew((WTCSR_HIGH << 8) | (__u16)val, WTCSR);
}
#endif /* CONFIG_CPU_SUBTYPE_SH7785 || CONFIG_CPU_SUBTYPE_SH7780 */
#endif /* __KERNEL__ */
diff --git a/arch/sh/include/cpu-sh2/cpu/ubc.h b/arch/sh/include/cpu-sh2/cpu/ubc.h
deleted file mode 100644
index ba0e87f19c7..00000000000
--- a/arch/sh/include/cpu-sh2/cpu/ubc.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * include/asm-sh/cpu-sh2/ubc.h
- *
- * Copyright (C) 2003 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.
- */
-#ifndef __ASM_CPU_SH2_UBC_H
-#define __ASM_CPU_SH2_UBC_H
-
-#define UBC_BARA 0xffffff40
-#define UBC_BAMRA 0xffffff44
-#define UBC_BBRA 0xffffff48
-#define UBC_BARB 0xffffff60
-#define UBC_BAMRB 0xffffff64
-#define UBC_BBRB 0xffffff68
-#define UBC_BDRB 0xffffff70
-#define UBC_BDMRB 0xffffff74
-#define UBC_BRCR 0xffffff78
-
-/*
- * We don't have any ASID changes to make in the UBC on the SH-2.
- *
- * Make these purposely invalid to track misuse.
- */
-#define UBC_BASRA 0x00000000
-#define UBC_BASRB 0x00000000
-
-#endif /* __ASM_CPU_SH2_UBC_H */
-
diff --git a/arch/sh/include/cpu-sh2/cpu/watchdog.h b/arch/sh/include/cpu-sh2/cpu/watchdog.h
index 393161c9c6d..1eab8aa63a6 100644
--- a/arch/sh/include/cpu-sh2/cpu/watchdog.h
+++ b/arch/sh/include/cpu-sh2/cpu/watchdog.h
@@ -44,7 +44,7 @@ static inline __u8 sh_wdt_read_rstcsr(void)
/*
* Same read/write brain-damage as for WTCNT here..
*/
- return ctrl_inb(RSTCSR_R);
+ return __raw_readb(RSTCSR_R);
}
/**
@@ -62,7 +62,7 @@ static inline void sh_wdt_write_rstcsr(__u8 val)
* we can't presently touch the WOVF bit, since the upper byte
* has to be swapped for this. So just leave it alone..
*/
- ctrl_outw((WTCNT_HIGH << 8) | (__u16)val, RSTCSR);
+ __raw_writeb((WTCNT_HIGH << 8) | (__u16)val, RSTCSR);
}
#endif /* __ASM_CPU_SH2_WATCHDOG_H */
diff --git a/arch/sh/include/cpu-sh3/cpu/dac.h b/arch/sh/include/cpu-sh3/cpu/dac.h
index 05fda8316eb..98f1d15f0ab 100644
--- a/arch/sh/include/cpu-sh3/cpu/dac.h
+++ b/arch/sh/include/cpu-sh3/cpu/dac.h
@@ -17,25 +17,25 @@
static __inline__ void sh_dac_enable(int channel)
{
unsigned char v;
- v = ctrl_inb(DACR);
+ v = __raw_readb(DACR);
if(channel) v |= DACR_DAOE1;
else v |= DACR_DAOE0;
- ctrl_outb(v,DACR);
+ __raw_writeb(v,DACR);
}
static __inline__ void sh_dac_disable(int channel)
{
unsigned char v;
- v = ctrl_inb(DACR);
+ v = __raw_readb(DACR);
if(channel) v &= ~DACR_DAOE1;
else v &= ~DACR_DAOE0;
- ctrl_outb(v,DACR);
+ __raw_writeb(v,DACR);
}
static __inline__ void sh_dac_output(u8 value, int channel)
{
- if(channel) ctrl_outb(value,DADR1);
- else ctrl_outb(value,DADR0);
+ if(channel) __raw_writeb(value,DADR1);
+ else __raw_writeb(value,DADR0);
}
#endif /* __ASM_CPU_SH3_DAC_H */
diff --git a/arch/sh/include/cpu-sh3/cpu/dma.h b/arch/sh/include/cpu-sh3/cpu/dma.h
index 0ea15f3f236..207811a7a65 100644
--- a/arch/sh/include/cpu-sh3/cpu/dma.h
+++ b/arch/sh/include/cpu-sh3/cpu/dma.h
@@ -20,8 +20,10 @@
#define TS_32 0x00000010
#define TS_128 0x00000018
-#define CHCR_TS_MASK 0x18
-#define CHCR_TS_SHIFT 3
+#define CHCR_TS_LOW_MASK 0x18
+#define CHCR_TS_LOW_SHIFT 3
+#define CHCR_TS_HIGH_MASK 0
+#define CHCR_TS_HIGH_SHIFT 0
#define DMAOR_INIT DMAOR_DME
@@ -36,11 +38,13 @@ enum {
XMIT_SZ_128BIT,
};
-static unsigned int ts_shift[] __maybe_unused = {
- [XMIT_SZ_8BIT] = 0,
- [XMIT_SZ_16BIT] = 1,
- [XMIT_SZ_32BIT] = 2,
- [XMIT_SZ_128BIT] = 4,
-};
+#define TS_SHIFT { \
+ [XMIT_SZ_8BIT] = 0, \
+ [XMIT_SZ_16BIT] = 1, \
+ [XMIT_SZ_32BIT] = 2, \
+ [XMIT_SZ_128BIT] = 4, \
+}
+
+#define TS_INDEX2VAL(i) (((i) & 3) << CHCR_TS_LOW_SHIFT)
#endif /* __ASM_CPU_SH3_DMA_H */
diff --git a/arch/sh/include/cpu-sh3/cpu/ubc.h b/arch/sh/include/cpu-sh3/cpu/ubc.h
deleted file mode 100644
index 4e6381d5ff7..00000000000
--- a/arch/sh/include/cpu-sh3/cpu/ubc.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * include/asm-sh/cpu-sh3/ubc.h
- *
- * Copyright (C) 1999 Niibe Yutaka
- * Copyright (C) 2003 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.
- */
-#ifndef __ASM_CPU_SH3_UBC_H
-#define __ASM_CPU_SH3_UBC_H
-
-#if defined(CONFIG_CPU_SUBTYPE_SH7710) || \
- defined(CONFIG_CPU_SUBTYPE_SH7720) || \
- defined(CONFIG_CPU_SUBTYPE_SH7721)
-#define UBC_BARA 0xa4ffffb0
-#define UBC_BAMRA 0xa4ffffb4
-#define UBC_BBRA 0xa4ffffb8
-#define UBC_BASRA 0xffffffe4
-#define UBC_BARB 0xa4ffffa0
-#define UBC_BAMRB 0xa4ffffa4
-#define UBC_BBRB 0xa4ffffa8
-#define UBC_BASRB 0xffffffe8
-#define UBC_BDRB 0xa4ffff90
-#define UBC_BDMRB 0xa4ffff94
-#define UBC_BRCR 0xa4ffff98
-#else
-#define UBC_BARA 0xffffffb0
-#define UBC_BAMRA 0xffffffb4
-#define UBC_BBRA 0xffffffb8
-#define UBC_BASRA 0xffffffe4
-#define UBC_BARB 0xffffffa0
-#define UBC_BAMRB 0xffffffa4
-#define UBC_BBRB 0xffffffa8
-#define UBC_BASRB 0xffffffe8
-#define UBC_BDRB 0xffffff90
-#define UBC_BDMRB 0xffffff94
-#define UBC_BRCR 0xffffff98
-#endif
-
-#endif /* __ASM_CPU_SH3_UBC_H */
diff --git a/arch/sh/include/cpu-sh4/cpu/addrspace.h b/arch/sh/include/cpu-sh4/cpu/addrspace.h
index a3fa733c1c7..d51da25da72 100644
--- a/arch/sh/include/cpu-sh4/cpu/addrspace.h
+++ b/arch/sh/include/cpu-sh4/cpu/addrspace.h
@@ -28,6 +28,15 @@
#define P4SEG_TLB_DATA 0xf7000000
#define P4SEG_REG_BASE 0xff000000
+#define PA_AREA0 0x00000000
+#define PA_AREA1 0x04000000
+#define PA_AREA2 0x08000000
+#define PA_AREA3 0x0c000000
+#define PA_AREA4 0x10000000
+#define PA_AREA5 0x14000000
+#define PA_AREA6 0x18000000
+#define PA_AREA7 0x1c000000
+
#define PA_AREA5_IO 0xb4000000 /* Area 5 IO Memory */
#define PA_AREA6_IO 0xb8000000 /* Area 6 IO Memory */
diff --git a/arch/sh/include/cpu-sh4/cpu/dma-sh4a.h b/arch/sh/include/cpu-sh4/cpu/dma-sh4a.h
index c4ed660c14c..e734ea47d8a 100644
--- a/arch/sh/include/cpu-sh4/cpu/dma-sh4a.h
+++ b/arch/sh/include/cpu-sh4/cpu/dma-sh4a.h
@@ -2,22 +2,38 @@
#define __ASM_SH_CPU_SH4_DMA_SH7780_H
#if defined(CONFIG_CPU_SUBTYPE_SH7343) || \
- defined(CONFIG_CPU_SUBTYPE_SH7722) || \
defined(CONFIG_CPU_SUBTYPE_SH7730)
#define DMTE0_IRQ 48
#define DMTE4_IRQ 76
#define DMAE0_IRQ 78 /* DMA Error IRQ*/
#define SH_DMAC_BASE0 0xFE008020
-#define SH_DMARS_BASE 0xFE009000
+#define SH_DMARS_BASE0 0xFE009000
+#define CHCR_TS_LOW_MASK 0x00000018
+#define CHCR_TS_LOW_SHIFT 3
+#define CHCR_TS_HIGH_MASK 0
+#define CHCR_TS_HIGH_SHIFT 0
+#elif defined(CONFIG_CPU_SUBTYPE_SH7722)
+#define DMTE0_IRQ 48
+#define DMTE4_IRQ 76
+#define DMAE0_IRQ 78 /* DMA Error IRQ*/
+#define SH_DMAC_BASE0 0xFE008020
+#define SH_DMARS_BASE0 0xFE009000
+#define CHCR_TS_LOW_MASK 0x00000018
+#define CHCR_TS_LOW_SHIFT 3
+#define CHCR_TS_HIGH_MASK 0x00300000
+#define CHCR_TS_HIGH_SHIFT 20
#elif defined(CONFIG_CPU_SUBTYPE_SH7763) || \
defined(CONFIG_CPU_SUBTYPE_SH7764)
#define DMTE0_IRQ 34
#define DMTE4_IRQ 44
#define DMAE0_IRQ 38
#define SH_DMAC_BASE0 0xFF608020
-#define SH_DMARS_BASE 0xFF609000
-#elif defined(CONFIG_CPU_SUBTYPE_SH7723) || \
- defined(CONFIG_CPU_SUBTYPE_SH7724)
+#define SH_DMARS_BASE0 0xFF609000
+#define CHCR_TS_LOW_MASK 0x00000018
+#define CHCR_TS_LOW_SHIFT 3
+#define CHCR_TS_HIGH_MASK 0
+#define CHCR_TS_HIGH_SHIFT 0
+#elif defined(CONFIG_CPU_SUBTYPE_SH7723)
#define DMTE0_IRQ 48 /* DMAC0A*/
#define DMTE4_IRQ 76 /* DMAC0B */
#define DMTE6_IRQ 40
@@ -29,7 +45,29 @@
#define DMAE1_IRQ 74 /* DMA Error IRQ*/
#define SH_DMAC_BASE0 0xFE008020
#define SH_DMAC_BASE1 0xFDC08020
-#define SH_DMARS_BASE 0xFDC09000
+#define SH_DMARS_BASE0 0xFDC09000
+#define CHCR_TS_LOW_MASK 0x00000018
+#define CHCR_TS_LOW_SHIFT 3
+#define CHCR_TS_HIGH_MASK 0
+#define CHCR_TS_HIGH_SHIFT 0
+#elif defined(CONFIG_CPU_SUBTYPE_SH7724)
+#define DMTE0_IRQ 48 /* DMAC0A*/
+#define DMTE4_IRQ 76 /* DMAC0B */
+#define DMTE6_IRQ 40
+#define DMTE8_IRQ 42 /* DMAC1A */
+#define DMTE9_IRQ 43
+#define DMTE10_IRQ 72 /* DMAC1B */
+#define DMTE11_IRQ 73
+#define DMAE0_IRQ 78 /* DMA Error IRQ*/
+#define DMAE1_IRQ 74 /* DMA Error IRQ*/
+#define SH_DMAC_BASE0 0xFE008020
+#define SH_DMAC_BASE1 0xFDC08020
+#define SH_DMARS_BASE0 0xFE009000
+#define SH_DMARS_BASE1 0xFDC09000
+#define CHCR_TS_LOW_MASK 0x00000018
+#define CHCR_TS_LOW_SHIFT 3
+#define CHCR_TS_HIGH_MASK 0x00600000
+#define CHCR_TS_HIGH_SHIFT 21
#elif defined(CONFIG_CPU_SUBTYPE_SH7780)
#define DMTE0_IRQ 34
#define DMTE4_IRQ 44
@@ -41,7 +79,11 @@
#define DMAE0_IRQ 38 /* DMA Error IRQ */
#define SH_DMAC_BASE0 0xFC808020
#define SH_DMAC_BASE1 0xFC818020
-#define SH_DMARS_BASE 0xFC809000
+#define SH_DMARS_BASE0 0xFC809000
+#define CHCR_TS_LOW_MASK 0x00000018
+#define CHCR_TS_LOW_SHIFT 3
+#define CHCR_TS_HIGH_MASK 0
+#define CHCR_TS_HIGH_SHIFT 0
#else /* SH7785 */
#define DMTE0_IRQ 33
#define DMTE4_IRQ 37
@@ -54,18 +96,17 @@
#define DMAE1_IRQ 58 /* DMA Error IRQ1 */
#define SH_DMAC_BASE0 0xFC808020
#define SH_DMAC_BASE1 0xFCC08020
-#define SH_DMARS_BASE 0xFC809000
+#define SH_DMARS_BASE0 0xFC809000
+#define CHCR_TS_LOW_MASK 0x00000018
+#define CHCR_TS_LOW_SHIFT 3
+#define CHCR_TS_HIGH_MASK 0
+#define CHCR_TS_HIGH_SHIFT 0
#endif
-#define REQ_HE 0x000000C0
-#define REQ_H 0x00000080
-#define REQ_LE 0x00000040
-#define TM_BURST 0x0000020
-#define TS_8 0x00000000
-#define TS_16 0x00000008
-#define TS_32 0x00000010
-#define TS_16BLK 0x00000018
-#define TS_32BLK 0x00100000
+#define REQ_HE 0x000000C0
+#define REQ_H 0x00000080
+#define REQ_LE 0x00000040
+#define TM_BURST 0x00000020
/*
* The SuperH DMAC supports a number of transmit sizes, we list them here,
@@ -74,22 +115,31 @@
* Defaults to a 64-bit transfer size.
*/
enum {
- XMIT_SZ_8BIT,
- XMIT_SZ_16BIT,
- XMIT_SZ_32BIT,
- XMIT_SZ_128BIT,
- XMIT_SZ_256BIT,
+ XMIT_SZ_8BIT = 0,
+ XMIT_SZ_16BIT = 1,
+ XMIT_SZ_32BIT = 2,
+ XMIT_SZ_64BIT = 7,
+ XMIT_SZ_128BIT = 3,
+ XMIT_SZ_256BIT = 4,
+ XMIT_SZ_128BIT_BLK = 0xb,
+ XMIT_SZ_256BIT_BLK = 0xc,
};
/*
* The DMA count is defined as the number of bytes to transfer.
*/
-static unsigned int ts_shift[] __maybe_unused = {
- [XMIT_SZ_8BIT] = 0,
- [XMIT_SZ_16BIT] = 1,
- [XMIT_SZ_32BIT] = 2,
- [XMIT_SZ_128BIT] = 4,
- [XMIT_SZ_256BIT] = 5,
-};
+#define TS_SHIFT { \
+ [XMIT_SZ_8BIT] = 0, \
+ [XMIT_SZ_16BIT] = 1, \
+ [XMIT_SZ_32BIT] = 2, \
+ [XMIT_SZ_64BIT] = 3, \
+ [XMIT_SZ_128BIT] = 4, \
+ [XMIT_SZ_256BIT] = 5, \
+ [XMIT_SZ_128BIT_BLK] = 4, \
+ [XMIT_SZ_256BIT_BLK] = 5, \
+}
+
+#define TS_INDEX2VAL(i) ((((i) & 3) << CHCR_TS_LOW_SHIFT) | \
+ ((((i) >> 2) & 3) << CHCR_TS_HIGH_SHIFT))
#endif /* __ASM_SH_CPU_SH4_DMA_SH7780_H */
diff --git a/arch/sh/include/cpu-sh4/cpu/dma.h b/arch/sh/include/cpu-sh4/cpu/dma.h
index bcb30246e85..114a369705b 100644
--- a/arch/sh/include/cpu-sh4/cpu/dma.h
+++ b/arch/sh/include/cpu-sh4/cpu/dma.h
@@ -6,8 +6,6 @@
#ifdef CONFIG_CPU_SH4A
#define DMAOR_INIT (DMAOR_DME)
-#define CHCR_TS_MASK 0x18
-#define CHCR_TS_SHIFT 3
#include <cpu/dma-sh4a.h>
#else /* CONFIG_CPU_SH4A */
@@ -29,8 +27,10 @@
#define TS_32 0x00000030
#define TS_64 0x00000000
-#define CHCR_TS_MASK 0x70
-#define CHCR_TS_SHIFT 4
+#define CHCR_TS_LOW_MASK 0x70
+#define CHCR_TS_LOW_SHIFT 4
+#define CHCR_TS_HIGH_MASK 0
+#define CHCR_TS_HIGH_SHIFT 0
#define DMAOR_COD 0x00000008
@@ -41,23 +41,26 @@
* Defaults to a 64-bit transfer size.
*/
enum {
- XMIT_SZ_64BIT,
- XMIT_SZ_8BIT,
- XMIT_SZ_16BIT,
- XMIT_SZ_32BIT,
- XMIT_SZ_256BIT,
+ XMIT_SZ_8BIT = 1,
+ XMIT_SZ_16BIT = 2,
+ XMIT_SZ_32BIT = 3,
+ XMIT_SZ_64BIT = 0,
+ XMIT_SZ_256BIT = 4,
};
/*
* The DMA count is defined as the number of bytes to transfer.
*/
-static unsigned int ts_shift[] __maybe_unused = {
- [XMIT_SZ_64BIT] = 3,
- [XMIT_SZ_8BIT] = 0,
- [XMIT_SZ_16BIT] = 1,
- [XMIT_SZ_32BIT] = 2,
- [XMIT_SZ_256BIT] = 5,
-};
+#define TS_SHIFT { \
+ [XMIT_SZ_8BIT] = 0, \
+ [XMIT_SZ_16BIT] = 1, \
+ [XMIT_SZ_32BIT] = 2, \
+ [XMIT_SZ_64BIT] = 3, \
+ [XMIT_SZ_256BIT] = 5, \
+}
+
+#define TS_INDEX2VAL(i) (((i) & 7) << CHCR_TS_LOW_SHIFT)
+
#endif
#endif /* __ASM_CPU_SH4_DMA_H */
diff --git a/arch/sh/include/cpu-sh4/cpu/mmu_context.h b/arch/sh/include/cpu-sh4/cpu/mmu_context.h
index 3ce7ef6c297..03ea75c5315 100644
--- a/arch/sh/include/cpu-sh4/cpu/mmu_context.h
+++ b/arch/sh/include/cpu-sh4/cpu/mmu_context.h
@@ -25,6 +25,10 @@
#define MMUCR_TI (1<<2)
+#define MMUCR_URB 0x00FC0000
+#define MMUCR_URB_SHIFT 18
+#define MMUCR_URB_NENTRIES 64
+
#if defined(CONFIG_32BIT) && defined(CONFIG_CPU_SUBTYPE_ST40)
#define MMUCR_SE (1 << 4)
#else
diff --git a/arch/sh/include/cpu-sh4/cpu/sq.h b/arch/sh/include/cpu-sh4/cpu/sq.h
index 586d6491816..74716ba2dc3 100644
--- a/arch/sh/include/cpu-sh4/cpu/sq.h
+++ b/arch/sh/include/cpu-sh4/cpu/sq.h
@@ -12,6 +12,7 @@
#define __ASM_CPU_SH4_SQ_H
#include <asm/addrspace.h>
+#include <asm/page.h>
/*
* Store queues range from e0000000-e3fffffc, allowing approx. 64MB to be
@@ -28,7 +29,7 @@
/* arch/sh/kernel/cpu/sh4/sq.c */
unsigned long sq_remap(unsigned long phys, unsigned int size,
- const char *name, unsigned long flags);
+ const char *name, pgprot_t prot);
void sq_unmap(unsigned long vaddr);
void sq_flush_range(unsigned long start, unsigned int len);
diff --git a/arch/sh/include/cpu-sh4/cpu/ubc.h b/arch/sh/include/cpu-sh4/cpu/ubc.h
deleted file mode 100644
index c86e1705093..00000000000
--- a/arch/sh/include/cpu-sh4/cpu/ubc.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * include/asm-sh/cpu-sh4/ubc.h
- *
- * Copyright (C) 1999 Niibe Yutaka
- * Copyright (C) 2003 Paul Mundt
- * Copyright (C) 2006 Lineo Solutions Inc. support SH4A UBC
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- */
-#ifndef __ASM_CPU_SH4_UBC_H
-#define __ASM_CPU_SH4_UBC_H
-
-#if defined(CONFIG_CPU_SH4A)
-#define UBC_CBR0 0xff200000
-#define UBC_CRR0 0xff200004
-#define UBC_CAR0 0xff200008
-#define UBC_CAMR0 0xff20000c
-#define UBC_CBR1 0xff200020
-#define UBC_CRR1 0xff200024
-#define UBC_CAR1 0xff200028
-#define UBC_CAMR1 0xff20002c
-#define UBC_CDR1 0xff200030
-#define UBC_CDMR1 0xff200034
-#define UBC_CETR1 0xff200038
-#define UBC_CCMFR 0xff200600
-#define UBC_CBCR 0xff200620
-
-/* CBR */
-#define UBC_CBR_AIE (0x01<<30)
-#define UBC_CBR_ID_INST (0x01<<4)
-#define UBC_CBR_RW_READ (0x01<<1)
-#define UBC_CBR_CE (0x01)
-
-#define UBC_CBR_AIV_MASK (0x00FF0000)
-#define UBC_CBR_AIV_SHIFT (16)
-#define UBC_CBR_AIV_SET(asid) (((asid)<<UBC_CBR_AIV_SHIFT) & UBC_CBR_AIV_MASK)
-
-#define UBC_CBR_INIT 0x20000000
-
-/* CRR */
-#define UBC_CRR_RES (0x01<<13)
-#define UBC_CRR_PCB (0x01<<1)
-#define UBC_CRR_BIE (0x01)
-
-#define UBC_CRR_INIT 0x00002000
-
-#else /* CONFIG_CPU_SH4 */
-#define UBC_BARA 0xff200000
-#define UBC_BAMRA 0xff200004
-#define UBC_BBRA 0xff200008
-#define UBC_BASRA 0xff000014
-#define UBC_BARB 0xff20000c
-#define UBC_BAMRB 0xff200010
-#define UBC_BBRB 0xff200014
-#define UBC_BASRB 0xff000018
-#define UBC_BDRB 0xff200018
-#define UBC_BDMRB 0xff20001c
-#define UBC_BRCR 0xff200020
-#endif /* CONFIG_CPU_SH4 */
-
-#endif /* __ASM_CPU_SH4_UBC_H */
-
diff --git a/arch/sh/include/mach-common/mach/magicpanelr2.h b/arch/sh/include/mach-common/mach/magicpanelr2.h
index c644a77ee35..183a2f74425 100644
--- a/arch/sh/include/mach-common/mach/magicpanelr2.h
+++ b/arch/sh/include/mach-common/mach/magicpanelr2.h
@@ -19,12 +19,12 @@
#include <asm/io_generic.h>
-#define SETBITS_OUTB(mask, reg) ctrl_outb(ctrl_inb(reg) | mask, reg)
-#define SETBITS_OUTW(mask, reg) ctrl_outw(ctrl_inw(reg) | mask, reg)
-#define SETBITS_OUTL(mask, reg) ctrl_outl(ctrl_inl(reg) | mask, reg)
-#define CLRBITS_OUTB(mask, reg) ctrl_outb(ctrl_inb(reg) & ~mask, reg)
-#define CLRBITS_OUTW(mask, reg) ctrl_outw(ctrl_inw(reg) & ~mask, reg)
-#define CLRBITS_OUTL(mask, reg) ctrl_outl(ctrl_inl(reg) & ~mask, reg)
+#define SETBITS_OUTB(mask, reg) __raw_writeb(__raw_readb(reg) | mask, reg)
+#define SETBITS_OUTW(mask, reg) __raw_writew(__raw_readw(reg) | mask, reg)
+#define SETBITS_OUTL(mask, reg) __raw_writel(__raw_readl(reg) | mask, reg)
+#define CLRBITS_OUTB(mask, reg) __raw_writeb(__raw_readb(reg) & ~mask, reg)
+#define CLRBITS_OUTW(mask, reg) __raw_writew(__raw_readw(reg) & ~mask, reg)
+#define CLRBITS_OUTL(mask, reg) __raw_writel(__raw_readl(reg) & ~mask, reg)
#define PA_LED PORT_PADR /* LED */
diff --git a/arch/sh/include/mach-dreamcast/mach/sysasic.h b/arch/sh/include/mach-dreamcast/mach/sysasic.h
index f33426608a8..58f710e1ebc 100644
--- a/arch/sh/include/mach-dreamcast/mach/sysasic.h
+++ b/arch/sh/include/mach-dreamcast/mach/sysasic.h
@@ -39,5 +39,10 @@
#define HW_EVENT_IRQ_MAX (HW_EVENT_IRQ_BASE + 95)
+/* arch/sh/boards/mach-dreamcast/irq.c */
+extern int systemasic_irq_demux(int);
+extern void systemasic_irq_init(void);
+extern void aica_time_init(void);
+
#endif /* __ASM_SH_DREAMCAST_SYSASIC_H */
diff --git a/arch/sh/include/mach-sdk7786/mach/fpga.h b/arch/sh/include/mach-sdk7786/mach/fpga.h
new file mode 100644
index 00000000000..2120d67dec7
--- /dev/null
+++ b/arch/sh/include/mach-sdk7786/mach/fpga.h
@@ -0,0 +1,114 @@
+#ifndef __MACH_SDK7786_FPGA_H
+#define __MACH_SDK7786_FPGA_H
+
+#include <linux/io.h>
+#include <linux/types.h>
+#include <linux/bitops.h>
+
+#define SRSTR 0x000
+#define SRSTR_MAGIC 0x1971 /* Fixed magical read value */
+
+#define INTASR 0x010
+#define INTAMR 0x020
+#define MODSWR 0x030
+#define INTTESTR 0x040
+#define SYSSR 0x050
+#define NRGPR 0x060
+#define NMISR 0x070
+
+#define NMIMR 0x080
+#define NMIMR_MAN_NMIM BIT(0) /* Manual NMI mask */
+#define NMIMR_AUX_NMIM BIT(1) /* Auxiliary NMI mask */
+
+#define INTBSR 0x090
+#define INTBMR 0x0a0
+#define USRLEDR 0x0b0
+#define MAPSWR 0x0c0
+#define FPGAVR 0x0d0
+#define FPGADR 0x0e0
+#define PCBRR 0x0f0
+#define RSR 0x100
+#define EXTASR 0x110
+#define SPCAR 0x120
+#define INTMSR 0x130
+#define PCIECR 0x140
+#define FAER 0x150
+#define USRGPIR 0x160
+/* 0x170 reserved */
+#define LCLASR 0x180
+
+#define SBCR 0x190
+#define SCBR_I2CMEN BIT(0) /* FPGA I2C master enable */
+#define SCBR_I2CCEN BIT(1) /* CPU I2C master enable */
+
+#define PWRCR 0x1a0
+#define SPCBR 0x1b0
+#define SPICR 0x1c0
+#define SPIDR 0x1d0
+#define I2CCR 0x1e0
+#define I2CDR 0x1f0
+#define FPGACR 0x200
+#define IASELR1 0x210
+#define IASELR2 0x220
+#define IASELR3 0x230
+#define IASELR4 0x240
+#define IASELR5 0x250
+#define IASELR6 0x260
+#define IASELR7 0x270
+#define IASELR8 0x280
+#define IASELR9 0x290
+#define IASELR10 0x2a0
+#define IASELR11 0x2b0
+#define IASELR12 0x2c0
+#define IASELR13 0x2d0
+#define IASELR14 0x2e0
+#define IASELR15 0x2f0
+/* 0x300 reserved */
+#define IBSELR1 0x310
+#define IBSELR2 0x320
+#define IBSELR3 0x330
+#define IBSELR4 0x340
+#define IBSELR5 0x350
+#define IBSELR6 0x360
+#define IBSELR7 0x370
+#define IBSELR8 0x380
+#define IBSELR9 0x390
+#define IBSELR10 0x3a0
+#define IBSELR11 0x3b0
+#define IBSELR12 0x3c0
+#define IBSELR13 0x3d0
+#define IBSELR14 0x3e0
+#define IBSELR15 0x3f0
+#define USRACR 0x400
+#define BEEPR 0x410
+#define USRLCDR 0x420
+#define SMBCR 0x430
+#define SMBDR 0x440
+#define USBCR 0x450
+#define AMSR 0x460
+#define ACCR 0x470
+#define SDIFCR 0x480
+
+/* arch/sh/boards/mach-sdk7786/fpga.c */
+extern void __iomem *sdk7786_fpga_base;
+extern void sdk7786_fpga_init(void);
+
+#define SDK7786_FPGA_REGADDR(reg) (sdk7786_fpga_base + (reg))
+
+/*
+ * A convenience wrapper from register offset to internal I2C address,
+ * when the FPGA is in I2C slave mode.
+ */
+#define SDK7786_FPGA_I2CADDR(reg) ((reg) >> 3)
+
+static inline u16 fpga_read_reg(unsigned int reg)
+{
+ return ioread16(sdk7786_fpga_base + reg);
+}
+
+static inline void fpga_write_reg(u16 val, unsigned int reg)
+{
+ iowrite16(val, sdk7786_fpga_base + reg);
+}
+
+#endif /* __MACH_SDK7786_FPGA_H */
diff --git a/arch/sh/include/mach-sdk7786/mach/irq.h b/arch/sh/include/mach-sdk7786/mach/irq.h
new file mode 100644
index 00000000000..0f584635e6e
--- /dev/null
+++ b/arch/sh/include/mach-sdk7786/mach/irq.h
@@ -0,0 +1,7 @@
+#ifndef __MACH_SDK7786_IRQ_H
+#define __MACH_SDK7786_IRQ_H
+
+/* arch/sh/boards/mach-sdk7786/irq.c */
+extern void sdk7786_init_irq(void);
+
+#endif /* __MACH_SDK7786_IRQ_H */
diff --git a/arch/sh/include/mach-se/mach/se7343.h b/arch/sh/include/mach-se/mach/se7343.h
index 749914b400f..8d8170d6cc4 100644
--- a/arch/sh/include/mach-se/mach/se7343.h
+++ b/arch/sh/include/mach-se/mach/se7343.h
@@ -94,26 +94,26 @@
#define PORT_DRVCR 0xA4050180
-#define PORT_PADR 0xA4050120
-#define PORT_PBDR 0xA4050122
-#define PORT_PCDR 0xA4050124
-#define PORT_PDDR 0xA4050126
-#define PORT_PEDR 0xA4050128
-#define PORT_PFDR 0xA405012A
-#define PORT_PGDR 0xA405012C
-#define PORT_PHDR 0xA405012E
-#define PORT_PJDR 0xA4050130
-#define PORT_PKDR 0xA4050132
-#define PORT_PLDR 0xA4050134
-#define PORT_PMDR 0xA4050136
-#define PORT_PNDR 0xA4050138
-#define PORT_PQDR 0xA405013A
-#define PORT_PRDR 0xA405013C
-#define PORT_PTDR 0xA4050160
-#define PORT_PUDR 0xA4050162
-#define PORT_PVDR 0xA4050164
-#define PORT_PWDR 0xA4050166
-#define PORT_PYDR 0xA4050168
+#define PORT_PADR 0xA4050120
+#define PORT_PBDR 0xA4050122
+#define PORT_PCDR 0xA4050124
+#define PORT_PDDR 0xA4050126
+#define PORT_PEDR 0xA4050128
+#define PORT_PFDR 0xA405012A
+#define PORT_PGDR 0xA405012C
+#define PORT_PHDR 0xA405012E
+#define PORT_PJDR 0xA4050130
+#define PORT_PKDR 0xA4050132
+#define PORT_PLDR 0xA4050134
+#define PORT_PMDR 0xA4050136
+#define PORT_PNDR 0xA4050138
+#define PORT_PQDR 0xA405013A
+#define PORT_PRDR 0xA405013C
+#define PORT_PTDR 0xA4050160
+#define PORT_PUDR 0xA4050162
+#define PORT_PVDR 0xA4050164
+#define PORT_PWDR 0xA4050166
+#define PORT_PYDR 0xA4050168
#define FPGA_IN 0xb1400000
#define FPGA_OUT 0xb1400002
@@ -133,18 +133,10 @@
#define SE7343_FPGA_IRQ_UARTB 11
#define SE7343_FPGA_IRQ_NR 12
-#define SE7343_FPGA_IRQ_BASE 120
-
-#define MRSHPC_IRQ3 (SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_MRSHPC3)
-#define MRSHPC_IRQ2 (SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_MRSHPC2)
-#define MRSHPC_IRQ1 (SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_MRSHPC1)
-#define MRSHPC_IRQ0 (SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_MRSHPC0)
-#define SMC_IRQ (SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_SMC)
-#define USB_IRQ (SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_USB)
-#define UARTA_IRQ (SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_UARTA)
-#define UARTB_IRQ (SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_UARTB)
/* arch/sh/boards/se/7343/irq.c */
+extern unsigned int se7343_fpga_irq[];
+
void init_7343se_IRQ(void);
#endif /* __ASM_SH_HITACHI_SE7343_H */
diff --git a/arch/sh/kernel/Makefile b/arch/sh/kernel/Makefile
index 0d587da1ef1..02fd3ae8b0e 100644
--- a/arch/sh/kernel/Makefile
+++ b/arch/sh/kernel/Makefile
@@ -13,8 +13,9 @@ CFLAGS_REMOVE_return_address.o = -pg
obj-y := debugtraps.o dma-nommu.o dumpstack.o \
idle.o io.o io_generic.o irq.o \
- irq_$(BITS).o machvec.o nmi_debug.o process_$(BITS).o \
- ptrace_$(BITS).o return_address.o \
+ irq_$(BITS).o machvec.o nmi_debug.o process.o \
+ process_$(BITS).o ptrace_$(BITS).o \
+ reboot.o return_address.o \
setup.o signal_$(BITS).o sys_sh.o sys_sh$(BITS).o \
syscalls_$(BITS).o time.o topology.o traps.o \
traps_$(BITS).o unwinder.o
@@ -22,7 +23,7 @@ obj-y := debugtraps.o dma-nommu.o dumpstack.o \
obj-y += cpu/
obj-$(CONFIG_VSYSCALL) += vsyscall/
obj-$(CONFIG_SMP) += smp.o
-obj-$(CONFIG_SH_STANDARD_BIOS) += sh_bios.o early_printk.o
+obj-$(CONFIG_SH_STANDARD_BIOS) += sh_bios.o
obj-$(CONFIG_KGDB) += kgdb.o
obj-$(CONFIG_SH_CPU_FREQ) += cpufreq.o
obj-$(CONFIG_MODULES) += sh_ksyms_$(BITS).o module.o
@@ -39,6 +40,7 @@ obj-$(CONFIG_HIBERNATION) += swsusp.o
obj-$(CONFIG_DWARF_UNWINDER) += dwarf.o
obj-$(CONFIG_PERF_EVENTS) += perf_event.o perf_callchain.o
+obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o
obj-$(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) += localtimer.o
EXTRA_CFLAGS += -Werror
diff --git a/arch/sh/kernel/cpu/Makefile b/arch/sh/kernel/cpu/Makefile
index d97c803719e..0e48bc61c27 100644
--- a/arch/sh/kernel/cpu/Makefile
+++ b/arch/sh/kernel/cpu/Makefile
@@ -17,5 +17,7 @@ obj-$(CONFIG_ARCH_SHMOBILE) += shmobile/
obj-$(CONFIG_SH_ADC) += adc.o
obj-$(CONFIG_SH_CLK_CPG) += clock-cpg.o
+obj-$(CONFIG_SH_FPU) += fpu.o
+obj-$(CONFIG_SH_FPU_EMU) += fpu.o
obj-y += irq/ init.o clock.o hwblk.o
diff --git a/arch/sh/kernel/cpu/adc.c b/arch/sh/kernel/cpu/adc.c
index da3d6877f93..d307571d54b 100644
--- a/arch/sh/kernel/cpu/adc.c
+++ b/arch/sh/kernel/cpu/adc.c
@@ -18,19 +18,19 @@ int adc_single(unsigned int channel)
off = (channel & 0x03) << 2;
- csr = ctrl_inb(ADCSR);
+ csr = __raw_readb(ADCSR);
csr = channel | ADCSR_ADST | ADCSR_CKS;
- ctrl_outb(csr, ADCSR);
+ __raw_writeb(csr, ADCSR);
do {
- csr = ctrl_inb(ADCSR);
+ csr = __raw_readb(ADCSR);
} while ((csr & ADCSR_ADF) == 0);
csr &= ~(ADCSR_ADF | ADCSR_ADST);
- ctrl_outb(csr, ADCSR);
+ __raw_writeb(csr, ADCSR);
- return (((ctrl_inb(ADDRAH + off) << 8) |
- ctrl_inb(ADDRAL + off)) >> 6);
+ return (((__raw_readb(ADDRAH + off) << 8) |
+ __raw_readb(ADDRAL + off)) >> 6);
}
EXPORT_SYMBOL(adc_single);
diff --git a/arch/sh/kernel/cpu/clock-cpg.c b/arch/sh/kernel/cpu/clock-cpg.c
index 6dfe2cced3f..eed5eaff96b 100644
--- a/arch/sh/kernel/cpu/clock-cpg.c
+++ b/arch/sh/kernel/cpu/clock-cpg.c
@@ -149,7 +149,8 @@ int __init sh_clk_div6_register(struct clk *clks, int nr)
static unsigned long sh_clk_div4_recalc(struct clk *clk)
{
- struct clk_div_mult_table *table = clk->priv;
+ struct clk_div4_table *d4t = clk->priv;
+ struct clk_div_mult_table *table = d4t->div_mult_table;
unsigned int idx;
clk_rate_table_build(clk, clk->freq_table, table->nr_divisors,
@@ -160,17 +161,90 @@ static unsigned long sh_clk_div4_recalc(struct clk *clk)
return clk->freq_table[idx].frequency;
}
+static int sh_clk_div4_set_parent(struct clk *clk, struct clk *parent)
+{
+ struct clk_div4_table *d4t = clk->priv;
+ struct clk_div_mult_table *table = d4t->div_mult_table;
+ u32 value;
+ int ret;
+
+ if (!strcmp("pll_clk", parent->name))
+ value = __raw_readl(clk->enable_reg) & ~(1 << 7);
+ else
+ value = __raw_readl(clk->enable_reg) | (1 << 7);
+
+ ret = clk_reparent(clk, parent);
+ if (ret < 0)
+ return ret;
+
+ __raw_writel(value, clk->enable_reg);
+
+ /* Rebiuld the frequency table */
+ clk_rate_table_build(clk, clk->freq_table, table->nr_divisors,
+ table, &clk->arch_flags);
+
+ return 0;
+}
+
+static int sh_clk_div4_set_rate(struct clk *clk, unsigned long rate, int algo_id)
+{
+ struct clk_div4_table *d4t = clk->priv;
+ unsigned long value;
+ int idx = clk_rate_table_find(clk, clk->freq_table, rate);
+ if (idx < 0)
+ return idx;
+
+ value = __raw_readl(clk->enable_reg);
+ value &= ~(0xf << clk->enable_bit);
+ value |= (idx << clk->enable_bit);
+ __raw_writel(value, clk->enable_reg);
+
+ if (d4t->kick)
+ d4t->kick(clk);
+
+ return 0;
+}
+
+static int sh_clk_div4_enable(struct clk *clk)
+{
+ __raw_writel(__raw_readl(clk->enable_reg) & ~(1 << 8), clk->enable_reg);
+ return 0;
+}
+
+static void sh_clk_div4_disable(struct clk *clk)
+{
+ __raw_writel(__raw_readl(clk->enable_reg) | (1 << 8), clk->enable_reg);
+}
+
static struct clk_ops sh_clk_div4_clk_ops = {
.recalc = sh_clk_div4_recalc,
+ .set_rate = sh_clk_div4_set_rate,
.round_rate = sh_clk_div_round_rate,
};
-int __init sh_clk_div4_register(struct clk *clks, int nr,
- struct clk_div_mult_table *table)
+static struct clk_ops sh_clk_div4_enable_clk_ops = {
+ .recalc = sh_clk_div4_recalc,
+ .set_rate = sh_clk_div4_set_rate,
+ .round_rate = sh_clk_div_round_rate,
+ .enable = sh_clk_div4_enable,
+ .disable = sh_clk_div4_disable,
+};
+
+static struct clk_ops sh_clk_div4_reparent_clk_ops = {
+ .recalc = sh_clk_div4_recalc,
+ .set_rate = sh_clk_div4_set_rate,
+ .round_rate = sh_clk_div_round_rate,
+ .enable = sh_clk_div4_enable,
+ .disable = sh_clk_div4_disable,
+ .set_parent = sh_clk_div4_set_parent,
+};
+
+static int __init sh_clk_div4_register_ops(struct clk *clks, int nr,
+ struct clk_div4_table *table, struct clk_ops *ops)
{
struct clk *clkp;
void *freq_table;
- int nr_divs = table->nr_divisors;
+ int nr_divs = table->div_mult_table->nr_divisors;
int freq_table_size = sizeof(struct cpufreq_frequency_table);
int ret = 0;
int k;
@@ -185,7 +259,7 @@ int __init sh_clk_div4_register(struct clk *clks, int nr,
for (k = 0; !ret && (k < nr); k++) {
clkp = clks + k;
- clkp->ops = &sh_clk_div4_clk_ops;
+ clkp->ops = ops;
clkp->id = -1;
clkp->priv = table;
@@ -198,6 +272,26 @@ int __init sh_clk_div4_register(struct clk *clks, int nr,
return ret;
}
+int __init sh_clk_div4_register(struct clk *clks, int nr,
+ struct clk_div4_table *table)
+{
+ return sh_clk_div4_register_ops(clks, nr, table, &sh_clk_div4_clk_ops);
+}
+
+int __init sh_clk_div4_enable_register(struct clk *clks, int nr,
+ struct clk_div4_table *table)
+{
+ return sh_clk_div4_register_ops(clks, nr, table,
+ &sh_clk_div4_enable_clk_ops);
+}
+
+int __init sh_clk_div4_reparent_register(struct clk *clks, int nr,
+ struct clk_div4_table *table)
+{
+ return sh_clk_div4_register_ops(clks, nr, table,
+ &sh_clk_div4_reparent_clk_ops);
+}
+
#ifdef CONFIG_SH_CLK_CPG_LEGACY
static struct clk master_clk = {
.name = "master_clk",
diff --git a/arch/sh/kernel/cpu/fpu.c b/arch/sh/kernel/cpu/fpu.c
new file mode 100644
index 00000000000..f059ed62cf5
--- /dev/null
+++ b/arch/sh/kernel/cpu/fpu.c
@@ -0,0 +1,84 @@
+#include <linux/sched.h>
+#include <asm/processor.h>
+#include <asm/fpu.h>
+
+int init_fpu(struct task_struct *tsk)
+{
+ if (tsk_used_math(tsk)) {
+ if ((boot_cpu_data.flags & CPU_HAS_FPU) && tsk == current)
+ unlazy_fpu(tsk, task_pt_regs(tsk));
+ return 0;
+ }
+
+ /*
+ * Memory allocation at the first usage of the FPU and other state.
+ */
+ if (!tsk->thread.xstate) {
+ tsk->thread.xstate = kmem_cache_alloc(task_xstate_cachep,
+ GFP_KERNEL);
+ if (!tsk->thread.xstate)
+ return -ENOMEM;
+ }
+
+ if (boot_cpu_data.flags & CPU_HAS_FPU) {
+ struct sh_fpu_hard_struct *fp = &tsk->thread.xstate->hardfpu;
+ memset(fp, 0, xstate_size);
+ fp->fpscr = FPSCR_INIT;
+ } else {
+ struct sh_fpu_soft_struct *fp = &tsk->thread.xstate->softfpu;
+ memset(fp, 0, xstate_size);
+ fp->fpscr = FPSCR_INIT;
+ }
+
+ set_stopped_child_used_math(tsk);
+ return 0;
+}
+
+#ifdef CONFIG_SH_FPU
+void __fpu_state_restore(void)
+{
+ struct task_struct *tsk = current;
+
+ restore_fpu(tsk);
+
+ task_thread_info(tsk)->status |= TS_USEDFPU;
+ tsk->fpu_counter++;
+}
+
+void fpu_state_restore(struct pt_regs *regs)
+{
+ struct task_struct *tsk = current;
+
+ if (unlikely(!user_mode(regs))) {
+ printk(KERN_ERR "BUG: FPU is used in kernel mode.\n");
+ BUG();
+ return;
+ }
+
+ if (!tsk_used_math(tsk)) {
+ local_irq_enable();
+ /*
+ * does a slab alloc which can sleep
+ */
+ if (init_fpu(tsk)) {
+ /*
+ * ran out of memory!
+ */
+ do_group_exit(SIGKILL);
+ return;
+ }
+ local_irq_disable();
+ }
+
+ grab_fpu(regs);
+
+ __fpu_state_restore();
+}
+
+BUILD_TRAP_HANDLER(fpu_state_restore)
+{
+ TRAP_HANDLER_DECL;
+
+ fpu_state_restore(regs);
+}
+#endif /* CONFIG_SH_FPU */
diff --git a/arch/sh/kernel/cpu/init.c b/arch/sh/kernel/cpu/init.c
index 89b4b76c0d7..c736422344e 100644
--- a/arch/sh/kernel/cpu/init.c
+++ b/arch/sh/kernel/cpu/init.c
@@ -24,22 +24,32 @@
#include <asm/elf.h>
#include <asm/io.h>
#include <asm/smp.h>
-#ifdef CONFIG_SUPERH32
-#include <asm/ubc.h>
+#include <asm/sh_bios.h>
+
+#ifdef CONFIG_SH_FPU
+#define cpu_has_fpu 1
+#else
+#define cpu_has_fpu 0
+#endif
+
+#ifdef CONFIG_SH_DSP
+#define cpu_has_dsp 1
+#else
+#define cpu_has_dsp 0
#endif
/*
* Generic wrapper for command line arguments to disable on-chip
* peripherals (nofpu, nodsp, and so forth).
*/
-#define onchip_setup(x) \
-static int x##_disabled __initdata = 0; \
- \
-static int __init x##_setup(char *opts) \
-{ \
- x##_disabled = 1; \
- return 1; \
-} \
+#define onchip_setup(x) \
+static int x##_disabled __initdata = !cpu_has_##x; \
+ \
+static int __init x##_setup(char *opts) \
+{ \
+ x##_disabled = 1; \
+ return 1; \
+} \
__setup("no" __stringify(x), x##_setup);
onchip_setup(fpu);
@@ -52,10 +62,10 @@ onchip_setup(dsp);
static void __init speculative_execution_init(void)
{
/* Clear RABD */
- ctrl_outl(ctrl_inl(CPUOPM) & ~CPUOPM_RABD, CPUOPM);
+ __raw_writel(__raw_readl(CPUOPM) & ~CPUOPM_RABD, CPUOPM);
/* Flush the update */
- (void)ctrl_inl(CPUOPM);
+ (void)__raw_readl(CPUOPM);
ctrl_barrier();
}
#else
@@ -89,7 +99,7 @@ static void __init expmask_init(void)
#endif
/* 2nd-level cache init */
-void __uses_jump_to_uncached __attribute__ ((weak)) l2_cache_init(void)
+void __attribute__ ((weak)) l2_cache_init(void)
{
}
@@ -97,12 +107,12 @@ void __uses_jump_to_uncached __attribute__ ((weak)) l2_cache_init(void)
* Generic first-level cache init
*/
#ifdef CONFIG_SUPERH32
-static void __uses_jump_to_uncached cache_init(void)
+static void cache_init(void)
{
unsigned long ccr, flags;
jump_to_uncached();
- ccr = ctrl_inl(CCR);
+ ccr = __raw_readl(CCR);
/*
* At this point we don't know whether the cache is enabled or not - a
@@ -146,7 +156,7 @@ static void __uses_jump_to_uncached cache_init(void)
for (addr = addrstart;
addr < addrstart + waysize;
addr += current_cpu_data.dcache.linesz)
- ctrl_outl(0, addr);
+ __raw_writel(0, addr);
addrstart += current_cpu_data.dcache.way_incr;
} while (--ways);
@@ -179,7 +189,7 @@ static void __uses_jump_to_uncached cache_init(void)
l2_cache_init();
- ctrl_outl(flags, CCR);
+ __raw_writel(flags, CCR);
back_to_cached();
}
#else
@@ -207,6 +217,18 @@ static void detect_cache_shape(void)
l2_cache_shape = -1; /* No S-cache */
}
+static void __init fpu_init(void)
+{
+ /* Disable the FPU */
+ if (fpu_disabled && (current_cpu_data.flags & CPU_HAS_FPU)) {
+ printk("FPU Disabled\n");
+ current_cpu_data.flags &= ~CPU_HAS_FPU;
+ }
+
+ disable_fpu();
+ clear_used_math();
+}
+
#ifdef CONFIG_SH_DSP
static void __init release_dsp(void)
{
@@ -244,28 +266,35 @@ static void __init dsp_init(void)
if (sr & SR_DSP)
current_cpu_data.flags |= CPU_HAS_DSP;
+ /* Disable the DSP */
+ if (dsp_disabled && (current_cpu_data.flags & CPU_HAS_DSP)) {
+ printk("DSP Disabled\n");
+ current_cpu_data.flags &= ~CPU_HAS_DSP;
+ }
+
/* Now that we've determined the DSP status, clear the DSP bit. */
release_dsp();
}
+#else
+static inline void __init dsp_init(void) { }
#endif /* CONFIG_SH_DSP */
/**
* sh_cpu_init
*
- * This is our initial entry point for each CPU, and is invoked on the boot
- * CPU prior to calling start_kernel(). For SMP, a combination of this and
- * start_secondary() will bring up each processor to a ready state prior
- * to hand forking the idle loop.
+ * This is our initial entry point for each CPU, and is invoked on the
+ * boot CPU prior to calling start_kernel(). For SMP, a combination of
+ * this and start_secondary() will bring up each processor to a ready
+ * state prior to hand forking the idle loop.
*
- * We do all of the basic processor init here, including setting up the
- * caches, FPU, DSP, kicking the UBC, etc. By the time start_kernel() is
- * hit (and subsequently platform_setup()) things like determining the
- * CPU subtype and initial configuration will all be done.
+ * We do all of the basic processor init here, including setting up
+ * the caches, FPU, DSP, etc. By the time start_kernel() is hit (and
+ * subsequently platform_setup()) things like determining the CPU
+ * subtype and initial configuration will all be done.
*
* Each processor family is still responsible for doing its own probing
* and cache configuration in detect_cpu_and_cache_system().
*/
-
asmlinkage void __init sh_cpu_init(void)
{
current_thread_info()->cpu = hard_smp_processor_id();
@@ -302,18 +331,8 @@ asmlinkage void __init sh_cpu_init(void)
detect_cache_shape();
}
- /* Disable the FPU */
- if (fpu_disabled) {
- printk("FPU Disabled\n");
- current_cpu_data.flags &= ~CPU_HAS_FPU;
- }
-
- /* FPU initialization */
- disable_fpu();
- if ((current_cpu_data.flags & CPU_HAS_FPU)) {
- current_thread_info()->status &= ~TS_USEDFPU;
- clear_used_math();
- }
+ fpu_init();
+ dsp_init();
/*
* Initialize the per-CPU ASID cache very early, since the
@@ -321,18 +340,24 @@ asmlinkage void __init sh_cpu_init(void)
*/
current_cpu_data.asid_cache = NO_CONTEXT;
-#ifdef CONFIG_SH_DSP
- /* Probe for DSP */
- dsp_init();
-
- /* Disable the DSP */
- if (dsp_disabled) {
- printk("DSP Disabled\n");
- current_cpu_data.flags &= ~CPU_HAS_DSP;
- release_dsp();
- }
-#endif
-
speculative_execution_init();
expmask_init();
+
+ /* Do the rest of the boot processor setup */
+ if (raw_smp_processor_id() == 0) {
+ /* Save off the BIOS VBR, if there is one */
+ sh_bios_vbr_init();
+
+ /*
+ * Setup VBR for boot CPU. Secondary CPUs do this through
+ * start_secondary().
+ */
+ per_cpu_trap_init();
+
+ /*
+ * Boot processor to setup the FP and extended state
+ * context info.
+ */
+ init_thread_xstate();
+ }
}
diff --git a/arch/sh/kernel/cpu/irq/intc-sh5.c b/arch/sh/kernel/cpu/irq/intc-sh5.c
index 06e7e2959b5..96a23958394 100644
--- a/arch/sh/kernel/cpu/irq/intc-sh5.c
+++ b/arch/sh/kernel/cpu/irq/intc-sh5.c
@@ -123,7 +123,7 @@ static void enable_intc_irq(unsigned int irq)
bitmask = 1 << (irq - 32);
}
- ctrl_outl(bitmask, reg);
+ __raw_writel(bitmask, reg);
}
static void disable_intc_irq(unsigned int irq)
@@ -139,7 +139,7 @@ static void disable_intc_irq(unsigned int irq)
bitmask = 1 << (irq - 32);
}
- ctrl_outl(bitmask, reg);
+ __raw_writel(bitmask, reg);
}
static void mask_and_ack_intc(unsigned int irq)
@@ -170,11 +170,11 @@ void __init plat_irq_setup(void)
/* Disable all interrupts and set all priorities to 0 to avoid trouble */
- ctrl_outl(-1, INTC_INTDSB_0);
- ctrl_outl(-1, INTC_INTDSB_1);
+ __raw_writel(-1, INTC_INTDSB_0);
+ __raw_writel(-1, INTC_INTDSB_1);
for (reg = INTC_INTPRI_0, i = 0; i < INTC_INTPRI_PREGS; i++, reg += 8)
- ctrl_outl( NO_PRIORITY, reg);
+ __raw_writel( NO_PRIORITY, reg);
#ifdef CONFIG_SH_CAYMAN
@@ -199,7 +199,7 @@ void __init plat_irq_setup(void)
reg = INTC_ICR_SET;
i = IRQ_IRL0;
}
- ctrl_outl(INTC_ICR_IRLM, reg);
+ __raw_writel(INTC_ICR_IRLM, reg);
/* Set interrupt priorities according to platform description */
for (data = 0, reg = INTC_INTPRI_0; i < NR_INTC_IRQS; i++) {
@@ -207,7 +207,7 @@ void __init plat_irq_setup(void)
((i % INTC_INTPRI_PPREG) * 4);
if ((i % INTC_INTPRI_PPREG) == (INTC_INTPRI_PPREG - 1)) {
/* Upon the 7th, set Priority Register */
- ctrl_outl(data, reg);
+ __raw_writel(data, reg);
data = 0;
reg += 8;
}
diff --git a/arch/sh/kernel/cpu/sh2/clock-sh7619.c b/arch/sh/kernel/cpu/sh2/clock-sh7619.c
index 4fe863170e3..0c9f24d7a02 100644
--- a/arch/sh/kernel/cpu/sh2/clock-sh7619.c
+++ b/arch/sh/kernel/cpu/sh2/clock-sh7619.c
@@ -31,7 +31,7 @@ static const int pfc_divisors[] = {1,2,0,4};
static void master_clk_init(struct clk *clk)
{
- clk->rate *= PLL2 * pll1rate[(ctrl_inw(FREQCR) >> 8) & 7];
+ clk->rate *= PLL2 * pll1rate[(__raw_readw(FREQCR) >> 8) & 7];
}
static struct clk_ops sh7619_master_clk_ops = {
@@ -40,7 +40,7 @@ static struct clk_ops sh7619_master_clk_ops = {
static unsigned long module_clk_recalc(struct clk *clk)
{
- int idx = (ctrl_inw(FREQCR) & 0x0007);
+ int idx = (__raw_readw(FREQCR) & 0x0007);
return clk->parent->rate / pfc_divisors[idx];
}
@@ -50,7 +50,7 @@ static struct clk_ops sh7619_module_clk_ops = {
static unsigned long bus_clk_recalc(struct clk *clk)
{
- return clk->parent->rate / pll1rate[(ctrl_inw(FREQCR) >> 8) & 7];
+ return clk->parent->rate / pll1rate[(__raw_readw(FREQCR) >> 8) & 7];
}
static struct clk_ops sh7619_bus_clk_ops = {
diff --git a/arch/sh/kernel/cpu/sh2a/clock-sh7201.c b/arch/sh/kernel/cpu/sh2a/clock-sh7201.c
index 7814c76159a..b26264dc2ae 100644
--- a/arch/sh/kernel/cpu/sh2a/clock-sh7201.c
+++ b/arch/sh/kernel/cpu/sh2a/clock-sh7201.c
@@ -34,7 +34,7 @@ static const int pfc_divisors[]={1,2,3,4,6,8,12};
static void master_clk_init(struct clk *clk)
{
- return 10000000 * PLL2 * pll1rate[(ctrl_inw(FREQCR) >> 8) & 0x0007];
+ return 10000000 * PLL2 * pll1rate[(__raw_readw(FREQCR) >> 8) & 0x0007];
}
static struct clk_ops sh7201_master_clk_ops = {
@@ -43,7 +43,7 @@ static struct clk_ops sh7201_master_clk_ops = {
static unsigned long module_clk_recalc(struct clk *clk)
{
- int idx = (ctrl_inw(FREQCR) & 0x0007);
+ int idx = (__raw_readw(FREQCR) & 0x0007);
return clk->parent->rate / pfc_divisors[idx];
}
@@ -53,7 +53,7 @@ static struct clk_ops sh7201_module_clk_ops = {
static unsigned long bus_clk_recalc(struct clk *clk)
{
- int idx = (ctrl_inw(FREQCR) & 0x0007);
+ int idx = (__raw_readw(FREQCR) & 0x0007);
return clk->parent->rate / pfc_divisors[idx];
}
@@ -63,7 +63,7 @@ static struct clk_ops sh7201_bus_clk_ops = {
static unsigned long cpu_clk_recalc(struct clk *clk)
{
- int idx = ((ctrl_inw(FREQCR) >> 4) & 0x0007);
+ int idx = ((__raw_readw(FREQCR) >> 4) & 0x0007);
return clk->parent->rate / ifc_divisors[idx];
}
diff --git a/arch/sh/kernel/cpu/sh2a/clock-sh7203.c b/arch/sh/kernel/cpu/sh2a/clock-sh7203.c
index 94098696510..7e75d8f7950 100644
--- a/arch/sh/kernel/cpu/sh2a/clock-sh7203.c
+++ b/arch/sh/kernel/cpu/sh2a/clock-sh7203.c
@@ -39,7 +39,7 @@ static const int pfc_divisors[]={1,2,3,4,6,8,12};
static void master_clk_init(struct clk *clk)
{
- clk->rate *= pll1rate[(ctrl_inw(FREQCR) >> 8) & 0x0003] * PLL2 ;
+ clk->rate *= pll1rate[(__raw_readw(FREQCR) >> 8) & 0x0003] * PLL2 ;
}
static struct clk_ops sh7203_master_clk_ops = {
@@ -48,7 +48,7 @@ static struct clk_ops sh7203_master_clk_ops = {
static unsigned long module_clk_recalc(struct clk *clk)
{
- int idx = (ctrl_inw(FREQCR) & 0x0007);
+ int idx = (__raw_readw(FREQCR) & 0x0007);
return clk->parent->rate / pfc_divisors[idx];
}
@@ -58,7 +58,7 @@ static struct clk_ops sh7203_module_clk_ops = {
static unsigned long bus_clk_recalc(struct clk *clk)
{
- int idx = (ctrl_inw(FREQCR) & 0x0007);
+ int idx = (__raw_readw(FREQCR) & 0x0007);
return clk->parent->rate / pfc_divisors[idx-2];
}
diff --git a/arch/sh/kernel/cpu/sh2a/clock-sh7206.c b/arch/sh/kernel/cpu/sh2a/clock-sh7206.c
index c2268bdecee..b27a5e2687a 100644
--- a/arch/sh/kernel/cpu/sh2a/clock-sh7206.c
+++ b/arch/sh/kernel/cpu/sh2a/clock-sh7206.c
@@ -34,7 +34,7 @@ static const int pfc_divisors[]={1,2,3,4,6,8,12};
static void master_clk_init(struct clk *clk)
{
- clk->rate *= PLL2 * pll1rate[(ctrl_inw(FREQCR) >> 8) & 0x0007];
+ clk->rate *= PLL2 * pll1rate[(__raw_readw(FREQCR) >> 8) & 0x0007];
}
static struct clk_ops sh7206_master_clk_ops = {
@@ -43,7 +43,7 @@ static struct clk_ops sh7206_master_clk_ops = {
static unsigned long module_clk_recalc(struct clk *clk)
{
- int idx = (ctrl_inw(FREQCR) & 0x0007);
+ int idx = (__raw_readw(FREQCR) & 0x0007);
return clk->parent->rate / pfc_divisors[idx];
}
@@ -53,7 +53,7 @@ static struct clk_ops sh7206_module_clk_ops = {
static unsigned long bus_clk_recalc(struct clk *clk)
{
- return clk->parent->rate / pll1rate[(ctrl_inw(FREQCR) >> 8) & 0x0007];
+ return clk->parent->rate / pll1rate[(__raw_readw(FREQCR) >> 8) & 0x0007];
}
static struct clk_ops sh7206_bus_clk_ops = {
@@ -62,7 +62,7 @@ static struct clk_ops sh7206_bus_clk_ops = {
static unsigned long cpu_clk_recalc(struct clk *clk)
{
- int idx = (ctrl_inw(FREQCR) & 0x0007);
+ int idx = (__raw_readw(FREQCR) & 0x0007);
return clk->parent->rate / ifc_divisors[idx];
}
diff --git a/arch/sh/kernel/cpu/sh2a/fpu.c b/arch/sh/kernel/cpu/sh2a/fpu.c
index d395ce5740e..488d24e0cdf 100644
--- a/arch/sh/kernel/cpu/sh2a/fpu.c
+++ b/arch/sh/kernel/cpu/sh2a/fpu.c
@@ -26,8 +26,7 @@
/*
* Save FPU registers onto task structure.
*/
-void
-save_fpu(struct task_struct *tsk)
+void save_fpu(struct task_struct *tsk)
{
unsigned long dummy;
@@ -52,7 +51,7 @@ save_fpu(struct task_struct *tsk)
"fmov.s fr0, @-%0\n\t"
"lds %3, fpscr\n\t"
: "=r" (dummy)
- : "0" ((char *)(&tsk->thread.fpu.hard.status)),
+ : "0" ((char *)(&tsk->thread.xstate->hardfpu.status)),
"r" (FPSCR_RCHG),
"r" (FPSCR_INIT)
: "memory");
@@ -60,8 +59,7 @@ save_fpu(struct task_struct *tsk)
disable_fpu();
}
-static void
-restore_fpu(struct task_struct *tsk)
+void restore_fpu(struct task_struct *tsk)
{
unsigned long dummy;
@@ -85,45 +83,12 @@ restore_fpu(struct task_struct *tsk)
"lds.l @%0+, fpscr\n\t"
"lds.l @%0+, fpul\n\t"
: "=r" (dummy)
- : "0" (&tsk->thread.fpu), "r" (FPSCR_RCHG)
+ : "0" (tsk->thread.xstate), "r" (FPSCR_RCHG)
: "memory");
disable_fpu();
}
/*
- * Load the FPU with signalling NANS. This bit pattern we're using
- * has the property that no matter wether considered as single or as
- * double precission represents signaling NANS.
- */
-
-static void
-fpu_init(void)
-{
- enable_fpu();
- asm volatile("lds %0, fpul\n\t"
- "fsts fpul, fr0\n\t"
- "fsts fpul, fr1\n\t"
- "fsts fpul, fr2\n\t"
- "fsts fpul, fr3\n\t"
- "fsts fpul, fr4\n\t"
- "fsts fpul, fr5\n\t"
- "fsts fpul, fr6\n\t"
- "fsts fpul, fr7\n\t"
- "fsts fpul, fr8\n\t"
- "fsts fpul, fr9\n\t"
- "fsts fpul, fr10\n\t"
- "fsts fpul, fr11\n\t"
- "fsts fpul, fr12\n\t"
- "fsts fpul, fr13\n\t"
- "fsts fpul, fr14\n\t"
- "fsts fpul, fr15\n\t"
- "lds %2, fpscr\n\t"
- : /* no output */
- : "r" (0), "r" (FPSCR_RCHG), "r" (FPSCR_INIT));
- disable_fpu();
-}
-
-/*
* Emulate arithmetic ops on denormalized number for some FPU insns.
*/
@@ -490,9 +455,9 @@ ieee_fpe_handler (struct pt_regs *regs)
if ((finsn & 0xf1ff) == 0xf0ad) { /* fcnvsd */
struct task_struct *tsk = current;
- if ((tsk->thread.fpu.hard.fpscr & FPSCR_FPU_ERROR)) {
+ if ((tsk->thread.xstate->hardfpu.fpscr & FPSCR_FPU_ERROR)) {
/* FPU error */
- denormal_to_double (&tsk->thread.fpu.hard,
+ denormal_to_double (&tsk->thread.xstate->hardfpu,
(finsn >> 8) & 0xf);
} else
return 0;
@@ -507,9 +472,9 @@ ieee_fpe_handler (struct pt_regs *regs)
n = (finsn >> 8) & 0xf;
m = (finsn >> 4) & 0xf;
- hx = tsk->thread.fpu.hard.fp_regs[n];
- hy = tsk->thread.fpu.hard.fp_regs[m];
- fpscr = tsk->thread.fpu.hard.fpscr;
+ hx = tsk->thread.xstate->hardfpu.fp_regs[n];
+ hy = tsk->thread.xstate->hardfpu.fp_regs[m];
+ fpscr = tsk->thread.xstate->hardfpu.fpscr;
prec = fpscr & (1 << 19);
if ((fpscr & FPSCR_FPU_ERROR)
@@ -519,15 +484,15 @@ ieee_fpe_handler (struct pt_regs *regs)
/* FPU error because of denormal */
llx = ((long long) hx << 32)
- | tsk->thread.fpu.hard.fp_regs[n+1];
+ | tsk->thread.xstate->hardfpu.fp_regs[n+1];
lly = ((long long) hy << 32)
- | tsk->thread.fpu.hard.fp_regs[m+1];
+ | tsk->thread.xstate->hardfpu.fp_regs[m+1];
if ((hx & 0x7fffffff) >= 0x00100000)
llx = denormal_muld(lly, llx);
else
llx = denormal_muld(llx, lly);
- tsk->thread.fpu.hard.fp_regs[n] = llx >> 32;
- tsk->thread.fpu.hard.fp_regs[n+1] = llx & 0xffffffff;
+ tsk->thread.xstate->hardfpu.fp_regs[n] = llx >> 32;
+ tsk->thread.xstate->hardfpu.fp_regs[n+1] = llx & 0xffffffff;
} else if ((fpscr & FPSCR_FPU_ERROR)
&& (!prec && ((hx & 0x7fffffff) < 0x00800000
|| (hy & 0x7fffffff) < 0x00800000))) {
@@ -536,7 +501,7 @@ ieee_fpe_handler (struct pt_regs *regs)
hx = denormal_mulf(hy, hx);
else
hx = denormal_mulf(hx, hy);
- tsk->thread.fpu.hard.fp_regs[n] = hx;
+ tsk->thread.xstate->hardfpu.fp_regs[n] = hx;
} else
return 0;
@@ -550,9 +515,9 @@ ieee_fpe_handler (struct pt_regs *regs)
n = (finsn >> 8) & 0xf;
m = (finsn >> 4) & 0xf;
- hx = tsk->thread.fpu.hard.fp_regs[n];
- hy = tsk->thread.fpu.hard.fp_regs[m];
- fpscr = tsk->thread.fpu.hard.fpscr;
+ hx = tsk->thread.xstate->hardfpu.fp_regs[n];
+ hy = tsk->thread.xstate->hardfpu.fp_regs[m];
+ fpscr = tsk->thread.xstate->hardfpu.fpscr;
prec = fpscr & (1 << 19);
if ((fpscr & FPSCR_FPU_ERROR)
@@ -562,15 +527,15 @@ ieee_fpe_handler (struct pt_regs *regs)
/* FPU error because of denormal */
llx = ((long long) hx << 32)
- | tsk->thread.fpu.hard.fp_regs[n+1];
+ | tsk->thread.xstate->hardfpu.fp_regs[n+1];
lly = ((long long) hy << 32)
- | tsk->thread.fpu.hard.fp_regs[m+1];
+ | tsk->thread.xstate->hardfpu.fp_regs[m+1];
if ((finsn & 0xf00f) == 0xf000)
llx = denormal_addd(llx, lly);
else
llx = denormal_addd(llx, lly ^ (1LL << 63));
- tsk->thread.fpu.hard.fp_regs[n] = llx >> 32;
- tsk->thread.fpu.hard.fp_regs[n+1] = llx & 0xffffffff;
+ tsk->thread.xstate->hardfpu.fp_regs[n] = llx >> 32;
+ tsk->thread.xstate->hardfpu.fp_regs[n+1] = llx & 0xffffffff;
} else if ((fpscr & FPSCR_FPU_ERROR)
&& (!prec && ((hx & 0x7fffffff) < 0x00800000
|| (hy & 0x7fffffff) < 0x00800000))) {
@@ -579,7 +544,7 @@ ieee_fpe_handler (struct pt_regs *regs)
hx = denormal_addf(hx, hy);
else
hx = denormal_addf(hx, hy ^ 0x80000000);
- tsk->thread.fpu.hard.fp_regs[n] = hx;
+ tsk->thread.xstate->hardfpu.fp_regs[n] = hx;
} else
return 0;
@@ -597,7 +562,7 @@ BUILD_TRAP_HANDLER(fpu_error)
__unlazy_fpu(tsk, regs);
if (ieee_fpe_handler(regs)) {
- tsk->thread.fpu.hard.fpscr &=
+ tsk->thread.xstate->hardfpu.fpscr &=
~(FPSCR_CAUSE_MASK | FPSCR_FLAG_MASK);
grab_fpu(regs);
restore_fpu(tsk);
@@ -607,33 +572,3 @@ BUILD_TRAP_HANDLER(fpu_error)
force_sig(SIGFPE, tsk);
}
-
-void fpu_state_restore(struct pt_regs *regs)
-{
- struct task_struct *tsk = current;
-
- grab_fpu(regs);
- if (unlikely(!user_mode(regs))) {
- printk(KERN_ERR "BUG: FPU is used in kernel mode.\n");
- BUG();
- return;
- }
-
- if (likely(used_math())) {
- /* Using the FPU again. */
- restore_fpu(tsk);
- } else {
- /* First time FPU user. */
- fpu_init();
- set_used_math();
- }
- task_thread_info(tsk)->status |= TS_USEDFPU;
- tsk->fpu_counter++;
-}
-
-BUILD_TRAP_HANDLER(fpu_state_restore)
-{
- TRAP_HANDLER_DECL;
-
- fpu_state_restore(regs);
-}
diff --git a/arch/sh/kernel/cpu/sh3/clock-sh3.c b/arch/sh/kernel/cpu/sh3/clock-sh3.c
index 27b8738f0b0..b78384afac0 100644
--- a/arch/sh/kernel/cpu/sh3/clock-sh3.c
+++ b/arch/sh/kernel/cpu/sh3/clock-sh3.c
@@ -28,7 +28,7 @@ static int pfc_divisors[] = { 1, 2, 3, 4, 6, 1, 1, 1 };
static void master_clk_init(struct clk *clk)
{
- int frqcr = ctrl_inw(FRQCR);
+ int frqcr = __raw_readw(FRQCR);
int idx = ((frqcr & 0x2000) >> 11) | (frqcr & 0x0003);
clk->rate *= pfc_divisors[idx];
@@ -40,7 +40,7 @@ static struct clk_ops sh3_master_clk_ops = {
static unsigned long module_clk_recalc(struct clk *clk)
{
- int frqcr = ctrl_inw(FRQCR);
+ int frqcr = __raw_readw(FRQCR);
int idx = ((frqcr & 0x2000) >> 11) | (frqcr & 0x0003);
return clk->parent->rate / pfc_divisors[idx];
@@ -52,7 +52,7 @@ static struct clk_ops sh3_module_clk_ops = {
static unsigned long bus_clk_recalc(struct clk *clk)
{
- int frqcr = ctrl_inw(FRQCR);
+ int frqcr = __raw_readw(FRQCR);
int idx = ((frqcr & 0x8000) >> 13) | ((frqcr & 0x0030) >> 4);
return clk->parent->rate / stc_multipliers[idx];
@@ -64,7 +64,7 @@ static struct clk_ops sh3_bus_clk_ops = {
static unsigned long cpu_clk_recalc(struct clk *clk)
{
- int frqcr = ctrl_inw(FRQCR);
+ int frqcr = __raw_readw(FRQCR);
int idx = ((frqcr & 0x4000) >> 12) | ((frqcr & 0x000c) >> 2);
return clk->parent->rate / ifc_divisors[idx];
diff --git a/arch/sh/kernel/cpu/sh3/clock-sh7705.c b/arch/sh/kernel/cpu/sh3/clock-sh7705.c
index 0ca8f2c3646..0ecea1451c6 100644
--- a/arch/sh/kernel/cpu/sh3/clock-sh7705.c
+++ b/arch/sh/kernel/cpu/sh3/clock-sh7705.c
@@ -32,7 +32,7 @@ static int pfc_divisors[] = { 1, 2, 3, 4, 6, 1, 1, 1 };
static void master_clk_init(struct clk *clk)
{
- clk->rate *= pfc_divisors[ctrl_inw(FRQCR) & 0x0003];
+ clk->rate *= pfc_divisors[__raw_readw(FRQCR) & 0x0003];
}
static struct clk_ops sh7705_master_clk_ops = {
@@ -41,7 +41,7 @@ static struct clk_ops sh7705_master_clk_ops = {
static unsigned long module_clk_recalc(struct clk *clk)
{
- int idx = ctrl_inw(FRQCR) & 0x0003;
+ int idx = __raw_readw(FRQCR) & 0x0003;
return clk->parent->rate / pfc_divisors[idx];
}
@@ -51,7 +51,7 @@ static struct clk_ops sh7705_module_clk_ops = {
static unsigned long bus_clk_recalc(struct clk *clk)
{
- int idx = (ctrl_inw(FRQCR) & 0x0300) >> 8;
+ int idx = (__raw_readw(FRQCR) & 0x0300) >> 8;
return clk->parent->rate / stc_multipliers[idx];
}
@@ -61,7 +61,7 @@ static struct clk_ops sh7705_bus_clk_ops = {
static unsigned long cpu_clk_recalc(struct clk *clk)
{
- int idx = (ctrl_inw(FRQCR) & 0x0030) >> 4;
+ int idx = (__raw_readw(FRQCR) & 0x0030) >> 4;
return clk->parent->rate / ifc_divisors[idx];
}
diff --git a/arch/sh/kernel/cpu/sh3/clock-sh7706.c b/arch/sh/kernel/cpu/sh3/clock-sh7706.c
index 4bf7887d310..6f9ff8b57dd 100644
--- a/arch/sh/kernel/cpu/sh3/clock-sh7706.c
+++ b/arch/sh/kernel/cpu/sh3/clock-sh7706.c
@@ -24,7 +24,7 @@ static int pfc_divisors[] = { 1, 2, 4, 1, 3, 6, 1, 1 };
static void master_clk_init(struct clk *clk)
{
- int frqcr = ctrl_inw(FRQCR);
+ int frqcr = __raw_readw(FRQCR);
int idx = ((frqcr & 0x2000) >> 11) | (frqcr & 0x0003);
clk->rate *= pfc_divisors[idx];
@@ -36,7 +36,7 @@ static struct clk_ops sh7706_master_clk_ops = {
static unsigned long module_clk_recalc(struct clk *clk)
{
- int frqcr = ctrl_inw(FRQCR);
+ int frqcr = __raw_readw(FRQCR);
int idx = ((frqcr & 0x2000) >> 11) | (frqcr & 0x0003);
return clk->parent->rate / pfc_divisors[idx];
@@ -48,7 +48,7 @@ static struct clk_ops sh7706_module_clk_ops = {
static unsigned long bus_clk_recalc(struct clk *clk)
{
- int frqcr = ctrl_inw(FRQCR);
+ int frqcr = __raw_readw(FRQCR);
int idx = ((frqcr & 0x8000) >> 13) | ((frqcr & 0x0030) >> 4);
return clk->parent->rate / stc_multipliers[idx];
@@ -60,7 +60,7 @@ static struct clk_ops sh7706_bus_clk_ops = {
static unsigned long cpu_clk_recalc(struct clk *clk)
{
- int frqcr = ctrl_inw(FRQCR);
+ int frqcr = __raw_readw(FRQCR);
int idx = ((frqcr & 0x4000) >> 12) | ((frqcr & 0x000c) >> 2);
return clk->parent->rate / ifc_divisors[idx];
diff --git a/arch/sh/kernel/cpu/sh3/clock-sh7709.c b/arch/sh/kernel/cpu/sh3/clock-sh7709.c
index e8749505bd2..f302ba09e68 100644
--- a/arch/sh/kernel/cpu/sh3/clock-sh7709.c
+++ b/arch/sh/kernel/cpu/sh3/clock-sh7709.c
@@ -24,7 +24,7 @@ static int pfc_divisors[] = { 1, 2, 4, 1, 3, 6, 1, 1 };
static void master_clk_init(struct clk *clk)
{
- int frqcr = ctrl_inw(FRQCR);
+ int frqcr = __raw_readw(FRQCR);
int idx = ((frqcr & 0x2000) >> 11) | (frqcr & 0x0003);
clk->rate *= pfc_divisors[idx];
@@ -36,7 +36,7 @@ static struct clk_ops sh7709_master_clk_ops = {
static unsigned long module_clk_recalc(struct clk *clk)
{
- int frqcr = ctrl_inw(FRQCR);
+ int frqcr = __raw_readw(FRQCR);
int idx = ((frqcr & 0x2000) >> 11) | (frqcr & 0x0003);
return clk->parent->rate / pfc_divisors[idx];
@@ -48,7 +48,7 @@ static struct clk_ops sh7709_module_clk_ops = {
static unsigned long bus_clk_recalc(struct clk *clk)
{
- int frqcr = ctrl_inw(FRQCR);
+ int frqcr = __raw_readw(FRQCR);
int idx = (frqcr & 0x0080) ?
((frqcr & 0x8000) >> 13) | ((frqcr & 0x0030) >> 4) : 1;
@@ -61,7 +61,7 @@ static struct clk_ops sh7709_bus_clk_ops = {
static unsigned long cpu_clk_recalc(struct clk *clk)
{
- int frqcr = ctrl_inw(FRQCR);
+ int frqcr = __raw_readw(FRQCR);
int idx = ((frqcr & 0x4000) >> 12) | ((frqcr & 0x000c) >> 2);
return clk->parent->rate / ifc_divisors[idx];
diff --git a/arch/sh/kernel/cpu/sh3/clock-sh7710.c b/arch/sh/kernel/cpu/sh3/clock-sh7710.c
index 030a58ba18a..29a87d8946a 100644
--- a/arch/sh/kernel/cpu/sh3/clock-sh7710.c
+++ b/arch/sh/kernel/cpu/sh3/clock-sh7710.c
@@ -26,7 +26,7 @@ static int md_table[] = { 1, 2, 3, 4, 6, 8, 12 };
static void master_clk_init(struct clk *clk)
{
- clk->rate *= md_table[ctrl_inw(FRQCR) & 0x0007];
+ clk->rate *= md_table[__raw_readw(FRQCR) & 0x0007];
}
static struct clk_ops sh7710_master_clk_ops = {
@@ -35,7 +35,7 @@ static struct clk_ops sh7710_master_clk_ops = {
static unsigned long module_clk_recalc(struct clk *clk)
{
- int idx = (ctrl_inw(FRQCR) & 0x0007);
+ int idx = (__raw_readw(FRQCR) & 0x0007);
return clk->parent->rate / md_table[idx];
}
@@ -45,7 +45,7 @@ static struct clk_ops sh7710_module_clk_ops = {
static unsigned long bus_clk_recalc(struct clk *clk)
{
- int idx = (ctrl_inw(FRQCR) & 0x0700) >> 8;
+ int idx = (__raw_readw(FRQCR) & 0x0700) >> 8;
return clk->parent->rate / md_table[idx];
}
@@ -55,7 +55,7 @@ static struct clk_ops sh7710_bus_clk_ops = {
static unsigned long cpu_clk_recalc(struct clk *clk)
{
- int idx = (ctrl_inw(FRQCR) & 0x0070) >> 4;
+ int idx = (__raw_readw(FRQCR) & 0x0070) >> 4;
return clk->parent->rate / md_table[idx];
}
diff --git a/arch/sh/kernel/cpu/sh3/clock-sh7712.c b/arch/sh/kernel/cpu/sh3/clock-sh7712.c
index 6428ee6c77e..b0d0c520399 100644
--- a/arch/sh/kernel/cpu/sh3/clock-sh7712.c
+++ b/arch/sh/kernel/cpu/sh3/clock-sh7712.c
@@ -23,7 +23,7 @@ static int divisors[] = { 1, 2, 3, 4, 6 };
static void master_clk_init(struct clk *clk)
{
- int frqcr = ctrl_inw(FRQCR);
+ int frqcr = __raw_readw(FRQCR);
int idx = (frqcr & 0x0300) >> 8;
clk->rate *= multipliers[idx];
@@ -35,7 +35,7 @@ static struct clk_ops sh7712_master_clk_ops = {
static unsigned long module_clk_recalc(struct clk *clk)
{
- int frqcr = ctrl_inw(FRQCR);
+ int frqcr = __raw_readw(FRQCR);
int idx = frqcr & 0x0007;
return clk->parent->rate / divisors[idx];
@@ -47,7 +47,7 @@ static struct clk_ops sh7712_module_clk_ops = {
static unsigned long cpu_clk_recalc(struct clk *clk)
{
- int frqcr = ctrl_inw(FRQCR);
+ int frqcr = __raw_readw(FRQCR);
int idx = (frqcr & 0x0030) >> 4;
return clk->parent->rate / divisors[idx];
diff --git a/arch/sh/kernel/cpu/sh3/ex.S b/arch/sh/kernel/cpu/sh3/ex.S
index 46610c35c23..99b4d020179 100644
--- a/arch/sh/kernel/cpu/sh3/ex.S
+++ b/arch/sh/kernel/cpu/sh3/ex.S
@@ -49,7 +49,7 @@ ENTRY(exception_handling_table)
.long exception_error ! reserved_instruction (filled by trap_init) /* 180 */
.long exception_error ! illegal_slot_instruction (filled by trap_init) /*1A0*/
.long nmi_trap_handler /* 1C0 */ ! Allow trap to debugger
- .long break_point_trap /* 1E0 */
+ .long breakpoint_trap_handler /* 1E0 */
/*
* Pad the remainder of the table out, exceptions residing in far
diff --git a/arch/sh/kernel/cpu/sh3/probe.c b/arch/sh/kernel/cpu/sh3/probe.c
index f9c7df64eb0..295ec4c99e9 100644
--- a/arch/sh/kernel/cpu/sh3/probe.c
+++ b/arch/sh/kernel/cpu/sh3/probe.c
@@ -16,7 +16,7 @@
#include <asm/cache.h>
#include <asm/io.h>
-int __uses_jump_to_uncached detect_cpu_and_cache_system(void)
+int detect_cpu_and_cache_system(void)
{
unsigned long addr0, addr1, data0, data1, data2, data3;
@@ -30,23 +30,23 @@ int __uses_jump_to_uncached detect_cpu_and_cache_system(void)
addr1 = CACHE_OC_ADDRESS_ARRAY + (1 << 12);
/* First, write back & invalidate */
- data0 = ctrl_inl(addr0);
- ctrl_outl(data0&~(SH_CACHE_VALID|SH_CACHE_UPDATED), addr0);
- data1 = ctrl_inl(addr1);
- ctrl_outl(data1&~(SH_CACHE_VALID|SH_CACHE_UPDATED), addr1);
+ data0 = __raw_readl(addr0);
+ __raw_writel(data0&~(SH_CACHE_VALID|SH_CACHE_UPDATED), addr0);
+ data1 = __raw_readl(addr1);
+ __raw_writel(data1&~(SH_CACHE_VALID|SH_CACHE_UPDATED), addr1);
/* Next, check if there's shadow or not */
- data0 = ctrl_inl(addr0);
+ data0 = __raw_readl(addr0);
data0 ^= SH_CACHE_VALID;
- ctrl_outl(data0, addr0);
- data1 = ctrl_inl(addr1);
+ __raw_writel(data0, addr0);
+ data1 = __raw_readl(addr1);
data2 = data1 ^ SH_CACHE_VALID;
- ctrl_outl(data2, addr1);
- data3 = ctrl_inl(addr0);
+ __raw_writel(data2, addr1);
+ data3 = __raw_readl(addr0);
/* Lastly, invaliate them. */
- ctrl_outl(data0&~SH_CACHE_VALID, addr0);
- ctrl_outl(data2&~SH_CACHE_VALID, addr1);
+ __raw_writel(data0&~SH_CACHE_VALID, addr0);
+ __raw_writel(data2&~SH_CACHE_VALID, addr1);
back_to_cached();
@@ -94,9 +94,9 @@ int __uses_jump_to_uncached detect_cpu_and_cache_system(void)
boot_cpu_data.dcache.way_incr = (1 << 13);
boot_cpu_data.dcache.entry_mask = 0x1ff0;
boot_cpu_data.dcache.sets = 512;
- ctrl_outl(CCR_CACHE_32KB, CCR3_REG);
+ __raw_writel(CCR_CACHE_32KB, CCR3_REG);
#else
- ctrl_outl(CCR_CACHE_16KB, CCR3_REG);
+ __raw_writel(CCR_CACHE_16KB, CCR3_REG);
#endif
#endif
}
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh3.c b/arch/sh/kernel/cpu/sh3/setup-sh3.c
index c9884685785..53be70b9811 100644
--- a/arch/sh/kernel/cpu/sh3/setup-sh3.c
+++ b/arch/sh/kernel/cpu/sh3/setup-sh3.c
@@ -58,7 +58,7 @@ static DECLARE_INTC_DESC_ACK(intc_desc_irq45, "sh3-irq45",
void __init plat_irq_setup_pins(int mode)
{
if (mode == IRQ_MODE_IRQ) {
- ctrl_outw(ctrl_inw(INTC_ICR1) & ~INTC_ICR1_IRQLVL, INTC_ICR1);
+ __raw_writew(__raw_readw(INTC_ICR1) & ~INTC_ICR1_IRQLVL, INTC_ICR1);
register_intc_controller(&intc_desc_irq0123);
return;
}
diff --git a/arch/sh/kernel/cpu/sh4/clock-sh4-202.c b/arch/sh/kernel/cpu/sh4/clock-sh4-202.c
index 21421e34e7d..6b80850294d 100644
--- a/arch/sh/kernel/cpu/sh4/clock-sh4-202.c
+++ b/arch/sh/kernel/cpu/sh4/clock-sh4-202.c
@@ -23,7 +23,7 @@ static int frqcr3_values[] = { 0, 1, 2, 3, 4, 5, 6 };
static unsigned long emi_clk_recalc(struct clk *clk)
{
- int idx = ctrl_inl(CPG2_FRQCR3) & 0x0007;
+ int idx = __raw_readl(CPG2_FRQCR3) & 0x0007;
return clk->parent->rate / frqcr3_divisors[idx];
}
@@ -52,7 +52,7 @@ static struct clk sh4202_emi_clk = {
static unsigned long femi_clk_recalc(struct clk *clk)
{
- int idx = (ctrl_inl(CPG2_FRQCR3) >> 3) & 0x0007;
+ int idx = (__raw_readl(CPG2_FRQCR3) >> 3) & 0x0007;
return clk->parent->rate / frqcr3_divisors[idx];
}
@@ -92,7 +92,7 @@ static void shoc_clk_init(struct clk *clk)
static unsigned long shoc_clk_recalc(struct clk *clk)
{
- int idx = (ctrl_inl(CPG2_FRQCR3) >> 6) & 0x0007;
+ int idx = (__raw_readl(CPG2_FRQCR3) >> 6) & 0x0007;
return clk->parent->rate / frqcr3_divisors[idx];
}
@@ -122,10 +122,10 @@ static int shoc_clk_set_rate(struct clk *clk, unsigned long rate, int algo_id)
tmp = frqcr3_lookup(clk, rate);
- frqcr3 = ctrl_inl(CPG2_FRQCR3);
+ frqcr3 = __raw_readl(CPG2_FRQCR3);
frqcr3 &= ~(0x0007 << 6);
frqcr3 |= tmp << 6;
- ctrl_outl(frqcr3, CPG2_FRQCR3);
+ __raw_writel(frqcr3, CPG2_FRQCR3);
clk->rate = clk->parent->rate / frqcr3_divisors[tmp];
diff --git a/arch/sh/kernel/cpu/sh4/clock-sh4.c b/arch/sh/kernel/cpu/sh4/clock-sh4.c
index 73294d9cd04..5add75c1f53 100644
--- a/arch/sh/kernel/cpu/sh4/clock-sh4.c
+++ b/arch/sh/kernel/cpu/sh4/clock-sh4.c
@@ -28,7 +28,7 @@ static int pfc_divisors[] = { 2, 3, 4, 6, 8, 2, 2, 2 };
static void master_clk_init(struct clk *clk)
{
- clk->rate *= pfc_divisors[ctrl_inw(FRQCR) & 0x0007];
+ clk->rate *= pfc_divisors[__raw_readw(FRQCR) & 0x0007];
}
static struct clk_ops sh4_master_clk_ops = {
@@ -37,7 +37,7 @@ static struct clk_ops sh4_master_clk_ops = {
static unsigned long module_clk_recalc(struct clk *clk)
{
- int idx = (ctrl_inw(FRQCR) & 0x0007);
+ int idx = (__raw_readw(FRQCR) & 0x0007);
return clk->parent->rate / pfc_divisors[idx];
}
@@ -47,7 +47,7 @@ static struct clk_ops sh4_module_clk_ops = {
static unsigned long bus_clk_recalc(struct clk *clk)
{
- int idx = (ctrl_inw(FRQCR) >> 3) & 0x0007;
+ int idx = (__raw_readw(FRQCR) >> 3) & 0x0007;
return clk->parent->rate / bfc_divisors[idx];
}
@@ -57,7 +57,7 @@ static struct clk_ops sh4_bus_clk_ops = {
static unsigned long cpu_clk_recalc(struct clk *clk)
{
- int idx = (ctrl_inw(FRQCR) >> 6) & 0x0007;
+ int idx = (__raw_readw(FRQCR) >> 6) & 0x0007;
return clk->parent->rate / ifc_divisors[idx];
}
diff --git a/arch/sh/kernel/cpu/sh4/fpu.c b/arch/sh/kernel/cpu/sh4/fpu.c
index e97857aec8a..447482d7f65 100644
--- a/arch/sh/kernel/cpu/sh4/fpu.c
+++ b/arch/sh/kernel/cpu/sh4/fpu.c
@@ -85,14 +85,14 @@ void save_fpu(struct task_struct *tsk)
"fmov.s fr1, @-%0\n\t"
"fmov.s fr0, @-%0\n\t"
"lds %3, fpscr\n\t":"=r" (dummy)
- :"0"((char *)(&tsk->thread.fpu.hard.status)),
+ :"0"((char *)(&tsk->thread.xstate->hardfpu.status)),
"r"(FPSCR_RCHG), "r"(FPSCR_INIT)
:"memory");
disable_fpu();
}
-static void restore_fpu(struct task_struct *tsk)
+void restore_fpu(struct task_struct *tsk)
{
unsigned long dummy;
@@ -135,62 +135,11 @@ static void restore_fpu(struct task_struct *tsk)
"lds.l @%0+, fpscr\n\t"
"lds.l @%0+, fpul\n\t"
:"=r" (dummy)
- :"0"(&tsk->thread.fpu), "r"(FPSCR_RCHG)
+ :"0" (tsk->thread.xstate), "r" (FPSCR_RCHG)
:"memory");
disable_fpu();
}
-/*
- * Load the FPU with signalling NANS. This bit pattern we're using
- * has the property that no matter wether considered as single or as
- * double precision represents signaling NANS.
- */
-
-static void fpu_init(void)
-{
- enable_fpu();
- asm volatile ( "lds %0, fpul\n\t"
- "lds %1, fpscr\n\t"
- "fsts fpul, fr0\n\t"
- "fsts fpul, fr1\n\t"
- "fsts fpul, fr2\n\t"
- "fsts fpul, fr3\n\t"
- "fsts fpul, fr4\n\t"
- "fsts fpul, fr5\n\t"
- "fsts fpul, fr6\n\t"
- "fsts fpul, fr7\n\t"
- "fsts fpul, fr8\n\t"
- "fsts fpul, fr9\n\t"
- "fsts fpul, fr10\n\t"
- "fsts fpul, fr11\n\t"
- "fsts fpul, fr12\n\t"
- "fsts fpul, fr13\n\t"
- "fsts fpul, fr14\n\t"
- "fsts fpul, fr15\n\t"
- "frchg\n\t"
- "fsts fpul, fr0\n\t"
- "fsts fpul, fr1\n\t"
- "fsts fpul, fr2\n\t"
- "fsts fpul, fr3\n\t"
- "fsts fpul, fr4\n\t"
- "fsts fpul, fr5\n\t"
- "fsts fpul, fr6\n\t"
- "fsts fpul, fr7\n\t"
- "fsts fpul, fr8\n\t"
- "fsts fpul, fr9\n\t"
- "fsts fpul, fr10\n\t"
- "fsts fpul, fr11\n\t"
- "fsts fpul, fr12\n\t"
- "fsts fpul, fr13\n\t"
- "fsts fpul, fr14\n\t"
- "fsts fpul, fr15\n\t"
- "frchg\n\t"
- "lds %2, fpscr\n\t"
- : /* no output */
- :"r" (0), "r"(FPSCR_RCHG), "r"(FPSCR_INIT));
- disable_fpu();
-}
-
/**
* denormal_to_double - Given denormalized float number,
* store double float
@@ -282,9 +231,9 @@ static int ieee_fpe_handler(struct pt_regs *regs)
/* fcnvsd */
struct task_struct *tsk = current;
- if ((tsk->thread.fpu.hard.fpscr & FPSCR_CAUSE_ERROR))
+ if ((tsk->thread.xstate->hardfpu.fpscr & FPSCR_CAUSE_ERROR))
/* FPU error */
- denormal_to_double(&tsk->thread.fpu.hard,
+ denormal_to_double(&tsk->thread.xstate->hardfpu,
(finsn >> 8) & 0xf);
else
return 0;
@@ -300,9 +249,9 @@ static int ieee_fpe_handler(struct pt_regs *regs)
n = (finsn >> 8) & 0xf;
m = (finsn >> 4) & 0xf;
- hx = tsk->thread.fpu.hard.fp_regs[n];
- hy = tsk->thread.fpu.hard.fp_regs[m];
- fpscr = tsk->thread.fpu.hard.fpscr;
+ hx = tsk->thread.xstate->hardfpu.fp_regs[n];
+ hy = tsk->thread.xstate->hardfpu.fp_regs[m];
+ fpscr = tsk->thread.xstate->hardfpu.fpscr;
prec = fpscr & FPSCR_DBL_PRECISION;
if ((fpscr & FPSCR_CAUSE_ERROR)
@@ -312,18 +261,18 @@ static int ieee_fpe_handler(struct pt_regs *regs)
/* FPU error because of denormal (doubles) */
llx = ((long long)hx << 32)
- | tsk->thread.fpu.hard.fp_regs[n + 1];
+ | tsk->thread.xstate->hardfpu.fp_regs[n + 1];
lly = ((long long)hy << 32)
- | tsk->thread.fpu.hard.fp_regs[m + 1];
+ | tsk->thread.xstate->hardfpu.fp_regs[m + 1];
llx = float64_mul(llx, lly);
- tsk->thread.fpu.hard.fp_regs[n] = llx >> 32;
- tsk->thread.fpu.hard.fp_regs[n + 1] = llx & 0xffffffff;
+ tsk->thread.xstate->hardfpu.fp_regs[n] = llx >> 32;
+ tsk->thread.xstate->hardfpu.fp_regs[n + 1] = llx & 0xffffffff;
} else if ((fpscr & FPSCR_CAUSE_ERROR)
&& (!prec && ((hx & 0x7fffffff) < 0x00800000
|| (hy & 0x7fffffff) < 0x00800000))) {
/* FPU error because of denormal (floats) */
hx = float32_mul(hx, hy);
- tsk->thread.fpu.hard.fp_regs[n] = hx;
+ tsk->thread.xstate->hardfpu.fp_regs[n] = hx;
} else
return 0;
@@ -338,9 +287,9 @@ static int ieee_fpe_handler(struct pt_regs *regs)
n = (finsn >> 8) & 0xf;
m = (finsn >> 4) & 0xf;
- hx = tsk->thread.fpu.hard.fp_regs[n];
- hy = tsk->thread.fpu.hard.fp_regs[m];
- fpscr = tsk->thread.fpu.hard.fpscr;
+ hx = tsk->thread.xstate->hardfpu.fp_regs[n];
+ hy = tsk->thread.xstate->hardfpu.fp_regs[m];
+ fpscr = tsk->thread.xstate->hardfpu.fpscr;
prec = fpscr & FPSCR_DBL_PRECISION;
if ((fpscr & FPSCR_CAUSE_ERROR)
@@ -350,15 +299,15 @@ static int ieee_fpe_handler(struct pt_regs *regs)
/* FPU error because of denormal (doubles) */
llx = ((long long)hx << 32)
- | tsk->thread.fpu.hard.fp_regs[n + 1];
+ | tsk->thread.xstate->hardfpu.fp_regs[n + 1];
lly = ((long long)hy << 32)
- | tsk->thread.fpu.hard.fp_regs[m + 1];
+ | tsk->thread.xstate->hardfpu.fp_regs[m + 1];
if ((finsn & 0xf00f) == 0xf000)
llx = float64_add(llx, lly);
else
llx = float64_sub(llx, lly);
- tsk->thread.fpu.hard.fp_regs[n] = llx >> 32;
- tsk->thread.fpu.hard.fp_regs[n + 1] = llx & 0xffffffff;
+ tsk->thread.xstate->hardfpu.fp_regs[n] = llx >> 32;
+ tsk->thread.xstate->hardfpu.fp_regs[n + 1] = llx & 0xffffffff;
} else if ((fpscr & FPSCR_CAUSE_ERROR)
&& (!prec && ((hx & 0x7fffffff) < 0x00800000
|| (hy & 0x7fffffff) < 0x00800000))) {
@@ -367,7 +316,7 @@ static int ieee_fpe_handler(struct pt_regs *regs)
hx = float32_add(hx, hy);
else
hx = float32_sub(hx, hy);
- tsk->thread.fpu.hard.fp_regs[n] = hx;
+ tsk->thread.xstate->hardfpu.fp_regs[n] = hx;
} else
return 0;
@@ -382,9 +331,9 @@ static int ieee_fpe_handler(struct pt_regs *regs)
n = (finsn >> 8) & 0xf;
m = (finsn >> 4) & 0xf;
- hx = tsk->thread.fpu.hard.fp_regs[n];
- hy = tsk->thread.fpu.hard.fp_regs[m];
- fpscr = tsk->thread.fpu.hard.fpscr;
+ hx = tsk->thread.xstate->hardfpu.fp_regs[n];
+ hy = tsk->thread.xstate->hardfpu.fp_regs[m];
+ fpscr = tsk->thread.xstate->hardfpu.fpscr;
prec = fpscr & FPSCR_DBL_PRECISION;
if ((fpscr & FPSCR_CAUSE_ERROR)
@@ -394,20 +343,20 @@ static int ieee_fpe_handler(struct pt_regs *regs)
/* FPU error because of denormal (doubles) */
llx = ((long long)hx << 32)
- | tsk->thread.fpu.hard.fp_regs[n + 1];
+ | tsk->thread.xstate->hardfpu.fp_regs[n + 1];
lly = ((long long)hy << 32)
- | tsk->thread.fpu.hard.fp_regs[m + 1];
+ | tsk->thread.xstate->hardfpu.fp_regs[m + 1];
llx = float64_div(llx, lly);
- tsk->thread.fpu.hard.fp_regs[n] = llx >> 32;
- tsk->thread.fpu.hard.fp_regs[n + 1] = llx & 0xffffffff;
+ tsk->thread.xstate->hardfpu.fp_regs[n] = llx >> 32;
+ tsk->thread.xstate->hardfpu.fp_regs[n + 1] = llx & 0xffffffff;
} else if ((fpscr & FPSCR_CAUSE_ERROR)
&& (!prec && ((hx & 0x7fffffff) < 0x00800000
|| (hy & 0x7fffffff) < 0x00800000))) {
/* FPU error because of denormal (floats) */
hx = float32_div(hx, hy);
- tsk->thread.fpu.hard.fp_regs[n] = hx;
+ tsk->thread.xstate->hardfpu.fp_regs[n] = hx;
} else
return 0;
@@ -420,17 +369,17 @@ static int ieee_fpe_handler(struct pt_regs *regs)
unsigned int hx;
m = (finsn >> 8) & 0x7;
- hx = tsk->thread.fpu.hard.fp_regs[m];
+ hx = tsk->thread.xstate->hardfpu.fp_regs[m];
- if ((tsk->thread.fpu.hard.fpscr & FPSCR_CAUSE_ERROR)
+ if ((tsk->thread.xstate->hardfpu.fpscr & FPSCR_CAUSE_ERROR)
&& ((hx & 0x7fffffff) < 0x00100000)) {
/* subnormal double to float conversion */
long long llx;
- llx = ((long long)tsk->thread.fpu.hard.fp_regs[m] << 32)
- | tsk->thread.fpu.hard.fp_regs[m + 1];
+ llx = ((long long)tsk->thread.xstate->hardfpu.fp_regs[m] << 32)
+ | tsk->thread.xstate->hardfpu.fp_regs[m + 1];
- tsk->thread.fpu.hard.fpul = float64_to_float32(llx);
+ tsk->thread.xstate->hardfpu.fpul = float64_to_float32(llx);
} else
return 0;
@@ -449,7 +398,7 @@ void float_raise(unsigned int flags)
int float_rounding_mode(void)
{
struct task_struct *tsk = current;
- int roundingMode = FPSCR_ROUNDING_MODE(tsk->thread.fpu.hard.fpscr);
+ int roundingMode = FPSCR_ROUNDING_MODE(tsk->thread.xstate->hardfpu.fpscr);
return roundingMode;
}
@@ -461,16 +410,16 @@ BUILD_TRAP_HANDLER(fpu_error)
__unlazy_fpu(tsk, regs);
fpu_exception_flags = 0;
if (ieee_fpe_handler(regs)) {
- tsk->thread.fpu.hard.fpscr &=
+ tsk->thread.xstate->hardfpu.fpscr &=
~(FPSCR_CAUSE_MASK | FPSCR_FLAG_MASK);
- tsk->thread.fpu.hard.fpscr |= fpu_exception_flags;
+ tsk->thread.xstate->hardfpu.fpscr |= fpu_exception_flags;
/* Set the FPSCR flag as well as cause bits - simply
* replicate the cause */
- tsk->thread.fpu.hard.fpscr |= (fpu_exception_flags >> 10);
+ tsk->thread.xstate->hardfpu.fpscr |= (fpu_exception_flags >> 10);
grab_fpu(regs);
restore_fpu(tsk);
task_thread_info(tsk)->status |= TS_USEDFPU;
- if ((((tsk->thread.fpu.hard.fpscr & FPSCR_ENABLE_MASK) >> 7) &
+ if ((((tsk->thread.xstate->hardfpu.fpscr & FPSCR_ENABLE_MASK) >> 7) &
(fpu_exception_flags >> 2)) == 0) {
return;
}
@@ -478,33 +427,3 @@ BUILD_TRAP_HANDLER(fpu_error)
force_sig(SIGFPE, tsk);
}
-
-void fpu_state_restore(struct pt_regs *regs)
-{
- struct task_struct *tsk = current;
-
- grab_fpu(regs);
- if (unlikely(!user_mode(regs))) {
- printk(KERN_ERR "BUG: FPU is used in kernel mode.\n");
- BUG();
- return;
- }
-
- if (likely(used_math())) {
- /* Using the FPU again. */
- restore_fpu(tsk);
- } else {
- /* First time FPU user. */
- fpu_init();
- set_used_math();
- }
- task_thread_info(tsk)->status |= TS_USEDFPU;
- tsk->fpu_counter++;
-}
-
-BUILD_TRAP_HANDLER(fpu_state_restore)
-{
- TRAP_HANDLER_DECL;
-
- fpu_state_restore(regs);
-}
diff --git a/arch/sh/kernel/cpu/sh4/probe.c b/arch/sh/kernel/cpu/sh4/probe.c
index d36f0c45f55..822977a06d8 100644
--- a/arch/sh/kernel/cpu/sh4/probe.c
+++ b/arch/sh/kernel/cpu/sh4/probe.c
@@ -28,9 +28,9 @@ int __init detect_cpu_and_cache_system(void)
[9] = (1 << 16)
};
- pvr = (ctrl_inl(CCN_PVR) >> 8) & 0xffffff;
- prr = (ctrl_inl(CCN_PRR) >> 4) & 0xff;
- cvr = (ctrl_inl(CCN_CVR));
+ pvr = (__raw_readl(CCN_PVR) >> 8) & 0xffffff;
+ prr = (__raw_readl(CCN_PRR) >> 4) & 0xff;
+ cvr = (__raw_readl(CCN_CVR));
/*
* Setup some sane SH-4 defaults for the icache
@@ -71,11 +71,11 @@ int __init detect_cpu_and_cache_system(void)
boot_cpu_data.dcache.ways = 4;
} else {
/* And some SH-4 defaults.. */
- boot_cpu_data.flags |= CPU_HAS_PTEA;
+ boot_cpu_data.flags |= CPU_HAS_PTEA | CPU_HAS_FPU;
boot_cpu_data.family = CPU_FAMILY_SH4;
}
- /* FPU detection works for everyone */
+ /* FPU detection works for almost everyone */
if ((cvr & 0x20000000))
boot_cpu_data.flags |= CPU_HAS_FPU;
@@ -124,6 +124,7 @@ int __init detect_cpu_and_cache_system(void)
boot_cpu_data.type = CPU_SH7785;
break;
case 0x4004:
+ case 0x4005:
boot_cpu_data.type = CPU_SH7786;
boot_cpu_data.flags |= CPU_HAS_PTEAEX | CPU_HAS_L2_CACHE;
break;
@@ -160,6 +161,7 @@ int __init detect_cpu_and_cache_system(void)
break;
case 0x700:
boot_cpu_data.type = CPU_SH4_501;
+ boot_cpu_data.flags &= ~CPU_HAS_FPU;
boot_cpu_data.icache.ways = 2;
boot_cpu_data.dcache.ways = 2;
break;
@@ -227,7 +229,7 @@ int __init detect_cpu_and_cache_system(void)
* Size calculation is much more sensible
* than it is for the L1.
*
- * Sizes are 128KB, 258KB, 512KB, and 1MB.
+ * Sizes are 128KB, 256KB, 512KB, and 1MB.
*/
size = (cvr & 0xf) << 17;
diff --git a/arch/sh/kernel/cpu/sh4/setup-sh4-202.c b/arch/sh/kernel/cpu/sh4/setup-sh4-202.c
index 4b733715cdb..b9b7e10ad68 100644
--- a/arch/sh/kernel/cpu/sh4/setup-sh4-202.c
+++ b/arch/sh/kernel/cpu/sh4/setup-sh4-202.c
@@ -198,7 +198,7 @@ void __init plat_irq_setup_pins(int mode)
{
switch (mode) {
case IRQ_MODE_IRQ: /* individual interrupt mode for IRL3-0 */
- ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR);
+ __raw_writew(__raw_readw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR);
register_intc_controller(&intc_desc_irlm);
break;
default:
diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7750.c b/arch/sh/kernel/cpu/sh4/setup-sh7750.c
index b2a9df1af64..ffd79e57254 100644
--- a/arch/sh/kernel/cpu/sh4/setup-sh7750.c
+++ b/arch/sh/kernel/cpu/sh4/setup-sh7750.c
@@ -442,7 +442,7 @@ void __init plat_irq_setup_pins(int mode)
switch (mode) {
case IRQ_MODE_IRQ: /* individual interrupt mode for IRL3-0 */
- ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR);
+ __raw_writew(__raw_readw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR);
register_intc_controller(&intc_desc_irlm);
break;
default:
diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7760.c b/arch/sh/kernel/cpu/sh4/setup-sh7760.c
index 5b74cc0b43d..a16eb3656f4 100644
--- a/arch/sh/kernel/cpu/sh4/setup-sh7760.c
+++ b/arch/sh/kernel/cpu/sh4/setup-sh7760.c
@@ -319,7 +319,7 @@ void __init plat_irq_setup_pins(int mode)
{
switch (mode) {
case IRQ_MODE_IRQ:
- ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR);
+ __raw_writew(__raw_readw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR);
register_intc_controller(&intc_desc_irq);
break;
default:
diff --git a/arch/sh/kernel/cpu/sh4/sq.c b/arch/sh/kernel/cpu/sh4/sq.c
index 8a8a993f55e..fc065f9da6e 100644
--- a/arch/sh/kernel/cpu/sh4/sq.c
+++ b/arch/sh/kernel/cpu/sh4/sq.c
@@ -43,9 +43,9 @@ static unsigned long *sq_bitmap;
#define store_queue_barrier() \
do { \
- (void)ctrl_inl(P4SEG_STORE_QUE); \
- ctrl_outl(0, P4SEG_STORE_QUE + 0); \
- ctrl_outl(0, P4SEG_STORE_QUE + 8); \
+ (void)__raw_readl(P4SEG_STORE_QUE); \
+ __raw_writel(0, P4SEG_STORE_QUE + 0); \
+ __raw_writel(0, P4SEG_STORE_QUE + 8); \
} while (0);
/**
@@ -100,7 +100,7 @@ static inline void sq_mapping_list_del(struct sq_mapping *map)
spin_unlock_irq(&sq_mapping_lock);
}
-static int __sq_remap(struct sq_mapping *map, unsigned long flags)
+static int __sq_remap(struct sq_mapping *map, pgprot_t prot)
{
#if defined(CONFIG_MMU)
struct vm_struct *vma;
@@ -113,7 +113,7 @@ static int __sq_remap(struct sq_mapping *map, unsigned long flags)
if (ioremap_page_range((unsigned long)vma->addr,
(unsigned long)vma->addr + map->size,
- vma->phys_addr, __pgprot(flags))) {
+ vma->phys_addr, prot)) {
vunmap(vma->addr);
return -EAGAIN;
}
@@ -123,8 +123,8 @@ static int __sq_remap(struct sq_mapping *map, unsigned long flags)
* straightforward, as we can just load up each queue's QACR with
* the physical address appropriately masked.
*/
- ctrl_outl(((map->addr >> 26) << 2) & 0x1c, SQ_QACR0);
- ctrl_outl(((map->addr >> 26) << 2) & 0x1c, SQ_QACR1);
+ __raw_writel(((map->addr >> 26) << 2) & 0x1c, SQ_QACR0);
+ __raw_writel(((map->addr >> 26) << 2) & 0x1c, SQ_QACR1);
#endif
return 0;
@@ -135,14 +135,14 @@ static int __sq_remap(struct sq_mapping *map, unsigned long flags)
* @phys: Physical address of mapping.
* @size: Length of mapping.
* @name: User invoking mapping.
- * @flags: Protection flags.
+ * @prot: Protection bits.
*
* Remaps the physical address @phys through the next available store queue
* address of @size length. @name is logged at boot time as well as through
* the sysfs interface.
*/
unsigned long sq_remap(unsigned long phys, unsigned int size,
- const char *name, unsigned long flags)
+ const char *name, pgprot_t prot)
{
struct sq_mapping *map;
unsigned long end;
@@ -177,7 +177,7 @@ unsigned long sq_remap(unsigned long phys, unsigned int size,
map->sq_addr = P4SEG_STORE_QUE + (page << PAGE_SHIFT);
- ret = __sq_remap(map, pgprot_val(PAGE_KERNEL_NOCACHE) | flags);
+ ret = __sq_remap(map, prot);
if (unlikely(ret != 0))
goto out;
@@ -309,8 +309,7 @@ static ssize_t mapping_store(const char *buf, size_t count)
return -EIO;
if (likely(len)) {
- int ret = sq_remap(base, len, "Userspace",
- pgprot_val(PAGE_SHARED));
+ int ret = sq_remap(base, len, "Userspace", PAGE_SHARED);
if (ret < 0)
return ret;
} else
diff --git a/arch/sh/kernel/cpu/sh4a/Makefile b/arch/sh/kernel/cpu/sh4a/Makefile
index 33bab477d2e..b144e8af89d 100644
--- a/arch/sh/kernel/cpu/sh4a/Makefile
+++ b/arch/sh/kernel/cpu/sh4a/Makefile
@@ -41,7 +41,8 @@ pinmux-$(CONFIG_CPU_SUBTYPE_SH7757) := pinmux-sh7757.o
pinmux-$(CONFIG_CPU_SUBTYPE_SH7785) := pinmux-sh7785.o
pinmux-$(CONFIG_CPU_SUBTYPE_SH7786) := pinmux-sh7786.o
-obj-y += $(clock-y)
-obj-$(CONFIG_SMP) += $(smp-y)
-obj-$(CONFIG_GENERIC_GPIO) += $(pinmux-y)
-obj-$(CONFIG_PERF_EVENTS) += perf_event.o
+obj-y += $(clock-y)
+obj-$(CONFIG_SMP) += $(smp-y)
+obj-$(CONFIG_GENERIC_GPIO) += $(pinmux-y)
+obj-$(CONFIG_PERF_EVENTS) += perf_event.o
+obj-$(CONFIG_HAVE_HW_BREAKPOINT) += ubc.o
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7343.c b/arch/sh/kernel/cpu/sh4a/clock-sh7343.c
index 0ee3ee86125..2c16df37eda 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7343.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7343.c
@@ -107,13 +107,17 @@ struct clk *main_clks[] = {
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 };
-static struct clk_div_mult_table div4_table = {
+static struct clk_div_mult_table div4_div_mult_table = {
.divisors = divisors,
.nr_divisors = ARRAY_SIZE(divisors),
.multipliers = multipliers,
.nr_multipliers = ARRAY_SIZE(multipliers),
};
+static struct clk_div4_table div4_table = {
+ .div_mult_table = &div4_div_mult_table,
+};
+
enum { DIV4_I, DIV4_U, DIV4_SH, DIV4_B, DIV4_B3, DIV4_P,
DIV4_SIUA, DIV4_SIUB, DIV4_NR };
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7366.c b/arch/sh/kernel/cpu/sh4a/clock-sh7366.c
index a95ebaba095..91588d280cd 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7366.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7366.c
@@ -110,13 +110,17 @@ struct clk *main_clks[] = {
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 };
-static struct clk_div_mult_table div4_table = {
+static struct clk_div_mult_table div4_div_mult_table = {
.divisors = divisors,
.nr_divisors = ARRAY_SIZE(divisors),
.multipliers = multipliers,
.nr_multipliers = ARRAY_SIZE(multipliers),
};
+static struct clk_div4_table div4_table = {
+ .div_mult_table = &div4_div_mult_table,
+};
+
enum { DIV4_I, DIV4_U, DIV4_SH, DIV4_B, DIV4_B3, DIV4_P,
DIV4_SIUA, DIV4_SIUB, DIV4_NR };
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c
index ea38b554dc0..15db6d521c5 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c
@@ -110,19 +110,22 @@ struct clk *main_clks[] = {
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 };
-static struct clk_div_mult_table div4_table = {
+static struct clk_div_mult_table div4_div_mult_table = {
.divisors = divisors,
.nr_divisors = ARRAY_SIZE(divisors),
.multipliers = multipliers,
.nr_multipliers = ARRAY_SIZE(multipliers),
};
-enum { DIV4_I, DIV4_U, DIV4_SH, DIV4_B, DIV4_B3, DIV4_P,
- DIV4_SIUA, DIV4_SIUB, DIV4_IRDA, DIV4_NR };
+static struct clk_div4_table div4_table = {
+ .div_mult_table = &div4_div_mult_table,
+};
#define DIV4(_str, _reg, _bit, _mask, _flags) \
SH_CLK_DIV4(_str, &pll_clk, _reg, _bit, _mask, _flags)
+enum { DIV4_I, DIV4_U, DIV4_SH, DIV4_B, DIV4_B3, DIV4_P, DIV4_NR };
+
struct clk div4_clks[DIV4_NR] = {
[DIV4_I] = DIV4("cpu_clk", FRQCR, 20, 0x1fef, CLK_ENABLE_ON_INIT),
[DIV4_U] = DIV4("umem_clk", FRQCR, 16, 0x1fff, CLK_ENABLE_ON_INIT),
@@ -130,9 +133,19 @@ struct clk div4_clks[DIV4_NR] = {
[DIV4_B] = DIV4("bus_clk", FRQCR, 8, 0x1fff, CLK_ENABLE_ON_INIT),
[DIV4_B3] = DIV4("b3_clk", FRQCR, 4, 0x1fff, CLK_ENABLE_ON_INIT),
[DIV4_P] = DIV4("peripheral_clk", FRQCR, 0, 0x1fff, 0),
+};
+
+enum { DIV4_IRDA, DIV4_ENABLE_NR };
+
+struct clk div4_enable_clks[DIV4_ENABLE_NR] = {
+ [DIV4_IRDA] = DIV4("irda_clk", IRDACLKCR, 0, 0x1fff, 0),
+};
+
+enum { DIV4_SIUA, DIV4_SIUB, DIV4_REPARENT_NR };
+
+struct clk div4_reparent_clks[DIV4_REPARENT_NR] = {
[DIV4_SIUA] = DIV4("siua_clk", SCLKACR, 0, 0x1fff, 0),
[DIV4_SIUB] = DIV4("siub_clk", SCLKBCR, 0, 0x1fff, 0),
- [DIV4_IRDA] = DIV4("irda_clk", IRDACLKCR, 0, 0x1fff, 0),
};
struct clk div6_clks[] = {
@@ -189,6 +202,14 @@ int __init arch_clk_init(void)
ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
if (!ret)
+ ret = sh_clk_div4_enable_register(div4_enable_clks,
+ DIV4_ENABLE_NR, &div4_table);
+
+ if (!ret)
+ ret = sh_clk_div4_reparent_register(div4_reparent_clks,
+ DIV4_REPARENT_NR, &div4_table);
+
+ if (!ret)
ret = sh_clk_div6_register(div6_clks, ARRAY_SIZE(div6_clks));
if (!ret)
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7723.c b/arch/sh/kernel/cpu/sh4a/clock-sh7723.c
index 20a31c2255a..50babe01fe4 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7723.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7723.c
@@ -110,15 +110,18 @@ struct clk *main_clks[] = {
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 };
-static struct clk_div_mult_table div4_table = {
+static struct clk_div_mult_table div4_div_mult_table = {
.divisors = divisors,
.nr_divisors = ARRAY_SIZE(divisors),
.multipliers = multipliers,
.nr_multipliers = ARRAY_SIZE(multipliers),
};
-enum { DIV4_I, DIV4_U, DIV4_SH, DIV4_B, DIV4_B3, DIV4_P,
- DIV4_SIUA, DIV4_SIUB, DIV4_IRDA, DIV4_NR };
+static struct clk_div4_table div4_table = {
+ .div_mult_table = &div4_div_mult_table,
+};
+
+enum { DIV4_I, DIV4_U, DIV4_SH, DIV4_B, DIV4_B3, DIV4_P, DIV4_NR };
#define DIV4(_str, _reg, _bit, _mask, _flags) \
SH_CLK_DIV4(_str, &pll_clk, _reg, _bit, _mask, _flags)
@@ -130,11 +133,20 @@ struct clk div4_clks[DIV4_NR] = {
[DIV4_B] = DIV4("bus_clk", FRQCR, 8, 0x0dbf, CLK_ENABLE_ON_INIT),
[DIV4_B3] = DIV4("b3_clk", FRQCR, 4, 0x0db4, CLK_ENABLE_ON_INIT),
[DIV4_P] = DIV4("peripheral_clk", FRQCR, 0, 0x0dbf, 0),
- [DIV4_SIUA] = DIV4("siua_clk", SCLKACR, 0, 0x0dbf, 0),
- [DIV4_SIUB] = DIV4("siub_clk", SCLKBCR, 0, 0x0dbf, 0),
+};
+
+enum { DIV4_IRDA, DIV4_ENABLE_NR };
+
+struct clk div4_enable_clks[DIV4_ENABLE_NR] = {
[DIV4_IRDA] = DIV4("irda_clk", IRDACLKCR, 0, 0x0dbf, 0),
};
+enum { DIV4_SIUA, DIV4_SIUB, DIV4_REPARENT_NR };
+
+struct clk div4_reparent_clks[DIV4_REPARENT_NR] = {
+ [DIV4_SIUA] = DIV4("siua_clk", SCLKACR, 0, 0x0dbf, 0),
+ [DIV4_SIUB] = DIV4("siub_clk", SCLKBCR, 0, 0x0dbf, 0),
+};
struct clk div6_clks[] = {
SH_CLK_DIV6("video_clk", &pll_clk, VCLKCR, 0),
};
@@ -216,6 +228,14 @@ int __init arch_clk_init(void)
ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
if (!ret)
+ ret = sh_clk_div4_enable_register(div4_enable_clks,
+ DIV4_ENABLE_NR, &div4_table);
+
+ if (!ret)
+ ret = sh_clk_div4_reparent_register(div4_reparent_clks,
+ DIV4_REPARENT_NR, &div4_table);
+
+ if (!ret)
ret = sh_clk_div6_register(div6_clks, ARRAY_SIZE(div6_clks));
if (!ret)
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c
index 9db743802f0..6707061fbf5 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c
@@ -127,13 +127,28 @@ struct clk *main_clks[] = {
&div3_clk,
};
+static void div4_kick(struct clk *clk)
+{
+ unsigned long value;
+
+ /* set KICK bit in FRQCRA to update hardware setting */
+ value = __raw_readl(FRQCRA);
+ value |= (1 << 31);
+ __raw_writel(value, FRQCRA);
+}
+
static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 0, 24, 32, 36, 48, 0, 72 };
-static struct clk_div_mult_table div4_table = {
+static struct clk_div_mult_table div4_div_mult_table = {
.divisors = divisors,
.nr_divisors = ARRAY_SIZE(divisors),
};
+static struct clk_div4_table div4_table = {
+ .div_mult_table = &div4_div_mult_table,
+ .kick = div4_kick,
+};
+
enum { DIV4_I, DIV4_SH, DIV4_B, DIV4_P, DIV4_M1, DIV4_NR };
#define DIV4(_str, _reg, _bit, _mask, _flags) \
@@ -144,7 +159,7 @@ struct clk div4_clks[DIV4_NR] = {
[DIV4_SH] = DIV4("shyway_clk", FRQCRA, 12, 0x2f7c, CLK_ENABLE_ON_INIT),
[DIV4_B] = DIV4("bus_clk", FRQCRA, 8, 0x2f7c, CLK_ENABLE_ON_INIT),
[DIV4_P] = DIV4("peripheral_clk", FRQCRA, 0, 0x2f7c, 0),
- [DIV4_M1] = DIV4("vpu_clk", FRQCRB, 4, 0x2f7c, 0),
+ [DIV4_M1] = DIV4("vpu_clk", FRQCRB, 4, 0x2f7c, CLK_ENABLE_ON_INIT),
};
struct clk div6_clks[] = {
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7757.c b/arch/sh/kernel/cpu/sh4a/clock-sh7757.c
index ddc235ca966..86aae60677d 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7757.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7757.c
@@ -35,7 +35,7 @@ static struct clk_ops sh7757_master_clk_ops = {
static void module_clk_recalc(struct clk *clk)
{
- int idx = ctrl_inl(FRQCR) & 0x0000000f;
+ int idx = __raw_readl(FRQCR) & 0x0000000f;
clk->rate = clk->parent->rate / p1fc_divisors[idx];
}
@@ -45,7 +45,7 @@ static struct clk_ops sh7757_module_clk_ops = {
static void bus_clk_recalc(struct clk *clk)
{
- int idx = (ctrl_inl(FRQCR) >> 8) & 0x0000000f;
+ int idx = (__raw_readl(FRQCR) >> 8) & 0x0000000f;
clk->rate = clk->parent->rate / bfc_divisors[idx];
}
@@ -55,7 +55,7 @@ static struct clk_ops sh7757_bus_clk_ops = {
static void cpu_clk_recalc(struct clk *clk)
{
- int idx = (ctrl_inl(FRQCR) >> 20) & 0x0000000f;
+ int idx = (__raw_readl(FRQCR) >> 20) & 0x0000000f;
clk->rate = clk->parent->rate / ifc_divisors[idx];
}
@@ -78,7 +78,7 @@ void __init arch_init_clk_ops(struct clk_ops **ops, int idx)
static void shyway_clk_recalc(struct clk *clk)
{
- int idx = (ctrl_inl(FRQCR) >> 12) & 0x0000000f;
+ int idx = (__raw_readl(FRQCR) >> 12) & 0x0000000f;
clk->rate = clk->parent->rate / sfc_divisors[idx];
}
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7763.c b/arch/sh/kernel/cpu/sh4a/clock-sh7763.c
index 370cd47642e..9f401163e71 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7763.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7763.c
@@ -22,7 +22,7 @@ static int cfc_divisors[] = { 1, 1, 4, 1, 1, 1, 1, 1 };
static void master_clk_init(struct clk *clk)
{
- clk->rate *= p0fc_divisors[(ctrl_inl(FRQCR) >> 4) & 0x07];
+ clk->rate *= p0fc_divisors[(__raw_readl(FRQCR) >> 4) & 0x07];
}
static struct clk_ops sh7763_master_clk_ops = {
@@ -31,7 +31,7 @@ static struct clk_ops sh7763_master_clk_ops = {
static unsigned long module_clk_recalc(struct clk *clk)
{
- int idx = ((ctrl_inl(FRQCR) >> 4) & 0x07);
+ int idx = ((__raw_readl(FRQCR) >> 4) & 0x07);
return clk->parent->rate / p0fc_divisors[idx];
}
@@ -41,7 +41,7 @@ static struct clk_ops sh7763_module_clk_ops = {
static unsigned long bus_clk_recalc(struct clk *clk)
{
- int idx = ((ctrl_inl(FRQCR) >> 16) & 0x07);
+ int idx = ((__raw_readl(FRQCR) >> 16) & 0x07);
return clk->parent->rate / bfc_divisors[idx];
}
@@ -68,7 +68,7 @@ void __init arch_init_clk_ops(struct clk_ops **ops, int idx)
static unsigned long shyway_clk_recalc(struct clk *clk)
{
- int idx = ((ctrl_inl(FRQCR) >> 20) & 0x07);
+ int idx = ((__raw_readl(FRQCR) >> 20) & 0x07);
return clk->parent->rate / cfc_divisors[idx];
}
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7770.c b/arch/sh/kernel/cpu/sh4a/clock-sh7770.c
index e0b89676920..9e3354365d4 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7770.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7770.c
@@ -21,7 +21,7 @@ static int pfc_divisors[] = { 1, 8, 1,10,12,16, 1, 1 };
static void master_clk_init(struct clk *clk)
{
- clk->rate *= pfc_divisors[(ctrl_inl(FRQCR) >> 28) & 0x000f];
+ clk->rate *= pfc_divisors[(__raw_readl(FRQCR) >> 28) & 0x000f];
}
static struct clk_ops sh7770_master_clk_ops = {
@@ -30,7 +30,7 @@ static struct clk_ops sh7770_master_clk_ops = {
static unsigned long module_clk_recalc(struct clk *clk)
{
- int idx = ((ctrl_inl(FRQCR) >> 28) & 0x000f);
+ int idx = ((__raw_readl(FRQCR) >> 28) & 0x000f);
return clk->parent->rate / pfc_divisors[idx];
}
@@ -40,7 +40,7 @@ static struct clk_ops sh7770_module_clk_ops = {
static unsigned long bus_clk_recalc(struct clk *clk)
{
- int idx = (ctrl_inl(FRQCR) & 0x000f);
+ int idx = (__raw_readl(FRQCR) & 0x000f);
return clk->parent->rate / bfc_divisors[idx];
}
@@ -50,7 +50,7 @@ static struct clk_ops sh7770_bus_clk_ops = {
static unsigned long cpu_clk_recalc(struct clk *clk)
{
- int idx = ((ctrl_inl(FRQCR) >> 24) & 0x000f);
+ int idx = ((__raw_readl(FRQCR) >> 24) & 0x000f);
return clk->parent->rate / ifc_divisors[idx];
}
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7780.c b/arch/sh/kernel/cpu/sh4a/clock-sh7780.c
index a249d823578..150963a6001 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7780.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7780.c
@@ -22,7 +22,7 @@ static int cfc_divisors[] = { 1, 1, 4, 1, 6, 1, 1, 1 };
static void master_clk_init(struct clk *clk)
{
- clk->rate *= pfc_divisors[ctrl_inl(FRQCR) & 0x0003];
+ clk->rate *= pfc_divisors[__raw_readl(FRQCR) & 0x0003];
}
static struct clk_ops sh7780_master_clk_ops = {
@@ -31,7 +31,7 @@ static struct clk_ops sh7780_master_clk_ops = {
static unsigned long module_clk_recalc(struct clk *clk)
{
- int idx = (ctrl_inl(FRQCR) & 0x0003);
+ int idx = (__raw_readl(FRQCR) & 0x0003);
return clk->parent->rate / pfc_divisors[idx];
}
@@ -41,7 +41,7 @@ static struct clk_ops sh7780_module_clk_ops = {
static unsigned long bus_clk_recalc(struct clk *clk)
{
- int idx = ((ctrl_inl(FRQCR) >> 16) & 0x0007);
+ int idx = ((__raw_readl(FRQCR) >> 16) & 0x0007);
return clk->parent->rate / bfc_divisors[idx];
}
@@ -51,7 +51,7 @@ static struct clk_ops sh7780_bus_clk_ops = {
static unsigned long cpu_clk_recalc(struct clk *clk)
{
- int idx = ((ctrl_inl(FRQCR) >> 24) & 0x0001);
+ int idx = ((__raw_readl(FRQCR) >> 24) & 0x0001);
return clk->parent->rate / ifc_divisors[idx];
}
@@ -74,7 +74,7 @@ void __init arch_init_clk_ops(struct clk_ops **ops, int idx)
static unsigned long shyway_clk_recalc(struct clk *clk)
{
- int idx = ((ctrl_inl(FRQCR) >> 20) & 0x0007);
+ int idx = ((__raw_readl(FRQCR) >> 20) & 0x0007);
return clk->parent->rate / cfc_divisors[idx];
}
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7785.c b/arch/sh/kernel/cpu/sh4a/clock-sh7785.c
index 73abfbf2f16..d997f0a25b1 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7785.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7785.c
@@ -57,11 +57,15 @@ static struct clk *clks[] = {
static unsigned int div2[] = { 1, 2, 4, 6, 8, 12, 16, 18,
24, 32, 36, 48 };
-static struct clk_div_mult_table div4_table = {
+static struct clk_div_mult_table div4_div_mult_table = {
.divisors = div2,
.nr_divisors = ARRAY_SIZE(div2),
};
+static struct clk_div4_table div4_table = {
+ .div_mult_table = &div4_div_mult_table,
+};
+
enum { DIV4_I, DIV4_U, DIV4_SH, DIV4_B, DIV4_DDR, DIV4_GA,
DIV4_DU, DIV4_P, DIV4_NR };
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7786.c b/arch/sh/kernel/cpu/sh4a/clock-sh7786.c
index a0e8869071a..af69fd46870 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7786.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7786.c
@@ -3,11 +3,7 @@
*
* SH7786 support for the clock framework
*
- * Copyright (C) 2008, 2009 Renesas Solutions Corp.
- * Kuninori Morimoto <morimoto.kuninori@renesas.com>
- *
- * Based on SH7785
- * Copyright (C) 2007 Paul Mundt
+ * Copyright (C) 2010 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
@@ -15,127 +11,127 @@
*/
#include <linux/init.h>
#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/io.h>
#include <asm/clock.h>
#include <asm/freq.h>
-#include <asm/io.h>
-
-static int ifc_divisors[] = { 1, 2, 4, 1 };
-static int sfc_divisors[] = { 1, 1, 4, 1 };
-static int bfc_divisors[] = { 1, 1, 1, 1, 1, 12, 16, 1,
- 24, 32, 1, 1, 1, 1, 1, 1 };
-static int mfc_divisors[] = { 1, 1, 4, 1 };
-static int pfc_divisors[] = { 1, 1, 1, 1, 1, 1, 16, 1,
- 24, 32, 1, 48, 1, 1, 1, 1 };
-static void master_clk_init(struct clk *clk)
-{
- clk->rate *= pfc_divisors[ctrl_inl(FRQMR1) & 0x000f];
-}
-
-static struct clk_ops sh7786_master_clk_ops = {
- .init = master_clk_init,
+/*
+ * Default rate for the root input clock, reset this with clk_set_rate()
+ * from the platform code.
+ */
+static struct clk extal_clk = {
+ .name = "extal",
+ .id = -1,
+ .rate = 33333333,
};
-static unsigned long module_clk_recalc(struct clk *clk)
+static unsigned long pll_recalc(struct clk *clk)
{
- int idx = (ctrl_inl(FRQMR1) & 0x000f);
- return clk->parent->rate / pfc_divisors[idx];
-}
+ int multiplier;
-static struct clk_ops sh7786_module_clk_ops = {
- .recalc = module_clk_recalc,
-};
+ /*
+ * Clock modes 0, 1, and 2 use an x64 multiplier against PLL1,
+ * while modes 3, 4, and 5 use an x32.
+ */
+ multiplier = (sh_mv.mv_mode_pins() & 0xf) < 3 ? 64 : 32;
-static unsigned long bus_clk_recalc(struct clk *clk)
-{
- int idx = ((ctrl_inl(FRQMR1) >> 16) & 0x000f);
- return clk->parent->rate / bfc_divisors[idx];
+ return clk->parent->rate * multiplier;
}
-static struct clk_ops sh7786_bus_clk_ops = {
- .recalc = bus_clk_recalc,
+static struct clk_ops pll_clk_ops = {
+ .recalc = pll_recalc,
};
-static unsigned long cpu_clk_recalc(struct clk *clk)
-{
- int idx = ((ctrl_inl(FRQMR1) >> 28) & 0x0003);
- return clk->parent->rate / ifc_divisors[idx];
-}
-
-static struct clk_ops sh7786_cpu_clk_ops = {
- .recalc = cpu_clk_recalc,
+static struct clk pll_clk = {
+ .name = "pll_clk",
+ .id = -1,
+ .ops = &pll_clk_ops,
+ .parent = &extal_clk,
+ .flags = CLK_ENABLE_ON_INIT,
};
-static struct clk_ops *sh7786_clk_ops[] = {
- &sh7786_master_clk_ops,
- &sh7786_module_clk_ops,
- &sh7786_bus_clk_ops,
- &sh7786_cpu_clk_ops,
+static struct clk *clks[] = {
+ &extal_clk,
+ &pll_clk,
};
-void __init arch_init_clk_ops(struct clk_ops **ops, int idx)
-{
- if (idx < ARRAY_SIZE(sh7786_clk_ops))
- *ops = sh7786_clk_ops[idx];
-}
+static unsigned int div2[] = { 1, 2, 4, 6, 8, 12, 16, 18,
+ 24, 32, 36, 48 };
-static unsigned long shyway_clk_recalc(struct clk *clk)
-{
- int idx = ((ctrl_inl(FRQMR1) >> 20) & 0x0003);
- return clk->parent->rate / sfc_divisors[idx];
-}
-
-static struct clk_ops sh7786_shyway_clk_ops = {
- .recalc = shyway_clk_recalc,
+static struct clk_div_mult_table div4_div_mult_table = {
+ .divisors = div2,
+ .nr_divisors = ARRAY_SIZE(div2),
};
-static struct clk sh7786_shyway_clk = {
- .name = "shyway_clk",
- .flags = CLK_ENABLE_ON_INIT,
- .ops = &sh7786_shyway_clk_ops,
+static struct clk_div4_table div4_table = {
+ .div_mult_table = &div4_div_mult_table,
};
-static unsigned long ddr_clk_recalc(struct clk *clk)
-{
- int idx = ((ctrl_inl(FRQMR1) >> 12) & 0x0003);
- return clk->parent->rate / mfc_divisors[idx];
-}
+enum { DIV4_I, DIV4_SH, DIV4_B, DIV4_DDR, DIV4_DU, DIV4_P, DIV4_NR };
-static struct clk_ops sh7786_ddr_clk_ops = {
- .recalc = ddr_clk_recalc,
-};
+#define DIV4(_str, _bit, _mask, _flags) \
+ SH_CLK_DIV4(_str, &pll_clk, FRQMR1, _bit, _mask, _flags)
-static struct clk sh7786_ddr_clk = {
- .name = "ddr_clk",
- .flags = CLK_ENABLE_ON_INIT,
- .ops = &sh7786_ddr_clk_ops,
+struct clk div4_clks[DIV4_NR] = {
+ [DIV4_P] = DIV4("peripheral_clk", 0, 0x0b40, 0),
+ [DIV4_DU] = DIV4("du_clk", 4, 0x0010, 0),
+ [DIV4_DDR] = DIV4("ddr_clk", 12, 0x0002, CLK_ENABLE_ON_INIT),
+ [DIV4_B] = DIV4("bus_clk", 16, 0x0360, CLK_ENABLE_ON_INIT),
+ [DIV4_SH] = DIV4("shyway_clk", 20, 0x0002, CLK_ENABLE_ON_INIT),
+ [DIV4_I] = DIV4("cpu_clk", 28, 0x0006, CLK_ENABLE_ON_INIT),
};
-/*
- * Additional SH7786-specific on-chip clocks that aren't already part of the
- * clock framework
- */
-static struct clk *sh7786_onchip_clocks[] = {
- &sh7786_shyway_clk,
- &sh7786_ddr_clk,
+#define MSTPCR0 0xffc40030
+#define MSTPCR1 0xffc40034
+
+static struct clk mstp_clks[] = {
+ /* MSTPCR0 */
+ SH_CLK_MSTP32("scif_fck", 5, &div4_clks[DIV4_P], MSTPCR0, 29, 0),
+ SH_CLK_MSTP32("scif_fck", 4, &div4_clks[DIV4_P], MSTPCR0, 28, 0),
+ SH_CLK_MSTP32("scif_fck", 3, &div4_clks[DIV4_P], MSTPCR0, 27, 0),
+ SH_CLK_MSTP32("scif_fck", 2, &div4_clks[DIV4_P], MSTPCR0, 26, 0),
+ SH_CLK_MSTP32("scif_fck", 1, &div4_clks[DIV4_P], MSTPCR0, 25, 0),
+ SH_CLK_MSTP32("scif_fck", 0, &div4_clks[DIV4_P], MSTPCR0, 24, 0),
+ SH_CLK_MSTP32("ssi_fck", 3, &div4_clks[DIV4_P], MSTPCR0, 23, 0),
+ SH_CLK_MSTP32("ssi_fck", 2, &div4_clks[DIV4_P], MSTPCR0, 22, 0),
+ SH_CLK_MSTP32("ssi_fck", 1, &div4_clks[DIV4_P], MSTPCR0, 21, 0),
+ SH_CLK_MSTP32("ssi_fck", 0, &div4_clks[DIV4_P], MSTPCR0, 20, 0),
+ SH_CLK_MSTP32("hac_fck", 1, &div4_clks[DIV4_P], MSTPCR0, 17, 0),
+ SH_CLK_MSTP32("hac_fck", 0, &div4_clks[DIV4_P], MSTPCR0, 16, 0),
+ SH_CLK_MSTP32("i2c_fck", 1, &div4_clks[DIV4_P], MSTPCR0, 15, 0),
+ SH_CLK_MSTP32("i2c_fck", 0, &div4_clks[DIV4_P], MSTPCR0, 14, 0),
+ SH_CLK_MSTP32("tmu9_11_fck", -1, &div4_clks[DIV4_P], MSTPCR0, 11, 0),
+ SH_CLK_MSTP32("tmu678_fck", -1, &div4_clks[DIV4_P], MSTPCR0, 10, 0),
+ SH_CLK_MSTP32("tmu345_fck", -1, &div4_clks[DIV4_P], MSTPCR0, 9, 0),
+ SH_CLK_MSTP32("tmu012_fck", -1, &div4_clks[DIV4_P], MSTPCR0, 8, 0),
+ SH_CLK_MSTP32("sdif_fck", 1, &div4_clks[DIV4_P], MSTPCR0, 5, 0),
+ SH_CLK_MSTP32("sdif_fck", 0, &div4_clks[DIV4_P], MSTPCR0, 4, 0),
+ SH_CLK_MSTP32("hspi_fck", -1, &div4_clks[DIV4_P], MSTPCR0, 2, 0),
+
+ /* MSTPCR1 */
+ SH_CLK_MSTP32("usb_fck", -1, NULL, MSTPCR1, 12, 0),
+ SH_CLK_MSTP32("pcie_fck", 2, NULL, MSTPCR1, 10, 0),
+ SH_CLK_MSTP32("pcie_fck", 1, NULL, MSTPCR1, 9, 0),
+ SH_CLK_MSTP32("pcie_fck", 0, NULL, MSTPCR1, 8, 0),
+ SH_CLK_MSTP32("dmac_11_6_fck", -1, NULL, MSTPCR1, 5, 0),
+ SH_CLK_MSTP32("dmac_5_0_fck", -1, NULL, MSTPCR1, 4, 0),
+ SH_CLK_MSTP32("du_fck", -1, NULL, MSTPCR1, 3, 0),
+ SH_CLK_MSTP32("ether_fck", -1, NULL, MSTPCR1, 2, 0),
};
int __init arch_clk_init(void)
{
- struct clk *clk;
int i, ret = 0;
- cpg_clk_init();
-
- clk = clk_get(NULL, "master_clk");
- for (i = 0; i < ARRAY_SIZE(sh7786_onchip_clocks); i++) {
- struct clk *clkp = sh7786_onchip_clocks[i];
-
- clkp->parent = clk;
- ret |= clk_register(clkp);
- }
+ for (i = 0; i < ARRAY_SIZE(clks); i++)
+ ret |= clk_register(clks[i]);
- clk_put(clk);
+ if (!ret)
+ ret = sh_clk_div4_register(div4_clks, ARRAY_SIZE(div4_clks),
+ &div4_table);
+ if (!ret)
+ ret = sh_clk_mstp32_register(mstp_clks, ARRAY_SIZE(mstp_clks));
return ret;
}
diff --git a/arch/sh/kernel/cpu/sh4a/clock-shx3.c b/arch/sh/kernel/cpu/sh4a/clock-shx3.c
index 23c27d32d98..e75c57bdfa5 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-shx3.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-shx3.c
@@ -33,7 +33,7 @@ static int cfc_divisors[] = { 1, 1, 4, 6 };
static void master_clk_init(struct clk *clk)
{
- clk->rate *= pfc_divisors[(ctrl_inl(FRQCR) >> PFC_POS) & PFC_MSK];
+ clk->rate *= pfc_divisors[(__raw_readl(FRQCR) >> PFC_POS) & PFC_MSK];
}
static struct clk_ops shx3_master_clk_ops = {
@@ -42,7 +42,7 @@ static struct clk_ops shx3_master_clk_ops = {
static unsigned long module_clk_recalc(struct clk *clk)
{
- int idx = ((ctrl_inl(FRQCR) >> PFC_POS) & PFC_MSK);
+ int idx = ((__raw_readl(FRQCR) >> PFC_POS) & PFC_MSK);
return clk->parent->rate / pfc_divisors[idx];
}
@@ -52,7 +52,7 @@ static struct clk_ops shx3_module_clk_ops = {
static unsigned long bus_clk_recalc(struct clk *clk)
{
- int idx = ((ctrl_inl(FRQCR) >> BFC_POS) & BFC_MSK);
+ int idx = ((__raw_readl(FRQCR) >> BFC_POS) & BFC_MSK);
return clk->parent->rate / bfc_divisors[idx];
}
@@ -62,7 +62,7 @@ static struct clk_ops shx3_bus_clk_ops = {
static unsigned long cpu_clk_recalc(struct clk *clk)
{
- int idx = ((ctrl_inl(FRQCR) >> IFC_POS) & IFC_MSK);
+ int idx = ((__raw_readl(FRQCR) >> IFC_POS) & IFC_MSK);
return clk->parent->rate / ifc_divisors[idx];
}
@@ -85,7 +85,7 @@ void __init arch_init_clk_ops(struct clk_ops **ops, int idx)
static unsigned long shyway_clk_recalc(struct clk *clk)
{
- int idx = ((ctrl_inl(FRQCR) >> CFC_POS) & CFC_MSK);
+ int idx = ((__raw_readl(FRQCR) >> CFC_POS) & CFC_MSK);
return clk->parent->rate / cfc_divisors[idx];
}
diff --git a/arch/sh/kernel/cpu/sh4a/pinmux-sh7722.c b/arch/sh/kernel/cpu/sh4a/pinmux-sh7722.c
index cb9d07bd59f..0688a7502f8 100644
--- a/arch/sh/kernel/cpu/sh4a/pinmux-sh7722.c
+++ b/arch/sh/kernel/cpu/sh4a/pinmux-sh7722.c
@@ -278,6 +278,7 @@ enum {
HIZA8_LCDC, HIZA8_HIZ,
HIZA7_LCDC, HIZA7_HIZ,
HIZA6_LCDC, HIZA6_HIZ,
+ HIZB4_SIUA, HIZB4_HIZ,
HIZB1_VIO, HIZB1_HIZ,
HIZB0_VIO, HIZB0_HIZ,
HIZC15_IRQ7, HIZC15_HIZ,
@@ -546,7 +547,7 @@ static pinmux_enum_t pinmux_data[] = {
PINMUX_DATA(VIO_VD2_MARK, PSE3_VIO, MSELB9_VIO2,
HIZB0_VIO, FOE_VIO_VD2),
PINMUX_DATA(VIO_HD2_MARK, PSE3_VIO, MSELB9_VIO2,
- HIZB1_VIO, HIZB1_VIO, FCE_VIO_HD2),
+ HIZB1_VIO, FCE_VIO_HD2),
PINMUX_DATA(VIO_CLK2_MARK, PSE3_VIO, MSELB9_VIO2,
HIZB1_VIO, FRB_VIO_CLK2),
@@ -658,14 +659,14 @@ static pinmux_enum_t pinmux_data[] = {
PINMUX_DATA(SDHICLK_MARK, SDHICLK),
/* SIU - Port A */
- PINMUX_DATA(SIUAOLR_MARK, PSC13_SIUAOLR, SIUAOLR_SIOF1_SYNC),
- PINMUX_DATA(SIUAOBT_MARK, PSC14_SIUAOBT, SIUAOBT_SIOF1_SCK),
- PINMUX_DATA(SIUAISLD_MARK, PSC15_SIUAISLD, SIUAISLD_SIOF1_RXD),
- PINMUX_DATA(SIUAILR_MARK, PSC11_SIUAILR, SIUAILR_SIOF1_SS2),
- PINMUX_DATA(SIUAIBT_MARK, PSC12_SIUAIBT, SIUAIBT_SIOF1_SS1),
- PINMUX_DATA(SIUAOSLD_MARK, PSB0_SIUAOSLD, SIUAOSLD_SIOF1_TXD),
- PINMUX_DATA(SIUMCKA_MARK, PSE11_SIUMCKA_SIOF1_MCK, PSB1_SIUMCKA, PTK0),
- PINMUX_DATA(SIUFCKA_MARK, PSE11_SIUFCKA, PTK0),
+ PINMUX_DATA(SIUAOLR_MARK, PSC13_SIUAOLR, HIZB4_SIUA, SIUAOLR_SIOF1_SYNC),
+ PINMUX_DATA(SIUAOBT_MARK, PSC14_SIUAOBT, HIZB4_SIUA, SIUAOBT_SIOF1_SCK),
+ PINMUX_DATA(SIUAISLD_MARK, PSC15_SIUAISLD, HIZB4_SIUA, SIUAISLD_SIOF1_RXD),
+ PINMUX_DATA(SIUAILR_MARK, PSC11_SIUAILR, HIZB4_SIUA, SIUAILR_SIOF1_SS2),
+ PINMUX_DATA(SIUAIBT_MARK, PSC12_SIUAIBT, HIZB4_SIUA, SIUAIBT_SIOF1_SS1),
+ PINMUX_DATA(SIUAOSLD_MARK, PSB0_SIUAOSLD, HIZB4_SIUA, SIUAOSLD_SIOF1_TXD),
+ PINMUX_DATA(SIUMCKA_MARK, PSE11_SIUMCKA_SIOF1_MCK, HIZB4_SIUA, PSB1_SIUMCKA, PTK0),
+ PINMUX_DATA(SIUFCKA_MARK, PSE11_SIUFCKA, HIZB4_SIUA, PTK0),
/* SIU - Port B */
PINMUX_DATA(SIUBOLR_MARK, PSB11_SIUBOLR, SIOSTRB1_SIUBOLR),
@@ -1612,7 +1613,7 @@ static struct pinmux_cfg_reg pinmux_config_regs[] = {
0, 0,
0, 0,
0, 0,
- 0, 0,
+ HIZB4_SIUA, HIZB4_HIZ,
0, 0,
0, 0,
HIZB1_VIO, HIZB1_HIZ,
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
index b5335b5e309..ef3f9782780 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
@@ -446,6 +446,8 @@ void __init plat_early_device_setup(void)
enum {
UNUSED=0,
+ ENABLED,
+ DISABLED,
/* interrupt sources */
IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7,
@@ -461,7 +463,6 @@ enum {
SCIF0, SCIF1, SCIF2, SIOF0, SIOF1, SIO,
FLCTL_FLSTEI, FLCTL_FLENDI, FLCTL_FLTREQ0I, FLCTL_FLTREQ1I,
I2C_ALI, I2C_TACKI, I2C_WAITI, I2C_DTEI,
- SDHI0, SDHI1, SDHI2, SDHI3,
CMT, TSIF, SIU, TWODG,
TMU0, TMU1, TMU2,
IRDA, JPU, LCDC,
@@ -494,8 +495,8 @@ static struct intc_vect vectors[] __initdata = {
INTC_VECT(FLCTL_FLTREQ0I, 0xdc0), INTC_VECT(FLCTL_FLTREQ1I, 0xde0),
INTC_VECT(I2C_ALI, 0xe00), INTC_VECT(I2C_TACKI, 0xe20),
INTC_VECT(I2C_WAITI, 0xe40), INTC_VECT(I2C_DTEI, 0xe60),
- INTC_VECT(SDHI0, 0xe80), INTC_VECT(SDHI1, 0xea0),
- INTC_VECT(SDHI2, 0xec0), INTC_VECT(SDHI3, 0xee0),
+ INTC_VECT(SDHI, 0xe80), INTC_VECT(SDHI, 0xea0),
+ INTC_VECT(SDHI, 0xec0), INTC_VECT(SDHI, 0xee0),
INTC_VECT(CMT, 0xf00), INTC_VECT(TSIF, 0xf20),
INTC_VECT(SIU, 0xf80), INTC_VECT(TWODG, 0xfa0),
INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420),
@@ -513,7 +514,6 @@ static struct intc_group groups[] __initdata = {
INTC_GROUP(FLCTL, FLCTL_FLSTEI, FLCTL_FLENDI,
FLCTL_FLTREQ0I, FLCTL_FLTREQ1I),
INTC_GROUP(I2C, I2C_ALI, I2C_TACKI, I2C_WAITI, I2C_DTEI),
- INTC_GROUP(SDHI, SDHI0, SDHI1, SDHI2, SDHI3),
};
static struct intc_mask_reg mask_registers[] __initdata = {
@@ -535,7 +535,7 @@ static struct intc_mask_reg mask_registers[] __initdata = {
{ I2C_DTEI, I2C_WAITI, I2C_TACKI, I2C_ALI,
FLCTL_FLTREQ1I, FLCTL_FLTREQ0I, FLCTL_FLENDI, FLCTL_FLSTEI } },
{ 0xa40800a0, 0xa40800e0, 8, /* IMR8 / IMCR8 */
- { SDHI3, SDHI2, SDHI1, SDHI0, 0, 0, TWODG, SIU } },
+ { DISABLED, DISABLED, ENABLED, ENABLED, 0, 0, TWODG, SIU } },
{ 0xa40800a4, 0xa40800e4, 8, /* IMR9 / IMCR9 */
{ 0, 0, 0, CMT, 0, USB_USBI1, USB_USBI0, } },
{ 0xa40800a8, 0xa40800e8, 8, /* IMR10 / IMCR10 */
@@ -573,9 +573,13 @@ static struct intc_mask_reg ack_registers[] __initdata = {
{ IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
};
-static DECLARE_INTC_DESC_ACK(intc_desc, "sh7722", vectors, groups,
- mask_registers, prio_registers, sense_registers,
- ack_registers);
+static struct intc_desc intc_desc __initdata = {
+ .name = "sh7722",
+ .force_enable = ENABLED,
+ .force_disable = DISABLED,
+ .hw = INTC_HW_DESC(vectors, groups, mask_registers,
+ prio_registers, sense_registers, ack_registers),
+};
void __init plat_irq_setup(void)
{
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c
index 772b9265d0e..85c61f62470 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c
@@ -592,14 +592,17 @@ void __init plat_early_device_setup(void)
#define RAMCR_CACHE_L2FC 0x0002
#define RAMCR_CACHE_L2E 0x0001
#define L2_CACHE_ENABLE (RAMCR_CACHE_L2E|RAMCR_CACHE_L2FC)
-void __uses_jump_to_uncached l2_cache_init(void)
+
+void l2_cache_init(void)
{
/* Enable L2 cache */
- ctrl_outl(L2_CACHE_ENABLE, RAMCR);
+ __raw_writel(L2_CACHE_ENABLE, RAMCR);
}
enum {
UNUSED=0,
+ ENABLED,
+ DISABLED,
/* interrupt sources */
IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7,
@@ -622,7 +625,6 @@ enum {
SCIFA_SCIFA1,
FLCTL_FLSTEI,FLCTL_FLTENDI,FLCTL_FLTREQ0I,FLCTL_FLTREQ1I,
I2C_ALI,I2C_TACKI,I2C_WAITI,I2C_DTEI,
- SDHI0_SDHII0,SDHI0_SDHII1,SDHI0_SDHII2,
CMT_CMTI,
TSIF_TSIFI,
SIU_SIUI,
@@ -630,7 +632,6 @@ enum {
TMU0_TUNI0, TMU0_TUNI1, TMU0_TUNI2,
IRDA_IRDAI,
ATAPI_ATAPII,
- SDHI1_SDHII0,SDHI1_SDHII1,SDHI1_SDHII2,
VEU2H1_VEU2HI,
LCDC_LCDCI,
TMU1_TUNI0,TMU1_TUNI1,TMU1_TUNI2,
@@ -701,9 +702,9 @@ static struct intc_vect vectors[] __initdata = {
INTC_VECT(I2C_WAITI,0xE40),
INTC_VECT(I2C_DTEI,0xE60),
- INTC_VECT(SDHI0_SDHII0,0xE80),
- INTC_VECT(SDHI0_SDHII1,0xEA0),
- INTC_VECT(SDHI0_SDHII2,0xEC0),
+ INTC_VECT(SDHI0, 0xE80),
+ INTC_VECT(SDHI0, 0xEA0),
+ INTC_VECT(SDHI0, 0xEC0),
INTC_VECT(CMT_CMTI,0xF00),
INTC_VECT(TSIF_TSIFI,0xF20),
@@ -717,9 +718,9 @@ static struct intc_vect vectors[] __initdata = {
INTC_VECT(IRDA_IRDAI,0x480),
INTC_VECT(ATAPI_ATAPII,0x4A0),
- INTC_VECT(SDHI1_SDHII0,0x4E0),
- INTC_VECT(SDHI1_SDHII1,0x500),
- INTC_VECT(SDHI1_SDHII2,0x520),
+ INTC_VECT(SDHI1, 0x4E0),
+ INTC_VECT(SDHI1, 0x500),
+ INTC_VECT(SDHI1, 0x520),
INTC_VECT(VEU2H1_VEU2HI,0x560),
INTC_VECT(LCDC_LCDCI,0x580),
@@ -738,15 +739,14 @@ static struct intc_group groups[] __initdata = {
INTC_GROUP(FLCTL,FLCTL_FLSTEI,FLCTL_FLTENDI,FLCTL_FLTREQ0I,FLCTL_FLTREQ1I),
INTC_GROUP(I2C,I2C_ALI,I2C_TACKI,I2C_WAITI,I2C_DTEI),
INTC_GROUP(_2DG, _2DG_TRI,_2DG_INI,_2DG_CEI),
- INTC_GROUP(SDHI1, SDHI1_SDHII0,SDHI1_SDHII1,SDHI1_SDHII2),
INTC_GROUP(RTC, RTC_ATI,RTC_PRI,RTC_CUI),
INTC_GROUP(DMAC1B, DMAC1B_DEI4,DMAC1B_DEI5,DMAC1B_DADERR),
- INTC_GROUP(SDHI0,SDHI0_SDHII0,SDHI0_SDHII1,SDHI0_SDHII2),
};
static struct intc_mask_reg mask_registers[] __initdata = {
{ 0xa4080080, 0xa40800c0, 8, /* IMR0 / IMCR0 */
- { 0, TMU1_TUNI2,TMU1_TUNI1,TMU1_TUNI0,0,SDHI1_SDHII2,SDHI1_SDHII1,SDHI1_SDHII0} },
+ { 0, TMU1_TUNI2, TMU1_TUNI1, TMU1_TUNI0,
+ 0, DISABLED, ENABLED, ENABLED } },
{ 0xa4080084, 0xa40800c4, 8, /* IMR1 / IMCR1 */
{ VIO_VOUI, VIO_VEU2HI,VIO_BEUI,VIO_CEUI,DMAC0A_DEI3,DMAC0A_DEI2,DMAC0A_DEI1,DMAC0A_DEI0 } },
{ 0xa4080088, 0xa40800c8, 8, /* IMR2 / IMCR2 */
@@ -763,7 +763,8 @@ static struct intc_mask_reg mask_registers[] __initdata = {
{ I2C_DTEI, I2C_WAITI, I2C_TACKI, I2C_ALI,
FLCTL_FLTREQ1I, FLCTL_FLTREQ0I, FLCTL_FLTENDI, FLCTL_FLSTEI } },
{ 0xa40800a0, 0xa40800e0, 8, /* IMR8 / IMCR8 */
- { 0,SDHI0_SDHII2,SDHI0_SDHII1,SDHI0_SDHII0,0,0,SCIFA_SCIFA2,SIU_SIUI } },
+ { 0, DISABLED, ENABLED, ENABLED,
+ 0, 0, SCIFA_SCIFA2, SIU_SIUI } },
{ 0xa40800a4, 0xa40800e4, 8, /* IMR9 / IMCR9 */
{ 0, 0, 0, CMT_CMTI, 0, 0, USB_USI0,0 } },
{ 0xa40800a8, 0xa40800e8, 8, /* IMR10 / IMCR10 */
@@ -803,9 +804,13 @@ static struct intc_mask_reg ack_registers[] __initdata = {
{ IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
};
-static DECLARE_INTC_DESC_ACK(intc_desc, "sh7723", vectors, groups,
- mask_registers, prio_registers, sense_registers,
- ack_registers);
+static struct intc_desc intc_desc __initdata = {
+ .name = "sh7723",
+ .force_enable = ENABLED,
+ .force_disable = DISABLED,
+ .hw = INTC_HW_DESC(vectors, groups, mask_registers,
+ prio_registers, sense_registers, ack_registers),
+};
void __init plat_irq_setup(void)
{
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c
index d32f96c1cc1..31e3451f7e3 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c
@@ -714,14 +714,17 @@ void __init plat_early_device_setup(void)
#define RAMCR_CACHE_L2FC 0x0002
#define RAMCR_CACHE_L2E 0x0001
#define L2_CACHE_ENABLE (RAMCR_CACHE_L2E|RAMCR_CACHE_L2FC)
-void __uses_jump_to_uncached l2_cache_init(void)
+
+void l2_cache_init(void)
{
/* Enable L2 cache */
- ctrl_outl(L2_CACHE_ENABLE, RAMCR);
+ __raw_writel(L2_CACHE_ENABLE, RAMCR);
}
enum {
UNUSED = 0,
+ ENABLED,
+ DISABLED,
/* interrupt sources */
IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7,
@@ -750,14 +753,12 @@ enum {
ETHI,
I2C1_ALI, I2C1_TACKI, I2C1_WAITI, I2C1_DTEI,
I2C0_ALI, I2C0_TACKI, I2C0_WAITI, I2C0_DTEI,
- SDHI0_SDHII0, SDHI0_SDHII1, SDHI0_SDHII2, SDHI0_SDHII3,
CMT,
TSIF,
FSI,
SCIFA5,
TMU0_TUNI0, TMU0_TUNI1, TMU0_TUNI2,
IRDA,
- SDHI1_SDHII0, SDHI1_SDHII1, SDHI1_SDHII2,
JPU,
_2DDMAC,
MMC_MMC2I, MMC_MMC3I,
@@ -839,10 +840,10 @@ static struct intc_vect vectors[] __initdata = {
INTC_VECT(I2C0_WAITI, 0xE40),
INTC_VECT(I2C0_DTEI, 0xE60),
- INTC_VECT(SDHI0_SDHII0, 0xE80),
- INTC_VECT(SDHI0_SDHII1, 0xEA0),
- INTC_VECT(SDHI0_SDHII2, 0xEC0),
- INTC_VECT(SDHI0_SDHII3, 0xEE0),
+ INTC_VECT(SDHI0, 0xE80),
+ INTC_VECT(SDHI0, 0xEA0),
+ INTC_VECT(SDHI0, 0xEC0),
+ INTC_VECT(SDHI0, 0xEE0),
INTC_VECT(CMT, 0xF00),
INTC_VECT(TSIF, 0xF20),
@@ -855,9 +856,9 @@ static struct intc_vect vectors[] __initdata = {
INTC_VECT(IRDA, 0x480),
- INTC_VECT(SDHI1_SDHII0, 0x4E0),
- INTC_VECT(SDHI1_SDHII1, 0x500),
- INTC_VECT(SDHI1_SDHII2, 0x520),
+ INTC_VECT(SDHI1, 0x4E0),
+ INTC_VECT(SDHI1, 0x500),
+ INTC_VECT(SDHI1, 0x520),
INTC_VECT(JPU, 0x560),
INTC_VECT(_2DDMAC, 0x4A0),
@@ -883,8 +884,6 @@ static struct intc_group groups[] __initdata = {
INTC_GROUP(DMAC0B, DMAC0B_DEI4, DMAC0B_DEI5, DMAC0B_DADERR),
INTC_GROUP(I2C0, I2C0_ALI, I2C0_TACKI, I2C0_WAITI, I2C0_DTEI),
INTC_GROUP(I2C1, I2C1_ALI, I2C1_TACKI, I2C1_WAITI, I2C1_DTEI),
- INTC_GROUP(SDHI0, SDHI0_SDHII0, SDHI0_SDHII1, SDHI0_SDHII2, SDHI0_SDHII3),
- INTC_GROUP(SDHI1, SDHI1_SDHII0, SDHI1_SDHII1, SDHI1_SDHII2),
INTC_GROUP(SPU, SPU_SPUI0, SPU_SPUI1),
INTC_GROUP(MMCIF, MMC_MMC2I, MMC_MMC3I),
};
@@ -892,7 +891,7 @@ static struct intc_group groups[] __initdata = {
static struct intc_mask_reg mask_registers[] __initdata = {
{ 0xa4080080, 0xa40800c0, 8, /* IMR0 / IMCR0 */
{ 0, TMU1_TUNI2, TMU1_TUNI1, TMU1_TUNI0,
- 0, SDHI1_SDHII2, SDHI1_SDHII1, SDHI1_SDHII0 } },
+ 0, DISABLED, ENABLED, ENABLED } },
{ 0xa4080084, 0xa40800c4, 8, /* IMR1 / IMCR1 */
{ VIO_VOU, VIO_VEU1, VIO_BEU0, VIO_CEU0,
DMAC0A_DEI3, DMAC0A_DEI2, DMAC0A_DEI1, DMAC0A_DEI0 } },
@@ -914,7 +913,7 @@ static struct intc_mask_reg mask_registers[] __initdata = {
{ I2C0_DTEI, I2C0_WAITI, I2C0_TACKI, I2C0_ALI,
I2C1_DTEI, I2C1_WAITI, I2C1_TACKI, I2C1_ALI } },
{ 0xa40800a0, 0xa40800e0, 8, /* IMR8 / IMCR8 */
- { SDHI0_SDHII3, SDHI0_SDHII2, SDHI0_SDHII1, SDHI0_SDHII0,
+ { DISABLED, DISABLED, ENABLED, ENABLED,
0, 0, SCIFA5, FSI } },
{ 0xa40800a4, 0xa40800e4, 8, /* IMR9 / IMCR9 */
{ 0, 0, 0, CMT, 0, USB1, USB0, 0 } },
@@ -961,9 +960,13 @@ static struct intc_mask_reg ack_registers[] __initdata = {
{ IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
};
-static DECLARE_INTC_DESC_ACK(intc_desc, "sh7724", vectors, groups,
- mask_registers, prio_registers, sense_registers,
- ack_registers);
+static struct intc_desc intc_desc __initdata = {
+ .name = "sh7724",
+ .force_enable = ENABLED,
+ .force_disable = DISABLED,
+ .hw = INTC_HW_DESC(vectors, groups, mask_registers,
+ prio_registers, sense_registers, ack_registers),
+};
void __init plat_irq_setup(void)
{
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7757.c b/arch/sh/kernel/cpu/sh4a/setup-sh7757.c
index 37e32efbbaa..e75edf58796 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7757.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7757.c
@@ -487,17 +487,17 @@ static DECLARE_INTC_DESC(intc_desc_irl4567, "sh7757-irl4567", vectors_irl4567,
void __init plat_irq_setup(void)
{
/* disable IRQ3-0 + IRQ7-4 */
- ctrl_outl(0xff000000, INTC_INTMSK0);
+ __raw_writel(0xff000000, INTC_INTMSK0);
/* disable IRL3-0 + IRL7-4 */
- ctrl_outl(0xc0000000, INTC_INTMSK1);
- ctrl_outl(0xfffefffe, INTC_INTMSK2);
+ __raw_writel(0xc0000000, INTC_INTMSK1);
+ __raw_writel(0xfffefffe, INTC_INTMSK2);
/* select IRL mode for IRL3-0 + IRL7-4 */
- ctrl_outl(ctrl_inl(INTC_ICR0) & ~0x00c00000, INTC_ICR0);
+ __raw_writel(__raw_readl(INTC_ICR0) & ~0x00c00000, INTC_ICR0);
/* disable holding function, ie enable "SH-4 Mode" */
- ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00200000, INTC_ICR0);
+ __raw_writel(__raw_readl(INTC_ICR0) | 0x00200000, INTC_ICR0);
register_intc_controller(&intc_desc);
}
@@ -507,32 +507,32 @@ void __init plat_irq_setup_pins(int mode)
switch (mode) {
case IRQ_MODE_IRQ7654:
/* select IRQ mode for IRL7-4 */
- ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00400000, INTC_ICR0);
+ __raw_writel(__raw_readl(INTC_ICR0) | 0x00400000, INTC_ICR0);
register_intc_controller(&intc_desc_irq4567);
break;
case IRQ_MODE_IRQ3210:
/* select IRQ mode for IRL3-0 */
- ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00800000, INTC_ICR0);
+ __raw_writel(__raw_readl(INTC_ICR0) | 0x00800000, INTC_ICR0);
register_intc_controller(&intc_desc_irq0123);
break;
case IRQ_MODE_IRL7654:
/* enable IRL7-4 but don't provide any masking */
- ctrl_outl(0x40000000, INTC_INTMSKCLR1);
- ctrl_outl(0x0000fffe, INTC_INTMSKCLR2);
+ __raw_writel(0x40000000, INTC_INTMSKCLR1);
+ __raw_writel(0x0000fffe, INTC_INTMSKCLR2);
break;
case IRQ_MODE_IRL3210:
/* enable IRL0-3 but don't provide any masking */
- ctrl_outl(0x80000000, INTC_INTMSKCLR1);
- ctrl_outl(0xfffe0000, INTC_INTMSKCLR2);
+ __raw_writel(0x80000000, INTC_INTMSKCLR1);
+ __raw_writel(0xfffe0000, INTC_INTMSKCLR2);
break;
case IRQ_MODE_IRL7654_MASK:
/* enable IRL7-4 and mask using cpu intc controller */
- ctrl_outl(0x40000000, INTC_INTMSKCLR1);
+ __raw_writel(0x40000000, INTC_INTMSKCLR1);
register_intc_controller(&intc_desc_irl4567);
break;
case IRQ_MODE_IRL3210_MASK:
/* enable IRL0-3 and mask using cpu intc controller */
- ctrl_outl(0x80000000, INTC_INTMSKCLR1);
+ __raw_writel(0x80000000, INTC_INTMSKCLR1);
register_intc_controller(&intc_desc_irl0123);
break;
default:
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7763.c b/arch/sh/kernel/cpu/sh4a/setup-sh7763.c
index 6aba26fec41..7f6b0a5f7f8 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7763.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7763.c
@@ -538,11 +538,11 @@ static DECLARE_INTC_DESC(intc_irl3210_desc, "sh7763-irl3210", irl_vectors,
void __init plat_irq_setup(void)
{
/* disable IRQ7-0 */
- ctrl_outl(0xff000000, INTC_INTMSK0);
+ __raw_writel(0xff000000, INTC_INTMSK0);
/* disable IRL3-0 + IRL7-4 */
- ctrl_outl(0xc0000000, INTC_INTMSK1);
- ctrl_outl(0xfffefffe, INTC_INTMSK2);
+ __raw_writel(0xc0000000, INTC_INTMSK1);
+ __raw_writel(0xfffefffe, INTC_INTMSK2);
register_intc_controller(&intc_desc);
}
@@ -552,27 +552,27 @@ void __init plat_irq_setup_pins(int mode)
switch (mode) {
case IRQ_MODE_IRQ:
/* select IRQ mode for IRL3-0 + IRL7-4 */
- ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00c00000, INTC_ICR0);
+ __raw_writel(__raw_readl(INTC_ICR0) | 0x00c00000, INTC_ICR0);
register_intc_controller(&intc_irq_desc);
break;
case IRQ_MODE_IRL7654:
/* enable IRL7-4 but don't provide any masking */
- ctrl_outl(0x40000000, INTC_INTMSKCLR1);
- ctrl_outl(0x0000fffe, INTC_INTMSKCLR2);
+ __raw_writel(0x40000000, INTC_INTMSKCLR1);
+ __raw_writel(0x0000fffe, INTC_INTMSKCLR2);
break;
case IRQ_MODE_IRL3210:
/* enable IRL0-3 but don't provide any masking */
- ctrl_outl(0x80000000, INTC_INTMSKCLR1);
- ctrl_outl(0xfffe0000, INTC_INTMSKCLR2);
+ __raw_writel(0x80000000, INTC_INTMSKCLR1);
+ __raw_writel(0xfffe0000, INTC_INTMSKCLR2);
break;
case IRQ_MODE_IRL7654_MASK:
/* enable IRL7-4 and mask using cpu intc controller */
- ctrl_outl(0x40000000, INTC_INTMSKCLR1);
+ __raw_writel(0x40000000, INTC_INTMSKCLR1);
register_intc_controller(&intc_irl7654_desc);
break;
case IRQ_MODE_IRL3210_MASK:
/* enable IRL0-3 and mask using cpu intc controller */
- ctrl_outl(0x80000000, INTC_INTMSKCLR1);
+ __raw_writel(0x80000000, INTC_INTMSKCLR1);
register_intc_controller(&intc_irl3210_desc);
break;
default:
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7770.c b/arch/sh/kernel/cpu/sh4a/setup-sh7770.c
index c1643bc9590..86d681ecf90 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7770.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7770.c
@@ -694,17 +694,17 @@ static DECLARE_INTC_DESC(intc_irl3210_desc, "sh7780-irl3210", irl_vectors,
void __init plat_irq_setup(void)
{
/* disable IRQ7-0 */
- ctrl_outl(0xff000000, INTC_INTMSK0);
+ __raw_writel(0xff000000, INTC_INTMSK0);
/* disable IRL3-0 + IRL7-4 */
- ctrl_outl(0xc0000000, INTC_INTMSK1);
- ctrl_outl(0xfffefffe, INTC_INTMSK2);
+ __raw_writel(0xc0000000, INTC_INTMSK1);
+ __raw_writel(0xfffefffe, INTC_INTMSK2);
/* select IRL mode for IRL3-0 + IRL7-4 */
- ctrl_outl(ctrl_inl(INTC_ICR0) & ~0x00c00000, INTC_ICR0);
+ __raw_writel(__raw_readl(INTC_ICR0) & ~0x00c00000, INTC_ICR0);
/* disable holding function, ie enable "SH-4 Mode" */
- ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00200000, INTC_ICR0);
+ __raw_writel(__raw_readl(INTC_ICR0) | 0x00200000, INTC_ICR0);
register_intc_controller(&intc_desc);
}
@@ -714,27 +714,27 @@ void __init plat_irq_setup_pins(int mode)
switch (mode) {
case IRQ_MODE_IRQ:
/* select IRQ mode for IRL3-0 + IRL7-4 */
- ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00c00000, INTC_ICR0);
+ __raw_writel(__raw_readl(INTC_ICR0) | 0x00c00000, INTC_ICR0);
register_intc_controller(&intc_irq_desc);
break;
case IRQ_MODE_IRL7654:
/* enable IRL7-4 but don't provide any masking */
- ctrl_outl(0x40000000, INTC_INTMSKCLR1);
- ctrl_outl(0x0000fffe, INTC_INTMSKCLR2);
+ __raw_writel(0x40000000, INTC_INTMSKCLR1);
+ __raw_writel(0x0000fffe, INTC_INTMSKCLR2);
break;
case IRQ_MODE_IRL3210:
/* enable IRL0-3 but don't provide any masking */
- ctrl_outl(0x80000000, INTC_INTMSKCLR1);
- ctrl_outl(0xfffe0000, INTC_INTMSKCLR2);
+ __raw_writel(0x80000000, INTC_INTMSKCLR1);
+ __raw_writel(0xfffe0000, INTC_INTMSKCLR2);
break;
case IRQ_MODE_IRL7654_MASK:
/* enable IRL7-4 and mask using cpu intc controller */
- ctrl_outl(0x40000000, INTC_INTMSKCLR1);
+ __raw_writel(0x40000000, INTC_INTMSKCLR1);
register_intc_controller(&intc_irl7654_desc);
break;
case IRQ_MODE_IRL3210_MASK:
/* enable IRL0-3 and mask using cpu intc controller */
- ctrl_outl(0x80000000, INTC_INTMSKCLR1);
+ __raw_writel(0x80000000, INTC_INTMSKCLR1);
register_intc_controller(&intc_irl3210_desc);
break;
default:
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c
index c310558490d..f8f21618d78 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c
@@ -461,17 +461,17 @@ static DECLARE_INTC_DESC(intc_irl3210_desc, "sh7780-irl3210", irl_vectors,
void __init plat_irq_setup(void)
{
/* disable IRQ7-0 */
- ctrl_outl(0xff000000, INTC_INTMSK0);
+ __raw_writel(0xff000000, INTC_INTMSK0);
/* disable IRL3-0 + IRL7-4 */
- ctrl_outl(0xc0000000, INTC_INTMSK1);
- ctrl_outl(0xfffefffe, INTC_INTMSK2);
+ __raw_writel(0xc0000000, INTC_INTMSK1);
+ __raw_writel(0xfffefffe, INTC_INTMSK2);
/* select IRL mode for IRL3-0 + IRL7-4 */
- ctrl_outl(ctrl_inl(INTC_ICR0) & ~0x00c00000, INTC_ICR0);
+ __raw_writel(__raw_readl(INTC_ICR0) & ~0x00c00000, INTC_ICR0);
/* disable holding function, ie enable "SH-4 Mode" */
- ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00200000, INTC_ICR0);
+ __raw_writel(__raw_readl(INTC_ICR0) | 0x00200000, INTC_ICR0);
register_intc_controller(&intc_desc);
}
@@ -481,27 +481,27 @@ void __init plat_irq_setup_pins(int mode)
switch (mode) {
case IRQ_MODE_IRQ:
/* select IRQ mode for IRL3-0 + IRL7-4 */
- ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00c00000, INTC_ICR0);
+ __raw_writel(__raw_readl(INTC_ICR0) | 0x00c00000, INTC_ICR0);
register_intc_controller(&intc_irq_desc);
break;
case IRQ_MODE_IRL7654:
/* enable IRL7-4 but don't provide any masking */
- ctrl_outl(0x40000000, INTC_INTMSKCLR1);
- ctrl_outl(0x0000fffe, INTC_INTMSKCLR2);
+ __raw_writel(0x40000000, INTC_INTMSKCLR1);
+ __raw_writel(0x0000fffe, INTC_INTMSKCLR2);
break;
case IRQ_MODE_IRL3210:
/* enable IRL0-3 but don't provide any masking */
- ctrl_outl(0x80000000, INTC_INTMSKCLR1);
- ctrl_outl(0xfffe0000, INTC_INTMSKCLR2);
+ __raw_writel(0x80000000, INTC_INTMSKCLR1);
+ __raw_writel(0xfffe0000, INTC_INTMSKCLR2);
break;
case IRQ_MODE_IRL7654_MASK:
/* enable IRL7-4 and mask using cpu intc controller */
- ctrl_outl(0x40000000, INTC_INTMSKCLR1);
+ __raw_writel(0x40000000, INTC_INTMSKCLR1);
register_intc_controller(&intc_irl7654_desc);
break;
case IRQ_MODE_IRL3210_MASK:
/* enable IRL0-3 and mask using cpu intc controller */
- ctrl_outl(0x80000000, INTC_INTMSKCLR1);
+ __raw_writel(0x80000000, INTC_INTMSKCLR1);
register_intc_controller(&intc_irl3210_desc);
break;
default:
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c
index f685b9b2199..23448d8c671 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c
@@ -541,17 +541,17 @@ static DECLARE_INTC_DESC(intc_desc_irl4567, "sh7785-irl4567", vectors_irl4567,
void __init plat_irq_setup(void)
{
/* disable IRQ3-0 + IRQ7-4 */
- ctrl_outl(0xff000000, INTC_INTMSK0);
+ __raw_writel(0xff000000, INTC_INTMSK0);
/* disable IRL3-0 + IRL7-4 */
- ctrl_outl(0xc0000000, INTC_INTMSK1);
- ctrl_outl(0xfffefffe, INTC_INTMSK2);
+ __raw_writel(0xc0000000, INTC_INTMSK1);
+ __raw_writel(0xfffefffe, INTC_INTMSK2);
/* select IRL mode for IRL3-0 + IRL7-4 */
- ctrl_outl(ctrl_inl(INTC_ICR0) & ~0x00c00000, INTC_ICR0);
+ __raw_writel(__raw_readl(INTC_ICR0) & ~0x00c00000, INTC_ICR0);
/* disable holding function, ie enable "SH-4 Mode" */
- ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00200000, INTC_ICR0);
+ __raw_writel(__raw_readl(INTC_ICR0) | 0x00200000, INTC_ICR0);
register_intc_controller(&intc_desc);
}
@@ -561,32 +561,32 @@ void __init plat_irq_setup_pins(int mode)
switch (mode) {
case IRQ_MODE_IRQ7654:
/* select IRQ mode for IRL7-4 */
- ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00400000, INTC_ICR0);
+ __raw_writel(__raw_readl(INTC_ICR0) | 0x00400000, INTC_ICR0);
register_intc_controller(&intc_desc_irq4567);
break;
case IRQ_MODE_IRQ3210:
/* select IRQ mode for IRL3-0 */
- ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00800000, INTC_ICR0);
+ __raw_writel(__raw_readl(INTC_ICR0) | 0x00800000, INTC_ICR0);
register_intc_controller(&intc_desc_irq0123);
break;
case IRQ_MODE_IRL7654:
/* enable IRL7-4 but don't provide any masking */
- ctrl_outl(0x40000000, INTC_INTMSKCLR1);
- ctrl_outl(0x0000fffe, INTC_INTMSKCLR2);
+ __raw_writel(0x40000000, INTC_INTMSKCLR1);
+ __raw_writel(0x0000fffe, INTC_INTMSKCLR2);
break;
case IRQ_MODE_IRL3210:
/* enable IRL0-3 but don't provide any masking */
- ctrl_outl(0x80000000, INTC_INTMSKCLR1);
- ctrl_outl(0xfffe0000, INTC_INTMSKCLR2);
+ __raw_writel(0x80000000, INTC_INTMSKCLR1);
+ __raw_writel(0xfffe0000, INTC_INTMSKCLR2);
break;
case IRQ_MODE_IRL7654_MASK:
/* enable IRL7-4 and mask using cpu intc controller */
- ctrl_outl(0x40000000, INTC_INTMSKCLR1);
+ __raw_writel(0x40000000, INTC_INTMSKCLR1);
register_intc_controller(&intc_desc_irl4567);
break;
case IRQ_MODE_IRL3210_MASK:
/* enable IRL0-3 and mask using cpu intc controller */
- ctrl_outl(0x80000000, INTC_INTMSKCLR1);
+ __raw_writel(0x80000000, INTC_INTMSKCLR1);
register_intc_controller(&intc_desc_irl0123);
break;
default:
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7786.c b/arch/sh/kernel/cpu/sh4a/setup-sh7786.c
index 71673487ace..7e585320710 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7786.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7786.c
@@ -867,14 +867,14 @@ static DECLARE_INTC_DESC(intc_desc_irl4567, "sh7786-irl4567", vectors_irl4567,
void __init plat_irq_setup(void)
{
/* disable IRQ3-0 + IRQ7-4 */
- ctrl_outl(0xff000000, INTC_INTMSK0);
+ __raw_writel(0xff000000, INTC_INTMSK0);
/* disable IRL3-0 + IRL7-4 */
- ctrl_outl(0xc0000000, INTC_INTMSK1);
- ctrl_outl(0xfffefffe, INTC_INTMSK2);
+ __raw_writel(0xc0000000, INTC_INTMSK1);
+ __raw_writel(0xfffefffe, INTC_INTMSK2);
/* select IRL mode for IRL3-0 + IRL7-4 */
- ctrl_outl(ctrl_inl(INTC_ICR0) & ~0x00c00000, INTC_ICR0);
+ __raw_writel(__raw_readl(INTC_ICR0) & ~0x00c00000, INTC_ICR0);
register_intc_controller(&intc_desc);
}
@@ -884,32 +884,32 @@ void __init plat_irq_setup_pins(int mode)
switch (mode) {
case IRQ_MODE_IRQ7654:
/* select IRQ mode for IRL7-4 */
- ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00400000, INTC_ICR0);
+ __raw_writel(__raw_readl(INTC_ICR0) | 0x00400000, INTC_ICR0);
register_intc_controller(&intc_desc_irq4567);
break;
case IRQ_MODE_IRQ3210:
/* select IRQ mode for IRL3-0 */
- ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00800000, INTC_ICR0);
+ __raw_writel(__raw_readl(INTC_ICR0) | 0x00800000, INTC_ICR0);
register_intc_controller(&intc_desc_irq0123);
break;
case IRQ_MODE_IRL7654:
/* enable IRL7-4 but don't provide any masking */
- ctrl_outl(0x40000000, INTC_INTMSKCLR1);
- ctrl_outl(0x0000fffe, INTC_INTMSKCLR2);
+ __raw_writel(0x40000000, INTC_INTMSKCLR1);
+ __raw_writel(0x0000fffe, INTC_INTMSKCLR2);
break;
case IRQ_MODE_IRL3210:
/* enable IRL0-3 but don't provide any masking */
- ctrl_outl(0x80000000, INTC_INTMSKCLR1);
- ctrl_outl(0xfffe0000, INTC_INTMSKCLR2);
+ __raw_writel(0x80000000, INTC_INTMSKCLR1);
+ __raw_writel(0xfffe0000, INTC_INTMSKCLR2);
break;
case IRQ_MODE_IRL7654_MASK:
/* enable IRL7-4 and mask using cpu intc controller */
- ctrl_outl(0x40000000, INTC_INTMSKCLR1);
+ __raw_writel(0x40000000, INTC_INTMSKCLR1);
register_intc_controller(&intc_desc_irl4567);
break;
case IRQ_MODE_IRL3210_MASK:
/* enable IRL0-3 and mask using cpu intc controller */
- ctrl_outl(0x80000000, INTC_INTMSKCLR1);
+ __raw_writel(0x80000000, INTC_INTMSKCLR1);
register_intc_controller(&intc_desc_irl0123);
break;
default:
diff --git a/arch/sh/kernel/cpu/sh4a/smp-shx3.c b/arch/sh/kernel/cpu/sh4a/smp-shx3.c
index 5863e0c4d02..11bf4c1e25c 100644
--- a/arch/sh/kernel/cpu/sh4a/smp-shx3.c
+++ b/arch/sh/kernel/cpu/sh4a/smp-shx3.c
@@ -78,7 +78,10 @@ void __init plat_prepare_cpus(unsigned int max_cpus)
void plat_start_cpu(unsigned int cpu, unsigned long entry_point)
{
- __raw_writel(entry_point, RESET_REG(cpu));
+ if (__in_29bit_mode())
+ __raw_writel(entry_point, RESET_REG(cpu));
+ else
+ __raw_writel(virt_to_phys(entry_point), RESET_REG(cpu));
if (!(__raw_readl(STBCR_REG(cpu)) & STBCR_MSTP))
__raw_writel(STBCR_MSTP, STBCR_REG(cpu));
diff --git a/arch/sh/kernel/cpu/sh4a/ubc.c b/arch/sh/kernel/cpu/sh4a/ubc.c
new file mode 100644
index 00000000000..efb2745bcb3
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh4a/ubc.c
@@ -0,0 +1,133 @@
+/*
+ * arch/sh/kernel/cpu/sh4a/ubc.c
+ *
+ * On-chip UBC support for SH-4A CPUs.
+ *
+ * Copyright (C) 2009 - 2010 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/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <asm/hw_breakpoint.h>
+
+#define UBC_CBR(idx) (0xff200000 + (0x20 * idx))
+#define UBC_CRR(idx) (0xff200004 + (0x20 * idx))
+#define UBC_CAR(idx) (0xff200008 + (0x20 * idx))
+#define UBC_CAMR(idx) (0xff20000c + (0x20 * idx))
+
+#define UBC_CCMFR 0xff200600
+#define UBC_CBCR 0xff200620
+
+/* CRR */
+#define UBC_CRR_PCB (1 << 1)
+#define UBC_CRR_BIE (1 << 0)
+
+/* CBR */
+#define UBC_CBR_CE (1 << 0)
+
+static struct sh_ubc sh4a_ubc;
+
+static void sh4a_ubc_enable(struct arch_hw_breakpoint *info, int idx)
+{
+ __raw_writel(UBC_CBR_CE | info->len | info->type, UBC_CBR(idx));
+ __raw_writel(info->address, UBC_CAR(idx));
+}
+
+static void sh4a_ubc_disable(struct arch_hw_breakpoint *info, int idx)
+{
+ __raw_writel(0, UBC_CBR(idx));
+ __raw_writel(0, UBC_CAR(idx));
+}
+
+static void sh4a_ubc_enable_all(unsigned long mask)
+{
+ int i;
+
+ for (i = 0; i < sh4a_ubc.num_events; i++)
+ if (mask & (1 << i))
+ __raw_writel(__raw_readl(UBC_CBR(i)) | UBC_CBR_CE,
+ UBC_CBR(i));
+}
+
+static void sh4a_ubc_disable_all(void)
+{
+ int i;
+
+ for (i = 0; i < sh4a_ubc.num_events; i++)
+ __raw_writel(__raw_readl(UBC_CBR(i)) & ~UBC_CBR_CE,
+ UBC_CBR(i));
+}
+
+static unsigned long sh4a_ubc_active_mask(void)
+{
+ unsigned long active = 0;
+ int i;
+
+ for (i = 0; i < sh4a_ubc.num_events; i++)
+ if (__raw_readl(UBC_CBR(i)) & UBC_CBR_CE)
+ active |= (1 << i);
+
+ return active;
+}
+
+static unsigned long sh4a_ubc_triggered_mask(void)
+{
+ return __raw_readl(UBC_CCMFR);
+}
+
+static void sh4a_ubc_clear_triggered_mask(unsigned long mask)
+{
+ __raw_writel(__raw_readl(UBC_CCMFR) & ~mask, UBC_CCMFR);
+}
+
+static struct sh_ubc sh4a_ubc = {
+ .name = "SH-4A",
+ .num_events = 2,
+ .trap_nr = 0x1e0,
+ .enable = sh4a_ubc_enable,
+ .disable = sh4a_ubc_disable,
+ .enable_all = sh4a_ubc_enable_all,
+ .disable_all = sh4a_ubc_disable_all,
+ .active_mask = sh4a_ubc_active_mask,
+ .triggered_mask = sh4a_ubc_triggered_mask,
+ .clear_triggered_mask = sh4a_ubc_clear_triggered_mask,
+};
+
+static int __init sh4a_ubc_init(void)
+{
+ struct clk *ubc_iclk = clk_get(NULL, "ubc0");
+ int i;
+
+ /*
+ * The UBC MSTP bit is optional, as not all platforms will have
+ * it. Just ignore it if we can't find it.
+ */
+ if (IS_ERR(ubc_iclk))
+ ubc_iclk = NULL;
+
+ clk_enable(ubc_iclk);
+
+ __raw_writel(0, UBC_CBCR);
+
+ for (i = 0; i < sh4a_ubc.num_events; i++) {
+ __raw_writel(0, UBC_CAMR(i));
+ __raw_writel(0, UBC_CBR(i));
+
+ __raw_writel(UBC_CRR_BIE | UBC_CRR_PCB, UBC_CRR(i));
+
+ /* dummy read for write posting */
+ (void)__raw_readl(UBC_CRR(i));
+ }
+
+ clk_disable(ubc_iclk);
+
+ sh4a_ubc.clk = ubc_iclk;
+
+ return register_sh_ubc(&sh4a_ubc);
+}
+arch_initcall(sh4a_ubc_init);
diff --git a/arch/sh/kernel/cpu/sh5/clock-sh5.c b/arch/sh/kernel/cpu/sh5/clock-sh5.c
index 7f864ebc51d..9cfc19b8dbe 100644
--- a/arch/sh/kernel/cpu/sh5/clock-sh5.c
+++ b/arch/sh/kernel/cpu/sh5/clock-sh5.c
@@ -24,7 +24,7 @@ static unsigned long cprc_base;
static void master_clk_init(struct clk *clk)
{
- int idx = (ctrl_inl(cprc_base + 0x00) >> 6) & 0x0007;
+ int idx = (__raw_readl(cprc_base + 0x00) >> 6) & 0x0007;
clk->rate *= ifc_table[idx];
}
@@ -34,7 +34,7 @@ static struct clk_ops sh5_master_clk_ops = {
static unsigned long module_clk_recalc(struct clk *clk)
{
- int idx = (ctrl_inw(cprc_base) >> 12) & 0x0007;
+ int idx = (__raw_readw(cprc_base) >> 12) & 0x0007;
return clk->parent->rate / ifc_table[idx];
}
@@ -44,7 +44,7 @@ static struct clk_ops sh5_module_clk_ops = {
static unsigned long bus_clk_recalc(struct clk *clk)
{
- int idx = (ctrl_inw(cprc_base) >> 3) & 0x0007;
+ int idx = (__raw_readw(cprc_base) >> 3) & 0x0007;
return clk->parent->rate / ifc_table[idx];
}
@@ -54,7 +54,7 @@ static struct clk_ops sh5_bus_clk_ops = {
static unsigned long cpu_clk_recalc(struct clk *clk)
{
- int idx = (ctrl_inw(cprc_base) & 0x0007);
+ int idx = (__raw_readw(cprc_base) & 0x0007);
return clk->parent->rate / ifc_table[idx];
}
diff --git a/arch/sh/kernel/cpu/sh5/entry.S b/arch/sh/kernel/cpu/sh5/entry.S
index 8f13f73cb2c..6b80295dd7a 100644
--- a/arch/sh/kernel/cpu/sh5/entry.S
+++ b/arch/sh/kernel/cpu/sh5/entry.S
@@ -187,7 +187,7 @@ trap_jtable:
.rept 6
.long do_exception_error /* 0x880 - 0x920 */
.endr
- .long do_software_break_point /* 0x940 */
+ .long breakpoint_trap_handler /* 0x940 */
.long do_exception_error /* 0x960 */
.long do_single_step /* 0x980 */
@@ -1124,7 +1124,7 @@ fpu_error_or_IRQA:
pta its_IRQ, tr0
beqi/l r4, EVENT_INTERRUPT, tr0
#ifdef CONFIG_SH_FPU
- movi do_fpu_state_restore, r6
+ movi fpu_state_restore_trap_handler, r6
#else
movi do_exception_error, r6
#endif
@@ -1135,7 +1135,7 @@ fpu_error_or_IRQB:
pta its_IRQ, tr0
beqi/l r4, EVENT_INTERRUPT, tr0
#ifdef CONFIG_SH_FPU
- movi do_fpu_state_restore, r6
+ movi fpu_state_restore_trap_handler, r6
#else
movi do_exception_error, r6
#endif
diff --git a/arch/sh/kernel/cpu/sh5/fpu.c b/arch/sh/kernel/cpu/sh5/fpu.c
index 4648ccee6c4..4b3bb35e99f 100644
--- a/arch/sh/kernel/cpu/sh5/fpu.c
+++ b/arch/sh/kernel/cpu/sh5/fpu.c
@@ -15,24 +15,6 @@
#include <linux/sched.h>
#include <linux/signal.h>
#include <asm/processor.h>
-#include <asm/user.h>
-#include <asm/io.h>
-#include <asm/fpu.h>
-
-/*
- * Initially load the FPU with signalling NANS. This bit pattern
- * has the property that no matter whether considered as single or as
- * double precision, it still represents a signalling NAN.
- */
-#define sNAN64 0xFFFFFFFFFFFFFFFFULL
-#define sNAN32 0xFFFFFFFFUL
-
-static union sh_fpu_union init_fpuregs = {
- .hard = {
- .fp_regs = { [0 ... 63] = sNAN32 },
- .fpscr = FPSCR_INIT
- }
-};
void save_fpu(struct task_struct *tsk)
{
@@ -72,12 +54,11 @@ void save_fpu(struct task_struct *tsk)
"fgetscr fr63\n\t"
"fst.s %0, (32*8), fr63\n\t"
: /* no output */
- : "r" (&tsk->thread.fpu.hard)
+ : "r" (&tsk->thread.xstate->hardfpu)
: "memory");
}
-static inline void
-fpload(struct sh_fpu_hard_struct *fpregs)
+void restore_fpu(struct task_struct *tsk)
{
asm volatile("fld.p %0, (0*8), fp0\n\t"
"fld.p %0, (1*8), fp2\n\t"
@@ -116,16 +97,11 @@ fpload(struct sh_fpu_hard_struct *fpregs)
"fld.p %0, (31*8), fp62\n\t"
: /* no output */
- : "r" (fpregs) );
-}
-
-void fpinit(struct sh_fpu_hard_struct *fpregs)
-{
- *fpregs = init_fpuregs.hard;
+ : "r" (&tsk->thread.xstate->hardfpu)
+ : "memory");
}
-asmlinkage void
-do_fpu_error(unsigned long ex, struct pt_regs *regs)
+asmlinkage void do_fpu_error(unsigned long ex, struct pt_regs *regs)
{
struct task_struct *tsk = current;
@@ -133,35 +109,6 @@ do_fpu_error(unsigned long ex, struct pt_regs *regs)
tsk->thread.trap_no = 11;
tsk->thread.error_code = 0;
- force_sig(SIGFPE, tsk);
-}
-
-
-asmlinkage void
-do_fpu_state_restore(unsigned long ex, struct pt_regs *regs)
-{
- void die(const char *str, struct pt_regs *regs, long err);
-
- if (! user_mode(regs))
- die("FPU used in kernel", regs, ex);
- regs->sr &= ~SR_FD;
-
- if (last_task_used_math == current)
- return;
-
- enable_fpu();
- if (last_task_used_math != NULL)
- /* Other processes fpu state, save away */
- save_fpu(last_task_used_math);
-
- last_task_used_math = current;
- if (used_math()) {
- fpload(&current->thread.fpu.hard);
- } else {
- /* First time FPU user. */
- fpload(&init_fpuregs.hard);
- set_used_math();
- }
- disable_fpu();
+ force_sig(SIGFPE, tsk);
}
diff --git a/arch/sh/kernel/cpu/shmobile/pm.c b/arch/sh/kernel/cpu/shmobile/pm.c
index ca029a44743..e5596871270 100644
--- a/arch/sh/kernel/cpu/shmobile/pm.c
+++ b/arch/sh/kernel/cpu/shmobile/pm.c
@@ -33,7 +33,8 @@ ATOMIC_NOTIFIER_HEAD(sh_mobile_post_sleep_notifier_list);
#define SUSP_MODE_SLEEP (SUSP_SH_SLEEP)
#define SUSP_MODE_SLEEP_SF (SUSP_SH_SLEEP | SUSP_SH_SF)
#define SUSP_MODE_STANDBY_SF (SUSP_SH_STANDBY | SUSP_SH_SF)
-#define SUSP_MODE_RSTANDBY (SUSP_SH_RSTANDBY | SUSP_SH_MMU | SUSP_SH_SF)
+#define SUSP_MODE_RSTANDBY_SF \
+ (SUSP_SH_RSTANDBY | SUSP_SH_MMU | SUSP_SH_REGS | SUSP_SH_SF)
/*
* U-standby mode is unsupported since it needs bootloader hacks
*/
diff --git a/arch/sh/kernel/cpu/shmobile/sleep.S b/arch/sh/kernel/cpu/shmobile/sleep.S
index e9dd7fa0abd..e6aac65f575 100644
--- a/arch/sh/kernel/cpu/shmobile/sleep.S
+++ b/arch/sh/kernel/cpu/shmobile/sleep.S
@@ -48,8 +48,48 @@ ENTRY(sh_mobile_sleep_enter_start)
stc sr, r0
mov.l r0, @(SH_SLEEP_SR, r5)
- /* save sp */
+ /* save general purpose registers to stack if needed */
+ mov.l @(SH_SLEEP_MODE, r5), r0
+ tst #SUSP_SH_REGS, r0
+ bt skip_regs_save
+
+ sts.l pr, @-r15
+ mov.l r14, @-r15
+ mov.l r13, @-r15
+ mov.l r12, @-r15
+ mov.l r11, @-r15
+ mov.l r10, @-r15
+ mov.l r9, @-r15
+ mov.l r8, @-r15
+
+ /* make sure bank0 is selected, save low registers */
+ mov.l rb_bit, r9
+ not r9, r9
+ bsr set_sr
+ mov #0, r10
+
+ bsr save_low_regs
+ nop
+
+ /* switch to bank 1, save low registers */
+ mov.l rb_bit, r10
+ bsr set_sr
+ mov #-1, r9
+
+ bsr save_low_regs
+ nop
+
+ /* switch back to bank 0 */
+ mov.l rb_bit, r9
+ not r9, r9
+ bsr set_sr
+ mov #0, r10
+
+skip_regs_save:
+
+ /* save sp, also set to internal ram */
mov.l r15, @(SH_SLEEP_SP, r5)
+ mov r5, r15
/* save stbcr */
bsr save_register
@@ -60,7 +100,7 @@ ENTRY(sh_mobile_sleep_enter_start)
tst #SUSP_SH_MMU, r0
bt skip_mmu_save_disable
- /* save mmu state */
+ /* save mmu state */
bsr save_register
mov #SH_SLEEP_REG_PTEH, r0
@@ -177,6 +217,29 @@ get_register:
mov.l @(r0, r5), r0
rts
nop
+
+set_sr:
+ stc sr, r8
+ and r9, r8
+ or r10, r8
+ ldc r8, sr
+ rts
+ nop
+
+save_low_regs:
+ mov.l r7, @-r15
+ mov.l r6, @-r15
+ mov.l r5, @-r15
+ mov.l r4, @-r15
+ mov.l r3, @-r15
+ mov.l r2, @-r15
+ mov.l r1, @-r15
+ rts
+ mov.l r0, @-r15
+
+ .balign 4
+rb_bit: .long 0x20000000 ! RB=1
+
ENTRY(sh_mobile_sleep_enter_end)
.balign 4
@@ -270,6 +333,40 @@ skip_restore_sf:
icbi @r0
skip_restore_mmu:
+
+ /* restore general purpose registers if needed */
+ mov.l @(SH_SLEEP_MODE, r5), r0
+ tst #SUSP_SH_REGS, r0
+ bt skip_restore_regs
+
+ /* switch to bank 1, restore low registers */
+ mov.l _rb_bit, r10
+ bsr _set_sr
+ mov #-1, r9
+
+ bsr restore_low_regs
+ nop
+
+ /* switch to bank0, restore low registers */
+ mov.l _rb_bit, r9
+ not r9, r9
+ bsr _set_sr
+ mov #0, r10
+
+ bsr restore_low_regs
+ nop
+
+ /* restore the rest of the registers */
+ mov.l @r15+, r8
+ mov.l @r15+, r9
+ mov.l @r15+, r10
+ mov.l @r15+, r11
+ mov.l @r15+, r12
+ mov.l @r15+, r13
+ mov.l @r15+, r14
+ lds.l @r15+, pr
+
+skip_restore_regs:
rte
nop
@@ -283,6 +380,26 @@ restore_register:
rts
nop
+_set_sr:
+ stc sr, r8
+ and r9, r8
+ or r10, r8
+ ldc r8, sr
+ rts
+ nop
+
+restore_low_regs:
+ mov.l @r15+, r0
+ mov.l @r15+, r1
+ mov.l @r15+, r2
+ mov.l @r15+, r3
+ mov.l @r15+, r4
+ mov.l @r15+, r5
+ mov.l @r15+, r6
+ rts
+ mov.l @r15+, r7
+
.balign 4
+_rb_bit: .long 0x20000000 ! RB=1
1: .long ~0x7ff
ENTRY(sh_mobile_sleep_resume_end)
diff --git a/arch/sh/kernel/debugtraps.S b/arch/sh/kernel/debugtraps.S
index 591741383ee..7a1b46fec0f 100644
--- a/arch/sh/kernel/debugtraps.S
+++ b/arch/sh/kernel/debugtraps.S
@@ -13,7 +13,6 @@
#include <linux/linkage.h>
#if !defined(CONFIG_KGDB)
-#define breakpoint_trap_handler debug_trap_handler
#define singlestep_trap_handler debug_trap_handler
#endif
diff --git a/arch/sh/kernel/dwarf.c b/arch/sh/kernel/dwarf.c
index e51168064e5..bd1c497280a 100644
--- a/arch/sh/kernel/dwarf.c
+++ b/arch/sh/kernel/dwarf.c
@@ -39,10 +39,10 @@ static mempool_t *dwarf_frame_pool;
static struct kmem_cache *dwarf_reg_cachep;
static mempool_t *dwarf_reg_pool;
-static LIST_HEAD(dwarf_cie_list);
+static struct rb_root cie_root;
static DEFINE_SPINLOCK(dwarf_cie_lock);
-static LIST_HEAD(dwarf_fde_list);
+static struct rb_root fde_root;
static DEFINE_SPINLOCK(dwarf_fde_lock);
static struct dwarf_cie *cached_cie;
@@ -301,7 +301,8 @@ static inline int dwarf_entry_len(char *addr, unsigned long *len)
*/
static struct dwarf_cie *dwarf_lookup_cie(unsigned long cie_ptr)
{
- struct dwarf_cie *cie;
+ struct rb_node **rb_node = &cie_root.rb_node;
+ struct dwarf_cie *cie = NULL;
unsigned long flags;
spin_lock_irqsave(&dwarf_cie_lock, flags);
@@ -315,16 +316,24 @@ static struct dwarf_cie *dwarf_lookup_cie(unsigned long cie_ptr)
goto out;
}
- list_for_each_entry(cie, &dwarf_cie_list, link) {
- if (cie->cie_pointer == cie_ptr) {
- cached_cie = cie;
- break;
+ while (*rb_node) {
+ struct dwarf_cie *cie_tmp;
+
+ cie_tmp = rb_entry(*rb_node, struct dwarf_cie, node);
+ BUG_ON(!cie_tmp);
+
+ if (cie_ptr == cie_tmp->cie_pointer) {
+ cie = cie_tmp;
+ cached_cie = cie_tmp;
+ goto out;
+ } else {
+ if (cie_ptr < cie_tmp->cie_pointer)
+ rb_node = &(*rb_node)->rb_left;
+ else
+ rb_node = &(*rb_node)->rb_right;
}
}
- /* Couldn't find the entry in the list. */
- if (&cie->link == &dwarf_cie_list)
- cie = NULL;
out:
spin_unlock_irqrestore(&dwarf_cie_lock, flags);
return cie;
@@ -336,25 +345,34 @@ out:
*/
struct dwarf_fde *dwarf_lookup_fde(unsigned long pc)
{
- struct dwarf_fde *fde;
+ struct rb_node **rb_node = &fde_root.rb_node;
+ struct dwarf_fde *fde = NULL;
unsigned long flags;
spin_lock_irqsave(&dwarf_fde_lock, flags);
- list_for_each_entry(fde, &dwarf_fde_list, link) {
- unsigned long start, end;
+ while (*rb_node) {
+ struct dwarf_fde *fde_tmp;
+ unsigned long tmp_start, tmp_end;
- start = fde->initial_location;
- end = fde->initial_location + fde->address_range;
+ fde_tmp = rb_entry(*rb_node, struct dwarf_fde, node);
+ BUG_ON(!fde_tmp);
- if (pc >= start && pc < end)
- break;
- }
+ tmp_start = fde_tmp->initial_location;
+ tmp_end = fde_tmp->initial_location + fde_tmp->address_range;
- /* Couldn't find the entry in the list. */
- if (&fde->link == &dwarf_fde_list)
- fde = NULL;
+ if (pc < tmp_start) {
+ rb_node = &(*rb_node)->rb_left;
+ } else {
+ if (pc < tmp_end) {
+ fde = fde_tmp;
+ goto out;
+ } else
+ rb_node = &(*rb_node)->rb_right;
+ }
+ }
+out:
spin_unlock_irqrestore(&dwarf_fde_lock, flags);
return fde;
@@ -552,8 +570,8 @@ extern void ret_from_irq(void);
* on the callstack. Each of the lower (older) stack frames are
* linked via the "prev" member.
*/
-struct dwarf_frame * dwarf_unwind_stack(unsigned long pc,
- struct dwarf_frame *prev)
+struct dwarf_frame *dwarf_unwind_stack(unsigned long pc,
+ struct dwarf_frame *prev)
{
struct dwarf_frame *frame;
struct dwarf_cie *cie;
@@ -708,6 +726,8 @@ bail:
static int dwarf_parse_cie(void *entry, void *p, unsigned long len,
unsigned char *end, struct module *mod)
{
+ struct rb_node **rb_node = &cie_root.rb_node;
+ struct rb_node *parent;
struct dwarf_cie *cie;
unsigned long flags;
int count;
@@ -802,11 +822,30 @@ static int dwarf_parse_cie(void *entry, void *p, unsigned long len,
cie->initial_instructions = p;
cie->instructions_end = end;
- cie->mod = mod;
-
/* Add to list */
spin_lock_irqsave(&dwarf_cie_lock, flags);
- list_add_tail(&cie->link, &dwarf_cie_list);
+
+ while (*rb_node) {
+ struct dwarf_cie *cie_tmp;
+
+ cie_tmp = rb_entry(*rb_node, struct dwarf_cie, node);
+
+ parent = *rb_node;
+
+ if (cie->cie_pointer < cie_tmp->cie_pointer)
+ rb_node = &parent->rb_left;
+ else if (cie->cie_pointer >= cie_tmp->cie_pointer)
+ rb_node = &parent->rb_right;
+ else
+ WARN_ON(1);
+ }
+
+ rb_link_node(&cie->node, parent, rb_node);
+ rb_insert_color(&cie->node, &cie_root);
+
+ if (mod != NULL)
+ list_add_tail(&cie->link, &mod->arch.cie_list);
+
spin_unlock_irqrestore(&dwarf_cie_lock, flags);
return 0;
@@ -816,6 +855,8 @@ static int dwarf_parse_fde(void *entry, u32 entry_type,
void *start, unsigned long len,
unsigned char *end, struct module *mod)
{
+ struct rb_node **rb_node = &fde_root.rb_node;
+ struct rb_node *parent;
struct dwarf_fde *fde;
struct dwarf_cie *cie;
unsigned long flags;
@@ -863,11 +904,38 @@ static int dwarf_parse_fde(void *entry, u32 entry_type,
fde->instructions = p;
fde->end = end;
- fde->mod = mod;
-
/* Add to list. */
spin_lock_irqsave(&dwarf_fde_lock, flags);
- list_add_tail(&fde->link, &dwarf_fde_list);
+
+ while (*rb_node) {
+ struct dwarf_fde *fde_tmp;
+ unsigned long tmp_start, tmp_end;
+ unsigned long start, end;
+
+ fde_tmp = rb_entry(*rb_node, struct dwarf_fde, node);
+
+ start = fde->initial_location;
+ end = fde->initial_location + fde->address_range;
+
+ tmp_start = fde_tmp->initial_location;
+ tmp_end = fde_tmp->initial_location + fde_tmp->address_range;
+
+ parent = *rb_node;
+
+ if (start < tmp_start)
+ rb_node = &parent->rb_left;
+ else if (start >= tmp_end)
+ rb_node = &parent->rb_right;
+ else
+ WARN_ON(1);
+ }
+
+ rb_link_node(&fde->node, parent, rb_node);
+ rb_insert_color(&fde->node, &fde_root);
+
+ if (mod != NULL)
+ list_add_tail(&fde->link, &mod->arch.fde_list);
+
spin_unlock_irqrestore(&dwarf_fde_lock, flags);
return 0;
@@ -912,19 +980,29 @@ static struct unwinder dwarf_unwinder = {
static void dwarf_unwinder_cleanup(void)
{
- struct dwarf_cie *cie, *cie_tmp;
- struct dwarf_fde *fde, *fde_tmp;
+ struct rb_node **fde_rb_node = &fde_root.rb_node;
+ struct rb_node **cie_rb_node = &cie_root.rb_node;
/*
* Deallocate all the memory allocated for the DWARF unwinder.
* Traverse all the FDE/CIE lists and remove and free all the
* memory associated with those data structures.
*/
- list_for_each_entry_safe(cie, cie_tmp, &dwarf_cie_list, link)
- kfree(cie);
+ while (*fde_rb_node) {
+ struct dwarf_fde *fde;
- list_for_each_entry_safe(fde, fde_tmp, &dwarf_fde_list, link)
+ fde = rb_entry(*fde_rb_node, struct dwarf_fde, node);
+ rb_erase(*fde_rb_node, &fde_root);
kfree(fde);
+ }
+
+ while (*cie_rb_node) {
+ struct dwarf_cie *cie;
+
+ cie = rb_entry(*cie_rb_node, struct dwarf_cie, node);
+ rb_erase(*cie_rb_node, &cie_root);
+ kfree(cie);
+ }
kmem_cache_destroy(dwarf_reg_cachep);
kmem_cache_destroy(dwarf_frame_cachep);
@@ -1024,6 +1102,8 @@ int module_dwarf_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs,
/* Did we find the .eh_frame section? */
if (i != hdr->e_shnum) {
+ INIT_LIST_HEAD(&me->arch.cie_list);
+ INIT_LIST_HEAD(&me->arch.fde_list);
err = dwarf_parse_section((char *)start, (char *)end, me);
if (err) {
printk(KERN_WARNING "%s: failed to parse DWARF info\n",
@@ -1044,38 +1124,26 @@ int module_dwarf_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs,
*/
void module_dwarf_cleanup(struct module *mod)
{
- struct dwarf_fde *fde;
- struct dwarf_cie *cie;
+ struct dwarf_fde *fde, *ftmp;
+ struct dwarf_cie *cie, *ctmp;
unsigned long flags;
spin_lock_irqsave(&dwarf_cie_lock, flags);
-again_cie:
- list_for_each_entry(cie, &dwarf_cie_list, link) {
- if (cie->mod == mod)
- break;
- }
-
- if (&cie->link != &dwarf_cie_list) {
+ list_for_each_entry_safe(cie, ctmp, &mod->arch.cie_list, link) {
list_del(&cie->link);
+ rb_erase(&cie->node, &cie_root);
kfree(cie);
- goto again_cie;
}
spin_unlock_irqrestore(&dwarf_cie_lock, flags);
spin_lock_irqsave(&dwarf_fde_lock, flags);
-again_fde:
- list_for_each_entry(fde, &dwarf_fde_list, link) {
- if (fde->mod == mod)
- break;
- }
-
- if (&fde->link != &dwarf_fde_list) {
+ list_for_each_entry_safe(fde, ftmp, &mod->arch.fde_list, link) {
list_del(&fde->link);
+ rb_erase(&fde->node, &fde_root);
kfree(fde);
- goto again_fde;
}
spin_unlock_irqrestore(&dwarf_fde_lock, flags);
@@ -1094,8 +1162,6 @@ again_fde:
static int __init dwarf_unwinder_init(void)
{
int err;
- INIT_LIST_HEAD(&dwarf_cie_list);
- INIT_LIST_HEAD(&dwarf_fde_list);
dwarf_frame_cachep = kmem_cache_create("dwarf_frames",
sizeof(struct dwarf_frame), 0,
diff --git a/arch/sh/kernel/early_printk.c b/arch/sh/kernel/early_printk.c
deleted file mode 100644
index f8bb50c6e05..00000000000
--- a/arch/sh/kernel/early_printk.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * arch/sh/kernel/early_printk.c
- *
- * Copyright (C) 1999, 2000 Niibe Yutaka
- * Copyright (C) 2002 M. R. Brown
- * Copyright (C) 2004 - 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/console.h>
-#include <linux/tty.h>
-#include <linux/init.h>
-#include <linux/io.h>
-#include <linux/delay.h>
-
-#include <asm/sh_bios.h>
-
-/*
- * Print a string through the BIOS
- */
-static void sh_console_write(struct console *co, const char *s,
- unsigned count)
-{
- sh_bios_console_write(s, count);
-}
-
-/*
- * Setup initial baud/bits/parity. We do two things here:
- * - construct a cflag setting for the first rs_open()
- * - initialize the serial port
- * Return non-zero if we didn't find a serial port.
- */
-static int __init sh_console_setup(struct console *co, char *options)
-{
- int cflag = CREAD | HUPCL | CLOCAL;
-
- /*
- * Now construct a cflag setting.
- * TODO: this is a totally bogus cflag, as we have
- * no idea what serial settings the BIOS is using, or
- * even if its using the serial port at all.
- */
- cflag |= B115200 | CS8 | /*no parity*/0;
-
- co->cflag = cflag;
-
- return 0;
-}
-
-static struct console bios_console = {
- .name = "bios",
- .write = sh_console_write,
- .setup = sh_console_setup,
- .flags = CON_PRINTBUFFER,
- .index = -1,
-};
-
-static struct console *early_console;
-
-static int __init setup_early_printk(char *buf)
-{
- int keep_early = 0;
-
- if (!buf)
- return 0;
-
- if (strstr(buf, "keep"))
- keep_early = 1;
-
- if (!strncmp(buf, "bios", 4))
- early_console = &bios_console;
-
- if (likely(early_console)) {
- if (keep_early)
- early_console->flags &= ~CON_BOOT;
- else
- early_console->flags |= CON_BOOT;
- register_console(early_console);
- }
-
- return 0;
-}
-early_param("earlyprintk", setup_early_printk);
diff --git a/arch/sh/kernel/head_32.S b/arch/sh/kernel/head_32.S
index 1151ecdffa7..fe0b743881b 100644
--- a/arch/sh/kernel/head_32.S
+++ b/arch/sh/kernel/head_32.S
@@ -3,6 +3,7 @@
* arch/sh/kernel/head.S
*
* Copyright (C) 1999, 2000 Niibe Yutaka & Kaz Kojima
+ * Copyright (C) 2010 Matt Fleming
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
@@ -13,6 +14,8 @@
#include <linux/init.h>
#include <linux/linkage.h>
#include <asm/thread_info.h>
+#include <asm/mmu.h>
+#include <cpu/mmu_context.h>
#ifdef CONFIG_CPU_SH4A
#define SYNCO() synco
@@ -33,7 +36,7 @@ ENTRY(empty_zero_page)
.long 1 /* LOADER_TYPE */
.long 0x00000000 /* INITRD_START */
.long 0x00000000 /* INITRD_SIZE */
-#if defined(CONFIG_32BIT) && defined(CONFIG_PMB_FIXED)
+#ifdef CONFIG_32BIT
.long 0x53453f00 + 32 /* "SE?" = 32 bit */
#else
.long 0x53453f00 + 29 /* "SE?" = 29 bit */
@@ -82,6 +85,209 @@ ENTRY(_stext)
ldc r0, r7_bank ! ... and initial thread_info
#endif
+#ifdef CONFIG_PMB
+/*
+ * Reconfigure the initial PMB mappings setup by the hardware.
+ *
+ * When we boot in 32-bit MMU mode there are 2 PMB entries already
+ * setup for us.
+ *
+ * Entry VPN PPN V SZ C UB WT
+ * ---------------------------------------------------------------
+ * 0 0x80000000 0x00000000 1 512MB 1 0 1
+ * 1 0xA0000000 0x00000000 1 512MB 0 0 0
+ *
+ * But we reprogram them here because we want complete control over
+ * our address space and the initial mappings may not map PAGE_OFFSET
+ * to __MEMORY_START (or even map all of our RAM).
+ *
+ * Once we've setup cached and uncached mappings we clear the rest of the
+ * PMB entries. This clearing also deals with the fact that PMB entries
+ * can persist across reboots. The PMB could have been left in any state
+ * when the reboot occurred, so to be safe we clear all entries and start
+ * with with a clean slate.
+ *
+ * The uncached mapping is constructed using the smallest possible
+ * mapping with a single unbufferable page. Only the kernel text needs to
+ * be covered via the uncached mapping so that certain functions can be
+ * run uncached.
+ *
+ * Drivers and the like that have previously abused the 1:1 identity
+ * mapping are unsupported in 32-bit mode and must specify their caching
+ * preference when page tables are constructed.
+ *
+ * This frees up the P2 space for more nefarious purposes.
+ *
+ * Register utilization is as follows:
+ *
+ * r0 = PMB_DATA data field
+ * r1 = PMB_DATA address field
+ * r2 = PMB_ADDR data field
+ * r3 = PMB_ADDR address field
+ * r4 = PMB_E_SHIFT
+ * r5 = remaining amount of RAM to map
+ * r6 = PMB mapping size we're trying to use
+ * r7 = cached_to_uncached
+ * r8 = scratch register
+ * r9 = scratch register
+ * r10 = number of PMB entries we've setup
+ */
+
+ mov.l .LMMUCR, r1 /* Flush the TLB */
+ mov.l @r1, r0
+ or #MMUCR_TI, r0
+ mov.l r0, @r1
+
+ mov.l .LMEMORY_SIZE, r5
+
+ mov #PMB_E_SHIFT, r0
+ mov #0x1, r4
+ shld r0, r4
+
+ mov.l .LFIRST_DATA_ENTRY, r0
+ mov.l .LPMB_DATA, r1
+ mov.l .LFIRST_ADDR_ENTRY, r2
+ mov.l .LPMB_ADDR, r3
+
+ /*
+ * First we need to walk the PMB and figure out if there are any
+ * existing mappings that match the initial mappings VPN/PPN.
+ * If these have already been established by the bootloader, we
+ * don't bother setting up new entries here, and let the late PMB
+ * initialization take care of things instead.
+ *
+ * Note that we may need to coalesce and merge entries in order
+ * to reclaim more available PMB slots, which is much more than
+ * we want to do at this early stage.
+ */
+ mov #0, r10
+ mov #NR_PMB_ENTRIES, r9
+
+ mov r1, r7 /* temporary PMB_DATA iter */
+
+.Lvalidate_existing_mappings:
+
+ mov.l @r7, r8
+ and r0, r8
+ cmp/eq r0, r8 /* Check for valid __MEMORY_START mappings */
+ bt .Lpmb_done
+
+ add #1, r10 /* Increment the loop counter */
+ cmp/eq r9, r10
+ bf/s .Lvalidate_existing_mappings
+ add r4, r7 /* Increment to the next PMB_DATA entry */
+
+ /*
+ * If we've fallen through, continue with setting up the initial
+ * mappings.
+ */
+
+ mov r5, r7 /* cached_to_uncached */
+ mov #0, r10
+
+#ifdef CONFIG_UNCACHED_MAPPING
+ /*
+ * Uncached mapping
+ */
+ mov #(PMB_SZ_16M >> 2), r9
+ shll2 r9
+
+ mov #(PMB_UB >> 8), r8
+ shll8 r8
+
+ or r0, r8
+ or r9, r8
+ mov.l r8, @r1
+ mov r2, r8
+ add r7, r8
+ mov.l r8, @r3
+
+ add r4, r1
+ add r4, r3
+ add #1, r10
+#endif
+
+/*
+ * Iterate over all of the available sizes from largest to
+ * smallest for constructing the cached mapping.
+ */
+#define __PMB_ITER_BY_SIZE(size) \
+.L##size: \
+ mov #(size >> 4), r6; \
+ shll16 r6; \
+ shll8 r6; \
+ \
+ cmp/hi r5, r6; \
+ bt 9999f; \
+ \
+ mov #(PMB_SZ_##size##M >> 2), r9; \
+ shll2 r9; \
+ \
+ /* \
+ * Cached mapping \
+ */ \
+ mov #PMB_C, r8; \
+ or r0, r8; \
+ or r9, r8; \
+ mov.l r8, @r1; \
+ mov.l r2, @r3; \
+ \
+ /* Increment to the next PMB_DATA entry */ \
+ add r4, r1; \
+ /* Increment to the next PMB_ADDR entry */ \
+ add r4, r3; \
+ /* Increment number of PMB entries */ \
+ add #1, r10; \
+ \
+ sub r6, r5; \
+ add r6, r0; \
+ add r6, r2; \
+ \
+ bra .L##size; \
+9999:
+
+ __PMB_ITER_BY_SIZE(512)
+ __PMB_ITER_BY_SIZE(128)
+ __PMB_ITER_BY_SIZE(64)
+ __PMB_ITER_BY_SIZE(16)
+
+#ifdef CONFIG_UNCACHED_MAPPING
+ /*
+ * Now that we can access it, update cached_to_uncached and
+ * uncached_size.
+ */
+ mov.l .Lcached_to_uncached, r0
+ mov.l r7, @r0
+
+ mov.l .Luncached_size, r0
+ mov #1, r7
+ shll16 r7
+ shll8 r7
+ mov.l r7, @r0
+#endif
+
+ /*
+ * Clear the remaining PMB entries.
+ *
+ * r3 = entry to begin clearing from
+ * r10 = number of entries we've setup so far
+ */
+ mov #0, r1
+ mov #NR_PMB_ENTRIES, r0
+
+.Lagain:
+ mov.l r1, @r3 /* Clear PMB_ADDR entry */
+ add #1, r10 /* Increment the loop counter */
+ cmp/eq r0, r10
+ bf/s .Lagain
+ add r4, r3 /* Increment to the next PMB_ADDR entry */
+
+ mov.l 6f, r0
+ icbi @r0
+
+.Lpmb_done:
+#endif /* CONFIG_PMB */
+
#ifndef CONFIG_SH_NO_BSS_INIT
/*
* Don't clear BSS if running on slow platforms such as an RTL simulation,
@@ -131,3 +337,16 @@ ENTRY(stack_start)
5: .long start_kernel
6: .long sh_cpu_init
7: .long init_thread_union
+
+#ifdef CONFIG_PMB
+.LPMB_ADDR: .long PMB_ADDR
+.LPMB_DATA: .long PMB_DATA
+.LFIRST_ADDR_ENTRY: .long PAGE_OFFSET | PMB_V
+.LFIRST_DATA_ENTRY: .long __MEMORY_START | PMB_V
+.LMMUCR: .long MMUCR
+.LMEMORY_SIZE: .long __MEMORY_SIZE
+#ifdef CONFIG_UNCACHED_MAPPING
+.Lcached_to_uncached: .long cached_to_uncached
+.Luncached_size: .long uncached_size
+#endif
+#endif
diff --git a/arch/sh/kernel/head_64.S b/arch/sh/kernel/head_64.S
index 3ea765844c7..defd851abef 100644
--- a/arch/sh/kernel/head_64.S
+++ b/arch/sh/kernel/head_64.S
@@ -220,7 +220,6 @@ clear_DTLB:
add.l r22, r63, r22 /* Sign extend */
putcfg r21, 0, r22 /* Set MMUDR[0].PTEH */
-#ifdef CONFIG_EARLY_PRINTK
/*
* Setup a DTLB translation for SCIF phys.
*/
@@ -231,7 +230,6 @@ clear_DTLB:
movi 0xfa03, r22 /* 0xfa030000, fixed SCIF virt */
shori 0x0003, r22
putcfg r21, 0, r22 /* PTEH last */
-#endif
/*
* Set cache behaviours.
diff --git a/arch/sh/kernel/hw_breakpoint.c b/arch/sh/kernel/hw_breakpoint.c
new file mode 100644
index 00000000000..e2f1753d275
--- /dev/null
+++ b/arch/sh/kernel/hw_breakpoint.c
@@ -0,0 +1,463 @@
+/*
+ * arch/sh/kernel/hw_breakpoint.c
+ *
+ * Unified kernel/user-space hardware breakpoint facility for the on-chip UBC.
+ *
+ * Copyright (C) 2009 - 2010 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/perf_event.h>
+#include <linux/hw_breakpoint.h>
+#include <linux/percpu.h>
+#include <linux/kallsyms.h>
+#include <linux/notifier.h>
+#include <linux/kprobes.h>
+#include <linux/kdebug.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <asm/hw_breakpoint.h>
+#include <asm/mmu_context.h>
+#include <asm/ptrace.h>
+
+/*
+ * Stores the breakpoints currently in use on each breakpoint address
+ * register for each cpus
+ */
+static DEFINE_PER_CPU(struct perf_event *, bp_per_reg[HBP_NUM]);
+
+/*
+ * A dummy placeholder for early accesses until the CPUs get a chance to
+ * register their UBCs later in the boot process.
+ */
+static struct sh_ubc ubc_dummy = { .num_events = 0 };
+
+static struct sh_ubc *sh_ubc __read_mostly = &ubc_dummy;
+
+/*
+ * Install a perf counter breakpoint.
+ *
+ * We seek a free UBC channel and use it for this breakpoint.
+ *
+ * Atomic: we hold the counter->ctx->lock and we only handle variables
+ * and registers local to this cpu.
+ */
+int arch_install_hw_breakpoint(struct perf_event *bp)
+{
+ struct arch_hw_breakpoint *info = counter_arch_bp(bp);
+ int i;
+
+ for (i = 0; i < sh_ubc->num_events; i++) {
+ struct perf_event **slot = &__get_cpu_var(bp_per_reg[i]);
+
+ if (!*slot) {
+ *slot = bp;
+ break;
+ }
+ }
+
+ if (WARN_ONCE(i == sh_ubc->num_events, "Can't find any breakpoint slot"))
+ return -EBUSY;
+
+ clk_enable(sh_ubc->clk);
+ sh_ubc->enable(info, i);
+
+ return 0;
+}
+
+/*
+ * Uninstall the breakpoint contained in the given counter.
+ *
+ * First we search the debug address register it uses and then we disable
+ * it.
+ *
+ * Atomic: we hold the counter->ctx->lock and we only handle variables
+ * and registers local to this cpu.
+ */
+void arch_uninstall_hw_breakpoint(struct perf_event *bp)
+{
+ struct arch_hw_breakpoint *info = counter_arch_bp(bp);
+ int i;
+
+ for (i = 0; i < sh_ubc->num_events; i++) {
+ struct perf_event **slot = &__get_cpu_var(bp_per_reg[i]);
+
+ if (*slot == bp) {
+ *slot = NULL;
+ break;
+ }
+ }
+
+ if (WARN_ONCE(i == sh_ubc->num_events, "Can't find any breakpoint slot"))
+ return;
+
+ sh_ubc->disable(info, i);
+ clk_disable(sh_ubc->clk);
+}
+
+static int get_hbp_len(u16 hbp_len)
+{
+ unsigned int len_in_bytes = 0;
+
+ switch (hbp_len) {
+ case SH_BREAKPOINT_LEN_1:
+ len_in_bytes = 1;
+ break;
+ case SH_BREAKPOINT_LEN_2:
+ len_in_bytes = 2;
+ break;
+ case SH_BREAKPOINT_LEN_4:
+ len_in_bytes = 4;
+ break;
+ case SH_BREAKPOINT_LEN_8:
+ len_in_bytes = 8;
+ break;
+ }
+ return len_in_bytes;
+}
+
+/*
+ * Check for virtual address in user space.
+ */
+int arch_check_va_in_userspace(unsigned long va, u16 hbp_len)
+{
+ unsigned int len;
+
+ len = get_hbp_len(hbp_len);
+
+ return (va <= TASK_SIZE - len);
+}
+
+/*
+ * Check for virtual address in kernel space.
+ */
+static int arch_check_va_in_kernelspace(unsigned long va, u8 hbp_len)
+{
+ unsigned int len;
+
+ len = get_hbp_len(hbp_len);
+
+ return (va >= TASK_SIZE) && ((va + len - 1) >= TASK_SIZE);
+}
+
+/*
+ * Store a breakpoint's encoded address, length, and type.
+ */
+static int arch_store_info(struct perf_event *bp)
+{
+ struct arch_hw_breakpoint *info = counter_arch_bp(bp);
+
+ /*
+ * User-space requests will always have the address field populated
+ * For kernel-addresses, either the address or symbol name can be
+ * specified.
+ */
+ if (info->name)
+ info->address = (unsigned long)kallsyms_lookup_name(info->name);
+ if (info->address)
+ return 0;
+
+ return -EINVAL;
+}
+
+int arch_bp_generic_fields(int sh_len, int sh_type,
+ int *gen_len, int *gen_type)
+{
+ /* Len */
+ switch (sh_len) {
+ case SH_BREAKPOINT_LEN_1:
+ *gen_len = HW_BREAKPOINT_LEN_1;
+ break;
+ case SH_BREAKPOINT_LEN_2:
+ *gen_len = HW_BREAKPOINT_LEN_2;
+ break;
+ case SH_BREAKPOINT_LEN_4:
+ *gen_len = HW_BREAKPOINT_LEN_4;
+ break;
+ case SH_BREAKPOINT_LEN_8:
+ *gen_len = HW_BREAKPOINT_LEN_8;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* Type */
+ switch (sh_type) {
+ case SH_BREAKPOINT_READ:
+ *gen_type = HW_BREAKPOINT_R;
+ case SH_BREAKPOINT_WRITE:
+ *gen_type = HW_BREAKPOINT_W;
+ break;
+ case SH_BREAKPOINT_RW:
+ *gen_type = HW_BREAKPOINT_W | HW_BREAKPOINT_R;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int arch_build_bp_info(struct perf_event *bp)
+{
+ struct arch_hw_breakpoint *info = counter_arch_bp(bp);
+
+ info->address = bp->attr.bp_addr;
+
+ /* Len */
+ switch (bp->attr.bp_len) {
+ case HW_BREAKPOINT_LEN_1:
+ info->len = SH_BREAKPOINT_LEN_1;
+ break;
+ case HW_BREAKPOINT_LEN_2:
+ info->len = SH_BREAKPOINT_LEN_2;
+ break;
+ case HW_BREAKPOINT_LEN_4:
+ info->len = SH_BREAKPOINT_LEN_4;
+ break;
+ case HW_BREAKPOINT_LEN_8:
+ info->len = SH_BREAKPOINT_LEN_8;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* Type */
+ switch (bp->attr.bp_type) {
+ case HW_BREAKPOINT_R:
+ info->type = SH_BREAKPOINT_READ;
+ break;
+ case HW_BREAKPOINT_W:
+ info->type = SH_BREAKPOINT_WRITE;
+ break;
+ case HW_BREAKPOINT_W | HW_BREAKPOINT_R:
+ info->type = SH_BREAKPOINT_RW;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/*
+ * Validate the arch-specific HW Breakpoint register settings
+ */
+int arch_validate_hwbkpt_settings(struct perf_event *bp,
+ struct task_struct *tsk)
+{
+ struct arch_hw_breakpoint *info = counter_arch_bp(bp);
+ unsigned int align;
+ int ret;
+
+ ret = arch_build_bp_info(bp);
+ if (ret)
+ return ret;
+
+ ret = -EINVAL;
+
+ switch (info->len) {
+ case SH_BREAKPOINT_LEN_1:
+ align = 0;
+ break;
+ case SH_BREAKPOINT_LEN_2:
+ align = 1;
+ break;
+ case SH_BREAKPOINT_LEN_4:
+ align = 3;
+ break;
+ case SH_BREAKPOINT_LEN_8:
+ align = 7;
+ break;
+ default:
+ return ret;
+ }
+
+ ret = arch_store_info(bp);
+
+ if (ret < 0)
+ return ret;
+
+ /*
+ * Check that the low-order bits of the address are appropriate
+ * for the alignment implied by len.
+ */
+ if (info->address & align)
+ return -EINVAL;
+
+ /* Check that the virtual address is in the proper range */
+ if (tsk) {
+ if (!arch_check_va_in_userspace(info->address, info->len))
+ return -EFAULT;
+ } else {
+ if (!arch_check_va_in_kernelspace(info->address, info->len))
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+/*
+ * Release the user breakpoints used by ptrace
+ */
+void flush_ptrace_hw_breakpoint(struct task_struct *tsk)
+{
+ int i;
+ struct thread_struct *t = &tsk->thread;
+
+ for (i = 0; i < sh_ubc->num_events; i++) {
+ unregister_hw_breakpoint(t->ptrace_bps[i]);
+ t->ptrace_bps[i] = NULL;
+ }
+}
+
+static int __kprobes hw_breakpoint_handler(struct die_args *args)
+{
+ int cpu, i, rc = NOTIFY_STOP;
+ struct perf_event *bp;
+ unsigned int cmf, resume_mask;
+
+ /*
+ * Do an early return if none of the channels triggered.
+ */
+ cmf = sh_ubc->triggered_mask();
+ if (unlikely(!cmf))
+ return NOTIFY_DONE;
+
+ /*
+ * By default, resume all of the active channels.
+ */
+ resume_mask = sh_ubc->active_mask();
+
+ /*
+ * Disable breakpoints during exception handling.
+ */
+ sh_ubc->disable_all();
+
+ cpu = get_cpu();
+ for (i = 0; i < sh_ubc->num_events; i++) {
+ unsigned long event_mask = (1 << i);
+
+ if (likely(!(cmf & event_mask)))
+ continue;
+
+ /*
+ * The counter may be concurrently released but that can only
+ * occur from a call_rcu() path. We can then safely fetch
+ * the breakpoint, use its callback, touch its counter
+ * while we are in an rcu_read_lock() path.
+ */
+ rcu_read_lock();
+
+ bp = per_cpu(bp_per_reg[i], cpu);
+ if (bp)
+ rc = NOTIFY_DONE;
+
+ /*
+ * Reset the condition match flag to denote completion of
+ * exception handling.
+ */
+ sh_ubc->clear_triggered_mask(event_mask);
+
+ /*
+ * bp can be NULL due to concurrent perf counter
+ * removing.
+ */
+ if (!bp) {
+ rcu_read_unlock();
+ break;
+ }
+
+ /*
+ * Don't restore the channel if the breakpoint is from
+ * ptrace, as it always operates in one-shot mode.
+ */
+ if (bp->overflow_handler == ptrace_triggered)
+ resume_mask &= ~(1 << i);
+
+ perf_bp_event(bp, args->regs);
+
+ /* Deliver the signal to userspace */
+ if (arch_check_va_in_userspace(bp->attr.bp_addr,
+ bp->attr.bp_len)) {
+ siginfo_t info;
+
+ info.si_signo = args->signr;
+ info.si_errno = notifier_to_errno(rc);
+ info.si_code = TRAP_HWBKPT;
+
+ force_sig_info(args->signr, &info, current);
+ }
+
+ rcu_read_unlock();
+ }
+
+ if (cmf == 0)
+ rc = NOTIFY_DONE;
+
+ sh_ubc->enable_all(resume_mask);
+
+ put_cpu();
+
+ return rc;
+}
+
+BUILD_TRAP_HANDLER(breakpoint)
+{
+ unsigned long ex = lookup_exception_vector();
+ TRAP_HANDLER_DECL;
+
+ notify_die(DIE_BREAKPOINT, "breakpoint", regs, 0, ex, SIGTRAP);
+}
+
+/*
+ * Handle debug exception notifications.
+ */
+int __kprobes hw_breakpoint_exceptions_notify(struct notifier_block *unused,
+ unsigned long val, void *data)
+{
+ struct die_args *args = data;
+
+ if (val != DIE_BREAKPOINT)
+ return NOTIFY_DONE;
+
+ /*
+ * If the breakpoint hasn't been triggered by the UBC, it's
+ * probably from a debugger, so don't do anything more here.
+ *
+ * This also permits the UBC interface clock to remain off for
+ * non-UBC breakpoints, as we don't need to check the triggered
+ * or active channel masks.
+ */
+ if (args->trapnr != sh_ubc->trap_nr)
+ return NOTIFY_DONE;
+
+ return hw_breakpoint_handler(data);
+}
+
+void hw_breakpoint_pmu_read(struct perf_event *bp)
+{
+ /* TODO */
+}
+
+void hw_breakpoint_pmu_unthrottle(struct perf_event *bp)
+{
+ /* TODO */
+}
+
+int register_sh_ubc(struct sh_ubc *ubc)
+{
+ /* Bail if it's already assigned */
+ if (sh_ubc != &ubc_dummy)
+ return -EBUSY;
+ sh_ubc = ubc;
+
+ pr_info("HW Breakpoints: %s UBC support registered\n", ubc->name);
+
+ WARN_ON(ubc->num_events > HBP_NUM);
+
+ return 0;
+}
diff --git a/arch/sh/kernel/idle.c b/arch/sh/kernel/idle.c
index 6b3d706deac..0fd7b41f0a2 100644
--- a/arch/sh/kernel/idle.c
+++ b/arch/sh/kernel/idle.c
@@ -20,10 +20,9 @@
#include <asm/system.h>
#include <asm/atomic.h>
-static int hlt_counter;
void (*pm_idle)(void) = NULL;
-void (*pm_power_off)(void);
-EXPORT_SYMBOL(pm_power_off);
+
+static int hlt_counter;
static int __init nohlt_setup(char *__unused)
{
@@ -131,6 +130,15 @@ static void do_nothing(void *unused)
{
}
+void stop_this_cpu(void *unused)
+{
+ local_irq_disable();
+ cpu_clear(smp_processor_id(), cpu_online_map);
+
+ for (;;)
+ cpu_sleep();
+}
+
/*
* cpu_idle_wait - Used to ensure that all the CPUs discard old value of
* pm_idle and update to new pm_idle value. Required while changing pm_idle
diff --git a/arch/sh/kernel/io_trapped.c b/arch/sh/kernel/io_trapped.c
index 69be603aa2d..4a8bb4eeb8a 100644
--- a/arch/sh/kernel/io_trapped.c
+++ b/arch/sh/kernel/io_trapped.c
@@ -184,31 +184,31 @@ static unsigned long long copy_word(unsigned long src_addr, int src_len,
switch (src_len) {
case 1:
- tmp = ctrl_inb(src_addr);
+ tmp = __raw_readb(src_addr);
break;
case 2:
- tmp = ctrl_inw(src_addr);
+ tmp = __raw_readw(src_addr);
break;
case 4:
- tmp = ctrl_inl(src_addr);
+ tmp = __raw_readl(src_addr);
break;
case 8:
- tmp = ctrl_inq(src_addr);
+ tmp = __raw_readq(src_addr);
break;
}
switch (dst_len) {
case 1:
- ctrl_outb(tmp, dst_addr);
+ __raw_writeb(tmp, dst_addr);
break;
case 2:
- ctrl_outw(tmp, dst_addr);
+ __raw_writew(tmp, dst_addr);
break;
case 4:
- ctrl_outl(tmp, dst_addr);
+ __raw_writel(tmp, dst_addr);
break;
case 8:
- ctrl_outq(tmp, dst_addr);
+ __raw_writeq(tmp, dst_addr);
break;
}
@@ -271,6 +271,8 @@ int handle_trapped_io(struct pt_regs *regs, unsigned long address)
insn_size_t instruction;
int tmp;
+ if (trapped_io_disable)
+ return 0;
if (!lookup_tiop(address))
return 0;
diff --git a/arch/sh/kernel/kgdb.c b/arch/sh/kernel/kgdb.c
index 3e532d0d4a5..70c69659b84 100644
--- a/arch/sh/kernel/kgdb.c
+++ b/arch/sh/kernel/kgdb.c
@@ -1,7 +1,7 @@
/*
* SuperH KGDB support
*
- * Copyright (C) 2008 Paul Mundt
+ * Copyright (C) 2008 - 2009 Paul Mundt
*
* Single stepping taken from the old stub by Henry Bell and Jeremy Siegel.
*
@@ -251,24 +251,60 @@ BUILD_TRAP_HANDLER(singlestep)
local_irq_restore(flags);
}
+static int __kgdb_notify(struct die_args *args, unsigned long cmd)
+{
+ int ret;
+
+ switch (cmd) {
+ case DIE_BREAKPOINT:
+ /*
+ * This means a user thread is single stepping
+ * a system call which should be ignored
+ */
+ if (test_thread_flag(TIF_SINGLESTEP))
+ return NOTIFY_DONE;
+
+ ret = kgdb_handle_exception(args->trapnr & 0xff, args->signr,
+ args->err, args->regs);
+ if (ret)
+ return NOTIFY_DONE;
+
+ break;
+ }
-BUILD_TRAP_HANDLER(breakpoint)
+ return NOTIFY_STOP;
+}
+
+static int
+kgdb_notify(struct notifier_block *self, unsigned long cmd, void *ptr)
{
unsigned long flags;
- TRAP_HANDLER_DECL;
+ int ret;
local_irq_save(flags);
- kgdb_handle_exception(vec >> 2, SIGTRAP, 0, regs);
+ ret = __kgdb_notify(ptr, cmd);
local_irq_restore(flags);
+
+ return ret;
}
+static struct notifier_block kgdb_notifier = {
+ .notifier_call = kgdb_notify,
+
+ /*
+ * Lowest-prio notifier priority, we want to be notified last:
+ */
+ .priority = -INT_MAX,
+};
+
int kgdb_arch_init(void)
{
- return 0;
+ return register_die_notifier(&kgdb_notifier);
}
void kgdb_arch_exit(void)
{
+ unregister_die_notifier(&kgdb_notifier);
}
struct kgdb_arch arch_kgdb_ops = {
diff --git a/arch/sh/kernel/machine_kexec.c b/arch/sh/kernel/machine_kexec.c
index 76f280223eb..7672141c841 100644
--- a/arch/sh/kernel/machine_kexec.c
+++ b/arch/sh/kernel/machine_kexec.c
@@ -21,6 +21,8 @@
#include <asm/mmu_context.h>
#include <asm/io.h>
#include <asm/cacheflush.h>
+#include <asm/sh_bios.h>
+#include <asm/reboot.h>
typedef void (*relocate_new_kernel_t)(unsigned long indirection_page,
unsigned long reboot_code_buffer,
@@ -28,15 +30,11 @@ typedef void (*relocate_new_kernel_t)(unsigned long indirection_page,
extern const unsigned char relocate_new_kernel[];
extern const unsigned int relocate_new_kernel_size;
-extern void *gdb_vbr_vector;
extern void *vbr_base;
-void machine_shutdown(void)
-{
-}
-
-void machine_crash_shutdown(struct pt_regs *regs)
+void native_machine_crash_shutdown(struct pt_regs *regs)
{
+ /* Nothing to do for UP, but definitely broken for SMP.. */
}
/*
@@ -117,11 +115,7 @@ void machine_kexec(struct kimage *image)
kexec_info(image);
flush_cache_all();
-#if defined(CONFIG_SH_STANDARD_BIOS)
- asm volatile("ldc %0, vbr" :
- : "r" (((unsigned long) gdb_vbr_vector) - 0x100)
- : "memory");
-#endif
+ sh_bios_vbr_reload();
/* now call it */
rnk = (relocate_new_kernel_t) reboot_code_buffer;
diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c
new file mode 100644
index 00000000000..81add9b9ea6
--- /dev/null
+++ b/arch/sh/kernel/process.c
@@ -0,0 +1,100 @@
+#include <linux/mm.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+struct kmem_cache *task_xstate_cachep = NULL;
+unsigned int xstate_size;
+
+int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
+{
+ *dst = *src;
+
+ if (src->thread.xstate) {
+ dst->thread.xstate = kmem_cache_alloc(task_xstate_cachep,
+ GFP_KERNEL);
+ if (!dst->thread.xstate)
+ return -ENOMEM;
+ memcpy(dst->thread.xstate, src->thread.xstate, xstate_size);
+ }
+
+ return 0;
+}
+
+void free_thread_xstate(struct task_struct *tsk)
+{
+ if (tsk->thread.xstate) {
+ kmem_cache_free(task_xstate_cachep, tsk->thread.xstate);
+ tsk->thread.xstate = NULL;
+ }
+}
+
+#if THREAD_SHIFT < PAGE_SHIFT
+static struct kmem_cache *thread_info_cache;
+
+struct thread_info *alloc_thread_info(struct task_struct *tsk)
+{
+ struct thread_info *ti;
+
+ ti = kmem_cache_alloc(thread_info_cache, GFP_KERNEL);
+ if (unlikely(ti == NULL))
+ return NULL;
+#ifdef CONFIG_DEBUG_STACK_USAGE
+ memset(ti, 0, THREAD_SIZE);
+#endif
+ return ti;
+}
+
+void free_thread_info(struct thread_info *ti)
+{
+ free_thread_xstate(ti->task);
+ kmem_cache_free(thread_info_cache, ti);
+}
+
+void thread_info_cache_init(void)
+{
+ thread_info_cache = kmem_cache_create("thread_info", THREAD_SIZE,
+ THREAD_SIZE, SLAB_PANIC, NULL);
+}
+#else
+struct thread_info *alloc_thread_info(struct task_struct *tsk)
+{
+#ifdef CONFIG_DEBUG_STACK_USAGE
+ gfp_t mask = GFP_KERNEL | __GFP_ZERO;
+#else
+ gfp_t mask = GFP_KERNEL;
+#endif
+ return (struct thread_info *)__get_free_pages(mask, THREAD_SIZE_ORDER);
+}
+
+void free_thread_info(struct thread_info *ti)
+{
+ free_thread_xstate(ti->task);
+ free_pages((unsigned long)ti, THREAD_SIZE_ORDER);
+}
+#endif /* THREAD_SHIFT < PAGE_SHIFT */
+
+void arch_task_cache_init(void)
+{
+ if (!xstate_size)
+ return;
+
+ task_xstate_cachep = kmem_cache_create("task_xstate", xstate_size,
+ __alignof__(union thread_xstate),
+ SLAB_PANIC | SLAB_NOTRACK, NULL);
+}
+
+#ifdef CONFIG_SH_FPU_EMU
+# define HAVE_SOFTFP 1
+#else
+# define HAVE_SOFTFP 0
+#endif
+
+void init_thread_xstate(void)
+{
+ if (boot_cpu_data.flags & CPU_HAS_FPU)
+ xstate_size = sizeof(struct sh_fpu_hard_struct);
+ else if (HAVE_SOFTFP)
+ xstate_size = sizeof(struct sh_fpu_soft_struct);
+ else
+ xstate_size = 0;
+}
diff --git a/arch/sh/kernel/process_32.c b/arch/sh/kernel/process_32.c
index d8af889366a..3cb88f114d7 100644
--- a/arch/sh/kernel/process_32.c
+++ b/arch/sh/kernel/process_32.c
@@ -16,65 +16,15 @@
#include <linux/module.h>
#include <linux/mm.h>
#include <linux/elfcore.h>
-#include <linux/pm.h>
#include <linux/kallsyms.h>
-#include <linux/kexec.h>
-#include <linux/kdebug.h>
-#include <linux/tick.h>
-#include <linux/reboot.h>
#include <linux/fs.h>
#include <linux/ftrace.h>
-#include <linux/preempt.h>
+#include <linux/hw_breakpoint.h>
#include <asm/uaccess.h>
#include <asm/mmu_context.h>
-#include <asm/pgalloc.h>
#include <asm/system.h>
-#include <asm/ubc.h>
#include <asm/fpu.h>
#include <asm/syscalls.h>
-#include <asm/watchdog.h>
-
-int ubc_usercnt = 0;
-
-#ifdef CONFIG_32BIT
-static void watchdog_trigger_immediate(void)
-{
- sh_wdt_write_cnt(0xFF);
- sh_wdt_write_csr(0xC2);
-}
-
-void machine_restart(char * __unused)
-{
- local_irq_disable();
-
- /* Use watchdog timer to trigger reset */
- watchdog_trigger_immediate();
-
- while (1)
- cpu_sleep();
-}
-#else
-void machine_restart(char * __unused)
-{
- /* SR.BL=1 and invoke address error to let CPU reset (manual reset) */
- asm volatile("ldc %0, sr\n\t"
- "mov.l @%1, %0" : : "r" (0x10000000), "r" (0x80000001));
-}
-#endif
-
-void machine_halt(void)
-{
- local_irq_disable();
-
- while (1)
- cpu_sleep();
-}
-
-void machine_power_off(void)
-{
- if (pm_power_off)
- pm_power_off();
-}
void show_regs(struct pt_regs * regs)
{
@@ -91,7 +41,7 @@ void show_regs(struct pt_regs * regs)
printk("PC : %08lx SP : %08lx SR : %08lx ",
regs->pc, regs->regs[15], regs->sr);
#ifdef CONFIG_MMU
- printk("TEA : %08x\n", ctrl_inl(MMU_TEA));
+ printk("TEA : %08x\n", __raw_readl(MMU_TEA));
#else
printk("\n");
#endif
@@ -147,21 +97,34 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
}
EXPORT_SYMBOL(kernel_thread);
+void start_thread(struct pt_regs *regs, unsigned long new_pc,
+ unsigned long new_sp)
+{
+ set_fs(USER_DS);
+
+ regs->pr = 0;
+ regs->sr = SR_FD;
+ regs->pc = new_pc;
+ regs->regs[15] = new_sp;
+
+ free_thread_xstate(current);
+}
+EXPORT_SYMBOL(start_thread);
+
/*
* Free current thread data structures etc..
*/
void exit_thread(void)
{
- if (current->thread.ubc_pc) {
- current->thread.ubc_pc = 0;
- ubc_usercnt -= 1;
- }
}
void flush_thread(void)
{
-#if defined(CONFIG_SH_FPU)
struct task_struct *tsk = current;
+
+ flush_ptrace_hw_breakpoint(tsk);
+
+#if defined(CONFIG_SH_FPU)
/* Forget lazy FPU state */
clear_fpu(tsk, task_pt_regs(tsk));
clear_used_math();
@@ -209,11 +172,10 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
{
struct thread_info *ti = task_thread_info(p);
struct pt_regs *childregs;
+
#if defined(CONFIG_SH_DSP)
struct task_struct *tsk = current;
-#endif
-#if defined(CONFIG_SH_DSP)
if (is_dsp_enabled(tsk)) {
/* We can use the __save_dsp or just copy the struct:
* __save_dsp(p);
@@ -244,53 +206,11 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
p->thread.sp = (unsigned long) childregs;
p->thread.pc = (unsigned long) ret_from_fork;
- p->thread.ubc_pc = 0;
+ memset(p->thread.ptrace_bps, 0, sizeof(p->thread.ptrace_bps));
return 0;
}
-/* Tracing by user break controller. */
-static void ubc_set_tracing(int asid, unsigned long pc)
-{
-#if defined(CONFIG_CPU_SH4A)
- unsigned long val;
-
- val = (UBC_CBR_ID_INST | UBC_CBR_RW_READ | UBC_CBR_CE);
- val |= (UBC_CBR_AIE | UBC_CBR_AIV_SET(asid));
-
- ctrl_outl(val, UBC_CBR0);
- ctrl_outl(pc, UBC_CAR0);
- ctrl_outl(0x0, UBC_CAMR0);
- ctrl_outl(0x0, UBC_CBCR);
-
- val = (UBC_CRR_RES | UBC_CRR_PCB | UBC_CRR_BIE);
- ctrl_outl(val, UBC_CRR0);
-
- /* Read UBC register that we wrote last, for checking update */
- val = ctrl_inl(UBC_CRR0);
-
-#else /* CONFIG_CPU_SH4A */
- ctrl_outl(pc, UBC_BARA);
-
-#ifdef CONFIG_MMU
- ctrl_outb(asid, UBC_BASRA);
-#endif
-
- ctrl_outl(0, UBC_BAMRA);
-
- if (current_cpu_data.type == CPU_SH7729 ||
- current_cpu_data.type == CPU_SH7710 ||
- current_cpu_data.type == CPU_SH7712 ||
- current_cpu_data.type == CPU_SH7203){
- ctrl_outw(BBR_INST | BBR_READ | BBR_CPU, UBC_BBRA);
- ctrl_outl(BRCR_PCBA | BRCR_PCTE, UBC_BRCR);
- } else {
- ctrl_outw(BBR_INST | BBR_READ, UBC_BBRA);
- ctrl_outw(BRCR_PCBA, UBC_BRCR);
- }
-#endif /* CONFIG_CPU_SH4A */
-}
-
/*
* switch_to(x,y) should switch tasks from x to y.
*
@@ -304,7 +224,7 @@ __switch_to(struct task_struct *prev, struct task_struct *next)
/* we're going to use this soon, after a few expensive things */
if (next->fpu_counter > 5)
- prefetch(&next_t->fpu.hard);
+ prefetch(next_t->xstate);
#ifdef CONFIG_MMU
/*
@@ -316,32 +236,13 @@ __switch_to(struct task_struct *prev, struct task_struct *next)
: "r" (task_thread_info(next)));
#endif
- /* If no tasks are using the UBC, we're done */
- if (ubc_usercnt == 0)
- /* If no tasks are using the UBC, we're done */;
- else if (next->thread.ubc_pc && next->mm) {
- int asid = 0;
-#ifdef CONFIG_MMU
- asid |= cpu_asid(smp_processor_id(), next->mm);
-#endif
- ubc_set_tracing(asid, next->thread.ubc_pc);
- } else {
-#if defined(CONFIG_CPU_SH4A)
- ctrl_outl(UBC_CBR_INIT, UBC_CBR0);
- ctrl_outl(UBC_CRR_INIT, UBC_CRR0);
-#else
- ctrl_outw(0, UBC_BBRA);
- ctrl_outw(0, UBC_BBRB);
-#endif
- }
-
/*
* If the task has used fpu the last 5 timeslices, just do a full
* restore of the math state immediately to avoid the trap; the
* chances of needing FPU soon are obviously high now
*/
if (next->fpu_counter > 5)
- fpu_state_restore(task_pt_regs(next));
+ __fpu_state_restore();
return prev;
}
@@ -434,20 +335,3 @@ unsigned long get_wchan(struct task_struct *p)
return pc;
}
-
-asmlinkage void break_point_trap(void)
-{
- /* Clear tracing. */
-#if defined(CONFIG_CPU_SH4A)
- ctrl_outl(UBC_CBR_INIT, UBC_CBR0);
- ctrl_outl(UBC_CRR_INIT, UBC_CRR0);
-#else
- ctrl_outw(0, UBC_BBRA);
- ctrl_outw(0, UBC_BBRB);
- ctrl_outl(0, UBC_BRCR);
-#endif
- current->thread.ubc_pc = 0;
- ubc_usercnt -= 1;
-
- force_sig(SIGTRAP, current);
-}
diff --git a/arch/sh/kernel/process_64.c b/arch/sh/kernel/process_64.c
index ec79faf6f02..c90957a459a 100644
--- a/arch/sh/kernel/process_64.c
+++ b/arch/sh/kernel/process_64.c
@@ -32,30 +32,7 @@
struct task_struct *last_task_used_math = NULL;
-void machine_restart(char * __unused)
-{
- extern void phys_stext(void);
-
- phys_stext();
-}
-
-void machine_halt(void)
-{
- for (;;);
-}
-
-void machine_power_off(void)
-{
- __asm__ __volatile__ (
- "sleep\n\t"
- "synci\n\t"
- "nop;nop;nop;nop\n\t"
- );
-
- panic("Unexpected wakeup!\n");
-}
-
-void show_regs(struct pt_regs * regs)
+void show_regs(struct pt_regs *regs)
{
unsigned long long ah, al, bh, bl, ch, cl;
@@ -410,7 +387,7 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu)
regs->sr |= SR_FD;
}
- memcpy(fpu, &tsk->thread.fpu.hard, sizeof(*fpu));
+ memcpy(fpu, &tsk->thread.xstate->hardfpu, sizeof(*fpu));
}
return fpvalid;
diff --git a/arch/sh/kernel/ptrace_32.c b/arch/sh/kernel/ptrace_32.c
index 9be35f34809..c625cdab76d 100644
--- a/arch/sh/kernel/ptrace_32.c
+++ b/arch/sh/kernel/ptrace_32.c
@@ -2,7 +2,7 @@
* SuperH process tracing
*
* Copyright (C) 1999, 2000 Kaz Kojima & Niibe Yutaka
- * Copyright (C) 2002 - 2008 Paul Mundt
+ * Copyright (C) 2002 - 2009 Paul Mundt
*
* Audit support by Yuichi Nakamura <ynakam@hitachisoft.jp>
*
@@ -26,6 +26,7 @@
#include <linux/tracehook.h>
#include <linux/elf.h>
#include <linux/regset.h>
+#include <linux/hw_breakpoint.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
#include <asm/system.h>
@@ -63,33 +64,64 @@ static inline int put_stack_long(struct task_struct *task, int offset,
return 0;
}
-void user_enable_single_step(struct task_struct *child)
+void ptrace_triggered(struct perf_event *bp, int nmi,
+ struct perf_sample_data *data, struct pt_regs *regs)
{
- /* Next scheduling will set up UBC */
- if (child->thread.ubc_pc == 0)
- ubc_usercnt += 1;
+ struct perf_event_attr attr;
+
+ /*
+ * Disable the breakpoint request here since ptrace has defined a
+ * one-shot behaviour for breakpoint exceptions.
+ */
+ attr = bp->attr;
+ attr.disabled = true;
+ modify_user_hw_breakpoint(bp, &attr);
+}
+
+static int set_single_step(struct task_struct *tsk, unsigned long addr)
+{
+ struct thread_struct *thread = &tsk->thread;
+ struct perf_event *bp;
+ struct perf_event_attr attr;
+
+ bp = thread->ptrace_bps[0];
+ if (!bp) {
+ hw_breakpoint_init(&attr);
+
+ attr.bp_addr = addr;
+ attr.bp_len = HW_BREAKPOINT_LEN_2;
+ attr.bp_type = HW_BREAKPOINT_R;
+
+ bp = register_user_hw_breakpoint(&attr, ptrace_triggered, tsk);
+ if (IS_ERR(bp))
+ return PTR_ERR(bp);
+
+ thread->ptrace_bps[0] = bp;
+ } else {
+ int err;
+
+ attr = bp->attr;
+ attr.bp_addr = addr;
+ err = modify_user_hw_breakpoint(bp, &attr);
+ if (unlikely(err))
+ return err;
+ }
+
+ return 0;
+}
- child->thread.ubc_pc = get_stack_long(child,
- offsetof(struct pt_regs, pc));
+void user_enable_single_step(struct task_struct *child)
+{
+ unsigned long pc = get_stack_long(child, offsetof(struct pt_regs, pc));
set_tsk_thread_flag(child, TIF_SINGLESTEP);
+
+ set_single_step(child, pc);
}
void user_disable_single_step(struct task_struct *child)
{
clear_tsk_thread_flag(child, TIF_SINGLESTEP);
-
- /*
- * Ensure the UBC is not programmed at the next context switch.
- *
- * Normally this is not needed but there are sequences such as
- * singlestep, signal delivery, and continue that leave the
- * ubc_pc non-zero leading to spurious SIGTRAPs.
- */
- if (child->thread.ubc_pc != 0) {
- ubc_usercnt -= 1;
- child->thread.ubc_pc = 0;
- }
}
/*
@@ -163,10 +195,10 @@ int fpregs_get(struct task_struct *target,
if ((boot_cpu_data.flags & CPU_HAS_FPU))
return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
- &target->thread.fpu.hard, 0, -1);
+ &target->thread.xstate->hardfpu, 0, -1);
return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
- &target->thread.fpu.soft, 0, -1);
+ &target->thread.xstate->softfpu, 0, -1);
}
static int fpregs_set(struct task_struct *target,
@@ -184,10 +216,10 @@ static int fpregs_set(struct task_struct *target,
if ((boot_cpu_data.flags & CPU_HAS_FPU))
return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
- &target->thread.fpu.hard, 0, -1);
+ &target->thread.xstate->hardfpu, 0, -1);
return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
- &target->thread.fpu.soft, 0, -1);
+ &target->thread.xstate->softfpu, 0, -1);
}
static int fpregs_active(struct task_struct *target,
@@ -333,7 +365,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
else
tmp = 0;
} else
- tmp = ((long *)&child->thread.fpu)
+ tmp = ((long *)child->thread.xstate)
[(addr - (long)&dummy->fpu) >> 2];
} else if (addr == (long) &dummy->u_fpvalid)
tmp = !!tsk_used_math(child);
@@ -362,7 +394,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
else if (addr >= (long) &dummy->fpu &&
addr < (long) &dummy->u_fpvalid) {
set_stopped_child_used_math(child);
- ((long *)&child->thread.fpu)
+ ((long *)child->thread.xstate)
[(addr - (long)&dummy->fpu) >> 2] = data;
ret = 0;
} else if (addr == (long) &dummy->u_fpvalid) {
diff --git a/arch/sh/kernel/ptrace_64.c b/arch/sh/kernel/ptrace_64.c
index b063eb8b18e..5fd644da7f0 100644
--- a/arch/sh/kernel/ptrace_64.c
+++ b/arch/sh/kernel/ptrace_64.c
@@ -88,7 +88,7 @@ get_fpu_long(struct task_struct *task, unsigned long addr)
regs->sr |= SR_FD;
}
- tmp = ((long *)&task->thread.fpu)[addr / sizeof(unsigned long)];
+ tmp = ((long *)task->thread.xstate)[addr / sizeof(unsigned long)];
return tmp;
}
@@ -114,8 +114,7 @@ put_fpu_long(struct task_struct *task, unsigned long addr, unsigned long data)
regs = (struct pt_regs*)((unsigned char *)task + THREAD_SIZE) - 1;
if (!tsk_used_math(task)) {
- fpinit(&task->thread.fpu.hard);
- set_stopped_child_used_math(task);
+ init_fpu(task);
} else if (last_task_used_math == task) {
enable_fpu();
save_fpu(task);
@@ -124,7 +123,7 @@ put_fpu_long(struct task_struct *task, unsigned long addr, unsigned long data)
regs->sr |= SR_FD;
}
- ((long *)&task->thread.fpu)[addr / sizeof(unsigned long)] = data;
+ ((long *)task->thread.xstate)[addr / sizeof(unsigned long)] = data;
return 0;
}
@@ -226,7 +225,7 @@ int fpregs_get(struct task_struct *target,
return ret;
return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
- &target->thread.fpu.hard, 0, -1);
+ &target->thread.xstate->hardfpu, 0, -1);
}
static int fpregs_set(struct task_struct *target,
@@ -243,7 +242,7 @@ static int fpregs_set(struct task_struct *target,
set_stopped_child_used_math(target);
return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
- &target->thread.fpu.hard, 0, -1);
+ &target->thread.xstate->hardfpu, 0, -1);
}
static int fpregs_active(struct task_struct *target,
@@ -486,9 +485,10 @@ asmlinkage void do_single_step(unsigned long long vec, struct pt_regs *regs)
}
/* Called with interrupts disabled */
-asmlinkage void do_software_break_point(unsigned long long vec,
- struct pt_regs *regs)
+BUILD_TRAP_HANDLER(breakpoint)
{
+ TRAP_HANDLER_DECL;
+
/* We need to forward step the PC, to counteract the backstep done
in signal.c. */
local_irq_enable();
diff --git a/arch/sh/kernel/reboot.c b/arch/sh/kernel/reboot.c
new file mode 100644
index 00000000000..b1fca66bb92
--- /dev/null
+++ b/arch/sh/kernel/reboot.c
@@ -0,0 +1,98 @@
+#include <linux/pm.h>
+#include <linux/kexec.h>
+#include <linux/kernel.h>
+#include <linux/reboot.h>
+#include <linux/module.h>
+#ifdef CONFIG_SUPERH32
+#include <asm/watchdog.h>
+#endif
+#include <asm/addrspace.h>
+#include <asm/reboot.h>
+#include <asm/system.h>
+
+void (*pm_power_off)(void);
+EXPORT_SYMBOL(pm_power_off);
+
+#ifdef CONFIG_SUPERH32
+static void watchdog_trigger_immediate(void)
+{
+ sh_wdt_write_cnt(0xFF);
+ sh_wdt_write_csr(0xC2);
+}
+#endif
+
+static void native_machine_restart(char * __unused)
+{
+ local_irq_disable();
+
+ /* Address error with SR.BL=1 first. */
+ trigger_address_error();
+
+#ifdef CONFIG_SUPERH32
+ /* If that fails or is unsupported, go for the watchdog next. */
+ watchdog_trigger_immediate();
+#endif
+
+ /*
+ * Give up and sleep.
+ */
+ while (1)
+ cpu_sleep();
+}
+
+static void native_machine_shutdown(void)
+{
+ smp_send_stop();
+}
+
+static void native_machine_power_off(void)
+{
+ if (pm_power_off)
+ pm_power_off();
+}
+
+static void native_machine_halt(void)
+{
+ /* stop other cpus */
+ machine_shutdown();
+
+ /* stop this cpu */
+ stop_this_cpu(NULL);
+}
+
+struct machine_ops machine_ops = {
+ .power_off = native_machine_power_off,
+ .shutdown = native_machine_shutdown,
+ .restart = native_machine_restart,
+ .halt = native_machine_halt,
+#ifdef CONFIG_KEXEC
+ .crash_shutdown = native_machine_crash_shutdown,
+#endif
+};
+
+void machine_power_off(void)
+{
+ machine_ops.power_off();
+}
+
+void machine_shutdown(void)
+{
+ machine_ops.shutdown();
+}
+
+void machine_restart(char *cmd)
+{
+ machine_ops.restart(cmd);
+}
+
+void machine_halt(void)
+{
+ machine_ops.halt();
+}
+
+#ifdef CONFIG_KEXEC
+void machine_crash_shutdown(struct pt_regs *regs)
+{
+ machine_ops.crash_shutdown(regs);
+}
+#endif
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index 8b0e69792cf..3459e70eed7 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -421,6 +421,8 @@ void __init setup_arch(char **cmdline_p)
parse_early_param();
+ uncached_init();
+
plat_early_device_setup();
/* Let earlyprintk output early console messages */
@@ -449,17 +451,15 @@ void __init setup_arch(char **cmdline_p)
#ifdef CONFIG_DUMMY_CONSOLE
conswitchp = &dummy_con;
#endif
+ paging_init();
+ pmb_init();
+
+ ioremap_fixed_init();
/* Perform the machine specific initialisation */
if (likely(sh_mv.mv_setup))
sh_mv.mv_setup(cmdline_p);
- paging_init();
-
-#ifdef CONFIG_PMB_ENABLE
- pmb_init();
-#endif
-
#ifdef CONFIG_SMP
plat_smp_setup();
#endif
diff --git a/arch/sh/kernel/sh_bios.c b/arch/sh/kernel/sh_bios.c
index c852f780572..47475cca068 100644
--- a/arch/sh/kernel/sh_bios.c
+++ b/arch/sh/kernel/sh_bios.c
@@ -1,19 +1,30 @@
/*
- * linux/arch/sh/kernel/sh_bios.c
* C interface for trapping into the standard LinuxSH BIOS.
*
* Copyright (C) 2000 Greg Banks, Mitch Davis
+ * Copyright (C) 1999, 2000 Niibe Yutaka
+ * Copyright (C) 2002 M. R. Brown
+ * Copyright (C) 2004 - 2010 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/module.h>
+#include <linux/console.h>
+#include <linux/tty.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/delay.h>
#include <asm/sh_bios.h>
#define BIOS_CALL_CONSOLE_WRITE 0
#define BIOS_CALL_ETH_NODE_ADDR 10
#define BIOS_CALL_SHUTDOWN 11
-#define BIOS_CALL_CHAR_OUT 0x1f /* TODO: hack */
#define BIOS_CALL_GDB_DETACH 0xff
+void *gdb_vbr_vector = NULL;
+
static inline long sh_bios_call(long func, long arg0, long arg1, long arg2,
long arg3)
{
@@ -23,6 +34,9 @@ static inline long sh_bios_call(long func, long arg0, long arg1, long arg2,
register long r6 __asm__("r6") = arg2;
register long r7 __asm__("r7") = arg3;
+ if (!gdb_vbr_vector)
+ return -ENOSYS;
+
__asm__ __volatile__("trapa #0x3f":"=z"(r0)
:"0"(r0), "r"(r4), "r"(r5), "r"(r6), "r"(r7)
:"memory");
@@ -34,11 +48,6 @@ void sh_bios_console_write(const char *buf, unsigned int len)
sh_bios_call(BIOS_CALL_CONSOLE_WRITE, (long)buf, (long)len, 0, 0);
}
-void sh_bios_char_out(char ch)
-{
- sh_bios_call(BIOS_CALL_CHAR_OUT, ch, 0, 0, 0);
-}
-
void sh_bios_gdb_detach(void)
{
sh_bios_call(BIOS_CALL_GDB_DETACH, 0, 0, 0, 0);
@@ -55,3 +64,109 @@ void sh_bios_shutdown(unsigned int how)
{
sh_bios_call(BIOS_CALL_SHUTDOWN, how, 0, 0, 0);
}
+
+/*
+ * Read the old value of the VBR register to initialise the vector
+ * through which debug and BIOS traps are delegated by the Linux trap
+ * handler.
+ */
+void sh_bios_vbr_init(void)
+{
+ unsigned long vbr;
+
+ if (unlikely(gdb_vbr_vector))
+ return;
+
+ __asm__ __volatile__ ("stc vbr, %0" : "=r" (vbr));
+
+ if (vbr) {
+ gdb_vbr_vector = (void *)(vbr + 0x100);
+ printk(KERN_NOTICE "Setting GDB trap vector to %p\n",
+ gdb_vbr_vector);
+ } else
+ printk(KERN_NOTICE "SH-BIOS not detected\n");
+}
+
+/**
+ * sh_bios_vbr_reload - Re-load the system VBR from the BIOS vector.
+ *
+ * This can be used by save/restore code to reinitialize the system VBR
+ * from the fixed BIOS VBR. A no-op if no BIOS VBR is known.
+ */
+void sh_bios_vbr_reload(void)
+{
+ if (gdb_vbr_vector)
+ __asm__ __volatile__ (
+ "ldc %0, vbr"
+ :
+ : "r" (((unsigned long) gdb_vbr_vector) - 0x100)
+ : "memory"
+ );
+}
+
+/*
+ * Print a string through the BIOS
+ */
+static void sh_console_write(struct console *co, const char *s,
+ unsigned count)
+{
+ sh_bios_console_write(s, count);
+}
+
+/*
+ * Setup initial baud/bits/parity. We do two things here:
+ * - construct a cflag setting for the first rs_open()
+ * - initialize the serial port
+ * Return non-zero if we didn't find a serial port.
+ */
+static int __init sh_console_setup(struct console *co, char *options)
+{
+ int cflag = CREAD | HUPCL | CLOCAL;
+
+ /*
+ * Now construct a cflag setting.
+ * TODO: this is a totally bogus cflag, as we have
+ * no idea what serial settings the BIOS is using, or
+ * even if its using the serial port at all.
+ */
+ cflag |= B115200 | CS8 | /*no parity*/0;
+
+ co->cflag = cflag;
+
+ return 0;
+}
+
+static struct console bios_console = {
+ .name = "bios",
+ .write = sh_console_write,
+ .setup = sh_console_setup,
+ .flags = CON_PRINTBUFFER,
+ .index = -1,
+};
+
+static struct console *early_console;
+
+static int __init setup_early_printk(char *buf)
+{
+ int keep_early = 0;
+
+ if (!buf)
+ return 0;
+
+ if (strstr(buf, "keep"))
+ keep_early = 1;
+
+ if (!strncmp(buf, "bios", 4))
+ early_console = &bios_console;
+
+ if (likely(early_console)) {
+ if (keep_early)
+ early_console->flags &= ~CON_BOOT;
+ else
+ early_console->flags |= CON_BOOT;
+ register_console(early_console);
+ }
+
+ return 0;
+}
+early_param("earlyprintk", setup_early_printk);
diff --git a/arch/sh/kernel/signal_32.c b/arch/sh/kernel/signal_32.c
index 12815ce01ec..579cd2ca358 100644
--- a/arch/sh/kernel/signal_32.c
+++ b/arch/sh/kernel/signal_32.c
@@ -150,7 +150,7 @@ static inline int restore_sigcontext_fpu(struct sigcontext __user *sc)
return 0;
set_used_math();
- return __copy_from_user(&tsk->thread.fpu.hard, &sc->sc_fpregs[0],
+ return __copy_from_user(&tsk->thread.xstate->hardfpu, &sc->sc_fpregs[0],
sizeof(long)*(16*2+2));
}
@@ -175,7 +175,7 @@ static inline int save_sigcontext_fpu(struct sigcontext __user *sc,
clear_used_math();
unlazy_fpu(tsk, regs);
- return __copy_to_user(&sc->sc_fpregs[0], &tsk->thread.fpu.hard,
+ return __copy_to_user(&sc->sc_fpregs[0], &tsk->thread.xstate->hardfpu,
sizeof(long)*(16*2+2));
}
#endif /* CONFIG_SH_FPU */
@@ -528,7 +528,7 @@ handle_syscall_restart(unsigned long save_r0, struct pt_regs *regs,
/* fallthrough */
case -ERESTARTNOINTR:
regs->regs[0] = save_r0;
- regs->pc -= instruction_size(ctrl_inw(regs->pc - 4));
+ regs->pc -= instruction_size(__raw_readw(regs->pc - 4));
break;
}
}
@@ -626,9 +626,9 @@ no_signal:
regs->regs[0] == -ERESTARTSYS ||
regs->regs[0] == -ERESTARTNOINTR) {
regs->regs[0] = save_r0;
- regs->pc -= instruction_size(ctrl_inw(regs->pc - 4));
+ regs->pc -= instruction_size(__raw_readw(regs->pc - 4));
} else if (regs->regs[0] == -ERESTART_RESTARTBLOCK) {
- regs->pc -= instruction_size(ctrl_inw(regs->pc - 4));
+ regs->pc -= instruction_size(__raw_readw(regs->pc - 4));
regs->regs[3] = __NR_restart_syscall;
}
}
diff --git a/arch/sh/kernel/signal_64.c b/arch/sh/kernel/signal_64.c
index 580e97d46ca..5a9f1f10ebf 100644
--- a/arch/sh/kernel/signal_64.c
+++ b/arch/sh/kernel/signal_64.c
@@ -297,7 +297,7 @@ restore_sigcontext_fpu(struct pt_regs *regs, struct sigcontext __user *sc)
regs->sr |= SR_FD;
}
- err |= __copy_from_user(&current->thread.fpu.hard, &sc->sc_fpregs[0],
+ err |= __copy_from_user(&current->thread.xstate->hardfpu, &sc->sc_fpregs[0],
(sizeof(long long) * 32) + (sizeof(int) * 1));
return err;
@@ -322,7 +322,7 @@ setup_sigcontext_fpu(struct pt_regs *regs, struct sigcontext __user *sc)
regs->sr |= SR_FD;
}
- err |= __copy_to_user(&sc->sc_fpregs[0], &current->thread.fpu.hard,
+ err |= __copy_to_user(&sc->sc_fpregs[0], &current->thread.xstate->hardfpu,
(sizeof(long long) * 32) + (sizeof(int) * 1));
clear_used_math();
diff --git a/arch/sh/kernel/smp.c b/arch/sh/kernel/smp.c
index 983e0792d5f..e124cf7008d 100644
--- a/arch/sh/kernel/smp.c
+++ b/arch/sh/kernel/smp.c
@@ -161,15 +161,6 @@ void smp_send_reschedule(int cpu)
plat_send_ipi(cpu, SMP_MSG_RESCHEDULE);
}
-static void stop_this_cpu(void *unused)
-{
- cpu_clear(smp_processor_id(), cpu_online_map);
- local_irq_disable();
-
- for (;;)
- cpu_relax();
-}
-
void smp_send_stop(void)
{
smp_call_function(stop_this_cpu, 0, 0);
diff --git a/arch/sh/kernel/traps.c b/arch/sh/kernel/traps.c
index 7b036339dc9..0830c2a9f71 100644
--- a/arch/sh/kernel/traps.c
+++ b/arch/sh/kernel/traps.c
@@ -58,7 +58,7 @@ BUILD_TRAP_HANDLER(debug)
TRAP_HANDLER_DECL;
/* Rewind */
- regs->pc -= instruction_size(ctrl_inw(regs->pc - 4));
+ regs->pc -= instruction_size(__raw_readw(regs->pc - 4));
if (notify_die(DIE_TRAP, "debug trap", regs, 0, vec & 0xff,
SIGTRAP) == NOTIFY_STOP)
@@ -75,7 +75,7 @@ BUILD_TRAP_HANDLER(bug)
TRAP_HANDLER_DECL;
/* Rewind */
- regs->pc -= instruction_size(ctrl_inw(regs->pc - 4));
+ regs->pc -= instruction_size(__raw_readw(regs->pc - 4));
if (notify_die(DIE_TRAP, "bug trap", regs, 0, TRAPA_BUG_OPCODE & 0xff,
SIGTRAP) == NOTIFY_STOP)
diff --git a/arch/sh/kernel/traps_32.c b/arch/sh/kernel/traps_32.c
index 86639beac3a..c3d86fa71dd 100644
--- a/arch/sh/kernel/traps_32.c
+++ b/arch/sh/kernel/traps_32.c
@@ -24,11 +24,10 @@
#include <linux/kdebug.h>
#include <linux/kexec.h>
#include <linux/limits.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
#include <linux/sysfs.h>
+#include <linux/uaccess.h>
#include <asm/system.h>
-#include <asm/uaccess.h>
+#include <asm/alignment.h>
#include <asm/fpu.h>
#include <asm/kprobes.h>
@@ -47,73 +46,6 @@
#define TRAP_ILLEGAL_SLOT_INST 13
#endif
-static unsigned long se_user;
-static unsigned long se_sys;
-static unsigned long se_half;
-static unsigned long se_word;
-static unsigned long se_dword;
-static unsigned long se_multi;
-/* bitfield: 1: warn 2: fixup 4: signal -> combinations 2|4 && 1|2|4 are not
- valid! */
-static int se_usermode = 3;
-/* 0: no warning 1: print a warning message, disabled by default */
-static int se_kernmode_warn;
-
-#ifdef CONFIG_PROC_FS
-static const char *se_usermode_action[] = {
- "ignored",
- "warn",
- "fixup",
- "fixup+warn",
- "signal",
- "signal+warn"
-};
-
-static int alignment_proc_show(struct seq_file *m, void *v)
-{
- seq_printf(m, "User:\t\t%lu\n", se_user);
- seq_printf(m, "System:\t\t%lu\n", se_sys);
- seq_printf(m, "Half:\t\t%lu\n", se_half);
- seq_printf(m, "Word:\t\t%lu\n", se_word);
- seq_printf(m, "DWord:\t\t%lu\n", se_dword);
- seq_printf(m, "Multi:\t\t%lu\n", se_multi);
- seq_printf(m, "User faults:\t%i (%s)\n", se_usermode,
- se_usermode_action[se_usermode]);
- seq_printf(m, "Kernel faults:\t%i (fixup%s)\n", se_kernmode_warn,
- se_kernmode_warn ? "+warn" : "");
- return 0;
-}
-
-static int alignment_proc_open(struct inode *inode, struct file *file)
-{
- return single_open(file, alignment_proc_show, NULL);
-}
-
-static ssize_t alignment_proc_write(struct file *file,
- const char __user *buffer, size_t count, loff_t *pos)
-{
- int *data = PDE(file->f_path.dentry->d_inode)->data;
- char mode;
-
- if (count > 0) {
- if (get_user(mode, buffer))
- return -EFAULT;
- if (mode >= '0' && mode <= '5')
- *data = mode - '0';
- }
- return count;
-}
-
-static const struct file_operations alignment_proc_fops = {
- .owner = THIS_MODULE,
- .open = alignment_proc_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
- .write = alignment_proc_write,
-};
-#endif
-
static void dump_mem(const char *str, unsigned long bottom, unsigned long top)
{
unsigned long p;
@@ -265,10 +197,10 @@ static int handle_unaligned_ins(insn_size_t instruction, struct pt_regs *regs,
count = 1<<(instruction&3);
switch (count) {
- case 1: se_half += 1; break;
- case 2: se_word += 1; break;
- case 4: se_dword += 1; break;
- case 8: se_multi += 1; break; /* ??? */
+ case 1: inc_unaligned_byte_access(); break;
+ case 2: inc_unaligned_word_access(); break;
+ case 4: inc_unaligned_dword_access(); break;
+ case 8: inc_unaligned_multi_access(); break;
}
ret = -EFAULT;
@@ -452,18 +384,8 @@ int handle_unaligned_access(insn_size_t instruction, struct pt_regs *regs,
rm = regs->regs[index];
/* shout about fixups */
- if (!expected) {
- if (user_mode(regs) && (se_usermode & 1) && printk_ratelimit())
- pr_notice("Fixing up unaligned userspace access "
- "in \"%s\" pid=%d pc=0x%p ins=0x%04hx\n",
- current->comm, task_pid_nr(current),
- (void *)regs->pc, instruction);
- else if (se_kernmode_warn && printk_ratelimit())
- pr_notice("Fixing up unaligned kernel access "
- "in \"%s\" pid=%d pc=0x%p ins=0x%04hx\n",
- current->comm, task_pid_nr(current),
- (void *)regs->pc, instruction);
- }
+ if (!expected)
+ unaligned_fixups_notify(current, instruction, regs);
ret = -EFAULT;
switch (instruction&0xF000) {
@@ -616,10 +538,10 @@ asmlinkage void do_address_error(struct pt_regs *regs,
if (user_mode(regs)) {
int si_code = BUS_ADRERR;
+ unsigned int user_action;
local_irq_enable();
-
- se_user += 1;
+ inc_unaligned_user_access();
set_fs(USER_DS);
if (copy_from_user(&instruction, (insn_size_t *)(regs->pc & ~1),
@@ -630,16 +552,12 @@ asmlinkage void do_address_error(struct pt_regs *regs,
set_fs(oldfs);
/* shout about userspace fixups */
- if (se_usermode & 1)
- printk(KERN_NOTICE "Unaligned userspace access "
- "in \"%s\" pid=%d pc=0x%p ins=0x%04hx\n",
- current->comm, current->pid, (void *)regs->pc,
- instruction);
+ unaligned_fixups_notify(current, instruction, regs);
- if (se_usermode & 2)
+ user_action = unaligned_user_action();
+ if (user_action & UM_FIXUP)
goto fixup;
-
- if (se_usermode & 4)
+ if (user_action & UM_SIGNAL)
goto uspace_segv;
else {
/* ignore */
@@ -659,7 +577,7 @@ fixup:
&user_mem_access, 0);
set_fs(oldfs);
- if (tmp==0)
+ if (tmp == 0)
return; /* sorted */
uspace_segv:
printk(KERN_NOTICE "Sending SIGBUS to \"%s\" due to unaligned "
@@ -672,7 +590,7 @@ uspace_segv:
info.si_addr = (void __user *)address;
force_sig_info(SIGBUS, &info, current);
} else {
- se_sys += 1;
+ inc_unaligned_kernel_access();
if (regs->pc & 1)
die("unaligned program counter", regs, error_code);
@@ -687,11 +605,7 @@ uspace_segv:
die("insn faulting in do_address_error", regs, 0);
}
- if (se_kernmode_warn)
- printk(KERN_NOTICE "Unaligned kernel access "
- "on behalf of \"%s\" pid=%d pc=0x%p ins=0x%04hx\n",
- current->comm, current->pid, (void *)regs->pc,
- instruction);
+ unaligned_fixups_notify(current, instruction, regs);
handle_unaligned_access(instruction, regs,
&user_mem_access, 0);
@@ -876,35 +790,10 @@ asmlinkage void do_exception_error(unsigned long r4, unsigned long r5,
die_if_kernel("exception", regs, ex);
}
-#if defined(CONFIG_SH_STANDARD_BIOS)
-void *gdb_vbr_vector;
-
-static inline void __init gdb_vbr_init(void)
-{
- register unsigned long vbr;
-
- /*
- * Read the old value of the VBR register to initialise
- * the vector through which debug and BIOS traps are
- * delegated by the Linux trap handler.
- */
- asm volatile("stc vbr, %0" : "=r" (vbr));
-
- gdb_vbr_vector = (void *)(vbr + 0x100);
- printk("Setting GDB trap vector to 0x%08lx\n",
- (unsigned long)gdb_vbr_vector);
-}
-#endif
-
void __cpuinit per_cpu_trap_init(void)
{
extern void *vbr_base;
-#ifdef CONFIG_SH_STANDARD_BIOS
- if (raw_smp_processor_id() == 0)
- gdb_vbr_init();
-#endif
-
/* NOTE: The VBR value should be at P1
(or P2, virtural "fixed" address space).
It's definitely should not in physical address. */
@@ -956,11 +845,8 @@ void __init trap_init(void)
#endif
#ifdef TRAP_UBC
- set_exception_table_vec(TRAP_UBC, break_point_trap);
+ set_exception_table_vec(TRAP_UBC, breakpoint_trap_handler);
#endif
-
- /* Setup VBR for boot cpu */
- per_cpu_trap_init();
}
void show_stack(struct task_struct *tsk, unsigned long *sp)
@@ -985,34 +871,3 @@ void dump_stack(void)
show_stack(NULL, NULL);
}
EXPORT_SYMBOL(dump_stack);
-
-#ifdef CONFIG_PROC_FS
-/*
- * This needs to be done after sysctl_init, otherwise sys/ will be
- * overwritten. Actually, this shouldn't be in sys/ at all since
- * it isn't a sysctl, and it doesn't contain sysctl information.
- * We now locate it in /proc/cpu/alignment instead.
- */
-static int __init alignment_init(void)
-{
- struct proc_dir_entry *dir, *res;
-
- dir = proc_mkdir("cpu", NULL);
- if (!dir)
- return -ENOMEM;
-
- res = proc_create_data("alignment", S_IWUSR | S_IRUGO, dir,
- &alignment_proc_fops, &se_usermode);
- if (!res)
- return -ENOMEM;
-
- res = proc_create_data("kernel_alignment", S_IWUSR | S_IRUGO, dir,
- &alignment_proc_fops, &se_kernmode_warn);
- if (!res)
- return -ENOMEM;
-
- return 0;
-}
-
-fs_initcall(alignment_init);
-#endif
diff --git a/arch/sh/kernel/traps_64.c b/arch/sh/kernel/traps_64.c
index d86f5315a0c..e3f92eb05ff 100644
--- a/arch/sh/kernel/traps_64.c
+++ b/arch/sh/kernel/traps_64.c
@@ -611,19 +611,19 @@ static int misaligned_fpu_load(struct pt_regs *regs,
switch (width_shift) {
case 2:
- current->thread.fpu.hard.fp_regs[destreg] = buflo;
+ current->thread.xstate->hardfpu.fp_regs[destreg] = buflo;
break;
case 3:
if (do_paired_load) {
- current->thread.fpu.hard.fp_regs[destreg] = buflo;
- current->thread.fpu.hard.fp_regs[destreg+1] = bufhi;
+ current->thread.xstate->hardfpu.fp_regs[destreg] = buflo;
+ current->thread.xstate->hardfpu.fp_regs[destreg+1] = bufhi;
} else {
#if defined(CONFIG_CPU_LITTLE_ENDIAN)
- current->thread.fpu.hard.fp_regs[destreg] = bufhi;
- current->thread.fpu.hard.fp_regs[destreg+1] = buflo;
+ current->thread.xstate->hardfpu.fp_regs[destreg] = bufhi;
+ current->thread.xstate->hardfpu.fp_regs[destreg+1] = buflo;
#else
- current->thread.fpu.hard.fp_regs[destreg] = buflo;
- current->thread.fpu.hard.fp_regs[destreg+1] = bufhi;
+ current->thread.xstate->hardfpu.fp_regs[destreg] = buflo;
+ current->thread.xstate->hardfpu.fp_regs[destreg+1] = bufhi;
#endif
}
break;
@@ -681,19 +681,19 @@ static int misaligned_fpu_store(struct pt_regs *regs,
switch (width_shift) {
case 2:
- buflo = current->thread.fpu.hard.fp_regs[srcreg];
+ buflo = current->thread.xstate->hardfpu.fp_regs[srcreg];
break;
case 3:
if (do_paired_load) {
- buflo = current->thread.fpu.hard.fp_regs[srcreg];
- bufhi = current->thread.fpu.hard.fp_regs[srcreg+1];
+ buflo = current->thread.xstate->hardfpu.fp_regs[srcreg];
+ bufhi = current->thread.xstate->hardfpu.fp_regs[srcreg+1];
} else {
#if defined(CONFIG_CPU_LITTLE_ENDIAN)
- bufhi = current->thread.fpu.hard.fp_regs[srcreg];
- buflo = current->thread.fpu.hard.fp_regs[srcreg+1];
+ bufhi = current->thread.xstate->hardfpu.fp_regs[srcreg];
+ buflo = current->thread.xstate->hardfpu.fp_regs[srcreg+1];
#else
- buflo = current->thread.fpu.hard.fp_regs[srcreg];
- bufhi = current->thread.fpu.hard.fp_regs[srcreg+1];
+ buflo = current->thread.xstate->hardfpu.fp_regs[srcreg];
+ bufhi = current->thread.xstate->hardfpu.fp_regs[srcreg+1];
#endif
}
break;
diff --git a/arch/sh/kernel/vmlinux.lds.S b/arch/sh/kernel/vmlinux.lds.S
index a1e4ec24f1f..7f8a709c3ad 100644
--- a/arch/sh/kernel/vmlinux.lds.S
+++ b/arch/sh/kernel/vmlinux.lds.S
@@ -3,7 +3,7 @@
* Written by Niibe Yutaka and Paul Mundt
*/
#ifdef CONFIG_SUPERH64
-#define LOAD_OFFSET CONFIG_PAGE_OFFSET
+#define LOAD_OFFSET PAGE_OFFSET
OUTPUT_ARCH(sh:sh5)
#else
#define LOAD_OFFSET 0
@@ -14,17 +14,16 @@ OUTPUT_ARCH(sh)
#include <asm/cache.h>
#include <asm/vmlinux.lds.h>
+#ifdef CONFIG_PMB
+ #define MEMORY_OFFSET 0
+#else
+ #define MEMORY_OFFSET __MEMORY_START
+#endif
+
ENTRY(_start)
SECTIONS
{
-#ifdef CONFIG_PMB_FIXED
- . = CONFIG_PAGE_OFFSET + (CONFIG_MEMORY_START & 0x1fffffff) +
- CONFIG_ZERO_PAGE_OFFSET;
-#elif defined(CONFIG_32BIT)
- . = CONFIG_PAGE_OFFSET + CONFIG_ZERO_PAGE_OFFSET;
-#else
- . = CONFIG_PAGE_OFFSET + CONFIG_MEMORY_START + CONFIG_ZERO_PAGE_OFFSET;
-#endif
+ . = PAGE_OFFSET + MEMORY_OFFSET + CONFIG_ZERO_PAGE_OFFSET;
_text = .; /* Text and read-only data */
@@ -35,12 +34,7 @@ SECTIONS
.text : AT(ADDR(.text) - LOAD_OFFSET) {
HEAD_TEXT
TEXT_TEXT
-
-#ifdef CONFIG_SUPERH64
- *(.text64)
- *(.text..SHmedia32)
-#endif
-
+ EXTRA_TEXT
SCHED_TEXT
LOCK_TEXT
KPROBES_TEXT
@@ -51,24 +45,12 @@ SECTIONS
} = 0x0009
EXCEPTION_TABLE(16)
-
NOTES
- RO_DATA(PAGE_SIZE)
-
- /*
- * Code which must be executed uncached and the associated data
- */
- . = ALIGN(PAGE_SIZE);
- .uncached : AT(ADDR(.uncached) - LOAD_OFFSET) {
- __uncached_start = .;
- *(.uncached.text)
- *(.uncached.data)
- __uncached_end = .;
- }
+ _sdata = .;
+ RO_DATA(PAGE_SIZE)
RW_DATA_SECTION(L1_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE)
-
- _edata = .; /* End of data section */
+ _edata = .;
DWARF_EH_FRAME
diff --git a/arch/sh/math-emu/math.c b/arch/sh/math-emu/math.c
index d6c15cae091..1fcdb122097 100644
--- a/arch/sh/math-emu/math.c
+++ b/arch/sh/math-emu/math.c
@@ -471,10 +471,10 @@ static int fpu_emulate(u16 code, struct sh_fpu_soft_struct *fregs, struct pt_reg
* denormal_to_double - Given denormalized float number,
* store double float
*
- * @fpu: Pointer to sh_fpu_hard structure
+ * @fpu: Pointer to sh_fpu_soft structure
* @n: Index to FP register
*/
-static void denormal_to_double(struct sh_fpu_hard_struct *fpu, int n)
+static void denormal_to_double(struct sh_fpu_soft_struct *fpu, int n)
{
unsigned long du, dl;
unsigned long x = fpu->fpul;
@@ -552,11 +552,11 @@ static int ieee_fpe_handler(struct pt_regs *regs)
if ((finsn & 0xf1ff) == 0xf0ad) { /* fcnvsd */
struct task_struct *tsk = current;
- if ((tsk->thread.fpu.hard.fpscr & (1 << 17))) {
+ if ((tsk->thread.xstate->softfpu.fpscr & (1 << 17))) {
/* FPU error */
- denormal_to_double (&tsk->thread.fpu.hard,
+ denormal_to_double (&tsk->thread.xstate->softfpu,
(finsn >> 8) & 0xf);
- tsk->thread.fpu.hard.fpscr &=
+ tsk->thread.xstate->softfpu.fpscr &=
~(FPSCR_CAUSE_MASK | FPSCR_FLAG_MASK);
task_thread_info(tsk)->status |= TS_USEDFPU;
} else {
@@ -617,7 +617,7 @@ static void fpu_init(struct sh_fpu_soft_struct *fpu)
int do_fpu_inst(unsigned short inst, struct pt_regs *regs)
{
struct task_struct *tsk = current;
- struct sh_fpu_soft_struct *fpu = &(tsk->thread.fpu.soft);
+ struct sh_fpu_soft_struct *fpu = &(tsk->thread.xstate->softfpu);
if (!(task_thread_info(tsk)->status & TS_USEDFPU)) {
/* initialize once. */
diff --git a/arch/sh/mm/Kconfig b/arch/sh/mm/Kconfig
index 986a71b88ca..1445ca6257d 100644
--- a/arch/sh/mm/Kconfig
+++ b/arch/sh/mm/Kconfig
@@ -75,52 +75,25 @@ config MEMORY_SIZE
config 29BIT
def_bool !32BIT
depends on SUPERH32
+ select UNCACHED_MAPPING
config 32BIT
bool
default y if CPU_SH5
-config PMB_ENABLE
- bool "Support 32-bit physical addressing through PMB"
- depends on MMU && EXPERIMENTAL && CPU_SH4A && !CPU_SH4AL_DSP
- help
- If you say Y here, physical addressing will be extended to
- 32-bits through the SH-4A PMB. If this is not set, legacy
- 29-bit physical addressing will be used.
-
-choice
- prompt "PMB handling type"
- depends on PMB_ENABLE
- default PMB_FIXED
-
config PMB
- bool "PMB"
+ bool "Support 32-bit physical addressing through PMB"
depends on MMU && EXPERIMENTAL && CPU_SH4A && !CPU_SH4AL_DSP
+ select 32BIT
+ select UNCACHED_MAPPING
help
If you say Y here, physical addressing will be extended to
32-bits through the SH-4A PMB. If this is not set, legacy
29-bit physical addressing will be used.
-config PMB_FIXED
- bool "fixed PMB"
- depends on MMU && EXPERIMENTAL && CPU_SH4A && !CPU_SH4AL_DSP
- select 32BIT
- help
- If this option is enabled, fixed PMB mappings are inherited
- from the boot loader, and the kernel does not attempt dynamic
- management. This is the closest to legacy 29-bit physical mode,
- and allows systems to support up to 512MiB of system memory.
-
-endchoice
-
config X2TLB
- bool "Enable extended TLB mode"
- depends on (CPU_SHX2 || CPU_SHX3) && MMU && EXPERIMENTAL
- help
- Selecting this option will enable the extended mode of the SH-X2
- TLB. For legacy SH-X behaviour and interoperability, say N. For
- all of the fun new features and a willingless to submit bug reports,
- say Y.
+ def_bool y
+ depends on (CPU_SHX2 || CPU_SHX3) && MMU
config VSYSCALL
bool "Support vsyscall page"
@@ -188,14 +161,19 @@ config ARCH_MEMORY_PROBE
def_bool y
depends on MEMORY_HOTPLUG
+config IOREMAP_FIXED
+ def_bool y
+ depends on X2TLB || SUPERH64
+
+config UNCACHED_MAPPING
+ bool
+
choice
prompt "Kernel page size"
- default PAGE_SIZE_8KB if X2TLB
default PAGE_SIZE_4KB
config PAGE_SIZE_4KB
bool "4kB"
- depends on !MMU || !X2TLB
help
This is the default page size used by all SuperH CPUs.
diff --git a/arch/sh/mm/Makefile b/arch/sh/mm/Makefile
index 8a70535fa7c..3dc8a8a6382 100644
--- a/arch/sh/mm/Makefile
+++ b/arch/sh/mm/Makefile
@@ -2,7 +2,7 @@
# Makefile for the Linux SuperH-specific parts of the memory manager.
#
-obj-y := cache.o init.o consistent.o mmap.o
+obj-y := alignment.o cache.o init.o consistent.o mmap.o
cacheops-$(CONFIG_CPU_SH2) := cache-sh2.o
cacheops-$(CONFIG_CPU_SH2A) := cache-sh2a.o
@@ -15,7 +15,7 @@ obj-y += $(cacheops-y)
mmu-y := nommu.o extable_32.o
mmu-$(CONFIG_MMU) := extable_$(BITS).o fault_$(BITS).o \
- ioremap_$(BITS).o kmap.o tlbflush_$(BITS).o
+ ioremap.o kmap.o pgtable.o tlbflush_$(BITS).o
obj-y += $(mmu-y)
obj-$(CONFIG_DEBUG_FS) += asids-debugfs.o
@@ -26,15 +26,17 @@ endif
ifdef CONFIG_MMU
tlb-$(CONFIG_CPU_SH3) := tlb-sh3.o
-tlb-$(CONFIG_CPU_SH4) := tlb-sh4.o
+tlb-$(CONFIG_CPU_SH4) := tlb-sh4.o tlb-urb.o
tlb-$(CONFIG_CPU_SH5) := tlb-sh5.o
-tlb-$(CONFIG_CPU_HAS_PTEAEX) := tlb-pteaex.o
+tlb-$(CONFIG_CPU_HAS_PTEAEX) := tlb-pteaex.o tlb-urb.o
obj-y += $(tlb-y)
endif
obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
-obj-$(CONFIG_PMB_ENABLE) += pmb.o
+obj-$(CONFIG_PMB) += pmb.o
obj-$(CONFIG_NUMA) += numa.o
+obj-$(CONFIG_IOREMAP_FIXED) += ioremap_fixed.o
+obj-$(CONFIG_UNCACHED_MAPPING) += uncached.o
# Special flags for fault_64.o. This puts restrictions on the number of
# caller-save registers that the compiler can target when building this file.
diff --git a/arch/sh/mm/alignment.c b/arch/sh/mm/alignment.c
new file mode 100644
index 00000000000..b2595b8548e
--- /dev/null
+++ b/arch/sh/mm/alignment.c
@@ -0,0 +1,189 @@
+/*
+ * Alignment access counters and corresponding user-space interfaces.
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Copyright (C) 2009 - 2010 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/module.h>
+#include <linux/kernel.h>
+#include <linux/seq_file.h>
+#include <linux/proc_fs.h>
+#include <linux/uaccess.h>
+#include <asm/alignment.h>
+#include <asm/processor.h>
+
+static unsigned long se_user;
+static unsigned long se_sys;
+static unsigned long se_half;
+static unsigned long se_word;
+static unsigned long se_dword;
+static unsigned long se_multi;
+/* bitfield: 1: warn 2: fixup 4: signal -> combinations 2|4 && 1|2|4 are not
+ valid! */
+static int se_usermode = UM_WARN | UM_FIXUP;
+/* 0: no warning 1: print a warning message, disabled by default */
+static int se_kernmode_warn;
+
+core_param(alignment, se_usermode, int, 0600);
+
+void inc_unaligned_byte_access(void)
+{
+ se_half++;
+}
+
+void inc_unaligned_word_access(void)
+{
+ se_word++;
+}
+
+void inc_unaligned_dword_access(void)
+{
+ se_dword++;
+}
+
+void inc_unaligned_multi_access(void)
+{
+ se_multi++;
+}
+
+void inc_unaligned_user_access(void)
+{
+ se_user++;
+}
+
+void inc_unaligned_kernel_access(void)
+{
+ se_sys++;
+}
+
+/*
+ * This defaults to the global policy which can be set from the command
+ * line, while processes can overload their preferences via prctl().
+ */
+unsigned int unaligned_user_action(void)
+{
+ unsigned int action = se_usermode;
+
+ if (current->thread.flags & SH_THREAD_UAC_SIGBUS) {
+ action &= ~UM_FIXUP;
+ action |= UM_SIGNAL;
+ }
+
+ if (current->thread.flags & SH_THREAD_UAC_NOPRINT)
+ action &= ~UM_WARN;
+
+ return action;
+}
+
+int get_unalign_ctl(struct task_struct *tsk, unsigned long addr)
+{
+ return put_user(tsk->thread.flags & SH_THREAD_UAC_MASK,
+ (unsigned int __user *)addr);
+}
+
+int set_unalign_ctl(struct task_struct *tsk, unsigned int val)
+{
+ tsk->thread.flags = (tsk->thread.flags & ~SH_THREAD_UAC_MASK) |
+ (val & SH_THREAD_UAC_MASK);
+ return 0;
+}
+
+void unaligned_fixups_notify(struct task_struct *tsk, insn_size_t insn,
+ struct pt_regs *regs)
+{
+ if (user_mode(regs) && (se_usermode & UM_WARN) && printk_ratelimit())
+ pr_notice("Fixing up unaligned userspace access "
+ "in \"%s\" pid=%d pc=0x%p ins=0x%04hx\n",
+ tsk->comm, task_pid_nr(tsk),
+ (void *)instruction_pointer(regs), insn);
+ else if (se_kernmode_warn && printk_ratelimit())
+ pr_notice("Fixing up unaligned kernel access "
+ "in \"%s\" pid=%d pc=0x%p ins=0x%04hx\n",
+ tsk->comm, task_pid_nr(tsk),
+ (void *)instruction_pointer(regs), insn);
+}
+
+static const char *se_usermode_action[] = {
+ "ignored",
+ "warn",
+ "fixup",
+ "fixup+warn",
+ "signal",
+ "signal+warn"
+};
+
+static int alignment_proc_show(struct seq_file *m, void *v)
+{
+ seq_printf(m, "User:\t\t%lu\n", se_user);
+ seq_printf(m, "System:\t\t%lu\n", se_sys);
+ seq_printf(m, "Half:\t\t%lu\n", se_half);
+ seq_printf(m, "Word:\t\t%lu\n", se_word);
+ seq_printf(m, "DWord:\t\t%lu\n", se_dword);
+ seq_printf(m, "Multi:\t\t%lu\n", se_multi);
+ seq_printf(m, "User faults:\t%i (%s)\n", se_usermode,
+ se_usermode_action[se_usermode]);
+ seq_printf(m, "Kernel faults:\t%i (fixup%s)\n", se_kernmode_warn,
+ se_kernmode_warn ? "+warn" : "");
+ return 0;
+}
+
+static int alignment_proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, alignment_proc_show, NULL);
+}
+
+static ssize_t alignment_proc_write(struct file *file,
+ const char __user *buffer, size_t count, loff_t *pos)
+{
+ int *data = PDE(file->f_path.dentry->d_inode)->data;
+ char mode;
+
+ if (count > 0) {
+ if (get_user(mode, buffer))
+ return -EFAULT;
+ if (mode >= '0' && mode <= '5')
+ *data = mode - '0';
+ }
+ return count;
+}
+
+static const struct file_operations alignment_proc_fops = {
+ .owner = THIS_MODULE,
+ .open = alignment_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+ .write = alignment_proc_write,
+};
+
+/*
+ * This needs to be done after sysctl_init, otherwise sys/ will be
+ * overwritten. Actually, this shouldn't be in sys/ at all since
+ * it isn't a sysctl, and it doesn't contain sysctl information.
+ * We now locate it in /proc/cpu/alignment instead.
+ */
+static int __init alignment_init(void)
+{
+ struct proc_dir_entry *dir, *res;
+
+ dir = proc_mkdir("cpu", NULL);
+ if (!dir)
+ return -ENOMEM;
+
+ res = proc_create_data("alignment", S_IWUSR | S_IRUGO, dir,
+ &alignment_proc_fops, &se_usermode);
+ if (!res)
+ return -ENOMEM;
+
+ res = proc_create_data("kernel_alignment", S_IWUSR | S_IRUGO, dir,
+ &alignment_proc_fops, &se_kernmode_warn);
+ if (!res)
+ return -ENOMEM;
+
+ return 0;
+}
+fs_initcall(alignment_init);
diff --git a/arch/sh/mm/cache-debugfs.c b/arch/sh/mm/cache-debugfs.c
index 5ba067b2659..690ed010d00 100644
--- a/arch/sh/mm/cache-debugfs.c
+++ b/arch/sh/mm/cache-debugfs.c
@@ -22,8 +22,7 @@ enum cache_type {
CACHE_TYPE_UNIFIED,
};
-static int __uses_jump_to_uncached cache_seq_show(struct seq_file *file,
- void *iter)
+static int cache_seq_show(struct seq_file *file, void *iter)
{
unsigned int cache_type = (unsigned int)file->private;
struct cache_info *cache;
@@ -37,7 +36,7 @@ static int __uses_jump_to_uncached cache_seq_show(struct seq_file *file,
*/
jump_to_uncached();
- ccr = ctrl_inl(CCR);
+ ccr = __raw_readl(CCR);
if ((ccr & CCR_CACHE_ENABLE) == 0) {
back_to_cached();
@@ -90,7 +89,7 @@ static int __uses_jump_to_uncached cache_seq_show(struct seq_file *file,
for (addr = addrstart, line = 0;
addr < addrstart + waysize;
addr += cache->linesz, line++) {
- unsigned long data = ctrl_inl(addr);
+ unsigned long data = __raw_readl(addr);
/* Check the V bit, ignore invalid cachelines */
if ((data & 1) == 0)
diff --git a/arch/sh/mm/cache-sh2.c b/arch/sh/mm/cache-sh2.c
index 699a71f4632..defcf719f2e 100644
--- a/arch/sh/mm/cache-sh2.c
+++ b/arch/sh/mm/cache-sh2.c
@@ -28,10 +28,10 @@ static void sh2__flush_wback_region(void *start, int size)
unsigned long addr = CACHE_OC_ADDRESS_ARRAY | (v & 0x00000ff0);
int way;
for (way = 0; way < 4; way++) {
- unsigned long data = ctrl_inl(addr | (way << 12));
+ unsigned long data = __raw_readl(addr | (way << 12));
if ((data & CACHE_PHYSADDR_MASK) == (v & CACHE_PHYSADDR_MASK)) {
data &= ~SH_CACHE_UPDATED;
- ctrl_outl(data, addr | (way << 12));
+ __raw_writel(data, addr | (way << 12));
}
}
}
@@ -47,7 +47,7 @@ static void sh2__flush_purge_region(void *start, int size)
& ~(L1_CACHE_BYTES-1);
for (v = begin; v < end; v+=L1_CACHE_BYTES)
- ctrl_outl((v & CACHE_PHYSADDR_MASK),
+ __raw_writel((v & CACHE_PHYSADDR_MASK),
CACHE_OC_ADDRESS_ARRAY | (v & 0x00000ff0) | 0x00000008);
}
@@ -63,9 +63,9 @@ static void sh2__flush_invalidate_region(void *start, int size)
local_irq_save(flags);
jump_to_uncached();
- ccr = ctrl_inl(CCR);
+ ccr = __raw_readl(CCR);
ccr |= CCR_CACHE_INVALIDATE;
- ctrl_outl(ccr, CCR);
+ __raw_writel(ccr, CCR);
back_to_cached();
local_irq_restore(flags);
@@ -78,7 +78,7 @@ static void sh2__flush_invalidate_region(void *start, int size)
& ~(L1_CACHE_BYTES-1);
for (v = begin; v < end; v+=L1_CACHE_BYTES)
- ctrl_outl((v & CACHE_PHYSADDR_MASK),
+ __raw_writel((v & CACHE_PHYSADDR_MASK),
CACHE_OC_ADDRESS_ARRAY | (v & 0x00000ff0) | 0x00000008);
#endif
}
diff --git a/arch/sh/mm/cache-sh2a.c b/arch/sh/mm/cache-sh2a.c
index 975899d8356..1f51225426a 100644
--- a/arch/sh/mm/cache-sh2a.c
+++ b/arch/sh/mm/cache-sh2a.c
@@ -32,10 +32,10 @@ static void sh2a__flush_wback_region(void *start, int size)
unsigned long addr = CACHE_OC_ADDRESS_ARRAY | (v & 0x000007f0);
int way;
for (way = 0; way < 4; way++) {
- unsigned long data = ctrl_inl(addr | (way << 11));
+ unsigned long data = __raw_readl(addr | (way << 11));
if ((data & CACHE_PHYSADDR_MASK) == (v & CACHE_PHYSADDR_MASK)) {
data &= ~SH_CACHE_UPDATED;
- ctrl_outl(data, addr | (way << 11));
+ __raw_writel(data, addr | (way << 11));
}
}
}
@@ -58,7 +58,7 @@ static void sh2a__flush_purge_region(void *start, int size)
jump_to_uncached();
for (v = begin; v < end; v+=L1_CACHE_BYTES) {
- ctrl_outl((v & CACHE_PHYSADDR_MASK),
+ __raw_writel((v & CACHE_PHYSADDR_MASK),
CACHE_OC_ADDRESS_ARRAY | (v & 0x000007f0) | 0x00000008);
}
back_to_cached();
@@ -78,17 +78,17 @@ static void sh2a__flush_invalidate_region(void *start, int size)
jump_to_uncached();
#ifdef CONFIG_CACHE_WRITEBACK
- ctrl_outl(ctrl_inl(CCR) | CCR_OCACHE_INVALIDATE, CCR);
+ __raw_writel(__raw_readl(CCR) | CCR_OCACHE_INVALIDATE, CCR);
/* I-cache invalidate */
for (v = begin; v < end; v+=L1_CACHE_BYTES) {
- ctrl_outl((v & CACHE_PHYSADDR_MASK),
+ __raw_writel((v & CACHE_PHYSADDR_MASK),
CACHE_IC_ADDRESS_ARRAY | (v & 0x000007f0) | 0x00000008);
}
#else
for (v = begin; v < end; v+=L1_CACHE_BYTES) {
- ctrl_outl((v & CACHE_PHYSADDR_MASK),
+ __raw_writel((v & CACHE_PHYSADDR_MASK),
CACHE_IC_ADDRESS_ARRAY | (v & 0x000007f0) | 0x00000008);
- ctrl_outl((v & CACHE_PHYSADDR_MASK),
+ __raw_writel((v & CACHE_PHYSADDR_MASK),
CACHE_OC_ADDRESS_ARRAY | (v & 0x000007f0) | 0x00000008);
}
#endif
@@ -115,14 +115,14 @@ static void sh2a_flush_icache_range(void *args)
int way;
/* O-Cache writeback */
for (way = 0; way < 4; way++) {
- unsigned long data = ctrl_inl(CACHE_OC_ADDRESS_ARRAY | addr | (way << 11));
+ unsigned long data = __raw_readl(CACHE_OC_ADDRESS_ARRAY | addr | (way << 11));
if ((data & CACHE_PHYSADDR_MASK) == (v & CACHE_PHYSADDR_MASK)) {
data &= ~SH_CACHE_UPDATED;
- ctrl_outl(data, CACHE_OC_ADDRESS_ARRAY | addr | (way << 11));
+ __raw_writel(data, CACHE_OC_ADDRESS_ARRAY | addr | (way << 11));
}
}
/* I-Cache invalidate */
- ctrl_outl(addr,
+ __raw_writel(addr,
CACHE_IC_ADDRESS_ARRAY | addr | 0x00000008);
}
diff --git a/arch/sh/mm/cache-sh3.c b/arch/sh/mm/cache-sh3.c
index faef80c9813..e37523f6519 100644
--- a/arch/sh/mm/cache-sh3.c
+++ b/arch/sh/mm/cache-sh3.c
@@ -50,12 +50,12 @@ static void sh3__flush_wback_region(void *start, int size)
p = __pa(v);
addr = addrstart | (v & current_cpu_data.dcache.entry_mask);
local_irq_save(flags);
- data = ctrl_inl(addr);
+ data = __raw_readl(addr);
if ((data & CACHE_PHYSADDR_MASK) ==
(p & CACHE_PHYSADDR_MASK)) {
data &= ~SH_CACHE_UPDATED;
- ctrl_outl(data, addr);
+ __raw_writel(data, addr);
local_irq_restore(flags);
break;
}
@@ -86,7 +86,7 @@ static void sh3__flush_purge_region(void *start, int size)
data = (v & 0xfffffc00); /* _Virtual_ address, ~U, ~V */
addr = CACHE_OC_ADDRESS_ARRAY |
(v & current_cpu_data.dcache.entry_mask) | SH_CACHE_ASSOC;
- ctrl_outl(data, addr);
+ __raw_writel(data, addr);
}
}
diff --git a/arch/sh/mm/cache-sh4.c b/arch/sh/mm/cache-sh4.c
index 560ddb6bc8a..2cfae81914a 100644
--- a/arch/sh/mm/cache-sh4.c
+++ b/arch/sh/mm/cache-sh4.c
@@ -36,7 +36,7 @@ static void __flush_cache_one(unsigned long addr, unsigned long phys,
* Called from kernel/module.c:sys_init_module and routine for a.out format,
* signal handler code and kprobes code
*/
-static void __uses_jump_to_uncached sh4_flush_icache_range(void *args)
+static void sh4_flush_icache_range(void *args)
{
struct flusher_data *data = args;
unsigned long start, end;
@@ -109,6 +109,7 @@ static inline void flush_cache_one(unsigned long start, unsigned long phys)
static void sh4_flush_dcache_page(void *arg)
{
struct page *page = arg;
+ unsigned long addr = (unsigned long)page_address(page);
#ifndef CONFIG_SMP
struct address_space *mapping = page_mapping(page);
@@ -116,22 +117,14 @@ static void sh4_flush_dcache_page(void *arg)
set_bit(PG_dcache_dirty, &page->flags);
else
#endif
- {
- unsigned long phys = page_to_phys(page);
- unsigned long addr = CACHE_OC_ADDRESS_ARRAY;
- int i, n;
-
- /* Loop all the D-cache */
- n = boot_cpu_data.dcache.n_aliases;
- for (i = 0; i < n; i++, addr += PAGE_SIZE)
- flush_cache_one(addr, phys);
- }
+ flush_cache_one(CACHE_OC_ADDRESS_ARRAY |
+ (addr & shm_align_mask), page_to_phys(page));
wmb();
}
/* TODO: Selective icache invalidation through IC address array.. */
-static void __uses_jump_to_uncached flush_icache_all(void)
+static void flush_icache_all(void)
{
unsigned long flags, ccr;
@@ -139,9 +132,9 @@ static void __uses_jump_to_uncached flush_icache_all(void)
jump_to_uncached();
/* Flush I-cache */
- ccr = ctrl_inl(CCR);
+ ccr = __raw_readl(CCR);
ccr |= CCR_CACHE_ICI;
- ctrl_outl(ccr, CCR);
+ __raw_writel(ccr, CCR);
/*
* back_to_cached() will take care of the barrier for us, don't add
@@ -384,9 +377,9 @@ extern void __weak sh4__flush_region_init(void);
void __init sh4_cache_init(void)
{
printk("PVR=%08x CVR=%08x PRR=%08x\n",
- ctrl_inl(CCN_PVR),
- ctrl_inl(CCN_CVR),
- ctrl_inl(CCN_PRR));
+ __raw_readl(CCN_PVR),
+ __raw_readl(CCN_CVR),
+ __raw_readl(CCN_PRR));
local_flush_icache_range = sh4_flush_icache_range;
local_flush_dcache_page = sh4_flush_dcache_page;
diff --git a/arch/sh/mm/cache-sh7705.c b/arch/sh/mm/cache-sh7705.c
index f527fb70fce..f498da1cce7 100644
--- a/arch/sh/mm/cache-sh7705.c
+++ b/arch/sh/mm/cache-sh7705.c
@@ -48,10 +48,10 @@ static inline void cache_wback_all(void)
unsigned long data;
int v = SH_CACHE_UPDATED | SH_CACHE_VALID;
- data = ctrl_inl(addr);
+ data = __raw_readl(addr);
if ((data & v) == v)
- ctrl_outl(data & ~v, addr);
+ __raw_writel(data & ~v, addr);
}
@@ -78,7 +78,7 @@ static void sh7705_flush_icache_range(void *args)
/*
* Writeback&Invalidate the D-cache of the page
*/
-static void __uses_jump_to_uncached __flush_dcache_page(unsigned long phys)
+static void __flush_dcache_page(unsigned long phys)
{
unsigned long ways, waysize, addrstart;
unsigned long flags;
@@ -115,10 +115,10 @@ static void __uses_jump_to_uncached __flush_dcache_page(unsigned long phys)
addr += current_cpu_data.dcache.linesz) {
unsigned long data;
- data = ctrl_inl(addr) & (0x1ffffC00 | SH_CACHE_VALID);
+ data = __raw_readl(addr) & (0x1ffffC00 | SH_CACHE_VALID);
if (data == phys) {
data &= ~(SH_CACHE_VALID | SH_CACHE_UPDATED);
- ctrl_outl(data, addr);
+ __raw_writel(data, addr);
}
}
@@ -144,7 +144,7 @@ static void sh7705_flush_dcache_page(void *arg)
__flush_dcache_page(__pa(page_address(page)));
}
-static void __uses_jump_to_uncached sh7705_flush_cache_all(void *args)
+static void sh7705_flush_cache_all(void *args)
{
unsigned long flags;
diff --git a/arch/sh/mm/cache.c b/arch/sh/mm/cache.c
index b8607fa7ae1..0f4095d7ac8 100644
--- a/arch/sh/mm/cache.c
+++ b/arch/sh/mm/cache.c
@@ -2,7 +2,7 @@
* arch/sh/mm/cache.c
*
* Copyright (C) 1999, 2000, 2002 Niibe Yutaka
- * Copyright (C) 2002 - 2009 Paul Mundt
+ * Copyright (C) 2002 - 2010 Paul Mundt
*
* Released under the terms of the GNU GPL v2.0.
*/
@@ -41,8 +41,17 @@ static inline void cacheop_on_each_cpu(void (*func) (void *info), void *info,
int wait)
{
preempt_disable();
- smp_call_function(func, info, wait);
+
+ /*
+ * It's possible that this gets called early on when IRQs are
+ * still disabled due to ioremapping by the boot CPU, so don't
+ * even attempt IPIs unless there are other CPUs online.
+ */
+ if (num_online_cpus() > 1)
+ smp_call_function(func, info, wait);
+
func(info);
+
preempt_enable();
}
diff --git a/arch/sh/mm/fault_32.c b/arch/sh/mm/fault_32.c
index 47530104e0a..28e22839c66 100644
--- a/arch/sh/mm/fault_32.c
+++ b/arch/sh/mm/fault_32.c
@@ -53,6 +53,9 @@ static inline pmd_t *vmalloc_sync_one(pgd_t *pgd, unsigned long address)
if (!pud_present(*pud_k))
return NULL;
+ if (!pud_present(*pud))
+ set_pud(pud, *pud_k);
+
pmd = pmd_offset(pud, address);
pmd_k = pmd_offset(pud_k, address);
if (!pmd_present(*pmd_k))
diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c
index 432acd07e76..68028e8f26c 100644
--- a/arch/sh/mm/init.c
+++ b/arch/sh/mm/init.c
@@ -21,25 +21,13 @@
#include <asm/cacheflush.h>
#include <asm/sections.h>
#include <asm/cache.h>
+#include <asm/sizes.h>
DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
pgd_t swapper_pg_dir[PTRS_PER_PGD];
-#ifdef CONFIG_SUPERH32
-/*
- * Handle trivial transitions between cached and uncached
- * segments, making use of the 1:1 mapping relationship in
- * 512MB lowmem.
- *
- * This is the offset of the uncached section from its cached alias.
- * Default value only valid in 29 bit mode, in 32bit mode will be
- * overridden in pmb_init.
- */
-unsigned long cached_to_uncached = P2SEG - P1SEG;
-#endif
-
#ifdef CONFIG_MMU
-static void set_pte_phys(unsigned long addr, unsigned long phys, pgprot_t prot)
+static pte_t *__get_pte_phys(unsigned long addr)
{
pgd_t *pgd;
pud_t *pud;
@@ -49,22 +37,30 @@ static void set_pte_phys(unsigned long addr, unsigned long phys, pgprot_t prot)
pgd = pgd_offset_k(addr);
if (pgd_none(*pgd)) {
pgd_ERROR(*pgd);
- return;
+ return NULL;
}
pud = pud_alloc(NULL, pgd, addr);
if (unlikely(!pud)) {
pud_ERROR(*pud);
- return;
+ return NULL;
}
pmd = pmd_alloc(NULL, pud, addr);
if (unlikely(!pmd)) {
pmd_ERROR(*pmd);
- return;
+ return NULL;
}
pte = pte_offset_kernel(pmd, addr);
+ return pte;
+}
+
+static void set_pte_phys(unsigned long addr, unsigned long phys, pgprot_t prot)
+{
+ pte_t *pte;
+
+ pte = __get_pte_phys(addr);
if (!pte_none(*pte)) {
pte_ERROR(*pte);
return;
@@ -72,23 +68,24 @@ static void set_pte_phys(unsigned long addr, unsigned long phys, pgprot_t prot)
set_pte(pte, pfn_pte(phys >> PAGE_SHIFT, prot));
local_flush_tlb_one(get_asid(), addr);
+
+ if (pgprot_val(prot) & _PAGE_WIRED)
+ tlb_wire_entry(NULL, addr, *pte);
+}
+
+static void clear_pte_phys(unsigned long addr, pgprot_t prot)
+{
+ pte_t *pte;
+
+ pte = __get_pte_phys(addr);
+
+ if (pgprot_val(prot) & _PAGE_WIRED)
+ tlb_unwire_entry();
+
+ set_pte(pte, pfn_pte(0, __pgprot(0)));
+ local_flush_tlb_one(get_asid(), addr);
}
-/*
- * As a performance optimization, other platforms preserve the fixmap mapping
- * across a context switch, we don't presently do this, but this could be done
- * in a similar fashion as to the wired TLB interface that sh64 uses (by way
- * of the memory mapped UTLB configuration) -- this unfortunately forces us to
- * give up a TLB entry for each mapping we want to preserve. While this may be
- * viable for a small number of fixmaps, it's not particularly useful for
- * everything and needs to be carefully evaluated. (ie, we may want this for
- * the vsyscall page).
- *
- * XXX: Perhaps add a _PAGE_WIRED flag or something similar that we can pass
- * in at __set_fixmap() time to determine the appropriate behavior to follow.
- *
- * -- PFM.
- */
void __set_fixmap(enum fixed_addresses idx, unsigned long phys, pgprot_t prot)
{
unsigned long address = __fix_to_virt(idx);
@@ -101,6 +98,18 @@ void __set_fixmap(enum fixed_addresses idx, unsigned long phys, pgprot_t prot)
set_pte_phys(address, phys, prot);
}
+void __clear_fixmap(enum fixed_addresses idx, pgprot_t prot)
+{
+ unsigned long address = __fix_to_virt(idx);
+
+ if (idx >= __end_of_fixed_addresses) {
+ BUG();
+ return;
+ }
+
+ clear_pte_phys(address, prot);
+}
+
void __init page_table_range_init(unsigned long start, unsigned long end,
pgd_t *pgd_base)
{
@@ -120,7 +129,13 @@ void __init page_table_range_init(unsigned long start, unsigned long end,
for ( ; (i < PTRS_PER_PGD) && (vaddr != end); pgd++, i++) {
pud = (pud_t *)pgd;
for ( ; (j < PTRS_PER_PUD) && (vaddr != end); pud++, j++) {
+#ifdef __PAGETABLE_PMD_FOLDED
pmd = (pmd_t *)pud;
+#else
+ pmd = (pmd_t *)alloc_bootmem_low_pages(PAGE_SIZE);
+ pud_populate(&init_mm, pud, pmd);
+ pmd += k;
+#endif
for (; (k < PTRS_PER_PMD) && (vaddr != end); pmd++, k++) {
if (pmd_none(*pmd)) {
pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
@@ -182,9 +197,6 @@ void __init paging_init(void)
}
free_area_init_nodes(max_zone_pfns);
-
- /* Set up the uncached fixmap */
- set_fixmap_nocache(FIX_UNCACHED, __pa(&__uncached_start));
}
/*
@@ -195,6 +207,8 @@ static void __init iommu_init(void)
no_iommu_init();
}
+unsigned int mem_init_done = 0;
+
void __init mem_init(void)
{
int codesize, datasize, initsize;
@@ -231,6 +245,8 @@ void __init mem_init(void)
memset(empty_zero_page, 0, PAGE_SIZE);
__flush_wback_region(empty_zero_page, PAGE_SIZE);
+ vsyscall_init();
+
codesize = (unsigned long) &_etext - (unsigned long) &_text;
datasize = (unsigned long) &_edata - (unsigned long) &_etext;
initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin;
@@ -243,8 +259,48 @@ void __init mem_init(void)
datasize >> 10,
initsize >> 10);
- /* Initialize the vDSO */
- vsyscall_init();
+ printk(KERN_INFO "virtual kernel memory layout:\n"
+ " fixmap : 0x%08lx - 0x%08lx (%4ld kB)\n"
+#ifdef CONFIG_HIGHMEM
+ " pkmap : 0x%08lx - 0x%08lx (%4ld kB)\n"
+#endif
+ " vmalloc : 0x%08lx - 0x%08lx (%4ld MB)\n"
+ " lowmem : 0x%08lx - 0x%08lx (%4ld MB) (cached)\n"
+#ifdef CONFIG_UNCACHED_MAPPING
+ " : 0x%08lx - 0x%08lx (%4ld MB) (uncached)\n"
+#endif
+ " .init : 0x%08lx - 0x%08lx (%4ld kB)\n"
+ " .data : 0x%08lx - 0x%08lx (%4ld kB)\n"
+ " .text : 0x%08lx - 0x%08lx (%4ld kB)\n",
+ FIXADDR_START, FIXADDR_TOP,
+ (FIXADDR_TOP - FIXADDR_START) >> 10,
+
+#ifdef CONFIG_HIGHMEM
+ PKMAP_BASE, PKMAP_BASE+LAST_PKMAP*PAGE_SIZE,
+ (LAST_PKMAP*PAGE_SIZE) >> 10,
+#endif
+
+ (unsigned long)VMALLOC_START, VMALLOC_END,
+ (VMALLOC_END - VMALLOC_START) >> 20,
+
+ (unsigned long)memory_start, (unsigned long)high_memory,
+ ((unsigned long)high_memory - (unsigned long)memory_start) >> 20,
+
+#ifdef CONFIG_UNCACHED_MAPPING
+ uncached_start, uncached_end, uncached_size >> 20,
+#endif
+
+ (unsigned long)&__init_begin, (unsigned long)&__init_end,
+ ((unsigned long)&__init_end -
+ (unsigned long)&__init_begin) >> 10,
+
+ (unsigned long)&_etext, (unsigned long)&_edata,
+ ((unsigned long)&_edata - (unsigned long)&_etext) >> 10,
+
+ (unsigned long)&_text, (unsigned long)&_etext,
+ ((unsigned long)&_etext - (unsigned long)&_text) >> 10);
+
+ mem_init_done = 1;
}
void free_initmem(void)
@@ -277,35 +333,6 @@ void free_initrd_mem(unsigned long start, unsigned long end)
}
#endif
-#if THREAD_SHIFT < PAGE_SHIFT
-static struct kmem_cache *thread_info_cache;
-
-struct thread_info *alloc_thread_info(struct task_struct *tsk)
-{
- struct thread_info *ti;
-
- ti = kmem_cache_alloc(thread_info_cache, GFP_KERNEL);
- if (unlikely(ti == NULL))
- return NULL;
-#ifdef CONFIG_DEBUG_STACK_USAGE
- memset(ti, 0, THREAD_SIZE);
-#endif
- return ti;
-}
-
-void free_thread_info(struct thread_info *ti)
-{
- kmem_cache_free(thread_info_cache, ti);
-}
-
-void thread_info_cache_init(void)
-{
- thread_info_cache = kmem_cache_create("thread_info", THREAD_SIZE,
- THREAD_SIZE, 0, NULL);
- BUG_ON(thread_info_cache == NULL);
-}
-#endif /* THREAD_SHIFT < PAGE_SHIFT */
-
#ifdef CONFIG_MEMORY_HOTPLUG
int arch_add_memory(int nid, u64 start, u64 size)
{
@@ -336,10 +363,3 @@ EXPORT_SYMBOL_GPL(memory_add_physaddr_to_nid);
#endif
#endif /* CONFIG_MEMORY_HOTPLUG */
-
-#ifdef CONFIG_PMB
-int __in_29bit_mode(void)
-{
- return !(ctrl_inl(PMB_PASCR) & PASCR_SE);
-}
-#endif /* CONFIG_PMB */
diff --git a/arch/sh/mm/ioremap_32.c b/arch/sh/mm/ioremap.c
index 2141befb4f9..c68d2d7d00a 100644
--- a/arch/sh/mm/ioremap_32.c
+++ b/arch/sh/mm/ioremap.c
@@ -1,13 +1,13 @@
/*
* arch/sh/mm/ioremap.c
*
+ * (C) Copyright 1995 1996 Linus Torvalds
+ * (C) Copyright 2005 - 2010 Paul Mundt
+ *
* Re-map IO memory to kernel address space so that we can access it.
* This is needed for high PCI addresses that aren't mapped in the
* 640k-1MB IO memory area on PC's
*
- * (C) Copyright 1995 1996 Linus Torvalds
- * (C) Copyright 2005, 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.
@@ -33,12 +33,12 @@
* have to convert them into an offset in a page-aligned mapping, but the
* caller shouldn't need to know that small detail.
*/
-void __iomem *__ioremap_caller(unsigned long phys_addr, unsigned long size,
- unsigned long flags, void *caller)
+void __iomem * __init_refok
+__ioremap_caller(unsigned long phys_addr, unsigned long size,
+ pgprot_t pgprot, void *caller)
{
struct vm_struct *area;
unsigned long offset, last_addr, addr, orig_addr;
- pgprot_t pgprot;
/* Don't allow wraparound or zero size */
last_addr = phys_addr + size - 1;
@@ -46,18 +46,6 @@ void __iomem *__ioremap_caller(unsigned long phys_addr, unsigned long size,
return NULL;
/*
- * If we're in the fixed PCI memory range, mapping through page
- * tables is not only pointless, but also fundamentally broken.
- * Just return the physical address instead.
- *
- * For boards that map a small PCI memory aperture somewhere in
- * P1/P2 space, ioremap() will already do the right thing,
- * and we'll never get this far.
- */
- if (is_pci_memory_fixed_range(phys_addr, size))
- return (void __iomem *)phys_addr;
-
- /*
* Mappings have to be page-aligned
*/
offset = phys_addr & ~PAGE_MASK;
@@ -65,6 +53,12 @@ void __iomem *__ioremap_caller(unsigned long phys_addr, unsigned long size,
size = PAGE_ALIGN(last_addr+1) - phys_addr;
/*
+ * If we can't yet use the regular approach, go the fixmap route.
+ */
+ if (!mem_init_done)
+ return ioremap_fixed(phys_addr, offset, size, pgprot);
+
+ /*
* Ok, go for it..
*/
area = get_vm_area_caller(size, VM_IOREMAP, caller);
@@ -84,8 +78,9 @@ void __iomem *__ioremap_caller(unsigned long phys_addr, unsigned long size,
* PMB entries are all pre-faulted.
*/
if (unlikely(phys_addr >= P1SEG)) {
- unsigned long mapped = pmb_remap(addr, phys_addr, size, flags);
+ unsigned long mapped;
+ mapped = pmb_remap(addr, phys_addr, size, pgprot);
if (likely(mapped)) {
addr += mapped;
phys_addr += mapped;
@@ -94,7 +89,6 @@ void __iomem *__ioremap_caller(unsigned long phys_addr, unsigned long size,
}
#endif
- pgprot = __pgprot(pgprot_val(PAGE_KERNEL_NOCACHE) | flags);
if (likely(size))
if (ioremap_page_range(addr, addr + size, phys_addr, pgprot)) {
vunmap((void *)orig_addr);
@@ -105,15 +99,38 @@ void __iomem *__ioremap_caller(unsigned long phys_addr, unsigned long size,
}
EXPORT_SYMBOL(__ioremap_caller);
+/*
+ * Simple checks for non-translatable mappings.
+ */
+static inline int iomapping_nontranslatable(unsigned long offset)
+{
+#ifdef CONFIG_29BIT
+ /*
+ * In 29-bit mode this includes the fixed P1/P2 areas, as well as
+ * parts of P3.
+ */
+ if (PXSEG(offset) < P3SEG || offset >= P3_ADDR_MAX)
+ return 1;
+#endif
+
+ return 0;
+}
+
void __iounmap(void __iomem *addr)
{
unsigned long vaddr = (unsigned long __force)addr;
- unsigned long seg = PXSEG(vaddr);
struct vm_struct *p;
- if (seg < P3SEG || vaddr >= P3_ADDR_MAX)
+ /*
+ * Nothing to do if there is no translatable mapping.
+ */
+ if (iomapping_nontranslatable(vaddr))
return;
- if (is_pci_memory_fixed_range(vaddr, 0))
+
+ /*
+ * There's no VMA if it's from an early fixed mapping.
+ */
+ if (iounmap_fixed(addr) == 0)
return;
#ifdef CONFIG_PMB
diff --git a/arch/sh/mm/ioremap_64.c b/arch/sh/mm/ioremap_64.c
deleted file mode 100644
index ef434657d42..00000000000
--- a/arch/sh/mm/ioremap_64.c
+++ /dev/null
@@ -1,326 +0,0 @@
-/*
- * arch/sh/mm/ioremap_64.c
- *
- * Copyright (C) 2000, 2001 Paolo Alberelli
- * Copyright (C) 2003 - 2007 Paul Mundt
- *
- * Mostly derived from arch/sh/mm/ioremap.c which, in turn is mostly
- * derived from arch/i386/mm/ioremap.c .
- *
- * (C) Copyright 1995 1996 Linus Torvalds
- *
- * 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/vmalloc.h>
-#include <linux/ioport.h>
-#include <linux/module.h>
-#include <linux/mm.h>
-#include <linux/io.h>
-#include <linux/bootmem.h>
-#include <linux/proc_fs.h>
-#include <linux/slab.h>
-#include <asm/page.h>
-#include <asm/pgalloc.h>
-#include <asm/addrspace.h>
-#include <asm/cacheflush.h>
-#include <asm/tlbflush.h>
-#include <asm/mmu.h>
-
-static struct resource shmedia_iomap = {
- .name = "shmedia_iomap",
- .start = IOBASE_VADDR + PAGE_SIZE,
- .end = IOBASE_END - 1,
-};
-
-static void shmedia_mapioaddr(unsigned long pa, unsigned long va,
- unsigned long flags);
-static void shmedia_unmapioaddr(unsigned long vaddr);
-static void __iomem *shmedia_ioremap(struct resource *res, u32 pa,
- int sz, unsigned long flags);
-
-/*
- * We have the same problem as the SPARC, so lets have the same comment:
- * Our mini-allocator...
- * Boy this is gross! We need it because we must map I/O for
- * timers and interrupt controller before the kmalloc is available.
- */
-
-#define XNMLN 15
-#define XNRES 10
-
-struct xresource {
- struct resource xres; /* Must be first */
- int xflag; /* 1 == used */
- char xname[XNMLN+1];
-};
-
-static struct xresource xresv[XNRES];
-
-static struct xresource *xres_alloc(void)
-{
- struct xresource *xrp;
- int n;
-
- xrp = xresv;
- for (n = 0; n < XNRES; n++) {
- if (xrp->xflag == 0) {
- xrp->xflag = 1;
- return xrp;
- }
- xrp++;
- }
- return NULL;
-}
-
-static void xres_free(struct xresource *xrp)
-{
- xrp->xflag = 0;
-}
-
-static struct resource *shmedia_find_resource(struct resource *root,
- unsigned long vaddr)
-{
- struct resource *res;
-
- for (res = root->child; res; res = res->sibling)
- if (res->start <= vaddr && res->end >= vaddr)
- return res;
-
- return NULL;
-}
-
-static void __iomem *shmedia_alloc_io(unsigned long phys, unsigned long size,
- const char *name, unsigned long flags)
-{
- struct xresource *xres;
- struct resource *res;
- char *tack;
- int tlen;
-
- if (name == NULL)
- name = "???";
-
- xres = xres_alloc();
- if (xres != 0) {
- tack = xres->xname;
- res = &xres->xres;
- } else {
- printk_once(KERN_NOTICE "%s: done with statics, "
- "switching to kmalloc\n", __func__);
- tlen = strlen(name);
- tack = kmalloc(sizeof(struct resource) + tlen + 1, GFP_KERNEL);
- if (!tack)
- return NULL;
- memset(tack, 0, sizeof(struct resource));
- res = (struct resource *) tack;
- tack += sizeof(struct resource);
- }
-
- strncpy(tack, name, XNMLN);
- tack[XNMLN] = 0;
- res->name = tack;
-
- return shmedia_ioremap(res, phys, size, flags);
-}
-
-static void __iomem *shmedia_ioremap(struct resource *res, u32 pa, int sz,
- unsigned long flags)
-{
- unsigned long offset = ((unsigned long) pa) & (~PAGE_MASK);
- unsigned long round_sz = (offset + sz + PAGE_SIZE-1) & PAGE_MASK;
- unsigned long va;
- unsigned int psz;
-
- if (allocate_resource(&shmedia_iomap, res, round_sz,
- shmedia_iomap.start, shmedia_iomap.end,
- PAGE_SIZE, NULL, NULL) != 0) {
- panic("alloc_io_res(%s): cannot occupy\n",
- (res->name != NULL) ? res->name : "???");
- }
-
- va = res->start;
- pa &= PAGE_MASK;
-
- psz = (res->end - res->start + (PAGE_SIZE - 1)) / PAGE_SIZE;
-
- for (psz = res->end - res->start + 1; psz != 0; psz -= PAGE_SIZE) {
- shmedia_mapioaddr(pa, va, flags);
- va += PAGE_SIZE;
- pa += PAGE_SIZE;
- }
-
- return (void __iomem *)(unsigned long)(res->start + offset);
-}
-
-static void shmedia_free_io(struct resource *res)
-{
- unsigned long len = res->end - res->start + 1;
-
- BUG_ON((len & (PAGE_SIZE - 1)) != 0);
-
- while (len) {
- len -= PAGE_SIZE;
- shmedia_unmapioaddr(res->start + len);
- }
-
- release_resource(res);
-}
-
-static __init_refok void *sh64_get_page(void)
-{
- void *page;
-
- if (slab_is_available())
- page = (void *)get_zeroed_page(GFP_KERNEL);
- else
- page = alloc_bootmem_pages(PAGE_SIZE);
-
- if (!page || ((unsigned long)page & ~PAGE_MASK))
- panic("sh64_get_page: Out of memory already?\n");
-
- return page;
-}
-
-static void shmedia_mapioaddr(unsigned long pa, unsigned long va,
- unsigned long flags)
-{
- pgd_t *pgdp;
- pud_t *pudp;
- pmd_t *pmdp;
- pte_t *ptep, pte;
- pgprot_t prot;
-
- pr_debug("shmedia_mapiopage pa %08lx va %08lx\n", pa, va);
-
- if (!flags)
- flags = 1; /* 1 = CB0-1 device */
-
- pgdp = pgd_offset_k(va);
- if (pgd_none(*pgdp) || !pgd_present(*pgdp)) {
- pudp = (pud_t *)sh64_get_page();
- set_pgd(pgdp, __pgd((unsigned long)pudp | _KERNPG_TABLE));
- }
-
- pudp = pud_offset(pgdp, va);
- if (pud_none(*pudp) || !pud_present(*pudp)) {
- pmdp = (pmd_t *)sh64_get_page();
- set_pud(pudp, __pud((unsigned long)pmdp | _KERNPG_TABLE));
- }
-
- pmdp = pmd_offset(pudp, va);
- if (pmd_none(*pmdp) || !pmd_present(*pmdp)) {
- ptep = (pte_t *)sh64_get_page();
- set_pmd(pmdp, __pmd((unsigned long)ptep + _PAGE_TABLE));
- }
-
- prot = __pgprot(_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE |
- _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_SHARED | flags);
-
- pte = pfn_pte(pa >> PAGE_SHIFT, prot);
- ptep = pte_offset_kernel(pmdp, va);
-
- if (!pte_none(*ptep) &&
- pte_val(*ptep) != pte_val(pte))
- pte_ERROR(*ptep);
-
- set_pte(ptep, pte);
-
- flush_tlb_kernel_range(va, PAGE_SIZE);
-}
-
-static void shmedia_unmapioaddr(unsigned long vaddr)
-{
- pgd_t *pgdp;
- pud_t *pudp;
- pmd_t *pmdp;
- pte_t *ptep;
-
- pgdp = pgd_offset_k(vaddr);
- if (pgd_none(*pgdp) || pgd_bad(*pgdp))
- return;
-
- pudp = pud_offset(pgdp, vaddr);
- if (pud_none(*pudp) || pud_bad(*pudp))
- return;
-
- pmdp = pmd_offset(pudp, vaddr);
- if (pmd_none(*pmdp) || pmd_bad(*pmdp))
- return;
-
- ptep = pte_offset_kernel(pmdp, vaddr);
-
- if (pte_none(*ptep) || !pte_present(*ptep))
- return;
-
- clear_page((void *)ptep);
- pte_clear(&init_mm, vaddr, ptep);
-}
-
-void __iomem *__ioremap_caller(unsigned long offset, unsigned long size,
- unsigned long flags, void *caller)
-{
- char name[14];
-
- sprintf(name, "phys_%08x", (u32)offset);
- return shmedia_alloc_io(offset, size, name, flags);
-}
-EXPORT_SYMBOL(__ioremap_caller);
-
-void __iounmap(void __iomem *virtual)
-{
- unsigned long vaddr = (unsigned long)virtual & PAGE_MASK;
- struct resource *res;
- unsigned int psz;
-
- res = shmedia_find_resource(&shmedia_iomap, vaddr);
- if (!res) {
- printk(KERN_ERR "%s: Failed to free 0x%08lx\n",
- __func__, vaddr);
- return;
- }
-
- psz = (res->end - res->start + (PAGE_SIZE - 1)) / PAGE_SIZE;
-
- shmedia_free_io(res);
-
- if ((char *)res >= (char *)xresv &&
- (char *)res < (char *)&xresv[XNRES]) {
- xres_free((struct xresource *)res);
- } else {
- kfree(res);
- }
-}
-EXPORT_SYMBOL(__iounmap);
-
-static int
-ioremap_proc_info(char *buf, char **start, off_t fpos, int length, int *eof,
- void *data)
-{
- char *p = buf, *e = buf + length;
- struct resource *r;
- const char *nm;
-
- for (r = ((struct resource *)data)->child; r != NULL; r = r->sibling) {
- if (p + 32 >= e) /* Better than nothing */
- break;
- nm = r->name;
- if (nm == NULL)
- nm = "???";
-
- p += sprintf(p, "%08lx-%08lx: %s\n",
- (unsigned long)r->start,
- (unsigned long)r->end, nm);
- }
-
- return p-buf;
-}
-
-static int __init register_proc_onchip(void)
-{
- create_proc_read_entry("io_map", 0, 0, ioremap_proc_info,
- &shmedia_iomap);
- return 0;
-}
-late_initcall(register_proc_onchip);
diff --git a/arch/sh/mm/ioremap_fixed.c b/arch/sh/mm/ioremap_fixed.c
new file mode 100644
index 00000000000..0b78b1e20ef
--- /dev/null
+++ b/arch/sh/mm/ioremap_fixed.c
@@ -0,0 +1,128 @@
+/*
+ * Re-map IO memory to kernel address space so that we can access it.
+ *
+ * These functions should only be used when it is necessary to map a
+ * physical address space into the kernel address space before ioremap()
+ * can be used, e.g. early in boot before paging_init().
+ *
+ * Copyright (C) 2009 Matt Fleming
+ */
+
+#include <linux/vmalloc.h>
+#include <linux/ioport.h>
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <linux/io.h>
+#include <linux/bootmem.h>
+#include <linux/proc_fs.h>
+#include <linux/slab.h>
+#include <asm/fixmap.h>
+#include <asm/page.h>
+#include <asm/pgalloc.h>
+#include <asm/addrspace.h>
+#include <asm/cacheflush.h>
+#include <asm/tlbflush.h>
+#include <asm/mmu.h>
+#include <asm/mmu_context.h>
+
+struct ioremap_map {
+ void __iomem *addr;
+ unsigned long size;
+ unsigned long fixmap_addr;
+};
+
+static struct ioremap_map ioremap_maps[FIX_N_IOREMAPS];
+
+void __init ioremap_fixed_init(void)
+{
+ struct ioremap_map *map;
+ int i;
+
+ for (i = 0; i < FIX_N_IOREMAPS; i++) {
+ map = &ioremap_maps[i];
+ map->fixmap_addr = __fix_to_virt(FIX_IOREMAP_BEGIN + i);
+ }
+}
+
+void __init __iomem *
+ioremap_fixed(resource_size_t phys_addr, unsigned long offset,
+ unsigned long size, pgprot_t prot)
+{
+ enum fixed_addresses idx0, idx;
+ struct ioremap_map *map;
+ unsigned int nrpages;
+ int i, slot;
+
+ slot = -1;
+ for (i = 0; i < FIX_N_IOREMAPS; i++) {
+ map = &ioremap_maps[i];
+ if (!map->addr) {
+ map->size = size;
+ slot = i;
+ break;
+ }
+ }
+
+ if (slot < 0)
+ return NULL;
+
+ /*
+ * Mappings have to fit in the FIX_IOREMAP area.
+ */
+ nrpages = size >> PAGE_SHIFT;
+ if (nrpages > FIX_N_IOREMAPS)
+ return NULL;
+
+ /*
+ * Ok, go for it..
+ */
+ idx0 = FIX_IOREMAP_BEGIN + slot;
+ idx = idx0;
+ while (nrpages > 0) {
+ pgprot_val(prot) |= _PAGE_WIRED;
+ __set_fixmap(idx, phys_addr, prot);
+ phys_addr += PAGE_SIZE;
+ idx++;
+ --nrpages;
+ }
+
+ map->addr = (void __iomem *)(offset + map->fixmap_addr);
+ return map->addr;
+}
+
+int iounmap_fixed(void __iomem *addr)
+{
+ enum fixed_addresses idx;
+ struct ioremap_map *map;
+ unsigned int nrpages;
+ int i, slot;
+
+ slot = -1;
+ for (i = 0; i < FIX_N_IOREMAPS; i++) {
+ map = &ioremap_maps[i];
+ if (map->addr == addr) {
+ slot = i;
+ break;
+ }
+ }
+
+ /*
+ * If we don't match, it's not for us.
+ */
+ if (slot < 0)
+ return -EINVAL;
+
+ nrpages = map->size >> PAGE_SHIFT;
+
+ idx = FIX_IOREMAP_BEGIN + slot + nrpages - 1;
+ while (nrpages > 0) {
+ __clear_fixmap(idx, __pgprot(_PAGE_WIRED));
+ --idx;
+ --nrpages;
+ }
+
+ map->size = 0;
+ map->addr = NULL;
+
+ return 0;
+}
diff --git a/arch/sh/mm/nommu.c b/arch/sh/mm/nommu.c
index ac16c05917e..7694f50c903 100644
--- a/arch/sh/mm/nommu.c
+++ b/arch/sh/mm/nommu.c
@@ -94,3 +94,7 @@ void __init page_table_range_init(unsigned long start, unsigned long end,
void __set_fixmap(enum fixed_addresses idx, unsigned long phys, pgprot_t prot)
{
}
+
+void pgtable_cache_init(void)
+{
+}
diff --git a/arch/sh/mm/pgtable.c b/arch/sh/mm/pgtable.c
new file mode 100644
index 00000000000..6f21fb1d872
--- /dev/null
+++ b/arch/sh/mm/pgtable.c
@@ -0,0 +1,56 @@
+#include <linux/mm.h>
+
+#define PGALLOC_GFP GFP_KERNEL | __GFP_REPEAT | __GFP_ZERO
+
+static struct kmem_cache *pgd_cachep;
+#if PAGETABLE_LEVELS > 2
+static struct kmem_cache *pmd_cachep;
+#endif
+
+void pgd_ctor(void *x)
+{
+ pgd_t *pgd = x;
+
+ memcpy(pgd + USER_PTRS_PER_PGD,
+ swapper_pg_dir + USER_PTRS_PER_PGD,
+ (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
+}
+
+void pgtable_cache_init(void)
+{
+ pgd_cachep = kmem_cache_create("pgd_cache",
+ PTRS_PER_PGD * (1<<PTE_MAGNITUDE),
+ PAGE_SIZE, SLAB_PANIC, pgd_ctor);
+#if PAGETABLE_LEVELS > 2
+ pmd_cachep = kmem_cache_create("pmd_cache",
+ PTRS_PER_PMD * (1<<PTE_MAGNITUDE),
+ PAGE_SIZE, SLAB_PANIC, NULL);
+#endif
+}
+
+pgd_t *pgd_alloc(struct mm_struct *mm)
+{
+ return kmem_cache_alloc(pgd_cachep, PGALLOC_GFP);
+}
+
+void pgd_free(struct mm_struct *mm, pgd_t *pgd)
+{
+ kmem_cache_free(pgd_cachep, pgd);
+}
+
+#if PAGETABLE_LEVELS > 2
+void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
+{
+ set_pud(pud, __pud((unsigned long)pmd));
+}
+
+pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address)
+{
+ return kmem_cache_alloc(pmd_cachep, PGALLOC_GFP);
+}
+
+void pmd_free(struct mm_struct *mm, pmd_t *pmd)
+{
+ kmem_cache_free(pmd_cachep, pmd);
+}
+#endif /* PAGETABLE_LEVELS > 2 */
diff --git a/arch/sh/mm/pmb.c b/arch/sh/mm/pmb.c
index 280f6a16603..198bcff5e96 100644
--- a/arch/sh/mm/pmb.c
+++ b/arch/sh/mm/pmb.c
@@ -3,11 +3,8 @@
*
* Privileged Space Mapping Buffer (PMB) Support.
*
- * Copyright (C) 2005, 2006, 2007 Paul Mundt
- *
- * P1/P2 Section mapping definitions from map32.h, which was:
- *
- * Copyright 2003 (c) Lineo Solutions,Inc.
+ * Copyright (C) 2005 - 2010 Paul Mundt
+ * Copyright (C) 2010 Matt Fleming
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
@@ -24,47 +21,67 @@
#include <linux/fs.h>
#include <linux/seq_file.h>
#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/spinlock.h>
+#include <linux/rwlock.h>
+#include <asm/sizes.h>
#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
+#include <asm/page.h>
#include <asm/mmu.h>
-#include <asm/io.h>
#include <asm/mmu_context.h>
-#define NR_PMB_ENTRIES 16
+struct pmb_entry;
+
+struct pmb_entry {
+ unsigned long vpn;
+ unsigned long ppn;
+ unsigned long flags;
+ unsigned long size;
-static void __pmb_unmap(struct pmb_entry *);
+ spinlock_t lock;
+
+ /*
+ * 0 .. NR_PMB_ENTRIES for specific entry selection, or
+ * PMB_NO_ENTRY to search for a free one
+ */
+ int entry;
+ /* Adjacent entry link for contiguous multi-entry mappings */
+ struct pmb_entry *link;
+};
+
+static void pmb_unmap_entry(struct pmb_entry *, int depth);
+
+static DEFINE_RWLOCK(pmb_rwlock);
static struct pmb_entry pmb_entry_list[NR_PMB_ENTRIES];
-static unsigned long pmb_map;
+static DECLARE_BITMAP(pmb_map, NR_PMB_ENTRIES);
-static inline unsigned long mk_pmb_entry(unsigned int entry)
+static __always_inline unsigned long mk_pmb_entry(unsigned int entry)
{
return (entry & PMB_E_MASK) << PMB_E_SHIFT;
}
-static inline unsigned long mk_pmb_addr(unsigned int entry)
+static __always_inline unsigned long mk_pmb_addr(unsigned int entry)
{
return mk_pmb_entry(entry) | PMB_ADDR;
}
-static inline unsigned long mk_pmb_data(unsigned int entry)
+static __always_inline unsigned long mk_pmb_data(unsigned int entry)
{
return mk_pmb_entry(entry) | PMB_DATA;
}
static int pmb_alloc_entry(void)
{
- unsigned int pos;
-
-repeat:
- pos = find_first_zero_bit(&pmb_map, NR_PMB_ENTRIES);
-
- if (unlikely(pos > NR_PMB_ENTRIES))
- return -ENOSPC;
+ int pos;
- if (test_and_set_bit(pos, &pmb_map))
- goto repeat;
+ pos = find_first_zero_bit(pmb_map, NR_PMB_ENTRIES);
+ if (pos >= 0 && pos < NR_PMB_ENTRIES)
+ __set_bit(pos, pmb_map);
+ else
+ pos = -ENOSPC;
return pos;
}
@@ -73,21 +90,34 @@ static struct pmb_entry *pmb_alloc(unsigned long vpn, unsigned long ppn,
unsigned long flags, int entry)
{
struct pmb_entry *pmbe;
+ unsigned long irqflags;
+ void *ret = NULL;
int pos;
+ write_lock_irqsave(&pmb_rwlock, irqflags);
+
if (entry == PMB_NO_ENTRY) {
pos = pmb_alloc_entry();
- if (pos < 0)
- return ERR_PTR(pos);
+ if (unlikely(pos < 0)) {
+ ret = ERR_PTR(pos);
+ goto out;
+ }
} else {
- if (test_bit(entry, &pmb_map))
- return ERR_PTR(-ENOSPC);
+ if (__test_and_set_bit(entry, pmb_map)) {
+ ret = ERR_PTR(-ENOSPC);
+ goto out;
+ }
+
pos = entry;
}
+ write_unlock_irqrestore(&pmb_rwlock, irqflags);
+
pmbe = &pmb_entry_list[pos];
- if (!pmbe)
- return ERR_PTR(-ENOMEM);
+
+ memset(pmbe, 0, sizeof(struct pmb_entry));
+
+ spin_lock_init(&pmbe->lock);
pmbe->vpn = vpn;
pmbe->ppn = ppn;
@@ -95,101 +125,113 @@ static struct pmb_entry *pmb_alloc(unsigned long vpn, unsigned long ppn,
pmbe->entry = pos;
return pmbe;
+
+out:
+ write_unlock_irqrestore(&pmb_rwlock, irqflags);
+ return ret;
}
static void pmb_free(struct pmb_entry *pmbe)
{
- int pos = pmbe->entry;
-
- pmbe->vpn = 0;
- pmbe->ppn = 0;
- pmbe->flags = 0;
- pmbe->entry = 0;
+ __clear_bit(pmbe->entry, pmb_map);
- clear_bit(pos, &pmb_map);
+ pmbe->entry = PMB_NO_ENTRY;
+ pmbe->link = NULL;
}
/*
- * Must be in P2 for __set_pmb_entry()
+ * Ensure that the PMB entries match our cache configuration.
+ *
+ * When we are in 32-bit address extended mode, CCR.CB becomes
+ * invalid, so care must be taken to manually adjust cacheable
+ * translations.
*/
-static void __set_pmb_entry(unsigned long vpn, unsigned long ppn,
- unsigned long flags, int pos)
+static __always_inline unsigned long pmb_cache_flags(void)
{
- ctrl_outl(vpn | PMB_V, mk_pmb_addr(pos));
+ unsigned long flags = 0;
-#ifdef CONFIG_CACHE_WRITETHROUGH
- /*
- * When we are in 32-bit address extended mode, CCR.CB becomes
- * invalid, so care must be taken to manually adjust cacheable
- * translations.
- */
- if (likely(flags & PMB_C))
- flags |= PMB_WT;
+#if defined(CONFIG_CACHE_WRITETHROUGH)
+ flags |= PMB_C | PMB_WT | PMB_UB;
+#elif defined(CONFIG_CACHE_WRITEBACK)
+ flags |= PMB_C;
#endif
- ctrl_outl(ppn | flags | PMB_V, mk_pmb_data(pos));
+ return flags;
}
-static void __uses_jump_to_uncached set_pmb_entry(struct pmb_entry *pmbe)
+/*
+ * Must be run uncached.
+ */
+static void __set_pmb_entry(struct pmb_entry *pmbe)
{
- jump_to_uncached();
- __set_pmb_entry(pmbe->vpn, pmbe->ppn, pmbe->flags, pmbe->entry);
- back_to_cached();
+ writel_uncached(pmbe->vpn | PMB_V, mk_pmb_addr(pmbe->entry));
+ writel_uncached(pmbe->ppn | pmbe->flags | PMB_V,
+ mk_pmb_data(pmbe->entry));
}
-static void __uses_jump_to_uncached clear_pmb_entry(struct pmb_entry *pmbe)
+static void __clear_pmb_entry(struct pmb_entry *pmbe)
{
- unsigned int entry = pmbe->entry;
- unsigned long addr;
+ unsigned long addr, data;
+ unsigned long addr_val, data_val;
- if (unlikely(entry >= NR_PMB_ENTRIES))
- return;
+ addr = mk_pmb_addr(pmbe->entry);
+ data = mk_pmb_data(pmbe->entry);
- jump_to_uncached();
+ addr_val = __raw_readl(addr);
+ data_val = __raw_readl(data);
/* Clear V-bit */
- addr = mk_pmb_addr(entry);
- ctrl_outl(ctrl_inl(addr) & ~PMB_V, addr);
+ writel_uncached(addr_val & ~PMB_V, addr);
+ writel_uncached(data_val & ~PMB_V, data);
+}
- addr = mk_pmb_data(entry);
- ctrl_outl(ctrl_inl(addr) & ~PMB_V, addr);
+static void set_pmb_entry(struct pmb_entry *pmbe)
+{
+ unsigned long flags;
- back_to_cached();
+ spin_lock_irqsave(&pmbe->lock, flags);
+ __set_pmb_entry(pmbe);
+ spin_unlock_irqrestore(&pmbe->lock, flags);
}
-
static struct {
unsigned long size;
int flag;
} pmb_sizes[] = {
- { .size = 0x20000000, .flag = PMB_SZ_512M, },
- { .size = 0x08000000, .flag = PMB_SZ_128M, },
- { .size = 0x04000000, .flag = PMB_SZ_64M, },
- { .size = 0x01000000, .flag = PMB_SZ_16M, },
+ { .size = SZ_512M, .flag = PMB_SZ_512M, },
+ { .size = SZ_128M, .flag = PMB_SZ_128M, },
+ { .size = SZ_64M, .flag = PMB_SZ_64M, },
+ { .size = SZ_16M, .flag = PMB_SZ_16M, },
};
long pmb_remap(unsigned long vaddr, unsigned long phys,
- unsigned long size, unsigned long flags)
+ unsigned long size, pgprot_t prot)
{
struct pmb_entry *pmbp, *pmbe;
unsigned long wanted;
int pmb_flags, i;
long err;
+ u64 flags;
+
+ flags = pgprot_val(prot);
+
+ pmb_flags = PMB_WT | PMB_UB;
/* Convert typical pgprot value to the PMB equivalent */
if (flags & _PAGE_CACHABLE) {
- if (flags & _PAGE_WT)
- pmb_flags = PMB_WT;
- else
- pmb_flags = PMB_C;
- } else
- pmb_flags = PMB_WT | PMB_UB;
+ pmb_flags |= PMB_C;
+
+ if ((flags & _PAGE_WT) == 0)
+ pmb_flags &= ~(PMB_WT | PMB_UB);
+ }
pmbp = NULL;
wanted = size;
again:
for (i = 0; i < ARRAY_SIZE(pmb_sizes); i++) {
+ unsigned long flags;
+
if (size < pmb_sizes[i].size)
continue;
@@ -200,18 +242,25 @@ again:
goto out;
}
- set_pmb_entry(pmbe);
+ spin_lock_irqsave(&pmbe->lock, flags);
+
+ __set_pmb_entry(pmbe);
phys += pmb_sizes[i].size;
vaddr += pmb_sizes[i].size;
size -= pmb_sizes[i].size;
+ pmbe->size = pmb_sizes[i].size;
+
/*
* Link adjacent entries that span multiple PMB entries
* for easier tear-down.
*/
- if (likely(pmbp))
+ if (likely(pmbp)) {
+ spin_lock(&pmbp->lock);
pmbp->link = pmbe;
+ spin_unlock(&pmbp->lock);
+ }
pmbp = pmbe;
@@ -221,16 +270,17 @@ again:
* pmb_sizes[i].size again.
*/
i--;
+
+ spin_unlock_irqrestore(&pmbe->lock, flags);
}
- if (size >= 0x1000000)
+ if (size >= SZ_16M)
goto again;
return wanted - size;
out:
- if (pmbp)
- __pmb_unmap(pmbp);
+ pmb_unmap_entry(pmbp, NR_PMB_ENTRIES);
return err;
}
@@ -240,24 +290,52 @@ void pmb_unmap(unsigned long addr)
struct pmb_entry *pmbe = NULL;
int i;
+ read_lock(&pmb_rwlock);
+
for (i = 0; i < ARRAY_SIZE(pmb_entry_list); i++) {
- if (test_bit(i, &pmb_map)) {
+ if (test_bit(i, pmb_map)) {
pmbe = &pmb_entry_list[i];
if (pmbe->vpn == addr)
break;
}
}
- if (unlikely(!pmbe))
- return;
+ read_unlock(&pmb_rwlock);
- __pmb_unmap(pmbe);
+ pmb_unmap_entry(pmbe, NR_PMB_ENTRIES);
}
-static void __pmb_unmap(struct pmb_entry *pmbe)
+static bool pmb_can_merge(struct pmb_entry *a, struct pmb_entry *b)
{
- BUG_ON(!test_bit(pmbe->entry, &pmb_map));
+ return (b->vpn == (a->vpn + a->size)) &&
+ (b->ppn == (a->ppn + a->size)) &&
+ (b->flags == a->flags);
+}
+static bool pmb_size_valid(unsigned long size)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(pmb_sizes); i++)
+ if (pmb_sizes[i].size == size)
+ return true;
+
+ return false;
+}
+
+static int pmb_size_to_flags(unsigned long size)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(pmb_sizes); i++)
+ if (pmb_sizes[i].size == size)
+ return pmb_sizes[i].flag;
+
+ return 0;
+}
+
+static void __pmb_unmap_entry(struct pmb_entry *pmbe, int depth)
+{
do {
struct pmb_entry *pmblink = pmbe;
@@ -268,102 +346,312 @@ static void __pmb_unmap(struct pmb_entry *pmbe)
* this entry in pmb_alloc() (even if we haven't filled
* it yet).
*
- * Therefore, calling clear_pmb_entry() is safe as no
+ * Therefore, calling __clear_pmb_entry() is safe as no
* other mapping can be using that slot.
*/
- clear_pmb_entry(pmbe);
+ __clear_pmb_entry(pmbe);
pmbe = pmblink->link;
pmb_free(pmblink);
- } while (pmbe);
+ } while (pmbe && --depth);
+}
+
+static void pmb_unmap_entry(struct pmb_entry *pmbe, int depth)
+{
+ unsigned long flags;
+
+ if (unlikely(!pmbe))
+ return;
+
+ write_lock_irqsave(&pmb_rwlock, flags);
+ __pmb_unmap_entry(pmbe, depth);
+ write_unlock_irqrestore(&pmb_rwlock, flags);
+}
+
+static __always_inline unsigned int pmb_ppn_in_range(unsigned long ppn)
+{
+ return ppn >= __pa(memory_start) && ppn < __pa(memory_end);
}
-#ifdef CONFIG_PMB
-int __uses_jump_to_uncached pmb_init(void)
+static void __init pmb_notify(void)
{
- unsigned int i;
- long size, ret;
+ int i;
- jump_to_uncached();
+ pr_info("PMB: boot mappings:\n");
+
+ read_lock(&pmb_rwlock);
+
+ for (i = 0; i < ARRAY_SIZE(pmb_entry_list); i++) {
+ struct pmb_entry *pmbe;
+
+ if (!test_bit(i, pmb_map))
+ continue;
+
+ pmbe = &pmb_entry_list[i];
+
+ pr_info(" 0x%08lx -> 0x%08lx [ %4ldMB %2scached ]\n",
+ pmbe->vpn >> PAGE_SHIFT, pmbe->ppn >> PAGE_SHIFT,
+ pmbe->size >> 20, (pmbe->flags & PMB_C) ? "" : "un");
+ }
+
+ read_unlock(&pmb_rwlock);
+}
+
+/*
+ * Sync our software copy of the PMB mappings with those in hardware. The
+ * mappings in the hardware PMB were either set up by the bootloader or
+ * very early on by the kernel.
+ */
+static void __init pmb_synchronize(void)
+{
+ struct pmb_entry *pmbp = NULL;
+ int i, j;
/*
- * Insert PMB entries for the P1 and P2 areas so that, after
- * we've switched the MMU to 32-bit mode, the semantics of P1
- * and P2 are the same as in 29-bit mode, e.g.
+ * Run through the initial boot mappings, log the established
+ * ones, and blow away anything that falls outside of the valid
+ * PPN range. Specifically, we only care about existing mappings
+ * that impact the cached/uncached sections.
*
- * P1 - provides a cached window onto physical memory
- * P2 - provides an uncached window onto physical memory
+ * Note that touching these can be a bit of a minefield; the boot
+ * loader can establish multi-page mappings with the same caching
+ * attributes, so we need to ensure that we aren't modifying a
+ * mapping that we're presently executing from, or may execute
+ * from in the case of straddling page boundaries.
+ *
+ * In the future we will have to tidy up after the boot loader by
+ * jumping between the cached and uncached mappings and tearing
+ * down alternating mappings while executing from the other.
*/
- size = __MEMORY_START + __MEMORY_SIZE;
+ for (i = 0; i < NR_PMB_ENTRIES; i++) {
+ unsigned long addr, data;
+ unsigned long addr_val, data_val;
+ unsigned long ppn, vpn, flags;
+ unsigned long irqflags;
+ unsigned int size;
+ struct pmb_entry *pmbe;
- ret = pmb_remap(P1SEG, 0x00000000, size, PMB_C);
- BUG_ON(ret != size);
+ addr = mk_pmb_addr(i);
+ data = mk_pmb_data(i);
- ret = pmb_remap(P2SEG, 0x00000000, size, PMB_WT | PMB_UB);
- BUG_ON(ret != size);
+ addr_val = __raw_readl(addr);
+ data_val = __raw_readl(data);
- ctrl_outl(0, PMB_IRMCR);
+ /*
+ * Skip over any bogus entries
+ */
+ if (!(data_val & PMB_V) || !(addr_val & PMB_V))
+ continue;
- /* PMB.SE and UB[7] */
- ctrl_outl(PASCR_SE | (1 << 7), PMB_PASCR);
+ ppn = data_val & PMB_PFN_MASK;
+ vpn = addr_val & PMB_PFN_MASK;
- /* Flush out the TLB */
- i = ctrl_inl(MMUCR);
- i |= MMUCR_TI;
- ctrl_outl(i, MMUCR);
+ /*
+ * Only preserve in-range mappings.
+ */
+ if (!pmb_ppn_in_range(ppn)) {
+ /*
+ * Invalidate anything out of bounds.
+ */
+ writel_uncached(addr_val & ~PMB_V, addr);
+ writel_uncached(data_val & ~PMB_V, data);
+ continue;
+ }
- back_to_cached();
+ /*
+ * Update the caching attributes if necessary
+ */
+ if (data_val & PMB_C) {
+ data_val &= ~PMB_CACHE_MASK;
+ data_val |= pmb_cache_flags();
- return 0;
+ writel_uncached(data_val, data);
+ }
+
+ size = data_val & PMB_SZ_MASK;
+ flags = size | (data_val & PMB_CACHE_MASK);
+
+ pmbe = pmb_alloc(vpn, ppn, flags, i);
+ if (IS_ERR(pmbe)) {
+ WARN_ON_ONCE(1);
+ continue;
+ }
+
+ spin_lock_irqsave(&pmbe->lock, irqflags);
+
+ for (j = 0; j < ARRAY_SIZE(pmb_sizes); j++)
+ if (pmb_sizes[j].flag == size)
+ pmbe->size = pmb_sizes[j].size;
+
+ if (pmbp) {
+ spin_lock(&pmbp->lock);
+
+ /*
+ * Compare the previous entry against the current one to
+ * see if the entries span a contiguous mapping. If so,
+ * setup the entry links accordingly. Compound mappings
+ * are later coalesced.
+ */
+ if (pmb_can_merge(pmbp, pmbe))
+ pmbp->link = pmbe;
+
+ spin_unlock(&pmbp->lock);
+ }
+
+ pmbp = pmbe;
+
+ spin_unlock_irqrestore(&pmbe->lock, irqflags);
+ }
+}
+
+static void __init pmb_merge(struct pmb_entry *head)
+{
+ unsigned long span, newsize;
+ struct pmb_entry *tail;
+ int i = 1, depth = 0;
+
+ span = newsize = head->size;
+
+ tail = head->link;
+ while (tail) {
+ span += tail->size;
+
+ if (pmb_size_valid(span)) {
+ newsize = span;
+ depth = i;
+ }
+
+ /* This is the end of the line.. */
+ if (!tail->link)
+ break;
+
+ tail = tail->link;
+ i++;
+ }
+
+ /*
+ * The merged page size must be valid.
+ */
+ if (!pmb_size_valid(newsize))
+ return;
+
+ head->flags &= ~PMB_SZ_MASK;
+ head->flags |= pmb_size_to_flags(newsize);
+
+ head->size = newsize;
+
+ __pmb_unmap_entry(head->link, depth);
+ __set_pmb_entry(head);
}
-#else
-int __uses_jump_to_uncached pmb_init(void)
+
+static void __init pmb_coalesce(void)
{
+ unsigned long flags;
int i;
- unsigned long addr, data;
- jump_to_uncached();
+ write_lock_irqsave(&pmb_rwlock, flags);
- for (i = 0; i < PMB_ENTRY_MAX; i++) {
+ for (i = 0; i < ARRAY_SIZE(pmb_entry_list); i++) {
struct pmb_entry *pmbe;
- unsigned long vpn, ppn, flags;
- addr = PMB_DATA + (i << PMB_E_SHIFT);
- data = ctrl_inl(addr);
- if (!(data & PMB_V))
+ if (!test_bit(i, pmb_map))
continue;
- if (data & PMB_C) {
-#if defined(CONFIG_CACHE_WRITETHROUGH)
- data |= PMB_WT;
-#elif defined(CONFIG_CACHE_WRITEBACK)
- data &= ~PMB_WT;
-#else
- data &= ~(PMB_C | PMB_WT);
-#endif
- }
- ctrl_outl(data, addr);
+ pmbe = &pmb_entry_list[i];
- ppn = data & PMB_PFN_MASK;
+ /*
+ * We're only interested in compound mappings
+ */
+ if (!pmbe->link)
+ continue;
- flags = data & (PMB_C | PMB_WT | PMB_UB);
- flags |= data & PMB_SZ_MASK;
+ /*
+ * Nothing to do if it already uses the largest possible
+ * page size.
+ */
+ if (pmbe->size == SZ_512M)
+ continue;
- addr = PMB_ADDR + (i << PMB_E_SHIFT);
- data = ctrl_inl(addr);
+ pmb_merge(pmbe);
+ }
- vpn = data & PMB_PFN_MASK;
+ write_unlock_irqrestore(&pmb_rwlock, flags);
+}
- pmbe = pmb_alloc(vpn, ppn, flags, i);
- WARN_ON(IS_ERR(pmbe));
+#ifdef CONFIG_UNCACHED_MAPPING
+static void __init pmb_resize(void)
+{
+ int i;
+
+ /*
+ * If the uncached mapping was constructed by the kernel, it will
+ * already be a reasonable size.
+ */
+ if (uncached_size == SZ_16M)
+ return;
+
+ read_lock(&pmb_rwlock);
+
+ for (i = 0; i < ARRAY_SIZE(pmb_entry_list); i++) {
+ struct pmb_entry *pmbe;
+ unsigned long flags;
+
+ if (!test_bit(i, pmb_map))
+ continue;
+
+ pmbe = &pmb_entry_list[i];
+
+ if (pmbe->vpn != uncached_start)
+ continue;
+
+ /*
+ * Found it, now resize it.
+ */
+ spin_lock_irqsave(&pmbe->lock, flags);
+
+ pmbe->size = SZ_16M;
+ pmbe->flags &= ~PMB_SZ_MASK;
+ pmbe->flags |= pmb_size_to_flags(pmbe->size);
+
+ uncached_resize(pmbe->size);
+
+ __set_pmb_entry(pmbe);
+
+ spin_unlock_irqrestore(&pmbe->lock, flags);
}
- back_to_cached();
+ read_lock(&pmb_rwlock);
+}
+#endif
+
+void __init pmb_init(void)
+{
+ /* Synchronize software state */
+ pmb_synchronize();
- return 0;
+ /* Attempt to combine compound mappings */
+ pmb_coalesce();
+
+#ifdef CONFIG_UNCACHED_MAPPING
+ /* Resize initial mappings, if necessary */
+ pmb_resize();
+#endif
+
+ /* Log them */
+ pmb_notify();
+
+ writel_uncached(0, PMB_IRMCR);
+
+ /* Flush out the TLB */
+ __raw_writel(__raw_readl(MMUCR) | MMUCR_TI, MMUCR);
+ ctrl_barrier();
+}
+
+bool __in_29bit_mode(void)
+{
+ return (__raw_readl(PMB_PASCR) & PASCR_SE) == 0;
}
-#endif /* CONFIG_PMB */
static int pmb_seq_show(struct seq_file *file, void *iter)
{
@@ -378,8 +666,8 @@ static int pmb_seq_show(struct seq_file *file, void *iter)
unsigned int size;
char *sz_str = NULL;
- addr = ctrl_inl(mk_pmb_addr(i));
- data = ctrl_inl(mk_pmb_data(i));
+ addr = __raw_readl(mk_pmb_addr(i));
+ data = __raw_readl(mk_pmb_data(i));
size = data & PMB_SZ_MASK;
sz_str = (size == PMB_SZ_16M) ? " 16MB":
@@ -437,14 +725,21 @@ static int pmb_sysdev_suspend(struct sys_device *dev, pm_message_t state)
if (state.event == PM_EVENT_ON &&
prev_state.event == PM_EVENT_FREEZE) {
struct pmb_entry *pmbe;
+
+ read_lock(&pmb_rwlock);
+
for (i = 0; i < ARRAY_SIZE(pmb_entry_list); i++) {
- if (test_bit(i, &pmb_map)) {
+ if (test_bit(i, pmb_map)) {
pmbe = &pmb_entry_list[i];
set_pmb_entry(pmbe);
}
}
+
+ read_unlock(&pmb_rwlock);
}
+
prev_state = state;
+
return 0;
}
@@ -462,6 +757,5 @@ static int __init pmb_sysdev_init(void)
{
return sysdev_driver_register(&cpu_sysdev_class, &pmb_sysdev_driver);
}
-
subsys_initcall(pmb_sysdev_init);
#endif
diff --git a/arch/sh/mm/tlb-pteaex.c b/arch/sh/mm/tlb-pteaex.c
index 409b7c2b4b9..32dc674c550 100644
--- a/arch/sh/mm/tlb-pteaex.c
+++ b/arch/sh/mm/tlb-pteaex.c
@@ -68,8 +68,7 @@ void __update_tlb(struct vm_area_struct *vma, unsigned long address, pte_t pte)
* in extended mode, the legacy 8-bit ASID field in address array 1 has
* undefined behaviour.
*/
-void __uses_jump_to_uncached local_flush_tlb_one(unsigned long asid,
- unsigned long page)
+void local_flush_tlb_one(unsigned long asid, unsigned long page)
{
jump_to_uncached();
__raw_writel(page, MMU_UTLB_ADDRESS_ARRAY | MMU_PAGE_ASSOC_BIT);
diff --git a/arch/sh/mm/tlb-sh3.c b/arch/sh/mm/tlb-sh3.c
index ace8e6d2f59..4f5f7cbdd50 100644
--- a/arch/sh/mm/tlb-sh3.c
+++ b/arch/sh/mm/tlb-sh3.c
@@ -41,14 +41,14 @@ void __update_tlb(struct vm_area_struct *vma, unsigned long address, pte_t pte)
/* Set PTEH register */
vpn = (address & MMU_VPN_MASK) | get_asid();
- ctrl_outl(vpn, MMU_PTEH);
+ __raw_writel(vpn, MMU_PTEH);
pteval = pte_val(pte);
/* Set PTEL register */
pteval &= _PAGE_FLAGS_HARDWARE_MASK; /* drop software flags */
/* conveniently, we want all the software flags to be 0 anyway */
- ctrl_outl(pteval, MMU_PTEL);
+ __raw_writel(pteval, MMU_PTEL);
/* Load the TLB */
asm volatile("ldtlb": /* no output */ : /* no input */ : "memory");
@@ -75,5 +75,5 @@ void local_flush_tlb_one(unsigned long asid, unsigned long page)
}
for (i = 0; i < ways; i++)
- ctrl_outl(data, addr + (i << 8));
+ __raw_writel(data, addr + (i << 8));
}
diff --git a/arch/sh/mm/tlb-sh4.c b/arch/sh/mm/tlb-sh4.c
index 8cf550e2570..ccac77f504a 100644
--- a/arch/sh/mm/tlb-sh4.c
+++ b/arch/sh/mm/tlb-sh4.c
@@ -29,7 +29,7 @@ void __update_tlb(struct vm_area_struct *vma, unsigned long address, pte_t pte)
/* Set PTEH register */
vpn = (address & MMU_VPN_MASK) | get_asid();
- ctrl_outl(vpn, MMU_PTEH);
+ __raw_writel(vpn, MMU_PTEH);
pteval = pte.pte_low;
@@ -41,13 +41,13 @@ void __update_tlb(struct vm_area_struct *vma, unsigned long address, pte_t pte)
* the protection bits (with the exception of the compat-mode SZ
* and PR bits, which are cleared) being written out in PTEL.
*/
- ctrl_outl(pte.pte_high, MMU_PTEA);
+ __raw_writel(pte.pte_high, MMU_PTEA);
#else
if (cpu_data->flags & CPU_HAS_PTEA) {
/* The last 3 bits and the first one of pteval contains
* the PTEA timing control and space attribute bits
*/
- ctrl_outl(copy_ptea_attributes(pteval), MMU_PTEA);
+ __raw_writel(copy_ptea_attributes(pteval), MMU_PTEA);
}
#endif
@@ -57,15 +57,14 @@ void __update_tlb(struct vm_area_struct *vma, unsigned long address, pte_t pte)
pteval |= _PAGE_WT;
#endif
/* conveniently, we want all the software flags to be 0 anyway */
- ctrl_outl(pteval, MMU_PTEL);
+ __raw_writel(pteval, MMU_PTEL);
/* Load the TLB */
asm volatile("ldtlb": /* no output */ : /* no input */ : "memory");
local_irq_restore(flags);
}
-void __uses_jump_to_uncached local_flush_tlb_one(unsigned long asid,
- unsigned long page)
+void local_flush_tlb_one(unsigned long asid, unsigned long page)
{
unsigned long addr, data;
@@ -78,6 +77,6 @@ void __uses_jump_to_uncached local_flush_tlb_one(unsigned long asid,
addr = MMU_UTLB_ADDRESS_ARRAY | MMU_PAGE_ASSOC_BIT;
data = page | asid; /* VALID bit is off */
jump_to_uncached();
- ctrl_outl(data, addr);
+ __raw_writel(data, addr);
back_to_cached();
}
diff --git a/arch/sh/mm/tlb-sh5.c b/arch/sh/mm/tlb-sh5.c
index fdb64e41ec5..f27dbe1c159 100644
--- a/arch/sh/mm/tlb-sh5.c
+++ b/arch/sh/mm/tlb-sh5.c
@@ -143,3 +143,42 @@ void sh64_setup_tlb_slot(unsigned long long config_addr, unsigned long eaddr,
*/
void sh64_teardown_tlb_slot(unsigned long long config_addr)
__attribute__ ((alias("__flush_tlb_slot")));
+
+static int dtlb_entry;
+static unsigned long long dtlb_entries[64];
+
+void tlb_wire_entry(struct vm_area_struct *vma, unsigned long addr, pte_t pte)
+{
+ unsigned long long entry;
+ unsigned long paddr, flags;
+
+ BUG_ON(dtlb_entry == ARRAY_SIZE(dtlb_entries));
+
+ local_irq_save(flags);
+
+ entry = sh64_get_wired_dtlb_entry();
+ dtlb_entries[dtlb_entry++] = entry;
+
+ paddr = pte_val(pte) & _PAGE_FLAGS_HARDWARE_MASK;
+ paddr &= ~PAGE_MASK;
+
+ sh64_setup_tlb_slot(entry, addr, get_asid(), paddr);
+
+ local_irq_restore(flags);
+}
+
+void tlb_unwire_entry(void)
+{
+ unsigned long long entry;
+ unsigned long flags;
+
+ BUG_ON(!dtlb_entry);
+
+ local_irq_save(flags);
+ entry = dtlb_entries[dtlb_entry--];
+
+ sh64_teardown_tlb_slot(entry);
+ sh64_put_wired_dtlb_entry(entry);
+
+ local_irq_restore(flags);
+}
diff --git a/arch/sh/mm/tlb-urb.c b/arch/sh/mm/tlb-urb.c
new file mode 100644
index 00000000000..bb5b9098956
--- /dev/null
+++ b/arch/sh/mm/tlb-urb.c
@@ -0,0 +1,81 @@
+/*
+ * arch/sh/mm/tlb-urb.c
+ *
+ * TLB entry wiring helpers for URB-equipped parts.
+ *
+ * Copyright (C) 2010 Matt Fleming
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/mm.h>
+#include <linux/io.h>
+#include <asm/tlb.h>
+#include <asm/mmu_context.h>
+
+/*
+ * Load the entry for 'addr' into the TLB and wire the entry.
+ */
+void tlb_wire_entry(struct vm_area_struct *vma, unsigned long addr, pte_t pte)
+{
+ unsigned long status, flags;
+ int urb;
+
+ local_irq_save(flags);
+
+ /* Load the entry into the TLB */
+ __update_tlb(vma, addr, pte);
+
+ /* ... and wire it up. */
+ status = __raw_readl(MMUCR);
+ urb = (status & MMUCR_URB) >> MMUCR_URB_SHIFT;
+ status &= ~MMUCR_URB;
+
+ /*
+ * Make sure we're not trying to wire the last TLB entry slot.
+ */
+ BUG_ON(!--urb);
+
+ urb = urb % MMUCR_URB_NENTRIES;
+
+ status |= (urb << MMUCR_URB_SHIFT);
+ __raw_writel(status, MMUCR);
+ ctrl_barrier();
+
+ local_irq_restore(flags);
+}
+
+/*
+ * Unwire the last wired TLB entry.
+ *
+ * It should also be noted that it is not possible to wire and unwire
+ * TLB entries in an arbitrary order. If you wire TLB entry N, followed
+ * by entry N+1, you must unwire entry N+1 first, then entry N. In this
+ * respect, it works like a stack or LIFO queue.
+ */
+void tlb_unwire_entry(void)
+{
+ unsigned long status, flags;
+ int urb;
+
+ local_irq_save(flags);
+
+ status = __raw_readl(MMUCR);
+ urb = (status & MMUCR_URB) >> MMUCR_URB_SHIFT;
+ status &= ~MMUCR_URB;
+
+ /*
+ * Make sure we're not trying to unwire a TLB entry when none
+ * have been wired.
+ */
+ BUG_ON(urb++ == MMUCR_URB_NENTRIES);
+
+ urb = urb % MMUCR_URB_NENTRIES;
+
+ status |= (urb << MMUCR_URB_SHIFT);
+ __raw_writel(status, MMUCR);
+ ctrl_barrier();
+
+ local_irq_restore(flags);
+}
diff --git a/arch/sh/mm/tlbflush_32.c b/arch/sh/mm/tlbflush_32.c
index 6f45c1f8a7f..004bb3f25b5 100644
--- a/arch/sh/mm/tlbflush_32.c
+++ b/arch/sh/mm/tlbflush_32.c
@@ -132,9 +132,9 @@ void local_flush_tlb_all(void)
* It's same position, bit #2.
*/
local_irq_save(flags);
- status = ctrl_inl(MMUCR);
+ status = __raw_readl(MMUCR);
status |= 0x04;
- ctrl_outl(status, MMUCR);
+ __raw_writel(status, MMUCR);
ctrl_barrier();
local_irq_restore(flags);
}
diff --git a/arch/sh/mm/tlbflush_64.c b/arch/sh/mm/tlbflush_64.c
index de0b0e88182..706da1d3a67 100644
--- a/arch/sh/mm/tlbflush_64.c
+++ b/arch/sh/mm/tlbflush_64.c
@@ -36,7 +36,7 @@ extern void die(const char *,struct pt_regs *,long);
static inline void print_prots(pgprot_t prot)
{
- printk("prot is 0x%08lx\n",pgprot_val(prot));
+ printk("prot is 0x%016llx\n",pgprot_val(prot));
printk("%s %s %s %s %s\n",PPROT(_PAGE_SHARED),PPROT(_PAGE_READ),
PPROT(_PAGE_EXECUTE),PPROT(_PAGE_WRITE),PPROT(_PAGE_USER));
diff --git a/arch/sh/mm/uncached.c b/arch/sh/mm/uncached.c
new file mode 100644
index 00000000000..cf20a5c5136
--- /dev/null
+++ b/arch/sh/mm/uncached.c
@@ -0,0 +1,34 @@
+#include <linux/init.h>
+#include <asm/sizes.h>
+#include <asm/page.h>
+
+/*
+ * This is the offset of the uncached section from its cached alias.
+ *
+ * Legacy platforms handle trivial transitions between cached and
+ * uncached segments by making use of the 1:1 mapping relationship in
+ * 512MB lowmem, others via a special uncached mapping.
+ *
+ * Default value only valid in 29 bit mode, in 32bit mode this will be
+ * updated by the early PMB initialization code.
+ */
+unsigned long cached_to_uncached = SZ_512M;
+unsigned long uncached_size = SZ_512M;
+unsigned long uncached_start, uncached_end;
+
+int virt_addr_uncached(unsigned long kaddr)
+{
+ return (kaddr >= uncached_start) && (kaddr < uncached_end);
+}
+
+void __init uncached_init(void)
+{
+ uncached_start = memory_end;
+ uncached_end = uncached_start + uncached_size;
+}
+
+void __init uncached_resize(unsigned long size)
+{
+ uncached_size = size;
+ uncached_end = uncached_start + uncached_size;
+}
diff --git a/arch/sh/tools/mach-types b/arch/sh/tools/mach-types
index 6639b25d8d5..b25aa554ee5 100644
--- a/arch/sh/tools/mach-types
+++ b/arch/sh/tools/mach-types
@@ -32,6 +32,7 @@ DREAMCAST SH_DREAMCAST
SNAPGEAR SH_SECUREEDGE5410
EDOSK7705 SH_EDOSK7705
EDOSK7760 SH_EDOSK7760
+SDK7786 SH_SDK7786
SH4202_MICRODEV SH_SH4202_MICRODEV
SH03 SH_SH03
LANDISK SH_LANDISK
diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
index 6b3e0c2f33e..6fe4f770118 100644
--- a/drivers/clocksource/sh_cmt.c
+++ b/drivers/clocksource/sh_cmt.c
@@ -603,18 +603,13 @@ static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev)
p->irqaction.handler = sh_cmt_interrupt;
p->irqaction.dev_id = p;
p->irqaction.flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL;
- ret = setup_irq(irq, &p->irqaction);
- if (ret) {
- pr_err("sh_cmt: failed to request irq %d\n", irq);
- goto err1;
- }
/* get hold of clock */
p->clk = clk_get(&p->pdev->dev, cfg->clk);
if (IS_ERR(p->clk)) {
pr_err("sh_cmt: cannot get clock \"%s\"\n", cfg->clk);
ret = PTR_ERR(p->clk);
- goto err2;
+ goto err1;
}
if (resource_size(res) == 6) {
@@ -627,14 +622,25 @@ static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev)
p->clear_bits = ~0xc000;
}
- return sh_cmt_register(p, cfg->name,
- cfg->clockevent_rating,
- cfg->clocksource_rating);
- err2:
- remove_irq(irq, &p->irqaction);
- err1:
+ ret = sh_cmt_register(p, cfg->name,
+ cfg->clockevent_rating,
+ cfg->clocksource_rating);
+ if (ret) {
+ pr_err("sh_cmt: registration failed\n");
+ goto err1;
+ }
+
+ ret = setup_irq(irq, &p->irqaction);
+ if (ret) {
+ pr_err("sh_cmt: failed to request irq %d\n", irq);
+ goto err1;
+ }
+
+ return 0;
+
+err1:
iounmap(p->mapbase);
- err0:
+err0:
return ret;
}
diff --git a/drivers/clocksource/sh_mtu2.c b/drivers/clocksource/sh_mtu2.c
index 973e714d605..4c8a759e60c 100644
--- a/drivers/clocksource/sh_mtu2.c
+++ b/drivers/clocksource/sh_mtu2.c
@@ -221,15 +221,15 @@ static void sh_mtu2_register_clockevent(struct sh_mtu2_priv *p,
ced->cpumask = cpumask_of(0);
ced->set_mode = sh_mtu2_clock_event_mode;
+ pr_info("sh_mtu2: %s used for clock events\n", ced->name);
+ clockevents_register_device(ced);
+
ret = setup_irq(p->irqaction.irq, &p->irqaction);
if (ret) {
pr_err("sh_mtu2: failed to request irq %d\n",
p->irqaction.irq);
return;
}
-
- pr_info("sh_mtu2: %s used for clock events\n", ced->name);
- clockevents_register_device(ced);
}
static int sh_mtu2_register(struct sh_mtu2_priv *p, char *name,
diff --git a/drivers/clocksource/sh_tmu.c b/drivers/clocksource/sh_tmu.c
index 93c2322feab..961f5b5ef6a 100644
--- a/drivers/clocksource/sh_tmu.c
+++ b/drivers/clocksource/sh_tmu.c
@@ -323,15 +323,15 @@ static void sh_tmu_register_clockevent(struct sh_tmu_priv *p,
ced->set_next_event = sh_tmu_clock_event_next;
ced->set_mode = sh_tmu_clock_event_mode;
+ pr_info("sh_tmu: %s used for clock events\n", ced->name);
+ clockevents_register_device(ced);
+
ret = setup_irq(p->irqaction.irq, &p->irqaction);
if (ret) {
pr_err("sh_tmu: failed to request irq %d\n",
p->irqaction.irq);
return;
}
-
- pr_info("sh_tmu: %s used for clock events\n", ced->name);
- clockevents_register_device(ced);
}
static int sh_tmu_register(struct sh_tmu_priv *p, char *name,
diff --git a/drivers/dma/shdma.c b/drivers/dma/shdma.c
index d10cc899c46..b75ce8b84c4 100644
--- a/drivers/dma/shdma.c
+++ b/drivers/dma/shdma.c
@@ -48,23 +48,20 @@ enum sh_dmae_desc_status {
*/
#define RS_DEFAULT (RS_DUAL)
+/* A bitmask with bits enough for enum sh_dmae_slave_chan_id */
+static unsigned long sh_dmae_slave_used[BITS_TO_LONGS(SHDMA_SLAVE_NUMBER)];
+
static void sh_dmae_chan_ld_cleanup(struct sh_dmae_chan *sh_chan, bool all);
#define SH_DMAC_CHAN_BASE(id) (dma_base_addr[id])
static void sh_dmae_writel(struct sh_dmae_chan *sh_dc, u32 data, u32 reg)
{
- ctrl_outl(data, (SH_DMAC_CHAN_BASE(sh_dc->id) + reg));
+ ctrl_outl(data, SH_DMAC_CHAN_BASE(sh_dc->id) + reg);
}
static u32 sh_dmae_readl(struct sh_dmae_chan *sh_dc, u32 reg)
{
- return ctrl_inl((SH_DMAC_CHAN_BASE(sh_dc->id) + reg));
-}
-
-static void dmae_init(struct sh_dmae_chan *sh_chan)
-{
- u32 chcr = RS_DEFAULT; /* default is DUAL mode */
- sh_dmae_writel(sh_chan, chcr, CHCR);
+ return ctrl_inl(SH_DMAC_CHAN_BASE(sh_dc->id) + reg);
}
/*
@@ -95,27 +92,30 @@ static int sh_dmae_rst(int id)
return 0;
}
-static int dmae_is_busy(struct sh_dmae_chan *sh_chan)
+static bool dmae_is_busy(struct sh_dmae_chan *sh_chan)
{
u32 chcr = sh_dmae_readl(sh_chan, CHCR);
- if (chcr & CHCR_DE) {
- if (!(chcr & CHCR_TE))
- return -EBUSY; /* working */
- }
- return 0; /* waiting */
+
+ if ((chcr & (CHCR_DE | CHCR_TE)) == CHCR_DE)
+ return true; /* working */
+
+ return false; /* waiting */
}
-static inline unsigned int calc_xmit_shift(struct sh_dmae_chan *sh_chan)
+static unsigned int ts_shift[] = TS_SHIFT;
+static inline unsigned int calc_xmit_shift(u32 chcr)
{
- u32 chcr = sh_dmae_readl(sh_chan, CHCR);
- return ts_shift[(chcr & CHCR_TS_MASK) >> CHCR_TS_SHIFT];
+ int cnt = ((chcr & CHCR_TS_LOW_MASK) >> CHCR_TS_LOW_SHIFT) |
+ ((chcr & CHCR_TS_HIGH_MASK) >> CHCR_TS_HIGH_SHIFT);
+
+ return ts_shift[cnt];
}
static void dmae_set_reg(struct sh_dmae_chan *sh_chan, struct sh_dmae_regs *hw)
{
sh_dmae_writel(sh_chan, hw->sar, SAR);
sh_dmae_writel(sh_chan, hw->dar, DAR);
- sh_dmae_writel(sh_chan, hw->tcr >> calc_xmit_shift(sh_chan), TCR);
+ sh_dmae_writel(sh_chan, hw->tcr >> sh_chan->xmit_shift, TCR);
}
static void dmae_start(struct sh_dmae_chan *sh_chan)
@@ -123,7 +123,7 @@ static void dmae_start(struct sh_dmae_chan *sh_chan)
u32 chcr = sh_dmae_readl(sh_chan, CHCR);
chcr |= CHCR_DE | CHCR_IE;
- sh_dmae_writel(sh_chan, chcr, CHCR);
+ sh_dmae_writel(sh_chan, chcr & ~CHCR_TE, CHCR);
}
static void dmae_halt(struct sh_dmae_chan *sh_chan)
@@ -134,55 +134,50 @@ static void dmae_halt(struct sh_dmae_chan *sh_chan)
sh_dmae_writel(sh_chan, chcr, CHCR);
}
+static void dmae_init(struct sh_dmae_chan *sh_chan)
+{
+ u32 chcr = RS_DEFAULT; /* default is DUAL mode */
+ sh_chan->xmit_shift = calc_xmit_shift(chcr);
+ sh_dmae_writel(sh_chan, chcr, CHCR);
+}
+
static int dmae_set_chcr(struct sh_dmae_chan *sh_chan, u32 val)
{
- int ret = dmae_is_busy(sh_chan);
/* When DMA was working, can not set data to CHCR */
- if (ret)
- return ret;
+ if (dmae_is_busy(sh_chan))
+ return -EBUSY;
+ sh_chan->xmit_shift = calc_xmit_shift(val);
sh_dmae_writel(sh_chan, val, CHCR);
+
return 0;
}
-#define DMARS1_ADDR 0x04
-#define DMARS2_ADDR 0x08
-#define DMARS_SHIFT 8
-#define DMARS_CHAN_MSK 0x01
+#define DMARS_SHIFT 8
+#define DMARS_CHAN_MSK 0x01
static int dmae_set_dmars(struct sh_dmae_chan *sh_chan, u16 val)
{
u32 addr;
int shift = 0;
- int ret = dmae_is_busy(sh_chan);
- if (ret)
- return ret;
+
+ if (dmae_is_busy(sh_chan))
+ return -EBUSY;
if (sh_chan->id & DMARS_CHAN_MSK)
shift = DMARS_SHIFT;
- switch (sh_chan->id) {
- /* DMARS0 */
- case 0:
- case 1:
- addr = SH_DMARS_BASE;
- break;
- /* DMARS1 */
- case 2:
- case 3:
- addr = (SH_DMARS_BASE + DMARS1_ADDR);
- break;
- /* DMARS2 */
- case 4:
- case 5:
- addr = (SH_DMARS_BASE + DMARS2_ADDR);
- break;
- default:
+ if (sh_chan->id < 6)
+ /* DMA0RS0 - DMA0RS2 */
+ addr = SH_DMARS_BASE0 + (sh_chan->id / 2) * 4;
+#ifdef SH_DMARS_BASE1
+ else if (sh_chan->id < 12)
+ /* DMA1RS0 - DMA1RS2 */
+ addr = SH_DMARS_BASE1 + ((sh_chan->id - 6) / 2) * 4;
+#endif
+ else
return -EINVAL;
- }
- ctrl_outw((val << shift) |
- (ctrl_inw(addr) & (shift ? 0xFF00 : 0x00FF)),
- addr);
+ ctrl_outw((val << shift) | (ctrl_inw(addr) & (0xFF00 >> shift)), addr);
return 0;
}
@@ -250,10 +245,53 @@ static struct sh_desc *sh_dmae_get_desc(struct sh_dmae_chan *sh_chan)
return NULL;
}
+static struct sh_dmae_slave_config *sh_dmae_find_slave(
+ struct sh_dmae_chan *sh_chan, enum sh_dmae_slave_chan_id slave_id)
+{
+ struct dma_device *dma_dev = sh_chan->common.device;
+ struct sh_dmae_device *shdev = container_of(dma_dev,
+ struct sh_dmae_device, common);
+ struct sh_dmae_pdata *pdata = &shdev->pdata;
+ int i;
+
+ if ((unsigned)slave_id >= SHDMA_SLAVE_NUMBER)
+ return NULL;
+
+ for (i = 0; i < pdata->config_num; i++)
+ if (pdata->config[i].slave_id == slave_id)
+ return pdata->config + i;
+
+ return NULL;
+}
+
static int sh_dmae_alloc_chan_resources(struct dma_chan *chan)
{
struct sh_dmae_chan *sh_chan = to_sh_chan(chan);
struct sh_desc *desc;
+ struct sh_dmae_slave *param = chan->private;
+
+ /*
+ * This relies on the guarantee from dmaengine that alloc_chan_resources
+ * never runs concurrently with itself or free_chan_resources.
+ */
+ if (param) {
+ struct sh_dmae_slave_config *cfg;
+
+ cfg = sh_dmae_find_slave(sh_chan, param->slave_id);
+ if (!cfg)
+ return -EINVAL;
+
+ if (test_and_set_bit(param->slave_id, sh_dmae_slave_used))
+ return -EBUSY;
+
+ param->config = cfg;
+
+ dmae_set_dmars(sh_chan, cfg->mid_rid);
+ dmae_set_chcr(sh_chan, cfg->chcr);
+ } else {
+ if ((sh_dmae_readl(sh_chan, CHCR) & 0x700) != 0x400)
+ dmae_set_chcr(sh_chan, RS_DEFAULT);
+ }
spin_lock_bh(&sh_chan->desc_lock);
while (sh_chan->descs_allocated < NR_DESCS_PER_CHANNEL) {
@@ -286,10 +324,18 @@ static void sh_dmae_free_chan_resources(struct dma_chan *chan)
struct sh_desc *desc, *_desc;
LIST_HEAD(list);
+ dmae_halt(sh_chan);
+
/* Prepared and not submitted descriptors can still be on the queue */
if (!list_empty(&sh_chan->ld_queue))
sh_dmae_chan_ld_cleanup(sh_chan, true);
+ if (chan->private) {
+ /* The caller is holding dma_list_mutex */
+ struct sh_dmae_slave *param = chan->private;
+ clear_bit(param->slave_id, sh_dmae_slave_used);
+ }
+
spin_lock_bh(&sh_chan->desc_lock);
list_splice_init(&sh_chan->ld_free, &list);
@@ -301,23 +347,97 @@ static void sh_dmae_free_chan_resources(struct dma_chan *chan)
kfree(desc);
}
-static struct dma_async_tx_descriptor *sh_dmae_prep_memcpy(
- struct dma_chan *chan, dma_addr_t dma_dest, dma_addr_t dma_src,
- size_t len, unsigned long flags)
+/**
+ * sh_dmae_add_desc - get, set up and return one transfer descriptor
+ * @sh_chan: DMA channel
+ * @flags: DMA transfer flags
+ * @dest: destination DMA address, incremented when direction equals
+ * DMA_FROM_DEVICE or DMA_BIDIRECTIONAL
+ * @src: source DMA address, incremented when direction equals
+ * DMA_TO_DEVICE or DMA_BIDIRECTIONAL
+ * @len: DMA transfer length
+ * @first: if NULL, set to the current descriptor and cookie set to -EBUSY
+ * @direction: needed for slave DMA to decide which address to keep constant,
+ * equals DMA_BIDIRECTIONAL for MEMCPY
+ * Returns 0 or an error
+ * Locks: called with desc_lock held
+ */
+static struct sh_desc *sh_dmae_add_desc(struct sh_dmae_chan *sh_chan,
+ unsigned long flags, dma_addr_t *dest, dma_addr_t *src, size_t *len,
+ struct sh_desc **first, enum dma_data_direction direction)
{
- struct sh_dmae_chan *sh_chan;
- struct sh_desc *first = NULL, *prev = NULL, *new;
+ struct sh_desc *new;
size_t copy_size;
- LIST_HEAD(tx_list);
- int chunks = (len + SH_DMA_TCR_MAX) / (SH_DMA_TCR_MAX + 1);
- if (!chan)
+ if (!*len)
return NULL;
- if (!len)
+ /* Allocate the link descriptor from the free list */
+ new = sh_dmae_get_desc(sh_chan);
+ if (!new) {
+ dev_err(sh_chan->dev, "No free link descriptor available\n");
return NULL;
+ }
- sh_chan = to_sh_chan(chan);
+ copy_size = min(*len, (size_t)SH_DMA_TCR_MAX + 1);
+
+ new->hw.sar = *src;
+ new->hw.dar = *dest;
+ new->hw.tcr = copy_size;
+
+ if (!*first) {
+ /* First desc */
+ new->async_tx.cookie = -EBUSY;
+ *first = new;
+ } else {
+ /* Other desc - invisible to the user */
+ new->async_tx.cookie = -EINVAL;
+ }
+
+ dev_dbg(sh_chan->dev,
+ "chaining (%u/%u)@%x -> %x with %p, cookie %d, shift %d\n",
+ copy_size, *len, *src, *dest, &new->async_tx,
+ new->async_tx.cookie, sh_chan->xmit_shift);
+
+ new->mark = DESC_PREPARED;
+ new->async_tx.flags = flags;
+ new->direction = direction;
+
+ *len -= copy_size;
+ if (direction == DMA_BIDIRECTIONAL || direction == DMA_TO_DEVICE)
+ *src += copy_size;
+ if (direction == DMA_BIDIRECTIONAL || direction == DMA_FROM_DEVICE)
+ *dest += copy_size;
+
+ return new;
+}
+
+/*
+ * sh_dmae_prep_sg - prepare transfer descriptors from an SG list
+ *
+ * Common routine for public (MEMCPY) and slave DMA. The MEMCPY case is also
+ * converted to scatter-gather to guarantee consistent locking and a correct
+ * list manipulation. For slave DMA direction carries the usual meaning, and,
+ * logically, the SG list is RAM and the addr variable contains slave address,
+ * e.g., the FIFO I/O register. For MEMCPY direction equals DMA_BIDIRECTIONAL
+ * and the SG list contains only one element and points at the source buffer.
+ */
+static struct dma_async_tx_descriptor *sh_dmae_prep_sg(struct sh_dmae_chan *sh_chan,
+ struct scatterlist *sgl, unsigned int sg_len, dma_addr_t *addr,
+ enum dma_data_direction direction, unsigned long flags)
+{
+ struct scatterlist *sg;
+ struct sh_desc *first = NULL, *new = NULL /* compiler... */;
+ LIST_HEAD(tx_list);
+ int chunks = 0;
+ int i;
+
+ if (!sg_len)
+ return NULL;
+
+ for_each_sg(sgl, sg, sg_len, i)
+ chunks += (sg_dma_len(sg) + SH_DMA_TCR_MAX) /
+ (SH_DMA_TCR_MAX + 1);
/* Have to lock the whole loop to protect against concurrent release */
spin_lock_bh(&sh_chan->desc_lock);
@@ -333,49 +453,32 @@ static struct dma_async_tx_descriptor *sh_dmae_prep_memcpy(
* only during this function, then they are immediately spliced
* back onto the free list in form of a chain
*/
- do {
- /* Allocate the link descriptor from the free list */
- new = sh_dmae_get_desc(sh_chan);
- if (!new) {
- dev_err(sh_chan->dev,
- "No free memory for link descriptor\n");
- list_for_each_entry(new, &tx_list, node)
- new->mark = DESC_IDLE;
- list_splice(&tx_list, &sh_chan->ld_free);
- spin_unlock_bh(&sh_chan->desc_lock);
- return NULL;
- }
-
- copy_size = min(len, (size_t)SH_DMA_TCR_MAX + 1);
-
- new->hw.sar = dma_src;
- new->hw.dar = dma_dest;
- new->hw.tcr = copy_size;
- if (!first) {
- /* First desc */
- new->async_tx.cookie = -EBUSY;
- first = new;
- } else {
- /* Other desc - invisible to the user */
- new->async_tx.cookie = -EINVAL;
- }
-
- dev_dbg(sh_chan->dev,
- "chaining %u of %u with %p, dst %x, cookie %d\n",
- copy_size, len, &new->async_tx, dma_dest,
- new->async_tx.cookie);
-
- new->mark = DESC_PREPARED;
- new->async_tx.flags = flags;
- new->chunks = chunks--;
-
- prev = new;
- len -= copy_size;
- dma_src += copy_size;
- dma_dest += copy_size;
- /* Insert the link descriptor to the LD ring */
- list_add_tail(&new->node, &tx_list);
- } while (len);
+ for_each_sg(sgl, sg, sg_len, i) {
+ dma_addr_t sg_addr = sg_dma_address(sg);
+ size_t len = sg_dma_len(sg);
+
+ if (!len)
+ goto err_get_desc;
+
+ do {
+ dev_dbg(sh_chan->dev, "Add SG #%d@%p[%d], dma %llx\n",
+ i, sg, len, (unsigned long long)sg_addr);
+
+ if (direction == DMA_FROM_DEVICE)
+ new = sh_dmae_add_desc(sh_chan, flags,
+ &sg_addr, addr, &len, &first,
+ direction);
+ else
+ new = sh_dmae_add_desc(sh_chan, flags,
+ addr, &sg_addr, &len, &first,
+ direction);
+ if (!new)
+ goto err_get_desc;
+
+ new->chunks = chunks--;
+ list_add_tail(&new->node, &tx_list);
+ } while (len);
+ }
if (new != first)
new->async_tx.cookie = -ENOSPC;
@@ -386,6 +489,77 @@ static struct dma_async_tx_descriptor *sh_dmae_prep_memcpy(
spin_unlock_bh(&sh_chan->desc_lock);
return &first->async_tx;
+
+err_get_desc:
+ list_for_each_entry(new, &tx_list, node)
+ new->mark = DESC_IDLE;
+ list_splice(&tx_list, &sh_chan->ld_free);
+
+ spin_unlock_bh(&sh_chan->desc_lock);
+
+ return NULL;
+}
+
+static struct dma_async_tx_descriptor *sh_dmae_prep_memcpy(
+ struct dma_chan *chan, dma_addr_t dma_dest, dma_addr_t dma_src,
+ size_t len, unsigned long flags)
+{
+ struct sh_dmae_chan *sh_chan;
+ struct scatterlist sg;
+
+ if (!chan || !len)
+ return NULL;
+
+ chan->private = NULL;
+
+ sh_chan = to_sh_chan(chan);
+
+ sg_init_table(&sg, 1);
+ sg_set_page(&sg, pfn_to_page(PFN_DOWN(dma_src)), len,
+ offset_in_page(dma_src));
+ sg_dma_address(&sg) = dma_src;
+ sg_dma_len(&sg) = len;
+
+ return sh_dmae_prep_sg(sh_chan, &sg, 1, &dma_dest, DMA_BIDIRECTIONAL,
+ flags);
+}
+
+static struct dma_async_tx_descriptor *sh_dmae_prep_slave_sg(
+ struct dma_chan *chan, struct scatterlist *sgl, unsigned int sg_len,
+ enum dma_data_direction direction, unsigned long flags)
+{
+ struct sh_dmae_slave *param;
+ struct sh_dmae_chan *sh_chan;
+
+ if (!chan)
+ return NULL;
+
+ sh_chan = to_sh_chan(chan);
+ param = chan->private;
+
+ /* Someone calling slave DMA on a public channel? */
+ if (!param || !sg_len) {
+ dev_warn(sh_chan->dev, "%s: bad parameter: %p, %d, %d\n",
+ __func__, param, sg_len, param ? param->slave_id : -1);
+ return NULL;
+ }
+
+ /*
+ * if (param != NULL), this is a successfully requested slave channel,
+ * therefore param->config != NULL too.
+ */
+ return sh_dmae_prep_sg(sh_chan, sgl, sg_len, &param->config->addr,
+ direction, flags);
+}
+
+static void sh_dmae_terminate_all(struct dma_chan *chan)
+{
+ struct sh_dmae_chan *sh_chan = to_sh_chan(chan);
+
+ if (!chan)
+ return;
+
+ sh_dmae_chan_ld_cleanup(sh_chan, true);
}
static dma_async_tx_callback __ld_cleanup(struct sh_dmae_chan *sh_chan, bool all)
@@ -419,7 +593,11 @@ static dma_async_tx_callback __ld_cleanup(struct sh_dmae_chan *sh_chan, bool all
cookie = tx->cookie;
if (desc->mark == DESC_COMPLETED && desc->chunks == 1) {
- BUG_ON(sh_chan->completed_cookie != desc->cookie - 1);
+ if (sh_chan->completed_cookie != desc->cookie - 1)
+ dev_dbg(sh_chan->dev,
+ "Completing cookie %d, expected %d\n",
+ desc->cookie,
+ sh_chan->completed_cookie + 1);
sh_chan->completed_cookie = desc->cookie;
}
@@ -492,7 +670,7 @@ static void sh_chan_xfer_ld_queue(struct sh_dmae_chan *sh_chan)
return;
}
- /* Find the first un-transfer desciptor */
+ /* Find the first not transferred desciptor */
list_for_each_entry(sd, &sh_chan->ld_queue, node)
if (sd->mark == DESC_SUBMITTED) {
/* Get the ld start address from ld_queue */
@@ -559,7 +737,7 @@ static irqreturn_t sh_dmae_err(int irq, void *data)
/* IRQ Multi */
if (shdev->pdata.mode & SHDMA_MIX_IRQ) {
- int cnt = 0;
+ int __maybe_unused cnt = 0;
switch (irq) {
#if defined(DMTE6_IRQ) && defined(DMAE1_IRQ)
case DMTE6_IRQ:
@@ -596,11 +774,14 @@ static void dmae_do_tasklet(unsigned long data)
struct sh_dmae_chan *sh_chan = (struct sh_dmae_chan *)data;
struct sh_desc *desc;
u32 sar_buf = sh_dmae_readl(sh_chan, SAR);
+ u32 dar_buf = sh_dmae_readl(sh_chan, DAR);
spin_lock(&sh_chan->desc_lock);
list_for_each_entry(desc, &sh_chan->ld_queue, node) {
- if ((desc->hw.sar + desc->hw.tcr) == sar_buf &&
- desc->mark == DESC_SUBMITTED) {
+ if (desc->mark == DESC_SUBMITTED &&
+ ((desc->direction == DMA_FROM_DEVICE &&
+ (desc->hw.dar + desc->hw.tcr) == dar_buf) ||
+ (desc->hw.sar + desc->hw.tcr) == sar_buf)) {
dev_dbg(sh_chan->dev, "done #%d@%p dst %u\n",
desc->async_tx.cookie, &desc->async_tx,
desc->hw.dar);
@@ -673,7 +854,7 @@ static int __devinit sh_dmae_chan_probe(struct sh_dmae_device *shdev, int id)
}
snprintf(new_sh_chan->dev_id, sizeof(new_sh_chan->dev_id),
- "sh-dmae%d", new_sh_chan->id);
+ "sh-dmae%d", new_sh_chan->id);
/* set up channel irq */
err = request_irq(irq, &sh_dmae_interrupt, irqflags,
@@ -684,11 +865,6 @@ static int __devinit sh_dmae_chan_probe(struct sh_dmae_device *shdev, int id)
goto err_no_irq;
}
- /* CHCR register control function */
- new_sh_chan->set_chcr = dmae_set_chcr;
- /* DMARS register control function */
- new_sh_chan->set_dmars = dmae_set_dmars;
-
shdev->chan[id] = new_sh_chan;
return 0;
@@ -759,12 +935,19 @@ static int __init sh_dmae_probe(struct platform_device *pdev)
INIT_LIST_HEAD(&shdev->common.channels);
dma_cap_set(DMA_MEMCPY, shdev->common.cap_mask);
+ dma_cap_set(DMA_SLAVE, shdev->common.cap_mask);
+
shdev->common.device_alloc_chan_resources
= sh_dmae_alloc_chan_resources;
shdev->common.device_free_chan_resources = sh_dmae_free_chan_resources;
shdev->common.device_prep_dma_memcpy = sh_dmae_prep_memcpy;
shdev->common.device_is_tx_complete = sh_dmae_is_complete;
shdev->common.device_issue_pending = sh_dmae_memcpy_issue_pending;
+
+ /* Compulsory for DMA_SLAVE fields */
+ shdev->common.device_prep_slave_sg = sh_dmae_prep_slave_sg;
+ shdev->common.device_terminate_all = sh_dmae_terminate_all;
+
shdev->common.dev = &pdev->dev;
/* Default transfer size of 32 bytes requires 32-byte alignment */
shdev->common.copy_align = 5;
diff --git a/drivers/dma/shdma.h b/drivers/dma/shdma.h
index 108f1cffb6f..7e227f3c87c 100644
--- a/drivers/dma/shdma.h
+++ b/drivers/dma/shdma.h
@@ -29,6 +29,7 @@ struct sh_desc {
struct sh_dmae_regs hw;
struct list_head node;
struct dma_async_tx_descriptor async_tx;
+ enum dma_data_direction direction;
dma_cookie_t cookie;
int chunks;
int mark;
@@ -45,13 +46,9 @@ struct sh_dmae_chan {
struct device *dev; /* Channel device */
struct tasklet_struct tasklet; /* Tasklet */
int descs_allocated; /* desc count */
+ int xmit_shift; /* log_2(bytes_per_xfer) */
int id; /* Raw id of this channel */
char dev_id[16]; /* unique name per DMAC of channel */
-
- /* Set chcr */
- int (*set_chcr)(struct sh_dmae_chan *sh_chan, u32 regs);
- /* Set DMA resource */
- int (*set_dmars)(struct sh_dmae_chan *sh_chan, u16 res);
};
struct sh_dmae_device {
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 677cd53f18c..bb646560423 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -457,10 +457,10 @@ config MTD_NAND_NOMADIK
config MTD_NAND_SH_FLCTL
tristate "Support for NAND on Renesas SuperH FLCTL"
- depends on MTD_NAND && SUPERH && CPU_SUBTYPE_SH7723
+ depends on MTD_NAND && SUPERH
help
Several Renesas SuperH CPU has FLCTL. This option enables support
- for NAND Flash using FLCTL. This driver support SH7723.
+ for NAND Flash using FLCTL.
config MTD_NAND_DAVINCI
tristate "Support NAND on DaVinci SoC"
diff --git a/drivers/mtd/nand/sh_flctl.c b/drivers/mtd/nand/sh_flctl.c
index 02bef21f2e4..1842df8bdd9 100644
--- a/drivers/mtd/nand/sh_flctl.c
+++ b/drivers/mtd/nand/sh_flctl.c
@@ -1,10 +1,10 @@
/*
* SuperH FLCTL nand controller
*
- * Copyright © 2008 Renesas Solutions Corp.
- * Copyright © 2008 Atom Create Engineering Co., Ltd.
+ * Copyright (c) 2008 Renesas Solutions Corp.
+ * Copyright (c) 2008 Atom Create Engineering Co., Ltd.
*
- * Based on fsl_elbc_nand.c, Copyright © 2006-2007 Freescale Semiconductor
+ * Based on fsl_elbc_nand.c, Copyright (c) 2006-2007 Freescale Semiconductor
*
* 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
@@ -75,6 +75,11 @@ static void start_translation(struct sh_flctl *flctl)
writeb(TRSTRT, FLTRCR(flctl));
}
+static void timeout_error(struct sh_flctl *flctl, const char *str)
+{
+ dev_err(&flctl->pdev->dev, "Timeout occured in %s\n", str);
+}
+
static void wait_completion(struct sh_flctl *flctl)
{
uint32_t timeout = LOOP_TIMEOUT_MAX;
@@ -87,7 +92,7 @@ static void wait_completion(struct sh_flctl *flctl)
udelay(1);
}
- printk(KERN_ERR "wait_completion(): Timeout occured \n");
+ timeout_error(flctl, __func__);
writeb(0x0, FLTRCR(flctl));
}
@@ -100,6 +105,8 @@ static void set_addr(struct mtd_info *mtd, int column, int page_addr)
addr = page_addr; /* ERASE1 */
} else if (page_addr != -1) {
/* SEQIN, READ0, etc.. */
+ if (flctl->chip.options & NAND_BUSWIDTH_16)
+ column >>= 1;
if (flctl->page_size) {
addr = column & 0x0FFF;
addr |= (page_addr & 0xff) << 16;
@@ -132,7 +139,7 @@ static void wait_rfifo_ready(struct sh_flctl *flctl)
return;
udelay(1);
}
- printk(KERN_ERR "wait_rfifo_ready(): Timeout occured \n");
+ timeout_error(flctl, __func__);
}
static void wait_wfifo_ready(struct sh_flctl *flctl)
@@ -146,7 +153,7 @@ static void wait_wfifo_ready(struct sh_flctl *flctl)
return;
udelay(1);
}
- printk(KERN_ERR "wait_wfifo_ready(): Timeout occured \n");
+ timeout_error(flctl, __func__);
}
static int wait_recfifo_ready(struct sh_flctl *flctl, int sector_number)
@@ -198,7 +205,7 @@ static int wait_recfifo_ready(struct sh_flctl *flctl, int sector_number)
writel(0, FL4ECCCR(flctl));
}
- printk(KERN_ERR "wait_recfifo_ready(): Timeout occured \n");
+ timeout_error(flctl, __func__);
return 1; /* timeout */
}
@@ -214,7 +221,7 @@ static void wait_wecfifo_ready(struct sh_flctl *flctl)
return;
udelay(1);
}
- printk(KERN_ERR "wait_wecfifo_ready(): Timeout occured \n");
+ timeout_error(flctl, __func__);
}
static void read_datareg(struct sh_flctl *flctl, int offset)
@@ -275,7 +282,7 @@ static void write_fiforeg(struct sh_flctl *flctl, int rlen, int offset)
static void set_cmd_regs(struct mtd_info *mtd, uint32_t cmd, uint32_t flcmcdr_val)
{
struct sh_flctl *flctl = mtd_to_flctl(mtd);
- uint32_t flcmncr_val = readl(FLCMNCR(flctl));
+ uint32_t flcmncr_val = readl(FLCMNCR(flctl)) & ~SEL_16BIT;
uint32_t flcmdcr_val, addr_len_bytes = 0;
/* Set SNAND bit if page size is 2048byte */
@@ -297,6 +304,8 @@ static void set_cmd_regs(struct mtd_info *mtd, uint32_t cmd, uint32_t flcmcdr_va
case NAND_CMD_READOOB:
addr_len_bytes = flctl->rw_ADRCNT;
flcmdcr_val |= CDSRC_E;
+ if (flctl->chip.options & NAND_BUSWIDTH_16)
+ flcmncr_val |= SEL_16BIT;
break;
case NAND_CMD_SEQIN:
/* This case is that cmd is READ0 or READ1 or READ00 */
@@ -305,6 +314,8 @@ static void set_cmd_regs(struct mtd_info *mtd, uint32_t cmd, uint32_t flcmcdr_va
case NAND_CMD_PAGEPROG:
addr_len_bytes = flctl->rw_ADRCNT;
flcmdcr_val |= DOCMD2_E | CDSRC_E | SELRW;
+ if (flctl->chip.options & NAND_BUSWIDTH_16)
+ flcmncr_val |= SEL_16BIT;
break;
case NAND_CMD_READID:
flcmncr_val &= ~SNAND_E;
@@ -523,6 +534,8 @@ static void flctl_cmdfunc(struct mtd_info *mtd, unsigned int command,
set_addr(mtd, 0, page_addr);
flctl->read_bytes = mtd->writesize + mtd->oobsize;
+ if (flctl->chip.options & NAND_BUSWIDTH_16)
+ column >>= 1;
flctl->index += column;
goto read_normal_exit;
@@ -686,6 +699,18 @@ static uint8_t flctl_read_byte(struct mtd_info *mtd)
return data;
}
+static uint16_t flctl_read_word(struct mtd_info *mtd)
+{
+ struct sh_flctl *flctl = mtd_to_flctl(mtd);
+ int index = flctl->index;
+ uint16_t data;
+ uint16_t *buf = (uint16_t *)&flctl->done_buff[index];
+
+ data = *buf;
+ flctl->index += 2;
+ return data;
+}
+
static void flctl_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
{
int i;
@@ -769,38 +794,36 @@ static int flctl_chip_init_tail(struct mtd_info *mtd)
return 0;
}
-static int __init flctl_probe(struct platform_device *pdev)
+static int __devinit flctl_probe(struct platform_device *pdev)
{
struct resource *res;
struct sh_flctl *flctl;
struct mtd_info *flctl_mtd;
struct nand_chip *nand;
struct sh_flctl_platform_data *pdata;
- int ret;
+ int ret = -ENXIO;
pdata = pdev->dev.platform_data;
if (pdata == NULL) {
- printk(KERN_ERR "sh_flctl platform_data not found.\n");
- return -ENODEV;
+ dev_err(&pdev->dev, "no platform data defined\n");
+ return -EINVAL;
}
flctl = kzalloc(sizeof(struct sh_flctl), GFP_KERNEL);
if (!flctl) {
- printk(KERN_ERR "Unable to allocate NAND MTD dev structure.\n");
+ dev_err(&pdev->dev, "failed to allocate driver data\n");
return -ENOMEM;
}
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
- printk(KERN_ERR "%s: resource not found.\n", __func__);
- ret = -ENODEV;
+ dev_err(&pdev->dev, "failed to get I/O memory\n");
goto err;
}
- flctl->reg = ioremap(res->start, res->end - res->start + 1);
+ flctl->reg = ioremap(res->start, resource_size(res));
if (flctl->reg == NULL) {
- printk(KERN_ERR "%s: ioremap error.\n", __func__);
- ret = -ENOMEM;
+ dev_err(&pdev->dev, "failed to remap I/O memory\n");
goto err;
}
@@ -808,6 +831,7 @@ static int __init flctl_probe(struct platform_device *pdev)
flctl_mtd = &flctl->mtd;
nand = &flctl->chip;
flctl_mtd->priv = nand;
+ flctl->pdev = pdev;
flctl->hwecc = pdata->has_hwecc;
flctl_register_init(flctl, pdata->flcmncr_val);
@@ -825,6 +849,11 @@ static int __init flctl_probe(struct platform_device *pdev)
nand->select_chip = flctl_select_chip;
nand->cmdfunc = flctl_cmdfunc;
+ if (pdata->flcmncr_val & SEL_16BIT) {
+ nand->options |= NAND_BUSWIDTH_16;
+ nand->read_word = flctl_read_word;
+ }
+
ret = nand_scan_ident(flctl_mtd, 1);
if (ret)
goto err;
@@ -846,7 +875,7 @@ err:
return ret;
}
-static int __exit flctl_remove(struct platform_device *pdev)
+static int __devexit flctl_remove(struct platform_device *pdev)
{
struct sh_flctl *flctl = platform_get_drvdata(pdev);
diff --git a/drivers/serial/sh-sci.h b/drivers/serial/sh-sci.h
index 0efcded59ae..f7d2589926d 100644
--- a/drivers/serial/sh-sci.h
+++ b/drivers/serial/sh-sci.h
@@ -518,34 +518,6 @@ static inline int sci_rxd_in(struct uart_port *port)
{
if (port->mapbase == 0xfffffe80)
return __raw_readb(SCPDR)&0x01 ? 1 : 0; /* SCI */
- if (port->mapbase == 0xa4000150)
- return __raw_readb(SCPDR)&0x10 ? 1 : 0; /* SCIF */
- if (port->mapbase == 0xa4000140)
- return __raw_readb(SCPDR)&0x04 ? 1 : 0; /* IRDA */
- return 1;
-}
-#elif defined(CONFIG_CPU_SUBTYPE_SH7705)
-static inline int sci_rxd_in(struct uart_port *port)
-{
- if (port->mapbase == SCIF0)
- return __raw_readb(SCPDR)&0x04 ? 1 : 0; /* IRDA */
- if (port->mapbase == SCIF2)
- return __raw_readb(SCPDR)&0x10 ? 1 : 0; /* SCIF */
- return 1;
-}
-#elif defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712)
-static inline int sci_rxd_in(struct uart_port *port)
-{
- return sci_in(port,SCxSR)&0x0010 ? 1 : 0;
-}
-#elif defined(CONFIG_CPU_SUBTYPE_SH7720) || \
- defined(CONFIG_CPU_SUBTYPE_SH7721)
-static inline int sci_rxd_in(struct uart_port *port)
-{
- if (port->mapbase == 0xa4430000)
- return sci_in(port, SCxSR) & 0x0003 ? 1 : 0;
- else if (port->mapbase == 0xa4438000)
- return sci_in(port, SCxSR) & 0x0003 ? 1 : 0;
return 1;
}
#elif defined(CONFIG_CPU_SUBTYPE_SH7750) || \
@@ -558,207 +530,17 @@ static inline int sci_rxd_in(struct uart_port *port)
{
if (port->mapbase == 0xffe00000)
return __raw_readb(SCSPTR1)&0x01 ? 1 : 0; /* SCI */
- if (port->mapbase == 0xffe80000)
- return __raw_readw(SCSPTR2)&0x0001 ? 1 : 0; /* SCIF */
- return 1;
-}
-#elif defined(CONFIG_CPU_SUBTYPE_SH4_202)
-static inline int sci_rxd_in(struct uart_port *port)
-{
- if (port->mapbase == 0xffe80000)
- return __raw_readw(SCSPTR2)&0x0001 ? 1 : 0; /* SCIF */
return 1;
}
-#elif defined(CONFIG_CPU_SUBTYPE_SH7757)
-static inline int sci_rxd_in(struct uart_port *port)
-{
- if (port->mapbase == 0xfe4b0000)
- return __raw_readw(SCSPTR0) & 0x0001 ? 1 : 0;
- if (port->mapbase == 0xfe4c0000)
- return __raw_readw(SCSPTR1) & 0x0001 ? 1 : 0;
- if (port->mapbase == 0xfe4d0000)
- return __raw_readw(SCSPTR2) & 0x0001 ? 1 : 0;
-}
-#elif defined(CONFIG_CPU_SUBTYPE_SH7760)
-static inline int sci_rxd_in(struct uart_port *port)
-{
- if (port->mapbase == 0xfe600000)
- return __raw_readw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */
- if (port->mapbase == 0xfe610000)
- return __raw_readw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */
- if (port->mapbase == 0xfe620000)
- return __raw_readw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */
- return 1;
-}
-#elif defined(CONFIG_CPU_SUBTYPE_SH7343)
-static inline int sci_rxd_in(struct uart_port *port)
-{
- if (port->mapbase == 0xffe00000)
- return __raw_readw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */
- if (port->mapbase == 0xffe10000)
- return __raw_readw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */
- if (port->mapbase == 0xffe20000)
- return __raw_readw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */
- if (port->mapbase == 0xffe30000)
- return __raw_readw(SCSPTR3) & 0x0001 ? 1 : 0; /* SCIF */
- return 1;
-}
-#elif defined(CONFIG_CPU_SUBTYPE_SH7366)
-static inline int sci_rxd_in(struct uart_port *port)
-{
- if (port->mapbase == 0xffe00000)
- return __raw_readb(SCPDR0) & 0x0001 ? 1 : 0; /* SCIF0 */
- return 1;
-}
-#elif defined(CONFIG_CPU_SUBTYPE_SH7722)
-static inline int sci_rxd_in(struct uart_port *port)
-{
- if (port->mapbase == 0xffe00000)
- return __raw_readb(PSDR) & 0x02 ? 1 : 0; /* SCIF0 */
- if (port->mapbase == 0xffe10000)
- return __raw_readb(PADR) & 0x40 ? 1 : 0; /* SCIF1 */
- if (port->mapbase == 0xffe20000)
- return __raw_readb(PWDR) & 0x04 ? 1 : 0; /* SCIF2 */
-
- return 1;
-}
-#elif defined(CONFIG_CPU_SUBTYPE_SH7723)
-static inline int sci_rxd_in(struct uart_port *port)
-{
- if (port->mapbase == 0xffe00000)
- return __raw_readb(SCSPTR0) & 0x0008 ? 1 : 0; /* SCIF0 */
- if (port->mapbase == 0xffe10000)
- return __raw_readb(SCSPTR1) & 0x0020 ? 1 : 0; /* SCIF1 */
- if (port->mapbase == 0xffe20000)
- return __raw_readb(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF2 */
- if (port->mapbase == 0xa4e30000)
- return __raw_readb(SCSPTR3) & 0x0001 ? 1 : 0; /* SCIF3 */
- if (port->mapbase == 0xa4e40000)
- return __raw_readb(SCSPTR4) & 0x0001 ? 1 : 0; /* SCIF4 */
- if (port->mapbase == 0xa4e50000)
- return __raw_readb(SCSPTR5) & 0x0008 ? 1 : 0; /* SCIF5 */
- return 1;
-}
-#elif defined(CONFIG_CPU_SUBTYPE_SH7724)
-# define SCFSR 0x0010
-# define SCASSR 0x0014
-static inline int sci_rxd_in(struct uart_port *port)
-{
- if (port->type == PORT_SCIF)
- return __raw_readw((port->mapbase + SCFSR)) & SCIF_BRK ? 1 : 0;
- if (port->type == PORT_SCIFA)
- return __raw_readw((port->mapbase + SCASSR)) & SCIF_BRK ? 1 : 0;
- return 1;
-}
-#elif defined(CONFIG_CPU_SUBTYPE_SH5_101) || defined(CONFIG_CPU_SUBTYPE_SH5_103)
-static inline int sci_rxd_in(struct uart_port *port)
-{
- return sci_in(port, SCSPTR)&0x0001 ? 1 : 0; /* SCIF */
-}
#elif defined(__H8300H__) || defined(__H8300S__)
static inline int sci_rxd_in(struct uart_port *port)
{
int ch = (port->mapbase - SMR0) >> 3;
return (H8300_SCI_DR(ch) & h8300_sci_pins[ch].rx) ? 1 : 0;
}
-#elif defined(CONFIG_CPU_SUBTYPE_SH7763)
-static inline int sci_rxd_in(struct uart_port *port)
-{
- if (port->mapbase == 0xffe00000)
- return __raw_readw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */
- if (port->mapbase == 0xffe08000)
- return __raw_readw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */
- if (port->mapbase == 0xffe10000)
- return __raw_readw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF/IRDA */
-
- return 1;
-}
-#elif defined(CONFIG_CPU_SUBTYPE_SH7770)
-static inline int sci_rxd_in(struct uart_port *port)
-{
- if (port->mapbase == 0xff923000)
- return __raw_readw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */
- if (port->mapbase == 0xff924000)
- return __raw_readw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */
- if (port->mapbase == 0xff925000)
- return __raw_readw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */
- return 1;
-}
-#elif defined(CONFIG_CPU_SUBTYPE_SH7780)
-static inline int sci_rxd_in(struct uart_port *port)
-{
- if (port->mapbase == 0xffe00000)
- return __raw_readw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */
- if (port->mapbase == 0xffe10000)
- return __raw_readw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */
- return 1;
-}
-#elif defined(CONFIG_CPU_SUBTYPE_SH7785) || \
- defined(CONFIG_CPU_SUBTYPE_SH7786)
-static inline int sci_rxd_in(struct uart_port *port)
-{
- if (port->mapbase == 0xffea0000)
- return __raw_readw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */
- if (port->mapbase == 0xffeb0000)
- return __raw_readw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */
- if (port->mapbase == 0xffec0000)
- return __raw_readw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */
- if (port->mapbase == 0xffed0000)
- return __raw_readw(SCSPTR3) & 0x0001 ? 1 : 0; /* SCIF */
- if (port->mapbase == 0xffee0000)
- return __raw_readw(SCSPTR4) & 0x0001 ? 1 : 0; /* SCIF */
- if (port->mapbase == 0xffef0000)
- return __raw_readw(SCSPTR5) & 0x0001 ? 1 : 0; /* SCIF */
- return 1;
-}
-#elif defined(CONFIG_CPU_SUBTYPE_SH7201) || \
- defined(CONFIG_CPU_SUBTYPE_SH7203) || \
- defined(CONFIG_CPU_SUBTYPE_SH7206) || \
- defined(CONFIG_CPU_SUBTYPE_SH7263)
-static inline int sci_rxd_in(struct uart_port *port)
-{
- if (port->mapbase == 0xfffe8000)
- return __raw_readw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */
- if (port->mapbase == 0xfffe8800)
- return __raw_readw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */
- if (port->mapbase == 0xfffe9000)
- return __raw_readw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */
- if (port->mapbase == 0xfffe9800)
- return __raw_readw(SCSPTR3) & 0x0001 ? 1 : 0; /* SCIF */
-#if defined(CONFIG_CPU_SUBTYPE_SH7201)
- if (port->mapbase == 0xfffeA000)
- return __raw_readw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */
- if (port->mapbase == 0xfffeA800)
- return __raw_readw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */
- if (port->mapbase == 0xfffeB000)
- return __raw_readw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */
- if (port->mapbase == 0xfffeB800)
- return __raw_readw(SCSPTR3) & 0x0001 ? 1 : 0; /* SCIF */
-#endif
- return 1;
-}
-#elif defined(CONFIG_CPU_SUBTYPE_SH7619)
-static inline int sci_rxd_in(struct uart_port *port)
-{
- if (port->mapbase == 0xf8400000)
- return __raw_readw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */
- if (port->mapbase == 0xf8410000)
- return __raw_readw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */
- if (port->mapbase == 0xf8420000)
- return __raw_readw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */
- return 1;
-}
-#elif defined(CONFIG_CPU_SUBTYPE_SHX3)
+#else /* default case for non-SCI processors */
static inline int sci_rxd_in(struct uart_port *port)
{
- if (port->mapbase == 0xffc30000)
- return __raw_readw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */
- if (port->mapbase == 0xffc40000)
- return __raw_readw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */
- if (port->mapbase == 0xffc50000)
- return __raw_readw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */
- if (port->mapbase == 0xffc60000)
- return __raw_readw(SCSPTR3) & 0x0001 ? 1 : 0; /* SCIF */
return 1;
}
#endif
diff --git a/drivers/sh/intc.c b/drivers/sh/intc.c
index d5d7f23c19a..3a5a17db947 100644
--- a/drivers/sh/intc.c
+++ b/drivers/sh/intc.c
@@ -259,6 +259,43 @@ static void intc_disable(unsigned int irq)
}
}
+static void (*intc_enable_noprio_fns[])(unsigned long addr,
+ unsigned long handle,
+ void (*fn)(unsigned long,
+ unsigned long,
+ unsigned long),
+ unsigned int irq) = {
+ [MODE_ENABLE_REG] = intc_mode_field,
+ [MODE_MASK_REG] = intc_mode_zero,
+ [MODE_DUAL_REG] = intc_mode_field,
+ [MODE_PRIO_REG] = intc_mode_field,
+ [MODE_PCLR_REG] = intc_mode_field,
+};
+
+static void intc_enable_disable(struct intc_desc_int *d,
+ unsigned long handle, int do_enable)
+{
+ unsigned long addr;
+ unsigned int cpu;
+ void (*fn)(unsigned long, unsigned long,
+ void (*)(unsigned long, unsigned long, unsigned long),
+ unsigned int);
+
+ if (do_enable) {
+ for (cpu = 0; cpu < SMP_NR(d, _INTC_ADDR_E(handle)); cpu++) {
+ addr = INTC_REG(d, _INTC_ADDR_E(handle), cpu);
+ fn = intc_enable_noprio_fns[_INTC_MODE(handle)];
+ fn(addr, handle, intc_reg_fns[_INTC_FN(handle)], 0);
+ }
+ } else {
+ for (cpu = 0; cpu < SMP_NR(d, _INTC_ADDR_D(handle)); cpu++) {
+ addr = INTC_REG(d, _INTC_ADDR_D(handle), cpu);
+ fn = intc_disable_fns[_INTC_MODE(handle)];
+ fn(addr, handle, intc_reg_fns[_INTC_FN(handle)], 0);
+ }
+ }
+}
+
static int intc_set_wake(unsigned int irq, unsigned int on)
{
return 0; /* allow wakeup, but setup hardware in intc_suspend() */
@@ -400,11 +437,11 @@ static unsigned int __init intc_get_reg(struct intc_desc_int *d,
static intc_enum __init intc_grp_id(struct intc_desc *desc,
intc_enum enum_id)
{
- struct intc_group *g = desc->groups;
+ struct intc_group *g = desc->hw.groups;
unsigned int i, j;
- for (i = 0; g && enum_id && i < desc->nr_groups; i++) {
- g = desc->groups + i;
+ for (i = 0; g && enum_id && i < desc->hw.nr_groups; i++) {
+ g = desc->hw.groups + i;
for (j = 0; g->enum_ids[j]; j++) {
if (g->enum_ids[j] != enum_id)
@@ -417,19 +454,21 @@ static intc_enum __init intc_grp_id(struct intc_desc *desc,
return 0;
}
-static unsigned int __init intc_mask_data(struct intc_desc *desc,
- struct intc_desc_int *d,
- intc_enum enum_id, int do_grps)
+static unsigned int __init _intc_mask_data(struct intc_desc *desc,
+ struct intc_desc_int *d,
+ intc_enum enum_id,
+ unsigned int *reg_idx,
+ unsigned int *fld_idx)
{
- struct intc_mask_reg *mr = desc->mask_regs;
- unsigned int i, j, fn, mode;
+ struct intc_mask_reg *mr = desc->hw.mask_regs;
+ unsigned int fn, mode;
unsigned long reg_e, reg_d;
- for (i = 0; mr && enum_id && i < desc->nr_mask_regs; i++) {
- mr = desc->mask_regs + i;
+ while (mr && enum_id && *reg_idx < desc->hw.nr_mask_regs) {
+ mr = desc->hw.mask_regs + *reg_idx;
- for (j = 0; j < ARRAY_SIZE(mr->enum_ids); j++) {
- if (mr->enum_ids[j] != enum_id)
+ for (; *fld_idx < ARRAY_SIZE(mr->enum_ids); (*fld_idx)++) {
+ if (mr->enum_ids[*fld_idx] != enum_id)
continue;
if (mr->set_reg && mr->clr_reg) {
@@ -455,29 +494,49 @@ static unsigned int __init intc_mask_data(struct intc_desc *desc,
intc_get_reg(d, reg_e),
intc_get_reg(d, reg_d),
1,
- (mr->reg_width - 1) - j);
+ (mr->reg_width - 1) - *fld_idx);
}
+
+ *fld_idx = 0;
+ (*reg_idx)++;
}
+ return 0;
+}
+
+static unsigned int __init intc_mask_data(struct intc_desc *desc,
+ struct intc_desc_int *d,
+ intc_enum enum_id, int do_grps)
+{
+ unsigned int i = 0;
+ unsigned int j = 0;
+ unsigned int ret;
+
+ ret = _intc_mask_data(desc, d, enum_id, &i, &j);
+ if (ret)
+ return ret;
+
if (do_grps)
return intc_mask_data(desc, d, intc_grp_id(desc, enum_id), 0);
return 0;
}
-static unsigned int __init intc_prio_data(struct intc_desc *desc,
- struct intc_desc_int *d,
- intc_enum enum_id, int do_grps)
+static unsigned int __init _intc_prio_data(struct intc_desc *desc,
+ struct intc_desc_int *d,
+ intc_enum enum_id,
+ unsigned int *reg_idx,
+ unsigned int *fld_idx)
{
- struct intc_prio_reg *pr = desc->prio_regs;
- unsigned int i, j, fn, mode, bit;
+ struct intc_prio_reg *pr = desc->hw.prio_regs;
+ unsigned int fn, n, mode, bit;
unsigned long reg_e, reg_d;
- for (i = 0; pr && enum_id && i < desc->nr_prio_regs; i++) {
- pr = desc->prio_regs + i;
+ while (pr && enum_id && *reg_idx < desc->hw.nr_prio_regs) {
+ pr = desc->hw.prio_regs + *reg_idx;
- for (j = 0; j < ARRAY_SIZE(pr->enum_ids); j++) {
- if (pr->enum_ids[j] != enum_id)
+ for (; *fld_idx < ARRAY_SIZE(pr->enum_ids); (*fld_idx)++) {
+ if (pr->enum_ids[*fld_idx] != enum_id)
continue;
if (pr->set_reg && pr->clr_reg) {
@@ -495,34 +554,79 @@ static unsigned int __init intc_prio_data(struct intc_desc *desc,
}
fn += (pr->reg_width >> 3) - 1;
+ n = *fld_idx + 1;
- BUG_ON((j + 1) * pr->field_width > pr->reg_width);
+ BUG_ON(n * pr->field_width > pr->reg_width);
- bit = pr->reg_width - ((j + 1) * pr->field_width);
+ bit = pr->reg_width - (n * pr->field_width);
return _INTC_MK(fn, mode,
intc_get_reg(d, reg_e),
intc_get_reg(d, reg_d),
pr->field_width, bit);
}
+
+ *fld_idx = 0;
+ (*reg_idx)++;
}
+ return 0;
+}
+
+static unsigned int __init intc_prio_data(struct intc_desc *desc,
+ struct intc_desc_int *d,
+ intc_enum enum_id, int do_grps)
+{
+ unsigned int i = 0;
+ unsigned int j = 0;
+ unsigned int ret;
+
+ ret = _intc_prio_data(desc, d, enum_id, &i, &j);
+ if (ret)
+ return ret;
+
if (do_grps)
return intc_prio_data(desc, d, intc_grp_id(desc, enum_id), 0);
return 0;
}
+static void __init intc_enable_disable_enum(struct intc_desc *desc,
+ struct intc_desc_int *d,
+ intc_enum enum_id, int enable)
+{
+ unsigned int i, j, data;
+
+ /* go through and enable/disable all mask bits */
+ i = j = 0;
+ do {
+ data = _intc_mask_data(desc, d, enum_id, &i, &j);
+ if (data)
+ intc_enable_disable(d, data, enable);
+ j++;
+ } while (data);
+
+ /* go through and enable/disable all priority fields */
+ i = j = 0;
+ do {
+ data = _intc_prio_data(desc, d, enum_id, &i, &j);
+ if (data)
+ intc_enable_disable(d, data, enable);
+
+ j++;
+ } while (data);
+}
+
static unsigned int __init intc_ack_data(struct intc_desc *desc,
struct intc_desc_int *d,
intc_enum enum_id)
{
- struct intc_mask_reg *mr = desc->ack_regs;
+ struct intc_mask_reg *mr = desc->hw.ack_regs;
unsigned int i, j, fn, mode;
unsigned long reg_e, reg_d;
- for (i = 0; mr && enum_id && i < desc->nr_ack_regs; i++) {
- mr = desc->ack_regs + i;
+ for (i = 0; mr && enum_id && i < desc->hw.nr_ack_regs; i++) {
+ mr = desc->hw.ack_regs + i;
for (j = 0; j < ARRAY_SIZE(mr->enum_ids); j++) {
if (mr->enum_ids[j] != enum_id)
@@ -549,11 +653,11 @@ static unsigned int __init intc_sense_data(struct intc_desc *desc,
struct intc_desc_int *d,
intc_enum enum_id)
{
- struct intc_sense_reg *sr = desc->sense_regs;
+ struct intc_sense_reg *sr = desc->hw.sense_regs;
unsigned int i, j, fn, bit;
- for (i = 0; sr && enum_id && i < desc->nr_sense_regs; i++) {
- sr = desc->sense_regs + i;
+ for (i = 0; sr && enum_id && i < desc->hw.nr_sense_regs; i++) {
+ sr = desc->hw.sense_regs + i;
for (j = 0; j < ARRAY_SIZE(sr->enum_ids); j++) {
if (sr->enum_ids[j] != enum_id)
@@ -656,7 +760,7 @@ static void __init intc_register_irq(struct intc_desc *desc,
/* irq should be disabled by default */
d->chip.mask(irq);
- if (desc->ack_regs)
+ if (desc->hw.ack_regs)
ack_handle[irq] = intc_ack_data(desc, d, enum_id);
}
@@ -684,6 +788,7 @@ static void intc_redirect_irq(unsigned int irq, struct irq_desc *desc)
void __init register_intc_controller(struct intc_desc *desc)
{
unsigned int i, k, smp;
+ struct intc_hw_desc *hw = &desc->hw;
struct intc_desc_int *d;
d = kzalloc(sizeof(*d), GFP_NOWAIT);
@@ -691,10 +796,10 @@ void __init register_intc_controller(struct intc_desc *desc)
INIT_LIST_HEAD(&d->list);
list_add(&d->list, &intc_list);
- d->nr_reg = desc->mask_regs ? desc->nr_mask_regs * 2 : 0;
- d->nr_reg += desc->prio_regs ? desc->nr_prio_regs * 2 : 0;
- d->nr_reg += desc->sense_regs ? desc->nr_sense_regs : 0;
- d->nr_reg += desc->ack_regs ? desc->nr_ack_regs : 0;
+ d->nr_reg = hw->mask_regs ? hw->nr_mask_regs * 2 : 0;
+ d->nr_reg += hw->prio_regs ? hw->nr_prio_regs * 2 : 0;
+ d->nr_reg += hw->sense_regs ? hw->nr_sense_regs : 0;
+ d->nr_reg += hw->ack_regs ? hw->nr_ack_regs : 0;
d->reg = kzalloc(d->nr_reg * sizeof(*d->reg), GFP_NOWAIT);
#ifdef CONFIG_SMP
@@ -702,30 +807,31 @@ void __init register_intc_controller(struct intc_desc *desc)
#endif
k = 0;
- if (desc->mask_regs) {
- for (i = 0; i < desc->nr_mask_regs; i++) {
- smp = IS_SMP(desc->mask_regs[i]);
- k += save_reg(d, k, desc->mask_regs[i].set_reg, smp);
- k += save_reg(d, k, desc->mask_regs[i].clr_reg, smp);
+ if (hw->mask_regs) {
+ for (i = 0; i < hw->nr_mask_regs; i++) {
+ smp = IS_SMP(hw->mask_regs[i]);
+ k += save_reg(d, k, hw->mask_regs[i].set_reg, smp);
+ k += save_reg(d, k, hw->mask_regs[i].clr_reg, smp);
}
}
- if (desc->prio_regs) {
- d->prio = kzalloc(desc->nr_vectors * sizeof(*d->prio), GFP_NOWAIT);
+ if (hw->prio_regs) {
+ d->prio = kzalloc(hw->nr_vectors * sizeof(*d->prio),
+ GFP_NOWAIT);
- for (i = 0; i < desc->nr_prio_regs; i++) {
- smp = IS_SMP(desc->prio_regs[i]);
- k += save_reg(d, k, desc->prio_regs[i].set_reg, smp);
- k += save_reg(d, k, desc->prio_regs[i].clr_reg, smp);
+ for (i = 0; i < hw->nr_prio_regs; i++) {
+ smp = IS_SMP(hw->prio_regs[i]);
+ k += save_reg(d, k, hw->prio_regs[i].set_reg, smp);
+ k += save_reg(d, k, hw->prio_regs[i].clr_reg, smp);
}
}
- if (desc->sense_regs) {
- d->sense = kzalloc(desc->nr_vectors * sizeof(*d->sense), GFP_NOWAIT);
+ if (hw->sense_regs) {
+ d->sense = kzalloc(hw->nr_vectors * sizeof(*d->sense),
+ GFP_NOWAIT);
- for (i = 0; i < desc->nr_sense_regs; i++) {
- k += save_reg(d, k, desc->sense_regs[i].reg, 0);
- }
+ for (i = 0; i < hw->nr_sense_regs; i++)
+ k += save_reg(d, k, hw->sense_regs[i].reg, 0);
}
d->chip.name = desc->name;
@@ -738,18 +844,26 @@ void __init register_intc_controller(struct intc_desc *desc)
d->chip.set_type = intc_set_sense;
d->chip.set_wake = intc_set_wake;
- if (desc->ack_regs) {
- for (i = 0; i < desc->nr_ack_regs; i++)
- k += save_reg(d, k, desc->ack_regs[i].set_reg, 0);
+ if (hw->ack_regs) {
+ for (i = 0; i < hw->nr_ack_regs; i++)
+ k += save_reg(d, k, hw->ack_regs[i].set_reg, 0);
d->chip.mask_ack = intc_mask_ack;
}
+ /* disable bits matching force_disable before registering irqs */
+ if (desc->force_disable)
+ intc_enable_disable_enum(desc, d, desc->force_disable, 0);
+
+ /* disable bits matching force_enable before registering irqs */
+ if (desc->force_enable)
+ intc_enable_disable_enum(desc, d, desc->force_enable, 0);
+
BUG_ON(k > 256); /* _INTC_ADDR_E() and _INTC_ADDR_D() are 8 bits */
/* register the vectors one by one */
- for (i = 0; i < desc->nr_vectors; i++) {
- struct intc_vect *vect = desc->vectors + i;
+ for (i = 0; i < hw->nr_vectors; i++) {
+ struct intc_vect *vect = hw->vectors + i;
unsigned int irq = evt2irq(vect->vect);
struct irq_desc *irq_desc;
@@ -764,8 +878,8 @@ void __init register_intc_controller(struct intc_desc *desc)
intc_register_irq(desc, d, vect->enum_id, irq);
- for (k = i + 1; k < desc->nr_vectors; k++) {
- struct intc_vect *vect2 = desc->vectors + k;
+ for (k = i + 1; k < hw->nr_vectors; k++) {
+ struct intc_vect *vect2 = hw->vectors + k;
unsigned int irq2 = evt2irq(vect2->vect);
if (vect->enum_id != vect2->enum_id)
@@ -785,11 +899,15 @@ void __init register_intc_controller(struct intc_desc *desc)
vect2->enum_id = 0;
/* redirect this interrupts to the first one */
- set_irq_chip_and_handler_name(irq2, &d->chip,
- intc_redirect_irq, "redirect");
+ set_irq_chip(irq2, &dummy_irq_chip);
+ set_irq_chained_handler(irq2, intc_redirect_irq);
set_irq_data(irq2, (void *)irq);
}
}
+
+ /* enable bits matching force_enable after registering irqs */
+ if (desc->force_enable)
+ intc_enable_disable_enum(desc, d, desc->force_enable, 1);
}
static int intc_suspend(struct sys_device *dev, pm_message_t state)
@@ -872,7 +990,7 @@ device_initcall(register_intc_sysdevs);
/*
* Dynamic IRQ allocation and deallocation
*/
-static unsigned int create_irq_on_node(unsigned int irq_want, int node)
+unsigned int create_irq_nr(unsigned int irq_want, int node)
{
unsigned int irq = 0, new;
unsigned long flags;
@@ -881,24 +999,28 @@ static unsigned int create_irq_on_node(unsigned int irq_want, int node)
spin_lock_irqsave(&vector_lock, flags);
/*
- * First try the wanted IRQ, then scan.
+ * First try the wanted IRQ
*/
- if (test_and_set_bit(irq_want, intc_irq_map)) {
+ if (test_and_set_bit(irq_want, intc_irq_map) == 0) {
+ new = irq_want;
+ } else {
+ /* .. then fall back to scanning. */
new = find_first_zero_bit(intc_irq_map, nr_irqs);
if (unlikely(new == nr_irqs))
goto out_unlock;
- desc = irq_to_desc_alloc_node(new, node);
- if (unlikely(!desc)) {
- pr_info("can't get irq_desc for %d\n", new);
- goto out_unlock;
- }
-
- desc = move_irq_desc(desc, node);
__set_bit(new, intc_irq_map);
- irq = new;
}
+ desc = irq_to_desc_alloc_node(new, node);
+ if (unlikely(!desc)) {
+ pr_info("can't get irq_desc for %d\n", new);
+ goto out_unlock;
+ }
+
+ desc = move_irq_desc(desc, node);
+ irq = new;
+
out_unlock:
spin_unlock_irqrestore(&vector_lock, flags);
@@ -913,7 +1035,7 @@ int create_irq(void)
int nid = cpu_to_node(smp_processor_id());
int irq;
- irq = create_irq_on_node(NR_IRQS_LEGACY, nid);
+ irq = create_irq_nr(NR_IRQS_LEGACY, nid);
if (irq == 0)
irq = -1;
diff --git a/drivers/sh/pfc.c b/drivers/sh/pfc.c
index 082604edc4c..cf0303acab8 100644
--- a/drivers/sh/pfc.c
+++ b/drivers/sh/pfc.c
@@ -337,12 +337,39 @@ static int pinmux_config_gpio(struct pinmux_info *gpioc, unsigned gpio,
if (!enum_id)
break;
+ /* first check if this is a function enum */
in_range = enum_in_range(enum_id, &gpioc->function);
- if (!in_range && range) {
- in_range = enum_in_range(enum_id, range);
-
- if (in_range && enum_id == range->force)
- continue;
+ if (!in_range) {
+ /* not a function enum */
+ if (range) {
+ /*
+ * other range exists, so this pin is
+ * a regular GPIO pin that now is being
+ * bound to a specific direction.
+ *
+ * for this case we only allow function enums
+ * and the enums that match the other range.
+ */
+ in_range = enum_in_range(enum_id, range);
+
+ /*
+ * special case pass through for fixed
+ * input-only or output-only pins without
+ * function enum register association.
+ */
+ if (in_range && enum_id == range->force)
+ continue;
+ } else {
+ /*
+ * no other range exists, so this pin
+ * must then be of the function type.
+ *
+ * allow function type pins to select
+ * any combination of function/in/out
+ * in their MARK lists.
+ */
+ in_range = 1;
+ }
}
if (!in_range)
diff --git a/drivers/video/pvr2fb.c b/drivers/video/pvr2fb.c
index 53f8f1100e8..f9975100d56 100644
--- a/drivers/video/pvr2fb.c
+++ b/drivers/video/pvr2fb.c
@@ -831,7 +831,7 @@ static int __devinit pvr2fb_common_init(void)
printk(KERN_NOTICE "fb%d: registering with SQ API\n", fb_info->node);
pvr2fb_map = sq_remap(fb_info->fix.smem_start, fb_info->fix.smem_len,
- fb_info->fix.id, pgprot_val(PAGE_SHARED));
+ fb_info->fix.id, PAGE_SHARED);
printk(KERN_NOTICE "fb%d: Mapped video memory to SQ addr 0x%lx\n",
fb_info->node, pvr2fb_map);
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
index a69830d26f7..8d7653e56df 100644
--- a/drivers/video/sh_mobile_lcdcfb.c
+++ b/drivers/video/sh_mobile_lcdcfb.c
@@ -19,6 +19,7 @@
#include <linux/dma-mapping.h>
#include <linux/interrupt.h>
#include <linux/vmalloc.h>
+#include <linux/ioctl.h>
#include <video/sh_mobile_lcdc.h>
#include <asm/atomic.h>
@@ -106,6 +107,7 @@ static unsigned long lcdc_offs_sublcd[NR_CH_REGS] = {
#define LDRCNTR_SRC 0x00010000
#define LDRCNTR_MRS 0x00000002
#define LDRCNTR_MRC 0x00000001
+#define LDSR_MRS 0x00000100
struct sh_mobile_lcdc_priv;
struct sh_mobile_lcdc_chan {
@@ -122,8 +124,8 @@ struct sh_mobile_lcdc_chan {
struct scatterlist *sglist;
unsigned long frame_end;
unsigned long pan_offset;
- unsigned long new_pan_offset;
wait_queue_head_t frame_end_wait;
+ struct completion vsync_completion;
};
struct sh_mobile_lcdc_priv {
@@ -366,19 +368,8 @@ static irqreturn_t sh_mobile_lcdc_irq(int irq, void *data)
}
/* VSYNC End */
- if (ldintr & LDINTR_VES) {
- unsigned long ldrcntr = lcdc_read(priv, _LDRCNTR);
- /* Set the source address for the next refresh */
- lcdc_write_chan_mirror(ch, LDSA1R, ch->dma_handle +
- ch->new_pan_offset);
- if (lcdc_chan_is_sublcd(ch))
- lcdc_write(ch->lcdc, _LDRCNTR,
- ldrcntr ^ LDRCNTR_SRS);
- else
- lcdc_write(ch->lcdc, _LDRCNTR,
- ldrcntr ^ LDRCNTR_MRS);
- ch->pan_offset = ch->new_pan_offset;
- }
+ if (ldintr & LDINTR_VES)
+ complete(&ch->vsync_completion);
}
return IRQ_HANDLED;
@@ -767,25 +758,69 @@ static int sh_mobile_fb_pan_display(struct fb_var_screeninfo *var,
struct fb_info *info)
{
struct sh_mobile_lcdc_chan *ch = info->par;
+ struct sh_mobile_lcdc_priv *priv = ch->lcdc;
+ unsigned long ldrcntr;
+ unsigned long new_pan_offset;
+
+ new_pan_offset = (var->yoffset * info->fix.line_length) +
+ (var->xoffset * (info->var.bits_per_pixel / 8));
- if (info->var.xoffset == var->xoffset &&
- info->var.yoffset == var->yoffset)
+ if (new_pan_offset == ch->pan_offset)
return 0; /* No change, do nothing */
- ch->new_pan_offset = (var->yoffset * info->fix.line_length) +
- (var->xoffset * (info->var.bits_per_pixel / 8));
+ ldrcntr = lcdc_read(priv, _LDRCNTR);
- if (ch->new_pan_offset != ch->pan_offset) {
- unsigned long ldintr;
- ldintr = lcdc_read(ch->lcdc, _LDINTR);
- ldintr |= LDINTR_VEE;
- lcdc_write(ch->lcdc, _LDINTR, ldintr);
- sh_mobile_lcdc_deferred_io_touch(info);
- }
+ /* Set the source address for the next refresh */
+ lcdc_write_chan_mirror(ch, LDSA1R, ch->dma_handle + new_pan_offset);
+ if (lcdc_chan_is_sublcd(ch))
+ lcdc_write(ch->lcdc, _LDRCNTR, ldrcntr ^ LDRCNTR_SRS);
+ else
+ lcdc_write(ch->lcdc, _LDRCNTR, ldrcntr ^ LDRCNTR_MRS);
+
+ ch->pan_offset = new_pan_offset;
+
+ sh_mobile_lcdc_deferred_io_touch(info);
+
+ return 0;
+}
+
+static int sh_mobile_wait_for_vsync(struct fb_info *info)
+{
+ struct sh_mobile_lcdc_chan *ch = info->par;
+ unsigned long ldintr;
+ int ret;
+
+ /* Enable VSync End interrupt */
+ ldintr = lcdc_read(ch->lcdc, _LDINTR);
+ ldintr |= LDINTR_VEE;
+ lcdc_write(ch->lcdc, _LDINTR, ldintr);
+
+ ret = wait_for_completion_interruptible_timeout(&ch->vsync_completion,
+ msecs_to_jiffies(100));
+ if (!ret)
+ return -ETIMEDOUT;
return 0;
}
+static int sh_mobile_ioctl(struct fb_info *info, unsigned int cmd,
+ unsigned long arg)
+{
+ int retval;
+
+ switch (cmd) {
+ case FBIO_WAITFORVSYNC:
+ retval = sh_mobile_wait_for_vsync(info);
+ break;
+
+ default:
+ retval = -ENOIOCTLCMD;
+ break;
+ }
+ return retval;
+}
+
+
static struct fb_ops sh_mobile_lcdc_ops = {
.owner = THIS_MODULE,
.fb_setcolreg = sh_mobile_lcdc_setcolreg,
@@ -795,6 +830,7 @@ static struct fb_ops sh_mobile_lcdc_ops = {
.fb_copyarea = sh_mobile_lcdc_copyarea,
.fb_imageblit = sh_mobile_lcdc_imageblit,
.fb_pan_display = sh_mobile_fb_pan_display,
+ .fb_ioctl = sh_mobile_ioctl,
};
static int sh_mobile_lcdc_set_bpp(struct fb_var_screeninfo *var, int bpp)
@@ -962,8 +998,8 @@ static int __init sh_mobile_lcdc_probe(struct platform_device *pdev)
goto err1;
}
init_waitqueue_head(&priv->ch[i].frame_end_wait);
+ init_completion(&priv->ch[i].vsync_completion);
priv->ch[j].pan_offset = 0;
- priv->ch[j].new_pan_offset = 0;
switch (pdata->ch[i].chan) {
case LCDC_CHAN_MAINLCD:
diff --git a/include/linux/mtd/sh_flctl.h b/include/linux/mtd/sh_flctl.h
index e77c1cea404..ab77609ec33 100644
--- a/include/linux/mtd/sh_flctl.h
+++ b/include/linux/mtd/sh_flctl.h
@@ -51,6 +51,8 @@
#define _4ECCCNTEN (0x1 << 24)
#define _4ECCEN (0x1 << 23)
#define _4ECCCORRECT (0x1 << 22)
+#define SHBUSSEL (0x1 << 20)
+#define SEL_16BIT (0x1 << 19)
#define SNAND_E (0x1 << 18) /* SNAND (0=512 1=2048)*/
#define QTSEL_E (0x1 << 17)
#define ENDIAN (0x1 << 16) /* 1 = little endian */
@@ -96,6 +98,7 @@
struct sh_flctl {
struct mtd_info mtd;
struct nand_chip chip;
+ struct platform_device *pdev;
void __iomem *reg;
uint8_t done_buff[2048 + 64]; /* max size 2048 + 64 */
diff --git a/include/linux/sh_intc.h b/include/linux/sh_intc.h
index 4ef246f1465..51d288d8ac8 100644
--- a/include/linux/sh_intc.h
+++ b/include/linux/sh_intc.h
@@ -45,7 +45,7 @@ struct intc_sense_reg {
#define INTC_SMP(stride, nr)
#endif
-struct intc_desc {
+struct intc_hw_desc {
struct intc_vect *vectors;
unsigned int nr_vectors;
struct intc_group *groups;
@@ -56,29 +56,40 @@ struct intc_desc {
unsigned int nr_prio_regs;
struct intc_sense_reg *sense_regs;
unsigned int nr_sense_regs;
- char *name;
struct intc_mask_reg *ack_regs;
unsigned int nr_ack_regs;
};
#define _INTC_ARRAY(a) a, sizeof(a)/sizeof(*a)
+#define INTC_HW_DESC(vectors, groups, mask_regs, \
+ prio_regs, sense_regs, ack_regs) \
+{ \
+ _INTC_ARRAY(vectors), _INTC_ARRAY(groups), \
+ _INTC_ARRAY(mask_regs), _INTC_ARRAY(prio_regs), \
+ _INTC_ARRAY(sense_regs), _INTC_ARRAY(ack_regs), \
+}
+
+struct intc_desc {
+ char *name;
+ intc_enum force_enable;
+ intc_enum force_disable;
+ struct intc_hw_desc hw;
+};
+
#define DECLARE_INTC_DESC(symbol, chipname, vectors, groups, \
mask_regs, prio_regs, sense_regs) \
struct intc_desc symbol __initdata = { \
- _INTC_ARRAY(vectors), _INTC_ARRAY(groups), \
- _INTC_ARRAY(mask_regs), _INTC_ARRAY(prio_regs), \
- _INTC_ARRAY(sense_regs), \
- chipname, \
+ .name = chipname, \
+ .hw = INTC_HW_DESC(vectors, groups, mask_regs, \
+ prio_regs, sense_regs, NULL), \
}
#define DECLARE_INTC_DESC_ACK(symbol, chipname, vectors, groups, \
mask_regs, prio_regs, sense_regs, ack_regs) \
struct intc_desc symbol __initdata = { \
- _INTC_ARRAY(vectors), _INTC_ARRAY(groups), \
- _INTC_ARRAY(mask_regs), _INTC_ARRAY(prio_regs), \
- _INTC_ARRAY(sense_regs), \
- chipname, \
- _INTC_ARRAY(ack_regs), \
+ .name = chipname, \
+ .hw = INTC_HW_DESC(vectors, groups, mask_regs, \
+ prio_regs, sense_regs, ack_regs), \
}
void __init register_intc_controller(struct intc_desc *desc);
diff --git a/include/video/sh_mobile_lcdc.h b/include/video/sh_mobile_lcdc.h
index 28820545771..2cc893fc1f8 100644
--- a/include/video/sh_mobile_lcdc.h
+++ b/include/video/sh_mobile_lcdc.h
@@ -34,6 +34,8 @@ enum { LCDC_CLK_BUS, LCDC_CLK_PERIPHERAL, LCDC_CLK_EXTERNAL };
#define LCDC_FLAGS_HSCNT (1 << 3) /* Disable HSYNC during VBLANK */
#define LCDC_FLAGS_DWCNT (1 << 4) /* Disable dotclock during blanking */
+#define FBIO_WAITFORVSYNC _IOW('F', 0x20, __u32)
+
struct sh_mobile_lcdc_sys_bus_cfg {
unsigned long ldmt2r;
unsigned long ldmt3r;
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 25c3ed594c5..d62e3cdab35 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -355,7 +355,7 @@ config SLUB_STATS
config DEBUG_KMEMLEAK
bool "Kernel memory leak detector"
depends on DEBUG_KERNEL && EXPERIMENTAL && !MEMORY_HOTPLUG && \
- (X86 || ARM || PPC || S390)
+ (X86 || ARM || PPC || S390 || SUPERH)
select DEBUG_FS if SYSFS
select STACKTRACE if STACKTRACE_SUPPORT
diff --git a/mm/Kconfig b/mm/Kconfig
index 17b8947aa7d..d34c2b97103 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -195,7 +195,7 @@ config BOUNCE
config NR_QUICK
int
depends on QUICKLIST
- default "2" if SUPERH || AVR32
+ default "2" if AVR32
default "1"
config VIRT_TO_BUS