[ARM] 4157/2: S3C24XX: move arch/arch/mach-s3c2410 into cpu components
The following patch and script moves the arch/arm/mach-s3c2410 directory into arch/arm/plat-s3c24xx for the generic core code and inti arch/arm/mach-s3c{cpu} for the cpu/machine support files Include directory include/asm-arm/plat-s3c24xx is added for the core include files. Signed-off-by: Ben Dooks <ben-linux@fluff.org> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
This commit is contained in:
parent
d19494b187
commit
a21765a70e
|
@ -363,7 +363,15 @@ source "arch/arm/mach-omap1/Kconfig"
|
||||||
|
|
||||||
source "arch/arm/mach-omap2/Kconfig"
|
source "arch/arm/mach-omap2/Kconfig"
|
||||||
|
|
||||||
|
source "arch/arm/plat-s3c24xx/Kconfig"
|
||||||
|
|
||||||
|
if ARCH_S3C2410
|
||||||
|
source "arch/arm/mach-s3c2400/Kconfig"
|
||||||
source "arch/arm/mach-s3c2410/Kconfig"
|
source "arch/arm/mach-s3c2410/Kconfig"
|
||||||
|
source "arch/arm/mach-s3c2412/Kconfig"
|
||||||
|
source "arch/arm/mach-s3c2440/Kconfig"
|
||||||
|
source "arch/arm/mach-s3c2442/Kconfig"
|
||||||
|
endif
|
||||||
|
|
||||||
source "arch/arm/mach-lh7a40x/Kconfig"
|
source "arch/arm/mach-lh7a40x/Kconfig"
|
||||||
|
|
||||||
|
|
|
@ -149,7 +149,7 @@ MACHINE := arch/arm/mach-$(machine-y)/
|
||||||
else
|
else
|
||||||
MACHINE :=
|
MACHINE :=
|
||||||
endif
|
endif
|
||||||
|
|
||||||
export TEXT_OFFSET GZFLAGS MMUEXT
|
export TEXT_OFFSET GZFLAGS MMUEXT
|
||||||
|
|
||||||
# Do we have FASTFPE?
|
# Do we have FASTFPE?
|
||||||
|
@ -161,6 +161,10 @@ endif
|
||||||
# If we have a machine-specific directory, then include it in the build.
|
# If we have a machine-specific directory, then include it in the build.
|
||||||
core-y += arch/arm/kernel/ arch/arm/mm/ arch/arm/common/
|
core-y += arch/arm/kernel/ arch/arm/mm/ arch/arm/common/
|
||||||
core-y += $(MACHINE)
|
core-y += $(MACHINE)
|
||||||
|
core-$(CONFIG_ARCH_S3C2410) += arch/arm/mach-s3c2400/
|
||||||
|
core-$(CONFIG_ARCH_S3C2410) += arch/arm/mach-s3c2412/
|
||||||
|
core-$(CONFIG_ARCH_S3C2410) += arch/arm/mach-s3c2440/
|
||||||
|
core-$(CONFIG_ARCH_S3C2410) += arch/arm/mach-s3c2442/
|
||||||
core-$(CONFIG_FPE_NWFPE) += arch/arm/nwfpe/
|
core-$(CONFIG_FPE_NWFPE) += arch/arm/nwfpe/
|
||||||
core-$(CONFIG_FPE_FASTFPE) += $(FASTFPE_OBJ)
|
core-$(CONFIG_FPE_FASTFPE) += $(FASTFPE_OBJ)
|
||||||
core-$(CONFIG_VFP) += arch/arm/vfp/
|
core-$(CONFIG_VFP) += arch/arm/vfp/
|
||||||
|
@ -168,6 +172,7 @@ core-$(CONFIG_VFP) += arch/arm/vfp/
|
||||||
# If we have a common platform directory, then include it in the build.
|
# If we have a common platform directory, then include it in the build.
|
||||||
core-$(CONFIG_PLAT_IOP) += arch/arm/plat-iop/
|
core-$(CONFIG_PLAT_IOP) += arch/arm/plat-iop/
|
||||||
core-$(CONFIG_ARCH_OMAP) += arch/arm/plat-omap/
|
core-$(CONFIG_ARCH_OMAP) += arch/arm/plat-omap/
|
||||||
|
core-$(CONFIG_PLAT_S3C24XX) += arch/arm/plat-s3c24xx/
|
||||||
|
|
||||||
drivers-$(CONFIG_OPROFILE) += arch/arm/oprofile/
|
drivers-$(CONFIG_OPROFILE) += arch/arm/oprofile/
|
||||||
drivers-$(CONFIG_ARCH_CLPS7500) += drivers/acorn/char/
|
drivers-$(CONFIG_ARCH_CLPS7500) += drivers/acorn/char/
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
# arch/arm/mach-s3c2400/Kconfig
|
||||||
|
#
|
||||||
|
# Copyright 2007 Simtec Electronics
|
||||||
|
#
|
||||||
|
# Licensed under GPLv2
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
menu "S3C2400 Machines"
|
||||||
|
|
||||||
|
|
||||||
|
endmenu
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
# arch/arm/mach-s3c2400/Makefile
|
||||||
|
#
|
||||||
|
# Copyright 2007 Simtec Electronics
|
||||||
|
#
|
||||||
|
# Licensed under GPLv2
|
||||||
|
|
||||||
|
obj-y :=
|
||||||
|
obj-m :=
|
||||||
|
obj-n :=
|
||||||
|
obj- :=
|
||||||
|
|
||||||
|
obj-$(CONFIG_CPU_S3C2400) += gpio.o
|
||||||
|
|
||||||
|
# Machine support
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* linux/arch/arm/mach-s3c2410/s3c2400-gpio.c
|
/* linux/arch/arm/mach-s3c2400/gpio.c
|
||||||
*
|
*
|
||||||
* Copyright (c) 2006 Lucas Correia Villa Real <lucasvr@gobolinux.org>
|
* Copyright (c) 2006 Lucas Correia Villa Real <lucasvr@gobolinux.org>
|
||||||
*
|
*
|
|
@ -1,179 +1,8 @@
|
||||||
if ARCH_S3C2410
|
# arch/arm/mach-s3c2410/Kconfig
|
||||||
|
#
|
||||||
menu "S3C24XX Implementations"
|
# Copyright 2007 Simtec Electronics
|
||||||
|
#
|
||||||
config MACH_AML_M5900
|
# Licensed under GPLv2
|
||||||
bool "AML M5900 Series"
|
|
||||||
select CPU_S3C2410
|
|
||||||
select PM_SIMTEC if PM
|
|
||||||
help
|
|
||||||
Say Y here if you are using the American Microsystems M5900 Series
|
|
||||||
<http://www.amltd.com>
|
|
||||||
|
|
||||||
config MACH_ANUBIS
|
|
||||||
bool "Simtec Electronics ANUBIS"
|
|
||||||
select CPU_S3C2440
|
|
||||||
select PM_SIMTEC if PM
|
|
||||||
help
|
|
||||||
Say Y here if you are using the Simtec Electronics ANUBIS
|
|
||||||
development system
|
|
||||||
|
|
||||||
config MACH_OSIRIS
|
|
||||||
bool "Simtec IM2440D20 (OSIRIS) module"
|
|
||||||
select CPU_S3C2440
|
|
||||||
select PM_SIMTEC if PM
|
|
||||||
help
|
|
||||||
Say Y here if you are using the Simtec IM2440D20 module, also
|
|
||||||
known as the Osiris.
|
|
||||||
|
|
||||||
config ARCH_BAST
|
|
||||||
bool "Simtec Electronics BAST (EB2410ITX)"
|
|
||||||
select CPU_S3C2410
|
|
||||||
select PM_SIMTEC if PM
|
|
||||||
select ISA
|
|
||||||
help
|
|
||||||
Say Y here if you are using the Simtec Electronics EB2410ITX
|
|
||||||
development board (also known as BAST)
|
|
||||||
|
|
||||||
Product page: <http://www.simtec.co.uk/products/EB2410ITX/>.
|
|
||||||
|
|
||||||
config BAST_PC104_IRQ
|
|
||||||
bool "BAST PC104 IRQ support"
|
|
||||||
depends on ARCH_BAST
|
|
||||||
default y
|
|
||||||
help
|
|
||||||
Say Y here to enable the PC104 IRQ routing on the
|
|
||||||
Simtec BAST (EB2410ITX)
|
|
||||||
|
|
||||||
config PM_H1940
|
|
||||||
bool
|
|
||||||
help
|
|
||||||
Internal node for H1940 and related PM
|
|
||||||
|
|
||||||
config ARCH_H1940
|
|
||||||
bool "IPAQ H1940"
|
|
||||||
select CPU_S3C2410
|
|
||||||
select PM_H1940 if PM
|
|
||||||
help
|
|
||||||
Say Y here if you are using the HP IPAQ H1940
|
|
||||||
|
|
||||||
<http://www.handhelds.org/projects/h1940.html>.
|
|
||||||
|
|
||||||
config MACH_N30
|
|
||||||
bool "Acer N30"
|
|
||||||
select CPU_S3C2410
|
|
||||||
help
|
|
||||||
Say Y here if you are using the Acer N30
|
|
||||||
|
|
||||||
<http://zoo.weinigel.se/n30>.
|
|
||||||
|
|
||||||
config MACH_SMDK
|
|
||||||
bool
|
|
||||||
help
|
|
||||||
Common machine code for SMDK2410 and SMDK2440
|
|
||||||
|
|
||||||
config ARCH_SMDK2410
|
|
||||||
bool "SMDK2410/A9M2410"
|
|
||||||
select CPU_S3C2410
|
|
||||||
select MACH_SMDK
|
|
||||||
help
|
|
||||||
Say Y here if you are using the SMDK2410 or the derived module A9M2410
|
|
||||||
<http://www.fsforth.de>
|
|
||||||
|
|
||||||
config ARCH_S3C2440
|
|
||||||
bool "SMDK2440"
|
|
||||||
select CPU_S3C2440
|
|
||||||
select MACH_SMDK
|
|
||||||
help
|
|
||||||
Say Y here if you are using the SMDK2440.
|
|
||||||
|
|
||||||
config SMDK2440_CPU2440
|
|
||||||
bool "SMDK2440 with S3C2440 CPU module"
|
|
||||||
depends on ARCH_S3C2440
|
|
||||||
default y if ARCH_S3C2440
|
|
||||||
select CPU_S3C2440
|
|
||||||
|
|
||||||
config SMDK2440_CPU2442
|
|
||||||
bool "SMDM2440 with S3C2442 CPU module"
|
|
||||||
depends on ARCH_S3C2440
|
|
||||||
select CPU_S3C2442
|
|
||||||
|
|
||||||
config MACH_S3C2413
|
|
||||||
bool
|
|
||||||
help
|
|
||||||
Internal node for S3C2413 version of SMDK2413, so that
|
|
||||||
machine_is_s3c2413() will work when MACH_SMDK2413 is
|
|
||||||
selected
|
|
||||||
|
|
||||||
config MACH_SMDK2413
|
|
||||||
bool "SMDK2413"
|
|
||||||
select CPU_S3C2412
|
|
||||||
select MACH_S3C2413
|
|
||||||
select MACH_SMDK
|
|
||||||
help
|
|
||||||
Say Y here if you are using an SMDK2413
|
|
||||||
|
|
||||||
config MACH_VR1000
|
|
||||||
bool "Thorcom VR1000"
|
|
||||||
select PM_SIMTEC if PM
|
|
||||||
select CPU_S3C2410
|
|
||||||
help
|
|
||||||
Say Y here if you are using the Thorcom VR1000 board.
|
|
||||||
|
|
||||||
This linux port is currently being maintained by Simtec, on behalf
|
|
||||||
of Thorcom. Any queries, please contact Thorcom first.
|
|
||||||
|
|
||||||
config MACH_RX3715
|
|
||||||
bool "HP iPAQ rx3715"
|
|
||||||
select CPU_S3C2440
|
|
||||||
select PM_H1940 if PM
|
|
||||||
help
|
|
||||||
Say Y here if you are using the HP iPAQ rx3715.
|
|
||||||
|
|
||||||
See <http://www.handhelds.org/projects/rx3715.html> for more
|
|
||||||
information on this project
|
|
||||||
|
|
||||||
config MACH_OTOM
|
|
||||||
bool "NexVision OTOM Board"
|
|
||||||
select CPU_S3C2410
|
|
||||||
help
|
|
||||||
Say Y here if you are using the Nex Vision OTOM board
|
|
||||||
|
|
||||||
config MACH_NEXCODER_2440
|
|
||||||
bool "NexVision NEXCODER 2440 Light Board"
|
|
||||||
select CPU_S3C2440
|
|
||||||
help
|
|
||||||
Say Y here if you are using the Nex Vision NEXCODER 2440 Light Board
|
|
||||||
|
|
||||||
config MACH_VSTMS
|
|
||||||
bool "VMSTMS"
|
|
||||||
select CPU_S3C2412
|
|
||||||
help
|
|
||||||
Say Y here if you are using an VSTMS board
|
|
||||||
|
|
||||||
endmenu
|
|
||||||
|
|
||||||
config S3C2410_CLOCK
|
|
||||||
bool
|
|
||||||
help
|
|
||||||
Clock code for the S3C2410, and similar processors
|
|
||||||
|
|
||||||
config S3C2410_GPIO
|
|
||||||
bool
|
|
||||||
help
|
|
||||||
GPIO code for S3C2410 and similar processors
|
|
||||||
|
|
||||||
config S3C2410_PM
|
|
||||||
bool
|
|
||||||
help
|
|
||||||
Power Management code common to S3C2410 and better
|
|
||||||
|
|
||||||
config CPU_S3C2410_DMA
|
|
||||||
bool
|
|
||||||
depends on S3C2410_DMA && (CPU_S3C2410 || CPU_S3C2442)
|
|
||||||
default y if CPU_S3C2410 || CPU_S3C2442
|
|
||||||
help
|
|
||||||
DMA device selection for S3C2410 and compatible CPUs
|
|
||||||
|
|
||||||
config CPU_S3C2410
|
config CPU_S3C2410
|
||||||
bool
|
bool
|
||||||
|
@ -185,158 +14,95 @@ config CPU_S3C2410
|
||||||
Support for S3C2410 and S3C2410A family from the S3C24XX line
|
Support for S3C2410 and S3C2410A family from the S3C24XX line
|
||||||
of Samsung Mobile CPUs.
|
of Samsung Mobile CPUs.
|
||||||
|
|
||||||
# internal node to signify if we are only dealing with an S3C2412
|
config CPU_S3C2410_DMA
|
||||||
|
|
||||||
config CPU_S3C2412_ONLY
|
|
||||||
bool
|
bool
|
||||||
depends on ARCH_S3C2410 && !CPU_S3C2400 && !CPU_S3C2410 && \
|
depends on S3C2410_DMA && (CPU_S3C2410 || CPU_S3C2442)
|
||||||
!CPU_S3C2440 && !CPU_S3C2442 && CPU_S3C2412
|
default y if CPU_S3C2410 || CPU_S3C2442
|
||||||
default y if CPU_S3C2412
|
help
|
||||||
|
DMA device selection for S3C2410 and compatible CPUs
|
||||||
|
|
||||||
config S3C2412_PM
|
config S3C2410_PM
|
||||||
bool
|
bool
|
||||||
help
|
help
|
||||||
Internal config node to apply S3C2412 power management
|
Power Management code common to S3C2410 and better
|
||||||
|
|
||||||
config S3C2412_DMA
|
config S3C2410_GPIO
|
||||||
bool
|
|
||||||
depends on CPU_S3C2412
|
|
||||||
help
|
|
||||||
Internal config node for S3C2412 DMA support
|
|
||||||
|
|
||||||
config CPU_S3C2412
|
|
||||||
bool
|
|
||||||
depends on ARCH_S3C2410
|
|
||||||
select S3C2412_PM if PM
|
|
||||||
select S3C2412_DMA if S3C2410_DMA
|
|
||||||
help
|
|
||||||
Support for the S3C2412 and S3C2413 SoCs from the S3C24XX line
|
|
||||||
|
|
||||||
config CPU_S3C244X
|
|
||||||
bool
|
|
||||||
depends on ARCH_S3C2410 && (CPU_S3C2440 || CPU_S3C2442)
|
|
||||||
help
|
|
||||||
Support for S3C2440 and S3C2442 Samsung Mobile CPU based systems.
|
|
||||||
|
|
||||||
config S3C2440_DMA
|
|
||||||
bool
|
|
||||||
depends on ARCH_S3C2410 && CPU_S3C24405B
|
|
||||||
help
|
|
||||||
Support for S3C2440 specific DMA code5A
|
|
||||||
|
|
||||||
config CPU_S3C2440
|
|
||||||
bool
|
|
||||||
depends on ARCH_S3C2410
|
|
||||||
select S3C2410_CLOCK
|
|
||||||
select S3C2410_PM if PM
|
|
||||||
select S3C2410_GPIO
|
|
||||||
select S3C2440_DMA if S3C2410_DMA
|
|
||||||
select CPU_S3C244X
|
|
||||||
help
|
|
||||||
Support for S3C2440 Samsung Mobile CPU based systems.
|
|
||||||
|
|
||||||
config CPU_S3C2442
|
|
||||||
bool
|
|
||||||
depends on ARCH_S3C2420
|
|
||||||
select S3C2410_CLOCK
|
|
||||||
select S3C2410_GPIO
|
|
||||||
select S3C2410_PM if PM
|
|
||||||
select CPU_S3C244X
|
|
||||||
help
|
|
||||||
Support for S3C2442 Samsung Mobile CPU based systems.
|
|
||||||
|
|
||||||
comment "S3C2410 Boot"
|
|
||||||
|
|
||||||
config S3C2410_BOOT_WATCHDOG
|
|
||||||
bool "S3C2410 Initialisation watchdog"
|
|
||||||
depends on ARCH_S3C2410 && S3C2410_WATCHDOG
|
|
||||||
help
|
|
||||||
Say y to enable the watchdog during the kernel decompression
|
|
||||||
stage. If the kernel fails to uncompress, then the watchdog
|
|
||||||
will trigger a reset and the system should restart.
|
|
||||||
|
|
||||||
Although this uses the same hardware unit as the kernel watchdog
|
|
||||||
driver, it is not a replacement for it. If you use this option,
|
|
||||||
you will have to use the watchdg driver to either stop the timeout
|
|
||||||
or restart it. If you do not, then your kernel will reboot after
|
|
||||||
startup.
|
|
||||||
|
|
||||||
The driver uses a fixed timeout value, so the exact time till the
|
|
||||||
system resets depends on the value of PCLK. The timeout on an
|
|
||||||
200MHz s3c2410 should be about 30 seconds.
|
|
||||||
|
|
||||||
config S3C2410_BOOT_ERROR_RESET
|
|
||||||
bool "S3C2410 Reboot on decompression error"
|
|
||||||
depends on ARCH_S3C2410
|
|
||||||
help
|
|
||||||
Say y here to use the watchdog to reset the system if the
|
|
||||||
kernel decompressor detects an error during decompression.
|
|
||||||
|
|
||||||
|
|
||||||
comment "S3C2410 Setup"
|
|
||||||
|
|
||||||
config S3C2410_DMA
|
|
||||||
bool "S3C2410 DMA support"
|
|
||||||
depends on ARCH_S3C2410
|
|
||||||
help
|
|
||||||
S3C2410 DMA support. This is needed for drivers like sound which
|
|
||||||
use the S3C2410's DMA system to move data to and from the
|
|
||||||
peripheral blocks.
|
|
||||||
|
|
||||||
config S3C2410_DMA_DEBUG
|
|
||||||
bool "S3C2410 DMA support debug"
|
|
||||||
depends on ARCH_S3C2410 && S3C2410_DMA
|
|
||||||
help
|
|
||||||
Enable debugging output for the DMA code. This option sends info
|
|
||||||
to the kernel log, at priority KERN_DEBUG.
|
|
||||||
|
|
||||||
Note, it is easy to create and fill the log buffer in a small
|
|
||||||
amount of time, as well as using an significant percentage of
|
|
||||||
the CPU time doing so.
|
|
||||||
|
|
||||||
config S3C2410_PM_DEBUG
|
|
||||||
bool "S3C2410 PM Suspend debug"
|
|
||||||
depends on ARCH_S3C2410 && PM
|
|
||||||
help
|
|
||||||
Say Y here if you want verbose debugging from the PM Suspend and
|
|
||||||
Resume code. See <file:Documentation/arm/Samsung-S3C24XX/Suspend.txt>
|
|
||||||
for more information.
|
|
||||||
|
|
||||||
config S3C2410_PM_CHECK
|
|
||||||
bool "S3C2410 PM Suspend Memory CRC"
|
|
||||||
depends on ARCH_S3C2410 && PM && CRC32
|
|
||||||
help
|
|
||||||
Enable the PM code's memory area checksum over sleep. This option
|
|
||||||
will generate CRCs of all blocks of memory, and store them before
|
|
||||||
going to sleep. The blocks are then checked on resume for any
|
|
||||||
errors.
|
|
||||||
|
|
||||||
config S3C2410_PM_CHECK_CHUNKSIZE
|
|
||||||
int "S3C2410 PM Suspend CRC Chunksize (KiB)"
|
|
||||||
depends on ARCH_S3C2410 && PM && S3C2410_PM_CHECK
|
|
||||||
default 64
|
|
||||||
help
|
|
||||||
Set the chunksize in Kilobytes of the CRC for checking memory
|
|
||||||
corruption over suspend and resume. A smaller value will mean that
|
|
||||||
the CRC data block will take more memory, but wil identify any
|
|
||||||
faults with better precision.
|
|
||||||
|
|
||||||
config PM_SIMTEC
|
|
||||||
bool
|
bool
|
||||||
help
|
help
|
||||||
Common power management code for systems that are
|
GPIO code for S3C2410 and similar processors
|
||||||
compatible with the Simtec style of power management
|
|
||||||
|
|
||||||
config S3C2410_LOWLEVEL_UART_PORT
|
config S3C2410_CLOCK
|
||||||
int "S3C2410 UART to use for low-level messages"
|
bool
|
||||||
default 0
|
|
||||||
help
|
help
|
||||||
Choice of which UART port to use for the low-level messages,
|
Clock code for the S3C2410, and similar processors
|
||||||
such as the `Uncompressing...` at start time. The value of
|
|
||||||
this configuration should be between zero and two. The port
|
|
||||||
must have been initialised by the boot-loader before use.
|
|
||||||
|
|
||||||
Note, this does not affect the port used by the debug messages,
|
|
||||||
which is a separate configuration.
|
|
||||||
|
|
||||||
endif
|
menu "S3C2410 Machines"
|
||||||
|
|
||||||
|
config ARCH_SMDK2410
|
||||||
|
bool "SMDK2410/A9M2410"
|
||||||
|
select CPU_S3C2410
|
||||||
|
select MACH_SMDK
|
||||||
|
help
|
||||||
|
Say Y here if you are using the SMDK2410 or the derived module A9M2410
|
||||||
|
<http://www.fsforth.de>
|
||||||
|
|
||||||
|
config ARCH_H1940
|
||||||
|
bool "IPAQ H1940"
|
||||||
|
select CPU_S3C2410
|
||||||
|
select PM_H1940 if PM
|
||||||
|
help
|
||||||
|
Say Y here if you are using the HP IPAQ H1940
|
||||||
|
|
||||||
|
config PM_H1940
|
||||||
|
bool
|
||||||
|
help
|
||||||
|
Internal node for H1940 and related PM
|
||||||
|
|
||||||
|
config MACH_N30
|
||||||
|
bool "Acer N30"
|
||||||
|
select CPU_S3C2410
|
||||||
|
help
|
||||||
|
Say Y here if you are using the Acer N30
|
||||||
|
|
||||||
|
config ARCH_BAST
|
||||||
|
bool "Simtec Electronics BAST (EB2410ITX)"
|
||||||
|
select CPU_S3C2410
|
||||||
|
select PM_SIMTEC if PM
|
||||||
|
select ISA
|
||||||
|
help
|
||||||
|
Say Y here if you are using the Simtec Electronics EB2410ITX
|
||||||
|
development board (also known as BAST)
|
||||||
|
|
||||||
|
config MACH_OTOM
|
||||||
|
bool "NexVision OTOM Board"
|
||||||
|
select CPU_S3C2410
|
||||||
|
help
|
||||||
|
Say Y here if you are using the Nex Vision OTOM board
|
||||||
|
|
||||||
|
config MACH_AML_M5900
|
||||||
|
bool "AML M5900 Series"
|
||||||
|
select CPU_S3C2410
|
||||||
|
select PM_SIMTEC if PM
|
||||||
|
help
|
||||||
|
Say Y here if you are using the American Microsystems M5900 Series
|
||||||
|
<http://www.amltd.com>
|
||||||
|
|
||||||
|
config BAST_PC104_IRQ
|
||||||
|
bool "BAST PC104 IRQ support"
|
||||||
|
depends on ARCH_BAST
|
||||||
|
default y
|
||||||
|
help
|
||||||
|
Say Y here to enable the PC104 IRQ routing on the
|
||||||
|
Simtec BAST (EB2410ITX)
|
||||||
|
|
||||||
|
config MACH_VR1000
|
||||||
|
bool "Thorcom VR1000"
|
||||||
|
select PM_SIMTEC if PM
|
||||||
|
select CPU_S3C2410
|
||||||
|
help
|
||||||
|
Say Y here if you are using the Thorcom VR1000 board.
|
||||||
|
|
||||||
|
|
||||||
|
endmenu
|
||||||
|
|
||||||
|
|
|
@ -1,85 +1,30 @@
|
||||||
|
# arch/arm/mach-s3c2410/Makefile
|
||||||
#
|
#
|
||||||
# Makefile for the linux kernel.
|
# Copyright 2007 Simtec Electronics
|
||||||
#
|
#
|
||||||
|
# Licensed under GPLv2
|
||||||
|
|
||||||
# Object file lists.
|
obj-y :=
|
||||||
|
obj-m :=
|
||||||
obj-y := cpu.o irq.o time.o gpio.o clock.o devs.o
|
obj-n :=
|
||||||
obj-m :=
|
obj- :=
|
||||||
obj-n :=
|
|
||||||
obj- :=
|
|
||||||
|
|
||||||
# DMA
|
|
||||||
obj-$(CONFIG_S3C2410_DMA) += dma.o
|
|
||||||
|
|
||||||
# S3C2400 support files
|
|
||||||
obj-$(CONFIG_CPU_S3C2400) += s3c2400-gpio.o
|
|
||||||
|
|
||||||
# S3C2410 support files
|
|
||||||
|
|
||||||
obj-$(CONFIG_CPU_S3C2410) += s3c2410.o
|
obj-$(CONFIG_CPU_S3C2410) += s3c2410.o
|
||||||
obj-$(CONFIG_CPU_S3C2410) += s3c2410-irq.o
|
obj-$(CONFIG_CPU_S3C2410) += irq.o
|
||||||
|
obj-$(CONFIG_CPU_S3C2410_DMA) += dma.o
|
||||||
|
obj-$(CONFIG_CPU_S3C2410_DMA) += dma.o
|
||||||
|
obj-$(CONFIG_S3C2410_PM) += pm.o sleep.o
|
||||||
|
obj-$(CONFIG_S3C2410_GPIO) += gpio.o
|
||||||
|
obj-$(CONFIG_S3C2410_CLOCK) += clock.o
|
||||||
|
|
||||||
obj-$(CONFIG_S3C2410_PM) += s3c2410-pm.o s3c2410-sleep.o
|
# Machine support
|
||||||
obj-$(CONFIG_S3C2410_GPIO) += s3c2410-gpio.o
|
|
||||||
obj-$(CONFIG_CPU_S3C2410_DMA) += s3c2410-dma.o
|
|
||||||
|
|
||||||
# Power Management support
|
|
||||||
|
|
||||||
obj-$(CONFIG_PM) += pm.o sleep.o
|
|
||||||
obj-$(CONFIG_PM_SIMTEC) += pm-simtec.o
|
|
||||||
obj-$(CONFIG_PM_H1940) += pm-h1940.o
|
|
||||||
|
|
||||||
# S3C2412 support
|
|
||||||
obj-$(CONFIG_CPU_S3C2412) += s3c2412.o
|
|
||||||
obj-$(CONFIG_CPU_S3C2412) += s3c2412-irq.o
|
|
||||||
obj-$(CONFIG_CPU_S3C2412) += s3c2412-clock.o
|
|
||||||
|
|
||||||
obj-$(CONFIG_S3C2412_PM) += s3c2412-pm.o
|
|
||||||
obj-$(CONFIG_S3C2412_DMA) += s3c2412-dma.o
|
|
||||||
|
|
||||||
#
|
|
||||||
# S3C244X support
|
|
||||||
|
|
||||||
obj-$(CONFIG_CPU_S3C244X) += s3c244x.o
|
|
||||||
obj-$(CONFIG_CPU_S3C244X) += s3c244x-irq.o
|
|
||||||
|
|
||||||
# Clock control
|
|
||||||
|
|
||||||
obj-$(CONFIG_S3C2410_CLOCK) += s3c2410-clock.o
|
|
||||||
|
|
||||||
# S3C2440 support
|
|
||||||
|
|
||||||
obj-$(CONFIG_CPU_S3C2440) += s3c2440.o s3c2440-dsc.o
|
|
||||||
obj-$(CONFIG_CPU_S3C2440) += s3c2440-irq.o
|
|
||||||
obj-$(CONFIG_CPU_S3C2440) += s3c2440-clock.o
|
|
||||||
obj-$(CONFIG_S3C2440_DMA) += s3c2440-dma.o
|
|
||||||
|
|
||||||
# S3C2442 support
|
|
||||||
|
|
||||||
obj-$(CONFIG_CPU_S3C2442) += s3c2442.o
|
|
||||||
obj-$(CONFIG_CPU_S3C2442) += s3c2442-clock.o
|
|
||||||
|
|
||||||
# bast extras
|
|
||||||
|
|
||||||
obj-$(CONFIG_BAST_PC104_IRQ) += bast-irq.o
|
|
||||||
|
|
||||||
# machine specific support
|
|
||||||
|
|
||||||
obj-$(CONFIG_MACH_AML_M5900) += mach-amlm5900.o
|
|
||||||
obj-$(CONFIG_MACH_ANUBIS) += mach-anubis.o
|
|
||||||
obj-$(CONFIG_MACH_OSIRIS) += mach-osiris.o
|
|
||||||
obj-$(CONFIG_ARCH_BAST) += mach-bast.o usb-simtec.o
|
|
||||||
obj-$(CONFIG_ARCH_H1940) += mach-h1940.o
|
|
||||||
obj-$(CONFIG_MACH_N30) += mach-n30.o
|
|
||||||
obj-$(CONFIG_ARCH_SMDK2410) += mach-smdk2410.o
|
obj-$(CONFIG_ARCH_SMDK2410) += mach-smdk2410.o
|
||||||
obj-$(CONFIG_MACH_SMDK2413) += mach-smdk2413.o
|
obj-$(CONFIG_ARCH_H1940) += mach-h1940.o
|
||||||
obj-$(CONFIG_ARCH_S3C2440) += mach-smdk2440.o
|
obj-$(CONFIG_PM_H1940) += pm-h1940.o
|
||||||
obj-$(CONFIG_MACH_VR1000) += mach-vr1000.o usb-simtec.o
|
obj-$(CONFIG_MACH_N30) += mach-n30.o
|
||||||
obj-$(CONFIG_MACH_RX3715) += mach-rx3715.o
|
obj-$(CONFIG_ARCH_BAST) += mach-bast.o usb-simtec.o
|
||||||
obj-$(CONFIG_MACH_OTOM) += mach-otom.o
|
obj-$(CONFIG_MACH_OTOM) += mach-otom.o
|
||||||
obj-$(CONFIG_MACH_NEXCODER_2440) += mach-nexcoder.o
|
obj-$(CONFIG_MACH_AML_M5900) += mach-amlm5900.o
|
||||||
obj-$(CONFIG_MACH_VSTMS) += mach-vstms.o
|
obj-$(CONFIG_BAST_PC104_IRQ) += bast-irq.o
|
||||||
|
obj-$(CONFIG_MACH_VR1000) += mach-vr1000.o usb-simtec.o
|
||||||
obj-$(CONFIG_MACH_SMDK) += common-smdk.o
|
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
#include <asm/arch/bast-map.h>
|
#include <asm/arch/bast-map.h>
|
||||||
#include <asm/arch/bast-irq.h>
|
#include <asm/arch/bast-irq.h>
|
||||||
|
|
||||||
#include "irq.h"
|
#include <asm/plat-s3c24xx/irq.h>
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
#include <asm/debug-ll.h>
|
#include <asm/debug-ll.h>
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
|
/* linux/arch/arm/mach-s3c2410/bast.h
|
||||||
extern void bast_init_irq(void);
|
extern void bast_init_irq(void);
|
||||||
|
|
|
@ -1,15 +1,9 @@
|
||||||
/* linux/arch/arm/mach-s3c2410/clock.c
|
/* linux/arch/arm/mach-s3c2410/clock.c
|
||||||
*
|
*
|
||||||
* Copyright (c) 2004-2005 Simtec Electronics
|
* Copyright (c) 2006 Simtec Electronics
|
||||||
* Ben Dooks <ben@simtec.co.uk>
|
* Ben Dooks <ben@simtec.co.uk>
|
||||||
*
|
*
|
||||||
* S3C24XX Core clock control support
|
* S3C2410,S3C2440,S3C2442 Clock control support
|
||||||
*
|
|
||||||
* Based on, and code from linux/arch/arm/mach-versatile/clock.c
|
|
||||||
**
|
|
||||||
** Copyright (C) 2004 ARM Limited.
|
|
||||||
** Written by Deep Blue Solutions Limited.
|
|
||||||
*
|
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -32,418 +26,251 @@
|
||||||
#include <linux/list.h>
|
#include <linux/list.h>
|
||||||
#include <linux/errno.h>
|
#include <linux/errno.h>
|
||||||
#include <linux/err.h>
|
#include <linux/err.h>
|
||||||
#include <linux/platform_device.h>
|
|
||||||
#include <linux/sysdev.h>
|
#include <linux/sysdev.h>
|
||||||
#include <linux/interrupt.h>
|
|
||||||
#include <linux/ioport.h>
|
|
||||||
#include <linux/clk.h>
|
#include <linux/clk.h>
|
||||||
#include <linux/mutex.h>
|
#include <linux/mutex.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
|
#include <linux/serial_core.h>
|
||||||
|
|
||||||
|
#include <asm/mach/map.h>
|
||||||
|
|
||||||
#include <asm/hardware.h>
|
#include <asm/hardware.h>
|
||||||
#include <asm/irq.h>
|
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
|
|
||||||
|
#include <asm/arch/regs-serial.h>
|
||||||
#include <asm/arch/regs-clock.h>
|
#include <asm/arch/regs-clock.h>
|
||||||
#include <asm/arch/regs-gpio.h>
|
#include <asm/arch/regs-gpio.h>
|
||||||
|
|
||||||
#include "clock.h"
|
#include <asm/plat-s3c24xx/s3c2410.h>
|
||||||
#include "cpu.h"
|
#include <asm/plat-s3c24xx/clock.h>
|
||||||
|
#include <asm/plat-s3c24xx/cpu.h>
|
||||||
|
|
||||||
/* clock information */
|
int s3c2410_clkcon_enable(struct clk *clk, int enable)
|
||||||
|
|
||||||
static LIST_HEAD(clocks);
|
|
||||||
|
|
||||||
DEFINE_MUTEX(clocks_mutex);
|
|
||||||
|
|
||||||
/* enable and disable calls for use with the clk struct */
|
|
||||||
|
|
||||||
static int clk_null_enable(struct clk *clk, int enable)
|
|
||||||
{
|
{
|
||||||
return 0;
|
unsigned int clocks = clk->ctrlbit;
|
||||||
}
|
unsigned long clkcon;
|
||||||
|
|
||||||
/* Clock API calls */
|
clkcon = __raw_readl(S3C2410_CLKCON);
|
||||||
|
|
||||||
struct clk *clk_get(struct device *dev, const char *id)
|
|
||||||
{
|
|
||||||
struct clk *p;
|
|
||||||
struct clk *clk = ERR_PTR(-ENOENT);
|
|
||||||
int idno;
|
|
||||||
|
|
||||||
if (dev == NULL || dev->bus != &platform_bus_type)
|
|
||||||
idno = -1;
|
|
||||||
else
|
|
||||||
idno = to_platform_device(dev)->id;
|
|
||||||
|
|
||||||
mutex_lock(&clocks_mutex);
|
|
||||||
|
|
||||||
list_for_each_entry(p, &clocks, list) {
|
|
||||||
if (p->id == idno &&
|
|
||||||
strcmp(id, p->name) == 0 &&
|
|
||||||
try_module_get(p->owner)) {
|
|
||||||
clk = p;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* check for the case where a device was supplied, but the
|
|
||||||
* clock that was being searched for is not device specific */
|
|
||||||
|
|
||||||
if (IS_ERR(clk)) {
|
|
||||||
list_for_each_entry(p, &clocks, list) {
|
|
||||||
if (p->id == -1 && strcmp(id, p->name) == 0 &&
|
|
||||||
try_module_get(p->owner)) {
|
|
||||||
clk = p;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mutex_unlock(&clocks_mutex);
|
|
||||||
return clk;
|
|
||||||
}
|
|
||||||
|
|
||||||
void clk_put(struct clk *clk)
|
|
||||||
{
|
|
||||||
module_put(clk->owner);
|
|
||||||
}
|
|
||||||
|
|
||||||
int clk_enable(struct clk *clk)
|
|
||||||
{
|
|
||||||
if (IS_ERR(clk) || clk == NULL)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
clk_enable(clk->parent);
|
|
||||||
|
|
||||||
mutex_lock(&clocks_mutex);
|
|
||||||
|
|
||||||
if ((clk->usage++) == 0)
|
|
||||||
(clk->enable)(clk, 1);
|
|
||||||
|
|
||||||
mutex_unlock(&clocks_mutex);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void clk_disable(struct clk *clk)
|
|
||||||
{
|
|
||||||
if (IS_ERR(clk) || clk == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
mutex_lock(&clocks_mutex);
|
|
||||||
|
|
||||||
if ((--clk->usage) == 0)
|
|
||||||
(clk->enable)(clk, 0);
|
|
||||||
|
|
||||||
mutex_unlock(&clocks_mutex);
|
|
||||||
clk_disable(clk->parent);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
unsigned long clk_get_rate(struct clk *clk)
|
|
||||||
{
|
|
||||||
if (IS_ERR(clk))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (clk->rate != 0)
|
|
||||||
return clk->rate;
|
|
||||||
|
|
||||||
if (clk->get_rate != NULL)
|
|
||||||
return (clk->get_rate)(clk);
|
|
||||||
|
|
||||||
if (clk->parent != NULL)
|
|
||||||
return clk_get_rate(clk->parent);
|
|
||||||
|
|
||||||
return clk->rate;
|
|
||||||
}
|
|
||||||
|
|
||||||
long clk_round_rate(struct clk *clk, unsigned long rate)
|
|
||||||
{
|
|
||||||
if (!IS_ERR(clk) && clk->round_rate)
|
|
||||||
return (clk->round_rate)(clk, rate);
|
|
||||||
|
|
||||||
return rate;
|
|
||||||
}
|
|
||||||
|
|
||||||
int clk_set_rate(struct clk *clk, unsigned long rate)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (IS_ERR(clk))
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
mutex_lock(&clocks_mutex);
|
|
||||||
ret = (clk->set_rate)(clk, rate);
|
|
||||||
mutex_unlock(&clocks_mutex);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct clk *clk_get_parent(struct clk *clk)
|
|
||||||
{
|
|
||||||
return clk->parent;
|
|
||||||
}
|
|
||||||
|
|
||||||
int clk_set_parent(struct clk *clk, struct clk *parent)
|
|
||||||
{
|
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
if (IS_ERR(clk))
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
mutex_lock(&clocks_mutex);
|
|
||||||
|
|
||||||
if (clk->set_parent)
|
|
||||||
ret = (clk->set_parent)(clk, parent);
|
|
||||||
|
|
||||||
mutex_unlock(&clocks_mutex);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
EXPORT_SYMBOL(clk_get);
|
|
||||||
EXPORT_SYMBOL(clk_put);
|
|
||||||
EXPORT_SYMBOL(clk_enable);
|
|
||||||
EXPORT_SYMBOL(clk_disable);
|
|
||||||
EXPORT_SYMBOL(clk_get_rate);
|
|
||||||
EXPORT_SYMBOL(clk_round_rate);
|
|
||||||
EXPORT_SYMBOL(clk_set_rate);
|
|
||||||
EXPORT_SYMBOL(clk_get_parent);
|
|
||||||
EXPORT_SYMBOL(clk_set_parent);
|
|
||||||
|
|
||||||
/* base clocks */
|
|
||||||
|
|
||||||
struct clk clk_xtal = {
|
|
||||||
.name = "xtal",
|
|
||||||
.id = -1,
|
|
||||||
.rate = 0,
|
|
||||||
.parent = NULL,
|
|
||||||
.ctrlbit = 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct clk clk_mpll = {
|
|
||||||
.name = "mpll",
|
|
||||||
.id = -1,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct clk clk_upll = {
|
|
||||||
.name = "upll",
|
|
||||||
.id = -1,
|
|
||||||
.parent = NULL,
|
|
||||||
.ctrlbit = 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct clk clk_f = {
|
|
||||||
.name = "fclk",
|
|
||||||
.id = -1,
|
|
||||||
.rate = 0,
|
|
||||||
.parent = &clk_mpll,
|
|
||||||
.ctrlbit = 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct clk clk_h = {
|
|
||||||
.name = "hclk",
|
|
||||||
.id = -1,
|
|
||||||
.rate = 0,
|
|
||||||
.parent = NULL,
|
|
||||||
.ctrlbit = 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct clk clk_p = {
|
|
||||||
.name = "pclk",
|
|
||||||
.id = -1,
|
|
||||||
.rate = 0,
|
|
||||||
.parent = NULL,
|
|
||||||
.ctrlbit = 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct clk clk_usb_bus = {
|
|
||||||
.name = "usb-bus",
|
|
||||||
.id = -1,
|
|
||||||
.rate = 0,
|
|
||||||
.parent = &clk_upll,
|
|
||||||
};
|
|
||||||
|
|
||||||
/* clocks that could be registered by external code */
|
|
||||||
|
|
||||||
static int s3c24xx_dclk_enable(struct clk *clk, int enable)
|
|
||||||
{
|
|
||||||
unsigned long dclkcon = __raw_readl(S3C24XX_DCLKCON);
|
|
||||||
|
|
||||||
if (enable)
|
if (enable)
|
||||||
dclkcon |= clk->ctrlbit;
|
clkcon |= clocks;
|
||||||
else
|
else
|
||||||
dclkcon &= ~clk->ctrlbit;
|
clkcon &= ~clocks;
|
||||||
|
|
||||||
__raw_writel(dclkcon, S3C24XX_DCLKCON);
|
/* ensure none of the special function bits set */
|
||||||
|
clkcon &= ~(S3C2410_CLKCON_IDLE|S3C2410_CLKCON_POWER);
|
||||||
|
|
||||||
|
__raw_writel(clkcon, S3C2410_CLKCON);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int s3c24xx_dclk_setparent(struct clk *clk, struct clk *parent)
|
static int s3c2410_upll_enable(struct clk *clk, int enable)
|
||||||
{
|
{
|
||||||
unsigned long dclkcon;
|
unsigned long clkslow = __raw_readl(S3C2410_CLKSLOW);
|
||||||
unsigned int uclk;
|
unsigned long orig = clkslow;
|
||||||
|
|
||||||
if (parent == &clk_upll)
|
if (enable)
|
||||||
uclk = 1;
|
clkslow &= ~S3C2410_CLKSLOW_UCLK_OFF;
|
||||||
else if (parent == &clk_p)
|
|
||||||
uclk = 0;
|
|
||||||
else
|
else
|
||||||
return -EINVAL;
|
clkslow |= S3C2410_CLKSLOW_UCLK_OFF;
|
||||||
|
|
||||||
clk->parent = parent;
|
__raw_writel(clkslow, S3C2410_CLKSLOW);
|
||||||
|
|
||||||
dclkcon = __raw_readl(S3C24XX_DCLKCON);
|
/* if we started the UPLL, then allow to settle */
|
||||||
|
|
||||||
if (clk->ctrlbit == S3C2410_DCLKCON_DCLK0EN) {
|
if (enable && (orig & S3C2410_CLKSLOW_UCLK_OFF))
|
||||||
if (uclk)
|
udelay(200);
|
||||||
dclkcon |= S3C2410_DCLKCON_DCLK0_UCLK;
|
|
||||||
else
|
return 0;
|
||||||
dclkcon &= ~S3C2410_DCLKCON_DCLK0_UCLK;
|
}
|
||||||
} else {
|
|
||||||
if (uclk)
|
/* standard clock definitions */
|
||||||
dclkcon |= S3C2410_DCLKCON_DCLK1_UCLK;
|
|
||||||
else
|
static struct clk init_clocks_disable[] = {
|
||||||
dclkcon &= ~S3C2410_DCLKCON_DCLK1_UCLK;
|
{
|
||||||
|
.name = "nand",
|
||||||
|
.id = -1,
|
||||||
|
.parent = &clk_h,
|
||||||
|
.enable = s3c2410_clkcon_enable,
|
||||||
|
.ctrlbit = S3C2410_CLKCON_NAND,
|
||||||
|
}, {
|
||||||
|
.name = "sdi",
|
||||||
|
.id = -1,
|
||||||
|
.parent = &clk_p,
|
||||||
|
.enable = s3c2410_clkcon_enable,
|
||||||
|
.ctrlbit = S3C2410_CLKCON_SDI,
|
||||||
|
}, {
|
||||||
|
.name = "adc",
|
||||||
|
.id = -1,
|
||||||
|
.parent = &clk_p,
|
||||||
|
.enable = s3c2410_clkcon_enable,
|
||||||
|
.ctrlbit = S3C2410_CLKCON_ADC,
|
||||||
|
}, {
|
||||||
|
.name = "i2c",
|
||||||
|
.id = -1,
|
||||||
|
.parent = &clk_p,
|
||||||
|
.enable = s3c2410_clkcon_enable,
|
||||||
|
.ctrlbit = S3C2410_CLKCON_IIC,
|
||||||
|
}, {
|
||||||
|
.name = "iis",
|
||||||
|
.id = -1,
|
||||||
|
.parent = &clk_p,
|
||||||
|
.enable = s3c2410_clkcon_enable,
|
||||||
|
.ctrlbit = S3C2410_CLKCON_IIS,
|
||||||
|
}, {
|
||||||
|
.name = "spi",
|
||||||
|
.id = -1,
|
||||||
|
.parent = &clk_p,
|
||||||
|
.enable = s3c2410_clkcon_enable,
|
||||||
|
.ctrlbit = S3C2410_CLKCON_SPI,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct clk init_clocks[] = {
|
||||||
|
{
|
||||||
|
.name = "lcd",
|
||||||
|
.id = -1,
|
||||||
|
.parent = &clk_h,
|
||||||
|
.enable = s3c2410_clkcon_enable,
|
||||||
|
.ctrlbit = S3C2410_CLKCON_LCDC,
|
||||||
|
}, {
|
||||||
|
.name = "gpio",
|
||||||
|
.id = -1,
|
||||||
|
.parent = &clk_p,
|
||||||
|
.enable = s3c2410_clkcon_enable,
|
||||||
|
.ctrlbit = S3C2410_CLKCON_GPIO,
|
||||||
|
}, {
|
||||||
|
.name = "usb-host",
|
||||||
|
.id = -1,
|
||||||
|
.parent = &clk_h,
|
||||||
|
.enable = s3c2410_clkcon_enable,
|
||||||
|
.ctrlbit = S3C2410_CLKCON_USBH,
|
||||||
|
}, {
|
||||||
|
.name = "usb-device",
|
||||||
|
.id = -1,
|
||||||
|
.parent = &clk_h,
|
||||||
|
.enable = s3c2410_clkcon_enable,
|
||||||
|
.ctrlbit = S3C2410_CLKCON_USBD,
|
||||||
|
}, {
|
||||||
|
.name = "timers",
|
||||||
|
.id = -1,
|
||||||
|
.parent = &clk_p,
|
||||||
|
.enable = s3c2410_clkcon_enable,
|
||||||
|
.ctrlbit = S3C2410_CLKCON_PWMT,
|
||||||
|
}, {
|
||||||
|
.name = "uart",
|
||||||
|
.id = 0,
|
||||||
|
.parent = &clk_p,
|
||||||
|
.enable = s3c2410_clkcon_enable,
|
||||||
|
.ctrlbit = S3C2410_CLKCON_UART0,
|
||||||
|
}, {
|
||||||
|
.name = "uart",
|
||||||
|
.id = 1,
|
||||||
|
.parent = &clk_p,
|
||||||
|
.enable = s3c2410_clkcon_enable,
|
||||||
|
.ctrlbit = S3C2410_CLKCON_UART1,
|
||||||
|
}, {
|
||||||
|
.name = "uart",
|
||||||
|
.id = 2,
|
||||||
|
.parent = &clk_p,
|
||||||
|
.enable = s3c2410_clkcon_enable,
|
||||||
|
.ctrlbit = S3C2410_CLKCON_UART2,
|
||||||
|
}, {
|
||||||
|
.name = "rtc",
|
||||||
|
.id = -1,
|
||||||
|
.parent = &clk_p,
|
||||||
|
.enable = s3c2410_clkcon_enable,
|
||||||
|
.ctrlbit = S3C2410_CLKCON_RTC,
|
||||||
|
}, {
|
||||||
|
.name = "watchdog",
|
||||||
|
.id = -1,
|
||||||
|
.parent = &clk_p,
|
||||||
|
.ctrlbit = 0,
|
||||||
|
}, {
|
||||||
|
.name = "usb-bus-host",
|
||||||
|
.id = -1,
|
||||||
|
.parent = &clk_usb_bus,
|
||||||
|
}, {
|
||||||
|
.name = "usb-bus-gadget",
|
||||||
|
.id = -1,
|
||||||
|
.parent = &clk_usb_bus,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
/* s3c2410_baseclk_add()
|
||||||
|
*
|
||||||
|
* Add all the clocks used by the s3c2410 or compatible CPUs
|
||||||
|
* such as the S3C2440 and S3C2442.
|
||||||
|
*
|
||||||
|
* We cannot use a system device as we are needed before any
|
||||||
|
* of the init-calls that initialise the devices are actually
|
||||||
|
* done.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int __init s3c2410_baseclk_add(void)
|
||||||
|
{
|
||||||
|
unsigned long clkslow = __raw_readl(S3C2410_CLKSLOW);
|
||||||
|
unsigned long clkcon = __raw_readl(S3C2410_CLKCON);
|
||||||
|
struct clk *clkp;
|
||||||
|
struct clk *xtal;
|
||||||
|
int ret;
|
||||||
|
int ptr;
|
||||||
|
|
||||||
|
clk_upll.enable = s3c2410_upll_enable;
|
||||||
|
|
||||||
|
if (s3c24xx_register_clock(&clk_usb_bus) < 0)
|
||||||
|
printk(KERN_ERR "failed to register usb bus clock\n");
|
||||||
|
|
||||||
|
/* register clocks from clock array */
|
||||||
|
|
||||||
|
clkp = init_clocks;
|
||||||
|
for (ptr = 0; ptr < ARRAY_SIZE(init_clocks); ptr++, clkp++) {
|
||||||
|
/* ensure that we note the clock state */
|
||||||
|
|
||||||
|
clkp->usage = clkcon & clkp->ctrlbit ? 1 : 0;
|
||||||
|
|
||||||
|
ret = s3c24xx_register_clock(clkp);
|
||||||
|
if (ret < 0) {
|
||||||
|
printk(KERN_ERR "Failed to register clock %s (%d)\n",
|
||||||
|
clkp->name, ret);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
__raw_writel(dclkcon, S3C24XX_DCLKCON);
|
/* We must be careful disabling the clocks we are not intending to
|
||||||
|
* be using at boot time, as subsytems such as the LCD which do
|
||||||
|
* their own DMA requests to the bus can cause the system to lockup
|
||||||
|
* if they where in the middle of requesting bus access.
|
||||||
|
*
|
||||||
|
* Disabling the LCD clock if the LCD is active is very dangerous,
|
||||||
|
* and therefore the bootloader should be careful to not enable
|
||||||
|
* the LCD clock if it is not needed.
|
||||||
|
*/
|
||||||
|
|
||||||
return 0;
|
/* install (and disable) the clocks we do not need immediately */
|
||||||
}
|
|
||||||
|
|
||||||
|
clkp = init_clocks_disable;
|
||||||
|
for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) {
|
||||||
|
|
||||||
static int s3c24xx_clkout_setparent(struct clk *clk, struct clk *parent)
|
ret = s3c24xx_register_clock(clkp);
|
||||||
{
|
if (ret < 0) {
|
||||||
unsigned long mask;
|
printk(KERN_ERR "Failed to register clock %s (%d)\n",
|
||||||
unsigned long source;
|
clkp->name, ret);
|
||||||
|
}
|
||||||
|
|
||||||
/* calculate the MISCCR setting for the clock */
|
s3c2410_clkcon_enable(clkp, 0);
|
||||||
|
|
||||||
if (parent == &clk_xtal)
|
|
||||||
source = S3C2410_MISCCR_CLK0_MPLL;
|
|
||||||
else if (parent == &clk_upll)
|
|
||||||
source = S3C2410_MISCCR_CLK0_UPLL;
|
|
||||||
else if (parent == &clk_f)
|
|
||||||
source = S3C2410_MISCCR_CLK0_FCLK;
|
|
||||||
else if (parent == &clk_h)
|
|
||||||
source = S3C2410_MISCCR_CLK0_HCLK;
|
|
||||||
else if (parent == &clk_p)
|
|
||||||
source = S3C2410_MISCCR_CLK0_PCLK;
|
|
||||||
else if (clk == &s3c24xx_clkout0 && parent == &s3c24xx_dclk0)
|
|
||||||
source = S3C2410_MISCCR_CLK0_DCLK0;
|
|
||||||
else if (clk == &s3c24xx_clkout1 && parent == &s3c24xx_dclk1)
|
|
||||||
source = S3C2410_MISCCR_CLK0_DCLK0;
|
|
||||||
else
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
clk->parent = parent;
|
|
||||||
|
|
||||||
if (clk == &s3c24xx_dclk0)
|
|
||||||
mask = S3C2410_MISCCR_CLK0_MASK;
|
|
||||||
else {
|
|
||||||
source <<= 4;
|
|
||||||
mask = S3C2410_MISCCR_CLK1_MASK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
s3c2410_modify_misccr(mask, source);
|
/* show the clock-slow value */
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* external clock definitions */
|
xtal = clk_get(NULL, "xtal");
|
||||||
|
|
||||||
struct clk s3c24xx_dclk0 = {
|
printk("CLOCK: Slow mode (%ld.%ld MHz), %s, MPLL %s, UPLL %s\n",
|
||||||
.name = "dclk0",
|
print_mhz(clk_get_rate(xtal) /
|
||||||
.id = -1,
|
( 2 * S3C2410_CLKSLOW_GET_SLOWVAL(clkslow))),
|
||||||
.ctrlbit = S3C2410_DCLKCON_DCLK0EN,
|
(clkslow & S3C2410_CLKSLOW_SLOW) ? "slow" : "fast",
|
||||||
.enable = s3c24xx_dclk_enable,
|
(clkslow & S3C2410_CLKSLOW_MPLL_OFF) ? "off" : "on",
|
||||||
.set_parent = s3c24xx_dclk_setparent,
|
(clkslow & S3C2410_CLKSLOW_UCLK_OFF) ? "off" : "on");
|
||||||
};
|
|
||||||
|
|
||||||
struct clk s3c24xx_dclk1 = {
|
|
||||||
.name = "dclk1",
|
|
||||||
.id = -1,
|
|
||||||
.ctrlbit = S3C2410_DCLKCON_DCLK0EN,
|
|
||||||
.enable = s3c24xx_dclk_enable,
|
|
||||||
.set_parent = s3c24xx_dclk_setparent,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct clk s3c24xx_clkout0 = {
|
|
||||||
.name = "clkout0",
|
|
||||||
.id = -1,
|
|
||||||
.set_parent = s3c24xx_clkout_setparent,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct clk s3c24xx_clkout1 = {
|
|
||||||
.name = "clkout1",
|
|
||||||
.id = -1,
|
|
||||||
.set_parent = s3c24xx_clkout_setparent,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct clk s3c24xx_uclk = {
|
|
||||||
.name = "uclk",
|
|
||||||
.id = -1,
|
|
||||||
};
|
|
||||||
|
|
||||||
/* initialise the clock system */
|
|
||||||
|
|
||||||
int s3c24xx_register_clock(struct clk *clk)
|
|
||||||
{
|
|
||||||
clk->owner = THIS_MODULE;
|
|
||||||
|
|
||||||
if (clk->enable == NULL)
|
|
||||||
clk->enable = clk_null_enable;
|
|
||||||
|
|
||||||
/* add to the list of available clocks */
|
|
||||||
|
|
||||||
mutex_lock(&clocks_mutex);
|
|
||||||
list_add(&clk->list, &clocks);
|
|
||||||
mutex_unlock(&clocks_mutex);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* initalise all the clocks */
|
|
||||||
|
|
||||||
int __init s3c24xx_setup_clocks(unsigned long xtal,
|
|
||||||
unsigned long fclk,
|
|
||||||
unsigned long hclk,
|
|
||||||
unsigned long pclk)
|
|
||||||
{
|
|
||||||
printk(KERN_INFO "S3C24XX Clocks, (c) 2004 Simtec Electronics\n");
|
|
||||||
|
|
||||||
/* initialise the main system clocks */
|
|
||||||
|
|
||||||
clk_xtal.rate = xtal;
|
|
||||||
clk_upll.rate = s3c2410_get_pll(__raw_readl(S3C2410_UPLLCON), xtal);
|
|
||||||
|
|
||||||
clk_mpll.rate = fclk;
|
|
||||||
clk_h.rate = hclk;
|
|
||||||
clk_p.rate = pclk;
|
|
||||||
clk_f.rate = fclk;
|
|
||||||
|
|
||||||
/* assume uart clocks are correctly setup */
|
|
||||||
|
|
||||||
/* register our clocks */
|
|
||||||
|
|
||||||
if (s3c24xx_register_clock(&clk_xtal) < 0)
|
|
||||||
printk(KERN_ERR "failed to register master xtal\n");
|
|
||||||
|
|
||||||
if (s3c24xx_register_clock(&clk_mpll) < 0)
|
|
||||||
printk(KERN_ERR "failed to register mpll clock\n");
|
|
||||||
|
|
||||||
if (s3c24xx_register_clock(&clk_upll) < 0)
|
|
||||||
printk(KERN_ERR "failed to register upll clock\n");
|
|
||||||
|
|
||||||
if (s3c24xx_register_clock(&clk_f) < 0)
|
|
||||||
printk(KERN_ERR "failed to register cpu fclk\n");
|
|
||||||
|
|
||||||
if (s3c24xx_register_clock(&clk_h) < 0)
|
|
||||||
printk(KERN_ERR "failed to register cpu hclk\n");
|
|
||||||
|
|
||||||
if (s3c24xx_register_clock(&clk_p) < 0)
|
|
||||||
printk(KERN_ERR "failed to register cpu pclk\n");
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,9 +1,9 @@
|
||||||
/* linux/arch/arm/mach-s3c2410/gpio.c
|
/* linux/arch/arm/mach-s3c2410/gpio.c
|
||||||
*
|
*
|
||||||
* Copyright (c) 2004-2005 Simtec Electronics
|
* Copyright (c) 2004-2006 Simtec Electronics
|
||||||
* Ben Dooks <ben@simtec.co.uk>
|
* Ben Dooks <ben@simtec.co.uk>
|
||||||
*
|
*
|
||||||
* S3C24XX GPIO support
|
* S3C2410 GPIO support
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -18,8 +18,7 @@
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
|
@ -33,156 +32,40 @@
|
||||||
|
|
||||||
#include <asm/arch/regs-gpio.h>
|
#include <asm/arch/regs-gpio.h>
|
||||||
|
|
||||||
void s3c2410_gpio_cfgpin(unsigned int pin, unsigned int function)
|
int s3c2410_gpio_irqfilter(unsigned int pin, unsigned int on,
|
||||||
|
unsigned int config)
|
||||||
{
|
{
|
||||||
void __iomem *base = S3C24XX_GPIO_BASE(pin);
|
void __iomem *reg = S3C24XX_EINFLT0;
|
||||||
unsigned long mask;
|
|
||||||
unsigned long con;
|
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
unsigned long val;
|
||||||
|
|
||||||
if (pin < S3C2410_GPIO_BANKB) {
|
if (pin < S3C2410_GPG8 || pin > S3C2410_GPG15)
|
||||||
mask = 1 << S3C2410_GPIO_OFFSET(pin);
|
return -1;
|
||||||
} else {
|
|
||||||
mask = 3 << S3C2410_GPIO_OFFSET(pin)*2;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (function) {
|
config &= 0xff;
|
||||||
case S3C2410_GPIO_LEAVE:
|
|
||||||
mask = 0;
|
|
||||||
function = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case S3C2410_GPIO_INPUT:
|
pin -= S3C2410_GPG8;
|
||||||
case S3C2410_GPIO_OUTPUT:
|
reg += pin & ~3;
|
||||||
case S3C2410_GPIO_SFN2:
|
|
||||||
case S3C2410_GPIO_SFN3:
|
|
||||||
if (pin < S3C2410_GPIO_BANKB) {
|
|
||||||
function -= 1;
|
|
||||||
function &= 1;
|
|
||||||
function <<= S3C2410_GPIO_OFFSET(pin);
|
|
||||||
} else {
|
|
||||||
function &= 3;
|
|
||||||
function <<= S3C2410_GPIO_OFFSET(pin)*2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* modify the specified register wwith IRQs off */
|
|
||||||
|
|
||||||
local_irq_save(flags);
|
local_irq_save(flags);
|
||||||
|
|
||||||
con = __raw_readl(base + 0x00);
|
/* update filter width and clock source */
|
||||||
con &= ~mask;
|
|
||||||
con |= function;
|
|
||||||
|
|
||||||
__raw_writel(con, base + 0x00);
|
val = __raw_readl(reg);
|
||||||
|
val &= ~(0xff << ((pin & 3) * 8));
|
||||||
|
val |= config << ((pin & 3) * 8);
|
||||||
|
__raw_writel(val, reg);
|
||||||
|
|
||||||
|
/* update filter enable */
|
||||||
|
|
||||||
|
val = __raw_readl(S3C24XX_EXTINT2);
|
||||||
|
val &= ~(1 << ((pin * 4) + 3));
|
||||||
|
val |= on << ((pin * 4) + 3);
|
||||||
|
__raw_writel(val, S3C24XX_EXTINT2);
|
||||||
|
|
||||||
local_irq_restore(flags);
|
local_irq_restore(flags);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT_SYMBOL(s3c2410_gpio_cfgpin);
|
EXPORT_SYMBOL(s3c2410_gpio_irqfilter);
|
||||||
|
|
||||||
unsigned int s3c2410_gpio_getcfg(unsigned int pin)
|
|
||||||
{
|
|
||||||
void __iomem *base = S3C24XX_GPIO_BASE(pin);
|
|
||||||
unsigned long val = __raw_readl(base);
|
|
||||||
|
|
||||||
if (pin < S3C2410_GPIO_BANKB) {
|
|
||||||
val >>= S3C2410_GPIO_OFFSET(pin);
|
|
||||||
val &= 1;
|
|
||||||
val += 1;
|
|
||||||
} else {
|
|
||||||
val >>= S3C2410_GPIO_OFFSET(pin)*2;
|
|
||||||
val &= 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
return val | S3C2410_GPIO_INPUT;
|
|
||||||
}
|
|
||||||
|
|
||||||
EXPORT_SYMBOL(s3c2410_gpio_getcfg);
|
|
||||||
|
|
||||||
void s3c2410_gpio_pullup(unsigned int pin, unsigned int to)
|
|
||||||
{
|
|
||||||
void __iomem *base = S3C24XX_GPIO_BASE(pin);
|
|
||||||
unsigned long offs = S3C2410_GPIO_OFFSET(pin);
|
|
||||||
unsigned long flags;
|
|
||||||
unsigned long up;
|
|
||||||
|
|
||||||
if (pin < S3C2410_GPIO_BANKB)
|
|
||||||
return;
|
|
||||||
|
|
||||||
local_irq_save(flags);
|
|
||||||
|
|
||||||
up = __raw_readl(base + 0x08);
|
|
||||||
up &= ~(1L << offs);
|
|
||||||
up |= to << offs;
|
|
||||||
__raw_writel(up, base + 0x08);
|
|
||||||
|
|
||||||
local_irq_restore(flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
EXPORT_SYMBOL(s3c2410_gpio_pullup);
|
|
||||||
|
|
||||||
void s3c2410_gpio_setpin(unsigned int pin, unsigned int to)
|
|
||||||
{
|
|
||||||
void __iomem *base = S3C24XX_GPIO_BASE(pin);
|
|
||||||
unsigned long offs = S3C2410_GPIO_OFFSET(pin);
|
|
||||||
unsigned long flags;
|
|
||||||
unsigned long dat;
|
|
||||||
|
|
||||||
local_irq_save(flags);
|
|
||||||
|
|
||||||
dat = __raw_readl(base + 0x04);
|
|
||||||
dat &= ~(1 << offs);
|
|
||||||
dat |= to << offs;
|
|
||||||
__raw_writel(dat, base + 0x04);
|
|
||||||
|
|
||||||
local_irq_restore(flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
EXPORT_SYMBOL(s3c2410_gpio_setpin);
|
|
||||||
|
|
||||||
unsigned int s3c2410_gpio_getpin(unsigned int pin)
|
|
||||||
{
|
|
||||||
void __iomem *base = S3C24XX_GPIO_BASE(pin);
|
|
||||||
unsigned long offs = S3C2410_GPIO_OFFSET(pin);
|
|
||||||
|
|
||||||
return __raw_readl(base + 0x04) & (1<< offs);
|
|
||||||
}
|
|
||||||
|
|
||||||
EXPORT_SYMBOL(s3c2410_gpio_getpin);
|
|
||||||
|
|
||||||
unsigned int s3c2410_modify_misccr(unsigned int clear, unsigned int change)
|
|
||||||
{
|
|
||||||
unsigned long flags;
|
|
||||||
unsigned long misccr;
|
|
||||||
|
|
||||||
local_irq_save(flags);
|
|
||||||
misccr = __raw_readl(S3C24XX_MISCCR);
|
|
||||||
misccr &= ~clear;
|
|
||||||
misccr ^= change;
|
|
||||||
__raw_writel(misccr, S3C24XX_MISCCR);
|
|
||||||
local_irq_restore(flags);
|
|
||||||
|
|
||||||
return misccr;
|
|
||||||
}
|
|
||||||
|
|
||||||
EXPORT_SYMBOL(s3c2410_modify_misccr);
|
|
||||||
|
|
||||||
int s3c2410_gpio_getirq(unsigned int pin)
|
|
||||||
{
|
|
||||||
if (pin < S3C2410_GPF0 || pin > S3C2410_GPG15)
|
|
||||||
return -1; /* not valid interrupts */
|
|
||||||
|
|
||||||
if (pin < S3C2410_GPG0 && pin > S3C2410_GPF7)
|
|
||||||
return -1; /* not valid pin */
|
|
||||||
|
|
||||||
if (pin < S3C2410_GPF4)
|
|
||||||
return (pin - S3C2410_GPF0) + IRQ_EINT0;
|
|
||||||
|
|
||||||
if (pin < S3C2410_GPG0)
|
|
||||||
return (pin - S3C2410_GPF4) + IRQ_EINT4;
|
|
||||||
|
|
||||||
return (pin - S3C2410_GPG0) + IRQ_EINT8;
|
|
||||||
}
|
|
||||||
|
|
||||||
EXPORT_SYMBOL(s3c2410_gpio_getirq);
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* linux/arch/arm/mach-s3c2410/irq.c
|
/* linux/arch/arm/mach-s3c2410/irq.c
|
||||||
*
|
*
|
||||||
* Copyright (c) 2003,2004 Simtec Electronics
|
* Copyright (c) 2006 Simtec Electronics
|
||||||
* Ben Dooks <ben@simtec.co.uk>
|
* Ben Dooks <ben@simtec.co.uk>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
@ -17,37 +17,6 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
*
|
*
|
||||||
* Changelog:
|
|
||||||
*
|
|
||||||
* 22-Jul-2004 Ben Dooks <ben@simtec.co.uk>
|
|
||||||
* Fixed compile warnings
|
|
||||||
*
|
|
||||||
* 22-Jul-2004 Roc Wu <cooloney@yahoo.com.cn>
|
|
||||||
* Fixed s3c_extirq_type
|
|
||||||
*
|
|
||||||
* 21-Jul-2004 Arnaud Patard (Rtp) <arnaud.patard@rtp-net.org>
|
|
||||||
* Addition of ADC/TC demux
|
|
||||||
*
|
|
||||||
* 04-Oct-2004 Klaus Fetscher <k.fetscher@fetron.de>
|
|
||||||
* Fix for set_irq_type() on low EINT numbers
|
|
||||||
*
|
|
||||||
* 05-Oct-2004 Ben Dooks <ben@simtec.co.uk>
|
|
||||||
* Tidy up KF's patch and sort out new release
|
|
||||||
*
|
|
||||||
* 05-Oct-2004 Ben Dooks <ben@simtec.co.uk>
|
|
||||||
* Add support for power management controls
|
|
||||||
*
|
|
||||||
* 04-Nov-2004 Ben Dooks
|
|
||||||
* Fix standard IRQ wake for EINT0..4 and RTC
|
|
||||||
*
|
|
||||||
* 22-Feb-2005 Ben Dooks
|
|
||||||
* Fixed edge-triggering on ADC IRQ
|
|
||||||
*
|
|
||||||
* 28-Jun-2005 Ben Dooks
|
|
||||||
* Mark IRQ_LCD valid
|
|
||||||
*
|
|
||||||
* 25-Jul-2005 Ben Dooks
|
|
||||||
* Split the S3C2440 IRQ code to seperate file
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
|
@ -57,745 +26,23 @@
|
||||||
#include <linux/ptrace.h>
|
#include <linux/ptrace.h>
|
||||||
#include <linux/sysdev.h>
|
#include <linux/sysdev.h>
|
||||||
|
|
||||||
#include <asm/hardware.h>
|
#include <asm/plat-s3c24xx/cpu.h>
|
||||||
#include <asm/irq.h>
|
#include <asm/plat-s3c24xx/pm.h>
|
||||||
#include <asm/io.h>
|
|
||||||
|
|
||||||
#include <asm/mach/irq.h>
|
static int s3c2410_irq_add(struct sys_device *sysdev)
|
||||||
|
|
||||||
#include <asm/arch/regs-irq.h>
|
|
||||||
#include <asm/arch/regs-gpio.h>
|
|
||||||
|
|
||||||
#include "cpu.h"
|
|
||||||
#include "pm.h"
|
|
||||||
#include "irq.h"
|
|
||||||
|
|
||||||
/* wakeup irq control */
|
|
||||||
|
|
||||||
#ifdef CONFIG_PM
|
|
||||||
|
|
||||||
/* state for IRQs over sleep */
|
|
||||||
|
|
||||||
/* default is to allow for EINT0..EINT15, and IRQ_RTC as wakeup sources
|
|
||||||
*
|
|
||||||
* set bit to 1 in allow bitfield to enable the wakeup settings on it
|
|
||||||
*/
|
|
||||||
|
|
||||||
unsigned long s3c_irqwake_intallow = 1L << (IRQ_RTC - IRQ_EINT0) | 0xfL;
|
|
||||||
unsigned long s3c_irqwake_intmask = 0xffffffffL;
|
|
||||||
unsigned long s3c_irqwake_eintallow = 0x0000fff0L;
|
|
||||||
unsigned long s3c_irqwake_eintmask = 0xffffffffL;
|
|
||||||
|
|
||||||
int
|
|
||||||
s3c_irq_wake(unsigned int irqno, unsigned int state)
|
|
||||||
{
|
{
|
||||||
unsigned long irqbit = 1 << (irqno - IRQ_EINT0);
|
|
||||||
|
|
||||||
if (!(s3c_irqwake_intallow & irqbit))
|
|
||||||
return -ENOENT;
|
|
||||||
|
|
||||||
printk(KERN_INFO "wake %s for irq %d\n",
|
|
||||||
state ? "enabled" : "disabled", irqno);
|
|
||||||
|
|
||||||
if (!state)
|
|
||||||
s3c_irqwake_intmask |= irqbit;
|
|
||||||
else
|
|
||||||
s3c_irqwake_intmask &= ~irqbit;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static struct sysdev_driver s3c2410_irq_driver = {
|
||||||
s3c_irqext_wake(unsigned int irqno, unsigned int state)
|
.add = s3c2410_irq_add,
|
||||||
{
|
.suspend = s3c24xx_irq_suspend,
|
||||||
unsigned long bit = 1L << (irqno - EXTINT_OFF);
|
.resume = s3c24xx_irq_resume,
|
||||||
|
|
||||||
if (!(s3c_irqwake_eintallow & bit))
|
|
||||||
return -ENOENT;
|
|
||||||
|
|
||||||
printk(KERN_INFO "wake %s for irq %d\n",
|
|
||||||
state ? "enabled" : "disabled", irqno);
|
|
||||||
|
|
||||||
if (!state)
|
|
||||||
s3c_irqwake_eintmask |= bit;
|
|
||||||
else
|
|
||||||
s3c_irqwake_eintmask &= ~bit;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
#define s3c_irqext_wake NULL
|
|
||||||
#define s3c_irq_wake NULL
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
s3c_irq_mask(unsigned int irqno)
|
|
||||||
{
|
|
||||||
unsigned long mask;
|
|
||||||
|
|
||||||
irqno -= IRQ_EINT0;
|
|
||||||
|
|
||||||
mask = __raw_readl(S3C2410_INTMSK);
|
|
||||||
mask |= 1UL << irqno;
|
|
||||||
__raw_writel(mask, S3C2410_INTMSK);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
s3c_irq_ack(unsigned int irqno)
|
|
||||||
{
|
|
||||||
unsigned long bitval = 1UL << (irqno - IRQ_EINT0);
|
|
||||||
|
|
||||||
__raw_writel(bitval, S3C2410_SRCPND);
|
|
||||||
__raw_writel(bitval, S3C2410_INTPND);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
s3c_irq_maskack(unsigned int irqno)
|
|
||||||
{
|
|
||||||
unsigned long bitval = 1UL << (irqno - IRQ_EINT0);
|
|
||||||
unsigned long mask;
|
|
||||||
|
|
||||||
mask = __raw_readl(S3C2410_INTMSK);
|
|
||||||
__raw_writel(mask|bitval, S3C2410_INTMSK);
|
|
||||||
|
|
||||||
__raw_writel(bitval, S3C2410_SRCPND);
|
|
||||||
__raw_writel(bitval, S3C2410_INTPND);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
s3c_irq_unmask(unsigned int irqno)
|
|
||||||
{
|
|
||||||
unsigned long mask;
|
|
||||||
|
|
||||||
if (irqno != IRQ_TIMER4 && irqno != IRQ_EINT8t23)
|
|
||||||
irqdbf2("s3c_irq_unmask %d\n", irqno);
|
|
||||||
|
|
||||||
irqno -= IRQ_EINT0;
|
|
||||||
|
|
||||||
mask = __raw_readl(S3C2410_INTMSK);
|
|
||||||
mask &= ~(1UL << irqno);
|
|
||||||
__raw_writel(mask, S3C2410_INTMSK);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct irq_chip s3c_irq_level_chip = {
|
|
||||||
.name = "s3c-level",
|
|
||||||
.ack = s3c_irq_maskack,
|
|
||||||
.mask = s3c_irq_mask,
|
|
||||||
.unmask = s3c_irq_unmask,
|
|
||||||
.set_wake = s3c_irq_wake
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct irq_chip s3c_irq_chip = {
|
static int s3c2410_irq_init(void)
|
||||||
.name = "s3c",
|
|
||||||
.ack = s3c_irq_ack,
|
|
||||||
.mask = s3c_irq_mask,
|
|
||||||
.unmask = s3c_irq_unmask,
|
|
||||||
.set_wake = s3c_irq_wake
|
|
||||||
};
|
|
||||||
|
|
||||||
static void
|
|
||||||
s3c_irqext_mask(unsigned int irqno)
|
|
||||||
{
|
{
|
||||||
unsigned long mask;
|
return sysdev_driver_register(&s3c2410_sysclass, &s3c2410_irq_driver);
|
||||||
|
|
||||||
irqno -= EXTINT_OFF;
|
|
||||||
|
|
||||||
mask = __raw_readl(S3C24XX_EINTMASK);
|
|
||||||
mask |= ( 1UL << irqno);
|
|
||||||
__raw_writel(mask, S3C24XX_EINTMASK);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
arch_initcall(s3c2410_irq_init);
|
||||||
s3c_irqext_ack(unsigned int irqno)
|
|
||||||
{
|
|
||||||
unsigned long req;
|
|
||||||
unsigned long bit;
|
|
||||||
unsigned long mask;
|
|
||||||
|
|
||||||
bit = 1UL << (irqno - EXTINT_OFF);
|
|
||||||
|
|
||||||
mask = __raw_readl(S3C24XX_EINTMASK);
|
|
||||||
|
|
||||||
__raw_writel(bit, S3C24XX_EINTPEND);
|
|
||||||
|
|
||||||
req = __raw_readl(S3C24XX_EINTPEND);
|
|
||||||
req &= ~mask;
|
|
||||||
|
|
||||||
/* not sure if we should be acking the parent irq... */
|
|
||||||
|
|
||||||
if (irqno <= IRQ_EINT7 ) {
|
|
||||||
if ((req & 0xf0) == 0)
|
|
||||||
s3c_irq_ack(IRQ_EINT4t7);
|
|
||||||
} else {
|
|
||||||
if ((req >> 8) == 0)
|
|
||||||
s3c_irq_ack(IRQ_EINT8t23);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
s3c_irqext_unmask(unsigned int irqno)
|
|
||||||
{
|
|
||||||
unsigned long mask;
|
|
||||||
|
|
||||||
irqno -= EXTINT_OFF;
|
|
||||||
|
|
||||||
mask = __raw_readl(S3C24XX_EINTMASK);
|
|
||||||
mask &= ~( 1UL << irqno);
|
|
||||||
__raw_writel(mask, S3C24XX_EINTMASK);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
s3c_irqext_type(unsigned int irq, unsigned int type)
|
|
||||||
{
|
|
||||||
void __iomem *extint_reg;
|
|
||||||
void __iomem *gpcon_reg;
|
|
||||||
unsigned long gpcon_offset, extint_offset;
|
|
||||||
unsigned long newvalue = 0, value;
|
|
||||||
|
|
||||||
if ((irq >= IRQ_EINT0) && (irq <= IRQ_EINT3))
|
|
||||||
{
|
|
||||||
gpcon_reg = S3C2410_GPFCON;
|
|
||||||
extint_reg = S3C24XX_EXTINT0;
|
|
||||||
gpcon_offset = (irq - IRQ_EINT0) * 2;
|
|
||||||
extint_offset = (irq - IRQ_EINT0) * 4;
|
|
||||||
}
|
|
||||||
else if ((irq >= IRQ_EINT4) && (irq <= IRQ_EINT7))
|
|
||||||
{
|
|
||||||
gpcon_reg = S3C2410_GPFCON;
|
|
||||||
extint_reg = S3C24XX_EXTINT0;
|
|
||||||
gpcon_offset = (irq - (EXTINT_OFF)) * 2;
|
|
||||||
extint_offset = (irq - (EXTINT_OFF)) * 4;
|
|
||||||
}
|
|
||||||
else if ((irq >= IRQ_EINT8) && (irq <= IRQ_EINT15))
|
|
||||||
{
|
|
||||||
gpcon_reg = S3C2410_GPGCON;
|
|
||||||
extint_reg = S3C24XX_EXTINT1;
|
|
||||||
gpcon_offset = (irq - IRQ_EINT8) * 2;
|
|
||||||
extint_offset = (irq - IRQ_EINT8) * 4;
|
|
||||||
}
|
|
||||||
else if ((irq >= IRQ_EINT16) && (irq <= IRQ_EINT23))
|
|
||||||
{
|
|
||||||
gpcon_reg = S3C2410_GPGCON;
|
|
||||||
extint_reg = S3C24XX_EXTINT2;
|
|
||||||
gpcon_offset = (irq - IRQ_EINT8) * 2;
|
|
||||||
extint_offset = (irq - IRQ_EINT16) * 4;
|
|
||||||
} else
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
/* Set the GPIO to external interrupt mode */
|
|
||||||
value = __raw_readl(gpcon_reg);
|
|
||||||
value = (value & ~(3 << gpcon_offset)) | (0x02 << gpcon_offset);
|
|
||||||
__raw_writel(value, gpcon_reg);
|
|
||||||
|
|
||||||
/* Set the external interrupt to pointed trigger type */
|
|
||||||
switch (type)
|
|
||||||
{
|
|
||||||
case IRQT_NOEDGE:
|
|
||||||
printk(KERN_WARNING "No edge setting!\n");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case IRQT_RISING:
|
|
||||||
newvalue = S3C2410_EXTINT_RISEEDGE;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case IRQT_FALLING:
|
|
||||||
newvalue = S3C2410_EXTINT_FALLEDGE;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case IRQT_BOTHEDGE:
|
|
||||||
newvalue = S3C2410_EXTINT_BOTHEDGE;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case IRQT_LOW:
|
|
||||||
newvalue = S3C2410_EXTINT_LOWLEV;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case IRQT_HIGH:
|
|
||||||
newvalue = S3C2410_EXTINT_HILEV;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
printk(KERN_ERR "No such irq type %d", type);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
value = __raw_readl(extint_reg);
|
|
||||||
value = (value & ~(7 << extint_offset)) | (newvalue << extint_offset);
|
|
||||||
__raw_writel(value, extint_reg);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct irq_chip s3c_irqext_chip = {
|
|
||||||
.name = "s3c-ext",
|
|
||||||
.mask = s3c_irqext_mask,
|
|
||||||
.unmask = s3c_irqext_unmask,
|
|
||||||
.ack = s3c_irqext_ack,
|
|
||||||
.set_type = s3c_irqext_type,
|
|
||||||
.set_wake = s3c_irqext_wake
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct irq_chip s3c_irq_eint0t4 = {
|
|
||||||
.name = "s3c-ext0",
|
|
||||||
.ack = s3c_irq_ack,
|
|
||||||
.mask = s3c_irq_mask,
|
|
||||||
.unmask = s3c_irq_unmask,
|
|
||||||
.set_wake = s3c_irq_wake,
|
|
||||||
.set_type = s3c_irqext_type,
|
|
||||||
};
|
|
||||||
|
|
||||||
/* mask values for the parent registers for each of the interrupt types */
|
|
||||||
|
|
||||||
#define INTMSK_UART0 (1UL << (IRQ_UART0 - IRQ_EINT0))
|
|
||||||
#define INTMSK_UART1 (1UL << (IRQ_UART1 - IRQ_EINT0))
|
|
||||||
#define INTMSK_UART2 (1UL << (IRQ_UART2 - IRQ_EINT0))
|
|
||||||
#define INTMSK_ADCPARENT (1UL << (IRQ_ADCPARENT - IRQ_EINT0))
|
|
||||||
|
|
||||||
|
|
||||||
/* UART0 */
|
|
||||||
|
|
||||||
static void
|
|
||||||
s3c_irq_uart0_mask(unsigned int irqno)
|
|
||||||
{
|
|
||||||
s3c_irqsub_mask(irqno, INTMSK_UART0, 7);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
s3c_irq_uart0_unmask(unsigned int irqno)
|
|
||||||
{
|
|
||||||
s3c_irqsub_unmask(irqno, INTMSK_UART0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
s3c_irq_uart0_ack(unsigned int irqno)
|
|
||||||
{
|
|
||||||
s3c_irqsub_maskack(irqno, INTMSK_UART0, 7);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct irq_chip s3c_irq_uart0 = {
|
|
||||||
.name = "s3c-uart0",
|
|
||||||
.mask = s3c_irq_uart0_mask,
|
|
||||||
.unmask = s3c_irq_uart0_unmask,
|
|
||||||
.ack = s3c_irq_uart0_ack,
|
|
||||||
};
|
|
||||||
|
|
||||||
/* UART1 */
|
|
||||||
|
|
||||||
static void
|
|
||||||
s3c_irq_uart1_mask(unsigned int irqno)
|
|
||||||
{
|
|
||||||
s3c_irqsub_mask(irqno, INTMSK_UART1, 7 << 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
s3c_irq_uart1_unmask(unsigned int irqno)
|
|
||||||
{
|
|
||||||
s3c_irqsub_unmask(irqno, INTMSK_UART1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
s3c_irq_uart1_ack(unsigned int irqno)
|
|
||||||
{
|
|
||||||
s3c_irqsub_maskack(irqno, INTMSK_UART1, 7 << 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct irq_chip s3c_irq_uart1 = {
|
|
||||||
.name = "s3c-uart1",
|
|
||||||
.mask = s3c_irq_uart1_mask,
|
|
||||||
.unmask = s3c_irq_uart1_unmask,
|
|
||||||
.ack = s3c_irq_uart1_ack,
|
|
||||||
};
|
|
||||||
|
|
||||||
/* UART2 */
|
|
||||||
|
|
||||||
static void
|
|
||||||
s3c_irq_uart2_mask(unsigned int irqno)
|
|
||||||
{
|
|
||||||
s3c_irqsub_mask(irqno, INTMSK_UART2, 7 << 6);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
s3c_irq_uart2_unmask(unsigned int irqno)
|
|
||||||
{
|
|
||||||
s3c_irqsub_unmask(irqno, INTMSK_UART2);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
s3c_irq_uart2_ack(unsigned int irqno)
|
|
||||||
{
|
|
||||||
s3c_irqsub_maskack(irqno, INTMSK_UART2, 7 << 6);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct irq_chip s3c_irq_uart2 = {
|
|
||||||
.name = "s3c-uart2",
|
|
||||||
.mask = s3c_irq_uart2_mask,
|
|
||||||
.unmask = s3c_irq_uart2_unmask,
|
|
||||||
.ack = s3c_irq_uart2_ack,
|
|
||||||
};
|
|
||||||
|
|
||||||
/* ADC and Touchscreen */
|
|
||||||
|
|
||||||
static void
|
|
||||||
s3c_irq_adc_mask(unsigned int irqno)
|
|
||||||
{
|
|
||||||
s3c_irqsub_mask(irqno, INTMSK_ADCPARENT, 3 << 9);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
s3c_irq_adc_unmask(unsigned int irqno)
|
|
||||||
{
|
|
||||||
s3c_irqsub_unmask(irqno, INTMSK_ADCPARENT);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
s3c_irq_adc_ack(unsigned int irqno)
|
|
||||||
{
|
|
||||||
s3c_irqsub_ack(irqno, INTMSK_ADCPARENT, 3 << 9);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct irq_chip s3c_irq_adc = {
|
|
||||||
.name = "s3c-adc",
|
|
||||||
.mask = s3c_irq_adc_mask,
|
|
||||||
.unmask = s3c_irq_adc_unmask,
|
|
||||||
.ack = s3c_irq_adc_ack,
|
|
||||||
};
|
|
||||||
|
|
||||||
/* irq demux for adc */
|
|
||||||
static void s3c_irq_demux_adc(unsigned int irq,
|
|
||||||
struct irq_desc *desc)
|
|
||||||
{
|
|
||||||
unsigned int subsrc, submsk;
|
|
||||||
unsigned int offset = 9;
|
|
||||||
struct irq_desc *mydesc;
|
|
||||||
|
|
||||||
/* read the current pending interrupts, and the mask
|
|
||||||
* for what it is available */
|
|
||||||
|
|
||||||
subsrc = __raw_readl(S3C2410_SUBSRCPND);
|
|
||||||
submsk = __raw_readl(S3C2410_INTSUBMSK);
|
|
||||||
|
|
||||||
subsrc &= ~submsk;
|
|
||||||
subsrc >>= offset;
|
|
||||||
subsrc &= 3;
|
|
||||||
|
|
||||||
if (subsrc != 0) {
|
|
||||||
if (subsrc & 1) {
|
|
||||||
mydesc = irq_desc + IRQ_TC;
|
|
||||||
desc_handle_irq(IRQ_TC, mydesc);
|
|
||||||
}
|
|
||||||
if (subsrc & 2) {
|
|
||||||
mydesc = irq_desc + IRQ_ADC;
|
|
||||||
desc_handle_irq(IRQ_ADC, mydesc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void s3c_irq_demux_uart(unsigned int start)
|
|
||||||
{
|
|
||||||
unsigned int subsrc, submsk;
|
|
||||||
unsigned int offset = start - IRQ_S3CUART_RX0;
|
|
||||||
struct irq_desc *desc;
|
|
||||||
|
|
||||||
/* read the current pending interrupts, and the mask
|
|
||||||
* for what it is available */
|
|
||||||
|
|
||||||
subsrc = __raw_readl(S3C2410_SUBSRCPND);
|
|
||||||
submsk = __raw_readl(S3C2410_INTSUBMSK);
|
|
||||||
|
|
||||||
irqdbf2("s3c_irq_demux_uart: start=%d (%d), subsrc=0x%08x,0x%08x\n",
|
|
||||||
start, offset, subsrc, submsk);
|
|
||||||
|
|
||||||
subsrc &= ~submsk;
|
|
||||||
subsrc >>= offset;
|
|
||||||
subsrc &= 7;
|
|
||||||
|
|
||||||
if (subsrc != 0) {
|
|
||||||
desc = irq_desc + start;
|
|
||||||
|
|
||||||
if (subsrc & 1)
|
|
||||||
desc_handle_irq(start, desc);
|
|
||||||
|
|
||||||
desc++;
|
|
||||||
|
|
||||||
if (subsrc & 2)
|
|
||||||
desc_handle_irq(start+1, desc);
|
|
||||||
|
|
||||||
desc++;
|
|
||||||
|
|
||||||
if (subsrc & 4)
|
|
||||||
desc_handle_irq(start+2, desc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* uart demux entry points */
|
|
||||||
|
|
||||||
static void
|
|
||||||
s3c_irq_demux_uart0(unsigned int irq,
|
|
||||||
struct irq_desc *desc)
|
|
||||||
{
|
|
||||||
irq = irq;
|
|
||||||
s3c_irq_demux_uart(IRQ_S3CUART_RX0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
s3c_irq_demux_uart1(unsigned int irq,
|
|
||||||
struct irq_desc *desc)
|
|
||||||
{
|
|
||||||
irq = irq;
|
|
||||||
s3c_irq_demux_uart(IRQ_S3CUART_RX1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
s3c_irq_demux_uart2(unsigned int irq,
|
|
||||||
struct irq_desc *desc)
|
|
||||||
{
|
|
||||||
irq = irq;
|
|
||||||
s3c_irq_demux_uart(IRQ_S3CUART_RX2);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
s3c_irq_demux_extint8(unsigned int irq,
|
|
||||||
struct irq_desc *desc)
|
|
||||||
{
|
|
||||||
unsigned long eintpnd = __raw_readl(S3C24XX_EINTPEND);
|
|
||||||
unsigned long eintmsk = __raw_readl(S3C24XX_EINTMASK);
|
|
||||||
|
|
||||||
eintpnd &= ~eintmsk;
|
|
||||||
eintpnd &= ~0xff; /* ignore lower irqs */
|
|
||||||
|
|
||||||
/* we may as well handle all the pending IRQs here */
|
|
||||||
|
|
||||||
while (eintpnd) {
|
|
||||||
irq = __ffs(eintpnd);
|
|
||||||
eintpnd &= ~(1<<irq);
|
|
||||||
|
|
||||||
irq += (IRQ_EINT4 - 4);
|
|
||||||
desc_handle_irq(irq, irq_desc + irq);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
s3c_irq_demux_extint4t7(unsigned int irq,
|
|
||||||
struct irq_desc *desc)
|
|
||||||
{
|
|
||||||
unsigned long eintpnd = __raw_readl(S3C24XX_EINTPEND);
|
|
||||||
unsigned long eintmsk = __raw_readl(S3C24XX_EINTMASK);
|
|
||||||
|
|
||||||
eintpnd &= ~eintmsk;
|
|
||||||
eintpnd &= 0xff; /* only lower irqs */
|
|
||||||
|
|
||||||
/* we may as well handle all the pending IRQs here */
|
|
||||||
|
|
||||||
while (eintpnd) {
|
|
||||||
irq = __ffs(eintpnd);
|
|
||||||
eintpnd &= ~(1<<irq);
|
|
||||||
|
|
||||||
irq += (IRQ_EINT4 - 4);
|
|
||||||
|
|
||||||
desc_handle_irq(irq, irq_desc + irq);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef CONFIG_PM
|
|
||||||
|
|
||||||
static struct sleep_save irq_save[] = {
|
|
||||||
SAVE_ITEM(S3C2410_INTMSK),
|
|
||||||
SAVE_ITEM(S3C2410_INTSUBMSK),
|
|
||||||
};
|
|
||||||
|
|
||||||
/* the extint values move between the s3c2410/s3c2440 and the s3c2412
|
|
||||||
* so we use an array to hold them, and to calculate the address of
|
|
||||||
* the register at run-time
|
|
||||||
*/
|
|
||||||
|
|
||||||
static unsigned long save_extint[3];
|
|
||||||
static unsigned long save_eintflt[4];
|
|
||||||
static unsigned long save_eintmask;
|
|
||||||
|
|
||||||
int s3c24xx_irq_suspend(struct sys_device *dev, pm_message_t state)
|
|
||||||
{
|
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(save_extint); i++)
|
|
||||||
save_extint[i] = __raw_readl(S3C24XX_EXTINT0 + (i*4));
|
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(save_eintflt); i++)
|
|
||||||
save_eintflt[i] = __raw_readl(S3C24XX_EINFLT0 + (i*4));
|
|
||||||
|
|
||||||
s3c2410_pm_do_save(irq_save, ARRAY_SIZE(irq_save));
|
|
||||||
save_eintmask = __raw_readl(S3C24XX_EINTMASK);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int s3c24xx_irq_resume(struct sys_device *dev)
|
|
||||||
{
|
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(save_extint); i++)
|
|
||||||
__raw_writel(save_extint[i], S3C24XX_EXTINT0 + (i*4));
|
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(save_eintflt); i++)
|
|
||||||
__raw_writel(save_eintflt[i], S3C24XX_EINFLT0 + (i*4));
|
|
||||||
|
|
||||||
s3c2410_pm_do_restore(irq_save, ARRAY_SIZE(irq_save));
|
|
||||||
__raw_writel(save_eintmask, S3C24XX_EINTMASK);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
#define s3c24xx_irq_suspend NULL
|
|
||||||
#define s3c24xx_irq_resume NULL
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* s3c24xx_init_irq
|
|
||||||
*
|
|
||||||
* Initialise S3C2410 IRQ system
|
|
||||||
*/
|
|
||||||
|
|
||||||
void __init s3c24xx_init_irq(void)
|
|
||||||
{
|
|
||||||
unsigned long pend;
|
|
||||||
unsigned long last;
|
|
||||||
int irqno;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
irqdbf("s3c2410_init_irq: clearing interrupt status flags\n");
|
|
||||||
|
|
||||||
/* first, clear all interrupts pending... */
|
|
||||||
|
|
||||||
last = 0;
|
|
||||||
for (i = 0; i < 4; i++) {
|
|
||||||
pend = __raw_readl(S3C24XX_EINTPEND);
|
|
||||||
|
|
||||||
if (pend == 0 || pend == last)
|
|
||||||
break;
|
|
||||||
|
|
||||||
__raw_writel(pend, S3C24XX_EINTPEND);
|
|
||||||
printk("irq: clearing pending ext status %08x\n", (int)pend);
|
|
||||||
last = pend;
|
|
||||||
}
|
|
||||||
|
|
||||||
last = 0;
|
|
||||||
for (i = 0; i < 4; i++) {
|
|
||||||
pend = __raw_readl(S3C2410_INTPND);
|
|
||||||
|
|
||||||
if (pend == 0 || pend == last)
|
|
||||||
break;
|
|
||||||
|
|
||||||
__raw_writel(pend, S3C2410_SRCPND);
|
|
||||||
__raw_writel(pend, S3C2410_INTPND);
|
|
||||||
printk("irq: clearing pending status %08x\n", (int)pend);
|
|
||||||
last = pend;
|
|
||||||
}
|
|
||||||
|
|
||||||
last = 0;
|
|
||||||
for (i = 0; i < 4; i++) {
|
|
||||||
pend = __raw_readl(S3C2410_SUBSRCPND);
|
|
||||||
|
|
||||||
if (pend == 0 || pend == last)
|
|
||||||
break;
|
|
||||||
|
|
||||||
printk("irq: clearing subpending status %08x\n", (int)pend);
|
|
||||||
__raw_writel(pend, S3C2410_SUBSRCPND);
|
|
||||||
last = pend;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* register the main interrupts */
|
|
||||||
|
|
||||||
irqdbf("s3c2410_init_irq: registering s3c2410 interrupt handlers\n");
|
|
||||||
|
|
||||||
for (irqno = IRQ_EINT4t7; irqno <= IRQ_ADCPARENT; irqno++) {
|
|
||||||
/* set all the s3c2410 internal irqs */
|
|
||||||
|
|
||||||
switch (irqno) {
|
|
||||||
/* deal with the special IRQs (cascaded) */
|
|
||||||
|
|
||||||
case IRQ_EINT4t7:
|
|
||||||
case IRQ_EINT8t23:
|
|
||||||
case IRQ_UART0:
|
|
||||||
case IRQ_UART1:
|
|
||||||
case IRQ_UART2:
|
|
||||||
case IRQ_ADCPARENT:
|
|
||||||
set_irq_chip(irqno, &s3c_irq_level_chip);
|
|
||||||
set_irq_handler(irqno, handle_level_irq);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case IRQ_RESERVED6:
|
|
||||||
case IRQ_RESERVED24:
|
|
||||||
/* no IRQ here */
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
//irqdbf("registering irq %d (s3c irq)\n", irqno);
|
|
||||||
set_irq_chip(irqno, &s3c_irq_chip);
|
|
||||||
set_irq_handler(irqno, handle_edge_irq);
|
|
||||||
set_irq_flags(irqno, IRQF_VALID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* setup the cascade irq handlers */
|
|
||||||
|
|
||||||
set_irq_chained_handler(IRQ_EINT4t7, s3c_irq_demux_extint4t7);
|
|
||||||
set_irq_chained_handler(IRQ_EINT8t23, s3c_irq_demux_extint8);
|
|
||||||
|
|
||||||
set_irq_chained_handler(IRQ_UART0, s3c_irq_demux_uart0);
|
|
||||||
set_irq_chained_handler(IRQ_UART1, s3c_irq_demux_uart1);
|
|
||||||
set_irq_chained_handler(IRQ_UART2, s3c_irq_demux_uart2);
|
|
||||||
set_irq_chained_handler(IRQ_ADCPARENT, s3c_irq_demux_adc);
|
|
||||||
|
|
||||||
/* external interrupts */
|
|
||||||
|
|
||||||
for (irqno = IRQ_EINT0; irqno <= IRQ_EINT3; irqno++) {
|
|
||||||
irqdbf("registering irq %d (ext int)\n", irqno);
|
|
||||||
set_irq_chip(irqno, &s3c_irq_eint0t4);
|
|
||||||
set_irq_handler(irqno, handle_edge_irq);
|
|
||||||
set_irq_flags(irqno, IRQF_VALID);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (irqno = IRQ_EINT4; irqno <= IRQ_EINT23; irqno++) {
|
|
||||||
irqdbf("registering irq %d (extended s3c irq)\n", irqno);
|
|
||||||
set_irq_chip(irqno, &s3c_irqext_chip);
|
|
||||||
set_irq_handler(irqno, handle_edge_irq);
|
|
||||||
set_irq_flags(irqno, IRQF_VALID);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* register the uart interrupts */
|
|
||||||
|
|
||||||
irqdbf("s3c2410: registering external interrupts\n");
|
|
||||||
|
|
||||||
for (irqno = IRQ_S3CUART_RX0; irqno <= IRQ_S3CUART_ERR0; irqno++) {
|
|
||||||
irqdbf("registering irq %d (s3c uart0 irq)\n", irqno);
|
|
||||||
set_irq_chip(irqno, &s3c_irq_uart0);
|
|
||||||
set_irq_handler(irqno, handle_level_irq);
|
|
||||||
set_irq_flags(irqno, IRQF_VALID);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (irqno = IRQ_S3CUART_RX1; irqno <= IRQ_S3CUART_ERR1; irqno++) {
|
|
||||||
irqdbf("registering irq %d (s3c uart1 irq)\n", irqno);
|
|
||||||
set_irq_chip(irqno, &s3c_irq_uart1);
|
|
||||||
set_irq_handler(irqno, handle_level_irq);
|
|
||||||
set_irq_flags(irqno, IRQF_VALID);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (irqno = IRQ_S3CUART_RX2; irqno <= IRQ_S3CUART_ERR2; irqno++) {
|
|
||||||
irqdbf("registering irq %d (s3c uart2 irq)\n", irqno);
|
|
||||||
set_irq_chip(irqno, &s3c_irq_uart2);
|
|
||||||
set_irq_handler(irqno, handle_level_irq);
|
|
||||||
set_irq_flags(irqno, IRQF_VALID);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (irqno = IRQ_TC; irqno <= IRQ_ADC; irqno++) {
|
|
||||||
irqdbf("registering irq %d (s3c adc irq)\n", irqno);
|
|
||||||
set_irq_chip(irqno, &s3c_irq_adc);
|
|
||||||
set_irq_handler(irqno, handle_edge_irq);
|
|
||||||
set_irq_flags(irqno, IRQF_VALID);
|
|
||||||
}
|
|
||||||
|
|
||||||
irqdbf("s3c2410: registered interrupt handlers\n");
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/***********************************************************************
|
/* linux/arch/arm/mach-s3c2410/mach-amlm5900.c
|
||||||
*
|
*
|
||||||
* linux/arch/arm/mach-s3c2410/mach-amlm5900.c
|
* linux/arch/arm/mach-s3c2410/mach-amlm5900.c
|
||||||
*
|
*
|
||||||
|
@ -52,8 +52,8 @@
|
||||||
#include <asm/arch/regs-lcd.h>
|
#include <asm/arch/regs-lcd.h>
|
||||||
#include <asm/arch/regs-gpio.h>
|
#include <asm/arch/regs-gpio.h>
|
||||||
|
|
||||||
#include "devs.h"
|
#include <asm/plat-s3c24xx/devs.h>
|
||||||
#include "cpu.h"
|
#include <asm/plat-s3c24xx/cpu.h>
|
||||||
|
|
||||||
#ifdef CONFIG_MTD_PARTITIONS
|
#ifdef CONFIG_MTD_PARTITIONS
|
||||||
|
|
||||||
|
|
|
@ -50,9 +50,9 @@
|
||||||
|
|
||||||
#include <linux/serial_8250.h>
|
#include <linux/serial_8250.h>
|
||||||
|
|
||||||
#include "clock.h"
|
#include <asm/plat-s3c24xx/clock.h>
|
||||||
#include "devs.h"
|
#include <asm/plat-s3c24xx/devs.h>
|
||||||
#include "cpu.h"
|
#include <asm/plat-s3c24xx/cpu.h>
|
||||||
#include "usb-simtec.h"
|
#include "usb-simtec.h"
|
||||||
|
|
||||||
#define COPYRIGHT ", (c) 2004-2005 Simtec Electronics"
|
#define COPYRIGHT ", (c) 2004-2005 Simtec Electronics"
|
||||||
|
|
|
@ -38,10 +38,10 @@
|
||||||
#include <asm/arch/h1940-latch.h>
|
#include <asm/arch/h1940-latch.h>
|
||||||
#include <asm/arch/fb.h>
|
#include <asm/arch/fb.h>
|
||||||
|
|
||||||
#include "clock.h"
|
#include <asm/plat-s3c24xx/clock.h>
|
||||||
#include "devs.h"
|
#include <asm/plat-s3c24xx/devs.h>
|
||||||
#include "cpu.h"
|
#include <asm/plat-s3c24xx/cpu.h>
|
||||||
#include "pm.h"
|
#include <asm/plat-s3c24xx/pm.h>
|
||||||
|
|
||||||
static struct map_desc h1940_iodesc[] __initdata = {
|
static struct map_desc h1940_iodesc[] __initdata = {
|
||||||
[0] = {
|
[0] = {
|
||||||
|
|
|
@ -38,10 +38,10 @@
|
||||||
#include <asm/arch/regs-gpio.h>
|
#include <asm/arch/regs-gpio.h>
|
||||||
#include <asm/arch/iic.h>
|
#include <asm/arch/iic.h>
|
||||||
|
|
||||||
#include "s3c2410.h"
|
#include <asm/plat-s3c24xx/s3c2410.h>
|
||||||
#include "clock.h"
|
#include <asm/plat-s3c24xx/clock.h>
|
||||||
#include "devs.h"
|
#include <asm/plat-s3c24xx/devs.h>
|
||||||
#include "cpu.h"
|
#include <asm/plat-s3c24xx/cpu.h>
|
||||||
|
|
||||||
static struct map_desc n30_iodesc[] __initdata = {
|
static struct map_desc n30_iodesc[] __initdata = {
|
||||||
/* nothing here yet */
|
/* nothing here yet */
|
||||||
|
|
|
@ -32,10 +32,10 @@
|
||||||
#include <asm/arch/regs-serial.h>
|
#include <asm/arch/regs-serial.h>
|
||||||
#include <asm/arch/regs-gpio.h>
|
#include <asm/arch/regs-gpio.h>
|
||||||
|
|
||||||
#include "s3c2410.h"
|
#include <asm/plat-s3c24xx/s3c2410.h>
|
||||||
#include "clock.h"
|
#include <asm/plat-s3c24xx/clock.h>
|
||||||
#include "devs.h"
|
#include <asm/plat-s3c24xx/devs.h>
|
||||||
#include "cpu.h"
|
#include <asm/plat-s3c24xx/cpu.h>
|
||||||
|
|
||||||
static struct map_desc otom11_iodesc[] __initdata = {
|
static struct map_desc otom11_iodesc[] __initdata = {
|
||||||
/* Device area */
|
/* Device area */
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/***********************************************************************
|
/* linux/arch/arm/mach-s3c2410/mach-smdk2410.c
|
||||||
*
|
*
|
||||||
* linux/arch/arm/mach-s3c2410/mach-smdk2410.c
|
* linux/arch/arm/mach-s3c2410/mach-smdk2410.c
|
||||||
*
|
*
|
||||||
|
@ -49,10 +49,10 @@
|
||||||
|
|
||||||
#include <asm/arch/regs-serial.h>
|
#include <asm/arch/regs-serial.h>
|
||||||
|
|
||||||
#include "devs.h"
|
#include <asm/plat-s3c24xx/devs.h>
|
||||||
#include "cpu.h"
|
#include <asm/plat-s3c24xx/cpu.h>
|
||||||
|
|
||||||
#include "common-smdk.h"
|
#include <asm/plat-s3c24xx/common-smdk.h>
|
||||||
|
|
||||||
static struct map_desc smdk2410_iodesc[] __initdata = {
|
static struct map_desc smdk2410_iodesc[] __initdata = {
|
||||||
/* nothing here yet */
|
/* nothing here yet */
|
||||||
|
|
|
@ -43,9 +43,9 @@
|
||||||
#include <asm/arch/regs-gpio.h>
|
#include <asm/arch/regs-gpio.h>
|
||||||
#include <asm/arch/leds-gpio.h>
|
#include <asm/arch/leds-gpio.h>
|
||||||
|
|
||||||
#include "clock.h"
|
#include <asm/plat-s3c24xx/clock.h>
|
||||||
#include "devs.h"
|
#include <asm/plat-s3c24xx/devs.h>
|
||||||
#include "cpu.h"
|
#include <asm/plat-s3c24xx/cpu.h>
|
||||||
#include "usb-simtec.h"
|
#include "usb-simtec.h"
|
||||||
|
|
||||||
/* macros for virtual address mods for the io space entries */
|
/* macros for virtual address mods for the io space entries */
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
/* linux/arch/arm/mach-s3c2410/pm.c
|
/* linux/arch/arm/mach-s3c2410/pm.c
|
||||||
*
|
*
|
||||||
* Copyright (c) 2004,2006 Simtec Electronics
|
* Copyright (c) 2006 Simtec Electronics
|
||||||
* Ben Dooks <ben@simtec.co.uk>
|
* Ben Dooks <ben@simtec.co.uk>
|
||||||
*
|
*
|
||||||
* S3C24XX Power Manager (Suspend-To-RAM) support
|
* S3C2410 (and compatible) Power Manager (Suspend-To-RAM) support
|
||||||
*
|
|
||||||
* See Documentation/arm/Samsung-S3C24XX/Suspend.txt for more information
|
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -20,640 +18,139 @@
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
*
|
|
||||||
* Parts based on arch/arm/mach-pxa/pm.c
|
|
||||||
*
|
|
||||||
* Thanks to Dimitry Andric for debugging
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/suspend.h>
|
#include <linux/suspend.h>
|
||||||
#include <linux/errno.h>
|
#include <linux/errno.h>
|
||||||
#include <linux/time.h>
|
#include <linux/time.h>
|
||||||
#include <linux/interrupt.h>
|
#include <linux/sysdev.h>
|
||||||
#include <linux/crc32.h>
|
|
||||||
#include <linux/ioport.h>
|
|
||||||
#include <linux/delay.h>
|
|
||||||
#include <linux/serial_core.h>
|
|
||||||
|
|
||||||
#include <asm/cacheflush.h>
|
|
||||||
#include <asm/hardware.h>
|
#include <asm/hardware.h>
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
|
|
||||||
#include <asm/arch/regs-serial.h>
|
#include <asm/mach-types.h>
|
||||||
#include <asm/arch/regs-clock.h>
|
|
||||||
#include <asm/arch/regs-gpio.h>
|
#include <asm/arch/regs-gpio.h>
|
||||||
#include <asm/arch/regs-mem.h>
|
#include <asm/arch/h1940.h>
|
||||||
#include <asm/arch/regs-irq.h>
|
|
||||||
|
|
||||||
#include <asm/mach/time.h>
|
#include <asm/plat-s3c24xx/cpu.h>
|
||||||
|
#include <asm/plat-s3c24xx/pm.h>
|
||||||
#include "pm.h"
|
|
||||||
|
|
||||||
/* for external use */
|
|
||||||
|
|
||||||
unsigned long s3c_pm_flags;
|
|
||||||
|
|
||||||
#define PFX "s3c24xx-pm: "
|
|
||||||
|
|
||||||
static struct sleep_save core_save[] = {
|
|
||||||
SAVE_ITEM(S3C2410_LOCKTIME),
|
|
||||||
SAVE_ITEM(S3C2410_CLKCON),
|
|
||||||
|
|
||||||
/* we restore the timings here, with the proviso that the board
|
|
||||||
* brings the system up in an slower, or equal frequency setting
|
|
||||||
* to the original system.
|
|
||||||
*
|
|
||||||
* if we cannot guarantee this, then things are going to go very
|
|
||||||
* wrong here, as we modify the refresh and both pll settings.
|
|
||||||
*/
|
|
||||||
|
|
||||||
SAVE_ITEM(S3C2410_BWSCON),
|
|
||||||
SAVE_ITEM(S3C2410_BANKCON0),
|
|
||||||
SAVE_ITEM(S3C2410_BANKCON1),
|
|
||||||
SAVE_ITEM(S3C2410_BANKCON2),
|
|
||||||
SAVE_ITEM(S3C2410_BANKCON3),
|
|
||||||
SAVE_ITEM(S3C2410_BANKCON4),
|
|
||||||
SAVE_ITEM(S3C2410_BANKCON5),
|
|
||||||
|
|
||||||
SAVE_ITEM(S3C2410_CLKDIVN),
|
|
||||||
SAVE_ITEM(S3C2410_MPLLCON),
|
|
||||||
SAVE_ITEM(S3C2410_UPLLCON),
|
|
||||||
SAVE_ITEM(S3C2410_CLKSLOW),
|
|
||||||
SAVE_ITEM(S3C2410_REFRESH),
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct sleep_save gpio_save[] = {
|
|
||||||
SAVE_ITEM(S3C2410_GPACON),
|
|
||||||
SAVE_ITEM(S3C2410_GPADAT),
|
|
||||||
|
|
||||||
SAVE_ITEM(S3C2410_GPBCON),
|
|
||||||
SAVE_ITEM(S3C2410_GPBDAT),
|
|
||||||
SAVE_ITEM(S3C2410_GPBUP),
|
|
||||||
|
|
||||||
SAVE_ITEM(S3C2410_GPCCON),
|
|
||||||
SAVE_ITEM(S3C2410_GPCDAT),
|
|
||||||
SAVE_ITEM(S3C2410_GPCUP),
|
|
||||||
|
|
||||||
SAVE_ITEM(S3C2410_GPDCON),
|
|
||||||
SAVE_ITEM(S3C2410_GPDDAT),
|
|
||||||
SAVE_ITEM(S3C2410_GPDUP),
|
|
||||||
|
|
||||||
SAVE_ITEM(S3C2410_GPECON),
|
|
||||||
SAVE_ITEM(S3C2410_GPEDAT),
|
|
||||||
SAVE_ITEM(S3C2410_GPEUP),
|
|
||||||
|
|
||||||
SAVE_ITEM(S3C2410_GPFCON),
|
|
||||||
SAVE_ITEM(S3C2410_GPFDAT),
|
|
||||||
SAVE_ITEM(S3C2410_GPFUP),
|
|
||||||
|
|
||||||
SAVE_ITEM(S3C2410_GPGCON),
|
|
||||||
SAVE_ITEM(S3C2410_GPGDAT),
|
|
||||||
SAVE_ITEM(S3C2410_GPGUP),
|
|
||||||
|
|
||||||
SAVE_ITEM(S3C2410_GPHCON),
|
|
||||||
SAVE_ITEM(S3C2410_GPHDAT),
|
|
||||||
SAVE_ITEM(S3C2410_GPHUP),
|
|
||||||
|
|
||||||
SAVE_ITEM(S3C2410_DCLKCON),
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef CONFIG_S3C2410_PM_DEBUG
|
#ifdef CONFIG_S3C2410_PM_DEBUG
|
||||||
|
extern void pm_dbg(const char *fmt, ...);
|
||||||
#define SAVE_UART(va) \
|
|
||||||
SAVE_ITEM((va) + S3C2410_ULCON), \
|
|
||||||
SAVE_ITEM((va) + S3C2410_UCON), \
|
|
||||||
SAVE_ITEM((va) + S3C2410_UFCON), \
|
|
||||||
SAVE_ITEM((va) + S3C2410_UMCON), \
|
|
||||||
SAVE_ITEM((va) + S3C2410_UBRDIV)
|
|
||||||
|
|
||||||
static struct sleep_save uart_save[] = {
|
|
||||||
SAVE_UART(S3C24XX_VA_UART0),
|
|
||||||
SAVE_UART(S3C24XX_VA_UART1),
|
|
||||||
#ifndef CONFIG_CPU_S3C2400
|
|
||||||
SAVE_UART(S3C24XX_VA_UART2),
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
/* debug
|
|
||||||
*
|
|
||||||
* we send the debug to printascii() to allow it to be seen if the
|
|
||||||
* system never wakes up from the sleep
|
|
||||||
*/
|
|
||||||
|
|
||||||
extern void printascii(const char *);
|
|
||||||
|
|
||||||
void pm_dbg(const char *fmt, ...)
|
|
||||||
{
|
|
||||||
va_list va;
|
|
||||||
char buff[256];
|
|
||||||
|
|
||||||
va_start(va, fmt);
|
|
||||||
vsprintf(buff, fmt, va);
|
|
||||||
va_end(va);
|
|
||||||
|
|
||||||
printascii(buff);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void s3c2410_pm_debug_init(void)
|
|
||||||
{
|
|
||||||
unsigned long tmp = __raw_readl(S3C2410_CLKCON);
|
|
||||||
|
|
||||||
/* re-start uart clocks */
|
|
||||||
tmp |= S3C2410_CLKCON_UART0;
|
|
||||||
tmp |= S3C2410_CLKCON_UART1;
|
|
||||||
tmp |= S3C2410_CLKCON_UART2;
|
|
||||||
|
|
||||||
__raw_writel(tmp, S3C2410_CLKCON);
|
|
||||||
udelay(10);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define DBG(fmt...) pm_dbg(fmt)
|
#define DBG(fmt...) pm_dbg(fmt)
|
||||||
#else
|
#else
|
||||||
#define DBG(fmt...) printk(KERN_DEBUG fmt)
|
#define DBG(fmt...) printk(KERN_DEBUG fmt)
|
||||||
|
|
||||||
#define s3c2410_pm_debug_init() do { } while(0)
|
|
||||||
|
|
||||||
static struct sleep_save uart_save[] = {};
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(CONFIG_S3C2410_PM_CHECK) && CONFIG_S3C2410_PM_CHECK_CHUNKSIZE != 0
|
static void s3c2410_pm_prepare(void)
|
||||||
|
|
||||||
/* suspend checking code...
|
|
||||||
*
|
|
||||||
* this next area does a set of crc checks over all the installed
|
|
||||||
* memory, so the system can verify if the resume was ok.
|
|
||||||
*
|
|
||||||
* CONFIG_S3C2410_PM_CHECK_CHUNKSIZE defines the block-size for the CRC,
|
|
||||||
* increasing it will mean that the area corrupted will be less easy to spot,
|
|
||||||
* and reducing the size will cause the CRC save area to grow
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define CHECK_CHUNKSIZE (CONFIG_S3C2410_PM_CHECK_CHUNKSIZE * 1024)
|
|
||||||
|
|
||||||
static u32 crc_size; /* size needed for the crc block */
|
|
||||||
static u32 *crcs; /* allocated over suspend/resume */
|
|
||||||
|
|
||||||
typedef u32 *(run_fn_t)(struct resource *ptr, u32 *arg);
|
|
||||||
|
|
||||||
/* s3c2410_pm_run_res
|
|
||||||
*
|
|
||||||
* go thorugh the given resource list, and look for system ram
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void s3c2410_pm_run_res(struct resource *ptr, run_fn_t fn, u32 *arg)
|
|
||||||
{
|
{
|
||||||
while (ptr != NULL) {
|
/* ensure at least GSTATUS3 has the resume address */
|
||||||
if (ptr->child != NULL)
|
|
||||||
s3c2410_pm_run_res(ptr->child, fn, arg);
|
|
||||||
|
|
||||||
if ((ptr->flags & IORESOURCE_MEM) &&
|
__raw_writel(virt_to_phys(s3c2410_cpu_resume), S3C2410_GSTATUS3);
|
||||||
strcmp(ptr->name, "System RAM") == 0) {
|
|
||||||
DBG("Found system RAM at %08lx..%08lx\n",
|
|
||||||
ptr->start, ptr->end);
|
|
||||||
arg = (fn)(ptr, arg);
|
|
||||||
}
|
|
||||||
|
|
||||||
ptr = ptr->sibling;
|
DBG("GSTATUS3 0x%08x\n", __raw_readl(S3C2410_GSTATUS3));
|
||||||
}
|
DBG("GSTATUS4 0x%08x\n", __raw_readl(S3C2410_GSTATUS4));
|
||||||
}
|
|
||||||
|
|
||||||
static void s3c2410_pm_run_sysram(run_fn_t fn, u32 *arg)
|
if (machine_is_h1940()) {
|
||||||
{
|
void *base = phys_to_virt(H1940_SUSPEND_CHECK);
|
||||||
s3c2410_pm_run_res(&iomem_resource, fn, arg);
|
unsigned long ptr;
|
||||||
}
|
unsigned long calc = 0;
|
||||||
|
|
||||||
static u32 *s3c2410_pm_countram(struct resource *res, u32 *val)
|
/* generate check for the bootloader to check on resume */
|
||||||
{
|
|
||||||
u32 size = (u32)(res->end - res->start)+1;
|
|
||||||
|
|
||||||
size += CHECK_CHUNKSIZE-1;
|
for (ptr = 0; ptr < 0x40000; ptr += 0x400)
|
||||||
size /= CHECK_CHUNKSIZE;
|
calc += __raw_readl(base+ptr);
|
||||||
|
|
||||||
DBG("Area %08lx..%08lx, %d blocks\n", res->start, res->end, size);
|
__raw_writel(calc, phys_to_virt(H1940_SUSPEND_CHECKSUM));
|
||||||
|
|
||||||
*val += size * sizeof(u32);
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* s3c2410_pm_prepare_check
|
|
||||||
*
|
|
||||||
* prepare the necessary information for creating the CRCs. This
|
|
||||||
* must be done before the final save, as it will require memory
|
|
||||||
* allocating, and thus touching bits of the kernel we do not
|
|
||||||
* know about.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void s3c2410_pm_check_prepare(void)
|
|
||||||
{
|
|
||||||
crc_size = 0;
|
|
||||||
|
|
||||||
s3c2410_pm_run_sysram(s3c2410_pm_countram, &crc_size);
|
|
||||||
|
|
||||||
DBG("s3c2410_pm_prepare_check: %u checks needed\n", crc_size);
|
|
||||||
|
|
||||||
crcs = kmalloc(crc_size+4, GFP_KERNEL);
|
|
||||||
if (crcs == NULL)
|
|
||||||
printk(KERN_ERR "Cannot allocated CRC save area\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
static u32 *s3c2410_pm_makecheck(struct resource *res, u32 *val)
|
|
||||||
{
|
|
||||||
unsigned long addr, left;
|
|
||||||
|
|
||||||
for (addr = res->start; addr < res->end;
|
|
||||||
addr += CHECK_CHUNKSIZE) {
|
|
||||||
left = res->end - addr;
|
|
||||||
|
|
||||||
if (left > CHECK_CHUNKSIZE)
|
|
||||||
left = CHECK_CHUNKSIZE;
|
|
||||||
|
|
||||||
*val = crc32_le(~0, phys_to_virt(addr), left);
|
|
||||||
val++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return val;
|
/* the RX3715 uses similar code and the same H1940 and the
|
||||||
|
* same offsets for resume and checksum pointers */
|
||||||
|
|
||||||
|
if (machine_is_rx3715()) {
|
||||||
|
void *base = phys_to_virt(H1940_SUSPEND_CHECK);
|
||||||
|
unsigned long ptr;
|
||||||
|
unsigned long calc = 0;
|
||||||
|
|
||||||
|
/* generate check for the bootloader to check on resume */
|
||||||
|
|
||||||
|
for (ptr = 0; ptr < 0x40000; ptr += 0x4)
|
||||||
|
calc += __raw_readl(base+ptr);
|
||||||
|
|
||||||
|
__raw_writel(calc, phys_to_virt(H1940_SUSPEND_CHECKSUM));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( machine_is_aml_m5900() )
|
||||||
|
s3c2410_gpio_setpin(S3C2410_GPF2, 1);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* s3c2410_pm_check_store
|
static int s3c2410_pm_resume(struct sys_device *dev)
|
||||||
*
|
|
||||||
* compute the CRC values for the memory blocks before the final
|
|
||||||
* sleep.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void s3c2410_pm_check_store(void)
|
|
||||||
{
|
{
|
||||||
if (crcs != NULL)
|
unsigned long tmp;
|
||||||
s3c2410_pm_run_sysram(s3c2410_pm_makecheck, crcs);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* in_region
|
/* unset the return-from-sleep flag, to ensure reset */
|
||||||
*
|
|
||||||
* return TRUE if the area defined by ptr..ptr+size contatins the
|
|
||||||
* what..what+whatsz
|
|
||||||
*/
|
|
||||||
|
|
||||||
static inline int in_region(void *ptr, int size, void *what, size_t whatsz)
|
tmp = __raw_readl(S3C2410_GSTATUS2);
|
||||||
{
|
tmp &= S3C2410_GSTATUS2_OFFRESET;
|
||||||
if ((what+whatsz) < ptr)
|
__raw_writel(tmp, S3C2410_GSTATUS2);
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (what > (ptr+size))
|
if ( machine_is_aml_m5900() )
|
||||||
return 0;
|
s3c2410_gpio_setpin(S3C2410_GPF2, 0);
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static u32 *s3c2410_pm_runcheck(struct resource *res, u32 *val)
|
|
||||||
{
|
|
||||||
void *save_at = phys_to_virt(s3c2410_sleep_save_phys);
|
|
||||||
unsigned long addr;
|
|
||||||
unsigned long left;
|
|
||||||
void *ptr;
|
|
||||||
u32 calc;
|
|
||||||
|
|
||||||
for (addr = res->start; addr < res->end;
|
|
||||||
addr += CHECK_CHUNKSIZE) {
|
|
||||||
left = res->end - addr;
|
|
||||||
|
|
||||||
if (left > CHECK_CHUNKSIZE)
|
|
||||||
left = CHECK_CHUNKSIZE;
|
|
||||||
|
|
||||||
ptr = phys_to_virt(addr);
|
|
||||||
|
|
||||||
if (in_region(ptr, left, crcs, crc_size)) {
|
|
||||||
DBG("skipping %08lx, has crc block in\n", addr);
|
|
||||||
goto skip_check;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (in_region(ptr, left, save_at, 32*4 )) {
|
|
||||||
DBG("skipping %08lx, has save block in\n", addr);
|
|
||||||
goto skip_check;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* calculate and check the checksum */
|
|
||||||
|
|
||||||
calc = crc32_le(~0, ptr, left);
|
|
||||||
if (calc != *val) {
|
|
||||||
printk(KERN_ERR PFX "Restore CRC error at "
|
|
||||||
"%08lx (%08x vs %08x)\n", addr, calc, *val);
|
|
||||||
|
|
||||||
DBG("Restore CRC error at %08lx (%08x vs %08x)\n",
|
|
||||||
addr, calc, *val);
|
|
||||||
}
|
|
||||||
|
|
||||||
skip_check:
|
|
||||||
val++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* s3c2410_pm_check_restore
|
|
||||||
*
|
|
||||||
* check the CRCs after the restore event and free the memory used
|
|
||||||
* to hold them
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void s3c2410_pm_check_restore(void)
|
|
||||||
{
|
|
||||||
if (crcs != NULL) {
|
|
||||||
s3c2410_pm_run_sysram(s3c2410_pm_runcheck, crcs);
|
|
||||||
kfree(crcs);
|
|
||||||
crcs = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#define s3c2410_pm_check_prepare() do { } while(0)
|
|
||||||
#define s3c2410_pm_check_restore() do { } while(0)
|
|
||||||
#define s3c2410_pm_check_store() do { } while(0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* helper functions to save and restore register state */
|
|
||||||
|
|
||||||
void s3c2410_pm_do_save(struct sleep_save *ptr, int count)
|
|
||||||
{
|
|
||||||
for (; count > 0; count--, ptr++) {
|
|
||||||
ptr->val = __raw_readl(ptr->reg);
|
|
||||||
DBG("saved %p value %08lx\n", ptr->reg, ptr->val);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* s3c2410_pm_do_restore
|
|
||||||
*
|
|
||||||
* restore the system from the given list of saved registers
|
|
||||||
*
|
|
||||||
* Note, we do not use DBG() in here, as the system may not have
|
|
||||||
* restore the UARTs state yet
|
|
||||||
*/
|
|
||||||
|
|
||||||
void s3c2410_pm_do_restore(struct sleep_save *ptr, int count)
|
|
||||||
{
|
|
||||||
for (; count > 0; count--, ptr++) {
|
|
||||||
printk(KERN_DEBUG "restore %p (restore %08lx, was %08x)\n",
|
|
||||||
ptr->reg, ptr->val, __raw_readl(ptr->reg));
|
|
||||||
|
|
||||||
__raw_writel(ptr->val, ptr->reg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* s3c2410_pm_do_restore_core
|
|
||||||
*
|
|
||||||
* similar to s3c2410_pm_do_restore_core
|
|
||||||
*
|
|
||||||
* WARNING: Do not put any debug in here that may effect memory or use
|
|
||||||
* peripherals, as things may be changing!
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void s3c2410_pm_do_restore_core(struct sleep_save *ptr, int count)
|
|
||||||
{
|
|
||||||
for (; count > 0; count--, ptr++) {
|
|
||||||
__raw_writel(ptr->val, ptr->reg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* s3c2410_pm_show_resume_irqs
|
|
||||||
*
|
|
||||||
* print any IRQs asserted at resume time (ie, we woke from)
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void s3c2410_pm_show_resume_irqs(int start, unsigned long which,
|
|
||||||
unsigned long mask)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
which &= ~mask;
|
|
||||||
|
|
||||||
for (i = 0; i <= 31; i++) {
|
|
||||||
if ((which) & (1L<<i)) {
|
|
||||||
DBG("IRQ %d asserted at resume\n", start+i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* s3c2410_pm_check_resume_pin
|
|
||||||
*
|
|
||||||
* check to see if the pin is configured correctly for sleep mode, and
|
|
||||||
* make any necessary adjustments if it is not
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void s3c2410_pm_check_resume_pin(unsigned int pin, unsigned int irqoffs)
|
|
||||||
{
|
|
||||||
unsigned long irqstate;
|
|
||||||
unsigned long pinstate;
|
|
||||||
int irq = s3c2410_gpio_getirq(pin);
|
|
||||||
|
|
||||||
if (irqoffs < 4)
|
|
||||||
irqstate = s3c_irqwake_intmask & (1L<<irqoffs);
|
|
||||||
else
|
|
||||||
irqstate = s3c_irqwake_eintmask & (1L<<irqoffs);
|
|
||||||
|
|
||||||
pinstate = s3c2410_gpio_getcfg(pin);
|
|
||||||
|
|
||||||
if (!irqstate) {
|
|
||||||
if (pinstate == S3C2410_GPIO_IRQ)
|
|
||||||
DBG("Leaving IRQ %d (pin %d) enabled\n", irq, pin);
|
|
||||||
} else {
|
|
||||||
if (pinstate == S3C2410_GPIO_IRQ) {
|
|
||||||
DBG("Disabling IRQ %d (pin %d)\n", irq, pin);
|
|
||||||
s3c2410_gpio_cfgpin(pin, S3C2410_GPIO_INPUT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* s3c2410_pm_configure_extint
|
|
||||||
*
|
|
||||||
* configure all external interrupt pins
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void s3c2410_pm_configure_extint(void)
|
|
||||||
{
|
|
||||||
int pin;
|
|
||||||
|
|
||||||
/* for each of the external interrupts (EINT0..EINT15) we
|
|
||||||
* need to check wether it is an external interrupt source,
|
|
||||||
* and then configure it as an input if it is not
|
|
||||||
*/
|
|
||||||
|
|
||||||
for (pin = S3C2410_GPF0; pin <= S3C2410_GPF7; pin++) {
|
|
||||||
s3c2410_pm_check_resume_pin(pin, pin - S3C2410_GPF0);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (pin = S3C2410_GPG0; pin <= S3C2410_GPG7; pin++) {
|
|
||||||
s3c2410_pm_check_resume_pin(pin, (pin - S3C2410_GPG0)+8);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void (*pm_cpu_prep)(void);
|
|
||||||
void (*pm_cpu_sleep)(void);
|
|
||||||
|
|
||||||
#define any_allowed(mask, allow) (((mask) & (allow)) != (allow))
|
|
||||||
|
|
||||||
/* s3c2410_pm_enter
|
|
||||||
*
|
|
||||||
* central control for sleep/resume process
|
|
||||||
*/
|
|
||||||
|
|
||||||
static int s3c2410_pm_enter(suspend_state_t state)
|
|
||||||
{
|
|
||||||
unsigned long regs_save[16];
|
|
||||||
|
|
||||||
/* ensure the debug is initialised (if enabled) */
|
|
||||||
|
|
||||||
s3c2410_pm_debug_init();
|
|
||||||
|
|
||||||
DBG("s3c2410_pm_enter(%d)\n", state);
|
|
||||||
|
|
||||||
if (pm_cpu_prep == NULL || pm_cpu_sleep == NULL) {
|
|
||||||
printk(KERN_ERR PFX "error: no cpu sleep functions set\n");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state != PM_SUSPEND_MEM) {
|
|
||||||
printk(KERN_ERR PFX "error: only PM_SUSPEND_MEM supported\n");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* check if we have anything to wake-up with... bad things seem
|
|
||||||
* to happen if you suspend with no wakeup (system will often
|
|
||||||
* require a full power-cycle)
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!any_allowed(s3c_irqwake_intmask, s3c_irqwake_intallow) &&
|
|
||||||
!any_allowed(s3c_irqwake_eintmask, s3c_irqwake_eintallow)) {
|
|
||||||
printk(KERN_ERR PFX "No sources enabled for wake-up!\n");
|
|
||||||
printk(KERN_ERR PFX "Aborting sleep\n");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* prepare check area if configured */
|
|
||||||
|
|
||||||
s3c2410_pm_check_prepare();
|
|
||||||
|
|
||||||
/* store the physical address of the register recovery block */
|
|
||||||
|
|
||||||
s3c2410_sleep_save_phys = virt_to_phys(regs_save);
|
|
||||||
|
|
||||||
DBG("s3c2410_sleep_save_phys=0x%08lx\n", s3c2410_sleep_save_phys);
|
|
||||||
|
|
||||||
/* save all necessary core registers not covered by the drivers */
|
|
||||||
|
|
||||||
s3c2410_pm_do_save(gpio_save, ARRAY_SIZE(gpio_save));
|
|
||||||
s3c2410_pm_do_save(core_save, ARRAY_SIZE(core_save));
|
|
||||||
s3c2410_pm_do_save(uart_save, ARRAY_SIZE(uart_save));
|
|
||||||
|
|
||||||
/* set the irq configuration for wake */
|
|
||||||
|
|
||||||
s3c2410_pm_configure_extint();
|
|
||||||
|
|
||||||
DBG("sleep: irq wakeup masks: %08lx,%08lx\n",
|
|
||||||
s3c_irqwake_intmask, s3c_irqwake_eintmask);
|
|
||||||
|
|
||||||
__raw_writel(s3c_irqwake_intmask, S3C2410_INTMSK);
|
|
||||||
__raw_writel(s3c_irqwake_eintmask, S3C2410_EINTMASK);
|
|
||||||
|
|
||||||
/* ack any outstanding external interrupts before we go to sleep */
|
|
||||||
|
|
||||||
__raw_writel(__raw_readl(S3C2410_EINTPEND), S3C2410_EINTPEND);
|
|
||||||
__raw_writel(__raw_readl(S3C2410_INTPND), S3C2410_INTPND);
|
|
||||||
__raw_writel(__raw_readl(S3C2410_SRCPND), S3C2410_SRCPND);
|
|
||||||
|
|
||||||
/* call cpu specific preperation */
|
|
||||||
|
|
||||||
pm_cpu_prep();
|
|
||||||
|
|
||||||
/* flush cache back to ram */
|
|
||||||
|
|
||||||
flush_cache_all();
|
|
||||||
|
|
||||||
s3c2410_pm_check_store();
|
|
||||||
|
|
||||||
/* send the cpu to sleep... */
|
|
||||||
|
|
||||||
__raw_writel(0x00, S3C2410_CLKCON); /* turn off clocks over sleep */
|
|
||||||
|
|
||||||
/* s3c2410_cpu_save will also act as our return point from when
|
|
||||||
* we resume as it saves its own register state, so use the return
|
|
||||||
* code to differentiate return from save and return from sleep */
|
|
||||||
|
|
||||||
if (s3c2410_cpu_save(regs_save) == 0) {
|
|
||||||
flush_cache_all();
|
|
||||||
pm_cpu_sleep();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* restore the cpu state */
|
|
||||||
|
|
||||||
cpu_init();
|
|
||||||
|
|
||||||
/* restore the system state */
|
|
||||||
|
|
||||||
s3c2410_pm_do_restore_core(core_save, ARRAY_SIZE(core_save));
|
|
||||||
s3c2410_pm_do_restore(gpio_save, ARRAY_SIZE(gpio_save));
|
|
||||||
s3c2410_pm_do_restore(uart_save, ARRAY_SIZE(uart_save));
|
|
||||||
|
|
||||||
s3c2410_pm_debug_init();
|
|
||||||
|
|
||||||
/* check what irq (if any) restored the system */
|
|
||||||
|
|
||||||
DBG("post sleep: IRQs 0x%08x, 0x%08x\n",
|
|
||||||
__raw_readl(S3C2410_SRCPND),
|
|
||||||
__raw_readl(S3C2410_EINTPEND));
|
|
||||||
|
|
||||||
s3c2410_pm_show_resume_irqs(IRQ_EINT0, __raw_readl(S3C2410_SRCPND),
|
|
||||||
s3c_irqwake_intmask);
|
|
||||||
|
|
||||||
s3c2410_pm_show_resume_irqs(IRQ_EINT4-4, __raw_readl(S3C2410_EINTPEND),
|
|
||||||
s3c_irqwake_eintmask);
|
|
||||||
|
|
||||||
DBG("post sleep, preparing to return\n");
|
|
||||||
|
|
||||||
s3c2410_pm_check_restore();
|
|
||||||
|
|
||||||
/* ok, let's return from sleep */
|
|
||||||
|
|
||||||
DBG("S3C2410 PM Resume (post-restore)\n");
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
static int s3c2410_pm_add(struct sys_device *dev)
|
||||||
* Called after processes are frozen, but before we shut down devices.
|
|
||||||
*/
|
|
||||||
static int s3c2410_pm_prepare(suspend_state_t state)
|
|
||||||
{
|
{
|
||||||
|
pm_cpu_prep = s3c2410_pm_prepare;
|
||||||
|
pm_cpu_sleep = s3c2410_cpu_suspend;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
#if defined(CONFIG_CPU_S3C2410)
|
||||||
* Called after devices are re-setup, but before processes are thawed.
|
static struct sysdev_driver s3c2410_pm_driver = {
|
||||||
*/
|
.add = s3c2410_pm_add,
|
||||||
static int s3c2410_pm_finish(suspend_state_t state)
|
.resume = s3c2410_pm_resume,
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set to PM_DISK_FIRMWARE so we can quickly veto suspend-to-disk.
|
|
||||||
*/
|
|
||||||
static struct pm_ops s3c2410_pm_ops = {
|
|
||||||
.pm_disk_mode = PM_DISK_FIRMWARE,
|
|
||||||
.prepare = s3c2410_pm_prepare,
|
|
||||||
.enter = s3c2410_pm_enter,
|
|
||||||
.finish = s3c2410_pm_finish,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* s3c2410_pm_init
|
/* register ourselves */
|
||||||
*
|
|
||||||
* Attach the power management functions. This should be called
|
|
||||||
* from the board specific initialisation if the board supports
|
|
||||||
* it.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int __init s3c2410_pm_init(void)
|
static int __init s3c2410_pm_drvinit(void)
|
||||||
{
|
{
|
||||||
printk("S3C2410 Power Management, (c) 2004 Simtec Electronics\n");
|
return sysdev_driver_register(&s3c2410_sysclass, &s3c2410_pm_driver);
|
||||||
|
|
||||||
pm_set_ops(&s3c2410_pm_ops);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
arch_initcall(s3c2410_pm_drvinit);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(CONFIG_CPU_S3C2440)
|
||||||
|
static struct sysdev_driver s3c2440_pm_driver = {
|
||||||
|
.add = s3c2410_pm_add,
|
||||||
|
.resume = s3c2410_pm_resume,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int __init s3c2440_pm_drvinit(void)
|
||||||
|
{
|
||||||
|
return sysdev_driver_register(&s3c2440_sysclass, &s3c2440_pm_driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
arch_initcall(s3c2440_pm_drvinit);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(CONFIG_CPU_S3C2442)
|
||||||
|
static struct sysdev_driver s3c2442_pm_driver = {
|
||||||
|
.add = s3c2410_pm_add,
|
||||||
|
.resume = s3c2410_pm_resume,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int __init s3c2442_pm_drvinit(void)
|
||||||
|
{
|
||||||
|
return sysdev_driver_register(&s3c2442_sysclass, &s3c2442_pm_driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
arch_initcall(s3c2442_pm_drvinit);
|
||||||
|
#endif
|
||||||
|
|
|
@ -1,276 +0,0 @@
|
||||||
/* linux/arch/arm/mach-s3c2410/s3c2410-clock.c
|
|
||||||
*
|
|
||||||
* Copyright (c) 2006 Simtec Electronics
|
|
||||||
* Ben Dooks <ben@simtec.co.uk>
|
|
||||||
*
|
|
||||||
* S3C2410,S3C2440,S3C2442 Clock control support
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <linux/init.h>
|
|
||||||
#include <linux/module.h>
|
|
||||||
#include <linux/kernel.h>
|
|
||||||
#include <linux/list.h>
|
|
||||||
#include <linux/errno.h>
|
|
||||||
#include <linux/err.h>
|
|
||||||
#include <linux/sysdev.h>
|
|
||||||
#include <linux/clk.h>
|
|
||||||
#include <linux/mutex.h>
|
|
||||||
#include <linux/delay.h>
|
|
||||||
#include <linux/serial_core.h>
|
|
||||||
|
|
||||||
#include <asm/mach/map.h>
|
|
||||||
|
|
||||||
#include <asm/hardware.h>
|
|
||||||
#include <asm/io.h>
|
|
||||||
|
|
||||||
#include <asm/arch/regs-serial.h>
|
|
||||||
#include <asm/arch/regs-clock.h>
|
|
||||||
#include <asm/arch/regs-gpio.h>
|
|
||||||
|
|
||||||
#include "s3c2410.h"
|
|
||||||
#include "clock.h"
|
|
||||||
#include "cpu.h"
|
|
||||||
|
|
||||||
int s3c2410_clkcon_enable(struct clk *clk, int enable)
|
|
||||||
{
|
|
||||||
unsigned int clocks = clk->ctrlbit;
|
|
||||||
unsigned long clkcon;
|
|
||||||
|
|
||||||
clkcon = __raw_readl(S3C2410_CLKCON);
|
|
||||||
|
|
||||||
if (enable)
|
|
||||||
clkcon |= clocks;
|
|
||||||
else
|
|
||||||
clkcon &= ~clocks;
|
|
||||||
|
|
||||||
/* ensure none of the special function bits set */
|
|
||||||
clkcon &= ~(S3C2410_CLKCON_IDLE|S3C2410_CLKCON_POWER);
|
|
||||||
|
|
||||||
__raw_writel(clkcon, S3C2410_CLKCON);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int s3c2410_upll_enable(struct clk *clk, int enable)
|
|
||||||
{
|
|
||||||
unsigned long clkslow = __raw_readl(S3C2410_CLKSLOW);
|
|
||||||
unsigned long orig = clkslow;
|
|
||||||
|
|
||||||
if (enable)
|
|
||||||
clkslow &= ~S3C2410_CLKSLOW_UCLK_OFF;
|
|
||||||
else
|
|
||||||
clkslow |= S3C2410_CLKSLOW_UCLK_OFF;
|
|
||||||
|
|
||||||
__raw_writel(clkslow, S3C2410_CLKSLOW);
|
|
||||||
|
|
||||||
/* if we started the UPLL, then allow to settle */
|
|
||||||
|
|
||||||
if (enable && (orig & S3C2410_CLKSLOW_UCLK_OFF))
|
|
||||||
udelay(200);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* standard clock definitions */
|
|
||||||
|
|
||||||
static struct clk init_clocks_disable[] = {
|
|
||||||
{
|
|
||||||
.name = "nand",
|
|
||||||
.id = -1,
|
|
||||||
.parent = &clk_h,
|
|
||||||
.enable = s3c2410_clkcon_enable,
|
|
||||||
.ctrlbit = S3C2410_CLKCON_NAND,
|
|
||||||
}, {
|
|
||||||
.name = "sdi",
|
|
||||||
.id = -1,
|
|
||||||
.parent = &clk_p,
|
|
||||||
.enable = s3c2410_clkcon_enable,
|
|
||||||
.ctrlbit = S3C2410_CLKCON_SDI,
|
|
||||||
}, {
|
|
||||||
.name = "adc",
|
|
||||||
.id = -1,
|
|
||||||
.parent = &clk_p,
|
|
||||||
.enable = s3c2410_clkcon_enable,
|
|
||||||
.ctrlbit = S3C2410_CLKCON_ADC,
|
|
||||||
}, {
|
|
||||||
.name = "i2c",
|
|
||||||
.id = -1,
|
|
||||||
.parent = &clk_p,
|
|
||||||
.enable = s3c2410_clkcon_enable,
|
|
||||||
.ctrlbit = S3C2410_CLKCON_IIC,
|
|
||||||
}, {
|
|
||||||
.name = "iis",
|
|
||||||
.id = -1,
|
|
||||||
.parent = &clk_p,
|
|
||||||
.enable = s3c2410_clkcon_enable,
|
|
||||||
.ctrlbit = S3C2410_CLKCON_IIS,
|
|
||||||
}, {
|
|
||||||
.name = "spi",
|
|
||||||
.id = -1,
|
|
||||||
.parent = &clk_p,
|
|
||||||
.enable = s3c2410_clkcon_enable,
|
|
||||||
.ctrlbit = S3C2410_CLKCON_SPI,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct clk init_clocks[] = {
|
|
||||||
{
|
|
||||||
.name = "lcd",
|
|
||||||
.id = -1,
|
|
||||||
.parent = &clk_h,
|
|
||||||
.enable = s3c2410_clkcon_enable,
|
|
||||||
.ctrlbit = S3C2410_CLKCON_LCDC,
|
|
||||||
}, {
|
|
||||||
.name = "gpio",
|
|
||||||
.id = -1,
|
|
||||||
.parent = &clk_p,
|
|
||||||
.enable = s3c2410_clkcon_enable,
|
|
||||||
.ctrlbit = S3C2410_CLKCON_GPIO,
|
|
||||||
}, {
|
|
||||||
.name = "usb-host",
|
|
||||||
.id = -1,
|
|
||||||
.parent = &clk_h,
|
|
||||||
.enable = s3c2410_clkcon_enable,
|
|
||||||
.ctrlbit = S3C2410_CLKCON_USBH,
|
|
||||||
}, {
|
|
||||||
.name = "usb-device",
|
|
||||||
.id = -1,
|
|
||||||
.parent = &clk_h,
|
|
||||||
.enable = s3c2410_clkcon_enable,
|
|
||||||
.ctrlbit = S3C2410_CLKCON_USBD,
|
|
||||||
}, {
|
|
||||||
.name = "timers",
|
|
||||||
.id = -1,
|
|
||||||
.parent = &clk_p,
|
|
||||||
.enable = s3c2410_clkcon_enable,
|
|
||||||
.ctrlbit = S3C2410_CLKCON_PWMT,
|
|
||||||
}, {
|
|
||||||
.name = "uart",
|
|
||||||
.id = 0,
|
|
||||||
.parent = &clk_p,
|
|
||||||
.enable = s3c2410_clkcon_enable,
|
|
||||||
.ctrlbit = S3C2410_CLKCON_UART0,
|
|
||||||
}, {
|
|
||||||
.name = "uart",
|
|
||||||
.id = 1,
|
|
||||||
.parent = &clk_p,
|
|
||||||
.enable = s3c2410_clkcon_enable,
|
|
||||||
.ctrlbit = S3C2410_CLKCON_UART1,
|
|
||||||
}, {
|
|
||||||
.name = "uart",
|
|
||||||
.id = 2,
|
|
||||||
.parent = &clk_p,
|
|
||||||
.enable = s3c2410_clkcon_enable,
|
|
||||||
.ctrlbit = S3C2410_CLKCON_UART2,
|
|
||||||
}, {
|
|
||||||
.name = "rtc",
|
|
||||||
.id = -1,
|
|
||||||
.parent = &clk_p,
|
|
||||||
.enable = s3c2410_clkcon_enable,
|
|
||||||
.ctrlbit = S3C2410_CLKCON_RTC,
|
|
||||||
}, {
|
|
||||||
.name = "watchdog",
|
|
||||||
.id = -1,
|
|
||||||
.parent = &clk_p,
|
|
||||||
.ctrlbit = 0,
|
|
||||||
}, {
|
|
||||||
.name = "usb-bus-host",
|
|
||||||
.id = -1,
|
|
||||||
.parent = &clk_usb_bus,
|
|
||||||
}, {
|
|
||||||
.name = "usb-bus-gadget",
|
|
||||||
.id = -1,
|
|
||||||
.parent = &clk_usb_bus,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
/* s3c2410_baseclk_add()
|
|
||||||
*
|
|
||||||
* Add all the clocks used by the s3c2410 or compatible CPUs
|
|
||||||
* such as the S3C2440 and S3C2442.
|
|
||||||
*
|
|
||||||
* We cannot use a system device as we are needed before any
|
|
||||||
* of the init-calls that initialise the devices are actually
|
|
||||||
* done.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int __init s3c2410_baseclk_add(void)
|
|
||||||
{
|
|
||||||
unsigned long clkslow = __raw_readl(S3C2410_CLKSLOW);
|
|
||||||
unsigned long clkcon = __raw_readl(S3C2410_CLKCON);
|
|
||||||
struct clk *clkp;
|
|
||||||
struct clk *xtal;
|
|
||||||
int ret;
|
|
||||||
int ptr;
|
|
||||||
|
|
||||||
clk_upll.enable = s3c2410_upll_enable;
|
|
||||||
|
|
||||||
if (s3c24xx_register_clock(&clk_usb_bus) < 0)
|
|
||||||
printk(KERN_ERR "failed to register usb bus clock\n");
|
|
||||||
|
|
||||||
/* register clocks from clock array */
|
|
||||||
|
|
||||||
clkp = init_clocks;
|
|
||||||
for (ptr = 0; ptr < ARRAY_SIZE(init_clocks); ptr++, clkp++) {
|
|
||||||
/* ensure that we note the clock state */
|
|
||||||
|
|
||||||
clkp->usage = clkcon & clkp->ctrlbit ? 1 : 0;
|
|
||||||
|
|
||||||
ret = s3c24xx_register_clock(clkp);
|
|
||||||
if (ret < 0) {
|
|
||||||
printk(KERN_ERR "Failed to register clock %s (%d)\n",
|
|
||||||
clkp->name, ret);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We must be careful disabling the clocks we are not intending to
|
|
||||||
* be using at boot time, as subsytems such as the LCD which do
|
|
||||||
* their own DMA requests to the bus can cause the system to lockup
|
|
||||||
* if they where in the middle of requesting bus access.
|
|
||||||
*
|
|
||||||
* Disabling the LCD clock if the LCD is active is very dangerous,
|
|
||||||
* and therefore the bootloader should be careful to not enable
|
|
||||||
* the LCD clock if it is not needed.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* install (and disable) the clocks we do not need immediately */
|
|
||||||
|
|
||||||
clkp = init_clocks_disable;
|
|
||||||
for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) {
|
|
||||||
|
|
||||||
ret = s3c24xx_register_clock(clkp);
|
|
||||||
if (ret < 0) {
|
|
||||||
printk(KERN_ERR "Failed to register clock %s (%d)\n",
|
|
||||||
clkp->name, ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
s3c2410_clkcon_enable(clkp, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* show the clock-slow value */
|
|
||||||
|
|
||||||
xtal = clk_get(NULL, "xtal");
|
|
||||||
|
|
||||||
printk("CLOCK: Slow mode (%ld.%ld MHz), %s, MPLL %s, UPLL %s\n",
|
|
||||||
print_mhz(clk_get_rate(xtal) /
|
|
||||||
( 2 * S3C2410_CLKSLOW_GET_SLOWVAL(clkslow))),
|
|
||||||
(clkslow & S3C2410_CLKSLOW_SLOW) ? "slow" : "fast",
|
|
||||||
(clkslow & S3C2410_CLKSLOW_MPLL_OFF) ? "off" : "on",
|
|
||||||
(clkslow & S3C2410_CLKSLOW_UCLK_OFF) ? "off" : "on");
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
|
@ -1,161 +0,0 @@
|
||||||
/* linux/arch/arm/mach-s3c2410/s3c2410-dma.c
|
|
||||||
*
|
|
||||||
* Copyright (c) 2006 Simtec Electronics
|
|
||||||
* Ben Dooks <ben@simtec.co.uk>
|
|
||||||
*
|
|
||||||
* S3C2410 DMA selection
|
|
||||||
*
|
|
||||||
* http://armlinux.simtec.co.uk/
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
|
||||||
* published by the Free Software Foundation.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <linux/kernel.h>
|
|
||||||
#include <linux/init.h>
|
|
||||||
#include <linux/sysdev.h>
|
|
||||||
#include <linux/serial_core.h>
|
|
||||||
|
|
||||||
#include <asm/dma.h>
|
|
||||||
#include <asm/arch/dma.h>
|
|
||||||
#include "dma.h"
|
|
||||||
|
|
||||||
#include "cpu.h"
|
|
||||||
|
|
||||||
#include <asm/arch/regs-serial.h>
|
|
||||||
#include <asm/arch/regs-gpio.h>
|
|
||||||
#include <asm/arch/regs-ac97.h>
|
|
||||||
#include <asm/arch/regs-mem.h>
|
|
||||||
#include <asm/arch/regs-lcd.h>
|
|
||||||
#include <asm/arch/regs-sdi.h>
|
|
||||||
#include <asm/arch/regs-iis.h>
|
|
||||||
#include <asm/arch/regs-spi.h>
|
|
||||||
|
|
||||||
static struct s3c24xx_dma_map __initdata s3c2410_dma_mappings[] = {
|
|
||||||
[DMACH_XD0] = {
|
|
||||||
.name = "xdreq0",
|
|
||||||
.channels[0] = S3C2410_DCON_CH0_XDREQ0 | DMA_CH_VALID,
|
|
||||||
},
|
|
||||||
[DMACH_XD1] = {
|
|
||||||
.name = "xdreq1",
|
|
||||||
.channels[1] = S3C2410_DCON_CH1_XDREQ1 | DMA_CH_VALID,
|
|
||||||
},
|
|
||||||
[DMACH_SDI] = {
|
|
||||||
.name = "sdi",
|
|
||||||
.channels[0] = S3C2410_DCON_CH0_SDI | DMA_CH_VALID,
|
|
||||||
.channels[2] = S3C2410_DCON_CH2_SDI | DMA_CH_VALID,
|
|
||||||
.channels[3] = S3C2410_DCON_CH3_SDI | DMA_CH_VALID,
|
|
||||||
.hw_addr.to = S3C2410_PA_IIS + S3C2410_IISFIFO,
|
|
||||||
.hw_addr.from = S3C2410_PA_IIS + S3C2410_IISFIFO,
|
|
||||||
},
|
|
||||||
[DMACH_SPI0] = {
|
|
||||||
.name = "spi0",
|
|
||||||
.channels[1] = S3C2410_DCON_CH1_SPI | DMA_CH_VALID,
|
|
||||||
.hw_addr.to = S3C2410_PA_SPI + S3C2410_SPTDAT,
|
|
||||||
.hw_addr.from = S3C2410_PA_SPI + S3C2410_SPRDAT,
|
|
||||||
},
|
|
||||||
[DMACH_SPI1] = {
|
|
||||||
.name = "spi1",
|
|
||||||
.channels[3] = S3C2410_DCON_CH3_SPI | DMA_CH_VALID,
|
|
||||||
.hw_addr.to = S3C2410_PA_SPI + 0x20 + S3C2410_SPTDAT,
|
|
||||||
.hw_addr.from = S3C2410_PA_SPI + 0x20 + S3C2410_SPRDAT,
|
|
||||||
},
|
|
||||||
[DMACH_UART0] = {
|
|
||||||
.name = "uart0",
|
|
||||||
.channels[0] = S3C2410_DCON_CH0_UART0 | DMA_CH_VALID,
|
|
||||||
.hw_addr.to = S3C2410_PA_UART0 + S3C2410_UTXH,
|
|
||||||
.hw_addr.from = S3C2410_PA_UART0 + S3C2410_URXH,
|
|
||||||
},
|
|
||||||
[DMACH_UART1] = {
|
|
||||||
.name = "uart1",
|
|
||||||
.channels[1] = S3C2410_DCON_CH1_UART1 | DMA_CH_VALID,
|
|
||||||
.hw_addr.to = S3C2410_PA_UART1 + S3C2410_UTXH,
|
|
||||||
.hw_addr.from = S3C2410_PA_UART1 + S3C2410_URXH,
|
|
||||||
},
|
|
||||||
[DMACH_UART2] = {
|
|
||||||
.name = "uart2",
|
|
||||||
.channels[3] = S3C2410_DCON_CH3_UART2 | DMA_CH_VALID,
|
|
||||||
.hw_addr.to = S3C2410_PA_UART2 + S3C2410_UTXH,
|
|
||||||
.hw_addr.from = S3C2410_PA_UART2 + S3C2410_URXH,
|
|
||||||
},
|
|
||||||
[DMACH_TIMER] = {
|
|
||||||
.name = "timer",
|
|
||||||
.channels[0] = S3C2410_DCON_CH0_TIMER | DMA_CH_VALID,
|
|
||||||
.channels[2] = S3C2410_DCON_CH2_TIMER | DMA_CH_VALID,
|
|
||||||
.channels[3] = S3C2410_DCON_CH3_TIMER | DMA_CH_VALID,
|
|
||||||
},
|
|
||||||
[DMACH_I2S_IN] = {
|
|
||||||
.name = "i2s-sdi",
|
|
||||||
.channels[1] = S3C2410_DCON_CH1_I2SSDI | DMA_CH_VALID,
|
|
||||||
.channels[2] = S3C2410_DCON_CH2_I2SSDI | DMA_CH_VALID,
|
|
||||||
.hw_addr.from = S3C2410_PA_IIS + S3C2410_IISFIFO,
|
|
||||||
},
|
|
||||||
[DMACH_I2S_OUT] = {
|
|
||||||
.name = "i2s-sdo",
|
|
||||||
.channels[2] = S3C2410_DCON_CH2_I2SSDO | DMA_CH_VALID,
|
|
||||||
.hw_addr.to = S3C2410_PA_IIS + S3C2410_IISFIFO,
|
|
||||||
},
|
|
||||||
[DMACH_USB_EP1] = {
|
|
||||||
.name = "usb-ep1",
|
|
||||||
.channels[0] = S3C2410_DCON_CH0_USBEP1 | DMA_CH_VALID,
|
|
||||||
},
|
|
||||||
[DMACH_USB_EP2] = {
|
|
||||||
.name = "usb-ep2",
|
|
||||||
.channels[1] = S3C2410_DCON_CH1_USBEP2 | DMA_CH_VALID,
|
|
||||||
},
|
|
||||||
[DMACH_USB_EP3] = {
|
|
||||||
.name = "usb-ep3",
|
|
||||||
.channels[2] = S3C2410_DCON_CH2_USBEP3 | DMA_CH_VALID,
|
|
||||||
},
|
|
||||||
[DMACH_USB_EP4] = {
|
|
||||||
.name = "usb-ep4",
|
|
||||||
.channels[3] =S3C2410_DCON_CH3_USBEP4 | DMA_CH_VALID,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
static void s3c2410_dma_select(struct s3c2410_dma_chan *chan,
|
|
||||||
struct s3c24xx_dma_map *map)
|
|
||||||
{
|
|
||||||
chan->dcon = map->channels[chan->number] & ~DMA_CH_VALID;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct s3c24xx_dma_selection __initdata s3c2410_dma_sel = {
|
|
||||||
.select = s3c2410_dma_select,
|
|
||||||
.dcon_mask = 7 << 24,
|
|
||||||
.map = s3c2410_dma_mappings,
|
|
||||||
.map_size = ARRAY_SIZE(s3c2410_dma_mappings),
|
|
||||||
};
|
|
||||||
|
|
||||||
static int s3c2410_dma_add(struct sys_device *sysdev)
|
|
||||||
{
|
|
||||||
return s3c24xx_dma_init_map(&s3c2410_dma_sel);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(CONFIG_CPU_S3C2410)
|
|
||||||
static struct sysdev_driver s3c2410_dma_driver = {
|
|
||||||
.add = s3c2410_dma_add,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int __init s3c2410_dma_init(void)
|
|
||||||
{
|
|
||||||
return sysdev_driver_register(&s3c2410_sysclass, &s3c2410_dma_driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
arch_initcall(s3c2410_dma_init);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(CONFIG_CPU_S3C2442)
|
|
||||||
/* S3C2442 DMA contains the same selection table as the S3C2410 */
|
|
||||||
static struct sysdev_driver s3c2442_dma_driver = {
|
|
||||||
.add = s3c2410_dma_add,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int __init s3c2442_dma_init(void)
|
|
||||||
{
|
|
||||||
return sysdev_driver_register(&s3c2442_sysclass, &s3c2442_dma_driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
arch_initcall(s3c2442_dma_init);
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -1,71 +0,0 @@
|
||||||
/* linux/arch/arm/mach-s3c2410/s3c2410-gpio.c
|
|
||||||
*
|
|
||||||
* Copyright (c) 2004-2006 Simtec Electronics
|
|
||||||
* Ben Dooks <ben@simtec.co.uk>
|
|
||||||
*
|
|
||||||
* S3C2410 GPIO support
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <linux/kernel.h>
|
|
||||||
#include <linux/init.h>
|
|
||||||
#include <linux/module.h>
|
|
||||||
#include <linux/interrupt.h>
|
|
||||||
#include <linux/ioport.h>
|
|
||||||
|
|
||||||
#include <asm/hardware.h>
|
|
||||||
#include <asm/irq.h>
|
|
||||||
#include <asm/io.h>
|
|
||||||
|
|
||||||
#include <asm/arch/regs-gpio.h>
|
|
||||||
|
|
||||||
int s3c2410_gpio_irqfilter(unsigned int pin, unsigned int on,
|
|
||||||
unsigned int config)
|
|
||||||
{
|
|
||||||
void __iomem *reg = S3C24XX_EINFLT0;
|
|
||||||
unsigned long flags;
|
|
||||||
unsigned long val;
|
|
||||||
|
|
||||||
if (pin < S3C2410_GPG8 || pin > S3C2410_GPG15)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
config &= 0xff;
|
|
||||||
|
|
||||||
pin -= S3C2410_GPG8;
|
|
||||||
reg += pin & ~3;
|
|
||||||
|
|
||||||
local_irq_save(flags);
|
|
||||||
|
|
||||||
/* update filter width and clock source */
|
|
||||||
|
|
||||||
val = __raw_readl(reg);
|
|
||||||
val &= ~(0xff << ((pin & 3) * 8));
|
|
||||||
val |= config << ((pin & 3) * 8);
|
|
||||||
__raw_writel(val, reg);
|
|
||||||
|
|
||||||
/* update filter enable */
|
|
||||||
|
|
||||||
val = __raw_readl(S3C24XX_EXTINT2);
|
|
||||||
val &= ~(1 << ((pin * 4) + 3));
|
|
||||||
val |= on << ((pin * 4) + 3);
|
|
||||||
__raw_writel(val, S3C24XX_EXTINT2);
|
|
||||||
|
|
||||||
local_irq_restore(flags);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
EXPORT_SYMBOL(s3c2410_gpio_irqfilter);
|
|
|
@ -1,48 +0,0 @@
|
||||||
/* linux/arch/arm/mach-s3c2410/s3c2410-irq.c
|
|
||||||
*
|
|
||||||
* Copyright (c) 2006 Simtec Electronics
|
|
||||||
* Ben Dooks <ben@simtec.co.uk>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <linux/init.h>
|
|
||||||
#include <linux/module.h>
|
|
||||||
#include <linux/interrupt.h>
|
|
||||||
#include <linux/ioport.h>
|
|
||||||
#include <linux/ptrace.h>
|
|
||||||
#include <linux/sysdev.h>
|
|
||||||
|
|
||||||
#include "cpu.h"
|
|
||||||
#include "pm.h"
|
|
||||||
|
|
||||||
static int s3c2410_irq_add(struct sys_device *sysdev)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct sysdev_driver s3c2410_irq_driver = {
|
|
||||||
.add = s3c2410_irq_add,
|
|
||||||
.suspend = s3c24xx_irq_suspend,
|
|
||||||
.resume = s3c24xx_irq_resume,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int s3c2410_irq_init(void)
|
|
||||||
{
|
|
||||||
return sysdev_driver_register(&s3c2410_sysclass, &s3c2410_irq_driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
arch_initcall(s3c2410_irq_init);
|
|
|
@ -1,156 +0,0 @@
|
||||||
/* linux/arch/arm/mach-s3c2410/s3c2410-pm.c
|
|
||||||
*
|
|
||||||
* Copyright (c) 2006 Simtec Electronics
|
|
||||||
* Ben Dooks <ben@simtec.co.uk>
|
|
||||||
*
|
|
||||||
* S3C2410 (and compatible) Power Manager (Suspend-To-RAM) support
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <linux/init.h>
|
|
||||||
#include <linux/suspend.h>
|
|
||||||
#include <linux/errno.h>
|
|
||||||
#include <linux/time.h>
|
|
||||||
#include <linux/sysdev.h>
|
|
||||||
|
|
||||||
#include <asm/hardware.h>
|
|
||||||
#include <asm/io.h>
|
|
||||||
|
|
||||||
#include <asm/mach-types.h>
|
|
||||||
|
|
||||||
#include <asm/arch/regs-gpio.h>
|
|
||||||
#include <asm/arch/h1940.h>
|
|
||||||
|
|
||||||
#include "cpu.h"
|
|
||||||
#include "pm.h"
|
|
||||||
|
|
||||||
#ifdef CONFIG_S3C2410_PM_DEBUG
|
|
||||||
extern void pm_dbg(const char *fmt, ...);
|
|
||||||
#define DBG(fmt...) pm_dbg(fmt)
|
|
||||||
#else
|
|
||||||
#define DBG(fmt...) printk(KERN_DEBUG fmt)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void s3c2410_pm_prepare(void)
|
|
||||||
{
|
|
||||||
/* ensure at least GSTATUS3 has the resume address */
|
|
||||||
|
|
||||||
__raw_writel(virt_to_phys(s3c2410_cpu_resume), S3C2410_GSTATUS3);
|
|
||||||
|
|
||||||
DBG("GSTATUS3 0x%08x\n", __raw_readl(S3C2410_GSTATUS3));
|
|
||||||
DBG("GSTATUS4 0x%08x\n", __raw_readl(S3C2410_GSTATUS4));
|
|
||||||
|
|
||||||
if (machine_is_h1940()) {
|
|
||||||
void *base = phys_to_virt(H1940_SUSPEND_CHECK);
|
|
||||||
unsigned long ptr;
|
|
||||||
unsigned long calc = 0;
|
|
||||||
|
|
||||||
/* generate check for the bootloader to check on resume */
|
|
||||||
|
|
||||||
for (ptr = 0; ptr < 0x40000; ptr += 0x400)
|
|
||||||
calc += __raw_readl(base+ptr);
|
|
||||||
|
|
||||||
__raw_writel(calc, phys_to_virt(H1940_SUSPEND_CHECKSUM));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* the RX3715 uses similar code and the same H1940 and the
|
|
||||||
* same offsets for resume and checksum pointers */
|
|
||||||
|
|
||||||
if (machine_is_rx3715()) {
|
|
||||||
void *base = phys_to_virt(H1940_SUSPEND_CHECK);
|
|
||||||
unsigned long ptr;
|
|
||||||
unsigned long calc = 0;
|
|
||||||
|
|
||||||
/* generate check for the bootloader to check on resume */
|
|
||||||
|
|
||||||
for (ptr = 0; ptr < 0x40000; ptr += 0x4)
|
|
||||||
calc += __raw_readl(base+ptr);
|
|
||||||
|
|
||||||
__raw_writel(calc, phys_to_virt(H1940_SUSPEND_CHECKSUM));
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( machine_is_aml_m5900() )
|
|
||||||
s3c2410_gpio_setpin(S3C2410_GPF2, 1);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static int s3c2410_pm_resume(struct sys_device *dev)
|
|
||||||
{
|
|
||||||
unsigned long tmp;
|
|
||||||
|
|
||||||
/* unset the return-from-sleep flag, to ensure reset */
|
|
||||||
|
|
||||||
tmp = __raw_readl(S3C2410_GSTATUS2);
|
|
||||||
tmp &= S3C2410_GSTATUS2_OFFRESET;
|
|
||||||
__raw_writel(tmp, S3C2410_GSTATUS2);
|
|
||||||
|
|
||||||
if ( machine_is_aml_m5900() )
|
|
||||||
s3c2410_gpio_setpin(S3C2410_GPF2, 0);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int s3c2410_pm_add(struct sys_device *dev)
|
|
||||||
{
|
|
||||||
pm_cpu_prep = s3c2410_pm_prepare;
|
|
||||||
pm_cpu_sleep = s3c2410_cpu_suspend;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(CONFIG_CPU_S3C2410)
|
|
||||||
static struct sysdev_driver s3c2410_pm_driver = {
|
|
||||||
.add = s3c2410_pm_add,
|
|
||||||
.resume = s3c2410_pm_resume,
|
|
||||||
};
|
|
||||||
|
|
||||||
/* register ourselves */
|
|
||||||
|
|
||||||
static int __init s3c2410_pm_drvinit(void)
|
|
||||||
{
|
|
||||||
return sysdev_driver_register(&s3c2410_sysclass, &s3c2410_pm_driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
arch_initcall(s3c2410_pm_drvinit);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(CONFIG_CPU_S3C2440)
|
|
||||||
static struct sysdev_driver s3c2440_pm_driver = {
|
|
||||||
.add = s3c2410_pm_add,
|
|
||||||
.resume = s3c2410_pm_resume,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int __init s3c2440_pm_drvinit(void)
|
|
||||||
{
|
|
||||||
return sysdev_driver_register(&s3c2440_sysclass, &s3c2440_pm_driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
arch_initcall(s3c2440_pm_drvinit);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(CONFIG_CPU_S3C2442)
|
|
||||||
static struct sysdev_driver s3c2442_pm_driver = {
|
|
||||||
.add = s3c2410_pm_add,
|
|
||||||
.resume = s3c2410_pm_resume,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int __init s3c2442_pm_drvinit(void)
|
|
||||||
{
|
|
||||||
return sysdev_driver_register(&s3c2442_sysclass, &s3c2442_pm_driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
arch_initcall(s3c2442_pm_drvinit);
|
|
||||||
#endif
|
|
|
@ -1,68 +0,0 @@
|
||||||
/* linux/arch/arm/mach-s3c2410/s3c2410-sleep.S
|
|
||||||
*
|
|
||||||
* Copyright (c) 2004 Simtec Electronics
|
|
||||||
* Ben Dooks <ben@simtec.co.uk>
|
|
||||||
*
|
|
||||||
* S3C2410 Power Manager (Suspend-To-RAM) support
|
|
||||||
*
|
|
||||||
* Based on PXA/SA1100 sleep code by:
|
|
||||||
* Nicolas Pitre, (c) 2002 Monta Vista Software Inc
|
|
||||||
* Cliff Brake, (c) 2001
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <linux/linkage.h>
|
|
||||||
#include <asm/assembler.h>
|
|
||||||
#include <asm/hardware.h>
|
|
||||||
#include <asm/arch/map.h>
|
|
||||||
|
|
||||||
#include <asm/arch/regs-gpio.h>
|
|
||||||
#include <asm/arch/regs-clock.h>
|
|
||||||
#include <asm/arch/regs-mem.h>
|
|
||||||
#include <asm/arch/regs-serial.h>
|
|
||||||
|
|
||||||
/* s3c2410_cpu_suspend
|
|
||||||
*
|
|
||||||
* put the cpu into sleep mode
|
|
||||||
*/
|
|
||||||
|
|
||||||
ENTRY(s3c2410_cpu_suspend)
|
|
||||||
@@ prepare cpu to sleep
|
|
||||||
|
|
||||||
ldr r4, =S3C2410_REFRESH
|
|
||||||
ldr r5, =S3C24XX_MISCCR
|
|
||||||
ldr r6, =S3C2410_CLKCON
|
|
||||||
ldr r7, [ r4 ] @ get REFRESH (and ensure in TLB)
|
|
||||||
ldr r8, [ r5 ] @ get MISCCR (and ensure in TLB)
|
|
||||||
ldr r9, [ r6 ] @ get CLKCON (and ensure in TLB)
|
|
||||||
|
|
||||||
orr r7, r7, #S3C2410_REFRESH_SELF @ SDRAM sleep command
|
|
||||||
orr r8, r8, #S3C2410_MISCCR_SDSLEEP @ SDRAM power-down signals
|
|
||||||
orr r9, r9, #S3C2410_CLKCON_POWER @ power down command
|
|
||||||
|
|
||||||
teq pc, #0 @ first as a trial-run to load cache
|
|
||||||
bl s3c2410_do_sleep
|
|
||||||
teq r0, r0 @ now do it for real
|
|
||||||
b s3c2410_do_sleep @
|
|
||||||
|
|
||||||
@@ align next bit of code to cache line
|
|
||||||
.align 8
|
|
||||||
s3c2410_do_sleep:
|
|
||||||
streq r7, [ r4 ] @ SDRAM sleep command
|
|
||||||
streq r8, [ r5 ] @ SDRAM power-down config
|
|
||||||
streq r9, [ r6 ] @ CPU sleep
|
|
||||||
1: beq 1b
|
|
||||||
mov pc, r14
|
|
|
@ -31,10 +31,10 @@
|
||||||
#include <asm/arch/regs-clock.h>
|
#include <asm/arch/regs-clock.h>
|
||||||
#include <asm/arch/regs-serial.h>
|
#include <asm/arch/regs-serial.h>
|
||||||
|
|
||||||
#include "s3c2410.h"
|
#include <asm/plat-s3c24xx/s3c2410.h>
|
||||||
#include "cpu.h"
|
#include <asm/plat-s3c24xx/cpu.h>
|
||||||
#include "devs.h"
|
#include <asm/plat-s3c24xx/devs.h>
|
||||||
#include "clock.h"
|
#include <asm/plat-s3c24xx/clock.h>
|
||||||
|
|
||||||
/* Initial IO mappings */
|
/* Initial IO mappings */
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* linux/arch/arm/mach-s3c2410/sleep.S
|
/* linux/arch/arm/mach-s3c2410/s3c2410-sleep.S
|
||||||
*
|
*
|
||||||
* Copyright (c) 2004 Simtec Electronics
|
* Copyright (c) 2004 Simtec Electronics
|
||||||
* Ben Dooks <ben@simtec.co.uk>
|
* Ben Dooks <ben@simtec.co.uk>
|
||||||
|
@ -34,126 +34,35 @@
|
||||||
#include <asm/arch/regs-mem.h>
|
#include <asm/arch/regs-mem.h>
|
||||||
#include <asm/arch/regs-serial.h>
|
#include <asm/arch/regs-serial.h>
|
||||||
|
|
||||||
/* CONFIG_DEBUG_RESUME is dangerous if your bootloader does not
|
/* s3c2410_cpu_suspend
|
||||||
* reset the UART configuration, only enable if you really need this!
|
|
||||||
*/
|
|
||||||
//#define CONFIG_DEBUG_RESUME
|
|
||||||
|
|
||||||
.text
|
|
||||||
|
|
||||||
/* s3c2410_cpu_save
|
|
||||||
*
|
*
|
||||||
* save enough of the CPU state to allow us to re-start
|
* put the cpu into sleep mode
|
||||||
* pm.c code. as we store items like the sp/lr, we will
|
|
||||||
* end up returning from this function when the cpu resumes
|
|
||||||
* so the return value is set to mark this.
|
|
||||||
*
|
|
||||||
* This arangement means we avoid having to flush the cache
|
|
||||||
* from this code.
|
|
||||||
*
|
|
||||||
* entry:
|
|
||||||
* r0 = pointer to save block
|
|
||||||
*
|
|
||||||
* exit:
|
|
||||||
* r0 = 0 => we stored everything
|
|
||||||
* 1 => resumed from sleep
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ENTRY(s3c2410_cpu_save)
|
ENTRY(s3c2410_cpu_suspend)
|
||||||
stmfd sp!, { r4 - r12, lr }
|
@@ prepare cpu to sleep
|
||||||
|
|
||||||
@@ store co-processor registers
|
ldr r4, =S3C2410_REFRESH
|
||||||
|
ldr r5, =S3C24XX_MISCCR
|
||||||
|
ldr r6, =S3C2410_CLKCON
|
||||||
|
ldr r7, [ r4 ] @ get REFRESH (and ensure in TLB)
|
||||||
|
ldr r8, [ r5 ] @ get MISCCR (and ensure in TLB)
|
||||||
|
ldr r9, [ r6 ] @ get CLKCON (and ensure in TLB)
|
||||||
|
|
||||||
mrc p15, 0, r4, c15, c1, 0 @ CP access register
|
orr r7, r7, #S3C2410_REFRESH_SELF @ SDRAM sleep command
|
||||||
mrc p15, 0, r5, c13, c0, 0 @ PID
|
orr r8, r8, #S3C2410_MISCCR_SDSLEEP @ SDRAM power-down signals
|
||||||
mrc p15, 0, r6, c3, c0, 0 @ Domain ID
|
orr r9, r9, #S3C2410_CLKCON_POWER @ power down command
|
||||||
mrc p15, 0, r7, c2, c0, 0 @ translation table base address
|
|
||||||
mrc p15, 0, r8, c1, c0, 0 @ control register
|
|
||||||
|
|
||||||
stmia r0, { r4 - r13 }
|
teq pc, #0 @ first as a trial-run to load cache
|
||||||
|
bl s3c2410_do_sleep
|
||||||
|
teq r0, r0 @ now do it for real
|
||||||
|
b s3c2410_do_sleep @
|
||||||
|
|
||||||
mov r0, #0
|
@@ align next bit of code to cache line
|
||||||
ldmfd sp, { r4 - r12, pc }
|
.align 8
|
||||||
|
s3c2410_do_sleep:
|
||||||
@@ return to the caller, after having the MMU
|
streq r7, [ r4 ] @ SDRAM sleep command
|
||||||
@@ turned on, this restores the last bits from the
|
streq r8, [ r5 ] @ SDRAM power-down config
|
||||||
@@ stack
|
streq r9, [ r6 ] @ CPU sleep
|
||||||
resume_with_mmu:
|
1: beq 1b
|
||||||
mov r0, #1
|
mov pc, r14
|
||||||
ldmfd sp!, { r4 - r12, pc }
|
|
||||||
|
|
||||||
.ltorg
|
|
||||||
|
|
||||||
@@ the next bits sit in the .data segment, even though they
|
|
||||||
@@ happen to be code... the s3c2410_sleep_save_phys needs to be
|
|
||||||
@@ accessed by the resume code before it can restore the MMU.
|
|
||||||
@@ This means that the variable has to be close enough for the
|
|
||||||
@@ code to read it... since the .text segment needs to be RO,
|
|
||||||
@@ the data segment can be the only place to put this code.
|
|
||||||
|
|
||||||
.data
|
|
||||||
|
|
||||||
.global s3c2410_sleep_save_phys
|
|
||||||
s3c2410_sleep_save_phys:
|
|
||||||
.word 0
|
|
||||||
|
|
||||||
/* s3c2410_cpu_resume
|
|
||||||
*
|
|
||||||
* resume code entry for bootloader to call
|
|
||||||
*
|
|
||||||
* we must put this code here in the data segment as we have no
|
|
||||||
* other way of restoring the stack pointer after sleep, and we
|
|
||||||
* must not write to the code segment (code is read-only)
|
|
||||||
*/
|
|
||||||
|
|
||||||
ENTRY(s3c2410_cpu_resume)
|
|
||||||
mov r0, #PSR_I_BIT | PSR_F_BIT | SVC_MODE
|
|
||||||
msr cpsr_c, r0
|
|
||||||
|
|
||||||
@@ load UART to allow us to print the two characters for
|
|
||||||
@@ resume debug
|
|
||||||
|
|
||||||
mov r2, #S3C24XX_PA_UART & 0xff000000
|
|
||||||
orr r2, r2, #S3C24XX_PA_UART & 0xff000
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
/* SMDK2440 LED set */
|
|
||||||
mov r14, #S3C24XX_PA_GPIO
|
|
||||||
ldr r12, [ r14, #0x54 ]
|
|
||||||
bic r12, r12, #3<<4
|
|
||||||
orr r12, r12, #1<<7
|
|
||||||
str r12, [ r14, #0x54 ]
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef CONFIG_DEBUG_RESUME
|
|
||||||
mov r3, #'L'
|
|
||||||
strb r3, [ r2, #S3C2410_UTXH ]
|
|
||||||
1001:
|
|
||||||
ldrb r14, [ r3, #S3C2410_UTRSTAT ]
|
|
||||||
tst r14, #S3C2410_UTRSTAT_TXE
|
|
||||||
beq 1001b
|
|
||||||
#endif /* CONFIG_DEBUG_RESUME */
|
|
||||||
|
|
||||||
mov r1, #0
|
|
||||||
mcr p15, 0, r1, c8, c7, 0 @@ invalidate I & D TLBs
|
|
||||||
mcr p15, 0, r1, c7, c7, 0 @@ invalidate I & D caches
|
|
||||||
|
|
||||||
ldr r0, s3c2410_sleep_save_phys @ address of restore block
|
|
||||||
ldmia r0, { r4 - r13 }
|
|
||||||
|
|
||||||
mcr p15, 0, r4, c15, c1, 0 @ CP access register
|
|
||||||
mcr p15, 0, r5, c13, c0, 0 @ PID
|
|
||||||
mcr p15, 0, r6, c3, c0, 0 @ Domain ID
|
|
||||||
mcr p15, 0, r7, c2, c0, 0 @ translation table base
|
|
||||||
|
|
||||||
#ifdef CONFIG_DEBUG_RESUME
|
|
||||||
mov r3, #'R'
|
|
||||||
strb r3, [ r2, #S3C2410_UTXH ]
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ldr r2, =resume_with_mmu
|
|
||||||
mcr p15, 0, r8, c1, c0, 0 @ turn on MMU, etc
|
|
||||||
nop @ second-to-last before mmu
|
|
||||||
mov pc, r2 @ go back to virtual address
|
|
||||||
|
|
||||||
.ltorg
|
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
#include <asm/irq.h>
|
#include <asm/irq.h>
|
||||||
|
|
||||||
#include "devs.h"
|
#include <asm/plat-s3c24xx/devs.h>
|
||||||
#include "usb-simtec.h"
|
#include "usb-simtec.h"
|
||||||
|
|
||||||
/* control power and monitor over-current events on various Simtec
|
/* control power and monitor over-current events on various Simtec
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
# arch/arm/mach-s3c2412/Kconfig
|
||||||
|
#
|
||||||
|
# Copyright 2007 Simtec Electronics
|
||||||
|
#
|
||||||
|
# Licensed under GPLv2
|
||||||
|
|
||||||
|
config CPU_S3C2412
|
||||||
|
bool
|
||||||
|
depends on ARCH_S3C2410
|
||||||
|
select S3C2412_PM if PM
|
||||||
|
select S3C2412_DMA if S3C2410_DMA
|
||||||
|
help
|
||||||
|
Support for the S3C2412 and S3C2413 SoCs from the S3C24XX line
|
||||||
|
|
||||||
|
config CPU_S3C2412_ONLY
|
||||||
|
bool
|
||||||
|
depends on ARCH_S3C2410 && !CPU_S3C2400 && !CPU_S3C2410 && \
|
||||||
|
!CPU_S3C2440 && !CPU_S3C2442 && CPU_S3C2412
|
||||||
|
default y if CPU_S3C2412
|
||||||
|
|
||||||
|
config S3C2412_DMA
|
||||||
|
bool
|
||||||
|
depends on CPU_S3C2412
|
||||||
|
help
|
||||||
|
Internal config node for S3C2412 DMA support
|
||||||
|
|
||||||
|
config S3C2412_PM
|
||||||
|
bool
|
||||||
|
help
|
||||||
|
Internal config node to apply S3C2412 power management
|
||||||
|
|
||||||
|
|
||||||
|
menu "S3C2412 Machines"
|
||||||
|
|
||||||
|
config MACH_SMDK2413
|
||||||
|
bool "SMDK2413"
|
||||||
|
select CPU_S3C2412
|
||||||
|
select MACH_S3C2413
|
||||||
|
select MACH_SMDK
|
||||||
|
help
|
||||||
|
Say Y here if you are using an SMDK2413
|
||||||
|
|
||||||
|
config MACH_S3C2413
|
||||||
|
bool
|
||||||
|
help
|
||||||
|
Internal node for S3C2413 version of SMDK2413, so that
|
||||||
|
machine_is_s3c2413() will work when MACH_SMDK2413 is
|
||||||
|
selected
|
||||||
|
|
||||||
|
config MACH_VSTMS
|
||||||
|
bool "VMSTMS"
|
||||||
|
select CPU_S3C2412
|
||||||
|
help
|
||||||
|
Say Y here if you are using an VSTMS board
|
||||||
|
|
||||||
|
|
||||||
|
endmenu
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
# arch/arm/mach-s3c2412/Makefile
|
||||||
|
#
|
||||||
|
# Copyright 2007 Simtec Electronics
|
||||||
|
#
|
||||||
|
# Licensed under GPLv2
|
||||||
|
|
||||||
|
obj-y :=
|
||||||
|
obj-m :=
|
||||||
|
obj-n :=
|
||||||
|
obj- :=
|
||||||
|
|
||||||
|
obj-$(CONFIG_CPU_S3C2412) += s3c2412.o
|
||||||
|
obj-$(CONFIG_CPU_S3C2412) += irq.o
|
||||||
|
obj-$(CONFIG_CPU_S3C2412) += clock.o
|
||||||
|
obj-$(CONFIG_S3C2412_DMA) += dma.o
|
||||||
|
obj-$(CONFIG_S3C2412_PM) += pm.o
|
||||||
|
|
||||||
|
# Machine support
|
||||||
|
|
||||||
|
obj-$(CONFIG_MACH_SMDK2413) += mach-smdk2413.o
|
||||||
|
obj-$(CONFIG_MACH_VSTMS) += mach-vstms.o
|
|
@ -1,4 +1,4 @@
|
||||||
/* linux/arch/arm/mach-s3c2410/s3c2412-clock.c
|
/* linux/arch/arm/mach-s3c2412/clock.c
|
||||||
*
|
*
|
||||||
* Copyright (c) 2006 Simtec Electronics
|
* Copyright (c) 2006 Simtec Electronics
|
||||||
* Ben Dooks <ben@simtec.co.uk>
|
* Ben Dooks <ben@simtec.co.uk>
|
||||||
|
@ -41,9 +41,9 @@
|
||||||
#include <asm/arch/regs-clock.h>
|
#include <asm/arch/regs-clock.h>
|
||||||
#include <asm/arch/regs-gpio.h>
|
#include <asm/arch/regs-gpio.h>
|
||||||
|
|
||||||
#include "s3c2412.h"
|
#include <asm/plat-s3c24xx/s3c2412.h>
|
||||||
#include "clock.h"
|
#include <asm/plat-s3c24xx/clock.h>
|
||||||
#include "cpu.h"
|
#include <asm/plat-s3c24xx/cpu.h>
|
||||||
|
|
||||||
/* We currently have to assume that the system is running
|
/* We currently have to assume that the system is running
|
||||||
* from the XTPll input, and that all ***REFCLKs are being
|
* from the XTPll input, and that all ***REFCLKs are being
|
|
@ -1,4 +1,4 @@
|
||||||
/* linux/arch/arm/mach-s3c2410/s3c2412-dma.c
|
/* linux/arch/arm/mach-s3c2412/dma.c
|
||||||
*
|
*
|
||||||
* Copyright (c) 2006 Simtec Electronics
|
* Copyright (c) 2006 Simtec Electronics
|
||||||
* Ben Dooks <ben@simtec.co.uk>
|
* Ben Dooks <ben@simtec.co.uk>
|
||||||
|
@ -21,8 +21,8 @@
|
||||||
#include <asm/arch/dma.h>
|
#include <asm/arch/dma.h>
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
|
|
||||||
#include "dma.h"
|
#include <asm/plat-s3c24xx/dma.h>
|
||||||
#include "cpu.h"
|
#include <asm/plat-s3c24xx/cpu.h>
|
||||||
|
|
||||||
#include <asm/arch/regs-serial.h>
|
#include <asm/arch/regs-serial.h>
|
||||||
#include <asm/arch/regs-gpio.h>
|
#include <asm/arch/regs-gpio.h>
|
|
@ -1,4 +1,4 @@
|
||||||
/* linux/arch/arm/mach-s3c2412/s3c2412-irq.c
|
/* linux/arch/arm/mach-s3c2412/irq.c
|
||||||
*
|
*
|
||||||
* Copyright (c) 2006 Simtec Electronics
|
* Copyright (c) 2006 Simtec Electronics
|
||||||
* Ben Dooks <ben@simtec.co.uk>
|
* Ben Dooks <ben@simtec.co.uk>
|
||||||
|
@ -35,9 +35,9 @@
|
||||||
#include <asm/arch/regs-irq.h>
|
#include <asm/arch/regs-irq.h>
|
||||||
#include <asm/arch/regs-gpio.h>
|
#include <asm/arch/regs-gpio.h>
|
||||||
|
|
||||||
#include "cpu.h"
|
#include <asm/plat-s3c24xx/cpu.h>
|
||||||
#include "irq.h"
|
#include <asm/plat-s3c24xx/irq.h>
|
||||||
#include "pm.h"
|
#include <asm/plat-s3c24xx/pm.h>
|
||||||
|
|
||||||
/* the s3c2412 changes the behaviour of IRQ_EINT0 through IRQ_EINT3 by
|
/* the s3c2412 changes the behaviour of IRQ_EINT0 through IRQ_EINT3 by
|
||||||
* having them turn up in both the INT* and the EINT* registers. Whilst
|
* having them turn up in both the INT* and the EINT* registers. Whilst
|
|
@ -1,4 +1,4 @@
|
||||||
/* linux/arch/arm/mach-s3c2410/mach-smdk2413.c
|
/* linux/arch/arm/mach-s3c2412/mach-smdk2413.c
|
||||||
*
|
*
|
||||||
* Copyright (c) 2006 Simtec Electronics
|
* Copyright (c) 2006 Simtec Electronics
|
||||||
* Ben Dooks <ben@simtec.co.uk>
|
* Ben Dooks <ben@simtec.co.uk>
|
||||||
|
@ -39,13 +39,13 @@
|
||||||
#include <asm/arch/idle.h>
|
#include <asm/arch/idle.h>
|
||||||
#include <asm/arch/fb.h>
|
#include <asm/arch/fb.h>
|
||||||
|
|
||||||
#include "s3c2410.h"
|
#include <asm/plat-s3c24xx/s3c2410.h>
|
||||||
#include "s3c2412.h"
|
#include <asm/plat-s3c24xx/s3c2412.h>
|
||||||
#include "clock.h"
|
#include <asm/plat-s3c24xx/clock.h>
|
||||||
#include "devs.h"
|
#include <asm/plat-s3c24xx/devs.h>
|
||||||
#include "cpu.h"
|
#include <asm/plat-s3c24xx/cpu.h>
|
||||||
|
|
||||||
#include "common-smdk.h"
|
#include <asm/plat-s3c24xx/common-smdk.h>
|
||||||
|
|
||||||
static struct map_desc smdk2413_iodesc[] __initdata = {
|
static struct map_desc smdk2413_iodesc[] __initdata = {
|
||||||
};
|
};
|
|
@ -1,4 +1,4 @@
|
||||||
/* linux/arch/arm/mach-s3c2410/mach-vstms.c
|
/* linux/arch/arm/mach-s3c2412/mach-vstms.c
|
||||||
*
|
*
|
||||||
* (C) 2006 Thomas Gleixner <tglx@linutronix.de>
|
* (C) 2006 Thomas Gleixner <tglx@linutronix.de>
|
||||||
*
|
*
|
||||||
|
@ -43,11 +43,11 @@
|
||||||
|
|
||||||
#include <asm/arch/nand.h>
|
#include <asm/arch/nand.h>
|
||||||
|
|
||||||
#include "s3c2410.h"
|
#include <asm/plat-s3c24xx/s3c2410.h>
|
||||||
#include "s3c2412.h"
|
#include <asm/plat-s3c24xx/s3c2412.h>
|
||||||
#include "clock.h"
|
#include <asm/plat-s3c24xx/clock.h>
|
||||||
#include "devs.h"
|
#include <asm/plat-s3c24xx/devs.h>
|
||||||
#include "cpu.h"
|
#include <asm/plat-s3c24xx/cpu.h>
|
||||||
|
|
||||||
|
|
||||||
static struct map_desc vstms_iodesc[] __initdata = {
|
static struct map_desc vstms_iodesc[] __initdata = {
|
|
@ -1,4 +1,4 @@
|
||||||
/* linux/arch/arm/mach-s3c2410/s3c2412-pm.c
|
/* linux/arch/arm/mach-s3c2412/pm.c
|
||||||
*
|
*
|
||||||
* Copyright (c) 2006 Simtec Electronics
|
* Copyright (c) 2006 Simtec Electronics
|
||||||
* Ben Dooks <ben@simtec.co.uk>
|
* Ben Dooks <ben@simtec.co.uk>
|
||||||
|
@ -28,10 +28,10 @@
|
||||||
#include <asm/arch/regs-gpio.h>
|
#include <asm/arch/regs-gpio.h>
|
||||||
#include <asm/arch/regs-dsc.h>
|
#include <asm/arch/regs-dsc.h>
|
||||||
|
|
||||||
#include "cpu.h"
|
#include <asm/plat-s3c24xx/cpu.h>
|
||||||
#include "pm.h"
|
#include <asm/plat-s3c24xx/pm.h>
|
||||||
|
|
||||||
#include "s3c2412.h"
|
#include <asm/plat-s3c24xx/s3c2412.h>
|
||||||
|
|
||||||
static void s3c2412_cpu_suspend(void)
|
static void s3c2412_cpu_suspend(void)
|
||||||
{
|
{
|
|
@ -1,4 +1,4 @@
|
||||||
/* linux/arch/arm/mach-s3c2410/s3c2412.c
|
/* linux/arch/arm/mach-s3c2412/s3c2412.c
|
||||||
*
|
*
|
||||||
* Copyright (c) 2006 Simtec Electronics
|
* Copyright (c) 2006 Simtec Electronics
|
||||||
* Ben Dooks <ben@simtec.co.uk>
|
* Ben Dooks <ben@simtec.co.uk>
|
||||||
|
@ -38,11 +38,11 @@
|
||||||
#include <asm/arch/regs-gpioj.h>
|
#include <asm/arch/regs-gpioj.h>
|
||||||
#include <asm/arch/regs-dsc.h>
|
#include <asm/arch/regs-dsc.h>
|
||||||
|
|
||||||
#include "s3c2412.h"
|
#include <asm/plat-s3c24xx/s3c2412.h>
|
||||||
#include "cpu.h"
|
#include <asm/plat-s3c24xx/cpu.h>
|
||||||
#include "devs.h"
|
#include <asm/plat-s3c24xx/devs.h>
|
||||||
#include "clock.h"
|
#include <asm/plat-s3c24xx/clock.h>
|
||||||
#include "pm.h"
|
#include <asm/plat-s3c24xx/pm.h>
|
||||||
|
|
||||||
#ifndef CONFIG_CPU_S3C2412_ONLY
|
#ifndef CONFIG_CPU_S3C2412_ONLY
|
||||||
void __iomem *s3c24xx_va_gpio2 = S3C24XX_VA_GPIO;
|
void __iomem *s3c24xx_va_gpio2 = S3C24XX_VA_GPIO;
|
|
@ -0,0 +1,71 @@
|
||||||
|
# arch/arm/mach-s3c2440/Kconfig
|
||||||
|
#
|
||||||
|
# Copyright 2007 Simtec Electronics
|
||||||
|
#
|
||||||
|
# Licensed under GPLv2
|
||||||
|
|
||||||
|
config CPU_S3C2440
|
||||||
|
bool
|
||||||
|
depends on ARCH_S3C2410
|
||||||
|
select S3C2410_CLOCK
|
||||||
|
select S3C2410_PM if PM
|
||||||
|
select S3C2410_GPIO
|
||||||
|
select S3C2440_DMA if S3C2410_DMA
|
||||||
|
select CPU_S3C244X
|
||||||
|
help
|
||||||
|
Support for S3C2440 Samsung Mobile CPU based systems.
|
||||||
|
|
||||||
|
config S3C2440_DMA
|
||||||
|
bool
|
||||||
|
depends on ARCH_S3C2410 && CPU_S3C24405B
|
||||||
|
help
|
||||||
|
Support for S3C2440 specific DMA code5A
|
||||||
|
|
||||||
|
|
||||||
|
menu "S3C2440 Machines"
|
||||||
|
|
||||||
|
config MACH_ANUBIS
|
||||||
|
bool "Simtec Electronics ANUBIS"
|
||||||
|
select CPU_S3C2440
|
||||||
|
select PM_SIMTEC if PM
|
||||||
|
help
|
||||||
|
Say Y here if you are using the Simtec Electronics ANUBIS
|
||||||
|
development system
|
||||||
|
|
||||||
|
config MACH_OSIRIS
|
||||||
|
bool "Simtec IM2440D20 (OSIRIS) module"
|
||||||
|
select CPU_S3C2440
|
||||||
|
select PM_SIMTEC if PM
|
||||||
|
help
|
||||||
|
Say Y here if you are using the Simtec IM2440D20 module, also
|
||||||
|
known as the Osiris.
|
||||||
|
|
||||||
|
config MACH_RX3715
|
||||||
|
bool "HP iPAQ rx3715"
|
||||||
|
select CPU_S3C2440
|
||||||
|
select PM_H1940 if PM
|
||||||
|
help
|
||||||
|
Say Y here if you are using the HP iPAQ rx3715.
|
||||||
|
|
||||||
|
config ARCH_S3C2440
|
||||||
|
bool "SMDK2440"
|
||||||
|
select CPU_S3C2440
|
||||||
|
select MACH_SMDK
|
||||||
|
help
|
||||||
|
Say Y here if you are using the SMDK2440.
|
||||||
|
|
||||||
|
config MACH_NEXCODER_2440
|
||||||
|
bool "NexVision NEXCODER 2440 Light Board"
|
||||||
|
select CPU_S3C2440
|
||||||
|
help
|
||||||
|
Say Y here if you are using the Nex Vision NEXCODER 2440 Light Board
|
||||||
|
|
||||||
|
config SMDK2440_CPU2440
|
||||||
|
bool "SMDK2440 with S3C2440 CPU module"
|
||||||
|
depends on ARCH_S3C2440
|
||||||
|
default y if ARCH_S3C2440
|
||||||
|
select CPU_S3C2440
|
||||||
|
|
||||||
|
|
||||||
|
endmenu
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
# arch/arm/mach-s3c2440/Makefile
|
||||||
|
#
|
||||||
|
# Copyright 2007 Simtec Electronics
|
||||||
|
#
|
||||||
|
# Licensed under GPLv2
|
||||||
|
|
||||||
|
obj-y :=
|
||||||
|
obj-m :=
|
||||||
|
obj-n :=
|
||||||
|
obj- :=
|
||||||
|
|
||||||
|
obj-$(CONFIG_CPU_S3C2440) += s3c2440.o dsc.o
|
||||||
|
obj-$(CONFIG_CPU_S3C2440) += irq.o
|
||||||
|
obj-$(CONFIG_CPU_S3C2440) += clock.o
|
||||||
|
obj-$(CONFIG_S3C2440_DMA) += dma.o
|
||||||
|
|
||||||
|
# Machine support
|
||||||
|
|
||||||
|
obj-$(CONFIG_MACH_ANUBIS) += mach-anubis.o
|
||||||
|
obj-$(CONFIG_MACH_OSIRIS) += mach-osiris.o
|
||||||
|
obj-$(CONFIG_MACH_RX3715) += mach-rx3715.o
|
||||||
|
obj-$(CONFIG_ARCH_S3C2440) += mach-smdk2440.o
|
||||||
|
obj-$(CONFIG_MACH_NEXCODER_2440) += mach-nexcoder.o
|
|
@ -1,4 +1,4 @@
|
||||||
/* linux/arch/arm/mach-s3c2410/s3c2440-clock.c
|
/* linux/arch/arm/mach-s3c2440/clock.c
|
||||||
*
|
*
|
||||||
* Copyright (c) 2004-2005 Simtec Electronics
|
* Copyright (c) 2004-2005 Simtec Electronics
|
||||||
* http://armlinux.simtec.co.uk/
|
* http://armlinux.simtec.co.uk/
|
||||||
|
@ -41,8 +41,8 @@
|
||||||
|
|
||||||
#include <asm/arch/regs-clock.h>
|
#include <asm/arch/regs-clock.h>
|
||||||
|
|
||||||
#include "clock.h"
|
#include <asm/plat-s3c24xx/clock.h>
|
||||||
#include "cpu.h"
|
#include <asm/plat-s3c24xx/cpu.h>
|
||||||
|
|
||||||
/* S3C2440 extended clock support */
|
/* S3C2440 extended clock support */
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* linux/arch/arm/mach-s3c2410/s3c2440-dma.c
|
/* linux/arch/arm/mach-s3c2440/dma.c
|
||||||
*
|
*
|
||||||
* Copyright (c) 2006 Simtec Electronics
|
* Copyright (c) 2006 Simtec Electronics
|
||||||
* Ben Dooks <ben@simtec.co.uk>
|
* Ben Dooks <ben@simtec.co.uk>
|
||||||
|
@ -19,9 +19,9 @@
|
||||||
|
|
||||||
#include <asm/dma.h>
|
#include <asm/dma.h>
|
||||||
#include <asm/arch/dma.h>
|
#include <asm/arch/dma.h>
|
||||||
#include "dma.h"
|
#include <asm/plat-s3c24xx/dma.h>
|
||||||
|
|
||||||
#include "cpu.h"
|
#include <asm/plat-s3c24xx/cpu.h>
|
||||||
|
|
||||||
#include <asm/arch/regs-serial.h>
|
#include <asm/arch/regs-serial.h>
|
||||||
#include <asm/arch/regs-gpio.h>
|
#include <asm/arch/regs-gpio.h>
|
|
@ -1,4 +1,4 @@
|
||||||
/* linux/arch/arm/mach-s3c2410/s3c2440-dsc.c
|
/* linux/arch/arm/mach-s3c2440/dsc.c
|
||||||
*
|
*
|
||||||
* Copyright (c) 2004-2005 Simtec Electronics
|
* Copyright (c) 2004-2005 Simtec Electronics
|
||||||
* Ben Dooks <ben@simtec.co.uk>
|
* Ben Dooks <ben@simtec.co.uk>
|
||||||
|
@ -27,8 +27,8 @@
|
||||||
#include <asm/arch/regs-gpio.h>
|
#include <asm/arch/regs-gpio.h>
|
||||||
#include <asm/arch/regs-dsc.h>
|
#include <asm/arch/regs-dsc.h>
|
||||||
|
|
||||||
#include "cpu.h"
|
#include <asm/plat-s3c24xx/cpu.h>
|
||||||
#include "s3c2440.h"
|
#include <asm/plat-s3c24xx/s3c2440.h>
|
||||||
|
|
||||||
int s3c2440_set_dsc(unsigned int pin, unsigned int value)
|
int s3c2440_set_dsc(unsigned int pin, unsigned int value)
|
||||||
{
|
{
|
|
@ -1,4 +1,4 @@
|
||||||
/* linux/arch/arm/mach-s3c2410/s3c2440-irq.c
|
/* linux/arch/arm/mach-s3c2440/irq.c
|
||||||
*
|
*
|
||||||
* Copyright (c) 2003,2004 Simtec Electronics
|
* Copyright (c) 2003,2004 Simtec Electronics
|
||||||
* Ben Dooks <ben@simtec.co.uk>
|
* Ben Dooks <ben@simtec.co.uk>
|
||||||
|
@ -35,9 +35,9 @@
|
||||||
#include <asm/arch/regs-irq.h>
|
#include <asm/arch/regs-irq.h>
|
||||||
#include <asm/arch/regs-gpio.h>
|
#include <asm/arch/regs-gpio.h>
|
||||||
|
|
||||||
#include "cpu.h"
|
#include <asm/plat-s3c24xx/cpu.h>
|
||||||
#include "pm.h"
|
#include <asm/plat-s3c24xx/pm.h>
|
||||||
#include "irq.h"
|
#include <asm/plat-s3c24xx/irq.h>
|
||||||
|
|
||||||
/* WDT/AC97 */
|
/* WDT/AC97 */
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* linux/arch/arm/mach-s3c2410/mach-anubis.c
|
/* linux/arch/arm/mach-s3c2440/mach-anubis.c
|
||||||
*
|
*
|
||||||
* Copyright (c) 2003-2005 Simtec Electronics
|
* Copyright (c) 2003-2005 Simtec Electronics
|
||||||
* http://armlinux.simtec.co.uk/
|
* http://armlinux.simtec.co.uk/
|
||||||
|
@ -42,9 +42,9 @@
|
||||||
#include <linux/mtd/nand_ecc.h>
|
#include <linux/mtd/nand_ecc.h>
|
||||||
#include <linux/mtd/partitions.h>
|
#include <linux/mtd/partitions.h>
|
||||||
|
|
||||||
#include "clock.h"
|
#include <asm/plat-s3c24xx/clock.h>
|
||||||
#include "devs.h"
|
#include <asm/plat-s3c24xx/devs.h>
|
||||||
#include "cpu.h"
|
#include <asm/plat-s3c24xx/cpu.h>
|
||||||
|
|
||||||
#define COPYRIGHT ", (c) 2005 Simtec Electronics"
|
#define COPYRIGHT ", (c) 2005 Simtec Electronics"
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* linux/arch/arm/mach-s3c2410/mach-nexcoder.c
|
/* linux/arch/arm/mach-s3c2440/mach-nexcoder.c
|
||||||
*
|
*
|
||||||
* Copyright (c) 2004 Nex Vision
|
* Copyright (c) 2004 Nex Vision
|
||||||
* Guillaume GOURAT <guillaume.gourat@nexvision.tv>
|
* Guillaume GOURAT <guillaume.gourat@nexvision.tv>
|
||||||
|
@ -38,11 +38,11 @@
|
||||||
#include <asm/arch/regs-gpio.h>
|
#include <asm/arch/regs-gpio.h>
|
||||||
#include <asm/arch/regs-serial.h>
|
#include <asm/arch/regs-serial.h>
|
||||||
|
|
||||||
#include "s3c2410.h"
|
#include <asm/plat-s3c24xx/s3c2410.h>
|
||||||
#include "s3c2440.h"
|
#include <asm/plat-s3c24xx/s3c2440.h>
|
||||||
#include "clock.h"
|
#include <asm/plat-s3c24xx/clock.h>
|
||||||
#include "devs.h"
|
#include <asm/plat-s3c24xx/devs.h>
|
||||||
#include "cpu.h"
|
#include <asm/plat-s3c24xx/cpu.h>
|
||||||
|
|
||||||
static struct map_desc nexcoder_iodesc[] __initdata = {
|
static struct map_desc nexcoder_iodesc[] __initdata = {
|
||||||
/* nothing here yet */
|
/* nothing here yet */
|
|
@ -1,4 +1,4 @@
|
||||||
/* linux/arch/arm/mach-s3c2410/mach-osiris.c
|
/* linux/arch/arm/mach-s3c2440/mach-osiris.c
|
||||||
*
|
*
|
||||||
* Copyright (c) 2005 Simtec Electronics
|
* Copyright (c) 2005 Simtec Electronics
|
||||||
* http://armlinux.simtec.co.uk/
|
* http://armlinux.simtec.co.uk/
|
||||||
|
@ -41,9 +41,9 @@
|
||||||
#include <linux/mtd/nand_ecc.h>
|
#include <linux/mtd/nand_ecc.h>
|
||||||
#include <linux/mtd/partitions.h>
|
#include <linux/mtd/partitions.h>
|
||||||
|
|
||||||
#include "clock.h"
|
#include <asm/plat-s3c24xx/clock.h>
|
||||||
#include "devs.h"
|
#include <asm/plat-s3c24xx/devs.h>
|
||||||
#include "cpu.h"
|
#include <asm/plat-s3c24xx/cpu.h>
|
||||||
|
|
||||||
/* onboard perihpheral map */
|
/* onboard perihpheral map */
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* linux/arch/arm/mach-s3c2410/mach-rx3715.c
|
/* linux/arch/arm/mach-s3c2440/mach-rx3715.c
|
||||||
*
|
*
|
||||||
* Copyright (c) 2003,2004 Simtec Electronics
|
* Copyright (c) 2003,2004 Simtec Electronics
|
||||||
* Ben Dooks <ben@simtec.co.uk>
|
* Ben Dooks <ben@simtec.co.uk>
|
||||||
|
@ -46,10 +46,10 @@
|
||||||
#include <asm/arch/nand.h>
|
#include <asm/arch/nand.h>
|
||||||
#include <asm/arch/fb.h>
|
#include <asm/arch/fb.h>
|
||||||
|
|
||||||
#include "clock.h"
|
#include <asm/plat-s3c24xx/clock.h>
|
||||||
#include "devs.h"
|
#include <asm/plat-s3c24xx/devs.h>
|
||||||
#include "cpu.h"
|
#include <asm/plat-s3c24xx/cpu.h>
|
||||||
#include "pm.h"
|
#include <asm/plat-s3c24xx/pm.h>
|
||||||
|
|
||||||
static struct map_desc rx3715_iodesc[] __initdata = {
|
static struct map_desc rx3715_iodesc[] __initdata = {
|
||||||
/* dump ISA space somewhere unused */
|
/* dump ISA space somewhere unused */
|
|
@ -1,4 +1,4 @@
|
||||||
/* linux/arch/arm/mach-s3c2410/mach-smdk2440.c
|
/* linux/arch/arm/mach-s3c2440/mach-smdk2440.c
|
||||||
*
|
*
|
||||||
* Copyright (c) 2004,2005 Simtec Electronics
|
* Copyright (c) 2004,2005 Simtec Electronics
|
||||||
* Ben Dooks <ben@simtec.co.uk>
|
* Ben Dooks <ben@simtec.co.uk>
|
||||||
|
@ -40,13 +40,13 @@
|
||||||
#include <asm/arch/idle.h>
|
#include <asm/arch/idle.h>
|
||||||
#include <asm/arch/fb.h>
|
#include <asm/arch/fb.h>
|
||||||
|
|
||||||
#include "s3c2410.h"
|
#include <asm/plat-s3c24xx/s3c2410.h>
|
||||||
#include "s3c2440.h"
|
#include <asm/plat-s3c24xx/s3c2440.h>
|
||||||
#include "clock.h"
|
#include <asm/plat-s3c24xx/clock.h>
|
||||||
#include "devs.h"
|
#include <asm/plat-s3c24xx/devs.h>
|
||||||
#include "cpu.h"
|
#include <asm/plat-s3c24xx/cpu.h>
|
||||||
|
|
||||||
#include "common-smdk.h"
|
#include <asm/plat-s3c24xx/common-smdk.h>
|
||||||
|
|
||||||
static struct map_desc smdk2440_iodesc[] __initdata = {
|
static struct map_desc smdk2440_iodesc[] __initdata = {
|
||||||
/* ISA IO Space map (memory space selected by A24) */
|
/* ISA IO Space map (memory space selected by A24) */
|
|
@ -1,4 +1,4 @@
|
||||||
/* linux/arch/arm/mach-s3c2410/s3c2440.c
|
/* linux/arch/arm/mach-s3c2440/s3c2440.c
|
||||||
*
|
*
|
||||||
* Copyright (c) 2004-2006 Simtec Electronics
|
* Copyright (c) 2004-2006 Simtec Electronics
|
||||||
* Ben Dooks <ben@simtec.co.uk>
|
* Ben Dooks <ben@simtec.co.uk>
|
||||||
|
@ -29,9 +29,9 @@
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
#include <asm/irq.h>
|
#include <asm/irq.h>
|
||||||
|
|
||||||
#include "s3c2440.h"
|
#include <asm/plat-s3c24xx/s3c2440.h>
|
||||||
#include "devs.h"
|
#include <asm/plat-s3c24xx/devs.h>
|
||||||
#include "cpu.h"
|
#include <asm/plat-s3c24xx/cpu.h>
|
||||||
|
|
||||||
static struct sys_device s3c2440_sysdev = {
|
static struct sys_device s3c2440_sysdev = {
|
||||||
.cls = &s3c2440_sysclass,
|
.cls = &s3c2440_sysclass,
|
|
@ -0,0 +1,27 @@
|
||||||
|
# arch/arm/mach-s3c2442/Kconfig
|
||||||
|
#
|
||||||
|
# Copyright 2007 Simtec Electronics
|
||||||
|
#
|
||||||
|
# Licensed under GPLv2
|
||||||
|
|
||||||
|
config CPU_S3C2442
|
||||||
|
bool
|
||||||
|
depends on ARCH_S3C2420
|
||||||
|
select S3C2410_CLOCK
|
||||||
|
select S3C2410_GPIO
|
||||||
|
select S3C2410_PM if PM
|
||||||
|
select CPU_S3C244X
|
||||||
|
help
|
||||||
|
Support for S3C2442 Samsung Mobile CPU based systems.
|
||||||
|
|
||||||
|
|
||||||
|
menu "S3C2442 Machines"
|
||||||
|
|
||||||
|
config SMDK2440_CPU2442
|
||||||
|
bool "SMDM2440 with S3C2442 CPU module"
|
||||||
|
depends on ARCH_S3C2440
|
||||||
|
select CPU_S3C2442
|
||||||
|
|
||||||
|
|
||||||
|
endmenu
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
# arch/arm/mach-s3c2442/Makefile
|
||||||
|
#
|
||||||
|
# Copyright 2007 Simtec Electronics
|
||||||
|
#
|
||||||
|
# Licensed under GPLv2
|
||||||
|
|
||||||
|
obj-y :=
|
||||||
|
obj-m :=
|
||||||
|
obj-n :=
|
||||||
|
obj- :=
|
||||||
|
|
||||||
|
obj-$(CONFIG_CPU_S3C2442) += s3c2442.o
|
||||||
|
obj-$(CONFIG_CPU_S3C2442) += clock.o
|
||||||
|
|
||||||
|
# Machine support
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* linux/arch/arm/mach-s3c2410/s3c2442-clock.c
|
/* linux/arch/arm/mach-s3c2442/clock.c
|
||||||
*
|
*
|
||||||
* Copyright (c) 2004-2005 Simtec Electronics
|
* Copyright (c) 2004-2005 Simtec Electronics
|
||||||
* http://armlinux.simtec.co.uk/
|
* http://armlinux.simtec.co.uk/
|
||||||
|
@ -41,8 +41,8 @@
|
||||||
|
|
||||||
#include <asm/arch/regs-clock.h>
|
#include <asm/arch/regs-clock.h>
|
||||||
|
|
||||||
#include "clock.h"
|
#include <asm/plat-s3c24xx/clock.h>
|
||||||
#include "cpu.h"
|
#include <asm/plat-s3c24xx/cpu.h>
|
||||||
|
|
||||||
/* S3C2442 extended clock support */
|
/* S3C2442 extended clock support */
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* linux/arch/arm/mach-s3c2410/s3c2442.c
|
/* linux/arch/arm/mach-s3c2442/s3c2442.c
|
||||||
*
|
*
|
||||||
* Copyright (c) 2006 Simtec Electronics
|
* Copyright (c) 2006 Simtec Electronics
|
||||||
* Ben Dooks <ben@simtec.co.uk>
|
* Ben Dooks <ben@simtec.co.uk>
|
||||||
|
@ -19,8 +19,8 @@
|
||||||
#include <linux/serial_core.h>
|
#include <linux/serial_core.h>
|
||||||
#include <linux/sysdev.h>
|
#include <linux/sysdev.h>
|
||||||
|
|
||||||
#include "s3c2442.h"
|
#include <asm/plat-s3c24xx/s3c2442.h>
|
||||||
#include "cpu.h"
|
#include <asm/plat-s3c24xx/cpu.h>
|
||||||
|
|
||||||
static struct sys_device s3c2442_sysdev = {
|
static struct sys_device s3c2442_sysdev = {
|
||||||
.cls = &s3c2442_sysclass,
|
.cls = &s3c2442_sysclass,
|
|
@ -0,0 +1,96 @@
|
||||||
|
# arch/arm/plat-s3c24xx/Kconfig
|
||||||
|
#
|
||||||
|
# Copyright 2007 Simtec Electronics
|
||||||
|
#
|
||||||
|
# Licensed under GPLv2
|
||||||
|
|
||||||
|
config PLAT_S3C24XX
|
||||||
|
bool
|
||||||
|
depends on ARCH_S3C2410
|
||||||
|
default y
|
||||||
|
help
|
||||||
|
Base platform code for any Samsung S3C device
|
||||||
|
|
||||||
|
config CPU_S3C244X
|
||||||
|
bool
|
||||||
|
depends on ARCH_S3C2410 && (CPU_S3C2440 || CPU_S3C2442)
|
||||||
|
help
|
||||||
|
Support for S3C2440 and S3C2442 Samsung Mobile CPU based systems.
|
||||||
|
|
||||||
|
config PM_SIMTEC
|
||||||
|
bool
|
||||||
|
help
|
||||||
|
Common power management code for systems that are
|
||||||
|
compatible with the Simtec style of power management
|
||||||
|
|
||||||
|
config S3C2410_BOOT_WATCHDOG
|
||||||
|
bool "S3C2410 Initialisation watchdog"
|
||||||
|
depends on ARCH_S3C2410 && S3C2410_WATCHDOG
|
||||||
|
help
|
||||||
|
Say y to enable the watchdog during the kernel decompression
|
||||||
|
stage. If the kernel fails to uncompress, then the watchdog
|
||||||
|
will trigger a reset and the system should restart.
|
||||||
|
|
||||||
|
config S3C2410_BOOT_ERROR_RESET
|
||||||
|
bool "S3C2410 Reboot on decompression error"
|
||||||
|
depends on ARCH_S3C2410
|
||||||
|
help
|
||||||
|
Say y here to use the watchdog to reset the system if the
|
||||||
|
kernel decompressor detects an error during decompression.
|
||||||
|
|
||||||
|
config S3C2410_PM_DEBUG
|
||||||
|
bool "S3C2410 PM Suspend debug"
|
||||||
|
depends on ARCH_S3C2410 && PM
|
||||||
|
help
|
||||||
|
Say Y here if you want verbose debugging from the PM Suspend and
|
||||||
|
Resume code. See <file:Documentation/arm/Samsung-S3C24XX/Suspend.txt>
|
||||||
|
for more information.
|
||||||
|
|
||||||
|
config S3C2410_PM_CHECK
|
||||||
|
bool "S3C2410 PM Suspend Memory CRC"
|
||||||
|
depends on ARCH_S3C2410 && PM && CRC32
|
||||||
|
help
|
||||||
|
Enable the PM code's memory area checksum over sleep. This option
|
||||||
|
will generate CRCs of all blocks of memory, and store them before
|
||||||
|
going to sleep. The blocks are then checked on resume for any
|
||||||
|
errors.
|
||||||
|
|
||||||
|
config S3C2410_PM_CHECK_CHUNKSIZE
|
||||||
|
int "S3C2410 PM Suspend CRC Chunksize (KiB)"
|
||||||
|
depends on ARCH_S3C2410 && PM && S3C2410_PM_CHECK
|
||||||
|
default 64
|
||||||
|
help
|
||||||
|
Set the chunksize in Kilobytes of the CRC for checking memory
|
||||||
|
corruption over suspend and resume. A smaller value will mean that
|
||||||
|
the CRC data block will take more memory, but wil identify any
|
||||||
|
faults with better precision.
|
||||||
|
|
||||||
|
config S3C2410_LOWLEVEL_UART_PORT
|
||||||
|
int "S3C2410 UART to use for low-level messages"
|
||||||
|
default 0
|
||||||
|
help
|
||||||
|
Choice of which UART port to use for the low-level messages,
|
||||||
|
such as the `Uncompressing...` at start time. The value of
|
||||||
|
this configuration should be between zero and two. The port
|
||||||
|
must have been initialised by the boot-loader before use.
|
||||||
|
|
||||||
|
config S3C2410_DMA
|
||||||
|
bool "S3C2410 DMA support"
|
||||||
|
depends on ARCH_S3C2410
|
||||||
|
help
|
||||||
|
S3C2410 DMA support. This is needed for drivers like sound which
|
||||||
|
use the S3C2410's DMA system to move data to and from the
|
||||||
|
peripheral blocks.
|
||||||
|
|
||||||
|
config S3C2410_DMA_DEBUG
|
||||||
|
bool "S3C2410 DMA support debug"
|
||||||
|
depends on ARCH_S3C2410 && S3C2410_DMA
|
||||||
|
help
|
||||||
|
Enable debugging output for the DMA code. This option sends info
|
||||||
|
to the kernel log, at priority KERN_DEBUG.
|
||||||
|
|
||||||
|
config MACH_SMDK
|
||||||
|
bool
|
||||||
|
help
|
||||||
|
Common machine code for SMDK2410 and SMDK2440
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
# arch/arm/plat-s3c24xx/Makefile
|
||||||
|
#
|
||||||
|
# Copyright 2007 Simtec Electronics
|
||||||
|
#
|
||||||
|
# Licensed under GPLv2
|
||||||
|
|
||||||
|
obj-y :=
|
||||||
|
obj-m :=
|
||||||
|
obj-n :=
|
||||||
|
obj- :=
|
||||||
|
|
||||||
|
|
||||||
|
# Core files
|
||||||
|
|
||||||
|
obj-y += cpu.o
|
||||||
|
obj-y += irq.o
|
||||||
|
obj-y += devs.o
|
||||||
|
obj-y += gpio.o
|
||||||
|
obj-y += time.o
|
||||||
|
obj-y += clock.o
|
||||||
|
|
||||||
|
# Architecture dependant builds
|
||||||
|
|
||||||
|
obj-$(CONFIG_CPU_S3C244X) += s3c244x.o
|
||||||
|
obj-$(CONFIG_CPU_S3C244X) += s3c244x-irq.o
|
||||||
|
obj-$(CONFIG_PM_SIMTEC) += pm-simtec.o
|
||||||
|
obj-$(CONFIG_PM) += pm.o
|
||||||
|
obj-$(CONFIG_PM) += sleep.o
|
||||||
|
obj-$(CONFIG_S3C2410_DMA) += dma.o
|
||||||
|
obj-$(CONFIG_MACH_SMDK) += common-smdk.o
|
|
@ -0,0 +1,449 @@
|
||||||
|
/* linux/arch/arm/plat-s3c24xx/clock.c
|
||||||
|
*
|
||||||
|
* Copyright (c) 2004-2005 Simtec Electronics
|
||||||
|
* Ben Dooks <ben@simtec.co.uk>
|
||||||
|
*
|
||||||
|
* S3C24XX Core clock control support
|
||||||
|
*
|
||||||
|
* Based on, and code from linux/arch/arm/mach-versatile/clock.c
|
||||||
|
**
|
||||||
|
** Copyright (C) 2004 ARM Limited.
|
||||||
|
** Written by Deep Blue Solutions Limited.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/init.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/list.h>
|
||||||
|
#include <linux/errno.h>
|
||||||
|
#include <linux/err.h>
|
||||||
|
#include <linux/platform_device.h>
|
||||||
|
#include <linux/sysdev.h>
|
||||||
|
#include <linux/interrupt.h>
|
||||||
|
#include <linux/ioport.h>
|
||||||
|
#include <linux/clk.h>
|
||||||
|
#include <linux/mutex.h>
|
||||||
|
#include <linux/delay.h>
|
||||||
|
|
||||||
|
#include <asm/hardware.h>
|
||||||
|
#include <asm/irq.h>
|
||||||
|
#include <asm/io.h>
|
||||||
|
|
||||||
|
#include <asm/arch/regs-clock.h>
|
||||||
|
#include <asm/arch/regs-gpio.h>
|
||||||
|
|
||||||
|
#include <asm/plat-s3c24xx/clock.h>
|
||||||
|
#include <asm/plat-s3c24xx/cpu.h>
|
||||||
|
|
||||||
|
/* clock information */
|
||||||
|
|
||||||
|
static LIST_HEAD(clocks);
|
||||||
|
|
||||||
|
DEFINE_MUTEX(clocks_mutex);
|
||||||
|
|
||||||
|
/* enable and disable calls for use with the clk struct */
|
||||||
|
|
||||||
|
static int clk_null_enable(struct clk *clk, int enable)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Clock API calls */
|
||||||
|
|
||||||
|
struct clk *clk_get(struct device *dev, const char *id)
|
||||||
|
{
|
||||||
|
struct clk *p;
|
||||||
|
struct clk *clk = ERR_PTR(-ENOENT);
|
||||||
|
int idno;
|
||||||
|
|
||||||
|
if (dev == NULL || dev->bus != &platform_bus_type)
|
||||||
|
idno = -1;
|
||||||
|
else
|
||||||
|
idno = to_platform_device(dev)->id;
|
||||||
|
|
||||||
|
mutex_lock(&clocks_mutex);
|
||||||
|
|
||||||
|
list_for_each_entry(p, &clocks, list) {
|
||||||
|
if (p->id == idno &&
|
||||||
|
strcmp(id, p->name) == 0 &&
|
||||||
|
try_module_get(p->owner)) {
|
||||||
|
clk = p;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check for the case where a device was supplied, but the
|
||||||
|
* clock that was being searched for is not device specific */
|
||||||
|
|
||||||
|
if (IS_ERR(clk)) {
|
||||||
|
list_for_each_entry(p, &clocks, list) {
|
||||||
|
if (p->id == -1 && strcmp(id, p->name) == 0 &&
|
||||||
|
try_module_get(p->owner)) {
|
||||||
|
clk = p;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex_unlock(&clocks_mutex);
|
||||||
|
return clk;
|
||||||
|
}
|
||||||
|
|
||||||
|
void clk_put(struct clk *clk)
|
||||||
|
{
|
||||||
|
module_put(clk->owner);
|
||||||
|
}
|
||||||
|
|
||||||
|
int clk_enable(struct clk *clk)
|
||||||
|
{
|
||||||
|
if (IS_ERR(clk) || clk == NULL)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
clk_enable(clk->parent);
|
||||||
|
|
||||||
|
mutex_lock(&clocks_mutex);
|
||||||
|
|
||||||
|
if ((clk->usage++) == 0)
|
||||||
|
(clk->enable)(clk, 1);
|
||||||
|
|
||||||
|
mutex_unlock(&clocks_mutex);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void clk_disable(struct clk *clk)
|
||||||
|
{
|
||||||
|
if (IS_ERR(clk) || clk == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
mutex_lock(&clocks_mutex);
|
||||||
|
|
||||||
|
if ((--clk->usage) == 0)
|
||||||
|
(clk->enable)(clk, 0);
|
||||||
|
|
||||||
|
mutex_unlock(&clocks_mutex);
|
||||||
|
clk_disable(clk->parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unsigned long clk_get_rate(struct clk *clk)
|
||||||
|
{
|
||||||
|
if (IS_ERR(clk))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (clk->rate != 0)
|
||||||
|
return clk->rate;
|
||||||
|
|
||||||
|
if (clk->get_rate != NULL)
|
||||||
|
return (clk->get_rate)(clk);
|
||||||
|
|
||||||
|
if (clk->parent != NULL)
|
||||||
|
return clk_get_rate(clk->parent);
|
||||||
|
|
||||||
|
return clk->rate;
|
||||||
|
}
|
||||||
|
|
||||||
|
long clk_round_rate(struct clk *clk, unsigned long rate)
|
||||||
|
{
|
||||||
|
if (!IS_ERR(clk) && clk->round_rate)
|
||||||
|
return (clk->round_rate)(clk, rate);
|
||||||
|
|
||||||
|
return rate;
|
||||||
|
}
|
||||||
|
|
||||||
|
int clk_set_rate(struct clk *clk, unsigned long rate)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (IS_ERR(clk))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
mutex_lock(&clocks_mutex);
|
||||||
|
ret = (clk->set_rate)(clk, rate);
|
||||||
|
mutex_unlock(&clocks_mutex);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct clk *clk_get_parent(struct clk *clk)
|
||||||
|
{
|
||||||
|
return clk->parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
int clk_set_parent(struct clk *clk, struct clk *parent)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if (IS_ERR(clk))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
mutex_lock(&clocks_mutex);
|
||||||
|
|
||||||
|
if (clk->set_parent)
|
||||||
|
ret = (clk->set_parent)(clk, parent);
|
||||||
|
|
||||||
|
mutex_unlock(&clocks_mutex);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPORT_SYMBOL(clk_get);
|
||||||
|
EXPORT_SYMBOL(clk_put);
|
||||||
|
EXPORT_SYMBOL(clk_enable);
|
||||||
|
EXPORT_SYMBOL(clk_disable);
|
||||||
|
EXPORT_SYMBOL(clk_get_rate);
|
||||||
|
EXPORT_SYMBOL(clk_round_rate);
|
||||||
|
EXPORT_SYMBOL(clk_set_rate);
|
||||||
|
EXPORT_SYMBOL(clk_get_parent);
|
||||||
|
EXPORT_SYMBOL(clk_set_parent);
|
||||||
|
|
||||||
|
/* base clocks */
|
||||||
|
|
||||||
|
struct clk clk_xtal = {
|
||||||
|
.name = "xtal",
|
||||||
|
.id = -1,
|
||||||
|
.rate = 0,
|
||||||
|
.parent = NULL,
|
||||||
|
.ctrlbit = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct clk clk_mpll = {
|
||||||
|
.name = "mpll",
|
||||||
|
.id = -1,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct clk clk_upll = {
|
||||||
|
.name = "upll",
|
||||||
|
.id = -1,
|
||||||
|
.parent = NULL,
|
||||||
|
.ctrlbit = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct clk clk_f = {
|
||||||
|
.name = "fclk",
|
||||||
|
.id = -1,
|
||||||
|
.rate = 0,
|
||||||
|
.parent = &clk_mpll,
|
||||||
|
.ctrlbit = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct clk clk_h = {
|
||||||
|
.name = "hclk",
|
||||||
|
.id = -1,
|
||||||
|
.rate = 0,
|
||||||
|
.parent = NULL,
|
||||||
|
.ctrlbit = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct clk clk_p = {
|
||||||
|
.name = "pclk",
|
||||||
|
.id = -1,
|
||||||
|
.rate = 0,
|
||||||
|
.parent = NULL,
|
||||||
|
.ctrlbit = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct clk clk_usb_bus = {
|
||||||
|
.name = "usb-bus",
|
||||||
|
.id = -1,
|
||||||
|
.rate = 0,
|
||||||
|
.parent = &clk_upll,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* clocks that could be registered by external code */
|
||||||
|
|
||||||
|
static int s3c24xx_dclk_enable(struct clk *clk, int enable)
|
||||||
|
{
|
||||||
|
unsigned long dclkcon = __raw_readl(S3C24XX_DCLKCON);
|
||||||
|
|
||||||
|
if (enable)
|
||||||
|
dclkcon |= clk->ctrlbit;
|
||||||
|
else
|
||||||
|
dclkcon &= ~clk->ctrlbit;
|
||||||
|
|
||||||
|
__raw_writel(dclkcon, S3C24XX_DCLKCON);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int s3c24xx_dclk_setparent(struct clk *clk, struct clk *parent)
|
||||||
|
{
|
||||||
|
unsigned long dclkcon;
|
||||||
|
unsigned int uclk;
|
||||||
|
|
||||||
|
if (parent == &clk_upll)
|
||||||
|
uclk = 1;
|
||||||
|
else if (parent == &clk_p)
|
||||||
|
uclk = 0;
|
||||||
|
else
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
clk->parent = parent;
|
||||||
|
|
||||||
|
dclkcon = __raw_readl(S3C24XX_DCLKCON);
|
||||||
|
|
||||||
|
if (clk->ctrlbit == S3C2410_DCLKCON_DCLK0EN) {
|
||||||
|
if (uclk)
|
||||||
|
dclkcon |= S3C2410_DCLKCON_DCLK0_UCLK;
|
||||||
|
else
|
||||||
|
dclkcon &= ~S3C2410_DCLKCON_DCLK0_UCLK;
|
||||||
|
} else {
|
||||||
|
if (uclk)
|
||||||
|
dclkcon |= S3C2410_DCLKCON_DCLK1_UCLK;
|
||||||
|
else
|
||||||
|
dclkcon &= ~S3C2410_DCLKCON_DCLK1_UCLK;
|
||||||
|
}
|
||||||
|
|
||||||
|
__raw_writel(dclkcon, S3C24XX_DCLKCON);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int s3c24xx_clkout_setparent(struct clk *clk, struct clk *parent)
|
||||||
|
{
|
||||||
|
unsigned long mask;
|
||||||
|
unsigned long source;
|
||||||
|
|
||||||
|
/* calculate the MISCCR setting for the clock */
|
||||||
|
|
||||||
|
if (parent == &clk_xtal)
|
||||||
|
source = S3C2410_MISCCR_CLK0_MPLL;
|
||||||
|
else if (parent == &clk_upll)
|
||||||
|
source = S3C2410_MISCCR_CLK0_UPLL;
|
||||||
|
else if (parent == &clk_f)
|
||||||
|
source = S3C2410_MISCCR_CLK0_FCLK;
|
||||||
|
else if (parent == &clk_h)
|
||||||
|
source = S3C2410_MISCCR_CLK0_HCLK;
|
||||||
|
else if (parent == &clk_p)
|
||||||
|
source = S3C2410_MISCCR_CLK0_PCLK;
|
||||||
|
else if (clk == &s3c24xx_clkout0 && parent == &s3c24xx_dclk0)
|
||||||
|
source = S3C2410_MISCCR_CLK0_DCLK0;
|
||||||
|
else if (clk == &s3c24xx_clkout1 && parent == &s3c24xx_dclk1)
|
||||||
|
source = S3C2410_MISCCR_CLK0_DCLK0;
|
||||||
|
else
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
clk->parent = parent;
|
||||||
|
|
||||||
|
if (clk == &s3c24xx_dclk0)
|
||||||
|
mask = S3C2410_MISCCR_CLK0_MASK;
|
||||||
|
else {
|
||||||
|
source <<= 4;
|
||||||
|
mask = S3C2410_MISCCR_CLK1_MASK;
|
||||||
|
}
|
||||||
|
|
||||||
|
s3c2410_modify_misccr(mask, source);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* external clock definitions */
|
||||||
|
|
||||||
|
struct clk s3c24xx_dclk0 = {
|
||||||
|
.name = "dclk0",
|
||||||
|
.id = -1,
|
||||||
|
.ctrlbit = S3C2410_DCLKCON_DCLK0EN,
|
||||||
|
.enable = s3c24xx_dclk_enable,
|
||||||
|
.set_parent = s3c24xx_dclk_setparent,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct clk s3c24xx_dclk1 = {
|
||||||
|
.name = "dclk1",
|
||||||
|
.id = -1,
|
||||||
|
.ctrlbit = S3C2410_DCLKCON_DCLK0EN,
|
||||||
|
.enable = s3c24xx_dclk_enable,
|
||||||
|
.set_parent = s3c24xx_dclk_setparent,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct clk s3c24xx_clkout0 = {
|
||||||
|
.name = "clkout0",
|
||||||
|
.id = -1,
|
||||||
|
.set_parent = s3c24xx_clkout_setparent,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct clk s3c24xx_clkout1 = {
|
||||||
|
.name = "clkout1",
|
||||||
|
.id = -1,
|
||||||
|
.set_parent = s3c24xx_clkout_setparent,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct clk s3c24xx_uclk = {
|
||||||
|
.name = "uclk",
|
||||||
|
.id = -1,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* initialise the clock system */
|
||||||
|
|
||||||
|
int s3c24xx_register_clock(struct clk *clk)
|
||||||
|
{
|
||||||
|
clk->owner = THIS_MODULE;
|
||||||
|
|
||||||
|
if (clk->enable == NULL)
|
||||||
|
clk->enable = clk_null_enable;
|
||||||
|
|
||||||
|
/* add to the list of available clocks */
|
||||||
|
|
||||||
|
mutex_lock(&clocks_mutex);
|
||||||
|
list_add(&clk->list, &clocks);
|
||||||
|
mutex_unlock(&clocks_mutex);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* initalise all the clocks */
|
||||||
|
|
||||||
|
int __init s3c24xx_setup_clocks(unsigned long xtal,
|
||||||
|
unsigned long fclk,
|
||||||
|
unsigned long hclk,
|
||||||
|
unsigned long pclk)
|
||||||
|
{
|
||||||
|
printk(KERN_INFO "S3C24XX Clocks, (c) 2004 Simtec Electronics\n");
|
||||||
|
|
||||||
|
/* initialise the main system clocks */
|
||||||
|
|
||||||
|
clk_xtal.rate = xtal;
|
||||||
|
clk_upll.rate = s3c2410_get_pll(__raw_readl(S3C2410_UPLLCON), xtal);
|
||||||
|
|
||||||
|
clk_mpll.rate = fclk;
|
||||||
|
clk_h.rate = hclk;
|
||||||
|
clk_p.rate = pclk;
|
||||||
|
clk_f.rate = fclk;
|
||||||
|
|
||||||
|
/* assume uart clocks are correctly setup */
|
||||||
|
|
||||||
|
/* register our clocks */
|
||||||
|
|
||||||
|
if (s3c24xx_register_clock(&clk_xtal) < 0)
|
||||||
|
printk(KERN_ERR "failed to register master xtal\n");
|
||||||
|
|
||||||
|
if (s3c24xx_register_clock(&clk_mpll) < 0)
|
||||||
|
printk(KERN_ERR "failed to register mpll clock\n");
|
||||||
|
|
||||||
|
if (s3c24xx_register_clock(&clk_upll) < 0)
|
||||||
|
printk(KERN_ERR "failed to register upll clock\n");
|
||||||
|
|
||||||
|
if (s3c24xx_register_clock(&clk_f) < 0)
|
||||||
|
printk(KERN_ERR "failed to register cpu fclk\n");
|
||||||
|
|
||||||
|
if (s3c24xx_register_clock(&clk_h) < 0)
|
||||||
|
printk(KERN_ERR "failed to register cpu hclk\n");
|
||||||
|
|
||||||
|
if (s3c24xx_register_clock(&clk_p) < 0)
|
||||||
|
printk(KERN_ERR "failed to register cpu pclk\n");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
/* linux/arch/arm/mach-s3c2410/common-smdk.c
|
/* linux/arch/arm/plat-s3c24xx/common-smdk.c
|
||||||
*
|
*
|
||||||
* Copyright (c) 2006 Simtec Electronics
|
* Copyright (c) 2006 Simtec Electronics
|
||||||
* Ben Dooks <ben@simtec.co.uk>
|
* Ben Dooks <ben@simtec.co.uk>
|
||||||
|
@ -38,9 +38,9 @@
|
||||||
|
|
||||||
#include <asm/arch/nand.h>
|
#include <asm/arch/nand.h>
|
||||||
|
|
||||||
#include "common-smdk.h"
|
#include <asm/plat-s3c24xx/common-smdk.h>
|
||||||
#include "devs.h"
|
#include <asm/plat-s3c24xx/devs.h>
|
||||||
#include "pm.h"
|
#include <asm/plat-s3c24xx/pm.h>
|
||||||
|
|
||||||
/* LED devices */
|
/* LED devices */
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* linux/arch/arm/mach-s3c2410/cpu.c
|
/* linux/arch/arm/plat-s3c24xx/cpu.c
|
||||||
*
|
*
|
||||||
* Copyright (c) 2004-2005 Simtec Electronics
|
* Copyright (c) 2004-2005 Simtec Electronics
|
||||||
* http://www.simtec.co.uk/products/SWLINUX/
|
* http://www.simtec.co.uk/products/SWLINUX/
|
||||||
|
@ -40,15 +40,15 @@
|
||||||
#include <asm/arch/regs-gpio.h>
|
#include <asm/arch/regs-gpio.h>
|
||||||
#include <asm/arch/regs-serial.h>
|
#include <asm/arch/regs-serial.h>
|
||||||
|
|
||||||
#include "cpu.h"
|
#include <asm/plat-s3c24xx/cpu.h>
|
||||||
#include "devs.h"
|
#include <asm/plat-s3c24xx/devs.h>
|
||||||
#include "clock.h"
|
#include <asm/plat-s3c24xx/clock.h>
|
||||||
#include "s3c2400.h"
|
#include <asm/plat-s3c24xx/s3c2400.h>
|
||||||
#include "s3c2410.h"
|
#include <asm/plat-s3c24xx/s3c2410.h>
|
||||||
#include "s3c2412.h"
|
#include <asm/plat-s3c24xx/s3c2412.h>
|
||||||
#include "s3c244x.h"
|
#include "s3c244x.h"
|
||||||
#include "s3c2440.h"
|
#include <asm/plat-s3c24xx/s3c2440.h>
|
||||||
#include "s3c2442.h"
|
#include <asm/plat-s3c24xx/s3c2442.h>
|
||||||
|
|
||||||
struct cpu_table {
|
struct cpu_table {
|
||||||
unsigned long idcode;
|
unsigned long idcode;
|
|
@ -1,4 +1,4 @@
|
||||||
/* linux/arch/arm/mach-s3c2410/devs.c
|
/* linux/arch/arm/plat-s3c24xx/devs.c
|
||||||
*
|
*
|
||||||
* Copyright (c) 2004 Simtec Electronics
|
* Copyright (c) 2004 Simtec Electronics
|
||||||
* Ben Dooks <ben@simtec.co.uk>
|
* Ben Dooks <ben@simtec.co.uk>
|
||||||
|
@ -30,8 +30,8 @@
|
||||||
|
|
||||||
#include <asm/arch/regs-serial.h>
|
#include <asm/arch/regs-serial.h>
|
||||||
|
|
||||||
#include "devs.h"
|
#include <asm/plat-s3c24xx/devs.h>
|
||||||
#include "cpu.h"
|
#include <asm/plat-s3c24xx/cpu.h>
|
||||||
|
|
||||||
/* Serial port registrations */
|
/* Serial port registrations */
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,188 @@
|
||||||
|
/* linux/arch/arm/plat-s3c24xx/gpio.c
|
||||||
|
*
|
||||||
|
* Copyright (c) 2004-2005 Simtec Electronics
|
||||||
|
* Ben Dooks <ben@simtec.co.uk>
|
||||||
|
*
|
||||||
|
* S3C24XX GPIO support
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/init.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/interrupt.h>
|
||||||
|
#include <linux/ioport.h>
|
||||||
|
|
||||||
|
#include <asm/hardware.h>
|
||||||
|
#include <asm/irq.h>
|
||||||
|
#include <asm/io.h>
|
||||||
|
|
||||||
|
#include <asm/arch/regs-gpio.h>
|
||||||
|
|
||||||
|
void s3c2410_gpio_cfgpin(unsigned int pin, unsigned int function)
|
||||||
|
{
|
||||||
|
void __iomem *base = S3C24XX_GPIO_BASE(pin);
|
||||||
|
unsigned long mask;
|
||||||
|
unsigned long con;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
if (pin < S3C2410_GPIO_BANKB) {
|
||||||
|
mask = 1 << S3C2410_GPIO_OFFSET(pin);
|
||||||
|
} else {
|
||||||
|
mask = 3 << S3C2410_GPIO_OFFSET(pin)*2;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (function) {
|
||||||
|
case S3C2410_GPIO_LEAVE:
|
||||||
|
mask = 0;
|
||||||
|
function = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case S3C2410_GPIO_INPUT:
|
||||||
|
case S3C2410_GPIO_OUTPUT:
|
||||||
|
case S3C2410_GPIO_SFN2:
|
||||||
|
case S3C2410_GPIO_SFN3:
|
||||||
|
if (pin < S3C2410_GPIO_BANKB) {
|
||||||
|
function -= 1;
|
||||||
|
function &= 1;
|
||||||
|
function <<= S3C2410_GPIO_OFFSET(pin);
|
||||||
|
} else {
|
||||||
|
function &= 3;
|
||||||
|
function <<= S3C2410_GPIO_OFFSET(pin)*2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* modify the specified register wwith IRQs off */
|
||||||
|
|
||||||
|
local_irq_save(flags);
|
||||||
|
|
||||||
|
con = __raw_readl(base + 0x00);
|
||||||
|
con &= ~mask;
|
||||||
|
con |= function;
|
||||||
|
|
||||||
|
__raw_writel(con, base + 0x00);
|
||||||
|
|
||||||
|
local_irq_restore(flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPORT_SYMBOL(s3c2410_gpio_cfgpin);
|
||||||
|
|
||||||
|
unsigned int s3c2410_gpio_getcfg(unsigned int pin)
|
||||||
|
{
|
||||||
|
void __iomem *base = S3C24XX_GPIO_BASE(pin);
|
||||||
|
unsigned long val = __raw_readl(base);
|
||||||
|
|
||||||
|
if (pin < S3C2410_GPIO_BANKB) {
|
||||||
|
val >>= S3C2410_GPIO_OFFSET(pin);
|
||||||
|
val &= 1;
|
||||||
|
val += 1;
|
||||||
|
} else {
|
||||||
|
val >>= S3C2410_GPIO_OFFSET(pin)*2;
|
||||||
|
val &= 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
return val | S3C2410_GPIO_INPUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPORT_SYMBOL(s3c2410_gpio_getcfg);
|
||||||
|
|
||||||
|
void s3c2410_gpio_pullup(unsigned int pin, unsigned int to)
|
||||||
|
{
|
||||||
|
void __iomem *base = S3C24XX_GPIO_BASE(pin);
|
||||||
|
unsigned long offs = S3C2410_GPIO_OFFSET(pin);
|
||||||
|
unsigned long flags;
|
||||||
|
unsigned long up;
|
||||||
|
|
||||||
|
if (pin < S3C2410_GPIO_BANKB)
|
||||||
|
return;
|
||||||
|
|
||||||
|
local_irq_save(flags);
|
||||||
|
|
||||||
|
up = __raw_readl(base + 0x08);
|
||||||
|
up &= ~(1L << offs);
|
||||||
|
up |= to << offs;
|
||||||
|
__raw_writel(up, base + 0x08);
|
||||||
|
|
||||||
|
local_irq_restore(flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPORT_SYMBOL(s3c2410_gpio_pullup);
|
||||||
|
|
||||||
|
void s3c2410_gpio_setpin(unsigned int pin, unsigned int to)
|
||||||
|
{
|
||||||
|
void __iomem *base = S3C24XX_GPIO_BASE(pin);
|
||||||
|
unsigned long offs = S3C2410_GPIO_OFFSET(pin);
|
||||||
|
unsigned long flags;
|
||||||
|
unsigned long dat;
|
||||||
|
|
||||||
|
local_irq_save(flags);
|
||||||
|
|
||||||
|
dat = __raw_readl(base + 0x04);
|
||||||
|
dat &= ~(1 << offs);
|
||||||
|
dat |= to << offs;
|
||||||
|
__raw_writel(dat, base + 0x04);
|
||||||
|
|
||||||
|
local_irq_restore(flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPORT_SYMBOL(s3c2410_gpio_setpin);
|
||||||
|
|
||||||
|
unsigned int s3c2410_gpio_getpin(unsigned int pin)
|
||||||
|
{
|
||||||
|
void __iomem *base = S3C24XX_GPIO_BASE(pin);
|
||||||
|
unsigned long offs = S3C2410_GPIO_OFFSET(pin);
|
||||||
|
|
||||||
|
return __raw_readl(base + 0x04) & (1<< offs);
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPORT_SYMBOL(s3c2410_gpio_getpin);
|
||||||
|
|
||||||
|
unsigned int s3c2410_modify_misccr(unsigned int clear, unsigned int change)
|
||||||
|
{
|
||||||
|
unsigned long flags;
|
||||||
|
unsigned long misccr;
|
||||||
|
|
||||||
|
local_irq_save(flags);
|
||||||
|
misccr = __raw_readl(S3C24XX_MISCCR);
|
||||||
|
misccr &= ~clear;
|
||||||
|
misccr ^= change;
|
||||||
|
__raw_writel(misccr, S3C24XX_MISCCR);
|
||||||
|
local_irq_restore(flags);
|
||||||
|
|
||||||
|
return misccr;
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPORT_SYMBOL(s3c2410_modify_misccr);
|
||||||
|
|
||||||
|
int s3c2410_gpio_getirq(unsigned int pin)
|
||||||
|
{
|
||||||
|
if (pin < S3C2410_GPF0 || pin > S3C2410_GPG15)
|
||||||
|
return -1; /* not valid interrupts */
|
||||||
|
|
||||||
|
if (pin < S3C2410_GPG0 && pin > S3C2410_GPF7)
|
||||||
|
return -1; /* not valid pin */
|
||||||
|
|
||||||
|
if (pin < S3C2410_GPF4)
|
||||||
|
return (pin - S3C2410_GPF0) + IRQ_EINT0;
|
||||||
|
|
||||||
|
if (pin < S3C2410_GPG0)
|
||||||
|
return (pin - S3C2410_GPF4) + IRQ_EINT4;
|
||||||
|
|
||||||
|
return (pin - S3C2410_GPG0) + IRQ_EINT8;
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPORT_SYMBOL(s3c2410_gpio_getirq);
|
|
@ -0,0 +1,801 @@
|
||||||
|
/* linux/arch/arm/plat-s3c24xx/irq.c
|
||||||
|
*
|
||||||
|
* Copyright (c) 2003,2004 Simtec Electronics
|
||||||
|
* Ben Dooks <ben@simtec.co.uk>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
* Changelog:
|
||||||
|
*
|
||||||
|
* 22-Jul-2004 Ben Dooks <ben@simtec.co.uk>
|
||||||
|
* Fixed compile warnings
|
||||||
|
*
|
||||||
|
* 22-Jul-2004 Roc Wu <cooloney@yahoo.com.cn>
|
||||||
|
* Fixed s3c_extirq_type
|
||||||
|
*
|
||||||
|
* 21-Jul-2004 Arnaud Patard (Rtp) <arnaud.patard@rtp-net.org>
|
||||||
|
* Addition of ADC/TC demux
|
||||||
|
*
|
||||||
|
* 04-Oct-2004 Klaus Fetscher <k.fetscher@fetron.de>
|
||||||
|
* Fix for set_irq_type() on low EINT numbers
|
||||||
|
*
|
||||||
|
* 05-Oct-2004 Ben Dooks <ben@simtec.co.uk>
|
||||||
|
* Tidy up KF's patch and sort out new release
|
||||||
|
*
|
||||||
|
* 05-Oct-2004 Ben Dooks <ben@simtec.co.uk>
|
||||||
|
* Add support for power management controls
|
||||||
|
*
|
||||||
|
* 04-Nov-2004 Ben Dooks
|
||||||
|
* Fix standard IRQ wake for EINT0..4 and RTC
|
||||||
|
*
|
||||||
|
* 22-Feb-2005 Ben Dooks
|
||||||
|
* Fixed edge-triggering on ADC IRQ
|
||||||
|
*
|
||||||
|
* 28-Jun-2005 Ben Dooks
|
||||||
|
* Mark IRQ_LCD valid
|
||||||
|
*
|
||||||
|
* 25-Jul-2005 Ben Dooks
|
||||||
|
* Split the S3C2440 IRQ code to seperate file
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/init.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/interrupt.h>
|
||||||
|
#include <linux/ioport.h>
|
||||||
|
#include <linux/ptrace.h>
|
||||||
|
#include <linux/sysdev.h>
|
||||||
|
|
||||||
|
#include <asm/hardware.h>
|
||||||
|
#include <asm/irq.h>
|
||||||
|
#include <asm/io.h>
|
||||||
|
|
||||||
|
#include <asm/mach/irq.h>
|
||||||
|
|
||||||
|
#include <asm/arch/regs-irq.h>
|
||||||
|
#include <asm/arch/regs-gpio.h>
|
||||||
|
|
||||||
|
#include <asm/plat-s3c24xx/cpu.h>
|
||||||
|
#include <asm/plat-s3c24xx/pm.h>
|
||||||
|
#include <asm/plat-s3c24xx/irq.h>
|
||||||
|
|
||||||
|
/* wakeup irq control */
|
||||||
|
|
||||||
|
#ifdef CONFIG_PM
|
||||||
|
|
||||||
|
/* state for IRQs over sleep */
|
||||||
|
|
||||||
|
/* default is to allow for EINT0..EINT15, and IRQ_RTC as wakeup sources
|
||||||
|
*
|
||||||
|
* set bit to 1 in allow bitfield to enable the wakeup settings on it
|
||||||
|
*/
|
||||||
|
|
||||||
|
unsigned long s3c_irqwake_intallow = 1L << (IRQ_RTC - IRQ_EINT0) | 0xfL;
|
||||||
|
unsigned long s3c_irqwake_intmask = 0xffffffffL;
|
||||||
|
unsigned long s3c_irqwake_eintallow = 0x0000fff0L;
|
||||||
|
unsigned long s3c_irqwake_eintmask = 0xffffffffL;
|
||||||
|
|
||||||
|
int
|
||||||
|
s3c_irq_wake(unsigned int irqno, unsigned int state)
|
||||||
|
{
|
||||||
|
unsigned long irqbit = 1 << (irqno - IRQ_EINT0);
|
||||||
|
|
||||||
|
if (!(s3c_irqwake_intallow & irqbit))
|
||||||
|
return -ENOENT;
|
||||||
|
|
||||||
|
printk(KERN_INFO "wake %s for irq %d\n",
|
||||||
|
state ? "enabled" : "disabled", irqno);
|
||||||
|
|
||||||
|
if (!state)
|
||||||
|
s3c_irqwake_intmask |= irqbit;
|
||||||
|
else
|
||||||
|
s3c_irqwake_intmask &= ~irqbit;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
s3c_irqext_wake(unsigned int irqno, unsigned int state)
|
||||||
|
{
|
||||||
|
unsigned long bit = 1L << (irqno - EXTINT_OFF);
|
||||||
|
|
||||||
|
if (!(s3c_irqwake_eintallow & bit))
|
||||||
|
return -ENOENT;
|
||||||
|
|
||||||
|
printk(KERN_INFO "wake %s for irq %d\n",
|
||||||
|
state ? "enabled" : "disabled", irqno);
|
||||||
|
|
||||||
|
if (!state)
|
||||||
|
s3c_irqwake_eintmask |= bit;
|
||||||
|
else
|
||||||
|
s3c_irqwake_eintmask &= ~bit;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
#define s3c_irqext_wake NULL
|
||||||
|
#define s3c_irq_wake NULL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
s3c_irq_mask(unsigned int irqno)
|
||||||
|
{
|
||||||
|
unsigned long mask;
|
||||||
|
|
||||||
|
irqno -= IRQ_EINT0;
|
||||||
|
|
||||||
|
mask = __raw_readl(S3C2410_INTMSK);
|
||||||
|
mask |= 1UL << irqno;
|
||||||
|
__raw_writel(mask, S3C2410_INTMSK);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
s3c_irq_ack(unsigned int irqno)
|
||||||
|
{
|
||||||
|
unsigned long bitval = 1UL << (irqno - IRQ_EINT0);
|
||||||
|
|
||||||
|
__raw_writel(bitval, S3C2410_SRCPND);
|
||||||
|
__raw_writel(bitval, S3C2410_INTPND);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
s3c_irq_maskack(unsigned int irqno)
|
||||||
|
{
|
||||||
|
unsigned long bitval = 1UL << (irqno - IRQ_EINT0);
|
||||||
|
unsigned long mask;
|
||||||
|
|
||||||
|
mask = __raw_readl(S3C2410_INTMSK);
|
||||||
|
__raw_writel(mask|bitval, S3C2410_INTMSK);
|
||||||
|
|
||||||
|
__raw_writel(bitval, S3C2410_SRCPND);
|
||||||
|
__raw_writel(bitval, S3C2410_INTPND);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
s3c_irq_unmask(unsigned int irqno)
|
||||||
|
{
|
||||||
|
unsigned long mask;
|
||||||
|
|
||||||
|
if (irqno != IRQ_TIMER4 && irqno != IRQ_EINT8t23)
|
||||||
|
irqdbf2("s3c_irq_unmask %d\n", irqno);
|
||||||
|
|
||||||
|
irqno -= IRQ_EINT0;
|
||||||
|
|
||||||
|
mask = __raw_readl(S3C2410_INTMSK);
|
||||||
|
mask &= ~(1UL << irqno);
|
||||||
|
__raw_writel(mask, S3C2410_INTMSK);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct irq_chip s3c_irq_level_chip = {
|
||||||
|
.name = "s3c-level",
|
||||||
|
.ack = s3c_irq_maskack,
|
||||||
|
.mask = s3c_irq_mask,
|
||||||
|
.unmask = s3c_irq_unmask,
|
||||||
|
.set_wake = s3c_irq_wake
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct irq_chip s3c_irq_chip = {
|
||||||
|
.name = "s3c",
|
||||||
|
.ack = s3c_irq_ack,
|
||||||
|
.mask = s3c_irq_mask,
|
||||||
|
.unmask = s3c_irq_unmask,
|
||||||
|
.set_wake = s3c_irq_wake
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
s3c_irqext_mask(unsigned int irqno)
|
||||||
|
{
|
||||||
|
unsigned long mask;
|
||||||
|
|
||||||
|
irqno -= EXTINT_OFF;
|
||||||
|
|
||||||
|
mask = __raw_readl(S3C24XX_EINTMASK);
|
||||||
|
mask |= ( 1UL << irqno);
|
||||||
|
__raw_writel(mask, S3C24XX_EINTMASK);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
s3c_irqext_ack(unsigned int irqno)
|
||||||
|
{
|
||||||
|
unsigned long req;
|
||||||
|
unsigned long bit;
|
||||||
|
unsigned long mask;
|
||||||
|
|
||||||
|
bit = 1UL << (irqno - EXTINT_OFF);
|
||||||
|
|
||||||
|
mask = __raw_readl(S3C24XX_EINTMASK);
|
||||||
|
|
||||||
|
__raw_writel(bit, S3C24XX_EINTPEND);
|
||||||
|
|
||||||
|
req = __raw_readl(S3C24XX_EINTPEND);
|
||||||
|
req &= ~mask;
|
||||||
|
|
||||||
|
/* not sure if we should be acking the parent irq... */
|
||||||
|
|
||||||
|
if (irqno <= IRQ_EINT7 ) {
|
||||||
|
if ((req & 0xf0) == 0)
|
||||||
|
s3c_irq_ack(IRQ_EINT4t7);
|
||||||
|
} else {
|
||||||
|
if ((req >> 8) == 0)
|
||||||
|
s3c_irq_ack(IRQ_EINT8t23);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
s3c_irqext_unmask(unsigned int irqno)
|
||||||
|
{
|
||||||
|
unsigned long mask;
|
||||||
|
|
||||||
|
irqno -= EXTINT_OFF;
|
||||||
|
|
||||||
|
mask = __raw_readl(S3C24XX_EINTMASK);
|
||||||
|
mask &= ~( 1UL << irqno);
|
||||||
|
__raw_writel(mask, S3C24XX_EINTMASK);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
s3c_irqext_type(unsigned int irq, unsigned int type)
|
||||||
|
{
|
||||||
|
void __iomem *extint_reg;
|
||||||
|
void __iomem *gpcon_reg;
|
||||||
|
unsigned long gpcon_offset, extint_offset;
|
||||||
|
unsigned long newvalue = 0, value;
|
||||||
|
|
||||||
|
if ((irq >= IRQ_EINT0) && (irq <= IRQ_EINT3))
|
||||||
|
{
|
||||||
|
gpcon_reg = S3C2410_GPFCON;
|
||||||
|
extint_reg = S3C24XX_EXTINT0;
|
||||||
|
gpcon_offset = (irq - IRQ_EINT0) * 2;
|
||||||
|
extint_offset = (irq - IRQ_EINT0) * 4;
|
||||||
|
}
|
||||||
|
else if ((irq >= IRQ_EINT4) && (irq <= IRQ_EINT7))
|
||||||
|
{
|
||||||
|
gpcon_reg = S3C2410_GPFCON;
|
||||||
|
extint_reg = S3C24XX_EXTINT0;
|
||||||
|
gpcon_offset = (irq - (EXTINT_OFF)) * 2;
|
||||||
|
extint_offset = (irq - (EXTINT_OFF)) * 4;
|
||||||
|
}
|
||||||
|
else if ((irq >= IRQ_EINT8) && (irq <= IRQ_EINT15))
|
||||||
|
{
|
||||||
|
gpcon_reg = S3C2410_GPGCON;
|
||||||
|
extint_reg = S3C24XX_EXTINT1;
|
||||||
|
gpcon_offset = (irq - IRQ_EINT8) * 2;
|
||||||
|
extint_offset = (irq - IRQ_EINT8) * 4;
|
||||||
|
}
|
||||||
|
else if ((irq >= IRQ_EINT16) && (irq <= IRQ_EINT23))
|
||||||
|
{
|
||||||
|
gpcon_reg = S3C2410_GPGCON;
|
||||||
|
extint_reg = S3C24XX_EXTINT2;
|
||||||
|
gpcon_offset = (irq - IRQ_EINT8) * 2;
|
||||||
|
extint_offset = (irq - IRQ_EINT16) * 4;
|
||||||
|
} else
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* Set the GPIO to external interrupt mode */
|
||||||
|
value = __raw_readl(gpcon_reg);
|
||||||
|
value = (value & ~(3 << gpcon_offset)) | (0x02 << gpcon_offset);
|
||||||
|
__raw_writel(value, gpcon_reg);
|
||||||
|
|
||||||
|
/* Set the external interrupt to pointed trigger type */
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case IRQT_NOEDGE:
|
||||||
|
printk(KERN_WARNING "No edge setting!\n");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IRQT_RISING:
|
||||||
|
newvalue = S3C2410_EXTINT_RISEEDGE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IRQT_FALLING:
|
||||||
|
newvalue = S3C2410_EXTINT_FALLEDGE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IRQT_BOTHEDGE:
|
||||||
|
newvalue = S3C2410_EXTINT_BOTHEDGE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IRQT_LOW:
|
||||||
|
newvalue = S3C2410_EXTINT_LOWLEV;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IRQT_HIGH:
|
||||||
|
newvalue = S3C2410_EXTINT_HILEV;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
printk(KERN_ERR "No such irq type %d", type);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
value = __raw_readl(extint_reg);
|
||||||
|
value = (value & ~(7 << extint_offset)) | (newvalue << extint_offset);
|
||||||
|
__raw_writel(value, extint_reg);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct irq_chip s3c_irqext_chip = {
|
||||||
|
.name = "s3c-ext",
|
||||||
|
.mask = s3c_irqext_mask,
|
||||||
|
.unmask = s3c_irqext_unmask,
|
||||||
|
.ack = s3c_irqext_ack,
|
||||||
|
.set_type = s3c_irqext_type,
|
||||||
|
.set_wake = s3c_irqext_wake
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct irq_chip s3c_irq_eint0t4 = {
|
||||||
|
.name = "s3c-ext0",
|
||||||
|
.ack = s3c_irq_ack,
|
||||||
|
.mask = s3c_irq_mask,
|
||||||
|
.unmask = s3c_irq_unmask,
|
||||||
|
.set_wake = s3c_irq_wake,
|
||||||
|
.set_type = s3c_irqext_type,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* mask values for the parent registers for each of the interrupt types */
|
||||||
|
|
||||||
|
#define INTMSK_UART0 (1UL << (IRQ_UART0 - IRQ_EINT0))
|
||||||
|
#define INTMSK_UART1 (1UL << (IRQ_UART1 - IRQ_EINT0))
|
||||||
|
#define INTMSK_UART2 (1UL << (IRQ_UART2 - IRQ_EINT0))
|
||||||
|
#define INTMSK_ADCPARENT (1UL << (IRQ_ADCPARENT - IRQ_EINT0))
|
||||||
|
|
||||||
|
|
||||||
|
/* UART0 */
|
||||||
|
|
||||||
|
static void
|
||||||
|
s3c_irq_uart0_mask(unsigned int irqno)
|
||||||
|
{
|
||||||
|
s3c_irqsub_mask(irqno, INTMSK_UART0, 7);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
s3c_irq_uart0_unmask(unsigned int irqno)
|
||||||
|
{
|
||||||
|
s3c_irqsub_unmask(irqno, INTMSK_UART0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
s3c_irq_uart0_ack(unsigned int irqno)
|
||||||
|
{
|
||||||
|
s3c_irqsub_maskack(irqno, INTMSK_UART0, 7);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct irq_chip s3c_irq_uart0 = {
|
||||||
|
.name = "s3c-uart0",
|
||||||
|
.mask = s3c_irq_uart0_mask,
|
||||||
|
.unmask = s3c_irq_uart0_unmask,
|
||||||
|
.ack = s3c_irq_uart0_ack,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* UART1 */
|
||||||
|
|
||||||
|
static void
|
||||||
|
s3c_irq_uart1_mask(unsigned int irqno)
|
||||||
|
{
|
||||||
|
s3c_irqsub_mask(irqno, INTMSK_UART1, 7 << 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
s3c_irq_uart1_unmask(unsigned int irqno)
|
||||||
|
{
|
||||||
|
s3c_irqsub_unmask(irqno, INTMSK_UART1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
s3c_irq_uart1_ack(unsigned int irqno)
|
||||||
|
{
|
||||||
|
s3c_irqsub_maskack(irqno, INTMSK_UART1, 7 << 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct irq_chip s3c_irq_uart1 = {
|
||||||
|
.name = "s3c-uart1",
|
||||||
|
.mask = s3c_irq_uart1_mask,
|
||||||
|
.unmask = s3c_irq_uart1_unmask,
|
||||||
|
.ack = s3c_irq_uart1_ack,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* UART2 */
|
||||||
|
|
||||||
|
static void
|
||||||
|
s3c_irq_uart2_mask(unsigned int irqno)
|
||||||
|
{
|
||||||
|
s3c_irqsub_mask(irqno, INTMSK_UART2, 7 << 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
s3c_irq_uart2_unmask(unsigned int irqno)
|
||||||
|
{
|
||||||
|
s3c_irqsub_unmask(irqno, INTMSK_UART2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
s3c_irq_uart2_ack(unsigned int irqno)
|
||||||
|
{
|
||||||
|
s3c_irqsub_maskack(irqno, INTMSK_UART2, 7 << 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct irq_chip s3c_irq_uart2 = {
|
||||||
|
.name = "s3c-uart2",
|
||||||
|
.mask = s3c_irq_uart2_mask,
|
||||||
|
.unmask = s3c_irq_uart2_unmask,
|
||||||
|
.ack = s3c_irq_uart2_ack,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* ADC and Touchscreen */
|
||||||
|
|
||||||
|
static void
|
||||||
|
s3c_irq_adc_mask(unsigned int irqno)
|
||||||
|
{
|
||||||
|
s3c_irqsub_mask(irqno, INTMSK_ADCPARENT, 3 << 9);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
s3c_irq_adc_unmask(unsigned int irqno)
|
||||||
|
{
|
||||||
|
s3c_irqsub_unmask(irqno, INTMSK_ADCPARENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
s3c_irq_adc_ack(unsigned int irqno)
|
||||||
|
{
|
||||||
|
s3c_irqsub_ack(irqno, INTMSK_ADCPARENT, 3 << 9);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct irq_chip s3c_irq_adc = {
|
||||||
|
.name = "s3c-adc",
|
||||||
|
.mask = s3c_irq_adc_mask,
|
||||||
|
.unmask = s3c_irq_adc_unmask,
|
||||||
|
.ack = s3c_irq_adc_ack,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* irq demux for adc */
|
||||||
|
static void s3c_irq_demux_adc(unsigned int irq,
|
||||||
|
struct irq_desc *desc)
|
||||||
|
{
|
||||||
|
unsigned int subsrc, submsk;
|
||||||
|
unsigned int offset = 9;
|
||||||
|
struct irq_desc *mydesc;
|
||||||
|
|
||||||
|
/* read the current pending interrupts, and the mask
|
||||||
|
* for what it is available */
|
||||||
|
|
||||||
|
subsrc = __raw_readl(S3C2410_SUBSRCPND);
|
||||||
|
submsk = __raw_readl(S3C2410_INTSUBMSK);
|
||||||
|
|
||||||
|
subsrc &= ~submsk;
|
||||||
|
subsrc >>= offset;
|
||||||
|
subsrc &= 3;
|
||||||
|
|
||||||
|
if (subsrc != 0) {
|
||||||
|
if (subsrc & 1) {
|
||||||
|
mydesc = irq_desc + IRQ_TC;
|
||||||
|
desc_handle_irq(IRQ_TC, mydesc);
|
||||||
|
}
|
||||||
|
if (subsrc & 2) {
|
||||||
|
mydesc = irq_desc + IRQ_ADC;
|
||||||
|
desc_handle_irq(IRQ_ADC, mydesc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void s3c_irq_demux_uart(unsigned int start)
|
||||||
|
{
|
||||||
|
unsigned int subsrc, submsk;
|
||||||
|
unsigned int offset = start - IRQ_S3CUART_RX0;
|
||||||
|
struct irq_desc *desc;
|
||||||
|
|
||||||
|
/* read the current pending interrupts, and the mask
|
||||||
|
* for what it is available */
|
||||||
|
|
||||||
|
subsrc = __raw_readl(S3C2410_SUBSRCPND);
|
||||||
|
submsk = __raw_readl(S3C2410_INTSUBMSK);
|
||||||
|
|
||||||
|
irqdbf2("s3c_irq_demux_uart: start=%d (%d), subsrc=0x%08x,0x%08x\n",
|
||||||
|
start, offset, subsrc, submsk);
|
||||||
|
|
||||||
|
subsrc &= ~submsk;
|
||||||
|
subsrc >>= offset;
|
||||||
|
subsrc &= 7;
|
||||||
|
|
||||||
|
if (subsrc != 0) {
|
||||||
|
desc = irq_desc + start;
|
||||||
|
|
||||||
|
if (subsrc & 1)
|
||||||
|
desc_handle_irq(start, desc);
|
||||||
|
|
||||||
|
desc++;
|
||||||
|
|
||||||
|
if (subsrc & 2)
|
||||||
|
desc_handle_irq(start+1, desc);
|
||||||
|
|
||||||
|
desc++;
|
||||||
|
|
||||||
|
if (subsrc & 4)
|
||||||
|
desc_handle_irq(start+2, desc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* uart demux entry points */
|
||||||
|
|
||||||
|
static void
|
||||||
|
s3c_irq_demux_uart0(unsigned int irq,
|
||||||
|
struct irq_desc *desc)
|
||||||
|
{
|
||||||
|
irq = irq;
|
||||||
|
s3c_irq_demux_uart(IRQ_S3CUART_RX0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
s3c_irq_demux_uart1(unsigned int irq,
|
||||||
|
struct irq_desc *desc)
|
||||||
|
{
|
||||||
|
irq = irq;
|
||||||
|
s3c_irq_demux_uart(IRQ_S3CUART_RX1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
s3c_irq_demux_uart2(unsigned int irq,
|
||||||
|
struct irq_desc *desc)
|
||||||
|
{
|
||||||
|
irq = irq;
|
||||||
|
s3c_irq_demux_uart(IRQ_S3CUART_RX2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
s3c_irq_demux_extint8(unsigned int irq,
|
||||||
|
struct irq_desc *desc)
|
||||||
|
{
|
||||||
|
unsigned long eintpnd = __raw_readl(S3C24XX_EINTPEND);
|
||||||
|
unsigned long eintmsk = __raw_readl(S3C24XX_EINTMASK);
|
||||||
|
|
||||||
|
eintpnd &= ~eintmsk;
|
||||||
|
eintpnd &= ~0xff; /* ignore lower irqs */
|
||||||
|
|
||||||
|
/* we may as well handle all the pending IRQs here */
|
||||||
|
|
||||||
|
while (eintpnd) {
|
||||||
|
irq = __ffs(eintpnd);
|
||||||
|
eintpnd &= ~(1<<irq);
|
||||||
|
|
||||||
|
irq += (IRQ_EINT4 - 4);
|
||||||
|
desc_handle_irq(irq, irq_desc + irq);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
s3c_irq_demux_extint4t7(unsigned int irq,
|
||||||
|
struct irq_desc *desc)
|
||||||
|
{
|
||||||
|
unsigned long eintpnd = __raw_readl(S3C24XX_EINTPEND);
|
||||||
|
unsigned long eintmsk = __raw_readl(S3C24XX_EINTMASK);
|
||||||
|
|
||||||
|
eintpnd &= ~eintmsk;
|
||||||
|
eintpnd &= 0xff; /* only lower irqs */
|
||||||
|
|
||||||
|
/* we may as well handle all the pending IRQs here */
|
||||||
|
|
||||||
|
while (eintpnd) {
|
||||||
|
irq = __ffs(eintpnd);
|
||||||
|
eintpnd &= ~(1<<irq);
|
||||||
|
|
||||||
|
irq += (IRQ_EINT4 - 4);
|
||||||
|
|
||||||
|
desc_handle_irq(irq, irq_desc + irq);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_PM
|
||||||
|
|
||||||
|
static struct sleep_save irq_save[] = {
|
||||||
|
SAVE_ITEM(S3C2410_INTMSK),
|
||||||
|
SAVE_ITEM(S3C2410_INTSUBMSK),
|
||||||
|
};
|
||||||
|
|
||||||
|
/* the extint values move between the s3c2410/s3c2440 and the s3c2412
|
||||||
|
* so we use an array to hold them, and to calculate the address of
|
||||||
|
* the register at run-time
|
||||||
|
*/
|
||||||
|
|
||||||
|
static unsigned long save_extint[3];
|
||||||
|
static unsigned long save_eintflt[4];
|
||||||
|
static unsigned long save_eintmask;
|
||||||
|
|
||||||
|
int s3c24xx_irq_suspend(struct sys_device *dev, pm_message_t state)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(save_extint); i++)
|
||||||
|
save_extint[i] = __raw_readl(S3C24XX_EXTINT0 + (i*4));
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(save_eintflt); i++)
|
||||||
|
save_eintflt[i] = __raw_readl(S3C24XX_EINFLT0 + (i*4));
|
||||||
|
|
||||||
|
s3c2410_pm_do_save(irq_save, ARRAY_SIZE(irq_save));
|
||||||
|
save_eintmask = __raw_readl(S3C24XX_EINTMASK);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int s3c24xx_irq_resume(struct sys_device *dev)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(save_extint); i++)
|
||||||
|
__raw_writel(save_extint[i], S3C24XX_EXTINT0 + (i*4));
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(save_eintflt); i++)
|
||||||
|
__raw_writel(save_eintflt[i], S3C24XX_EINFLT0 + (i*4));
|
||||||
|
|
||||||
|
s3c2410_pm_do_restore(irq_save, ARRAY_SIZE(irq_save));
|
||||||
|
__raw_writel(save_eintmask, S3C24XX_EINTMASK);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
#define s3c24xx_irq_suspend NULL
|
||||||
|
#define s3c24xx_irq_resume NULL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* s3c24xx_init_irq
|
||||||
|
*
|
||||||
|
* Initialise S3C2410 IRQ system
|
||||||
|
*/
|
||||||
|
|
||||||
|
void __init s3c24xx_init_irq(void)
|
||||||
|
{
|
||||||
|
unsigned long pend;
|
||||||
|
unsigned long last;
|
||||||
|
int irqno;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
irqdbf("s3c2410_init_irq: clearing interrupt status flags\n");
|
||||||
|
|
||||||
|
/* first, clear all interrupts pending... */
|
||||||
|
|
||||||
|
last = 0;
|
||||||
|
for (i = 0; i < 4; i++) {
|
||||||
|
pend = __raw_readl(S3C24XX_EINTPEND);
|
||||||
|
|
||||||
|
if (pend == 0 || pend == last)
|
||||||
|
break;
|
||||||
|
|
||||||
|
__raw_writel(pend, S3C24XX_EINTPEND);
|
||||||
|
printk("irq: clearing pending ext status %08x\n", (int)pend);
|
||||||
|
last = pend;
|
||||||
|
}
|
||||||
|
|
||||||
|
last = 0;
|
||||||
|
for (i = 0; i < 4; i++) {
|
||||||
|
pend = __raw_readl(S3C2410_INTPND);
|
||||||
|
|
||||||
|
if (pend == 0 || pend == last)
|
||||||
|
break;
|
||||||
|
|
||||||
|
__raw_writel(pend, S3C2410_SRCPND);
|
||||||
|
__raw_writel(pend, S3C2410_INTPND);
|
||||||
|
printk("irq: clearing pending status %08x\n", (int)pend);
|
||||||
|
last = pend;
|
||||||
|
}
|
||||||
|
|
||||||
|
last = 0;
|
||||||
|
for (i = 0; i < 4; i++) {
|
||||||
|
pend = __raw_readl(S3C2410_SUBSRCPND);
|
||||||
|
|
||||||
|
if (pend == 0 || pend == last)
|
||||||
|
break;
|
||||||
|
|
||||||
|
printk("irq: clearing subpending status %08x\n", (int)pend);
|
||||||
|
__raw_writel(pend, S3C2410_SUBSRCPND);
|
||||||
|
last = pend;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* register the main interrupts */
|
||||||
|
|
||||||
|
irqdbf("s3c2410_init_irq: registering s3c2410 interrupt handlers\n");
|
||||||
|
|
||||||
|
for (irqno = IRQ_EINT4t7; irqno <= IRQ_ADCPARENT; irqno++) {
|
||||||
|
/* set all the s3c2410 internal irqs */
|
||||||
|
|
||||||
|
switch (irqno) {
|
||||||
|
/* deal with the special IRQs (cascaded) */
|
||||||
|
|
||||||
|
case IRQ_EINT4t7:
|
||||||
|
case IRQ_EINT8t23:
|
||||||
|
case IRQ_UART0:
|
||||||
|
case IRQ_UART1:
|
||||||
|
case IRQ_UART2:
|
||||||
|
case IRQ_ADCPARENT:
|
||||||
|
set_irq_chip(irqno, &s3c_irq_level_chip);
|
||||||
|
set_irq_handler(irqno, handle_level_irq);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IRQ_RESERVED6:
|
||||||
|
case IRQ_RESERVED24:
|
||||||
|
/* no IRQ here */
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
//irqdbf("registering irq %d (s3c irq)\n", irqno);
|
||||||
|
set_irq_chip(irqno, &s3c_irq_chip);
|
||||||
|
set_irq_handler(irqno, handle_edge_irq);
|
||||||
|
set_irq_flags(irqno, IRQF_VALID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* setup the cascade irq handlers */
|
||||||
|
|
||||||
|
set_irq_chained_handler(IRQ_EINT4t7, s3c_irq_demux_extint4t7);
|
||||||
|
set_irq_chained_handler(IRQ_EINT8t23, s3c_irq_demux_extint8);
|
||||||
|
|
||||||
|
set_irq_chained_handler(IRQ_UART0, s3c_irq_demux_uart0);
|
||||||
|
set_irq_chained_handler(IRQ_UART1, s3c_irq_demux_uart1);
|
||||||
|
set_irq_chained_handler(IRQ_UART2, s3c_irq_demux_uart2);
|
||||||
|
set_irq_chained_handler(IRQ_ADCPARENT, s3c_irq_demux_adc);
|
||||||
|
|
||||||
|
/* external interrupts */
|
||||||
|
|
||||||
|
for (irqno = IRQ_EINT0; irqno <= IRQ_EINT3; irqno++) {
|
||||||
|
irqdbf("registering irq %d (ext int)\n", irqno);
|
||||||
|
set_irq_chip(irqno, &s3c_irq_eint0t4);
|
||||||
|
set_irq_handler(irqno, handle_edge_irq);
|
||||||
|
set_irq_flags(irqno, IRQF_VALID);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (irqno = IRQ_EINT4; irqno <= IRQ_EINT23; irqno++) {
|
||||||
|
irqdbf("registering irq %d (extended s3c irq)\n", irqno);
|
||||||
|
set_irq_chip(irqno, &s3c_irqext_chip);
|
||||||
|
set_irq_handler(irqno, handle_edge_irq);
|
||||||
|
set_irq_flags(irqno, IRQF_VALID);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* register the uart interrupts */
|
||||||
|
|
||||||
|
irqdbf("s3c2410: registering external interrupts\n");
|
||||||
|
|
||||||
|
for (irqno = IRQ_S3CUART_RX0; irqno <= IRQ_S3CUART_ERR0; irqno++) {
|
||||||
|
irqdbf("registering irq %d (s3c uart0 irq)\n", irqno);
|
||||||
|
set_irq_chip(irqno, &s3c_irq_uart0);
|
||||||
|
set_irq_handler(irqno, handle_level_irq);
|
||||||
|
set_irq_flags(irqno, IRQF_VALID);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (irqno = IRQ_S3CUART_RX1; irqno <= IRQ_S3CUART_ERR1; irqno++) {
|
||||||
|
irqdbf("registering irq %d (s3c uart1 irq)\n", irqno);
|
||||||
|
set_irq_chip(irqno, &s3c_irq_uart1);
|
||||||
|
set_irq_handler(irqno, handle_level_irq);
|
||||||
|
set_irq_flags(irqno, IRQF_VALID);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (irqno = IRQ_S3CUART_RX2; irqno <= IRQ_S3CUART_ERR2; irqno++) {
|
||||||
|
irqdbf("registering irq %d (s3c uart2 irq)\n", irqno);
|
||||||
|
set_irq_chip(irqno, &s3c_irq_uart2);
|
||||||
|
set_irq_handler(irqno, handle_level_irq);
|
||||||
|
set_irq_flags(irqno, IRQF_VALID);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (irqno = IRQ_TC; irqno <= IRQ_ADC; irqno++) {
|
||||||
|
irqdbf("registering irq %d (s3c adc irq)\n", irqno);
|
||||||
|
set_irq_chip(irqno, &s3c_irq_adc);
|
||||||
|
set_irq_handler(irqno, handle_edge_irq);
|
||||||
|
set_irq_flags(irqno, IRQF_VALID);
|
||||||
|
}
|
||||||
|
|
||||||
|
irqdbf("s3c2410: registered interrupt handlers\n");
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
/* linux/arch/arm/mach-s3c2410/pm-simtec.c
|
/* linux/arch/arm/plat-s3c24xx/pm-simtec.c
|
||||||
*
|
*
|
||||||
* Copyright (c) 2004 Simtec Electronics
|
* Copyright (c) 2004 Simtec Electronics
|
||||||
* Ben Dooks <ben@simtec.co.uk>
|
* Ben Dooks <ben@simtec.co.uk>
|
||||||
|
@ -32,7 +32,7 @@
|
||||||
|
|
||||||
#include <asm/mach-types.h>
|
#include <asm/mach-types.h>
|
||||||
|
|
||||||
#include "pm.h"
|
#include <asm/plat-s3c24xx/pm.h>
|
||||||
|
|
||||||
#define COPYRIGHT ", (c) 2005 Simtec Electronics"
|
#define COPYRIGHT ", (c) 2005 Simtec Electronics"
|
||||||
|
|
|
@ -0,0 +1,659 @@
|
||||||
|
/* linux/arch/arm/plat-s3c24xx/pm.c
|
||||||
|
*
|
||||||
|
* Copyright (c) 2004,2006 Simtec Electronics
|
||||||
|
* Ben Dooks <ben@simtec.co.uk>
|
||||||
|
*
|
||||||
|
* S3C24XX Power Manager (Suspend-To-RAM) support
|
||||||
|
*
|
||||||
|
* See Documentation/arm/Samsung-S3C24XX/Suspend.txt for more information
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
* Parts based on arch/arm/mach-pxa/pm.c
|
||||||
|
*
|
||||||
|
* Thanks to Dimitry Andric for debugging
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/init.h>
|
||||||
|
#include <linux/suspend.h>
|
||||||
|
#include <linux/errno.h>
|
||||||
|
#include <linux/time.h>
|
||||||
|
#include <linux/interrupt.h>
|
||||||
|
#include <linux/crc32.h>
|
||||||
|
#include <linux/ioport.h>
|
||||||
|
#include <linux/delay.h>
|
||||||
|
#include <linux/serial_core.h>
|
||||||
|
|
||||||
|
#include <asm/cacheflush.h>
|
||||||
|
#include <asm/hardware.h>
|
||||||
|
#include <asm/io.h>
|
||||||
|
|
||||||
|
#include <asm/arch/regs-serial.h>
|
||||||
|
#include <asm/arch/regs-clock.h>
|
||||||
|
#include <asm/arch/regs-gpio.h>
|
||||||
|
#include <asm/arch/regs-mem.h>
|
||||||
|
#include <asm/arch/regs-irq.h>
|
||||||
|
|
||||||
|
#include <asm/mach/time.h>
|
||||||
|
|
||||||
|
#include <asm/plat-s3c24xx/pm.h>
|
||||||
|
|
||||||
|
/* for external use */
|
||||||
|
|
||||||
|
unsigned long s3c_pm_flags;
|
||||||
|
|
||||||
|
#define PFX "s3c24xx-pm: "
|
||||||
|
|
||||||
|
static struct sleep_save core_save[] = {
|
||||||
|
SAVE_ITEM(S3C2410_LOCKTIME),
|
||||||
|
SAVE_ITEM(S3C2410_CLKCON),
|
||||||
|
|
||||||
|
/* we restore the timings here, with the proviso that the board
|
||||||
|
* brings the system up in an slower, or equal frequency setting
|
||||||
|
* to the original system.
|
||||||
|
*
|
||||||
|
* if we cannot guarantee this, then things are going to go very
|
||||||
|
* wrong here, as we modify the refresh and both pll settings.
|
||||||
|
*/
|
||||||
|
|
||||||
|
SAVE_ITEM(S3C2410_BWSCON),
|
||||||
|
SAVE_ITEM(S3C2410_BANKCON0),
|
||||||
|
SAVE_ITEM(S3C2410_BANKCON1),
|
||||||
|
SAVE_ITEM(S3C2410_BANKCON2),
|
||||||
|
SAVE_ITEM(S3C2410_BANKCON3),
|
||||||
|
SAVE_ITEM(S3C2410_BANKCON4),
|
||||||
|
SAVE_ITEM(S3C2410_BANKCON5),
|
||||||
|
|
||||||
|
SAVE_ITEM(S3C2410_CLKDIVN),
|
||||||
|
SAVE_ITEM(S3C2410_MPLLCON),
|
||||||
|
SAVE_ITEM(S3C2410_UPLLCON),
|
||||||
|
SAVE_ITEM(S3C2410_CLKSLOW),
|
||||||
|
SAVE_ITEM(S3C2410_REFRESH),
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct sleep_save gpio_save[] = {
|
||||||
|
SAVE_ITEM(S3C2410_GPACON),
|
||||||
|
SAVE_ITEM(S3C2410_GPADAT),
|
||||||
|
|
||||||
|
SAVE_ITEM(S3C2410_GPBCON),
|
||||||
|
SAVE_ITEM(S3C2410_GPBDAT),
|
||||||
|
SAVE_ITEM(S3C2410_GPBUP),
|
||||||
|
|
||||||
|
SAVE_ITEM(S3C2410_GPCCON),
|
||||||
|
SAVE_ITEM(S3C2410_GPCDAT),
|
||||||
|
SAVE_ITEM(S3C2410_GPCUP),
|
||||||
|
|
||||||
|
SAVE_ITEM(S3C2410_GPDCON),
|
||||||
|
SAVE_ITEM(S3C2410_GPDDAT),
|
||||||
|
SAVE_ITEM(S3C2410_GPDUP),
|
||||||
|
|
||||||
|
SAVE_ITEM(S3C2410_GPECON),
|
||||||
|
SAVE_ITEM(S3C2410_GPEDAT),
|
||||||
|
SAVE_ITEM(S3C2410_GPEUP),
|
||||||
|
|
||||||
|
SAVE_ITEM(S3C2410_GPFCON),
|
||||||
|
SAVE_ITEM(S3C2410_GPFDAT),
|
||||||
|
SAVE_ITEM(S3C2410_GPFUP),
|
||||||
|
|
||||||
|
SAVE_ITEM(S3C2410_GPGCON),
|
||||||
|
SAVE_ITEM(S3C2410_GPGDAT),
|
||||||
|
SAVE_ITEM(S3C2410_GPGUP),
|
||||||
|
|
||||||
|
SAVE_ITEM(S3C2410_GPHCON),
|
||||||
|
SAVE_ITEM(S3C2410_GPHDAT),
|
||||||
|
SAVE_ITEM(S3C2410_GPHUP),
|
||||||
|
|
||||||
|
SAVE_ITEM(S3C2410_DCLKCON),
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef CONFIG_S3C2410_PM_DEBUG
|
||||||
|
|
||||||
|
#define SAVE_UART(va) \
|
||||||
|
SAVE_ITEM((va) + S3C2410_ULCON), \
|
||||||
|
SAVE_ITEM((va) + S3C2410_UCON), \
|
||||||
|
SAVE_ITEM((va) + S3C2410_UFCON), \
|
||||||
|
SAVE_ITEM((va) + S3C2410_UMCON), \
|
||||||
|
SAVE_ITEM((va) + S3C2410_UBRDIV)
|
||||||
|
|
||||||
|
static struct sleep_save uart_save[] = {
|
||||||
|
SAVE_UART(S3C24XX_VA_UART0),
|
||||||
|
SAVE_UART(S3C24XX_VA_UART1),
|
||||||
|
#ifndef CONFIG_CPU_S3C2400
|
||||||
|
SAVE_UART(S3C24XX_VA_UART2),
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
/* debug
|
||||||
|
*
|
||||||
|
* we send the debug to printascii() to allow it to be seen if the
|
||||||
|
* system never wakes up from the sleep
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern void printascii(const char *);
|
||||||
|
|
||||||
|
void pm_dbg(const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list va;
|
||||||
|
char buff[256];
|
||||||
|
|
||||||
|
va_start(va, fmt);
|
||||||
|
vsprintf(buff, fmt, va);
|
||||||
|
va_end(va);
|
||||||
|
|
||||||
|
printascii(buff);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void s3c2410_pm_debug_init(void)
|
||||||
|
{
|
||||||
|
unsigned long tmp = __raw_readl(S3C2410_CLKCON);
|
||||||
|
|
||||||
|
/* re-start uart clocks */
|
||||||
|
tmp |= S3C2410_CLKCON_UART0;
|
||||||
|
tmp |= S3C2410_CLKCON_UART1;
|
||||||
|
tmp |= S3C2410_CLKCON_UART2;
|
||||||
|
|
||||||
|
__raw_writel(tmp, S3C2410_CLKCON);
|
||||||
|
udelay(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define DBG(fmt...) pm_dbg(fmt)
|
||||||
|
#else
|
||||||
|
#define DBG(fmt...) printk(KERN_DEBUG fmt)
|
||||||
|
|
||||||
|
#define s3c2410_pm_debug_init() do { } while(0)
|
||||||
|
|
||||||
|
static struct sleep_save uart_save[] = {};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(CONFIG_S3C2410_PM_CHECK) && CONFIG_S3C2410_PM_CHECK_CHUNKSIZE != 0
|
||||||
|
|
||||||
|
/* suspend checking code...
|
||||||
|
*
|
||||||
|
* this next area does a set of crc checks over all the installed
|
||||||
|
* memory, so the system can verify if the resume was ok.
|
||||||
|
*
|
||||||
|
* CONFIG_S3C2410_PM_CHECK_CHUNKSIZE defines the block-size for the CRC,
|
||||||
|
* increasing it will mean that the area corrupted will be less easy to spot,
|
||||||
|
* and reducing the size will cause the CRC save area to grow
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define CHECK_CHUNKSIZE (CONFIG_S3C2410_PM_CHECK_CHUNKSIZE * 1024)
|
||||||
|
|
||||||
|
static u32 crc_size; /* size needed for the crc block */
|
||||||
|
static u32 *crcs; /* allocated over suspend/resume */
|
||||||
|
|
||||||
|
typedef u32 *(run_fn_t)(struct resource *ptr, u32 *arg);
|
||||||
|
|
||||||
|
/* s3c2410_pm_run_res
|
||||||
|
*
|
||||||
|
* go thorugh the given resource list, and look for system ram
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void s3c2410_pm_run_res(struct resource *ptr, run_fn_t fn, u32 *arg)
|
||||||
|
{
|
||||||
|
while (ptr != NULL) {
|
||||||
|
if (ptr->child != NULL)
|
||||||
|
s3c2410_pm_run_res(ptr->child, fn, arg);
|
||||||
|
|
||||||
|
if ((ptr->flags & IORESOURCE_MEM) &&
|
||||||
|
strcmp(ptr->name, "System RAM") == 0) {
|
||||||
|
DBG("Found system RAM at %08lx..%08lx\n",
|
||||||
|
ptr->start, ptr->end);
|
||||||
|
arg = (fn)(ptr, arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
ptr = ptr->sibling;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void s3c2410_pm_run_sysram(run_fn_t fn, u32 *arg)
|
||||||
|
{
|
||||||
|
s3c2410_pm_run_res(&iomem_resource, fn, arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static u32 *s3c2410_pm_countram(struct resource *res, u32 *val)
|
||||||
|
{
|
||||||
|
u32 size = (u32)(res->end - res->start)+1;
|
||||||
|
|
||||||
|
size += CHECK_CHUNKSIZE-1;
|
||||||
|
size /= CHECK_CHUNKSIZE;
|
||||||
|
|
||||||
|
DBG("Area %08lx..%08lx, %d blocks\n", res->start, res->end, size);
|
||||||
|
|
||||||
|
*val += size * sizeof(u32);
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* s3c2410_pm_prepare_check
|
||||||
|
*
|
||||||
|
* prepare the necessary information for creating the CRCs. This
|
||||||
|
* must be done before the final save, as it will require memory
|
||||||
|
* allocating, and thus touching bits of the kernel we do not
|
||||||
|
* know about.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void s3c2410_pm_check_prepare(void)
|
||||||
|
{
|
||||||
|
crc_size = 0;
|
||||||
|
|
||||||
|
s3c2410_pm_run_sysram(s3c2410_pm_countram, &crc_size);
|
||||||
|
|
||||||
|
DBG("s3c2410_pm_prepare_check: %u checks needed\n", crc_size);
|
||||||
|
|
||||||
|
crcs = kmalloc(crc_size+4, GFP_KERNEL);
|
||||||
|
if (crcs == NULL)
|
||||||
|
printk(KERN_ERR "Cannot allocated CRC save area\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static u32 *s3c2410_pm_makecheck(struct resource *res, u32 *val)
|
||||||
|
{
|
||||||
|
unsigned long addr, left;
|
||||||
|
|
||||||
|
for (addr = res->start; addr < res->end;
|
||||||
|
addr += CHECK_CHUNKSIZE) {
|
||||||
|
left = res->end - addr;
|
||||||
|
|
||||||
|
if (left > CHECK_CHUNKSIZE)
|
||||||
|
left = CHECK_CHUNKSIZE;
|
||||||
|
|
||||||
|
*val = crc32_le(~0, phys_to_virt(addr), left);
|
||||||
|
val++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* s3c2410_pm_check_store
|
||||||
|
*
|
||||||
|
* compute the CRC values for the memory blocks before the final
|
||||||
|
* sleep.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void s3c2410_pm_check_store(void)
|
||||||
|
{
|
||||||
|
if (crcs != NULL)
|
||||||
|
s3c2410_pm_run_sysram(s3c2410_pm_makecheck, crcs);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* in_region
|
||||||
|
*
|
||||||
|
* return TRUE if the area defined by ptr..ptr+size contatins the
|
||||||
|
* what..what+whatsz
|
||||||
|
*/
|
||||||
|
|
||||||
|
static inline int in_region(void *ptr, int size, void *what, size_t whatsz)
|
||||||
|
{
|
||||||
|
if ((what+whatsz) < ptr)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (what > (ptr+size))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static u32 *s3c2410_pm_runcheck(struct resource *res, u32 *val)
|
||||||
|
{
|
||||||
|
void *save_at = phys_to_virt(s3c2410_sleep_save_phys);
|
||||||
|
unsigned long addr;
|
||||||
|
unsigned long left;
|
||||||
|
void *ptr;
|
||||||
|
u32 calc;
|
||||||
|
|
||||||
|
for (addr = res->start; addr < res->end;
|
||||||
|
addr += CHECK_CHUNKSIZE) {
|
||||||
|
left = res->end - addr;
|
||||||
|
|
||||||
|
if (left > CHECK_CHUNKSIZE)
|
||||||
|
left = CHECK_CHUNKSIZE;
|
||||||
|
|
||||||
|
ptr = phys_to_virt(addr);
|
||||||
|
|
||||||
|
if (in_region(ptr, left, crcs, crc_size)) {
|
||||||
|
DBG("skipping %08lx, has crc block in\n", addr);
|
||||||
|
goto skip_check;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in_region(ptr, left, save_at, 32*4 )) {
|
||||||
|
DBG("skipping %08lx, has save block in\n", addr);
|
||||||
|
goto skip_check;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* calculate and check the checksum */
|
||||||
|
|
||||||
|
calc = crc32_le(~0, ptr, left);
|
||||||
|
if (calc != *val) {
|
||||||
|
printk(KERN_ERR PFX "Restore CRC error at "
|
||||||
|
"%08lx (%08x vs %08x)\n", addr, calc, *val);
|
||||||
|
|
||||||
|
DBG("Restore CRC error at %08lx (%08x vs %08x)\n",
|
||||||
|
addr, calc, *val);
|
||||||
|
}
|
||||||
|
|
||||||
|
skip_check:
|
||||||
|
val++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* s3c2410_pm_check_restore
|
||||||
|
*
|
||||||
|
* check the CRCs after the restore event and free the memory used
|
||||||
|
* to hold them
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void s3c2410_pm_check_restore(void)
|
||||||
|
{
|
||||||
|
if (crcs != NULL) {
|
||||||
|
s3c2410_pm_run_sysram(s3c2410_pm_runcheck, crcs);
|
||||||
|
kfree(crcs);
|
||||||
|
crcs = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define s3c2410_pm_check_prepare() do { } while(0)
|
||||||
|
#define s3c2410_pm_check_restore() do { } while(0)
|
||||||
|
#define s3c2410_pm_check_store() do { } while(0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* helper functions to save and restore register state */
|
||||||
|
|
||||||
|
void s3c2410_pm_do_save(struct sleep_save *ptr, int count)
|
||||||
|
{
|
||||||
|
for (; count > 0; count--, ptr++) {
|
||||||
|
ptr->val = __raw_readl(ptr->reg);
|
||||||
|
DBG("saved %p value %08lx\n", ptr->reg, ptr->val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* s3c2410_pm_do_restore
|
||||||
|
*
|
||||||
|
* restore the system from the given list of saved registers
|
||||||
|
*
|
||||||
|
* Note, we do not use DBG() in here, as the system may not have
|
||||||
|
* restore the UARTs state yet
|
||||||
|
*/
|
||||||
|
|
||||||
|
void s3c2410_pm_do_restore(struct sleep_save *ptr, int count)
|
||||||
|
{
|
||||||
|
for (; count > 0; count--, ptr++) {
|
||||||
|
printk(KERN_DEBUG "restore %p (restore %08lx, was %08x)\n",
|
||||||
|
ptr->reg, ptr->val, __raw_readl(ptr->reg));
|
||||||
|
|
||||||
|
__raw_writel(ptr->val, ptr->reg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* s3c2410_pm_do_restore_core
|
||||||
|
*
|
||||||
|
* similar to s3c2410_pm_do_restore_core
|
||||||
|
*
|
||||||
|
* WARNING: Do not put any debug in here that may effect memory or use
|
||||||
|
* peripherals, as things may be changing!
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void s3c2410_pm_do_restore_core(struct sleep_save *ptr, int count)
|
||||||
|
{
|
||||||
|
for (; count > 0; count--, ptr++) {
|
||||||
|
__raw_writel(ptr->val, ptr->reg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* s3c2410_pm_show_resume_irqs
|
||||||
|
*
|
||||||
|
* print any IRQs asserted at resume time (ie, we woke from)
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void s3c2410_pm_show_resume_irqs(int start, unsigned long which,
|
||||||
|
unsigned long mask)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
which &= ~mask;
|
||||||
|
|
||||||
|
for (i = 0; i <= 31; i++) {
|
||||||
|
if ((which) & (1L<<i)) {
|
||||||
|
DBG("IRQ %d asserted at resume\n", start+i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* s3c2410_pm_check_resume_pin
|
||||||
|
*
|
||||||
|
* check to see if the pin is configured correctly for sleep mode, and
|
||||||
|
* make any necessary adjustments if it is not
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void s3c2410_pm_check_resume_pin(unsigned int pin, unsigned int irqoffs)
|
||||||
|
{
|
||||||
|
unsigned long irqstate;
|
||||||
|
unsigned long pinstate;
|
||||||
|
int irq = s3c2410_gpio_getirq(pin);
|
||||||
|
|
||||||
|
if (irqoffs < 4)
|
||||||
|
irqstate = s3c_irqwake_intmask & (1L<<irqoffs);
|
||||||
|
else
|
||||||
|
irqstate = s3c_irqwake_eintmask & (1L<<irqoffs);
|
||||||
|
|
||||||
|
pinstate = s3c2410_gpio_getcfg(pin);
|
||||||
|
|
||||||
|
if (!irqstate) {
|
||||||
|
if (pinstate == S3C2410_GPIO_IRQ)
|
||||||
|
DBG("Leaving IRQ %d (pin %d) enabled\n", irq, pin);
|
||||||
|
} else {
|
||||||
|
if (pinstate == S3C2410_GPIO_IRQ) {
|
||||||
|
DBG("Disabling IRQ %d (pin %d)\n", irq, pin);
|
||||||
|
s3c2410_gpio_cfgpin(pin, S3C2410_GPIO_INPUT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* s3c2410_pm_configure_extint
|
||||||
|
*
|
||||||
|
* configure all external interrupt pins
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void s3c2410_pm_configure_extint(void)
|
||||||
|
{
|
||||||
|
int pin;
|
||||||
|
|
||||||
|
/* for each of the external interrupts (EINT0..EINT15) we
|
||||||
|
* need to check wether it is an external interrupt source,
|
||||||
|
* and then configure it as an input if it is not
|
||||||
|
*/
|
||||||
|
|
||||||
|
for (pin = S3C2410_GPF0; pin <= S3C2410_GPF7; pin++) {
|
||||||
|
s3c2410_pm_check_resume_pin(pin, pin - S3C2410_GPF0);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (pin = S3C2410_GPG0; pin <= S3C2410_GPG7; pin++) {
|
||||||
|
s3c2410_pm_check_resume_pin(pin, (pin - S3C2410_GPG0)+8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void (*pm_cpu_prep)(void);
|
||||||
|
void (*pm_cpu_sleep)(void);
|
||||||
|
|
||||||
|
#define any_allowed(mask, allow) (((mask) & (allow)) != (allow))
|
||||||
|
|
||||||
|
/* s3c2410_pm_enter
|
||||||
|
*
|
||||||
|
* central control for sleep/resume process
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int s3c2410_pm_enter(suspend_state_t state)
|
||||||
|
{
|
||||||
|
unsigned long regs_save[16];
|
||||||
|
|
||||||
|
/* ensure the debug is initialised (if enabled) */
|
||||||
|
|
||||||
|
s3c2410_pm_debug_init();
|
||||||
|
|
||||||
|
DBG("s3c2410_pm_enter(%d)\n", state);
|
||||||
|
|
||||||
|
if (pm_cpu_prep == NULL || pm_cpu_sleep == NULL) {
|
||||||
|
printk(KERN_ERR PFX "error: no cpu sleep functions set\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state != PM_SUSPEND_MEM) {
|
||||||
|
printk(KERN_ERR PFX "error: only PM_SUSPEND_MEM supported\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check if we have anything to wake-up with... bad things seem
|
||||||
|
* to happen if you suspend with no wakeup (system will often
|
||||||
|
* require a full power-cycle)
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!any_allowed(s3c_irqwake_intmask, s3c_irqwake_intallow) &&
|
||||||
|
!any_allowed(s3c_irqwake_eintmask, s3c_irqwake_eintallow)) {
|
||||||
|
printk(KERN_ERR PFX "No sources enabled for wake-up!\n");
|
||||||
|
printk(KERN_ERR PFX "Aborting sleep\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* prepare check area if configured */
|
||||||
|
|
||||||
|
s3c2410_pm_check_prepare();
|
||||||
|
|
||||||
|
/* store the physical address of the register recovery block */
|
||||||
|
|
||||||
|
s3c2410_sleep_save_phys = virt_to_phys(regs_save);
|
||||||
|
|
||||||
|
DBG("s3c2410_sleep_save_phys=0x%08lx\n", s3c2410_sleep_save_phys);
|
||||||
|
|
||||||
|
/* save all necessary core registers not covered by the drivers */
|
||||||
|
|
||||||
|
s3c2410_pm_do_save(gpio_save, ARRAY_SIZE(gpio_save));
|
||||||
|
s3c2410_pm_do_save(core_save, ARRAY_SIZE(core_save));
|
||||||
|
s3c2410_pm_do_save(uart_save, ARRAY_SIZE(uart_save));
|
||||||
|
|
||||||
|
/* set the irq configuration for wake */
|
||||||
|
|
||||||
|
s3c2410_pm_configure_extint();
|
||||||
|
|
||||||
|
DBG("sleep: irq wakeup masks: %08lx,%08lx\n",
|
||||||
|
s3c_irqwake_intmask, s3c_irqwake_eintmask);
|
||||||
|
|
||||||
|
__raw_writel(s3c_irqwake_intmask, S3C2410_INTMSK);
|
||||||
|
__raw_writel(s3c_irqwake_eintmask, S3C2410_EINTMASK);
|
||||||
|
|
||||||
|
/* ack any outstanding external interrupts before we go to sleep */
|
||||||
|
|
||||||
|
__raw_writel(__raw_readl(S3C2410_EINTPEND), S3C2410_EINTPEND);
|
||||||
|
__raw_writel(__raw_readl(S3C2410_INTPND), S3C2410_INTPND);
|
||||||
|
__raw_writel(__raw_readl(S3C2410_SRCPND), S3C2410_SRCPND);
|
||||||
|
|
||||||
|
/* call cpu specific preperation */
|
||||||
|
|
||||||
|
pm_cpu_prep();
|
||||||
|
|
||||||
|
/* flush cache back to ram */
|
||||||
|
|
||||||
|
flush_cache_all();
|
||||||
|
|
||||||
|
s3c2410_pm_check_store();
|
||||||
|
|
||||||
|
/* send the cpu to sleep... */
|
||||||
|
|
||||||
|
__raw_writel(0x00, S3C2410_CLKCON); /* turn off clocks over sleep */
|
||||||
|
|
||||||
|
/* s3c2410_cpu_save will also act as our return point from when
|
||||||
|
* we resume as it saves its own register state, so use the return
|
||||||
|
* code to differentiate return from save and return from sleep */
|
||||||
|
|
||||||
|
if (s3c2410_cpu_save(regs_save) == 0) {
|
||||||
|
flush_cache_all();
|
||||||
|
pm_cpu_sleep();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* restore the cpu state */
|
||||||
|
|
||||||
|
cpu_init();
|
||||||
|
|
||||||
|
/* restore the system state */
|
||||||
|
|
||||||
|
s3c2410_pm_do_restore_core(core_save, ARRAY_SIZE(core_save));
|
||||||
|
s3c2410_pm_do_restore(gpio_save, ARRAY_SIZE(gpio_save));
|
||||||
|
s3c2410_pm_do_restore(uart_save, ARRAY_SIZE(uart_save));
|
||||||
|
|
||||||
|
s3c2410_pm_debug_init();
|
||||||
|
|
||||||
|
/* check what irq (if any) restored the system */
|
||||||
|
|
||||||
|
DBG("post sleep: IRQs 0x%08x, 0x%08x\n",
|
||||||
|
__raw_readl(S3C2410_SRCPND),
|
||||||
|
__raw_readl(S3C2410_EINTPEND));
|
||||||
|
|
||||||
|
s3c2410_pm_show_resume_irqs(IRQ_EINT0, __raw_readl(S3C2410_SRCPND),
|
||||||
|
s3c_irqwake_intmask);
|
||||||
|
|
||||||
|
s3c2410_pm_show_resume_irqs(IRQ_EINT4-4, __raw_readl(S3C2410_EINTPEND),
|
||||||
|
s3c_irqwake_eintmask);
|
||||||
|
|
||||||
|
DBG("post sleep, preparing to return\n");
|
||||||
|
|
||||||
|
s3c2410_pm_check_restore();
|
||||||
|
|
||||||
|
/* ok, let's return from sleep */
|
||||||
|
|
||||||
|
DBG("S3C2410 PM Resume (post-restore)\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Called after processes are frozen, but before we shut down devices.
|
||||||
|
*/
|
||||||
|
static int s3c2410_pm_prepare(suspend_state_t state)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Called after devices are re-setup, but before processes are thawed.
|
||||||
|
*/
|
||||||
|
static int s3c2410_pm_finish(suspend_state_t state)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set to PM_DISK_FIRMWARE so we can quickly veto suspend-to-disk.
|
||||||
|
*/
|
||||||
|
static struct pm_ops s3c2410_pm_ops = {
|
||||||
|
.pm_disk_mode = PM_DISK_FIRMWARE,
|
||||||
|
.prepare = s3c2410_pm_prepare,
|
||||||
|
.enter = s3c2410_pm_enter,
|
||||||
|
.finish = s3c2410_pm_finish,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* s3c2410_pm_init
|
||||||
|
*
|
||||||
|
* Attach the power management functions. This should be called
|
||||||
|
* from the board specific initialisation if the board supports
|
||||||
|
* it.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int __init s3c2410_pm_init(void)
|
||||||
|
{
|
||||||
|
printk("S3C2410 Power Management, (c) 2004 Simtec Electronics\n");
|
||||||
|
|
||||||
|
pm_set_ops(&s3c2410_pm_ops);
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
/* linux/arch/arm/mach-s3c2410/s3c244x-irq.c
|
/* linux/arch/arm/plat-s3c24xx/s3c244x-irq.c
|
||||||
*
|
*
|
||||||
* Copyright (c) 2003,2004 Simtec Electronics
|
* Copyright (c) 2003,2004 Simtec Electronics
|
||||||
* Ben Dooks <ben@simtec.co.uk>
|
* Ben Dooks <ben@simtec.co.uk>
|
||||||
|
@ -35,9 +35,9 @@
|
||||||
#include <asm/arch/regs-irq.h>
|
#include <asm/arch/regs-irq.h>
|
||||||
#include <asm/arch/regs-gpio.h>
|
#include <asm/arch/regs-gpio.h>
|
||||||
|
|
||||||
#include "cpu.h"
|
#include <asm/plat-s3c24xx/cpu.h>
|
||||||
#include "pm.h"
|
#include <asm/plat-s3c24xx/pm.h>
|
||||||
#include "irq.h"
|
#include <asm/plat-s3c24xx/irq.h>
|
||||||
|
|
||||||
/* camera irq */
|
/* camera irq */
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* linux/arch/arm/mach-s3c2410/s3c244x.c
|
/* linux/arch/arm/plat-s3c24xx/s3c244x.c
|
||||||
*
|
*
|
||||||
* Copyright (c) 2004-2006 Simtec Electronics
|
* Copyright (c) 2004-2006 Simtec Electronics
|
||||||
* Ben Dooks <ben@simtec.co.uk>
|
* Ben Dooks <ben@simtec.co.uk>
|
||||||
|
@ -35,13 +35,13 @@
|
||||||
#include <asm/arch/regs-gpioj.h>
|
#include <asm/arch/regs-gpioj.h>
|
||||||
#include <asm/arch/regs-dsc.h>
|
#include <asm/arch/regs-dsc.h>
|
||||||
|
|
||||||
#include "s3c2410.h"
|
#include <asm/plat-s3c24xx/s3c2410.h>
|
||||||
#include "s3c2440.h"
|
#include <asm/plat-s3c24xx/s3c2440.h>
|
||||||
#include "s3c244x.h"
|
#include "s3c244x.h"
|
||||||
#include "clock.h"
|
#include <asm/plat-s3c24xx/clock.h>
|
||||||
#include "devs.h"
|
#include <asm/plat-s3c24xx/devs.h>
|
||||||
#include "cpu.h"
|
#include <asm/plat-s3c24xx/cpu.h>
|
||||||
#include "pm.h"
|
#include <asm/plat-s3c24xx/pm.h>
|
||||||
|
|
||||||
static struct map_desc s3c244x_iodesc[] __initdata = {
|
static struct map_desc s3c244x_iodesc[] __initdata = {
|
||||||
IODESC_ENT(CLKPWR),
|
IODESC_ENT(CLKPWR),
|
|
@ -1,4 +1,4 @@
|
||||||
/* arch/arm/mach-s3c2410/s3c244x.h
|
/* linux/arch/arm/plat-s3c24xx/s3c244x.h
|
||||||
*
|
*
|
||||||
* Copyright (c) 2004-2005 Simtec Electronics
|
* Copyright (c) 2004-2005 Simtec Electronics
|
||||||
* Ben Dooks <ben@simtec.co.uk>
|
* Ben Dooks <ben@simtec.co.uk>
|
|
@ -0,0 +1,159 @@
|
||||||
|
/* linux/arch/arm/mach-s3c2410/sleep.S
|
||||||
|
*
|
||||||
|
* Copyright (c) 2004 Simtec Electronics
|
||||||
|
* Ben Dooks <ben@simtec.co.uk>
|
||||||
|
*
|
||||||
|
* S3C2410 Power Manager (Suspend-To-RAM) support
|
||||||
|
*
|
||||||
|
* Based on PXA/SA1100 sleep code by:
|
||||||
|
* Nicolas Pitre, (c) 2002 Monta Vista Software Inc
|
||||||
|
* Cliff Brake, (c) 2001
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/linkage.h>
|
||||||
|
#include <asm/assembler.h>
|
||||||
|
#include <asm/hardware.h>
|
||||||
|
#include <asm/arch/map.h>
|
||||||
|
|
||||||
|
#include <asm/arch/regs-gpio.h>
|
||||||
|
#include <asm/arch/regs-clock.h>
|
||||||
|
#include <asm/arch/regs-mem.h>
|
||||||
|
#include <asm/arch/regs-serial.h>
|
||||||
|
|
||||||
|
/* CONFIG_DEBUG_RESUME is dangerous if your bootloader does not
|
||||||
|
* reset the UART configuration, only enable if you really need this!
|
||||||
|
*/
|
||||||
|
//#define CONFIG_DEBUG_RESUME
|
||||||
|
|
||||||
|
.text
|
||||||
|
|
||||||
|
/* s3c2410_cpu_save
|
||||||
|
*
|
||||||
|
* save enough of the CPU state to allow us to re-start
|
||||||
|
* pm.c code. as we store items like the sp/lr, we will
|
||||||
|
* end up returning from this function when the cpu resumes
|
||||||
|
* so the return value is set to mark this.
|
||||||
|
*
|
||||||
|
* This arangement means we avoid having to flush the cache
|
||||||
|
* from this code.
|
||||||
|
*
|
||||||
|
* entry:
|
||||||
|
* r0 = pointer to save block
|
||||||
|
*
|
||||||
|
* exit:
|
||||||
|
* r0 = 0 => we stored everything
|
||||||
|
* 1 => resumed from sleep
|
||||||
|
*/
|
||||||
|
|
||||||
|
ENTRY(s3c2410_cpu_save)
|
||||||
|
stmfd sp!, { r4 - r12, lr }
|
||||||
|
|
||||||
|
@@ store co-processor registers
|
||||||
|
|
||||||
|
mrc p15, 0, r4, c15, c1, 0 @ CP access register
|
||||||
|
mrc p15, 0, r5, c13, c0, 0 @ PID
|
||||||
|
mrc p15, 0, r6, c3, c0, 0 @ Domain ID
|
||||||
|
mrc p15, 0, r7, c2, c0, 0 @ translation table base address
|
||||||
|
mrc p15, 0, r8, c1, c0, 0 @ control register
|
||||||
|
|
||||||
|
stmia r0, { r4 - r13 }
|
||||||
|
|
||||||
|
mov r0, #0
|
||||||
|
ldmfd sp, { r4 - r12, pc }
|
||||||
|
|
||||||
|
@@ return to the caller, after having the MMU
|
||||||
|
@@ turned on, this restores the last bits from the
|
||||||
|
@@ stack
|
||||||
|
resume_with_mmu:
|
||||||
|
mov r0, #1
|
||||||
|
ldmfd sp!, { r4 - r12, pc }
|
||||||
|
|
||||||
|
.ltorg
|
||||||
|
|
||||||
|
@@ the next bits sit in the .data segment, even though they
|
||||||
|
@@ happen to be code... the s3c2410_sleep_save_phys needs to be
|
||||||
|
@@ accessed by the resume code before it can restore the MMU.
|
||||||
|
@@ This means that the variable has to be close enough for the
|
||||||
|
@@ code to read it... since the .text segment needs to be RO,
|
||||||
|
@@ the data segment can be the only place to put this code.
|
||||||
|
|
||||||
|
.data
|
||||||
|
|
||||||
|
.global s3c2410_sleep_save_phys
|
||||||
|
s3c2410_sleep_save_phys:
|
||||||
|
.word 0
|
||||||
|
|
||||||
|
/* s3c2410_cpu_resume
|
||||||
|
*
|
||||||
|
* resume code entry for bootloader to call
|
||||||
|
*
|
||||||
|
* we must put this code here in the data segment as we have no
|
||||||
|
* other way of restoring the stack pointer after sleep, and we
|
||||||
|
* must not write to the code segment (code is read-only)
|
||||||
|
*/
|
||||||
|
|
||||||
|
ENTRY(s3c2410_cpu_resume)
|
||||||
|
mov r0, #PSR_I_BIT | PSR_F_BIT | SVC_MODE
|
||||||
|
msr cpsr_c, r0
|
||||||
|
|
||||||
|
@@ load UART to allow us to print the two characters for
|
||||||
|
@@ resume debug
|
||||||
|
|
||||||
|
mov r2, #S3C24XX_PA_UART & 0xff000000
|
||||||
|
orr r2, r2, #S3C24XX_PA_UART & 0xff000
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/* SMDK2440 LED set */
|
||||||
|
mov r14, #S3C24XX_PA_GPIO
|
||||||
|
ldr r12, [ r14, #0x54 ]
|
||||||
|
bic r12, r12, #3<<4
|
||||||
|
orr r12, r12, #1<<7
|
||||||
|
str r12, [ r14, #0x54 ]
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_DEBUG_RESUME
|
||||||
|
mov r3, #'L'
|
||||||
|
strb r3, [ r2, #S3C2410_UTXH ]
|
||||||
|
1001:
|
||||||
|
ldrb r14, [ r3, #S3C2410_UTRSTAT ]
|
||||||
|
tst r14, #S3C2410_UTRSTAT_TXE
|
||||||
|
beq 1001b
|
||||||
|
#endif /* CONFIG_DEBUG_RESUME */
|
||||||
|
|
||||||
|
mov r1, #0
|
||||||
|
mcr p15, 0, r1, c8, c7, 0 @@ invalidate I & D TLBs
|
||||||
|
mcr p15, 0, r1, c7, c7, 0 @@ invalidate I & D caches
|
||||||
|
|
||||||
|
ldr r0, s3c2410_sleep_save_phys @ address of restore block
|
||||||
|
ldmia r0, { r4 - r13 }
|
||||||
|
|
||||||
|
mcr p15, 0, r4, c15, c1, 0 @ CP access register
|
||||||
|
mcr p15, 0, r5, c13, c0, 0 @ PID
|
||||||
|
mcr p15, 0, r6, c3, c0, 0 @ Domain ID
|
||||||
|
mcr p15, 0, r7, c2, c0, 0 @ translation table base
|
||||||
|
|
||||||
|
#ifdef CONFIG_DEBUG_RESUME
|
||||||
|
mov r3, #'R'
|
||||||
|
strb r3, [ r2, #S3C2410_UTXH ]
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ldr r2, =resume_with_mmu
|
||||||
|
mcr p15, 0, r8, c1, c0, 0 @ turn on MMU, etc
|
||||||
|
nop @ second-to-last before mmu
|
||||||
|
mov pc, r2 @ go back to virtual address
|
||||||
|
|
||||||
|
.ltorg
|
|
@ -1,4 +1,4 @@
|
||||||
/* linux/arch/arm/mach-s3c2410/time.c
|
/* linux/arch/arm/plat-s3c24xx/time.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2003-2005 Simtec Electronics
|
* Copyright (C) 2003-2005 Simtec Electronics
|
||||||
* Ben Dooks, <ben@simtec.co.uk>
|
* Ben Dooks, <ben@simtec.co.uk>
|
||||||
|
@ -37,8 +37,8 @@
|
||||||
#include <asm/arch/regs-irq.h>
|
#include <asm/arch/regs-irq.h>
|
||||||
#include <asm/mach/time.h>
|
#include <asm/mach/time.h>
|
||||||
|
|
||||||
#include "clock.h"
|
#include <asm/plat-s3c24xx/clock.h>
|
||||||
#include "cpu.h"
|
#include <asm/plat-s3c24xx/cpu.h>
|
||||||
|
|
||||||
static unsigned long timer_startval;
|
static unsigned long timer_startval;
|
||||||
static unsigned long timer_usec_ticks;
|
static unsigned long timer_usec_ticks;
|
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/* linux/include/asm-arm/plat-s3c24xx/clock.h
|
||||||
* linux/arch/arm/mach-s3c2410/clock.h
|
* linux/arch/arm/mach-s3c2410/clock.h
|
||||||
*
|
*
|
||||||
* Copyright (c) 2004-2005 Simtec Electronics
|
* Copyright (c) 2004-2005 Simtec Electronics
|
|
@ -1,4 +1,4 @@
|
||||||
/* linux/arch/arm/mach-s3c2410/common-smdk.h
|
/* linux/include/asm-arm/plat-s3c24xx/common-smdk.h
|
||||||
*
|
*
|
||||||
* Copyright (c) 2006 Simtec Electronics
|
* Copyright (c) 2006 Simtec Electronics
|
||||||
* Ben Dooks <ben@simtec.co.uk>
|
* Ben Dooks <ben@simtec.co.uk>
|
|
@ -1,4 +1,4 @@
|
||||||
/* arch/arm/mach-s3c2410/cpu.h
|
/* linux/include/asm-arm/plat-s3c24xx/cpu.h
|
||||||
*
|
*
|
||||||
* Copyright (c) 2004-2005 Simtec Electronics
|
* Copyright (c) 2004-2005 Simtec Electronics
|
||||||
* Ben Dooks <ben@simtec.co.uk>
|
* Ben Dooks <ben@simtec.co.uk>
|
|
@ -1,4 +1,4 @@
|
||||||
/* arch/arm/mach-s3c2410/devs.h
|
/* linux/include/asm-arm/plat-s3c24xx/devs.h
|
||||||
*
|
*
|
||||||
* Copyright (c) 2004 Simtec Electronics
|
* Copyright (c) 2004 Simtec Electronics
|
||||||
* Ben Dooks <ben@simtec.co.uk>
|
* Ben Dooks <ben@simtec.co.uk>
|
|
@ -1,4 +1,4 @@
|
||||||
/* arch/arm/mach-s3c2410/dma.h
|
/* linux/include/asm-arm/plat-s3c24xx/dma.h
|
||||||
*
|
*
|
||||||
* Copyright (C) 2006 Simtec Electronics
|
* Copyright (C) 2006 Simtec Electronics
|
||||||
* Ben Dooks <ben@simtec.co.uk>
|
* Ben Dooks <ben@simtec.co.uk>
|
|
@ -1,4 +1,4 @@
|
||||||
/* arch/arm/mach-s3c2410/irq.h
|
/* linux/include/asm-arm/plat-s3c24xx/irq.h
|
||||||
*
|
*
|
||||||
* Copyright (c) 2004-2005 Simtec Electronics
|
* Copyright (c) 2004-2005 Simtec Electronics
|
||||||
* Ben Dooks <ben@simtec.co.uk>
|
* Ben Dooks <ben@simtec.co.uk>
|
|
@ -1,4 +1,4 @@
|
||||||
/* linux/arch/arm/mach-s3c2410/pm.h
|
/* linux/include/asm-arm/plat-s3c24xx/pm.h
|
||||||
*
|
*
|
||||||
* Copyright (c) 2004 Simtec Electronics
|
* Copyright (c) 2004 Simtec Electronics
|
||||||
* Written by Ben Dooks, <ben@simtec.co.uk>
|
* Written by Ben Dooks, <ben@simtec.co.uk>
|
|
@ -1,4 +1,4 @@
|
||||||
/* arch/arm/mach-s3c2410/s3c2400.h
|
/* linux/include/asm-arm/plat-s3c24xx/s3c2400.h
|
||||||
*
|
*
|
||||||
* Copyright (c) 2004 Simtec Electronics
|
* Copyright (c) 2004 Simtec Electronics
|
||||||
* Ben Dooks <ben@simtec.co.uk>
|
* Ben Dooks <ben@simtec.co.uk>
|
|
@ -1,4 +1,4 @@
|
||||||
/* arch/arm/mach-s3c2410/s3c2410.h
|
/* linux/include/asm-arm/plat-s3c24xx/s3c2410.h
|
||||||
*
|
*
|
||||||
* Copyright (c) 2004 Simtec Electronics
|
* Copyright (c) 2004 Simtec Electronics
|
||||||
* Ben Dooks <ben@simtec.co.uk>
|
* Ben Dooks <ben@simtec.co.uk>
|
|
@ -1,4 +1,4 @@
|
||||||
/* arch/arm/mach-s3c2410/s3c2412.h
|
/* linux/include/asm-arm/plat-s3c24xx/s3c2412.h
|
||||||
*
|
*
|
||||||
* Copyright (c) 2006 Simtec Electronics
|
* Copyright (c) 2006 Simtec Electronics
|
||||||
* Ben Dooks <ben@simtec.co.uk>
|
* Ben Dooks <ben@simtec.co.uk>
|
|
@ -1,4 +1,4 @@
|
||||||
/* arch/arm/mach-s3c2410/s3c2440.h
|
/* linux/include/asm-arm/plat-s3c24xx/s3c2440.h
|
||||||
*
|
*
|
||||||
* Copyright (c) 2004-2005 Simtec Electronics
|
* Copyright (c) 2004-2005 Simtec Electronics
|
||||||
* Ben Dooks <ben@simtec.co.uk>
|
* Ben Dooks <ben@simtec.co.uk>
|
|
@ -1,4 +1,4 @@
|
||||||
/* arch/arm/mach-s3c2410/s3c2442.h
|
/* linux/include/asm-arm/plat-s3c24xx/s3c2442.h
|
||||||
*
|
*
|
||||||
* Copyright (c) 2006 Simtec Electronics
|
* Copyright (c) 2006 Simtec Electronics
|
||||||
* Ben Dooks <ben@simtec.co.uk>
|
* Ben Dooks <ben@simtec.co.uk>
|
Loading…
Reference in New Issue