Merge branch 'master' of /home/trondmy/kernel/linux-2.6/

Conflicts:

	include/linux/nfs_fs.h

Fixed up conflict with kernel header updates.
This commit is contained in:
Trond Myklebust 2006-06-20 20:46:21 -04:00
commit 70ac4385a1
1170 changed files with 25359 additions and 10569 deletions

View file

@ -0,0 +1,61 @@
README on the ADC/Touchscreen Controller
========================================
The LH79524 and LH7A404 include a built-in Analog to Digital
controller (ADC) that is used to process input from a touchscreen.
The driver only implements a four-wire touch panel protocol.
The touchscreen driver is maintenance free except for the pen-down or
touch threshold. Some resistive displays and board combinations may
require tuning of this threshold. The driver exposes some of it's
internal state in the sys filesystem. If the kernel is configured
with it, CONFIG_SYSFS, and sysfs is mounted at /sys, there will be a
directory
/sys/devices/platform/adc-lh7.0
containing these files.
-r--r--r-- 1 root root 4096 Jan 1 00:00 samples
-rw-r--r-- 1 root root 4096 Jan 1 00:00 threshold
-r--r--r-- 1 root root 4096 Jan 1 00:00 threshold_range
The threshold is the current touch threshold. It defaults to 750 on
most targets.
# cat threshold
750
The threshold_range contains the range of valid values for the
threshold. Values outside of this range will be silently ignored.
# cat threshold_range
0 1023
To change the threshold, write a value to the threshold file.
# echo 500 > threshold
# cat threshold
500
The samples file contains the most recently sampled values from the
ADC. There are 12. Below are typical of the last sampled values when
the pen has been released. The first two and last two samples are for
detecting whether or not the pen is down. The third through sixth are
X coordinate samples. The seventh through tenth are Y coordinate
samples.
# cat samples
1023 1023 0 0 0 0 530 529 530 529 1023 1023
To determine a reasonable threshold, press on the touch panel with an
appropriate stylus and read the values from samples.
# cat samples
1023 676 92 103 101 102 855 919 922 922 1023 679
The first and eleventh samples are discarded. Thus, the important
values are the second and twelfth which are used to determine if the
pen is down. When both are below the threshold, the driver registers
that the pen is down. When either is above the threshold, it
registers then pen is up.

View file

@ -0,0 +1,59 @@
README on the LCD Panels
========================
Configuration options for several LCD panels, available from Logic PD,
are included in the kernel source. This README will help you
understand the configuration data and give you some guidance for
adding support for other panels if you wish.
lcd-panels.h
------------
There is no way, at present, to detect which panel is attached to the
system at runtime. Thus the kernel configuration is static. The file
arch/arm/mach-ld7a40x/lcd-panels.h (or similar) defines all of the
panel specific parameters.
It should be possible for this data to be shared among several device
families. The current layout may be insufficiently general, but it is
amenable to improvement.
PIXEL_CLOCK
-----------
The panel data sheets will give a range of acceptable pixel clocks.
The fundamental LCDCLK input frequency is divided down by a PCD
constant in field '.tim2'. It may happen that it is impossible to set
the pixel clock within this range. A clock which is too slow will
tend to flicker. For the highest quality image, set the clock as high
as possible.
MARGINS
-------
These values may be difficult to glean from the panel data sheet. In
the case of the Sharp panels, the upper margin is explicitly called
out as a specific number of lines from the top of the frame. The
other values may not matter as much as the panels tend to
automatically center the image.
Sync Sense
----------
The sense of the hsync and vsync pulses may be called out in the data
sheet. On one panel, the sense of these pulses determine the height
of the visible region on the panel. Most of the Sharp panels use
negative sense sync pulses set by the TIM2_IHS and TIM2_IVS bits in
'.tim2'.
Pel Layout
----------
The Sharp color TFT panels are all configured for 16 bit direct color
modes. The amba-lcd driver sets the pel mode to 565 for 5 bits of
each red and blue and 6 bits of green.

View file

@ -69,17 +69,135 @@ Prototypes:
int inotify_rm_watch (int fd, __u32 mask);
(iii) Internal Kernel Implementation
(iii) Kernel Interface
Each inotify instance is associated with an inotify_device structure.
Inotify's kernel API consists a set of functions for managing watches and an
event callback.
To use the kernel API, you must first initialize an inotify instance with a set
of inotify_operations. You are given an opaque inotify_handle, which you use
for any further calls to inotify.
struct inotify_handle *ih = inotify_init(my_event_handler);
You must provide a function for processing events and a function for destroying
the inotify watch.
void handle_event(struct inotify_watch *watch, u32 wd, u32 mask,
u32 cookie, const char *name, struct inode *inode)
watch - the pointer to the inotify_watch that triggered this call
wd - the watch descriptor
mask - describes the event that occurred
cookie - an identifier for synchronizing events
name - the dentry name for affected files in a directory-based event
inode - the affected inode in a directory-based event
void destroy_watch(struct inotify_watch *watch)
You may add watches by providing a pre-allocated and initialized inotify_watch
structure and specifying the inode to watch along with an inotify event mask.
You must pin the inode during the call. You will likely wish to embed the
inotify_watch structure in a structure of your own which contains other
information about the watch. Once you add an inotify watch, it is immediately
subject to removal depending on filesystem events. You must grab a reference if
you depend on the watch hanging around after the call.
inotify_init_watch(&my_watch->iwatch);
inotify_get_watch(&my_watch->iwatch); // optional
s32 wd = inotify_add_watch(ih, &my_watch->iwatch, inode, mask);
inotify_put_watch(&my_watch->iwatch); // optional
You may use the watch descriptor (wd) or the address of the inotify_watch for
other inotify operations. You must not directly read or manipulate data in the
inotify_watch. Additionally, you must not call inotify_add_watch() more than
once for a given inotify_watch structure, unless you have first called either
inotify_rm_watch() or inotify_rm_wd().
To determine if you have already registered a watch for a given inode, you may
call inotify_find_watch(), which gives you both the wd and the watch pointer for
the inotify_watch, or an error if the watch does not exist.
wd = inotify_find_watch(ih, inode, &watchp);
You may use container_of() on the watch pointer to access your own data
associated with a given watch. When an existing watch is found,
inotify_find_watch() bumps the refcount before releasing its locks. You must
put that reference with:
put_inotify_watch(watchp);
Call inotify_find_update_watch() to update the event mask for an existing watch.
inotify_find_update_watch() returns the wd of the updated watch, or an error if
the watch does not exist.
wd = inotify_find_update_watch(ih, inode, mask);
An existing watch may be removed by calling either inotify_rm_watch() or
inotify_rm_wd().
int ret = inotify_rm_watch(ih, &my_watch->iwatch);
int ret = inotify_rm_wd(ih, wd);
A watch may be removed while executing your event handler with the following:
inotify_remove_watch_locked(ih, iwatch);
Call inotify_destroy() to remove all watches from your inotify instance and
release it. If there are no outstanding references, inotify_destroy() will call
your destroy_watch op for each watch.
inotify_destroy(ih);
When inotify removes a watch, it sends an IN_IGNORED event to your callback.
You may use this event as an indication to free the watch memory. Note that
inotify may remove a watch due to filesystem events, as well as by your request.
If you use IN_ONESHOT, inotify will remove the watch after the first event, at
which point you may call the final inotify_put_watch.
(iv) Kernel Interface Prototypes
struct inotify_handle *inotify_init(struct inotify_operations *ops);
inotify_init_watch(struct inotify_watch *watch);
s32 inotify_add_watch(struct inotify_handle *ih,
struct inotify_watch *watch,
struct inode *inode, u32 mask);
s32 inotify_find_watch(struct inotify_handle *ih, struct inode *inode,
struct inotify_watch **watchp);
s32 inotify_find_update_watch(struct inotify_handle *ih,
struct inode *inode, u32 mask);
int inotify_rm_wd(struct inotify_handle *ih, u32 wd);
int inotify_rm_watch(struct inotify_handle *ih,
struct inotify_watch *watch);
void inotify_remove_watch_locked(struct inotify_handle *ih,
struct inotify_watch *watch);
void inotify_destroy(struct inotify_handle *ih);
void get_inotify_watch(struct inotify_watch *watch);
void put_inotify_watch(struct inotify_watch *watch);
(v) Internal Kernel Implementation
Each inotify instance is represented by an inotify_handle structure.
Inotify's userspace consumers also have an inotify_device which is
associated with the inotify_handle, and on which events are queued.
Each watch is associated with an inotify_watch structure. Watches are chained
off of each associated device and each associated inode.
off of each associated inotify_handle and each associated inode.
See fs/inotify.c for the locking and lifetime rules.
See fs/inotify.c and fs/inotify_user.c for the locking and lifetime rules.
(iv) Rationale
(vi) Rationale
Q: What is the design decision behind not tying the watch to the open fd of
the watched object?
@ -145,7 +263,7 @@ A: The poor user-space interface is the second biggest problem with dnotify.
file descriptor-based one that allows basic file I/O and poll/select.
Obtaining the fd and managing the watches could have been done either via a
device file or a family of new system calls. We decided to implement a
family of system calls because that is the preffered approach for new kernel
family of system calls because that is the preferred approach for new kernel
interfaces. The only real difference was whether we wanted to use open(2)
and ioctl(2) or a couple of new system calls. System calls beat ioctls.

View file

@ -1843,12 +1843,12 @@ S: linux-scsi@vger.kernel.org
W: http://megaraid.lsilogic.com
S: Maintained
MEMORY TECHNOLOGY DEVICES
MEMORY TECHNOLOGY DEVICES (MTD)
P: David Woodhouse
M: dwmw2@infradead.org
W: http://www.linux-mtd.infradead.org/
L: linux-mtd@lists.infradead.org
T: git kernel.org:/pub/scm/linux/kernel/git/tglx/mtd-2.6.git
T: git git://git.infradead.org/mtd-2.6.git
S: Maintained
MICROTEK X6 SCANNER
@ -1895,7 +1895,7 @@ L: linux-kernel@vger.kernel.org
W: http://www.atnf.csiro.au/~rgooch/linux/kernel-patches.html
S: Maintained
MULTIMEDIA CARD SUBSYSTEM
MULTIMEDIA CARD (MMC) SUBSYSTEM
P: Russell King
M: rmk+mmc@arm.linux.org.uk
S: Maintained

View file

@ -270,6 +270,11 @@ config ARCH_AT91RM9200
Say Y here if you intend to run this kernel on an Atmel
AT91RM9200-based board.
config ARCH_PNX4008
bool "Philips Nexperia PNX4008 Mobile"
help
This enables support for Philips PNX4008 mobile platform.
endchoice
source "arch/arm/mach-clps711x/Kconfig"

View file

@ -116,6 +116,7 @@ endif
machine-$(CONFIG_ARCH_REALVIEW) := realview
machine-$(CONFIG_ARCH_AT91RM9200) := at91rm9200
machine-$(CONFIG_ARCH_EP93XX) := ep93xx
machine-$(CONFIG_ARCH_PNX4008) := pnx4008
ifeq ($(CONFIG_ARCH_EBSA110),y)
# This is what happens if you forget the IOCS16 line.

View file

@ -605,8 +605,8 @@ proc_types:
b __armv4_mmu_cache_off
b __armv4_mmu_cache_flush
.word 0x00070000 @ ARMv6
.word 0x000f0000
.word 0x0007b000 @ ARMv6
.word 0x0007f000
b __armv4_mmu_cache_on
b __armv4_mmu_cache_off
b __armv6_mmu_cache_flush

View file

@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.12-rc1-bk2
# Mon Mar 28 00:06:33 2005
# Linux kernel version: 2.6.12
# Thu Nov 3 14:15:32 2005
#
CONFIG_ARM=y
CONFIG_MMU=y
@ -17,6 +17,7 @@ CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
CONFIG_LOCK_KERNEL=y
CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
@ -36,6 +37,8 @@ CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_ALL is not set
# CONFIG_KALLSYMS_EXTRA_PASS is not set
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
# CONFIG_EPOLL is not set
@ -71,6 +74,7 @@ CONFIG_BASE_SMALL=0
# CONFIG_ARCH_SA1100 is not set
# CONFIG_ARCH_S3C2410 is not set
# CONFIG_ARCH_SHARK is not set
# CONFIG_ARCH_LH7952X is not set
CONFIG_ARCH_LH7A40X=y
# CONFIG_ARCH_OMAP is not set
# CONFIG_ARCH_VERSATILE is not set
@ -84,6 +88,7 @@ CONFIG_ARCH_LH7A40X=y
CONFIG_MACH_LPD7A400=y
# CONFIG_MACH_LPD7A404 is not set
CONFIG_ARCH_LH7A400=y
CONFIG_LPD7A40X_CPLD_SSP=y
# CONFIG_LH7A40X_CONTIGMEM is not set
# CONFIG_LH7A40X_ONE_BANK_PER_NODE is not set
@ -110,6 +115,8 @@ CONFIG_ARM_THUMB=y
#
# Bus support
#
CONFIG_ARM_AMBA=y
CONFIG_ISA_DMA_API=y
#
# PCCARD (PCMCIA/CardBus) support
@ -119,6 +126,7 @@ CONFIG_ARM_THUMB=y
#
# Kernel Features
#
# CONFIG_SMP is not set
CONFIG_PREEMPT=y
CONFIG_DISCONTIGMEM=y
CONFIG_ALIGNMENT_TRAP=y
@ -175,7 +183,7 @@ CONFIG_MTD=y
# CONFIG_MTD_CONCAT is not set
CONFIG_MTD_PARTITIONS=y
# CONFIG_MTD_REDBOOT_PARTS is not set
# CONFIG_MTD_CMDLINE_PARTS is not set
CONFIG_MTD_CMDLINE_PARTS=y
# CONFIG_MTD_AFS_PARTS is not set
#
@ -217,7 +225,10 @@ CONFIG_MTD_CFI_UTIL=y
# Mapping drivers for chip access
#
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
# CONFIG_MTD_PHYSMAP is not set
CONFIG_MTD_PHYSMAP=y
CONFIG_MTD_PHYSMAP_START=0x00000000
CONFIG_MTD_PHYSMAP_LEN=0x04000000
CONFIG_MTD_PHYSMAP_BANKWIDTH=4
# CONFIG_MTD_ARM_INTEGRATOR is not set
# CONFIG_MTD_EDB7312 is not set
@ -254,7 +265,6 @@ CONFIG_MTD_CFI_UTIL=y
#
# Block devices
#
# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_DEV_COW_COMMON is not set
CONFIG_BLK_DEV_LOOP=y
# CONFIG_BLK_DEV_CRYPTOLOOP is not set
@ -288,13 +298,15 @@ CONFIG_BLK_DEV_IDEDISK=y
# CONFIG_BLK_DEV_IDECD is not set
# CONFIG_BLK_DEV_IDETAPE is not set
# CONFIG_BLK_DEV_IDEFLOPPY is not set
# CONFIG_BLK_DEV_IDESCSI is not set
# CONFIG_IDE_TASK_IOCTL is not set
CONFIG_IDE_POLL=y
#
# IDE chipset support/bugfixes
#
CONFIG_IDE_GENERIC=y
# CONFIG_IDE_ARM is not set
CONFIG_IDE_ARM=y
# CONFIG_BLK_DEV_IDEDMA is not set
# CONFIG_IDEDMA_AUTO is not set
# CONFIG_BLK_DEV_HD is not set
@ -302,7 +314,37 @@ CONFIG_IDE_GENERIC=y
#
# SCSI device support
#
# CONFIG_SCSI is not set
CONFIG_SCSI=y
# CONFIG_SCSI_PROC_FS is not set
#
# SCSI support type (disk, tape, CD-ROM)
#
# CONFIG_BLK_DEV_SD is not set
# CONFIG_CHR_DEV_ST is not set
# CONFIG_CHR_DEV_OSST is not set
# CONFIG_BLK_DEV_SR is not set
# CONFIG_CHR_DEV_SG is not set
#
# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
#
# CONFIG_SCSI_MULTI_LUN is not set
# CONFIG_SCSI_CONSTANTS is not set
# CONFIG_SCSI_LOGGING is not set
#
# SCSI Transport Attributes
#
# CONFIG_SCSI_SPI_ATTRS is not set
# CONFIG_SCSI_FC_ATTRS is not set
# CONFIG_SCSI_ISCSI_ATTRS is not set
#
# SCSI low-level drivers
#
# CONFIG_SCSI_SATA is not set
# CONFIG_SCSI_DEBUG is not set
#
# Multi-device support (RAID and LVM)
@ -331,7 +373,6 @@ CONFIG_NET=y
#
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
# CONFIG_NETLINK_DEV is not set
CONFIG_UNIX=y
# CONFIG_NET_KEY is not set
CONFIG_INET=y
@ -438,13 +479,10 @@ CONFIG_INPUT=y
#
# Userland interfaces
#
CONFIG_INPUT_MOUSEDEV=y
CONFIG_INPUT_MOUSEDEV_PSAUX=y
CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_MOUSEDEV is not set
# CONFIG_INPUT_JOYDEV is not set
# CONFIG_INPUT_TSDEV is not set
# CONFIG_INPUT_EVDEV is not set
CONFIG_INPUT_EVDEV=y
# CONFIG_INPUT_EVBUG is not set
#
@ -453,7 +491,13 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_KEYBOARD is not set
# CONFIG_INPUT_MOUSE is not set
# CONFIG_INPUT_JOYSTICK is not set
# CONFIG_INPUT_TOUCHSCREEN is not set
CONFIG_INPUT_TOUCHSCREEN=y
# CONFIG_TOUCHSCREEN_GUNZE is not set
# CONFIG_TOUCHSCREEN_ELO is not set
# CONFIG_TOUCHSCREEN_MTOUCH is not set
# CONFIG_TOUCHSCREEN_MK712 is not set
CONFIG_TOUCHSCREEN_ADS7843_LH7=y
CONFIG_HAS_TOUCHSCREEN_ADS7843_LH7=y
# CONFIG_INPUT_MISC is not set
#
@ -461,7 +505,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
#
# CONFIG_SERIO is not set
# CONFIG_GAMEPORT is not set
CONFIG_SOUND_GAMEPORT=y
#
# Character devices
@ -479,6 +522,8 @@ CONFIG_HW_CONSOLE=y
#
# Non-8250 serial port support
#
# CONFIG_SERIAL_AMBA_PL010 is not set
# CONFIG_SERIAL_AMBA_PL011 is not set
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
CONFIG_SERIAL_LH7A40X=y
@ -510,7 +555,6 @@ CONFIG_RTC=y
#
# TPM devices
#
# CONFIG_TCG_TPM is not set
#
# I2C support
@ -534,18 +578,73 @@ CONFIG_RTC=y
#
# Graphics support
#
# CONFIG_FB is not set
CONFIG_FB=y
CONFIG_FB_CFB_FILLRECT=y
CONFIG_FB_CFB_COPYAREA=y
CONFIG_FB_CFB_IMAGEBLIT=y
CONFIG_FB_SOFT_CURSOR=y
# CONFIG_FB_MACMODES is not set
# CONFIG_FB_MODE_HELPERS is not set
# CONFIG_FB_TILEBLITTING is not set
CONFIG_FB_ARMCLCD=y
CONFIG_FB_ARMCLCD_SHARP_LQ035Q7DB02_HRTFT=y
# CONFIG_FB_ARMCLCD_SHARP_LQ057Q3DC02 is not set
# CONFIG_FB_ARMCLCD_SHARP_LQ64D343 is not set
# CONFIG_FB_ARMCLCD_SHARP_LQ10D368 is not set
# CONFIG_FB_ARMCLCD_SHARP_LQ121S1DG41 is not set
# CONFIG_FB_S1D13XXX is not set
# CONFIG_FB_VIRTUAL is not set
#
# Console display driver support
#
# CONFIG_VGA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
# CONFIG_FRAMEBUFFER_CONSOLE is not set
#
# Logo configuration
#
# CONFIG_LOGO is not set
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
#
# CONFIG_SOUND is not set
CONFIG_SOUND=y
#
# Advanced Linux Sound Architecture
#
CONFIG_SND=y
CONFIG_SND_TIMER=y
CONFIG_SND_PCM=y
# CONFIG_SND_SEQUENCER is not set
CONFIG_SND_OSSEMUL=y
CONFIG_SND_MIXER_OSS=y
CONFIG_SND_PCM_OSS=y
# CONFIG_SND_RTCTIMER is not set
# CONFIG_SND_VERBOSE_PRINTK is not set
# CONFIG_SND_DEBUG is not set
#
# Generic devices
#
# CONFIG_SND_DUMMY is not set
# CONFIG_SND_MTPAV is not set
# CONFIG_SND_SERIAL_U16550 is not set
# CONFIG_SND_MPU401 is not set
CONFIG_SND_AC97_CODEC=y
#
# ALSA ARM devices
#
CONFIG_SND_LH7A40X_AC97=y
#
# Open Sound System
#
# CONFIG_SOUND_PRIME is not set
#
# USB support

View file

@ -1,58 +1,81 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.12-rc1-bk2
# Mon Mar 28 00:14:08 2005
# Linux kernel version: 2.6.16
# Thu Mar 23 17:50:31 2006
#
CONFIG_ARM=y
CONFIG_MMU=y
CONFIG_UID16=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_GENERIC_IOMAP=y
#
# Code maturity level options
#
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
CONFIG_LOCK_KERNEL=y
CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
CONFIG_LOCALVERSION_AUTO=y
# CONFIG_SWAP is not set
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
# CONFIG_HOTPLUG is not set
CONFIG_KOBJECT_UEVENT=y
CONFIG_IKCONFIG=y
# CONFIG_IKCONFIG_PROC is not set
CONFIG_INITRAMFS_SOURCE=""
CONFIG_UID16=y
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_ALL is not set
# CONFIG_KALLSYMS_EXTRA_PASS is not set
# CONFIG_HOTPLUG is not set
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
# CONFIG_EPOLL is not set
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SHMEM=y
CONFIG_CC_ALIGN_FUNCTIONS=0
CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
CONFIG_SLAB=y
# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
# CONFIG_SLOB is not set
CONFIG_OBSOLETE_INTERMODULE=y
#
# Loadable module support
#
# CONFIG_MODULES is not set
#
# Block layer
#
#
# IO Schedulers
#
CONFIG_IOSCHED_NOOP=y
# CONFIG_IOSCHED_AS is not set
# CONFIG_IOSCHED_DEADLINE is not set
CONFIG_IOSCHED_CFQ=y
# CONFIG_DEFAULT_AS is not set
# CONFIG_DEFAULT_DEADLINE is not set
CONFIG_DEFAULT_CFQ=y
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="cfq"
#
# System Type
#
@ -71,11 +94,15 @@ CONFIG_BASE_SMALL=0
# CONFIG_ARCH_SA1100 is not set
# CONFIG_ARCH_S3C2410 is not set
# CONFIG_ARCH_SHARK is not set
# CONFIG_ARCH_LH7952X is not set
CONFIG_ARCH_LH7A40X=y
# CONFIG_ARCH_OMAP is not set
# CONFIG_ARCH_VERSATILE is not set
# CONFIG_ARCH_REALVIEW is not set
# CONFIG_ARCH_IMX is not set
# CONFIG_ARCH_H720X is not set
# CONFIG_ARCH_AAEC2000 is not set
# CONFIG_ARCH_AT91RM9200 is not set
#
# LH7A40X Implementations
@ -110,6 +137,7 @@ CONFIG_ARM_THUMB=y
#
# Bus support
#
CONFIG_ARM_AMBA=y
#
# PCCARD (PCMCIA/CardBus) support
@ -120,7 +148,18 @@ CONFIG_ARM_THUMB=y
# Kernel Features
#
CONFIG_PREEMPT=y
# CONFIG_NO_IDLE_HZ is not set
# CONFIG_AEABI is not set
CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
CONFIG_SELECT_MEMORY_MODEL=y
# CONFIG_FLATMEM_MANUAL is not set
CONFIG_DISCONTIGMEM_MANUAL=y
# CONFIG_SPARSEMEM_MANUAL is not set
CONFIG_DISCONTIGMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
CONFIG_NEED_MULTIPLE_NODES=y
# CONFIG_SPARSEMEM_STATIC is not set
CONFIG_SPLIT_PTLOCK_CPUS=4096
CONFIG_ALIGNMENT_TRAP=y
#
@ -154,6 +193,84 @@ CONFIG_BINFMT_ELF=y
# Power management options
#
# CONFIG_PM is not set
# CONFIG_APM is not set
#
# Networking
#
CONFIG_NET=y
#
# Networking options
#
# CONFIG_NETDEBUG is not set
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
# CONFIG_NET_KEY is not set
CONFIG_INET=y
# CONFIG_IP_MULTICAST is not set
# CONFIG_IP_ADVANCED_ROUTER is not set
CONFIG_IP_FIB_HASH=y
CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=y
CONFIG_IP_PNP_BOOTP=y
CONFIG_IP_PNP_RARP=y
# CONFIG_NET_IPIP is not set
# CONFIG_NET_IPGRE is not set
# CONFIG_ARPD is not set
# CONFIG_SYN_COOKIES is not set
# CONFIG_INET_AH is not set
# CONFIG_INET_ESP is not set
# CONFIG_INET_IPCOMP is not set
# CONFIG_INET_TUNNEL is not set
CONFIG_INET_DIAG=y
CONFIG_INET_TCP_DIAG=y
# CONFIG_TCP_CONG_ADVANCED is not set
CONFIG_TCP_CONG_BIC=y
# CONFIG_IPV6 is not set
# CONFIG_NETFILTER is not set
#
# DCCP Configuration (EXPERIMENTAL)
#
# CONFIG_IP_DCCP is not set
#
# SCTP Configuration (EXPERIMENTAL)
#
# CONFIG_IP_SCTP is not set
#
# TIPC Configuration (EXPERIMENTAL)
#
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
# CONFIG_VLAN_8021Q is not set
# CONFIG_DECNET is not set
# CONFIG_LLC2 is not set
# CONFIG_IPX is not set
# CONFIG_ATALK is not set
# CONFIG_X25 is not set
# CONFIG_LAPB is not set
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
#
# QoS and/or fair queueing
#
# CONFIG_NET_SCHED is not set
#
# Network testing
#
# CONFIG_NET_PKTGEN is not set
# CONFIG_HAMRADIO is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_IEEE80211 is not set
#
# Device Drivers
@ -167,6 +284,11 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
# CONFIG_DEBUG_DRIVER is not set
#
# Connector - unified userspace <-> kernelspace linker
#
# CONFIG_CONNECTOR is not set
#
# Memory Technology Devices (MTD)
#
@ -175,7 +297,7 @@ CONFIG_MTD=y
# CONFIG_MTD_CONCAT is not set
CONFIG_MTD_PARTITIONS=y
# CONFIG_MTD_REDBOOT_PARTS is not set
# CONFIG_MTD_CMDLINE_PARTS is not set
CONFIG_MTD_CMDLINE_PARTS=y
# CONFIG_MTD_AFS_PARTS is not set
#
@ -186,6 +308,7 @@ CONFIG_MTD_BLOCK=y
# CONFIG_FTL is not set
# CONFIG_NFTL is not set
# CONFIG_INFTL is not set
# CONFIG_RFD_FTL is not set
#
# RAM/ROM/Flash chip drivers
@ -211,15 +334,18 @@ CONFIG_MTD_CFI_UTIL=y
# CONFIG_MTD_RAM is not set
# CONFIG_MTD_ROM is not set
# CONFIG_MTD_ABSENT is not set
# CONFIG_MTD_XIP is not set
# CONFIG_MTD_OBSOLETE_CHIPS is not set
#
# Mapping drivers for chip access
#
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
# CONFIG_MTD_PHYSMAP is not set
CONFIG_MTD_PHYSMAP=y
CONFIG_MTD_PHYSMAP_START=0x00000000
CONFIG_MTD_PHYSMAP_LEN=0x04000000
CONFIG_MTD_PHYSMAP_BANKWIDTH=4
# CONFIG_MTD_ARM_INTEGRATOR is not set
# CONFIG_MTD_EDB7312 is not set
# CONFIG_MTD_PLATRAM is not set
#
# Self-contained MTD device drivers
@ -242,6 +368,11 @@ CONFIG_MTD_CFI_UTIL=y
#
# CONFIG_MTD_NAND is not set
#
# OneNAND Flash Device Drivers
#
# CONFIG_MTD_ONENAND is not set
#
# Parallel port support
#
@ -254,7 +385,6 @@ CONFIG_MTD_CFI_UTIL=y
#
# Block devices
#
# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_DEV_COW_COMMON is not set
CONFIG_BLK_DEV_LOOP=y
# CONFIG_BLK_DEV_CRYPTOLOOP is not set
@ -262,16 +392,7 @@ CONFIG_BLK_DEV_LOOP=y
# CONFIG_BLK_DEV_UB is not set
# CONFIG_BLK_DEV_RAM is not set
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_INITRAMFS_SOURCE=""
# CONFIG_CDROM_PKTCDVD is not set
#
# IO Schedulers
#
CONFIG_IOSCHED_NOOP=y
# CONFIG_IOSCHED_AS is not set
# CONFIG_IOSCHED_DEADLINE is not set
CONFIG_IOSCHED_CFQ=y
# CONFIG_ATA_OVER_ETH is not set
#
@ -291,12 +412,13 @@ CONFIG_BLK_DEV_IDEDISK=y
# CONFIG_BLK_DEV_IDEFLOPPY is not set
# CONFIG_BLK_DEV_IDESCSI is not set
# CONFIG_IDE_TASK_IOCTL is not set
CONFIG_IDE_POLL=y
#
# IDE chipset support/bugfixes
#
CONFIG_IDE_GENERIC=y
# CONFIG_IDE_ARM is not set
CONFIG_IDE_ARM=y
# CONFIG_BLK_DEV_IDEDMA is not set
# CONFIG_IDEDMA_AUTO is not set
# CONFIG_BLK_DEV_HD is not set
@ -304,6 +426,7 @@ CONFIG_IDE_GENERIC=y
#
# SCSI device support
#
# CONFIG_RAID_ATTRS is not set
CONFIG_SCSI=y
# CONFIG_SCSI_PROC_FS is not set
@ -315,6 +438,7 @@ CONFIG_SCSI=y
# CONFIG_CHR_DEV_OSST is not set
# CONFIG_BLK_DEV_SR is not set
# CONFIG_CHR_DEV_SG is not set
# CONFIG_CHR_DEV_SCH is not set
#
# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
@ -329,10 +453,12 @@ CONFIG_SCSI=y
# CONFIG_SCSI_SPI_ATTRS is not set
# CONFIG_SCSI_FC_ATTRS is not set
# CONFIG_SCSI_ISCSI_ATTRS is not set
# CONFIG_SCSI_SAS_ATTRS is not set
#
# SCSI low-level drivers
#
# CONFIG_ISCSI_TCP is not set
# CONFIG_SCSI_SATA is not set
# CONFIG_SCSI_DEBUG is not set
@ -344,6 +470,7 @@ CONFIG_SCSI=y
#
# Fusion MPT device support
#
# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
@ -354,82 +481,26 @@ CONFIG_SCSI=y
#
#
# Networking support
# Network device support
#
CONFIG_NET=y
#
# Networking options
#
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
# CONFIG_NETLINK_DEV is not set
CONFIG_UNIX=y
# CONFIG_NET_KEY is not set
CONFIG_INET=y
# CONFIG_IP_MULTICAST is not set
# CONFIG_IP_ADVANCED_ROUTER is not set
CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=y
CONFIG_IP_PNP_BOOTP=y
CONFIG_IP_PNP_RARP=y
# CONFIG_NET_IPIP is not set
# CONFIG_NET_IPGRE is not set
# CONFIG_ARPD is not set
# CONFIG_SYN_COOKIES is not set
# CONFIG_INET_AH is not set
# CONFIG_INET_ESP is not set
# CONFIG_INET_IPCOMP is not set
# CONFIG_INET_TUNNEL is not set
# CONFIG_IP_TCPDIAG is not set
# CONFIG_IP_TCPDIAG_IPV6 is not set
# CONFIG_IPV6 is not set
# CONFIG_NETFILTER is not set
#
# SCTP Configuration (EXPERIMENTAL)
#
# CONFIG_IP_SCTP is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
# CONFIG_VLAN_8021Q is not set
# CONFIG_DECNET is not set
# CONFIG_LLC2 is not set
# CONFIG_IPX is not set
# CONFIG_ATALK is not set
# CONFIG_X25 is not set
# CONFIG_LAPB is not set
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
#
# QoS and/or fair queueing
#
# CONFIG_NET_SCHED is not set
# CONFIG_NET_CLS_ROUTE is not set
#
# Network testing
#
# CONFIG_NET_PKTGEN is not set
# CONFIG_NETPOLL is not set
# CONFIG_NET_POLL_CONTROLLER is not set
# CONFIG_HAMRADIO is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
CONFIG_NETDEVICES=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
#
# PHY device support
#
# CONFIG_PHYLIB is not set
#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
CONFIG_MII=y
CONFIG_SMC91X=y
# CONFIG_DM9000 is not set
#
# Ethernet (1000 Mbit)
@ -456,6 +527,8 @@ CONFIG_SMC91X=y
# CONFIG_SLIP is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
# CONFIG_NETPOLL is not set
# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@ -470,10 +543,13 @@ CONFIG_INPUT=y
#
# Userland interfaces
#
# CONFIG_INPUT_MOUSEDEV is not set
CONFIG_INPUT_MOUSEDEV=y
# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_JOYDEV is not set
# CONFIG_INPUT_TSDEV is not set
# CONFIG_INPUT_EVDEV is not set
CONFIG_INPUT_EVDEV=y
# CONFIG_INPUT_EVBUG is not set
#
@ -482,7 +558,13 @@ CONFIG_INPUT=y
# CONFIG_INPUT_KEYBOARD is not set
# CONFIG_INPUT_MOUSE is not set
# CONFIG_INPUT_JOYSTICK is not set
# CONFIG_INPUT_TOUCHSCREEN is not set
CONFIG_INPUT_TOUCHSCREEN=y
# CONFIG_TOUCHSCREEN_GUNZE is not set
# CONFIG_TOUCHSCREEN_ELO is not set
# CONFIG_TOUCHSCREEN_MTOUCH is not set
# CONFIG_TOUCHSCREEN_MK712 is not set
CONFIG_TOUCHSCREEN_ADC_LH7=y
CONFIG_HAS_TOUCHSCREEN_ADC_LH7=y
# CONFIG_INPUT_MISC is not set
#
@ -490,7 +572,6 @@ CONFIG_INPUT=y
#
# CONFIG_SERIO is not set
# CONFIG_GAMEPORT is not set
CONFIG_SOUND_GAMEPORT=y
#
# Character devices
@ -508,6 +589,8 @@ CONFIG_HW_CONSOLE=y
#
# Non-8250 serial port support
#
# CONFIG_SERIAL_AMBA_PL010 is not set
# CONFIG_SERIAL_AMBA_PL011 is not set
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
CONFIG_SERIAL_LH7A40X=y
@ -533,23 +616,46 @@ CONFIG_RTC=y
#
# Ftape, the floppy tape device driver
#
# CONFIG_DRM is not set
# CONFIG_RAW_DRIVER is not set
#
# TPM devices
#
# CONFIG_TCG_TPM is not set
# CONFIG_TELCLOCK is not set
#
# I2C support
#
# CONFIG_I2C is not set
#
# SPI support
#
# CONFIG_SPI is not set
# CONFIG_SPI_MASTER is not set
#
# Dallas's 1-wire bus
#
# CONFIG_W1 is not set
#
# Hardware Monitoring support
#
CONFIG_HWMON=y
# CONFIG_HWMON_VID is not set
# CONFIG_SENSORS_F71805F is not set
# CONFIG_HWMON_DEBUG_CHIP is not set
#
# Misc devices
#
#
# Multimedia Capabilities Port drivers
#
#
# Multimedia devices
#
@ -563,18 +669,83 @@ CONFIG_RTC=y
#
# Graphics support
#
# CONFIG_FB is not set
CONFIG_FB=y
CONFIG_FB_CFB_FILLRECT=y
CONFIG_FB_CFB_COPYAREA=y
CONFIG_FB_CFB_IMAGEBLIT=y
# CONFIG_FB_MACMODES is not set
# CONFIG_FB_MODE_HELPERS is not set
# CONFIG_FB_TILEBLITTING is not set
CONFIG_FB_ARMCLCD=y
CONFIG_FB_ARMCLCD_SHARP_LQ035Q7DB02_HRTFT=y
# CONFIG_FB_ARMCLCD_SHARP_LQ057Q3DC02 is not set
# CONFIG_FB_ARMCLCD_SHARP_LQ64D343 is not set
# CONFIG_FB_ARMCLCD_SHARP_LQ10D368 is not set
# CONFIG_FB_ARMCLCD_SHARP_LQ121S1DG41 is not set
# CONFIG_FB_ARMCLCD_AUO_A070VW01_WIDE is not set
# CONFIG_FB_ARMCLCD_HITACHI is not set
# CONFIG_FB_S1D13XXX is not set
# CONFIG_FB_VIRTUAL is not set
#
# Console display driver support
#
# CONFIG_VGA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
# CONFIG_FRAMEBUFFER_CONSOLE is not set
#
# Logo configuration
#
# CONFIG_LOGO is not set
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
#
# CONFIG_SOUND is not set
CONFIG_SOUND=y
#
# Advanced Linux Sound Architecture
#
CONFIG_SND=y
CONFIG_SND_TIMER=y
CONFIG_SND_PCM=y
# CONFIG_SND_SEQUENCER is not set
CONFIG_SND_OSSEMUL=y
CONFIG_SND_MIXER_OSS=y
CONFIG_SND_PCM_OSS=y
# CONFIG_SND_RTCTIMER is not set
# CONFIG_SND_DYNAMIC_MINORS is not set
CONFIG_SND_SUPPORT_OLD_API=y
# CONFIG_SND_VERBOSE_PRINTK is not set
# CONFIG_SND_DEBUG is not set
#
# Generic devices
#
CONFIG_SND_AC97_CODEC=y
CONFIG_SND_AC97_BUS=y
# CONFIG_SND_DUMMY is not set
# CONFIG_SND_MTPAV is not set
# CONFIG_SND_SERIAL_U16550 is not set
# CONFIG_SND_MPU401 is not set
#
# ALSA ARM devices
#
# CONFIG_SND_ARMAACI is not set
CONFIG_SND_LH7A40X_AC97=y
#
# USB devices
#
# CONFIG_SND_USB_AUDIO is not set
#
# Open Sound System
#
# CONFIG_SOUND_PRIME is not set
#
# USB support
@ -595,6 +766,7 @@ CONFIG_USB_DEVICEFS=y
#
# USB Host Controller Drivers
#
# CONFIG_USB_ISP116X_HCD is not set
CONFIG_USB_OHCI_HCD=y
# CONFIG_USB_OHCI_BIG_ENDIAN is not set
CONFIG_USB_OHCI_LITTLE_ENDIAN=y
@ -603,16 +775,19 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
#
# USB Device Class drivers
#
# CONFIG_USB_BLUETOOTH_TTY is not set
# CONFIG_OBSOLETE_OSS_USB_DRIVER is not set
# CONFIG_USB_ACM is not set
# CONFIG_USB_PRINTER is not set
#
# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
#
#
# may also be needed; see USB_STORAGE Help for more information
#
CONFIG_USB_STORAGE=y
CONFIG_USB_STORAGE_DEBUG=y
# CONFIG_USB_STORAGE_RW_DETECT is not set
CONFIG_USB_STORAGE_DATAFAB=y
# CONFIG_USB_STORAGE_FREECOM is not set
# CONFIG_USB_STORAGE_ISD200 is not set
@ -621,22 +796,32 @@ CONFIG_USB_STORAGE_DATAFAB=y
# CONFIG_USB_STORAGE_SDDR09 is not set
# CONFIG_USB_STORAGE_SDDR55 is not set
# CONFIG_USB_STORAGE_JUMPSHOT is not set
# CONFIG_USB_STORAGE_ALAUDA is not set
# CONFIG_USB_STORAGE_ONETOUCH is not set
# CONFIG_USB_LIBUSUAL is not set
#
# USB Input Devices
#
CONFIG_USB_HID=y
CONFIG_USB_HIDINPUT=y
# CONFIG_USB_HIDINPUT_POWERBOOK is not set
# CONFIG_HID_FF is not set
# CONFIG_USB_HIDDEV is not set
# CONFIG_USB_AIPTEK is not set
# CONFIG_USB_WACOM is not set
# CONFIG_USB_ACECAD is not set
# CONFIG_USB_KBTAB is not set
# CONFIG_USB_POWERMATE is not set
# CONFIG_USB_MTOUCH is not set
# CONFIG_USB_ITMTOUCH is not set
# CONFIG_USB_EGALAX is not set
# CONFIG_USB_YEALINK is not set
# CONFIG_USB_XPAD is not set
# CONFIG_USB_ATI_REMOTE is not set
# CONFIG_USB_ATI_REMOTE2 is not set
# CONFIG_USB_KEYSPAN_REMOTE is not set
# CONFIG_USB_APPLETOUCH is not set
#
# USB Imaging devices
@ -686,16 +871,33 @@ CONFIG_USB_MON=y
# CONFIG_USB_PHIDGETKIT is not set
# CONFIG_USB_PHIDGETSERVO is not set
# CONFIG_USB_IDMOUSE is not set
# CONFIG_USB_LD is not set
# CONFIG_USB_TEST is not set
#
# USB ATM/DSL drivers
# USB DSL modem support
#
#
# USB Gadget Support
#
# CONFIG_USB_GADGET is not set
CONFIG_USB_GADGET=y
# CONFIG_USB_GADGET_DEBUG_FILES is not set
CONFIG_USB_GADGET_SELECTED=y
# CONFIG_USB_GADGET_NET2280 is not set
# CONFIG_USB_GADGET_PXA2XX is not set
# CONFIG_USB_GADGET_GOKU is not set
# CONFIG_USB_GADGET_LH7A40X is not set
CONFIG_USB_GADGET_LH7=y
CONFIG_USB_LH7=y
# CONFIG_USB_GADGET_OMAP is not set
# CONFIG_USB_GADGET_DUMMY_HCD is not set
# CONFIG_USB_GADGET_DUALSPEED is not set
CONFIG_USB_ZERO=y
# CONFIG_USB_ETH is not set
# CONFIG_USB_GADGETFS is not set
# CONFIG_USB_FILE_STORAGE is not set
# CONFIG_USB_G_SERIAL is not set
#
# MMC/SD Card support
@ -707,6 +909,7 @@ CONFIG_USB_MON=y
#
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
CONFIG_EXT3_FS_XATTR=y
# CONFIG_EXT3_FS_POSIX_ACL is not set
@ -716,17 +919,17 @@ CONFIG_JBD=y
CONFIG_FS_MBCACHE=y
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
#
# XFS support
#
# CONFIG_FS_POSIX_ACL is not set
# CONFIG_XFS_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
# CONFIG_FUSE_FS is not set
#
# CD-ROM/DVD Filesystems
@ -749,12 +952,11 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
#
CONFIG_PROC_FS=y
CONFIG_SYSFS=y
# CONFIG_DEVFS_FS is not set
# CONFIG_DEVPTS_FS_XATTR is not set
CONFIG_TMPFS=y
# CONFIG_TMPFS_XATTR is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
# CONFIG_RELAYFS_FS is not set
# CONFIG_CONFIGFS_FS is not set
#
# Miscellaneous filesystems
@ -769,8 +971,8 @@ CONFIG_RAMFS=y
# CONFIG_JFFS_FS is not set
CONFIG_JFFS2_FS=y
CONFIG_JFFS2_FS_DEBUG=0
# CONFIG_JFFS2_FS_NAND is not set
# CONFIG_JFFS2_FS_NOR_ECC is not set
CONFIG_JFFS2_FS_WRITEBUFFER=y
# CONFIG_JFFS2_SUMMARY is not set
# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
CONFIG_JFFS2_ZLIB=y
CONFIG_JFFS2_RTIME=y
@ -787,12 +989,14 @@ CONFIG_CRAMFS=y
#
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
# CONFIG_NFS_V3_ACL is not set
# CONFIG_NFS_V4 is not set
# CONFIG_NFS_DIRECTIO is not set
# CONFIG_NFSD is not set
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
@ -801,6 +1005,7 @@ CONFIG_SUNRPC=y
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
# CONFIG_9P_FS is not set
#
# Partition Types
@ -820,6 +1025,7 @@ CONFIG_MSDOS_PARTITION=y
# CONFIG_SGI_PARTITION is not set
# CONFIG_ULTRIX_PARTITION is not set
# CONFIG_SUN_PARTITION is not set
# CONFIG_KARMA_PARTITION is not set
# CONFIG_EFI_PARTITION is not set
#
@ -875,19 +1081,24 @@ CONFIG_NLS_DEFAULT="iso8859-1"
# Kernel hacking
#
# CONFIG_PRINTK_TIME is not set
CONFIG_DEBUG_KERNEL=y
CONFIG_MAGIC_SYSRQ=y
CONFIG_LOG_BUF_SHIFT=14
CONFIG_DEBUG_KERNEL=y
CONFIG_LOG_BUF_SHIFT=16
CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_DEBUG_SLAB is not set
CONFIG_DEBUG_PREEMPT=y
CONFIG_DEBUG_MUTEXES=y
# CONFIG_DEBUG_SPINLOCK is not set
# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
# CONFIG_DEBUG_KOBJECT is not set
CONFIG_DEBUG_BUGVERBOSE=y
CONFIG_DEBUG_INFO=y
# CONFIG_DEBUG_FS is not set
# CONFIG_DEBUG_VM is not set
CONFIG_FRAME_POINTER=y
CONFIG_FORCED_INLINING=y
# CONFIG_RCU_TORTURE_TEST is not set
CONFIG_DEBUG_USER=y
# CONFIG_DEBUG_WAITQ is not set
CONFIG_DEBUG_ERRORS=y
@ -912,6 +1123,7 @@ CONFIG_DEBUG_ERRORS=y
# Library routines
#
# CONFIG_CRC_CCITT is not set
# CONFIG_CRC16 is not set
CONFIG_CRC32=y
# CONFIG_LIBCRC32C is not set
CONFIG_ZLIB_INFLATE=y

File diff suppressed because it is too large Load diff

View file

@ -271,7 +271,7 @@ ENTRY(sys_call_table)
@ r8 = syscall table
.type sys_syscall, #function
sys_syscall:
eor scno, r0, #__NR_OABI_SYSCALL_BASE
bic scno, r0, #__NR_OABI_SYSCALL_BASE
cmp scno, #__NR_syscall - __NR_SYSCALL_BASE
cmpne scno, #NR_syscalls @ check range
stmloia sp, {r5, r6} @ shuffle args

View file

@ -342,10 +342,10 @@ __do_irq(unsigned int irq, struct irqaction *action, struct pt_regs *regs)
#ifdef CONFIG_NO_IDLE_HZ
if (!(action->flags & SA_TIMER) && system_timer->dyn_tick != NULL) {
write_seqlock(&xtime_lock);
spin_lock(&system_timer->dyn_tick->lock);
if (system_timer->dyn_tick->state & DYN_TICK_ENABLED)
system_timer->dyn_tick->handler(irq, 0, regs);
write_sequnlock(&xtime_lock);
spin_unlock(&system_timer->dyn_tick->lock);
}
#endif

View file

@ -379,7 +379,7 @@ static int timer_dyn_tick_enable(void)
int ret = -ENODEV;
if (dyn_tick) {
write_seqlock_irqsave(&xtime_lock, flags);
spin_lock_irqsave(&dyn_tick->lock, flags);
ret = 0;
if (!(dyn_tick->state & DYN_TICK_ENABLED)) {
ret = dyn_tick->enable();
@ -387,7 +387,7 @@ static int timer_dyn_tick_enable(void)
if (ret == 0)
dyn_tick->state |= DYN_TICK_ENABLED;
}
write_sequnlock_irqrestore(&xtime_lock, flags);
spin_unlock_irqrestore(&dyn_tick->lock, flags);
}
return ret;
@ -400,7 +400,7 @@ static int timer_dyn_tick_disable(void)
int ret = -ENODEV;
if (dyn_tick) {
write_seqlock_irqsave(&xtime_lock, flags);
spin_lock_irqsave(&dyn_tick->lock, flags);
ret = 0;
if (dyn_tick->state & DYN_TICK_ENABLED) {
ret = dyn_tick->disable();
@ -408,7 +408,7 @@ static int timer_dyn_tick_disable(void)
if (ret == 0)
dyn_tick->state &= ~DYN_TICK_ENABLED;
}
write_sequnlock_irqrestore(&xtime_lock, flags);
spin_unlock_irqrestore(&dyn_tick->lock, flags);
}
return ret;
@ -422,15 +422,20 @@ static int timer_dyn_tick_disable(void)
void timer_dyn_reprogram(void)
{
struct dyn_tick_timer *dyn_tick = system_timer->dyn_tick;
unsigned long next, seq;
unsigned long next, seq, flags;
if (dyn_tick && (dyn_tick->state & DYN_TICK_ENABLED)) {
if (!dyn_tick)
return;
spin_lock_irqsave(&dyn_tick->lock, flags);
if (dyn_tick->state & DYN_TICK_ENABLED) {
next = next_timer_interrupt();
do {
seq = read_seqbegin(&xtime_lock);
dyn_tick->reprogram(next_timer_interrupt() - jiffies);
dyn_tick->reprogram(next - jiffies);
} while (read_seqretry(&xtime_lock, seq));
}
spin_unlock_irqrestore(&dyn_tick->lock, flags);
}
static ssize_t timer_show_dyn_tick(struct sys_device *dev, char *buf)
@ -499,5 +504,10 @@ void __init time_init(void)
if (system_timer->offset == NULL)
system_timer->offset = dummy_gettimeoffset;
system_timer->init();
#ifdef CONFIG_NO_IDLE_HZ
if (system_timer->dyn_tick)
system_timer->dyn_tick->lock = SPIN_LOCK_UNLOCKED;
#endif
}

View file

@ -14,6 +14,7 @@ config MACH_LPD7A400
bool "LPD7A400 Card Engine"
select ARCH_LH7A400
# select IDE_POLL
select HAS_TOUCHSCREEN_ADS7843_LH7
help
Say Y here if you are using Logic Product Development's
LPD7A400 CardEngine. For the time being, the LPD7A400 and
@ -23,6 +24,7 @@ config MACH_LPD7A404
bool "LPD7A404 Card Engine"
select ARCH_LH7A404
# select IDE_POLL
select HAS_TOUCHSCREEN_ADC_LH7
help
Say Y here if you are using Logic Product Development's
LPD7A404 CardEngine. For the time being, the LPD7A400 and
@ -34,6 +36,9 @@ config ARCH_LH7A400
config ARCH_LH7A404
bool
config LPD7A40X_CPLD_SSP
bool
config LH7A40X_CONTIGMEM
bool "Disable NUMA Support"
depends on ARCH_LH7A40X

View file

@ -4,11 +4,14 @@
# Object file lists.
obj-y := time.o
obj-$(CONFIG_MACH_KEV7A400) += arch-kev7a400.o irq-lh7a400.o
obj-$(CONFIG_MACH_LPD7A400) += arch-lpd7a40x.o irq-lh7a400.o
obj-$(CONFIG_MACH_LPD7A404) += arch-lpd7a40x.o irq-lh7a404.o
obj-y := time.o clocks.o
obj-m :=
obj-n :=
obj- :=
obj-$(CONFIG_MACH_KEV7A400) += arch-kev7a400.o irq-lh7a400.o
obj-$(CONFIG_MACH_LPD7A400) += arch-lpd7a40x.o irq-lh7a400.o
obj-$(CONFIG_MACH_LPD7A404) += arch-lpd7a40x.o irq-lh7a404.o
obj-$(CONFIG_LPD7A40X_CPLD_SSP) += ssp-cpld.o
obj-$(CONFIG_FB_ARMCLCD) += clcd.o
obj-m :=
obj-n :=
obj- :=

View file

@ -23,6 +23,28 @@
#include "common.h"
#define CPLD_INT_NETHERNET (1<<0)
#define CPLD_INTMASK_ETHERNET (1<<2)
#if defined (CONFIG_MACH_LPD7A400)
# define CPLD_INT_NTOUCH (1<<1)
# define CPLD_INTMASK_TOUCH (1<<3)
# define CPLD_INT_PEN (1<<4)
# define CPLD_INTMASK_PEN (1<<4)
# define CPLD_INT_PIRQ (1<<4)
#endif
#define CPLD_INTMASK_CPLD (1<<7)
#define CPLD_INT_CPLD (1<<6)
#define CPLD_CONTROL_SWINT (1<<7) /* Disable all CPLD IRQs */
#define CPLD_CONTROL_OCMSK (1<<6) /* Mask USB1 connect IRQ */
#define CPLD_CONTROL_PDRV (1<<5) /* PCC_nDRV high */
#define CPLD_CONTROL_USB1C (1<<4) /* USB1 connect IRQ active */
#define CPLD_CONTROL_USB1P (1<<3) /* USB1 power disable */
#define CPLD_CONTROL_AWKP (1<<2) /* Auto-wakeup disabled */
#define CPLD_CONTROL_LCD_ENABLE (1<<1) /* LCD Vee enable */
#define CPLD_CONTROL_WRLAN_NENABLE (1<<0) /* SMC91x power disable */
static struct resource smc91x_resources[] = {
[0] = {
.start = CPLD00_PHYS,
@ -48,12 +70,12 @@ static struct platform_device smc91x_device = {
static struct resource lh7a40x_usbclient_resources[] = {
[0] = {
.start = USB_PHYS,
.end = (USB_PHYS + 0xFF),
.end = (USB_PHYS + PAGE_SIZE),
.flags = IORESOURCE_MEM,
},
[1] = {
.start = IRQ_USBINTR,
.end = IRQ_USBINTR,
.start = IRQ_USB,
.end = IRQ_USB,
.flags = IORESOURCE_IRQ,
},
};
@ -61,7 +83,8 @@ static struct resource lh7a40x_usbclient_resources[] = {
static u64 lh7a40x_usbclient_dma_mask = 0xffffffffUL;
static struct platform_device lh7a40x_usbclient_device = {
.name = "lh7a40x_udc",
// .name = "lh7a40x_udc",
.name = "lh7-udc",
.id = 0,
.dev = {
.dma_mask = &lh7a40x_usbclient_dma_mask,
@ -101,7 +124,7 @@ static struct platform_device lh7a404_usbhost_device = {
#endif
static struct platform_device *lpd7a40x_devs[] __initdata = {
static struct platform_device* lpd7a40x_devs[] __initdata = {
&smc91x_device,
&lh7a40x_usbclient_device,
#if defined (CONFIG_ARCH_LH7A404)
@ -113,29 +136,52 @@ extern void lpd7a400_map_io (void);
static void __init lpd7a40x_init (void)
{
CPLD_CONTROL |= (1<<6); /* Mask USB1 connection IRQ */
#if defined (CONFIG_MACH_LPD7A400)
CPLD_CONTROL |= 0
| CPLD_CONTROL_SWINT /* Disable software interrupt */
| CPLD_CONTROL_OCMSK; /* Mask USB1 connection IRQ */
CPLD_CONTROL &= ~(0
| (1<<1) /* Disable LCD */
| (1<<0) /* Enable WLAN */
| CPLD_CONTROL_LCD_ENABLE /* Disable LCD */
| CPLD_CONTROL_WRLAN_NENABLE /* Enable SMC91x */
);
#endif
#if defined (CONFIG_MACH_LPD7A404)
CPLD_CONTROL &= ~(0
| CPLD_CONTROL_WRLAN_NENABLE /* Enable SMC91x */
);
#endif
platform_add_devices (lpd7a40x_devs, ARRAY_SIZE (lpd7a40x_devs));
#if defined (CONFIG_FB_ARMCLCD)
lh7a40x_clcd_init ();
#endif
}
static void lh7a40x_ack_cpld_irq (u32 irq)
{
/* CPLD doesn't have ack capability */
/* CPLD doesn't have ack capability, but some devices may */
#if defined (CPLD_INTMASK_TOUCH)
/* The touch control *must* mask the the interrupt because the
* interrupt bit is read by the driver to determine if the pen
* is still down. */
if (irq == IRQ_TOUCH)
CPLD_INTERRUPTS |= CPLD_INTMASK_TOUCH;
#endif
}
static void lh7a40x_mask_cpld_irq (u32 irq)
{
switch (irq) {
case IRQ_LPD7A40X_ETH_INT:
CPLD_INTERRUPTS = CPLD_INTERRUPTS | 0x4;
CPLD_INTERRUPTS |= CPLD_INTMASK_ETHERNET;
break;
case IRQ_LPD7A400_TS:
CPLD_INTERRUPTS = CPLD_INTERRUPTS | 0x8;
#if defined (IRQ_TOUCH)
case IRQ_TOUCH:
CPLD_INTERRUPTS |= CPLD_INTMASK_TOUCH;
break;
#endif
}
}
@ -143,11 +189,13 @@ static void lh7a40x_unmask_cpld_irq (u32 irq)
{
switch (irq) {
case IRQ_LPD7A40X_ETH_INT:
CPLD_INTERRUPTS = CPLD_INTERRUPTS & ~ 0x4;
CPLD_INTERRUPTS &= ~CPLD_INTMASK_ETHERNET;
break;
case IRQ_LPD7A400_TS:
CPLD_INTERRUPTS = CPLD_INTERRUPTS & ~ 0x8;
#if defined (IRQ_TOUCH)
case IRQ_TOUCH:
CPLD_INTERRUPTS &= ~CPLD_INTMASK_TOUCH;
break;
#endif
}
}
@ -164,11 +212,13 @@ static void lpd7a40x_cpld_handler (unsigned int irq, struct irqdesc *desc,
desc->chip->ack (irq);
if ((mask & 0x1) == 0) /* WLAN */
if ((mask & (1<<0)) == 0) /* WLAN */
IRQ_DISPATCH (IRQ_LPD7A40X_ETH_INT);
if ((mask & 0x2) == 0) /* Touch */
IRQ_DISPATCH (IRQ_LPD7A400_TS);
#if defined (IRQ_TOUCH)
if ((mask & (1<<1)) == 0) /* Touch */
IRQ_DISPATCH (IRQ_TOUCH);
#endif
desc->chip->unmask (irq); /* Level-triggered need this */
}
@ -204,9 +254,21 @@ void __init lh7a40x_init_board_irq (void)
/* Then, configure CPLD interrupt */
CPLD_INTERRUPTS = 0x9c; /* Disable all CPLD interrupts */
/* Disable all CPLD interrupts */
#if defined (CONFIG_MACH_LPD7A400)
CPLD_INTERRUPTS = CPLD_INTMASK_TOUCH | CPLD_INTMASK_PEN
| CPLD_INTMASK_ETHERNET;
/* *** FIXME: don't know why we need 7 and 4. 7 is way wrong
and 4 is uncefined. */
// (1<<7)|(1<<4)|(1<<3)|(1<<2);
#endif
#if defined (CONFIG_MACH_LPD7A404)
CPLD_INTERRUPTS = CPLD_INTMASK_ETHERNET;
/* *** FIXME: don't know why we need 6 and 5, neither is defined. */
// (1<<6)|(1<<5)|(1<<3);
#endif
GPIO_PFDD &= ~(1 << pinCPLD); /* Make input */
GPIO_INTTYPE1 |= (1 << pinCPLD); /* Edge triggered */
GPIO_INTTYPE1 &= ~(1 << pinCPLD); /* Level triggered */
GPIO_INTTYPE2 &= ~(1 << pinCPLD); /* Active low */
barrier ();
GPIO_GPIOFINTEN |= (1 << pinCPLD); /* Enable */
@ -216,7 +278,7 @@ void __init lh7a40x_init_board_irq (void)
for (irq = IRQ_BOARD_START;
irq < IRQ_BOARD_START + NR_IRQ_BOARD; ++irq) {
set_irq_chip (irq, &lpd7a40x_cpld_chip);
set_irq_handler (irq, do_edge_IRQ);
set_irq_handler (irq, do_level_IRQ);
set_irq_flags (irq, IRQF_VALID);
}
@ -226,91 +288,109 @@ void __init lh7a40x_init_board_irq (void)
lpd7a40x_cpld_handler);
}
static struct map_desc lpd7a400_io_desc[] __initdata = {
static struct map_desc lpd7a40x_io_desc[] __initdata = {
{
.virtual = IO_VIRT,
.virtual = IO_VIRT,
.pfn = __phys_to_pfn(IO_PHYS),
.length = IO_SIZE,
.length = IO_SIZE,
.type = MT_DEVICE
}, { /* Mapping added to work around chip select problems */
},
{ /* Mapping added to work around chip select problems */
.virtual = IOBARRIER_VIRT,
.pfn = __phys_to_pfn(IOBARRIER_PHYS),
.length = IOBARRIER_SIZE,
.type = MT_DEVICE
}, {
},
{
.virtual = CF_VIRT,
.pfn = __phys_to_pfn(CF_PHYS),
.length = CF_SIZE,
.type = MT_DEVICE
}, {
.virtual = CPLD02_VIRT,
.pfn = __phys_to_pfn(CPLD02_PHYS),
.length = CPLD02_SIZE,
.type = MT_DEVICE
}, {
.virtual = CPLD06_VIRT,
.pfn = __phys_to_pfn(CPLD06_PHYS),
.length = CPLD06_SIZE,
.type = MT_DEVICE
}, {
.virtual = CPLD08_VIRT,
.pfn = __phys_to_pfn(CPLD08_PHYS),
.length = CPLD08_SIZE,
.type = MT_DEVICE
}, {
.virtual = CPLD0C_VIRT,
.pfn = __phys_to_pfn(CPLD0C_PHYS),
.length = CPLD0C_SIZE,
.type = MT_DEVICE
}, {
.virtual = CPLD0E_VIRT,
.pfn = __phys_to_pfn(CPLD0E_PHYS),
.length = CPLD0E_SIZE,
.type = MT_DEVICE
}, {
.virtual = CPLD10_VIRT,
.pfn = __phys_to_pfn(CPLD10_PHYS),
.length = CPLD10_SIZE,
.type = MT_DEVICE
}, {
.virtual = CPLD12_VIRT,
.pfn = __phys_to_pfn(CPLD12_PHYS),
.length = CPLD12_SIZE,
.type = MT_DEVICE
}, {
.virtual = CPLD14_VIRT,
.pfn = __phys_to_pfn(CPLD14_PHYS),
.length = CPLD14_SIZE,
.type = MT_DEVICE
}, {
.virtual = CPLD16_VIRT,
.pfn = __phys_to_pfn(CPLD16_PHYS),
.length = CPLD16_SIZE,
.type = MT_DEVICE
}, {
.virtual = CPLD18_VIRT,
.pfn = __phys_to_pfn(CPLD18_PHYS),
.length = CPLD18_SIZE,
.type = MT_DEVICE
}, {
.virtual = CPLD1A_VIRT,
.pfn = __phys_to_pfn(CPLD1A_PHYS),
.length = CPLD1A_SIZE,
.length = CF_SIZE,
.type = MT_DEVICE
},
{
.virtual = CPLD02_VIRT,
.pfn = __phys_to_pfn(CPLD02_PHYS),
.length = CPLD02_SIZE,
.type = MT_DEVICE
},
{
.virtual = CPLD06_VIRT,
.pfn = __phys_to_pfn(CPLD06_PHYS),
.length = CPLD06_SIZE,
.type = MT_DEVICE
},
{
.virtual = CPLD08_VIRT,
.pfn = __phys_to_pfn(CPLD08_PHYS),
.length = CPLD08_SIZE,
.type = MT_DEVICE
},
{
.virtual = CPLD08_VIRT,
.pfn = __phys_to_pfn(CPLD08_PHYS),
.length = CPLD08_SIZE,
.type = MT_DEVICE
},
{
.virtual = CPLD0A_VIRT,
.pfn = __phys_to_pfn(CPLD0A_PHYS),
.length = CPLD0A_SIZE,
.type = MT_DEVICE
},
{
.virtual = CPLD0C_VIRT,
.pfn = __phys_to_pfn(CPLD0C_PHYS),
.length = CPLD0C_SIZE,
.type = MT_DEVICE
},
{
.virtual = CPLD0E_VIRT,
.pfn = __phys_to_pfn(CPLD0E_PHYS),
.length = CPLD0E_SIZE,
.type = MT_DEVICE
},
{
.virtual = CPLD10_VIRT,
.pfn = __phys_to_pfn(CPLD10_PHYS),
.length = CPLD10_SIZE,
.type = MT_DEVICE
},
{
.virtual = CPLD12_VIRT,
.pfn = __phys_to_pfn(CPLD12_PHYS),
.length = CPLD12_SIZE,
.type = MT_DEVICE
},
{
.virtual = CPLD14_VIRT,
.pfn = __phys_to_pfn(CPLD14_PHYS),
.length = CPLD14_SIZE,
.type = MT_DEVICE
},
{
.virtual = CPLD16_VIRT,
.pfn = __phys_to_pfn(CPLD16_PHYS),
.length = CPLD16_SIZE,
.type = MT_DEVICE
},
{
.virtual = CPLD18_VIRT,
.pfn = __phys_to_pfn(CPLD18_PHYS),
.length = CPLD18_SIZE,
.type = MT_DEVICE
},
{
.virtual = CPLD1A_VIRT,
.pfn = __phys_to_pfn(CPLD1A_PHYS),
.length = CPLD1A_SIZE,
.type = MT_DEVICE
},
/* This mapping is redundant since the smc driver performs another. */
/* { CPLD00_VIRT, CPLD00_PHYS, CPLD00_SIZE, MT_DEVICE }, */
};
void __init
lpd7a400_map_io(void)
lpd7a40x_map_io(void)
{
iotable_init (lpd7a400_io_desc, ARRAY_SIZE (lpd7a400_io_desc));
/* Fixup (improve) Static Memory Controller settings */
SMC_BCR0 = 0x200039af; /* Boot Flash */
SMC_BCR6 = 0x1000fbe0; /* CPLD */
SMC_BCR7 = 0x1000b2c2; /* Compact Flash */
iotable_init (lpd7a40x_io_desc, ARRAY_SIZE (lpd7a40x_io_desc));
}
#ifdef CONFIG_MACH_LPD7A400
@ -320,7 +400,7 @@ MACHINE_START (LPD7A400, "Logic Product Development LPD7A400-10")
.phys_io = 0x80000000,
.io_pg_offst = ((io_p2v (0x80000000))>>18) & 0xfffc,
.boot_params = 0xc0000100,
.map_io = lpd7a400_map_io,
.map_io = lpd7a40x_map_io,
.init_irq = lh7a400_init_irq,
.timer = &lh7a40x_timer,
.init_machine = lpd7a40x_init,
@ -335,7 +415,7 @@ MACHINE_START (LPD7A404, "Logic Product Development LPD7A404-10")
.phys_io = 0x80000000,
.io_pg_offst = ((io_p2v (0x80000000))>>18) & 0xfffc,
.boot_params = 0xc0000100,
.map_io = lpd7a400_map_io,
.map_io = lpd7a40x_map_io,
.init_irq = lh7a404_init_irq,
.timer = &lh7a40x_timer,
.init_machine = lpd7a40x_init,

View file

@ -0,0 +1,241 @@
/*
* arch/arm/mach-lh7a40x/clcd.c
*
* Copyright (C) 2004 Marc Singer
*
* 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/config.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/dma-mapping.h>
#include <linux/sysdev.h>
#include <linux/interrupt.h>
//#include <linux/module.h>
//#include <linux/time.h>
//#include <asm/hardware.h>
//#include <asm/mach/time.h>
#include <asm/irq.h>
#include <asm/mach/irq.h>
#include <asm/system.h>
#include <asm/hardware.h>
#include <linux/amba/bus.h>
#include <linux/amba/clcd.h>
#define HRTFTC_HRSETUP __REG(HRTFTC_PHYS + 0x00)
#define HRTFTC_HRCON __REG(HRTFTC_PHYS + 0x04)
#define HRTFTC_HRTIMING1 __REG(HRTFTC_PHYS + 0x08)
#define HRTFTC_HRTIMING2 __REG(HRTFTC_PHYS + 0x0c)
#define ALI_SETUP __REG(ALI_PHYS + 0x00)
#define ALI_CONTROL __REG(ALI_PHYS + 0x04)
#define ALI_TIMING1 __REG(ALI_PHYS + 0x08)
#define ALI_TIMING2 __REG(ALI_PHYS + 0x0c)
#include "lcd-panel.h"
static void lh7a40x_clcd_disable (struct clcd_fb *fb)
{
#if defined (CONFIG_MACH_LPD7A400)
CPLD_CONTROL &= ~(1<<1); /* Disable LCD Vee */
#endif
#if defined (CONFIG_MACH_LPD7A404)
GPIO_PCD &= ~(1<<3); /* Disable LCD Vee */
#endif
#if defined (CONFIG_ARCH_LH7A400)
HRTFTC_HRSETUP &= ~(1<<13); /* Disable HRTFT controller */
#endif
#if defined (CONFIG_ARCH_LH7A404)
ALI_SETUP &= ~(1<<13); /* Disable ALI */
#endif
}
static void lh7a40x_clcd_enable (struct clcd_fb *fb)
{
struct clcd_panel_extra* extra
= (struct clcd_panel_extra*) fb->board_data;
#if defined (CONFIG_MACH_LPD7A400)
CPLD_CONTROL |= (1<<1); /* Enable LCD Vee */
#endif
#if defined (CONFIG_MACH_LPD7A404)
GPIO_PCDD &= ~(1<<3); /* Enable LCD Vee */
GPIO_PCD |= (1<<3);
#endif
#if defined (CONFIG_ARCH_LH7A400)
if (extra) {
HRTFTC_HRSETUP
= (1 << 13)
| ((fb->fb.var.xres - 1) << 4)
| 0xc
| (extra->hrmode ? 1 : 0);
HRTFTC_HRCON
= ((extra->clsen ? 1 : 0) << 1)
| ((extra->spsen ? 1 : 0) << 0);
HRTFTC_HRTIMING1
= (extra->pcdel << 8)
| (extra->revdel << 4)
| (extra->lpdel << 0);
HRTFTC_HRTIMING2
= (extra->spldel << 9)
| (extra->pc2del << 0);
}
else
HRTFTC_HRSETUP
= (1 << 13)
| 0xc;
#endif
#if defined (CONFIG_ARCH_LH7A404)
if (extra) {
ALI_SETUP
= (1 << 13)
| ((fb->fb.var.xres - 1) << 4)
| 0xc
| (extra->hrmode ? 1 : 0);
ALI_CONTROL
= ((extra->clsen ? 1 : 0) << 1)
| ((extra->spsen ? 1 : 0) << 0);
ALI_TIMING1
= (extra->pcdel << 8)
| (extra->revdel << 4)
| (extra->lpdel << 0);
ALI_TIMING2
= (extra->spldel << 9)
| (extra->pc2del << 0);
}
else
ALI_SETUP
= (1 << 13)
| 0xc;
#endif
}
#define FRAMESIZE(s) (((s) + PAGE_SIZE - 1)&PAGE_MASK)
static int lh7a40x_clcd_setup (struct clcd_fb *fb)
{
dma_addr_t dma;
u32 len = FRAMESIZE (lcd_panel.mode.xres*lcd_panel.mode.yres
*(lcd_panel.bpp/8));
fb->panel = &lcd_panel;
/* Enforce the sync polarity defaults */
if (!(fb->panel->tim2 & TIM2_IHS))
fb->fb.var.sync |= FB_SYNC_HOR_HIGH_ACT;
if (!(fb->panel->tim2 & TIM2_IVS))
fb->fb.var.sync |= FB_SYNC_VERT_HIGH_ACT;
#if defined (HAS_LCD_PANEL_EXTRA)
fb->board_data = &lcd_panel_extra;
#endif
fb->fb.screen_base
= dma_alloc_writecombine (&fb->dev->dev, len,
&dma, GFP_KERNEL);
printk ("CLCD: LCD setup fb virt 0x%p phys 0x%p l %x io 0x%p \n",
fb->fb.screen_base, (void*) dma, len,
(void*) io_p2v (CLCDC_PHYS));
printk ("CLCD: pixclock %d\n", lcd_panel.mode.pixclock);
if (!fb->fb.screen_base) {
printk(KERN_ERR "CLCD: unable to map framebuffer\n");
return -ENOMEM;
}
#if defined (USE_RGB555)
fb->fb.var.green.length = 5; /* Panel uses RGB 5:5:5 */
#endif
fb->fb.fix.smem_start = dma;
fb->fb.fix.smem_len = len;
/* Drive PE4 high to prevent CPLD crash */
GPIO_PEDD |= (1<<4);
GPIO_PED |= (1<<4);
GPIO_PINMUX |= (1<<1) | (1<<0); /* LCDVD[15:4] */
// fb->fb.fbops->fb_check_var (&fb->fb.var, &fb->fb);
// fb->fb.fbops->fb_set_par (&fb->fb);
return 0;
}
static int lh7a40x_clcd_mmap (struct clcd_fb *fb, struct vm_area_struct *vma)
{
return dma_mmap_writecombine(&fb->dev->dev, vma,
fb->fb.screen_base,
fb->fb.fix.smem_start,
fb->fb.fix.smem_len);
}
static void lh7a40x_clcd_remove (struct clcd_fb *fb)
{
dma_free_writecombine (&fb->dev->dev, fb->fb.fix.smem_len,
fb->fb.screen_base, fb->fb.fix.smem_start);
}
static struct clcd_board clcd_platform_data = {
.name = "lh7a40x FB",
.check = clcdfb_check,
.decode = clcdfb_decode,
.enable = lh7a40x_clcd_enable,
.setup = lh7a40x_clcd_setup,
.mmap = lh7a40x_clcd_mmap,
.remove = lh7a40x_clcd_remove,
.disable = lh7a40x_clcd_disable,
};
#define IRQ_CLCDC (IRQ_LCDINTR)
#define AMBA_DEVICE(name,busid,base,plat,pid) \
static struct amba_device name##_device = { \
.dev = { \
.coherent_dma_mask = ~0, \
.bus_id = busid, \
.platform_data = plat, \
}, \
.res = { \
.start = base##_PHYS, \
.end = (base##_PHYS) + (4*1024) - 1, \
.flags = IORESOURCE_MEM, \
}, \
.dma_mask = ~0, \
.irq = { IRQ_##base, }, \
/* .dma = base##_DMA,*/ \
.periphid = pid, \
}
AMBA_DEVICE(clcd, "cldc-lh7a40x", CLCDC, &clcd_platform_data, 0x41110);
static struct amba_device *amba_devs[] __initdata = {
&clcd_device,
};
void __init lh7a40x_clcd_init (void)
{
int i;
int result;
printk ("CLCD: registering amba devices\n");
for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
struct amba_device *d = amba_devs[i];
result = amba_device_register(d, &iomem_resource);
printk (" %d -> %d\n", i ,result);
}
}

View file

@ -0,0 +1,199 @@
/* arch/arm/mach-lh7a40x/clocks.c
*
* Copyright (C) 2004 Marc Singer
*
* 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/config.h>
#include <linux/cpufreq.h>
#include <asm/hardware.h>
#include <asm/arch/clocks.h>
#include <linux/err.h>
struct module;
struct icst525_params;
struct clk {
struct list_head node;
unsigned long rate;
struct module *owner;
const char *name;
// void *data;
// const struct icst525_params *params;
// void (*setvco)(struct clk *, struct icst525_vco vco);
};
int clk_register(struct clk *clk);
void clk_unregister(struct clk *clk);
/* ----- */
#define MAINDIV1(c) (((c) >> 7) & 0x0f)
#define MAINDIV2(c) (((c) >> 11) & 0x1f)
#define PS(c) (((c) >> 18) & 0x03)
#define PREDIV(c) (((c) >> 2) & 0x1f)
#define HCLKDIV(c) (((c) >> 0) & 0x02)
#define PCLKDIV(c) (((c) >> 16) & 0x03)
unsigned int cpufreq_get (unsigned int cpu) /* in kHz */
{
return fclkfreq_get ()/1000;
}
EXPORT_SYMBOL(cpufreq_get);
unsigned int fclkfreq_get (void)
{
unsigned int clkset = CSC_CLKSET;
unsigned int gclk
= XTAL_IN
/ (1 << PS(clkset))
* (MAINDIV1(clkset) + 2)
/ (PREDIV(clkset) + 2)
* (MAINDIV2(clkset) + 2)
;
return gclk;
}
unsigned int hclkfreq_get (void)
{
unsigned int clkset = CSC_CLKSET;
unsigned int hclk = fclkfreq_get () / (HCLKDIV(clkset) + 1);
return hclk;
}
unsigned int pclkfreq_get (void)
{
unsigned int clkset = CSC_CLKSET;
int pclkdiv = PCLKDIV(clkset);
unsigned int pclk;
if (pclkdiv == 0x3)
pclkdiv = 0x2;
pclk = hclkfreq_get () / (1 << pclkdiv);
return pclk;
}
/* ----- */
static LIST_HEAD(clocks);
static DECLARE_MUTEX(clocks_sem);
struct clk *clk_get (struct device *dev, const char *id)
{
struct clk *p;
struct clk *clk = ERR_PTR(-ENOENT);
down (&clocks_sem);
list_for_each_entry (p, &clocks, node) {
if (strcmp (id, p->name) == 0
&& try_module_get(p->owner)) {
clk = p;
break;
}
}
up (&clocks_sem);
return clk;
}
EXPORT_SYMBOL(clk_get);
void clk_put (struct clk *clk)
{
module_put(clk->owner);
}
EXPORT_SYMBOL(clk_put);
int clk_enable (struct clk *clk)
{
return 0;
}
EXPORT_SYMBOL(clk_enable);
void clk_disable (struct clk *clk)
{
}
EXPORT_SYMBOL(clk_disable);
int clk_use (struct clk *clk)
{
return 0;
}
EXPORT_SYMBOL(clk_use);
void clk_unuse (struct clk *clk)
{
}
EXPORT_SYMBOL(clk_unuse);
unsigned long clk_get_rate (struct clk *clk)
{
return clk->rate;
}
EXPORT_SYMBOL(clk_get_rate);
long clk_round_rate (struct clk *clk, unsigned long rate)
{
return rate;
}
EXPORT_SYMBOL(clk_round_rate);
int clk_set_rate (struct clk *clk, unsigned long rate)
{
int ret = -EIO;
return ret;
}
EXPORT_SYMBOL(clk_set_rate);
#if 0
/*
* These are fixed clocks.
*/
static struct clk kmi_clk = {
.name = "KMIREFCLK",
.rate = 24000000,
};
static struct clk uart_clk = {
.name = "UARTCLK",
.rate = 24000000,
};
static struct clk mmci_clk = {
.name = "MCLK",
.rate = 33000000,
};
#endif
static struct clk clcd_clk = {
.name = "CLCDCLK",
.rate = 0,
};
int clk_register (struct clk *clk)
{
down (&clocks_sem);
list_add (&clk->node, &clocks);
up (&clocks_sem);
return 0;
}
EXPORT_SYMBOL(clk_register);
void clk_unregister (struct clk *clk)
{
down (&clocks_sem);
list_del (&clk->node);
up (&clocks_sem);
}
EXPORT_SYMBOL(clk_unregister);
static int __init clk_init (void)
{
clk_register(&clcd_clk);
return 0;
}
arch_initcall(clk_init);

View file

@ -12,6 +12,7 @@ extern struct sys_timer lh7a40x_timer;
extern void lh7a400_init_irq (void);
extern void lh7a404_init_irq (void);
extern void lh7a40x_clcd_init (void);
extern void lh7a40x_init_board_irq (void);
#define IRQ_DISPATCH(irq) desc_handle_irq((irq),(irq_desc + irq), regs)

View file

@ -28,13 +28,17 @@
static unsigned char irq_pri_vic1[] = {
#if defined (USE_PRIORITIES)
IRQ_GPIO3INTR,
IRQ_GPIO3INTR, /* CPLD */
IRQ_DMAM2P4, IRQ_DMAM2P5, /* AC97 */
#endif
};
static unsigned char irq_pri_vic2[] = {
#if defined (USE_PRIORITIES)
IRQ_T3UI, IRQ_GPIO7INTR,
IRQ_T3UI, /* Timer */
IRQ_GPIO7INTR, /* CPLD */
IRQ_UART1INTR, IRQ_UART2INTR, IRQ_UART3INTR,
IRQ_LCDINTR, /* LCD */
IRQ_TSCINTR, /* ADC/Touchscreen */
#endif
};
@ -98,10 +102,19 @@ static struct irqchip lh7a404_gpio_vic2_chip = {
/* IRQ initialization */
#if defined (CONFIG_ARCH_LH7A400) && defined (CONFIG_ARCH_LH7A404)
extern void* branch_irq_lh7a400;
#endif
void __init lh7a404_init_irq (void)
{
int irq;
#if defined (CONFIG_ARCH_LH7A400) && defined (CONFIG_ARCH_LH7A404)
#define NOP 0xe1a00000 /* mov r0, r0 */
branch_irq_lh7a400 = NOP;
#endif
VIC1_INTENCLR = 0xffffffff;
VIC2_INTENCLR = 0xffffffff;
VIC1_INTSEL = 0; /* All IRQs */

View file

@ -0,0 +1,346 @@
/* lcd-panel.h
$Id$
written by Marc Singer
18 Jul 2005
Copyright (C) 2005 Marc Singer
-----------
DESCRIPTION
-----------
Only one panel may be defined at a time.
The pixel clock is calculated to be no greater than the target.
Each timing value is accompanied by a specification comment.
UNITS/MIN/TYP/MAX
Most of the units will be in clocks.
USE_RGB555
Define this macro to configure the AMBA LCD controller to use an
RGB555 encoding for the pels instead of the normal RGB565.
LPD9520, LPD79524, LPD7A400, LPD7A404-10, LPD7A404-11
These boards are best approximated by 555 for all panels. Some
can use an extra low-order bit of blue in bit 16 of the color
value, but we don't have a way to communicate this non-linear
mapping to the kernel.
*/
#if !defined (__LCD_PANEL_H__)
# define __LCD_PANEL_H__
#if defined (MACH_LPD79520)\
|| defined (MACH_LPD79524)\
|| defined (MACH_LPD7A400)\
|| defined (MACH_LPD7A404)
# define USE_RGB555
#endif
struct clcd_panel_extra {
unsigned int hrmode;
unsigned int clsen;
unsigned int spsen;
unsigned int pcdel;
unsigned int revdel;
unsigned int lpdel;
unsigned int spldel;
unsigned int pc2del;
};
#define NS_TO_CLOCK(ns,c) ((((ns)*((c)/1000) + (1000000 - 1))/1000000))
#define CLOCK_TO_DIV(e,c) (((c) + (e) - 1)/(e))
#if defined CONFIG_FB_ARMCLCD_SHARP_LQ035Q7DB02_HRTFT
/* Logic Product Development LCD 3.5" QVGA HRTFT -10 */
/* Sharp PN LQ035Q7DB02 w/HRTFT controller chip */
#define PIX_CLOCK_TARGET (6800000)
#define PIX_CLOCK_DIVIDER CLOCK_TO_DIV (PIX_CLOCK_TARGET, HCLK)
#define PIX_CLOCK (HCLK/PIX_CLOCK_DIVIDER)
static struct clcd_panel lcd_panel = {
.mode = {
.name = "3.5in QVGA (LQ035Q7DB02)",
.xres = 240,
.yres = 320,
.pixclock = PIX_CLOCK,
.left_margin = 16,
.right_margin = 21,
.upper_margin = 8, // line/8/8/8
.lower_margin = 5,
.hsync_len = 61,
.vsync_len = NS_TO_CLOCK (60, PIX_CLOCK),
.vmode = FB_VMODE_NONINTERLACED,
},
.width = -1,
.height = -1,
.tim2 = TIM2_IPC | (PIX_CLOCK_DIVIDER - 2),
.cntl = CNTL_LCDTFT | CNTL_WATERMARK,
.bpp = 16,
};
#define HAS_LCD_PANEL_EXTRA
static struct clcd_panel_extra lcd_panel_extra = {
.hrmode = 1,
.clsen = 1,
.spsen = 1,
.pcdel = 8,
.revdel = 7,
.lpdel = 13,
.spldel = 77,
.pc2del = 208,
};
#endif
#if defined CONFIG_FB_ARMCLCD_SHARP_LQ057Q3DC02
/* Logic Product Development LCD 5.7" QVGA -10 */
/* Sharp PN LQ057Q3DC02 */
/* QVGA mode, V/Q=LOW */
/* From Sharp on 2006.1.3. I believe some of the values are incorrect
* based on the datasheet.
Timing0 TIMING1 TIMING2 CONTROL
0x140A0C4C 0x080504EF 0x013F380D 0x00000829
HBP= 20 VBP= 8 BCD= 0
HFP= 10 VFP= 5 CPL=319
HSW= 12 VSW= 1 IOE= 0
PPL= 19 LPP=239 IPC= 1
IHS= 1
IVS= 1
ACB= 0
CSEL= 0
PCD= 13
*/
/* The full horozontal cycle (Th) is clock/360/400/450. */
/* The full vertical cycle (Tv) is line/251/262/280. */
#define PIX_CLOCK_TARGET (6300000) /* -/6.3/7 MHz */
#define PIX_CLOCK_DIVIDER CLOCK_TO_DIV (PIX_CLOCK_TARGET, HCLK)
#define PIX_CLOCK (HCLK/PIX_CLOCK_DIVIDER)
static struct clcd_panel lcd_panel = {
.mode = {
.name = "5.7in QVGA (LQ057Q3DC02)",
.xres = 320,
.yres = 240,
.pixclock = PIX_CLOCK,
.left_margin = 11,
.right_margin = 400-11-320-2,
.upper_margin = 7, // line/7/7/7
.lower_margin = 262-7-240-2,
.hsync_len = 2, // clk/2/96/200
.vsync_len = 2, // line/2/-/34
.vmode = FB_VMODE_NONINTERLACED,
},
.width = -1,
.height = -1,
.tim2 = TIM2_IHS | TIM2_IVS
| (PIX_CLOCK_DIVIDER - 2),
.cntl = CNTL_LCDTFT | CNTL_WATERMARK,
.bpp = 16,
};
#endif
#if defined CONFIG_FB_ARMCLCD_SHARP_LQ64D343
/* Logic Product Development LCD 6.4" VGA -10 */
/* Sharp PN LQ64D343 */
/* The full horozontal cycle (Th) is clock/750/800/900. */
/* The full vertical cycle (Tv) is line/515/525/560. */
#define PIX_CLOCK_TARGET (28330000)
#define PIX_CLOCK_DIVIDER CLOCK_TO_DIV (PIX_CLOCK_TARGET, HCLK)
#define PIX_CLOCK (HCLK/PIX_CLOCK_DIVIDER)
static struct clcd_panel lcd_panel = {
.mode = {
.name = "6.4in QVGA (LQ64D343)",
.xres = 640,
.yres = 480,
.pixclock = PIX_CLOCK,
.left_margin = 32,
.right_margin = 800-32-640-96,
.upper_margin = 32, // line/34/34/34
.lower_margin = 540-32-480-2,
.hsync_len = 96, // clk/2/96/200
.vsync_len = 2, // line/2/-/34
.vmode = FB_VMODE_NONINTERLACED,
},
.width = -1,
.height = -1,
.tim2 = TIM2_IHS | TIM2_IVS
| (PIX_CLOCK_DIVIDER - 2),
.cntl = CNTL_LCDTFT | CNTL_WATERMARK,
.bpp = 16,
};
#endif
#if defined CONFIG_FB_ARMCLCD_SHARP_LQ10D368
/* Logic Product Development LCD 10.4" VGA -10 */
/* Sharp PN LQ10D368 */
#define PIX_CLOCK_TARGET (28330000)
#define PIX_CLOCK_DIVIDER CLOCK_TO_DIV (PIX_CLOCK_TARGET, HCLK)
#define PIX_CLOCK (HCLK/PIX_CLOCK_DIVIDER)
static struct clcd_panel lcd_panel = {
.mode = {
.name = "10.4in VGA (LQ10D368)",
.xres = 640,
.yres = 480,
.pixclock = PIX_CLOCK,
.left_margin = 21,
.right_margin = 15,
.upper_margin = 34,
.lower_margin = 5,
.hsync_len = 96,
.vsync_len = 16,
.vmode = FB_VMODE_NONINTERLACED,
},
.width = -1,
.height = -1,
.tim2 = TIM2_IHS | TIM2_IVS
| (PIX_CLOCK_DIVIDER - 2),
.cntl = CNTL_LCDTFT | CNTL_WATERMARK,
.bpp = 16,
};
#endif
#if defined CONFIG_FB_ARMCLCD_SHARP_LQ121S1DG41
/* Logic Product Development LCD 12.1" SVGA -10 */
/* Sharp PN LQ121S1DG41, was LQ121S1DG31 */
/* Note that with a 99993900 Hz HCLK, it is not possible to hit the
* target clock frequency range of 35MHz to 42MHz. */
/* If the target pixel clock is substantially lower than the panel
* spec, this is done to prevent the LCD display from glitching when
* the CPU is under load. A pixel clock higher than 25MHz
* (empirically determined) will compete with the CPU for bus cycles
* for the Ethernet chip. However, even a pixel clock of 10MHz
* competes with Compact Flash interface during some operations
* (fdisk, e2fsck). And, at that speed the display may have a visible
* flicker. */
/* The full horozontal cycle (Th) is clock/832/1056/1395. */
#define PIX_CLOCK_TARGET (20000000)
#define PIX_CLOCK_DIVIDER CLOCK_TO_DIV (PIX_CLOCK_TARGET, HCLK)
#define PIX_CLOCK (HCLK/PIX_CLOCK_DIVIDER)
static struct clcd_panel lcd_panel = {
.mode = {
.name = "12.1in SVGA (LQ121S1DG41)",
.xres = 800,
.yres = 600,
.pixclock = PIX_CLOCK,
.left_margin = 89, // ns/5/-/(1/PIX_CLOCK)-10
.right_margin = 1056-800-89-128,
.upper_margin = 23, // line/23/23/23
.lower_margin = 44,
.hsync_len = 128, // clk/2/128/200
.vsync_len = 4, // line/2/4/6
.vmode = FB_VMODE_NONINTERLACED,
},
.width = -1,
.height = -1,
.tim2 = TIM2_IHS | TIM2_IVS
| (PIX_CLOCK_DIVIDER - 2),
.cntl = CNTL_LCDTFT | CNTL_WATERMARK,
.bpp = 16,
};
#endif
#if defined CONFIG_FB_ARMCLCD_HITACHI
/* Hitachi*/
/* Submitted by Michele Da Rold <michele.darold@ecsproject.com> */
#define PIX_CLOCK_TARGET (49000000)
#define PIX_CLOCK_DIVIDER CLOCK_TO_DIV (PIX_CLOCK_TARGET, HCLK)
#define PIX_CLOCK (HCLK/PIX_CLOCK_DIVIDER)
static struct clcd_panel lcd_panel = {
.mode = {
.name = "Hitachi 800x480",
.xres = 800,
.yres = 480,
.pixclock = PIX_CLOCK,
.left_margin = 88,
.right_margin = 40,
.upper_margin = 32,
.lower_margin = 11,
.hsync_len = 128,
.vsync_len = 2,
.vmode = FB_VMODE_NONINTERLACED,
},
.width = -1,
.height = -1,
.tim2 = TIM2_IPC | TIM2_IHS | TIM2_IVS
| (PIX_CLOCK_DIVIDER - 2),
.cntl = CNTL_LCDTFT | CNTL_WATERMARK,
.bpp = 16,
};
#endif
#if defined CONFIG_FB_ARMCLCD_AUO_A070VW01_WIDE
/* AU Optotronics A070VW01 7.0 Wide Screen color Display*/
/* Submitted by Michele Da Rold <michele.darold@ecsproject.com> */
#define PIX_CLOCK_TARGET (10000000)
#define PIX_CLOCK_DIVIDER CLOCK_TO_DIV (PIX_CLOCK_TARGET, HCLK)
#define PIX_CLOCK (HCLK/PIX_CLOCK_DIVIDER)
static struct clcd_panel lcd_panel = {
.mode = {
.name = "7.0in Wide (A070VW01)",
.xres = 480,
.yres = 234,
.pixclock = PIX_CLOCK,
.left_margin = 30,
.right_margin = 25,
.upper_margin = 14,
.lower_margin = 12,
.hsync_len = 100,
.vsync_len = 1,
.vmode = FB_VMODE_NONINTERLACED,
},
.width = -1,
.height = -1,
.tim2 = TIM2_IPC | TIM2_IHS | TIM2_IVS
| (PIX_CLOCK_DIVIDER - 2),
.cntl = CNTL_LCDTFT | CNTL_WATERMARK,
.bpp = 16,
};
#endif
#undef NS_TO_CLOCK
#undef CLOCK_TO_DIV
#endif /* __LCD_PANEL_H__ */

View file

@ -0,0 +1,343 @@
/* arch/arm/mach-lh7a40x/ssp-cpld.c
*
* Copyright (C) 2004,2005 Marc Singer
*
* 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.
*
* SSP/SPI driver for the CardEngine CPLD.
*
*/
/* NOTES
-----
o *** This driver is cribbed from the 7952x implementation.
Some comments may not apply.
o This driver contains sufficient logic to control either the
serial EEPROMs or the audio codec. It is included in the kernel
to support the codec. The EEPROMs are really the responsibility
of the boot loader and should probably be left alone.
o The code must be augmented to cope with multiple, simultaneous
clients.
o The audio codec writes to the codec chip whenever playback
starts.
o The touchscreen driver writes to the ads chip every time it
samples.
o The audio codec must write 16 bits, but the touch chip writes
are 8 bits long.
o We need to be able to keep these configurations separate while
simultaneously active.
*/
#include <linux/module.h>
#include <linux/kernel.h>
//#include <linux/sched.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
//#include <linux/ioport.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/spinlock.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/hardware.h>
#include <asm/arch/ssp.h>
//#define TALK
#if defined (TALK)
#define PRINTK(f...) printk (f)
#else
#define PRINTK(f...) do {} while (0)
#endif
#if defined (CONFIG_ARCH_LH7A400)
# define CPLD_SPID __REGP16(CPLD06_VIRT) /* SPI data */
# define CPLD_SPIC __REGP16(CPLD08_VIRT) /* SPI control */
# define CPLD_SPIC_CS_CODEC (1<<0)
# define CPLD_SPIC_CS_TOUCH (1<<1)
# define CPLD_SPIC_WRITE (0<<2)
# define CPLD_SPIC_READ (1<<2)
# define CPLD_SPIC_DONE (1<<3) /* r/o */
# define CPLD_SPIC_LOAD (1<<4)
# define CPLD_SPIC_START (1<<4)
# define CPLD_SPIC_LOADED (1<<5) /* r/o */
#endif
#define CPLD_SPI __REGP16(CPLD0A_VIRT) /* SPI operation */
#define CPLD_SPI_CS_EEPROM (1<<3)
#define CPLD_SPI_SCLK (1<<2)
#define CPLD_SPI_TX_SHIFT (1)
#define CPLD_SPI_TX (1<<CPLD_SPI_TX_SHIFT)
#define CPLD_SPI_RX_SHIFT (0)
#define CPLD_SPI_RX (1<<CPLD_SPI_RX_SHIFT)
/* *** FIXME: these timing values are substantially larger than the
*** chip requires. We may implement an nsleep () function. */
#define T_SKH 1 /* Clock time high (us) */
#define T_SKL 1 /* Clock time low (us) */
#define T_CS 1 /* Minimum chip select low time (us) */
#define T_CSS 1 /* Minimum chip select setup time (us) */
#define T_DIS 1 /* Data setup time (us) */
/* EEPROM SPI bits */
#define P_START (1<<9)
#define P_WRITE (1<<7)
#define P_READ (2<<7)
#define P_ERASE (3<<7)
#define P_EWDS (0<<7)
#define P_WRAL (0<<7)
#define P_ERAL (0<<7)
#define P_EWEN (0<<7)
#define P_A_EWDS (0<<5)
#define P_A_WRAL (1<<5)
#define P_A_ERAL (2<<5)
#define P_A_EWEN (3<<5)
struct ssp_configuration {
int device;
int mode;
int speed;
int frame_size_write;
int frame_size_read;
};
static struct ssp_configuration ssp_configuration;
static spinlock_t ssp_lock;
static void enable_cs (void)
{
switch (ssp_configuration.device) {
case DEVICE_EEPROM:
CPLD_SPI |= CPLD_SPI_CS_EEPROM;
break;
}
udelay (T_CSS);
}
static void disable_cs (void)
{
switch (ssp_configuration.device) {
case DEVICE_EEPROM:
CPLD_SPI &= ~CPLD_SPI_CS_EEPROM;
break;
}
udelay (T_CS);
}
static void pulse_clock (void)
{
CPLD_SPI |= CPLD_SPI_SCLK;
udelay (T_SKH);
CPLD_SPI &= ~CPLD_SPI_SCLK;
udelay (T_SKL);
}
/* execute_spi_command
sends an spi command to a device. It first sends cwrite bits from
v. If cread is greater than zero it will read cread bits
(discarding the leading 0 bit) and return them. If cread is less
than zero it will check for completetion status and return 0 on
success or -1 on timeout. If cread is zero it does nothing other
than sending the command.
On the LPD7A400, we can only read or write multiples of 8 bits on
the codec and the touch screen device. Here, we round up.
*/
static int execute_spi_command (int v, int cwrite, int cread)
{
unsigned long l = 0;
#if defined (CONFIG_MACH_LPD7A400)
/* The codec and touch devices cannot be bit-banged. Instead,
* the CPLD provides an eight-bit shift register and a crude
* interface. */
if ( ssp_configuration.device == DEVICE_CODEC
|| ssp_configuration.device == DEVICE_TOUCH) {
int select = 0;
PRINTK ("spi(%d %d.%d) 0x%04x",
ssp_configuration.device, cwrite, cread,
v);
#if defined (TALK)
if (ssp_configuration.device == DEVICE_CODEC)
PRINTK (" 0x%03x -> %2d", v & 0x1ff, (v >> 9) & 0x7f);
#endif
PRINTK ("\n");
if (ssp_configuration.device == DEVICE_CODEC)
select = CPLD_SPIC_CS_CODEC;
if (ssp_configuration.device == DEVICE_TOUCH)
select = CPLD_SPIC_CS_TOUCH;
if (cwrite) {
for (cwrite = (cwrite + 7)/8; cwrite-- > 0; ) {
CPLD_SPID = (v >> (8*cwrite)) & 0xff;
CPLD_SPIC = select | CPLD_SPIC_LOAD;
while (!(CPLD_SPIC & CPLD_SPIC_LOADED))
;
CPLD_SPIC = select;
while (!(CPLD_SPIC & CPLD_SPIC_DONE))
;
}
v = 0;
}
if (cread) {
mdelay (2); /* *** FIXME: required by ads7843? */
v = 0;
for (cread = (cread + 7)/8; cread-- > 0;) {
CPLD_SPID = 0;
CPLD_SPIC = select | CPLD_SPIC_READ
| CPLD_SPIC_START;
while (!(CPLD_SPIC & CPLD_SPIC_LOADED))
;
CPLD_SPIC = select | CPLD_SPIC_READ;
while (!(CPLD_SPIC & CPLD_SPIC_DONE))
;
v = (v << 8) | CPLD_SPID;
}
}
return v;
}
#endif
PRINTK ("spi(%d) 0x%04x -> 0x%x\r\n", ssp_configuration.device,
v & 0x1ff, (v >> 9) & 0x7f);
enable_cs ();
v <<= CPLD_SPI_TX_SHIFT; /* Correction for position of SPI_TX bit */
while (cwrite--) {
CPLD_SPI
= (CPLD_SPI & ~CPLD_SPI_TX)
| ((v >> cwrite) & CPLD_SPI_TX);
udelay (T_DIS);
pulse_clock ();
}
if (cread < 0) {
int delay = 10;
disable_cs ();
udelay (1);
enable_cs ();
l = -1;
do {
if (CPLD_SPI & CPLD_SPI_RX) {
l = 0;
break;
}
} while (udelay (1), --delay);
}
else
/* We pulse the clock before the data to skip the leading zero. */
while (cread-- > 0) {
pulse_clock ();
l = (l<<1)
| (((CPLD_SPI & CPLD_SPI_RX)
>> CPLD_SPI_RX_SHIFT) & 0x1);
}
disable_cs ();
return l;
}
static int ssp_init (void)
{
spin_lock_init (&ssp_lock);
memset (&ssp_configuration, 0, sizeof (ssp_configuration));
return 0;
}
/* ssp_chip_select
drops the chip select line for the CPLD shift-register controlled
devices. It doesn't enable chip
*/
static void ssp_chip_select (int enable)
{
#if defined (CONFIG_MACH_LPD7A400)
int select;
if (ssp_configuration.device == DEVICE_CODEC)
select = CPLD_SPIC_CS_CODEC;
else if (ssp_configuration.device == DEVICE_TOUCH)
select = CPLD_SPIC_CS_TOUCH;
else
return;
if (enable)
CPLD_SPIC = select;
else
CPLD_SPIC = 0;
#endif
}
static void ssp_acquire (void)
{
spin_lock (&ssp_lock);
}
static void ssp_release (void)
{
ssp_chip_select (0); /* just in case */
spin_unlock (&ssp_lock);
}
static int ssp_configure (int device, int mode, int speed,
int frame_size_write, int frame_size_read)
{
ssp_configuration.device = device;
ssp_configuration.mode = mode;
ssp_configuration.speed = speed;
ssp_configuration.frame_size_write = frame_size_write;
ssp_configuration.frame_size_read = frame_size_read;
return 0;
}
static int ssp_read (void)
{
return execute_spi_command (0, 0, ssp_configuration.frame_size_read);
}
static int ssp_write (u16 data)
{
execute_spi_command (data, ssp_configuration.frame_size_write, 0);
return 0;
}
static int ssp_write_read (u16 data)
{
return execute_spi_command (data, ssp_configuration.frame_size_write,
ssp_configuration.frame_size_read);
}
struct ssp_driver lh7a40x_cpld_ssp_driver = {
.init = ssp_init,
.acquire = ssp_acquire,
.release = ssp_release,
.configure = ssp_configure,
.chip_select = ssp_chip_select,
.read = ssp_read,
.write = ssp_write,
.write_read = ssp_write_read,
};
MODULE_AUTHOR("Marc Singer");
MODULE_DESCRIPTION("LPD7A40X CPLD SPI driver");
MODULE_LICENSE("GPL");

View file

@ -1,4 +1,4 @@
/*
/*
* arch/arm/mach-lh7a40x/time.c
*
* Copyright (C) 2004 Logic Product Development
@ -57,7 +57,7 @@ static struct irqaction lh7a40x_timer_irq = {
.handler = lh7a40x_timer_interrupt,
};
static void __init lh7a40x_timer_init(void)
static void __init lh7a40x_timer_init (void)
{
/* Stop/disable all timers */
TIMER_CONTROL1 = 0;

View file

@ -0,0 +1,12 @@
#
# Makefile for the linux kernel.
#
obj-y := core.o irq.o time.o clock.o gpio.o serial.o dma.o
obj-m :=
obj-n :=
obj- :=
# Power Management
obj-$(CONFIG_PM) += pm.o sleep.o

View file

@ -0,0 +1,4 @@
zreladdr-y := 0x80008000
params_phys-y := 0x80000100
initrd_phys-y := 0x80800000

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,43 @@
/*
* arch/arm/mach-pnx4008/clock.h
*
* Clock control driver for PNX4008 - internal header file
*
* Author: Vitaly Wool <source@mvista.com>
*
* 2006 (c) MontaVista Software, Inc. This file is licensed under
* the terms of the GNU General Public License version 2. This program
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
*/
#ifndef __ARCH_ARM_PNX4008_CLOCK_H__
#define __ARCH_ARM_PNX4008_CLOCK_H__
struct clk {
struct list_head node;
struct module *owner;
const char *name;
struct clk *parent;
struct clk *propagate_next;
u32 rate;
u32 user_rate;
s8 usecount;
u32 flags;
u32 scale_reg;
u8 enable_shift;
u32 enable_reg;
u8 enable_shift1;
u32 enable_reg1;
u32 parent_switch_reg;
u32(*round_rate) (struct clk *, u32);
int (*set_rate) (struct clk *, u32);
int (*set_parent) (struct clk * clk, struct clk * parent);
};
/* Flags */
#define RATE_PROPAGATES (1<<0)
#define NEEDS_INITIALIZATION (1<<1)
#define PARENT_SET_RATE (1<<2)
#define FIXED_RATE (1<<3)
#endif

View file

@ -0,0 +1,207 @@
/*
* arch/arm/mach-pnx4008/core.c
*
* PNX4008 core startup code
*
* Authors: Vitaly Wool, Dmitry Chigirev,
* Grigory Tolstolytkin, Dmitry Pervushin <source@mvista.com>
*
* Based on reference code received from Philips:
* Copyright (C) 2003 Philips Semiconductors
*
* 2005 (c) MontaVista Software, Inc. This file is licensed under
* the terms of the GNU General Public License version 2. This program
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
*/
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
#include <linux/list.h>
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/serial_8250.h>
#include <linux/device.h>
#include <linux/spi/spi.h>
#include <asm/hardware.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <asm/setup.h>
#include <asm/mach-types.h>
#include <asm/pgtable.h>
#include <asm/page.h>
#include <asm/system.h>
#include <asm/mach/arch.h>
#include <asm/mach/irq.h>
#include <asm/mach/map.h>
#include <asm/mach/time.h>
#include <asm/arch/irq.h>
#include <asm/arch/clock.h>
#include <asm/arch/dma.h>
struct resource spipnx_0_resources[] = {
{
.start = PNX4008_SPI1_BASE,
.end = PNX4008_SPI1_BASE + SZ_4K,
.flags = IORESOURCE_MEM,
}, {
.start = PER_SPI1_REC_XMIT,
.flags = IORESOURCE_DMA,
}, {
.start = SPI1_INT,
.flags = IORESOURCE_IRQ,
}, {
.flags = 0,
},
};
struct resource spipnx_1_resources[] = {
{
.start = PNX4008_SPI2_BASE,
.end = PNX4008_SPI2_BASE + SZ_4K,
.flags = IORESOURCE_MEM,
}, {
.start = PER_SPI2_REC_XMIT,
.flags = IORESOURCE_DMA,
}, {
.start = SPI2_INT,
.flags = IORESOURCE_IRQ,
}, {
.flags = 0,
}
};
static struct spi_board_info spi_board_info[] __initdata = {
{
.modalias = "m25p80",
.max_speed_hz = 1000000,
.bus_num = 1,
.chip_select = 0,
},
};
static struct platform_device spipnx_1 = {
.name = "spipnx",
.id = 1,
.num_resources = ARRAY_SIZE(spipnx_0_resources),
.resource = spipnx_0_resources,
.dev = {
.coherent_dma_mask = 0xFFFFFFFF,
},
};
static struct platform_device spipnx_2 = {
.name = "spipnx",
.id = 2,
.num_resources = ARRAY_SIZE(spipnx_1_resources),
.resource = spipnx_1_resources,
.dev = {
.coherent_dma_mask = 0xFFFFFFFF,
},
};
static struct plat_serial8250_port platform_serial_ports[] = {
{
.membase = (void *)__iomem(IO_ADDRESS(PNX4008_UART5_BASE)),
.mapbase = (unsigned long)PNX4008_UART5_BASE,
.irq = IIR5_INT,
.uartclk = PNX4008_UART_CLK,
.regshift = 2,
.iotype = UPIO_MEM,
.flags = UPF_BOOT_AUTOCONF | UPF_BUGGY_UART | UPF_SKIP_TEST,
},
{
.membase = (void *)__iomem(IO_ADDRESS(PNX4008_UART3_BASE)),
.mapbase = (unsigned long)PNX4008_UART3_BASE,
.irq = IIR3_INT,
.uartclk = PNX4008_UART_CLK,
.regshift = 2,
.iotype = UPIO_MEM,
.flags = UPF_BOOT_AUTOCONF | UPF_BUGGY_UART | UPF_SKIP_TEST,
},
{}
};
static struct platform_device serial_device = {
.name = "serial8250",
.id = PLAT8250_DEV_PLATFORM,
.dev = {
.platform_data = &platform_serial_ports,
},
};
static struct platform_device *devices[] __initdata = {
&spipnx_1,
&spipnx_2,
&serial_device,
};
extern void pnx4008_uart_init(void);
static void __init pnx4008_init(void)
{
/*disable all START interrupt sources,
and clear all START interrupt flags */
__raw_writel(0, START_INT_ER_REG(SE_PIN_BASE_INT));
__raw_writel(0, START_INT_ER_REG(SE_INT_BASE_INT));
__raw_writel(0xffffffff, START_INT_RSR_REG(SE_PIN_BASE_INT));
__raw_writel(0xffffffff, START_INT_RSR_REG(SE_INT_BASE_INT));
platform_add_devices(devices, ARRAY_SIZE(devices));
spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
/* Switch on the UART clocks */
pnx4008_uart_init();
}
static struct map_desc pnx4008_io_desc[] __initdata = {
{
.virtual = IO_ADDRESS(PNX4008_IRAM_BASE),
.pfn = __phys_to_pfn(PNX4008_IRAM_BASE),
.length = SZ_64K,
.type = MT_DEVICE,
}, {
.virtual = IO_ADDRESS(PNX4008_NDF_FLASH_BASE),
.pfn = __phys_to_pfn(PNX4008_NDF_FLASH_BASE),
.length = SZ_1M - SZ_128K,
.type = MT_DEVICE,
}, {
.virtual = IO_ADDRESS(PNX4008_JPEG_CONFIG_BASE),
.pfn = __phys_to_pfn(PNX4008_JPEG_CONFIG_BASE),
.length = SZ_128K * 3,
.type = MT_DEVICE,
}, {
.virtual = IO_ADDRESS(PNX4008_DMA_CONFIG_BASE),
.pfn = __phys_to_pfn(PNX4008_DMA_CONFIG_BASE),
.length = SZ_1M,
.type = MT_DEVICE,
}, {
.virtual = IO_ADDRESS(PNX4008_AHB2FAB_BASE),
.pfn = __phys_to_pfn(PNX4008_AHB2FAB_BASE),
.length = SZ_1M,
.type = MT_DEVICE,
},
};
void __init pnx4008_map_io(void)
{
iotable_init(pnx4008_io_desc, ARRAY_SIZE(pnx4008_io_desc));
}
extern struct sys_timer pnx4008_timer;
MACHINE_START(PNX4008, "Philips PNX4008")
/* Maintainer: MontaVista Software Inc. */
.phys_io = 0x40090000,
.io_pg_offst = (0xf4090000 >> 18) & 0xfffc,
.boot_params = 0x80000100,
.map_io = pnx4008_map_io,
.init_irq = pnx4008_init_irq,
.init_machine = pnx4008_init,
.timer = &pnx4008_timer,
MACHINE_END

1109
arch/arm/mach-pnx4008/dma.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,330 @@
/*
* arch/arm/mach-pnx4008/gpio.c
*
* PNX4008 GPIO driver
*
* Author: Dmitry Chigirev <source@mvista.com>
*
* Based on reference code by Iwo Mergler and Z.Tabaaloute from Philips:
* Copyright (c) 2005 Koninklijke Philips Electronics N.V.
*
* 2005 (c) MontaVista Software, Inc. This file is licensed under
* the terms of the GNU General Public License version 2. This program
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
*/
#include <linux/config.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <asm/semaphore.h>
#include <asm/io.h>
#include <asm/arch/platform.h>
#include <asm/arch/gpio.h>
/* register definitions */
#define PIO_VA_BASE IO_ADDRESS(PNX4008_PIO_BASE)
#define PIO_INP_STATE (0x00U)
#define PIO_OUTP_SET (0x04U)
#define PIO_OUTP_CLR (0x08U)
#define PIO_OUTP_STATE (0x0CU)
#define PIO_DRV_SET (0x10U)
#define PIO_DRV_CLR (0x14U)
#define PIO_DRV_STATE (0x18U)
#define PIO_SDINP_STATE (0x1CU)
#define PIO_SDOUTP_SET (0x20U)
#define PIO_SDOUTP_CLR (0x24U)
#define PIO_MUX_SET (0x28U)
#define PIO_MUX_CLR (0x2CU)
#define PIO_MUX_STATE (0x30U)
static inline void gpio_lock(void)
{
local_irq_disable();
}
static inline void gpio_unlock(void)
{
local_irq_enable();
}
/* Inline functions */
static inline int gpio_read_bit(u32 reg, int gpio)
{
u32 bit, val;
int ret = -EFAULT;
if (gpio < 0)
goto out;
bit = GPIO_BIT(gpio);
if (bit) {
val = __raw_readl(PIO_VA_BASE + reg);
ret = (val & bit) ? 1 : 0;
}
out:
return ret;
}
static inline int gpio_set_bit(u32 reg, int gpio)
{
u32 bit, val;
int ret = -EFAULT;
if (gpio < 0)
goto out;
bit = GPIO_BIT(gpio);
if (bit) {
val = __raw_readl(PIO_VA_BASE + reg);
val |= bit;
__raw_writel(val, PIO_VA_BASE + reg);
ret = 0;
}
out:
return ret;
}
/* Very simple access control, bitmap for allocated/free */
static unsigned long access_map[4];
#define INP_INDEX 0
#define OUTP_INDEX 1
#define GPIO_INDEX 2
#define MUX_INDEX 3
/*GPIO to Input Mapping */
static short gpio_to_inp_map[32] = {
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
-1, 10, 11, 12, 13, 14, 24, -1
};
/*GPIO to Mux Mapping */
static short gpio_to_mux_map[32] = {
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, 0, 1, 4, 5, -1
};
/*Output to Mux Mapping */
static short outp_to_mux_map[32] = {
-1, -1, -1, 6, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, 2, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1
};
int pnx4008_gpio_register_pin(unsigned short pin)
{
unsigned long bit = GPIO_BIT(pin);
int ret = -EBUSY; /* Already in use */
gpio_lock();
if (GPIO_ISBID(pin)) {
if (access_map[GPIO_INDEX] & bit)
goto out;
access_map[GPIO_INDEX] |= bit;
} else if (GPIO_ISRAM(pin)) {
if (access_map[GPIO_INDEX] & bit)
goto out;
access_map[GPIO_INDEX] |= bit;
} else if (GPIO_ISMUX(pin)) {
if (access_map[MUX_INDEX] & bit)
goto out;
access_map[MUX_INDEX] |= bit;
} else if (GPIO_ISOUT(pin)) {
if (access_map[OUTP_INDEX] & bit)
goto out;
access_map[OUTP_INDEX] |= bit;
} else if (GPIO_ISIN(pin)) {
if (access_map[INP_INDEX] & bit)
goto out;
access_map[INP_INDEX] |= bit;
} else
goto out;
ret = 0;
out:
gpio_unlock();
return ret;
}
EXPORT_SYMBOL(pnx4008_gpio_register_pin);
int pnx4008_gpio_unregister_pin(unsigned short pin)
{
unsigned long bit = GPIO_BIT(pin);
int ret = -EFAULT; /* Not registered */
gpio_lock();
if (GPIO_ISBID(pin)) {
if (~access_map[GPIO_INDEX] & bit)
goto out;
access_map[GPIO_INDEX] &= ~bit;
} else if (GPIO_ISRAM(pin)) {
if (~access_map[GPIO_INDEX] & bit)
goto out;
access_map[GPIO_INDEX] &= ~bit;
} else if (GPIO_ISMUX(pin)) {
if (~access_map[MUX_INDEX] & bit)
goto out;
access_map[MUX_INDEX] &= ~bit;
} else if (GPIO_ISOUT(pin)) {
if (~access_map[OUTP_INDEX] & bit)
goto out;
access_map[OUTP_INDEX] &= ~bit;
} else if (GPIO_ISIN(pin)) {
if (~access_map[INP_INDEX] & bit)
goto out;
access_map[INP_INDEX] &= ~bit;
} else
goto out;
ret = 0;
out:
gpio_unlock();
return ret;
}
EXPORT_SYMBOL(pnx4008_gpio_unregister_pin);
unsigned long pnx4008_gpio_read_pin(unsigned short pin)
{
unsigned long ret = -EFAULT;
int gpio = GPIO_BIT_MASK(pin);
gpio_lock();
if (GPIO_ISOUT(pin)) {
ret = gpio_read_bit(PIO_OUTP_STATE, gpio);
} else if (GPIO_ISRAM(pin)) {
if (gpio_read_bit(PIO_DRV_STATE, gpio) == 0) {
ret = gpio_read_bit(PIO_SDINP_STATE, gpio);
}
} else if (GPIO_ISBID(pin)) {
ret = gpio_read_bit(PIO_DRV_STATE, gpio);
if (ret > 0)
ret = gpio_read_bit(PIO_OUTP_STATE, gpio);
else if (ret == 0)
ret =
gpio_read_bit(PIO_INP_STATE, gpio_to_inp_map[gpio]);
} else if (GPIO_ISIN(pin)) {
ret = gpio_read_bit(PIO_INP_STATE, gpio);
}
gpio_unlock();
return ret;
}
EXPORT_SYMBOL(pnx4008_gpio_read_pin);
/* Write Value to output */
int pnx4008_gpio_write_pin(unsigned short pin, int output)
{
int gpio = GPIO_BIT_MASK(pin);
int ret = -EFAULT;
gpio_lock();
if (GPIO_ISOUT(pin)) {
printk( "writing '%x' to '%x'\n",
gpio, output ? PIO_OUTP_SET : PIO_OUTP_CLR );
ret = gpio_set_bit(output ? PIO_OUTP_SET : PIO_OUTP_CLR, gpio);
} else if (GPIO_ISRAM(pin)) {
if (gpio_read_bit(PIO_DRV_STATE, gpio) > 0)
ret = gpio_set_bit(output ? PIO_SDOUTP_SET :
PIO_SDOUTP_CLR, gpio);
} else if (GPIO_ISBID(pin)) {
if (gpio_read_bit(PIO_DRV_STATE, gpio) > 0)
ret = gpio_set_bit(output ? PIO_OUTP_SET :
PIO_OUTP_CLR, gpio);
}
gpio_unlock();
return ret;
}
EXPORT_SYMBOL(pnx4008_gpio_write_pin);
/* Value = 1 : Set GPIO pin as output */
/* Value = 0 : Set GPIO pin as input */
int pnx4008_gpio_set_pin_direction(unsigned short pin, int output)
{
int gpio = GPIO_BIT_MASK(pin);
int ret = -EFAULT;
gpio_lock();
if (GPIO_ISBID(pin) || GPIO_ISRAM(pin)) {
ret = gpio_set_bit(output ? PIO_DRV_SET : PIO_DRV_CLR, gpio);
}
gpio_unlock();
return ret;
}
EXPORT_SYMBOL(pnx4008_gpio_set_pin_direction);
/* Read GPIO pin direction: 0= pin used as input, 1= pin used as output*/
int pnx4008_gpio_read_pin_direction(unsigned short pin)
{
int gpio = GPIO_BIT_MASK(pin);
int ret = -EFAULT;
gpio_lock();
if (GPIO_ISBID(pin) || GPIO_ISRAM(pin)) {
ret = gpio_read_bit(PIO_DRV_STATE, gpio);
}
gpio_unlock();
return ret;
}
EXPORT_SYMBOL(pnx4008_gpio_read_pin_direction);
/* Value = 1 : Set pin to muxed function */
/* Value = 0 : Set pin as GPIO */
int pnx4008_gpio_set_pin_mux(unsigned short pin, int output)
{
int gpio = GPIO_BIT_MASK(pin);
int ret = -EFAULT;
gpio_lock();
if (GPIO_ISBID(pin)) {
ret =
gpio_set_bit(output ? PIO_MUX_SET : PIO_MUX_CLR,
gpio_to_mux_map[gpio]);
} else if (GPIO_ISOUT(pin)) {
ret =
gpio_set_bit(output ? PIO_MUX_SET : PIO_MUX_CLR,
outp_to_mux_map[gpio]);
} else if (GPIO_ISMUX(pin)) {
ret = gpio_set_bit(output ? PIO_MUX_SET : PIO_MUX_CLR, gpio);
}
gpio_unlock();
return ret;
}
EXPORT_SYMBOL(pnx4008_gpio_set_pin_mux);
/* Read pin mux function: 0= pin used as GPIO, 1= pin used for muxed function*/
int pnx4008_gpio_read_pin_mux(unsigned short pin)
{
int gpio = GPIO_BIT_MASK(pin);
int ret = -EFAULT;
gpio_lock();
if (GPIO_ISBID(pin)) {
ret = gpio_read_bit(PIO_MUX_STATE, gpio_to_mux_map[gpio]);
} else if (GPIO_ISOUT(pin)) {
ret = gpio_read_bit(PIO_MUX_STATE, outp_to_mux_map[gpio]);
} else if (GPIO_ISMUX(pin)) {
ret = gpio_read_bit(PIO_MUX_STATE, gpio);
}
gpio_unlock();
return ret;
}
EXPORT_SYMBOL(pnx4008_gpio_read_pin_mux);

121
arch/arm/mach-pnx4008/irq.c Normal file
View file

@ -0,0 +1,121 @@
/*
* arch/arm/mach-pnx4008/irq.c
*
* PNX4008 IRQ controller driver
*
* Author: Dmitry Chigirev <source@mvista.com>
*
* Based on reference code received from Philips:
* Copyright (C) 2003 Philips Semiconductors
*
* 2005 (c) MontaVista Software, Inc. This file is licensed under
* the terms of the GNU General Public License version 2. This program
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
*/
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
#include <linux/list.h>
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/device.h>
#include <asm/hardware.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <asm/setup.h>
#include <asm/mach-types.h>
#include <asm/pgtable.h>
#include <asm/page.h>
#include <asm/system.h>
#include <asm/mach/arch.h>
#include <asm/mach/irq.h>
#include <asm/mach/map.h>
#include <asm/arch/irq.h>
static u8 pnx4008_irq_type[NR_IRQS] = PNX4008_IRQ_TYPES;
static void pnx4008_mask_irq(unsigned int irq)
{
__raw_writel(__raw_readl(INTC_ER(irq)) & ~INTC_BIT(irq), INTC_ER(irq)); /* mask interrupt */
}
static void pnx4008_unmask_irq(unsigned int irq)
{
__raw_writel(__raw_readl(INTC_ER(irq)) | INTC_BIT(irq), INTC_ER(irq)); /* unmask interrupt */
}
static void pnx4008_mask_ack_irq(unsigned int irq)
{
__raw_writel(__raw_readl(INTC_ER(irq)) & ~INTC_BIT(irq), INTC_ER(irq)); /* mask interrupt */
__raw_writel(INTC_BIT(irq), INTC_SR(irq)); /* clear interrupt status */
}
static int pnx4008_set_irq_type(unsigned int irq, unsigned int type)
{
switch (type) {
case IRQT_RISING:
__raw_writel(__raw_readl(INTC_ATR(irq)) | INTC_BIT(irq), INTC_ATR(irq)); /*edge sensitive */
__raw_writel(__raw_readl(INTC_APR(irq)) | INTC_BIT(irq), INTC_APR(irq)); /*rising edge */
set_irq_handler(irq, do_edge_IRQ);
break;
case IRQT_FALLING:
__raw_writel(__raw_readl(INTC_ATR(irq)) | INTC_BIT(irq), INTC_ATR(irq)); /*edge sensitive */
__raw_writel(__raw_readl(INTC_APR(irq)) & ~INTC_BIT(irq), INTC_APR(irq)); /*falling edge */
set_irq_handler(irq, do_edge_IRQ);
break;
case IRQT_LOW:
__raw_writel(__raw_readl(INTC_ATR(irq)) & ~INTC_BIT(irq), INTC_ATR(irq)); /*level sensitive */
__raw_writel(__raw_readl(INTC_APR(irq)) & ~INTC_BIT(irq), INTC_APR(irq)); /*low level */
set_irq_handler(irq, do_level_IRQ);
break;
case IRQT_HIGH:
__raw_writel(__raw_readl(INTC_ATR(irq)) & ~INTC_BIT(irq), INTC_ATR(irq)); /*level sensitive */
__raw_writel(__raw_readl(INTC_APR(irq)) | INTC_BIT(irq), INTC_APR(irq)); /* high level */
set_irq_handler(irq, do_level_IRQ);
break;
/* IRQT_BOTHEDGE is not supported */
default:
printk(KERN_ERR "PNX4008 IRQ: Unsupported irq type %d\n", type);
return -1;
}
return 0;
}
static struct irqchip pnx4008_irq_chip = {
.ack = pnx4008_mask_ack_irq,
.mask = pnx4008_mask_irq,
.unmask = pnx4008_unmask_irq,
.set_type = pnx4008_set_irq_type,
};
void __init pnx4008_init_irq(void)
{
unsigned int i;
/* configure and enable IRQ 0,1,30,31 (cascade interrupts) mask all others */
pnx4008_set_irq_type(SUB1_IRQ_N, pnx4008_irq_type[SUB1_IRQ_N]);
pnx4008_set_irq_type(SUB2_IRQ_N, pnx4008_irq_type[SUB2_IRQ_N]);
pnx4008_set_irq_type(SUB1_FIQ_N, pnx4008_irq_type[SUB1_FIQ_N]);
pnx4008_set_irq_type(SUB2_FIQ_N, pnx4008_irq_type[SUB2_FIQ_N]);
__raw_writel((1 << SUB2_FIQ_N) | (1 << SUB1_FIQ_N) |
(1 << SUB2_IRQ_N) | (1 << SUB1_IRQ_N),
INTC_ER(MAIN_BASE_INT));
__raw_writel(0, INTC_ER(SIC1_BASE_INT));
__raw_writel(0, INTC_ER(SIC2_BASE_INT));
/* configure all other IRQ's */
for (i = 0; i < NR_IRQS; i++) {
if (i == SUB2_FIQ_N || i == SUB1_FIQ_N ||
i == SUB2_IRQ_N || i == SUB1_IRQ_N)
continue;
set_irq_flags(i, IRQF_VALID);
set_irq_chip(i, &pnx4008_irq_chip);
pnx4008_set_irq_type(i, pnx4008_irq_type[i]);
}
}

184
arch/arm/mach-pnx4008/pm.c Normal file
View file

@ -0,0 +1,184 @@
/*
* arch/arm/mach-pnx4008/pm.c
*
* Power Management driver for PNX4008
*
* Authors: Vitaly Wool, Dmitry Chigirev <source@mvista.com>
*
* 2005 (c) MontaVista Software, Inc. This file is licensed under
* the terms of the GNU General Public License version 2. This program
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
*/
#include <linux/pm.h>
#include <linux/rtc.h>
#include <linux/sched.h>
#include <linux/proc_fs.h>
#include <linux/pm.h>
#include <linux/delay.h>
#include <linux/clk.h>
#include <asm/io.h>
#include <asm/mach-types.h>
#include <asm/cacheflush.h>
#include <asm/arch/pm.h>
#include <asm/arch/clock.h>
#define SRAM_VA IO_ADDRESS(PNX4008_IRAM_BASE)
static void *saved_sram;
static struct clk *pll4_clk;
static inline void pnx4008_standby(void)
{
void (*pnx4008_cpu_standby_ptr) (void);
local_irq_disable();
local_fiq_disable();
clk_disable(pll4_clk);
/*saving portion of SRAM to be used by suspend function. */
memcpy(saved_sram, (void *)SRAM_VA, pnx4008_cpu_standby_sz);
/*make sure SRAM copy gets physically written into SDRAM.
SDRAM will be placed into self-refresh during power down */
flush_cache_all();
/*copy suspend function into SRAM */
memcpy((void *)SRAM_VA, pnx4008_cpu_standby, pnx4008_cpu_standby_sz);
/*do suspend */
pnx4008_cpu_standby_ptr = (void *)SRAM_VA;
pnx4008_cpu_standby_ptr();
/*restoring portion of SRAM that was used by suspend function */
memcpy((void *)SRAM_VA, saved_sram, pnx4008_cpu_standby_sz);
clk_enable(pll4_clk);
local_fiq_enable();
local_irq_enable();
}
static inline void pnx4008_suspend(void)
{
void (*pnx4008_cpu_suspend_ptr) (void);
local_irq_disable();
local_fiq_disable();
clk_disable(pll4_clk);
__raw_writel(0xffffffff, START_INT_RSR_REG(SE_PIN_BASE_INT));
__raw_writel(0xffffffff, START_INT_RSR_REG(SE_INT_BASE_INT));
/*saving portion of SRAM to be used by suspend function. */
memcpy(saved_sram, (void *)SRAM_VA, pnx4008_cpu_suspend_sz);
/*make sure SRAM copy gets physically written into SDRAM.
SDRAM will be placed into self-refresh during power down */
flush_cache_all();
/*copy suspend function into SRAM */
memcpy((void *)SRAM_VA, pnx4008_cpu_suspend, pnx4008_cpu_suspend_sz);
/*do suspend */
pnx4008_cpu_suspend_ptr = (void *)SRAM_VA;
pnx4008_cpu_suspend_ptr();
/*restoring portion of SRAM that was used by suspend function */
memcpy((void *)SRAM_VA, saved_sram, pnx4008_cpu_suspend_sz);
clk_enable(pll4_clk);
local_fiq_enable();
local_irq_enable();
}
static int pnx4008_pm_enter(suspend_state_t state)
{
switch (state) {
case PM_SUSPEND_STANDBY:
pnx4008_standby();
break;
case PM_SUSPEND_MEM:
pnx4008_suspend();
break;
case PM_SUSPEND_DISK:
return -ENOTSUPP;
default:
return -EINVAL;
}
return 0;
}
/*
* Called after processes are frozen, but before we shut down devices.
*/
static int pnx4008_pm_prepare(suspend_state_t state)
{
switch (state) {
case PM_SUSPEND_STANDBY:
case PM_SUSPEND_MEM:
break;
case PM_SUSPEND_DISK:
return -ENOTSUPP;
break;
default:
return -EINVAL;
break;
}
return 0;
}
/*
* Called after devices are re-setup, but before processes are thawed.
*/
static int pnx4008_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 pnx4008_pm_ops = {
.prepare = pnx4008_pm_prepare,
.enter = pnx4008_pm_enter,
.finish = pnx4008_pm_finish,
};
static int __init pnx4008_pm_init(void)
{
u32 sram_size_to_allocate;
pll4_clk = clk_get(0, "ck_pll4");
if (IS_ERR(pll4_clk)) {
printk(KERN_ERR
"PM Suspend cannot acquire ARM(PLL4) clock control\n");
return PTR_ERR(pll4_clk);
}
if (pnx4008_cpu_standby_sz > pnx4008_cpu_suspend_sz)
sram_size_to_allocate = pnx4008_cpu_standby_sz;
else
sram_size_to_allocate = pnx4008_cpu_suspend_sz;
saved_sram = kmalloc(sram_size_to_allocate, GFP_ATOMIC);
if (!saved_sram) {
printk(KERN_ERR
"PM Suspend: cannot allocate memory to save portion of SRAM\n");
clk_put(pll4_clk);
return -ENOMEM;
}
pm_set_ops(&pnx4008_pm_ops);
return 0;
}
late_initcall(pnx4008_pm_init);

View file

@ -0,0 +1,69 @@
/*
* linux/arch/arm/mach-pnx4008/serial.c
*
* PNX4008 UART initialization
*
* Copyright: MontaVista Software Inc. (c) 2005
*
* 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/types.h>
#include <asm/io.h>
#include <asm/arch/platform.h>
#include <asm/arch/hardware.h>
#include <linux/serial_core.h>
#include <linux/serial_reg.h>
#include <asm/arch/pm.h>
#include <asm/arch/clock.h>
#define UART_3 0
#define UART_4 1
#define UART_5 2
#define UART_6 3
#define UART_UNKNOWN (-1)
#define UART3_BASE_VA IO_ADDRESS(PNX4008_UART3_BASE)
#define UART4_BASE_VA IO_ADDRESS(PNX4008_UART4_BASE)
#define UART5_BASE_VA IO_ADDRESS(PNX4008_UART5_BASE)
#define UART6_BASE_VA IO_ADDRESS(PNX4008_UART6_BASE)
#define UART_FCR_OFFSET 8
#define UART_FIFO_SIZE 64
void pnx4008_uart_init(void)
{
u32 tmp;
int i = UART_FIFO_SIZE;
__raw_writel(0xC1, UART5_BASE_VA + UART_FCR_OFFSET);
__raw_writel(0xC1, UART3_BASE_VA + UART_FCR_OFFSET);
/* Send a NULL to fix the UART HW bug */
__raw_writel(0x00, UART5_BASE_VA);
__raw_writel(0x00, UART3_BASE_VA);
while (i--) {
tmp = __raw_readl(UART5_BASE_VA);
tmp = __raw_readl(UART3_BASE_VA);
}
__raw_writel(0, UART5_BASE_VA + UART_FCR_OFFSET);
__raw_writel(0, UART3_BASE_VA + UART_FCR_OFFSET);
/* setup wakeup interrupt */
start_int_set_rising_edge(SE_U3_RX_INT);
start_int_ack(SE_U3_RX_INT);
start_int_umask(SE_U3_RX_INT);
start_int_set_rising_edge(SE_U5_RX_INT);
start_int_ack(SE_U5_RX_INT);
start_int_umask(SE_U5_RX_INT);
}

View file

@ -0,0 +1,196 @@
/*
* linux/arch/arm/mach-pnx4008/sleep.S
*
* PNX4008 support for STOP mode and SDRAM self-refresh
*
* Authors: Dmitry Chigirev, Vitaly Wool <source@mvista.com>
*
* 2005 (c) MontaVista Software, Inc. This file is licensed under
* the terms of the GNU General Public License version 2. This program
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
*/
#include <linux/config.h>
#include <linux/linkage.h>
#include <asm/assembler.h>
#include <asm/hardware.h>
#define PWRMAN_VA_BASE IO_ADDRESS(PNX4008_PWRMAN_BASE)
#define PWR_CTRL_REG_OFFS 0x44
#define SDRAM_CFG_VA_BASE IO_ADDRESS(PNX4008_SDRAM_CFG_BASE)
#define MPMC_STATUS_REG_OFFS 0x4
.text
ENTRY(pnx4008_cpu_suspend)
@this function should be entered in Direct run mode.
@ save registers on stack
stmfd sp!, {r0 - r6, lr}
@ setup Power Manager base address in r4
@ and put it's value in r5
mov r4, #(PWRMAN_VA_BASE & 0xff000000)
orr r4, r4, #(PWRMAN_VA_BASE & 0x00ff0000)
orr r4, r4, #(PWRMAN_VA_BASE & 0x0000ff00)
orr r4, r4, #(PWRMAN_VA_BASE & 0x000000ff)
ldr r5, [r4, #PWR_CTRL_REG_OFFS]
@ setup SDRAM controller base address in r2
@ and put it's value in r3
mov r2, #(SDRAM_CFG_VA_BASE & 0xff000000)
orr r2, r2, #(SDRAM_CFG_VA_BASE & 0x00ff0000)
orr r2, r2, #(SDRAM_CFG_VA_BASE & 0x0000ff00)
orr r2, r2, #(SDRAM_CFG_VA_BASE & 0x000000ff)
ldr r3, [r2, #MPMC_STATUS_REG_OFFS] @extra read - HW bug workaround
@ clear SDRAM self-refresh bit latch
and r5, r5, #(~(1 << 8))
@ clear SDRAM self-refresh bit
and r5, r5, #(~(1 << 9))
str r5, [r4, #PWR_CTRL_REG_OFFS]
@ do save current bit settings in r1
mov r1, r5
@ set SDRAM self-refresh bit
orr r5, r5, #(1 << 9)
str r5, [r4, #PWR_CTRL_REG_OFFS]
@ set SDRAM self-refresh bit latch
orr r5, r5, #(1 << 8)
str r5, [r4, #PWR_CTRL_REG_OFFS]
@ clear SDRAM self-refresh bit latch
and r5, r5, #(~(1 << 8))
str r5, [r4, #PWR_CTRL_REG_OFFS]
@ clear SDRAM self-refresh bit
and r5, r5, #(~(1 << 9))
str r5, [r4, #PWR_CTRL_REG_OFFS]
@ wait for SDRAM to get into self-refresh mode
2: ldr r3, [r2, #MPMC_STATUS_REG_OFFS]
tst r3, #(1 << 2)
beq 2b
@ to prepare SDRAM to get out of self-refresh mode after wakeup
orr r5, r5, #(1 << 7)
str r5, [r4, #PWR_CTRL_REG_OFFS]
@ do enter stop mode
orr r5, r5, #(1 << 0)
str r5, [r4, #PWR_CTRL_REG_OFFS]
nop
nop
nop
nop
nop
nop
nop
nop
nop
@ sleeping now...
@ coming out of STOP mode into Direct Run mode
@ clear STOP mode and SDRAM self-refresh bits
str r1, [r4, #PWR_CTRL_REG_OFFS]
@ wait for SDRAM to get out self-refresh mode
3: ldr r3, [r2, #MPMC_STATUS_REG_OFFS]
tst r3, #5
bne 3b
@ restore regs and return
ldmfd sp!, {r0 - r6, pc}
ENTRY(pnx4008_cpu_suspend_sz)
.word . - pnx4008_cpu_suspend
ENTRY(pnx4008_cpu_standby)
@ save registers on stack
stmfd sp!, {r0 - r6, lr}
@ setup Power Manager base address in r4
@ and put it's value in r5
mov r4, #(PWRMAN_VA_BASE & 0xff000000)
orr r4, r4, #(PWRMAN_VA_BASE & 0x00ff0000)
orr r4, r4, #(PWRMAN_VA_BASE & 0x0000ff00)
orr r4, r4, #(PWRMAN_VA_BASE & 0x000000ff)
ldr r5, [r4, #PWR_CTRL_REG_OFFS]
@ setup SDRAM controller base address in r2
@ and put it's value in r3
mov r2, #(SDRAM_CFG_VA_BASE & 0xff000000)
orr r2, r2, #(SDRAM_CFG_VA_BASE & 0x00ff0000)
orr r2, r2, #(SDRAM_CFG_VA_BASE & 0x0000ff00)
orr r2, r2, #(SDRAM_CFG_VA_BASE & 0x000000ff)
ldr r3, [r2, #MPMC_STATUS_REG_OFFS] @extra read - HW bug workaround
@ clear SDRAM self-refresh bit latch
and r5, r5, #(~(1 << 8))
@ clear SDRAM self-refresh bit
and r5, r5, #(~(1 << 9))
str r5, [r4, #PWR_CTRL_REG_OFFS]
@ do save current bit settings in r1
mov r1, r5
@ set SDRAM self-refresh bit
orr r5, r5, #(1 << 9)
str r5, [r4, #PWR_CTRL_REG_OFFS]
@ set SDRAM self-refresh bit latch
orr r5, r5, #(1 << 8)
str r5, [r4, #PWR_CTRL_REG_OFFS]
@ clear SDRAM self-refresh bit latch
and r5, r5, #(~(1 << 8))
str r5, [r4, #PWR_CTRL_REG_OFFS]
@ clear SDRAM self-refresh bit
and r5, r5, #(~(1 << 9))
str r5, [r4, #PWR_CTRL_REG_OFFS]
@ wait for SDRAM to get into self-refresh mode
2: ldr r3, [r2, #MPMC_STATUS_REG_OFFS]
tst r3, #(1 << 2)
beq 2b
@ set 'get out of self-refresh mode after wakeup' bit
orr r5, r5, #(1 << 7)
str r5, [r4, #PWR_CTRL_REG_OFFS]
mcr p15, 0, r0, c7, c0, 4 @ kinda sleeping now...
@ set SDRAM self-refresh bit latch
orr r5, r5, #(1 << 8)
str r5, [r4, #PWR_CTRL_REG_OFFS]
@ clear SDRAM self-refresh bit latch
and r5, r5, #(~(1 << 8))
str r5, [r4, #PWR_CTRL_REG_OFFS]
@ wait for SDRAM to get out self-refresh mode
3: ldr r3, [r2, #MPMC_STATUS_REG_OFFS]
tst r3, #5
bne 3b
@ restore regs and return
ldmfd sp!, {r0 - r6, pc}
ENTRY(pnx4008_cpu_standby_sz)
.word . - pnx4008_cpu_standby
ENTRY(pnx4008_cache_clean_invalidate)
stmfd sp!, {r0 - r6, lr}
#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache
#else
1: mrc p15, 0, r15, c7, c14, 3 @ test,clean,invalidate
bne 1b
#endif
ldmfd sp!, {r0 - r6, pc}

View file

@ -0,0 +1,141 @@
/*
* arch/arm/mach-pnx4008/time.c
*
* PNX4008 Timers
*
* Authors: Vitaly Wool, Dmitry Chigirev, Grigory Tolstolytkin <source@mvista.com>
*
* 2005 (c) MontaVista Software, Inc. This file is licensed under
* the terms of the GNU General Public License version 2. This program
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
*/
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/sched.h>
#include <linux/spinlock.h>
#include <linux/module.h>
#include <linux/kallsyms.h>
#include <asm/system.h>
#include <asm/hardware.h>
#include <asm/io.h>
#include <asm/leds.h>
#include <asm/irq.h>
#include <asm/mach/irq.h>
#include <asm/mach/time.h>
#include <linux/time.h>
#include <linux/timex.h>
#include <asm/errno.h>
/*! Note: all timers are UPCOUNTING */
/*!
* Returns number of us since last clock interrupt. Note that interrupts
* will have been disabled by do_gettimeoffset()
*/
static unsigned long pnx4008_gettimeoffset(void)
{
u32 ticks_to_match =
__raw_readl(HSTIM_MATCH0) - __raw_readl(HSTIM_COUNTER);
u32 elapsed = LATCH - ticks_to_match;
return (elapsed * (tick_nsec / 1000)) / LATCH;
}
/*!
* IRQ handler for the timer
*/
static irqreturn_t pnx4008_timer_interrupt(int irq, void *dev_id,
struct pt_regs *regs)
{
if (__raw_readl(HSTIM_INT) & MATCH0_INT) {
write_seqlock(&xtime_lock);
do {
timer_tick(regs);
/*
* this algorithm takes care of possible delay
* for this interrupt handling longer than a normal
* timer period
*/
__raw_writel(__raw_readl(HSTIM_MATCH0) + LATCH,
HSTIM_MATCH0);
__raw_writel(MATCH0_INT, HSTIM_INT); /* clear interrupt */
/*
* The goal is to keep incrementing HSTIM_MATCH0
* register until HSTIM_MATCH0 indicates time after
* what HSTIM_COUNTER indicates.
*/
} while ((signed)
(__raw_readl(HSTIM_MATCH0) -
__raw_readl(HSTIM_COUNTER)) < 0);
write_sequnlock(&xtime_lock);
}
return IRQ_HANDLED;
}
static struct irqaction pnx4008_timer_irq = {
.name = "PNX4008 Tick Timer",
.flags = SA_INTERRUPT | SA_TIMER,
.handler = pnx4008_timer_interrupt
};
/*!
* Set up timer and timer interrupt.
*/
static __init void pnx4008_setup_timer(void)
{
__raw_writel(RESET_COUNT, MSTIM_CTRL);
while (__raw_readl(MSTIM_COUNTER)) ; /* wait for reset to complete. 100% guarantee event */
__raw_writel(0, MSTIM_CTRL); /* stop the timer */
__raw_writel(0, MSTIM_MCTRL);
__raw_writel(RESET_COUNT, HSTIM_CTRL);
while (__raw_readl(HSTIM_COUNTER)) ; /* wait for reset to complete. 100% guarantee event */
__raw_writel(0, HSTIM_CTRL);
__raw_writel(0, HSTIM_MCTRL);
__raw_writel(0, HSTIM_CCR);
__raw_writel(12, HSTIM_PMATCH); /* scale down to 1 MHZ */
__raw_writel(LATCH, HSTIM_MATCH0);
__raw_writel(MR0_INT, HSTIM_MCTRL);
setup_irq(HSTIMER_INT, &pnx4008_timer_irq);
__raw_writel(COUNT_ENAB | DEBUG_EN, HSTIM_CTRL); /*start timer, stop when JTAG active */
}
/* Timer Clock Control in PM register */
#define TIMCLK_CTRL_REG IO_ADDRESS((PNX4008_PWRMAN_BASE + 0xBC))
#define WATCHDOG_CLK_EN 1
#define TIMER_CLK_EN 2 /* HS and MS timers? */
static u32 timclk_ctrl_reg_save;
void pnx4008_timer_suspend(void)
{
timclk_ctrl_reg_save = __raw_readl(TIMCLK_CTRL_REG);
__raw_writel(0, TIMCLK_CTRL_REG); /* disable timers */
}
void pnx4008_timer_resume(void)
{
__raw_writel(timclk_ctrl_reg_save, TIMCLK_CTRL_REG); /* enable timers */
}
struct sys_timer pnx4008_timer = {
.init = pnx4008_setup_timer,
.offset = pnx4008_gettimeoffset,
.suspend = pnx4008_timer_suspend,
.resume = pnx4008_timer_resume,
};

View file

@ -22,6 +22,10 @@
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/spi/spi.h>
#include <linux/spi/ads7846.h>
#include <asm/arch/pxa2xx_spi.h>
#include <asm/setup.h>
#include <asm/memory.h>
#include <asm/mach-types.h>
@ -196,6 +200,78 @@ static struct resource smc91x_resources[] = {
},
};
/* ADS7846 is connected through SSP ... and if your board has J5 populated,
* you can select it to replace the ucb1400 by switching the touchscreen cable
* (to J5) and poking board registers (as done below). Else it's only useful
* for the temperature sensors.
*/
static struct resource pxa_ssp_resources[] = {
[0] = {
.start = __PREG(SSCR0_P(1)),
.end = __PREG(SSCR0_P(1)) + 0x14,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = IRQ_SSP,
.end = IRQ_SSP,
.flags = IORESOURCE_IRQ,
},
};
static struct pxa2xx_spi_master pxa_ssp_master_info = {
.ssp_type = PXA25x_SSP,
.clock_enable = CKEN3_SSP,
.num_chipselect = 0,
};
static struct platform_device pxa_ssp = {
.name = "pxa2xx-spi",
.id = 1,
.resource = pxa_ssp_resources,
.num_resources = ARRAY_SIZE(pxa_ssp_resources),
.dev = {
.platform_data = &pxa_ssp_master_info,
},
};
static int lubbock_ads7846_pendown_state(void)
{
/* TS_BUSY is bit 8 in LUB_MISC_RD, but pendown is irq-only */
return 0;
}
static struct ads7846_platform_data ads_info = {
.model = 7846,
.vref_delay_usecs = 100, /* internal, no cap */
.get_pendown_state = lubbock_ads7846_pendown_state,
// .x_plate_ohms = 500, /* GUESS! */
// .y_plate_ohms = 500, /* GUESS! */
};
static void ads7846_cs(u32 command)
{
static const unsigned TS_nCS = 1 << 11;
lubbock_set_misc_wr(TS_nCS, (command == PXA2XX_CS_ASSERT) ? 0 : TS_nCS);
}
static struct pxa2xx_spi_chip ads_hw = {
.tx_threshold = 1,
.rx_threshold = 2,
.cs_control = ads7846_cs,
};
static struct spi_board_info spi_board_info[] __initdata = { {
.modalias = "ads7846",
.platform_data = &ads_info,
.controller_data = &ads_hw,
.irq = LUBBOCK_BB_IRQ,
.max_speed_hz = 120000 /* max sample rate at 3V */
* 26 /* command + data + overhead */,
.bus_num = 1,
.chip_select = 0,
},
};
static struct platform_device smc91x_device = {
.name = "smc91x",
.id = -1,
@ -272,6 +348,7 @@ static struct platform_device *devices[] __initdata = {
&smc91x_device,
&lubbock_flash_device[0],
&lubbock_flash_device[1],
&pxa_ssp,
};
static struct pxafb_mach_info sharp_lm8v31 __initdata = {
@ -400,6 +477,8 @@ static void __init lubbock_init(void)
lubbock_flash_data[flashboot^1].name = "application-flash";
lubbock_flash_data[flashboot].name = "boot-rom";
(void) platform_add_devices(devices, ARRAY_SIZE(devices));
spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
}
static struct map_desc lubbock_io_desc[] __initdata = {
@ -416,6 +495,11 @@ static void __init lubbock_map_io(void)
pxa_map_io();
iotable_init(lubbock_io_desc, ARRAY_SIZE(lubbock_io_desc));
/* SSP data pins */
pxa_gpio_mode(GPIO23_SCLK_MD);
pxa_gpio_mode(GPIO25_STXD_MD);
pxa_gpio_mode(GPIO26_SRXD_MD);
/* This enables the BTUART */
pxa_gpio_mode(GPIO42_BTRXD_MD);
pxa_gpio_mode(GPIO43_BTTXD_MD);

View file

@ -70,6 +70,18 @@ config ARCH_S3C2440
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_VR1000
bool "Thorcom VR1000"
select CPU_S3C2410
@ -109,12 +121,26 @@ config CPU_S3C2410
Support for S3C2410 and S3C2410A family from the S3C24XX line
of Samsung Mobile CPUs.
config CPU_S3C244X
bool
depends on ARCH_S3C2410 && (CPU_S3C2440 || CPU_S3C2442)
help
Support for S3C2440 and S3C2442 Samsung Mobile CPU based systems.
config CPU_S3C2440
bool
depends on ARCH_S3C2410
select CPU_S3C244X
help
Support for S3C2440 Samsung Mobile CPU based systems.
config CPU_S3C2442
bool
depends on ARCH_S3C2420
select CPU_S3C244X
help
Support for S3C2442 Samsung Mobile CPU based systems.
comment "S3C2410 Boot"
config S3C2410_BOOT_WATCHDOG

View file

@ -24,6 +24,11 @@ obj-$(CONFIG_S3C2410_DMA) += dma.o
obj-$(CONFIG_PM) += pm.o sleep.o
obj-$(CONFIG_PM_SIMTEC) += pm-simtec.o
# S3C244X support
obj-$(CONFIG_CPU_S3C244X) += s3c244x.o
obj-$(CONFIG_CPU_S3C244X) += s3c244x-irq.o
# S3C2440 support
obj-$(CONFIG_CPU_S3C2440) += s3c2440.o s3c2440-dsc.o
@ -31,6 +36,11 @@ obj-$(CONFIG_CPU_S3C2440) += s3c2440-irq.o
obj-$(CONFIG_CPU_S3C2440) += s3c2440-clock.o
obj-$(CONFIG_CPU_S3C2440) += s3c2410-gpio.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

View file

@ -70,7 +70,7 @@ void inline s3c24xx_clk_enable(unsigned int clocks, unsigned int enable)
clkcon &= ~clocks;
/* ensure none of the special function bits set */
clkcon &= ~(S3C2410_CLKCON_IDLE|S3C2410_CLKCON_POWER);
clkcon &= ~(S3C2410_CLKCON_IDLE|S3C2410_CLKCON_POWER | 3);
__raw_writel(clkcon, S3C2410_CLKCON);
}

View file

@ -34,6 +34,7 @@
#include <asm/irq.h>
#include <asm/arch/regs-gpio.h>
#include <asm/arch/leds-gpio.h>
#include <asm/arch/nand.h>
@ -41,6 +42,66 @@
#include "devs.h"
#include "pm.h"
/* LED devices */
static struct s3c24xx_led_platdata smdk_pdata_led4 = {
.gpio = S3C2410_GPF4,
.flags = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE,
.name = "led4",
.def_trigger = "timer",
};
static struct s3c24xx_led_platdata smdk_pdata_led5 = {
.gpio = S3C2410_GPF5,
.flags = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE,
.name = "led5",
.def_trigger = "nand-disk",
};
static struct s3c24xx_led_platdata smdk_pdata_led6 = {
.gpio = S3C2410_GPF6,
.flags = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE,
.name = "led6",
};
static struct s3c24xx_led_platdata smdk_pdata_led7 = {
.gpio = S3C2410_GPF7,
.flags = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE,
.name = "led7",
};
static struct platform_device smdk_led4 = {
.name = "s3c24xx_led",
.id = 0,
.dev = {
.platform_data = &smdk_pdata_led4,
},
};
static struct platform_device smdk_led5 = {
.name = "s3c24xx_led",
.id = 1,
.dev = {
.platform_data = &smdk_pdata_led5,
},
};
static struct platform_device smdk_led6 = {
.name = "s3c24xx_led",
.id = 2,
.dev = {
.platform_data = &smdk_pdata_led6,
},
};
static struct platform_device smdk_led7 = {
.name = "s3c24xx_led",
.id = 3,
.dev = {
.platform_data = &smdk_pdata_led7,
},
};
/* NAND parititon from 2.4.18-swl5 */
static struct mtd_partition smdk_default_nand_part[] = {
@ -111,6 +172,10 @@ static struct s3c2410_platform_nand smdk_nand_info = {
static struct platform_device __initdata *smdk_devs[] = {
&s3c_device_nand,
&smdk_led4,
&smdk_led5,
&smdk_led6,
&smdk_led7,
};
void __init smdk_machine_init(void)

View file

@ -37,12 +37,16 @@
#include <asm/mach/map.h>
#include <asm/arch/regs-gpio.h>
#include <asm/arch/regs-serial.h>
#include "cpu.h"
#include "devs.h"
#include "clock.h"
#include "s3c2400.h"
#include "s3c2410.h"
#include "s3c244x.h"
#include "s3c2440.h"
#include "s3c2442.h"
struct cpu_table {
unsigned long idcode;
@ -59,6 +63,7 @@ struct cpu_table {
static const char name_s3c2400[] = "S3C2400";
static const char name_s3c2410[] = "S3C2410";
static const char name_s3c2440[] = "S3C2440";
static const char name_s3c2442[] = "S3C2442";
static const char name_s3c2410a[] = "S3C2410A";
static const char name_s3c2440a[] = "S3C2440A";
@ -84,21 +89,30 @@ static struct cpu_table cpu_ids[] __initdata = {
{
.idcode = 0x32440000,
.idmask = 0xffffffff,
.map_io = s3c2440_map_io,
.init_clocks = s3c2440_init_clocks,
.init_uarts = s3c2440_init_uarts,
.map_io = s3c244x_map_io,
.init_clocks = s3c244x_init_clocks,
.init_uarts = s3c244x_init_uarts,
.init = s3c2440_init,
.name = name_s3c2440
},
{
.idcode = 0x32440001,
.idmask = 0xffffffff,
.map_io = s3c2440_map_io,
.init_clocks = s3c2440_init_clocks,
.init_uarts = s3c2440_init_uarts,
.map_io = s3c244x_map_io,
.init_clocks = s3c244x_init_clocks,
.init_uarts = s3c244x_init_uarts,
.init = s3c2440_init,
.name = name_s3c2440a
},
{
.idcode = 0x32440aaa,
.idmask = 0xffffffff,
.map_io = s3c244x_map_io,
.init_clocks = s3c244x_init_clocks,
.init_uarts = s3c244x_init_uarts,
.init = s3c2442_init,
.name = name_s3c2442
},
{
.idcode = 0x0, /* S3C2400 doesn't have an idcode */
.idmask = 0xffffffff,
@ -175,13 +189,13 @@ void __init s3c24xx_init_io(struct map_desc *mach_desc, int size)
panic("Unknown S3C24XX CPU");
}
printk("CPU %s (id 0x%08lx)\n", cpu->name, idcode);
if (cpu->map_io == NULL || cpu->init == NULL) {
printk(KERN_ERR "CPU %s support not enabled\n", cpu->name);
panic("Unsupported S3C24XX CPU");
}
printk("CPU %s (id 0x%08lx)\n", cpu->name, idcode);
(cpu->map_io)(mach_desc, size);
}
@ -208,6 +222,49 @@ void __init s3c24xx_init_clocks(int xtal)
(cpu->init_clocks)(xtal);
}
/* uart management */
static int nr_uarts __initdata = 0;
static struct s3c2410_uartcfg uart_cfgs[3];
/* s3c24xx_init_uartdevs
*
* copy the specified platform data and configuration into our central
* set of devices, before the data is thrown away after the init process.
*
* This also fills in the array passed to the serial driver for the
* early initialisation of the console.
*/
void __init s3c24xx_init_uartdevs(char *name,
struct s3c24xx_uart_resources *res,
struct s3c2410_uartcfg *cfg, int no)
{
struct platform_device *platdev;
struct s3c2410_uartcfg *cfgptr = uart_cfgs;
struct s3c24xx_uart_resources *resp;
int uart;
memcpy(cfgptr, cfg, sizeof(struct s3c2410_uartcfg) * no);
for (uart = 0; uart < no; uart++, cfg++, cfgptr++) {
platdev = s3c24xx_uart_src[cfgptr->hwport];
resp = res + cfgptr->hwport;
s3c24xx_uart_devs[uart] = platdev;
platdev->name = name;
platdev->resource = resp->resources;
platdev->num_resources = resp->nr_resources;
platdev->dev.platform_data = cfgptr;
}
nr_uarts = no;
}
void __init s3c24xx_init_uarts(struct s3c2410_uartcfg *cfg, int no)
{
if (cpu == NULL)
@ -232,6 +289,10 @@ static int __init s3c_arch_init(void)
if (ret != 0)
return ret;
ret = platform_add_devices(s3c24xx_uart_devs, nr_uarts);
if (ret != 0)
return ret;
if (board != NULL) {
struct platform_device **ptr = board->devices;
int i;

View file

@ -31,6 +31,8 @@
#define print_mhz(m) ((m) / MHZ), ((m / 1000) % 1000)
/* forward declaration */
struct s3c24xx_uart_resources;
struct platform_device;
struct s3c2410_uartcfg;
struct map_desc;
@ -44,6 +46,10 @@ extern void s3c24xx_init_uarts(struct s3c2410_uartcfg *cfg, int no);
extern void s3c24xx_init_clocks(int xtal);
extern void s3c24xx_init_uartdevs(char *name,
struct s3c24xx_uart_resources *res,
struct s3c2410_uartcfg *cfg, int no);
/* the board structure is used at first initialsation time
* to get info such as the devices to register for this
* board. This is done because platfrom_add_devices() cannot
@ -68,3 +74,4 @@ extern struct sys_timer s3c24xx_timer;
/* system device classes */
extern struct sysdev_class s3c2440_sysclass;
extern struct sysdev_class s3c2442_sysclass;

View file

@ -38,10 +38,86 @@
#include <asm/arch/regs-serial.h>
#include "devs.h"
#include "cpu.h"
/* Serial port registrations */
struct platform_device *s3c24xx_uart_devs[3];
static struct resource s3c2410_uart0_resource[] = {
[0] = {
.start = S3C2410_PA_UART0,
.end = S3C2410_PA_UART0 + 0x3fff,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = IRQ_S3CUART_RX0,
.end = IRQ_S3CUART_ERR0,
.flags = IORESOURCE_IRQ,
}
};
static struct resource s3c2410_uart1_resource[] = {
[0] = {
.start = S3C2410_PA_UART1,
.end = S3C2410_PA_UART1 + 0x3fff,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = IRQ_S3CUART_RX1,
.end = IRQ_S3CUART_ERR1,
.flags = IORESOURCE_IRQ,
}
};
static struct resource s3c2410_uart2_resource[] = {
[0] = {
.start = S3C2410_PA_UART2,
.end = S3C2410_PA_UART2 + 0x3fff,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = IRQ_S3CUART_RX2,
.end = IRQ_S3CUART_ERR2,
.flags = IORESOURCE_IRQ,
}
};
struct s3c24xx_uart_resources s3c2410_uart_resources[] __initdata = {
[0] = {
.resources = s3c2410_uart0_resource,
.nr_resources = ARRAY_SIZE(s3c2410_uart0_resource),
},
[1] = {
.resources = s3c2410_uart1_resource,
.nr_resources = ARRAY_SIZE(s3c2410_uart1_resource),
},
[2] = {
.resources = s3c2410_uart2_resource,
.nr_resources = ARRAY_SIZE(s3c2410_uart2_resource),
},
};
/* yart devices */
static struct platform_device s3c24xx_uart_device0 = {
.id = 0,
};
static struct platform_device s3c24xx_uart_device1 = {
.id = 1,
};
static struct platform_device s3c24xx_uart_device2 = {
.id = 2,
};
struct platform_device *s3c24xx_uart_src[3] = {
&s3c24xx_uart_device0,
&s3c24xx_uart_device1,
&s3c24xx_uart_device2,
};
struct platform_device *s3c24xx_uart_devs[3] = {
};
/* USB Host Controller */

View file

@ -17,7 +17,15 @@
#include <linux/config.h>
#include <linux/platform_device.h>
struct s3c24xx_uart_resources {
struct resource *resources;
unsigned long nr_resources;
};
extern struct s3c24xx_uart_resources s3c2410_uart_resources[];
extern struct platform_device *s3c24xx_uart_devs[];
extern struct platform_device *s3c24xx_uart_src[];
extern struct platform_device s3c_device_usb;
extern struct platform_device s3c_device_lcd;

View file

@ -131,7 +131,7 @@ static struct s3c24xx_uart_clksrc anubis_serial_clocks[] = {
};
static struct s3c2410_uartcfg anubis_uartcfgs[] = {
static struct s3c2410_uartcfg anubis_uartcfgs[] __initdata = {
[0] = {
.hwport = 0,
.flags = 0,

View file

@ -208,7 +208,7 @@ static struct s3c24xx_uart_clksrc bast_serial_clocks[] = {
};
static struct s3c2410_uartcfg bast_uartcfgs[] = {
static struct s3c2410_uartcfg bast_uartcfgs[] __initdata = {
[0] = {
.hwport = 0,
.flags = 0,

View file

@ -72,7 +72,7 @@ static struct map_desc h1940_iodesc[] __initdata = {
#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
static struct s3c2410_uartcfg h1940_uartcfgs[] = {
static struct s3c2410_uartcfg h1940_uartcfgs[] __initdata = {
[0] = {
.hwport = 0,
.flags = 0,

View file

@ -51,7 +51,7 @@ static struct map_desc nexcoder_iodesc[] __initdata = {
#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
#define UFCON S3C2410_UFCON_RXTRIG12 | S3C2410_UFCON_FIFOMODE
static struct s3c2410_uartcfg nexcoder_uartcfgs[] = {
static struct s3c2410_uartcfg nexcoder_uartcfgs[] __initdata = {
[0] = {
.hwport = 0,
.flags = 0,

View file

@ -95,8 +95,7 @@ static struct s3c24xx_uart_clksrc osiris_serial_clocks[] = {
}
};
static struct s3c2410_uartcfg osiris_uartcfgs[] = {
static struct s3c2410_uartcfg osiris_uartcfgs[] __initdata = {
[0] = {
.hwport = 0,
.flags = 0,
@ -107,7 +106,7 @@ static struct s3c2410_uartcfg osiris_uartcfgs[] = {
.clocks_size = ARRAY_SIZE(osiris_serial_clocks)
},
[1] = {
.hwport = 2,
.hwport = 1,
.flags = 0,
.ucon = UCON,
.ulcon = ULCON,

View file

@ -45,7 +45,7 @@ static struct map_desc otom11_iodesc[] __initdata = {
#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
#define UFCON S3C2410_UFCON_RXTRIG12 | S3C2410_UFCON_FIFOMODE
static struct s3c2410_uartcfg otom11_uartcfgs[] = {
static struct s3c2410_uartcfg otom11_uartcfgs[] __initdata = {
[0] = {
.hwport = 0,
.flags = 0,

View file

@ -65,7 +65,7 @@ static struct map_desc smdk2410_iodesc[] __initdata = {
#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
static struct s3c2410_uartcfg smdk2410_uartcfgs[] = {
static struct s3c2410_uartcfg smdk2410_uartcfgs[] __initdata = {
[0] = {
.hwport = 0,
.flags = 0,

View file

@ -86,7 +86,7 @@ static struct map_desc smdk2440_iodesc[] __initdata = {
#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
static struct s3c2410_uartcfg smdk2440_uartcfgs[] = {
static struct s3c2410_uartcfg smdk2440_uartcfgs[] __initdata = {
[0] = {
.hwport = 0,
.flags = 0,

View file

@ -166,7 +166,7 @@ static struct s3c24xx_uart_clksrc vr1000_serial_clocks[] = {
}
};
static struct s3c2410_uartcfg vr1000_uartcfgs[] = {
static struct s3c2410_uartcfg vr1000_uartcfgs[] __initdata = {
[0] = {
.hwport = 0,
.flags = 0,

View file

@ -58,7 +58,11 @@ unsigned long s3c_pm_flags;
/* cache functions from arch/arm/mm/proc-arm920.S */
#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
extern void arm920_flush_kern_cache_all(void);
#else
static void arm920_flush_kern_cache_all(void) { }
#endif
#define PFX "s3c24xx-pm: "

View file

@ -42,6 +42,7 @@
#include "s3c2410.h"
#include "cpu.h"
#include "devs.h"
#include "clock.h"
/* Initial IO mappings */
@ -55,93 +56,13 @@ static struct map_desc s3c2410_iodesc[] __initdata = {
IODESC_ENT(WATCHDOG),
};
static struct resource s3c_uart0_resource[] = {
[0] = {
.start = S3C2410_PA_UART0,
.end = S3C2410_PA_UART0 + 0x3fff,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = IRQ_S3CUART_RX0,
.end = IRQ_S3CUART_ERR0,
.flags = IORESOURCE_IRQ,
}
};
static struct resource s3c_uart1_resource[] = {
[0] = {
.start = S3C2410_PA_UART1,
.end = S3C2410_PA_UART1 + 0x3fff,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = IRQ_S3CUART_RX1,
.end = IRQ_S3CUART_ERR1,
.flags = IORESOURCE_IRQ,
}
};
static struct resource s3c_uart2_resource[] = {
[0] = {
.start = S3C2410_PA_UART2,
.end = S3C2410_PA_UART2 + 0x3fff,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = IRQ_S3CUART_RX2,
.end = IRQ_S3CUART_ERR2,
.flags = IORESOURCE_IRQ,
}
};
/* our uart devices */
static struct platform_device s3c_uart0 = {
.name = "s3c2410-uart",
.id = 0,
.num_resources = ARRAY_SIZE(s3c_uart0_resource),
.resource = s3c_uart0_resource,
};
static struct platform_device s3c_uart1 = {
.name = "s3c2410-uart",
.id = 1,
.num_resources = ARRAY_SIZE(s3c_uart1_resource),
.resource = s3c_uart1_resource,
};
static struct platform_device s3c_uart2 = {
.name = "s3c2410-uart",
.id = 2,
.num_resources = ARRAY_SIZE(s3c_uart2_resource),
.resource = s3c_uart2_resource,
};
static struct platform_device *uart_devices[] __initdata = {
&s3c_uart0,
&s3c_uart1,
&s3c_uart2
};
static int s3c2410_uart_count = 0;
/* uart registration process */
void __init s3c2410_init_uarts(struct s3c2410_uartcfg *cfg, int no)
{
struct platform_device *platdev;
int uart;
for (uart = 0; uart < no; uart++, cfg++) {
platdev = uart_devices[cfg->hwport];
s3c24xx_uart_devs[uart] = platdev;
platdev->dev.platform_data = cfg;
}
s3c2410_uart_count = uart;
s3c24xx_init_uartdevs("s3c2410-uart", s3c2410_uart_resources, cfg, no);
}
/* s3c2410_map_io
@ -193,5 +114,5 @@ int __init s3c2410_init(void)
{
printk("S3C2410: Initialising architecture\n");
return platform_add_devices(s3c24xx_uart_devs, s3c2410_uart_count);
return 0;
}

View file

@ -100,73 +100,12 @@ static struct irqchip s3c_irq_wdtac97 = {
.ack = s3c_irq_wdtac97_ack,
};
/* camera irq */
static void s3c_irq_demux_cam(unsigned int irq,
struct irqdesc *desc,
struct pt_regs *regs)
{
unsigned int subsrc, submsk;
struct irqdesc *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 >>= 11;
subsrc &= 3;
if (subsrc != 0) {
if (subsrc & 1) {
mydesc = irq_desc + IRQ_S3C2440_CAM_C;
desc_handle_irq(IRQ_S3C2440_CAM_C, mydesc, regs);
}
if (subsrc & 2) {
mydesc = irq_desc + IRQ_S3C2440_CAM_P;
desc_handle_irq(IRQ_S3C2440_CAM_P, mydesc, regs);
}
}
}
#define INTMSK_CAM (1UL << (IRQ_CAM - IRQ_EINT0))
static void
s3c_irq_cam_mask(unsigned int irqno)
{
s3c_irqsub_mask(irqno, INTMSK_CAM, 3<<11);
}
static void
s3c_irq_cam_unmask(unsigned int irqno)
{
s3c_irqsub_unmask(irqno, INTMSK_CAM);
}
static void
s3c_irq_cam_ack(unsigned int irqno)
{
s3c_irqsub_maskack(irqno, INTMSK_CAM, 3<<11);
}
static struct irqchip s3c_irq_cam = {
.mask = s3c_irq_cam_mask,
.unmask = s3c_irq_cam_unmask,
.ack = s3c_irq_cam_ack,
};
static int s3c2440_irq_add(struct sys_device *sysdev)
{
unsigned int irqno;
printk("S3C2440: IRQ Support\n");
set_irq_chip(IRQ_NFCON, &s3c_irq_level_chip);
set_irq_handler(IRQ_NFCON, do_level_IRQ);
set_irq_flags(IRQ_NFCON, IRQF_VALID);
/* add new chained handler for wdt, ac7 */
set_irq_chip(IRQ_WDT, &s3c_irq_level_chip);
@ -179,18 +118,6 @@ static int s3c2440_irq_add(struct sys_device *sysdev)
set_irq_flags(irqno, IRQF_VALID);
}
/* add chained handler for camera */
set_irq_chip(IRQ_CAM, &s3c_irq_level_chip);
set_irq_handler(IRQ_CAM, do_level_IRQ);
set_irq_chained_handler(IRQ_CAM, s3c_irq_demux_cam);
for (irqno = IRQ_S3C2440_CAM_C; irqno <= IRQ_S3C2440_CAM_P; irqno++) {
set_irq_chip(irqno, &s3c_irq_cam);
set_irq_handler(irqno, do_level_IRQ);
set_irq_flags(irqno, IRQF_VALID);
}
return 0;
}
@ -198,10 +125,10 @@ static struct sysdev_driver s3c2440_irq_driver = {
.add = s3c2440_irq_add,
};
static int s3c24xx_irq_driver(void)
static int s3c2440_irq_init(void)
{
return sysdev_driver_register(&s3c2440_sysclass, &s3c2440_irq_driver);
}
arch_initcall(s3c24xx_irq_driver);
arch_initcall(s3c2440_irq_init);

View file

@ -1,6 +1,6 @@
/* linux/arch/arm/mach-s3c2410/s3c2440.c
*
* Copyright (c) 2004-2005 Simtec Electronics
* Copyright (c) 2004-2006 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
*
* Samsung S3C2440 Mobile CPU support
@ -8,16 +8,6 @@
* 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.
*
* Modifications:
* 24-Aug-2004 BJD Start of s3c2440 support
* 12-Oct-2004 BJD Moved clock info out to clock.c
* 01-Nov-2004 BJD Fixed clock build code
* 09-Nov-2004 BJD Added sysdev for power management
* 04-Nov-2004 BJD New serial registration
* 15-Nov-2004 BJD Rename the i2c device for the s3c2440
* 14-Jan-2005 BJD Moved clock init code into seperate function
* 14-Jan-2005 BJD Removed un-used clock bits
*/
#include <linux/kernel.h>
@ -50,234 +40,20 @@
#include "cpu.h"
#include "pm.h"
static struct map_desc s3c2440_iodesc[] __initdata = {
IODESC_ENT(USBHOST),
IODESC_ENT(CLKPWR),
IODESC_ENT(LCD),
IODESC_ENT(TIMER),
IODESC_ENT(ADC),
IODESC_ENT(WATCHDOG),
};
static struct resource s3c_uart0_resource[] = {
[0] = {
.start = S3C2410_PA_UART0,
.end = S3C2410_PA_UART0 + 0x3fff,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = IRQ_S3CUART_RX0,
.end = IRQ_S3CUART_ERR0,
.flags = IORESOURCE_IRQ,
}
};
static struct resource s3c_uart1_resource[] = {
[0] = {
.start = S3C2410_PA_UART1,
.end = S3C2410_PA_UART1 + 0x3fff,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = IRQ_S3CUART_RX1,
.end = IRQ_S3CUART_ERR1,
.flags = IORESOURCE_IRQ,
}
};
static struct resource s3c_uart2_resource[] = {
[0] = {
.start = S3C2410_PA_UART2,
.end = S3C2410_PA_UART2 + 0x3fff,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = IRQ_S3CUART_RX2,
.end = IRQ_S3CUART_ERR2,
.flags = IORESOURCE_IRQ,
}
};
/* our uart devices */
static struct platform_device s3c_uart0 = {
.name = "s3c2440-uart",
.id = 0,
.num_resources = ARRAY_SIZE(s3c_uart0_resource),
.resource = s3c_uart0_resource,
};
static struct platform_device s3c_uart1 = {
.name = "s3c2440-uart",
.id = 1,
.num_resources = ARRAY_SIZE(s3c_uart1_resource),
.resource = s3c_uart1_resource,
};
static struct platform_device s3c_uart2 = {
.name = "s3c2440-uart",
.id = 2,
.num_resources = ARRAY_SIZE(s3c_uart2_resource),
.resource = s3c_uart2_resource,
};
static struct platform_device *uart_devices[] __initdata = {
&s3c_uart0,
&s3c_uart1,
&s3c_uart2
};
/* uart initialisation */
static int __initdata s3c2440_uart_count;
void __init s3c2440_init_uarts(struct s3c2410_uartcfg *cfg, int no)
{
struct platform_device *platdev;
int uart;
for (uart = 0; uart < no; uart++, cfg++) {
platdev = uart_devices[cfg->hwport];
s3c24xx_uart_devs[uart] = platdev;
platdev->dev.platform_data = cfg;
}
s3c2440_uart_count = uart;
}
#ifdef CONFIG_PM
static struct sleep_save s3c2440_sleep[] = {
SAVE_ITEM(S3C2440_DSC0),
SAVE_ITEM(S3C2440_DSC1),
SAVE_ITEM(S3C2440_GPJDAT),
SAVE_ITEM(S3C2440_GPJCON),
SAVE_ITEM(S3C2440_GPJUP)
};
static int s3c2440_suspend(struct sys_device *dev, pm_message_t state)
{
s3c2410_pm_do_save(s3c2440_sleep, ARRAY_SIZE(s3c2440_sleep));
return 0;
}
static int s3c2440_resume(struct sys_device *dev)
{
s3c2410_pm_do_restore(s3c2440_sleep, ARRAY_SIZE(s3c2440_sleep));
return 0;
}
#else
#define s3c2440_suspend NULL
#define s3c2440_resume NULL
#endif
struct sysdev_class s3c2440_sysclass = {
set_kset_name("s3c2440-core"),
.suspend = s3c2440_suspend,
.resume = s3c2440_resume
};
static struct sys_device s3c2440_sysdev = {
.cls = &s3c2440_sysclass,
};
void __init s3c2440_map_io(struct map_desc *mach_desc, int size)
int __init s3c2440_init(void)
{
/* register our io-tables */
iotable_init(s3c2440_iodesc, ARRAY_SIZE(s3c2440_iodesc));
iotable_init(mach_desc, size);
/* rename any peripherals used differing from the s3c2410 */
s3c_device_i2c.name = "s3c2440-i2c";
s3c_device_nand.name = "s3c2440-nand";
printk("S3C2440: Initialising architecture\n");
/* change irq for watchdog */
s3c_device_wdt.resource[1].start = IRQ_S3C2440_WDT;
s3c_device_wdt.resource[1].end = IRQ_S3C2440_WDT;
}
void __init s3c2440_init_clocks(int xtal)
{
unsigned long clkdiv;
unsigned long camdiv;
unsigned long hclk, fclk, pclk;
int hdiv = 1;
/* now we've got our machine bits initialised, work out what
* clocks we've got */
fclk = s3c2410_get_pll(__raw_readl(S3C2410_MPLLCON), xtal) * 2;
clkdiv = __raw_readl(S3C2410_CLKDIVN);
camdiv = __raw_readl(S3C2440_CAMDIVN);
/* work out clock scalings */
switch (clkdiv & S3C2440_CLKDIVN_HDIVN_MASK) {
case S3C2440_CLKDIVN_HDIVN_1:
hdiv = 1;
break;
case S3C2440_CLKDIVN_HDIVN_2:
hdiv = 2;
break;
case S3C2440_CLKDIVN_HDIVN_4_8:
hdiv = (camdiv & S3C2440_CAMDIVN_HCLK4_HALF) ? 8 : 4;
break;
case S3C2440_CLKDIVN_HDIVN_3_6:
hdiv = (camdiv & S3C2440_CAMDIVN_HCLK3_HALF) ? 6 : 3;
break;
}
hclk = fclk / hdiv;
pclk = hclk / ((clkdiv & S3C2440_CLKDIVN_PDIVN)? 2:1);
/* print brief summary of clocks, etc */
printk("S3C2440: core %ld.%03ld MHz, memory %ld.%03ld MHz, peripheral %ld.%03ld MHz\n",
print_mhz(fclk), print_mhz(hclk), print_mhz(pclk));
/* initialise the clocks here, to allow other things like the
* console to use them, and to add new ones after the initialisation
*/
s3c24xx_setup_clocks(xtal, fclk, hclk, pclk);
}
/* need to register class before we actually register the device, and
* we also need to ensure that it has been initialised before any of the
* drivers even try to use it (even if not on an s3c2440 based system)
* as a driver which may support both 2410 and 2440 may try and use it.
*/
static int __init s3c2440_core_init(void)
{
return sysdev_class_register(&s3c2440_sysclass);
}
core_initcall(s3c2440_core_init);
int __init s3c2440_init(void)
{
int ret;
printk("S3C2440: Initialising architecture\n");
ret = sysdev_register(&s3c2440_sysdev);
if (ret != 0)
printk(KERN_ERR "failed to register sysdev for s3c2440\n");
else
ret = platform_add_devices(s3c24xx_uart_devs, s3c2440_uart_count);
return ret;
/* register our system device for everything else */
return sysdev_register(&s3c2440_sysdev);
}

View file

@ -0,0 +1,171 @@
/* linux/arch/arm/mach-s3c2410/s3c2442-clock.c
*
* Copyright (c) 2004-2005 Simtec Electronics
* http://armlinux.simtec.co.uk/
* Ben Dooks <ben@simtec.co.uk>
*
* S3C2442 Clock 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/device.h>
#include <linux/sysdev.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/mutex.h>
#include <linux/clk.h>
#include <asm/hardware.h>
#include <asm/atomic.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <asm/arch/regs-clock.h>
#include "clock.h"
#include "cpu.h"
/* S3C2442 extended clock support */
static unsigned long s3c2442_camif_upll_round(struct clk *clk,
unsigned long rate)
{
unsigned long parent_rate = clk_get_rate(clk->parent);
int div;
if (rate > parent_rate)
return parent_rate;
div = parent_rate / rate;
if (div == 3)
return parent_rate / 3;
/* note, we remove the +/- 1 calculations for the divisor */
div /= 2;
if (div < 1)
div = 1;
else if (div > 16)
div = 16;
return parent_rate / (div * 2);
}
static int s3c2442_camif_upll_setrate(struct clk *clk, unsigned long rate)
{
unsigned long parent_rate = clk_get_rate(clk->parent);
unsigned long camdivn = __raw_readl(S3C2440_CAMDIVN);
rate = s3c2442_camif_upll_round(clk, rate);
camdivn &= ~S3C2442_CAMDIVN_CAMCLK_DIV3;
if (rate == parent_rate) {
camdivn &= ~S3C2440_CAMDIVN_CAMCLK_SEL;
} else if ((parent_rate / rate) == 3) {
camdivn |= S3C2440_CAMDIVN_CAMCLK_SEL;
camdivn |= S3C2442_CAMDIVN_CAMCLK_DIV3;
} else {
camdivn &= ~S3C2440_CAMDIVN_CAMCLK_MASK;
camdivn |= S3C2440_CAMDIVN_CAMCLK_SEL;
camdivn |= (((parent_rate / rate) / 2) - 1);
}
__raw_writel(camdivn, S3C2440_CAMDIVN);
return 0;
}
/* Extra S3C2442 clocks */
static struct clk s3c2442_clk_cam = {
.name = "camif",
.id = -1,
.enable = s3c24xx_clkcon_enable,
.ctrlbit = S3C2440_CLKCON_CAMERA,
};
static struct clk s3c2442_clk_cam_upll = {
.name = "camif-upll",
.id = -1,
.set_rate = s3c2442_camif_upll_setrate,
.round_rate = s3c2442_camif_upll_round,
};
static int s3c2442_clk_add(struct sys_device *sysdev)
{
unsigned long camdivn = __raw_readl(S3C2440_CAMDIVN);
unsigned long clkdivn;
struct clk *clk_h;
struct clk *clk_p;
struct clk *clk_upll;
printk("S3C2442: Clock Support, DVS %s\n",
(camdivn & S3C2440_CAMDIVN_DVSEN) ? "on" : "off");
clk_p = clk_get(NULL, "pclk");
clk_h = clk_get(NULL, "hclk");
clk_upll = clk_get(NULL, "upll");
if (IS_ERR(clk_p) || IS_ERR(clk_h) || IS_ERR(clk_upll)) {
printk(KERN_ERR "S3C2442: Failed to get parent clocks\n");
return -EINVAL;
}
/* check rate of UPLL, and if it is near 96MHz, then change
* to using half the UPLL rate for the system */
if (clk_get_rate(clk_upll) > (94 * MHZ)) {
clk_usb_bus.rate = clk_get_rate(clk_upll) / 2;
mutex_lock(&clocks_mutex);
clkdivn = __raw_readl(S3C2410_CLKDIVN);
clkdivn |= S3C2440_CLKDIVN_UCLK;
__raw_writel(clkdivn, S3C2410_CLKDIVN);
mutex_unlock(&clocks_mutex);
}
s3c2442_clk_cam.parent = clk_h;
s3c2442_clk_cam_upll.parent = clk_upll;
s3c24xx_register_clock(&s3c2442_clk_cam);
s3c24xx_register_clock(&s3c2442_clk_cam_upll);
clk_disable(&s3c2442_clk_cam);
return 0;
}
static struct sysdev_driver s3c2442_clk_driver = {
.add = s3c2442_clk_add,
};
static __init int s3c2442_clk_init(void)
{
return sysdev_driver_register(&s3c2442_sysclass, &s3c2442_clk_driver);
}
arch_initcall(s3c2442_clk_init);

View file

@ -0,0 +1,52 @@
/* linux/arch/arm/mach-s3c2410/s3c2440.c
*
* Copyright (c) 2006 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
*
* Samsung S3C2442 Mobile CPU support
*
* 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/types.h>
#include <linux/interrupt.h>
#include <linux/list.h>
#include <linux/timer.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/sysdev.h>
#include <linux/clk.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
#include <asm/hardware.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/arch/regs-clock.h>
#include <asm/arch/regs-serial.h>
#include <asm/arch/regs-gpio.h>
#include <asm/arch/regs-gpioj.h>
#include <asm/arch/regs-dsc.h>
#include "s3c2442.h"
#include "clock.h"
#include "devs.h"
#include "cpu.h"
#include "pm.h"
static struct sys_device s3c2442_sysdev = {
.cls = &s3c2442_sysclass,
};
int __init s3c2442_init(void)
{
printk("S3C2442: Initialising architecture\n");
return sysdev_register(&s3c2442_sysdev);
}

View file

@ -0,0 +1,17 @@
/* arch/arm/mach-s3c2410/s3c2442.h
*
* Copyright (c) 2006 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
*
* Header file for s3c2442 cpu support
*
* 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.
*/
#ifdef CONFIG_CPU_S3C2442
extern int s3c2442_init(void);
#else
#define s3c2442_init NULL
#endif

View file

@ -0,0 +1,142 @@
/* linux/arch/arm/mach-s3c2410/s3c2440-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:
* 25-Jul-2005 BJD Split from irq.c
*
*/
#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 "cpu.h"
#include "pm.h"
#include "irq.h"
/* camera irq */
static void s3c_irq_demux_cam(unsigned int irq,
struct irqdesc *desc,
struct pt_regs *regs)
{
unsigned int subsrc, submsk;
struct irqdesc *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 >>= 11;
subsrc &= 3;
if (subsrc != 0) {
if (subsrc & 1) {
mydesc = irq_desc + IRQ_S3C2440_CAM_C;
desc_handle_irq(IRQ_S3C2440_CAM_C, mydesc, regs);
}
if (subsrc & 2) {
mydesc = irq_desc + IRQ_S3C2440_CAM_P;
desc_handle_irq(IRQ_S3C2440_CAM_P, mydesc, regs);
}
}
}
#define INTMSK_CAM (1UL << (IRQ_CAM - IRQ_EINT0))
static void
s3c_irq_cam_mask(unsigned int irqno)
{
s3c_irqsub_mask(irqno, INTMSK_CAM, 3<<11);
}
static void
s3c_irq_cam_unmask(unsigned int irqno)
{
s3c_irqsub_unmask(irqno, INTMSK_CAM);
}
static void
s3c_irq_cam_ack(unsigned int irqno)
{
s3c_irqsub_maskack(irqno, INTMSK_CAM, 3<<11);
}
static struct irqchip s3c_irq_cam = {
.mask = s3c_irq_cam_mask,
.unmask = s3c_irq_cam_unmask,
.ack = s3c_irq_cam_ack,
};
static int s3c244x_irq_add(struct sys_device *sysdev)
{
unsigned int irqno;
set_irq_chip(IRQ_NFCON, &s3c_irq_level_chip);
set_irq_handler(IRQ_NFCON, do_level_IRQ);
set_irq_flags(IRQ_NFCON, IRQF_VALID);
/* add chained handler for camera */
set_irq_chip(IRQ_CAM, &s3c_irq_level_chip);
set_irq_handler(IRQ_CAM, do_level_IRQ);
set_irq_chained_handler(IRQ_CAM, s3c_irq_demux_cam);
for (irqno = IRQ_S3C2440_CAM_C; irqno <= IRQ_S3C2440_CAM_P; irqno++) {
set_irq_chip(irqno, &s3c_irq_cam);
set_irq_handler(irqno, do_level_IRQ);
set_irq_flags(irqno, IRQF_VALID);
}
return 0;
}
static struct sysdev_driver s3c244x_irq_driver = {
.add = s3c244x_irq_add,
};
static int s3c2440_irq_init(void)
{
return sysdev_driver_register(&s3c2440_sysclass, &s3c244x_irq_driver);
}
arch_initcall(s3c2440_irq_init);
static int s3c2442_irq_init(void)
{
return sysdev_driver_register(&s3c2442_sysclass, &s3c244x_irq_driver);
}
arch_initcall(s3c2442_irq_init);

View file

@ -0,0 +1,182 @@
/* linux/arch/arm/mach-s3c2410/s3c244x.c
*
* Copyright (c) 2004-2006 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
*
* Samsung S3C2440 and S3C2442 Mobile CPU support
*
* 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/types.h>
#include <linux/interrupt.h>
#include <linux/list.h>
#include <linux/timer.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/sysdev.h>
#include <linux/clk.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
#include <asm/hardware.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/arch/regs-clock.h>
#include <asm/arch/regs-serial.h>
#include <asm/arch/regs-gpio.h>
#include <asm/arch/regs-gpioj.h>
#include <asm/arch/regs-dsc.h>
#include "s3c2440.h"
#include "s3c244x.h"
#include "clock.h"
#include "devs.h"
#include "cpu.h"
#include "pm.h"
static struct map_desc s3c244x_iodesc[] __initdata = {
IODESC_ENT(CLKPWR),
IODESC_ENT(TIMER),
IODESC_ENT(WATCHDOG),
IODESC_ENT(LCD),
IODESC_ENT(ADC),
IODESC_ENT(USBHOST),
};
/* uart initialisation */
void __init s3c244x_init_uarts(struct s3c2410_uartcfg *cfg, int no)
{
s3c24xx_init_uartdevs("s3c2440-uart", s3c2410_uart_resources, cfg, no);
}
void __init s3c244x_map_io(struct map_desc *mach_desc, int size)
{
/* register our io-tables */
iotable_init(s3c244x_iodesc, ARRAY_SIZE(s3c244x_iodesc));
iotable_init(mach_desc, size);
/* rename any peripherals used differing from the s3c2410 */
s3c_device_i2c.name = "s3c2440-i2c";
s3c_device_nand.name = "s3c2440-nand";
}
void __init s3c244x_init_clocks(int xtal)
{
unsigned long clkdiv;
unsigned long camdiv;
unsigned long hclk, fclk, pclk;
int hdiv = 1;
/* now we've got our machine bits initialised, work out what
* clocks we've got */
fclk = s3c2410_get_pll(__raw_readl(S3C2410_MPLLCON), xtal) * 2;
clkdiv = __raw_readl(S3C2410_CLKDIVN);
camdiv = __raw_readl(S3C2440_CAMDIVN);
/* work out clock scalings */
switch (clkdiv & S3C2440_CLKDIVN_HDIVN_MASK) {
case S3C2440_CLKDIVN_HDIVN_1:
hdiv = 1;
break;
case S3C2440_CLKDIVN_HDIVN_2:
hdiv = 2;
break;
case S3C2440_CLKDIVN_HDIVN_4_8:
hdiv = (camdiv & S3C2440_CAMDIVN_HCLK4_HALF) ? 8 : 4;
break;
case S3C2440_CLKDIVN_HDIVN_3_6:
hdiv = (camdiv & S3C2440_CAMDIVN_HCLK3_HALF) ? 6 : 3;
break;
}
hclk = fclk / hdiv;
pclk = hclk / ((clkdiv & S3C2440_CLKDIVN_PDIVN)? 2:1);
/* print brief summary of clocks, etc */
printk("S3C244X: core %ld.%03ld MHz, memory %ld.%03ld MHz, peripheral %ld.%03ld MHz\n",
print_mhz(fclk), print_mhz(hclk), print_mhz(pclk));
/* initialise the clocks here, to allow other things like the
* console to use them, and to add new ones after the initialisation
*/
s3c24xx_setup_clocks(xtal, fclk, hclk, pclk);
}
#ifdef CONFIG_PM
static struct sleep_save s3c244x_sleep[] = {
SAVE_ITEM(S3C2440_DSC0),
SAVE_ITEM(S3C2440_DSC1),
SAVE_ITEM(S3C2440_GPJDAT),
SAVE_ITEM(S3C2440_GPJCON),
SAVE_ITEM(S3C2440_GPJUP)
};
static int s3c244x_suspend(struct sys_device *dev, pm_message_t state)
{
s3c2410_pm_do_save(s3c244x_sleep, ARRAY_SIZE(s3c244x_sleep));
return 0;
}
static int s3c244x_resume(struct sys_device *dev)
{
s3c2410_pm_do_restore(s3c244x_sleep, ARRAY_SIZE(s3c244x_sleep));
return 0;
}
#else
#define s3c244x_suspend NULL
#define s3c244x_resume NULL
#endif
/* Since the S3C2442 and S3C2440 share items, put both sysclasses here */
struct sysdev_class s3c2440_sysclass = {
set_kset_name("s3c2440-core"),
.suspend = s3c244x_suspend,
.resume = s3c244x_resume
};
struct sysdev_class s3c2442_sysclass = {
set_kset_name("s3c2442-core"),
.suspend = s3c244x_suspend,
.resume = s3c244x_resume
};
/* need to register class before we actually register the device, and
* we also need to ensure that it has been initialised before any of the
* drivers even try to use it (even if not on an s3c2440 based system)
* as a driver which may support both 2410 and 2440 may try and use it.
*/
static int __init s3c2440_core_init(void)
{
return sysdev_class_register(&s3c2440_sysclass);
}
core_initcall(s3c2440_core_init);
static int __init s3c2442_core_init(void)
{
return sysdev_class_register(&s3c2442_sysclass);
}
core_initcall(s3c2442_core_init);

View file

@ -0,0 +1,25 @@
/* arch/arm/mach-s3c2410/s3c2440.h
*
* Copyright (c) 2004-2005 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
*
* Header file for S3C2440 and S3C2442 cpu support
*
* 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.
*/
#if defined(CONFIG_CPU_S3C2440) || defined(CONFIG_CPU_S3C2442)
extern void s3c244x_map_io(struct map_desc *mach_desc, int size);
extern void s3c244x_init_uarts(struct s3c2410_uartcfg *cfg, int no);
extern void s3c244x_init_clocks(int xtal);
#else
#define s3c244x_init_clocks NULL
#define s3c244x_init_uarts NULL
#define s3c244x_map_io NULL
#endif

View file

@ -66,7 +66,9 @@ ENTRY(s3c2410_cpu_suspend)
@@ flush the caches to ensure everything is back out to
@@ SDRAM before the core powers down
#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
bl arm920_flush_kern_cache_all
#endif
@@ prepare cpu to sleep

View file

@ -121,8 +121,8 @@ config CPU_ARM925T
# ARM926T
config CPU_ARM926T
bool "Support ARM926T processor"
depends on ARCH_INTEGRATOR || ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || MACH_REALVIEW_EB
default y if ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX
depends on ARCH_INTEGRATOR || ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || MACH_REALVIEW_EB || ARCH_PNX4008
default y if ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || ARCH_PNX4008
select CPU_32v5
select CPU_ABRT_EV5TJ
select CPU_CACHE_VIVT

View file

@ -69,7 +69,7 @@ static void insert_phys_mapping(struct phys_desc *desc)
panic("Physical remapping for %p already present",
desc->virt);
rb_link_node(&desc->rb, (*n)->rb_parent, n);
rb_link_node(&desc->rb, rb_parent(*n), n);
rb_insert_color(&desc->rb, &phys_mappings);
}

View file

@ -353,10 +353,9 @@ static struct request *as_find_arq_hash(struct as_data *ad, sector_t offset)
/*
* rb tree support functions
*/
#define RB_NONE (2)
#define RB_EMPTY(root) ((root)->rb_node == NULL)
#define ON_RB(node) ((node)->rb_color != RB_NONE)
#define RB_CLEAR(node) ((node)->rb_color = RB_NONE)
#define ON_RB(node) (rb_parent(node) != node)
#define RB_CLEAR(node) (rb_set_parent(node, node))
#define rb_entry_arq(node) rb_entry((node), struct as_rq, rb_node)
#define ARQ_RB_ROOT(ad, arq) (&(ad)->sort_list[(arq)->is_sync])
#define rq_rb_key(rq) (rq)->sector

View file

@ -60,14 +60,9 @@ static DEFINE_SPINLOCK(cfq_exit_lock);
/*
* rb-tree defines
*/
#define RB_NONE (2)
#define RB_EMPTY(node) ((node)->rb_node == NULL)
#define RB_CLEAR_COLOR(node) (node)->rb_color = RB_NONE
#define RB_CLEAR(node) do { \
(node)->rb_parent = NULL; \
RB_CLEAR_COLOR((node)); \
(node)->rb_right = NULL; \
(node)->rb_left = NULL; \
memset(node, 0, sizeof(*node)); \
} while (0)
#define RB_CLEAR_ROOT(root) ((root)->rb_node = NULL)
#define rb_entry_crq(node) rb_entry((node), struct cfq_rq, rb_node)
@ -567,7 +562,6 @@ static inline void cfq_del_crq_rb(struct cfq_rq *crq)
cfq_update_next_crq(crq);
rb_erase(&crq->rb_node, &cfqq->sort_list);
RB_CLEAR_COLOR(&crq->rb_node);
if (cfq_cfqq_on_rr(cfqq) && RB_EMPTY(&cfqq->sort_list))
cfq_del_cfqq_rr(cfqd, cfqq);

View file

@ -165,10 +165,9 @@ deadline_find_drq_hash(struct deadline_data *dd, sector_t offset)
/*
* rb tree support functions
*/
#define RB_NONE (2)
#define RB_EMPTY(root) ((root)->rb_node == NULL)
#define ON_RB(node) ((node)->rb_color != RB_NONE)
#define RB_CLEAR(node) ((node)->rb_color = RB_NONE)
#define ON_RB(node) (rb_parent(node) != node)
#define RB_CLEAR(node) (rb_set_parent(node, node))
#define rb_entry_drq(node) rb_entry((node), struct deadline_rq, rb_node)
#define DRQ_RB_ROOT(dd, drq) (&(dd)->sort_list[rq_data_dir((drq)->request)])
#define rq_rb_key(rq) (rq)->sector

View file

@ -51,7 +51,7 @@ struct Error {
};
struct DownLoad {
char *DataP;
char __user *DataP;
unsigned int Count;
unsigned int ProductCode;
};
@ -83,18 +83,18 @@ struct PortSetup {
struct LpbReq {
unsigned int Host;
unsigned int Link;
struct LPB *LpbP;
struct LPB __user *LpbP;
};
struct RupReq {
unsigned int HostNum;
unsigned int RupNum;
struct RUP *RupP;
struct RUP __user *RupP;
};
struct PortReq {
unsigned int SysPort;
struct Port *PortP;
struct Port __user *PortP;
};
struct StreamInfo {
@ -105,12 +105,12 @@ struct StreamInfo {
struct HostReq {
unsigned int HostNum;
struct Host *HostP;
struct Host __user *HostP;
};
struct HostDpRam {
unsigned int HostNum;
struct DpRam *DpRamP;
struct DpRam __user *DpRamP;
};
struct DebugCtrl {

View file

@ -46,7 +46,7 @@ int RIOBootCodeRTA(struct rio_info *, struct DownLoad *);
int RIOBootCodeHOST(struct rio_info *, struct DownLoad *);
int RIOBootCodeUNKNOWN(struct rio_info *, struct DownLoad *);
void msec_timeout(struct Host *);
int RIOBootRup(struct rio_info *, unsigned int, struct Host *, struct PKT *);
int RIOBootRup(struct rio_info *, unsigned int, struct Host *, struct PKT __iomem *);
int RIOBootOk(struct rio_info *, struct Host *, unsigned long);
int RIORtaBound(struct rio_info *, unsigned int);
void rio_fill_host_slot(int, int, unsigned int, struct Host *);
@ -55,8 +55,8 @@ void rio_fill_host_slot(int, int, unsigned int, struct Host *);
int RIOFoadRta(struct Host *, struct Map *);
int RIOZombieRta(struct Host *, struct Map *);
int RIOCommandRta(struct rio_info *, unsigned long, int (*func) (struct Host *, struct Map *));
int RIOIdentifyRta(struct rio_info *, void *);
int RIOKillNeighbour(struct rio_info *, void *);
int RIOIdentifyRta(struct rio_info *, void __user *);
int RIOKillNeighbour(struct rio_info *, void __user *);
int RIOSuspendBootRta(struct Host *, int, int);
int RIOFoadWakeup(struct rio_info *);
struct CmdBlk *RIOGetCmdBlk(void);
@ -68,7 +68,8 @@ int RIORFlushEnable(unsigned long, struct CmdBlk *);
int RIOUnUse(unsigned long, struct CmdBlk *);
/* rioctrl.c */
int riocontrol(struct rio_info *, dev_t, int, caddr_t, int);
int riocontrol(struct rio_info *, dev_t, int, unsigned long, int);
int RIOPreemptiveCmd(struct rio_info *, struct Port *, unsigned char);
/* rioinit.c */
@ -77,13 +78,13 @@ void RIOInitHosts(struct rio_info *, struct RioHostInfo *);
void RIOISAinit(struct rio_info *, int);
int RIODoAT(struct rio_info *, int, int);
caddr_t RIOCheckForATCard(int);
int RIOAssignAT(struct rio_info *, int, caddr_t, int);
int RIOBoardTest(unsigned long, caddr_t, unsigned char, int);
int RIOAssignAT(struct rio_info *, int, void __iomem *, int);
int RIOBoardTest(unsigned long, void __iomem *, unsigned char, int);
void RIOAllocDataStructs(struct rio_info *);
void RIOSetupDataStructs(struct rio_info *);
int RIODefaultName(struct rio_info *, struct Host *, unsigned int);
struct rioVersion *RIOVersid(void);
void RIOHostReset(unsigned int, struct DpRam *, unsigned int);
void RIOHostReset(unsigned int, struct DpRam __iomem *, unsigned int);
/* riointr.c */
void RIOTxEnable(char *);
@ -95,14 +96,14 @@ int RIOParam(struct Port *, int, int, int);
int RIODelay(struct Port *PortP, int);
int RIODelay_ni(struct Port *PortP, int);
void ms_timeout(struct Port *);
int can_add_transmit(struct PKT **, struct Port *);
int can_add_transmit(struct PKT __iomem **, struct Port *);
void add_transmit(struct Port *);
void put_free_end(struct Host *, struct PKT *);
int can_remove_receive(struct PKT **, struct Port *);
void put_free_end(struct Host *, struct PKT __iomem *);
int can_remove_receive(struct PKT __iomem **, struct Port *);
void remove_receive(struct Port *);
/* rioroute.c */
int RIORouteRup(struct rio_info *, unsigned int, struct Host *, struct PKT *);
int RIORouteRup(struct rio_info *, unsigned int, struct Host *, struct PKT __iomem *);
void RIOFixPhbs(struct rio_info *, struct Host *, unsigned int);
unsigned int GetUnitType(unsigned int);
int RIOSetChange(struct rio_info *);
@ -139,7 +140,7 @@ int rio_isr_thread(char *);
struct rio_info *rio_info_store(int cmd, struct rio_info *p);
#endif
extern void rio_copy_to_card(void *to, void *from, int len);
extern void rio_copy_to_card(void *from, void __iomem *to, int len);
extern int rio_minor(struct tty_struct *tty);
extern int rio_ismodem(struct tty_struct *tty);

View file

@ -48,8 +48,8 @@ struct Host {
unsigned char Ivec; /* POLLED or ivec number */
unsigned char Mode; /* Control stuff */
unsigned char Slot; /* Slot */
caddr_t Caddr; /* KV address of DPRAM */
struct DpRam *CardP; /* KV address of DPRAM, with overlay */
void __iomem *Caddr; /* KV address of DPRAM */
struct DpRam __iomem *CardP; /* KV address of DPRAM, with overlay */
unsigned long PaddrP; /* Phys. address of DPRAM */
char Name[MAX_NAME_LEN]; /* The name of the host */
unsigned int UniqueNum; /* host unique number */
@ -57,7 +57,7 @@ struct Host {
unsigned int WorkToBeDone; /* set to true each interrupt */
unsigned int InIntr; /* Being serviced? */
unsigned int IntSrvDone; /* host's interrupt has been serviced */
void (*Copy) (void *, void *, int); /* copy func */
void (*Copy) (void *, void __iomem *, int); /* copy func */
struct timer_list timer;
/*
** I M P O R T A N T !
@ -83,11 +83,11 @@ struct Host {
struct Top Topology[LINKS_PER_UNIT]; /* one per link */
struct Map Mapping[MAX_RUP]; /* Mappings for host */
struct PHB *PhbP; /* Pointer to the PHB array */
unsigned short *PhbNumP; /* Ptr to Number of PHB's */
struct LPB *LinkStrP; /* Link Structure Array */
struct RUP *RupP; /* Sixteen real rups here */
struct PARM_MAP *ParmMapP; /* points to the parmmap */
struct PHB __iomem *PhbP; /* Pointer to the PHB array */
unsigned short __iomem *PhbNumP; /* Ptr to Number of PHB's */
struct LPB __iomem *LinkStrP; /* Link Structure Array */
struct RUP __iomem *RupP; /* Sixteen real rups here */
struct PARM_MAP __iomem *ParmMapP; /* points to the parmmap */
unsigned int ExtraUnits[MAX_EXTRA_UNITS]; /* unknown things */
unsigned int NumExtraBooted; /* how many of the above */
/*

View file

@ -40,7 +40,7 @@ struct Port {
struct gs_port gs;
int PortNum; /* RIO port no., 0-511 */
struct Host *HostP;
caddr_t Caddr;
void __iomem *Caddr;
unsigned short HostPort; /* Port number on host card */
unsigned char RupNum; /* Number of RUP for port */
unsigned char ID2; /* Second ID of RTA for port */
@ -92,13 +92,13 @@ struct Port {
#define RIO_RTSFLOW 0x0400 /* RIO's own RTSFLOW flag */
struct PHB *PhbP; /* pointer to PHB for port */
u16 *TxAdd; /* Add packets here */
u16 *TxStart; /* Start of add array */
u16 *TxEnd; /* End of add array */
u16 *RxRemove; /* Remove packets here */
u16 *RxStart; /* Start of remove array */
u16 *RxEnd; /* End of remove array */
struct PHB __iomem *PhbP; /* pointer to PHB for port */
u16 __iomem *TxAdd; /* Add packets here */
u16 __iomem *TxStart; /* Start of add array */
u16 __iomem *TxEnd; /* End of add array */
u16 __iomem *RxRemove; /* Remove packets here */
u16 __iomem *RxStart; /* Start of remove array */
u16 __iomem *RxEnd; /* End of remove array */
unsigned int RtaUniqueNum; /* Unique number of RTA */
unsigned short PortState; /* status of port */
unsigned short ModemState; /* status of modem lines */

View file

@ -129,8 +129,8 @@
** RIO_OBJ takes hostp->Caddr and a UNIX pointer to an object and
** returns the offset into the DP RAM area.
*/
#define RIO_PTR(C,O) (((unsigned char *)(C))+(0xFFFF&(O)))
#define RIO_OFF(C,O) ((long)(O)-(long)(C))
#define RIO_PTR(C,O) (((unsigned char __iomem *)(C))+(0xFFFF&(O)))
#define RIO_OFF(C,O) ((unsigned char __iomem *)(O)-(unsigned char __iomem *)(C))
/*
** How to convert from various different device number formats:

View file

@ -333,9 +333,9 @@ int RIODelay_ni(struct Port *PortP, int njiffies)
return !RIO_FAIL;
}
void rio_copy_to_card(void *to, void *from, int len)
void rio_copy_to_card(void *from, void __iomem *to, int len)
{
rio_memcpy_toio(NULL, to, from, len);
rio_copy_toio(to, from, len);
}
int rio_minor(struct tty_struct *tty)
@ -573,7 +573,7 @@ static int rio_fw_ioctl(struct inode *inode, struct file *filp, unsigned int cmd
func_enter();
/* The "dev" argument isn't used. */
rc = riocontrol(p, 0, cmd, (void *) arg, capable(CAP_SYS_ADMIN));
rc = riocontrol(p, 0, cmd, arg, capable(CAP_SYS_ADMIN));
func_exit();
return rc;
@ -583,6 +583,7 @@ extern int RIOShortCommand(struct rio_info *p, struct Port *PortP, int command,
static int rio_ioctl(struct tty_struct *tty, struct file *filp, unsigned int cmd, unsigned long arg)
{
void __user *argp = (void __user *)arg;
int rc;
struct Port *PortP;
int ival;
@ -594,14 +595,14 @@ static int rio_ioctl(struct tty_struct *tty, struct file *filp, unsigned int cmd
rc = 0;
switch (cmd) {
case TIOCSSOFTCAR:
if ((rc = get_user(ival, (unsigned int *) arg)) == 0) {
if ((rc = get_user(ival, (unsigned __user *) argp)) == 0) {
tty->termios->c_cflag = (tty->termios->c_cflag & ~CLOCAL) | (ival ? CLOCAL : 0);
}
break;
case TIOCGSERIAL:
rc = -EFAULT;
if (access_ok(VERIFY_WRITE, (void *) arg, sizeof(struct serial_struct)))
rc = gs_getserial(&PortP->gs, (struct serial_struct *) arg);
if (access_ok(VERIFY_WRITE, argp, sizeof(struct serial_struct)))
rc = gs_getserial(&PortP->gs, argp);
break;
case TCSBRK:
if (PortP->State & RIO_DELETED) {
@ -631,8 +632,8 @@ static int rio_ioctl(struct tty_struct *tty, struct file *filp, unsigned int cmd
break;
case TIOCSSERIAL:
rc = -EFAULT;
if (access_ok(VERIFY_READ, (void *) arg, sizeof(struct serial_struct)))
rc = gs_setserial(&PortP->gs, (struct serial_struct *) arg);
if (access_ok(VERIFY_READ, argp, sizeof(struct serial_struct)))
rc = gs_setserial(&PortP->gs, argp);
break;
default:
rc = -ENOIOCTLCMD;
@ -919,7 +920,7 @@ static void __exit rio_release_drivers(void)
static void fix_rio_pci(struct pci_dev *pdev)
{
unsigned long hwbase;
unsigned char *rebase;
unsigned char __iomem *rebase;
unsigned int t;
#define CNTRL_REG_OFFSET 0x50
@ -999,7 +1000,7 @@ static int __init rio_init(void)
if (((1 << hp->Ivec) & rio_irqmask) == 0)
hp->Ivec = 0;
hp->Caddr = ioremap(p->RIOHosts[p->RIONumHosts].PaddrP, RIO_WINDOW_LEN);
hp->CardP = (struct DpRam *) hp->Caddr;
hp->CardP = (struct DpRam __iomem *) hp->Caddr;
hp->Type = RIO_PCI;
hp->Copy = rio_copy_to_card;
hp->Mode = RIO_PCI_BOOT_FROM_RAM;
@ -1021,7 +1022,7 @@ static int __init rio_init(void)
p->RIONumHosts++;
found++;
} else {
iounmap((char *) (p->RIOHosts[p->RIONumHosts].Caddr));
iounmap(p->RIOHosts[p->RIONumHosts].Caddr);
}
}
@ -1047,7 +1048,7 @@ static int __init rio_init(void)
hp->Ivec = 0;
hp->Ivec |= 0x8000; /* Mark as non-sharable */
hp->Caddr = ioremap(p->RIOHosts[p->RIONumHosts].PaddrP, RIO_WINDOW_LEN);
hp->CardP = (struct DpRam *) hp->Caddr;
hp->CardP = (struct DpRam __iomem *) hp->Caddr;
hp->Type = RIO_PCI;
hp->Copy = rio_copy_to_card;
hp->Mode = RIO_PCI_BOOT_FROM_RAM;
@ -1070,7 +1071,7 @@ static int __init rio_init(void)
p->RIONumHosts++;
found++;
} else {
iounmap((char *) (p->RIOHosts[p->RIONumHosts].Caddr));
iounmap(p->RIOHosts[p->RIONumHosts].Caddr);
}
#else
printk(KERN_ERR "Found an older RIO PCI card, but the driver is not " "compiled to support it.\n");
@ -1085,7 +1086,7 @@ static int __init rio_init(void)
/* There was something about the IRQs of these cards. 'Forget what.--REW */
hp->Ivec = 0;
hp->Caddr = ioremap(p->RIOHosts[p->RIONumHosts].PaddrP, RIO_WINDOW_LEN);
hp->CardP = (struct DpRam *) hp->Caddr;
hp->CardP = (struct DpRam __iomem *) hp->Caddr;
hp->Type = RIO_AT;
hp->Copy = rio_copy_to_card; /* AT card PCI???? - PVDL
* -- YES! this is now a normal copy. Only the
@ -1111,7 +1112,7 @@ static int __init rio_init(void)
}
if (!okboard)
iounmap((char *) (hp->Caddr));
iounmap(hp->Caddr);
}
}

View file

@ -131,9 +131,9 @@ struct vpd_prom {
#ifdef CONFIG_RIO_OLDPCI
static inline void *rio_memcpy_toio(void *dummy, void *dest, void *source, int n)
static inline void __iomem *rio_memcpy_toio(void __iomem *dummy, void __iomem *dest, void *source, int n)
{
char *dst = dest;
char __iomem *dst = dest;
char *src = source;
while (n--) {
@ -144,11 +144,22 @@ static inline void *rio_memcpy_toio(void *dummy, void *dest, void *source, int n
return dest;
}
static inline void __iomem *rio_copy_toio(void __iomem *dest, void *source, int n)
{
char __iomem *dst = dest;
char *src = source;
static inline void *rio_memcpy_fromio(void *dest, void *source, int n)
while (n--)
writeb(*src++, dst++);
return dest;
}
static inline void *rio_memcpy_fromio(void *dest, void __iomem *source, int n)
{
char *dst = dest;
char *src = source;
char __iomem *src = source;
while (n--)
*dst++ = readb(src++);
@ -158,6 +169,7 @@ static inline void *rio_memcpy_fromio(void *dest, void *source, int n)
#else
#define rio_memcpy_toio(dummy,dest,source,n) memcpy_toio(dest, source, n)
#define rio_copy_toio memcpy_toio
#define rio_memcpy_fromio memcpy_fromio
#endif

View file

@ -71,7 +71,7 @@
#include "cmdblk.h"
#include "route.h"
static int RIOBootComplete(struct rio_info *p, struct Host *HostP, unsigned int Rup, struct PktCmd *PktCmdP);
static int RIOBootComplete(struct rio_info *p, struct Host *HostP, unsigned int Rup, struct PktCmd __iomem *PktCmdP);
static const unsigned char RIOAtVec2Ctrl[] = {
/* 0 */ INTERRUPT_DISABLE,
@ -204,13 +204,13 @@ void rio_start_card_running(struct Host *HostP)
int RIOBootCodeHOST(struct rio_info *p, struct DownLoad *rbp)
{
struct Host *HostP;
u8 *Cad;
PARM_MAP *ParmMapP;
u8 __iomem *Cad;
PARM_MAP __iomem *ParmMapP;
int RupN;
int PortN;
unsigned int host;
u8 *StartP;
u8 *DestP;
u8 __iomem *StartP;
u8 __iomem *DestP;
int wait_count;
u16 OldParmMap;
u16 offset; /* It is very important that this is a u16 */
@ -262,7 +262,7 @@ int RIOBootCodeHOST(struct rio_info *p, struct DownLoad *rbp)
** Ensure that the host really is stopped.
** Disable it's external bus & twang its reset line.
*/
RIOHostReset(HostP->Type, (struct DpRam *) HostP->CardP, HostP->Slot);
RIOHostReset(HostP->Type, HostP->CardP, HostP->Slot);
/*
** Copy the data directly from user space to the SRAM.
@ -280,7 +280,7 @@ int RIOBootCodeHOST(struct rio_info *p, struct DownLoad *rbp)
func_exit();
return -ENOMEM;
}
if (copy_from_user(rbp->DataP, DownCode, rbp->Count)) {
if (copy_from_user(DownCode, rbp->DataP, rbp->Count)) {
kfree(DownCode);
p->RIOError.Error = COPYIN_FAILED;
func_exit();
@ -366,7 +366,7 @@ int RIOBootCodeHOST(struct rio_info *p, struct DownLoad *rbp)
** a short branch to 0x7FF8, where a long branch is coded.
*/
DestP = (u8 *) &Cad[0x7FF8]; /* <<<---- READ THE ABOVE COMMENTS */
DestP = &Cad[0x7FF8]; /* <<<---- READ THE ABOVE COMMENTS */
#define NFIX(N) (0x60 | (N)) /* .O = (~(.O + N))<<4 */
#define PFIX(N) (0x20 | (N)) /* .O = (.O + N)<<4 */
@ -438,7 +438,7 @@ int RIOBootCodeHOST(struct rio_info *p, struct DownLoad *rbp)
rio_dprintk(RIO_DEBUG_BOOT, "RIO Mesg Run Fail\n");
HostP->Flags &= ~RUN_STATE;
HostP->Flags |= RC_STUFFED;
RIOHostReset( HostP->Type, (struct DpRam *)HostP->CardP, HostP->Slot );
RIOHostReset( HostP->Type, HostP->CardP, HostP->Slot );
continue;
}
@ -453,9 +453,9 @@ int RIOBootCodeHOST(struct rio_info *p, struct DownLoad *rbp)
/*
** Grab a 32 bit pointer to the parmmap structure
*/
ParmMapP = (PARM_MAP *) RIO_PTR(Cad, readw(&HostP->__ParmMapR));
ParmMapP = (PARM_MAP __iomem *) RIO_PTR(Cad, readw(&HostP->__ParmMapR));
rio_dprintk(RIO_DEBUG_BOOT, "ParmMapP : %p\n", ParmMapP);
ParmMapP = (PARM_MAP *) ((unsigned long) Cad + readw(&HostP->__ParmMapR));
ParmMapP = (PARM_MAP __iomem *)(Cad + readw(&HostP->__ParmMapR));
rio_dprintk(RIO_DEBUG_BOOT, "ParmMapP : %p\n", ParmMapP);
/*
@ -468,7 +468,7 @@ int RIOBootCodeHOST(struct rio_info *p, struct DownLoad *rbp)
rio_dprintk(RIO_DEBUG_BOOT, "Links = 0x%x\n", readw(&ParmMapP->links));
HostP->Flags &= ~RUN_STATE;
HostP->Flags |= RC_STUFFED;
RIOHostReset( HostP->Type, (struct DpRam *)HostP->CardP, HostP->Slot );
RIOHostReset( HostP->Type, HostP->CardP, HostP->Slot );
continue;
}
@ -491,7 +491,7 @@ int RIOBootCodeHOST(struct rio_info *p, struct DownLoad *rbp)
rio_dprintk(RIO_DEBUG_BOOT, "Timedout waiting for init_done\n");
HostP->Flags &= ~RUN_STATE;
HostP->Flags |= RC_STUFFED;
RIOHostReset( HostP->Type, (struct DpRam *)HostP->CardP, HostP->Slot );
RIOHostReset( HostP->Type, HostP->CardP, HostP->Slot );
continue;
}
@ -512,10 +512,10 @@ int RIOBootCodeHOST(struct rio_info *p, struct DownLoad *rbp)
** 32 bit pointers for the driver in ioremap space.
*/
HostP->ParmMapP = ParmMapP;
HostP->PhbP = (struct PHB *) RIO_PTR(Cad, readw(&ParmMapP->phb_ptr));
HostP->RupP = (struct RUP *) RIO_PTR(Cad, readw(&ParmMapP->rups));
HostP->PhbNumP = (unsigned short *) RIO_PTR(Cad, readw(&ParmMapP->phb_num_ptr));
HostP->LinkStrP = (struct LPB *) RIO_PTR(Cad, readw(&ParmMapP->link_str_ptr));
HostP->PhbP = (struct PHB __iomem *) RIO_PTR(Cad, readw(&ParmMapP->phb_ptr));
HostP->RupP = (struct RUP __iomem *) RIO_PTR(Cad, readw(&ParmMapP->rups));
HostP->PhbNumP = (unsigned short __iomem *) RIO_PTR(Cad, readw(&ParmMapP->phb_num_ptr));
HostP->LinkStrP = (struct LPB __iomem *) RIO_PTR(Cad, readw(&ParmMapP->link_str_ptr));
/*
** point the UnixRups at the real Rups
@ -540,7 +540,7 @@ int RIOBootCodeHOST(struct rio_info *p, struct DownLoad *rbp)
for (PortN = p->RIOFirstPortsMapped; PortN < p->RIOLastPortsMapped + PORTS_PER_RTA; PortN++) {
if (p->RIOPortp[PortN]->HostP == HostP) {
struct Port *PortP = p->RIOPortp[PortN];
struct PHB *PhbP;
struct PHB __iomem *PhbP;
/* int oldspl; */
if (!PortP->Mapped)
@ -551,12 +551,12 @@ int RIOBootCodeHOST(struct rio_info *p, struct DownLoad *rbp)
PortP->PhbP = PhbP;
PortP->TxAdd = (u16 *) RIO_PTR(Cad, readw(&PhbP->tx_add));
PortP->TxStart = (u16 *) RIO_PTR(Cad, readw(&PhbP->tx_start));
PortP->TxEnd = (u16 *) RIO_PTR(Cad, readw(&PhbP->tx_end));
PortP->RxRemove = (u16 *) RIO_PTR(Cad, readw(&PhbP->rx_remove));
PortP->RxStart = (u16 *) RIO_PTR(Cad, readw(&PhbP->rx_start));
PortP->RxEnd = (u16 *) RIO_PTR(Cad, readw(&PhbP->rx_end));
PortP->TxAdd = (u16 __iomem *) RIO_PTR(Cad, readw(&PhbP->tx_add));
PortP->TxStart = (u16 __iomem *) RIO_PTR(Cad, readw(&PhbP->tx_start));
PortP->TxEnd = (u16 __iomem *) RIO_PTR(Cad, readw(&PhbP->tx_end));
PortP->RxRemove = (u16 __iomem *) RIO_PTR(Cad, readw(&PhbP->rx_remove));
PortP->RxStart = (u16 __iomem *) RIO_PTR(Cad, readw(&PhbP->rx_start));
PortP->RxEnd = (u16 __iomem *) RIO_PTR(Cad, readw(&PhbP->rx_end));
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
/*
@ -601,9 +601,9 @@ int RIOBootCodeHOST(struct rio_info *p, struct DownLoad *rbp)
* return 1. If we havent, then return 0.
*/
int RIOBootRup(struct rio_info *p, unsigned int Rup, struct Host *HostP, struct PKT *PacketP)
int RIOBootRup(struct rio_info *p, unsigned int Rup, struct Host *HostP, struct PKT __iomem *PacketP)
{
struct PktCmd *PktCmdP = (struct PktCmd *) PacketP->data;
struct PktCmd __iomem *PktCmdP = (struct PktCmd __iomem *) PacketP->data;
struct PktCmd_M *PktReplyP;
struct CmdBlk *CmdBlkP;
unsigned int sequence;
@ -722,7 +722,7 @@ int RIOBootRup(struct rio_info *p, unsigned int Rup, struct Host *HostP, struct
* RtaUniq is the booted RTA.
*/
static int RIOBootComplete(struct rio_info *p, struct Host *HostP, unsigned int Rup, struct PktCmd *PktCmdP)
static int RIOBootComplete(struct rio_info *p, struct Host *HostP, unsigned int Rup, struct PktCmd __iomem *PktCmdP)
{
struct Map *MapP = NULL;
struct Map *MapP2 = NULL;

View file

@ -180,7 +180,7 @@ int RIOCommandRta(struct rio_info *p, unsigned long RtaUnique, int (*func) (stru
}
int RIOIdentifyRta(struct rio_info *p, void * arg)
int RIOIdentifyRta(struct rio_info *p, void __user * arg)
{
unsigned int Host;
@ -245,7 +245,7 @@ int RIOIdentifyRta(struct rio_info *p, void * arg)
}
int RIOKillNeighbour(struct rio_info *p, void * arg)
int RIOKillNeighbour(struct rio_info *p, void __user * arg)
{
uint Host;
uint ID;
@ -370,9 +370,9 @@ int RIOFoadWakeup(struct rio_info *p)
/*
** Incoming command on the COMMAND_RUP to be processed.
*/
static int RIOCommandRup(struct rio_info *p, uint Rup, struct Host *HostP, struct PKT * PacketP)
static int RIOCommandRup(struct rio_info *p, uint Rup, struct Host *HostP, struct PKT __iomem *PacketP)
{
struct PktCmd *PktCmdP = (struct PktCmd *) PacketP->data;
struct PktCmd __iomem *PktCmdP = (struct PktCmd __iomem *)PacketP->data;
struct Port *PortP;
struct UnixRup *UnixRupP;
unsigned short SysPort;
@ -407,12 +407,12 @@ static int RIOCommandRup(struct rio_info *p, uint Rup, struct Host *HostP, struc
} else
rio_dprintk(RIO_DEBUG_CMD, "CONTROL information: This is the RUP for link ``%c'' of host ``%s''\n", ('A' + Rup - MAX_RUP), HostP->Name);
rio_dprintk(RIO_DEBUG_CMD, "PACKET information: Destination 0x%x:0x%x\n", PacketP->dest_unit, PacketP->dest_port);
rio_dprintk(RIO_DEBUG_CMD, "PACKET information: Source 0x%x:0x%x\n", PacketP->src_unit, PacketP->src_port);
rio_dprintk(RIO_DEBUG_CMD, "PACKET information: Length 0x%x (%d)\n", PacketP->len, PacketP->len);
rio_dprintk(RIO_DEBUG_CMD, "PACKET information: Control 0x%x (%d)\n", PacketP->control, PacketP->control);
rio_dprintk(RIO_DEBUG_CMD, "PACKET information: Check 0x%x (%d)\n", PacketP->csum, PacketP->csum);
rio_dprintk(RIO_DEBUG_CMD, "COMMAND information: Host Port Number 0x%x, " "Command Code 0x%x\n", PktCmdP->PhbNum, PktCmdP->Command);
rio_dprintk(RIO_DEBUG_CMD, "PACKET information: Destination 0x%x:0x%x\n", readb(&PacketP->dest_unit), readb(&PacketP->dest_port));
rio_dprintk(RIO_DEBUG_CMD, "PACKET information: Source 0x%x:0x%x\n", readb(&PacketP->src_unit), readb(&PacketP->src_port));
rio_dprintk(RIO_DEBUG_CMD, "PACKET information: Length 0x%x (%d)\n", readb(&PacketP->len), readb(&PacketP->len));
rio_dprintk(RIO_DEBUG_CMD, "PACKET information: Control 0x%x (%d)\n", readb(&PacketP->control), readb(&PacketP->control));
rio_dprintk(RIO_DEBUG_CMD, "PACKET information: Check 0x%x (%d)\n", readw(&PacketP->csum), readw(&PacketP->csum));
rio_dprintk(RIO_DEBUG_CMD, "COMMAND information: Host Port Number 0x%x, " "Command Code 0x%x\n", readb(&PktCmdP->PhbNum), readb(&PktCmdP->Command));
return 1;
}
PortP = p->RIOPortp[SysPort];
@ -601,7 +601,7 @@ int RIOQueueCmdBlk(struct Host *HostP, uint Rup, struct CmdBlk *CmdBlkP)
/*
** Whammy! blat that pack!
*/
HostP->Copy((caddr_t) & CmdBlkP->Packet, RIO_PTR(HostP->Caddr, UnixRupP->RupP->txpkt), sizeof(struct PKT));
HostP->Copy(&CmdBlkP->Packet, RIO_PTR(HostP->Caddr, readw(&UnixRupP->RupP->txpkt)), sizeof(struct PKT));
/*
** place command packet on the pending position.
@ -655,7 +655,7 @@ void RIOPollHostCommands(struct rio_info *p, struct Host *HostP)
{
struct CmdBlk *CmdBlkP;
struct UnixRup *UnixRupP;
struct PKT *PacketP;
struct PKT __iomem *PacketP;
unsigned short Rup;
unsigned long flags;
@ -676,7 +676,7 @@ void RIOPollHostCommands(struct rio_info *p, struct Host *HostP)
if (readw(&UnixRupP->RupP->rxcontrol) != RX_RUP_INACTIVE) {
int FreeMe;
PacketP = (struct PKT *) RIO_PTR(HostP->Caddr, readw(&UnixRupP->RupP->rxpkt));
PacketP = (struct PKT __iomem *) RIO_PTR(HostP->Caddr, readw(&UnixRupP->RupP->rxpkt));
switch (readb(&PacketP->dest_port)) {
case BOOT_RUP:
@ -694,9 +694,9 @@ void RIOPollHostCommands(struct rio_info *p, struct Host *HostP)
*/
rio_spin_unlock_irqrestore(&UnixRupP->RupLock, flags);
FreeMe = RIOCommandRup(p, Rup, HostP, PacketP);
if (PacketP->data[5] == MEMDUMP) {
rio_dprintk(RIO_DEBUG_CMD, "Memdump from 0x%x complete\n", *(unsigned short *) & (PacketP->data[6]));
HostP->Copy((caddr_t) & (PacketP->data[8]), (caddr_t) p->RIOMemDump, 32);
if (readb(&PacketP->data[5]) == MEMDUMP) {
rio_dprintk(RIO_DEBUG_CMD, "Memdump from 0x%x complete\n", readw(&(PacketP->data[6])));
rio_memcpy_fromio(p->RIOMemDump, &(PacketP->data[8]), 32);
}
rio_spin_lock_irqsave(&UnixRupP->RupLock, flags);
break;
@ -782,7 +782,7 @@ void RIOPollHostCommands(struct rio_info *p, struct Host *HostP)
/*
** Whammy! blat that pack!
*/
HostP->Copy((caddr_t) & CmdBlkP->Packet, RIO_PTR(HostP->Caddr, UnixRupP->RupP->txpkt), sizeof(struct PKT));
HostP->Copy(&CmdBlkP->Packet, RIO_PTR(HostP->Caddr, readw(&UnixRupP->RupP->txpkt)), sizeof(struct PKT));
/*
** remove the command from the rup command queue...
@ -824,7 +824,7 @@ int RIOWFlushMark(unsigned long iPortP, struct CmdBlk *CmdBlkP)
int RIORFlushEnable(unsigned long iPortP, struct CmdBlk *CmdBlkP)
{
struct Port *PortP = (struct Port *) iPortP;
struct PKT *PacketP;
struct PKT __iomem *PacketP;
unsigned long flags;
rio_spin_lock_irqsave(&PortP->portSem, flags);

View file

@ -80,7 +80,7 @@ static char *_rioctrl_c_sccs_ = "@(#)rioctrl.c 1.3";
static struct LpbReq LpbReq;
static struct RupReq RupReq;
static struct PortReq PortReq;
static struct HostReq HostReq;
static struct HostReq HostReq; /* oh really? global? and no locking? */
static struct HostDpRam HostDpRam;
static struct DebugCtrl DebugCtrl;
static struct Map MapEnt;
@ -126,12 +126,19 @@ static int
#define drv_makedev(maj, min) ((((uint) maj & 0xff) << 8) | ((uint) min & 0xff))
int riocontrol(p, dev, cmd, arg, su)
struct rio_info *p;
dev_t dev;
int cmd;
caddr_t arg;
int su;
static int copy_from_io(void __user *to, void __iomem *from, size_t size)
{
void *buf = kmalloc(size, GFP_KERNEL);
int res = -ENOMEM;
if (buf) {
rio_memcpy_fromio(buf, from, size);
res = copy_to_user(to, buf, size);
kfree(buf);
}
return res;
}
int riocontrol(struct rio_info *p, dev_t dev, int cmd, unsigned long arg, int su)
{
uint Host; /* leave me unsigned! */
uint port; /* and me! */
@ -139,9 +146,10 @@ int su;
ushort loop;
int Entry;
struct Port *PortP;
struct PKT *PacketP;
struct PKT __iomem *PacketP;
int retval = 0;
unsigned long flags;
void __user *argp = (void __user *)arg;
func_enter();
@ -149,7 +157,7 @@ int su;
Host = 0;
PortP = NULL;
rio_dprintk(RIO_DEBUG_CTRL, "control ioctl cmd: 0x%x arg: %p\n", cmd, arg);
rio_dprintk(RIO_DEBUG_CTRL, "control ioctl cmd: 0x%x arg: %p\n", cmd, argp);
switch (cmd) {
/*
@ -160,11 +168,11 @@ int su;
** otherwise just the specified host card will be changed.
*/
case RIO_SET_TIMER:
rio_dprintk(RIO_DEBUG_CTRL, "RIO_SET_TIMER to %ldms\n", (unsigned long)arg);
rio_dprintk(RIO_DEBUG_CTRL, "RIO_SET_TIMER to %ldms\n", arg);
{
int host, value;
host = ((unsigned long) arg >> 16) & 0x0000FFFF;
value = (unsigned long) arg & 0x0000ffff;
host = (arg >> 16) & 0x0000FFFF;
value = arg & 0x0000ffff;
if (host == -1) {
for (host = 0; host < p->RIONumHosts; host++) {
if (p->RIOHosts[host].Flags == RC_RUNNING) {
@ -183,26 +191,26 @@ int su;
case RIO_FOAD_RTA:
rio_dprintk(RIO_DEBUG_CTRL, "RIO_FOAD_RTA\n");
return RIOCommandRta(p, (unsigned long)arg, RIOFoadRta);
return RIOCommandRta(p, arg, RIOFoadRta);
case RIO_ZOMBIE_RTA:
rio_dprintk(RIO_DEBUG_CTRL, "RIO_ZOMBIE_RTA\n");
return RIOCommandRta(p, (unsigned long)arg, RIOZombieRta);
return RIOCommandRta(p, arg, RIOZombieRta);
case RIO_IDENTIFY_RTA:
rio_dprintk(RIO_DEBUG_CTRL, "RIO_IDENTIFY_RTA\n");
return RIOIdentifyRta(p, arg);
return RIOIdentifyRta(p, argp);
case RIO_KILL_NEIGHBOUR:
rio_dprintk(RIO_DEBUG_CTRL, "RIO_KILL_NEIGHBOUR\n");
return RIOKillNeighbour(p, arg);
return RIOKillNeighbour(p, argp);
case SPECIAL_RUP_CMD:
{
struct CmdBlk *CmdBlkP;
rio_dprintk(RIO_DEBUG_CTRL, "SPECIAL_RUP_CMD\n");
if (copy_from_user(&SpecialRupCmd, arg, sizeof(SpecialRupCmd))) {
if (copy_from_user(&SpecialRupCmd, argp, sizeof(SpecialRupCmd))) {
rio_dprintk(RIO_DEBUG_CTRL, "SPECIAL_RUP_CMD copy failed\n");
p->RIOError.Error = COPYIN_FAILED;
return -EFAULT;
@ -239,7 +247,7 @@ int su;
if ((retval = RIOApel(p)) != 0)
return retval;
if (copy_to_user(arg, p->RIOConnectTable, TOTAL_MAP_ENTRIES * sizeof(struct Map))) {
if (copy_to_user(argp, p->RIOConnectTable, TOTAL_MAP_ENTRIES * sizeof(struct Map))) {
rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_TABLE copy failed\n");
p->RIOError.Error = COPYOUT_FAILED;
return -EFAULT;
@ -284,7 +292,7 @@ int su;
p->RIOError.Error = NOT_SUPER_USER;
return -EPERM;
}
if (copy_from_user(&p->RIOConnectTable[0], arg, TOTAL_MAP_ENTRIES * sizeof(struct Map))) {
if (copy_from_user(&p->RIOConnectTable[0], argp, TOTAL_MAP_ENTRIES * sizeof(struct Map))) {
rio_dprintk(RIO_DEBUG_CTRL, "RIO_PUT_TABLE copy failed\n");
p->RIOError.Error = COPYIN_FAILED;
return -EFAULT;
@ -330,7 +338,7 @@ int su;
p->RIOError.Error = NOT_SUPER_USER;
return -EPERM;
}
if (copy_to_user(arg, p->RIOBindTab, (sizeof(ulong) * MAX_RTA_BINDINGS))) {
if (copy_to_user(argp, p->RIOBindTab, (sizeof(ulong) * MAX_RTA_BINDINGS))) {
rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_BINDINGS copy failed\n");
p->RIOError.Error = COPYOUT_FAILED;
return -EFAULT;
@ -349,7 +357,7 @@ int su;
p->RIOError.Error = NOT_SUPER_USER;
return -EPERM;
}
if (copy_from_user(&p->RIOBindTab[0], arg, (sizeof(ulong) * MAX_RTA_BINDINGS))) {
if (copy_from_user(&p->RIOBindTab[0], argp, (sizeof(ulong) * MAX_RTA_BINDINGS))) {
rio_dprintk(RIO_DEBUG_CTRL, "RIO_PUT_BINDINGS copy failed\n");
p->RIOError.Error = COPYIN_FAILED;
return -EFAULT;
@ -373,12 +381,12 @@ int su;
for (Entry = 0; Entry < MAX_RTA_BINDINGS; Entry++) {
if ((EmptySlot == -1) && (p->RIOBindTab[Entry] == 0L))
EmptySlot = Entry;
else if (p->RIOBindTab[Entry] == (long)arg) {
else if (p->RIOBindTab[Entry] == arg) {
/*
** Already exists - delete
*/
p->RIOBindTab[Entry] = 0L;
rio_dprintk(RIO_DEBUG_CTRL, "Removing Rta %ld from p->RIOBindTab\n", (unsigned long)arg);
rio_dprintk(RIO_DEBUG_CTRL, "Removing Rta %ld from p->RIOBindTab\n", arg);
return 0;
}
}
@ -386,10 +394,10 @@ int su;
** Dosen't exist - add
*/
if (EmptySlot != -1) {
p->RIOBindTab[EmptySlot] = (unsigned long)arg;
rio_dprintk(RIO_DEBUG_CTRL, "Adding Rta %lx to p->RIOBindTab\n", (unsigned long) arg);
p->RIOBindTab[EmptySlot] = arg;
rio_dprintk(RIO_DEBUG_CTRL, "Adding Rta %lx to p->RIOBindTab\n", arg);
} else {
rio_dprintk(RIO_DEBUG_CTRL, "p->RIOBindTab full! - Rta %lx not added\n", (unsigned long) arg);
rio_dprintk(RIO_DEBUG_CTRL, "p->RIOBindTab full! - Rta %lx not added\n", arg);
return -ENOMEM;
}
return 0;
@ -397,7 +405,7 @@ int su;
case RIO_RESUME:
rio_dprintk(RIO_DEBUG_CTRL, "RIO_RESUME\n");
port = (unsigned long) arg;
port = arg;
if ((port < 0) || (port > 511)) {
rio_dprintk(RIO_DEBUG_CTRL, "RIO_RESUME: Bad port number %d\n", port);
p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
@ -433,7 +441,7 @@ int su;
p->RIOError.Error = NOT_SUPER_USER;
return -EPERM;
}
if (copy_from_user(&MapEnt, arg, sizeof(MapEnt))) {
if (copy_from_user(&MapEnt, argp, sizeof(MapEnt))) {
rio_dprintk(RIO_DEBUG_CTRL, "Copy from user space failed\n");
p->RIOError.Error = COPYIN_FAILED;
return -EFAULT;
@ -447,7 +455,7 @@ int su;
p->RIOError.Error = NOT_SUPER_USER;
return -EPERM;
}
if (copy_from_user(&MapEnt, arg, sizeof(MapEnt))) {
if (copy_from_user(&MapEnt, argp, sizeof(MapEnt))) {
rio_dprintk(RIO_DEBUG_CTRL, "Copy from user space failed\n");
p->RIOError.Error = COPYIN_FAILED;
return -EFAULT;
@ -461,7 +469,7 @@ int su;
p->RIOError.Error = NOT_SUPER_USER;
return -EPERM;
}
if (copy_from_user(&MapEnt, arg, sizeof(MapEnt))) {
if (copy_from_user(&MapEnt, argp, sizeof(MapEnt))) {
rio_dprintk(RIO_DEBUG_CTRL, "Copy from data space failed\n");
p->RIOError.Error = COPYIN_FAILED;
return -EFAULT;
@ -469,14 +477,14 @@ int su;
return RIODeleteRta(p, &MapEnt);
case RIO_QUICK_CHECK:
if (copy_to_user(arg, &p->RIORtaDisCons, sizeof(unsigned int))) {
if (copy_to_user(argp, &p->RIORtaDisCons, sizeof(unsigned int))) {
p->RIOError.Error = COPYOUT_FAILED;
return -EFAULT;
}
return 0;
case RIO_LAST_ERROR:
if (copy_to_user(arg, &p->RIOError, sizeof(struct Error)))
if (copy_to_user(argp, &p->RIOError, sizeof(struct Error)))
return -EFAULT;
return 0;
@ -485,7 +493,7 @@ int su;
return -EINVAL;
case RIO_GET_MODTYPE:
if (copy_from_user(&port, arg, sizeof(unsigned int))) {
if (copy_from_user(&port, argp, sizeof(unsigned int))) {
p->RIOError.Error = COPYIN_FAILED;
return -EFAULT;
}
@ -505,7 +513,7 @@ int su;
** Return module type of port
*/
port = PortP->HostP->UnixRups[PortP->RupNum].ModTypes;
if (copy_to_user(arg, &port, sizeof(unsigned int))) {
if (copy_to_user(argp, &port, sizeof(unsigned int))) {
p->RIOError.Error = COPYOUT_FAILED;
return -EFAULT;
}
@ -521,7 +529,7 @@ int su;
case RIO_SETUP_PORTS:
rio_dprintk(RIO_DEBUG_CTRL, "Setup ports\n");
if (copy_from_user(&PortSetup, arg, sizeof(PortSetup))) {
if (copy_from_user(&PortSetup, argp, sizeof(PortSetup))) {
p->RIOError.Error = COPYIN_FAILED;
rio_dprintk(RIO_DEBUG_CTRL, "EFAULT");
return -EFAULT;
@ -551,7 +559,7 @@ int su;
case RIO_GET_PORT_SETUP:
rio_dprintk(RIO_DEBUG_CTRL, "Get port setup\n");
if (copy_from_user(&PortSetup, arg, sizeof(PortSetup))) {
if (copy_from_user(&PortSetup, argp, sizeof(PortSetup))) {
p->RIOError.Error = COPYIN_FAILED;
return -EFAULT;
}
@ -572,7 +580,7 @@ int su;
PortSetup.XpOn[MAX_XP_CTRL_LEN - 1] = '\0';
PortSetup.XpOff[MAX_XP_CTRL_LEN - 1] = '\0';
if (copy_to_user(arg, &PortSetup, sizeof(PortSetup))) {
if (copy_to_user(argp, &PortSetup, sizeof(PortSetup))) {
p->RIOError.Error = COPYOUT_FAILED;
return -EFAULT;
}
@ -580,7 +588,7 @@ int su;
case RIO_GET_PORT_PARAMS:
rio_dprintk(RIO_DEBUG_CTRL, "Get port params\n");
if (copy_from_user(&PortParams, arg, sizeof(struct PortParams))) {
if (copy_from_user(&PortParams, argp, sizeof(struct PortParams))) {
p->RIOError.Error = COPYIN_FAILED;
return -EFAULT;
}
@ -593,7 +601,7 @@ int su;
PortParams.State = PortP->State;
rio_dprintk(RIO_DEBUG_CTRL, "Port %d\n", PortParams.Port);
if (copy_to_user(arg, &PortParams, sizeof(struct PortParams))) {
if (copy_to_user(argp, &PortParams, sizeof(struct PortParams))) {
p->RIOError.Error = COPYOUT_FAILED;
return -EFAULT;
}
@ -601,7 +609,7 @@ int su;
case RIO_GET_PORT_TTY:
rio_dprintk(RIO_DEBUG_CTRL, "Get port tty\n");
if (copy_from_user(&PortTty, arg, sizeof(struct PortTty))) {
if (copy_from_user(&PortTty, argp, sizeof(struct PortTty))) {
p->RIOError.Error = COPYIN_FAILED;
return -EFAULT;
}
@ -612,14 +620,14 @@ int su;
rio_dprintk(RIO_DEBUG_CTRL, "Port %d\n", PortTty.port);
PortP = (p->RIOPortp[PortTty.port]);
if (copy_to_user(arg, &PortTty, sizeof(struct PortTty))) {
if (copy_to_user(argp, &PortTty, sizeof(struct PortTty))) {
p->RIOError.Error = COPYOUT_FAILED;
return -EFAULT;
}
return retval;
case RIO_SET_PORT_TTY:
if (copy_from_user(&PortTty, arg, sizeof(struct PortTty))) {
if (copy_from_user(&PortTty, argp, sizeof(struct PortTty))) {
p->RIOError.Error = COPYIN_FAILED;
return -EFAULT;
}
@ -634,7 +642,7 @@ int su;
case RIO_SET_PORT_PARAMS:
rio_dprintk(RIO_DEBUG_CTRL, "Set port params\n");
if (copy_from_user(&PortParams, arg, sizeof(PortParams))) {
if (copy_from_user(&PortParams, argp, sizeof(PortParams))) {
p->RIOError.Error = COPYIN_FAILED;
return -EFAULT;
}
@ -650,7 +658,7 @@ int su;
case RIO_GET_PORT_STATS:
rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_PORT_STATS\n");
if (copy_from_user(&portStats, arg, sizeof(struct portStats))) {
if (copy_from_user(&portStats, argp, sizeof(struct portStats))) {
p->RIOError.Error = COPYIN_FAILED;
return -EFAULT;
}
@ -665,14 +673,14 @@ int su;
portStats.opens = PortP->opens;
portStats.closes = PortP->closes;
portStats.ioctls = PortP->ioctls;
if (copy_to_user(arg, &portStats, sizeof(struct portStats))) {
if (copy_to_user(argp, &portStats, sizeof(struct portStats))) {
p->RIOError.Error = COPYOUT_FAILED;
return -EFAULT;
}
return retval;
case RIO_RESET_PORT_STATS:
port = (unsigned long) arg;
port = arg;
rio_dprintk(RIO_DEBUG_CTRL, "RIO_RESET_PORT_STATS\n");
if (port >= RIO_PORTS) {
p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
@ -690,7 +698,7 @@ int su;
case RIO_GATHER_PORT_STATS:
rio_dprintk(RIO_DEBUG_CTRL, "RIO_GATHER_PORT_STATS\n");
if (copy_from_user(&portStats, arg, sizeof(struct portStats))) {
if (copy_from_user(&portStats, argp, sizeof(struct portStats))) {
p->RIOError.Error = COPYIN_FAILED;
return -EFAULT;
}
@ -706,7 +714,7 @@ int su;
case RIO_READ_CONFIG:
rio_dprintk(RIO_DEBUG_CTRL, "RIO_READ_CONFIG\n");
if (copy_to_user(arg, &p->RIOConf, sizeof(struct Conf))) {
if (copy_to_user(argp, &p->RIOConf, sizeof(struct Conf))) {
p->RIOError.Error = COPYOUT_FAILED;
return -EFAULT;
}
@ -718,7 +726,7 @@ int su;
p->RIOError.Error = NOT_SUPER_USER;
return -EPERM;
}
if (copy_from_user(&p->RIOConf, arg, sizeof(struct Conf))) {
if (copy_from_user(&p->RIOConf, argp, sizeof(struct Conf))) {
p->RIOError.Error = COPYIN_FAILED;
return -EFAULT;
}
@ -746,7 +754,7 @@ int su;
case RIO_SETDEBUG:
case RIO_GETDEBUG:
rio_dprintk(RIO_DEBUG_CTRL, "RIO_SETDEBUG/RIO_GETDEBUG\n");
if (copy_from_user(&DebugCtrl, arg, sizeof(DebugCtrl))) {
if (copy_from_user(&DebugCtrl, argp, sizeof(DebugCtrl))) {
p->RIOError.Error = COPYIN_FAILED;
return -EFAULT;
}
@ -763,7 +771,7 @@ int su;
rio_dprintk(RIO_DEBUG_CTRL, "Get global debug 0x%x wait 0x%x\n", p->rio_debug, p->RIODebugWait);
DebugCtrl.Debug = p->rio_debug;
DebugCtrl.Wait = p->RIODebugWait;
if (copy_to_user(arg, &DebugCtrl, sizeof(DebugCtrl))) {
if (copy_to_user(argp, &DebugCtrl, sizeof(DebugCtrl))) {
rio_dprintk(RIO_DEBUG_CTRL, "RIO_SET/GET DEBUG: bad port number %d\n", DebugCtrl.SysPort);
p->RIOError.Error = COPYOUT_FAILED;
return -EFAULT;
@ -785,7 +793,7 @@ int su;
} else {
rio_dprintk(RIO_DEBUG_CTRL, "RIO_GETDEBUG 0x%x\n", p->RIOPortp[DebugCtrl.SysPort]->Debug);
DebugCtrl.Debug = p->RIOPortp[DebugCtrl.SysPort]->Debug;
if (copy_to_user(arg, &DebugCtrl, sizeof(DebugCtrl))) {
if (copy_to_user(argp, &DebugCtrl, sizeof(DebugCtrl))) {
rio_dprintk(RIO_DEBUG_CTRL, "RIO_GETDEBUG: Bad copy to user space\n");
p->RIOError.Error = COPYOUT_FAILED;
return -EFAULT;
@ -800,7 +808,7 @@ int su;
** textual null terminated string.
*/
rio_dprintk(RIO_DEBUG_CTRL, "RIO_VERSID\n");
if (copy_to_user(arg, RIOVersid(), sizeof(struct rioVersion))) {
if (copy_to_user(argp, RIOVersid(), sizeof(struct rioVersion))) {
rio_dprintk(RIO_DEBUG_CTRL, "RIO_VERSID: Bad copy to user space (host=%d)\n", Host);
p->RIOError.Error = COPYOUT_FAILED;
return -EFAULT;
@ -813,7 +821,7 @@ int su;
** at init time.
*/
rio_dprintk(RIO_DEBUG_CTRL, "RIO_NUM_HOSTS\n");
if (copy_to_user(arg, &p->RIONumHosts, sizeof(p->RIONumHosts))) {
if (copy_to_user(argp, &p->RIONumHosts, sizeof(p->RIONumHosts))) {
rio_dprintk(RIO_DEBUG_CTRL, "RIO_NUM_HOSTS: Bad copy to user space\n");
p->RIOError.Error = COPYOUT_FAILED;
return -EFAULT;
@ -824,7 +832,7 @@ int su;
/*
** Kill host. This may not be in the final version...
*/
rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_FOAD %ld\n", (unsigned long) arg);
rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_FOAD %ld\n", arg);
if (!su) {
rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_FOAD: Not super user\n");
p->RIOError.Error = NOT_SUPER_USER;
@ -858,7 +866,7 @@ int su;
p->RIOError.Error = NOT_SUPER_USER;
return -EPERM;
}
if (copy_from_user(&DownLoad, arg, sizeof(DownLoad))) {
if (copy_from_user(&DownLoad, argp, sizeof(DownLoad))) {
rio_dprintk(RIO_DEBUG_CTRL, "RIO_DOWNLOAD: Copy in from user space failed\n");
p->RIOError.Error = COPYIN_FAILED;
return -EFAULT;
@ -888,7 +896,7 @@ int su;
{
unsigned int host;
if (copy_from_user(&host, arg, sizeof(host))) {
if (copy_from_user(&host, argp, sizeof(host))) {
rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_REQ: Copy in from user space failed\n");
p->RIOError.Error = COPYIN_FAILED;
return -EFAULT;
@ -897,7 +905,7 @@ int su;
** Fetch the parmmap
*/
rio_dprintk(RIO_DEBUG_CTRL, "RIO_PARMS\n");
if (copy_to_user(arg, p->RIOHosts[host].ParmMapP, sizeof(PARM_MAP))) {
if (copy_from_io(argp, p->RIOHosts[host].ParmMapP, sizeof(PARM_MAP))) {
p->RIOError.Error = COPYOUT_FAILED;
rio_dprintk(RIO_DEBUG_CTRL, "RIO_PARMS: Copy out to user space failed\n");
return -EFAULT;
@ -907,7 +915,7 @@ int su;
case RIO_HOST_REQ:
rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_REQ\n");
if (copy_from_user(&HostReq, arg, sizeof(HostReq))) {
if (copy_from_user(&HostReq, argp, sizeof(HostReq))) {
rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_REQ: Copy in from user space failed\n");
p->RIOError.Error = COPYIN_FAILED;
return -EFAULT;
@ -928,7 +936,7 @@ int su;
case RIO_HOST_DPRAM:
rio_dprintk(RIO_DEBUG_CTRL, "Request for DPRAM\n");
if (copy_from_user(&HostDpRam, arg, sizeof(HostDpRam))) {
if (copy_from_user(&HostDpRam, argp, sizeof(HostDpRam))) {
rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_DPRAM: Copy in from user space failed\n");
p->RIOError.Error = COPYIN_FAILED;
return -EFAULT;
@ -945,13 +953,13 @@ int su;
/* It's hardware like this that really gets on my tits. */
static unsigned char copy[sizeof(struct DpRam)];
for (off = 0; off < sizeof(struct DpRam); off++)
copy[off] = readb(&p->RIOHosts[HostDpRam.HostNum].Caddr[off]);
copy[off] = readb(p->RIOHosts[HostDpRam.HostNum].Caddr + off);
if (copy_to_user(HostDpRam.DpRamP, copy, sizeof(struct DpRam))) {
p->RIOError.Error = COPYOUT_FAILED;
rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_DPRAM: Bad copy to user space\n");
return -EFAULT;
}
} else if (copy_to_user(HostDpRam.DpRamP, p->RIOHosts[HostDpRam.HostNum].Caddr, sizeof(struct DpRam))) {
} else if (copy_from_io(HostDpRam.DpRamP, p->RIOHosts[HostDpRam.HostNum].Caddr, sizeof(struct DpRam))) {
p->RIOError.Error = COPYOUT_FAILED;
rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_DPRAM: Bad copy to user space\n");
return -EFAULT;
@ -960,13 +968,13 @@ int su;
case RIO_SET_BUSY:
rio_dprintk(RIO_DEBUG_CTRL, "RIO_SET_BUSY\n");
if ((unsigned long) arg > 511) {
rio_dprintk(RIO_DEBUG_CTRL, "RIO_SET_BUSY: Bad port number %ld\n", (unsigned long) arg);
if (arg > 511) {
rio_dprintk(RIO_DEBUG_CTRL, "RIO_SET_BUSY: Bad port number %ld\n", arg);
p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
return -EINVAL;
}
rio_spin_lock_irqsave(&PortP->portSem, flags);
p->RIOPortp[(unsigned long) arg]->State |= RIO_BUSY;
p->RIOPortp[arg]->State |= RIO_BUSY;
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
return retval;
@ -976,7 +984,7 @@ int su;
** (probably for debug reasons)
*/
rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_PORT\n");
if (copy_from_user(&PortReq, arg, sizeof(PortReq))) {
if (copy_from_user(&PortReq, argp, sizeof(PortReq))) {
rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_PORT: Copy in from user space failed\n");
p->RIOError.Error = COPYIN_FAILED;
return -EFAULT;
@ -1001,7 +1009,7 @@ int su;
** (probably for debug reasons)
*/
rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_RUP\n");
if (copy_from_user(&RupReq, arg, sizeof(RupReq))) {
if (copy_from_user(&RupReq, argp, sizeof(RupReq))) {
rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_RUP: Copy in from user space failed\n");
p->RIOError.Error = COPYIN_FAILED;
return -EFAULT;
@ -1025,7 +1033,7 @@ int su;
}
rio_dprintk(RIO_DEBUG_CTRL, "Request for rup %d from host %d\n", RupReq.RupNum, RupReq.HostNum);
if (copy_to_user(HostP->UnixRups[RupReq.RupNum].RupP, RupReq.RupP, sizeof(struct RUP))) {
if (copy_from_io(RupReq.RupP, HostP->UnixRups[RupReq.RupNum].RupP, sizeof(struct RUP))) {
p->RIOError.Error = COPYOUT_FAILED;
rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_RUP: Bad copy to user space\n");
return -EFAULT;
@ -1038,7 +1046,7 @@ int su;
** (probably for debug reasons)
*/
rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_LPB\n");
if (copy_from_user(&LpbReq, arg, sizeof(LpbReq))) {
if (copy_from_user(&LpbReq, argp, sizeof(LpbReq))) {
rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_LPB: Bad copy from user space\n");
p->RIOError.Error = COPYIN_FAILED;
return -EFAULT;
@ -1062,7 +1070,7 @@ int su;
}
rio_dprintk(RIO_DEBUG_CTRL, "Request for lpb %d from host %d\n", LpbReq.Link, LpbReq.Host);
if (copy_to_user(LpbReq.LpbP, &HostP->LinkStrP[LpbReq.Link], sizeof(struct LPB))) {
if (copy_from_io(LpbReq.LpbP, &HostP->LinkStrP[LpbReq.Link], sizeof(struct LPB))) {
rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_LPB: Bad copy to user space\n");
p->RIOError.Error = COPYOUT_FAILED;
return -EFAULT;
@ -1136,7 +1144,7 @@ int su;
case RIO_MAP_B110_TO_110:
case RIO_MAP_B110_TO_115200:
rio_dprintk(RIO_DEBUG_CTRL, "Baud rate mapping\n");
port = (unsigned long) arg;
port = arg;
if (port < 0 || port > 511) {
rio_dprintk(RIO_DEBUG_CTRL, "Baud rate mapping: Bad port number %d\n", port);
p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
@ -1166,7 +1174,7 @@ int su;
case RIO_SEND_PACKET:
rio_dprintk(RIO_DEBUG_CTRL, "RIO_SEND_PACKET\n");
if (copy_from_user(&SendPack, arg, sizeof(SendPack))) {
if (copy_from_user(&SendPack, argp, sizeof(SendPack))) {
rio_dprintk(RIO_DEBUG_CTRL, "RIO_SEND_PACKET: Bad copy from user space\n");
p->RIOError.Error = COPYIN_FAILED;
return -EFAULT;
@ -1210,7 +1218,7 @@ int su;
return su ? 0 : -EPERM;
case RIO_WHAT_MESG:
if (copy_to_user(arg, &p->RIONoMessage, sizeof(p->RIONoMessage))) {
if (copy_to_user(argp, &p->RIONoMessage, sizeof(p->RIONoMessage))) {
rio_dprintk(RIO_DEBUG_CTRL, "RIO_WHAT_MESG: Bad copy to user space\n");
p->RIOError.Error = COPYOUT_FAILED;
return -EFAULT;
@ -1218,7 +1226,7 @@ int su;
return 0;
case RIO_MEM_DUMP:
if (copy_from_user(&SubCmd, arg, sizeof(struct SubCmdStruct))) {
if (copy_from_user(&SubCmd, argp, sizeof(struct SubCmdStruct))) {
p->RIOError.Error = COPYIN_FAILED;
return -EFAULT;
}
@ -1248,7 +1256,7 @@ int su;
PortP->State |= RIO_BUSY;
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
if (copy_to_user(arg, p->RIOMemDump, MEMDUMP_SIZE)) {
if (copy_to_user(argp, p->RIOMemDump, MEMDUMP_SIZE)) {
rio_dprintk(RIO_DEBUG_CTRL, "RIO_MEM_DUMP copy failed\n");
p->RIOError.Error = COPYOUT_FAILED;
return -EFAULT;
@ -1256,30 +1264,30 @@ int su;
return 0;
case RIO_TICK:
if ((unsigned long) arg >= p->RIONumHosts)
if (arg >= p->RIONumHosts)
return -EINVAL;
rio_dprintk(RIO_DEBUG_CTRL, "Set interrupt for host %ld\n", (unsigned long) arg);
writeb(0xFF, &p->RIOHosts[(unsigned long) arg].SetInt);
rio_dprintk(RIO_DEBUG_CTRL, "Set interrupt for host %ld\n", arg);
writeb(0xFF, &p->RIOHosts[arg].SetInt);
return 0;
case RIO_TOCK:
if ((unsigned long) arg >= p->RIONumHosts)
if (arg >= p->RIONumHosts)
return -EINVAL;
rio_dprintk(RIO_DEBUG_CTRL, "Clear interrupt for host %ld\n", (unsigned long) arg);
writeb(0xFF, &p->RIOHosts[(unsigned long) arg].ResetInt);
rio_dprintk(RIO_DEBUG_CTRL, "Clear interrupt for host %ld\n", arg);
writeb(0xFF, &p->RIOHosts[arg].ResetInt);
return 0;
case RIO_READ_CHECK:
/* Check reads for pkts with data[0] the same */
p->RIOReadCheck = !p->RIOReadCheck;
if (copy_to_user(arg, &p->RIOReadCheck, sizeof(unsigned int))) {
if (copy_to_user(argp, &p->RIOReadCheck, sizeof(unsigned int))) {
p->RIOError.Error = COPYOUT_FAILED;
return -EFAULT;
}
return 0;
case RIO_READ_REGISTER:
if (copy_from_user(&SubCmd, arg, sizeof(struct SubCmdStruct))) {
if (copy_from_user(&SubCmd, argp, sizeof(struct SubCmdStruct))) {
p->RIOError.Error = COPYIN_FAILED;
return -EFAULT;
}
@ -1314,7 +1322,7 @@ int su;
PortP->State |= RIO_BUSY;
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
if (copy_to_user(arg, &p->CdRegister, sizeof(unsigned int))) {
if (copy_to_user(argp, &p->CdRegister, sizeof(unsigned int))) {
rio_dprintk(RIO_DEBUG_CTRL, "RIO_READ_REGISTER copy failed\n");
p->RIOError.Error = COPYOUT_FAILED;
return -EFAULT;
@ -1327,10 +1335,10 @@ int su;
*/
case RIO_MAKE_DEV:
{
unsigned int port = (unsigned long) arg & RIO_MODEM_MASK;
unsigned int port = arg & RIO_MODEM_MASK;
unsigned int ret;
switch ((unsigned long) arg & RIO_DEV_MASK) {
switch (arg & RIO_DEV_MASK) {
case RIO_DEV_DIRECT:
ret = drv_makedev(MAJOR(dev), port);
rio_dprintk(RIO_DEBUG_CTRL, "Makedev direct 0x%x is 0x%x\n", port, ret);
@ -1358,7 +1366,7 @@ int su;
int mino;
unsigned long ret;
dv = (dev_t) ((unsigned long) arg);
dv = (dev_t) (arg);
mino = RIO_UNMODEM(dv);
if (RIO_ISMODEM(dv)) {

View file

@ -79,7 +79,7 @@ static char *_rioinit_c_sccs_ = "@(#)rioinit.c 1.3";
int RIOPCIinit(struct rio_info *p, int Mode);
static int RIOScrub(int, u8 *, int);
static int RIOScrub(int, u8 __iomem *, int);
/**
@ -92,10 +92,10 @@ static int RIOScrub(int, u8 *, int);
** bits > 0 indicates 16 bit operation.
*/
int RIOAssignAT(struct rio_info *p, int Base, caddr_t virtAddr, int mode)
int RIOAssignAT(struct rio_info *p, int Base, void __iomem *virtAddr, int mode)
{
int bits;
struct DpRam *cardp = (struct DpRam *)virtAddr;
struct DpRam __iomem *cardp = (struct DpRam __iomem *)virtAddr;
if ((Base < ONE_MEG) || (mode & BYTE_ACCESS_MODE))
bits = BYTE_OPERATION;
@ -107,7 +107,7 @@ int RIOAssignAT(struct rio_info *p, int Base, caddr_t virtAddr, int mode)
** transient stuff.
*/
p->RIOHosts[p->RIONumHosts].Caddr = virtAddr;
p->RIOHosts[p->RIONumHosts].CardP = (struct DpRam *)virtAddr;
p->RIOHosts[p->RIONumHosts].CardP = virtAddr;
/*
** Revision 01 AT host cards don't support WORD operations,
@ -151,10 +151,10 @@ static u8 val[] = {
** RAM test a board.
** Nothing too complicated, just enough to check it out.
*/
int RIOBoardTest(unsigned long paddr, caddr_t caddr, unsigned char type, int slot)
int RIOBoardTest(unsigned long paddr, void __iomem *caddr, unsigned char type, int slot)
{
struct DpRam *DpRam = (struct DpRam *)caddr;
char *ram[4];
struct DpRam __iomem *DpRam = caddr;
void __iomem *ram[4];
int size[4];
int op, bank;
int nbanks;
@ -179,12 +179,12 @@ int RIOBoardTest(unsigned long paddr, caddr_t caddr, unsigned char type, int slo
size[2] = DP_SRAM3_SIZE;
size[3] = DP_SCRATCH_SIZE;
ram[0] = (char *)&DpRam->DpSram1[0];
ram[1] = (char *)&DpRam->DpSram2[0];
ram[2] = (char *)&DpRam->DpSram3[0];
ram[0] = DpRam->DpSram1;
ram[1] = DpRam->DpSram2;
ram[2] = DpRam->DpSram3;
nbanks = (type == RIO_PCI) ? 3 : 4;
if (nbanks == 4)
ram[3] = (char *)&DpRam->DpScratch[0];
ram[3] = DpRam->DpScratch;
if (nbanks == 3) {
@ -202,7 +202,7 @@ int RIOBoardTest(unsigned long paddr, caddr_t caddr, unsigned char type, int slo
*/
for (op=0; op<TEST_END; op++) {
for (bank=0; bank<nbanks; bank++) {
if (RIOScrub(op, (u8 *)ram[bank], size[bank]) == RIO_FAIL) {
if (RIOScrub(op, ram[bank], size[bank]) == RIO_FAIL) {
rio_dprintk (RIO_DEBUG_INIT, "RIO-init: RIOScrub band %d, op %d failed\n",
bank, op);
return RIO_FAIL;
@ -227,7 +227,7 @@ int RIOBoardTest(unsigned long paddr, caddr_t caddr, unsigned char type, int slo
** to check that the data from the previous phase was retained.
*/
static int RIOScrub(int op, u8 *ram, int size)
static int RIOScrub(int op, u8 __iomem *ram, int size)
{
int off;
unsigned char oldbyte;
@ -393,7 +393,7 @@ struct rioVersion *RIOVersid(void)
return &stVersion;
}
void RIOHostReset(unsigned int Type, struct DpRam *DpRamP, unsigned int Slot)
void RIOHostReset(unsigned int Type, struct DpRam __iomem *DpRamP, unsigned int Slot)
{
/*
** Reset the Tpu

View file

@ -102,7 +102,7 @@ void RIOTxEnable(char *en)
struct rio_info *p;
struct tty_struct *tty;
int c;
struct PKT *PacketP;
struct PKT __iomem *PacketP;
unsigned long flags;
PortP = (struct Port *) en;
@ -144,7 +144,7 @@ void RIOTxEnable(char *en)
if (c == 0)
break;
rio_memcpy_toio(PortP->HostP->Caddr, (caddr_t) PacketP->data, PortP->gs.xmit_buf + PortP->gs.xmit_tail, c);
rio_memcpy_toio(PortP->HostP->Caddr, PacketP->data, PortP->gs.xmit_buf + PortP->gs.xmit_tail, c);
/* udelay (1); */
writeb(c, &(PacketP->len));
@ -219,7 +219,7 @@ void RIOServiceHost(struct rio_info *p, struct Host *HostP, int From)
for (port = p->RIOFirstPortsBooted; port < p->RIOLastPortsBooted + PORTS_PER_RTA; port++) {
struct Port *PortP = p->RIOPortp[port];
struct tty_struct *ttyP;
struct PKT *PacketP;
struct PKT __iomem *PacketP;
/*
** not mapped in - most of the RIOPortp[] information
@ -298,7 +298,7 @@ void RIOServiceHost(struct rio_info *p, struct Host *HostP, int From)
for (port = p->RIOFirstPortsBooted; port < p->RIOLastPortsBooted + PORTS_PER_RTA; port++) {
struct Port *PortP = p->RIOPortp[port];
struct tty_struct *ttyP;
struct PKT *PacketP;
struct PKT __iomem *PacketP;
/*
** not mapped in - most of the RIOPortp[] information
@ -427,13 +427,13 @@ void RIOServiceHost(struct rio_info *p, struct Host *HostP, int From)
while (PortP->WflushFlag && can_add_transmit(&PacketP, PortP) && (PortP->InUse == NOT_INUSE)) {
int p;
struct PktCmd *PktCmdP;
struct PktCmd __iomem *PktCmdP;
rio_dprintk(RIO_DEBUG_INTR, "Add WFLUSH marker to data queue\n");
/*
** make it look just like a WFLUSH command
*/
PktCmdP = (struct PktCmd *) &PacketP->data[0];
PktCmdP = (struct PktCmd __iomem *) &PacketP->data[0];
writeb(WFLUSH, &PktCmdP->Command);
@ -525,9 +525,9 @@ static void RIOReceive(struct rio_info *p, struct Port *PortP)
{
struct tty_struct *TtyP;
unsigned short transCount;
struct PKT *PacketP;
struct PKT __iomem *PacketP;
register unsigned int DataCnt;
unsigned char *ptr;
unsigned char __iomem *ptr;
unsigned char *buf;
int copied = 0;
@ -585,19 +585,19 @@ static void RIOReceive(struct rio_info *p, struct Port *PortP)
/*
** check that it is not a command!
*/
if (PacketP->len & PKT_CMD_BIT) {
if (readb(&PacketP->len) & PKT_CMD_BIT) {
rio_dprintk(RIO_DEBUG_INTR, "RIO: unexpected command packet received on PHB\n");
/* rio_dprint(RIO_DEBUG_INTR, (" sysport = %d\n", p->RIOPortp->PortNum)); */
rio_dprintk(RIO_DEBUG_INTR, " dest_unit = %d\n", PacketP->dest_unit);
rio_dprintk(RIO_DEBUG_INTR, " dest_port = %d\n", PacketP->dest_port);
rio_dprintk(RIO_DEBUG_INTR, " src_unit = %d\n", PacketP->src_unit);
rio_dprintk(RIO_DEBUG_INTR, " src_port = %d\n", PacketP->src_port);
rio_dprintk(RIO_DEBUG_INTR, " len = %d\n", PacketP->len);
rio_dprintk(RIO_DEBUG_INTR, " control = %d\n", PacketP->control);
rio_dprintk(RIO_DEBUG_INTR, " csum = %d\n", PacketP->csum);
rio_dprintk(RIO_DEBUG_INTR, " dest_unit = %d\n", readb(&PacketP->dest_unit));
rio_dprintk(RIO_DEBUG_INTR, " dest_port = %d\n", readb(&PacketP->dest_port));
rio_dprintk(RIO_DEBUG_INTR, " src_unit = %d\n", readb(&PacketP->src_unit));
rio_dprintk(RIO_DEBUG_INTR, " src_port = %d\n", readb(&PacketP->src_port));
rio_dprintk(RIO_DEBUG_INTR, " len = %d\n", readb(&PacketP->len));
rio_dprintk(RIO_DEBUG_INTR, " control = %d\n", readb(&PacketP->control));
rio_dprintk(RIO_DEBUG_INTR, " csum = %d\n", readw(&PacketP->csum));
rio_dprintk(RIO_DEBUG_INTR, " data bytes: ");
for (DataCnt = 0; DataCnt < PKT_MAX_DATA_LEN; DataCnt++)
rio_dprintk(RIO_DEBUG_INTR, "%d\n", PacketP->data[DataCnt]);
rio_dprintk(RIO_DEBUG_INTR, "%d\n", readb(&PacketP->data[DataCnt]));
remove_receive(PortP);
put_free_end(PortP->HostP, PacketP);
continue; /* with next packet */
@ -618,24 +618,24 @@ static void RIOReceive(struct rio_info *p, struct Port *PortP)
** and available space.
*/
transCount = tty_buffer_request_room(TtyP, PacketP->len & PKT_LEN_MASK);
transCount = tty_buffer_request_room(TtyP, readb(&PacketP->len) & PKT_LEN_MASK);
rio_dprintk(RIO_DEBUG_REC, "port %d: Copy %d bytes\n", PortP->PortNum, transCount);
/*
** To use the following 'kkprintfs' for debugging - change the '#undef'
** to '#define', (this is the only place ___DEBUG_IT___ occurs in the
** driver).
*/
ptr = (unsigned char *) PacketP->data + PortP->RxDataStart;
ptr = (unsigned char __iomem *) PacketP->data + PortP->RxDataStart;
tty_prepare_flip_string(TtyP, &buf, transCount);
rio_memcpy_fromio(buf, ptr, transCount);
PortP->RxDataStart += transCount;
PacketP->len -= transCount;
writeb(readb(&PacketP->len)-transCount, &PacketP->len);
copied += transCount;
if (PacketP->len == 0) {
if (readb(&PacketP->len) == 0) {
/*
** If we have emptied the packet, then we can
** free it, and reset the start pointer for

View file

@ -154,8 +154,8 @@ int RIOParam(struct Port *PortP, int cmd, int Modem, int SleepFlag)
{
struct tty_struct *TtyP;
int retval;
struct phb_param *phb_param_ptr;
struct PKT *PacketP;
struct phb_param __iomem *phb_param_ptr;
struct PKT __iomem *PacketP;
int res;
u8 Cor1 = 0, Cor2 = 0, Cor4 = 0, Cor5 = 0;
u8 TxXon = 0, TxXoff = 0, RxXon = 0, RxXoff = 0;
@ -235,7 +235,7 @@ int RIOParam(struct Port *PortP, int cmd, int Modem, int SleepFlag)
rio_dprintk(RIO_DEBUG_PARAM, "can_add_transmit() returns %x\n", res);
rio_dprintk(RIO_DEBUG_PARAM, "Packet is %p\n", PacketP);
phb_param_ptr = (struct phb_param *) PacketP->data;
phb_param_ptr = (struct phb_param __iomem *) PacketP->data;
switch (TtyP->termios->c_cflag & CSIZE) {
@ -580,11 +580,11 @@ int RIOParam(struct Port *PortP, int cmd, int Modem, int SleepFlag)
** We can add another packet to a transmit queue if the packet pointer pointed
** to by the TxAdd pointer has PKT_IN_USE clear in its address.
*/
int can_add_transmit(struct PKT **PktP, struct Port *PortP)
int can_add_transmit(struct PKT __iomem **PktP, struct Port *PortP)
{
struct PKT *tp;
struct PKT __iomem *tp;
*PktP = tp = (struct PKT *) RIO_PTR(PortP->Caddr, readw(PortP->TxAdd));
*PktP = tp = (struct PKT __iomem *) RIO_PTR(PortP->Caddr, readw(PortP->TxAdd));
return !((unsigned long) tp & PKT_IN_USE);
}
@ -608,9 +608,9 @@ void add_transmit(struct Port *PortP)
* Put a packet onto the end of the
* free list
****************************************/
void put_free_end(struct Host *HostP, struct PKT *PktP)
void put_free_end(struct Host *HostP, struct PKT __iomem *PktP)
{
struct rio_free_list *tmp_pointer;
struct rio_free_list __iomem *tmp_pointer;
unsigned short old_end, new_end;
unsigned long flags;
@ -625,15 +625,15 @@ void put_free_end(struct Host *HostP, struct PKT *PktP)
if ((old_end = readw(&HostP->ParmMapP->free_list_end)) != TPNULL) {
new_end = RIO_OFF(HostP->Caddr, PktP);
tmp_pointer = (struct rio_free_list *) RIO_PTR(HostP->Caddr, old_end);
tmp_pointer = (struct rio_free_list __iomem *) RIO_PTR(HostP->Caddr, old_end);
writew(new_end, &tmp_pointer->next);
writew(old_end, &((struct rio_free_list *) PktP)->prev);
writew(TPNULL, &((struct rio_free_list *) PktP)->next);
writew(old_end, &((struct rio_free_list __iomem *) PktP)->prev);
writew(TPNULL, &((struct rio_free_list __iomem *) PktP)->next);
writew(new_end, &HostP->ParmMapP->free_list_end);
} else { /* First packet on the free list this should never happen! */
rio_dprintk(RIO_DEBUG_PFE, "put_free_end(): This should never happen\n");
writew(RIO_OFF(HostP->Caddr, PktP), &HostP->ParmMapP->free_list_end);
tmp_pointer = (struct rio_free_list *) PktP;
tmp_pointer = (struct rio_free_list __iomem *) PktP;
writew(TPNULL, &tmp_pointer->prev);
writew(TPNULL, &tmp_pointer->next);
}
@ -647,10 +647,10 @@ void put_free_end(struct Host *HostP, struct PKT *PktP)
** relevant packet, [having cleared the PKT_IN_USE bit]. If PKT_IN_USE is clear,
** then can_remove_receive() returns 0.
*/
int can_remove_receive(struct PKT **PktP, struct Port *PortP)
int can_remove_receive(struct PKT __iomem **PktP, struct Port *PortP)
{
if (readw(PortP->RxRemove) & PKT_IN_USE) {
*PktP = (struct PKT *) RIO_PTR(PortP->Caddr, readw(PortP->RxRemove) & ~PKT_IN_USE);
*PktP = (struct PKT __iomem *) RIO_PTR(PortP->Caddr, readw(PortP->RxRemove) & ~PKT_IN_USE);
return 1;
}
return 0;

View file

@ -86,9 +86,9 @@ static void RIOConCon(struct rio_info *, struct Host *, unsigned int, unsigned i
** Incoming on the ROUTE_RUP
** I wrote this while I was tired. Forgive me.
*/
int RIORouteRup(struct rio_info *p, unsigned int Rup, struct Host *HostP, struct PKT * PacketP)
int RIORouteRup(struct rio_info *p, unsigned int Rup, struct Host *HostP, struct PKT __iomem * PacketP)
{
struct PktCmd *PktCmdP = (struct PktCmd *) PacketP->data;
struct PktCmd __iomem *PktCmdP = (struct PktCmd __iomem *) PacketP->data;
struct PktCmd_M *PktReplyP;
struct CmdBlk *CmdBlkP;
struct Port *PortP;
@ -307,7 +307,7 @@ int RIORouteRup(struct rio_info *p, unsigned int Rup, struct Host *HostP, struct
if (!RIOBootOk(p, HostP, RtaUniq)) {
rio_dprintk(RIO_DEBUG_ROUTE, "RTA %x tried to get an ID, but does not belong - FOAD it!\n", RtaUniq);
PktReplyP->Command = ROUTE_FOAD;
HostP->Copy("RT_FOAD", PktReplyP->CommandText, 7);
memcpy(PktReplyP->CommandText, "RT_FOAD", 7);
RIOQueueCmdBlk(HostP, Rup, CmdBlkP);
return 1;
}
@ -341,7 +341,7 @@ int RIORouteRup(struct rio_info *p, unsigned int Rup, struct Host *HostP, struct
HostP->Mapping[ThisUnit].Flags |= MSG_DONE;
}
PktReplyP->Command = ROUTE_FOAD;
HostP->Copy("RT_FOAD", PktReplyP->CommandText, 7);
memcpy(PktReplyP->CommandText, "RT_FOAD", 7);
RIOQueueCmdBlk(HostP, Rup, CmdBlkP);
return 1;
}
@ -367,7 +367,7 @@ int RIORouteRup(struct rio_info *p, unsigned int Rup, struct Host *HostP, struct
PktReplyP->IDNum2 = ROUTE_NO_ID;
rio_dprintk(RIO_DEBUG_ROUTE, "RTA '%s' has been allocated ID %d\n", HostP->Mapping[ThisUnit].Name, PktReplyP->IDNum);
}
HostP->Copy("RT_ALLOCAT", PktReplyP->CommandText, 10);
memcpy(PktReplyP->CommandText, "RT_ALLOCAT", 10);
RIOQueueCmdBlk(HostP, Rup, CmdBlkP);
@ -469,7 +469,7 @@ int RIORouteRup(struct rio_info *p, unsigned int Rup, struct Host *HostP, struct
}
PktReplyP->Command = ROUTE_FOAD;
HostP->Copy("RT_FOAD", PktReplyP->CommandText, 7);
memcpy(PktReplyP->CommandText, "RT_FOAD", 7);
} else {
/*
** we did boot it (as an extra), and there may now be a table
@ -489,7 +489,7 @@ int RIORouteRup(struct rio_info *p, unsigned int Rup, struct Host *HostP, struct
}
}
PktReplyP->Command = ROUTE_USED;
HostP->Copy("RT_USED", PktReplyP->CommandText, 7);
memcpy(PktReplyP->CommandText, "RT_USED", 7);
}
RIOQueueCmdBlk(HostP, Rup, CmdBlkP);
return 1;
@ -517,8 +517,8 @@ void RIOFixPhbs(struct rio_info *p, struct Host *HostP, unsigned int unit)
for (port = 0; port < PORTS_PER_RTA; port++, PortN++) {
unsigned short dest_port = port + 8;
u16 *TxPktP;
struct PKT *Pkt;
u16 __iomem *TxPktP;
struct PKT __iomem *Pkt;
PortP = p->RIOPortp[PortN];
@ -555,12 +555,12 @@ void RIOFixPhbs(struct rio_info *p, struct Host *HostP, unsigned int unit)
** card. This needs to be translated into a 32 bit pointer
** so it can be accessed from the driver.
*/
Pkt = (struct PKT *) RIO_PTR(HostP->Caddr, readw(TxPktP));
Pkt = (struct PKT __iomem *) RIO_PTR(HostP->Caddr, readw(TxPktP));
/*
** If the packet is used, reset it.
*/
Pkt = (struct PKT *) ((unsigned long) Pkt & ~PKT_IN_USE);
Pkt = (struct PKT __iomem *) ((unsigned long) Pkt & ~PKT_IN_USE);
writeb(dest_unit, &Pkt->dest_unit);
writeb(dest_port, &Pkt->dest_port);
}

View file

@ -534,8 +534,8 @@ int RIODeleteRta(struct rio_info *p, struct Map *MapP)
if (PortP->SecondBlock) {
u16 dest_unit = HostMapP->ID;
u16 dest_port = port - SysPort;
u16 *TxPktP;
struct PKT *Pkt;
u16 __iomem *TxPktP;
struct PKT __iomem *Pkt;
for (TxPktP = PortP->TxStart; TxPktP <= PortP->TxEnd; TxPktP++) {
/*
@ -545,12 +545,12 @@ int RIODeleteRta(struct rio_info *p, struct Map *MapP)
** a 32 bit pointer so it can be
** accessed from the driver.
*/
Pkt = (struct PKT *) RIO_PTR(HostP->Caddr, readw(&*TxPktP));
rio_dprintk(RIO_DEBUG_TABLE, "Tx packet (%x) destination: Old %x:%x New %x:%x\n", *TxPktP, Pkt->dest_unit, Pkt->dest_port, dest_unit, dest_port);
Pkt = (struct PKT __iomem *) RIO_PTR(HostP->Caddr, readw(&*TxPktP));
rio_dprintk(RIO_DEBUG_TABLE, "Tx packet (%x) destination: Old %x:%x New %x:%x\n", readw(TxPktP), readb(&Pkt->dest_unit), readb(&Pkt->dest_port), dest_unit, dest_port);
writew(dest_unit, &Pkt->dest_unit);
writew(dest_port, &Pkt->dest_port);
}
rio_dprintk(RIO_DEBUG_TABLE, "Port %d phb destination: Old %x:%x New %x:%x\n", port, PortP->PhbP->destination & 0xff, (PortP->PhbP->destination >> 8) & 0xff, dest_unit, dest_port);
rio_dprintk(RIO_DEBUG_TABLE, "Port %d phb destination: Old %x:%x New %x:%x\n", port, readb(&PortP->PhbP->destination) & 0xff, (readb(&PortP->PhbP->destination) >> 8) & 0xff, dest_unit, dest_port);
writew(dest_unit + (dest_port << 8), &PortP->PhbP->destination);
}
rio_spin_unlock_irqrestore(&PortP->portSem, sem_flags);
@ -781,13 +781,13 @@ int RIOReMapPorts(struct rio_info *p, struct Host *HostP, struct Map *HostMapP)
** unless the host has been booted
*/
if ((HostP->Flags & RUN_STATE) == RC_RUNNING) {
struct PHB *PhbP = PortP->PhbP = &HostP->PhbP[HostPort];
PortP->TxAdd = (u16 *) RIO_PTR(HostP->Caddr, readw(&PhbP->tx_add));
PortP->TxStart = (u16 *) RIO_PTR(HostP->Caddr, readw(&PhbP->tx_start));
PortP->TxEnd = (u16 *) RIO_PTR(HostP->Caddr, readw(&PhbP->tx_end));
PortP->RxRemove = (u16 *) RIO_PTR(HostP->Caddr, readw(&PhbP->rx_remove));
PortP->RxStart = (u16 *) RIO_PTR(HostP->Caddr, readw(&PhbP->rx_start));
PortP->RxEnd = (u16 *) RIO_PTR(HostP->Caddr, readw(&PhbP->rx_end));
struct PHB __iomem *PhbP = PortP->PhbP = &HostP->PhbP[HostPort];
PortP->TxAdd = (u16 __iomem *) RIO_PTR(HostP->Caddr, readw(&PhbP->tx_add));
PortP->TxStart = (u16 __iomem *) RIO_PTR(HostP->Caddr, readw(&PhbP->tx_start));
PortP->TxEnd = (u16 __iomem *) RIO_PTR(HostP->Caddr, readw(&PhbP->tx_end));
PortP->RxRemove = (u16 __iomem *) RIO_PTR(HostP->Caddr, readw(&PhbP->rx_remove));
PortP->RxStart = (u16 __iomem *) RIO_PTR(HostP->Caddr, readw(&PhbP->rx_start));
PortP->RxEnd = (u16 __iomem *) RIO_PTR(HostP->Caddr, readw(&PhbP->rx_end));
} else
PortP->PhbP = NULL;

View file

@ -576,7 +576,7 @@ static void RIOClearUp(struct Port *PortP)
*/
int RIOShortCommand(struct rio_info *p, struct Port *PortP, int command, int len, int arg)
{
struct PKT *PacketP;
struct PKT __iomem *PacketP;
int retries = 20; /* at 10 per second -> 2 seconds */
unsigned long flags;

View file

@ -44,7 +44,7 @@ static char *_unixrup_h_sccs_ = "@(#)unixrup.h 1.2";
struct UnixRup {
struct CmdBlk *CmdsWaitingP; /* Commands waiting to be done */
struct CmdBlk *CmdPendingP; /* The command currently being sent */
struct RUP *RupP; /* the Rup to send it to */
struct RUP __iomem *RupP; /* the Rup to send it to */
unsigned int Id; /* Id number */
unsigned int BaseSysPort; /* SysPort of first tty on this RTA */
unsigned int ModTypes; /* Modules on this RTA */

View file

@ -1073,7 +1073,7 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot)
tasklet_init(&host->finish_tasklet,
sdhci_tasklet_finish, (unsigned long)host);
setup_timer(&host->timer, sdhci_timeout_timer, (int)host);
setup_timer(&host->timer, sdhci_timeout_timer, (long)host);
ret = request_irq(host->irq, sdhci_irq, SA_SHIRQ,
host->slot_descr, host);

View file

@ -78,7 +78,7 @@ config MTD_REDBOOT_DIRECTORY_BLOCK
option.
The option specifies which Flash sectors holds the RedBoot
partition table. A zero or positive value gives an absolete
partition table. A zero or positive value gives an absolute
erase block number. A negative value specifies a number of
sectors before the end of the device.
@ -103,7 +103,7 @@ config MTD_CMDLINE_PARTS
bool "Command line partition table parsing"
depends on MTD_PARTITIONS = "y"
---help---
Allow generic configuration of the MTD paritition tables via the kernel
Allow generic configuration of the MTD partition tables via the kernel
command line. Multiple flash resources are supported for hardware where
different kinds of flash memory are available.

View file

@ -30,7 +30,6 @@ config MTD_JEDECPROBE
config MTD_GEN_PROBE
tristate
select OBSOLETE_INTERMODULE
config MTD_CFI_ADV_OPTIONS
bool "Flash chip driver advanced configuration options"

View file

@ -3,13 +3,6 @@
#
# $Id: Makefile.common,v 1.5 2005/11/07 11:14:22 gleixner Exp $
# *** BIG UGLY NOTE ***
#
# The removal of get_module_symbol() and replacement with
# inter_module_register() et al has introduced a link order dependency
# here where previously there was none. We now have to ensure that
# the CFI command set drivers are linked before gen_probe.o
obj-$(CONFIG_MTD) += chipreg.o
obj-$(CONFIG_MTD_AMDSTD) += amd_flash.o
obj-$(CONFIG_MTD_CFI) += cfi_probe.o

View file

@ -97,7 +97,6 @@ struct amd_flash_private {
int interleave;
int numchips;
unsigned long chipshift;
// const char *im_name;
struct flchip chips[0];
};
@ -131,12 +130,6 @@ static struct mtd_chip_driver amd_flash_chipdrv = {
.module = THIS_MODULE
};
static const char im_name[] = "amd_flash";
static inline __u32 wide_read(struct map_info *map, __u32 addr)
{
if (map->buswidth == 1) {
@ -737,6 +730,7 @@ static struct mtd_info *amd_flash_probe(struct map_info *map)
offset += dev_size;
}
mtd->type = MTD_NORFLASH;
mtd->writesize = 1;
mtd->flags = MTD_CAP_NORFLASH;
mtd->name = map->name;
mtd->erase = amd_flash_erase;

View file

@ -331,13 +331,6 @@ read_pri_intelext(struct map_info *map, __u16 adr)
return extp;
}
/* This routine is made available to other mtd code via
* inter_module_register. It must only be accessed through
* inter_module_get which will bump the use count of this module. The
* addresses passed back in cfi are valid as long as the use count of
* this module is non-zero, i.e. between inter_module_get and
* inter_module_put. Keith Owens <kaos@ocs.com.au> 29 Oct 2000.
*/
struct mtd_info *cfi_cmdset_0001(struct map_info *map, int primary)
{
struct cfi_private *cfi = map->fldrv_priv;
@ -406,7 +399,7 @@ struct mtd_info *cfi_cmdset_0001(struct map_info *map, int primary)
for (i=0; i< cfi->numchips; i++) {
cfi->chips[i].word_write_time = 1<<cfi->cfiq->WordWriteTimeoutTyp;
cfi->chips[i].buffer_write_time = 1<<cfi->cfiq->BufWriteTimeoutTyp;
cfi->chips[i].erase_time = 1<<cfi->cfiq->BlockEraseTimeoutTyp;
cfi->chips[i].erase_time = 1000<<cfi->cfiq->BlockEraseTimeoutTyp;
cfi->chips[i].ref_point_counter = 0;
init_waitqueue_head(&(cfi->chips[i].wq));
}
@ -415,6 +408,11 @@ struct mtd_info *cfi_cmdset_0001(struct map_info *map, int primary)
return cfi_intelext_setup(mtd);
}
struct mtd_info *cfi_cmdset_0003(struct map_info *map, int primary) __attribute__((alias("cfi_cmdset_0001")));
struct mtd_info *cfi_cmdset_0200(struct map_info *map, int primary) __attribute__((alias("cfi_cmdset_0001")));
EXPORT_SYMBOL_GPL(cfi_cmdset_0001);
EXPORT_SYMBOL_GPL(cfi_cmdset_0003);
EXPORT_SYMBOL_GPL(cfi_cmdset_0200);
static struct mtd_info *cfi_intelext_setup(struct mtd_info *mtd)
{
@ -547,12 +545,12 @@ static int cfi_intelext_partition_fixup(struct mtd_info *mtd,
if (extp->MinorVersion >= '4') {
struct cfi_intelext_programming_regioninfo *prinfo;
prinfo = (struct cfi_intelext_programming_regioninfo *)&extp->extra[offs];
MTD_PROGREGION_SIZE(mtd) = cfi->interleave << prinfo->ProgRegShift;
mtd->writesize = cfi->interleave << prinfo->ProgRegShift;
MTD_PROGREGION_CTRLMODE_VALID(mtd) = cfi->interleave * prinfo->ControlValid;
MTD_PROGREGION_CTRLMODE_INVALID(mtd) = cfi->interleave * prinfo->ControlInvalid;
mtd->flags |= MTD_PROGRAM_REGIONS;
mtd->flags &= ~MTD_BIT_WRITEABLE;
printk(KERN_DEBUG "%s: program region size/ctrl_valid/ctrl_inval = %d/%d/%d\n",
map->name, MTD_PROGREGION_SIZE(mtd),
map->name, mtd->writesize,
MTD_PROGREGION_CTRLMODE_VALID(mtd),
MTD_PROGREGION_CTRLMODE_INVALID(mtd));
}
@ -896,26 +894,33 @@ static void __xipram xip_enable(struct map_info *map, struct flchip *chip,
/*
* When a delay is required for the flash operation to complete, the
* xip_udelay() function is polling for both the given timeout and pending
* (but still masked) hardware interrupts. Whenever there is an interrupt
* pending then the flash erase or write operation is suspended, array mode
* restored and interrupts unmasked. Task scheduling might also happen at that
* point. The CPU eventually returns from the interrupt or the call to
* schedule() and the suspended flash operation is resumed for the remaining
* of the delay period.
* xip_wait_for_operation() function is polling for both the given timeout
* and pending (but still masked) hardware interrupts. Whenever there is an
* interrupt pending then the flash erase or write operation is suspended,
* array mode restored and interrupts unmasked. Task scheduling might also
* happen at that point. The CPU eventually returns from the interrupt or
* the call to schedule() and the suspended flash operation is resumed for
* the remaining of the delay period.
*
* Warning: this function _will_ fool interrupt latency tracing tools.
*/
static void __xipram xip_udelay(struct map_info *map, struct flchip *chip,
unsigned long adr, int usec)
static int __xipram xip_wait_for_operation(
struct map_info *map, struct flchip *chip,
unsigned long adr, int *chip_op_time )
{
struct cfi_private *cfi = map->fldrv_priv;
struct cfi_pri_intelext *cfip = cfi->cmdset_priv;
map_word status, OK = CMD(0x80);
unsigned long suspended, start = xip_currtime();
unsigned long usec, suspended, start, done;
flstate_t oldstate, newstate;
start = xip_currtime();
usec = *chip_op_time * 8;
if (usec == 0)
usec = 500000;
done = 0;
do {
cpu_relax();
if (xip_irqpending() && cfip &&
@ -932,9 +937,9 @@ static void __xipram xip_udelay(struct map_info *map, struct flchip *chip,
* we resume the whole thing at once). Yes, it
* can happen!
*/
usec -= done;
map_write(map, CMD(0xb0), adr);
map_write(map, CMD(0x70), adr);
usec -= xip_elapsed_since(start);
suspended = xip_currtime();
do {
if (xip_elapsed_since(suspended) > 100000) {
@ -944,7 +949,7 @@ static void __xipram xip_udelay(struct map_info *map, struct flchip *chip,
* This is a critical error but there
* is not much we can do here.
*/
return;
return -EIO;
}
status = map_read(map, adr);
} while (!map_word_andequal(map, status, OK, OK));
@ -1004,65 +1009,107 @@ static void __xipram xip_udelay(struct map_info *map, struct flchip *chip,
xip_cpu_idle();
}
status = map_read(map, adr);
done = xip_elapsed_since(start);
} while (!map_word_andequal(map, status, OK, OK)
&& xip_elapsed_since(start) < usec);
}
&& done < usec);
#define UDELAY(map, chip, adr, usec) xip_udelay(map, chip, adr, usec)
return (done >= usec) ? -ETIME : 0;
}
/*
* The INVALIDATE_CACHED_RANGE() macro is normally used in parallel while
* the flash is actively programming or erasing since we have to poll for
* the operation to complete anyway. We can't do that in a generic way with
* a XIP setup so do it before the actual flash operation in this case
* and stub it out from INVALIDATE_CACHE_UDELAY.
* and stub it out from INVAL_CACHE_AND_WAIT.
*/
#define XIP_INVAL_CACHED_RANGE(map, from, size) \
INVALIDATE_CACHED_RANGE(map, from, size)
#define INVALIDATE_CACHE_UDELAY(map, chip, cmd_adr, adr, len, usec) \
UDELAY(map, chip, cmd_adr, usec)
/*
* Extra notes:
*
* Activating this XIP support changes the way the code works a bit. For
* example the code to suspend the current process when concurrent access
* happens is never executed because xip_udelay() will always return with the
* same chip state as it was entered with. This is why there is no care for
* the presence of add_wait_queue() or schedule() calls from within a couple
* xip_disable()'d areas of code, like in do_erase_oneblock for example.
* The queueing and scheduling are always happening within xip_udelay().
*
* Similarly, get_chip() and put_chip() just happen to always be executed
* with chip->state set to FL_READY (or FL_XIP_WHILE_*) where flash state
* is in array mode, therefore never executing many cases therein and not
* causing any problem with XIP.
*/
#define INVAL_CACHE_AND_WAIT(map, chip, cmd_adr, inval_adr, inval_len, p_usec) \
xip_wait_for_operation(map, chip, cmd_adr, p_usec)
#else
#define xip_disable(map, chip, adr)
#define xip_enable(map, chip, adr)
#define XIP_INVAL_CACHED_RANGE(x...)
#define INVAL_CACHE_AND_WAIT inval_cache_and_wait_for_operation
#define UDELAY(map, chip, adr, usec) \
do { \
spin_unlock(chip->mutex); \
cfi_udelay(usec); \
spin_lock(chip->mutex); \
} while (0)
static int inval_cache_and_wait_for_operation(
struct map_info *map, struct flchip *chip,
unsigned long cmd_adr, unsigned long inval_adr, int inval_len,
int *chip_op_time )
{
struct cfi_private *cfi = map->fldrv_priv;
map_word status, status_OK = CMD(0x80);
int z, chip_state = chip->state;
unsigned long timeo;
#define INVALIDATE_CACHE_UDELAY(map, chip, cmd_adr, adr, len, usec) \
do { \
spin_unlock(chip->mutex); \
INVALIDATE_CACHED_RANGE(map, adr, len); \
cfi_udelay(usec); \
spin_lock(chip->mutex); \
} while (0)
spin_unlock(chip->mutex);
if (inval_len)
INVALIDATE_CACHED_RANGE(map, inval_adr, inval_len);
if (*chip_op_time)
cfi_udelay(*chip_op_time);
spin_lock(chip->mutex);
timeo = *chip_op_time * 8 * HZ / 1000000;
if (timeo < HZ/2)
timeo = HZ/2;
timeo += jiffies;
z = 0;
for (;;) {
if (chip->state != chip_state) {
/* Someone's suspended the operation: sleep */
DECLARE_WAITQUEUE(wait, current);
set_current_state(TASK_UNINTERRUPTIBLE);
add_wait_queue(&chip->wq, &wait);
spin_unlock(chip->mutex);
schedule();
remove_wait_queue(&chip->wq, &wait);
timeo = jiffies + (HZ / 2); /* FIXME */
spin_lock(chip->mutex);
continue;
}
status = map_read(map, cmd_adr);
if (map_word_andequal(map, status, status_OK, status_OK))
break;
/* OK Still waiting */
if (time_after(jiffies, timeo)) {
map_write(map, CMD(0x70), cmd_adr);
chip->state = FL_STATUS;
return -ETIME;
}
/* Latency issues. Drop the lock, wait a while and retry */
z++;
spin_unlock(chip->mutex);
cfi_udelay(1);
spin_lock(chip->mutex);
}
if (!z) {
if (!--(*chip_op_time))
*chip_op_time = 1;
} else if (z > 1)
++(*chip_op_time);
/* Done and happy. */
chip->state = FL_STATUS;
return 0;
}
#endif
#define WAIT_TIMEOUT(map, chip, adr, udelay) \
({ int __udelay = (udelay); \
INVAL_CACHE_AND_WAIT(map, chip, adr, 0, 0, &__udelay); })
static int do_point_onechip (struct map_info *map, struct flchip *chip, loff_t adr, size_t len)
{
unsigned long cmd_addr;
@ -1252,14 +1299,11 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip,
unsigned long adr, map_word datum, int mode)
{
struct cfi_private *cfi = map->fldrv_priv;
map_word status, status_OK, write_cmd;
unsigned long timeo;
int z, ret=0;
map_word status, write_cmd;
int ret=0;
adr += chip->start;
/* Let's determine those according to the interleave only once */
status_OK = CMD(0x80);
switch (mode) {
case FL_WRITING:
write_cmd = (cfi->cfiq->P_ID != 0x0200) ? CMD(0x40) : CMD(0x41);
@ -1285,57 +1329,17 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip,
map_write(map, datum, adr);
chip->state = mode;
INVALIDATE_CACHE_UDELAY(map, chip, adr,
adr, map_bankwidth(map),
chip->word_write_time);
timeo = jiffies + (HZ/2);
z = 0;
for (;;) {
if (chip->state != mode) {
/* Someone's suspended the write. Sleep */
DECLARE_WAITQUEUE(wait, current);
set_current_state(TASK_UNINTERRUPTIBLE);
add_wait_queue(&chip->wq, &wait);
spin_unlock(chip->mutex);
schedule();
remove_wait_queue(&chip->wq, &wait);
timeo = jiffies + (HZ / 2); /* FIXME */
spin_lock(chip->mutex);
continue;
}
status = map_read(map, adr);
if (map_word_andequal(map, status, status_OK, status_OK))
break;
/* OK Still waiting */
if (time_after(jiffies, timeo)) {
map_write(map, CMD(0x70), adr);
chip->state = FL_STATUS;
xip_enable(map, chip, adr);
printk(KERN_ERR "%s: word write error (status timeout)\n", map->name);
ret = -EIO;
goto out;
}
/* Latency issues. Drop the lock, wait a while and retry */
z++;
UDELAY(map, chip, adr, 1);
ret = INVAL_CACHE_AND_WAIT(map, chip, adr,
adr, map_bankwidth(map),
&chip->word_write_time);
if (ret) {
xip_enable(map, chip, adr);
printk(KERN_ERR "%s: word write error (status timeout)\n", map->name);
goto out;
}
if (!z) {
chip->word_write_time--;
if (!chip->word_write_time)
chip->word_write_time = 1;
}
if (z > 1)
chip->word_write_time++;
/* Done and happy. */
chip->state = FL_STATUS;
/* check for errors */
status = map_read(map, adr);
if (map_word_bitsset(map, status, CMD(0x1a))) {
unsigned long chipstatus = MERGESTATUS(status);
@ -1452,9 +1456,9 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
unsigned long *pvec_seek, int len)
{
struct cfi_private *cfi = map->fldrv_priv;
map_word status, status_OK, write_cmd, datum;
unsigned long cmd_adr, timeo;
int wbufsize, z, ret=0, word_gap, words;
map_word status, write_cmd, datum;
unsigned long cmd_adr;
int ret, wbufsize, word_gap, words;
const struct kvec *vec;
unsigned long vec_seek;
@ -1463,7 +1467,6 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
cmd_adr = adr & ~(wbufsize-1);
/* Let's determine this according to the interleave only once */
status_OK = CMD(0x80);
write_cmd = (cfi->cfiq->P_ID != 0x0200) ? CMD(0xe8) : CMD(0xe9);
spin_lock(chip->mutex);
@ -1477,12 +1480,14 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
ENABLE_VPP(map);
xip_disable(map, chip, cmd_adr);
/* §4.8 of the 28FxxxJ3A datasheet says "Any time SR.4 and/or SR.5 is set
/* §4.8 of the 28FxxxJ3A datasheet says "Any time SR.4 and/or SR.5 is set
[...], the device will not accept any more Write to Buffer commands".
So we must check here and reset those bits if they're set. Otherwise
we're just pissing in the wind */
if (chip->state != FL_STATUS)
if (chip->state != FL_STATUS) {
map_write(map, CMD(0x70), cmd_adr);
chip->state = FL_STATUS;
}
status = map_read(map, cmd_adr);
if (map_word_bitsset(map, status, CMD(0x30))) {
xip_enable(map, chip, cmd_adr);
@ -1493,32 +1498,20 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
}
chip->state = FL_WRITING_TO_BUFFER;
z = 0;
for (;;) {
map_write(map, write_cmd, cmd_adr);
map_write(map, write_cmd, cmd_adr);
ret = WAIT_TIMEOUT(map, chip, cmd_adr, 0);
if (ret) {
/* Argh. Not ready for write to buffer */
map_word Xstatus = map_read(map, cmd_adr);
map_write(map, CMD(0x70), cmd_adr);
chip->state = FL_STATUS;
status = map_read(map, cmd_adr);
if (map_word_andequal(map, status, status_OK, status_OK))
break;
UDELAY(map, chip, cmd_adr, 1);
if (++z > 20) {
/* Argh. Not ready for write to buffer */
map_word Xstatus;
map_write(map, CMD(0x70), cmd_adr);
chip->state = FL_STATUS;
Xstatus = map_read(map, cmd_adr);
/* Odd. Clear status bits */
map_write(map, CMD(0x50), cmd_adr);
map_write(map, CMD(0x70), cmd_adr);
xip_enable(map, chip, cmd_adr);
printk(KERN_ERR "%s: Chip not ready for buffer write. status = %lx, Xstatus = %lx\n",
map->name, status.x[0], Xstatus.x[0]);
ret = -EIO;
goto out;
}
map_write(map, CMD(0x50), cmd_adr);
map_write(map, CMD(0x70), cmd_adr);
xip_enable(map, chip, cmd_adr);
printk(KERN_ERR "%s: Chip not ready for buffer write. Xstatus = %lx, status = %lx\n",
map->name, Xstatus.x[0], status.x[0]);
goto out;
}
/* Figure out the number of words to write */
@ -1573,56 +1566,19 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
map_write(map, CMD(0xd0), cmd_adr);
chip->state = FL_WRITING;
INVALIDATE_CACHE_UDELAY(map, chip, cmd_adr,
adr, len,
chip->buffer_write_time);
timeo = jiffies + (HZ/2);
z = 0;
for (;;) {
if (chip->state != FL_WRITING) {
/* Someone's suspended the write. Sleep */
DECLARE_WAITQUEUE(wait, current);
set_current_state(TASK_UNINTERRUPTIBLE);
add_wait_queue(&chip->wq, &wait);
spin_unlock(chip->mutex);
schedule();
remove_wait_queue(&chip->wq, &wait);
timeo = jiffies + (HZ / 2); /* FIXME */
spin_lock(chip->mutex);
continue;
}
status = map_read(map, cmd_adr);
if (map_word_andequal(map, status, status_OK, status_OK))
break;
/* OK Still waiting */
if (time_after(jiffies, timeo)) {
map_write(map, CMD(0x70), cmd_adr);
chip->state = FL_STATUS;
xip_enable(map, chip, cmd_adr);
printk(KERN_ERR "%s: buffer write error (status timeout)\n", map->name);
ret = -EIO;
goto out;
}
/* Latency issues. Drop the lock, wait a while and retry */
z++;
UDELAY(map, chip, cmd_adr, 1);
ret = INVAL_CACHE_AND_WAIT(map, chip, cmd_adr,
adr, len,
&chip->buffer_write_time);
if (ret) {
map_write(map, CMD(0x70), cmd_adr);
chip->state = FL_STATUS;
xip_enable(map, chip, cmd_adr);
printk(KERN_ERR "%s: buffer write error (status timeout)\n", map->name);
goto out;
}
if (!z) {
chip->buffer_write_time--;
if (!chip->buffer_write_time)
chip->buffer_write_time = 1;
}
if (z > 1)
chip->buffer_write_time++;
/* Done and happy. */
chip->state = FL_STATUS;
/* check for errors */
status = map_read(map, cmd_adr);
if (map_word_bitsset(map, status, CMD(0x1a))) {
unsigned long chipstatus = MERGESTATUS(status);
@ -1693,6 +1649,11 @@ static int cfi_intelext_writev (struct mtd_info *mtd, const struct kvec *vecs,
if (chipnum == cfi->numchips)
return 0;
}
/* Be nice and reschedule with the chip in a usable state for other
processes. */
cond_resched();
} while (len);
return 0;
@ -1713,17 +1674,12 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
unsigned long adr, int len, void *thunk)
{
struct cfi_private *cfi = map->fldrv_priv;
map_word status, status_OK;
unsigned long timeo;
map_word status;
int retries = 3;
DECLARE_WAITQUEUE(wait, current);
int ret = 0;
int ret;
adr += chip->start;
/* Let's determine this according to the interleave only once */
status_OK = CMD(0x80);
retry:
spin_lock(chip->mutex);
ret = get_chip(map, chip, adr, FL_ERASING);
@ -1745,48 +1701,15 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
chip->state = FL_ERASING;
chip->erase_suspended = 0;
INVALIDATE_CACHE_UDELAY(map, chip, adr,
adr, len,
chip->erase_time*1000/2);
/* FIXME. Use a timer to check this, and return immediately. */
/* Once the state machine's known to be working I'll do that */
timeo = jiffies + (HZ*20);
for (;;) {
if (chip->state != FL_ERASING) {
/* Someone's suspended the erase. Sleep */
set_current_state(TASK_UNINTERRUPTIBLE);
add_wait_queue(&chip->wq, &wait);
spin_unlock(chip->mutex);
schedule();
remove_wait_queue(&chip->wq, &wait);
spin_lock(chip->mutex);
continue;
}
if (chip->erase_suspended) {
/* This erase was suspended and resumed.
Adjust the timeout */
timeo = jiffies + (HZ*20); /* FIXME */
chip->erase_suspended = 0;
}
status = map_read(map, adr);
if (map_word_andequal(map, status, status_OK, status_OK))
break;
/* OK Still waiting */
if (time_after(jiffies, timeo)) {
map_write(map, CMD(0x70), adr);
chip->state = FL_STATUS;
xip_enable(map, chip, adr);
printk(KERN_ERR "%s: block erase error: (status timeout)\n", map->name);
ret = -EIO;
goto out;
}
/* Latency issues. Drop the lock, wait a while and retry */
UDELAY(map, chip, adr, 1000000/HZ);
ret = INVAL_CACHE_AND_WAIT(map, chip, adr,
adr, len,
&chip->erase_time);
if (ret) {
map_write(map, CMD(0x70), adr);
chip->state = FL_STATUS;
xip_enable(map, chip, adr);
printk(KERN_ERR "%s: block erase error: (status timeout)\n", map->name);
goto out;
}
/* We've broken this before. It doesn't hurt to be safe */
@ -1815,7 +1738,6 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
ret = -EIO;
} else if (chipstatus & 0x20 && retries--) {
printk(KERN_DEBUG "block erase failed at 0x%08lx: status 0x%lx. Retrying...\n", adr, chipstatus);
timeo = jiffies + HZ;
put_chip(map, chip, adr);
spin_unlock(chip->mutex);
goto retry;
@ -1921,15 +1843,11 @@ static int __xipram do_xxlock_oneblock(struct map_info *map, struct flchip *chip
{
struct cfi_private *cfi = map->fldrv_priv;
struct cfi_pri_intelext *extp = cfi->cmdset_priv;
map_word status, status_OK;
unsigned long timeo = jiffies + HZ;
int udelay;
int ret;
adr += chip->start;
/* Let's determine this according to the interleave only once */
status_OK = CMD(0x80);
spin_lock(chip->mutex);
ret = get_chip(map, chip, adr, FL_LOCKING);
if (ret) {
@ -1954,41 +1872,21 @@ static int __xipram do_xxlock_oneblock(struct map_info *map, struct flchip *chip
* If Instant Individual Block Locking supported then no need
* to delay.
*/
udelay = (!extp || !(extp->FeatureSupport & (1 << 5))) ? 1000000/HZ : 0;
if (!extp || !(extp->FeatureSupport & (1 << 5)))
UDELAY(map, chip, adr, 1000000/HZ);
/* FIXME. Use a timer to check this, and return immediately. */
/* Once the state machine's known to be working I'll do that */
timeo = jiffies + (HZ*20);
for (;;) {
status = map_read(map, adr);
if (map_word_andequal(map, status, status_OK, status_OK))
break;
/* OK Still waiting */
if (time_after(jiffies, timeo)) {
map_write(map, CMD(0x70), adr);
chip->state = FL_STATUS;
xip_enable(map, chip, adr);
printk(KERN_ERR "%s: block unlock error: (status timeout)\n", map->name);
put_chip(map, chip, adr);
spin_unlock(chip->mutex);
return -EIO;
}
/* Latency issues. Drop the lock, wait a while and retry */
UDELAY(map, chip, adr, 1);
ret = WAIT_TIMEOUT(map, chip, adr, udelay);
if (ret) {
map_write(map, CMD(0x70), adr);
chip->state = FL_STATUS;
xip_enable(map, chip, adr);
printk(KERN_ERR "%s: block unlock error: (status timeout)\n", map->name);
goto out;
}
/* Done and happy. */
chip->state = FL_STATUS;
xip_enable(map, chip, adr);
put_chip(map, chip, adr);
out: put_chip(map, chip, adr);
spin_unlock(chip->mutex);
return 0;
return ret;
}
static int cfi_intelext_lock(struct mtd_info *mtd, loff_t ofs, size_t len)
@ -2445,28 +2343,8 @@ static void cfi_intelext_destroy(struct mtd_info *mtd)
kfree(mtd->eraseregions);
}
static char im_name_0001[] = "cfi_cmdset_0001";
static char im_name_0003[] = "cfi_cmdset_0003";
static char im_name_0200[] = "cfi_cmdset_0200";
static int __init cfi_intelext_init(void)
{
inter_module_register(im_name_0001, THIS_MODULE, &cfi_cmdset_0001);
inter_module_register(im_name_0003, THIS_MODULE, &cfi_cmdset_0001);
inter_module_register(im_name_0200, THIS_MODULE, &cfi_cmdset_0001);
return 0;
}
static void __exit cfi_intelext_exit(void)
{
inter_module_unregister(im_name_0001);
inter_module_unregister(im_name_0003);
inter_module_unregister(im_name_0200);
}
module_init(cfi_intelext_init);
module_exit(cfi_intelext_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org> et al.");
MODULE_DESCRIPTION("MTD chip driver for Intel/Sharp flash chips");
MODULE_ALIAS("cfi_cmdset_0003");
MODULE_ALIAS("cfi_cmdset_0200");

View file

@ -236,6 +236,7 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
mtd->resume = cfi_amdstd_resume;
mtd->flags = MTD_CAP_NORFLASH;
mtd->name = map->name;
mtd->writesize = 1;
if (cfi->cfi_mode==CFI_MODE_CFI){
unsigned char bootloc;
@ -326,7 +327,7 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
return cfi_amdstd_setup(mtd);
}
EXPORT_SYMBOL_GPL(cfi_cmdset_0002);
static struct mtd_info *cfi_amdstd_setup(struct mtd_info *mtd)
{
@ -1758,25 +1759,6 @@ static void cfi_amdstd_destroy(struct mtd_info *mtd)
kfree(mtd->eraseregions);
}
static char im_name[]="cfi_cmdset_0002";
static int __init cfi_amdstd_init(void)
{
inter_module_register(im_name, THIS_MODULE, &cfi_cmdset_0002);
return 0;
}
static void __exit cfi_amdstd_exit(void)
{
inter_module_unregister(im_name);
}
module_init(cfi_amdstd_init);
module_exit(cfi_amdstd_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Crossnet Co. <info@crossnet.co.jp> et al.");
MODULE_DESCRIPTION("MTD chip driver for AMD/Fujitsu flash chips");

View file

@ -162,6 +162,7 @@ struct mtd_info *cfi_cmdset_0020(struct map_info *map, int primary)
return cfi_staa_setup(map);
}
EXPORT_SYMBOL_GPL(cfi_cmdset_0020);
static struct mtd_info *cfi_staa_setup(struct map_info *map)
{
@ -237,9 +238,8 @@ static struct mtd_info *cfi_staa_setup(struct map_info *map)
mtd->unlock = cfi_staa_unlock;
mtd->suspend = cfi_staa_suspend;
mtd->resume = cfi_staa_resume;
mtd->flags = MTD_CAP_NORFLASH;
mtd->flags |= MTD_ECC; /* FIXME: Not all STMicro flashes have this */
mtd->eccsize = 8; /* FIXME: Should be 0 for STMicro flashes w/out ECC */
mtd->flags = MTD_CAP_NORFLASH & ~MTD_BIT_WRITEABLE;
mtd->writesize = 8; /* FIXME: Should be 0 for STMicro flashes w/out ECC */
map->fldrv = &cfi_staa_chipdrv;
__module_get(THIS_MODULE);
mtd->name = map->name;
@ -1410,20 +1410,4 @@ static void cfi_staa_destroy(struct mtd_info *mtd)
kfree(cfi);
}
static char im_name[]="cfi_cmdset_0020";
static int __init cfi_staa_init(void)
{
inter_module_register(im_name, THIS_MODULE, &cfi_cmdset_0020);
return 0;
}
static void __exit cfi_staa_exit(void)
{
inter_module_unregister(im_name);
}
module_init(cfi_staa_init);
module_exit(cfi_staa_exit);
MODULE_LICENSE("GPL");

View file

@ -349,12 +349,12 @@ static void print_cfi_ident(struct cfi_ident *cfip)
else
printk("No Vpp line\n");
printk("Typical byte/word write timeout: %d µs\n", 1<<cfip->WordWriteTimeoutTyp);
printk("Maximum byte/word write timeout: %d µs\n", (1<<cfip->WordWriteTimeoutMax) * (1<<cfip->WordWriteTimeoutTyp));
printk("Typical byte/word write timeout: %d µs\n", 1<<cfip->WordWriteTimeoutTyp);
printk("Maximum byte/word write timeout: %d µs\n", (1<<cfip->WordWriteTimeoutMax) * (1<<cfip->WordWriteTimeoutTyp));
if (cfip->BufWriteTimeoutTyp || cfip->BufWriteTimeoutMax) {
printk("Typical full buffer write timeout: %d µs\n", 1<<cfip->BufWriteTimeoutTyp);
printk("Maximum full buffer write timeout: %d µs\n", (1<<cfip->BufWriteTimeoutMax) * (1<<cfip->BufWriteTimeoutTyp));
printk("Typical full buffer write timeout: %d µs\n", 1<<cfip->BufWriteTimeoutTyp);
printk("Maximum full buffer write timeout: %d µs\n", (1<<cfip->BufWriteTimeoutMax) * (1<<cfip->BufWriteTimeoutTyp));
}
else
printk("Full buffer write not supported\n");

View file

@ -37,8 +37,15 @@ struct mtd_info *mtd_do_chip_probe(struct map_info *map, struct chip_probe *cp)
if (!mtd)
mtd = check_cmd_set(map, 0); /* Then the secondary */
if (mtd)
if (mtd) {
if (mtd->size > map->size) {
printk(KERN_WARNING "Reducing visibility of %ldKiB chip to %ldKiB\n",
(unsigned long)mtd->size >> 10,
(unsigned long)map->size >> 10);
mtd->size = map->size;
}
return mtd;
}
printk(KERN_WARNING"gen_probe: No supported Vendor Command Set found\n");
@ -100,7 +107,12 @@ static struct cfi_private *genprobe_ident_chips(struct map_info *map, struct chi
* Align bitmap storage size to full byte.
*/
max_chips = map->size >> cfi.chipshift;
mapsize = (max_chips / 8) + ((max_chips % 8) ? 1 : 0);
if (!max_chips) {
printk(KERN_WARNING "NOR chip too large to fit in mapping. Attempting to cope...\n");
max_chips = 1;
}
mapsize = (max_chips + BITS_PER_LONG-1) / BITS_PER_LONG;
chip_map = kmalloc(mapsize, GFP_KERNEL);
if (!chip_map) {
printk(KERN_WARNING "%s: kmalloc failed for CFI chip map\n", map->name);
@ -194,25 +206,28 @@ static inline struct mtd_info *cfi_cmdset_unknown(struct map_info *map,
{
struct cfi_private *cfi = map->fldrv_priv;
__u16 type = primary?cfi->cfiq->P_ID:cfi->cfiq->A_ID;
#if defined(CONFIG_MODULES) && defined(HAVE_INTER_MODULE)
char probename[32];
#ifdef CONFIG_MODULES
char probename[16+sizeof(MODULE_SYMBOL_PREFIX)];
cfi_cmdset_fn_t *probe_function;
sprintf(probename, "cfi_cmdset_%4.4X", type);
sprintf(probename, MODULE_SYMBOL_PREFIX "cfi_cmdset_%4.4X", type);
probe_function = inter_module_get_request(probename, probename);
probe_function = __symbol_get(probename);
if (!probe_function) {
request_module(probename + sizeof(MODULE_SYMBOL_PREFIX) - 1);
probe_function = __symbol_get(probename);
}
if (probe_function) {
struct mtd_info *mtd;
mtd = (*probe_function)(map, primary);
/* If it was happy, it'll have increased its own use count */
inter_module_put(probename);
symbol_put_addr(probe_function);
return mtd;
}
#endif
printk(KERN_NOTICE "Support for command set %04X not present\n",
type);
printk(KERN_NOTICE "Support for command set %04X not present\n", type);
return NULL;
}
@ -226,12 +241,8 @@ static struct mtd_info *check_cmd_set(struct map_info *map, int primary)
return NULL;
switch(type){
/* Urgh. Ifdefs. The version with weak symbols was
* _much_ nicer. Shame it didn't seem to work on
* anything but x86, really.
* But we can't rely in inter_module_get() because
* that'd mean we depend on link order.
*/
/* We need these for the !CONFIG_MODULES case,
because symbol_get() doesn't work there */
#ifdef CONFIG_MTD_CFI_INTELEXT
case 0x0001:
case 0x0003:
@ -246,9 +257,9 @@ static struct mtd_info *check_cmd_set(struct map_info *map, int primary)
case 0x0020:
return cfi_cmdset_0020(map, primary);
#endif
default:
return cfi_cmdset_unknown(map, primary);
}
return cfi_cmdset_unknown(map, primary);
}
MODULE_LICENSE("GPL");

View file

@ -70,7 +70,7 @@ static struct mtd_info *map_ram_probe(struct map_info *map)
mtd->read = mapram_read;
mtd->write = mapram_write;
mtd->sync = mapram_nop;
mtd->flags = MTD_CAP_RAM | MTD_VOLATILE;
mtd->flags = MTD_CAP_RAM;
mtd->erasesize = PAGE_SIZE;
while(mtd->size & (mtd->erasesize - 1))

View file

@ -46,9 +46,7 @@ static struct mtd_info *map_rom_probe(struct map_info *map)
mtd->write = maprom_write;
mtd->sync = maprom_nop;
mtd->flags = MTD_CAP_ROM;
mtd->erasesize = 131072;
while(mtd->size & (mtd->erasesize - 1))
mtd->erasesize >>= 1;
mtd->erasesize = map->size;
__module_get(THIS_MODULE);
return mtd;

View file

@ -140,6 +140,7 @@ static struct mtd_info *sharp_probe(struct map_info *map)
mtd->suspend = sharp_suspend;
mtd->resume = sharp_resume;
mtd->flags = MTD_CAP_NORFLASH;
mtd->writesize = 1;
mtd->name = map->name;
memset(sharp, 0, sizeof(*sharp));

View file

@ -47,6 +47,11 @@ config MTD_MS02NV
accelerator. Say Y here if you have a DECstation 5000/2x0 or a
DECsystem 5900 equipped with such a module.
If you want to compile this driver as a module ( = code which can be
inserted in and removed from the running kernel whenever you want),
say M here and read <file:Documentation/modules.txt>. The module will
be called ms02-nv.o.
config MTD_DATAFLASH
tristate "Support for AT45xxx DataFlash"
depends on MTD && SPI_MASTER && EXPERIMENTAL
@ -209,7 +214,6 @@ config MTD_DOC2001PLUS
config MTD_DOCPROBE
tristate
select MTD_DOCECC
select OBSOLETE_INTERMODULE
config MTD_DOCECC
tristate

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