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:
Коммит
b98adfccdf
|
@ -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.
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
173
arch/sh/Kconfig
173
arch/sh/Kconfig
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
#
|
||||
# Makefile for ADX boards
|
||||
#
|
||||
|
||||
obj-y := setup.o irq.o irq_maskreq.o
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
#
|
||||
# Makefile for the CAT-68701 specific parts of the kernel
|
||||
#
|
||||
|
||||
obj-y := setup.o irq.o
|
||||
|
|
@ -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);
|
||||
}
|
|
@ -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) */
|
||||
}
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
#
|
||||
# Makefile for the CqREEK specific parts of the kernel
|
||||
#
|
||||
|
||||
obj-y := setup.o irq.o
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
#
|
||||
# Makefile for the DataMyte Industrial Digital Assistant(tm) specific parts
|
||||
# of the kernel
|
||||
#
|
||||
|
||||
obj-y := mach.o
|
||||
|
|
@ -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)
|
||||
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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)
|
|
@ -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));
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
|
@ -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");
|
|
@ -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);
|
|
@ -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
|
|
@ -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)
|
||||
|
|
|
@ -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
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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)
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
|
@ -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 & 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);
|
||||
}
|
|
@ -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;
|
||||
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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 */
|
|
@ -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)
|
|
@ -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));
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 .. */
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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)
|
|
@ -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)
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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--;
|
||||
}
|
|
@ -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)
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)
|
|
@ -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)
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
obj-y := setup.o
|
|
@ -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)
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
||||
}
|
||||
|
|
|
@ -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
|
|
@ -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);
|
||||
}
|
|
@ -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 */
|
||||
}
|
|
@ -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);
|
||||
|
||||
}
|
|
@ -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)
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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)
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче