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

* master.kernel.org:/pub/scm/linux/kernel/git/lethal/sh-2.6: (108 commits)
  sh: Fix occasional flush_cache_4096() stack corruption.
  sh: Calculate shm alignment at runtime.
  sh: dma-mapping compile fixes.
  sh: Initial vsyscall page support.
  sh: Clean up PAGE_SIZE definition for assembly use.
  sh: Selective flush_cache_mm() flushing.
  sh: More intelligent entry_mask/way_size calculation.
  sh: Support for L2 cache on newer SH-4A CPUs.
  sh: Update kexec support for API changes.
  sh: Optimized readsl()/writesl() support.
  sh: Report movli.l/movco.l capabilities.
  sh: CPU flags in AT_HWCAP in ELF auxvt.
  sh: Add support for 4K stacks.
  sh: Enable /proc/kcore support.
  sh: stack debugging support.
  sh: select CONFIG_EMBEDDED.
  sh: machvec rework.
  sh: Solution Engine SH7343 board support.
  sh: SH7710VoIPGW board support.
  sh: Enable verbose BUG() support.
  ...
This commit is contained in:
Linus Torvalds 2006-09-27 08:49:07 -07:00
commit b98adfccdf
355 changed files with 20724 additions and 9021 deletions

View file

@ -41,11 +41,6 @@ Board-specific code:
|
.. more boards here ...
It should also be noted that each board is required to have some certain
headers. At the time of this writing, io.h is the only thing that needs
to be provided for each board, and can generally just reference generic
functions (with the exception of isa_port2addr).
Next, for companion chips:
.
`-- arch
@ -104,12 +99,13 @@ and then populate that with sub-directories for each member of the family.
Both the Solution Engine and the hp6xx boards are an example of this.
After you have setup your new arch/sh/boards/ directory, remember that you
also must add a directory in include/asm-sh for headers localized to this
board. In order to interoperate seamlessly with the build system, it's best
to have this directory the same as the arch/sh/boards/ directory name,
though if your board is again part of a family, the build system has ways
of dealing with this, and you can feel free to name the directory after
the family member itself.
should also add a directory in include/asm-sh for headers localized to this
board (if there are going to be more than one). In order to interoperate
seamlessly with the build system, it's best to have this directory the same
as the arch/sh/boards/ directory name, though if your board is again part of
a family, the build system has ways of dealing with this (via incdir-y
overloading), and you can feel free to name the directory after the family
member itself.
There are a few things that each board is required to have, both in the
arch/sh/boards and the include/asm-sh/ heirarchy. In order to better
@ -122,6 +118,7 @@ might look something like:
* arch/sh/boards/vapor/setup.c - Setup code for imaginary board
*/
#include <linux/init.h>
#include <asm/rtc.h> /* for board_time_init() */
const char *get_system_type(void)
{
@ -152,79 +149,57 @@ int __init platform_setup(void)
}
Our new imaginary board will also have to tie into the machvec in order for it
to be of any use. Currently the machvec is slowly on its way out, but is still
required for the time being. As such, let us take a look at what needs to be
done for the machvec assignment.
to be of any use.
machvec functions fall into a number of categories:
- I/O functions to IO memory (inb etc) and PCI/main memory (readb etc).
- I/O remapping functions (ioremap etc)
- some initialisation functions
- a 'heartbeat' function
- some miscellaneous flags
- I/O mapping functions (ioport_map, ioport_unmap, etc).
- a 'heartbeat' function.
- PCI and IRQ initialization routines.
- Consistent allocators (for boards that need special allocators,
particularly for allocating out of some board-specific SRAM for DMA
handles).
The tree can be built in two ways:
- as a fully generic build. All drivers are linked in, and all functions
go through the machvec
- as a machine specific build. In this case only the required drivers
will be linked in, and some macros may be redefined to not go through
the machvec where performance is important (in particular IO functions).
There are machvec functions added and removed over time, so always be sure to
consult include/asm-sh/machvec.h for the current state of the machvec.
There are three ways in which IO can be performed:
- none at all. This is really only useful for the 'unknown' machine type,
which us designed to run on a machine about which we know nothing, and
so all all IO instructions do nothing.
- fully custom. In this case all IO functions go to a machine specific
set of functions which can do what they like
- a generic set of functions. These will cope with most situations,
and rely on a single function, mv_port2addr, which is called through the
machine vector, and converts an IO address into a memory address, which
can be read from/written to directly.
The kernel will automatically wrap in generic routines for undefined function
pointers in the machvec at boot time, as machvec functions are referenced
unconditionally throughout most of the tree. Some boards have incredibly
sparse machvecs (such as the dreamcast and sh03), whereas others must define
virtually everything (rts7751r2d).
Thus adding a new machine involves the following steps (I will assume I am
adding a machine called vapor):
Adding a new machine is relatively trivial (using vapor as an example):
- add a new file include/asm-sh/vapor/io.h which contains prototypes for
If the board-specific definitions are quite minimalistic, as is the case for
the vast majority of boards, simply having a single board-specific header is
sufficient.
- add a new file include/asm-sh/vapor.h which contains prototypes for
any machine specific IO functions prefixed with the machine name, for
example vapor_inb. These will be needed when filling out the machine
vector.
This is the minimum that is required, however there are ample
opportunities to optimise this. In particular, by making the prototypes
inline function definitions, it is possible to inline the function when
building machine specific versions. Note that the machine vector
functions will still be needed, so that a module built for a generic
setup can be loaded.
Note that these prototypes are generated automatically by setting
__IO_PREFIX to something sensible. A typical example would be:
- add a new file arch/sh/boards/vapor/mach.c. This contains the definition
of the machine vector. When building the machine specific version, this
will be the real machine vector (via an alias), while in the generic
version is used to initialise the machine vector, and then freed, by
making it initdata. This should be defined as:
#define __IO_PREFIX vapor
#include <asm/io_generic.h>
struct sh_machine_vector mv_vapor __initmv = {
.mv_name = "vapor",
}
ALIAS_MV(vapor)
somewhere in the board-specific header. Any boards being ported that still
have a legacy io.h should remove it entirely and switch to the new model.
- finally add a file arch/sh/boards/vapor/io.c, which contains
definitions of the machine specific io functions.
- Add machine vector definitions to the board's setup.c. At a bare minimum,
this must be defined as something like:
A note about initialisation functions. Three initialisation functions are
provided in the machine vector:
- mv_arch_init - called very early on from setup_arch
- mv_init_irq - called from init_IRQ, after the generic SH interrupt
initialisation
- mv_init_pci - currently not used
struct sh_machine_vector mv_vapor __initmv = {
.mv_name = "vapor",
};
ALIAS_MV(vapor)
Any other remaining functions which need to be called at start up can be
added to the list using the __initcalls macro (or module_init if the code
can be built as a module). Many generic drivers probe to see if the device
they are targeting is present, however this may not always be appropriate,
so a flag can be added to the machine vector which will be set on those
machines which have the hardware in question, reducing the probe to a
single conditional.
- finally add a file arch/sh/boards/vapor/io.c, which contains definitions of
the machine specific io functions (if there are enough to warrant it).
3. Hooking into the Build System
================================
@ -303,4 +278,3 @@ which will in turn copy the defconfig for this board, run it through
oldconfig (prompting you for any new options since the time of creation),
and start you on your way to having a functional kernel for your new
board.

View file

@ -0,0 +1,33 @@
Notes on register bank usage in the kernel
==========================================
Introduction
------------
The SH-3 and SH-4 CPU families traditionally include a single partial register
bank (selected by SR.RB, only r0 ... r7 are banked), whereas other families
may have more full-featured banking or simply no such capabilities at all.
SR.RB banking
-------------
In the case of this type of banking, banked registers are mapped directly to
r0 ... r7 if SR.RB is set to the bank we are interested in, otherwise ldc/stc
can still be used to reference the banked registers (as r0_bank ... r7_bank)
when in the context of another bank. The developer must keep the SR.RB value
in mind when writing code that utilizes these banked registers, for obvious
reasons. Userspace is also not able to poke at the bank1 values, so these can
be used rather effectively as scratch registers by the kernel.
Presently the kernel uses several of these registers.
- r0_bank, r1_bank (referenced as k0 and k1, used for scratch
registers when doing exception handling).
- r2_bank (used to track the EXPEVT/INTEVT code)
- Used by do_IRQ() and friends for doing irq mapping based off
of the interrupt exception vector jump table offset
- r6_bank (global interrupt mask)
- The SR.IMASK interrupt handler makes use of this to set the
interrupt priority level (used by local_irq_enable())
- r7_bank (current)

View file

@ -8,6 +8,7 @@ mainmenu "Linux/SuperH Kernel Configuration"
config SUPERH
bool
default y
select EMBEDDED
help
The SuperH is a RISC processor targeted for use in embedded systems
and consumer electronics; it was also used in the Sega Dreamcast
@ -51,18 +52,23 @@ source "init/Kconfig"
menu "System type"
config SOLUTION_ENGINE
bool
choice
prompt "SuperH system type"
default SH_UNKNOWN
config SH_SOLUTION_ENGINE
bool "SolutionEngine"
select SOLUTION_ENGINE
help
Select SolutionEngine if configuring for a Hitachi SH7709
or SH7750 evaluation board.
config SH_7751_SOLUTION_ENGINE
bool "SolutionEngine7751"
select SOLUTION_ENGINE
select CPU_SUBTYPE_SH7751
help
Select 7751 SolutionEngine if configuring for a Hitachi SH7751
@ -70,17 +76,27 @@ config SH_7751_SOLUTION_ENGINE
config SH_7300_SOLUTION_ENGINE
bool "SolutionEngine7300"
select SOLUTION_ENGINE
select CPU_SUBTYPE_SH7300
help
Select 7300 SolutionEngine if configuring for a Hitachi SH7300(SH-Mobile V)
evaluation board.
Select 7300 SolutionEngine if configuring for a Hitachi
SH7300(SH-Mobile V) evaluation board.
config SH_7343_SOLUTION_ENGINE
bool "SolutionEngine7343"
select SOLUTION_ENGINE
select CPU_SUBTYPE_SH7343
help
Select 7343 SolutionEngine if configuring for a Hitachi
SH7343 (SH-Mobile 3AS) evaluation board.
config SH_73180_SOLUTION_ENGINE
bool "SolutionEngine73180"
select CPU_SUBTYPE_SH73180
help
Select 73180 SolutionEngine if configuring for a Hitachi SH73180(SH-Mobile 3)
evaluation board.
select SOLUTION_ENGINE
select CPU_SUBTYPE_SH73180
help
Select 73180 SolutionEngine if configuring for a Hitachi
SH73180(SH-Mobile 3) evaluation board.
config SH_7751_SYSTEMH
bool "SystemH7751R"
@ -89,12 +105,6 @@ config SH_7751_SYSTEMH
Select SystemH if you are configuring for a Renesas SystemH
7751R evaluation board.
config SH_STB1_HARP
bool "STB1_Harp"
config SH_STB1_OVERDRIVE
bool "STB1_Overdrive"
config SH_HP6XX
bool "HP6XX"
help
@ -102,19 +112,6 @@ config SH_HP6XX
More information (hardware only) at
<http://www.hp.com/jornada/>.
config SH_CQREEK
bool "CqREEK"
help
Select CqREEK if configuring for a CqREEK SH7708 or SH7750.
More information at
<http://sources.redhat.com/ecos/hardware.html#SuperH>.
config SH_DMIDA
bool "DMIDA"
help
Select DMIDA if configuring for a DataMyte 4000 Industrial
Digital Assistant. More information at <http://www.dmida.com/>.
config SH_EC3104
bool "EC3104"
help
@ -136,25 +133,9 @@ config SH_DREAMCAST
<http://www.m17n.org/linux-sh/dreamcast/>. There is a
Dreamcast project is at <http://linuxdc.sourceforge.net/>.
config SH_CAT68701
bool "CAT68701"
config SH_BIGSUR
bool "BigSur"
config SH_SH2000
bool "SH2000"
select CPU_SUBTYPE_SH7709
help
SH-2000 is a single-board computer based around SH7709A chip
intended for embedded applications.
It has an Ethernet interface (CS8900A), direct connected
Compact Flash socket, three serial ports and PC-104 bus.
More information at <http://sh2000.sh-linux.org>.
config SH_ADX
bool "ADX"
config SH_MPC1211
bool "Interface MPC1211"
help
@ -184,6 +165,13 @@ config SH_HS7751RVOIP
Select HS7751RVOIP if configuring for a Renesas Technology
Sales VoIP board.
config SH_7710VOIPGW
bool "SH7710-VOIP-GW"
select CPU_SUBTYPE_SH7710
help
Select this option to build a kernel for the SH7710 based
VOIP GW.
config SH_RTS7751R2D
bool "RTS7751R2D"
select CPU_SUBTYPE_SH7751R
@ -222,6 +210,12 @@ config SH_TITAN
Select Titan if you are configuring for a Nimble Microsystems
NetEngine NP51R.
config SH_SHMIN
bool "SHMIN"
select CPU_SUBTYPE_SH7706
help
Select SHMIN if configureing for the SHMIN board
config SH_UNKNOWN
bool "BareCPU"
help
@ -238,35 +232,9 @@ endchoice
source "arch/sh/mm/Kconfig"
config MEMORY_START
hex "Physical memory start address"
default "0x08000000"
---help---
Computers built with Hitachi SuperH processors always
map the ROM starting at address zero. But the processor
does not specify the range that RAM takes.
The physical memory (RAM) start address will be automatically
set to 08000000. Other platforms, such as the Solution Engine
boards typically map RAM at 0C000000.
Tweak this only when porting to a new machine which does not
already have a defconfig. Changing it from the known correct
value on any of the known systems will only lead to disaster.
config MEMORY_SIZE
hex "Physical memory size"
default "0x00400000"
help
This sets the default memory size assumed by your SH kernel. It can
be overridden as normal by the 'mem=' argument on the kernel command
line. If unsure, consult your board specifications or just leave it
as 0x00400000 which was the default value before this became
configurable.
config CF_ENABLER
bool "Compact Flash Enabler support"
depends on SH_ADX || SH_SOLUTION_ENGINE || SH_UNKNOWN || SH_CAT68701 || SH_SH03
depends on SH_SOLUTION_ENGINE || SH_UNKNOWN || SH_SH03
---help---
Compact Flash is a small, removable mass storage device introduced
in 1994 originally as a PCMCIA device. If you say `Y' here, you
@ -294,7 +262,7 @@ config CF_AREA5
- "Area5" if CompactFlash is connected to Area 5 (0x14000000)
- "Area6" if it is connected to Area 6 (0x18000000)
"Area6" will work for most boards. For ADX, select "Area5".
"Area6" will work for most boards.
config CF_AREA6
bool "Area6"
@ -316,19 +284,6 @@ config CPU_LITTLE_ENDIAN
endian byte order. These modes require different kernels. Say Y if
your machine is little endian, N if it's a big endian machine.
# The SH7750 RTC module is disabled in the Dreamcast
config SH_RTC
bool
depends on !SH_DREAMCAST && !SH_SATURN && !SH_7300_SOLUTION_ENGINE && \
!SH_73180_SOLUTION_ENGINE && !SH_LANDISK && \
!SH_R7780RP
default y
help
Selecting this option will allow the Linux kernel to emulate
PC's RTC.
If unsure, say N.
config SH_FPU
bool "FPU support"
depends on !CPU_SH3
@ -339,14 +294,22 @@ config SH_FPU
This option must be set in order to enable the FPU.
config SH_FPU_EMU
bool "FPU emulation support"
depends on !SH_FPU && EXPERIMENTAL
default n
help
Selecting this option will enable support for software FPU emulation.
Most SH-3 users will want to say Y here, whereas most SH-4 users will
want to say N.
config SH_DSP
bool "DSP support"
depends on !CPU_SH4
default y
default y if SH4AL_DSP || !CPU_SH4
default n
help
Selecting this option will enable support for SH processors that
have DSP units (ie, SH2-DSP and SH3-DSP). It is safe to say Y here
by default, as the existance of the DSP will be probed at runtime.
have DSP units (ie, SH2-DSP, SH3-DSP, and SH4AL-DSP).
This option must be set in order to enable the DSP.
@ -373,6 +336,9 @@ config CPU_HAS_INTEVT
config CPU_HAS_PINT_IRQ
bool
config CPU_HAS_MASKREG_IRQ
bool
config CPU_HAS_INTC2_IRQ
bool
@ -400,16 +366,19 @@ config SH_TMU
endmenu
#source "arch/sh/boards/renesas/hs7751rvoip/Kconfig"
source "arch/sh/boards/renesas/hs7751rvoip/Kconfig"
#source "arch/sh/boards/renesas/rts7751r2d/Kconfig"
source "arch/sh/boards/renesas/rts7751r2d/Kconfig"
source "arch/sh/boards/renesas/r7780rp/Kconfig"
config SH_PCLK_FREQ
int "Peripheral clock frequency (in Hz)"
default "50000000" if CPU_SUBTYPE_SH7750 || CPU_SUBTYPE_SH7780
default "60000000" if CPU_SUBTYPE_SH7751
default "33333333" if CPU_SUBTYPE_SH7300 || CPU_SUBTYPE_SH7770 || CPU_SUBTYPE_SH7760
default "27000000" if CPU_SUBTYPE_SH73180
default "33333333" if CPU_SUBTYPE_SH7300 || CPU_SUBTYPE_SH7770 || \
CPU_SUBTYPE_SH7760
default "27000000" if CPU_SUBTYPE_SH73180 || CPU_SUBTYPE_SH7343
default "66000000" if CPU_SUBTYPE_SH4_202
help
This option is used to specify the peripheral clock frequency.
@ -440,10 +409,8 @@ source "arch/sh/cchips/Kconfig"
config HEARTBEAT
bool "Heartbeat LED"
depends on SH_MPC1211 || SH_SH03 || SH_CAT68701 || \
SH_STB1_HARP || SH_STB1_OVERDRIVE || SH_BIGSUR || \
SH_7751_SOLUTION_ENGINE || SH_7300_SOLUTION_ENGINE || \
SH_73180_SOLUTION_ENGINE || SH_SOLUTION_ENGINE || \
depends on SH_MPC1211 || SH_SH03 || \
SH_BIGSUR || SOLUTION_ENGINE || \
SH_RTS7751R2D || SH_SH4202_MICRODEV || SH_LANDISK
help
Use the power-on LED on your machine as a load meter. The exact
@ -459,6 +426,8 @@ config ISA_DMA_API
menu "Kernel features"
source kernel/Kconfig.hz
config KEXEC
bool "kexec system call (EXPERIMENTAL)"
depends on EXPERIMENTAL
@ -476,10 +445,6 @@ config KEXEC
support. As of this writing the exact hardware interface is
strongly in flux, so no good recommendation can be made.
config PREEMPT
bool "Preemptible Kernel (EXPERIMENTAL)"
depends on EXPERIMENTAL
config SMP
bool "Symmetric multi-processing support"
---help---
@ -515,6 +480,8 @@ config NR_CPUS
This is purely to save memory - each supported CPU adds
approximately eight kilobytes to the kernel image.
source "kernel/Kconfig.preempt"
config CPU_HAS_SR_RB
bool "CPU has SR.RB"
depends on CPU_SH3 || CPU_SH4
@ -636,6 +603,16 @@ source "fs/Kconfig.binfmt"
endmenu
menu "Power management options (EXPERIMENTAL)"
depends on EXPERIMENTAL
source kernel/power/Kconfig
config APM
bool "Advanced Power Management Emulation"
depends on PM
endmenu
source "net/Kconfig"
source "drivers/Kconfig"

View file

@ -30,8 +30,35 @@ config EARLY_PRINTK
when the kernel may crash or hang before the serial console is
initialised. If unsure, say N.
config DEBUG_STACKOVERFLOW
bool "Check for stack overflows"
depends on DEBUG_KERNEL
help
This option will cause messages to be printed if free stack space
drops below a certain limit.
config DEBUG_STACK_USAGE
bool "Stack utilization instrumentation"
depends on DEBUG_KERNEL
help
Enables the display of the minimum amount of free stack which each
task has ever had available in the sysrq-T and sysrq-P debug output.
This option will slow down process creation somewhat.
config 4KSTACKS
bool "Use 4Kb for kernel stacks instead of 8Kb"
depends on DEBUG_KERNEL
help
If you say Y here the kernel will use a 4Kb stacksize for the
kernel stack attached to each process/thread. This facilitates
running more threads on a system and also reduces the pressure
on the VM subsystem for higher order allocations. This option
will also use IRQ stacks to compensate for the reduced stackspace.
config KGDB
bool "Include KGDB kernel debugger"
select FRAME_POINTER
help
Include in-kernel hooks for kgdb, the Linux kernel source level
debugger. See <http://kgdb.sourceforge.net/> for more information.
@ -112,13 +139,4 @@ endchoice
endmenu
config FRAME_POINTER
bool "Compile the kernel with frame pointers"
default y if KGDB
help
If you say Y here the resulting kernel image will be slightly larger
and slower, but it will give very useful debugging information.
If you don't debug the kernel, you can say N, but we may not be able
to solve problems without frame pointers.
endmenu

View file

@ -18,11 +18,13 @@ cflags-y := -mb
cflags-$(CONFIG_CPU_LITTLE_ENDIAN) := -ml
isa-y := any
isa-$(CONFIG_SH_DSP) := sh
isa-$(CONFIG_CPU_SH2) := sh2
isa-$(CONFIG_CPU_SH2A) := sh2a
isa-$(CONFIG_CPU_SH3) := sh3
isa-$(CONFIG_CPU_SH4) := sh4
isa-$(CONFIG_CPU_SH4A) := sh4a
isa-$(CONFIG_CPU_SH2A) := sh2a
isa-$(CONFIG_CPU_SH4AL_DSP) := sh4al
isa-$(CONFIG_SH_DSP) := $(isa-y)-dsp
@ -30,9 +32,11 @@ ifndef CONFIG_MMU
isa-y := $(isa-y)-nommu
endif
ifndef CONFIG_SH_DSP
ifndef CONFIG_SH_FPU
isa-y := $(isa-y)-nofpu
endif
endif
cflags-y += $(call as-option,-Wa$(comma)-isa=$(isa-y),)
@ -79,24 +83,19 @@ head-y := arch/sh/kernel/head.o arch/sh/kernel/init_task.o
LIBGCC := $(shell $(CC) $(CFLAGS) -print-libgcc-file-name)
core-y += arch/sh/kernel/ arch/sh/mm/
core-$(CONFIG_SH_FPU_EMU) += arch/sh/math-emu/
# Boards
machdir-$(CONFIG_SH_SOLUTION_ENGINE) := se/770x
machdir-$(CONFIG_SH_7751_SOLUTION_ENGINE) := se/7751
machdir-$(CONFIG_SH_7300_SOLUTION_ENGINE) := se/7300
machdir-$(CONFIG_SH_7343_SOLUTION_ENGINE) := se/7343
machdir-$(CONFIG_SH_73180_SOLUTION_ENGINE) := se/73180
machdir-$(CONFIG_SH_STB1_HARP) := harp
machdir-$(CONFIG_SH_STB1_OVERDRIVE) := overdrive
machdir-$(CONFIG_SH_HP6XX) := hp6xx
machdir-$(CONFIG_SH_CQREEK) := cqreek
machdir-$(CONFIG_SH_DMIDA) := dmida
machdir-$(CONFIG_SH_EC3104) := ec3104
machdir-$(CONFIG_SH_SATURN) := saturn
machdir-$(CONFIG_SH_DREAMCAST) := dreamcast
machdir-$(CONFIG_SH_CAT68701) := cat68701
machdir-$(CONFIG_SH_BIGSUR) := bigsur
machdir-$(CONFIG_SH_SH2000) := sh2000
machdir-$(CONFIG_SH_ADX) := adx
machdir-$(CONFIG_SH_MPC1211) := mpc1211
machdir-$(CONFIG_SH_SH03) := sh03
machdir-$(CONFIG_SH_SECUREEDGE5410) := snapgear
@ -104,16 +103,16 @@ machdir-$(CONFIG_SH_HS7751RVOIP) := renesas/hs7751rvoip
machdir-$(CONFIG_SH_RTS7751R2D) := renesas/rts7751r2d
machdir-$(CONFIG_SH_7751_SYSTEMH) := renesas/systemh
machdir-$(CONFIG_SH_EDOSK7705) := renesas/edosk7705
machdir-$(CONFIG_SH_R7780RP) := renesas/r7780rp
machdir-$(CONFIG_SH_7710VOIPGW) := renesas/sh7710voipgw
machdir-$(CONFIG_SH_SH4202_MICRODEV) := superh/microdev
machdir-$(CONFIG_SH_LANDISK) := landisk
machdir-$(CONFIG_SH_TITAN) := titan
machdir-$(CONFIG_SH_SHMIN) := shmin
machdir-$(CONFIG_SH_UNKNOWN) := unknown
incdir-y := $(notdir $(machdir-y))
incdir-$(CONFIG_SH_SOLUTION_ENGINE) := se
incdir-$(CONFIG_SH_7751_SOLUTION_ENGINE) := se7751
incdir-$(CONFIG_SH_7300_SOLUTION_ENGINE) := se7300
incdir-$(CONFIG_SH_73180_SOLUTION_ENGINE) := se73180
incdir-$(CONFIG_SH_HP600) := hp6xx
incdir-$(CONFIG_SH_HP6XX) := hp6xx
ifneq ($(machdir-y),)
core-y += arch/sh/boards/$(machdir-y)/
@ -137,17 +136,14 @@ boot := arch/sh/boot
CPPFLAGS_vmlinux.lds := -traditional
ifneq ($(KBUILD_SRC),)
incdir-prefix := $(srctree)/include/asm-sh/
else
incdir-prefix :=
endif
# Update machine arch and proc symlinks if something which affects
# them changed. We use .arch and .mach to indicate when they were
# updated last, otherwise make uses the target directory mtime.
include/asm-sh/.cpu: $(wildcard include/config/cpu/*.h) include/config/auto.conf
include/asm-sh/.cpu: $(wildcard include/config/cpu/*.h) \
include/config/auto.conf FORCE
@echo ' SYMLINK include/asm-sh/cpu -> include/asm-sh/$(cpuincdir-y)'
$(Q)if [ ! -d include/asm-sh ]; then mkdir -p include/asm-sh; fi
$(Q)ln -fsn $(incdir-prefix)$(cpuincdir-y) include/asm-sh/cpu
@ -157,7 +153,8 @@ include/asm-sh/.cpu: $(wildcard include/config/cpu/*.h) include/config/auto.conf
# don't, just reference the parent directory so the semantics are
# kept roughly the same.
include/asm-sh/.mach: $(wildcard include/config/sh/*.h) include/config/auto.conf
include/asm-sh/.mach: $(wildcard include/config/sh/*.h) \
include/config/auto.conf FORCE
@echo -n ' SYMLINK include/asm-sh/mach -> '
$(Q)if [ ! -d include/asm-sh ]; then mkdir -p include/asm-sh; fi
$(Q)if [ -d $(incdir-prefix)$(incdir-y) ]; then \
@ -170,7 +167,7 @@ include/asm-sh/.mach: $(wildcard include/config/sh/*.h) include/config/auto.conf
fi
@touch $@
archprepare: maketools include/asm-sh/.cpu include/asm-sh/.mach
archprepare: include/asm-sh/.cpu include/asm-sh/.mach maketools
PHONY += maketools FORCE
maketools: include/linux/version.h FORCE
@ -191,4 +188,3 @@ CLEAN_FILES += include/asm-sh/machtypes.h
define archhelp
@echo ' zImage - Compressed kernel image (arch/sh/boot/zImage)'
endef

View file

@ -1,6 +0,0 @@
#
# Makefile for ADX boards
#
obj-y := setup.o irq.o irq_maskreq.o

View file

@ -1,31 +0,0 @@
/*
* linux/arch/sh/boards/adx/irq.c
*
* Copyright (C) 2001 A&D Co., Ltd.
*
* I/O routine and setup routines for A&D ADX Board
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
*/
#include <asm/irq.h>
void init_adx_IRQ(void)
{
int i;
/* printk("init_adx_IRQ()\n");*/
/* setup irq_mask_register */
irq_mask_register = (unsigned short *)0xa6000008;
/* cover all external interrupt area by maskreg_irq_type
* (Actually, irq15 doesn't exist)
*/
for (i = 0; i < 16; i++) {
make_maskreg_irq(i);
disable_irq(i);
}
}

View file

@ -1,56 +0,0 @@
/*
* linux/arch/sh/board/adx/setup.c
*
* Copyright (C) 2001 A&D Co., Ltd.
*
* I/O routine and setup routines for A&D ADX Board
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
*/
#include <asm/machvec.h>
#include <linux/module.h>
extern void init_adx_IRQ(void);
extern void *cf_io_base;
const char *get_system_type(void)
{
return "A&D ADX";
}
unsigned long adx_isa_port2addr(unsigned long offset)
{
/* CompactFlash (IDE) */
if (((offset >= 0x1f0) && (offset <= 0x1f7)) || (offset == 0x3f6)) {
return (unsigned long)cf_io_base + offset;
}
/* eth0 */
if ((offset >= 0x300) && (offset <= 0x30f)) {
return 0xa5000000 + offset; /* COMM BOARD (AREA1) */
}
return offset + 0xb0000000; /* IOBUS (AREA 4)*/
}
/*
* The Machine Vector
*/
struct sh_machine_vector mv_adx __initmv = {
.mv_nr_irqs = 48,
.mv_isa_port2addr = adx_isa_port2addr,
.mv_init_irq = init_adx_IRQ,
};
ALIAS_MV(adx)
int __init platform_setup(void)
{
/* Nothing to see here .. */
return 0;
}

View file

@ -19,6 +19,7 @@
* IRQ functions for a Hitachi Big Sur Evaluation Board.
*
*/
#undef DEBUG
#include <linux/sched.h>
#include <linux/module.h>
@ -41,10 +42,8 @@
#undef BIGSUR_DEBUG
#ifdef BIGSUR_DEBUG
#define DPRINTK(args...) printk(args)
#define DIPRINTK(n, args...) if (BIGSUR_DEBUG>(n)) printk(args)
#else
#define DPRINTK(args...)
#define DIPRINTK(n, args...)
#endif /* BIGSUR_DEBUG */
@ -60,45 +59,39 @@ extern int hd64465_irq_demux(int irq);
/* Level 1 IRQ routines */
static void disable_bigsur_l1irq(unsigned int irq)
{
unsigned long flags;
unsigned char mask;
unsigned int mask_port = ((irq - BIGSUR_IRQ_LOW)/8) ? BIGSUR_IRLMR1 : BIGSUR_IRLMR0;
unsigned char bit = (1 << ((irq - MGATE_IRQ_LOW)%8) );
if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH) {
DPRINTK("Disable L1 IRQ %d\n", irq);
pr_debug("Disable L1 IRQ %d\n", irq);
DIPRINTK(2,"disable_bigsur_l1irq: IMR=0x%08x mask=0x%x\n",
mask_port, bit);
local_irq_save(flags);
/* Disable IRQ - set mask bit */
mask = inb(mask_port) | bit;
outb(mask, mask_port);
local_irq_restore(flags);
return;
}
DPRINTK("disable_bigsur_l1irq: Invalid IRQ %d\n", irq);
pr_debug("disable_bigsur_l1irq: Invalid IRQ %d\n", irq);
}
static void enable_bigsur_l1irq(unsigned int irq)
{
unsigned long flags;
unsigned char mask;
unsigned int mask_port = ((irq - BIGSUR_IRQ_LOW)/8) ? BIGSUR_IRLMR1 : BIGSUR_IRLMR0;
unsigned char bit = (1 << ((irq - MGATE_IRQ_LOW)%8) );
if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH) {
DPRINTK("Enable L1 IRQ %d\n", irq);
pr_debug("Enable L1 IRQ %d\n", irq);
DIPRINTK(2,"enable_bigsur_l1irq: IMR=0x%08x mask=0x%x\n",
mask_port, bit);
local_irq_save(flags);
/* Enable L1 IRQ - clear mask bit */
mask = inb(mask_port) & ~bit;
outb(mask, mask_port);
local_irq_restore(flags);
return;
}
DPRINTK("enable_bigsur_l1irq: Invalid IRQ %d\n", irq);
pr_debug("enable_bigsur_l1irq: Invalid IRQ %d\n", irq);
}
@ -126,51 +119,45 @@ static const u32 imr_offset = BIGSUR_IMR0 - BIGSUR_IMR1;
/* Level 2 IRQ routines */
static void disable_bigsur_l2irq(unsigned int irq)
{
unsigned long flags;
unsigned char mask;
unsigned char bit = 1 << ((irq-BIGSUR_2NDLVL_IRQ_LOW)%8);
unsigned int mask_port = imr_base - REG_NUM(irq)*imr_offset;
if(irq >= BIGSUR_2NDLVL_IRQ_LOW && irq < BIGSUR_2NDLVL_IRQ_HIGH) {
DPRINTK("Disable L2 IRQ %d\n", irq);
if(irq >= BIGSUR_2NDLVL_IRQ_LOW && irq < BIGSUR_2NDLVL_IRQ_HIGH) {
pr_debug("Disable L2 IRQ %d\n", irq);
DIPRINTK(2,"disable_bigsur_l2irq: IMR=0x%08x mask=0x%x\n",
mask_port, bit);
local_irq_save(flags);
/* Disable L2 IRQ - set mask bit */
mask = inb(mask_port) | bit;
outb(mask, mask_port);
local_irq_restore(flags);
return;
}
DPRINTK("disable_bigsur_l2irq: Invalid IRQ %d\n", irq);
pr_debug("disable_bigsur_l2irq: Invalid IRQ %d\n", irq);
}
static void enable_bigsur_l2irq(unsigned int irq)
{
unsigned long flags;
unsigned char mask;
unsigned char bit = 1 << ((irq-BIGSUR_2NDLVL_IRQ_LOW)%8);
unsigned int mask_port = imr_base - REG_NUM(irq)*imr_offset;
if(irq >= BIGSUR_2NDLVL_IRQ_LOW && irq < BIGSUR_2NDLVL_IRQ_HIGH) {
DPRINTK("Enable L2 IRQ %d\n", irq);
if(irq >= BIGSUR_2NDLVL_IRQ_LOW && irq < BIGSUR_2NDLVL_IRQ_HIGH) {
pr_debug("Enable L2 IRQ %d\n", irq);
DIPRINTK(2,"enable_bigsur_l2irq: IMR=0x%08x mask=0x%x\n",
mask_port, bit);
local_irq_save(flags);
/* Enable L2 IRQ - clear mask bit */
mask = inb(mask_port) & ~bit;
outb(mask, mask_port);
local_irq_restore(flags);
return;
}
DPRINTK("enable_bigsur_l2irq: Invalid IRQ %d\n", irq);
pr_debug("enable_bigsur_l2irq: Invalid IRQ %d\n", irq);
}
static void mask_and_ack_bigsur(unsigned int irq)
{
DPRINTK("mask_and_ack_bigsur IRQ %d\n", irq);
pr_debug("mask_and_ack_bigsur IRQ %d\n", irq);
if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH)
disable_bigsur_l1irq(irq);
else
@ -179,7 +166,7 @@ static void mask_and_ack_bigsur(unsigned int irq)
static void end_bigsur_irq(unsigned int irq)
{
DPRINTK("end_bigsur_irq IRQ %d\n", irq);
pr_debug("end_bigsur_irq IRQ %d\n", irq);
if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) {
if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH)
enable_bigsur_l1irq(irq);
@ -193,7 +180,7 @@ static unsigned int startup_bigsur_irq(unsigned int irq)
u8 mask;
u32 reg;
DPRINTK("startup_bigsur_irq IRQ %d\n", irq);
pr_debug("startup_bigsur_irq IRQ %d\n", irq);
if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH) {
/* Enable the L1 IRQ */
@ -218,7 +205,7 @@ static unsigned int startup_bigsur_irq(unsigned int irq)
static void shutdown_bigsur_irq(unsigned int irq)
{
DPRINTK("shutdown_bigsur_irq IRQ %d\n", irq);
pr_debug("shutdown_bigsur_irq IRQ %d\n", irq);
if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH)
disable_bigsur_l1irq(irq);
else
@ -260,7 +247,7 @@ static void make_bigsur_l1isr(unsigned int irq) {
disable_bigsur_l1irq(irq);
return;
}
DPRINTK("make_bigsur_l1isr: bad irq, %d\n", irq);
pr_debug("make_bigsur_l1isr: bad irq, %d\n", irq);
return;
}
@ -277,7 +264,7 @@ static void make_bigsur_l2isr(unsigned int irq) {
disable_bigsur_l2irq(irq);
return;
}
DPRINTK("make_bigsur_l2isr: bad irq, %d\n", irq);
pr_debug("make_bigsur_l2isr: bad irq, %d\n", irq);
return;
}

View file

@ -41,31 +41,7 @@
// Big Sur Init Routines
/*===========================================================*/
const char *get_system_type(void)
{
return "Big Sur";
}
/*
* The Machine Vector
*/
extern void heartbeat_bigsur(void);
extern void init_bigsur_IRQ(void);
struct sh_machine_vector mv_bigsur __initmv = {
.mv_nr_irqs = NR_IRQS, // Defined in <asm/irq.h>
.mv_isa_port2addr = bigsur_isa_port2addr,
.mv_irq_demux = bigsur_irq_demux,
.mv_init_irq = init_bigsur_IRQ,
#ifdef CONFIG_HEARTBEAT
.mv_heartbeat = heartbeat_bigsur,
#endif
};
ALIAS_MV(bigsur)
int __init platform_setup(void)
static void __init bigsur_setup(char **cmdline_p)
{
/* Mask all 2nd level IRQ's */
outb(-1,BIGSUR_IMR0);
@ -89,7 +65,24 @@ int __init platform_setup(void)
outw(1, BIGSUR_ETHR+0xe);
/* set the IO port to BIGSUR_ETHER_IOPORT */
outw(BIGSUR_ETHER_IOPORT<<3, BIGSUR_ETHR+0x2);
return 0;
}
/*
* The Machine Vector
*/
extern void heartbeat_bigsur(void);
extern void init_bigsur_IRQ(void);
struct sh_machine_vector mv_bigsur __initmv = {
.mv_name = "Big Sur",
.mv_setup = bigsur_setup,
.mv_isa_port2addr = bigsur_isa_port2addr,
.mv_irq_demux = bigsur_irq_demux,
.mv_init_irq = init_bigsur_IRQ,
#ifdef CONFIG_HEARTBEAT
.mv_heartbeat = heartbeat_bigsur,
#endif
};
ALIAS_MV(bigsur)

View file

@ -1,6 +0,0 @@
#
# Makefile for the CAT-68701 specific parts of the kernel
#
obj-y := setup.o irq.o

View file

@ -1,28 +0,0 @@
/*
* linux/arch/sh/boards/cat68701/irq.c
*
* Copyright (C) 2000 Niibe Yutaka
* 2001 Yutaro Ebihara
*
* Setup routines for A-ONE Corp CAT-68701 SH7708 Board
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
*/
#include <asm/irq.h>
int cat68701_irq_demux(int irq)
{
if(irq==13) return 14;
if(irq==7) return 10;
return irq;
}
void init_cat68701_IRQ()
{
make_imask_irq(10);
make_imask_irq(14);
}

View file

@ -1,85 +0,0 @@
/*
* linux/arch/sh/boards/cat68701/setup.c
*
* Copyright (C) 2000 Niibe Yutaka
* 2001 Yutaro Ebihara
*
* Setup routines for A-ONE Corp CAT-68701 SH7708 Board
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
*/
#include <asm/io.h>
#include <asm/machvec.h>
#include <asm/mach/io.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/sched.h>
const char *get_system_type(void)
{
return "CAT-68701";
}
#ifdef CONFIG_HEARTBEAT
void heartbeat_cat68701()
{
static unsigned int cnt = 0, period = 0 , bit = 0;
cnt += 1;
if (cnt < period) {
return;
}
cnt = 0;
/* Go through the points (roughly!):
* f(0)=10, f(1)=16, f(2)=20, f(5)=35,f(inf)->110
*/
period = 110 - ( (300<<FSHIFT)/
((avenrun[0]/5) + (3<<FSHIFT)) );
if(bit){ bit=0; }else{ bit=1; }
outw(bit<<15,0x3fe);
}
#endif /* CONFIG_HEARTBEAT */
unsigned long cat68701_isa_port2addr(unsigned long offset)
{
/* CompactFlash (IDE) */
if (((offset >= 0x1f0) && (offset <= 0x1f7)) || (offset==0x3f6))
return 0xba000000 + offset;
/* INPUT PORT */
if ((offset >= 0x3fc) && (offset <= 0x3fd))
return 0xb4007000 + offset;
/* OUTPUT PORT */
if ((offset >= 0x3fe) && (offset <= 0x3ff))
return 0xb4007400 + offset;
return offset + 0xb4000000; /* other I/O (EREA 5)*/
}
/*
* The Machine Vector
*/
struct sh_machine_vector mv_cat68701 __initmv = {
.mv_nr_irqs = 32,
.mv_isa_port2addr = cat68701_isa_port2addr,
.mv_irq_demux = cat68701_irq_demux,
.mv_init_irq = init_cat68701_IRQ,
#ifdef CONFIG_HEARTBEAT
.mv_heartbeat = heartbeat_cat68701,
#endif
};
ALIAS_MV(cat68701)
int __init platform_setup(void)
{
/* dummy read erea5 (CS8900A) */
}

View file

@ -1,6 +0,0 @@
#
# Makefile for the CqREEK specific parts of the kernel
#
obj-y := setup.o irq.o

View file

@ -1,128 +0,0 @@
/* $Id: irq.c,v 1.1.2.4 2002/11/04 20:33:56 lethal Exp $
*
* arch/sh/boards/cqreek/irq.c
*
* Copyright (C) 2000 Niibe Yutaka
*
* CqREEK IDE/ISA Bridge Support.
*
*/
#include <linux/irq.h>
#include <linux/init.h>
#include <asm/cqreek/cqreek.h>
#include <asm/io.h>
#include <asm/io_generic.h>
#include <asm/irq.h>
#include <asm/machvec.h>
#include <asm/machvec_init.h>
#include <asm/rtc.h>
struct cqreek_irq_data {
unsigned short mask_port; /* Port of Interrupt Mask Register */
unsigned short stat_port; /* Port of Interrupt Status Register */
unsigned short bit; /* Value of the bit */
};
static struct cqreek_irq_data cqreek_irq_data[NR_IRQS];
static void disable_cqreek_irq(unsigned int irq)
{
unsigned long flags;
unsigned short mask;
unsigned short mask_port = cqreek_irq_data[irq].mask_port;
unsigned short bit = cqreek_irq_data[irq].bit;
local_irq_save(flags);
/* Disable IRQ */
mask = inw(mask_port) & ~bit;
outw_p(mask, mask_port);
local_irq_restore(flags);
}
static void enable_cqreek_irq(unsigned int irq)
{
unsigned long flags;
unsigned short mask;
unsigned short mask_port = cqreek_irq_data[irq].mask_port;
unsigned short bit = cqreek_irq_data[irq].bit;
local_irq_save(flags);
/* Enable IRQ */
mask = inw(mask_port) | bit;
outw_p(mask, mask_port);
local_irq_restore(flags);
}
static void mask_and_ack_cqreek(unsigned int irq)
{
unsigned short stat_port = cqreek_irq_data[irq].stat_port;
unsigned short bit = cqreek_irq_data[irq].bit;
disable_cqreek_irq(irq);
/* Clear IRQ (it might be edge IRQ) */
inw(stat_port);
outw_p(bit, stat_port);
}
static void end_cqreek_irq(unsigned int irq)
{
if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
enable_cqreek_irq(irq);
}
static unsigned int startup_cqreek_irq(unsigned int irq)
{
enable_cqreek_irq(irq);
return 0;
}
static void shutdown_cqreek_irq(unsigned int irq)
{
disable_cqreek_irq(irq);
}
static struct hw_interrupt_type cqreek_irq_type = {
.typename = "CqREEK-IRQ",
.startup = startup_cqreek_irq,
.shutdown = shutdown_cqreek_irq,
.enable = enable_cqreek_irq,
.disable = disable_cqreek_irq,
.ack = mask_and_ack_cqreek,
.end = end_cqreek_irq
};
int cqreek_has_ide, cqreek_has_isa;
/* XXX: This is just for test for my NE2000 ISA board
What we really need is virtualized IRQ and demultiplexer like HP600 port */
void __init init_cqreek_IRQ(void)
{
if (cqreek_has_ide) {
cqreek_irq_data[14].mask_port = BRIDGE_IDE_INTR_MASK;
cqreek_irq_data[14].stat_port = BRIDGE_IDE_INTR_STAT;
cqreek_irq_data[14].bit = 1;
irq_desc[14].chip = &cqreek_irq_type;
irq_desc[14].status = IRQ_DISABLED;
irq_desc[14].action = 0;
irq_desc[14].depth = 1;
disable_cqreek_irq(14);
}
if (cqreek_has_isa) {
cqreek_irq_data[10].mask_port = BRIDGE_ISA_INTR_MASK;
cqreek_irq_data[10].stat_port = BRIDGE_ISA_INTR_STAT;
cqreek_irq_data[10].bit = (1 << 10);
/* XXX: Err... we may need demultiplexer for ISA irq... */
irq_desc[10].chip = &cqreek_irq_type;
irq_desc[10].status = IRQ_DISABLED;
irq_desc[10].action = 0;
irq_desc[10].depth = 1;
disable_cqreek_irq(10);
}
}

View file

@ -1,100 +0,0 @@
/* $Id: setup.c,v 1.5 2003/08/04 01:51:58 lethal Exp $
*
* arch/sh/kernel/setup_cqreek.c
*
* Copyright (C) 2000 Niibe Yutaka
*
* CqREEK IDE/ISA Bridge Support.
*
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <asm/mach/cqreek.h>
#include <asm/machvec.h>
#include <asm/io.h>
#include <asm/io_generic.h>
#include <asm/irq.h>
#include <asm/rtc.h>
#define IDE_OFFSET 0xA4000000UL
#define ISA_OFFSET 0xA4A00000UL
const char *get_system_type(void)
{
return "CqREEK";
}
static unsigned long cqreek_port2addr(unsigned long port)
{
if (0x0000<=port && port<=0x0040)
return IDE_OFFSET + port;
if ((0x01f0<=port && port<=0x01f7) || port == 0x03f6)
return IDE_OFFSET + port;
return ISA_OFFSET + port;
}
/*
* The Machine Vector
*/
struct sh_machine_vector mv_cqreek __initmv = {
#if defined(CONFIG_CPU_SH4)
.mv_nr_irqs = 48,
#elif defined(CONFIG_CPU_SUBTYPE_SH7708)
.mv_nr_irqs = 32,
#elif defined(CONFIG_CPU_SUBTYPE_SH7709)
.mv_nr_irqs = 61,
#endif
.mv_init_irq = init_cqreek_IRQ,
.mv_isa_port2addr = cqreek_port2addr,
};
ALIAS_MV(cqreek)
/*
* Initialize the board
*/
void __init platform_setup(void)
{
int i;
/* udelay is not available at setup time yet... */
#define DELAY() do {for (i=0; i<10000; i++) ctrl_inw(0xa0000000);} while(0)
if ((inw (BRIDGE_FEATURE) & 1)) { /* We have IDE interface */
outw_p(0, BRIDGE_IDE_INTR_LVL);
outw_p(0, BRIDGE_IDE_INTR_MASK);
outw_p(0, BRIDGE_IDE_CTRL);
DELAY();
outw_p(0x8000, BRIDGE_IDE_CTRL);
DELAY();
outw_p(0xffff, BRIDGE_IDE_INTR_STAT); /* Clear interrupt status */
outw_p(0x0f-14, BRIDGE_IDE_INTR_LVL); /* Use 14 IPR */
outw_p(1, BRIDGE_IDE_INTR_MASK); /* Enable interrupt */
cqreek_has_ide=1;
}
if ((inw (BRIDGE_FEATURE) & 2)) { /* We have ISA interface */
outw_p(0, BRIDGE_ISA_INTR_LVL);
outw_p(0, BRIDGE_ISA_INTR_MASK);
outw_p(0, BRIDGE_ISA_CTRL);
DELAY();
outw_p(0x8000, BRIDGE_ISA_CTRL);
DELAY();
outw_p(0xffff, BRIDGE_ISA_INTR_STAT); /* Clear interrupt status */
outw_p(0x0f-10, BRIDGE_ISA_INTR_LVL); /* Use 10 IPR */
outw_p(0xfff8, BRIDGE_ISA_INTR_MASK); /* Enable interrupt */
cqreek_has_isa=1;
}
printk(KERN_INFO "CqREEK Setup (IDE=%d, ISA=%d)...done\n", cqreek_has_ide, cqreek_has_isa);
}

View file

@ -1,7 +0,0 @@
#
# Makefile for the DataMyte Industrial Digital Assistant(tm) specific parts
# of the kernel
#
obj-y := mach.o

View file

@ -1,59 +0,0 @@
/*
* linux/arch/sh/boards/dmida/mach.c
*
* by Greg Banks <gbanks@pocketpenguins.com>
* (c) 2000 PocketPenguins Inc
*
* Derived from mach_hp600.c, which bore the message:
* Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com)
*
* May be copied or modified under the terms of the GNU General Public
* License. See linux/COPYING for more information.
*
* Machine vector for the DataMyte Industrial Digital Assistant(tm).
* See http://www.dmida.com
*
*/
#include <linux/init.h>
#include <asm/machvec.h>
#include <asm/rtc.h>
#include <asm/machvec_init.h>
#include <asm/io.h>
#include <asm/hd64465/hd64465.h>
#include <asm/irq.h>
/*
* The Machine Vector
*/
struct sh_machine_vector mv_dmida __initmv = {
.mv_nr_irqs = HD64465_IRQ_BASE+HD64465_IRQ_NUM,
.mv_inb = hd64465_inb,
.mv_inw = hd64465_inw,
.mv_inl = hd64465_inl,
.mv_outb = hd64465_outb,
.mv_outw = hd64465_outw,
.mv_outl = hd64465_outl,
.mv_inb_p = hd64465_inb_p,
.mv_inw_p = hd64465_inw,
.mv_inl_p = hd64465_inl,
.mv_outb_p = hd64465_outb_p,
.mv_outw_p = hd64465_outw,
.mv_outl_p = hd64465_outl,
.mv_insb = hd64465_insb,
.mv_insw = hd64465_insw,
.mv_insl = hd64465_insl,
.mv_outsb = hd64465_outsb,
.mv_outsw = hd64465_outsw,
.mv_outsl = hd64465_outsl,
.mv_irq_demux = hd64465_irq_demux,
};
ALIAS_MV(dmida)

View file

@ -10,7 +10,6 @@
*/
#include <linux/irq.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/dreamcast/sysasic.h>
@ -26,10 +25,10 @@
event.
There are three 32-bit ESRs located at 0xa05f8900 - 0xa05f6908. Event
types can be found in include/asm-sh/dc_sysasic.h. There are three groups
of EMRs that parallel the ESRs. Each EMR group corresponds to an IRQ, so
0xa05f6910 - 0xa05f6918 triggers IRQ 13, 0xa05f6920 - 0xa05f6928 triggers
IRQ 11, and 0xa05f6930 - 0xa05f6938 triggers IRQ 9.
types can be found in include/asm-sh/dreamcast/sysasic.h. There are three
groups of EMRs that parallel the ESRs. Each EMR group corresponds to an
IRQ, so 0xa05f6910 - 0xa05f6918 triggers IRQ 13, 0xa05f6920 - 0xa05f6928
triggers IRQ 11, and 0xa05f6930 - 0xa05f6938 triggers IRQ 9.
In the kernel, these events are mapped to virtual IRQs so that drivers can
respond to them as they would a normal interrupt. In order to keep this
@ -57,29 +56,23 @@
/* Disable the hardware event by masking its bit in its EMR */
static inline void disable_systemasic_irq(unsigned int irq)
{
unsigned long flags;
__u32 emr = EMR_BASE + (LEVEL(irq) << 4) + (LEVEL(irq) << 2);
__u32 mask;
local_irq_save(flags);
mask = inl(emr);
mask &= ~(1 << EVENT_BIT(irq));
outl(mask, emr);
local_irq_restore(flags);
}
/* Enable the hardware event by setting its bit in its EMR */
static inline void enable_systemasic_irq(unsigned int irq)
{
unsigned long flags;
__u32 emr = EMR_BASE + (LEVEL(irq) << 4) + (LEVEL(irq) << 2);
__u32 mask;
local_irq_save(flags);
mask = inl(emr);
mask |= (1 << EVENT_BIT(irq));
outl(mask, emr);
local_irq_restore(flags);
}
/* Acknowledge a hardware event by writing its bit back to its ESR */

View file

@ -1,4 +1,5 @@
/* arch/sh/kernel/rtc-aica.c
/*
* arch/sh/boards/dreamcast/rtc.c
*
* Dreamcast AICA RTC routines.
*
@ -10,15 +11,12 @@
*/
#include <linux/time.h>
#include <asm/rtc.h>
#include <asm/io.h>
extern void (*rtc_get_time)(struct timespec *);
extern int (*rtc_set_time)(const time_t);
/* The AICA RTC has an Epoch of 1/1/1950, so we must subtract 20 years (in
seconds to get the standard Unix Epoch when getting the time, and add 20
years when setting the time. */
seconds) to get the standard Unix Epoch when getting the time, and add
20 years when setting the time. */
#define TWENTY_YEARS ((20 * 365LU + 5) * 86400)
/* The AICA RTC is represented by a 32-bit seconds counter stored in 2 16-bit
@ -32,7 +30,8 @@ extern int (*rtc_set_time)(const time_t);
*
* Grabs the current RTC seconds counter and adjusts it to the Unix Epoch.
*/
void aica_rtc_gettimeofday(struct timespec *ts) {
void aica_rtc_gettimeofday(struct timespec *ts)
{
unsigned long val1, val2;
do {
@ -55,7 +54,8 @@ void aica_rtc_gettimeofday(struct timespec *ts) {
*
* Adjusts the given @tv to the AICA Epoch and sets the RTC seconds counter.
*/
int aica_rtc_settimeofday(const time_t secs) {
int aica_rtc_settimeofday(const time_t secs)
{
unsigned long val1, val2;
unsigned long adj = secs + TWENTY_YEARS;
@ -75,7 +75,7 @@ int aica_rtc_settimeofday(const time_t secs) {
void aica_time_init(void)
{
rtc_get_time = aica_rtc_gettimeofday;
rtc_set_time = aica_rtc_settimeofday;
rtc_sh_get_time = aica_rtc_gettimeofday;
rtc_sh_set_time = aica_rtc_settimeofday;
}

View file

@ -22,41 +22,21 @@
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/device.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/rtc.h>
#include <asm/machvec.h>
#include <asm/machvec_init.h>
#include <asm/mach/sysasic.h>
extern struct hw_interrupt_type systemasic_int;
/* XXX: Move this into it's proper header. */
extern void (*board_time_init)(void);
extern void aica_time_init(void);
extern int gapspci_init(void);
extern int systemasic_irq_demux(int);
void *dreamcast_consistent_alloc(struct device *, size_t, dma_addr_t *, int);
void *dreamcast_consistent_alloc(struct device *, size_t, dma_addr_t *, gfp_t);
int dreamcast_consistent_free(struct device *, size_t, void *, dma_addr_t);
const char *get_system_type(void)
{
return "Sega Dreamcast";
}
struct sh_machine_vector mv_dreamcast __initmv = {
.mv_nr_irqs = NR_IRQS,
.mv_irq_demux = systemasic_irq_demux,
#ifdef CONFIG_PCI
.mv_consistent_alloc = dreamcast_consistent_alloc,
.mv_consistent_free = dreamcast_consistent_free,
#endif
};
ALIAS_MV(dreamcast)
int __init platform_setup(void)
static void __init dreamcast_setup(char **cmdline_p)
{
int i;
@ -78,6 +58,16 @@ int __init platform_setup(void)
if (gapspci_init() < 0)
printk(KERN_WARNING "GAPSPCI was not detected.\n");
#endif
return 0;
}
struct sh_machine_vector mv_dreamcast __initmv = {
.mv_name = "Sega Dreamcast",
.mv_setup = dreamcast_setup,
.mv_irq_demux = systemasic_irq_demux,
#ifdef CONFIG_PCI
.mv_consistent_alloc = dreamcast_consistent_alloc,
.mv_consistent_free = dreamcast_consistent_free,
#endif
};
ALIAS_MV(dreamcast)

View file

@ -21,22 +21,36 @@
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/types.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/machvec.h>
#include <asm/mach/ec3104.h>
const char *get_system_type(void)
static void __init ec3104_setup(char **cmdline_p)
{
return "EC3104";
char str[8];
int i;
for (i=0; i<8; i++)
str[i] = ctrl_readb(EC3104_BASE + i);
for (i = EC3104_IRQBASE; i < EC3104_IRQBASE + 32; i++)
irq_desc[i].handler = &ec3104_int;
printk("initializing EC3104 \"%.8s\" at %08x, IRQ %d, IRQ base %d\n",
str, EC3104_BASE, EC3104_IRQ, EC3104_IRQBASE);
/* mask all interrupts. this should have been done by the boot
* loader for us but we want to be sure ... */
ctrl_writel(0xffffffff, EC3104_IMR);
}
/*
* The Machine Vector
*/
struct sh_machine_vector mv_ec3104 __initmv = {
.mv_name = "EC3104",
.mv_setup = ec3104_setup,
.mv_nr_irqs = 96,
.mv_inb = ec3104_inb,
@ -48,31 +62,4 @@ struct sh_machine_vector mv_ec3104 __initmv = {
.mv_irq_demux = ec3104_irq_demux,
};
ALIAS_MV(ec3104)
int __init platform_setup(void)
{
char str[8];
int i;
if (0)
return 0;
for (i=0; i<8; i++)
str[i] = ctrl_readb(EC3104_BASE + i);
for (i = EC3104_IRQBASE; i < EC3104_IRQBASE + 32; i++)
irq_desc[i].chip = &ec3104_int;
printk("initializing EC3104 \"%.8s\" at %08x, IRQ %d, IRQ base %d\n",
str, EC3104_BASE, EC3104_IRQ, EC3104_IRQBASE);
/* mask all interrupts. this should have been done by the boot
* loader for us but we want to be sure ... */
ctrl_writel(0xffffffff, EC3104_IMR);
return 0;
}

View file

@ -1,8 +0,0 @@
#
# Makefile for STMicroelectronics board specific parts of the kernel
#
obj-y := irq.o setup.o mach.o led.o
obj-$(CONFIG_PCI) += pcidma.o

View file

@ -1,147 +0,0 @@
/*
* Copyright (C) 2000 David J. Mckay (david.mckay@st.com)
*
* May be copied or modified under the terms of the GNU General Public
* License. See linux/COPYING for more information.
*
* Looks after interrupts on the HARP board.
*
* Bases on the IPR irq system
*/
#include <linux/init.h>
#include <linux/irq.h>
#include <asm/system.h>
#include <asm/io.h>
#include <asm/harp/harp.h>
#define NUM_EXTERNAL_IRQS 16
// Early versions of the STB1 Overdrive required this nasty frig
//#define INVERT_INTMASK_WRITES
static void enable_harp_irq(unsigned int irq);
static void disable_harp_irq(unsigned int irq);
/* shutdown is same as "disable" */
#define shutdown_harp_irq disable_harp_irq
static void mask_and_ack_harp(unsigned int);
static void end_harp_irq(unsigned int irq);
static unsigned int startup_harp_irq(unsigned int irq)
{
enable_harp_irq(irq);
return 0; /* never anything pending */
}
static struct hw_interrupt_type harp_irq_type = {
.typename = "Harp-IRQ",
.startup = startup_harp_irq,
.shutdown = shutdown_harp_irq,
.enable = enable_harp_irq,
.disable = disable_harp_irq,
.ack = mask_and_ack_harp,
.end = end_harp_irq
};
static void disable_harp_irq(unsigned int irq)
{
unsigned val, flags;
unsigned maskReg;
unsigned mask;
int pri;
if (irq < 0 || irq >= NUM_EXTERNAL_IRQS)
return;
pri = 15 - irq;
if (pri < 8) {
maskReg = EPLD_INTMASK0;
} else {
maskReg = EPLD_INTMASK1;
pri -= 8;
}
local_irq_save(flags);
mask = ctrl_inl(maskReg);
mask &= (~(1 << pri));
#if defined(INVERT_INTMASK_WRITES)
mask ^= 0xff;
#endif
ctrl_outl(mask, maskReg);
local_irq_restore(flags);
}
static void enable_harp_irq(unsigned int irq)
{
unsigned flags;
unsigned maskReg;
unsigned mask;
int pri;
if (irq < 0 || irq >= NUM_EXTERNAL_IRQS)
return;
pri = 15 - irq;
if (pri < 8) {
maskReg = EPLD_INTMASK0;
} else {
maskReg = EPLD_INTMASK1;
pri -= 8;
}
local_irq_save(flags);
mask = ctrl_inl(maskReg);
mask |= (1 << pri);
#if defined(INVERT_INTMASK_WRITES)
mask ^= 0xff;
#endif
ctrl_outl(mask, maskReg);
local_irq_restore(flags);
}
/* This functions sets the desired irq handler to be an overdrive type */
static void __init make_harp_irq(unsigned int irq)
{
disable_irq_nosync(irq);
irq_desc[irq].chip = &harp_irq_type;
disable_harp_irq(irq);
}
static void mask_and_ack_harp(unsigned int irq)
{
disable_harp_irq(irq);
}
static void end_harp_irq(unsigned int irq)
{
enable_harp_irq(irq);
}
void __init init_harp_irq(void)
{
int i;
#if !defined(INVERT_INTMASK_WRITES)
// On the harp these are set to enable an interrupt
ctrl_outl(0x00, EPLD_INTMASK0);
ctrl_outl(0x00, EPLD_INTMASK1);
#else
// On the Overdrive the data is inverted before being stored in the reg
ctrl_outl(0xff, EPLD_INTMASK0);
ctrl_outl(0xff, EPLD_INTMASK1);
#endif
for (i = 0; i < NUM_EXTERNAL_IRQS; i++) {
make_harp_irq(i);
}
}

View file

@ -1,51 +0,0 @@
/*
* linux/arch/sh/stboards/led.c
*
* Copyright (C) 2000 Stuart Menefy <stuart.menefy@st.com>
*
* May be copied or modified under the terms of the GNU General Public
* License. See linux/COPYING for more information.
*
* This file contains ST40STB1 HARP and compatible code.
*/
#include <asm/io.h>
#include <asm/harp/harp.h>
/* Harp: Flash LD10 (front pannel) connected to EPLD (IC8) */
/* Overdrive: Flash LD1 (front panel) connected to EPLD (IC4) */
/* Works for HARP and overdrive */
static void mach_led(int position, int value)
{
if (value) {
ctrl_outl(EPLD_LED_ON, EPLD_LED);
} else {
ctrl_outl(EPLD_LED_OFF, EPLD_LED);
}
}
#ifdef CONFIG_HEARTBEAT
#include <linux/sched.h>
/* acts like an actual heart beat -- ie thump-thump-pause... */
void heartbeat_harp(void)
{
static unsigned cnt = 0, period = 0, dist = 0;
if (cnt == 0 || cnt == dist)
mach_led( -1, 1);
else if (cnt == 7 || cnt == dist+7)
mach_led( -1, 0);
if (++cnt > period) {
cnt = 0;
/* The hyperbolic function below modifies the heartbeat period
* length in dependency of the current (5min) load. It goes
* through the points f(0)=126, f(1)=86, f(5)=51,
* f(inf)->30. */
period = ((672<<FSHIFT)/(5*avenrun[0]+(7<<FSHIFT))) + 30;
dist = period / 4;
}
}
#endif

View file

@ -1,62 +0,0 @@
/*
* linux/arch/sh/boards/harp/mach.c
*
* Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com)
*
* May be copied or modified under the terms of the GNU General Public
* License. See linux/COPYING for more information.
*
* Machine vector for the STMicroelectronics STB1 HARP and compatible boards
*/
#include <linux/init.h>
#include <asm/machvec.h>
#include <asm/rtc.h>
#include <asm/machvec_init.h>
#include <asm/hd64465/io.h>
#include <asm/hd64465/hd64465.h>
void setup_harp(void);
void init_harp_irq(void);
void heartbeat_harp(void);
/*
* The Machine Vector
*/
struct sh_machine_vector mv_harp __initmv = {
.mv_nr_irqs = 89 + HD64465_IRQ_NUM,
.mv_inb = hd64465_inb,
.mv_inw = hd64465_inw,
.mv_inl = hd64465_inl,
.mv_outb = hd64465_outb,
.mv_outw = hd64465_outw,
.mv_outl = hd64465_outl,
.mv_inb_p = hd64465_inb_p,
.mv_inw_p = hd64465_inw,
.mv_inl_p = hd64465_inl,
.mv_outb_p = hd64465_outb_p,
.mv_outw_p = hd64465_outw,
.mv_outl_p = hd64465_outl,
.mv_insb = hd64465_insb,
.mv_insw = hd64465_insw,
.mv_insl = hd64465_insl,
.mv_outsb = hd64465_outsb,
.mv_outsw = hd64465_outsw,
.mv_outsl = hd64465_outsl,
.mv_isa_port2addr = hd64465_isa_port2addr,
#ifdef CONFIG_PCI
.mv_init_irq = init_harp_irq,
#endif
#ifdef CONFIG_HEARTBEAT
.mv_heartbeat = heartbeat_harp,
#endif
};
ALIAS_MV(harp)

View file

@ -1,42 +0,0 @@
/*
* Copyright (C) 2001 David J. Mckay (david.mckay@st.com)
*
* May be copied or modified under the terms of the GNU General Public
* License. See linux/COPYING for more information.
*
* Dynamic DMA mapping support.
*/
#include <linux/types.h>
#include <linux/mm.h>
#include <linux/string.h>
#include <linux/pci.h>
#include <asm/io.h>
#include <asm/addrspace.h>
void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
dma_addr_t * dma_handle)
{
void *ret;
int gfp = GFP_ATOMIC;
ret = (void *) __get_free_pages(gfp, get_order(size));
if (ret != NULL) {
/* Is it neccessary to do the memset? */
memset(ret, 0, size);
*dma_handle = virt_to_bus(ret);
}
/* We must flush the cache before we pass it on to the device */
flush_cache_all();
return P2SEGADDR(ret);
}
void pci_free_consistent(struct pci_dev *hwdev, size_t size,
void *vaddr, dma_addr_t dma_handle)
{
unsigned long p1addr=P1SEGADDR((unsigned long)vaddr);
free_pages(p1addr, get_order(size));
}

View file

@ -1,90 +0,0 @@
/*
* arch/sh/stboard/setup.c
*
* Copyright (C) 2001 Stuart Menefy (stuart.menefy@st.com)
*
* May be copied or modified under the terms of the GNU General Public
* License. See linux/COPYING for more information.
*
* STMicroelectronics ST40STB1 HARP and compatible support.
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <asm/io.h>
#include <asm/harp/harp.h>
const char *get_system_type(void)
{
return "STB1 Harp";
}
/*
* Initialize the board
*/
int __init platform_setup(void)
{
#ifdef CONFIG_SH_STB1_HARP
unsigned long ic8_version, ic36_version;
ic8_version = ctrl_inl(EPLD_REVID2);
ic36_version = ctrl_inl(EPLD_REVID1);
printk("STMicroelectronics STB1 HARP initialisaton\n");
printk("EPLD versions: IC8: %d.%02d, IC36: %d.%02d\n",
(ic8_version >> 4) & 0xf, ic8_version & 0xf,
(ic36_version >> 4) & 0xf, ic36_version & 0xf);
#elif defined(CONFIG_SH_STB1_OVERDRIVE)
unsigned long version;
version = ctrl_inl(EPLD_REVID);
printk("STMicroelectronics STB1 Overdrive initialisaton\n");
printk("EPLD version: %d.%02d\n",
(version >> 4) & 0xf, version & 0xf);
#else
#error Undefined machine
#endif
/* Currently all STB1 chips have problems with the sleep instruction,
* so disable it here.
*/
disable_hlt();
return 0;
}
/*
* pcibios_map_platform_irq
*
* This is board specific and returns the IRQ for a given PCI device.
* It is used by the PCI code (arch/sh/kernel/st40_pci*)
*
*/
#define HARP_PCI_IRQ 1
#define HARP_BRIDGE_IRQ 2
#define OVERDRIVE_SLOT0_IRQ 0
int __init pcibios_map_platform_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
switch (slot) {
#ifdef CONFIG_SH_STB1_HARP
case 2: /*This is the PCI slot on the */
return HARP_PCI_IRQ;
case 1: /* this is the bridge */
return HARP_BRIDGE_IRQ;
#elif defined(CONFIG_SH_STB1_OVERDRIVE)
case 1:
case 2:
case 3:
return slot - 1;
#else
#error Unknown board
#endif
default:
return -1;
}
}

View file

@ -2,5 +2,6 @@
# Makefile for the HP6xx specific parts of the kernel
#
obj-y := mach.o setup.o
obj-y := setup.o
obj-$(CONFIG_PM) += pm.o pm_wakeup.o
obj-$(CONFIG_APM) += hp6xx_apm.o

View file

@ -0,0 +1,123 @@
/*
* bios-less APM driver for hp680
*
* Copyright 2005 (c) Andriy Skulysh <askulysh@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License.
*/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/apm_bios.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <asm/io.h>
#include <asm/apm.h>
#include <asm/adc.h>
#include <asm/hp6xx/hp6xx.h>
#define SH7709_PGDR 0xa400012c
#define APM_CRITICAL 10
#define APM_LOW 30
#define HP680_BATTERY_MAX 875
#define HP680_BATTERY_MIN 600
#define HP680_BATTERY_AC_ON 900
#define MODNAME "hp6x0_apm"
static int hp6x0_apm_get_info(char *buf, char **start, off_t fpos, int length)
{
u8 pgdr;
char *p;
int battery_status;
int battery_flag;
int ac_line_status;
int time_units = APM_BATTERY_LIFE_UNKNOWN;
int battery = adc_single(ADC_CHANNEL_BATTERY);
int backup = adc_single(ADC_CHANNEL_BACKUP);
int charging = adc_single(ADC_CHANNEL_CHARGE);
int percentage;
percentage = 100 * (battery - HP680_BATTERY_MIN) /
(HP680_BATTERY_MAX - HP680_BATTERY_MIN);
ac_line_status = (battery > HP680_BATTERY_AC_ON) ?
APM_AC_ONLINE : APM_AC_OFFLINE;
p = buf;
pgdr = ctrl_inb(SH7709_PGDR);
if (pgdr & PGDR_MAIN_BATTERY_OUT) {
battery_status = APM_BATTERY_STATUS_NOT_PRESENT;
battery_flag = 0x80;
percentage = -1;
} else if (charging < 8 ) {
battery_status = APM_BATTERY_STATUS_CHARGING;
battery_flag = 0x08;
ac_line_status = 0xff;
} else if (percentage <= APM_CRITICAL) {
battery_status = APM_BATTERY_STATUS_CRITICAL;
battery_flag = 0x04;
} else if (percentage <= APM_LOW) {
battery_status = APM_BATTERY_STATUS_LOW;
battery_flag = 0x02;
} else {
battery_status = APM_BATTERY_STATUS_HIGH;
battery_flag = 0x01;
}
p += sprintf(p, "1.0 1.2 0x%02x 0x%02x 0x%02x 0x%02x %d%% %d %s\n",
APM_32_BIT_SUPPORT,
ac_line_status,
battery_status,
battery_flag,
percentage,
time_units,
"min");
p += sprintf(p, "bat=%d backup=%d charge=%d\n",
battery, backup, charging);
return p - buf;
}
static irqreturn_t hp6x0_apm_interrupt(int irq, void *dev, struct pt_regs *regs)
{
if (!apm_suspended)
apm_queue_event(APM_USER_SUSPEND);
return IRQ_HANDLED;
}
static int __init hp6x0_apm_init(void)
{
int ret;
ret = request_irq(HP680_BTN_IRQ, hp6x0_apm_interrupt,
SA_INTERRUPT, MODNAME, 0);
if (unlikely(ret < 0)) {
printk(KERN_ERR MODNAME ": IRQ %d request failed\n",
HP680_BTN_IRQ);
return ret;
}
apm_get_info = hp6x0_apm_get_info;
return ret;
}
static void __exit hp6x0_apm_exit(void)
{
free_irq(HP680_BTN_IRQ, 0);
apm_get_info = 0;
}
module_init(hp6x0_apm_init);
module_exit(hp6x0_apm_exit);
MODULE_AUTHOR("Adriy Skulysh");
MODULE_DESCRIPTION("hp6xx Advanced Power Management");
MODULE_LICENSE("GPL");

88
arch/sh/boards/hp6xx/pm.c Normal file
View file

@ -0,0 +1,88 @@
/*
* hp6x0 Power Management Routines
*
* Copyright (c) 2006 Andriy Skulysh <askulsyh@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License.
*/
#include <linux/config.h>
#include <linux/init.h>
#include <linux/suspend.h>
#include <linux/errno.h>
#include <linux/time.h>
#include <asm/io.h>
#include <asm/hd64461.h>
#include <asm/hp6xx/hp6xx.h>
#include <asm/cpu/dac.h>
#include <asm/pm.h>
#define STBCR 0xffffff82
#define STBCR2 0xffffff88
static int hp6x0_pm_enter(suspend_state_t state)
{
u8 stbcr, stbcr2;
#ifdef CONFIG_HD64461_ENABLER
u8 scr;
u16 hd64461_stbcr;
#endif
if (state != PM_SUSPEND_MEM)
return -EINVAL;
#ifdef CONFIG_HD64461_ENABLER
outb(0, HD64461_PCC1CSCIER);
scr = inb(HD64461_PCC1SCR);
scr |= HD64461_PCCSCR_VCC1;
outb(scr, HD64461_PCC1SCR);
hd64461_stbcr = inw(HD64461_STBCR);
hd64461_stbcr |= HD64461_STBCR_SPC1ST;
outw(hd64461_stbcr, HD64461_STBCR);
#endif
ctrl_outb(0x1f, DACR);
stbcr = ctrl_inb(STBCR);
ctrl_outb(0x01, STBCR);
stbcr2 = ctrl_inb(STBCR2);
ctrl_outb(0x7f , STBCR2);
outw(0xf07f, HD64461_SCPUCR);
pm_enter();
outw(0, HD64461_SCPUCR);
ctrl_outb(stbcr, STBCR);
ctrl_outb(stbcr2, STBCR2);
#ifdef CONFIG_HD64461_ENABLER
hd64461_stbcr = inw(HD64461_STBCR);
hd64461_stbcr &= ~HD64461_STBCR_SPC1ST;
outw(hd64461_stbcr, HD64461_STBCR);
outb(0x4c, HD64461_PCC1CSCIER);
outb(0x00, HD64461_PCC1CSCR);
#endif
return 0;
}
/*
* Set to PM_DISK_FIRMWARE so we can quickly veto suspend-to-disk.
*/
static struct pm_ops hp6x0_pm_ops = {
.pm_disk_mode = PM_DISK_FIRMWARE,
.enter = hp6x0_pm_enter,
};
static int __init hp6x0_pm_init(void)
{
pm_set_ops(&hp6x0_pm_ops);
return 0;
}
late_initcall(hp6x0_pm_init);

View file

@ -0,0 +1,58 @@
/*
* Copyright (c) 2006 Andriy Skulysh <askulsyh@gmail.com>
*
* 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/linkage.h>
#include <asm/cpu/mmu_context.h>
#define k0 r0
#define k1 r1
#define k2 r2
#define k3 r3
#define k4 r4
/*
* Kernel mode register usage:
* k0 scratch
* k1 scratch
* k2 scratch (Exception code)
* k3 scratch (Return address)
* k4 scratch
* k5 reserved
* k6 Global Interrupt Mask (0--15 << 4)
* k7 CURRENT_THREAD_INFO (pointer to current thread info)
*/
ENTRY(wakeup_start)
! clear STBY bit
mov #-126, k2
and #127, k0
mov.b k0, @k2
! enable refresh
mov.l 5f, k1
mov.w 6f, k0
mov.w k0, @k1
! jump to handler
mov.l 2f, k2
mov.l 3f, k3
mov.l @k2, k2
mov.l 4f, k1
jmp @k1
nop
.align 2
1: .long EXPEVT
2: .long INTEVT
3: .long ret_from_irq
4: .long handle_exception
5: .long 0xffffff68
6: .word 0x0524
ENTRY(wakeup_end)
nop

View file

@ -8,22 +8,22 @@
*
* Setup code for an HP680 (internal peripherials only)
*/
#include <linux/types.h>
#include <linux/init.h>
#include <asm/io.h>
#include <asm/hd64461.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/hp6xx/hp6xx.h>
#include <asm/cpu/dac.h>
const char *get_system_type(void)
{
return "HP6xx";
}
#define SCPCR 0xa4000116
#define SCPDR 0xa4000136
int __init platform_setup(void)
static void __init hp6xx_setup(char **cmdline_p)
{
u8 v8;
u16 v;
v = inw(HD64461_STBCR);
v |= HD64461_STBCR_SURTST | HD64461_STBCR_SIRST |
HD64461_STBCR_STM1ST | HD64461_STBCR_STM0ST |
@ -50,5 +50,51 @@ int __init platform_setup(void)
v8 &= ~DACR_DAE;
ctrl_outb(v8,DACR);
return 0;
v8 = ctrl_inb(SCPDR);
v8 |= SCPDR_TS_SCAN_X | SCPDR_TS_SCAN_Y;
v8 &= ~SCPDR_TS_SCAN_ENABLE;
ctrl_outb(v8, SCPDR);
v = ctrl_inw(SCPCR);
v &= ~SCPCR_TS_MASK;
v |= SCPCR_TS_ENABLE;
ctrl_outw(v, SCPCR);
}
/*
* XXX: This is stupid, we should have a generic machine vector for the cchips
* and just wrap the platform setup code in to this, as it's the only thing
* that ends up being different.
*/
struct sh_machine_vector mv_hp6xx __initmv = {
.mv_name = "hp6xx",
.mv_setup = hp6xx_setup,
.mv_nr_irqs = HD64461_IRQBASE + HD64461_IRQ_NUM,
.mv_inb = hd64461_inb,
.mv_inw = hd64461_inw,
.mv_inl = hd64461_inl,
.mv_outb = hd64461_outb,
.mv_outw = hd64461_outw,
.mv_outl = hd64461_outl,
.mv_inb_p = hd64461_inb_p,
.mv_inw_p = hd64461_inw,
.mv_inl_p = hd64461_inl,
.mv_outb_p = hd64461_outb_p,
.mv_outw_p = hd64461_outw,
.mv_outl_p = hd64461_outl,
.mv_insb = hd64461_insb,
.mv_insw = hd64461_insw,
.mv_insl = hd64461_insl,
.mv_outsb = hd64461_outsb,
.mv_outsw = hd64461_outsw,
.mv_outsl = hd64461_outsl,
.mv_readw = hd64461_readw,
.mv_writew = hd64461_writew,
.mv_irq_demux = hd64461_irq_demux,
};
ALIAS_MV(hp6xx)

View file

@ -0,0 +1,5 @@
#
# Makefile for I-O DATA DEVICE, INC. "LANDISK Series"
#
obj-y := setup.o io.o irq.o rtc.o landisk_pwb.o

250
arch/sh/boards/landisk/io.c Normal file
View file

@ -0,0 +1,250 @@
/*
* arch/sh/boards/landisk/io.c
*
* Copyright (C) 2001 Ian da Silva, Jeremy Siegel
* Based largely on io_se.c.
*
* I/O routine for I-O Data Device, Inc. LANDISK.
*
* Initial version only to support LAN access; some
* placeholder code from io_landisk.c left in with the
* expectation of later SuperIO and PCMCIA access.
*/
/*
* modifed by kogiidena
* 2005.03.03
*/
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/pci.h>
#include <asm/landisk/iodata_landisk.h>
#include <asm/addrspace.h>
#include <asm/io.h>
extern void *area5_io_base; /* Area 5 I/O Base address */
extern void *area6_io_base; /* Area 6 I/O Base address */
static inline unsigned long port2adr(unsigned int port)
{
if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6)
if (port == 0x3f6)
return ((unsigned long)area5_io_base + 0x2c);
else
return ((unsigned long)area5_io_base + PA_PIDE_OFFSET +
((port - 0x1f0) << 1));
else if ((0x170 <= port && port < 0x178) || port == 0x376)
if (port == 0x376)
return ((unsigned long)area6_io_base + 0x2c);
else
return ((unsigned long)area6_io_base + PA_SIDE_OFFSET +
((port - 0x170) << 1));
else
maybebadio((unsigned long)port);
return port;
}
/*
* General outline: remap really low stuff [eventually] to SuperIO,
* stuff in PCI IO space (at or above window at pci.h:PCIBIOS_MIN_IO)
* is mapped through the PCI IO window. Stuff with high bits (PXSEG)
* should be way beyond the window, and is used w/o translation for
* compatibility.
*/
u8 landisk_inb(unsigned long port)
{
if (PXSEG(port))
return ctrl_inb(port);
else if (is_pci_ioaddr(port))
return ctrl_inb(pci_ioaddr(port));
return ctrl_inw(port2adr(port)) & 0xff;
}
u8 landisk_inb_p(unsigned long port)
{
u8 v;
if (PXSEG(port))
v = ctrl_inb(port);
else if (is_pci_ioaddr(port))
v = ctrl_inb(pci_ioaddr(port));
else
v = ctrl_inw(port2adr(port)) & 0xff;
ctrl_delay();
return v;
}
u16 landisk_inw(unsigned long port)
{
if (PXSEG(port))
return ctrl_inw(port);
else if (is_pci_ioaddr(port))
return ctrl_inw(pci_ioaddr(port));
else
maybebadio(port);
return 0;
}
u32 landisk_inl(unsigned long port)
{
if (PXSEG(port))
return ctrl_inl(port);
else if (is_pci_ioaddr(port))
return ctrl_inl(pci_ioaddr(port));
else
maybebadio(port);
return 0;
}
void landisk_outb(u8 value, unsigned long port)
{
if (PXSEG(port))
ctrl_outb(value, port);
else if (is_pci_ioaddr(port))
ctrl_outb(value, pci_ioaddr(port));
else
ctrl_outw(value, port2adr(port));
}
void landisk_outb_p(u8 value, unsigned long port)
{
if (PXSEG(port))
ctrl_outb(value, port);
else if (is_pci_ioaddr(port))
ctrl_outb(value, pci_ioaddr(port));
else
ctrl_outw(value, port2adr(port));
ctrl_delay();
}
void landisk_outw(u16 value, unsigned long port)
{
if (PXSEG(port))
ctrl_outw(value, port);
else if (is_pci_ioaddr(port))
ctrl_outw(value, pci_ioaddr(port));
else
maybebadio(port);
}
void landisk_outl(u32 value, unsigned long port)
{
if (PXSEG(port))
ctrl_outl(value, port);
else if (is_pci_ioaddr(port))
ctrl_outl(value, pci_ioaddr(port));
else
maybebadio(port);
}
void landisk_insb(unsigned long port, void *dst, unsigned long count)
{
volatile u16 *p;
u8 *buf = dst;
if (PXSEG(port)) {
while (count--)
*buf++ = *(volatile u8 *)port;
} else if (is_pci_ioaddr(port)) {
volatile u8 *bp = (volatile u8 *)pci_ioaddr(port);
while (count--)
*buf++ = *bp;
} else {
p = (volatile u16 *)port2adr(port);
while (count--)
*buf++ = *p & 0xff;
}
}
void landisk_insw(unsigned long port, void *dst, unsigned long count)
{
volatile u16 *p;
u16 *buf = dst;
if (PXSEG(port))
p = (volatile u16 *)port;
else if (is_pci_ioaddr(port))
p = (volatile u16 *)pci_ioaddr(port);
else
p = (volatile u16 *)port2adr(port);
while (count--)
*buf++ = *p;
}
void landisk_insl(unsigned long port, void *dst, unsigned long count)
{
u32 *buf = dst;
if (is_pci_ioaddr(port)) {
volatile u32 *p = (volatile u32 *)pci_ioaddr(port);
while (count--)
*buf++ = *p;
} else
maybebadio(port);
}
void landisk_outsb(unsigned long port, const void *src, unsigned long count)
{
volatile u16 *p;
const u8 *buf = src;
if (PXSEG(port))
while (count--)
ctrl_outb(*buf++, port);
else if (is_pci_ioaddr(port)) {
volatile u8 *bp = (volatile u8 *)pci_ioaddr(port);
while (count--)
*bp = *buf++;
} else {
p = (volatile u16 *)port2adr(port);
while (count--)
*p = *buf++;
}
}
void landisk_outsw(unsigned long port, const void *src, unsigned long count)
{
volatile u16 *p;
const u16 *buf = src;
if (PXSEG(port))
p = (volatile u16 *)port;
else if (is_pci_ioaddr(port))
p = (volatile u16 *)pci_ioaddr(port);
else
p = (volatile u16 *)port2adr(port);
while (count--)
*p = *buf++;
}
void landisk_outsl(unsigned long port, const void *src, unsigned long count)
{
const u32 *buf = src;
if (is_pci_ioaddr(port)) {
volatile u32 *p = (volatile u32 *)pci_ioaddr(port);
while (count--)
*p = *buf++;
} else
maybebadio(port);
}
void __iomem *landisk_ioport_map(unsigned long port, unsigned int size)
{
if (PXSEG(port))
return (void __iomem *)port;
else if (is_pci_ioaddr(port))
return (void __iomem *)pci_ioaddr(port);
return (void __iomem *)port2adr(port);
}

View file

@ -0,0 +1,99 @@
/*
* arch/sh/boards/landisk/irq.c
*
* Copyright (C) 2001 Ian da Silva, Jeremy Siegel
* Based largely on io_se.c.
*
* I/O routine for I-O Data Device, Inc. LANDISK.
*
* Initial version only to support LAN access; some
* placeholder code from io_landisk.c left in with the
* expectation of later SuperIO and PCMCIA access.
*/
/*
* modified by kogiidena
* 2005.03.03
*/
#include <linux/config.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/landisk/iodata_landisk.h>
static void enable_landisk_irq(unsigned int irq);
static void disable_landisk_irq(unsigned int irq);
/* shutdown is same as "disable" */
#define shutdown_landisk_irq disable_landisk_irq
static void ack_landisk_irq(unsigned int irq);
static void end_landisk_irq(unsigned int irq);
static unsigned int startup_landisk_irq(unsigned int irq)
{
enable_landisk_irq(irq);
return 0; /* never anything pending */
}
static void disable_landisk_irq(unsigned int irq)
{
unsigned char val;
unsigned char mask = 0xff ^ (0x01 << (irq - 5));
/* Set the priority in IPR to 0 */
val = ctrl_inb(PA_IMASK);
val &= mask;
ctrl_outb(val, PA_IMASK);
}
static void enable_landisk_irq(unsigned int irq)
{
unsigned char val;
unsigned char value = (0x01 << (irq - 5));
/* Set priority in IPR back to original value */
val = ctrl_inb(PA_IMASK);
val |= value;
ctrl_outb(val, PA_IMASK);
}
static void ack_landisk_irq(unsigned int irq)
{
disable_landisk_irq(irq);
}
static void end_landisk_irq(unsigned int irq)
{
if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
enable_landisk_irq(irq);
}
static struct hw_interrupt_type landisk_irq_type = {
.typename = "LANDISK IRQ",
.startup = startup_landisk_irq,
.shutdown = shutdown_landisk_irq,
.enable = enable_landisk_irq,
.disable = disable_landisk_irq,
.ack = ack_landisk_irq,
.end = end_landisk_irq
};
static void make_landisk_irq(unsigned int irq)
{
disable_irq_nosync(irq);
irq_desc[irq].handler = &landisk_irq_type;
disable_landisk_irq(irq);
}
/*
* Initialize IRQ setting
*/
void __init init_landisk_IRQ(void)
{
int i;
for (i = 5; i < 14; i++)
make_landisk_irq(i);
}

View file

@ -0,0 +1,348 @@
/*
* arch/sh/boards/landisk/landisk_pwb.c -- driver for the Power control switch.
*
* This driver will also support the I-O DATA Device, Inc. LANDISK Board.
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* Copylight (C) 2002 Atom Create Engineering Co., Ltd.
*
* LED control drive function added by kogiidena
*/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/signal.h>
#include <linux/major.h>
#include <linux/poll.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/sched.h>
#include <linux/timer.h>
#include <linux/interrupt.h>
#include <asm/system.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
#include <asm/landisk/iodata_landisk.h>
#define SHUTDOWN_BTN_MINOR 1 /* Shutdown button device minor no. */
#define LED_MINOR 21 /* LED minor no. */
#define BTN_MINOR 22 /* BUTTON minor no. */
#define GIO_MINOR 40 /* GIO minor no. */
static int openCnt;
static int openCntLED;
static int openCntGio;
static int openCntBtn;
static int landisk_btn;
static int landisk_btnctrlpid;
/*
* Functions prototypes
*/
static int gio_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg);
static int swdrv_open(struct inode *inode, struct file *filp)
{
int minor;
minor = MINOR(inode->i_rdev);
filp->private_data = (void *)minor;
if (minor == SHUTDOWN_BTN_MINOR) {
if (openCnt > 0) {
return -EALREADY;
} else {
openCnt++;
return 0;
}
} else if (minor == LED_MINOR) {
if (openCntLED > 0) {
return -EALREADY;
} else {
openCntLED++;
return 0;
}
} else if (minor == BTN_MINOR) {
if (openCntBtn > 0) {
return -EALREADY;
} else {
openCntBtn++;
return 0;
}
} else if (minor == GIO_MINOR) {
if (openCntGio > 0) {
return -EALREADY;
} else {
openCntGio++;
return 0;
}
}
return -ENOENT;
}
static int swdrv_close(struct inode *inode, struct file *filp)
{
int minor;
minor = MINOR(inode->i_rdev);
if (minor == SHUTDOWN_BTN_MINOR) {
openCnt--;
} else if (minor == LED_MINOR) {
openCntLED--;
} else if (minor == BTN_MINOR) {
openCntBtn--;
} else if (minor == GIO_MINOR) {
openCntGio--;
}
return 0;
}
static int swdrv_read(struct file *filp, char *buff, size_t count,
loff_t * ppos)
{
int minor;
minor = (int)(filp->private_data);
if (!access_ok(VERIFY_WRITE, (void *)buff, count))
return -EFAULT;
if (minor == SHUTDOWN_BTN_MINOR) {
if (landisk_btn & 0x10) {
put_user(1, buff);
return 1;
} else {
return 0;
}
}
return 0;
}
static int swdrv_write(struct file *filp, const char *buff, size_t count,
loff_t * ppos)
{
int minor;
minor = (int)(filp->private_data);
if (minor == SHUTDOWN_BTN_MINOR) {
return count;
}
return count;
}
static irqreturn_t sw_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
landisk_btn = (0x0ff & (~ctrl_inb(PA_STATUS)));
disable_irq(IRQ_BUTTON);
disable_irq(IRQ_POWER);
ctrl_outb(0x00, PA_PWRINT_CLR);
if (landisk_btnctrlpid != 0) {
kill_proc(landisk_btnctrlpid, SIGUSR1, 1);
landisk_btnctrlpid = 0;
}
return IRQ_HANDLED;
}
static struct file_operations swdrv_fops = {
.read = swdrv_read, /* read */
.write = swdrv_write, /* write */
.open = swdrv_open, /* open */
.release = swdrv_close, /* release */
.ioctl = gio_ioctl, /* ioctl */
};
static char banner[] __initdata =
KERN_INFO "LANDISK and USL-5P Button, LED and GIO driver initialized\n";
int __init swdrv_init(void)
{
int error;
printk("%s", banner);
openCnt = 0;
openCntLED = 0;
openCntBtn = 0;
openCntGio = 0;
landisk_btn = 0;
landisk_btnctrlpid = 0;
if ((error = register_chrdev(SHUTDOWN_BTN_MAJOR, "swdrv", &swdrv_fops))) {
printk(KERN_ERR
"Button, LED and GIO driver:Couldn't register driver, error=%d\n",
error);
return 1;
}
if (request_irq(IRQ_POWER, sw_interrupt, 0, "SHUTDOWNSWITCH", NULL)) {
printk(KERN_ERR "Unable to get IRQ 11.\n");
return 1;
}
if (request_irq(IRQ_BUTTON, sw_interrupt, 0, "USL-5P BUTTON", NULL)) {
printk(KERN_ERR "Unable to get IRQ 12.\n");
return 1;
}
ctrl_outb(0x00, PA_PWRINT_CLR);
return 0;
}
module_init(swdrv_init);
/*
* gio driver
*
*/
#include <asm/landisk/gio.h>
static int gio_ioctl(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
int minor;
unsigned int data, mask;
static unsigned int addr = 0;
minor = (int)(filp->private_data);
/* access control */
if (minor == GIO_MINOR) {
;
} else if (minor == LED_MINOR) {
if (((cmd & 0x0ff) >= 9) && ((cmd & 0x0ff) < 20)) {
;
} else {
return -EINVAL;
}
} else if (minor == BTN_MINOR) {
if (((cmd & 0x0ff) >= 20) && ((cmd & 0x0ff) < 30)) {
;
} else {
return -EINVAL;
}
} else {
return -EINVAL;
}
if (cmd & 0x01) { /* write */
if (copy_from_user(&data, (int *)arg, sizeof(int))) {
return -EFAULT;
}
}
switch (cmd) {
case GIODRV_IOCSGIOSETADDR: /* addres set */
addr = data;
break;
case GIODRV_IOCSGIODATA1: /* write byte */
ctrl_outb((unsigned char)(0x0ff & data), addr);
break;
case GIODRV_IOCSGIODATA2: /* write word */
if (addr & 0x01) {
return -EFAULT;
}
ctrl_outw((unsigned short int)(0x0ffff & data), addr);
break;
case GIODRV_IOCSGIODATA4: /* write long */
if (addr & 0x03) {
return -EFAULT;
}
ctrl_outl(data, addr);
break;
case GIODRV_IOCGGIODATA1: /* read byte */
data = ctrl_inb(addr);
break;
case GIODRV_IOCGGIODATA2: /* read word */
if (addr & 0x01) {
return -EFAULT;
}
data = ctrl_inw(addr);
break;
case GIODRV_IOCGGIODATA4: /* read long */
if (addr & 0x03) {
return -EFAULT;
}
data = ctrl_inl(addr);
break;
case GIODRV_IOCSGIO_LED: /* write */
mask = ((data & 0x00ffffff) << 8)
| ((data & 0x0000ffff) << 16)
| ((data & 0x000000ff) << 24);
landisk_ledparam = data & (~mask);
if (landisk_arch == 0) { /* arch == landisk */
landisk_ledparam &= 0x03030303;
mask = (~(landisk_ledparam >> 22)) & 0x000c;
landisk_ledparam |= mask;
} else { /* arch == usl-5p */
mask = (landisk_ledparam >> 24) & 0x0001;
landisk_ledparam |= mask;
landisk_ledparam &= 0x007f7f7f;
}
landisk_ledparam |= 0x80;
break;
case GIODRV_IOCGGIO_LED: /* read */
data = landisk_ledparam;
if (landisk_arch == 0) { /* arch == landisk */
data &= 0x03030303;
} else { /* arch == usl-5p */
;
}
data &= (~0x080);
break;
case GIODRV_IOCSGIO_BUZZER: /* write */
landisk_buzzerparam = data;
landisk_ledparam |= 0x80;
break;
case GIODRV_IOCGGIO_LANDISK: /* read */
data = landisk_arch & 0x01;
break;
case GIODRV_IOCGGIO_BTN: /* read */
data = (0x0ff & ctrl_inb(PA_PWRINT_CLR));
data <<= 8;
data |= (0x0ff & ctrl_inb(PA_IMASK));
data <<= 8;
data |= (0x0ff & landisk_btn);
data <<= 8;
data |= (0x0ff & (~ctrl_inb(PA_STATUS)));
break;
case GIODRV_IOCSGIO_BTNPID: /* write */
landisk_btnctrlpid = data;
landisk_btn = 0;
if (irq_desc[IRQ_BUTTON].depth) {
enable_irq(IRQ_BUTTON);
}
if (irq_desc[IRQ_POWER].depth) {
enable_irq(IRQ_POWER);
}
break;
case GIODRV_IOCGGIO_BTNPID: /* read */
data = landisk_btnctrlpid;
break;
default:
return -EFAULT;
break;
}
if ((cmd & 0x01) == 0) { /* read */
if (copy_to_user((int *)arg, &data, sizeof(int))) {
return -EFAULT;
}
}
return 0;
}

View file

@ -0,0 +1,93 @@
/*
* arch/sh/boards/landisk/rtc.c -- RTC support
*
* Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
* Copyright (C) 1999 Tetsuya Okada & Niibe Yutaka
*/
/*
* modifed by kogiidena
* 2005.09.16
*/
#include <linux/config.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/time.h>
#include <linux/delay.h>
#include <linux/spinlock.h>
#include <linux/bcd.h>
#include <asm/rtc.h>
extern spinlock_t rtc_lock;
extern void
rs5c313_set_cmos_time(unsigned int BCD_yr, unsigned int BCD_mon,
unsigned int BCD_day, unsigned int BCD_hr,
unsigned int BCD_min, unsigned int BCD_sec);
extern unsigned long
rs5c313_get_cmos_time(unsigned int *BCD_yr, unsigned int *BCD_mon,
unsigned int *BCD_day, unsigned int *BCD_hr,
unsigned int *BCD_min, unsigned int *BCD_sec);
void landisk_rtc_gettimeofday(struct timespec *tv)
{
unsigned int BCD_yr, BCD_mon, BCD_day, BCD_hr, BCD_min, BCD_sec;
unsigned long flags;
spin_lock_irqsave(&rtc_lock, flags);
tv->tv_sec = rs5c313_get_cmos_time
(&BCD_yr, &BCD_mon, &BCD_day, &BCD_hr, &BCD_min, &BCD_sec);
tv->tv_nsec = 0;
spin_unlock_irqrestore(&rtc_lock, flags);
}
int landisk_rtc_settimeofday(const time_t secs)
{
int retval = 0;
int real_seconds, real_minutes, cmos_minutes;
unsigned long flags;
unsigned long nowtime = secs;
unsigned int BCD_yr, BCD_mon, BCD_day, BCD_hr, BCD_min, BCD_sec;
spin_lock_irqsave(&rtc_lock, flags);
rs5c313_get_cmos_time
(&BCD_yr, &BCD_mon, &BCD_day, &BCD_hr, &BCD_min, &BCD_sec);
cmos_minutes = BCD_min;
BCD_TO_BIN(cmos_minutes);
/*
* since we're only adjusting minutes and seconds,
* don't interfere with hour overflow. This avoids
* messing with unknown time zones but requires your
* RTC not to be off by more than 15 minutes
*/
real_seconds = nowtime % 60;
real_minutes = nowtime / 60;
if (((abs(real_minutes - cmos_minutes) + 15) / 30) & 1)
real_minutes += 30; /* correct for half hour time zone */
real_minutes %= 60;
if (abs(real_minutes - cmos_minutes) < 30) {
BIN_TO_BCD(real_seconds);
BIN_TO_BCD(real_minutes);
rs5c313_set_cmos_time(BCD_yr, BCD_mon, BCD_day, BCD_hr,
real_minutes, real_seconds);
} else {
printk(KERN_WARNING
"set_rtc_time: can't update from %d to %d\n",
cmos_minutes, real_minutes);
retval = -1;
}
spin_unlock_irqrestore(&rtc_lock, flags);
return retval;
}
void landisk_time_init(void)
{
rtc_sh_get_time = landisk_rtc_gettimeofday;
rtc_sh_set_time = landisk_rtc_settimeofday;
}

View file

@ -0,0 +1,177 @@
/*
* arch/sh/boards/landisk/setup.c
*
* Copyright (C) 2000 Kazumoto Kojima
* Copyright (C) 2002 Paul Mundt
*
* I-O DATA Device, Inc. LANDISK Support.
*
* Modified for LANDISK by
* Atom Create Engineering Co., Ltd. 2002.
*
* modifed by kogiidena
* 2005.09.16
*
* 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/config.h>
#include <linux/init.h>
#include <linux/pm.h>
#include <linux/mm.h>
#include <asm/machvec.h>
#include <asm/rtc.h>
#include <asm/landisk/iodata_landisk.h>
#include <asm/io.h>
void landisk_time_init(void);
void init_landisk_IRQ(void);
int landisk_ledparam;
int landisk_buzzerparam;
int landisk_arch;
/* cycle the led's in the clasic knightrider/sun pattern */
static void heartbeat_landisk(void)
{
static unsigned int cnt = 0, blink = 0x00, period = 25;
volatile u8 *p = (volatile u8 *)PA_LED;
char data;
if ((landisk_ledparam & 0x080) == 0)
return;
cnt += 1;
if (cnt < period)
return;
cnt = 0;
blink++;
data = (blink & 0x01) ? (landisk_ledparam >> 16) : 0;
data |= (blink & 0x02) ? (landisk_ledparam >> 8) : 0;
data |= landisk_ledparam;
/* buzzer */
if (landisk_buzzerparam & 0x1) {
data |= 0x80;
} else {
data &= 0x7f;
}
*p = data;
if (((landisk_ledparam & 0x007f7f00) == 0) &&
(landisk_buzzerparam == 0))
landisk_ledparam &= (~0x0080);
landisk_buzzerparam >>= 1;
}
static void landisk_power_off(void)
{
ctrl_outb(0x01, PA_SHUTDOWN);
}
static void check_usl5p(void)
{
volatile u8 *p = (volatile u8 *)PA_LED;
u8 tmp1, tmp2;
tmp1 = *p;
*p = 0x40;
tmp2 = *p;
*p = tmp1;
landisk_arch = (tmp2 == 0x40);
if (landisk_arch == 1) {
/* arch == usl-5p */
landisk_ledparam = 0x00000380;
landisk_ledparam |= (tmp1 & 0x07c);
} else {
/* arch == landisk */
landisk_ledparam = 0x02000180;
landisk_ledparam |= 0x04;
}
}
void *area5_io_base;
void *area6_io_base;
static int __init landisk_cf_init(void)
{
pgprot_t prot;
unsigned long paddrbase, psize;
/* open I/O area window */
paddrbase = virt_to_phys((void *)PA_AREA5_IO);
psize = PAGE_SIZE;
prot = PAGE_KERNEL_PCC(1, _PAGE_PCC_IO16);
area5_io_base = p3_ioremap(paddrbase, psize, prot.pgprot);
if (!area5_io_base) {
printk("allocate_cf_area : can't open CF I/O window!\n");
return -ENOMEM;
}
paddrbase = virt_to_phys((void *)PA_AREA6_IO);
psize = PAGE_SIZE;
prot = PAGE_KERNEL_PCC(0, _PAGE_PCC_IO16);
area6_io_base = p3_ioremap(paddrbase, psize, prot.pgprot);
if (!area6_io_base) {
printk("allocate_cf_area : can't open HDD I/O window!\n");
return -ENOMEM;
}
printk(KERN_INFO "Allocate Area5/6 success.\n");
/* XXX : do we need attribute and common-memory area also? */
return 0;
}
static void __init landisk_setup(char **cmdline_p)
{
device_initcall(landisk_cf_init);
landisk_buzzerparam = 0;
check_usl5p();
printk(KERN_INFO "I-O DATA DEVICE, INC. \"LANDISK Series\" support.\n");
board_time_init = landisk_time_init;
pm_power_off = landisk_power_off;
}
/*
* The Machine Vector
*/
struct sh_machine_vector mv_landisk __initmv = {
.mv_name = "LANDISK",
.mv_setup = landisk_setup,
.mv_nr_irqs = 72,
.mv_inb = landisk_inb,
.mv_inw = landisk_inw,
.mv_inl = landisk_inl,
.mv_outb = landisk_outb,
.mv_outw = landisk_outw,
.mv_outl = landisk_outl,
.mv_inb_p = landisk_inb_p,
.mv_inw_p = landisk_inw,
.mv_inl_p = landisk_inl,
.mv_outb_p = landisk_outb_p,
.mv_outw_p = landisk_outw,
.mv_outl_p = landisk_outl,
.mv_insb = landisk_insb,
.mv_insw = landisk_insw,
.mv_insl = landisk_insl,
.mv_outsb = landisk_outsb,
.mv_outsw = landisk_outsw,
.mv_outsl = landisk_outsl,
.mv_ioport_map = landisk_ioport_map,
.mv_init_irq = init_landisk_IRQ,
#ifdef CONFIG_HEARTBEAT
.mv_heartbeat = heartbeat_landisk,
#endif
};
ALIAS_MV(landisk)

View file

@ -130,7 +130,7 @@ int mpc1211_rtc_settimeofday(const struct timeval *tv)
void mpc1211_time_init(void)
{
rtc_get_time = mpc1211_rtc_gettimeofday;
rtc_set_time = mpc1211_rtc_settimeofday;
rtc_sh_get_time = mpc1211_rtc_gettimeofday;
rtc_sh_set_time = mpc1211_rtc_settimeofday;
}

View file

@ -10,14 +10,12 @@
#include <linux/hdreg.h>
#include <linux/ide.h>
#include <linux/interrupt.h>
#include <asm/io.h>
#include <asm/machvec.h>
#include <asm/mpc1211/mpc1211.h>
#include <asm/mpc1211/pci.h>
#include <asm/mpc1211/m1543c.h>
/* ALI15X3 SMBus address offsets */
#define SMBHSTSTS (0 + 0x3100)
#define SMBHSTCNT (1 + 0x3100)
@ -50,11 +48,6 @@
#define ALI15X3_STS_TERM 0x80 /* terminated by abort */
#define ALI15X3_STS_ERR 0xE0 /* all the bad error bits */
const char *get_system_type(void)
{
return "Interface MPC-1211(CTP/PCI/MPC-SH02)";
}
static void __init pci_write_config(unsigned long busNo,
unsigned long devNo,
unsigned long fncNo,
@ -80,9 +73,6 @@ volatile unsigned long irq_err_count;
static void disable_mpc1211_irq(unsigned int irq)
{
unsigned long flags;
save_and_cli(flags);
if( irq < 8) {
m_irq_mask |= (1 << irq);
outb(m_irq_mask,I8259_M_MR);
@ -90,16 +80,11 @@ static void disable_mpc1211_irq(unsigned int irq)
s_irq_mask |= (1 << (irq - 8));
outb(s_irq_mask,I8259_S_MR);
}
restore_flags(flags);
}
static void enable_mpc1211_irq(unsigned int irq)
{
unsigned long flags;
save_and_cli(flags);
if( irq < 8) {
m_irq_mask &= ~(1 << irq);
outb(m_irq_mask,I8259_M_MR);
@ -107,7 +92,6 @@ static void enable_mpc1211_irq(unsigned int irq)
s_irq_mask &= ~(1 << (irq - 8));
outb(s_irq_mask,I8259_S_MR);
}
restore_flags(flags);
}
static inline int mpc1211_irq_real(unsigned int irq)
@ -131,10 +115,6 @@ static inline int mpc1211_irq_real(unsigned int irq)
static void mask_and_ack_mpc1211(unsigned int irq)
{
unsigned long flags;
save_and_cli(flags);
if(irq < 8) {
if(m_irq_mask & (1<<irq)){
if(!mpc1211_irq_real(irq)){
@ -162,7 +142,6 @@ static void mask_and_ack_mpc1211(unsigned int irq)
outb(0x60+(irq-8),I8259_S_CR); /* EOI */
outb(0x60+2,I8259_M_CR);
}
restore_flags(flags);
}
static void end_mpc1211_irq(unsigned int irq)
@ -219,7 +198,7 @@ int mpc1211_irq_demux(int irq)
return irq;
}
void __init init_mpc1211_IRQ(void)
static void __init init_mpc1211_IRQ(void)
{
int i;
/*
@ -255,23 +234,12 @@ void __init init_mpc1211_IRQ(void)
}
}
/*
Initialize the board
*/
static void delay (void)
{
volatile unsigned short tmp;
tmp = *(volatile unsigned short *) 0xa0000000;
}
static void delay1000 (void)
static void delay1000(void)
{
int i;
for (i=0; i<1000; i++)
delay ();
ctrl_delay();
}
static int put_smb_blk(unsigned char *p, int address, int command, int no)
@ -314,26 +282,10 @@ static int put_smb_blk(unsigned char *p, int address, int command, int no)
return 0;
}
/*
* The Machine Vector
*/
struct sh_machine_vector mv_mpc1211 __initmv = {
.mv_nr_irqs = 48,
.mv_irq_demux = mpc1211_irq_demux,
.mv_init_irq = init_mpc1211_IRQ,
#ifdef CONFIG_HEARTBEAT
.mv_heartbeat = heartbeat_mpc1211,
#endif
};
ALIAS_MV(mpc1211)
/* arch/sh/boards/mpc1211/rtc.c */
void mpc1211_time_init(void);
int __init platform_setup(void)
static void __init mpc1211_setup(char **cmdline_p)
{
unsigned char spd_buf[128];
@ -357,3 +309,18 @@ int __init platform_setup(void)
return 0;
}
/*
* The Machine Vector
*/
struct sh_machine_vector mv_mpc1211 __initmv = {
.mv_name = "Interface MPC-1211(CTP/PCI/MPC-SH02)",
.mv_setup = mpc1211_setup,
.mv_nr_irqs = 48,
.mv_irq_demux = mpc1211_irq_demux,
.mv_init_irq = init_mpc1211_IRQ,
#ifdef CONFIG_HEARTBEAT
.mv_heartbeat = heartbeat_mpc1211,
#endif
};
ALIAS_MV(mpc1211)

View file

@ -1,8 +0,0 @@
#
# Makefile for the STMicroelectronics Overdrive specific parts of the kernel
#
obj-y := mach.o setup.o io.o irq.o led.o
obj-$(CONFIG_PCI) += fpga.o galileo.o pcidma.o

View file

@ -1,133 +0,0 @@
/*
* Copyright (C) 2000 David J. Mckay (david.mckay@st.com)
*
* May be copied or modified under the terms of the GNU General Public
* License. See linux/COPYING for more information.
*
* This file handles programming up the Altera Flex10K that interfaces to
* the Galileo, and does the PS/2 keyboard and mouse
*
*/
#include <linux/kernel.h>
#include <linux/smp.h>
#include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/pci.h>
#include <linux/delay.h>
#include <asm/overdriver/gt64111.h>
#include <asm/overdrive/overdrive.h>
#include <asm/overdrive/fpga.h>
#define FPGA_NotConfigHigh() (*FPGA_ControlReg) = (*FPGA_ControlReg) | ENABLE_FPGA_BIT
#define FPGA_NotConfigLow() (*FPGA_ControlReg) = (*FPGA_ControlReg) & RESET_FPGA_MASK
/* I need to find out what (if any) the real delay factor here is */
/* The delay is definately not critical */
#define long_delay() {int i;for(i=0;i<10000;i++);}
#define short_delay() {int i;for(i=0;i<100;i++);}
static void __init program_overdrive_fpga(const unsigned char *fpgacode,
int size)
{
int timeout = 0;
int i, j;
unsigned char b;
static volatile unsigned char *FPGA_ControlReg =
(volatile unsigned char *) (OVERDRIVE_CTRL);
static volatile unsigned char *FPGA_ProgramReg =
(volatile unsigned char *) (FPGA_DCLK_ADDRESS);
printk("FPGA: Commencing FPGA Programming\n");
/* The PCI reset but MUST be low when programming the FPGA !!! */
b = (*FPGA_ControlReg) & RESET_PCI_MASK;
(*FPGA_ControlReg) = b;
/* Prepare FPGA to program */
FPGA_NotConfigHigh();
long_delay();
FPGA_NotConfigLow();
short_delay();
while ((*FPGA_ProgramReg & FPGA_NOT_STATUS) != 0) {
printk("FPGA: Waiting for NotStatus to go Low ... \n");
}
FPGA_NotConfigHigh();
/* Wait for FPGA "ready to be programmed" signal */
printk("FPGA: Waiting for NotStatus to go high (FPGA ready)... \n");
for (timeout = 0;
(((*FPGA_ProgramReg & FPGA_NOT_STATUS) == 0)
&& (timeout < FPGA_TIMEOUT)); timeout++);
/* Check if timeout condition occured - i.e. an error */
if (timeout == FPGA_TIMEOUT) {
printk
("FPGA: Failed to program - Timeout waiting for notSTATUS to go high\n");
return;
}
printk("FPGA: Copying data to FPGA ... %d bytes\n", size);
/* Copy array to FPGA - bit at a time */
for (i = 0; i < size; i++) {
volatile unsigned w = 0;
for (j = 0; j < 8; j++) {
*FPGA_ProgramReg = (fpgacode[i] >> j) & 0x01;
short_delay();
}
if ((i & 0x3ff) == 0) {
printk(".");
}
}
/* Waiting for CONFDONE to go high - means the program is complete */
for (timeout = 0;
(((*FPGA_ProgramReg & FPGA_CONFDONE) == 0)
&& (timeout < FPGA_TIMEOUT)); timeout++) {
*FPGA_ProgramReg = 0x0;
long_delay();
}
if (timeout == FPGA_TIMEOUT) {
printk
("FPGA: Failed to program - Timeout waiting for CONFDONE to go high\n");
return;
} else { /* Clock another 10 times - gets the device into a working state */
for (i = 0; i < 10; i++) {
*FPGA_ProgramReg = 0x0;
short_delay();
}
}
printk("FPGA: Programming complete\n");
}
static const unsigned char __init fpgacode[] = {
#include "./overdrive.ttf" /* Code from maxplus2 compiler */
, 0, 0
};
int __init init_overdrive_fpga(void)
{
program_overdrive_fpga(fpgacode, sizeof(fpgacode));
return 0;
}

View file

@ -1,587 +0,0 @@
/*
* Copyright (C) 2000 David J. Mckay (david.mckay@st.com)
*
* May be copied or modified under the terms of the GNU General Public
* License. See linux/COPYING for more information.
*
* This file contains the PCI routines required for the Galileo GT6411
* PCI bridge as used on the Orion and Overdrive boards.
*
*/
#include <linux/kernel.h>
#include <linux/smp.h>
#include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/types.h>
#include <linux/ioport.h>
#include <asm/overdrive/overdrive.h>
#include <asm/overdrive/gt64111.h>
/* After boot, we shift the Galileo registers so that they appear
* in BANK6, along with IO space. This means we can have one contingous
* lump of PCI address space without these registers appearing in the
* middle of them
*/
#define GT64111_BASE_ADDRESS 0xbb000000
#define GT64111_IO_BASE_ADDRESS 0x1000
/* The GT64111 registers appear at this address to the SH4 after reset */
#define RESET_GT64111_BASE_ADDRESS 0xb4000000
/* Macros used to access the Galileo registers */
#define RESET_GT64111_REG(x) (RESET_GT64111_BASE_ADDRESS+x)
#define GT64111_REG(x) (GT64111_BASE_ADDRESS+x)
#define RESET_GT_WRITE(x,v) writel((v),RESET_GT64111_REG(x))
#define RESET_GT_READ(x) readl(RESET_GT64111_REG(x))
#define GT_WRITE(x,v) writel((v),GT64111_REG(x))
#define GT_WRITE_BYTE(x,v) writeb((v),GT64111_REG(x))
#define GT_WRITE_SHORT(x,v) writew((v),GT64111_REG(x))
#define GT_READ(x) readl(GT64111_REG(x))
#define GT_READ_BYTE(x) readb(GT64111_REG(x))
#define GT_READ_SHORT(x) readw(GT64111_REG(x))
/* Where the various SH banks start at */
#define SH_BANK4_ADR 0xb0000000
#define SH_BANK5_ADR 0xb4000000
#define SH_BANK6_ADR 0xb8000000
/* Masks out everything but lines 28,27,26 */
#define BANK_SELECT_MASK 0x1c000000
#define SH4_TO_BANK(x) ( (x) & BANK_SELECT_MASK)
/*
* Masks used for address conversaion. Bank 6 is used for IO and
* has all the address bits zeroed by the FPGA. Special case this
*/
#define MEMORY_BANK_MASK 0x1fffffff
#define IO_BANK_MASK 0x03ffffff
/* Mark bank 6 as the bank used for IO. You can change this in the FPGA code
* if you want
*/
#define IO_BANK_ADR PCI_GTIO_BASE
/* Will select the correct mask to apply depending on the SH$ address */
#define SELECT_BANK_MASK(x) \
( (SH4_TO_BANK(x)==SH4_TO_BANK(IO_BANK_ADR)) ? IO_BANK_MASK : MEMORY_BANK_MASK)
/* Converts between PCI space and P2 region */
#define SH4_TO_PCI(x) ((x)&SELECT_BANK_MASK(x))
/* Various macros for figuring out what to stick in the Galileo registers.
* You *really* don't want to figure this stuff out by hand, you always get
* it wrong
*/
#define GT_MEM_LO_ADR(x) ((((unsigned)((x)&SELECT_BANK_MASK(x)))>>21)&0x7ff)
#define GT_MEM_HI_ADR(x) ((((unsigned)((x)&SELECT_BANK_MASK(x)))>>21)&0x7f)
#define GT_MEM_SUB_ADR(x) ((((unsigned)((x)&SELECT_BANK_MASK(x)))>>20)&0xff)
#define PROGRAM_HI_LO(block,a,s) \
GT_WRITE(block##_LO_DEC_ADR,GT_MEM_LO_ADR(a));\
GT_WRITE(block##_HI_DEC_ADR,GT_MEM_HI_ADR(a+s-1))
#define PROGRAM_SUB_HI_LO(block,a,s) \
GT_WRITE(block##_LO_DEC_ADR,GT_MEM_SUB_ADR(a));\
GT_WRITE(block##_HI_DEC_ADR,GT_MEM_SUB_ADR(a+s-1))
/* We need to set the size, and the offset register */
#define GT_BAR_MASK(x) ((x)&~0xfff)
/* Macro to set up the BAR in the Galileo. Essentially used for the DRAM */
#define PROGRAM_GT_BAR(block,a,s) \
GT_WRITE(PCI_##block##_BANK_SIZE,GT_BAR_MASK((s-1)));\
write_config_to_galileo(PCI_CONFIG_##block##_BASE_ADR,\
GT_BAR_MASK(a))
#define DISABLE_GT_BAR(block) \
GT_WRITE(PCI_##block##_BANK_SIZE,0),\
GT_CONFIG_WRITE(PCI_CONFIG_##block##_BASE_ADR,\
0x80000000)
/* Macros to disable things we are not going to use */
#define DISABLE_DECODE(x) GT_WRITE(x##_LO_DEC_ADR,0x7ff);\
GT_WRITE(x##_HI_DEC_ADR,0x00)
#define DISABLE_SUB_DECODE(x) GT_WRITE(x##_LO_DEC_ADR,0xff);\
GT_WRITE(x##_HI_DEC_ADR,0x00)
static void __init reset_pci(void)
{
/* Set RESET_PCI bit high */
writeb(readb(OVERDRIVE_CTRL) | ENABLE_PCI_BIT, OVERDRIVE_CTRL);
udelay(250);
/* Set RESET_PCI bit low */
writeb(readb(OVERDRIVE_CTRL) & RESET_PCI_MASK, OVERDRIVE_CTRL);
udelay(250);
writeb(readb(OVERDRIVE_CTRL) | ENABLE_PCI_BIT, OVERDRIVE_CTRL);
udelay(250);
}
static int write_config_to_galileo(int where, u32 val);
#define GT_CONFIG_WRITE(where,val) write_config_to_galileo(where,val)
#define ENABLE_PCI_DRAM
#ifdef TEST_DRAM
/* Test function to check out if the PCI DRAM is working OK */
static int /* __init */ test_dram(unsigned *base, unsigned size)
{
unsigned *p = base;
unsigned *end = (unsigned *) (((unsigned) base) + size);
unsigned w;
for (p = base; p < end; p++) {
*p = 0xffffffff;
if (*p != 0xffffffff) {
printk("AAARGH -write failed!!! at %p is %x\n", p,
*p);
return 0;
}
*p = 0x0;
if (*p != 0x0) {
printk("AAARGH -write failed!!!\n");
return 0;
}
}
for (p = base; p < end; p++) {
*p = (unsigned) p;
if (*p != (unsigned) p) {
printk("Failed at 0x%p, actually is 0x%x\n", p,
*p);
return 0;
}
}
for (p = base; p < end; p++) {
w = ((unsigned) p & 0xffff0000);
*p = w | (w >> 16);
}
for (p = base; p < end; p++) {
w = ((unsigned) p & 0xffff0000);
w |= (w >> 16);
if (*p != w) {
printk
("Failed at 0x%p, should be 0x%x actually is 0x%x\n",
p, w, *p);
return 0;
}
}
return 1;
}
#endif
/* Function to set up and initialise the galileo. This sets up the BARS,
* maps the DRAM into the address space etc,etc
*/
int __init galileo_init(void)
{
reset_pci();
/* Now shift the galileo regs into this block */
RESET_GT_WRITE(INTERNAL_SPACE_DEC,
GT_MEM_LO_ADR(GT64111_BASE_ADDRESS));
/* Should have a sanity check here, that you can read back at the new
* address what you just wrote
*/
/* Disable decode for all regions */
DISABLE_DECODE(RAS10);
DISABLE_DECODE(RAS32);
DISABLE_DECODE(CS20);
DISABLE_DECODE(CS3);
DISABLE_DECODE(PCI_IO);
DISABLE_DECODE(PCI_MEM0);
DISABLE_DECODE(PCI_MEM1);
/* Disable all BARS */
GT_WRITE(BAR_ENABLE_ADR, 0x1ff);
DISABLE_GT_BAR(RAS10);
DISABLE_GT_BAR(RAS32);
DISABLE_GT_BAR(CS20);
DISABLE_GT_BAR(CS3);
/* Tell the BAR where the IO registers now are */
GT_CONFIG_WRITE(PCI_CONFIG_INT_REG_IO_ADR,GT_BAR_MASK(
(GT64111_IO_BASE_ADDRESS &
IO_BANK_MASK)));
/* set up a 112 Mb decode */
PROGRAM_HI_LO(PCI_MEM0, SH_BANK4_ADR, 112 * 1024 * 1024);
/* Set up a 32 MB io space decode */
PROGRAM_HI_LO(PCI_IO, IO_BANK_ADR, 32 * 1024 * 1024);
#ifdef ENABLE_PCI_DRAM
/* Program up the DRAM configuration - there is DRAM only in bank 0 */
/* Now set up the DRAM decode */
PROGRAM_HI_LO(RAS10, PCI_DRAM_BASE, PCI_DRAM_SIZE);
/* And the sub decode */
PROGRAM_SUB_HI_LO(RAS0, PCI_DRAM_BASE, PCI_DRAM_SIZE);
DISABLE_SUB_DECODE(RAS1);
/* Set refresh rate */
GT_WRITE(DRAM_BANK0_PARMS, 0x3f);
GT_WRITE(DRAM_CFG, 0x100);
/* we have to lob off the top bits rememeber!! */
PROGRAM_GT_BAR(RAS10, SH4_TO_PCI(PCI_DRAM_BASE), PCI_DRAM_SIZE);
#endif
/* We are only interested in decoding RAS10 and the Galileo's internal
* registers (as IO) on the PCI bus
*/
#ifdef ENABLE_PCI_DRAM
GT_WRITE(BAR_ENABLE_ADR, (~((1 << 8) | (1 << 3))) & 0x1ff);
#else
GT_WRITE(BAR_ENABLE_ADR, (~(1 << 3)) & 0x1ff);
#endif
/* Change the class code to host bridge, it actually powers up
* as a memory controller
*/
GT_CONFIG_WRITE(8, 0x06000011);
/* Allow the galileo to master the PCI bus */
GT_CONFIG_WRITE(PCI_COMMAND,
PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
PCI_COMMAND_IO);
#if 0
printk("Testing PCI DRAM - ");
if(test_dram(PCI_DRAM_BASE,PCI_DRAM_SIZE)) {
printk("Passed\n");
}else {
printk("FAILED\n");
}
#endif
return 0;
}
#define SET_CONFIG_BITS(bus,devfn,where)\
((1<<31) | ((bus) << 16) | ((devfn) << 8) | ((where) & ~3))
#define CONFIG_CMD(dev, where) SET_CONFIG_BITS((dev)->bus->number,(dev)->devfn,where)
/* This write to the galileo config registers, unlike the functions below, can
* be used before the PCI subsystem has started up
*/
static int __init write_config_to_galileo(int where, u32 val)
{
GT_WRITE(PCI_CFG_ADR, SET_CONFIG_BITS(0, 0, where));
GT_WRITE(PCI_CFG_DATA, val);
return 0;
}
/* We exclude the galileo and slot 31, the galileo because I don't know how to stop
* the setup code shagging up the setup I have done on it, and 31 because the whole
* thing locks up if you try to access that slot (which doesn't exist of course anyway
*/
#define EXCLUDED_DEV(dev) ((dev->bus->number==0) && ((PCI_SLOT(dev->devfn)==0) || (PCI_SLOT(dev->devfn) == 31)))
static int galileo_read_config_byte(struct pci_dev *dev, int where,
u8 * val)
{
/* I suspect this doesn't work because this drives a special cycle ? */
if (EXCLUDED_DEV(dev)) {
*val = 0xff;
return PCIBIOS_SUCCESSFUL;
}
/* Start the config cycle */
GT_WRITE(PCI_CFG_ADR, CONFIG_CMD(dev, where));
/* Read back the result */
*val = GT_READ_BYTE(PCI_CFG_DATA + (where & 3));
return PCIBIOS_SUCCESSFUL;
}
static int galileo_read_config_word(struct pci_dev *dev, int where,
u16 * val)
{
if (EXCLUDED_DEV(dev)) {
*val = 0xffff;
return PCIBIOS_SUCCESSFUL;
}
GT_WRITE(PCI_CFG_ADR, CONFIG_CMD(dev, where));
*val = GT_READ_SHORT(PCI_CFG_DATA + (where & 2));
return PCIBIOS_SUCCESSFUL;
}
static int galileo_read_config_dword(struct pci_dev *dev, int where,
u32 * val)
{
if (EXCLUDED_DEV(dev)) {
*val = 0xffffffff;
return PCIBIOS_SUCCESSFUL;
}
GT_WRITE(PCI_CFG_ADR, CONFIG_CMD(dev, where));
*val = GT_READ(PCI_CFG_DATA);
return PCIBIOS_SUCCESSFUL;
}
static int galileo_write_config_byte(struct pci_dev *dev, int where,
u8 val)
{
GT_WRITE(PCI_CFG_ADR, CONFIG_CMD(dev, where));
GT_WRITE_BYTE(PCI_CFG_DATA + (where & 3), val);
return PCIBIOS_SUCCESSFUL;
}
static int galileo_write_config_word(struct pci_dev *dev, int where,
u16 val)
{
GT_WRITE(PCI_CFG_ADR, CONFIG_CMD(dev, where));
GT_WRITE_SHORT(PCI_CFG_DATA + (where & 2), val);
return PCIBIOS_SUCCESSFUL;
}
static int galileo_write_config_dword(struct pci_dev *dev, int where,
u32 val)
{
GT_WRITE(PCI_CFG_ADR, CONFIG_CMD(dev, where));
GT_WRITE(PCI_CFG_DATA, val);
return PCIBIOS_SUCCESSFUL;
}
static struct pci_ops pci_config_ops = {
galileo_read_config_byte,
galileo_read_config_word,
galileo_read_config_dword,
galileo_write_config_byte,
galileo_write_config_word,
galileo_write_config_dword
};
/* Everything hangs off this */
static struct pci_bus *pci_root_bus;
static u8 __init no_swizzle(struct pci_dev *dev, u8 * pin)
{
return PCI_SLOT(dev->devfn);
}
static int __init map_od_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
/* Slot 1: Galileo
* Slot 2: PCI Slot 1
* Slot 3: PCI Slot 2
* Slot 4: ESS
*/
switch (slot) {
case 2:
return OVERDRIVE_PCI_IRQ1;
case 3:
/* Note this assumes you have a hacked card in slot 2 */
return OVERDRIVE_PCI_IRQ2;
case 4:
return OVERDRIVE_ESS_IRQ;
default:
/* printk("PCI: Unexpected IRQ mapping request for slot %d\n", slot); */
return -1;
}
}
void __init
pcibios_fixup_pbus_ranges(struct pci_bus *bus, struct pbus_set_ranges_data *ranges)
{
ranges->io_start -= bus->resource[0]->start;
ranges->io_end -= bus->resource[0]->start;
ranges->mem_start -= bus->resource[1]->start;
ranges->mem_end -= bus->resource[1]->start;
}
static void __init pci_fixup_ide_bases(struct pci_dev *d)
{
int i;
/*
* PCI IDE controllers use non-standard I/O port decoding, respect it.
*/
if ((d->class >> 8) != PCI_CLASS_STORAGE_IDE)
return;
printk("PCI: IDE base address fixup for %s\n", pci_name(d));
for(i=0; i<4; i++) {
struct resource *r = &d->resource[i];
if ((r->start & ~0x80) == 0x374) {
r->start |= 2;
r->end = r->start;
}
}
}
DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases);
void __init pcibios_init(void)
{
static struct resource galio,galmem;
/* Allocate the registers used by the Galileo */
galio.flags = IORESOURCE_IO;
galio.name = "Galileo GT64011";
galmem.flags = IORESOURCE_MEM|IORESOURCE_PREFETCH;
galmem.name = "Galileo GT64011 DRAM";
allocate_resource(&ioport_resource, &galio, 256,
GT64111_IO_BASE_ADDRESS,GT64111_IO_BASE_ADDRESS+256, 256, NULL, NULL);
allocate_resource(&iomem_resource, &galmem,PCI_DRAM_SIZE,
PHYSADDR(PCI_DRAM_BASE), PHYSADDR(PCI_DRAM_BASE)+PCI_DRAM_SIZE,
PCI_DRAM_SIZE, NULL, NULL);
/* ok, do the scan man */
pci_root_bus = pci_scan_bus(0, &pci_config_ops, NULL);
pci_assign_unassigned_resources();
pci_fixup_irqs(no_swizzle, map_od_irq);
#ifdef TEST_DRAM
printk("Testing PCI DRAM - ");
if(test_dram(PCI_DRAM_BASE,PCI_DRAM_SIZE)) {
printk("Passed\n");
}else {
printk("FAILED\n");
}
#endif
}
char * __init pcibios_setup(char *str)
{
return str;
}
int pcibios_enable_device(struct pci_dev *dev)
{
u16 cmd, old_cmd;
int idx;
struct resource *r;
pci_read_config_word(dev, PCI_COMMAND, &cmd);
old_cmd = cmd;
for (idx = 0; idx < 6; idx++) {
r = dev->resource + idx;
if (!r->start && r->end) {
printk(KERN_ERR
"PCI: Device %s not available because"
" of resource collisions\n",
pci_name(dev));
return -EINVAL;
}
if (r->flags & IORESOURCE_IO)
cmd |= PCI_COMMAND_IO;
if (r->flags & IORESOURCE_MEM)
cmd |= PCI_COMMAND_MEMORY;
}
if (cmd != old_cmd) {
printk("PCI: enabling device %s (%04x -> %04x)\n",
pci_name(dev), old_cmd, cmd);
pci_write_config_word(dev, PCI_COMMAND, cmd);
}
return 0;
}
/* We should do some optimisation work here I think. Ok for now though */
void __init pcibios_fixup_bus(struct pci_bus *bus)
{
}
void pcibios_align_resource(void *data, struct resource *res,
resource_size_t size)
{
}
void __init pcibios_update_resource(struct pci_dev *dev, struct resource *root,
struct resource *res, int resource)
{
unsigned long where, size;
u32 reg;
printk("PCI: Assigning %3s %08lx to %s\n",
res->flags & IORESOURCE_IO ? "IO" : "MEM",
res->start, dev->name);
where = PCI_BASE_ADDRESS_0 + resource * 4;
size = res->end - res->start;
pci_read_config_dword(dev, where, &reg);
reg = (reg & size) | (((u32) (res->start - root->start)) & ~size);
pci_write_config_dword(dev, where, reg);
}
void __init pcibios_update_irq(struct pci_dev *dev, int irq)
{
printk("PCI: Assigning IRQ %02d to %s\n", irq, dev->name);
pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
}
/*
* If we set up a device for bus mastering, we need to check the latency
* timer as certain crappy BIOSes forget to set it properly.
*/
unsigned int pcibios_max_latency = 255;
void pcibios_set_master(struct pci_dev *dev)
{
u8 lat;
pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
if (lat < 16)
lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency;
else if (lat > pcibios_max_latency)
lat = pcibios_max_latency;
else
return;
printk("PCI: Setting latency timer of device %s to %d\n", pci_name(dev), lat);
pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
}

View file

@ -1,172 +0,0 @@
/*
* Copyright (C) 2000 David J. Mckay (david.mckay@st.com)
*
* May be copied or modified under the terms of the GNU General Public
* License. See linux/COPYING for more information.
*
* This file contains the I/O routines for use on the overdrive board
*
*/
#include <linux/types.h>
#include <linux/delay.h>
#include <asm/processor.h>
#include <asm/io.h>
#include <asm/addrspace.h>
#include <asm/overdrive/overdrive.h>
/*
* readX/writeX() are used to access memory mapped devices. On some
* architectures the memory mapped IO stuff needs to be accessed
* differently. On the SuperH architecture, we just read/write the
* memory location directly.
*/
#define dprintk(x...)
/* Translates an IO address to where it is mapped in memory */
#define io_addr(x) (((unsigned)(x))|PCI_GTIO_BASE)
unsigned char od_inb(unsigned long port)
{
dprintk("od_inb(%x)\n", port);
return readb(io_addr(port)) & 0xff;
}
unsigned short od_inw(unsigned long port)
{
dprintk("od_inw(%x)\n", port);
return readw(io_addr(port)) & 0xffff;
}
unsigned int od_inl(unsigned long port)
{
dprintk("od_inl(%x)\n", port);
return readl(io_addr(port));
}
void od_outb(unsigned char value, unsigned long port)
{
dprintk("od_outb(%x, %x)\n", value, port);
writeb(value, io_addr(port));
}
void od_outw(unsigned short value, unsigned long port)
{
dprintk("od_outw(%x, %x)\n", value, port);
writew(value, io_addr(port));
}
void od_outl(unsigned int value, unsigned long port)
{
dprintk("od_outl(%x, %x)\n", value, port);
writel(value, io_addr(port));
}
/* This is horrible at the moment - needs more work to do something sensible */
#define IO_DELAY() udelay(10)
#define OUT_DELAY(x,type) \
void od_out##x##_p(unsigned type value,unsigned long port){out##x(value,port);IO_DELAY();}
#define IN_DELAY(x,type) \
unsigned type od_in##x##_p(unsigned long port) {unsigned type tmp=in##x(port);IO_DELAY();return tmp;}
OUT_DELAY(b,char)
OUT_DELAY(w,short)
OUT_DELAY(l,int)
IN_DELAY(b,char)
IN_DELAY(w,short)
IN_DELAY(l,int)
/* Now for the string version of these functions */
void od_outsb(unsigned long port, const void *addr, unsigned long count)
{
int i;
unsigned char *p = (unsigned char *) addr;
for (i = 0; i < count; i++, p++) {
outb(*p, port);
}
}
void od_insb(unsigned long port, void *addr, unsigned long count)
{
int i;
unsigned char *p = (unsigned char *) addr;
for (i = 0; i < count; i++, p++) {
*p = inb(port);
}
}
/* For the 16 and 32 bit string functions, we have to worry about alignment.
* The SH does not do unaligned accesses, so we have to read as bytes and
* then write as a word or dword.
* This can be optimised a lot more, especially in the case where the data
* is aligned
*/
void od_outsw(unsigned long port, const void *addr, unsigned long count)
{
int i;
unsigned short tmp;
unsigned char *p = (unsigned char *) addr;
for (i = 0; i < count; i++, p += 2) {
tmp = (*p) | ((*(p + 1)) << 8);
outw(tmp, port);
}
}
void od_insw(unsigned long port, void *addr, unsigned long count)
{
int i;
unsigned short tmp;
unsigned char *p = (unsigned char *) addr;
for (i = 0; i < count; i++, p += 2) {
tmp = inw(port);
p[0] = tmp & 0xff;
p[1] = (tmp >> 8) & 0xff;
}
}
void od_outsl(unsigned long port, const void *addr, unsigned long count)
{
int i;
unsigned tmp;
unsigned char *p = (unsigned char *) addr;
for (i = 0; i < count; i++, p += 4) {
tmp = (*p) | ((*(p + 1)) << 8) | ((*(p + 2)) << 16) |
((*(p + 3)) << 24);
outl(tmp, port);
}
}
void od_insl(unsigned long port, void *addr, unsigned long count)
{
int i;
unsigned tmp;
unsigned char *p = (unsigned char *) addr;
for (i = 0; i < count; i++, p += 4) {
tmp = inl(port);
p[0] = tmp & 0xff;
p[1] = (tmp >> 8) & 0xff;
p[2] = (tmp >> 16) & 0xff;
p[3] = (tmp >> 24) & 0xff;
}
}

View file

@ -1,191 +0,0 @@
/*
* Copyright (C) 2000 David J. Mckay (david.mckay@st.com)
*
* May be copied or modified under the terms of the GNU General Public
* License. See linux/COPYING for more information.
*
* Looks after interrupts on the overdrive board.
*
* Bases on the IPR irq system
*/
#include <linux/init.h>
#include <linux/irq.h>
#include <asm/system.h>
#include <asm/io.h>
#include <asm/overdrive/overdrive.h>
struct od_data {
int overdrive_irq;
int irq_mask;
};
#define NUM_EXTERNAL_IRQS 16
#define EXTERNAL_IRQ_NOT_IN_USE (-1)
#define EXTERNAL_IRQ_NOT_ASSIGNED (-1)
/*
* This table is used to determine what to program into the FPGA's CT register
* for the specified Linux IRQ.
*
* The irq_mask gives the interrupt number from the PCI board (PCI_Int(6:0))
* but is one greater than that because the because the FPGA treats 0
* as disabled, a value of 1 asserts PCI_Int0, and so on.
*
* The overdrive_irq specifies which of the eight interrupt sources generates
* that interrupt, and but is multiplied by four to give the bit offset into
* the CT register.
*
* The seven interrupts levels (SH4 IRL's) we have available here is hardwired
* by the EPLD. The assignments here of which PCI interrupt generates each
* level is arbitary.
*/
static struct od_data od_data_table[NUM_EXTERNAL_IRQS] = {
/* overdrive_irq , irq_mask */
{EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE}, /* 0 */
{EXTERNAL_IRQ_NOT_ASSIGNED, 7}, /* 1 */
{EXTERNAL_IRQ_NOT_ASSIGNED, 6}, /* 2 */
{EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE}, /* 3 */
{EXTERNAL_IRQ_NOT_ASSIGNED, 5}, /* 4 */
{EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE}, /* 5 */
{EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE}, /* 6 */
{EXTERNAL_IRQ_NOT_ASSIGNED, 4}, /* 7 */
{EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE}, /* 8 */
{EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE}, /* 9 */
{EXTERNAL_IRQ_NOT_ASSIGNED, 3}, /* 10 */
{EXTERNAL_IRQ_NOT_ASSIGNED, 2}, /* 11 */
{EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE}, /* 12 */
{EXTERNAL_IRQ_NOT_ASSIGNED, 1}, /* 13 */
{EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE}, /* 14 */
{EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE} /* 15 */
};
static void set_od_data(int overdrive_irq, int irq)
{
if (irq >= NUM_EXTERNAL_IRQS || irq < 0)
return;
od_data_table[irq].overdrive_irq = overdrive_irq << 2;
}
static void enable_od_irq(unsigned int irq);
void disable_od_irq(unsigned int irq);
/* shutdown is same as "disable" */
#define shutdown_od_irq disable_od_irq
static void mask_and_ack_od(unsigned int);
static void end_od_irq(unsigned int irq);
static unsigned int startup_od_irq(unsigned int irq)
{
enable_od_irq(irq);
return 0; /* never anything pending */
}
static struct hw_interrupt_type od_irq_type = {
.typename = "Overdrive-IRQ",
.startup = startup_od_irq,
.shutdown = shutdown_od_irq,
.enable = enable_od_irq,
.disable = disable_od_irq,
.ack = mask_and_ack_od,
.end = end_od_irq
};
static void disable_od_irq(unsigned int irq)
{
unsigned val, flags;
int overdrive_irq;
unsigned mask;
/* Not a valid interrupt */
if (irq < 0 || irq >= NUM_EXTERNAL_IRQS)
return;
/* Is is necessary to use a cli here? Would a spinlock not be
* mroe efficient?
*/
local_irq_save(flags);
overdrive_irq = od_data_table[irq].overdrive_irq;
if (overdrive_irq != EXTERNAL_IRQ_NOT_ASSIGNED) {
mask = ~(0x7 << overdrive_irq);
val = ctrl_inl(OVERDRIVE_INT_CT);
val &= mask;
ctrl_outl(val, OVERDRIVE_INT_CT);
}
local_irq_restore(flags);
}
static void enable_od_irq(unsigned int irq)
{
unsigned val, flags;
int overdrive_irq;
unsigned mask;
/* Not a valid interrupt */
if (irq < 0 || irq >= NUM_EXTERNAL_IRQS)
return;
/* Set priority in OD back to original value */
local_irq_save(flags);
/* This one is not in use currently */
overdrive_irq = od_data_table[irq].overdrive_irq;
if (overdrive_irq != EXTERNAL_IRQ_NOT_ASSIGNED) {
val = ctrl_inl(OVERDRIVE_INT_CT);
mask = ~(0x7 << overdrive_irq);
val &= mask;
mask = od_data_table[irq].irq_mask << overdrive_irq;
val |= mask;
ctrl_outl(val, OVERDRIVE_INT_CT);
}
local_irq_restore(flags);
}
/* this functions sets the desired irq handler to be an overdrive type */
static void __init make_od_irq(unsigned int irq)
{
disable_irq_nosync(irq);
irq_desc[irq].chip = &od_irq_type;
disable_od_irq(irq);
}
static void mask_and_ack_od(unsigned int irq)
{
disable_od_irq(irq);
}
static void end_od_irq(unsigned int irq)
{
enable_od_irq(irq);
}
void __init init_overdrive_irq(void)
{
int i;
/* Disable all interrupts */
ctrl_outl(0, OVERDRIVE_INT_CT);
/* Update interrupt pin mode to use encoded interrupts */
i = ctrl_inw(INTC_ICR);
i &= ~INTC_ICR_IRLM;
ctrl_outw(i, INTC_ICR);
for (i = 0; i < NUM_EXTERNAL_IRQS; i++) {
if (od_data_table[i].irq_mask != EXTERNAL_IRQ_NOT_IN_USE) {
make_od_irq(i);
} else if (i != 15) { // Cannot use imask on level 15
make_imask_irq(i);
}
}
/* Set up the interrupts */
set_od_data(OVERDRIVE_PCI_INTA, OVERDRIVE_PCI_IRQ1);
set_od_data(OVERDRIVE_PCI_INTB, OVERDRIVE_PCI_IRQ2);
set_od_data(OVERDRIVE_AUDIO_INT, OVERDRIVE_ESS_IRQ);
}

View file

@ -1,58 +0,0 @@
/*
* linux/arch/sh/overdrive/led.c
*
* Copyright (C) 1999 Stuart Menefy <stuart.menefy@st.com>
*
* May be copied or modified under the terms of the GNU General Public
* License. See linux/COPYING for more information.
*
* This file contains an Overdrive specific LED feature.
*/
#include <asm/system.h>
#include <asm/io.h>
#include <asm/overdrive/overdrive.h>
static void mach_led(int position, int value)
{
unsigned long flags;
unsigned long reg;
local_irq_save(flags);
reg = readl(OVERDRIVE_CTRL);
if (value) {
reg |= (1<<3);
} else {
reg &= ~(1<<3);
}
writel(reg, OVERDRIVE_CTRL);
local_irq_restore(flags);
}
#ifdef CONFIG_HEARTBEAT
#include <linux/sched.h>
/* acts like an actual heart beat -- ie thump-thump-pause... */
void heartbeat_od(void)
{
static unsigned cnt = 0, period = 0, dist = 0;
if (cnt == 0 || cnt == dist)
mach_led( -1, 1);
else if (cnt == 7 || cnt == dist+7)
mach_led( -1, 0);
if (++cnt > period) {
cnt = 0;
/* The hyperbolic function below modifies the heartbeat period
* length in dependency of the current (5min) load. It goes
* through the points f(0)=126, f(1)=86, f(5)=51,
* f(inf)->30. */
period = ((672<<FSHIFT)/(5*avenrun[0]+(7<<FSHIFT))) + 30;
dist = period / 4;
}
}
#endif /* CONFIG_HEARTBEAT */

View file

@ -1,62 +0,0 @@
/*
* linux/arch/sh/overdrive/mach.c
*
* Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com)
*
* May be copied or modified under the terms of the GNU General Public
* License. See linux/COPYING for more information.
*
* Machine vector for the STMicroelectronics Overdrive
*/
#include <linux/init.h>
#include <asm/machvec.h>
#include <asm/rtc.h>
#include <asm/machvec_init.h>
#include <asm/io_unknown.h>
#include <asm/io_generic.h>
#include <asm/overdrive/io.h>
void heartbeat_od(void);
void init_overdrive_irq(void);
void galileo_pcibios_init(void);
/*
* The Machine Vector
*/
struct sh_machine_vector mv_od __initmv = {
.mv_nr_irqs = 48,
.mv_inb = od_inb,
.mv_inw = od_inw,
.mv_inl = od_inl,
.mv_outb = od_outb,
.mv_outw = od_outw,
.mv_outl = od_outl,
.mv_inb_p = od_inb_p,
.mv_inw_p = od_inw_p,
.mv_inl_p = od_inl_p,
.mv_outb_p = od_outb_p,
.mv_outw_p = od_outw_p,
.mv_outl_p = od_outl_p,
.mv_insb = od_insb,
.mv_insw = od_insw,
.mv_insl = od_insl,
.mv_outsb = od_outsb,
.mv_outsw = od_outsw,
.mv_outsl = od_outsl,
#ifdef CONFIG_PCI
.mv_init_irq = init_overdrive_irq,
#endif
#ifdef CONFIG_HEARTBEAT
.mv_heartbeat = heartbeat_od,
#endif
};
ALIAS_MV(od)

View file

@ -1,46 +0,0 @@
/*
* Copyright (C) 2000 David J. Mckay (david.mckay@st.com)
*
* May be copied or modified under the terms of the GNU General Public
* License. See linux/COPYING for more information.
*
* Dynamic DMA mapping support.
*
* On the overdrive, we can only DMA from memory behind the PCI bus!
* this means that all DMA'able memory must come from there.
* this restriction will not apply to later boards.
*/
#include <linux/types.h>
#include <linux/mm.h>
#include <linux/string.h>
#include <linux/pci.h>
#include <asm/io.h>
void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
dma_addr_t * dma_handle)
{
void *ret;
int gfp = GFP_ATOMIC;
printk("BUG: pci_alloc_consistent() called - not yet supported\n");
/* We ALWAYS need DMA memory on the overdrive hardware,
* due to it's extreme weirdness
* Need to flush the cache here as well, since the memory
* can still be seen through the cache!
*/
gfp |= GFP_DMA;
ret = (void *) __get_free_pages(gfp, get_order(size));
if (ret != NULL) {
memset(ret, 0, size);
*dma_handle = virt_to_bus(ret);
}
return ret;
}
void pci_free_consistent(struct pci_dev *hwdev, size_t size,
void *vaddr, dma_addr_t dma_handle)
{
free_pages((unsigned long) vaddr, get_order(size));
}

View file

@ -1,36 +0,0 @@
/*
* arch/sh/overdrive/setup.c
*
* Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com)
*
* May be copied or modified under the terms of the GNU General Public
* License. See linux/COPYING for more information.
*
* STMicroelectronics Overdrive Support.
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <asm/io.h>
#include <asm/overdrive/overdrive.h>
#include <asm/overdrive/fpga.h>
const char *get_system_type(void)
{
return "SH7750 Overdrive";
}
/*
* Initialize the board
*/
int __init platform_setup(void)
{
#ifdef CONFIG_PCI
init_overdrive_fpga();
galileo_init();
#endif
/* Enable RS232 receive buffers */
writel(0x1e, OVERDRIVE_CTRL);
}

View file

@ -1,10 +1,6 @@
#
# Makefile for the EDOSK7705 specific parts of the kernel
#
# Note! Dependencies are done automagically by 'make dep', which also
# removes any old dependencies. DON'T put your own dependencies here
# unless it's something special (ie not a .c file).
#
obj-y := setup.o io.o

View file

@ -8,19 +8,21 @@
* Modified for edosk7705 development
* board by S. Dunn, 2003.
*/
#include <linux/init.h>
#include <asm/machvec.h>
#include <asm/machvec_init.h>
#include <asm/edosk7705/io.h>
static void init_edosk7705(void);
static void __init sh_edosk7705_init_irq(void)
{
/* This is the Ethernet interrupt */
make_imask_irq(0x09);
}
/*
* The Machine Vector
*/
struct sh_machine_vector mv_edosk7705 __initmv = {
.mv_name = "EDOSK7705",
.mv_nr_irqs = 80,
.mv_inb = sh_edosk7705_inb,
@ -37,23 +39,6 @@ struct sh_machine_vector mv_edosk7705 __initmv = {
.mv_outsl = sh_edosk7705_outsl,
.mv_isa_port2addr = sh_edosk7705_isa_port2addr,
.mv_init_irq = init_edosk7705,
.mv_init_irq = sh_edosk7705_init_irq,
};
ALIAS_MV(edosk7705)
static void __init init_edosk7705(void)
{
/* This is the Ethernet interrupt */
make_imask_irq(0x09);
}
const char *get_system_type(void)
{
return "EDOSK7705";
}
void __init platform_setup(void)
{
/* Nothing .. */
}

View file

@ -0,0 +1,12 @@
if SH_HS7751RVOIP
menu "HS7751RVoIP options"
config HS7751RVOIP_CODEC
bool "Support VoIP Codec section"
help
Selecting this option will support CODEC section.
endmenu
endif

View file

@ -1,12 +1,8 @@
#
# Makefile for the HS7751RVoIP specific parts of the kernel
#
# Note! Dependencies are done automagically by 'make dep', which also
# removes any old dependencies. DON'T put your own dependencies here
# unless it's something special (ie not a .c file).
#
obj-y := mach.o setup.o io.o irq.o led.o
obj-y := setup.o io.o irq.o
obj-$(CONFIG_PCI) += pci.o

View file

@ -10,21 +10,16 @@
* placeholder code from io_hs7751rvoip.c left in with the
* expectation of later SuperIO and PCMCIA access.
*/
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <asm/io.h>
#include <asm/hs7751rvoip/hs7751rvoip.h>
#include <asm/addrspace.h>
#include <linux/module.h>
#include <linux/pci.h>
#include "../../../drivers/pci/pci-sh7751.h"
extern void *area5_io8_base; /* Area 5 8bit I/O Base address */
extern void *area6_io8_base; /* Area 6 8bit I/O Base address */
extern void *area5_io16_base; /* Area 5 16bit I/O Base address */
extern void *area6_io16_base; /* Area 6 16bit I/O Base address */
/*
* The 7751R HS7751RVoIP uses the built-in PCI controller (PCIC)
@ -33,25 +28,8 @@ extern void *area6_io16_base; /* Area 6 16bit I/O Base address */
* like the other Solution Engine boards.
*/
#define PCIIOBR (volatile long *)PCI_REG(SH7751_PCIIOBR)
#define PCIMBR (volatile long *)PCI_REG(SH7751_PCIMBR)
#define PCI_IO_AREA SH7751_PCI_IO_BASE
#define PCI_MEM_AREA SH7751_PCI_CONFIG_BASE
#define PCI_IOMAP(adr) (PCI_IO_AREA + (adr & ~SH7751_PCIIOBR_MASK))
#if defined(CONFIG_HS7751RVOIP_CODEC)
#define CODEC_IO_BASE 0x1000
#endif
#define maybebadio(name,port) \
printk("bad PC-like io %s for port 0x%lx at 0x%08x\n", \
#name, (port), (__u32) __builtin_return_address(0))
static inline void delay(void)
{
ctrl_inw(0xa0000000);
}
#define CODEC_IOMAP(a) ((unsigned long)area6_io8_base + ((a) - CODEC_IO_BASE))
static inline unsigned long port2adr(unsigned int port)
{
@ -59,9 +37,10 @@ static inline unsigned long port2adr(unsigned int port)
if (port == 0x3f6)
return ((unsigned long)area5_io16_base + 0x0c);
else
return ((unsigned long)area5_io16_base + 0x800 + ((port-0x1f0) << 1));
return ((unsigned long)area5_io16_base + 0x800 +
((port-0x1f0) << 1));
else
maybebadio(port2adr, (unsigned long)port);
maybebadio((unsigned long)port);
return port;
}
@ -78,25 +57,10 @@ static inline int shifted_port(unsigned long port)
}
#if defined(CONFIG_HS7751RVOIP_CODEC)
static inline int
codec_port(unsigned long port)
{
if (CODEC_IO_BASE <= port && port < (CODEC_IO_BASE+0x20))
return 1;
else
return 0;
}
#endif
/* In case someone configures the kernel w/o PCI support: in that */
/* scenario, don't ever bother to check for PCI-window addresses */
/* NOTE: WINDOW CHECK MAY BE A BIT OFF, HIGH PCIBIOS_MIN_IO WRAPS? */
#if defined(CONFIG_PCI)
#define CHECK_SH7751_PCIIO(port) \
((port >= PCIBIOS_MIN_IO) && (port < (PCIBIOS_MIN_IO + SH7751_PCI_IO_SIZE)))
#define codec_port(port) \
((CODEC_IO_BASE <= (port)) && ((port) < (CODEC_IO_BASE + 0x20)))
#else
#define CHECK_SH7751_PCIIO(port) (0)
#define codec_port(port) (0)
#endif
/*
@ -109,15 +73,13 @@ codec_port(unsigned long port)
unsigned char hs7751rvoip_inb(unsigned long port)
{
if (PXSEG(port))
return *(volatile unsigned char *)port;
#if defined(CONFIG_HS7751RVOIP_CODEC)
return ctrl_inb(port);
else if (codec_port(port))
return *(volatile unsigned char *)((unsigned long)area6_io8_base+(port-CODEC_IO_BASE));
#endif
else if (CHECK_SH7751_PCIIO(port) || shifted_port(port))
return *(volatile unsigned char *)PCI_IOMAP(port);
return ctrl_inb(CODEC_IOMAP(port));
else if (is_pci_ioaddr(port) || shifted_port(port))
return ctrl_inb(pci_ioaddr(port));
else
return (*(volatile unsigned short *)port2adr(port) & 0xff);
return ctrl_inw(port2adr(port)) & 0xff;
}
unsigned char hs7751rvoip_inb_p(unsigned long port)
@ -125,38 +87,36 @@ unsigned char hs7751rvoip_inb_p(unsigned long port)
unsigned char v;
if (PXSEG(port))
v = *(volatile unsigned char *)port;
#if defined(CONFIG_HS7751RVOIP_CODEC)
v = ctrl_inb(port);
else if (codec_port(port))
v = *(volatile unsigned char *)((unsigned long)area6_io8_base+(port-CODEC_IO_BASE));
#endif
else if (CHECK_SH7751_PCIIO(port) || shifted_port(port))
v = *(volatile unsigned char *)PCI_IOMAP(port);
v = ctrl_inb(CODEC_IOMAP(port));
else if (is_pci_ioaddr(port) || shifted_port(port))
v = ctrl_inb(pci_ioaddr(port));
else
v = (*(volatile unsigned short *)port2adr(port) & 0xff);
delay();
v = ctrl_inw(port2adr(port)) & 0xff;
ctrl_delay();
return v;
}
unsigned short hs7751rvoip_inw(unsigned long port)
{
if (PXSEG(port))
return *(volatile unsigned short *)port;
else if (CHECK_SH7751_PCIIO(port) || shifted_port(port))
return *(volatile unsigned short *)PCI_IOMAP(port);
return ctrl_inw(port);
else if (is_pci_ioaddr(port) || shifted_port(port))
return ctrl_inw(pci_ioaddr(port));
else
maybebadio(inw, port);
maybebadio(port);
return 0;
}
unsigned int hs7751rvoip_inl(unsigned long port)
{
if (PXSEG(port))
return *(volatile unsigned long *)port;
else if (CHECK_SH7751_PCIIO(port) || shifted_port(port))
return *(volatile unsigned long *)PCI_IOMAP(port);
return ctrl_inl(port);
else if (is_pci_ioaddr(port) || shifted_port(port))
return ctrl_inl(pci_ioaddr(port));
else
maybebadio(inl, port);
maybebadio(port);
return 0;
}
@ -164,146 +124,160 @@ void hs7751rvoip_outb(unsigned char value, unsigned long port)
{
if (PXSEG(port))
*(volatile unsigned char *)port = value;
#if defined(CONFIG_HS7751RVOIP_CODEC)
ctrl_outb(value, port);
else if (codec_port(port))
*(volatile unsigned cjar *)((unsigned long)area6_io8_base+(port-CODEC_IO_BASE)) = value;
#endif
else if (CHECK_SH7751_PCIIO(port) || shifted_port(port))
*(unsigned char *)PCI_IOMAP(port) = value;
ctrl_outb(value, CODEC_IOMAP(port));
else if (is_pci_ioaddr(port) || shifted_port(port))
ctrl_outb(value, pci_ioaddr(port));
else
*(volatile unsigned short *)port2adr(port) = value;
ctrl_outb(value, port2adr(port));
}
void hs7751rvoip_outb_p(unsigned char value, unsigned long port)
{
if (PXSEG(port))
*(volatile unsigned char *)port = value;
#if defined(CONFIG_HS7751RVOIP_CODEC)
ctrl_outb(value, port);
else if (codec_port(port))
*(volatile unsigned cjar *)((unsigned long)area6_io8_base+(port-CODEC_IO_BASE)) = value;
#endif
else if (CHECK_SH7751_PCIIO(port) || shifted_port(port))
*(unsigned char *)PCI_IOMAP(port) = value;
ctrl_outb(value, CODEC_IOMAP(port));
else if (is_pci_ioaddr(port) || shifted_port(port))
ctrl_outb(value, pci_ioaddr(port));
else
*(volatile unsigned short *)port2adr(port) = value;
delay();
ctrl_outw(value, port2adr(port));
ctrl_delay();
}
void hs7751rvoip_outw(unsigned short value, unsigned long port)
{
if (PXSEG(port))
*(volatile unsigned short *)port = value;
else if (CHECK_SH7751_PCIIO(port) || shifted_port(port))
*(unsigned short *)PCI_IOMAP(port) = value;
ctrl_outw(value, port);
else if (is_pci_ioaddr(port) || shifted_port(port))
ctrl_outw(value, pci_ioaddr(port));
else
maybebadio(outw, port);
maybebadio(port);
}
void hs7751rvoip_outl(unsigned int value, unsigned long port)
{
if (PXSEG(port))
*(volatile unsigned long *)port = value;
else if (CHECK_SH7751_PCIIO(port) || shifted_port(port))
*((unsigned long *)PCI_IOMAP(port)) = value;
ctrl_outl(value, port);
else if (is_pci_ioaddr(port) || shifted_port(port))
ctrl_outl(value, pci_ioaddr(port));
else
maybebadio(outl, port);
maybebadio(port);
}
void hs7751rvoip_insb(unsigned long port, void *addr, unsigned long count)
{
u8 *buf = addr;
if (PXSEG(port))
while (count--) *((unsigned char *) addr)++ = *(volatile unsigned char *)port;
#if defined(CONFIG_HS7751RVOIP_CODEC)
while (count--)
*buf++ = ctrl_inb(port);
else if (codec_port(port))
while (count--) *((unsigned char *) addr)++ = *(volatile unsigned char *)((unsigned long)area6_io8_base+(port-CODEC_IO_BASE));
#endif
else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) {
volatile __u8 *bp = (__u8 *)PCI_IOMAP(port);
while (count--)
*buf++ = ctrl_inb(CODEC_IOMAP(port));
else if (is_pci_ioaddr(port) || shifted_port(port)) {
volatile u8 *bp = (volatile u8 *)pci_ioaddr(port);
while (count--) *((volatile unsigned char *) addr)++ = *bp;
while (count--)
*buf++ = *bp;
} else {
volatile __u16 *p = (volatile unsigned short *)port2adr(port);
volatile u16 *p = (volatile u16 *)port2adr(port);
while (count--) *((unsigned char *) addr)++ = *p & 0xff;
while (count--)
*buf++ = *p & 0xff;
}
}
void hs7751rvoip_insw(unsigned long port, void *addr, unsigned long count)
{
volatile __u16 *p;
volatile u16 *p;
u16 *buf = addr;
if (PXSEG(port))
p = (volatile unsigned short *)port;
else if (CHECK_SH7751_PCIIO(port) || shifted_port(port))
p = (volatile unsigned short *)PCI_IOMAP(port);
p = (volatile u16 *)port;
else if (is_pci_ioaddr(port) || shifted_port(port))
p = (volatile u16 *)pci_ioaddr(port);
else
p = (volatile unsigned short *)port2adr(port);
while (count--) *((__u16 *) addr)++ = *p;
p = (volatile u16 *)port2adr(port);
while (count--)
*buf++ = *p;
}
void hs7751rvoip_insl(unsigned long port, void *addr, unsigned long count)
{
if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) {
volatile __u32 *p = (__u32 *)PCI_IOMAP(port);
while (count--) *((__u32 *) addr)++ = *p;
if (is_pci_ioaddr(port) || shifted_port(port)) {
volatile u32 *p = (volatile u32 *)pci_ioaddr(port);
u32 *buf = addr;
while (count--)
*buf++ = *p;
} else
maybebadio(insl, port);
maybebadio(port);
}
void hs7751rvoip_outsb(unsigned long port, const void *addr, unsigned long count)
{
const u8 *buf = addr;
if (PXSEG(port))
while (count--) *(volatile unsigned char *)port = *((unsigned char *) addr)++;
#if defined(CONFIG_HS7751RVOIP_CODEC)
while (count--)
ctrl_outb(*buf++, port);
else if (codec_port(port))
while (count--) *(volatile unsigned char *)((unsigned long)area6_io8_base+(port-CODEC_IO_BASE)) = *((unsigned char *) addr)++;
#endif
else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) {
volatile __u8 *bp = (__u8 *)PCI_IOMAP(port);
while (count--)
ctrl_outb(*buf++, CODEC_IOMAP(port));
else if (is_pci_ioaddr(port) || shifted_port(port)) {
volatile u8 *bp = (volatile u8 *)pci_ioaddr(port);
while (count--) *bp = *((volatile unsigned char *) addr)++;
while (count--)
*bp = *buf++;
} else {
volatile __u16 *p = (volatile unsigned short *)port2adr(port);
volatile u16 *p = (volatile u16 *)port2adr(port);
while (count--) *p = *((unsigned char *) addr)++;
while (count--)
*p = *buf++;
}
}
void hs7751rvoip_outsw(unsigned long port, const void *addr, unsigned long count)
{
volatile __u16 *p;
volatile u16 *p;
const u16 *buf = addr;
if (PXSEG(port))
p = (volatile unsigned short *)port;
else if (CHECK_SH7751_PCIIO(port) || shifted_port(port))
p = (volatile unsigned short *)PCI_IOMAP(port);
p = (volatile u16 *)port;
else if (is_pci_ioaddr(port) || shifted_port(port))
p = (volatile u16 *)pci_ioaddr(port);
else
p = (volatile unsigned short *)port2adr(port);
while (count--) *p = *((__u16 *) addr)++;
p = (volatile u16 *)port2adr(port);
while (count--)
*p = *buf++;
}
void hs7751rvoip_outsl(unsigned long port, const void *addr, unsigned long count)
{
if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) {
volatile __u32 *p = (__u32 *)PCI_IOMAP(port);
const u32 *buf = addr;
while (count--) *p = *((__u32 *) addr)++;
if (is_pci_ioaddr(port) || shifted_port(port)) {
volatile u32 *p = (volatile u32 *)pci_ioaddr(port);
while (count--)
*p = *buf++;
} else
maybebadio(outsl, port);
maybebadio(port);
}
void *hs7751rvoip_ioremap(unsigned long offset, unsigned long size)
void __iomem *hs7751rvoip_ioport_map(unsigned long port, unsigned int size)
{
if (offset >= 0xfd000000)
return (void *)offset;
else
return (void *)P2SEGADDR(offset);
}
EXPORT_SYMBOL(hs7751rvoip_ioremap);
if (PXSEG(port))
return (void __iomem *)port;
else if (unlikely(codec_port(port) && (size == 1)))
return (void __iomem *)CODEC_IOMAP(port);
else if (is_pci_ioaddr(port))
return (void __iomem *)pci_ioaddr(port);
unsigned long hs7751rvoip_isa_port2addr(unsigned long offset)
{
return port2adr(offset);
return (void __iomem *)port2adr(port);
}

View file

@ -35,30 +35,24 @@ static unsigned int startup_hs7751rvoip_irq(unsigned int irq)
static void disable_hs7751rvoip_irq(unsigned int irq)
{
unsigned long flags;
unsigned short val;
unsigned short mask = 0xffff ^ (0x0001 << mask_pos[irq]);
/* Set the priority in IPR to 0 */
local_irq_save(flags);
val = ctrl_inw(IRLCNTR3);
val &= mask;
ctrl_outw(val, IRLCNTR3);
local_irq_restore(flags);
}
static void enable_hs7751rvoip_irq(unsigned int irq)
{
unsigned long flags;
unsigned short val;
unsigned short value = (0x0001 << mask_pos[irq]);
/* Set priority in IPR back to original value */
local_irq_save(flags);
val = ctrl_inw(IRLCNTR3);
val |= value;
ctrl_outw(val, IRLCNTR3);
local_irq_restore(flags);
}
static void ack_hs7751rvoip_irq(unsigned int irq)

View file

@ -1,26 +0,0 @@
/*
* linux/arch/sh/kernel/setup_hs7751rvoip.c
*
* Copyright (C) 2000 Kazumoto Kojima
*
* Renesas Technology Sales HS7751RVoIP Support.
*
* Modified for HS7751RVoIP by
* Atom Create Engineering Co., Ltd. 2002.
* Lineo uSolutions, Inc. 2003.
*/
#include <asm/io.h>
#include <asm/hs7751rvoip/hs7751rvoip.h>
extern unsigned int debug_counter;
void debug_led_disp(void)
{
unsigned short value;
value = (unsigned char)debug_counter++;
ctrl_outb((0xf0|value), PA_OUTPORTR);
if (value == 0x0f)
debug_counter = 0;
}

View file

@ -1,54 +0,0 @@
/*
* linux/arch/sh/kernel/mach_hs7751rvoip.c
*
* Minor tweak of mach_se.c file to reference hs7751rvoip-specific items.
*
* May be copied or modified under the terms of the GNU General Public
* License. See linux/COPYING for more information.
*
* Machine vector for the Renesas Technology sales HS7751RVoIP
*/
#include <linux/init.h>
#include <asm/machvec.h>
#include <asm/rtc.h>
#include <asm/irq.h>
#include <asm/hs7751rvoip/io.h>
extern void init_hs7751rvoip_IRQ(void);
extern void *hs7751rvoip_ioremap(unsigned long, unsigned long);
/*
* The Machine Vector
*/
struct sh_machine_vector mv_hs7751rvoip __initmv = {
.mv_nr_irqs = 72,
.mv_inb = hs7751rvoip_inb,
.mv_inw = hs7751rvoip_inw,
.mv_inl = hs7751rvoip_inl,
.mv_outb = hs7751rvoip_outb,
.mv_outw = hs7751rvoip_outw,
.mv_outl = hs7751rvoip_outl,
.mv_inb_p = hs7751rvoip_inb_p,
.mv_inw_p = hs7751rvoip_inw,
.mv_inl_p = hs7751rvoip_inl,
.mv_outb_p = hs7751rvoip_outb_p,
.mv_outw_p = hs7751rvoip_outw,
.mv_outl_p = hs7751rvoip_outl,
.mv_insb = hs7751rvoip_insb,
.mv_insw = hs7751rvoip_insw,
.mv_insl = hs7751rvoip_insl,
.mv_outsb = hs7751rvoip_outsb,
.mv_outsw = hs7751rvoip_outsw,
.mv_outsl = hs7751rvoip_outsl,
.mv_ioremap = hs7751rvoip_ioremap,
.mv_isa_port2addr = hs7751rvoip_isa_port2addr,
.mv_init_irq = init_hs7751rvoip_IRQ,
};
ALIAS_MV(hs7751rvoip)

View file

@ -1,44 +1,38 @@
/*
* linux/arch/sh/kernel/setup_hs7751rvoip.c
* Renesas Technology Sales HS7751RVoIP Support.
*
* Copyright (C) 2000 Kazumoto Kojima
*
* Renesas Technology Sales HS7751RVoIP Support.
*
* Modified for HS7751RVoIP by
* Atom Create Engineering Co., Ltd. 2002.
* Lineo uSolutions, Inc. 2003.
*/
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/hdreg.h>
#include <linux/ide.h>
#include <asm/io.h>
#include <asm/hs7751rvoip/hs7751rvoip.h>
#include <linux/mm.h>
#include <linux/vmalloc.h>
#include <linux/hdreg.h>
#include <linux/ide.h>
#include <linux/pm.h>
#include <asm/io.h>
#include <asm/hs7751rvoip/hs7751rvoip.h>
#include <asm/machvec.h>
#include <asm/rtc.h>
#include <asm/irq.h>
/* defined in mm/ioremap.c */
extern void * p3_ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags);
unsigned int debug_counter;
const char *get_system_type(void)
static void __init hs7751rvoip_init_irq(void)
{
return "HS7751RVoIP";
#if defined(CONFIG_HS7751RVOIP_CODEC)
make_ipr_irq(DMTE0_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY);
make_ipr_irq(DMTE1_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY);
#endif
init_hs7751rvoip_IRQ();
}
/*
* Initialize the board
*/
void __init platform_setup(void)
static void hs7751rvoip_power_off(void)
{
printk(KERN_INFO "Renesas Technology Sales HS7751RVoIP-2 support.\n");
ctrl_outb(0xf0, PA_OUTPORTR);
debug_counter = 0;
ctrl_outw(ctrl_inw(PA_OUTPORTR) & 0xffdf, PA_OUTPORTR);
}
void *area5_io8_base;
@ -46,16 +40,15 @@ void *area6_io8_base;
void *area5_io16_base;
void *area6_io16_base;
int __init cf_init(void)
static int __init hs7751rvoip_cf_init(void)
{
pgprot_t prot;
unsigned long paddrbase, psize;
unsigned long paddrbase;
/* open I/O area window */
paddrbase = virt_to_phys((void *)(PA_AREA5_IO+0x00000800));
psize = PAGE_SIZE;
prot = PAGE_KERNEL_PCC(1, _PAGE_PCC_COM16);
area5_io16_base = p3_ioremap(paddrbase, psize, prot.pgprot);
area5_io16_base = p3_ioremap(paddrbase, PAGE_SIZE, prot.pgprot);
if (!area5_io16_base) {
printk("allocate_cf_area : can't open CF I/O window!\n");
return -ENOMEM;
@ -64,19 +57,18 @@ int __init cf_init(void)
/* XXX : do we need attribute and common-memory area also? */
paddrbase = virt_to_phys((void *)PA_AREA6_IO);
psize = PAGE_SIZE;
#if defined(CONFIG_HS7751RVOIP_CODEC)
prot = PAGE_KERNEL_PCC(0, _PAGE_PCC_COM8);
#else
prot = PAGE_KERNEL_PCC(0, _PAGE_PCC_IO8);
#endif
area6_io8_base = p3_ioremap(paddrbase, psize, prot.pgprot);
area6_io8_base = p3_ioremap(paddrbase, PAGE_SIZE, prot.pgprot);
if (!area6_io8_base) {
printk("allocate_cf_area : can't open CODEC I/O 8bit window!\n");
return -ENOMEM;
}
prot = PAGE_KERNEL_PCC(0, _PAGE_PCC_IO16);
area6_io16_base = p3_ioremap(paddrbase, psize, prot.pgprot);
area6_io16_base = p3_ioremap(paddrbase, PAGE_SIZE, prot.pgprot);
if (!area6_io16_base) {
printk("allocate_cf_area : can't open CODEC I/O 16bit window!\n");
return -ENOMEM;
@ -85,4 +77,46 @@ int __init cf_init(void)
return 0;
}
__initcall (cf_init);
/*
* Initialize the board
*/
static void __init hs7751rvoip_setup(char **cmdline_p)
{
device_initcall(hs7751rvoip_cf_init);
ctrl_outb(0xf0, PA_OUTPORTR);
pm_power_off = hs7751rvoip_power_off;
printk(KERN_INFO "Renesas Technology Sales HS7751RVoIP-2 support.\n");
}
struct sh_machine_vector mv_hs7751rvoip __initmv = {
.mv_name = "HS7751RVoIP",
.mv_setup = hs7751rvoip_setup,
.mv_nr_irqs = 72,
.mv_inb = hs7751rvoip_inb,
.mv_inw = hs7751rvoip_inw,
.mv_inl = hs7751rvoip_inl,
.mv_outb = hs7751rvoip_outb,
.mv_outw = hs7751rvoip_outw,
.mv_outl = hs7751rvoip_outl,
.mv_inb_p = hs7751rvoip_inb_p,
.mv_inw_p = hs7751rvoip_inw,
.mv_inl_p = hs7751rvoip_inl,
.mv_outb_p = hs7751rvoip_outb_p,
.mv_outw_p = hs7751rvoip_outw,
.mv_outl_p = hs7751rvoip_outl,
.mv_insb = hs7751rvoip_insb,
.mv_insw = hs7751rvoip_insw,
.mv_insl = hs7751rvoip_insl,
.mv_outsb = hs7751rvoip_outsb,
.mv_outsw = hs7751rvoip_outsw,
.mv_outsl = hs7751rvoip_outsl,
.mv_init_irq = hs7751rvoip_init_irq,
.mv_ioport_map = hs7751rvoip_ioport_map,
};
ALIAS_MV(hs7751rvoip)

View file

@ -0,0 +1,14 @@
if SH_R7780RP
menu "R7780RP options"
config SH_R7780MP
bool "R7780MP board support"
default y
help
Selecting this option will enable support for the mass-production
version of the R7780RP. If in doubt, say Y.
endmenu
endif

View file

@ -0,0 +1,6 @@
#
# Makefile for the R7780RP-1 specific parts of the kernel
#
obj-y := setup.o io.o irq.o
obj-$(CONFIG_HEARTBEAT) += led.o

View file

@ -0,0 +1,301 @@
/*
* Copyright (C) 2001 Ian da Silva, Jeremy Siegel
* Based largely on io_se.c.
*
* I/O routine for Renesas Solutions Highlander R7780RP-1
*
* Initial version only to support LAN access; some
* placeholder code from io_r7780rp.c left in with the
* expectation of later SuperIO and PCMCIA access.
*/
#include <linux/pci.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <asm/r7780rp/r7780rp.h>
#include <asm/addrspace.h>
#include <asm/io.h>
static inline unsigned long port2adr(unsigned int port)
{
if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6)
if (port == 0x3f6)
return (PA_AREA5_IO + 0x80c);
else
return (PA_AREA5_IO + 0x1000 + ((port-0x1f0) << 1));
else
maybebadio((unsigned long)port);
return port;
}
static inline unsigned long port88796l(unsigned int port, int flag)
{
unsigned long addr;
if (flag)
addr = PA_AX88796L + ((port - AX88796L_IO_BASE) << 1);
else
addr = PA_AX88796L + ((port - AX88796L_IO_BASE) << 1) + 0x1000;
return addr;
}
/* The 7780 R7780RP-1 seems to have everything hooked */
/* up pretty normally (nothing on high-bytes only...) so this */
/* shouldn't be needed */
static inline int shifted_port(unsigned long port)
{
/* For IDE registers, value is not shifted */
if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6)
return 0;
else
return 1;
}
#if defined(CONFIG_NE2000) || defined(CONFIG_NE2000_MODULE)
#define CHECK_AX88796L_PORT(port) \
((port >= AX88796L_IO_BASE) && (port < (AX88796L_IO_BASE+0x20)))
#else
#define CHECK_AX88796L_PORT(port) (0)
#endif
/*
* General outline: remap really low stuff [eventually] to SuperIO,
* stuff in PCI IO space (at or above window at pci.h:PCIBIOS_MIN_IO)
* is mapped through the PCI IO window. Stuff with high bits (PXSEG)
* should be way beyond the window, and is used w/o translation for
* compatibility.
*/
u8 r7780rp_inb(unsigned long port)
{
if (CHECK_AX88796L_PORT(port))
return ctrl_inw(port88796l(port, 0)) & 0xff;
else if (PXSEG(port))
return ctrl_inb(port);
else if (is_pci_ioaddr(port) || shifted_port(port))
return ctrl_inb(pci_ioaddr(port));
return ctrl_inw(port2adr(port)) & 0xff;
}
u8 r7780rp_inb_p(unsigned long port)
{
u8 v;
if (CHECK_AX88796L_PORT(port))
v = ctrl_inw(port88796l(port, 0)) & 0xff;
else if (PXSEG(port))
v = ctrl_inb(port);
else if (is_pci_ioaddr(port) || shifted_port(port))
v = ctrl_inb(pci_ioaddr(port));
else
v = ctrl_inw(port2adr(port)) & 0xff;
ctrl_delay();
return v;
}
u16 r7780rp_inw(unsigned long port)
{
if (CHECK_AX88796L_PORT(port))
maybebadio(port);
else if (PXSEG(port))
return ctrl_inw(port);
else if (is_pci_ioaddr(port) || shifted_port(port))
return ctrl_inw(pci_ioaddr(port));
else
maybebadio(port);
return 0;
}
u32 r7780rp_inl(unsigned long port)
{
if (CHECK_AX88796L_PORT(port))
maybebadio(port);
else if (PXSEG(port))
return ctrl_inl(port);
else if (is_pci_ioaddr(port) || shifted_port(port))
return ctrl_inl(pci_ioaddr(port));
else
maybebadio(port);
return 0;
}
void r7780rp_outb(u8 value, unsigned long port)
{
if (CHECK_AX88796L_PORT(port))
ctrl_outw(value, port88796l(port, 0));
else if (PXSEG(port))
ctrl_outb(value, port);
else if (is_pci_ioaddr(port) || shifted_port(port))
ctrl_outb(value, pci_ioaddr(port));
else
ctrl_outw(value, port2adr(port));
}
void r7780rp_outb_p(u8 value, unsigned long port)
{
if (CHECK_AX88796L_PORT(port))
ctrl_outw(value, port88796l(port, 0));
else if (PXSEG(port))
ctrl_outb(value, port);
else if (is_pci_ioaddr(port) || shifted_port(port))
ctrl_outb(value, pci_ioaddr(port));
else
ctrl_outw(value, port2adr(port));
ctrl_delay();
}
void r7780rp_outw(u16 value, unsigned long port)
{
if (CHECK_AX88796L_PORT(port))
maybebadio(port);
else if (PXSEG(port))
ctrl_outw(value, port);
else if (is_pci_ioaddr(port) || shifted_port(port))
ctrl_outw(value, pci_ioaddr(port));
else
maybebadio(port);
}
void r7780rp_outl(u32 value, unsigned long port)
{
if (CHECK_AX88796L_PORT(port))
maybebadio(port);
else if (PXSEG(port))
ctrl_outl(value, port);
else if (is_pci_ioaddr(port) || shifted_port(port))
ctrl_outl(value, pci_ioaddr(port));
else
maybebadio(port);
}
void r7780rp_insb(unsigned long port, void *dst, unsigned long count)
{
volatile u16 *p;
u8 *buf = dst;
if (CHECK_AX88796L_PORT(port)) {
p = (volatile u16 *)port88796l(port, 0);
while (count--)
*buf++ = *p & 0xff;
} else if (PXSEG(port)) {
while (count--)
*buf++ = *(volatile u8 *)port;
} else if (is_pci_ioaddr(port) || shifted_port(port)) {
volatile u8 *bp = (volatile u8 *)pci_ioaddr(port);
while (count--)
*buf++ = *bp;
} else {
p = (volatile u16 *)port2adr(port);
while (count--)
*buf++ = *p & 0xff;
}
}
void r7780rp_insw(unsigned long port, void *dst, unsigned long count)
{
volatile u16 *p;
u16 *buf = dst;
if (CHECK_AX88796L_PORT(port))
p = (volatile u16 *)port88796l(port, 1);
else if (PXSEG(port))
p = (volatile u16 *)port;
else if (is_pci_ioaddr(port) || shifted_port(port))
p = (volatile u16 *)pci_ioaddr(port);
else
p = (volatile u16 *)port2adr(port);
while (count--)
*buf++ = *p;
}
void r7780rp_insl(unsigned long port, void *dst, unsigned long count)
{
u32 *buf = dst;
if (CHECK_AX88796L_PORT(port))
maybebadio(port);
else if (is_pci_ioaddr(port) || shifted_port(port)) {
volatile u32 *p = (volatile u32 *)pci_ioaddr(port);
while (count--)
*buf++ = *p;
} else
maybebadio(port);
}
void r7780rp_outsb(unsigned long port, const void *src, unsigned long count)
{
volatile u16 *p;
const u8 *buf = src;
if (CHECK_AX88796L_PORT(port)) {
p = (volatile u16 *)port88796l(port, 0);
while (count--)
*p = *buf++;
} else if (PXSEG(port))
while (count--)
ctrl_outb(*buf++, port);
else if (is_pci_ioaddr(port) || shifted_port(port)) {
volatile u8 *bp = (volatile u8 *)pci_ioaddr(port);
while (count--)
*bp = *buf++;
} else {
p = (volatile u16 *)port2adr(port);
while (count--)
*p = *buf++;
}
}
void r7780rp_outsw(unsigned long port, const void *src, unsigned long count)
{
volatile u16 *p;
const u16 *buf = src;
if (CHECK_AX88796L_PORT(port))
p = (volatile u16 *)port88796l(port, 1);
else if (PXSEG(port))
p = (volatile u16 *)port;
else if (is_pci_ioaddr(port) || shifted_port(port))
p = (volatile u16 *)pci_ioaddr(port);
else
p = (volatile u16 *)port2adr(port);
while (count--)
*p = *buf++;
}
void r7780rp_outsl(unsigned long port, const void *src, unsigned long count)
{
const u32 *buf = src;
if (CHECK_AX88796L_PORT(port))
maybebadio(port);
else if (is_pci_ioaddr(port) || shifted_port(port)) {
volatile u32 *p = (volatile u32 *)pci_ioaddr(port);
while (count--)
*p = *buf++;
} else
maybebadio(port);
}
void __iomem *r7780rp_ioport_map(unsigned long port, unsigned int size)
{
if (CHECK_AX88796L_PORT(port))
return (void __iomem *)port88796l(port, size > 1);
else if (PXSEG(port))
return (void __iomem *)port;
else if (is_pci_ioaddr(port) || shifted_port(port))
return (void __iomem *)pci_ioaddr(port);
return (void __iomem *)port2adr(port);
}

View file

@ -0,0 +1,117 @@
/*
* linux/arch/sh/boards/renesas/r7780rp/irq.c
*
* Copyright (C) 2000 Kazumoto Kojima
*
* Renesas Solutions Highlander R7780RP-1 Support.
*
* Modified for R7780RP-1 by
* Atom Create Engineering Co., Ltd. 2002.
*/
#include <linux/config.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/r7780rp/r7780rp.h>
#ifdef CONFIG_SH_R7780MP
static int mask_pos[] = {12, 11, 9, 14, 15, 8, 13, 6, 5, 4, 3, 2, 0, 0, 1, 0};
#else
static int mask_pos[] = {15, 14, 13, 12, 11, 10, 9, 8, 7, 5, 6, 4, 0, 1, 2, 0};
#endif
static void enable_r7780rp_irq(unsigned int irq);
static void disable_r7780rp_irq(unsigned int irq);
/* shutdown is same as "disable" */
#define shutdown_r7780rp_irq disable_r7780rp_irq
static void ack_r7780rp_irq(unsigned int irq);
static void end_r7780rp_irq(unsigned int irq);
static unsigned int startup_r7780rp_irq(unsigned int irq)
{
enable_r7780rp_irq(irq);
return 0; /* never anything pending */
}
static void disable_r7780rp_irq(unsigned int irq)
{
unsigned short val;
unsigned short mask = 0xffff ^ (0x0001 << mask_pos[irq]);
/* Set the priority in IPR to 0 */
val = ctrl_inw(IRLCNTR1);
val &= mask;
ctrl_outw(val, IRLCNTR1);
}
static void enable_r7780rp_irq(unsigned int irq)
{
unsigned short val;
unsigned short value = (0x0001 << mask_pos[irq]);
/* Set priority in IPR back to original value */
val = ctrl_inw(IRLCNTR1);
val |= value;
ctrl_outw(val, IRLCNTR1);
}
static void ack_r7780rp_irq(unsigned int irq)
{
disable_r7780rp_irq(irq);
}
static void end_r7780rp_irq(unsigned int irq)
{
if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
enable_r7780rp_irq(irq);
}
static struct hw_interrupt_type r7780rp_irq_type = {
.typename = "R7780RP-IRQ",
.startup = startup_r7780rp_irq,
.shutdown = shutdown_r7780rp_irq,
.enable = enable_r7780rp_irq,
.disable = disable_r7780rp_irq,
.ack = ack_r7780rp_irq,
.end = end_r7780rp_irq,
};
static void make_r7780rp_irq(unsigned int irq)
{
disable_irq_nosync(irq);
irq_desc[irq].handler = &r7780rp_irq_type;
disable_r7780rp_irq(irq);
}
/*
* Initialize IRQ setting
*/
void __init init_r7780rp_IRQ(void)
{
int i;
/* IRL0=PCI Slot #A
* IRL1=PCI Slot #B
* IRL2=PCI Slot #C
* IRL3=PCI Slot #D
* IRL4=CF Card
* IRL5=CF Card Insert
* IRL6=M66596
* IRL7=SD Card
* IRL8=Touch Panel
* IRL9=SCI
* IRL10=Serial
* IRL11=Extention #A
* IRL11=Extention #B
* IRL12=Debug LAN
* IRL13=Push Switch
* IRL14=ZiggBee IO
*/
for (i=0; i<15; i++)
make_r7780rp_irq(i);
}

View file

@ -0,0 +1,45 @@
/*
* Copyright (C) Atom Create Engineering Co., Ltd.
*
* May be copied or modified under the terms of GNU General Public
* License. See linux/COPYING for more information.
*
* This file contains Renesas Solutions HIGHLANDER R7780RP-1 specific LED code.
*/
#include <linux/config.h>
#include <linux/sched.h>
#include <asm/io.h>
#include <asm/r7780rp/r7780rp.h>
/* Cycle the LED's in the clasic Knightriger/Sun pattern */
void heartbeat_r7780rp(void)
{
static unsigned int cnt = 0, period = 0;
volatile unsigned short *p = (volatile unsigned short *)PA_OBLED;
static unsigned bit = 0, up = 1;
unsigned bit_pos[] = {2, 1, 0, 3, 6, 5, 4, 7};
cnt += 1;
if (cnt < period)
return;
cnt = 0;
/* Go through the points (roughly!):
* f(0)=10, f(1)=16, f(2)=20, f(5)=35, f(int)->110
*/
period = 110 - ((300 << FSHIFT)/((avenrun[0]/5) + (3<<FSHIFT)));
*p = 1 << bit_pos[bit];
if (up)
if (bit == 7) {
bit--;
up = 0;
} else
bit++;
else if (bit == 0)
up = 1;
else
bit--;
}

View file

@ -0,0 +1,163 @@
/*
* arch/sh/boards/renesas/r7780rp/setup.c
*
* Copyright (C) 2002 Atom Create Engineering Co., Ltd.
* Copyright (C) 2005, 2006 Paul Mundt
*
* Renesas Solutions Highlander R7780RP-1 Support.
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*/
#include <linux/init.h>
#include <linux/platform_device.h>
#include <asm/machvec.h>
#include <asm/r7780rp/r7780rp.h>
#include <asm/clock.h>
#include <asm/io.h>
extern void heartbeat_r7780rp(void);
extern void init_r7780rp_IRQ(void);
static struct resource m66596_usb_host_resources[] = {
[0] = {
.start = 0xa4800000,
.end = 0xa4ffffff,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = 6, /* irq number */
.end = 6,
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device m66596_usb_host_device = {
.name = "m66596-hcd",
.id = 0,
.dev = {
.dma_mask = NULL, /* don't use dma */
.coherent_dma_mask = 0xffffffff,
},
.num_resources = ARRAY_SIZE(m66596_usb_host_resources),
.resource = m66596_usb_host_resources,
};
static struct platform_device *r7780rp_devices[] __initdata = {
&m66596_usb_host_device,
};
static int __init r7780rp_devices_setup(void)
{
return platform_add_devices(r7780rp_devices,
ARRAY_SIZE(r7780rp_devices));
}
/*
* Platform specific clocks
*/
static void ivdr_clk_enable(struct clk *clk)
{
ctrl_outw(ctrl_inw(PA_IVDRCTL) | (1 << 8), PA_IVDRCTL);
}
static void ivdr_clk_disable(struct clk *clk)
{
ctrl_outw(ctrl_inw(PA_IVDRCTL) & ~(1 << 8), PA_IVDRCTL);
}
static struct clk_ops ivdr_clk_ops = {
.enable = ivdr_clk_enable,
.disable = ivdr_clk_disable,
};
static struct clk ivdr_clk = {
.name = "ivdr_clk",
.ops = &ivdr_clk_ops,
};
static struct clk *r7780rp_clocks[] = {
&ivdr_clk,
};
static void r7780rp_power_off(void)
{
#ifdef CONFIG_SH_R7780MP
ctrl_outw(0x0001, PA_POFF);
#endif
}
/*
* Initialize the board
*/
static void __init r7780rp_setup(char **cmdline_p)
{
u16 ver = ctrl_inw(PA_VERREG);
int i;
device_initcall(r7780rp_devices_setup);
printk(KERN_INFO "Renesas Solutions Highlander R7780RP-1 support.\n");
printk(KERN_INFO "Board version: %d (revision %d), "
"FPGA version: %d (revision %d)\n",
(ver >> 12) & 0xf, (ver >> 8) & 0xf,
(ver >> 4) & 0xf, ver & 0xf);
/*
* Enable the important clocks right away..
*/
for (i = 0; i < ARRAY_SIZE(r7780rp_clocks); i++) {
struct clk *clk = r7780rp_clocks[i];
clk_register(clk);
clk_enable(clk);
}
ctrl_outw(0x0000, PA_OBLED); /* Clear LED. */
#ifndef CONFIG_SH_R7780MP
ctrl_outw(0x0001, PA_SDPOW); /* SD Power ON */
#endif
ctrl_outw(ctrl_inw(PA_IVDRCTL) | 0x0100, PA_IVDRCTL); /* Si13112 */
pm_power_off = r7780rp_power_off;
}
/*
* The Machine Vector
*/
struct sh_machine_vector mv_r7780rp __initmv = {
.mv_name = "Highlander R7780RP-1",
.mv_setup = r7780rp_setup,
.mv_nr_irqs = 109,
.mv_inb = r7780rp_inb,
.mv_inw = r7780rp_inw,
.mv_inl = r7780rp_inl,
.mv_outb = r7780rp_outb,
.mv_outw = r7780rp_outw,
.mv_outl = r7780rp_outl,
.mv_inb_p = r7780rp_inb_p,
.mv_inw_p = r7780rp_inw,
.mv_inl_p = r7780rp_inl,
.mv_outb_p = r7780rp_outb_p,
.mv_outw_p = r7780rp_outw,
.mv_outl_p = r7780rp_outl,
.mv_insb = r7780rp_insb,
.mv_insw = r7780rp_insw,
.mv_insl = r7780rp_insl,
.mv_outsb = r7780rp_outsb,
.mv_outsw = r7780rp_outsw,
.mv_outsl = r7780rp_outsl,
.mv_ioport_map = r7780rp_ioport_map,
.mv_init_irq = init_r7780rp_IRQ,
#ifdef CONFIG_HEARTBEAT
.mv_heartbeat = heartbeat_r7780rp,
#endif
};
ALIAS_MV(r7780rp)

View file

@ -0,0 +1,12 @@
if SH_RTS7751R2D
menu "RTS7751R2D options"
config RTS7751R2D_REV11
bool "RTS7751R2D Rev. 1.1 board support"
help
Selecting this option will support version rev. 1.1.
endmenu
endif

View file

@ -1,10 +1,6 @@
#
# Makefile for the RTS7751R2D specific parts of the kernel
#
# Note! Dependencies are done automagically by 'make dep', which also
# removes any old dependencies. DON'T put your own dependencies here
# unless it's something special (ie not a .c file).
#
obj-y := mach.o setup.o io.o irq.o led.o
obj-y := setup.o io.o irq.o
obj-$(CONFIG_HEARTBEAT) += led.o

View file

@ -1,6 +1,4 @@
/*
* linux/arch/sh/kernel/io_rts7751r2d.c
*
* Copyright (C) 2001 Ian da Silva, Jeremy Siegel
* Based largely on io_se.c.
*
@ -10,16 +8,12 @@
* placeholder code from io_rts7751r2d.c left in with the
* expectation of later SuperIO and PCMCIA access.
*/
#include <linux/kernel.h>
#include <linux/types.h>
#include <asm/io.h>
#include <asm/rts7751r2d/rts7751r2d.h>
#include <asm/addrspace.h>
#include <linux/module.h>
#include <linux/pci.h>
#include "../../../drivers/pci/pci-sh7751.h"
#include <asm/rts7751r2d/rts7751r2d.h>
#include <asm/io.h>
#include <asm/addrspace.h>
/*
* The 7751R RTS7751R2D uses the built-in PCI controller (PCIC)
@ -28,22 +22,6 @@
* like the other Solution Engine boards.
*/
#define PCIIOBR (volatile long *)PCI_REG(SH7751_PCIIOBR)
#define PCIMBR (volatile long *)PCI_REG(SH7751_PCIMBR)
#define PCI_IO_AREA SH7751_PCI_IO_BASE
#define PCI_MEM_AREA SH7751_PCI_CONFIG_BASE
#define PCI_IOMAP(adr) (PCI_IO_AREA + (adr & ~SH7751_PCIIOBR_MASK))
#define maybebadio(name,port) \
printk("bad PC-like io %s for port 0x%lx at 0x%08x\n", \
#name, (port), (__u32) __builtin_return_address(0))
static inline void delay(void)
{
ctrl_inw(0xa0000000);
}
static inline unsigned long port2adr(unsigned int port)
{
if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6)
@ -52,7 +30,7 @@ static inline unsigned long port2adr(unsigned int port)
else
return (PA_AREA5_IO + 0x1000 + ((port-0x1f0) << 1));
else
maybebadio(port2adr, (unsigned long)port);
maybebadio((unsigned long)port);
return port;
}
@ -81,17 +59,6 @@ static inline int shifted_port(unsigned long port)
return 1;
}
/* In case someone configures the kernel w/o PCI support: in that */
/* scenario, don't ever bother to check for PCI-window addresses */
/* NOTE: WINDOW CHECK MAY BE A BIT OFF, HIGH PCIBIOS_MIN_IO WRAPS? */
#if defined(CONFIG_PCI)
#define CHECK_SH7751_PCIIO(port) \
((port >= PCIBIOS_MIN_IO) && (port < (PCIBIOS_MIN_IO + SH7751_PCI_IO_SIZE)))
#else
#define CHECK_SH7751_PCIIO(port) (0)
#endif
#if defined(CONFIG_NE2000) || defined(CONFIG_NE2000_MODULE)
#define CHECK_AX88796L_PORT(port) \
((port >= AX88796L_IO_BASE) && (port < (AX88796L_IO_BASE+0x20)))
@ -112,8 +79,8 @@ unsigned char rts7751r2d_inb(unsigned long port)
return (*(volatile unsigned short *)port88796l(port, 0)) & 0xff;
else if (PXSEG(port))
return *(volatile unsigned char *)port;
else if (CHECK_SH7751_PCIIO(port) || shifted_port(port))
return *(volatile unsigned char *)PCI_IOMAP(port);
else if (is_pci_ioaddr(port) || shifted_port(port))
return *(volatile unsigned char *)pci_ioaddr(port);
else
return (*(volatile unsigned short *)port2adr(port) & 0xff);
}
@ -126,11 +93,12 @@ unsigned char rts7751r2d_inb_p(unsigned long port)
v = (*(volatile unsigned short *)port88796l(port, 0)) & 0xff;
else if (PXSEG(port))
v = *(volatile unsigned char *)port;
else if (CHECK_SH7751_PCIIO(port) || shifted_port(port))
v = *(volatile unsigned char *)PCI_IOMAP(port);
else if (is_pci_ioaddr(port) || shifted_port(port))
v = *(volatile unsigned char *)pci_ioaddr(port);
else
v = (*(volatile unsigned short *)port2adr(port) & 0xff);
delay();
ctrl_delay();
return v;
}
@ -138,13 +106,13 @@ unsigned char rts7751r2d_inb_p(unsigned long port)
unsigned short rts7751r2d_inw(unsigned long port)
{
if (CHECK_AX88796L_PORT(port))
maybebadio(inw, port);
maybebadio(port);
else if (PXSEG(port))
return *(volatile unsigned short *)port;
else if (CHECK_SH7751_PCIIO(port) || shifted_port(port))
return *(volatile unsigned short *)PCI_IOMAP(port);
else if (is_pci_ioaddr(port) || shifted_port(port))
return *(volatile unsigned short *)pci_ioaddr(port);
else
maybebadio(inw, port);
maybebadio(port);
return 0;
}
@ -152,13 +120,13 @@ unsigned short rts7751r2d_inw(unsigned long port)
unsigned int rts7751r2d_inl(unsigned long port)
{
if (CHECK_AX88796L_PORT(port))
maybebadio(inl, port);
maybebadio(port);
else if (PXSEG(port))
return *(volatile unsigned long *)port;
else if (CHECK_SH7751_PCIIO(port) || shifted_port(port))
return *(volatile unsigned long *)PCI_IOMAP(port);
else if (is_pci_ioaddr(port) || shifted_port(port))
return *(volatile unsigned long *)pci_ioaddr(port);
else
maybebadio(inl, port);
maybebadio(port);
return 0;
}
@ -169,8 +137,8 @@ void rts7751r2d_outb(unsigned char value, unsigned long port)
*((volatile unsigned short *)port88796l(port, 0)) = value;
else if (PXSEG(port))
*(volatile unsigned char *)port = value;
else if (CHECK_SH7751_PCIIO(port) || shifted_port(port))
*(volatile unsigned char *)PCI_IOMAP(port) = value;
else if (is_pci_ioaddr(port) || shifted_port(port))
*(volatile unsigned char *)pci_ioaddr(port) = value;
else
*(volatile unsigned short *)port2adr(port) = value;
}
@ -181,144 +149,153 @@ void rts7751r2d_outb_p(unsigned char value, unsigned long port)
*((volatile unsigned short *)port88796l(port, 0)) = value;
else if (PXSEG(port))
*(volatile unsigned char *)port = value;
else if (CHECK_SH7751_PCIIO(port) || shifted_port(port))
*(volatile unsigned char *)PCI_IOMAP(port) = value;
else if (is_pci_ioaddr(port) || shifted_port(port))
*(volatile unsigned char *)pci_ioaddr(port) = value;
else
*(volatile unsigned short *)port2adr(port) = value;
delay();
ctrl_delay();
}
void rts7751r2d_outw(unsigned short value, unsigned long port)
{
if (CHECK_AX88796L_PORT(port))
maybebadio(outw, port);
maybebadio(port);
else if (PXSEG(port))
*(volatile unsigned short *)port = value;
else if (CHECK_SH7751_PCIIO(port) || shifted_port(port))
*(volatile unsigned short *)PCI_IOMAP(port) = value;
else if (is_pci_ioaddr(port) || shifted_port(port))
*(volatile unsigned short *)pci_ioaddr(port) = value;
else
maybebadio(outw, port);
maybebadio(port);
}
void rts7751r2d_outl(unsigned int value, unsigned long port)
{
if (CHECK_AX88796L_PORT(port))
maybebadio(outl, port);
maybebadio(port);
else if (PXSEG(port))
*(volatile unsigned long *)port = value;
else if (CHECK_SH7751_PCIIO(port) || shifted_port(port))
*(volatile unsigned long *)PCI_IOMAP(port) = value;
else if (is_pci_ioaddr(port) || shifted_port(port))
*(volatile unsigned long *)pci_ioaddr(port) = value;
else
maybebadio(outl, port);
maybebadio(port);
}
void rts7751r2d_insb(unsigned long port, void *addr, unsigned long count)
{
unsigned long a = (unsigned long)addr;
volatile __u8 *bp;
volatile __u16 *p;
unsigned char *s = addr;
if (CHECK_AX88796L_PORT(port)) {
p = (volatile unsigned short *)port88796l(port, 0);
while (count--) *s++ = *p & 0xff;
while (count--)
ctrl_outb(*p & 0xff, a++);
} else if (PXSEG(port))
while (count--) *s++ = *(volatile unsigned char *)port;
else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) {
bp = (__u8 *)PCI_IOMAP(port);
while (count--) *s++ = *bp;
while (count--)
ctrl_outb(ctrl_inb(port), a++);
else if (is_pci_ioaddr(port) || shifted_port(port)) {
bp = (__u8 *)pci_ioaddr(port);
while (count--)
ctrl_outb(*bp, a++);
} else {
p = (volatile unsigned short *)port2adr(port);
while (count--) *s++ = *p & 0xff;
while (count--)
ctrl_outb(*p & 0xff, a++);
}
}
void rts7751r2d_insw(unsigned long port, void *addr, unsigned long count)
{
unsigned long a = (unsigned long)addr;
volatile __u16 *p;
__u16 *s = addr;
if (CHECK_AX88796L_PORT(port))
p = (volatile unsigned short *)port88796l(port, 1);
else if (PXSEG(port))
p = (volatile unsigned short *)port;
else if (CHECK_SH7751_PCIIO(port) || shifted_port(port))
p = (volatile unsigned short *)PCI_IOMAP(port);
else if (is_pci_ioaddr(port) || shifted_port(port))
p = (volatile unsigned short *)pci_ioaddr(port);
else
p = (volatile unsigned short *)port2adr(port);
while (count--) *s++ = *p;
while (count--)
ctrl_outw(*p, a++);
}
void rts7751r2d_insl(unsigned long port, void *addr, unsigned long count)
{
if (CHECK_AX88796L_PORT(port))
maybebadio(insl, port);
else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) {
volatile __u32 *p = (__u32 *)PCI_IOMAP(port);
__u32 *s = addr;
maybebadio(port);
else if (is_pci_ioaddr(port) || shifted_port(port)) {
unsigned long a = (unsigned long)addr;
while (count--) *s++ = *p;
while (count--) {
ctrl_outl(ctrl_inl(pci_ioaddr(port)), a);
a += 4;
}
} else
maybebadio(insl, port);
maybebadio(port);
}
void rts7751r2d_outsb(unsigned long port, const void *addr, unsigned long count)
{
unsigned long a = (unsigned long)addr;
volatile __u8 *bp;
volatile __u16 *p;
const __u8 *s = addr;
if (CHECK_AX88796L_PORT(port)) {
p = (volatile unsigned short *)port88796l(port, 0);
while (count--) *p = *s++;
while (count--)
*p = ctrl_inb(a++);
} else if (PXSEG(port))
while (count--) *(volatile unsigned char *)port = *s++;
else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) {
bp = (__u8 *)PCI_IOMAP(port);
while (count--) *bp = *s++;
while (count--)
ctrl_outb(a++, port);
else if (is_pci_ioaddr(port) || shifted_port(port)) {
bp = (__u8 *)pci_ioaddr(port);
while (count--)
*bp = ctrl_inb(a++);
} else {
p = (volatile unsigned short *)port2adr(port);
while (count--) *p = *s++;
while (count--)
*p = ctrl_inb(a++);
}
}
void rts7751r2d_outsw(unsigned long port, const void *addr, unsigned long count)
{
unsigned long a = (unsigned long)addr;
volatile __u16 *p;
const __u16 *s = addr;
if (CHECK_AX88796L_PORT(port))
p = (volatile unsigned short *)port88796l(port, 1);
else if (PXSEG(port))
p = (volatile unsigned short *)port;
else if (CHECK_SH7751_PCIIO(port) || shifted_port(port))
p = (volatile unsigned short *)PCI_IOMAP(port);
else if (is_pci_ioaddr(port) || shifted_port(port))
p = (volatile unsigned short *)pci_ioaddr(port);
else
p = (volatile unsigned short *)port2adr(port);
while (count--) *p = *s++;
while (count--) {
ctrl_outw(*p, a);
a += 2;
}
}
void rts7751r2d_outsl(unsigned long port, const void *addr, unsigned long count)
{
if (CHECK_AX88796L_PORT(port))
maybebadio(outsl, port);
else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) {
volatile __u32 *p = (__u32 *)PCI_IOMAP(port);
const __u32 *s = addr;
maybebadio(port);
else if (is_pci_ioaddr(port) || shifted_port(port)) {
unsigned long a = (unsigned long)addr;
while (count--) *p = *s++;
while (count--) {
ctrl_outl(ctrl_inl(a), pci_ioaddr(port));
a += 4;
}
} else
maybebadio(outsl, port);
maybebadio(port);
}
void *rts7751r2d_ioremap(unsigned long offset, unsigned long size)
{
if (offset >= 0xfd000000)
return (void *)offset;
else
return (void *)P2SEGADDR(offset);
}
EXPORT_SYMBOL(rts7751r2d_ioremap);
unsigned long rts7751r2d_isa_port2addr(unsigned long offset)
{
return port2adr(offset);

View file

@ -41,30 +41,24 @@ static unsigned int startup_rts7751r2d_irq(unsigned int irq)
static void disable_rts7751r2d_irq(unsigned int irq)
{
unsigned long flags;
unsigned short val;
unsigned short mask = 0xffff ^ (0x0001 << mask_pos[irq]);
/* Set the priority in IPR to 0 */
local_irq_save(flags);
val = ctrl_inw(IRLCNTR1);
val &= mask;
ctrl_outw(val, IRLCNTR1);
local_irq_restore(flags);
}
static void enable_rts7751r2d_irq(unsigned int irq)
{
unsigned long flags;
unsigned short val;
unsigned short value = (0x0001 << mask_pos[irq]);
/* Set priority in IPR back to original value */
local_irq_save(flags);
val = ctrl_inw(IRLCNTR1);
val |= value;
ctrl_outw(val, IRLCNTR1);
local_irq_restore(flags);
}
int rts7751r2d_irq_demux(int irq)

View file

@ -12,8 +12,6 @@
#include <asm/io.h>
#include <asm/rts7751r2d/rts7751r2d.h>
extern unsigned int debug_counter;
#ifdef CONFIG_HEARTBEAT
#include <linux/sched.h>
@ -55,12 +53,3 @@ void rts7751r2d_led(unsigned short value)
ctrl_outw(value, PA_OUTPORT);
}
void debug_led_disp(void)
{
unsigned short value;
value = (unsigned short)debug_counter++;
rts7751r2d_led(value);
if (value == 0xff)
debug_counter = 0;
}

View file

@ -1,69 +0,0 @@
/*
* linux/arch/sh/kernel/mach_rts7751r2d.c
*
* Minor tweak of mach_se.c file to reference rts7751r2d-specific items.
*
* May be copied or modified under the terms of the GNU General Public
* License. See linux/COPYING for more information.
*
* Machine vector for the Renesas Technology sales RTS7751R2D
*/
#include <linux/init.h>
#include <linux/types.h>
#include <asm/machvec.h>
#include <asm/rtc.h>
#include <asm/irq.h>
#include <asm/rts7751r2d/io.h>
extern void heartbeat_rts7751r2d(void);
extern void init_rts7751r2d_IRQ(void);
extern void *rts7751r2d_ioremap(unsigned long, unsigned long);
extern int rts7751r2d_irq_demux(int irq);
extern void *voyagergx_consistent_alloc(struct device *, size_t, dma_addr_t *, gfp_t);
extern int voyagergx_consistent_free(struct device *, size_t, void *, dma_addr_t);
/*
* The Machine Vector
*/
struct sh_machine_vector mv_rts7751r2d __initmv = {
.mv_nr_irqs = 72,
.mv_inb = rts7751r2d_inb,
.mv_inw = rts7751r2d_inw,
.mv_inl = rts7751r2d_inl,
.mv_outb = rts7751r2d_outb,
.mv_outw = rts7751r2d_outw,
.mv_outl = rts7751r2d_outl,
.mv_inb_p = rts7751r2d_inb_p,
.mv_inw_p = rts7751r2d_inw,
.mv_inl_p = rts7751r2d_inl,
.mv_outb_p = rts7751r2d_outb_p,
.mv_outw_p = rts7751r2d_outw,
.mv_outl_p = rts7751r2d_outl,
.mv_insb = rts7751r2d_insb,
.mv_insw = rts7751r2d_insw,
.mv_insl = rts7751r2d_insl,
.mv_outsb = rts7751r2d_outsb,
.mv_outsw = rts7751r2d_outsw,
.mv_outsl = rts7751r2d_outsl,
.mv_ioremap = rts7751r2d_ioremap,
.mv_isa_port2addr = rts7751r2d_isa_port2addr,
.mv_init_irq = init_rts7751r2d_IRQ,
#ifdef CONFIG_HEARTBEAT
.mv_heartbeat = heartbeat_rts7751r2d,
#endif
.mv_irq_demux = rts7751r2d_irq_demux,
#ifdef CONFIG_USB_OHCI_HCD
.mv_consistent_alloc = voyagergx_consistent_alloc,
.mv_consistent_free = voyagergx_consistent_free,
#endif
};
ALIAS_MV(rts7751r2d)

View file

@ -1,31 +1,142 @@
/*
* linux/arch/sh/kernel/setup_rts7751r2d.c
*
* Copyright (C) 2000 Kazumoto Kojima
*
* Renesas Technology Sales RTS7751R2D Support.
*
* Modified for RTS7751R2D by
* Atom Create Engineering Co., Ltd. 2002.
* Copyright (C) 2002 Atom Create Engineering Co., Ltd.
* Copyright (C) 2004 - 2006 Paul Mundt
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*/
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/serial_8250.h>
#include <linux/pm.h>
#include <asm/io.h>
#include <asm/rts7751r2d/rts7751r2d.h>
#include <asm/machvec.h>
#include <asm/mach/rts7751r2d.h>
#include <asm/voyagergx.h>
unsigned int debug_counter;
extern void heartbeat_rts7751r2d(void);
extern void init_rts7751r2d_IRQ(void);
extern int rts7751r2d_irq_demux(int irq);
const char *get_system_type(void)
extern void *voyagergx_consistent_alloc(struct device *, size_t, dma_addr_t *, gfp_t);
extern int voyagergx_consistent_free(struct device *, size_t, void *, dma_addr_t);
static struct plat_serial8250_port uart_platform_data[] = {
{
.membase = (void *)VOYAGER_UART_BASE,
.mapbase = VOYAGER_UART_BASE,
.iotype = UPIO_MEM,
.irq = VOYAGER_UART0_IRQ,
.flags = UPF_BOOT_AUTOCONF,
.regshift = 2,
.uartclk = (9600 * 16),
}, {
.flags = 0,
},
};
static void __init voyagergx_serial_init(void)
{
return "RTS7751R2D";
unsigned long val;
/*
* GPIO Control
*/
val = inl(GPIO_MUX_HIGH);
val |= 0x00001fe0;
outl(val, GPIO_MUX_HIGH);
/*
* Power Mode Gate
*/
val = inl(POWER_MODE0_GATE);
val |= (POWER_MODE0_GATE_U0 | POWER_MODE0_GATE_U1);
outl(val, POWER_MODE0_GATE);
val = inl(POWER_MODE1_GATE);
val |= (POWER_MODE1_GATE_U0 | POWER_MODE1_GATE_U1);
outl(val, POWER_MODE1_GATE);
}
static struct platform_device uart_device = {
.name = "serial8250",
.id = -1,
.dev = {
.platform_data = uart_platform_data,
},
};
static struct platform_device *rts7751r2d_devices[] __initdata = {
&uart_device,
};
static int __init rts7751r2d_devices_setup(void)
{
return platform_add_devices(rts7751r2d_devices,
ARRAY_SIZE(rts7751r2d_devices));
}
static void rts7751r2d_power_off(void)
{
ctrl_outw(0x0001, PA_POWOFF);
}
/*
* Initialize the board
*/
void __init platform_setup(void)
static void __init rts7751r2d_setup(char **cmdline_p)
{
printk(KERN_INFO "Renesas Technology Sales RTS7751R2D support.\n");
device_initcall(rts7751r2d_devices_setup);
ctrl_outw(0x0000, PA_OUTPORT);
debug_counter = 0;
pm_power_off = rts7751r2d_power_off;
voyagergx_serial_init();
printk(KERN_INFO "Renesas Technology Sales RTS7751R2D support.\n");
}
/*
* The Machine Vector
*/
struct sh_machine_vector mv_rts7751r2d __initmv = {
.mv_name = "RTS7751R2D",
.mv_setup = rts7751r2d_setup,
.mv_nr_irqs = 72,
.mv_inb = rts7751r2d_inb,
.mv_inw = rts7751r2d_inw,
.mv_inl = rts7751r2d_inl,
.mv_outb = rts7751r2d_outb,
.mv_outw = rts7751r2d_outw,
.mv_outl = rts7751r2d_outl,
.mv_inb_p = rts7751r2d_inb_p,
.mv_inw_p = rts7751r2d_inw,
.mv_inl_p = rts7751r2d_inl,
.mv_outb_p = rts7751r2d_outb_p,
.mv_outw_p = rts7751r2d_outw,
.mv_outl_p = rts7751r2d_outl,
.mv_insb = rts7751r2d_insb,
.mv_insw = rts7751r2d_insw,
.mv_insl = rts7751r2d_insl,
.mv_outsb = rts7751r2d_outsb,
.mv_outsw = rts7751r2d_outsw,
.mv_outsl = rts7751r2d_outsl,
.mv_init_irq = init_rts7751r2d_IRQ,
#ifdef CONFIG_HEARTBEAT
.mv_heartbeat = heartbeat_rts7751r2d,
#endif
.mv_irq_demux = rts7751r2d_irq_demux,
#ifdef CONFIG_USB_SM501
.mv_consistent_alloc = voyagergx_consistent_alloc,
.mv_consistent_free = voyagergx_consistent_free,
#endif
};
ALIAS_MV(rts7751r2d)

View file

@ -0,0 +1 @@
obj-y := setup.o

View file

@ -0,0 +1,109 @@
/*
* Renesas Technology SH7710 VoIP Gateway
*
* Copyright (C) 2006 Ranjit Deshpande
* Kenati Technologies Inc.
*
* May be copied or modified under the terms of the GNU General Public
* License. See linux/COPYING for more information.
*/
#include <linux/init.h>
#include <asm/machvec.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <asm/irq.h>
/*
* Initialize IRQ setting
*/
static void __init sh7710voipgw_init_irq(void)
{
/* Disable all interrupts in IPR registers */
ctrl_outw(0x0, INTC_IPRA);
ctrl_outw(0x0, INTC_IPRB);
ctrl_outw(0x0, INTC_IPRC);
ctrl_outw(0x0, INTC_IPRD);
ctrl_outw(0x0, INTC_IPRE);
ctrl_outw(0x0, INTC_IPRF);
ctrl_outw(0x0, INTC_IPRG);
ctrl_outw(0x0, INTC_IPRH);
ctrl_outw(0x0, INTC_IPRI);
/* Ack all interrupt sources in the IRR0 register */
ctrl_outb(0x3f, INTC_IRR0);
/* Use IRQ0 - IRQ3 as active low interrupt lines i.e. disable
* IRL mode.
*/
ctrl_outw(0x2aa, INTC_ICR1);
/* Now make IPR interrupts */
make_ipr_irq(TIMER2_IRQ, TIMER2_IPR_ADDR,
TIMER2_IPR_POS, TIMER2_PRIORITY);
make_ipr_irq(WDT_IRQ, WDT_IPR_ADDR, WDT_IPR_POS, WDT_PRIORITY);
/* SCIF0 */
make_ipr_irq(SCIF0_ERI_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS,
SCIF0_PRIORITY);
make_ipr_irq(SCIF0_RXI_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS,
SCIF0_PRIORITY);
make_ipr_irq(SCIF0_BRI_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS,
SCIF0_PRIORITY);
make_ipr_irq(SCIF0_TXI_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS,
SCIF0_PRIORITY);
/* DMAC-1 */
make_ipr_irq(DMTE0_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY);
make_ipr_irq(DMTE1_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY);
make_ipr_irq(DMTE2_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY);
make_ipr_irq(DMTE3_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY);
/* DMAC-2 */
make_ipr_irq(DMTE4_IRQ, DMA2_IPR_ADDR, DMA2_IPR_POS, DMA2_PRIORITY);
make_ipr_irq(DMTE4_IRQ, DMA2_IPR_ADDR, DMA2_IPR_POS, DMA2_PRIORITY);
/* IPSEC */
make_ipr_irq(IPSEC_IRQ, IPSEC_IPR_ADDR, IPSEC_IPR_POS, IPSEC_PRIORITY);
/* EDMAC */
make_ipr_irq(EDMAC0_IRQ, EDMAC0_IPR_ADDR, EDMAC0_IPR_POS,
EDMAC0_PRIORITY);
make_ipr_irq(EDMAC1_IRQ, EDMAC1_IPR_ADDR, EDMAC1_IPR_POS,
EDMAC1_PRIORITY);
make_ipr_irq(EDMAC2_IRQ, EDMAC2_IPR_ADDR, EDMAC2_IPR_POS,
EDMAC2_PRIORITY);
/* SIOF0 */
make_ipr_irq(SIOF0_ERI_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS,
SIOF0_PRIORITY);
make_ipr_irq(SIOF0_TXI_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS,
SIOF0_PRIORITY);
make_ipr_irq(SIOF0_RXI_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS,
SIOF0_PRIORITY);
make_ipr_irq(SIOF0_CCI_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS,
SIOF0_PRIORITY);
/* SIOF1 */
make_ipr_irq(SIOF1_ERI_IRQ, SIOF1_IPR_ADDR, SIOF1_IPR_POS,
SIOF1_PRIORITY);
make_ipr_irq(SIOF1_TXI_IRQ, SIOF1_IPR_ADDR, SIOF1_IPR_POS,
SIOF1_PRIORITY);
make_ipr_irq(SIOF1_RXI_IRQ, SIOF1_IPR_ADDR, SIOF1_IPR_POS,
SIOF1_PRIORITY);
make_ipr_irq(SIOF1_CCI_IRQ, SIOF1_IPR_ADDR, SIOF1_IPR_POS,
SIOF1_PRIORITY);
/* SLIC IRQ's */
make_ipr_irq(IRQ1_IRQ, IRQ1_IPR_ADDR, IRQ1_IPR_POS, IRQ1_PRIORITY);
make_ipr_irq(IRQ2_IRQ, IRQ2_IPR_ADDR, IRQ2_IPR_POS, IRQ2_PRIORITY);
}
/*
* The Machine Vector
*/
struct sh_machine_vector mv_sh7710voipgw __initmv = {
.mv_name = "SH7710 VoIP Gateway",
.mv_nr_irqs = 104,
.mv_init_irq = sh7710voipgw_init_irq,
};
ALIAS_MV(sh7710voipgw)

View file

@ -5,66 +5,25 @@
* Based largely on io_se.c.
*
* I/O routine for Hitachi 7751 Systemh.
*
*/
#include <linux/kernel.h>
#include <linux/types.h>
#include <asm/systemh/7751systemh.h>
#include <linux/pci.h>
#include <asm/systemh7751.h>
#include <asm/addrspace.h>
#include <asm/io.h>
#include <linux/pci.h>
#include "../../drivers/pci/pci-sh7751.h"
/*
* The 7751 SystemH Engine uses the built-in PCI controller (PCIC)
* of the 7751 processor, and has a SuperIO accessible on its memory
* bus.
*/
#define PCIIOBR (volatile long *)PCI_REG(SH7751_PCIIOBR)
#define PCIMBR (volatile long *)PCI_REG(SH7751_PCIMBR)
#define PCI_IO_AREA SH7751_PCI_IO_BASE
#define PCI_MEM_AREA SH7751_PCI_CONFIG_BASE
#define PCI_IOMAP(adr) (PCI_IO_AREA + (adr & ~SH7751_PCIIOBR_MASK))
#define ETHER_IOMAP(adr) (0xB3000000 + (adr)) /*map to 16bits access area
of smc lan chip*/
#define maybebadio(name,port) \
printk("bad PC-like io %s for port 0x%lx at 0x%08x\n", \
#name, (port), (__u32) __builtin_return_address(0))
static inline void delay(void)
{
ctrl_inw(0xa0000000);
}
static inline volatile __u16 *
port2adr(unsigned int port)
{
if (port >= 0x2000)
return (volatile __u16 *) (PA_MRSHPC + (port - 0x2000));
#if 0
else
return (volatile __u16 *) (PA_SUPERIO + (port << 1));
#endif
maybebadio(name,(unsigned long)port);
maybebadio((unsigned long)port);
return (volatile __u16*)port;
}
/* In case someone configures the kernel w/o PCI support: in that */
/* scenario, don't ever bother to check for PCI-window addresses */
/* NOTE: WINDOW CHECK MAY BE A BIT OFF, HIGH PCIBIOS_MIN_IO WRAPS? */
#if defined(CONFIG_PCI)
#define CHECK_SH7751_PCIIO(port) \
((port >= PCIBIOS_MIN_IO) && (port < (PCIBIOS_MIN_IO + SH7751_PCI_IO_SIZE)))
#else
#define CHECK_SH7751_PCIIO(port) (0)
#endif
/*
* General outline: remap really low stuff [eventually] to SuperIO,
* stuff in PCI IO space (at or above window at pci.h:PCIBIOS_MIN_IO)
@ -76,8 +35,8 @@ unsigned char sh7751systemh_inb(unsigned long port)
{
if (PXSEG(port))
return *(volatile unsigned char *)port;
else if (CHECK_SH7751_PCIIO(port))
return *(volatile unsigned char *)PCI_IOMAP(port);
else if (is_pci_ioaddr(port))
return *(volatile unsigned char *)pci_ioaddr(port);
else if (port <= 0x3F1)
return *(volatile unsigned char *)ETHER_IOMAP(port);
else
@ -90,13 +49,13 @@ unsigned char sh7751systemh_inb_p(unsigned long port)
if (PXSEG(port))
v = *(volatile unsigned char *)port;
else if (CHECK_SH7751_PCIIO(port))
v = *(volatile unsigned char *)PCI_IOMAP(port);
else if (is_pci_ioaddr(port))
v = *(volatile unsigned char *)pci_ioaddr(port);
else if (port <= 0x3F1)
v = *(volatile unsigned char *)ETHER_IOMAP(port);
else
v = (*port2adr(port))&0xff;
delay();
ctrl_delay();
return v;
}
@ -104,14 +63,14 @@ unsigned short sh7751systemh_inw(unsigned long port)
{
if (PXSEG(port))
return *(volatile unsigned short *)port;
else if (CHECK_SH7751_PCIIO(port))
return *(volatile unsigned short *)PCI_IOMAP(port);
else if (is_pci_ioaddr(port))
return *(volatile unsigned short *)pci_ioaddr(port);
else if (port >= 0x2000)
return *port2adr(port);
else if (port <= 0x3F1)
return *(volatile unsigned int *)ETHER_IOMAP(port);
else
maybebadio(inw, port);
maybebadio(port);
return 0;
}
@ -119,14 +78,14 @@ unsigned int sh7751systemh_inl(unsigned long port)
{
if (PXSEG(port))
return *(volatile unsigned long *)port;
else if (CHECK_SH7751_PCIIO(port))
return *(volatile unsigned int *)PCI_IOMAP(port);
else if (is_pci_ioaddr(port))
return *(volatile unsigned int *)pci_ioaddr(port);
else if (port >= 0x2000)
return *port2adr(port);
else if (port <= 0x3F1)
return *(volatile unsigned int *)ETHER_IOMAP(port);
else
maybebadio(inl, port);
maybebadio(port);
return 0;
}
@ -135,8 +94,8 @@ void sh7751systemh_outb(unsigned char value, unsigned long port)
if (PXSEG(port))
*(volatile unsigned char *)port = value;
else if (CHECK_SH7751_PCIIO(port))
*((unsigned char*)PCI_IOMAP(port)) = value;
else if (is_pci_ioaddr(port))
*((unsigned char*)pci_ioaddr(port)) = value;
else if (port <= 0x3F1)
*(volatile unsigned char *)ETHER_IOMAP(port) = value;
else
@ -147,37 +106,37 @@ void sh7751systemh_outb_p(unsigned char value, unsigned long port)
{
if (PXSEG(port))
*(volatile unsigned char *)port = value;
else if (CHECK_SH7751_PCIIO(port))
*((unsigned char*)PCI_IOMAP(port)) = value;
else if (is_pci_ioaddr(port))
*((unsigned char*)pci_ioaddr(port)) = value;
else if (port <= 0x3F1)
*(volatile unsigned char *)ETHER_IOMAP(port) = value;
else
*(port2adr(port)) = value;
delay();
ctrl_delay();
}
void sh7751systemh_outw(unsigned short value, unsigned long port)
{
if (PXSEG(port))
*(volatile unsigned short *)port = value;
else if (CHECK_SH7751_PCIIO(port))
*((unsigned short *)PCI_IOMAP(port)) = value;
else if (is_pci_ioaddr(port))
*((unsigned short *)pci_ioaddr(port)) = value;
else if (port >= 0x2000)
*port2adr(port) = value;
else if (port <= 0x3F1)
*(volatile unsigned short *)ETHER_IOMAP(port) = value;
else
maybebadio(outw, port);
maybebadio(port);
}
void sh7751systemh_outl(unsigned int value, unsigned long port)
{
if (PXSEG(port))
*(volatile unsigned long *)port = value;
else if (CHECK_SH7751_PCIIO(port))
*((unsigned long*)PCI_IOMAP(port)) = value;
else if (is_pci_ioaddr(port))
*((unsigned long*)pci_ioaddr(port)) = value;
else
maybebadio(outl, port);
maybebadio(port);
}
void sh7751systemh_insb(unsigned long port, void *addr, unsigned long count)
@ -194,7 +153,7 @@ void sh7751systemh_insw(unsigned long port, void *addr, unsigned long count)
void sh7751systemh_insl(unsigned long port, void *addr, unsigned long count)
{
maybebadio(insl, port);
maybebadio(port);
}
void sh7751systemh_outsb(unsigned long port, const void *addr, unsigned long count)
@ -211,73 +170,5 @@ void sh7751systemh_outsw(unsigned long port, const void *addr, unsigned long cou
void sh7751systemh_outsl(unsigned long port, const void *addr, unsigned long count)
{
maybebadio(outsw, port);
}
/* For read/write calls, just copy generic (pass-thru); PCIMBR is */
/* already set up. For a larger memory space, these would need to */
/* reset PCIMBR as needed on a per-call basis... */
unsigned char sh7751systemh_readb(unsigned long addr)
{
return *(volatile unsigned char*)addr;
}
unsigned short sh7751systemh_readw(unsigned long addr)
{
return *(volatile unsigned short*)addr;
}
unsigned int sh7751systemh_readl(unsigned long addr)
{
return *(volatile unsigned long*)addr;
}
void sh7751systemh_writeb(unsigned char b, unsigned long addr)
{
*(volatile unsigned char*)addr = b;
}
void sh7751systemh_writew(unsigned short b, unsigned long addr)
{
*(volatile unsigned short*)addr = b;
}
void sh7751systemh_writel(unsigned int b, unsigned long addr)
{
*(volatile unsigned long*)addr = b;
}
/* Map ISA bus address to the real address. Only for PCMCIA. */
/* ISA page descriptor. */
static __u32 sh_isa_memmap[256];
#if 0
static int
sh_isa_mmap(__u32 start, __u32 length, __u32 offset)
{
int idx;
if (start >= 0x100000 || (start & 0xfff) || (length != 0x1000))
return -1;
idx = start >> 12;
sh_isa_memmap[idx] = 0xb8000000 + (offset &~ 0xfff);
printk("sh_isa_mmap: start %x len %x offset %x (idx %x paddr %x)\n",
start, length, offset, idx, sh_isa_memmap[idx]);
return 0;
}
#endif
unsigned long
sh7751systemh_isa_port2addr(unsigned long offset)
{
int idx;
idx = (offset >> 12) & 0xff;
offset &= 0xfff;
return sh_isa_memmap[idx] + offset;
maybebadio(port);
}

View file

@ -15,7 +15,7 @@
#include <linux/hdreg.h>
#include <linux/ide.h>
#include <asm/io.h>
#include <asm/mach/7751systemh.h>
#include <asm/systemh7751.h>
#include <asm/smc37c93x.h>
/* address of external interrupt mask register
@ -57,12 +57,9 @@ static void shutdown_systemh_irq(unsigned int irq)
static void disable_systemh_irq(unsigned int irq)
{
if (systemh_irq_mask_register) {
unsigned long flags;
unsigned long val, mask = 0x01 << 1;
/* Clear the "irq"th bit in the mask and set it in the request */
local_irq_save(flags);
val = ctrl_inl((unsigned long)systemh_irq_mask_register);
val &= ~mask;
ctrl_outl(val, (unsigned long)systemh_irq_mask_register);
@ -70,23 +67,18 @@ static void disable_systemh_irq(unsigned int irq)
val = ctrl_inl((unsigned long)systemh_irq_request_register);
val |= mask;
ctrl_outl(val, (unsigned long)systemh_irq_request_register);
local_irq_restore(flags);
}
}
static void enable_systemh_irq(unsigned int irq)
{
if (systemh_irq_mask_register) {
unsigned long flags;
unsigned long val, mask = 0x01 << 1;
/* Set "irq"th bit in the mask register */
local_irq_save(flags);
val = ctrl_inl((unsigned long)systemh_irq_mask_register);
val |= mask;
ctrl_outl(val, (unsigned long)systemh_irq_mask_register);
local_irq_restore(flags);
}
}

View file

@ -15,28 +15,21 @@
* for more details.
*/
#include <linux/init.h>
#include <asm/mach/7751systemh.h>
#include <asm/mach/io.h>
#include <asm/machvec.h>
#include <asm/systemh7751.h>
extern void make_systemh_irq(unsigned int irq);
const char *get_system_type(void)
{
return "7751 SystemH";
}
/*
* Initialize IRQ setting
*/
void __init init_7751systemh_IRQ(void)
static void __init sh7751systemh_init_irq(void)
{
/* make_ipr_irq(10, BCR_ILCRD, 1, 0x0f-10); LAN */
/* make_ipr_irq(14, BCR_ILCRA, 2, 0x0f-4); */
make_systemh_irq(0xb); /* Ethernet interrupt */
}
struct sh_machine_vector mv_7751systemh __initmv = {
.mv_name = "7751 SystemH",
.mv_nr_irqs = 72,
.mv_inb = sh7751systemh_inb,
@ -60,21 +53,6 @@ struct sh_machine_vector mv_7751systemh __initmv = {
.mv_outsw = sh7751systemh_outsw,
.mv_outsl = sh7751systemh_outsl,
.mv_readb = sh7751systemh_readb,
.mv_readw = sh7751systemh_readw,
.mv_readl = sh7751systemh_readl,
.mv_writeb = sh7751systemh_writeb,
.mv_writew = sh7751systemh_writew,
.mv_writel = sh7751systemh_writel,
.mv_isa_port2addr = sh7751systemh_isa_port2addr,
.mv_init_irq = init_7751systemh_IRQ,
.mv_init_irq = sh7751system_init_irq,
};
ALIAS_MV(7751systemh)
int __init platform_setup(void)
{
return 0;
}

View file

@ -9,22 +9,17 @@
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <asm/io.h>
#include <asm/machvec.h>
#include <asm/mach/io.h>
extern int saturn_irq_demux(int irq_nr);
const char *get_system_type(void)
{
return "Sega Saturn";
}
/*
* The Machine Vector
*/
struct sh_machine_vector mv_saturn __initmv = {
.mv_name = "Sega Saturn",
.mv_nr_irqs = 80, /* Fix this later */
.mv_isa_port2addr = saturn_isa_port2addr,
@ -33,11 +28,4 @@ struct sh_machine_vector mv_saturn __initmv = {
.mv_ioremap = saturn_ioremap,
.mv_iounmap = saturn_iounmap,
};
ALIAS_MV(saturn)
int __init platform_setup(void)
{
return 0;
}

View file

@ -9,8 +9,8 @@
*/
#include <linux/kernel.h>
#include <asm/mach/se7300.h>
#include <asm/io.h>
#include <asm/se7300.h>
#define badio(fn, a) panic("bad i/o operation %s for %08lx.", #fn, a)
@ -99,6 +99,7 @@ bad_outb(struct iop *p, unsigned char value, unsigned long port)
badio(inw, port);
}
#ifdef CONFIG_SMC91X
/* MSTLANEX01 LAN at 0xb400:0000 */
static struct iop laniop = {
.start = 0x300,
@ -110,6 +111,7 @@ static struct iop laniop = {
.outb = simple_outb,
.outw = simple_outw,
};
#endif
/* NE2000 pc card NIC */
static struct iop neiop = {
@ -123,6 +125,7 @@ static struct iop neiop = {
.outw = simple_outw,
};
#ifdef CONFIG_IDE
/* CF in CF slot */
static struct iop cfiop = {
.base = 0xb0600000,
@ -132,12 +135,13 @@ static struct iop cfiop = {
.outb = pcc_outb,
.outw = simple_outw,
};
#endif
static __inline__ struct iop *
port2iop(unsigned long port)
{
if (0) ;
#if defined(CONFIG_SMC91111)
#if defined(CONFIG_SMC91X)
else if (laniop.check(&laniop, port))
return &laniop;
#endif

View file

@ -11,7 +11,7 @@
#include <linux/irq.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <asm/mach/se7300.h>
#include <asm/se7300.h>
/*
* Initialize IRQ setting

View file

@ -12,24 +12,10 @@
*/
#include <linux/sched.h>
#include <asm/mach/se7300.h>
static void
mach_led(int position, int value)
{
volatile unsigned short *p = (volatile unsigned short *) PA_LED;
if (value) {
*p |= (1 << 8);
} else {
*p &= ~(1 << 8);
}
}
#include <asm/se7300.h>
/* Cycle the LED's in the clasic Knightrider/Sun pattern */
void
heartbeat_7300se(void)
void heartbeat_7300se(void)
{
static unsigned int cnt = 0, period = 0;
volatile unsigned short *p = (volatile unsigned short *) PA_LED;

View file

@ -9,23 +9,16 @@
#include <linux/init.h>
#include <asm/machvec.h>
#include <asm/machvec_init.h>
#include <asm/mach/io.h>
#include <asm/se7300.h>
void heartbeat_7300se(void);
void init_7300se_IRQ(void);
const char *
get_system_type(void)
{
return "SolutionEngine 7300";
}
/*
* The Machine Vector
*/
struct sh_machine_vector mv_7300se __initmv = {
.mv_name = "SolutionEngine 7300",
.mv_nr_irqs = 109,
.mv_inb = sh7300se_inb,
.mv_inw = sh7300se_inw,
@ -53,13 +46,4 @@ struct sh_machine_vector mv_7300se __initmv = {
.mv_heartbeat = heartbeat_7300se,
#endif
};
ALIAS_MV(7300se)
/*
* Initialize the board
*/
void __init
platform_setup(void)
{
}

View file

@ -99,6 +99,7 @@ bad_outb(struct iop *p, unsigned char value, unsigned long port)
badio(inw, port);
}
#ifdef CONFIG_SMC91X
/* MSTLANEX01 LAN at 0xb400:0000 */
static struct iop laniop = {
.start = 0x300,
@ -110,6 +111,7 @@ static struct iop laniop = {
.outb = simple_outb,
.outw = simple_outw,
};
#endif
/* NE2000 pc card NIC */
static struct iop neiop = {
@ -123,6 +125,7 @@ static struct iop neiop = {
.outw = simple_outw,
};
#ifdef CONFIG_IDE
/* CF in CF slot */
static struct iop cfiop = {
.base = 0xb0600000,
@ -132,12 +135,13 @@ static struct iop cfiop = {
.outb = pcc_outb,
.outw = simple_outw,
};
#endif
static __inline__ struct iop *
port2iop(unsigned long port)
{
if (0) ;
#if defined(CONFIG_SMC91111)
#if defined(CONFIG_SMC91X)
else if (laniop.check(&laniop, port))
return &laniop;
#endif

View file

@ -7,7 +7,6 @@
* Modified for SH-Mobile SolutionEngine 73180 Support
* by YOSHII Takashi <yoshii-takashi@hitachi-ul.co.jp>
*
*
*/
#include <linux/init.h>
@ -16,14 +15,6 @@
#include <asm/io.h>
#include <asm/mach/se73180.h>
static int
intreq2irq(int i)
{
if (i == 5)
return 10;
return 32 + 7 - i;
}
static int
irq2intreq(int irq)
{

View file

@ -14,21 +14,8 @@
#include <linux/sched.h>
#include <asm/mach/se73180.h>
static void
mach_led(int position, int value)
{
volatile unsigned short *p = (volatile unsigned short *) PA_LED;
if (value) {
*p |= (1 << LED_SHIFT);
} else {
*p &= ~(1 << LED_SHIFT);
}
}
/* Cycle the LED's in the clasic Knightrider/Sun pattern */
void
heartbeat_73180se(void)
void heartbeat_73180se(void)
{
static unsigned int cnt = 0, period = 0;
volatile unsigned short *p = (volatile unsigned short *) PA_LED;

View file

@ -11,23 +11,17 @@
#include <linux/init.h>
#include <asm/machvec.h>
#include <asm/machvec_init.h>
#include <asm/mach/io.h>
#include <asm/se73180.h>
#include <asm/irq.h>
void heartbeat_73180se(void);
void init_73180se_IRQ(void);
const char *
get_system_type(void)
{
return "SolutionEngine 73180";
}
/*
* The Machine Vector
*/
struct sh_machine_vector mv_73180se __initmv = {
.mv_name = "SolutionEngine 73180",
.mv_nr_irqs = 108,
.mv_inb = sh73180se_inb,
.mv_inw = sh73180se_inw,
@ -51,17 +45,9 @@ struct sh_machine_vector mv_73180se __initmv = {
.mv_outsl = sh73180se_outsl,
.mv_init_irq = init_73180se_IRQ,
.mv_irq_demux = shmse_irq_demux,
#ifdef CONFIG_HEARTBEAT
.mv_heartbeat = heartbeat_73180se,
#endif
};
ALIAS_MV(73180se)
/*
* Initialize the board
*/
void __init
platform_setup(void)
{
}

View file

@ -0,0 +1,7 @@
#
# Makefile for the 7343 SolutionEngine specific parts of the kernel
#
obj-y := setup.o io.o irq.o
obj-$(CONFIG_HEARTBEAT) += led.o

275
arch/sh/boards/se/7343/io.c Normal file
View file

@ -0,0 +1,275 @@
/*
* arch/sh/boards/se/7343/io.c
*
* I/O routine for SH-Mobile3AS 7343 SolutionEngine.
*
*/
#include <linux/config.h>
#include <linux/kernel.h>
#include <asm/io.h>
#include <asm/mach/se7343.h>
#define badio(fn, a) panic("bad i/o operation %s for %08lx.", #fn, a)
struct iop {
unsigned long start, end;
unsigned long base;
struct iop *(*check) (struct iop * p, unsigned long port);
unsigned char (*inb) (struct iop * p, unsigned long port);
unsigned short (*inw) (struct iop * p, unsigned long port);
void (*outb) (struct iop * p, unsigned char value, unsigned long port);
void (*outw) (struct iop * p, unsigned short value, unsigned long port);
};
struct iop *
simple_check(struct iop *p, unsigned long port)
{
static int count;
if (count < 100)
count++;
port &= 0xFFFF;
if ((p->start <= port) && (port <= p->end))
return p;
else
badio(check, port);
}
struct iop *
ide_check(struct iop *p, unsigned long port)
{
if (((0x1f0 <= port) && (port <= 0x1f7)) || (port == 0x3f7))
return p;
return NULL;
}
unsigned char
simple_inb(struct iop *p, unsigned long port)
{
return *(unsigned char *) (p->base + port);
}
unsigned short
simple_inw(struct iop *p, unsigned long port)
{
return *(unsigned short *) (p->base + port);
}
void
simple_outb(struct iop *p, unsigned char value, unsigned long port)
{
*(unsigned char *) (p->base + port) = value;
}
void
simple_outw(struct iop *p, unsigned short value, unsigned long port)
{
*(unsigned short *) (p->base + port) = value;
}
unsigned char
pcc_inb(struct iop *p, unsigned long port)
{
unsigned long addr = p->base + port + 0x40000;
unsigned long v;
if (port & 1)
addr += 0x00400000;
v = *(volatile unsigned char *) addr;
return v;
}
void
pcc_outb(struct iop *p, unsigned char value, unsigned long port)
{
unsigned long addr = p->base + port + 0x40000;
if (port & 1)
addr += 0x00400000;
*(volatile unsigned char *) addr = value;
}
unsigned char
bad_inb(struct iop *p, unsigned long port)
{
badio(inb, port);
}
void
bad_outb(struct iop *p, unsigned char value, unsigned long port)
{
badio(inw, port);
}
#ifdef CONFIG_SMC91X
/* MSTLANEX01 LAN at 0xb400:0000 */
static struct iop laniop = {
.start = 0x00,
.end = 0x0F,
.base = 0x04000000,
.check = simple_check,
.inb = simple_inb,
.inw = simple_inw,
.outb = simple_outb,
.outw = simple_outw,
};
#endif
#ifdef CONFIG_NE2000
/* NE2000 pc card NIC */
static struct iop neiop = {
.start = 0x280,
.end = 0x29f,
.base = 0xb0600000 + 0x80, /* soft 0x280 -> hard 0x300 */
.check = simple_check,
.inb = pcc_inb,
.inw = simple_inw,
.outb = pcc_outb,
.outw = simple_outw,
};
#endif
#ifdef CONFIG_IDE
/* CF in CF slot */
static struct iop cfiop = {
.base = 0xb0600000,
.check = ide_check,
.inb = pcc_inb,
.inw = simple_inw,
.outb = pcc_outb,
.outw = simple_outw,
};
#endif
static __inline__ struct iop *
port2iop(unsigned long port)
{
if (0) ;
#if defined(CONFIG_SMC91X)
else if (laniop.check(&laniop, port))
return &laniop;
#endif
#if defined(CONFIG_NE2000)
else if (neiop.check(&neiop, port))
return &neiop;
#endif
#if defined(CONFIG_IDE)
else if (cfiop.check(&cfiop, port))
return &cfiop;
#endif
else
return NULL;
}
static inline void
delay(void)
{
ctrl_inw(0xac000000);
ctrl_inw(0xac000000);
}
unsigned char
sh7343se_inb(unsigned long port)
{
struct iop *p = port2iop(port);
return (p->inb) (p, port);
}
unsigned char
sh7343se_inb_p(unsigned long port)
{
unsigned char v = sh7343se_inb(port);
delay();
return v;
}
unsigned short
sh7343se_inw(unsigned long port)
{
struct iop *p = port2iop(port);
return (p->inw) (p, port);
}
unsigned int
sh7343se_inl(unsigned long port)
{
badio(inl, port);
}
void
sh7343se_outb(unsigned char value, unsigned long port)
{
struct iop *p = port2iop(port);
(p->outb) (p, value, port);
}
void
sh7343se_outb_p(unsigned char value, unsigned long port)
{
sh7343se_outb(value, port);
delay();
}
void
sh7343se_outw(unsigned short value, unsigned long port)
{
struct iop *p = port2iop(port);
(p->outw) (p, value, port);
}
void
sh7343se_outl(unsigned int value, unsigned long port)
{
badio(outl, port);
}
void
sh7343se_insb(unsigned long port, void *addr, unsigned long count)
{
unsigned char *a = addr;
struct iop *p = port2iop(port);
while (count--)
*a++ = (p->inb) (p, port);
}
void
sh7343se_insw(unsigned long port, void *addr, unsigned long count)
{
unsigned short *a = addr;
struct iop *p = port2iop(port);
while (count--)
*a++ = (p->inw) (p, port);
}
void
sh7343se_insl(unsigned long port, void *addr, unsigned long count)
{
badio(insl, port);
}
void
sh7343se_outsb(unsigned long port, const void *addr, unsigned long count)
{
unsigned char *a = (unsigned char *) addr;
struct iop *p = port2iop(port);
while (count--)
(p->outb) (p, *a++, port);
}
void
sh7343se_outsw(unsigned long port, const void *addr, unsigned long count)
{
unsigned short *a = (unsigned short *) addr;
struct iop *p = port2iop(port);
while (count--)
(p->outw) (p, *a++, port);
}
void
sh7343se_outsl(unsigned long port, const void *addr, unsigned long count)
{
badio(outsw, port);
}

View file

@ -0,0 +1,193 @@
/*
* arch/sh/boards/se/7343/irq.c
*
*/
#include <linux/config.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <asm/mach/se7343.h>
static void
disable_intreq_irq(unsigned int irq)
{
int bit = irq - OFFCHIP_IRQ_BASE;
u16 val;
val = ctrl_inw(PA_CPLD_IMSK);
val |= 1 << bit;
ctrl_outw(val, PA_CPLD_IMSK);
}
static void
enable_intreq_irq(unsigned int irq)
{
int bit = irq - OFFCHIP_IRQ_BASE;
u16 val;
val = ctrl_inw(PA_CPLD_IMSK);
val &= ~(1 << bit);
ctrl_outw(val, PA_CPLD_IMSK);
}
static void
mask_and_ack_intreq_irq(unsigned int irq)
{
disable_intreq_irq(irq);
}
static unsigned int
startup_intreq_irq(unsigned int irq)
{
enable_intreq_irq(irq);
return 0;
}
static void
shutdown_intreq_irq(unsigned int irq)
{
disable_intreq_irq(irq);
}
static void
end_intreq_irq(unsigned int irq)
{
if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
enable_intreq_irq(irq);
}
static struct hw_interrupt_type intreq_irq_type = {
.typename = "FPGA-IRQ",
.startup = startup_intreq_irq,
.shutdown = shutdown_intreq_irq,
.enable = enable_intreq_irq,
.disable = disable_intreq_irq,
.ack = mask_and_ack_intreq_irq,
.end = end_intreq_irq
};
static void
make_intreq_irq(unsigned int irq)
{
disable_irq_nosync(irq);
irq_desc[irq].handler = &intreq_irq_type;
disable_intreq_irq(irq);
}
int
shmse_irq_demux(int irq)
{
int bit;
volatile u16 val;
if (irq == IRQ5_IRQ) {
/* Read status Register */
val = ctrl_inw(PA_CPLD_ST);
bit = ffs(val);
if (bit != 0)
return OFFCHIP_IRQ_BASE + bit - 1;
}
return irq;
}
/* IRQ5 is multiplexed between the following sources:
* 1. PC Card socket
* 2. Extension slot
* 3. USB Controller
* 4. Serial Controller
*
* We configure IRQ5 as a cascade IRQ.
*/
static struct irqaction irq5 = { no_action, 0, CPU_MASK_NONE, "IRQ5-cascade",
NULL, NULL};
/*
* Initialize IRQ setting
*/
void __init
init_7343se_IRQ(void)
{
/* Setup Multiplexed interrupts */
ctrl_outw(8, PA_CPLD_MODESET); /* Set all CPLD interrupts to active
* low.
*/
/* Mask all CPLD controller interrupts */
ctrl_outw(0x0fff, PA_CPLD_IMSK);
/* PC Card interrupts */
make_intreq_irq(PC_IRQ0);
make_intreq_irq(PC_IRQ1);
make_intreq_irq(PC_IRQ2);
make_intreq_irq(PC_IRQ3);
/* Extension Slot Interrupts */
make_intreq_irq(EXT_IRQ0);
make_intreq_irq(EXT_IRQ1);
make_intreq_irq(EXT_IRQ2);
make_intreq_irq(EXT_IRQ3);
/* USB Controller interrupts */
make_intreq_irq(USB_IRQ0);
make_intreq_irq(USB_IRQ1);
/* Serial Controller interrupts */
make_intreq_irq(UART_IRQ0);
make_intreq_irq(UART_IRQ1);
/* Setup all external interrupts to be active low */
ctrl_outw(0xaaaa, INTC_ICR1);
make_ipr_irq(IRQ5_IRQ, IRQ5_IPR_ADDR+2, IRQ5_IPR_POS, IRQ5_PRIORITY);
setup_irq(IRQ5_IRQ, &irq5);
/* Set port control to use IRQ5 */
*(u16 *)0xA4050108 &= ~0xc;
make_ipr_irq(SIOF0_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY);
make_ipr_irq(VPU_IRQ, VPU_IPR_ADDR, VPU_IPR_POS, 8);
ctrl_outb(0x0f, INTC_IMCR5); /* enable SCIF IRQ */
make_ipr_irq(DMTE0_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY);
make_ipr_irq(DMTE1_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY);
make_ipr_irq(DMTE2_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY);
make_ipr_irq(DMTE3_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY);
make_ipr_irq(DMTE4_IRQ, DMA2_IPR_ADDR, DMA2_IPR_POS, DMA2_PRIORITY);
make_ipr_irq(DMTE5_IRQ, DMA2_IPR_ADDR, DMA2_IPR_POS, DMA2_PRIORITY);
/* I2C block */
make_ipr_irq(IIC0_ALI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, IIC0_PRIORITY);
make_ipr_irq(IIC0_TACKI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS,
IIC0_PRIORITY);
make_ipr_irq(IIC0_WAITI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS,
IIC0_PRIORITY);
make_ipr_irq(IIC0_DTEI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, IIC0_PRIORITY);
make_ipr_irq(IIC1_ALI_IRQ, IIC1_IPR_ADDR, IIC1_IPR_POS, IIC1_PRIORITY);
make_ipr_irq(IIC1_TACKI_IRQ, IIC1_IPR_ADDR, IIC1_IPR_POS,
IIC1_PRIORITY);
make_ipr_irq(IIC1_WAITI_IRQ, IIC1_IPR_ADDR, IIC1_IPR_POS,
IIC1_PRIORITY);
make_ipr_irq(IIC1_DTEI_IRQ, IIC1_IPR_ADDR, IIC1_IPR_POS, IIC1_PRIORITY);
/* SIOF */
make_ipr_irq(SIOF0_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY);
/* SIU */
make_ipr_irq(SIU_IRQ, SIU_IPR_ADDR, SIU_IPR_POS, SIU_PRIORITY);
/* VIO interrupt */
make_ipr_irq(CEU_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY);
make_ipr_irq(BEU_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY);
make_ipr_irq(VEU_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY);
/*MFI interrupt*/
make_ipr_irq(MFI_IRQ, MFI_IPR_ADDR, MFI_IPR_POS, MFI_PRIORITY);
/* LCD controller */
make_ipr_irq(LCDC_IRQ, LCDC_IPR_ADDR, LCDC_IPR_POS, LCDC_PRIORITY);
ctrl_outw(0x2000, PA_MRSHPC + 0x0c); /* mrshpc irq enable */
}

View file

@ -0,0 +1,46 @@
/*
* arch/sh/boards/se/7343/led.c
*
*/
#include <linux/config.h>
#include <linux/sched.h>
#include <asm/mach/se7343.h>
/* Cycle the LED's in the clasic Knightrider/Sun pattern */
void heartbeat_7343se(void)
{
static unsigned int cnt = 0, period = 0;
volatile unsigned short *p = (volatile unsigned short *) PA_LED;
static unsigned bit = 0, up = 1;
cnt += 1;
if (cnt < period) {
return;
}
cnt = 0;
/* Go through the points (roughly!):
* f(0)=10, f(1)=16, f(2)=20, f(5)=35,f(inf)->110
*/
period = 110 - ((300 << FSHIFT) / ((avenrun[0] / 5) + (3 << FSHIFT)));
if (up) {
if (bit == 7) {
bit--;
up = 0;
} else {
bit++;
}
} else {
if (bit == 0) {
bit++;
up = 1;
} else {
bit--;
}
}
*p = 1 << (bit + LED_SHIFT);
}

View file

@ -0,0 +1,84 @@
#include <linux/config.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <asm/machvec.h>
#include <asm/mach/se7343.h>
#include <asm/irq.h>
void heartbeat_7343se(void);
void init_7343se_IRQ(void);
static struct resource smc91x_resources[] = {
[0] = {
.start = 0x10000000,
.end = 0x1000000F,
.flags = IORESOURCE_MEM,
},
[1] = {
/*
* shared with other devices via externel
* interrupt controller in FPGA...
*/
.start = EXT_IRQ2,
.end = EXT_IRQ2,
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device smc91x_device = {
.name = "smc91x",
.id = 0,
.num_resources = ARRAY_SIZE(smc91x_resources),
.resource = smc91x_resources,
};
static struct platform_device *smc91x_platform_devices[] __initdata = {
&smc91x_device,
};
static int __init sh7343se_devices_setup(void)
{
return platform_add_devices(smc91x_platform_devices,
ARRAY_SIZE(smc91x_platform_devices));
}
static void __init sh7343se_setup(char **cmdline_p)
{
device_initcall(sh7343se_devices_setup);
}
/*
* The Machine Vector
*/
struct sh_machine_vector mv_7343se __initmv = {
.mv_name = "SolutionEngine 7343",
.mv_setup = sh7343se_setup,
.mv_nr_irqs = 108,
.mv_inb = sh7343se_inb,
.mv_inw = sh7343se_inw,
.mv_inl = sh7343se_inl,
.mv_outb = sh7343se_outb,
.mv_outw = sh7343se_outw,
.mv_outl = sh7343se_outl,
.mv_inb_p = sh7343se_inb_p,
.mv_inw_p = sh7343se_inw,
.mv_inl_p = sh7343se_inl,
.mv_outb_p = sh7343se_outb_p,
.mv_outw_p = sh7343se_outw,
.mv_outl_p = sh7343se_outl,
.mv_insb = sh7343se_insb,
.mv_insw = sh7343se_insw,
.mv_insl = sh7343se_insl,
.mv_outsb = sh7343se_outsb,
.mv_outsw = sh7343se_outsw,
.mv_outsl = sh7343se_outsl,
.mv_init_irq = init_7343se_IRQ,
.mv_irq_demux = shmse_irq_demux,
#ifdef CONFIG_HEARTBEAT
.mv_heartbeat = heartbeat_7343se,
#endif
};
ALIAS_MV(7343se)

View file

@ -2,5 +2,5 @@
# Makefile for the 770x SolutionEngine specific parts of the kernel
#
obj-y := mach.o setup.o io.o irq.o led.o
obj-y := setup.o io.o irq.o
obj-$(CONFIG_HEARTBEAT) += led.o

View file

@ -1,4 +1,4 @@
/* $Id: io.c,v 1.5 2004/02/22 23:08:43 kkojima Exp $
/* $Id: io.c,v 1.7 2006/02/05 21:55:29 lethal Exp $
*
* linux/arch/sh/kernel/io_se.c
*
@ -11,7 +11,7 @@
#include <linux/kernel.h>
#include <linux/types.h>
#include <asm/io.h>
#include <asm/se/se.h>
#include <asm/se.h>
/* SH pcmcia io window base, start and end. */
int sh_pcic_io_wbase = 0xb8400000;
@ -20,11 +20,6 @@ int sh_pcic_io_stop;
int sh_pcic_io_type;
int sh_pcic_io_dummy;
static inline void delay(void)
{
ctrl_inw(0xa0000000);
}
/* MS7750 requires special versions of in*, out* routines, since
PC-like io ports are located at upper half byte of 16-bit word which
can be accessed only with 16-bit wide. */
@ -52,10 +47,6 @@ shifted_port(unsigned long port)
return 1;
}
#define maybebadio(name,port) \
printk("bad PC-like io %s for port 0x%lx at 0x%08x\n", \
#name, (port), (__u32) __builtin_return_address(0))
unsigned char se_inb(unsigned long port)
{
if (sh_pcic_io_start <= port && port <= sh_pcic_io_stop)
@ -76,7 +67,7 @@ unsigned char se_inb_p(unsigned long port)
v = (*port2adr(port) >> 8);
else
v = (*port2adr(port))&0xff;
delay();
ctrl_delay();
return v;
}
@ -86,13 +77,13 @@ unsigned short se_inw(unsigned long port)
(sh_pcic_io_start <= port && port <= sh_pcic_io_stop))
return *port2adr(port);
else
maybebadio(inw, port);
maybebadio(port);
return 0;
}
unsigned int se_inl(unsigned long port)
{
maybebadio(inl, port);
maybebadio(port);
return 0;
}
@ -114,7 +105,7 @@ void se_outb_p(unsigned char value, unsigned long port)
*(port2adr(port)) = value << 8;
else
*(port2adr(port)) = value;
delay();
ctrl_delay();
}
void se_outw(unsigned short value, unsigned long port)
@ -123,12 +114,12 @@ void se_outw(unsigned short value, unsigned long port)
(sh_pcic_io_start <= port && port <= sh_pcic_io_stop))
*port2adr(port) = value;
else
maybebadio(outw, port);
maybebadio(port);
}
void se_outl(unsigned int value, unsigned long port)
{
maybebadio(outl, port);
maybebadio(port);
}
void se_insb(unsigned long port, void *addr, unsigned long count)
@ -159,7 +150,7 @@ void se_insw(unsigned long port, void *addr, unsigned long count)
void se_insl(unsigned long port, void *addr, unsigned long count)
{
maybebadio(insl, port);
maybebadio(port);
}
void se_outsb(unsigned long port, const void *addr, unsigned long count)
@ -190,37 +181,5 @@ void se_outsw(unsigned long port, const void *addr, unsigned long count)
void se_outsl(unsigned long port, const void *addr, unsigned long count)
{
maybebadio(outsw, port);
}
/* Map ISA bus address to the real address. Only for PCMCIA. */
/* ISA page descriptor. */
static __u32 sh_isa_memmap[256];
static int
sh_isa_mmap(__u32 start, __u32 length, __u32 offset)
{
int idx;
if (start >= 0x100000 || (start & 0xfff) || (length != 0x1000))
return -1;
idx = start >> 12;
sh_isa_memmap[idx] = 0xb8000000 + (offset &~ 0xfff);
#if 0
printk("sh_isa_mmap: start %x len %x offset %x (idx %x paddr %x)\n",
start, length, offset, idx, sh_isa_memmap[idx]);
#endif
return 0;
}
unsigned long
se_isa_port2addr(unsigned long offset)
{
int idx;
idx = (offset >> 12) & 0xff;
offset &= 0xfff;
return sh_isa_memmap[idx] + offset;
maybebadio(port);
}

View file

@ -11,7 +11,7 @@
#include <linux/irq.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <asm/se/se.h>
#include <asm/se.h>
/*
* Initialize IRQ setting

View file

@ -9,22 +9,8 @@
* This file contains Solution Engine specific LED code.
*/
#include <asm/se/se.h>
static void mach_led(int position, int value)
{
volatile unsigned short* p = (volatile unsigned short*)PA_LED;
if (value) {
*p |= (1<<8);
} else {
*p &= ~(1<<8);
}
}
#ifdef CONFIG_HEARTBEAT
#include <linux/sched.h>
#include <asm/se.h>
/* Cycle the LED's in the clasic Knightrider/Sun pattern */
void heartbeat_se(void)
@ -64,4 +50,3 @@ void heartbeat_se(void)
*p = 1<<(bit+8);
}
#endif /* CONFIG_HEARTBEAT */

View file

@ -1,67 +0,0 @@
/*
* linux/arch/sh/kernel/mach_se.c
*
* Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com)
*
* May be copied or modified under the terms of the GNU General Public
* License. See linux/COPYING for more information.
*
* Machine vector for the Hitachi SolutionEngine
*/
#include <linux/init.h>
#include <asm/machvec.h>
#include <asm/rtc.h>
#include <asm/machvec_init.h>
#include <asm/se/io.h>
void heartbeat_se(void);
void setup_se(void);
void init_se_IRQ(void);
/*
* The Machine Vector
*/
struct sh_machine_vector mv_se __initmv = {
#if defined(CONFIG_CPU_SH4)
.mv_nr_irqs = 48,
#elif defined(CONFIG_CPU_SUBTYPE_SH7708)
.mv_nr_irqs = 32,
#elif defined(CONFIG_CPU_SUBTYPE_SH7709)
.mv_nr_irqs = 61,
#elif defined(CONFIG_CPU_SUBTYPE_SH7705)
.mv_nr_irqs = 86,
#endif
.mv_inb = se_inb,
.mv_inw = se_inw,
.mv_inl = se_inl,
.mv_outb = se_outb,
.mv_outw = se_outw,
.mv_outl = se_outl,
.mv_inb_p = se_inb_p,
.mv_inw_p = se_inw,
.mv_inl_p = se_inl,
.mv_outb_p = se_outb_p,
.mv_outw_p = se_outw,
.mv_outl_p = se_outl,
.mv_insb = se_insb,
.mv_insw = se_insw,
.mv_insl = se_insl,
.mv_outsb = se_outsb,
.mv_outsw = se_outsw,
.mv_outsl = se_outsl,
.mv_isa_port2addr = se_isa_port2addr,
.mv_init_irq = init_se_IRQ,
#ifdef CONFIG_HEARTBEAT
.mv_heartbeat = heartbeat_se,
#endif
};
ALIAS_MV(se)

View file

@ -7,15 +7,17 @@
* Hitachi SolutionEngine Support.
*
*/
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/hdreg.h>
#include <linux/ide.h>
#include <asm/io.h>
#include <asm/se/se.h>
#include <asm/se/smc37c93x.h>
#include <asm/se.h>
#include <asm/smc37c93x.h>
#include <asm/machvec.h>
void heartbeat_se(void);
void init_se_IRQ(void);
/*
* Configure the Super I/O chip
@ -26,7 +28,8 @@ static void __init smsc_config(int index, int data)
outb_p(data, DATA_PORT);
}
static void __init init_smsc(void)
/* XXX: Another candidate for a more generic cchip machine vector */
static void __init smsc_setup(char **cmdline_p)
{
outb_p(CONFIG_ENTER, CONFIG_PORT);
outb_p(CONFIG_ENTER, CONFIG_PORT);
@ -69,16 +72,46 @@ static void __init init_smsc(void)
outb_p(CONFIG_EXIT, CONFIG_PORT);
}
const char *get_system_type(void)
{
return "SolutionEngine";
}
/*
* Initialize the board
* The Machine Vector
*/
void __init platform_setup(void)
{
init_smsc();
/* XXX: RTC setting comes here */
}
struct sh_machine_vector mv_se __initmv = {
.mv_name = "SolutionEngine",
.mv_setup = smsc_setup,
#if defined(CONFIG_CPU_SH4)
.mv_nr_irqs = 48,
#elif defined(CONFIG_CPU_SUBTYPE_SH7708)
.mv_nr_irqs = 32,
#elif defined(CONFIG_CPU_SUBTYPE_SH7709)
.mv_nr_irqs = 61,
#elif defined(CONFIG_CPU_SUBTYPE_SH7705)
.mv_nr_irqs = 86,
#endif
.mv_inb = se_inb,
.mv_inw = se_inw,
.mv_inl = se_inl,
.mv_outb = se_outb,
.mv_outw = se_outw,
.mv_outl = se_outl,
.mv_inb_p = se_inb_p,
.mv_inw_p = se_inw,
.mv_inl_p = se_inl,
.mv_outb_p = se_outb_p,
.mv_outw_p = se_outw,
.mv_outl_p = se_outl,
.mv_insb = se_insb,
.mv_insw = se_insw,
.mv_insl = se_insl,
.mv_outsb = se_outsb,
.mv_outsw = se_outsw,
.mv_outsl = se_outsl,
.mv_init_irq = init_se_IRQ,
#ifdef CONFIG_HEARTBEAT
.mv_heartbeat = heartbeat_se,
#endif
};
ALIAS_MV(se)

View file

@ -2,7 +2,7 @@
# Makefile for the 7751 SolutionEngine specific parts of the kernel
#
obj-y := mach.o setup.o io.o irq.o led.o
obj-y := setup.o io.o irq.o
obj-$(CONFIG_PCI) += pci.o
obj-$(CONFIG_HEARTBEAT) += led.o

View file

@ -1,6 +1,4 @@
/*
* linux/arch/sh/kernel/io_7751se.c
*
/*
* Copyright (C) 2001 Ian da Silva, Jeremy Siegel
* Based largely on io_se.c.
*
@ -10,96 +8,21 @@
* placeholder code from io_se.c left in with the
* expectation of later SuperIO and PCMCIA access.
*/
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/pci.h>
#include <asm/io.h>
#include <asm/se7751/se7751.h>
#include <asm/se7751.h>
#include <asm/addrspace.h>
#include <linux/pci.h>
#include "../../../drivers/pci/pci-sh7751.h"
#if 0
/******************************************************************
* Variables from io_se.c, related to PCMCIA (not PCI); we're not
* compiling them in, and have removed references from functions
* which follow. [Many checked for IO ports in the range bounded
* by sh_pcic_io_start/stop, and used sh_pcic_io_wbase as offset.
* As start/stop are uninitialized, only port 0x0 would match?]
* When used, remember to adjust names to avoid clash with io_se?
*****************************************************************/
/* SH pcmcia io window base, start and end. */
int sh_pcic_io_wbase = 0xb8400000;
int sh_pcic_io_start;
int sh_pcic_io_stop;
int sh_pcic_io_type;
int sh_pcic_io_dummy;
/*************************************************************/
#endif
/*
* The 7751 Solution Engine uses the built-in PCI controller (PCIC)
* of the 7751 processor, and has a SuperIO accessible via the PCI.
* The board also includes a PCMCIA controller on its memory bus,
* like the other Solution Engine boards.
*/
#define PCIIOBR (volatile long *)PCI_REG(SH7751_PCIIOBR)
#define PCIMBR (volatile long *)PCI_REG(SH7751_PCIMBR)
#define PCI_IO_AREA SH7751_PCI_IO_BASE
#define PCI_MEM_AREA SH7751_PCI_CONFIG_BASE
#define PCI_IOMAP(adr) (PCI_IO_AREA + (adr & ~SH7751_PCIIOBR_MASK))
#define maybebadio(name,port) \
printk("bad PC-like io %s for port 0x%lx at 0x%08x\n", \
#name, (port), (__u32) __builtin_return_address(0))
static inline void delay(void)
{
ctrl_inw(0xa0000000);
}
static inline volatile __u16 *
port2adr(unsigned int port)
static inline volatile u16 *port2adr(unsigned int port)
{
if (port >= 0x2000)
return (volatile __u16 *) (PA_MRSHPC + (port - 0x2000));
#if 0
else
return (volatile __u16 *) (PA_SUPERIO + (port << 1));
#endif
maybebadio(name,(unsigned long)port);
maybebadio((unsigned long)port);
return (volatile __u16*)port;
}
#if 0
/* The 7751 Solution Engine seems to have everything hooked */
/* up pretty normally (nothing on high-bytes only...) so this */
/* shouldn't be needed */
static inline int
shifted_port(unsigned long port)
{
/* For IDE registers, value is not shifted */
if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6)
return 0;
else
return 1;
}
#endif
/* In case someone configures the kernel w/o PCI support: in that */
/* scenario, don't ever bother to check for PCI-window addresses */
/* NOTE: WINDOW CHECK MAY BE A BIT OFF, HIGH PCIBIOS_MIN_IO WRAPS? */
#if defined(CONFIG_PCI)
#define CHECK_SH7751_PCIIO(port) \
((port >= PCIBIOS_MIN_IO) && (port < (PCIBIOS_MIN_IO + SH7751_PCI_IO_SIZE)))
#else
#define CHECK_SH7751_PCIIO(port) (0)
#endif
/*
* General outline: remap really low stuff [eventually] to SuperIO,
* stuff in PCI IO space (at or above window at pci.h:PCIBIOS_MIN_IO)
@ -111,10 +34,10 @@ unsigned char sh7751se_inb(unsigned long port)
{
if (PXSEG(port))
return *(volatile unsigned char *)port;
else if (CHECK_SH7751_PCIIO(port))
return *(volatile unsigned char *)PCI_IOMAP(port);
else if (is_pci_ioaddr(port))
return *(volatile unsigned char *)pci_ioaddr(port);
else
return (*port2adr(port))&0xff;
return (*port2adr(port)) & 0xff;
}
unsigned char sh7751se_inb_p(unsigned long port)
@ -123,11 +46,11 @@ unsigned char sh7751se_inb_p(unsigned long port)
if (PXSEG(port))
v = *(volatile unsigned char *)port;
else if (CHECK_SH7751_PCIIO(port))
v = *(volatile unsigned char *)PCI_IOMAP(port);
else if (is_pci_ioaddr(port))
v = *(volatile unsigned char *)pci_ioaddr(port);
else
v = (*port2adr(port))&0xff;
delay();
v = (*port2adr(port)) & 0xff;
ctrl_delay();
return v;
}
@ -135,12 +58,12 @@ unsigned short sh7751se_inw(unsigned long port)
{
if (PXSEG(port))
return *(volatile unsigned short *)port;
else if (CHECK_SH7751_PCIIO(port))
return *(volatile unsigned short *)PCI_IOMAP(port);
else if (is_pci_ioaddr(port))
return *(volatile unsigned short *)pci_ioaddr(port);
else if (port >= 0x2000)
return *port2adr(port);
else
maybebadio(inw, port);
maybebadio(port);
return 0;
}
@ -148,12 +71,12 @@ unsigned int sh7751se_inl(unsigned long port)
{
if (PXSEG(port))
return *(volatile unsigned long *)port;
else if (CHECK_SH7751_PCIIO(port))
return *(volatile unsigned int *)PCI_IOMAP(port);
else if (is_pci_ioaddr(port))
return *(volatile unsigned int *)pci_ioaddr(port);
else if (port >= 0x2000)
return *port2adr(port);
else
maybebadio(inl, port);
maybebadio(port);
return 0;
}
@ -162,8 +85,8 @@ void sh7751se_outb(unsigned char value, unsigned long port)
if (PXSEG(port))
*(volatile unsigned char *)port = value;
else if (CHECK_SH7751_PCIIO(port))
*((unsigned char*)PCI_IOMAP(port)) = value;
else if (is_pci_ioaddr(port))
*((unsigned char*)pci_ioaddr(port)) = value;
else
*(port2adr(port)) = value;
}
@ -172,73 +95,41 @@ void sh7751se_outb_p(unsigned char value, unsigned long port)
{
if (PXSEG(port))
*(volatile unsigned char *)port = value;
else if (CHECK_SH7751_PCIIO(port))
*((unsigned char*)PCI_IOMAP(port)) = value;
else if (is_pci_ioaddr(port))
*((unsigned char*)pci_ioaddr(port)) = value;
else
*(port2adr(port)) = value;
delay();
ctrl_delay();
}
void sh7751se_outw(unsigned short value, unsigned long port)
{
if (PXSEG(port))
*(volatile unsigned short *)port = value;
else if (CHECK_SH7751_PCIIO(port))
*((unsigned short *)PCI_IOMAP(port)) = value;
else if (is_pci_ioaddr(port))
*((unsigned short *)pci_ioaddr(port)) = value;
else if (port >= 0x2000)
*port2adr(port) = value;
else
maybebadio(outw, port);
maybebadio(port);
}
void sh7751se_outl(unsigned int value, unsigned long port)
{
if (PXSEG(port))
*(volatile unsigned long *)port = value;
else if (CHECK_SH7751_PCIIO(port))
*((unsigned long*)PCI_IOMAP(port)) = value;
else if (is_pci_ioaddr(port))
*((unsigned long*)pci_ioaddr(port)) = value;
else
maybebadio(outl, port);
maybebadio(port);
}
void sh7751se_insl(unsigned long port, void *addr, unsigned long count)
{
maybebadio(insl, port);
maybebadio(port);
}
void sh7751se_outsl(unsigned long port, const void *addr, unsigned long count)
{
maybebadio(outsw, port);
}
/* Map ISA bus address to the real address. Only for PCMCIA. */
/* ISA page descriptor. */
static __u32 sh_isa_memmap[256];
#if 0
static int
sh_isa_mmap(__u32 start, __u32 length, __u32 offset)
{
int idx;
if (start >= 0x100000 || (start & 0xfff) || (length != 0x1000))
return -1;
idx = start >> 12;
sh_isa_memmap[idx] = 0xb8000000 + (offset &~ 0xfff);
printk("sh_isa_mmap: start %x len %x offset %x (idx %x paddr %x)\n",
start, length, offset, idx, sh_isa_memmap[idx]);
return 0;
}
#endif
unsigned long
sh7751se_isa_port2addr(unsigned long offset)
{
int idx;
idx = (offset >> 12) & 0xff;
offset &= 0xfff;
return sh_isa_memmap[idx] + offset;
maybebadio(port);
}

View file

@ -12,7 +12,7 @@
#include <linux/init.h>
#include <linux/irq.h>
#include <asm/irq.h>
#include <asm/se7751/se7751.h>
#include <asm/se7751.h>
/*
* Initialize IRQ setting

Some files were not shown because too many files have changed in this diff Show more