mirror of
https://github.com/torvalds/linux.git
synced 2024-11-15 16:41:58 +00:00
Merge /spare/repo/linux-2.6/
This commit is contained in:
commit
142e27fc8a
@ -96,7 +96,7 @@
|
||||
|
||||
<chapter id="pubfunctions">
|
||||
<title>Public Functions Provided</title>
|
||||
!Earch/i386/kernel/mca.c
|
||||
!Edrivers/mca/mca-legacy.c
|
||||
</chapter>
|
||||
|
||||
<chapter id="dmafunctions">
|
||||
|
@ -605,12 +605,13 @@ is in the ipmi_poweroff module. When the system requests a powerdown,
|
||||
it will send the proper IPMI commands to do this. This is supported on
|
||||
several platforms.
|
||||
|
||||
There is a module parameter named "poweroff_control" that may either be zero
|
||||
(do a power down) or 2 (do a power cycle, power the system off, then power
|
||||
it on in a few seconds). Setting ipmi_poweroff.poweroff_control=x will do
|
||||
the same thing on the kernel command line. The parameter is also available
|
||||
via the proc filesystem in /proc/ipmi/poweroff_control. Note that if the
|
||||
system does not support power cycling, it will always to the power off.
|
||||
There is a module parameter named "poweroff_powercycle" that may
|
||||
either be zero (do a power down) or non-zero (do a power cycle, power
|
||||
the system off, then power it on in a few seconds). Setting
|
||||
ipmi_poweroff.poweroff_control=x will do the same thing on the kernel
|
||||
command line. The parameter is also available via the proc filesystem
|
||||
in /proc/sys/dev/ipmi/poweroff_powercycle. Note that if the system
|
||||
does not support power cycling, it will always do the power off.
|
||||
|
||||
Note that if you have ACPI enabled, the system will prefer using ACPI to
|
||||
power off.
|
||||
|
112
Documentation/RCU/NMI-RCU.txt
Normal file
112
Documentation/RCU/NMI-RCU.txt
Normal file
@ -0,0 +1,112 @@
|
||||
Using RCU to Protect Dynamic NMI Handlers
|
||||
|
||||
|
||||
Although RCU is usually used to protect read-mostly data structures,
|
||||
it is possible to use RCU to provide dynamic non-maskable interrupt
|
||||
handlers, as well as dynamic irq handlers. This document describes
|
||||
how to do this, drawing loosely from Zwane Mwaikambo's NMI-timer
|
||||
work in "arch/i386/oprofile/nmi_timer_int.c" and in
|
||||
"arch/i386/kernel/traps.c".
|
||||
|
||||
The relevant pieces of code are listed below, each followed by a
|
||||
brief explanation.
|
||||
|
||||
static int dummy_nmi_callback(struct pt_regs *regs, int cpu)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
The dummy_nmi_callback() function is a "dummy" NMI handler that does
|
||||
nothing, but returns zero, thus saying that it did nothing, allowing
|
||||
the NMI handler to take the default machine-specific action.
|
||||
|
||||
static nmi_callback_t nmi_callback = dummy_nmi_callback;
|
||||
|
||||
This nmi_callback variable is a global function pointer to the current
|
||||
NMI handler.
|
||||
|
||||
fastcall void do_nmi(struct pt_regs * regs, long error_code)
|
||||
{
|
||||
int cpu;
|
||||
|
||||
nmi_enter();
|
||||
|
||||
cpu = smp_processor_id();
|
||||
++nmi_count(cpu);
|
||||
|
||||
if (!rcu_dereference(nmi_callback)(regs, cpu))
|
||||
default_do_nmi(regs);
|
||||
|
||||
nmi_exit();
|
||||
}
|
||||
|
||||
The do_nmi() function processes each NMI. It first disables preemption
|
||||
in the same way that a hardware irq would, then increments the per-CPU
|
||||
count of NMIs. It then invokes the NMI handler stored in the nmi_callback
|
||||
function pointer. If this handler returns zero, do_nmi() invokes the
|
||||
default_do_nmi() function to handle a machine-specific NMI. Finally,
|
||||
preemption is restored.
|
||||
|
||||
Strictly speaking, rcu_dereference() is not needed, since this code runs
|
||||
only on i386, which does not need rcu_dereference() anyway. However,
|
||||
it is a good documentation aid, particularly for anyone attempting to
|
||||
do something similar on Alpha.
|
||||
|
||||
Quick Quiz: Why might the rcu_dereference() be necessary on Alpha,
|
||||
given that the code referenced by the pointer is read-only?
|
||||
|
||||
|
||||
Back to the discussion of NMI and RCU...
|
||||
|
||||
void set_nmi_callback(nmi_callback_t callback)
|
||||
{
|
||||
rcu_assign_pointer(nmi_callback, callback);
|
||||
}
|
||||
|
||||
The set_nmi_callback() function registers an NMI handler. Note that any
|
||||
data that is to be used by the callback must be initialized up -before-
|
||||
the call to set_nmi_callback(). On architectures that do not order
|
||||
writes, the rcu_assign_pointer() ensures that the NMI handler sees the
|
||||
initialized values.
|
||||
|
||||
void unset_nmi_callback(void)
|
||||
{
|
||||
rcu_assign_pointer(nmi_callback, dummy_nmi_callback);
|
||||
}
|
||||
|
||||
This function unregisters an NMI handler, restoring the original
|
||||
dummy_nmi_handler(). However, there may well be an NMI handler
|
||||
currently executing on some other CPU. We therefore cannot free
|
||||
up any data structures used by the old NMI handler until execution
|
||||
of it completes on all other CPUs.
|
||||
|
||||
One way to accomplish this is via synchronize_sched(), perhaps as
|
||||
follows:
|
||||
|
||||
unset_nmi_callback();
|
||||
synchronize_sched();
|
||||
kfree(my_nmi_data);
|
||||
|
||||
This works because synchronize_sched() blocks until all CPUs complete
|
||||
any preemption-disabled segments of code that they were executing.
|
||||
Since NMI handlers disable preemption, synchronize_sched() is guaranteed
|
||||
not to return until all ongoing NMI handlers exit. It is therefore safe
|
||||
to free up the handler's data as soon as synchronize_sched() returns.
|
||||
|
||||
|
||||
Answer to Quick Quiz
|
||||
|
||||
Why might the rcu_dereference() be necessary on Alpha, given
|
||||
that the code referenced by the pointer is read-only?
|
||||
|
||||
Answer: The caller to set_nmi_callback() might well have
|
||||
initialized some data that is to be used by the
|
||||
new NMI handler. In this case, the rcu_dereference()
|
||||
would be needed, because otherwise a CPU that received
|
||||
an NMI just after the new handler was set might see
|
||||
the pointer to the new NMI handler, but the old
|
||||
pre-initialized version of the handler's data.
|
||||
|
||||
More important, the rcu_dereference() makes it clear
|
||||
to someone reading the code that the pointer is being
|
||||
protected by RCU.
|
@ -68,7 +68,8 @@ it a better device citizen. Further thanks to Joel Katz
|
||||
Porfiri Claudio <C.Porfiri@nisms.tei.ericsson.se> for patches
|
||||
to make the driver work with the older CDU-510/515 series, and
|
||||
Heiko Eissfeldt <heiko@colossus.escape.de> for pointing out that
|
||||
the verify_area() checks were ignoring the results of said checks.
|
||||
the verify_area() checks were ignoring the results of said checks
|
||||
(note: verify_area() has since been replaced by access_ok()).
|
||||
|
||||
(Acknowledgments from Ron Jeppesen in the 0.3 release:)
|
||||
Thanks to Corey Minyard who wrote the original CDU-31A driver on which
|
||||
|
@ -60,6 +60,18 @@ all of the cpus in the system. This removes any overhead due to
|
||||
load balancing code trying to pull tasks outside of the cpu exclusive
|
||||
cpuset only to be prevented by the tasks' cpus_allowed mask.
|
||||
|
||||
A cpuset that is mem_exclusive restricts kernel allocations for
|
||||
page, buffer and other data commonly shared by the kernel across
|
||||
multiple users. All cpusets, whether mem_exclusive or not, restrict
|
||||
allocations of memory for user space. This enables configuring a
|
||||
system so that several independent jobs can share common kernel
|
||||
data, such as file system pages, while isolating each jobs user
|
||||
allocation in its own cpuset. To do this, construct a large
|
||||
mem_exclusive cpuset to hold all the jobs, and construct child,
|
||||
non-mem_exclusive cpusets for each individual job. Only a small
|
||||
amount of typical kernel memory, such as requests from interrupt
|
||||
handlers, is allowed to be taken outside even a mem_exclusive cpuset.
|
||||
|
||||
User level code may create and destroy cpusets by name in the cpuset
|
||||
virtual file system, manage the attributes and permissions of these
|
||||
cpusets and which CPUs and Memory Nodes are assigned to each cpuset,
|
||||
|
@ -223,6 +223,7 @@ CAST5 algorithm contributors:
|
||||
|
||||
TEA/XTEA algorithm contributors:
|
||||
Aaron Grothe
|
||||
Michael Ringe
|
||||
|
||||
Khazad algorithm contributors:
|
||||
Aaron Grothe
|
||||
|
91
Documentation/dcdbas.txt
Normal file
91
Documentation/dcdbas.txt
Normal file
@ -0,0 +1,91 @@
|
||||
Overview
|
||||
|
||||
The Dell Systems Management Base Driver provides a sysfs interface for
|
||||
systems management software such as Dell OpenManage to perform system
|
||||
management interrupts and host control actions (system power cycle or
|
||||
power off after OS shutdown) on certain Dell systems.
|
||||
|
||||
Dell OpenManage requires this driver on the following Dell PowerEdge systems:
|
||||
300, 1300, 1400, 400SC, 500SC, 1500SC, 1550, 600SC, 1600SC, 650, 1655MC,
|
||||
700, and 750. Other Dell software such as the open source libsmbios project
|
||||
is expected to make use of this driver, and it may include the use of this
|
||||
driver on other Dell systems.
|
||||
|
||||
The Dell libsmbios project aims towards providing access to as much BIOS
|
||||
information as possible. See http://linux.dell.com/libsmbios/main/ for
|
||||
more information about the libsmbios project.
|
||||
|
||||
|
||||
System Management Interrupt
|
||||
|
||||
On some Dell systems, systems management software must access certain
|
||||
management information via a system management interrupt (SMI). The SMI data
|
||||
buffer must reside in 32-bit address space, and the physical address of the
|
||||
buffer is required for the SMI. The driver maintains the memory required for
|
||||
the SMI and provides a way for the application to generate the SMI.
|
||||
The driver creates the following sysfs entries for systems management
|
||||
software to perform these system management interrupts:
|
||||
|
||||
/sys/devices/platform/dcdbas/smi_data
|
||||
/sys/devices/platform/dcdbas/smi_data_buf_phys_addr
|
||||
/sys/devices/platform/dcdbas/smi_data_buf_size
|
||||
/sys/devices/platform/dcdbas/smi_request
|
||||
|
||||
Systems management software must perform the following steps to execute
|
||||
a SMI using this driver:
|
||||
|
||||
1) Lock smi_data.
|
||||
2) Write system management command to smi_data.
|
||||
3) Write "1" to smi_request to generate a calling interface SMI or
|
||||
"2" to generate a raw SMI.
|
||||
4) Read system management command response from smi_data.
|
||||
5) Unlock smi_data.
|
||||
|
||||
|
||||
Host Control Action
|
||||
|
||||
Dell OpenManage supports a host control feature that allows the administrator
|
||||
to perform a power cycle or power off of the system after the OS has finished
|
||||
shutting down. On some Dell systems, this host control feature requires that
|
||||
a driver perform a SMI after the OS has finished shutting down.
|
||||
|
||||
The driver creates the following sysfs entries for systems management software
|
||||
to schedule the driver to perform a power cycle or power off host control
|
||||
action after the system has finished shutting down:
|
||||
|
||||
/sys/devices/platform/dcdbas/host_control_action
|
||||
/sys/devices/platform/dcdbas/host_control_smi_type
|
||||
/sys/devices/platform/dcdbas/host_control_on_shutdown
|
||||
|
||||
Dell OpenManage performs the following steps to execute a power cycle or
|
||||
power off host control action using this driver:
|
||||
|
||||
1) Write host control action to be performed to host_control_action.
|
||||
2) Write type of SMI that driver needs to perform to host_control_smi_type.
|
||||
3) Write "1" to host_control_on_shutdown to enable host control action.
|
||||
4) Initiate OS shutdown.
|
||||
(Driver will perform host control SMI when it is notified that the OS
|
||||
has finished shutting down.)
|
||||
|
||||
|
||||
Host Control SMI Type
|
||||
|
||||
The following table shows the value to write to host_control_smi_type to
|
||||
perform a power cycle or power off host control action:
|
||||
|
||||
PowerEdge System Host Control SMI Type
|
||||
---------------- ---------------------
|
||||
300 HC_SMITYPE_TYPE1
|
||||
1300 HC_SMITYPE_TYPE1
|
||||
1400 HC_SMITYPE_TYPE2
|
||||
500SC HC_SMITYPE_TYPE2
|
||||
1500SC HC_SMITYPE_TYPE2
|
||||
1550 HC_SMITYPE_TYPE2
|
||||
600SC HC_SMITYPE_TYPE2
|
||||
1600SC HC_SMITYPE_TYPE2
|
||||
650 HC_SMITYPE_TYPE2
|
||||
1655MC HC_SMITYPE_TYPE2
|
||||
700 HC_SMITYPE_TYPE3
|
||||
750 HC_SMITYPE_TYPE3
|
||||
|
||||
|
74
Documentation/dell_rbu.txt
Normal file
74
Documentation/dell_rbu.txt
Normal file
@ -0,0 +1,74 @@
|
||||
Purpose:
|
||||
Demonstrate the usage of the new open sourced rbu (Remote BIOS Update) driver
|
||||
for updating BIOS images on Dell servers and desktops.
|
||||
|
||||
Scope:
|
||||
This document discusses the functionality of the rbu driver only.
|
||||
It does not cover the support needed from aplications to enable the BIOS to
|
||||
update itself with the image downloaded in to the memory.
|
||||
|
||||
Overview:
|
||||
This driver works with Dell OpenManage or Dell Update Packages for updating
|
||||
the BIOS on Dell servers (starting from servers sold since 1999), desktops
|
||||
and notebooks (starting from those sold in 2005).
|
||||
Please go to http://support.dell.com register and you can find info on
|
||||
OpenManage and Dell Update packages (DUP).
|
||||
|
||||
Dell_RBU driver supports BIOS update using the monilothic image and packetized
|
||||
image methods. In case of moniolithic the driver allocates a contiguous chunk
|
||||
of physical pages having the BIOS image. In case of packetized the app
|
||||
using the driver breaks the image in to packets of fixed sizes and the driver
|
||||
would place each packet in contiguous physical memory. The driver also
|
||||
maintains a link list of packets for reading them back.
|
||||
If the dell_rbu driver is unloaded all the allocated memory is freed.
|
||||
|
||||
The rbu driver needs to have an application which will inform the BIOS to
|
||||
enable the update in the next system reboot.
|
||||
|
||||
The user should not unload the rbu driver after downloading the BIOS image
|
||||
or updating.
|
||||
|
||||
The driver load creates the following directories under the /sys file system.
|
||||
/sys/class/firmware/dell_rbu/loading
|
||||
/sys/class/firmware/dell_rbu/data
|
||||
/sys/devices/platform/dell_rbu/image_type
|
||||
/sys/devices/platform/dell_rbu/data
|
||||
|
||||
The driver supports two types of update mechanism; monolithic and packetized.
|
||||
These update mechanism depends upon the BIOS currently running on the system.
|
||||
Most of the Dell systems support a monolithic update where the BIOS image is
|
||||
copied to a single contiguous block of physical memory.
|
||||
In case of packet mechanism the single memory can be broken in smaller chuks
|
||||
of contiguous memory and the BIOS image is scattered in these packets.
|
||||
|
||||
By default the driver uses monolithic memory for the update type. This can be
|
||||
changed to contiguous during the driver load time by specifying the load
|
||||
parameter image_type=packet. This can also be changed later as below
|
||||
echo packet > /sys/devices/platform/dell_rbu/image_type
|
||||
|
||||
Do the steps below to download the BIOS image.
|
||||
1) echo 1 > /sys/class/firmware/dell_rbu/loading
|
||||
2) cp bios_image.hdr /sys/class/firmware/dell_rbu/data
|
||||
3) echo 0 > /sys/class/firmware/dell_rbu/loading
|
||||
|
||||
The /sys/class/firmware/dell_rbu/ entries will remain till the following is
|
||||
done.
|
||||
echo -1 > /sys/class/firmware/dell_rbu/loading
|
||||
|
||||
Until this step is completed the drivr cannot be unloaded.
|
||||
|
||||
Also the driver provides /sys/devices/platform/dell_rbu/data readonly file to
|
||||
read back the image downloaded. This is useful in case of packet update
|
||||
mechanism where the above steps 1,2,3 will repeated for every packet.
|
||||
By reading the /sys/devices/platform/dell_rbu/data file all packet data
|
||||
downloaded can be verified in a single file.
|
||||
The packets are arranged in this file one after the other in a FIFO order.
|
||||
|
||||
NOTE:
|
||||
This driver requires a patch for firmware_class.c which has the addition
|
||||
of request_firmware_nowait_nohotplug function to wortk
|
||||
Also after updating the BIOS image an user mdoe application neeeds to execute
|
||||
code which message the BIOS update request to the BIOS. So on the next reboot
|
||||
the BIOS knows about the new image downloaded and it updates it self.
|
||||
Also don't unload the rbu drive if the image has to be updated.
|
||||
|
@ -16,7 +16,7 @@ Enable the following options:
|
||||
"Device drivers" => "Multimedia devices"
|
||||
=> "Video For Linux" => "BT848 Video For Linux"
|
||||
"Device drivers" => "Multimedia devices" => "Digital Video Broadcasting Devices"
|
||||
=> "DVB for Linux" "DVB Core Support" "Nebula/Pinnacle PCTV/TwinHan PCI Cards"
|
||||
=> "DVB for Linux" "DVB Core Support" "BT8xx based PCI cards"
|
||||
|
||||
3) Loading Modules, described by two approaches
|
||||
===============================================
|
||||
|
@ -7,7 +7,7 @@ To protect itself the kernel has to verify this address.
|
||||
|
||||
In older versions of Linux this was done with the
|
||||
int verify_area(int type, const void * addr, unsigned long size)
|
||||
function.
|
||||
function (which has since been replaced by access_ok()).
|
||||
|
||||
This function verified that the memory area starting at address
|
||||
addr and of size size was accessible for the operation specified
|
||||
|
@ -51,14 +51,6 @@ Who: Adrian Bunk <bunk@stusta.de>
|
||||
|
||||
---------------------------
|
||||
|
||||
What: register_ioctl32_conversion() / unregister_ioctl32_conversion()
|
||||
When: April 2005
|
||||
Why: Replaced by ->compat_ioctl in file_operations and other method
|
||||
vecors.
|
||||
Who: Andi Kleen <ak@muc.de>, Christoph Hellwig <hch@lst.de>
|
||||
|
||||
---------------------------
|
||||
|
||||
What: RCU API moves to EXPORT_SYMBOL_GPL
|
||||
When: April 2006
|
||||
Files: include/linux/rcupdate.h, kernel/rcupdate.c
|
||||
@ -74,14 +66,6 @@ Who: Paul E. McKenney <paulmck@us.ibm.com>
|
||||
|
||||
---------------------------
|
||||
|
||||
What: remove verify_area()
|
||||
When: July 2006
|
||||
Files: Various uaccess.h headers.
|
||||
Why: Deprecated and redundant. access_ok() should be used instead.
|
||||
Who: Jesper Juhl <juhl-lkml@dif.dk>
|
||||
|
||||
---------------------------
|
||||
|
||||
What: IEEE1394 Audio and Music Data Transmission Protocol driver,
|
||||
Connection Management Procedures driver
|
||||
When: November 2005
|
||||
@ -102,16 +86,6 @@ Who: Jody McIntyre <scjody@steamballoon.com>
|
||||
|
||||
---------------------------
|
||||
|
||||
What: register_serial/unregister_serial
|
||||
When: September 2005
|
||||
Why: This interface does not allow serial ports to be registered against
|
||||
a struct device, and as such does not allow correct power management
|
||||
of such ports. 8250-based ports should use serial8250_register_port
|
||||
and serial8250_unregister_port, or platform devices instead.
|
||||
Who: Russell King <rmk@arm.linux.org.uk>
|
||||
|
||||
---------------------------
|
||||
|
||||
What: i2c sysfs name change: in1_ref, vid deprecated in favour of cpu0_vid
|
||||
When: November 2005
|
||||
Files: drivers/i2c/chips/adm1025.c, drivers/i2c/chips/adm1026.c
|
||||
|
@ -133,6 +133,7 @@ Table 1-1: Process specific entries in /proc
|
||||
statm Process memory status information
|
||||
status Process status in human readable form
|
||||
wchan If CONFIG_KALLSYMS is set, a pre-decoded wchan
|
||||
smaps Extension based on maps, presenting the rss size for each mapped file
|
||||
..............................................................................
|
||||
|
||||
For example, to get the status information of a process, all you have to do is
|
||||
|
362
Documentation/filesystems/relayfs.txt
Normal file
362
Documentation/filesystems/relayfs.txt
Normal file
@ -0,0 +1,362 @@
|
||||
|
||||
relayfs - a high-speed data relay filesystem
|
||||
============================================
|
||||
|
||||
relayfs is a filesystem designed to provide an efficient mechanism for
|
||||
tools and facilities to relay large and potentially sustained streams
|
||||
of data from kernel space to user space.
|
||||
|
||||
The main abstraction of relayfs is the 'channel'. A channel consists
|
||||
of a set of per-cpu kernel buffers each represented by a file in the
|
||||
relayfs filesystem. Kernel clients write into a channel using
|
||||
efficient write functions which automatically log to the current cpu's
|
||||
channel buffer. User space applications mmap() the per-cpu files and
|
||||
retrieve the data as it becomes available.
|
||||
|
||||
The format of the data logged into the channel buffers is completely
|
||||
up to the relayfs client; relayfs does however provide hooks which
|
||||
allow clients to impose some stucture on the buffer data. Nor does
|
||||
relayfs implement any form of data filtering - this also is left to
|
||||
the client. The purpose is to keep relayfs as simple as possible.
|
||||
|
||||
This document provides an overview of the relayfs API. The details of
|
||||
the function parameters are documented along with the functions in the
|
||||
filesystem code - please see that for details.
|
||||
|
||||
Semantics
|
||||
=========
|
||||
|
||||
Each relayfs channel has one buffer per CPU, each buffer has one or
|
||||
more sub-buffers. Messages are written to the first sub-buffer until
|
||||
it is too full to contain a new message, in which case it it is
|
||||
written to the next (if available). Messages are never split across
|
||||
sub-buffers. At this point, userspace can be notified so it empties
|
||||
the first sub-buffer, while the kernel continues writing to the next.
|
||||
|
||||
When notified that a sub-buffer is full, the kernel knows how many
|
||||
bytes of it are padding i.e. unused. Userspace can use this knowledge
|
||||
to copy only valid data.
|
||||
|
||||
After copying it, userspace can notify the kernel that a sub-buffer
|
||||
has been consumed.
|
||||
|
||||
relayfs can operate in a mode where it will overwrite data not yet
|
||||
collected by userspace, and not wait for it to consume it.
|
||||
|
||||
relayfs itself does not provide for communication of such data between
|
||||
userspace and kernel, allowing the kernel side to remain simple and not
|
||||
impose a single interface on userspace. It does provide a separate
|
||||
helper though, described below.
|
||||
|
||||
klog, relay-app & librelay
|
||||
==========================
|
||||
|
||||
relayfs itself is ready to use, but to make things easier, two
|
||||
additional systems are provided. klog is a simple wrapper to make
|
||||
writing formatted text or raw data to a channel simpler, regardless of
|
||||
whether a channel to write into exists or not, or whether relayfs is
|
||||
compiled into the kernel or is configured as a module. relay-app is
|
||||
the kernel counterpart of userspace librelay.c, combined these two
|
||||
files provide glue to easily stream data to disk, without having to
|
||||
bother with housekeeping. klog and relay-app can be used together,
|
||||
with klog providing high-level logging functions to the kernel and
|
||||
relay-app taking care of kernel-user control and disk-logging chores.
|
||||
|
||||
It is possible to use relayfs without relay-app & librelay, but you'll
|
||||
have to implement communication between userspace and kernel, allowing
|
||||
both to convey the state of buffers (full, empty, amount of padding).
|
||||
|
||||
klog, relay-app and librelay can be found in the relay-apps tarball on
|
||||
http://relayfs.sourceforge.net
|
||||
|
||||
The relayfs user space API
|
||||
==========================
|
||||
|
||||
relayfs implements basic file operations for user space access to
|
||||
relayfs channel buffer data. Here are the file operations that are
|
||||
available and some comments regarding their behavior:
|
||||
|
||||
open() enables user to open an _existing_ buffer.
|
||||
|
||||
mmap() results in channel buffer being mapped into the caller's
|
||||
memory space. Note that you can't do a partial mmap - you must
|
||||
map the entire file, which is NRBUF * SUBBUFSIZE.
|
||||
|
||||
read() read the contents of a channel buffer. The bytes read are
|
||||
'consumed' by the reader i.e. they won't be available again
|
||||
to subsequent reads. If the channel is being used in
|
||||
no-overwrite mode (the default), it can be read at any time
|
||||
even if there's an active kernel writer. If the channel is
|
||||
being used in overwrite mode and there are active channel
|
||||
writers, results may be unpredictable - users should make
|
||||
sure that all logging to the channel has ended before using
|
||||
read() with overwrite mode.
|
||||
|
||||
poll() POLLIN/POLLRDNORM/POLLERR supported. User applications are
|
||||
notified when sub-buffer boundaries are crossed.
|
||||
|
||||
close() decrements the channel buffer's refcount. When the refcount
|
||||
reaches 0 i.e. when no process or kernel client has the buffer
|
||||
open, the channel buffer is freed.
|
||||
|
||||
|
||||
In order for a user application to make use of relayfs files, the
|
||||
relayfs filesystem must be mounted. For example,
|
||||
|
||||
mount -t relayfs relayfs /mnt/relay
|
||||
|
||||
NOTE: relayfs doesn't need to be mounted for kernel clients to create
|
||||
or use channels - it only needs to be mounted when user space
|
||||
applications need access to the buffer data.
|
||||
|
||||
|
||||
The relayfs kernel API
|
||||
======================
|
||||
|
||||
Here's a summary of the API relayfs provides to in-kernel clients:
|
||||
|
||||
|
||||
channel management functions:
|
||||
|
||||
relay_open(base_filename, parent, subbuf_size, n_subbufs,
|
||||
callbacks)
|
||||
relay_close(chan)
|
||||
relay_flush(chan)
|
||||
relay_reset(chan)
|
||||
relayfs_create_dir(name, parent)
|
||||
relayfs_remove_dir(dentry)
|
||||
|
||||
channel management typically called on instigation of userspace:
|
||||
|
||||
relay_subbufs_consumed(chan, cpu, subbufs_consumed)
|
||||
|
||||
write functions:
|
||||
|
||||
relay_write(chan, data, length)
|
||||
__relay_write(chan, data, length)
|
||||
relay_reserve(chan, length)
|
||||
|
||||
callbacks:
|
||||
|
||||
subbuf_start(buf, subbuf, prev_subbuf, prev_padding)
|
||||
buf_mapped(buf, filp)
|
||||
buf_unmapped(buf, filp)
|
||||
|
||||
helper functions:
|
||||
|
||||
relay_buf_full(buf)
|
||||
subbuf_start_reserve(buf, length)
|
||||
|
||||
|
||||
Creating a channel
|
||||
------------------
|
||||
|
||||
relay_open() is used to create a channel, along with its per-cpu
|
||||
channel buffers. Each channel buffer will have an associated file
|
||||
created for it in the relayfs filesystem, which can be opened and
|
||||
mmapped from user space if desired. The files are named
|
||||
basename0...basenameN-1 where N is the number of online cpus, and by
|
||||
default will be created in the root of the filesystem. If you want a
|
||||
directory structure to contain your relayfs files, you can create it
|
||||
with relayfs_create_dir() and pass the parent directory to
|
||||
relay_open(). Clients are responsible for cleaning up any directory
|
||||
structure they create when the channel is closed - use
|
||||
relayfs_remove_dir() for that.
|
||||
|
||||
The total size of each per-cpu buffer is calculated by multiplying the
|
||||
number of sub-buffers by the sub-buffer size passed into relay_open().
|
||||
The idea behind sub-buffers is that they're basically an extension of
|
||||
double-buffering to N buffers, and they also allow applications to
|
||||
easily implement random-access-on-buffer-boundary schemes, which can
|
||||
be important for some high-volume applications. The number and size
|
||||
of sub-buffers is completely dependent on the application and even for
|
||||
the same application, different conditions will warrant different
|
||||
values for these parameters at different times. Typically, the right
|
||||
values to use are best decided after some experimentation; in general,
|
||||
though, it's safe to assume that having only 1 sub-buffer is a bad
|
||||
idea - you're guaranteed to either overwrite data or lose events
|
||||
depending on the channel mode being used.
|
||||
|
||||
Channel 'modes'
|
||||
---------------
|
||||
|
||||
relayfs channels can be used in either of two modes - 'overwrite' or
|
||||
'no-overwrite'. The mode is entirely determined by the implementation
|
||||
of the subbuf_start() callback, as described below. In 'overwrite'
|
||||
mode, also known as 'flight recorder' mode, writes continuously cycle
|
||||
around the buffer and will never fail, but will unconditionally
|
||||
overwrite old data regardless of whether it's actually been consumed.
|
||||
In no-overwrite mode, writes will fail i.e. data will be lost, if the
|
||||
number of unconsumed sub-buffers equals the total number of
|
||||
sub-buffers in the channel. It should be clear that if there is no
|
||||
consumer or if the consumer can't consume sub-buffers fast enought,
|
||||
data will be lost in either case; the only difference is whether data
|
||||
is lost from the beginning or the end of a buffer.
|
||||
|
||||
As explained above, a relayfs channel is made of up one or more
|
||||
per-cpu channel buffers, each implemented as a circular buffer
|
||||
subdivided into one or more sub-buffers. Messages are written into
|
||||
the current sub-buffer of the channel's current per-cpu buffer via the
|
||||
write functions described below. Whenever a message can't fit into
|
||||
the current sub-buffer, because there's no room left for it, the
|
||||
client is notified via the subbuf_start() callback that a switch to a
|
||||
new sub-buffer is about to occur. The client uses this callback to 1)
|
||||
initialize the next sub-buffer if appropriate 2) finalize the previous
|
||||
sub-buffer if appropriate and 3) return a boolean value indicating
|
||||
whether or not to actually go ahead with the sub-buffer switch.
|
||||
|
||||
To implement 'no-overwrite' mode, the userspace client would provide
|
||||
an implementation of the subbuf_start() callback something like the
|
||||
following:
|
||||
|
||||
static int subbuf_start(struct rchan_buf *buf,
|
||||
void *subbuf,
|
||||
void *prev_subbuf,
|
||||
unsigned int prev_padding)
|
||||
{
|
||||
if (prev_subbuf)
|
||||
*((unsigned *)prev_subbuf) = prev_padding;
|
||||
|
||||
if (relay_buf_full(buf))
|
||||
return 0;
|
||||
|
||||
subbuf_start_reserve(buf, sizeof(unsigned int));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
If the current buffer is full i.e. all sub-buffers remain unconsumed,
|
||||
the callback returns 0 to indicate that the buffer switch should not
|
||||
occur yet i.e. until the consumer has had a chance to read the current
|
||||
set of ready sub-buffers. For the relay_buf_full() function to make
|
||||
sense, the consumer is reponsible for notifying relayfs when
|
||||
sub-buffers have been consumed via relay_subbufs_consumed(). Any
|
||||
subsequent attempts to write into the buffer will again invoke the
|
||||
subbuf_start() callback with the same parameters; only when the
|
||||
consumer has consumed one or more of the ready sub-buffers will
|
||||
relay_buf_full() return 0, in which case the buffer switch can
|
||||
continue.
|
||||
|
||||
The implementation of the subbuf_start() callback for 'overwrite' mode
|
||||
would be very similar:
|
||||
|
||||
static int subbuf_start(struct rchan_buf *buf,
|
||||
void *subbuf,
|
||||
void *prev_subbuf,
|
||||
unsigned int prev_padding)
|
||||
{
|
||||
if (prev_subbuf)
|
||||
*((unsigned *)prev_subbuf) = prev_padding;
|
||||
|
||||
subbuf_start_reserve(buf, sizeof(unsigned int));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
In this case, the relay_buf_full() check is meaningless and the
|
||||
callback always returns 1, causing the buffer switch to occur
|
||||
unconditionally. It's also meaningless for the client to use the
|
||||
relay_subbufs_consumed() function in this mode, as it's never
|
||||
consulted.
|
||||
|
||||
The default subbuf_start() implementation, used if the client doesn't
|
||||
define any callbacks, or doesn't define the subbuf_start() callback,
|
||||
implements the simplest possible 'no-overwrite' mode i.e. it does
|
||||
nothing but return 0.
|
||||
|
||||
Header information can be reserved at the beginning of each sub-buffer
|
||||
by calling the subbuf_start_reserve() helper function from within the
|
||||
subbuf_start() callback. This reserved area can be used to store
|
||||
whatever information the client wants. In the example above, room is
|
||||
reserved in each sub-buffer to store the padding count for that
|
||||
sub-buffer. This is filled in for the previous sub-buffer in the
|
||||
subbuf_start() implementation; the padding value for the previous
|
||||
sub-buffer is passed into the subbuf_start() callback along with a
|
||||
pointer to the previous sub-buffer, since the padding value isn't
|
||||
known until a sub-buffer is filled. The subbuf_start() callback is
|
||||
also called for the first sub-buffer when the channel is opened, to
|
||||
give the client a chance to reserve space in it. In this case the
|
||||
previous sub-buffer pointer passed into the callback will be NULL, so
|
||||
the client should check the value of the prev_subbuf pointer before
|
||||
writing into the previous sub-buffer.
|
||||
|
||||
Writing to a channel
|
||||
--------------------
|
||||
|
||||
kernel clients write data into the current cpu's channel buffer using
|
||||
relay_write() or __relay_write(). relay_write() is the main logging
|
||||
function - it uses local_irqsave() to protect the buffer and should be
|
||||
used if you might be logging from interrupt context. If you know
|
||||
you'll never be logging from interrupt context, you can use
|
||||
__relay_write(), which only disables preemption. These functions
|
||||
don't return a value, so you can't determine whether or not they
|
||||
failed - the assumption is that you wouldn't want to check a return
|
||||
value in the fast logging path anyway, and that they'll always succeed
|
||||
unless the buffer is full and no-overwrite mode is being used, in
|
||||
which case you can detect a failed write in the subbuf_start()
|
||||
callback by calling the relay_buf_full() helper function.
|
||||
|
||||
relay_reserve() is used to reserve a slot in a channel buffer which
|
||||
can be written to later. This would typically be used in applications
|
||||
that need to write directly into a channel buffer without having to
|
||||
stage data in a temporary buffer beforehand. Because the actual write
|
||||
may not happen immediately after the slot is reserved, applications
|
||||
using relay_reserve() can keep a count of the number of bytes actually
|
||||
written, either in space reserved in the sub-buffers themselves or as
|
||||
a separate array. See the 'reserve' example in the relay-apps tarball
|
||||
at http://relayfs.sourceforge.net for an example of how this can be
|
||||
done. Because the write is under control of the client and is
|
||||
separated from the reserve, relay_reserve() doesn't protect the buffer
|
||||
at all - it's up to the client to provide the appropriate
|
||||
synchronization when using relay_reserve().
|
||||
|
||||
Closing a channel
|
||||
-----------------
|
||||
|
||||
The client calls relay_close() when it's finished using the channel.
|
||||
The channel and its associated buffers are destroyed when there are no
|
||||
longer any references to any of the channel buffers. relay_flush()
|
||||
forces a sub-buffer switch on all the channel buffers, and can be used
|
||||
to finalize and process the last sub-buffers before the channel is
|
||||
closed.
|
||||
|
||||
Misc
|
||||
----
|
||||
|
||||
Some applications may want to keep a channel around and re-use it
|
||||
rather than open and close a new channel for each use. relay_reset()
|
||||
can be used for this purpose - it resets a channel to its initial
|
||||
state without reallocating channel buffer memory or destroying
|
||||
existing mappings. It should however only be called when it's safe to
|
||||
do so i.e. when the channel isn't currently being written to.
|
||||
|
||||
Finally, there are a couple of utility callbacks that can be used for
|
||||
different purposes. buf_mapped() is called whenever a channel buffer
|
||||
is mmapped from user space and buf_unmapped() is called when it's
|
||||
unmapped. The client can use this notification to trigger actions
|
||||
within the kernel application, such as enabling/disabling logging to
|
||||
the channel.
|
||||
|
||||
|
||||
Resources
|
||||
=========
|
||||
|
||||
For news, example code, mailing list, etc. see the relayfs homepage:
|
||||
|
||||
http://relayfs.sourceforge.net
|
||||
|
||||
|
||||
Credits
|
||||
=======
|
||||
|
||||
The ideas and specs for relayfs came about as a result of discussions
|
||||
on tracing involving the following:
|
||||
|
||||
Michel Dagenais <michel.dagenais@polymtl.ca>
|
||||
Richard Moore <richardj_moore@uk.ibm.com>
|
||||
Bob Wisniewski <bob@watson.ibm.com>
|
||||
Karim Yaghmour <karim@opersys.com>
|
||||
Tom Zanussi <zanussi@us.ibm.com>
|
||||
|
||||
Also thanks to Hubertus Franke for a lot of useful suggestions and bug
|
||||
reports.
|
@ -90,7 +90,7 @@ void device_remove_file(struct device *, struct device_attribute *);
|
||||
|
||||
It also defines this helper for defining device attributes:
|
||||
|
||||
#define DEVICE_ATTR(_name,_mode,_show,_store) \
|
||||
#define DEVICE_ATTR(_name, _mode, _show, _store) \
|
||||
struct device_attribute dev_attr_##_name = { \
|
||||
.attr = {.name = __stringify(_name) , .mode = _mode }, \
|
||||
.show = _show, \
|
||||
@ -99,14 +99,14 @@ struct device_attribute dev_attr_##_name = { \
|
||||
|
||||
For example, declaring
|
||||
|
||||
static DEVICE_ATTR(foo,0644,show_foo,store_foo);
|
||||
static DEVICE_ATTR(foo, S_IWUSR | S_IRUGO, show_foo, store_foo);
|
||||
|
||||
is equivalent to doing:
|
||||
|
||||
static struct device_attribute dev_attr_foo = {
|
||||
.attr = {
|
||||
.name = "foo",
|
||||
.mode = 0644,
|
||||
.mode = S_IWUSR | S_IRUGO,
|
||||
},
|
||||
.show = show_foo,
|
||||
.store = store_foo,
|
||||
@ -121,8 +121,8 @@ set of sysfs operations for forwarding read and write calls to the
|
||||
show and store methods of the attribute owners.
|
||||
|
||||
struct sysfs_ops {
|
||||
ssize_t (*show)(struct kobject *, struct attribute *,char *);
|
||||
ssize_t (*store)(struct kobject *,struct attribute *,const char *);
|
||||
ssize_t (*show)(struct kobject *, struct attribute *, char *);
|
||||
ssize_t (*store)(struct kobject *, struct attribute *, const char *);
|
||||
};
|
||||
|
||||
[ Subsystems should have already defined a struct kobj_type as a
|
||||
@ -137,7 +137,7 @@ calls the associated methods.
|
||||
|
||||
To illustrate:
|
||||
|
||||
#define to_dev_attr(_attr) container_of(_attr,struct device_attribute,attr)
|
||||
#define to_dev_attr(_attr) container_of(_attr, struct device_attribute, attr)
|
||||
#define to_dev(d) container_of(d, struct device, kobj)
|
||||
|
||||
static ssize_t
|
||||
@ -148,7 +148,7 @@ dev_attr_show(struct kobject * kobj, struct attribute * attr, char * buf)
|
||||
ssize_t ret = 0;
|
||||
|
||||
if (dev_attr->show)
|
||||
ret = dev_attr->show(dev,buf);
|
||||
ret = dev_attr->show(dev, buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -216,16 +216,16 @@ A very simple (and naive) implementation of a device attribute is:
|
||||
|
||||
static ssize_t show_name(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
{
|
||||
return sprintf(buf,"%s\n",dev->name);
|
||||
return snprintf(buf, PAGE_SIZE, "%s\n", dev->name);
|
||||
}
|
||||
|
||||
static ssize_t store_name(struct device * dev, const char * buf)
|
||||
{
|
||||
sscanf(buf,"%20s",dev->name);
|
||||
return strlen(buf);
|
||||
sscanf(buf, "%20s", dev->name);
|
||||
return strnlen(buf, PAGE_SIZE);
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(name,S_IRUGO,show_name,store_name);
|
||||
static DEVICE_ATTR(name, S_IRUGO, show_name, store_name);
|
||||
|
||||
|
||||
(Note that the real implementation doesn't allow userspace to set the
|
||||
@ -290,7 +290,7 @@ struct device_attribute {
|
||||
|
||||
Declaring:
|
||||
|
||||
DEVICE_ATTR(_name,_str,_mode,_show,_store);
|
||||
DEVICE_ATTR(_name, _str, _mode, _show, _store);
|
||||
|
||||
Creation/Removal:
|
||||
|
||||
@ -310,7 +310,7 @@ struct bus_attribute {
|
||||
|
||||
Declaring:
|
||||
|
||||
BUS_ATTR(_name,_mode,_show,_store)
|
||||
BUS_ATTR(_name, _mode, _show, _store)
|
||||
|
||||
Creation/Removal:
|
||||
|
||||
@ -331,7 +331,7 @@ struct driver_attribute {
|
||||
|
||||
Declaring:
|
||||
|
||||
DRIVER_ATTR(_name,_mode,_show,_store)
|
||||
DRIVER_ATTR(_name, _mode, _show, _store)
|
||||
|
||||
Creation/Removal:
|
||||
|
||||
|
@ -2,16 +2,11 @@ Kernel driver lm78
|
||||
==================
|
||||
|
||||
Supported chips:
|
||||
* National Semiconductor LM78
|
||||
* National Semiconductor LM78 / LM78-J
|
||||
Prefix: 'lm78'
|
||||
Addresses scanned: I2C 0x20 - 0x2f, ISA 0x290 (8 I/O ports)
|
||||
Datasheet: Publicly available at the National Semiconductor website
|
||||
http://www.national.com/
|
||||
* National Semiconductor LM78-J
|
||||
Prefix: 'lm78-j'
|
||||
Addresses scanned: I2C 0x20 - 0x2f, ISA 0x290 (8 I/O ports)
|
||||
Datasheet: Publicly available at the National Semiconductor website
|
||||
http://www.national.com/
|
||||
* National Semiconductor LM79
|
||||
Prefix: 'lm79'
|
||||
Addresses scanned: I2C 0x20 - 0x2f, ISA 0x290 (8 I/O ports)
|
||||
|
174
Documentation/hwmon/w83792d
Normal file
174
Documentation/hwmon/w83792d
Normal file
@ -0,0 +1,174 @@
|
||||
Kernel driver w83792d
|
||||
=====================
|
||||
|
||||
Supported chips:
|
||||
* Winbond W83792D
|
||||
Prefix: 'w83792d'
|
||||
Addresses scanned: I2C 0x2c - 0x2f
|
||||
Datasheet: http://www.winbond.com.tw/E-WINBONDHTM/partner/PDFresult.asp?Pname=1035
|
||||
|
||||
Author: Chunhao Huang
|
||||
Contact: DZShen <DZShen@Winbond.com.tw>
|
||||
|
||||
|
||||
Module Parameters
|
||||
-----------------
|
||||
|
||||
* init int
|
||||
(default 1)
|
||||
Use 'init=0' to bypass initializing the chip.
|
||||
Try this if your computer crashes when you load the module.
|
||||
|
||||
* force_subclients=bus,caddr,saddr,saddr
|
||||
This is used to force the i2c addresses for subclients of
|
||||
a certain chip. Example usage is `force_subclients=0,0x2f,0x4a,0x4b'
|
||||
to force the subclients of chip 0x2f on bus 0 to i2c addresses
|
||||
0x4a and 0x4b.
|
||||
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
This driver implements support for the Winbond W83792AD/D.
|
||||
|
||||
Detection of the chip can sometimes be foiled because it can be in an
|
||||
internal state that allows no clean access (Bank with ID register is not
|
||||
currently selected). If you know the address of the chip, use a 'force'
|
||||
parameter; this will put it into a more well-behaved state first.
|
||||
|
||||
The driver implements three temperature sensors, seven fan rotation speed
|
||||
sensors, nine voltage sensors, and two automatic fan regulation
|
||||
strategies called: Smart Fan I (Thermal Cruise mode) and Smart Fan II.
|
||||
Automatic fan control mode is possible only for fan1-fan3. Fan4-fan7 can run
|
||||
synchronized with selected fan (fan1-fan3). This functionality and manual PWM
|
||||
control for fan4-fan7 is not yet implemented.
|
||||
|
||||
Temperatures are measured in degrees Celsius and measurement resolution is 1
|
||||
degC for temp1 and 0.5 degC for temp2 and temp3. An alarm is triggered when
|
||||
the temperature gets higher than the Overtemperature Shutdown value; it stays
|
||||
on until the temperature falls below the Hysteresis value.
|
||||
|
||||
Fan rotation speeds are reported in RPM (rotations per minute). An alarm is
|
||||
triggered if the rotation speed has dropped below a programmable limit. Fan
|
||||
readings can be divided by a programmable divider (1, 2, 4, 8, 16, 32, 64 or
|
||||
128) to give the readings more range or accuracy.
|
||||
|
||||
Voltage sensors (also known as IN sensors) report their values in millivolts.
|
||||
An alarm is triggered if the voltage has crossed a programmable minimum
|
||||
or maximum limit.
|
||||
|
||||
Alarms are provided as output from "realtime status register". Following bits
|
||||
are defined:
|
||||
|
||||
bit - alarm on:
|
||||
0 - in0
|
||||
1 - in1
|
||||
2 - temp1
|
||||
3 - temp2
|
||||
4 - temp3
|
||||
5 - fan1
|
||||
6 - fan2
|
||||
7 - fan3
|
||||
8 - in2
|
||||
9 - in3
|
||||
10 - in4
|
||||
11 - in5
|
||||
12 - in6
|
||||
13 - VID change
|
||||
14 - chassis
|
||||
15 - fan7
|
||||
16 - tart1
|
||||
17 - tart2
|
||||
18 - tart3
|
||||
19 - in7
|
||||
20 - in8
|
||||
21 - fan4
|
||||
22 - fan5
|
||||
23 - fan6
|
||||
|
||||
Tart will be asserted while target temperature cannot be achieved after 3 minutes
|
||||
of full speed rotation of corresponding fan.
|
||||
|
||||
In addition to the alarms described above, there is a CHAS alarm on the chips
|
||||
which triggers if your computer case is open (This one is latched, contrary
|
||||
to realtime alarms).
|
||||
|
||||
The chips only update values each 3 seconds; reading them more often will
|
||||
do no harm, but will return 'old' values.
|
||||
|
||||
|
||||
W83792D PROBLEMS
|
||||
----------------
|
||||
Known problems:
|
||||
- This driver is only for Winbond W83792D C version device, there
|
||||
are also some motherboards with B version W83792D device. The
|
||||
calculation method to in6-in7(measured value, limits) is a little
|
||||
different between C and B version. C or B version can be identified
|
||||
by CR[0x49h].
|
||||
- The function of vid and vrm has not been finished, because I'm NOT
|
||||
very familiar with them. Adding support is welcome.
|
||||
- The function of chassis open detection needs more tests.
|
||||
- If you have ASUS server board and chip was not found: Then you will
|
||||
need to upgrade to latest (or beta) BIOS. If it does not help please
|
||||
contact us.
|
||||
|
||||
Fan control
|
||||
-----------
|
||||
|
||||
Manual mode
|
||||
-----------
|
||||
|
||||
Works as expected. You just need to specify desired PWM/DC value (fan speed)
|
||||
in appropriate pwm# file.
|
||||
|
||||
Thermal cruise
|
||||
--------------
|
||||
|
||||
In this mode, W83792D provides the Smart Fan system to automatically control
|
||||
fan speed to keep the temperatures of CPU and the system within specific
|
||||
range. At first a wanted temperature and interval must be set. This is done
|
||||
via thermal_cruise# file. The tolerance# file serves to create T +- tolerance
|
||||
interval. The fan speed will be lowered as long as the current temperature
|
||||
remains below the thermal_cruise# +- tolerance# value. Once the temperature
|
||||
exceeds the high limit (T+tolerance), the fan will be turned on with a
|
||||
specific speed set by pwm# and automatically controlled its PWM duty cycle
|
||||
with the temperature varying. Three conditions may occur:
|
||||
|
||||
(1) If the temperature still exceeds the high limit, PWM duty
|
||||
cycle will increase slowly.
|
||||
|
||||
(2) If the temperature goes below the high limit, but still above the low
|
||||
limit (T-tolerance), the fan speed will be fixed at the current speed because
|
||||
the temperature is in the target range.
|
||||
|
||||
(3) If the temperature goes below the low limit, PWM duty cycle will decrease
|
||||
slowly to 0 or a preset stop value until the temperature exceeds the low
|
||||
limit. (The preset stop value handling is not yet implemented in driver)
|
||||
|
||||
Smart Fan II
|
||||
------------
|
||||
|
||||
W83792D also provides a special mode for fan. Four temperature points are
|
||||
available. When related temperature sensors detects the temperature in preset
|
||||
temperature region (sf2_point@_fan# +- tolerance#) it will cause fans to run
|
||||
on programmed value from sf2_level@_fan#. You need to set four temperatures
|
||||
for each fan.
|
||||
|
||||
|
||||
/sys files
|
||||
----------
|
||||
|
||||
pwm[1-3] - this file stores PWM duty cycle or DC value (fan speed) in range:
|
||||
0 (stop) to 255 (full)
|
||||
pwm[1-3]_enable - this file controls mode of fan/temperature control:
|
||||
* 0 Disabled
|
||||
* 1 Manual mode
|
||||
* 2 Smart Fan II
|
||||
* 3 Thermal Cruise
|
||||
pwm[1-3]_mode - Select PWM of DC mode
|
||||
* 0 DC
|
||||
* 1 PWM
|
||||
thermal_cruise[1-3] - Selects the desired temperature for cruise (degC)
|
||||
tolerance[1-3] - Value in degrees of Celsius (degC) for +- T
|
||||
sf2_point[1-4]_fan[1-3] - four temperature points for each fan for Smart Fan II
|
||||
sf2_level[1-3]_fan[1-3] - three PWM/DC levels for each fan for Smart Fan II
|
@ -4,22 +4,13 @@ Kernel driver max6875
|
||||
Supported chips:
|
||||
* Maxim MAX6874, MAX6875
|
||||
Prefix: 'max6875'
|
||||
Addresses scanned: 0x50, 0x52
|
||||
Addresses scanned: None (see below)
|
||||
Datasheet:
|
||||
http://pdfserv.maxim-ic.com/en/ds/MAX6874-MAX6875.pdf
|
||||
|
||||
Author: Ben Gardner <bgardner@wabtec.com>
|
||||
|
||||
|
||||
Module Parameters
|
||||
-----------------
|
||||
|
||||
* allow_write int
|
||||
Set to non-zero to enable write permission:
|
||||
*0: Read only
|
||||
1: Read and write
|
||||
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
@ -33,34 +24,85 @@ registers.
|
||||
|
||||
The Maxim MAX6874 is a similar, mostly compatible device, with more intputs
|
||||
and outputs:
|
||||
|
||||
vin gpi vout
|
||||
MAX6874 6 4 8
|
||||
MAX6875 4 3 5
|
||||
|
||||
MAX6874 chips can have four different addresses (as opposed to only two for
|
||||
the MAX6875). The additional addresses (0x54 and 0x56) are not probed by
|
||||
this driver by default, but the probe module parameter can be used if
|
||||
needed.
|
||||
|
||||
See the datasheet for details on how to program the EEPROM.
|
||||
See the datasheet for more information.
|
||||
|
||||
|
||||
Sysfs entries
|
||||
-------------
|
||||
|
||||
eeprom_user - 512 bytes of user-defined EEPROM space. Only writable if
|
||||
allow_write was set and register 0x43 is 0.
|
||||
|
||||
eeprom_config - 70 bytes of config EEPROM. Note that changes will not get
|
||||
loaded into register space until a power cycle or device reset.
|
||||
|
||||
reg_config - 70 bytes of register space. Any changes take affect immediately.
|
||||
eeprom - 512 bytes of user-defined EEPROM space.
|
||||
|
||||
|
||||
General Remarks
|
||||
---------------
|
||||
|
||||
A typical application will require that the EEPROMs be programmed once and
|
||||
never altered afterwards.
|
||||
Valid addresses for the MAX6875 are 0x50 and 0x52.
|
||||
Valid addresses for the MAX6874 are 0x50, 0x52, 0x54 and 0x56.
|
||||
The driver does not probe any address, so you must force the address.
|
||||
|
||||
Example:
|
||||
$ modprobe max6875 force=0,0x50
|
||||
|
||||
The MAX6874/MAX6875 ignores address bit 0, so this driver attaches to multiple
|
||||
addresses. For example, for address 0x50, it also reserves 0x51.
|
||||
The even-address instance is called 'max6875', the odd one is 'max6875 subclient'.
|
||||
|
||||
|
||||
Programming the chip using i2c-dev
|
||||
----------------------------------
|
||||
|
||||
Use the i2c-dev interface to access and program the chips.
|
||||
Reads and writes are performed differently depending on the address range.
|
||||
|
||||
The configuration registers are at addresses 0x00 - 0x45.
|
||||
Use i2c_smbus_write_byte_data() to write a register and
|
||||
i2c_smbus_read_byte_data() to read a register.
|
||||
The command is the register number.
|
||||
|
||||
Examples:
|
||||
To write a 1 to register 0x45:
|
||||
i2c_smbus_write_byte_data(fd, 0x45, 1);
|
||||
|
||||
To read register 0x45:
|
||||
value = i2c_smbus_read_byte_data(fd, 0x45);
|
||||
|
||||
|
||||
The configuration EEPROM is at addresses 0x8000 - 0x8045.
|
||||
The user EEPROM is at addresses 0x8100 - 0x82ff.
|
||||
|
||||
Use i2c_smbus_write_word_data() to write a byte to EEPROM.
|
||||
|
||||
The command is the upper byte of the address: 0x80, 0x81, or 0x82.
|
||||
The data word is the lower part of the address or'd with data << 8.
|
||||
cmd = address >> 8;
|
||||
val = (address & 0xff) | (data << 8);
|
||||
|
||||
Example:
|
||||
To write 0x5a to address 0x8003:
|
||||
i2c_smbus_write_word_data(fd, 0x80, 0x5a03);
|
||||
|
||||
|
||||
Reading data from the EEPROM is a little more complicated.
|
||||
Use i2c_smbus_write_byte_data() to set the read address and then
|
||||
i2c_smbus_read_byte() or i2c_smbus_read_i2c_block_data() to read the data.
|
||||
|
||||
Example:
|
||||
To read data starting at offset 0x8100, first set the address:
|
||||
i2c_smbus_write_byte_data(fd, 0x81, 0x00);
|
||||
|
||||
And then read the data
|
||||
value = i2c_smbus_read_byte(fd);
|
||||
|
||||
or
|
||||
|
||||
count = i2c_smbus_read_i2c_block_data(fd, 0x84, buffer);
|
||||
|
||||
The block read should read 16 bytes.
|
||||
0x84 is the block read command.
|
||||
|
||||
See the datasheet for more details.
|
||||
|
||||
|
@ -115,7 +115,7 @@ CHECKING THROUGH /DEV
|
||||
If you try to access an adapter from a userspace program, you will have
|
||||
to use the /dev interface. You will still have to check whether the
|
||||
functionality you need is supported, of course. This is done using
|
||||
the I2C_FUNCS ioctl. An example, adapted from the lm_sensors i2c_detect
|
||||
the I2C_FUNCS ioctl. An example, adapted from the lm_sensors i2cdetect
|
||||
program, is below:
|
||||
|
||||
int file;
|
||||
|
@ -1,4 +1,4 @@
|
||||
Revision 4, 2004-03-30
|
||||
Revision 5, 2005-07-29
|
||||
Jean Delvare <khali@linux-fr.org>
|
||||
Greg KH <greg@kroah.com>
|
||||
|
||||
@ -17,20 +17,22 @@ yours for best results.
|
||||
|
||||
Technical changes:
|
||||
|
||||
* [Includes] Get rid of "version.h". Replace <linux/i2c-proc.h> with
|
||||
<linux/i2c-sensor.h>. Includes typically look like that:
|
||||
* [Includes] Get rid of "version.h" and <linux/i2c-proc.h>.
|
||||
Includes typically look like that:
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/i2c-sensor.h>
|
||||
#include <linux/i2c-vid.h> /* if you need VRM support */
|
||||
#include <linux/hwmon.h> /* for hardware monitoring drivers */
|
||||
#include <linux/hwmon-sysfs.h>
|
||||
#include <linux/hwmon-vid.h> /* if you need VRM support */
|
||||
#include <asm/io.h> /* if you have I/O operations */
|
||||
Please respect this inclusion order. Some extra headers may be
|
||||
required for a given driver (e.g. "lm75.h").
|
||||
|
||||
* [Addresses] SENSORS_I2C_END becomes I2C_CLIENT_END, SENSORS_ISA_END
|
||||
becomes I2C_CLIENT_ISA_END.
|
||||
* [Addresses] SENSORS_I2C_END becomes I2C_CLIENT_END, ISA addresses
|
||||
are no more handled by the i2c core.
|
||||
SENSORS_INSMOD_<n> becomes I2C_CLIENT_INSMOD_<n>.
|
||||
|
||||
* [Client data] Get rid of sysctl_id. Try using standard names for
|
||||
register values (for example, temp_os becomes temp_max). You're
|
||||
@ -66,13 +68,15 @@ Technical changes:
|
||||
if (!(adapter->class & I2C_CLASS_HWMON))
|
||||
return 0;
|
||||
ISA-only drivers of course don't need this.
|
||||
Call i2c_probe() instead of i2c_detect().
|
||||
|
||||
* [Detect] As mentioned earlier, the flags parameter is gone.
|
||||
The type_name and client_name strings are replaced by a single
|
||||
name string, which will be filled with a lowercase, short string
|
||||
(typically the driver name, e.g. "lm75").
|
||||
In i2c-only drivers, drop the i2c_is_isa_adapter check, it's
|
||||
useless.
|
||||
useless. Same for isa-only drivers, as the test would always be
|
||||
true. Only hybrid drivers (which are quite rare) still need it.
|
||||
The errorN labels are reduced to the number needed. If that number
|
||||
is 2 (i2c-only drivers), it is advised that the labels are named
|
||||
exit and exit_free. For i2c+isa drivers, labels should be named
|
||||
@ -86,6 +90,8 @@ Technical changes:
|
||||
device_create_file. Move the driver initialization before any
|
||||
sysfs file creation.
|
||||
Drop client->id.
|
||||
Drop any 24RF08 corruption prevention you find, as this is now done
|
||||
at the i2c-core level, and doing it twice voids it.
|
||||
|
||||
* [Init] Limits must not be set by the driver (can be done later in
|
||||
user-space). Chip should not be reset default (although a module
|
||||
@ -93,7 +99,8 @@ Technical changes:
|
||||
limited to the strictly necessary steps.
|
||||
|
||||
* [Detach] Get rid of data, remove the call to
|
||||
i2c_deregister_entry.
|
||||
i2c_deregister_entry. Do not log an error message if
|
||||
i2c_detach_client fails, as i2c-core will now do it for you.
|
||||
|
||||
* [Update] Don't access client->data directly, use
|
||||
i2c_get_clientdata(client) instead.
|
||||
|
@ -148,15 +148,15 @@ are defined in i2c.h to help you support them, as well as a generic
|
||||
detection algorithm.
|
||||
|
||||
You do not have to use this parameter interface; but don't try to use
|
||||
function i2c_probe() (or i2c_detect()) if you don't.
|
||||
function i2c_probe() if you don't.
|
||||
|
||||
NOTE: If you want to write a `sensors' driver, the interface is slightly
|
||||
different! See below.
|
||||
|
||||
|
||||
|
||||
Probing classes (i2c)
|
||||
---------------------
|
||||
Probing classes
|
||||
---------------
|
||||
|
||||
All parameters are given as lists of unsigned 16-bit integers. Lists are
|
||||
terminated by I2C_CLIENT_END.
|
||||
@ -171,12 +171,18 @@ The following lists are used internally:
|
||||
ignore: insmod parameter.
|
||||
A list of pairs. The first value is a bus number (-1 for any I2C bus),
|
||||
the second is the I2C address. These addresses are never probed.
|
||||
This parameter overrules 'normal' and 'probe', but not the 'force' lists.
|
||||
This parameter overrules the 'normal_i2c' list only.
|
||||
force: insmod parameter.
|
||||
A list of pairs. The first value is a bus number (-1 for any I2C bus),
|
||||
the second is the I2C address. A device is blindly assumed to be on
|
||||
the given address, no probing is done.
|
||||
|
||||
Additionally, kind-specific force lists may optionally be defined if
|
||||
the driver supports several chip kinds. They are grouped in a
|
||||
NULL-terminated list of pointers named forces, those first element if the
|
||||
generic force list mentioned above. Each additional list correspond to an
|
||||
insmod parameter of the form force_<kind>.
|
||||
|
||||
Fortunately, as a module writer, you just have to define the `normal_i2c'
|
||||
parameter. The complete declaration could look like this:
|
||||
|
||||
@ -186,66 +192,17 @@ parameter. The complete declaration could look like this:
|
||||
|
||||
/* Magic definition of all other variables and things */
|
||||
I2C_CLIENT_INSMOD;
|
||||
/* Or, if your driver supports, say, 2 kind of devices: */
|
||||
I2C_CLIENT_INSMOD_2(foo, bar);
|
||||
|
||||
If you use the multi-kind form, an enum will be defined for you:
|
||||
enum chips { any_chip, foo, bar, ... }
|
||||
You can then (and certainly should) use it in the driver code.
|
||||
|
||||
Note that you *have* to call the defined variable `normal_i2c',
|
||||
without any prefix!
|
||||
|
||||
|
||||
Probing classes (sensors)
|
||||
-------------------------
|
||||
|
||||
If you write a `sensors' driver, you use a slightly different interface.
|
||||
As well as I2C addresses, we have to cope with ISA addresses. Also, we
|
||||
use a enum of chip types. Don't forget to include `sensors.h'.
|
||||
|
||||
The following lists are used internally. They are all lists of integers.
|
||||
|
||||
normal_i2c: filled in by the module writer. Terminated by SENSORS_I2C_END.
|
||||
A list of I2C addresses which should normally be examined.
|
||||
normal_isa: filled in by the module writer. Terminated by SENSORS_ISA_END.
|
||||
A list of ISA addresses which should normally be examined.
|
||||
probe: insmod parameter. Initialize this list with SENSORS_I2C_END values.
|
||||
A list of pairs. The first value is a bus number (SENSORS_ISA_BUS for
|
||||
the ISA bus, -1 for any I2C bus), the second is the address. These
|
||||
addresses are also probed, as if they were in the 'normal' list.
|
||||
ignore: insmod parameter. Initialize this list with SENSORS_I2C_END values.
|
||||
A list of pairs. The first value is a bus number (SENSORS_ISA_BUS for
|
||||
the ISA bus, -1 for any I2C bus), the second is the I2C address. These
|
||||
addresses are never probed. This parameter overrules 'normal' and
|
||||
'probe', but not the 'force' lists.
|
||||
|
||||
Also used is a list of pointers to sensors_force_data structures:
|
||||
force_data: insmod parameters. A list, ending with an element of which
|
||||
the force field is NULL.
|
||||
Each element contains the type of chip and a list of pairs.
|
||||
The first value is a bus number (SENSORS_ISA_BUS for the ISA bus,
|
||||
-1 for any I2C bus), the second is the address.
|
||||
These are automatically translated to insmod variables of the form
|
||||
force_foo.
|
||||
|
||||
So we have a generic insmod variabled `force', and chip-specific variables
|
||||
`force_CHIPNAME'.
|
||||
|
||||
Fortunately, as a module writer, you just have to define the `normal_i2c'
|
||||
and `normal_isa' parameters, and define what chip names are used.
|
||||
The complete declaration could look like this:
|
||||
/* Scan i2c addresses 0x37, and 0x48 to 0x4f */
|
||||
static unsigned short normal_i2c[] = { 0x37, 0x48, 0x49, 0x4a, 0x4b, 0x4c,
|
||||
0x4d, 0x4e, 0x4f, I2C_CLIENT_END };
|
||||
/* Scan ISA address 0x290 */
|
||||
static unsigned int normal_isa[] = {0x0290,SENSORS_ISA_END};
|
||||
|
||||
/* Define chips foo and bar, as well as all module parameters and things */
|
||||
SENSORS_INSMOD_2(foo,bar);
|
||||
|
||||
If you have one chip, you use macro SENSORS_INSMOD_1(chip), if you have 2
|
||||
you use macro SENSORS_INSMOD_2(chip1,chip2), etc. If you do not want to
|
||||
bother with chip types, you can use SENSORS_INSMOD_0.
|
||||
|
||||
A enum is automatically defined as follows:
|
||||
enum chips { any_chip, chip1, chip2, ... }
|
||||
|
||||
|
||||
Attaching to an adapter
|
||||
-----------------------
|
||||
|
||||
@ -264,17 +221,10 @@ detected at a specific address, another callback is called.
|
||||
return i2c_probe(adapter,&addr_data,&foo_detect_client);
|
||||
}
|
||||
|
||||
For `sensors' drivers, use the i2c_detect function instead:
|
||||
|
||||
int foo_attach_adapter(struct i2c_adapter *adapter)
|
||||
{
|
||||
return i2c_detect(adapter,&addr_data,&foo_detect_client);
|
||||
}
|
||||
|
||||
Remember, structure `addr_data' is defined by the macros explained above,
|
||||
so you do not have to define it yourself.
|
||||
|
||||
The i2c_probe or i2c_detect function will call the foo_detect_client
|
||||
The i2c_probe function will call the foo_detect_client
|
||||
function only for those i2c addresses that actually have a device on
|
||||
them (unless a `force' parameter was used). In addition, addresses that
|
||||
are already in use (by some other registered client) are skipped.
|
||||
@ -283,19 +233,18 @@ are already in use (by some other registered client) are skipped.
|
||||
The detect client function
|
||||
--------------------------
|
||||
|
||||
The detect client function is called by i2c_probe or i2c_detect.
|
||||
The `kind' parameter contains 0 if this call is due to a `force'
|
||||
parameter, and -1 otherwise (for i2c_detect, it contains 0 if
|
||||
this call is due to the generic `force' parameter, and the chip type
|
||||
number if it is due to a specific `force' parameter).
|
||||
The detect client function is called by i2c_probe. The `kind' parameter
|
||||
contains -1 for a probed detection, 0 for a forced detection, or a positive
|
||||
number for a forced detection with a chip type forced.
|
||||
|
||||
Below, some things are only needed if this is a `sensors' driver. Those
|
||||
parts are between /* SENSORS ONLY START */ and /* SENSORS ONLY END */
|
||||
markers.
|
||||
|
||||
This function should only return an error (any value != 0) if there is
|
||||
some reason why no more detection should be done anymore. If the
|
||||
detection just fails for this address, return 0.
|
||||
Returning an error different from -ENODEV in a detect function will cause
|
||||
the detection to stop: other addresses and adapters won't be scanned.
|
||||
This should only be done on fatal or internal errors, such as a memory
|
||||
shortage or i2c_attach_client failing.
|
||||
|
||||
For now, you can ignore the `flags' parameter. It is there for future use.
|
||||
|
||||
@ -320,11 +269,10 @@ For now, you can ignore the `flags' parameter. It is there for future use.
|
||||
const char *type_name = "";
|
||||
int is_isa = i2c_is_isa_adapter(adapter);
|
||||
|
||||
if (is_isa) {
|
||||
/* Do this only if the chip can additionally be found on the ISA bus
|
||||
(hybrid chip). */
|
||||
|
||||
/* If this client can't be on the ISA bus at all, we can stop now
|
||||
(call `goto ERROR0'). But for kicks, we will assume it is all
|
||||
right. */
|
||||
if (is_isa) {
|
||||
|
||||
/* Discard immediately if this ISA range is already used */
|
||||
if (check_region(address,FOO_EXTENT))
|
||||
@ -495,15 +443,13 @@ much simpler than the attachment code, fortunately!
|
||||
/* SENSORS ONLY END */
|
||||
|
||||
/* Try to detach the client from i2c space */
|
||||
if ((err = i2c_detach_client(client))) {
|
||||
printk("foo.o: Client deregistration failed, client not detached.\n");
|
||||
if ((err = i2c_detach_client(client)))
|
||||
return err;
|
||||
}
|
||||
|
||||
/* SENSORS ONLY START */
|
||||
/* HYBRID SENSORS CHIP ONLY START */
|
||||
if i2c_is_isa_client(client)
|
||||
release_region(client->addr,LM78_EXTENT);
|
||||
/* SENSORS ONLY END */
|
||||
/* HYBRID SENSORS CHIP ONLY END */
|
||||
|
||||
kfree(client); /* Frees client data too, if allocated at the same time */
|
||||
return 0;
|
||||
|
@ -2,7 +2,7 @@
|
||||
----------------------------
|
||||
|
||||
H. Peter Anvin <hpa@zytor.com>
|
||||
Last update 2002-01-01
|
||||
Last update 2005-09-02
|
||||
|
||||
On the i386 platform, the Linux kernel uses a rather complicated boot
|
||||
convention. This has evolved partially due to historical aspects, as
|
||||
@ -34,6 +34,8 @@ Protocol 2.02: (Kernel 2.4.0-test3-pre3) New command line protocol.
|
||||
Protocol 2.03: (Kernel 2.4.18-pre1) Explicitly makes the highest possible
|
||||
initrd address available to the bootloader.
|
||||
|
||||
Protocol 2.04: (Kernel 2.6.14) Extend the syssize field to four bytes.
|
||||
|
||||
|
||||
**** MEMORY LAYOUT
|
||||
|
||||
@ -103,10 +105,9 @@ The header looks like:
|
||||
Offset Proto Name Meaning
|
||||
/Size
|
||||
|
||||
01F1/1 ALL setup_sects The size of the setup in sectors
|
||||
01F1/1 ALL(1 setup_sects The size of the setup in sectors
|
||||
01F2/2 ALL root_flags If set, the root is mounted readonly
|
||||
01F4/2 ALL syssize DO NOT USE - for bootsect.S use only
|
||||
01F6/2 ALL swap_dev DO NOT USE - obsolete
|
||||
01F4/4 2.04+(2 syssize The size of the 32-bit code in 16-byte paras
|
||||
01F8/2 ALL ram_size DO NOT USE - for bootsect.S use only
|
||||
01FA/2 ALL vid_mode Video mode control
|
||||
01FC/2 ALL root_dev Default root device number
|
||||
@ -129,8 +130,12 @@ Offset Proto Name Meaning
|
||||
0228/4 2.02+ cmd_line_ptr 32-bit pointer to the kernel command line
|
||||
022C/4 2.03+ initrd_addr_max Highest legal initrd address
|
||||
|
||||
For backwards compatibility, if the setup_sects field contains 0, the
|
||||
real value is 4.
|
||||
(1) For backwards compatibility, if the setup_sects field contains 0, the
|
||||
real value is 4.
|
||||
|
||||
(2) For boot protocol prior to 2.04, the upper two bytes of the syssize
|
||||
field are unusable, which means the size of a bzImage kernel
|
||||
cannot be determined.
|
||||
|
||||
If the "HdrS" (0x53726448) magic number is not found at offset 0x202,
|
||||
the boot protocol version is "old". Loading an old kernel, the
|
||||
@ -230,12 +235,16 @@ loader to communicate with the kernel. Some of its options are also
|
||||
relevant to the boot loader itself, see "special command line options"
|
||||
below.
|
||||
|
||||
The kernel command line is a null-terminated string up to 255
|
||||
characters long, plus the final null.
|
||||
The kernel command line is a null-terminated string currently up to
|
||||
255 characters long, plus the final null. A string that is too long
|
||||
will be automatically truncated by the kernel, a boot loader may allow
|
||||
a longer command line to be passed to permit future kernels to extend
|
||||
this limit.
|
||||
|
||||
If the boot protocol version is 2.02 or later, the address of the
|
||||
kernel command line is given by the header field cmd_line_ptr (see
|
||||
above.)
|
||||
above.) This address can be anywhere between the end of the setup
|
||||
heap and 0xA0000.
|
||||
|
||||
If the protocol version is *not* 2.02 or higher, the kernel
|
||||
command line is entered using the following protocol:
|
||||
@ -255,7 +264,7 @@ command line is entered using the following protocol:
|
||||
**** SAMPLE BOOT CONFIGURATION
|
||||
|
||||
As a sample configuration, assume the following layout of the real
|
||||
mode segment:
|
||||
mode segment (this is a typical, and recommended layout):
|
||||
|
||||
0x0000-0x7FFF Real mode kernel
|
||||
0x8000-0x8FFF Stack and heap
|
||||
@ -312,9 +321,9 @@ Such a boot loader should enter the following fields in the header:
|
||||
|
||||
**** LOADING THE REST OF THE KERNEL
|
||||
|
||||
The non-real-mode kernel starts at offset (setup_sects+1)*512 in the
|
||||
kernel file (again, if setup_sects == 0 the real value is 4.) It
|
||||
should be loaded at address 0x10000 for Image/zImage kernels and
|
||||
The 32-bit (non-real-mode) kernel starts at offset (setup_sects+1)*512
|
||||
in the kernel file (again, if setup_sects == 0 the real value is 4.)
|
||||
It should be loaded at address 0x10000 for Image/zImage kernels and
|
||||
0x100000 for bzImage kernels.
|
||||
|
||||
The kernel is a bzImage kernel if the protocol >= 2.00 and the 0x01
|
||||
|
@ -872,7 +872,13 @@ When kbuild executes the following steps are followed (roughly):
|
||||
Assignments to $(targets) are without $(obj)/ prefix.
|
||||
if_changed may be used in conjunction with custom commands as
|
||||
defined in 6.7 "Custom kbuild commands".
|
||||
|
||||
Note: It is a typical mistake to forget the FORCE prerequisite.
|
||||
Another common pitfall is that whitespace is sometimes
|
||||
significant; for instance, the below will fail (note the extra space
|
||||
after the comma):
|
||||
target: source(s) FORCE
|
||||
#WRONG!# $(call if_changed, ld/objcopy/gzip)
|
||||
|
||||
ld
|
||||
Link target. Often LDFLAGS_$@ is used to set specific options to ld.
|
||||
|
@ -1174,6 +1174,11 @@ running once the system is up.
|
||||
New name for the ramdisk parameter.
|
||||
See Documentation/ramdisk.txt.
|
||||
|
||||
rdinit= [KNL]
|
||||
Format: <full_path>
|
||||
Run specified binary instead of /init from the ramdisk,
|
||||
used for early userspace startup. See initrd.
|
||||
|
||||
reboot= [BUGS=IA-32,BUGS=ARM,BUGS=IA-64] Rebooting mode
|
||||
Format: <reboot_mode>[,<reboot_mode2>[,...]]
|
||||
See arch/*/kernel/reboot.c.
|
||||
|
246
Documentation/networking/README.ipw2100
Normal file
246
Documentation/networking/README.ipw2100
Normal file
@ -0,0 +1,246 @@
|
||||
|
||||
===========================
|
||||
Intel(R) PRO/Wireless 2100 Network Connection Driver for Linux
|
||||
README.ipw2100
|
||||
|
||||
March 14, 2005
|
||||
|
||||
===========================
|
||||
Index
|
||||
---------------------------
|
||||
0. Introduction
|
||||
1. Release 1.1.0 Current Features
|
||||
2. Command Line Parameters
|
||||
3. Sysfs Helper Files
|
||||
4. Radio Kill Switch
|
||||
5. Dynamic Firmware
|
||||
6. Power Management
|
||||
7. Support
|
||||
8. License
|
||||
|
||||
|
||||
===========================
|
||||
0. Introduction
|
||||
------------ ----- ----- ---- --- -- -
|
||||
|
||||
This document provides a brief overview of the features supported by the
|
||||
IPW2100 driver project. The main project website, where the latest
|
||||
development version of the driver can be found, is:
|
||||
|
||||
http://ipw2100.sourceforge.net
|
||||
|
||||
There you can find the not only the latest releases, but also information about
|
||||
potential fixes and patches, as well as links to the development mailing list
|
||||
for the driver project.
|
||||
|
||||
|
||||
===========================
|
||||
1. Release 1.1.0 Current Supported Features
|
||||
---------------------------
|
||||
- Managed (BSS) and Ad-Hoc (IBSS)
|
||||
- WEP (shared key and open)
|
||||
- Wireless Tools support
|
||||
- 802.1x (tested with XSupplicant 1.0.1)
|
||||
|
||||
Enabled (but not supported) features:
|
||||
- Monitor/RFMon mode
|
||||
- WPA/WPA2
|
||||
|
||||
The distinction between officially supported and enabled is a reflection
|
||||
on the amount of validation and interoperability testing that has been
|
||||
performed on a given feature.
|
||||
|
||||
|
||||
===========================
|
||||
2. Command Line Parameters
|
||||
---------------------------
|
||||
|
||||
If the driver is built as a module, the following optional parameters are used
|
||||
by entering them on the command line with the modprobe command using this
|
||||
syntax:
|
||||
|
||||
modprobe ipw2100 [<option>=<VAL1><,VAL2>...]
|
||||
|
||||
For example, to disable the radio on driver loading, enter:
|
||||
|
||||
modprobe ipw2100 disable=1
|
||||
|
||||
The ipw2100 driver supports the following module parameters:
|
||||
|
||||
Name Value Example:
|
||||
debug 0x0-0xffffffff debug=1024
|
||||
mode 0,1,2 mode=1 /* AdHoc */
|
||||
channel int channel=3 /* Only valid in AdHoc or Monitor */
|
||||
associate boolean associate=0 /* Do NOT auto associate */
|
||||
disable boolean disable=1 /* Do not power the HW */
|
||||
|
||||
|
||||
===========================
|
||||
3. Sysfs Helper Files
|
||||
---------------------------
|
||||
|
||||
There are several ways to control the behavior of the driver. Many of the
|
||||
general capabilities are exposed through the Wireless Tools (iwconfig). There
|
||||
are a few capabilities that are exposed through entries in the Linux Sysfs.
|
||||
|
||||
|
||||
----- Driver Level ------
|
||||
For the driver level files, look in /sys/bus/pci/drivers/ipw2100/
|
||||
|
||||
debug_level
|
||||
|
||||
This controls the same global as the 'debug' module parameter. For
|
||||
information on the various debugging levels available, run the 'dvals'
|
||||
script found in the driver source directory.
|
||||
|
||||
NOTE: 'debug_level' is only enabled if CONFIG_IPW2100_DEBUG is turn
|
||||
on.
|
||||
|
||||
----- Device Level ------
|
||||
For the device level files look in
|
||||
|
||||
/sys/bus/pci/drivers/ipw2100/{PCI-ID}/
|
||||
|
||||
For example:
|
||||
/sys/bus/pci/drivers/ipw2100/0000:02:01.0
|
||||
|
||||
For the device level files, see /sys/bus/pci/drivers/ipw2100:
|
||||
|
||||
rf_kill
|
||||
read -
|
||||
0 = RF kill not enabled (radio on)
|
||||
1 = SW based RF kill active (radio off)
|
||||
2 = HW based RF kill active (radio off)
|
||||
3 = Both HW and SW RF kill active (radio off)
|
||||
write -
|
||||
0 = If SW based RF kill active, turn the radio back on
|
||||
1 = If radio is on, activate SW based RF kill
|
||||
|
||||
NOTE: If you enable the SW based RF kill and then toggle the HW
|
||||
based RF kill from ON -> OFF -> ON, the radio will NOT come back on
|
||||
|
||||
|
||||
===========================
|
||||
4. Radio Kill Switch
|
||||
---------------------------
|
||||
Most laptops provide the ability for the user to physically disable the radio.
|
||||
Some vendors have implemented this as a physical switch that requires no
|
||||
software to turn the radio off and on. On other laptops, however, the switch
|
||||
is controlled through a button being pressed and a software driver then making
|
||||
calls to turn the radio off and on. This is referred to as a "software based
|
||||
RF kill switch"
|
||||
|
||||
See the Sysfs helper file 'rf_kill' for determining the state of the RF switch
|
||||
on your system.
|
||||
|
||||
|
||||
===========================
|
||||
5. Dynamic Firmware
|
||||
---------------------------
|
||||
As the firmware is licensed under a restricted use license, it can not be
|
||||
included within the kernel sources. To enable the IPW2100 you will need a
|
||||
firmware image to load into the wireless NIC's processors.
|
||||
|
||||
You can obtain these images from <http://ipw2100.sf.net/firmware.php>.
|
||||
|
||||
See INSTALL for instructions on installing the firmware.
|
||||
|
||||
|
||||
===========================
|
||||
6. Power Management
|
||||
---------------------------
|
||||
The IPW2100 supports the configuration of the Power Save Protocol
|
||||
through a private wireless extension interface. The IPW2100 supports
|
||||
the following different modes:
|
||||
|
||||
off No power management. Radio is always on.
|
||||
on Automatic power management
|
||||
1-5 Different levels of power management. The higher the
|
||||
number the greater the power savings, but with an impact to
|
||||
packet latencies.
|
||||
|
||||
Power management works by powering down the radio after a certain
|
||||
interval of time has passed where no packets are passed through the
|
||||
radio. Once powered down, the radio remains in that state for a given
|
||||
period of time. For higher power savings, the interval between last
|
||||
packet processed to sleep is shorter and the sleep period is longer.
|
||||
|
||||
When the radio is asleep, the access point sending data to the station
|
||||
must buffer packets at the AP until the station wakes up and requests
|
||||
any buffered packets. If you have an AP that does not correctly support
|
||||
the PSP protocol you may experience packet loss or very poor performance
|
||||
while power management is enabled. If this is the case, you will need
|
||||
to try and find a firmware update for your AP, or disable power
|
||||
management (via `iwconfig eth1 power off`)
|
||||
|
||||
To configure the power level on the IPW2100 you use a combination of
|
||||
iwconfig and iwpriv. iwconfig is used to turn power management on, off,
|
||||
and set it to auto.
|
||||
|
||||
iwconfig eth1 power off Disables radio power down
|
||||
iwconfig eth1 power on Enables radio power management to
|
||||
last set level (defaults to AUTO)
|
||||
iwpriv eth1 set_power 0 Sets power level to AUTO and enables
|
||||
power management if not previously
|
||||
enabled.
|
||||
iwpriv eth1 set_power 1-5 Set the power level as specified,
|
||||
enabling power management if not
|
||||
previously enabled.
|
||||
|
||||
You can view the current power level setting via:
|
||||
|
||||
iwpriv eth1 get_power
|
||||
|
||||
It will return the current period or timeout that is configured as a string
|
||||
in the form of xxxx/yyyy (z) where xxxx is the timeout interval (amount of
|
||||
time after packet processing), yyyy is the period to sleep (amount of time to
|
||||
wait before powering the radio and querying the access point for buffered
|
||||
packets), and z is the 'power level'. If power management is turned off the
|
||||
xxxx/yyyy will be replaced with 'off' -- the level reported will be the active
|
||||
level if `iwconfig eth1 power on` is invoked.
|
||||
|
||||
|
||||
===========================
|
||||
7. Support
|
||||
---------------------------
|
||||
|
||||
For general development information and support,
|
||||
go to:
|
||||
|
||||
http://ipw2100.sf.net/
|
||||
|
||||
The ipw2100 1.1.0 driver and firmware can be downloaded from:
|
||||
|
||||
http://support.intel.com
|
||||
|
||||
For installation support on the ipw2100 1.1.0 driver on Linux kernels
|
||||
2.6.8 or greater, email support is available from:
|
||||
|
||||
http://supportmail.intel.com
|
||||
|
||||
===========================
|
||||
8. License
|
||||
---------------------------
|
||||
|
||||
Copyright(c) 2003 - 2005 Intel Corporation. All rights reserved.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
The full GNU General Public License is included in this distribution in the
|
||||
file called LICENSE.
|
||||
|
||||
License Contact Information:
|
||||
James P. Ketrenos <ipw2100-admin@linux.intel.com>
|
||||
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
|
300
Documentation/networking/README.ipw2200
Normal file
300
Documentation/networking/README.ipw2200
Normal file
@ -0,0 +1,300 @@
|
||||
|
||||
Intel(R) PRO/Wireless 2915ABG Driver for Linux in support of:
|
||||
|
||||
Intel(R) PRO/Wireless 2200BG Network Connection
|
||||
Intel(R) PRO/Wireless 2915ABG Network Connection
|
||||
|
||||
Note: The Intel(R) PRO/Wireless 2915ABG Driver for Linux and Intel(R)
|
||||
PRO/Wireless 2200BG Driver for Linux is a unified driver that works on
|
||||
both hardware adapters listed above. In this document the Intel(R)
|
||||
PRO/Wireless 2915ABG Driver for Linux will be used to reference the
|
||||
unified driver.
|
||||
|
||||
Copyright (C) 2004-2005, Intel Corporation
|
||||
|
||||
README.ipw2200
|
||||
|
||||
Version: 1.0.0
|
||||
Date : January 31, 2005
|
||||
|
||||
|
||||
Index
|
||||
-----------------------------------------------
|
||||
1. Introduction
|
||||
1.1. Overview of features
|
||||
1.2. Module parameters
|
||||
1.3. Wireless Extension Private Methods
|
||||
1.4. Sysfs Helper Files
|
||||
2. About the Version Numbers
|
||||
3. Support
|
||||
4. License
|
||||
|
||||
|
||||
1. Introduction
|
||||
-----------------------------------------------
|
||||
The following sections attempt to provide a brief introduction to using
|
||||
the Intel(R) PRO/Wireless 2915ABG Driver for Linux.
|
||||
|
||||
This document is not meant to be a comprehensive manual on
|
||||
understanding or using wireless technologies, but should be sufficient
|
||||
to get you moving without wires on Linux.
|
||||
|
||||
For information on building and installing the driver, see the INSTALL
|
||||
file.
|
||||
|
||||
|
||||
1.1. Overview of Features
|
||||
-----------------------------------------------
|
||||
The current release (1.0.0) supports the following features:
|
||||
|
||||
+ BSS mode (Infrastructure, Managed)
|
||||
+ IBSS mode (Ad-Hoc)
|
||||
+ WEP (OPEN and SHARED KEY mode)
|
||||
+ 802.1x EAP via wpa_supplicant and xsupplicant
|
||||
+ Wireless Extension support
|
||||
+ Full B and G rate support (2200 and 2915)
|
||||
+ Full A rate support (2915 only)
|
||||
+ Transmit power control
|
||||
+ S state support (ACPI suspend/resume)
|
||||
+ long/short preamble support
|
||||
|
||||
|
||||
|
||||
1.2. Command Line Parameters
|
||||
-----------------------------------------------
|
||||
|
||||
Like many modules used in the Linux kernel, the Intel(R) PRO/Wireless
|
||||
2915ABG Driver for Linux allows certain configuration options to be
|
||||
provided as module parameters. The most common way to specify a module
|
||||
parameter is via the command line.
|
||||
|
||||
The general form is:
|
||||
|
||||
% modprobe ipw2200 parameter=value
|
||||
|
||||
Where the supported parameter are:
|
||||
|
||||
associate
|
||||
Set to 0 to disable the auto scan-and-associate functionality of the
|
||||
driver. If disabled, the driver will not attempt to scan
|
||||
for and associate to a network until it has been configured with
|
||||
one or more properties for the target network, for example configuring
|
||||
the network SSID. Default is 1 (auto-associate)
|
||||
|
||||
Example: % modprobe ipw2200 associate=0
|
||||
|
||||
auto_create
|
||||
Set to 0 to disable the auto creation of an Ad-Hoc network
|
||||
matching the channel and network name parameters provided.
|
||||
Default is 1.
|
||||
|
||||
channel
|
||||
channel number for association. The normal method for setting
|
||||
the channel would be to use the standard wireless tools
|
||||
(i.e. `iwconfig eth1 channel 10`), but it is useful sometimes
|
||||
to set this while debugging. Channel 0 means 'ANY'
|
||||
|
||||
debug
|
||||
If using a debug build, this is used to control the amount of debug
|
||||
info is logged. See the 'dval' and 'load' script for more info on
|
||||
how to use this (the dval and load scripts are provided as part
|
||||
of the ipw2200 development snapshot releases available from the
|
||||
SourceForge project at http://ipw2200.sf.net)
|
||||
|
||||
mode
|
||||
Can be used to set the default mode of the adapter.
|
||||
0 = Managed, 1 = Ad-Hoc
|
||||
|
||||
|
||||
1.3. Wireless Extension Private Methods
|
||||
-----------------------------------------------
|
||||
|
||||
As an interface designed to handle generic hardware, there are certain
|
||||
capabilities not exposed through the normal Wireless Tool interface. As
|
||||
such, a provision is provided for a driver to declare custom, or
|
||||
private, methods. The Intel(R) PRO/Wireless 2915ABG Driver for Linux
|
||||
defines several of these to configure various settings.
|
||||
|
||||
The general form of using the private wireless methods is:
|
||||
|
||||
% iwpriv $IFNAME method parameters
|
||||
|
||||
Where $IFNAME is the interface name the device is registered with
|
||||
(typically eth1, customized via one of the various network interface
|
||||
name managers, such as ifrename)
|
||||
|
||||
The supported private methods are:
|
||||
|
||||
get_mode
|
||||
Can be used to report out which IEEE mode the driver is
|
||||
configured to support. Example:
|
||||
|
||||
% iwpriv eth1 get_mode
|
||||
eth1 get_mode:802.11bg (6)
|
||||
|
||||
set_mode
|
||||
Can be used to configure which IEEE mode the driver will
|
||||
support.
|
||||
|
||||
Usage:
|
||||
% iwpriv eth1 set_mode {mode}
|
||||
Where {mode} is a number in the range 1-7:
|
||||
1 802.11a (2915 only)
|
||||
2 802.11b
|
||||
3 802.11ab (2915 only)
|
||||
4 802.11g
|
||||
5 802.11ag (2915 only)
|
||||
6 802.11bg
|
||||
7 802.11abg (2915 only)
|
||||
|
||||
get_preamble
|
||||
Can be used to report configuration of preamble length.
|
||||
|
||||
set_preamble
|
||||
Can be used to set the configuration of preamble length:
|
||||
|
||||
Usage:
|
||||
% iwpriv eth1 set_preamble {mode}
|
||||
Where {mode} is one of:
|
||||
1 Long preamble only
|
||||
0 Auto (long or short based on connection)
|
||||
|
||||
|
||||
1.4. Sysfs Helper Files:
|
||||
-----------------------------------------------
|
||||
|
||||
The Linux kernel provides a pseudo file system that can be used to
|
||||
access various components of the operating system. The Intel(R)
|
||||
PRO/Wireless 2915ABG Driver for Linux exposes several configuration
|
||||
parameters through this mechanism.
|
||||
|
||||
An entry in the sysfs can support reading and/or writing. You can
|
||||
typically query the contents of a sysfs entry through the use of cat,
|
||||
and can set the contents via echo. For example:
|
||||
|
||||
% cat /sys/bus/pci/drivers/ipw2200/debug_level
|
||||
|
||||
Will report the current debug level of the driver's logging subsystem
|
||||
(only available if CONFIG_IPW_DEBUG was configured when the driver was
|
||||
built).
|
||||
|
||||
You can set the debug level via:
|
||||
|
||||
% echo $VALUE > /sys/bus/pci/drivers/ipw2200/debug_level
|
||||
|
||||
Where $VALUE would be a number in the case of this sysfs entry. The
|
||||
input to sysfs files does not have to be a number. For example, the
|
||||
firmware loader used by hotplug utilizes sysfs entries for transferring
|
||||
the firmware image from user space into the driver.
|
||||
|
||||
The Intel(R) PRO/Wireless 2915ABG Driver for Linux exposes sysfs entries
|
||||
at two levels -- driver level, which apply to all instances of the
|
||||
driver (in the event that there are more than one device installed) and
|
||||
device level, which applies only to the single specific instance.
|
||||
|
||||
|
||||
1.4.1 Driver Level Sysfs Helper Files
|
||||
-----------------------------------------------
|
||||
|
||||
For the driver level files, look in /sys/bus/pci/drivers/ipw2200/
|
||||
|
||||
debug_level
|
||||
|
||||
This controls the same global as the 'debug' module parameter
|
||||
|
||||
|
||||
1.4.2 Device Level Sysfs Helper Files
|
||||
-----------------------------------------------
|
||||
|
||||
For the device level files, look in
|
||||
|
||||
/sys/bus/pci/drivers/ipw2200/{PCI-ID}/
|
||||
|
||||
For example:
|
||||
/sys/bus/pci/drivers/ipw2200/0000:02:01.0
|
||||
|
||||
For the device level files, see /sys/bus/pci/[drivers/ipw2200:
|
||||
|
||||
rf_kill
|
||||
read -
|
||||
0 = RF kill not enabled (radio on)
|
||||
1 = SW based RF kill active (radio off)
|
||||
2 = HW based RF kill active (radio off)
|
||||
3 = Both HW and SW RF kill active (radio off)
|
||||
write -
|
||||
0 = If SW based RF kill active, turn the radio back on
|
||||
1 = If radio is on, activate SW based RF kill
|
||||
|
||||
NOTE: If you enable the SW based RF kill and then toggle the HW
|
||||
based RF kill from ON -> OFF -> ON, the radio will NOT come back on
|
||||
|
||||
ucode
|
||||
read-only access to the ucode version number
|
||||
|
||||
|
||||
2. About the Version Numbers
|
||||
-----------------------------------------------
|
||||
|
||||
Due to the nature of open source development projects, there are
|
||||
frequently changes being incorporated that have not gone through
|
||||
a complete validation process. These changes are incorporated into
|
||||
development snapshot releases.
|
||||
|
||||
Releases are numbered with a three level scheme:
|
||||
|
||||
major.minor.development
|
||||
|
||||
Any version where the 'development' portion is 0 (for example
|
||||
1.0.0, 1.1.0, etc.) indicates a stable version that will be made
|
||||
available for kernel inclusion.
|
||||
|
||||
Any version where the 'development' portion is not a 0 (for
|
||||
example 1.0.1, 1.1.5, etc.) indicates a development version that is
|
||||
being made available for testing and cutting edge users. The stability
|
||||
and functionality of the development releases are not know. We make
|
||||
efforts to try and keep all snapshots reasonably stable, but due to the
|
||||
frequency of their release, and the desire to get those releases
|
||||
available as quickly as possible, unknown anomalies should be expected.
|
||||
|
||||
The major version number will be incremented when significant changes
|
||||
are made to the driver. Currently, there are no major changes planned.
|
||||
|
||||
|
||||
3. Support
|
||||
-----------------------------------------------
|
||||
|
||||
For installation support of the 1.0.0 version, you can contact
|
||||
http://supportmail.intel.com, or you can use the open source project
|
||||
support.
|
||||
|
||||
For general information and support, go to:
|
||||
|
||||
http://ipw2200.sf.net/
|
||||
|
||||
|
||||
4. License
|
||||
-----------------------------------------------
|
||||
|
||||
Copyright(c) 2003 - 2005 Intel Corporation. All rights reserved.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
The full GNU General Public License is included in this distribution in the
|
||||
file called LICENSE.
|
||||
|
||||
Contact Information:
|
||||
James P. Ketrenos <ipw2100-admin@linux.intel.com>
|
||||
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
|
||||
|
138
Documentation/power/swsusp-dmcrypt.txt
Normal file
138
Documentation/power/swsusp-dmcrypt.txt
Normal file
@ -0,0 +1,138 @@
|
||||
Author: Andreas Steinmetz <ast@domdv.de>
|
||||
|
||||
|
||||
How to use dm-crypt and swsusp together:
|
||||
========================================
|
||||
|
||||
Some prerequisites:
|
||||
You know how dm-crypt works. If not, visit the following web page:
|
||||
http://www.saout.de/misc/dm-crypt/
|
||||
You have read Documentation/power/swsusp.txt and understand it.
|
||||
You did read Documentation/initrd.txt and know how an initrd works.
|
||||
You know how to create or how to modify an initrd.
|
||||
|
||||
Now your system is properly set up, your disk is encrypted except for
|
||||
the swap device(s) and the boot partition which may contain a mini
|
||||
system for crypto setup and/or rescue purposes. You may even have
|
||||
an initrd that does your current crypto setup already.
|
||||
|
||||
At this point you want to encrypt your swap, too. Still you want to
|
||||
be able to suspend using swsusp. This, however, means that you
|
||||
have to be able to either enter a passphrase or that you read
|
||||
the key(s) from an external device like a pcmcia flash disk
|
||||
or an usb stick prior to resume. So you need an initrd, that sets
|
||||
up dm-crypt and then asks swsusp to resume from the encrypted
|
||||
swap device.
|
||||
|
||||
The most important thing is that you set up dm-crypt in such
|
||||
a way that the swap device you suspend to/resume from has
|
||||
always the same major/minor within the initrd as well as
|
||||
within your running system. The easiest way to achieve this is
|
||||
to always set up this swap device first with dmsetup, so that
|
||||
it will always look like the following:
|
||||
|
||||
brw------- 1 root root 254, 0 Jul 28 13:37 /dev/mapper/swap0
|
||||
|
||||
Now set up your kernel to use /dev/mapper/swap0 as the default
|
||||
resume partition, so your kernel .config contains:
|
||||
|
||||
CONFIG_PM_STD_PARTITION="/dev/mapper/swap0"
|
||||
|
||||
Prepare your boot loader to use the initrd you will create or
|
||||
modify. For lilo the simplest setup looks like the following
|
||||
lines:
|
||||
|
||||
image=/boot/vmlinuz
|
||||
initrd=/boot/initrd.gz
|
||||
label=linux
|
||||
append="root=/dev/ram0 init=/linuxrc rw"
|
||||
|
||||
Finally you need to create or modify your initrd. Lets assume
|
||||
you create an initrd that reads the required dm-crypt setup
|
||||
from a pcmcia flash disk card. The card is formatted with an ext2
|
||||
fs which resides on /dev/hde1 when the card is inserted. The
|
||||
card contains at least the encrypted swap setup in a file
|
||||
named "swapkey". /etc/fstab of your initrd contains something
|
||||
like the following:
|
||||
|
||||
/dev/hda1 /mnt ext3 ro 0 0
|
||||
none /proc proc defaults,noatime,nodiratime 0 0
|
||||
none /sys sysfs defaults,noatime,nodiratime 0 0
|
||||
|
||||
/dev/hda1 contains an unencrypted mini system that sets up all
|
||||
of your crypto devices, again by reading the setup from the
|
||||
pcmcia flash disk. What follows now is a /linuxrc for your
|
||||
initrd that allows you to resume from encrypted swap and that
|
||||
continues boot with your mini system on /dev/hda1 if resume
|
||||
does not happen:
|
||||
|
||||
#!/bin/sh
|
||||
PATH=/sbin:/bin:/usr/sbin:/usr/bin
|
||||
mount /proc
|
||||
mount /sys
|
||||
mapped=0
|
||||
noresume=`grep -c noresume /proc/cmdline`
|
||||
if [ "$*" != "" ]
|
||||
then
|
||||
noresume=1
|
||||
fi
|
||||
dmesg -n 1
|
||||
/sbin/cardmgr -q
|
||||
for i in 1 2 3 4 5 6 7 8 9 0
|
||||
do
|
||||
if [ -f /proc/ide/hde/media ]
|
||||
then
|
||||
usleep 500000
|
||||
mount -t ext2 -o ro /dev/hde1 /mnt
|
||||
if [ -f /mnt/swapkey ]
|
||||
then
|
||||
dmsetup create swap0 /mnt/swapkey > /dev/null 2>&1 && mapped=1
|
||||
fi
|
||||
umount /mnt
|
||||
break
|
||||
fi
|
||||
usleep 500000
|
||||
done
|
||||
killproc /sbin/cardmgr
|
||||
dmesg -n 6
|
||||
if [ $mapped = 1 ]
|
||||
then
|
||||
if [ $noresume != 0 ]
|
||||
then
|
||||
mkswap /dev/mapper/swap0 > /dev/null 2>&1
|
||||
fi
|
||||
echo 254:0 > /sys/power/resume
|
||||
dmsetup remove swap0
|
||||
fi
|
||||
umount /sys
|
||||
mount /mnt
|
||||
umount /proc
|
||||
cd /mnt
|
||||
pivot_root . mnt
|
||||
mount /proc
|
||||
umount -l /mnt
|
||||
umount /proc
|
||||
exec chroot . /sbin/init $* < dev/console > dev/console 2>&1
|
||||
|
||||
Please don't mind the weird loop above, busybox's msh doesn't know
|
||||
the let statement. Now, what is happening in the script?
|
||||
First we have to decide if we want to try to resume, or not.
|
||||
We will not resume if booting with "noresume" or any parameters
|
||||
for init like "single" or "emergency" as boot parameters.
|
||||
|
||||
Then we need to set up dmcrypt with the setup data from the
|
||||
pcmcia flash disk. If this succeeds we need to reset the swap
|
||||
device if we don't want to resume. The line "echo 254:0 > /sys/power/resume"
|
||||
then attempts to resume from the first device mapper device.
|
||||
Note that it is important to set the device in /sys/power/resume,
|
||||
regardless if resuming or not, otherwise later suspend will fail.
|
||||
If resume starts, script execution terminates here.
|
||||
|
||||
Otherwise we just remove the encrypted swap device and leave it to the
|
||||
mini system on /dev/hda1 to set the whole crypto up (it is up to
|
||||
you to modify this to your taste).
|
||||
|
||||
What then follows is the well known process to change the root
|
||||
file system and continue booting from there. I prefer to unmount
|
||||
the initrd prior to continue booting but it is up to you to modify
|
||||
this.
|
@ -1,22 +1,20 @@
|
||||
From kernel/suspend.c:
|
||||
Some warnings, first.
|
||||
|
||||
* BIG FAT WARNING *********************************************************
|
||||
*
|
||||
* If you have unsupported (*) devices using DMA...
|
||||
* ...say goodbye to your data.
|
||||
*
|
||||
* If you touch anything on disk between suspend and resume...
|
||||
* ...kiss your data goodbye.
|
||||
*
|
||||
* If your disk driver does not support suspend... (IDE does)
|
||||
* ...you'd better find out how to get along
|
||||
* without your data.
|
||||
* If you do resume from initrd after your filesystems are mounted...
|
||||
* ...bye bye root partition.
|
||||
* [this is actually same case as above]
|
||||
*
|
||||
* If you change kernel command line between suspend and resume...
|
||||
* ...prepare for nasty fsck or worse.
|
||||
*
|
||||
* If you change your hardware while system is suspended...
|
||||
* ...well, it was not good idea.
|
||||
* If you have unsupported (*) devices using DMA, you may have some
|
||||
* problems. If your disk driver does not support suspend... (IDE does),
|
||||
* it may cause some problems, too. If you change kernel command line
|
||||
* between suspend and resume, it may do something wrong. If you change
|
||||
* your hardware while system is suspended... well, it was not good idea;
|
||||
* but it will probably only crash.
|
||||
*
|
||||
* (*) suspend/resume support is needed to make it safe.
|
||||
|
||||
@ -30,6 +28,13 @@ echo shutdown > /sys/power/disk; echo disk > /sys/power/state
|
||||
echo platform > /sys/power/disk; echo disk > /sys/power/state
|
||||
|
||||
|
||||
Encrypted suspend image:
|
||||
------------------------
|
||||
If you want to store your suspend image encrypted with a temporary
|
||||
key to prevent data gathering after resume you must compile
|
||||
crypto and the aes algorithm into the kernel - modules won't work
|
||||
as they cannot be loaded at resume time.
|
||||
|
||||
|
||||
Article about goals and implementation of Software Suspend for Linux
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
@ -85,11 +90,6 @@ resume.
|
||||
You have your server on UPS. Power died, and UPS is indicating 30
|
||||
seconds to failure. What do you do? Suspend to disk.
|
||||
|
||||
Ethernet card in your server died. You want to replace it. Your
|
||||
server is not hotplug capable. What do you do? Suspend to disk,
|
||||
replace ethernet card, resume. If you are fast your users will not
|
||||
even see broken connections.
|
||||
|
||||
|
||||
Q: Maybe I'm missing something, but why don't the regular I/O paths work?
|
||||
|
||||
@ -117,31 +117,6 @@ Q: Does linux support ACPI S4?
|
||||
|
||||
A: Yes. That's what echo platform > /sys/power/disk does.
|
||||
|
||||
Q: My machine doesn't work with ACPI. How can I use swsusp than ?
|
||||
|
||||
A: Do a reboot() syscall with right parameters. Warning: glibc gets in
|
||||
its way, so check with strace:
|
||||
|
||||
reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, 0xd000fce2)
|
||||
|
||||
(Thanks to Peter Osterlund:)
|
||||
|
||||
#include <unistd.h>
|
||||
#include <syscall.h>
|
||||
|
||||
#define LINUX_REBOOT_MAGIC1 0xfee1dead
|
||||
#define LINUX_REBOOT_MAGIC2 672274793
|
||||
#define LINUX_REBOOT_CMD_SW_SUSPEND 0xD000FCE2
|
||||
|
||||
int main()
|
||||
{
|
||||
syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
|
||||
LINUX_REBOOT_CMD_SW_SUSPEND, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Also /sys/ interface should be still present.
|
||||
|
||||
Q: What is 'suspend2'?
|
||||
|
||||
A: suspend2 is 'Software Suspend 2', a forked implementation of
|
||||
@ -311,3 +286,46 @@ As a rule of thumb use encrypted swap to protect your data while your
|
||||
system is shut down or suspended. Additionally use the encrypted
|
||||
suspend image to prevent sensitive data from being stolen after
|
||||
resume.
|
||||
|
||||
Q: Why can't we suspend to a swap file?
|
||||
|
||||
A: Because accessing swap file needs the filesystem mounted, and
|
||||
filesystem might do something wrong (like replaying the journal)
|
||||
during mount.
|
||||
|
||||
There are few ways to get that fixed:
|
||||
|
||||
1) Probably could be solved by modifying every filesystem to support
|
||||
some kind of "really read-only!" option. Patches welcome.
|
||||
|
||||
2) suspend2 gets around that by storing absolute positions in on-disk
|
||||
image (and blocksize), with resume parameter pointing directly to
|
||||
suspend header.
|
||||
|
||||
Q: Is there a maximum system RAM size that is supported by swsusp?
|
||||
|
||||
A: It should work okay with highmem.
|
||||
|
||||
Q: Does swsusp (to disk) use only one swap partition or can it use
|
||||
multiple swap partitions (aggregate them into one logical space)?
|
||||
|
||||
A: Only one swap partition, sorry.
|
||||
|
||||
Q: If my application(s) causes lots of memory & swap space to be used
|
||||
(over half of the total system RAM), is it correct that it is likely
|
||||
to be useless to try to suspend to disk while that app is running?
|
||||
|
||||
A: No, it should work okay, as long as your app does not mlock()
|
||||
it. Just prepare big enough swap partition.
|
||||
|
||||
Q: What information is usefull for debugging suspend-to-disk problems?
|
||||
|
||||
A: Well, last messages on the screen are always useful. If something
|
||||
is broken, it is usually some kernel driver, therefore trying with as
|
||||
little as possible modules loaded helps a lot. I also prefer people to
|
||||
suspend from console, preferably without X running. Booting with
|
||||
init=/bin/bash, then swapon and starting suspend sequence manually
|
||||
usually does the trick. Then it is good idea to try with latest
|
||||
vanilla kernel.
|
||||
|
||||
|
||||
|
@ -46,6 +46,12 @@ There are a few types of systems where video works after S3 resume:
|
||||
POSTing bios works. Ole Rohne has patch to do just that at
|
||||
http://dev.gentoo.org/~marineam/patch-radeonfb-2.6.11-rc2-mm2.
|
||||
|
||||
(8) on some systems, you can use the video_post utility mentioned here:
|
||||
http://bugzilla.kernel.org/show_bug.cgi?id=3670. Do echo 3 > /sys/power/state
|
||||
&& /usr/sbin/video_post - which will initialize the display in console mode.
|
||||
If you are in X, you can switch to a virtual terminal and back to X using
|
||||
CTRL+ALT+F1 - CTRL+ALT+F7 to get the display working in graphical mode again.
|
||||
|
||||
Now, if you pass acpi_sleep=something, and it does not work with your
|
||||
bios, you'll get a hard crash during resume. Be careful. Also it is
|
||||
safest to do your experiments with plain old VGA console. The vesafb
|
||||
@ -64,7 +70,8 @@ Model hack (or "how to do it")
|
||||
------------------------------------------------------------------------------
|
||||
Acer Aspire 1406LC ole's late BIOS init (7), turn off DRI
|
||||
Acer TM 242FX vbetool (6)
|
||||
Acer TM C300 vga=normal (only suspend on console, not in X), vbetool (6)
|
||||
Acer TM C110 video_post (8)
|
||||
Acer TM C300 vga=normal (only suspend on console, not in X), vbetool (6) or video_post (8)
|
||||
Acer TM 4052LCi s3_bios (2)
|
||||
Acer TM 636Lci s3_bios vga=normal (2)
|
||||
Acer TM 650 (Radeon M7) vga=normal plus boot-radeon (5) gets text console back
|
||||
@ -113,6 +120,7 @@ IBM ThinkPad T42p (2373-GTG) s3_bios (2)
|
||||
IBM TP X20 ??? (*)
|
||||
IBM TP X30 s3_bios (2)
|
||||
IBM TP X31 / Type 2672-XXH none (1), use radeontool (http://fdd.com/software/radeon/) to turn off backlight.
|
||||
IBM TP X32 none (1), but backlight is on and video is trashed after long suspend
|
||||
IBM Thinkpad X40 Type 2371-7JG s3_bios,s3_mode (4)
|
||||
Medion MD4220 ??? (*)
|
||||
Samsung P35 vbetool needed (6)
|
||||
|
@ -1,5 +1,5 @@
|
||||
====================================================================
|
||||
= Adaptec Aic7xxx Fast -> Ultra160 Family Manager Set v6.2.28 =
|
||||
= Adaptec Aic7xxx Fast -> Ultra160 Family Manager Set v7.0 =
|
||||
= README for =
|
||||
= The Linux Operating System =
|
||||
====================================================================
|
||||
@ -131,6 +131,10 @@ The following information is available in this file:
|
||||
SCSI "stub" effects.
|
||||
|
||||
2. Version History
|
||||
7.0 (4th August, 2005)
|
||||
- Updated driver to use SCSI transport class infrastructure
|
||||
- Upported sequencer and core fixes from last adaptec released
|
||||
version of the driver.
|
||||
6.2.36 (June 3rd, 2003)
|
||||
- Correct code that disables PCI parity error checking.
|
||||
- Correct and simplify handling of the ignore wide residue
|
||||
|
@ -373,13 +373,11 @@ Summary:
|
||||
scsi_activate_tcq - turn on tag command queueing
|
||||
scsi_add_device - creates new scsi device (lu) instance
|
||||
scsi_add_host - perform sysfs registration and SCSI bus scan.
|
||||
scsi_add_timer - (re-)start timer on a SCSI command.
|
||||
scsi_adjust_queue_depth - change the queue depth on a SCSI device
|
||||
scsi_assign_lock - replace default host_lock with given lock
|
||||
scsi_bios_ptable - return copy of block device's partition table
|
||||
scsi_block_requests - prevent further commands being queued to given host
|
||||
scsi_deactivate_tcq - turn off tag command queueing
|
||||
scsi_delete_timer - cancel timer on a SCSI command.
|
||||
scsi_host_alloc - return a new scsi_host instance whose refcount==1
|
||||
scsi_host_get - increments Scsi_Host instance's refcount
|
||||
scsi_host_put - decrements Scsi_Host instance's refcount (free if 0)
|
||||
@ -457,27 +455,6 @@ struct scsi_device * scsi_add_device(struct Scsi_Host *shost,
|
||||
int scsi_add_host(struct Scsi_Host *shost, struct device * dev)
|
||||
|
||||
|
||||
/**
|
||||
* scsi_add_timer - (re-)start timer on a SCSI command.
|
||||
* @scmd: pointer to scsi command instance
|
||||
* @timeout: duration of timeout in "jiffies"
|
||||
* @complete: pointer to function to call if timeout expires
|
||||
*
|
||||
* Returns nothing
|
||||
*
|
||||
* Might block: no
|
||||
*
|
||||
* Notes: Each scsi command has its own timer, and as it is added
|
||||
* to the queue, we set up the timer. When the command completes,
|
||||
* we cancel the timer. An LLD can use this function to change
|
||||
* the existing timeout value.
|
||||
*
|
||||
* Defined in: drivers/scsi/scsi_error.c
|
||||
**/
|
||||
void scsi_add_timer(struct scsi_cmnd *scmd, int timeout,
|
||||
void (*complete)(struct scsi_cmnd *))
|
||||
|
||||
|
||||
/**
|
||||
* scsi_adjust_queue_depth - allow LLD to change queue depth on a SCSI device
|
||||
* @sdev: pointer to SCSI device to change queue depth on
|
||||
@ -565,24 +542,6 @@ void scsi_block_requests(struct Scsi_Host * shost)
|
||||
void scsi_deactivate_tcq(struct scsi_device *sdev, int depth)
|
||||
|
||||
|
||||
/**
|
||||
* scsi_delete_timer - cancel timer on a SCSI command.
|
||||
* @scmd: pointer to scsi command instance
|
||||
*
|
||||
* Returns 1 if able to cancel timer else 0 (i.e. too late or already
|
||||
* cancelled).
|
||||
*
|
||||
* Might block: no [may in the future if it invokes del_timer_sync()]
|
||||
*
|
||||
* Notes: All commands issued by upper levels already have a timeout
|
||||
* associated with them. An LLD can use this function to cancel the
|
||||
* timer.
|
||||
*
|
||||
* Defined in: drivers/scsi/scsi_error.c
|
||||
**/
|
||||
int scsi_delete_timer(struct scsi_cmnd *scmd)
|
||||
|
||||
|
||||
/**
|
||||
* scsi_host_alloc - create a scsi host adapter instance and perform basic
|
||||
* initialization.
|
||||
|
@ -111,24 +111,17 @@ hardware.
|
||||
Interrupts: locally disabled.
|
||||
This call must not sleep
|
||||
|
||||
stop_tx(port,tty_stop)
|
||||
stop_tx(port)
|
||||
Stop transmitting characters. This might be due to the CTS
|
||||
line becoming inactive or the tty layer indicating we want
|
||||
to stop transmission.
|
||||
|
||||
tty_stop: 1 if this call is due to the TTY layer issuing a
|
||||
TTY stop to the driver (equiv to rs_stop).
|
||||
to stop transmission due to an XOFF character.
|
||||
|
||||
Locking: port->lock taken.
|
||||
Interrupts: locally disabled.
|
||||
This call must not sleep
|
||||
|
||||
start_tx(port,tty_start)
|
||||
start transmitting characters. (incidentally, nonempty will
|
||||
always be nonzero, and shouldn't be used - it will be dropped).
|
||||
|
||||
tty_start: 1 if this call was due to the TTY layer issuing
|
||||
a TTY start to the driver (equiv to rs_start)
|
||||
start_tx(port)
|
||||
start transmitting characters.
|
||||
|
||||
Locking: port->lock taken.
|
||||
Interrupts: locally disabled.
|
||||
|
@ -99,6 +99,7 @@ statically linked into the kernel). Those options are:
|
||||
SONYPI_MEYE_MASK 0x0400
|
||||
SONYPI_MEMORYSTICK_MASK 0x0800
|
||||
SONYPI_BATTERY_MASK 0x1000
|
||||
SONYPI_WIRELESS_MASK 0x2000
|
||||
|
||||
useinput: if set (which is the default) two input devices are
|
||||
created, one which interprets the jogdial events as
|
||||
@ -137,6 +138,15 @@ Bugs:
|
||||
speed handling etc). Use ACPI instead of APM if it works on your
|
||||
laptop.
|
||||
|
||||
- sonypi lacks the ability to distinguish between certain key
|
||||
events on some models.
|
||||
|
||||
- some models with the nvidia card (geforce go 6200 tc) uses a
|
||||
different way to adjust the backlighting of the screen. There
|
||||
is a userspace utility to adjust the brightness on those models,
|
||||
which can be downloaded from
|
||||
http://www.acc.umu.se/~erikw/program/smartdimmer-0.1.tar.bz2
|
||||
|
||||
- since all development was done by reverse engineering, there is
|
||||
_absolutely no guarantee_ that this driver will not crash your
|
||||
laptop. Permanently.
|
||||
|
@ -83,19 +83,18 @@ single address space optimization, so that the zap_page_range (from
|
||||
vmtruncate) does not lose sending ipi's to cloned threads that might
|
||||
be spawned underneath it and go to user mode to drag in pte's into tlbs.
|
||||
|
||||
swap_list_lock/swap_device_lock
|
||||
-------------------------------
|
||||
swap_lock
|
||||
--------------
|
||||
The swap devices are chained in priority order from the "swap_list" header.
|
||||
The "swap_list" is used for the round-robin swaphandle allocation strategy.
|
||||
The #free swaphandles is maintained in "nr_swap_pages". These two together
|
||||
are protected by the swap_list_lock.
|
||||
are protected by the swap_lock.
|
||||
|
||||
The swap_device_lock, which is per swap device, protects the reference
|
||||
counts on the corresponding swaphandles, maintained in the "swap_map"
|
||||
array, and the "highest_bit" and "lowest_bit" fields.
|
||||
The swap_lock also protects all the device reference counts on the
|
||||
corresponding swaphandles, maintained in the "swap_map" array, and the
|
||||
"highest_bit" and "lowest_bit" fields.
|
||||
|
||||
Both of these are spinlocks, and are never acquired from intr level. The
|
||||
locking hierarchy is swap_list_lock -> swap_device_lock.
|
||||
The swap_lock is a spinlock, and is never acquired from intr level.
|
||||
|
||||
To prevent races between swap space deletion or async readahead swapins
|
||||
deciding whether a swap handle is being used, ie worthy of being read in
|
||||
|
@ -228,6 +228,26 @@ advantechwdt.c -- Advantech Single Board Computer
|
||||
The GETSTATUS call returns if the device is open or not.
|
||||
[FIXME -- silliness again?]
|
||||
|
||||
booke_wdt.c -- PowerPC BookE Watchdog Timer
|
||||
|
||||
Timeout default varies according to frequency, supports
|
||||
SETTIMEOUT
|
||||
|
||||
Watchdog can not be turned off, CONFIG_WATCHDOG_NOWAYOUT
|
||||
does not make sense
|
||||
|
||||
GETSUPPORT returns the watchdog_info struct, and
|
||||
GETSTATUS returns the supported options. GETBOOTSTATUS
|
||||
returns a 1 if the last reset was caused by the
|
||||
watchdog and a 0 otherwise. This watchdog can not be
|
||||
disabled once it has been started. The wdt_period kernel
|
||||
parameter selects which bit of the time base changing
|
||||
from 0->1 will trigger the watchdog exception. Changing
|
||||
the timeout from the ioctl calls will change the
|
||||
wdt_period as defined above. Finally if you would like to
|
||||
replace the default Watchdog Handler you can implement the
|
||||
WatchdogHandler() function in your own code.
|
||||
|
||||
eurotechwdt.c -- Eurotech CPU-1220/1410
|
||||
|
||||
The timeout can be set using the SETTIMEOUT ioctl and defaults
|
||||
|
43
MAINTAINERS
43
MAINTAINERS
@ -202,13 +202,6 @@ P: Colin Leroy
|
||||
M: colin@colino.net
|
||||
S: Maintained
|
||||
|
||||
ADVANSYS SCSI DRIVER
|
||||
P: Bob Frey
|
||||
M: linux@advansys.com
|
||||
W: http://www.advansys.com/linux.html
|
||||
L: linux-scsi@vger.kernel.org
|
||||
S: Maintained
|
||||
|
||||
AEDSP16 DRIVER
|
||||
P: Riccardo Facchetti
|
||||
M: fizban@tin.it
|
||||
@ -696,6 +689,11 @@ M: dz@debian.org
|
||||
W: http://www.debian.org/~dz/i8k/
|
||||
S: Maintained
|
||||
|
||||
DELL SYSTEMS MANAGEMENT BASE DRIVER (dcdbas)
|
||||
P: Doug Warzecha
|
||||
M: Douglas_Warzecha@dell.com
|
||||
S: Maintained
|
||||
|
||||
DEVICE-MAPPER
|
||||
P: Alasdair Kergon
|
||||
L: dm-devel@redhat.com
|
||||
@ -824,6 +822,13 @@ L: emu10k1-devel@lists.sourceforge.net
|
||||
W: http://sourceforge.net/projects/emu10k1/
|
||||
S: Maintained
|
||||
|
||||
EMULEX LPFC FC SCSI DRIVER
|
||||
P: James Smart
|
||||
M: james.smart@emulex.com
|
||||
L: linux-scsi@vger.kernel.org
|
||||
W: http://sourceforge.net/projects/lpfcxxxx
|
||||
S: Supported
|
||||
|
||||
EPSON 1355 FRAMEBUFFER DRIVER
|
||||
P: Christopher Hoover
|
||||
M: ch@murgatroid.com, ch@hpl.hp.com
|
||||
@ -879,7 +884,7 @@ S: Maintained
|
||||
|
||||
FILESYSTEMS (VFS and infrastructure)
|
||||
P: Alexander Viro
|
||||
M: viro@parcelfarce.linux.theplanet.co.uk
|
||||
M: viro@zeniv.linux.org.uk
|
||||
S: Maintained
|
||||
|
||||
FIRMWARE LOADER (request_firmware)
|
||||
@ -933,6 +938,13 @@ M: khc@pm.waw.pl
|
||||
W: http://www.kernel.org/pub/linux/utils/net/hdlc/
|
||||
S: Maintained
|
||||
|
||||
HARDWARE MONITORING
|
||||
P: Jean Delvare
|
||||
M: khali@linux-fr.org
|
||||
L: lm-sensors@lm-sensors.org
|
||||
W: http://www.lm-sensors.nu/
|
||||
S: Maintained
|
||||
|
||||
HARMONY SOUND DRIVER
|
||||
P: Kyle McMartin
|
||||
M: kyle@parisc-linux.org
|
||||
@ -991,6 +1003,13 @@ M: mike.miller@hp.com
|
||||
L: iss_storagedev@hp.com
|
||||
S: Supported
|
||||
|
||||
HOST AP DRIVER
|
||||
P: Jouni Malinen
|
||||
M: jkmaline@cc.hut.fi
|
||||
L: hostap@shmoo.com
|
||||
W: http://hostap.epitest.fi/
|
||||
S: Maintained
|
||||
|
||||
HP100: Driver for HP 10/100 Mbit/s Voice Grade Network Adapter Series
|
||||
P: Jaroslav Kysela
|
||||
M: perex@suse.cz
|
||||
@ -1007,7 +1026,7 @@ P: William Irwin
|
||||
M: wli@holomorphy.com
|
||||
S: Maintained
|
||||
|
||||
I2C AND SENSORS DRIVERS
|
||||
I2C SUBSYSTEM
|
||||
P: Greg Kroah-Hartman
|
||||
M: greg@kroah.com
|
||||
P: Jean Delvare
|
||||
@ -1953,7 +1972,6 @@ S: Supported
|
||||
|
||||
ROCKETPORT DRIVER
|
||||
P: Comtrol Corp.
|
||||
M: support@comtrol.com
|
||||
W: http://www.comtrol.com
|
||||
S: Maintained
|
||||
|
||||
@ -2643,11 +2661,6 @@ S: Maintained
|
||||
UCLINUX (AND M68KNOMMU)
|
||||
P: Greg Ungerer
|
||||
M: gerg@uclinux.org
|
||||
M: gerg@snapgear.com
|
||||
P: David McCullough
|
||||
M: davidm@snapgear.com
|
||||
P: D. Jeff Dionne (created first uClinux port)
|
||||
M: jeff@uclinux.org
|
||||
W: http://www.uclinux.org/
|
||||
L: uclinux-dev@uclinux.org (subscribers-only)
|
||||
S: Maintained
|
||||
|
164
Makefile
164
Makefile
@ -109,10 +109,9 @@ $(if $(KBUILD_OUTPUT),, \
|
||||
.PHONY: $(MAKECMDGOALS)
|
||||
|
||||
$(filter-out _all,$(MAKECMDGOALS)) _all:
|
||||
$(if $(KBUILD_VERBOSE:1=),@)$(MAKE) -C $(KBUILD_OUTPUT) \
|
||||
KBUILD_SRC=$(CURDIR) KBUILD_VERBOSE=$(KBUILD_VERBOSE) \
|
||||
KBUILD_CHECK=$(KBUILD_CHECK) KBUILD_EXTMOD="$(KBUILD_EXTMOD)" \
|
||||
-f $(CURDIR)/Makefile $@
|
||||
$(if $(KBUILD_VERBOSE:1=),@)$(MAKE) -C $(KBUILD_OUTPUT) \
|
||||
KBUILD_SRC=$(CURDIR) \
|
||||
KBUILD_EXTMOD="$(KBUILD_EXTMOD)" -f $(CURDIR)/Makefile $@
|
||||
|
||||
# Leave processing to above invocation of make
|
||||
skip-makefile := 1
|
||||
@ -233,7 +232,7 @@ ifeq ($(MAKECMDGOALS),)
|
||||
KBUILD_MODULES := 1
|
||||
endif
|
||||
|
||||
export KBUILD_MODULES KBUILD_BUILTIN KBUILD_VERBOSE
|
||||
export KBUILD_MODULES KBUILD_BUILTIN
|
||||
export KBUILD_CHECKSRC KBUILD_SRC KBUILD_EXTMOD
|
||||
|
||||
# Beautify output
|
||||
@ -309,6 +308,9 @@ cc-version = $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-version.sh \
|
||||
# Look for make include files relative to root of kernel src
|
||||
MAKEFLAGS += --include-dir=$(srctree)
|
||||
|
||||
# We need some generic definitions
|
||||
include $(srctree)/scripts/Kbuild.include
|
||||
|
||||
# For maximum performance (+ possibly random breakage, uncomment
|
||||
# the following)
|
||||
|
||||
@ -348,7 +350,7 @@ LINUXINCLUDE := -Iinclude \
|
||||
|
||||
CPPFLAGS := -D__KERNEL__ $(LINUXINCLUDE)
|
||||
|
||||
CFLAGS := -Wall -Wstrict-prototypes -Wno-trigraphs \
|
||||
CFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
|
||||
-fno-strict-aliasing -fno-common \
|
||||
-ffreestanding
|
||||
AFLAGS := -D__ASSEMBLY__
|
||||
@ -367,15 +369,10 @@ export AFLAGS AFLAGS_KERNEL AFLAGS_MODULE
|
||||
# even be read-only.
|
||||
export MODVERDIR := $(if $(KBUILD_EXTMOD),$(firstword $(KBUILD_EXTMOD))/).tmp_versions
|
||||
|
||||
# The temporary file to save gcc -MD generated dependencies must not
|
||||
# contain a comma
|
||||
comma := ,
|
||||
depfile = $(subst $(comma),_,$(@D)/.$(@F).d)
|
||||
|
||||
# Files to ignore in find ... statements
|
||||
|
||||
RCS_FIND_IGNORE := \( -name SCCS -o -name BitKeeper -o -name .svn -o -name CVS -o -name .pc \) -prune -o
|
||||
RCS_TAR_IGNORE := --exclude SCCS --exclude BitKeeper --exclude .svn --exclude CVS --exclude .pc
|
||||
RCS_FIND_IGNORE := \( -name SCCS -o -name BitKeeper -o -name .svn -o -name CVS -o -name .pc -o -name .hg \) -prune -o
|
||||
RCS_TAR_IGNORE := --exclude SCCS --exclude BitKeeper --exclude .svn --exclude CVS --exclude .pc --exclude .hg
|
||||
|
||||
# ===========================================================================
|
||||
# Rules shared between *config targets and build targets
|
||||
@ -551,6 +548,26 @@ export KBUILD_IMAGE ?= vmlinux
|
||||
# images. Default is /boot, but you can set it to other values
|
||||
export INSTALL_PATH ?= /boot
|
||||
|
||||
# If CONFIG_LOCALVERSION_AUTO is set, we automatically perform some tests
|
||||
# and try to determine if the current source tree is a release tree, of any sort,
|
||||
# or if is a pure development tree.
|
||||
#
|
||||
# A 'release tree' is any tree with a git TAG associated
|
||||
# with it. The primary goal of this is to make it safe for a native
|
||||
# git/CVS/SVN user to build a release tree (i.e, 2.6.9) and also to
|
||||
# continue developing against the current Linus tree, without having the Linus
|
||||
# tree overwrite the 2.6.9 tree when installed.
|
||||
#
|
||||
# Currently, only git is supported.
|
||||
# Other SCMs can edit scripts/setlocalversion and add the appropriate
|
||||
# checks as needed.
|
||||
|
||||
|
||||
ifdef CONFIG_LOCALVERSION_AUTO
|
||||
localversion-auto := $(shell $(PERL) $(srctree)/scripts/setlocalversion $(srctree))
|
||||
LOCALVERSION := $(LOCALVERSION)$(localversion-auto)
|
||||
endif
|
||||
|
||||
#
|
||||
# INSTALL_MOD_PATH specifies a prefix to MODLIB for module directory
|
||||
# relocations required by build roots. This is not defined in the
|
||||
@ -691,8 +708,10 @@ endef
|
||||
|
||||
# Update vmlinux version before link
|
||||
# Use + in front of this rule to silent warning about make -j1
|
||||
# First command is ':' to allow us to use + in front of this rule
|
||||
cmd_ksym_ld = $(cmd_vmlinux__)
|
||||
define rule_ksym_ld
|
||||
:
|
||||
+$(call cmd,vmlinux_version)
|
||||
$(call cmd,vmlinux__)
|
||||
$(Q)echo 'cmd_$@ := $(cmd_vmlinux__)' > $(@D)/.$(@F).cmd
|
||||
@ -722,6 +741,16 @@ quiet_cmd_kallsyms = KSYM $@
|
||||
# Needs to visit scripts/ before $(KALLSYMS) can be used.
|
||||
$(KALLSYMS): scripts ;
|
||||
|
||||
# Generate some data for debugging strange kallsyms problems
|
||||
debug_kallsyms: .tmp_map$(last_kallsyms)
|
||||
|
||||
.tmp_map%: .tmp_vmlinux% FORCE
|
||||
($(OBJDUMP) -h $< | $(AWK) '/^ +[0-9]/{print $$4 " 0 " $$2}'; $(NM) $<) | sort > $@
|
||||
|
||||
.tmp_map3: .tmp_map2
|
||||
|
||||
.tmp_map2: .tmp_map1
|
||||
|
||||
endif # ifdef CONFIG_KALLSYMS
|
||||
|
||||
# vmlinux image - including updated kernel symbols
|
||||
@ -757,7 +786,7 @@ $(vmlinux-dirs): prepare-all scripts
|
||||
prepare2:
|
||||
ifneq ($(KBUILD_SRC),)
|
||||
@echo ' Using $(srctree) as source for kernel'
|
||||
$(Q)if [ -h $(srctree)/include/asm -o -f $(srctree)/.config ]; then \
|
||||
$(Q)if [ -f $(srctree)/.config ]; then \
|
||||
echo " $(srctree) is not clean, please run 'make mrproper'";\
|
||||
echo " in the '$(srctree)' directory.";\
|
||||
/bin/false; \
|
||||
@ -769,7 +798,8 @@ endif
|
||||
# prepare1 creates a makefile if using a separate output directory
|
||||
prepare1: prepare2 outputmakefile
|
||||
|
||||
prepare0: prepare1 include/linux/version.h include/asm include/config/MARKER
|
||||
prepare0: prepare1 include/linux/version.h include/asm \
|
||||
include/config/MARKER
|
||||
ifneq ($(KBUILD_MODULES),)
|
||||
$(Q)rm -rf $(MODVERDIR)
|
||||
$(Q)mkdir -p $(MODVERDIR)
|
||||
@ -875,7 +905,7 @@ modules_install: _modinst_ _modinst_post
|
||||
|
||||
.PHONY: _modinst_
|
||||
_modinst_:
|
||||
@if [ -z "`$(DEPMOD) -V | grep module-init-tools`" ]; then \
|
||||
@if [ -z "`$(DEPMOD) -V 2>/dev/null | grep module-init-tools`" ]; then \
|
||||
echo "Warning: you may need to install module-init-tools"; \
|
||||
echo "See http://www.codemonkey.org.uk/docs/post-halloween-2.6.txt";\
|
||||
sleep 1; \
|
||||
@ -1159,37 +1189,49 @@ else
|
||||
__srctree = $(srctree)/
|
||||
endif
|
||||
|
||||
ALLSOURCE_ARCHS := $(ARCH)
|
||||
|
||||
define all-sources
|
||||
( find $(__srctree) $(RCS_FIND_IGNORE) \
|
||||
\( -name include -o -name arch \) -prune -o \
|
||||
-name '*.[chS]' -print; \
|
||||
find $(__srctree)arch/$(ARCH) $(RCS_FIND_IGNORE) \
|
||||
-name '*.[chS]' -print; \
|
||||
for ARCH in $(ALLSOURCE_ARCHS) ; do \
|
||||
find $(__srctree)arch/$${ARCH} $(RCS_FIND_IGNORE) \
|
||||
-name '*.[chS]' -print; \
|
||||
done ; \
|
||||
find $(__srctree)security/selinux/include $(RCS_FIND_IGNORE) \
|
||||
-name '*.[chS]' -print; \
|
||||
find $(__srctree)include $(RCS_FIND_IGNORE) \
|
||||
\( -name config -o -name 'asm-*' \) -prune \
|
||||
-o -name '*.[chS]' -print; \
|
||||
find $(__srctree)include/asm-$(ARCH) $(RCS_FIND_IGNORE) \
|
||||
-name '*.[chS]' -print; \
|
||||
for ARCH in $(ALLSOURCE_ARCHS) ; do \
|
||||
find $(__srctree)include/asm-$${ARCH} $(RCS_FIND_IGNORE) \
|
||||
-name '*.[chS]' -print; \
|
||||
done ; \
|
||||
find $(__srctree)include/asm-generic $(RCS_FIND_IGNORE) \
|
||||
-name '*.[chS]' -print )
|
||||
endef
|
||||
|
||||
quiet_cmd_cscope-file = FILELST cscope.files
|
||||
cmd_cscope-file = $(all-sources) > cscope.files
|
||||
cmd_cscope-file = (echo \-k; echo \-q; $(all-sources)) > cscope.files
|
||||
|
||||
quiet_cmd_cscope = MAKE cscope.out
|
||||
cmd_cscope = cscope -k -b -q
|
||||
cmd_cscope = cscope -b
|
||||
|
||||
cscope: FORCE
|
||||
$(call cmd,cscope-file)
|
||||
$(call cmd,cscope)
|
||||
|
||||
quiet_cmd_TAGS = MAKE $@
|
||||
cmd_TAGS = $(all-sources) | etags -
|
||||
define cmd_TAGS
|
||||
rm -f $@; \
|
||||
ETAGSF=`etags --version | grep -i exuberant >/dev/null && echo "-I __initdata,__exitdata,EXPORT_SYMBOL,EXPORT_SYMBOL_GPL --extra=+f"`; \
|
||||
$(all-sources) | xargs etags $$ETAGSF -a
|
||||
endef
|
||||
|
||||
TAGS: FORCE
|
||||
$(call cmd,TAGS)
|
||||
|
||||
# Exuberant ctags works better with -I
|
||||
|
||||
quiet_cmd_tags = MAKE $@
|
||||
define cmd_tags
|
||||
@ -1198,9 +1240,6 @@ define cmd_tags
|
||||
$(all-sources) | xargs ctags $$CTAGSF -a
|
||||
endef
|
||||
|
||||
TAGS: FORCE
|
||||
$(call cmd,TAGS)
|
||||
|
||||
tags: FORCE
|
||||
$(call cmd,tags)
|
||||
|
||||
@ -1268,82 +1307,11 @@ ifneq ($(cmd_files),)
|
||||
include $(cmd_files)
|
||||
endif
|
||||
|
||||
# Execute command and generate cmd file
|
||||
if_changed = $(if $(strip $? \
|
||||
$(filter-out $(cmd_$(1)),$(cmd_$@))\
|
||||
$(filter-out $(cmd_$@),$(cmd_$(1)))),\
|
||||
@set -e; \
|
||||
$(if $($(quiet)cmd_$(1)),echo ' $(subst ','\'',$($(quiet)cmd_$(1)))';) \
|
||||
$(cmd_$(1)); \
|
||||
echo 'cmd_$@ := $(subst $$,$$$$,$(subst ','\'',$(cmd_$(1))))' > $(@D)/.$(@F).cmd)
|
||||
|
||||
|
||||
# execute the command and also postprocess generated .d dependencies
|
||||
# file
|
||||
if_changed_dep = $(if $(strip $? $(filter-out FORCE $(wildcard $^),$^)\
|
||||
$(filter-out $(cmd_$(1)),$(cmd_$@))\
|
||||
$(filter-out $(cmd_$@),$(cmd_$(1)))),\
|
||||
$(Q)set -e; \
|
||||
$(if $($(quiet)cmd_$(1)),echo ' $(subst ','\'',$($(quiet)cmd_$(1)))';) \
|
||||
$(cmd_$(1)); \
|
||||
scripts/basic/fixdep $(depfile) $@ '$(subst $$,$$$$,$(subst ','\'',$(cmd_$(1))))' > $(@D)/.$(@F).tmp; \
|
||||
rm -f $(depfile); \
|
||||
mv -f $(@D)/.$(@F).tmp $(@D)/.$(@F).cmd)
|
||||
|
||||
# Usage: $(call if_changed_rule,foo)
|
||||
# will check if $(cmd_foo) changed, or any of the prequisites changed,
|
||||
# and if so will execute $(rule_foo)
|
||||
|
||||
if_changed_rule = $(if $(strip $? \
|
||||
$(filter-out $(cmd_$(1)),$(cmd_$(@F)))\
|
||||
$(filter-out $(cmd_$(@F)),$(cmd_$(1)))),\
|
||||
$(Q)$(rule_$(1)))
|
||||
|
||||
# If quiet is set, only print short version of command
|
||||
|
||||
cmd = @$(if $($(quiet)cmd_$(1)),echo ' $($(quiet)cmd_$(1))' &&) $(cmd_$(1))
|
||||
|
||||
# filechk is used to check if the content of a generated file is updated.
|
||||
# Sample usage:
|
||||
# define filechk_sample
|
||||
# echo $KERNELRELEASE
|
||||
# endef
|
||||
# version.h : Makefile
|
||||
# $(call filechk,sample)
|
||||
# The rule defined shall write to stdout the content of the new file.
|
||||
# The existing file will be compared with the new one.
|
||||
# - If no file exist it is created
|
||||
# - If the content differ the new file is used
|
||||
# - If they are equal no change, and no timestamp update
|
||||
|
||||
define filechk
|
||||
@set -e; \
|
||||
echo ' CHK $@'; \
|
||||
mkdir -p $(dir $@); \
|
||||
$(filechk_$(1)) < $< > $@.tmp; \
|
||||
if [ -r $@ ] && cmp -s $@ $@.tmp; then \
|
||||
rm -f $@.tmp; \
|
||||
else \
|
||||
echo ' UPD $@'; \
|
||||
mv -f $@.tmp $@; \
|
||||
fi
|
||||
endef
|
||||
|
||||
# Shorthand for $(Q)$(MAKE) -f scripts/Makefile.build obj=dir
|
||||
# Usage:
|
||||
# $(Q)$(MAKE) $(build)=dir
|
||||
build := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.build obj
|
||||
|
||||
# Shorthand for $(Q)$(MAKE) -f scripts/Makefile.clean obj=dir
|
||||
# Usage:
|
||||
# $(Q)$(MAKE) $(clean)=dir
|
||||
clean := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.clean obj
|
||||
|
||||
# $(call descend,<dir>,<target>)
|
||||
# Recursively call a sub-make in <dir> with target <target>
|
||||
# Usage is deprecated, because make does not see this as an invocation of make.
|
||||
descend =$(Q)$(MAKE) -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.build obj=$(1) $(2)
|
||||
|
||||
endif # skip-makefile
|
||||
|
||||
FORCE:
|
||||
|
@ -479,6 +479,9 @@ config EISA
|
||||
depends on ALPHA_GENERIC || ALPHA_JENSEN || ALPHA_ALCOR || ALPHA_MIKASA || ALPHA_SABLE || ALPHA_LYNX || ALPHA_NORITAKE || ALPHA_RAWHIDE
|
||||
default y
|
||||
|
||||
config ARCH_MAY_HAVE_PC_FDC
|
||||
def_bool y
|
||||
|
||||
config SMP
|
||||
bool "Symmetric multi-processing support"
|
||||
depends on ALPHA_SABLE || ALPHA_LYNX || ALPHA_RAWHIDE || ALPHA_DP264 || ALPHA_WILDFIRE || ALPHA_TITAN || ALPHA_GENERIC || ALPHA_SHARK || ALPHA_MARVEL
|
||||
|
@ -149,7 +149,7 @@ irqreturn_t timer_interrupt(int irq, void *dev, struct pt_regs * regs)
|
||||
* CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
|
||||
* called as close as possible to 500 ms before the new second starts.
|
||||
*/
|
||||
if ((time_status & STA_UNSYNC) == 0
|
||||
if (ntp_synced()
|
||||
&& xtime.tv_sec > state.last_rtc_update + 660
|
||||
&& xtime.tv_nsec >= 500000 - ((unsigned) TICK_SIZE) / 2
|
||||
&& xtime.tv_nsec <= 500000 + ((unsigned) TICK_SIZE) / 2) {
|
||||
@ -502,10 +502,7 @@ do_settimeofday(struct timespec *tv)
|
||||
set_normalized_timespec(&xtime, sec, nsec);
|
||||
set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
|
||||
|
||||
time_adjust = 0; /* stop active adjtime() */
|
||||
time_status |= STA_UNSYNC;
|
||||
time_maxerror = NTP_PHASE_LIMIT;
|
||||
time_esterror = NTP_PHASE_LIMIT;
|
||||
ntp_clear();
|
||||
|
||||
write_sequnlock_irq(&xtime_lock);
|
||||
clock_was_set();
|
||||
|
@ -64,6 +64,9 @@ config GENERIC_CALIBRATE_DELAY
|
||||
config GENERIC_BUST_SPINLOCK
|
||||
bool
|
||||
|
||||
config ARCH_MAY_HAVE_PC_FDC
|
||||
bool
|
||||
|
||||
config GENERIC_ISA_DMA
|
||||
bool
|
||||
|
||||
@ -150,6 +153,7 @@ config ARCH_RPC
|
||||
select ARCH_ACORN
|
||||
select FIQ
|
||||
select TIMER_ACORN
|
||||
select ARCH_MAY_HAVE_PC_FDC
|
||||
help
|
||||
On the Acorn Risc-PC, Linux can support the internal IDE disk and
|
||||
CD-ROM interface, serial and parallel port, and the floppy drive.
|
||||
@ -365,8 +369,8 @@ config NO_IDLE_HZ
|
||||
|
||||
Please note that dynamic tick may affect the accuracy of
|
||||
timekeeping on some platforms depending on the implementation.
|
||||
Currently at least OMAP platform is known to have accurate
|
||||
timekeeping with dynamic tick.
|
||||
Currently at least OMAP, PXA2xx and SA11x0 platforms are known
|
||||
to have accurate timekeeping with dynamic tick.
|
||||
|
||||
config ARCH_DISCONTIGMEM_ENABLE
|
||||
bool
|
||||
|
@ -7,7 +7,8 @@
|
||||
* so we have to figure out the machine for ourselves...
|
||||
*
|
||||
* Support for Poodle, Corgi (SL-C700), Shepherd (SL-C750)
|
||||
* and Husky (SL-C760).
|
||||
* Husky (SL-C760), Tosa (SL-C6000), Spitz (SL-C3000),
|
||||
* Akita (SL-C1000) and Borzoi (SL-C3100).
|
||||
*
|
||||
*/
|
||||
|
||||
@ -23,6 +24,22 @@
|
||||
|
||||
__SharpSL_start:
|
||||
|
||||
/* Check for TC6393 - if found we have a Tosa */
|
||||
ldr r7, .TOSAID
|
||||
mov r1, #0x10000000 @ Base address of TC6393 chip
|
||||
mov r6, #0x03
|
||||
ldrh r3, [r1, #8] @ Load TC6393XB Revison: This is 0x0003
|
||||
cmp r6, r3
|
||||
beq .SHARPEND @ Success -> tosa
|
||||
|
||||
/* Check for pxa270 - if found, branch */
|
||||
mrc p15, 0, r4, c0, c0 @ Get Processor ID
|
||||
and r4, r4, #0xffffff00
|
||||
ldr r3, .PXA270ID
|
||||
cmp r4, r3
|
||||
beq .PXA270
|
||||
|
||||
/* Check for w100 - if not found we have a Poodle */
|
||||
ldr r1, .W100ADDR @ Base address of w100 chip + regs offset
|
||||
|
||||
mov r6, #0x31 @ Load Magic Init value
|
||||
@ -30,7 +47,7 @@ __SharpSL_start:
|
||||
mov r5, #0x3000
|
||||
.W100LOOP:
|
||||
subs r5, r5, #1
|
||||
bne .W100LOOP
|
||||
bne .W100LOOP
|
||||
mov r6, #0x30 @ Load 2nd Magic Init value
|
||||
str r6, [r1, #0x280] @ to SCRATCH_UMSK
|
||||
|
||||
@ -40,45 +57,52 @@ __SharpSL_start:
|
||||
cmp r6, r3
|
||||
bne .SHARPEND @ We have no w100 - Poodle
|
||||
|
||||
mrc p15, 0, r6, c0, c0 @ Get Processor ID
|
||||
and r6, r6, #0xffffff00
|
||||
/* Check for pxa250 - if found we have a Corgi */
|
||||
ldr r7, .CORGIID
|
||||
ldr r3, .PXA255ID
|
||||
cmp r6, r3
|
||||
cmp r4, r3
|
||||
blo .SHARPEND @ We have a PXA250 - Corgi
|
||||
|
||||
mov r1, #0x0c000000 @ Base address of NAND chip
|
||||
ldrb r3, [r1, #24] @ Load FLASHCTL
|
||||
bic r3, r3, #0x11 @ SET NCE
|
||||
orr r3, r3, #0x0a @ SET CLR + FLWP
|
||||
strb r3, [r1, #24] @ Save to FLASHCTL
|
||||
mov r2, #0x90 @ Command "readid"
|
||||
strb r2, [r1, #20] @ Save to FLASHIO
|
||||
bic r3, r3, #2 @ CLR CLE
|
||||
orr r3, r3, #4 @ SET ALE
|
||||
strb r3, [r1, #24] @ Save to FLASHCTL
|
||||
mov r2, #0 @ Address 0x00
|
||||
strb r2, [r1, #20] @ Save to FLASHIO
|
||||
bic r3, r3, #4 @ CLR ALE
|
||||
strb r3, [r1, #24] @ Save to FLASHCTL
|
||||
.SHARP1:
|
||||
ldrb r3, [r1, #24] @ Load FLASHCTL
|
||||
tst r3, #32 @ Is chip ready?
|
||||
beq .SHARP1
|
||||
ldrb r2, [r1, #20] @ NAND Manufacturer ID
|
||||
ldrb r3, [r1, #20] @ NAND Chip ID
|
||||
/* Check for 64MiB flash - if found we have a Shepherd */
|
||||
bl get_flash_ids
|
||||
ldr r7, .SHEPHERDID
|
||||
cmp r3, #0x76 @ 64MiB flash
|
||||
beq .SHARPEND @ We have Shepherd
|
||||
|
||||
/* Must be a Husky */
|
||||
ldr r7, .HUSKYID @ Must be Husky
|
||||
b .SHARPEND
|
||||
|
||||
.PXA270:
|
||||
/* Check for 16MiB flash - if found we have Spitz */
|
||||
bl get_flash_ids
|
||||
ldr r7, .SPITZID
|
||||
cmp r3, #0x73 @ 16MiB flash
|
||||
beq .SHARPEND @ We have Spitz
|
||||
|
||||
/* Check for a second SCOOP chip - if found we have Borzoi */
|
||||
ldr r1, .SCOOP2ADDR
|
||||
ldr r7, .BORZOIID
|
||||
mov r6, #0x0140
|
||||
strh r6, [r1]
|
||||
ldrh r6, [r1]
|
||||
cmp r6, #0x0140
|
||||
beq .SHARPEND @ We have Borzoi
|
||||
|
||||
/* Must be Akita */
|
||||
ldr r7, .AKITAID
|
||||
b .SHARPEND @ We have Borzoi
|
||||
|
||||
.PXA255ID:
|
||||
.word 0x69052d00 @ PXA255 Processor ID
|
||||
.PXA270ID:
|
||||
.word 0x69054100 @ PXA270 Processor ID
|
||||
.W100ID:
|
||||
.word 0x57411002 @ w100 Chip ID
|
||||
.W100ADDR:
|
||||
.word 0x08010000 @ w100 Chip ID Reg Address
|
||||
.SCOOP2ADDR:
|
||||
.word 0x08800040
|
||||
.POODLEID:
|
||||
.word MACH_TYPE_POODLE
|
||||
.CORGIID:
|
||||
@ -87,6 +111,41 @@ __SharpSL_start:
|
||||
.word MACH_TYPE_SHEPHERD
|
||||
.HUSKYID:
|
||||
.word MACH_TYPE_HUSKY
|
||||
.TOSAID:
|
||||
.word MACH_TYPE_TOSA
|
||||
.SPITZID:
|
||||
.word MACH_TYPE_SPITZ
|
||||
.AKITAID:
|
||||
.word MACH_TYPE_AKITA
|
||||
.BORZOIID:
|
||||
.word MACH_TYPE_BORZOI
|
||||
|
||||
/*
|
||||
* Return: r2 - NAND Manufacturer ID
|
||||
* r3 - NAND Chip ID
|
||||
* Corrupts: r1
|
||||
*/
|
||||
get_flash_ids:
|
||||
mov r1, #0x0c000000 @ Base address of NAND chip
|
||||
ldrb r3, [r1, #24] @ Load FLASHCTL
|
||||
bic r3, r3, #0x11 @ SET NCE
|
||||
orr r3, r3, #0x0a @ SET CLR + FLWP
|
||||
strb r3, [r1, #24] @ Save to FLASHCTL
|
||||
mov r2, #0x90 @ Command "readid"
|
||||
strb r2, [r1, #20] @ Save to FLASHIO
|
||||
bic r3, r3, #2 @ CLR CLE
|
||||
orr r3, r3, #4 @ SET ALE
|
||||
strb r3, [r1, #24] @ Save to FLASHCTL
|
||||
mov r2, #0 @ Address 0x00
|
||||
strb r2, [r1, #20] @ Save to FLASHIO
|
||||
bic r3, r3, #4 @ CLR ALE
|
||||
strb r3, [r1, #24] @ Save to FLASHCTL
|
||||
.fids1:
|
||||
ldrb r3, [r1, #24] @ Load FLASHCTL
|
||||
tst r3, #32 @ Is chip ready?
|
||||
beq .fids1
|
||||
ldrb r2, [r1, #20] @ NAND Manufacturer ID
|
||||
ldrb r3, [r1, #20] @ NAND Chip ID
|
||||
mov pc, lr
|
||||
|
||||
.SHARPEND:
|
||||
|
||||
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/smp.h>
|
||||
#include <linux/cpumask.h>
|
||||
|
||||
#include <asm/irq.h>
|
||||
#include <asm/io.h>
|
||||
|
@ -177,7 +177,7 @@ static void locomo_handler(unsigned int irq, struct irqdesc *desc,
|
||||
d = irq_desc + irq;
|
||||
for (i = 0; i <= 3; i++, d++, irq++) {
|
||||
if (req & (0x0100 << i)) {
|
||||
d->handle(irq, d, regs);
|
||||
desc_handle_irq(irq, d, regs);
|
||||
}
|
||||
|
||||
}
|
||||
@ -220,7 +220,7 @@ static void locomo_key_handler(unsigned int irq, struct irqdesc *desc,
|
||||
|
||||
if (locomo_readl(mapbase + LOCOMO_KEYBOARD + LOCOMO_KIC) & 0x0001) {
|
||||
d = irq_desc + LOCOMO_IRQ_KEY_START;
|
||||
d->handle(LOCOMO_IRQ_KEY_START, d, regs);
|
||||
desc_handle_irq(LOCOMO_IRQ_KEY_START, d, regs);
|
||||
}
|
||||
}
|
||||
|
||||
@ -273,7 +273,7 @@ static void locomo_gpio_handler(unsigned int irq, struct irqdesc *desc,
|
||||
d = irq_desc + LOCOMO_IRQ_GPIO_START;
|
||||
for (i = 0; i <= 15; i++, irq++, d++) {
|
||||
if (req & (0x0001 << i)) {
|
||||
d->handle(irq, d, regs);
|
||||
desc_handle_irq(irq, d, regs);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -328,7 +328,7 @@ static void locomo_lt_handler(unsigned int irq, struct irqdesc *desc,
|
||||
|
||||
if (locomo_readl(mapbase + LOCOMO_LTINT) & 0x0001) {
|
||||
d = irq_desc + LOCOMO_IRQ_LT_START;
|
||||
d->handle(LOCOMO_IRQ_LT_START, d, regs);
|
||||
desc_handle_irq(LOCOMO_IRQ_LT_START, d, regs);
|
||||
}
|
||||
}
|
||||
|
||||
@ -379,7 +379,7 @@ static void locomo_spi_handler(unsigned int irq, struct irqdesc *desc,
|
||||
|
||||
for (i = 0; i <= 3; i++, irq++, d++) {
|
||||
if (req & (0x0001 << i)) {
|
||||
d->handle(irq, d, regs);
|
||||
desc_handle_irq(irq, d, regs);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -651,15 +651,15 @@ __locomo_probe(struct device *me, struct resource *mem, int irq)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int locomo_remove_child(struct device *dev, void *data)
|
||||
{
|
||||
device_unregister(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __locomo_remove(struct locomo *lchip)
|
||||
{
|
||||
struct list_head *l, *n;
|
||||
|
||||
list_for_each_safe(l, n, &lchip->dev->children) {
|
||||
struct device *d = list_to_dev(l);
|
||||
|
||||
device_unregister(d);
|
||||
}
|
||||
device_for_each_child(lchip->dev, NULL, locomo_remove_child);
|
||||
|
||||
if (lchip->irq != NO_IRQ) {
|
||||
set_irq_chained_handler(lchip->irq, NULL);
|
||||
|
@ -268,8 +268,8 @@ static struct irqchip sa1111_low_chip = {
|
||||
.mask = sa1111_mask_lowirq,
|
||||
.unmask = sa1111_unmask_lowirq,
|
||||
.retrigger = sa1111_retrigger_lowirq,
|
||||
.type = sa1111_type_lowirq,
|
||||
.wake = sa1111_wake_lowirq,
|
||||
.set_type = sa1111_type_lowirq,
|
||||
.set_wake = sa1111_wake_lowirq,
|
||||
};
|
||||
|
||||
static void sa1111_mask_highirq(unsigned int irq)
|
||||
@ -364,8 +364,8 @@ static struct irqchip sa1111_high_chip = {
|
||||
.mask = sa1111_mask_highirq,
|
||||
.unmask = sa1111_unmask_highirq,
|
||||
.retrigger = sa1111_retrigger_highirq,
|
||||
.type = sa1111_type_highirq,
|
||||
.wake = sa1111_wake_highirq,
|
||||
.set_type = sa1111_type_highirq,
|
||||
.set_wake = sa1111_wake_highirq,
|
||||
};
|
||||
|
||||
static void sa1111_setup_irq(struct sa1111 *sachip)
|
||||
|
@ -17,6 +17,12 @@
|
||||
|
||||
#define SCOOP_REG(d,adr) (*(volatile unsigned short*)(d +(adr)))
|
||||
|
||||
/* PCMCIA to Scoop linkage structures for pxa2xx_sharpsl.c
|
||||
There is no easy way to link multiple scoop devices into one
|
||||
single entity for the pxa2xx_pcmcia device */
|
||||
int scoop_num;
|
||||
struct scoop_pcmcia_dev *scoop_devs;
|
||||
|
||||
struct scoop_dev {
|
||||
void *base;
|
||||
spinlock_t scoop_lock;
|
||||
|
@ -1,7 +1,7 @@
|
||||
#
|
||||
# Automatically generated make config: don't edit
|
||||
# Linux kernel version: 2.6.13-rc2
|
||||
# Fri Jul 8 04:49:34 2005
|
||||
# Linux kernel version: 2.6.13
|
||||
# Mon Sep 5 18:07:12 2005
|
||||
#
|
||||
CONFIG_ARM=y
|
||||
CONFIG_MMU=y
|
||||
@ -102,9 +102,11 @@ CONFIG_OMAP_MUX_WARNINGS=y
|
||||
# CONFIG_OMAP_MPU_TIMER is not set
|
||||
CONFIG_OMAP_32K_TIMER=y
|
||||
CONFIG_OMAP_32K_TIMER_HZ=128
|
||||
# CONFIG_OMAP_DM_TIMER is not set
|
||||
CONFIG_OMAP_LL_DEBUG_UART1=y
|
||||
# CONFIG_OMAP_LL_DEBUG_UART2 is not set
|
||||
# CONFIG_OMAP_LL_DEBUG_UART3 is not set
|
||||
CONFIG_OMAP_SERIAL_WAKE=y
|
||||
|
||||
#
|
||||
# OMAP Core Type
|
||||
@ -166,7 +168,6 @@ CONFIG_ISA_DMA_API=y
|
||||
#
|
||||
# Kernel Features
|
||||
#
|
||||
# CONFIG_SMP is not set
|
||||
CONFIG_PREEMPT=y
|
||||
CONFIG_NO_IDLE_HZ=y
|
||||
# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
|
||||
@ -229,6 +230,68 @@ CONFIG_BINFMT_AOUT=y
|
||||
CONFIG_PM=y
|
||||
# CONFIG_APM is not set
|
||||
|
||||
#
|
||||
# Networking
|
||||
#
|
||||
CONFIG_NET=y
|
||||
|
||||
#
|
||||
# Networking options
|
||||
#
|
||||
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 is not set
|
||||
# CONFIG_NET_IPIP is not set
|
||||
# CONFIG_NET_IPGRE is not set
|
||||
# CONFIG_ARPD is not set
|
||||
# CONFIG_SYN_COOKIES is not set
|
||||
# CONFIG_INET_AH is not set
|
||||
# CONFIG_INET_ESP is not set
|
||||
# CONFIG_INET_IPCOMP is not set
|
||||
# CONFIG_INET_TUNNEL is not set
|
||||
CONFIG_IP_TCPDIAG=y
|
||||
# CONFIG_IP_TCPDIAG_IPV6 is not set
|
||||
# CONFIG_TCP_CONG_ADVANCED is not set
|
||||
CONFIG_TCP_CONG_BIC=y
|
||||
# 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
|
||||
# CONFIG_NET_SCHED is not set
|
||||
# CONFIG_NET_CLS_ROUTE 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
|
||||
|
||||
#
|
||||
# Device Drivers
|
||||
#
|
||||
@ -243,78 +306,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
|
||||
#
|
||||
# Memory Technology Devices (MTD)
|
||||
#
|
||||
CONFIG_MTD=y
|
||||
CONFIG_MTD_DEBUG=y
|
||||
CONFIG_MTD_DEBUG_VERBOSE=3
|
||||
# CONFIG_MTD_CONCAT is not set
|
||||
CONFIG_MTD_PARTITIONS=y
|
||||
# CONFIG_MTD_REDBOOT_PARTS is not set
|
||||
CONFIG_MTD_CMDLINE_PARTS=y
|
||||
# CONFIG_MTD_AFS_PARTS is not set
|
||||
|
||||
#
|
||||
# User Modules And Translation Layers
|
||||
#
|
||||
CONFIG_MTD_CHAR=y
|
||||
CONFIG_MTD_BLOCK=y
|
||||
# CONFIG_FTL is not set
|
||||
# CONFIG_NFTL is not set
|
||||
# CONFIG_INFTL is not set
|
||||
|
||||
#
|
||||
# RAM/ROM/Flash chip drivers
|
||||
#
|
||||
CONFIG_MTD_CFI=y
|
||||
# CONFIG_MTD_JEDECPROBE is not set
|
||||
CONFIG_MTD_GEN_PROBE=y
|
||||
# CONFIG_MTD_CFI_ADV_OPTIONS is not set
|
||||
CONFIG_MTD_MAP_BANK_WIDTH_1=y
|
||||
CONFIG_MTD_MAP_BANK_WIDTH_2=y
|
||||
CONFIG_MTD_MAP_BANK_WIDTH_4=y
|
||||
# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
|
||||
# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
|
||||
# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
|
||||
CONFIG_MTD_CFI_I1=y
|
||||
CONFIG_MTD_CFI_I2=y
|
||||
# CONFIG_MTD_CFI_I4 is not set
|
||||
# CONFIG_MTD_CFI_I8 is not set
|
||||
CONFIG_MTD_CFI_INTELEXT=y
|
||||
# CONFIG_MTD_CFI_AMDSTD is not set
|
||||
# CONFIG_MTD_CFI_STAA is not set
|
||||
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
|
||||
|
||||
#
|
||||
# Mapping drivers for chip access
|
||||
#
|
||||
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
|
||||
# CONFIG_MTD_PHYSMAP is not set
|
||||
# CONFIG_MTD_ARM_INTEGRATOR is not set
|
||||
# CONFIG_MTD_EDB7312 is not set
|
||||
|
||||
#
|
||||
# Self-contained MTD device drivers
|
||||
#
|
||||
# CONFIG_MTD_SLRAM is not set
|
||||
# CONFIG_MTD_PHRAM is not set
|
||||
# CONFIG_MTD_MTDRAM is not set
|
||||
# CONFIG_MTD_BLKMTD is not set
|
||||
# CONFIG_MTD_BLOCK2MTD is not set
|
||||
|
||||
#
|
||||
# Disk-On-Chip Device Drivers
|
||||
#
|
||||
# CONFIG_MTD_DOC2000 is not set
|
||||
# CONFIG_MTD_DOC2001 is not set
|
||||
# CONFIG_MTD_DOC2001PLUS is not set
|
||||
|
||||
#
|
||||
# NAND Flash Device Drivers
|
||||
#
|
||||
# CONFIG_MTD_NAND is not set
|
||||
# CONFIG_MTD is not set
|
||||
|
||||
#
|
||||
# Parallel port support
|
||||
@ -403,72 +395,8 @@ CONFIG_SCSI_PROC_FS=y
|
||||
#
|
||||
|
||||
#
|
||||
# Networking support
|
||||
# Network device support
|
||||
#
|
||||
CONFIG_NET=y
|
||||
|
||||
#
|
||||
# Networking options
|
||||
#
|
||||
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 is not set
|
||||
# CONFIG_NET_IPIP is not set
|
||||
# CONFIG_NET_IPGRE is not set
|
||||
# CONFIG_ARPD is not set
|
||||
# CONFIG_SYN_COOKIES is not set
|
||||
# CONFIG_INET_AH is not set
|
||||
# CONFIG_INET_ESP is not set
|
||||
# CONFIG_INET_IPCOMP is not set
|
||||
# CONFIG_INET_TUNNEL is not set
|
||||
CONFIG_IP_TCPDIAG=y
|
||||
# CONFIG_IP_TCPDIAG_IPV6 is not set
|
||||
# CONFIG_TCP_CONG_ADVANCED is not set
|
||||
CONFIG_TCP_CONG_BIC=y
|
||||
# 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
|
||||
@ -518,6 +446,8 @@ CONFIG_SLIP_COMPRESSED=y
|
||||
# CONFIG_SLIP_MODE_SLIP6 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
|
||||
@ -615,77 +545,15 @@ CONFIG_WATCHDOG_NOWAYOUT=y
|
||||
#
|
||||
# I2C support
|
||||
#
|
||||
CONFIG_I2C=y
|
||||
CONFIG_I2C_CHARDEV=y
|
||||
|
||||
#
|
||||
# I2C Algorithms
|
||||
#
|
||||
# CONFIG_I2C_ALGOBIT is not set
|
||||
# CONFIG_I2C_ALGOPCF is not set
|
||||
# CONFIG_I2C_ALGOPCA is not set
|
||||
|
||||
#
|
||||
# I2C Hardware Bus support
|
||||
#
|
||||
# CONFIG_I2C_ISA is not set
|
||||
# CONFIG_I2C_PARPORT_LIGHT is not set
|
||||
# CONFIG_I2C_STUB is not set
|
||||
# CONFIG_I2C_PCA_ISA is not set
|
||||
|
||||
#
|
||||
# Hardware Sensors Chip support
|
||||
#
|
||||
# CONFIG_I2C is not set
|
||||
# CONFIG_I2C_SENSOR is not set
|
||||
# CONFIG_SENSORS_ADM1021 is not set
|
||||
# CONFIG_SENSORS_ADM1025 is not set
|
||||
# CONFIG_SENSORS_ADM1026 is not set
|
||||
# CONFIG_SENSORS_ADM1031 is not set
|
||||
# CONFIG_SENSORS_ADM9240 is not set
|
||||
# CONFIG_SENSORS_ASB100 is not set
|
||||
# CONFIG_SENSORS_ATXP1 is not set
|
||||
# CONFIG_SENSORS_DS1621 is not set
|
||||
# CONFIG_SENSORS_FSCHER is not set
|
||||
# CONFIG_SENSORS_FSCPOS is not set
|
||||
# CONFIG_SENSORS_GL518SM is not set
|
||||
# CONFIG_SENSORS_GL520SM is not set
|
||||
# CONFIG_SENSORS_IT87 is not set
|
||||
# CONFIG_SENSORS_LM63 is not set
|
||||
# CONFIG_SENSORS_LM75 is not set
|
||||
# CONFIG_SENSORS_LM77 is not set
|
||||
# CONFIG_SENSORS_LM78 is not set
|
||||
# CONFIG_SENSORS_LM80 is not set
|
||||
# CONFIG_SENSORS_LM83 is not set
|
||||
# CONFIG_SENSORS_LM85 is not set
|
||||
# CONFIG_SENSORS_LM87 is not set
|
||||
# CONFIG_SENSORS_LM90 is not set
|
||||
# CONFIG_SENSORS_LM92 is not set
|
||||
# CONFIG_SENSORS_MAX1619 is not set
|
||||
# CONFIG_SENSORS_PC87360 is not set
|
||||
# CONFIG_SENSORS_SMSC47B397 is not set
|
||||
# CONFIG_SENSORS_SMSC47M1 is not set
|
||||
# CONFIG_SENSORS_W83781D is not set
|
||||
# CONFIG_SENSORS_W83L785TS is not set
|
||||
# CONFIG_SENSORS_W83627HF is not set
|
||||
# CONFIG_SENSORS_W83627EHF is not set
|
||||
CONFIG_ISP1301_OMAP=y
|
||||
|
||||
#
|
||||
# Other I2C Chip support
|
||||
# Hardware Monitoring support
|
||||
#
|
||||
# CONFIG_SENSORS_DS1337 is not set
|
||||
# CONFIG_SENSORS_DS1374 is not set
|
||||
# CONFIG_SENSORS_EEPROM is not set
|
||||
# CONFIG_SENSORS_PCF8574 is not set
|
||||
# CONFIG_SENSORS_PCA9539 is not set
|
||||
# CONFIG_SENSORS_PCF8591 is not set
|
||||
# CONFIG_SENSORS_RTC8564 is not set
|
||||
CONFIG_ISP1301_OMAP=y
|
||||
CONFIG_TPS65010=y
|
||||
# CONFIG_SENSORS_MAX6875 is not set
|
||||
# CONFIG_I2C_DEBUG_CORE is not set
|
||||
# CONFIG_I2C_DEBUG_ALGO is not set
|
||||
# CONFIG_I2C_DEBUG_BUS is not set
|
||||
# CONFIG_I2C_DEBUG_CHIP is not set
|
||||
CONFIG_HWMON=y
|
||||
# CONFIG_HWMON_DEBUG_CHIP is not set
|
||||
|
||||
#
|
||||
# Misc devices
|
||||
@ -756,15 +624,9 @@ CONFIG_SOUND=y
|
||||
# Open Sound System
|
||||
#
|
||||
CONFIG_SOUND_PRIME=y
|
||||
# CONFIG_SOUND_BT878 is not set
|
||||
# CONFIG_SOUND_FUSION is not set
|
||||
# CONFIG_SOUND_CS4281 is not set
|
||||
# CONFIG_SOUND_SONICVIBES is not set
|
||||
# CONFIG_SOUND_TRIDENT is not set
|
||||
# CONFIG_SOUND_MSNDCLAS is not set
|
||||
# CONFIG_SOUND_MSNDPIN is not set
|
||||
# CONFIG_SOUND_OSS is not set
|
||||
# CONFIG_SOUND_TVMIXER is not set
|
||||
# CONFIG_SOUND_AD1980 is not set
|
||||
|
||||
#
|
||||
@ -810,6 +672,7 @@ CONFIG_EXT2_FS=y
|
||||
# CONFIG_JBD is not set
|
||||
# CONFIG_REISERFS_FS is not set
|
||||
# CONFIG_JFS_FS is not set
|
||||
# CONFIG_FS_POSIX_ACL is not set
|
||||
|
||||
#
|
||||
# XFS support
|
||||
@ -817,6 +680,7 @@ CONFIG_EXT2_FS=y
|
||||
# CONFIG_XFS_FS is not set
|
||||
# CONFIG_MINIX_FS is not set
|
||||
CONFIG_ROMFS_FS=y
|
||||
CONFIG_INOTIFY=y
|
||||
# CONFIG_QUOTA is not set
|
||||
CONFIG_DNOTIFY=y
|
||||
# CONFIG_AUTOFS_FS is not set
|
||||
@ -857,15 +721,6 @@ CONFIG_RAMFS=y
|
||||
# CONFIG_BEFS_FS is not set
|
||||
# CONFIG_BFS_FS is not set
|
||||
# CONFIG_EFS_FS is not set
|
||||
# CONFIG_JFFS_FS is not set
|
||||
CONFIG_JFFS2_FS=y
|
||||
CONFIG_JFFS2_FS_DEBUG=2
|
||||
# CONFIG_JFFS2_FS_NAND is not set
|
||||
# CONFIG_JFFS2_FS_NOR_ECC is not set
|
||||
# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
|
||||
CONFIG_JFFS2_ZLIB=y
|
||||
CONFIG_JFFS2_RTIME=y
|
||||
# CONFIG_JFFS2_RUBIN is not set
|
||||
CONFIG_CRAMFS=y
|
||||
# CONFIG_VXFS_FS is not set
|
||||
# CONFIG_HPFS_FS is not set
|
||||
@ -1007,4 +862,3 @@ CONFIG_CRYPTO_DES=y
|
||||
CONFIG_CRC32=y
|
||||
# CONFIG_LIBCRC32C is not set
|
||||
CONFIG_ZLIB_INFLATE=y
|
||||
CONFIG_ZLIB_DEFLATE=y
|
||||
|
@ -284,7 +284,7 @@ __syscall_start:
|
||||
.long sys_fstatfs64
|
||||
.long sys_tgkill
|
||||
.long sys_utimes
|
||||
/* 270 */ .long sys_fadvise64_64
|
||||
/* 270 */ .long sys_arm_fadvise64_64_wrapper
|
||||
.long sys_pciconfig_iobase
|
||||
.long sys_pciconfig_read
|
||||
.long sys_pciconfig_write
|
||||
|
@ -585,7 +585,7 @@ ecard_irq_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
|
||||
|
||||
if (pending) {
|
||||
struct irqdesc *d = irq_desc + ec->irq;
|
||||
d->handle(ec->irq, d, regs);
|
||||
desc_handle_irq(ec->irq, d, regs);
|
||||
called ++;
|
||||
}
|
||||
}
|
||||
@ -632,7 +632,7 @@ ecard_irqexp_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *reg
|
||||
* Serial cards should go in 0/1, ethernet/scsi in 2/3
|
||||
* otherwise you will lose serial data at high speeds!
|
||||
*/
|
||||
d->handle(ec->irq, d, regs);
|
||||
desc_handle_irq(ec->irq, d, regs);
|
||||
} else {
|
||||
printk(KERN_WARNING "card%d: interrupt from unclaimed "
|
||||
"card???\n", slot);
|
||||
|
@ -265,6 +265,10 @@ sys_futex_wrapper:
|
||||
str r5, [sp, #4] @ push sixth arg
|
||||
b sys_futex
|
||||
|
||||
sys_arm_fadvise64_64_wrapper:
|
||||
str r5, [sp, #4] @ push r5 to stack
|
||||
b sys_arm_fadvise64_64
|
||||
|
||||
/*
|
||||
* Note: off_4k (r5) is always units of 4K. If we can't do the requested
|
||||
* offset, we return EINVAL.
|
||||
|
@ -207,8 +207,8 @@ void enable_irq_wake(unsigned int irq)
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&irq_controller_lock, flags);
|
||||
if (desc->chip->wake)
|
||||
desc->chip->wake(irq, 1);
|
||||
if (desc->chip->set_wake)
|
||||
desc->chip->set_wake(irq, 1);
|
||||
spin_unlock_irqrestore(&irq_controller_lock, flags);
|
||||
}
|
||||
EXPORT_SYMBOL(enable_irq_wake);
|
||||
@ -219,8 +219,8 @@ void disable_irq_wake(unsigned int irq)
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&irq_controller_lock, flags);
|
||||
if (desc->chip->wake)
|
||||
desc->chip->wake(irq, 0);
|
||||
if (desc->chip->set_wake)
|
||||
desc->chip->set_wake(irq, 0);
|
||||
spin_unlock_irqrestore(&irq_controller_lock, flags);
|
||||
}
|
||||
EXPORT_SYMBOL(disable_irq_wake);
|
||||
@ -517,7 +517,7 @@ static void do_pending_irqs(struct pt_regs *regs)
|
||||
list_for_each_safe(l, n, &head) {
|
||||
desc = list_entry(l, struct irqdesc, pend);
|
||||
list_del_init(&desc->pend);
|
||||
desc->handle(desc - irq_desc, desc, regs);
|
||||
desc_handle_irq(desc - irq_desc, desc, regs);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -545,7 +545,7 @@ asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs)
|
||||
|
||||
irq_enter();
|
||||
spin_lock(&irq_controller_lock);
|
||||
desc->handle(irq, desc, regs);
|
||||
desc_handle_irq(irq, desc, regs);
|
||||
|
||||
/*
|
||||
* Now re-run any pending interrupts.
|
||||
@ -624,9 +624,9 @@ int set_irq_type(unsigned int irq, unsigned int type)
|
||||
}
|
||||
|
||||
desc = irq_desc + irq;
|
||||
if (desc->chip->type) {
|
||||
if (desc->chip->set_type) {
|
||||
spin_lock_irqsave(&irq_controller_lock, flags);
|
||||
ret = desc->chip->type(irq, type);
|
||||
ret = desc->chip->set_type(irq, type);
|
||||
spin_unlock_irqrestore(&irq_controller_lock, flags);
|
||||
}
|
||||
|
||||
@ -846,8 +846,8 @@ unsigned long probe_irq_on(void)
|
||||
|
||||
irq_desc[i].probing = 1;
|
||||
irq_desc[i].triggered = 0;
|
||||
if (irq_desc[i].chip->type)
|
||||
irq_desc[i].chip->type(i, IRQT_PROBE);
|
||||
if (irq_desc[i].chip->set_type)
|
||||
irq_desc[i].chip->set_type(i, IRQT_PROBE);
|
||||
irq_desc[i].chip->unmask(i);
|
||||
irqs += 1;
|
||||
}
|
||||
|
@ -110,7 +110,7 @@ int __cpuinit __cpu_up(unsigned int cpu)
|
||||
* We need to tell the secondary core where to find
|
||||
* its stack and the page tables.
|
||||
*/
|
||||
secondary_data.stack = (void *)idle->thread_info + THREAD_SIZE - 8;
|
||||
secondary_data.stack = (void *)idle->thread_info + THREAD_START_SP;
|
||||
secondary_data.pgdir = virt_to_phys(pgd);
|
||||
wmb();
|
||||
|
||||
|
@ -311,3 +311,13 @@ long execve(const char *filename, char **argv, char **envp)
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(execve);
|
||||
|
||||
/*
|
||||
* Since loff_t is a 64 bit type we avoid a lot of ABI hastle
|
||||
* with a different argument ordering.
|
||||
*/
|
||||
asmlinkage long sys_arm_fadvise64_64(int fd, int advice,
|
||||
loff_t offset, loff_t len)
|
||||
{
|
||||
return sys_fadvise64_64(fd, offset, len, advice);
|
||||
}
|
||||
|
@ -102,7 +102,7 @@ static unsigned long next_rtc_update;
|
||||
*/
|
||||
static inline void do_set_rtc(void)
|
||||
{
|
||||
if (time_status & STA_UNSYNC || set_rtc == NULL)
|
||||
if (!ntp_synced() || set_rtc == NULL)
|
||||
return;
|
||||
|
||||
if (next_rtc_update &&
|
||||
@ -292,10 +292,7 @@ int do_settimeofday(struct timespec *tv)
|
||||
set_normalized_timespec(&xtime, sec, nsec);
|
||||
set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
|
||||
|
||||
time_adjust = 0; /* stop active adjtime() */
|
||||
time_status |= STA_UNSYNC;
|
||||
time_maxerror = NTP_PHASE_LIMIT;
|
||||
time_esterror = NTP_PHASE_LIMIT;
|
||||
ntp_clear();
|
||||
write_sequnlock_irq(&xtime_lock);
|
||||
clock_was_set();
|
||||
return 0;
|
||||
@ -433,10 +430,12 @@ void timer_dyn_reprogram(void)
|
||||
{
|
||||
struct dyn_tick_timer *dyn_tick = system_timer->dyn_tick;
|
||||
|
||||
write_seqlock(&xtime_lock);
|
||||
if (dyn_tick->state & DYN_TICK_ENABLED)
|
||||
dyn_tick->reprogram(next_timer_interrupt() - jiffies);
|
||||
write_sequnlock(&xtime_lock);
|
||||
if (dyn_tick) {
|
||||
write_seqlock(&xtime_lock);
|
||||
if (dyn_tick->state & DYN_TICK_ENABLED)
|
||||
dyn_tick->reprogram(next_timer_interrupt() - jiffies);
|
||||
write_sequnlock(&xtime_lock);
|
||||
}
|
||||
}
|
||||
|
||||
static ssize_t timer_show_dyn_tick(struct sys_device *dev, char *buf)
|
||||
|
@ -87,6 +87,7 @@ config FOOTBRIDGE_ADDIN
|
||||
|
||||
# EBSA285 board in either host or addin mode
|
||||
config ARCH_EBSA285
|
||||
select ARCH_MAY_HAVE_PC_FDC
|
||||
bool
|
||||
|
||||
endif
|
||||
|
@ -95,7 +95,7 @@ isa_irq_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
|
||||
}
|
||||
|
||||
desc = irq_desc + isa_irq;
|
||||
desc->handle(isa_irq, desc, regs);
|
||||
desc_handle_irq(isa_irq, desc, regs);
|
||||
}
|
||||
|
||||
static struct irqaction irq_cascade = { .handler = no_action, .name = "cascade", };
|
||||
|
@ -108,7 +108,7 @@ h720x_gpio_handler(unsigned int mask, unsigned int irq,
|
||||
while (mask) {
|
||||
if (mask & 1) {
|
||||
IRQDBG("handling irq %d\n", irq);
|
||||
desc->handle(irq, desc, regs);
|
||||
desc_handle_irq(irq, desc, regs);
|
||||
}
|
||||
irq++;
|
||||
desc++;
|
||||
|
@ -126,7 +126,7 @@ h7202_timerx_demux_handler(unsigned int irq_unused, struct irqdesc *desc,
|
||||
desc = irq_desc + irq;
|
||||
while (mask) {
|
||||
if (mask & 1)
|
||||
desc->handle(irq, desc, regs);
|
||||
desc_handle_irq(irq, desc, regs);
|
||||
irq++;
|
||||
desc++;
|
||||
mask >>= 1;
|
||||
|
@ -152,7 +152,7 @@ imx_gpio_handler(unsigned int mask, unsigned int irq,
|
||||
while (mask) {
|
||||
if (mask & 1) {
|
||||
DEBUG_IRQ("handling irq %d\n", irq);
|
||||
desc->handle(irq, desc, regs);
|
||||
desc_handle_irq(irq, desc, regs);
|
||||
}
|
||||
irq++;
|
||||
desc++;
|
||||
@ -214,7 +214,7 @@ static struct irqchip imx_gpio_chip = {
|
||||
.ack = imx_gpio_ack_irq,
|
||||
.mask = imx_gpio_mask_irq,
|
||||
.unmask = imx_gpio_unmask_irq,
|
||||
.type = imx_gpio_irq_type,
|
||||
.set_type = imx_gpio_irq_type,
|
||||
};
|
||||
|
||||
void __init
|
||||
|
@ -170,7 +170,7 @@ sic_handle_irq(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
|
||||
irq += IRQ_SIC_START;
|
||||
|
||||
desc = irq_desc + irq;
|
||||
desc->handle(irq, desc, regs);
|
||||
desc_handle_irq(irq, desc, regs);
|
||||
} while (status);
|
||||
}
|
||||
|
||||
|
@ -60,7 +60,7 @@ static unsigned long iop321_gettimeoffset(void)
|
||||
/*
|
||||
* Now convert them to usec.
|
||||
*/
|
||||
usec = (unsigned long)(elapsed * (tick_nsec / 1000)) / LATCH;
|
||||
usec = (unsigned long)(elapsed / (CLOCK_TICK_RATE/1000000));
|
||||
|
||||
return usec;
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ static unsigned long iop331_gettimeoffset(void)
|
||||
/*
|
||||
* Now convert them to usec.
|
||||
*/
|
||||
usec = (unsigned long)(elapsed * (tick_nsec / 1000)) / LATCH;
|
||||
usec = (unsigned long)(elapsed / (CLOCK_TICK_RATE/1000000));
|
||||
|
||||
return usec;
|
||||
}
|
||||
|
@ -317,7 +317,7 @@ static void ixp2000_GPIO_irq_handler(unsigned int irq, struct irqdesc *desc, str
|
||||
for (i = 0; i <= 7; i++) {
|
||||
if (status & (1<<i)) {
|
||||
desc = irq_desc + i + IRQ_IXP2000_GPIO0;
|
||||
desc->handle(i + IRQ_IXP2000_GPIO0, desc, regs);
|
||||
desc_handle_irq(i + IRQ_IXP2000_GPIO0, desc, regs);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -380,10 +380,10 @@ static void ixp2000_GPIO_irq_unmask(unsigned int irq)
|
||||
}
|
||||
|
||||
static struct irqchip ixp2000_GPIO_irq_chip = {
|
||||
.type = ixp2000_GPIO_irq_type,
|
||||
.ack = ixp2000_GPIO_irq_mask_ack,
|
||||
.mask = ixp2000_GPIO_irq_mask,
|
||||
.unmask = ixp2000_GPIO_irq_unmask
|
||||
.ack = ixp2000_GPIO_irq_mask_ack,
|
||||
.mask = ixp2000_GPIO_irq_mask,
|
||||
.unmask = ixp2000_GPIO_irq_unmask,
|
||||
.set_type = ixp2000_GPIO_irq_type,
|
||||
};
|
||||
|
||||
static void ixp2000_pci_irq_mask(unsigned int irq)
|
||||
|
@ -133,7 +133,7 @@ static void ixdp2x00_irq_handler(unsigned int irq, struct irqdesc *desc, struct
|
||||
struct irqdesc *cpld_desc;
|
||||
int cpld_irq = IXP2000_BOARD_IRQ(0) + i;
|
||||
cpld_desc = irq_desc + cpld_irq;
|
||||
cpld_desc->handle(cpld_irq, cpld_desc, regs);
|
||||
desc_handle_irq(cpld_irq, cpld_desc, regs);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -82,7 +82,7 @@ static void ixdp2x01_irq_handler(unsigned int irq, struct irqdesc *desc, struct
|
||||
struct irqdesc *cpld_desc;
|
||||
int cpld_irq = IXP2000_BOARD_IRQ(0) + i;
|
||||
cpld_desc = irq_desc + cpld_irq;
|
||||
cpld_desc->handle(cpld_irq, cpld_desc, regs);
|
||||
desc_handle_irq(cpld_irq, cpld_desc, regs);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -38,90 +38,6 @@
|
||||
#include <asm/mach/irq.h>
|
||||
#include <asm/mach/time.h>
|
||||
|
||||
enum ixp4xx_irq_type {
|
||||
IXP4XX_IRQ_LEVEL, IXP4XX_IRQ_EDGE
|
||||
};
|
||||
static void ixp4xx_config_irq(unsigned irq, enum ixp4xx_irq_type type);
|
||||
|
||||
/*************************************************************************
|
||||
* GPIO acces functions
|
||||
*************************************************************************/
|
||||
|
||||
/*
|
||||
* Configure GPIO line for input, interrupt, or output operation
|
||||
*
|
||||
* TODO: Enable/disable the irq_desc based on interrupt or output mode.
|
||||
* TODO: Should these be named ixp4xx_gpio_?
|
||||
*/
|
||||
void gpio_line_config(u8 line, u32 style)
|
||||
{
|
||||
static const int gpio2irq[] = {
|
||||
6, 7, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29
|
||||
};
|
||||
u32 enable;
|
||||
volatile u32 *int_reg;
|
||||
u32 int_style;
|
||||
enum ixp4xx_irq_type irq_type;
|
||||
|
||||
enable = *IXP4XX_GPIO_GPOER;
|
||||
|
||||
if (style & IXP4XX_GPIO_OUT) {
|
||||
enable &= ~((1) << line);
|
||||
} else if (style & IXP4XX_GPIO_IN) {
|
||||
enable |= ((1) << line);
|
||||
|
||||
switch (style & IXP4XX_GPIO_INTSTYLE_MASK)
|
||||
{
|
||||
case (IXP4XX_GPIO_ACTIVE_HIGH):
|
||||
int_style = IXP4XX_GPIO_STYLE_ACTIVE_HIGH;
|
||||
irq_type = IXP4XX_IRQ_LEVEL;
|
||||
break;
|
||||
case (IXP4XX_GPIO_ACTIVE_LOW):
|
||||
int_style = IXP4XX_GPIO_STYLE_ACTIVE_LOW;
|
||||
irq_type = IXP4XX_IRQ_LEVEL;
|
||||
break;
|
||||
case (IXP4XX_GPIO_RISING_EDGE):
|
||||
int_style = IXP4XX_GPIO_STYLE_RISING_EDGE;
|
||||
irq_type = IXP4XX_IRQ_EDGE;
|
||||
break;
|
||||
case (IXP4XX_GPIO_FALLING_EDGE):
|
||||
int_style = IXP4XX_GPIO_STYLE_FALLING_EDGE;
|
||||
irq_type = IXP4XX_IRQ_EDGE;
|
||||
break;
|
||||
case (IXP4XX_GPIO_TRANSITIONAL):
|
||||
int_style = IXP4XX_GPIO_STYLE_TRANSITIONAL;
|
||||
irq_type = IXP4XX_IRQ_EDGE;
|
||||
break;
|
||||
default:
|
||||
int_style = IXP4XX_GPIO_STYLE_ACTIVE_HIGH;
|
||||
irq_type = IXP4XX_IRQ_LEVEL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (style & IXP4XX_GPIO_INTSTYLE_MASK)
|
||||
ixp4xx_config_irq(gpio2irq[line], irq_type);
|
||||
|
||||
if (line >= 8) { /* pins 8-15 */
|
||||
line -= 8;
|
||||
int_reg = IXP4XX_GPIO_GPIT2R;
|
||||
}
|
||||
else { /* pins 0-7 */
|
||||
int_reg = IXP4XX_GPIO_GPIT1R;
|
||||
}
|
||||
|
||||
/* Clear the style for the appropriate pin */
|
||||
*int_reg &= ~(IXP4XX_GPIO_STYLE_CLEAR <<
|
||||
(line * IXP4XX_GPIO_STYLE_SIZE));
|
||||
|
||||
/* Set the new style */
|
||||
*int_reg |= (int_style << (line * IXP4XX_GPIO_STYLE_SIZE));
|
||||
}
|
||||
|
||||
*IXP4XX_GPIO_GPOER = enable;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(gpio_line_config);
|
||||
|
||||
/*************************************************************************
|
||||
* IXP4xx chipset I/O mapping
|
||||
*************************************************************************/
|
||||
@ -165,6 +81,69 @@ void __init ixp4xx_map_io(void)
|
||||
* (be it PCI or something else) configures that GPIO line
|
||||
* as an IRQ.
|
||||
**************************************************************************/
|
||||
enum ixp4xx_irq_type {
|
||||
IXP4XX_IRQ_LEVEL, IXP4XX_IRQ_EDGE
|
||||
};
|
||||
|
||||
static void ixp4xx_config_irq(unsigned irq, enum ixp4xx_irq_type type);
|
||||
|
||||
/*
|
||||
* IRQ -> GPIO mapping table
|
||||
*/
|
||||
static int irq2gpio[32] = {
|
||||
-1, -1, -1, -1, -1, -1, 0, 1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, 2, 3, 4, 5, 6,
|
||||
7, 8, 9, 10, 11, 12, -1, -1,
|
||||
};
|
||||
|
||||
static int ixp4xx_set_irq_type(unsigned int irq, unsigned int type)
|
||||
{
|
||||
int line = irq2gpio[irq];
|
||||
u32 int_style;
|
||||
enum ixp4xx_irq_type irq_type;
|
||||
volatile u32 *int_reg;
|
||||
|
||||
/*
|
||||
* Only for GPIO IRQs
|
||||
*/
|
||||
if (line < 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (type & IRQT_BOTHEDGE) {
|
||||
int_style = IXP4XX_GPIO_STYLE_TRANSITIONAL;
|
||||
irq_type = IXP4XX_IRQ_EDGE;
|
||||
} else if (type & IRQT_RISING) {
|
||||
int_style = IXP4XX_GPIO_STYLE_RISING_EDGE;
|
||||
irq_type = IXP4XX_IRQ_EDGE;
|
||||
} else if (type & IRQT_FALLING) {
|
||||
int_style = IXP4XX_GPIO_STYLE_FALLING_EDGE;
|
||||
irq_type = IXP4XX_IRQ_EDGE;
|
||||
} else if (type & IRQT_HIGH) {
|
||||
int_style = IXP4XX_GPIO_STYLE_ACTIVE_HIGH;
|
||||
irq_type = IXP4XX_IRQ_LEVEL;
|
||||
} else if (type & IRQT_LOW) {
|
||||
int_style = IXP4XX_GPIO_STYLE_ACTIVE_LOW;
|
||||
irq_type = IXP4XX_IRQ_LEVEL;
|
||||
}
|
||||
|
||||
ixp4xx_config_irq(irq, irq_type);
|
||||
|
||||
if (line >= 8) { /* pins 8-15 */
|
||||
line -= 8;
|
||||
int_reg = IXP4XX_GPIO_GPIT2R;
|
||||
} else { /* pins 0-7 */
|
||||
int_reg = IXP4XX_GPIO_GPIT1R;
|
||||
}
|
||||
|
||||
/* Clear the style for the appropriate pin */
|
||||
*int_reg &= ~(IXP4XX_GPIO_STYLE_CLEAR <<
|
||||
(line * IXP4XX_GPIO_STYLE_SIZE));
|
||||
|
||||
/* Set the new style */
|
||||
*int_reg |= (int_style << (line * IXP4XX_GPIO_STYLE_SIZE));
|
||||
}
|
||||
|
||||
static void ixp4xx_irq_mask(unsigned int irq)
|
||||
{
|
||||
if (cpu_is_ixp46x() && irq >= 32)
|
||||
@ -183,12 +162,6 @@ static void ixp4xx_irq_unmask(unsigned int irq)
|
||||
|
||||
static void ixp4xx_irq_ack(unsigned int irq)
|
||||
{
|
||||
static int irq2gpio[32] = {
|
||||
-1, -1, -1, -1, -1, -1, 0, 1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, 2, 3, 4, 5, 6,
|
||||
7, 8, 9, 10, 11, 12, -1, -1,
|
||||
};
|
||||
int line = (irq < 32) ? irq2gpio[irq] : -1;
|
||||
|
||||
if (line >= 0)
|
||||
@ -206,15 +179,17 @@ static void ixp4xx_irq_level_unmask(unsigned int irq)
|
||||
}
|
||||
|
||||
static struct irqchip ixp4xx_irq_level_chip = {
|
||||
.ack = ixp4xx_irq_mask,
|
||||
.mask = ixp4xx_irq_mask,
|
||||
.unmask = ixp4xx_irq_level_unmask,
|
||||
.ack = ixp4xx_irq_mask,
|
||||
.mask = ixp4xx_irq_mask,
|
||||
.unmask = ixp4xx_irq_level_unmask,
|
||||
.set_type = ixp4xx_set_irq_type,
|
||||
};
|
||||
|
||||
static struct irqchip ixp4xx_irq_edge_chip = {
|
||||
.ack = ixp4xx_irq_ack,
|
||||
.mask = ixp4xx_irq_mask,
|
||||
.unmask = ixp4xx_irq_unmask,
|
||||
.ack = ixp4xx_irq_ack,
|
||||
.mask = ixp4xx_irq_mask,
|
||||
.unmask = ixp4xx_irq_unmask,
|
||||
.set_type = ixp4xx_set_irq_type,
|
||||
};
|
||||
|
||||
static void ixp4xx_config_irq(unsigned irq, enum ixp4xx_irq_type type)
|
||||
|
@ -30,11 +30,8 @@ extern struct pci_bus *ixp4xx_scan_bus(int nr, struct pci_sys_data *sys);
|
||||
|
||||
void __init coyote_pci_preinit(void)
|
||||
{
|
||||
gpio_line_config(COYOTE_PCI_SLOT0_PIN,
|
||||
IXP4XX_GPIO_IN | IXP4XX_GPIO_ACTIVE_LOW);
|
||||
|
||||
gpio_line_config(COYOTE_PCI_SLOT1_PIN,
|
||||
IXP4XX_GPIO_IN | IXP4XX_GPIO_ACTIVE_LOW);
|
||||
set_irq_type(IRQ_COYOTE_PCI_SLOT0, IRQT_LOW);
|
||||
set_irq_type(IRQ_COYOTE_PCI_SLOT1, IRQT_LOW);
|
||||
|
||||
gpio_line_isr_clear(COYOTE_PCI_SLOT0_PIN);
|
||||
gpio_line_isr_clear(COYOTE_PCI_SLOT1_PIN);
|
||||
|
@ -24,11 +24,6 @@
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/flash.h>
|
||||
|
||||
void __init coyote_map_io(void)
|
||||
{
|
||||
ixp4xx_map_io();
|
||||
}
|
||||
|
||||
static struct flash_platform_data coyote_flash_data = {
|
||||
.map_name = "cfi_probe",
|
||||
.width = 2,
|
||||
@ -107,7 +102,7 @@ MACHINE_START(ADI_COYOTE, "ADI Engineering Coyote")
|
||||
.phys_ram = PHYS_OFFSET,
|
||||
.phys_io = IXP4XX_PERIPHERAL_BASE_PHYS,
|
||||
.io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc,
|
||||
.map_io = coyote_map_io,
|
||||
.map_io = ixp4xx_map_io,
|
||||
.init_irq = ixp4xx_init_irq,
|
||||
.timer = &ixp4xx_timer,
|
||||
.boot_params = 0x0100,
|
||||
@ -125,7 +120,7 @@ MACHINE_START(IXDPG425, "Intel IXDPG425")
|
||||
.phys_ram = PHYS_OFFSET,
|
||||
.phys_io = IXP4XX_PERIPHERAL_BASE_PHYS,
|
||||
.io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc,
|
||||
.map_io = coyote_map_io,
|
||||
.map_io = ixp4xx_map_io,
|
||||
.init_irq = ixp4xx_init_irq,
|
||||
.timer = &ixp4xx_timer,
|
||||
.boot_params = 0x0100,
|
||||
|
@ -35,26 +35,20 @@ extern void ixp4xx_pci_preinit(void);
|
||||
extern int ixp4xx_setup(int nr, struct pci_sys_data *sys);
|
||||
extern struct pci_bus *ixp4xx_scan_bus(int nr, struct pci_sys_data *sys);
|
||||
|
||||
/*
|
||||
* The exact GPIO pins and IRQs are defined in arch-ixp4xx/gtwx5715.h
|
||||
* Slot 0 isn't actually populated with a card connector but
|
||||
* we initialize it anyway in case a future version has the
|
||||
* slot populated or someone with good soldering skills has
|
||||
* some free time.
|
||||
*/
|
||||
|
||||
|
||||
static void gtwx5715_init_gpio(u8 pin, u32 style)
|
||||
{
|
||||
gpio_line_config(pin, style | IXP4XX_GPIO_ACTIVE_LOW);
|
||||
|
||||
if (style & IXP4XX_GPIO_IN) gpio_line_isr_clear(pin);
|
||||
}
|
||||
|
||||
/*
|
||||
* The exact GPIO pins and IRQs are defined in arch-ixp4xx/gtwx5715.h
|
||||
* Slot 0 isn't actually populated with a card connector but
|
||||
* we initialize it anyway in case a future version has the
|
||||
* slot populated or someone with good soldering skills has
|
||||
* some free time.
|
||||
*/
|
||||
void __init gtwx5715_pci_preinit(void)
|
||||
{
|
||||
gtwx5715_init_gpio(GTWX5715_PCI_SLOT0_INTA_GPIO, IXP4XX_GPIO_IN);
|
||||
gtwx5715_init_gpio(GTWX5715_PCI_SLOT1_INTA_GPIO, IXP4XX_GPIO_IN);
|
||||
set_irq_type(GTWX5715_PCI_SLOT0_INTA_IRQ, IRQT_LOW);
|
||||
set_irq_type(GTWX5715_PCI_SLOT0_INTB_IRQ, IRQT_LOW);
|
||||
set_irq_type(GTWX5715_PCI_SLOT1_INTA_IRQ, IRQT_LOW);
|
||||
set_irq_type(GTWX5715_PCI_SLOT1_INTB_IRQ, IRQT_LOW);
|
||||
|
||||
ixp4xx_pci_preinit();
|
||||
}
|
||||
|
@ -101,12 +101,6 @@ static struct platform_device gtwx5715_uart_device = {
|
||||
.resource = gtwx5715_uart_resources,
|
||||
};
|
||||
|
||||
|
||||
void __init gtwx5715_map_io(void)
|
||||
{
|
||||
ixp4xx_map_io();
|
||||
}
|
||||
|
||||
static struct flash_platform_data gtwx5715_flash_data = {
|
||||
.map_name = "cfi_probe",
|
||||
.width = 2,
|
||||
@ -144,7 +138,7 @@ MACHINE_START(GTWX5715, "Gemtek GTWX5715 (Linksys WRV54G)")
|
||||
.phys_ram = PHYS_OFFSET,
|
||||
.phys_io = IXP4XX_UART2_BASE_PHYS,
|
||||
.io_pg_offst = ((IXP4XX_UART2_BASE_VIRT) >> 18) & 0xfffc,
|
||||
.map_io = gtwx5715_map_io,
|
||||
.map_io = ixp4xx_map_io,
|
||||
.init_irq = ixp4xx_init_irq,
|
||||
.timer = &ixp4xx_timer,
|
||||
.boot_params = 0x0100,
|
||||
|
@ -27,14 +27,10 @@
|
||||
|
||||
void __init ixdp425_pci_preinit(void)
|
||||
{
|
||||
gpio_line_config(IXDP425_PCI_INTA_PIN,
|
||||
IXP4XX_GPIO_IN | IXP4XX_GPIO_ACTIVE_LOW);
|
||||
gpio_line_config(IXDP425_PCI_INTB_PIN,
|
||||
IXP4XX_GPIO_IN | IXP4XX_GPIO_ACTIVE_LOW);
|
||||
gpio_line_config(IXDP425_PCI_INTC_PIN,
|
||||
IXP4XX_GPIO_IN | IXP4XX_GPIO_ACTIVE_LOW);
|
||||
gpio_line_config(IXDP425_PCI_INTD_PIN,
|
||||
IXP4XX_GPIO_IN | IXP4XX_GPIO_ACTIVE_LOW);
|
||||
set_irq_type(IRQ_IXDP425_PCI_INTA, IRQT_LOW);
|
||||
set_irq_type(IRQ_IXDP425_PCI_INTB, IRQT_LOW);
|
||||
set_irq_type(IRQ_IXDP425_PCI_INTC, IRQT_LOW);
|
||||
set_irq_type(IRQ_IXDP425_PCI_INTD, IRQT_LOW);
|
||||
|
||||
gpio_line_isr_clear(IXDP425_PCI_INTA_PIN);
|
||||
gpio_line_isr_clear(IXDP425_PCI_INTB_PIN);
|
||||
|
@ -24,11 +24,6 @@
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/flash.h>
|
||||
|
||||
void __init ixdp425_map_io(void)
|
||||
{
|
||||
ixp4xx_map_io();
|
||||
}
|
||||
|
||||
static struct flash_platform_data ixdp425_flash_data = {
|
||||
.map_name = "cfi_probe",
|
||||
.width = 2,
|
||||
@ -133,7 +128,7 @@ MACHINE_START(IXDP425, "Intel IXDP425 Development Platform")
|
||||
.phys_ram = PHYS_OFFSET,
|
||||
.phys_io = IXP4XX_PERIPHERAL_BASE_PHYS,
|
||||
.io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc,
|
||||
.map_io = ixdp425_map_io,
|
||||
.map_io = ixp4xx_map_io,
|
||||
.init_irq = ixp4xx_init_irq,
|
||||
.timer = &ixp4xx_timer,
|
||||
.boot_params = 0x0100,
|
||||
@ -145,7 +140,7 @@ MACHINE_START(IXDP465, "Intel IXDP465 Development Platform")
|
||||
.phys_ram = PHYS_OFFSET,
|
||||
.phys_io = IXP4XX_PERIPHERAL_BASE_PHYS,
|
||||
.io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc,
|
||||
.map_io = ixdp425_map_io,
|
||||
.map_io = ixp4xx_map_io,
|
||||
.init_irq = ixp4xx_init_irq,
|
||||
.timer = &ixp4xx_timer,
|
||||
.boot_params = 0x0100,
|
||||
@ -157,7 +152,7 @@ MACHINE_START(IXCDP1100, "Intel IXCDP1100 Development Platform")
|
||||
.phys_ram = PHYS_OFFSET,
|
||||
.phys_io = IXP4XX_PERIPHERAL_BASE_PHYS,
|
||||
.io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc,
|
||||
.map_io = ixdp425_map_io,
|
||||
.map_io = ixp4xx_map_io,
|
||||
.init_irq = ixp4xx_init_irq,
|
||||
.timer = &ixp4xx_timer,
|
||||
.boot_params = 0x0100,
|
||||
@ -176,7 +171,7 @@ MACHINE_START(AVILA, "Gateworks Avila Network Platform")
|
||||
.phys_ram = PHYS_OFFSET,
|
||||
.phys_io = IXP4XX_PERIPHERAL_BASE_PHYS,
|
||||
.io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc,
|
||||
.map_io = ixdp425_map_io,
|
||||
.map_io = ixp4xx_map_io,
|
||||
.init_irq = ixp4xx_init_irq,
|
||||
.timer = &ixp4xx_timer,
|
||||
.boot_params = 0x0100,
|
||||
|
@ -29,8 +29,8 @@ extern struct pci_bus *ixp4xx_scan_bus(int nr, struct pci_sys_data *sys);
|
||||
|
||||
void __init ixdpg425_pci_preinit(void)
|
||||
{
|
||||
gpio_line_config(6, IXP4XX_GPIO_IN | IXP4XX_GPIO_ACTIVE_LOW);
|
||||
gpio_line_config(7, IXP4XX_GPIO_IN | IXP4XX_GPIO_ACTIVE_LOW);
|
||||
set_irq_type(IRQ_IXP4XX_GPIO6, IRQT_LOW);
|
||||
set_irq_type(IRQ_IXP4XX_GPIO7, IRQT_LOW);
|
||||
|
||||
gpio_line_isr_clear(6);
|
||||
gpio_line_isr_clear(7);
|
||||
|
@ -13,4 +13,4 @@ extern struct sys_timer lh7a40x_timer;
|
||||
extern void lh7a400_init_irq (void);
|
||||
extern void lh7a404_init_irq (void);
|
||||
|
||||
#define IRQ_DISPATCH(irq) irq_desc[irq].handle ((irq), &irq_desc[irq], regs)
|
||||
#define IRQ_DISPATCH(irq) desc_handle_irq((irq),(irq_desc + irq), regs)
|
||||
|
@ -102,7 +102,7 @@ void innovator_fpga_IRQ_demux(unsigned int irq, struct irqdesc *desc,
|
||||
fpga_irq++, stat >>= 1) {
|
||||
if (stat & 1) {
|
||||
d = irq_desc + fpga_irq;
|
||||
d->handle(fpga_irq, d, regs);
|
||||
desc_handle_irq(fpga_irq, d, regs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -165,10 +165,10 @@ static struct omap_irq_bank omap1610_irq_banks[] = {
|
||||
#endif
|
||||
|
||||
static struct irqchip omap_irq_chip = {
|
||||
.ack = omap_mask_ack_irq,
|
||||
.mask = omap_mask_irq,
|
||||
.unmask = omap_unmask_irq,
|
||||
.wake = omap_wake_irq,
|
||||
.ack = omap_mask_ack_irq,
|
||||
.mask = omap_mask_irq,
|
||||
.unmask = omap_unmask_irq,
|
||||
.set_wake = omap_wake_irq,
|
||||
};
|
||||
|
||||
void __init omap_init_irq(void)
|
||||
|
@ -11,7 +11,7 @@ obj-$(CONFIG_PXA27x) += pxa27x.o
|
||||
obj-$(CONFIG_ARCH_LUBBOCK) += lubbock.o
|
||||
obj-$(CONFIG_MACH_MAINSTONE) += mainstone.o
|
||||
obj-$(CONFIG_ARCH_PXA_IDP) += idp.o
|
||||
obj-$(CONFIG_PXA_SHARP_C7xx) += corgi.o corgi_ssp.o ssp.o
|
||||
obj-$(CONFIG_PXA_SHARP_C7xx) += corgi.o corgi_ssp.o corgi_lcd.o ssp.o
|
||||
obj-$(CONFIG_MACH_POODLE) += poodle.o
|
||||
|
||||
# Support for blinky lights
|
||||
|
@ -39,7 +39,6 @@
|
||||
|
||||
#include <asm/mach/sharpsl_param.h>
|
||||
#include <asm/hardware/scoop.h>
|
||||
#include <video/w100fb.h>
|
||||
|
||||
#include "generic.h"
|
||||
|
||||
@ -60,6 +59,15 @@ static struct scoop_config corgi_scoop_setup = {
|
||||
.io_out = CORGI_SCOOP_IO_OUT,
|
||||
};
|
||||
|
||||
static struct scoop_pcmcia_dev corgi_pcmcia_scoop[] = {
|
||||
{
|
||||
.dev = &corgiscoop_device.dev,
|
||||
.irq = CORGI_IRQ_GPIO_CF_IRQ,
|
||||
.cd_irq = CORGI_IRQ_GPIO_CF_CD,
|
||||
.cd_irq_str = "PCMCIA0 CD",
|
||||
},
|
||||
};
|
||||
|
||||
struct platform_device corgiscoop_device = {
|
||||
.name = "sharp-scoop",
|
||||
.id = -1,
|
||||
@ -78,7 +86,7 @@ struct platform_device corgiscoop_device = {
|
||||
* also use scoop functions and this makes the power up/down order
|
||||
* work correctly.
|
||||
*/
|
||||
static struct platform_device corgissp_device = {
|
||||
struct platform_device corgissp_device = {
|
||||
.name = "corgi-ssp",
|
||||
.dev = {
|
||||
.parent = &corgiscoop_device.dev,
|
||||
@ -87,35 +95,6 @@ static struct platform_device corgissp_device = {
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Corgi w100 Frame Buffer Device
|
||||
*/
|
||||
static struct w100fb_mach_info corgi_fb_info = {
|
||||
.w100fb_ssp_send = corgi_ssp_lcdtg_send,
|
||||
.comadj = -1,
|
||||
.phadadj = -1,
|
||||
};
|
||||
|
||||
static struct resource corgi_fb_resources[] = {
|
||||
[0] = {
|
||||
.start = 0x08000000,
|
||||
.end = 0x08ffffff,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device corgifb_device = {
|
||||
.name = "w100fb",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.platform_data = &corgi_fb_info,
|
||||
.parent = &corgissp_device.dev,
|
||||
},
|
||||
.num_resources = ARRAY_SIZE(corgi_fb_resources),
|
||||
.resource = corgi_fb_resources,
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Corgi Backlight Device
|
||||
*/
|
||||
@ -128,6 +107,27 @@ static struct platform_device corgibl_device = {
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Corgi Keyboard Device
|
||||
*/
|
||||
static struct platform_device corgikbd_device = {
|
||||
.name = "corgi-keyboard",
|
||||
.id = -1,
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Corgi Touch Screen Device
|
||||
*/
|
||||
static struct platform_device corgits_device = {
|
||||
.name = "corgi-ts",
|
||||
.dev = {
|
||||
.parent = &corgissp_device.dev,
|
||||
},
|
||||
.id = -1,
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* MMC/SD Device
|
||||
*
|
||||
@ -190,6 +190,11 @@ static void corgi_mci_setpower(struct device *dev, unsigned int vdd)
|
||||
}
|
||||
}
|
||||
|
||||
static int corgi_mci_get_ro(struct device *dev)
|
||||
{
|
||||
return GPLR(CORGI_GPIO_nSD_WP) & GPIO_bit(CORGI_GPIO_nSD_WP);
|
||||
}
|
||||
|
||||
static void corgi_mci_exit(struct device *dev, void *data)
|
||||
{
|
||||
free_irq(CORGI_IRQ_GPIO_nSD_DETECT, data);
|
||||
@ -199,11 +204,13 @@ static void corgi_mci_exit(struct device *dev, void *data)
|
||||
static struct pxamci_platform_data corgi_mci_platform_data = {
|
||||
.ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
|
||||
.init = corgi_mci_init,
|
||||
.get_ro = corgi_mci_get_ro,
|
||||
.setpower = corgi_mci_setpower,
|
||||
.exit = corgi_mci_exit,
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* USB Device Controller
|
||||
*/
|
||||
@ -229,18 +236,20 @@ static struct platform_device *devices[] __initdata = {
|
||||
&corgiscoop_device,
|
||||
&corgissp_device,
|
||||
&corgifb_device,
|
||||
&corgikbd_device,
|
||||
&corgibl_device,
|
||||
&corgits_device,
|
||||
};
|
||||
|
||||
static void __init corgi_init(void)
|
||||
{
|
||||
corgi_fb_info.comadj=sharpsl_param.comadj;
|
||||
corgi_fb_info.phadadj=sharpsl_param.phadadj;
|
||||
|
||||
pxa_gpio_mode(CORGI_GPIO_USB_PULLUP | GPIO_OUT);
|
||||
pxa_set_udc_info(&udc_info);
|
||||
pxa_set_mci_info(&corgi_mci_platform_data);
|
||||
|
||||
scoop_num = 1;
|
||||
scoop_devs = &corgi_pcmcia_scoop[0];
|
||||
|
||||
platform_add_devices(devices, ARRAY_SIZE(devices));
|
||||
}
|
||||
|
||||
|
396
arch/arm/mach-pxa/corgi_lcd.c
Normal file
396
arch/arm/mach-pxa/corgi_lcd.c
Normal file
@ -0,0 +1,396 @@
|
||||
/*
|
||||
* linux/drivers/video/w100fb.c
|
||||
*
|
||||
* Corgi LCD Specific Code for ATI Imageon w100 (Wallaby)
|
||||
*
|
||||
* Copyright (C) 2005 Richard Purdie
|
||||
*
|
||||
* 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/delay.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/device.h>
|
||||
#include <asm/arch/corgi.h>
|
||||
#include <asm/mach/sharpsl_param.h>
|
||||
#include <video/w100fb.h>
|
||||
|
||||
/* Register Addresses */
|
||||
#define RESCTL_ADRS 0x00
|
||||
#define PHACTRL_ADRS 0x01
|
||||
#define DUTYCTRL_ADRS 0x02
|
||||
#define POWERREG0_ADRS 0x03
|
||||
#define POWERREG1_ADRS 0x04
|
||||
#define GPOR3_ADRS 0x05
|
||||
#define PICTRL_ADRS 0x06
|
||||
#define POLCTRL_ADRS 0x07
|
||||
|
||||
/* Resgister Bit Definitions */
|
||||
#define RESCTL_QVGA 0x01
|
||||
#define RESCTL_VGA 0x00
|
||||
|
||||
#define POWER1_VW_ON 0x01 /* VW Supply FET ON */
|
||||
#define POWER1_GVSS_ON 0x02 /* GVSS(-8V) Power Supply ON */
|
||||
#define POWER1_VDD_ON 0x04 /* VDD(8V),SVSS(-4V) Power Supply ON */
|
||||
|
||||
#define POWER1_VW_OFF 0x00 /* VW Supply FET OFF */
|
||||
#define POWER1_GVSS_OFF 0x00 /* GVSS(-8V) Power Supply OFF */
|
||||
#define POWER1_VDD_OFF 0x00 /* VDD(8V),SVSS(-4V) Power Supply OFF */
|
||||
|
||||
#define POWER0_COM_DCLK 0x01 /* COM Voltage DC Bias DAC Serial Data Clock */
|
||||
#define POWER0_COM_DOUT 0x02 /* COM Voltage DC Bias DAC Serial Data Out */
|
||||
#define POWER0_DAC_ON 0x04 /* DAC Power Supply ON */
|
||||
#define POWER0_COM_ON 0x08 /* COM Powewr Supply ON */
|
||||
#define POWER0_VCC5_ON 0x10 /* VCC5 Power Supply ON */
|
||||
|
||||
#define POWER0_DAC_OFF 0x00 /* DAC Power Supply OFF */
|
||||
#define POWER0_COM_OFF 0x00 /* COM Powewr Supply OFF */
|
||||
#define POWER0_VCC5_OFF 0x00 /* VCC5 Power Supply OFF */
|
||||
|
||||
#define PICTRL_INIT_STATE 0x01
|
||||
#define PICTRL_INIOFF 0x02
|
||||
#define PICTRL_POWER_DOWN 0x04
|
||||
#define PICTRL_COM_SIGNAL_OFF 0x08
|
||||
#define PICTRL_DAC_SIGNAL_OFF 0x10
|
||||
|
||||
#define POLCTRL_SYNC_POL_FALL 0x01
|
||||
#define POLCTRL_EN_POL_FALL 0x02
|
||||
#define POLCTRL_DATA_POL_FALL 0x04
|
||||
#define POLCTRL_SYNC_ACT_H 0x08
|
||||
#define POLCTRL_EN_ACT_L 0x10
|
||||
|
||||
#define POLCTRL_SYNC_POL_RISE 0x00
|
||||
#define POLCTRL_EN_POL_RISE 0x00
|
||||
#define POLCTRL_DATA_POL_RISE 0x00
|
||||
#define POLCTRL_SYNC_ACT_L 0x00
|
||||
#define POLCTRL_EN_ACT_H 0x00
|
||||
|
||||
#define PHACTRL_PHASE_MANUAL 0x01
|
||||
#define DEFAULT_PHAD_QVGA (9)
|
||||
#define DEFAULT_COMADJ (125)
|
||||
|
||||
/*
|
||||
* This is only a psuedo I2C interface. We can't use the standard kernel
|
||||
* routines as the interface is write only. We just assume the data is acked...
|
||||
*/
|
||||
static void lcdtg_ssp_i2c_send(u8 data)
|
||||
{
|
||||
corgi_ssp_lcdtg_send(POWERREG0_ADRS, data);
|
||||
udelay(10);
|
||||
}
|
||||
|
||||
static void lcdtg_i2c_send_bit(u8 data)
|
||||
{
|
||||
lcdtg_ssp_i2c_send(data);
|
||||
lcdtg_ssp_i2c_send(data | POWER0_COM_DCLK);
|
||||
lcdtg_ssp_i2c_send(data);
|
||||
}
|
||||
|
||||
static void lcdtg_i2c_send_start(u8 base)
|
||||
{
|
||||
lcdtg_ssp_i2c_send(base | POWER0_COM_DCLK | POWER0_COM_DOUT);
|
||||
lcdtg_ssp_i2c_send(base | POWER0_COM_DCLK);
|
||||
lcdtg_ssp_i2c_send(base);
|
||||
}
|
||||
|
||||
static void lcdtg_i2c_send_stop(u8 base)
|
||||
{
|
||||
lcdtg_ssp_i2c_send(base);
|
||||
lcdtg_ssp_i2c_send(base | POWER0_COM_DCLK);
|
||||
lcdtg_ssp_i2c_send(base | POWER0_COM_DCLK | POWER0_COM_DOUT);
|
||||
}
|
||||
|
||||
static void lcdtg_i2c_send_byte(u8 base, u8 data)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (data & 0x80)
|
||||
lcdtg_i2c_send_bit(base | POWER0_COM_DOUT);
|
||||
else
|
||||
lcdtg_i2c_send_bit(base);
|
||||
data <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void lcdtg_i2c_wait_ack(u8 base)
|
||||
{
|
||||
lcdtg_i2c_send_bit(base);
|
||||
}
|
||||
|
||||
static void lcdtg_set_common_voltage(u8 base_data, u8 data)
|
||||
{
|
||||
/* Set Common Voltage to M62332FP via I2C */
|
||||
lcdtg_i2c_send_start(base_data);
|
||||
lcdtg_i2c_send_byte(base_data, 0x9c);
|
||||
lcdtg_i2c_wait_ack(base_data);
|
||||
lcdtg_i2c_send_byte(base_data, 0x00);
|
||||
lcdtg_i2c_wait_ack(base_data);
|
||||
lcdtg_i2c_send_byte(base_data, data);
|
||||
lcdtg_i2c_wait_ack(base_data);
|
||||
lcdtg_i2c_send_stop(base_data);
|
||||
}
|
||||
|
||||
/* Set Phase Adjuct */
|
||||
static void lcdtg_set_phadadj(struct w100fb_par *par)
|
||||
{
|
||||
int adj;
|
||||
switch(par->xres) {
|
||||
case 480:
|
||||
case 640:
|
||||
/* Setting for VGA */
|
||||
adj = sharpsl_param.phadadj;
|
||||
if (adj < 0) {
|
||||
adj = PHACTRL_PHASE_MANUAL;
|
||||
} else {
|
||||
adj = ((adj & 0x0f) << 1) | PHACTRL_PHASE_MANUAL;
|
||||
}
|
||||
break;
|
||||
case 240:
|
||||
case 320:
|
||||
default:
|
||||
/* Setting for QVGA */
|
||||
adj = (DEFAULT_PHAD_QVGA << 1) | PHACTRL_PHASE_MANUAL;
|
||||
break;
|
||||
}
|
||||
|
||||
corgi_ssp_lcdtg_send(PHACTRL_ADRS, adj);
|
||||
}
|
||||
|
||||
static int lcd_inited;
|
||||
|
||||
static void lcdtg_hw_init(struct w100fb_par *par)
|
||||
{
|
||||
if (!lcd_inited) {
|
||||
int comadj;
|
||||
|
||||
/* Initialize Internal Logic & Port */
|
||||
corgi_ssp_lcdtg_send(PICTRL_ADRS, PICTRL_POWER_DOWN | PICTRL_INIOFF | PICTRL_INIT_STATE
|
||||
| PICTRL_COM_SIGNAL_OFF | PICTRL_DAC_SIGNAL_OFF);
|
||||
|
||||
corgi_ssp_lcdtg_send(POWERREG0_ADRS, POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_OFF
|
||||
| POWER0_COM_OFF | POWER0_VCC5_OFF);
|
||||
|
||||
corgi_ssp_lcdtg_send(POWERREG1_ADRS, POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_OFF);
|
||||
|
||||
/* VDD(+8V), SVSS(-4V) ON */
|
||||
corgi_ssp_lcdtg_send(POWERREG1_ADRS, POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_ON);
|
||||
mdelay(3);
|
||||
|
||||
/* DAC ON */
|
||||
corgi_ssp_lcdtg_send(POWERREG0_ADRS, POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_ON
|
||||
| POWER0_COM_OFF | POWER0_VCC5_OFF);
|
||||
|
||||
/* INIB = H, INI = L */
|
||||
/* PICTL[0] = H , PICTL[1] = PICTL[2] = PICTL[4] = L */
|
||||
corgi_ssp_lcdtg_send(PICTRL_ADRS, PICTRL_INIT_STATE | PICTRL_COM_SIGNAL_OFF);
|
||||
|
||||
/* Set Common Voltage */
|
||||
comadj = sharpsl_param.comadj;
|
||||
if (comadj < 0)
|
||||
comadj = DEFAULT_COMADJ;
|
||||
lcdtg_set_common_voltage((POWER0_DAC_ON | POWER0_COM_OFF | POWER0_VCC5_OFF), comadj);
|
||||
|
||||
/* VCC5 ON, DAC ON */
|
||||
corgi_ssp_lcdtg_send(POWERREG0_ADRS, POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_ON |
|
||||
POWER0_COM_OFF | POWER0_VCC5_ON);
|
||||
|
||||
/* GVSS(-8V) ON, VDD ON */
|
||||
corgi_ssp_lcdtg_send(POWERREG1_ADRS, POWER1_VW_OFF | POWER1_GVSS_ON | POWER1_VDD_ON);
|
||||
mdelay(2);
|
||||
|
||||
/* COM SIGNAL ON (PICTL[3] = L) */
|
||||
corgi_ssp_lcdtg_send(PICTRL_ADRS, PICTRL_INIT_STATE);
|
||||
|
||||
/* COM ON, DAC ON, VCC5_ON */
|
||||
corgi_ssp_lcdtg_send(POWERREG0_ADRS, POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_ON
|
||||
| POWER0_COM_ON | POWER0_VCC5_ON);
|
||||
|
||||
/* VW ON, GVSS ON, VDD ON */
|
||||
corgi_ssp_lcdtg_send(POWERREG1_ADRS, POWER1_VW_ON | POWER1_GVSS_ON | POWER1_VDD_ON);
|
||||
|
||||
/* Signals output enable */
|
||||
corgi_ssp_lcdtg_send(PICTRL_ADRS, 0);
|
||||
|
||||
/* Set Phase Adjuct */
|
||||
lcdtg_set_phadadj(par);
|
||||
|
||||
/* Initialize for Input Signals from ATI */
|
||||
corgi_ssp_lcdtg_send(POLCTRL_ADRS, POLCTRL_SYNC_POL_RISE | POLCTRL_EN_POL_RISE
|
||||
| POLCTRL_DATA_POL_RISE | POLCTRL_SYNC_ACT_L | POLCTRL_EN_ACT_H);
|
||||
udelay(1000);
|
||||
|
||||
lcd_inited=1;
|
||||
} else {
|
||||
lcdtg_set_phadadj(par);
|
||||
}
|
||||
|
||||
switch(par->xres) {
|
||||
case 480:
|
||||
case 640:
|
||||
/* Set Lcd Resolution (VGA) */
|
||||
corgi_ssp_lcdtg_send(RESCTL_ADRS, RESCTL_VGA);
|
||||
break;
|
||||
case 240:
|
||||
case 320:
|
||||
default:
|
||||
/* Set Lcd Resolution (QVGA) */
|
||||
corgi_ssp_lcdtg_send(RESCTL_ADRS, RESCTL_QVGA);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void lcdtg_suspend(struct w100fb_par *par)
|
||||
{
|
||||
/* 60Hz x 2 frame = 16.7msec x 2 = 33.4 msec */
|
||||
mdelay(34);
|
||||
|
||||
/* (1)VW OFF */
|
||||
corgi_ssp_lcdtg_send(POWERREG1_ADRS, POWER1_VW_OFF | POWER1_GVSS_ON | POWER1_VDD_ON);
|
||||
|
||||
/* (2)COM OFF */
|
||||
corgi_ssp_lcdtg_send(PICTRL_ADRS, PICTRL_COM_SIGNAL_OFF);
|
||||
corgi_ssp_lcdtg_send(POWERREG0_ADRS, POWER0_DAC_ON | POWER0_COM_OFF | POWER0_VCC5_ON);
|
||||
|
||||
/* (3)Set Common Voltage Bias 0V */
|
||||
lcdtg_set_common_voltage(POWER0_DAC_ON | POWER0_COM_OFF | POWER0_VCC5_ON, 0);
|
||||
|
||||
/* (4)GVSS OFF */
|
||||
corgi_ssp_lcdtg_send(POWERREG1_ADRS, POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_ON);
|
||||
|
||||
/* (5)VCC5 OFF */
|
||||
corgi_ssp_lcdtg_send(POWERREG0_ADRS, POWER0_DAC_ON | POWER0_COM_OFF | POWER0_VCC5_OFF);
|
||||
|
||||
/* (6)Set PDWN, INIOFF, DACOFF */
|
||||
corgi_ssp_lcdtg_send(PICTRL_ADRS, PICTRL_INIOFF | PICTRL_DAC_SIGNAL_OFF |
|
||||
PICTRL_POWER_DOWN | PICTRL_COM_SIGNAL_OFF);
|
||||
|
||||
/* (7)DAC OFF */
|
||||
corgi_ssp_lcdtg_send(POWERREG0_ADRS, POWER0_DAC_OFF | POWER0_COM_OFF | POWER0_VCC5_OFF);
|
||||
|
||||
/* (8)VDD OFF */
|
||||
corgi_ssp_lcdtg_send(POWERREG1_ADRS, POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_OFF);
|
||||
|
||||
lcd_inited = 0;
|
||||
}
|
||||
|
||||
static struct w100_tg_info corgi_lcdtg_info = {
|
||||
.change=lcdtg_hw_init,
|
||||
.suspend=lcdtg_suspend,
|
||||
.resume=lcdtg_hw_init,
|
||||
};
|
||||
|
||||
/*
|
||||
* Corgi w100 Frame Buffer Device
|
||||
*/
|
||||
|
||||
static struct w100_mem_info corgi_fb_mem = {
|
||||
.ext_cntl = 0x00040003,
|
||||
.sdram_mode_reg = 0x00650021,
|
||||
.ext_timing_cntl = 0x10002a4a,
|
||||
.io_cntl = 0x7ff87012,
|
||||
.size = 0x1fffff,
|
||||
};
|
||||
|
||||
static struct w100_gen_regs corgi_fb_regs = {
|
||||
.lcd_format = 0x00000003,
|
||||
.lcdd_cntl1 = 0x01CC0000,
|
||||
.lcdd_cntl2 = 0x0003FFFF,
|
||||
.genlcd_cntl1 = 0x00FFFF0D,
|
||||
.genlcd_cntl2 = 0x003F3003,
|
||||
.genlcd_cntl3 = 0x000102aa,
|
||||
};
|
||||
|
||||
static struct w100_gpio_regs corgi_fb_gpio = {
|
||||
.init_data1 = 0x000000bf,
|
||||
.init_data2 = 0x00000000,
|
||||
.gpio_dir1 = 0x00000000,
|
||||
.gpio_oe1 = 0x03c0feff,
|
||||
.gpio_dir2 = 0x00000000,
|
||||
.gpio_oe2 = 0x00000000,
|
||||
};
|
||||
|
||||
static struct w100_mode corgi_fb_modes[] = {
|
||||
{
|
||||
.xres = 480,
|
||||
.yres = 640,
|
||||
.left_margin = 0x56,
|
||||
.right_margin = 0x55,
|
||||
.upper_margin = 0x03,
|
||||
.lower_margin = 0x00,
|
||||
.crtc_ss = 0x82360056,
|
||||
.crtc_ls = 0xA0280000,
|
||||
.crtc_gs = 0x80280028,
|
||||
.crtc_vpos_gs = 0x02830002,
|
||||
.crtc_rev = 0x00400008,
|
||||
.crtc_dclk = 0xA0000000,
|
||||
.crtc_gclk = 0x8015010F,
|
||||
.crtc_goe = 0x80100110,
|
||||
.crtc_ps1_active = 0x41060010,
|
||||
.pll_freq = 75,
|
||||
.fast_pll_freq = 100,
|
||||
.sysclk_src = CLK_SRC_PLL,
|
||||
.sysclk_divider = 0,
|
||||
.pixclk_src = CLK_SRC_PLL,
|
||||
.pixclk_divider = 2,
|
||||
.pixclk_divider_rotated = 6,
|
||||
},{
|
||||
.xres = 240,
|
||||
.yres = 320,
|
||||
.left_margin = 0x27,
|
||||
.right_margin = 0x2e,
|
||||
.upper_margin = 0x01,
|
||||
.lower_margin = 0x00,
|
||||
.crtc_ss = 0x81170027,
|
||||
.crtc_ls = 0xA0140000,
|
||||
.crtc_gs = 0xC0140014,
|
||||
.crtc_vpos_gs = 0x00010141,
|
||||
.crtc_rev = 0x00400008,
|
||||
.crtc_dclk = 0xA0000000,
|
||||
.crtc_gclk = 0x8015010F,
|
||||
.crtc_goe = 0x80100110,
|
||||
.crtc_ps1_active = 0x41060010,
|
||||
.pll_freq = 0,
|
||||
.fast_pll_freq = 0,
|
||||
.sysclk_src = CLK_SRC_XTAL,
|
||||
.sysclk_divider = 0,
|
||||
.pixclk_src = CLK_SRC_XTAL,
|
||||
.pixclk_divider = 1,
|
||||
.pixclk_divider_rotated = 1,
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
static struct w100fb_mach_info corgi_fb_info = {
|
||||
.tg = &corgi_lcdtg_info,
|
||||
.init_mode = INIT_MODE_ROTATED,
|
||||
.mem = &corgi_fb_mem,
|
||||
.regs = &corgi_fb_regs,
|
||||
.modelist = &corgi_fb_modes[0],
|
||||
.num_modes = 2,
|
||||
.gpio = &corgi_fb_gpio,
|
||||
.xtal_freq = 12500000,
|
||||
.xtal_dbl = 0,
|
||||
};
|
||||
|
||||
static struct resource corgi_fb_resources[] = {
|
||||
[0] = {
|
||||
.start = 0x08000000,
|
||||
.end = 0x08ffffff,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
};
|
||||
|
||||
struct platform_device corgifb_device = {
|
||||
.name = "w100fb",
|
||||
.id = -1,
|
||||
.num_resources = ARRAY_SIZE(corgi_fb_resources),
|
||||
.resource = corgi_fb_resources,
|
||||
.dev = {
|
||||
.platform_data = &corgi_fb_info,
|
||||
.parent = &corgissp_device.dev,
|
||||
},
|
||||
|
||||
};
|
@ -133,7 +133,7 @@ static struct irqchip pxa_low_gpio_chip = {
|
||||
.ack = pxa_ack_low_gpio,
|
||||
.mask = pxa_mask_low_irq,
|
||||
.unmask = pxa_unmask_low_irq,
|
||||
.type = pxa_gpio_irq_type,
|
||||
.set_type = pxa_gpio_irq_type,
|
||||
};
|
||||
|
||||
/*
|
||||
@ -157,7 +157,7 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irqdesc *desc,
|
||||
mask >>= 2;
|
||||
do {
|
||||
if (mask & 1)
|
||||
desc->handle(irq, desc, regs);
|
||||
desc_handle_irq(irq, desc, regs);
|
||||
irq++;
|
||||
desc++;
|
||||
mask >>= 1;
|
||||
@ -172,7 +172,7 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irqdesc *desc,
|
||||
desc = irq_desc + irq;
|
||||
do {
|
||||
if (mask & 1)
|
||||
desc->handle(irq, desc, regs);
|
||||
desc_handle_irq(irq, desc, regs);
|
||||
irq++;
|
||||
desc++;
|
||||
mask >>= 1;
|
||||
@ -187,7 +187,7 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irqdesc *desc,
|
||||
desc = irq_desc + irq;
|
||||
do {
|
||||
if (mask & 1)
|
||||
desc->handle(irq, desc, regs);
|
||||
desc_handle_irq(irq, desc, regs);
|
||||
irq++;
|
||||
desc++;
|
||||
mask >>= 1;
|
||||
@ -203,7 +203,7 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irqdesc *desc,
|
||||
desc = irq_desc + irq;
|
||||
do {
|
||||
if (mask & 1)
|
||||
desc->handle(irq, desc, regs);
|
||||
desc_handle_irq(irq, desc, regs);
|
||||
irq++;
|
||||
desc++;
|
||||
mask >>= 1;
|
||||
@ -241,7 +241,7 @@ static struct irqchip pxa_muxed_gpio_chip = {
|
||||
.ack = pxa_ack_muxed_gpio,
|
||||
.mask = pxa_mask_muxed_gpio,
|
||||
.unmask = pxa_unmask_muxed_gpio,
|
||||
.type = pxa_gpio_irq_type,
|
||||
.set_type = pxa_gpio_irq_type,
|
||||
};
|
||||
|
||||
|
||||
|
@ -84,7 +84,7 @@ static void lubbock_irq_handler(unsigned int irq, struct irqdesc *desc,
|
||||
if (likely(pending)) {
|
||||
irq = LUBBOCK_IRQ(0) + __ffs(pending);
|
||||
desc = irq_desc + irq;
|
||||
desc->handle(irq, desc, regs);
|
||||
desc_handle_irq(irq, desc, regs);
|
||||
}
|
||||
pending = LUB_IRQ_SET_CLR & lubbock_irq_enabled;
|
||||
} while (pending);
|
||||
|
@ -72,7 +72,7 @@ static void mainstone_irq_handler(unsigned int irq, struct irqdesc *desc,
|
||||
if (likely(pending)) {
|
||||
irq = MAINSTONE_IRQ(0) + __ffs(pending);
|
||||
desc = irq_desc + irq;
|
||||
desc->handle(irq, desc, regs);
|
||||
desc_handle_irq(irq, desc, regs);
|
||||
}
|
||||
pending = MST_INTSETCLR & mainstone_irq_enabled;
|
||||
} while (pending);
|
||||
|
@ -62,6 +62,15 @@ struct platform_device poodle_scoop_device = {
|
||||
.resource = poodle_scoop_resources,
|
||||
};
|
||||
|
||||
static struct scoop_pcmcia_dev poodle_pcmcia_scoop[] = {
|
||||
{
|
||||
.dev = &poodle_scoop_device.dev,
|
||||
.irq = POODLE_IRQ_GPIO_CF_IRQ,
|
||||
.cd_irq = POODLE_IRQ_GPIO_CF_CD,
|
||||
.cd_irq_str = "PCMCIA0 CD",
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
/* LoCoMo device */
|
||||
static struct resource locomo_resources[] = {
|
||||
@ -147,6 +156,9 @@ static void __init poodle_init(void)
|
||||
|
||||
set_pxa_fb_info(&poodle_fb_info);
|
||||
|
||||
scoop_num = 1;
|
||||
scoop_devs = &poodle_pcmcia_scoop[0];
|
||||
|
||||
ret = platform_add_devices(devices, ARRAY_SIZE(devices));
|
||||
if (ret) {
|
||||
printk(KERN_WARNING "poodle: Unable to register LoCoMo device\n");
|
||||
|
@ -70,6 +70,11 @@ static unsigned long pxa_gettimeoffset (void)
|
||||
return usec;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NO_IDLE_HZ
|
||||
static unsigned long initial_match;
|
||||
static int match_posponed;
|
||||
#endif
|
||||
|
||||
static irqreturn_t
|
||||
pxa_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
|
||||
{
|
||||
@ -77,11 +82,19 @@ pxa_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
|
||||
|
||||
write_seqlock(&xtime_lock);
|
||||
|
||||
#ifdef CONFIG_NO_IDLE_HZ
|
||||
if (match_posponed) {
|
||||
match_posponed = 0;
|
||||
OSMR0 = initial_match;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Loop until we get ahead of the free running timer.
|
||||
* This ensures an exact clock tick count and time accuracy.
|
||||
* IRQs are disabled inside the loop to ensure coherence between
|
||||
* lost_ticks (updated in do_timer()) and the match reg value, so we
|
||||
* can use do_gettimeofday() from interrupt handlers.
|
||||
* Since IRQs are disabled at this point, coherence between
|
||||
* lost_ticks(updated in do_timer()) and the match reg value is
|
||||
* ensured, hence we can use do_gettimeofday() from interrupt
|
||||
* handlers.
|
||||
*
|
||||
* HACK ALERT: it seems that the PXA timer regs aren't updated right
|
||||
* away in all cases when a write occurs. We therefore compare with
|
||||
@ -126,6 +139,42 @@ static void __init pxa_timer_init(void)
|
||||
OSCR = 0; /* initialize free-running timer, force first match */
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NO_IDLE_HZ
|
||||
static int pxa_dyn_tick_enable_disable(void)
|
||||
{
|
||||
/* nothing to do */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void pxa_dyn_tick_reprogram(unsigned long ticks)
|
||||
{
|
||||
if (ticks > 1) {
|
||||
initial_match = OSMR0;
|
||||
OSMR0 = initial_match + ticks * LATCH;
|
||||
match_posponed = 1;
|
||||
}
|
||||
}
|
||||
|
||||
static irqreturn_t
|
||||
pxa_dyn_tick_handler(int irq, void *dev_id, struct pt_regs *regs)
|
||||
{
|
||||
if (match_posponed) {
|
||||
match_posponed = 0;
|
||||
OSMR0 = initial_match;
|
||||
if ( (signed long)(initial_match - OSCR) <= 8 )
|
||||
return pxa_timer_interrupt(irq, dev_id, regs);
|
||||
}
|
||||
return IRQ_NONE;
|
||||
}
|
||||
|
||||
static struct dyn_tick_timer pxa_dyn_tick = {
|
||||
.enable = pxa_dyn_tick_enable_disable,
|
||||
.disable = pxa_dyn_tick_enable_disable,
|
||||
.reprogram = pxa_dyn_tick_reprogram,
|
||||
.handler = pxa_dyn_tick_handler,
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static unsigned long osmr[4], oier;
|
||||
|
||||
@ -161,4 +210,7 @@ struct sys_timer pxa_timer = {
|
||||
.suspend = pxa_timer_suspend,
|
||||
.resume = pxa_timer_resume,
|
||||
.offset = pxa_gettimeoffset,
|
||||
#ifdef CONFIG_NO_IDLE_HZ
|
||||
.dyn_tick = &pxa_dyn_tick,
|
||||
#endif
|
||||
};
|
||||
|
@ -2,6 +2,13 @@ if ARCH_S3C2410
|
||||
|
||||
menu "S3C24XX Implementations"
|
||||
|
||||
config MACH_ANUBIS
|
||||
bool "Simtec Electronics ANUBIS"
|
||||
select CPU_S3C2440
|
||||
help
|
||||
Say Y gere if you are using the Simtec Electronics ANUBIS
|
||||
development system
|
||||
|
||||
config ARCH_BAST
|
||||
bool "Simtec Electronics BAST (EB2410ITX)"
|
||||
select CPU_S3C2410
|
||||
@ -11,6 +18,14 @@ config ARCH_BAST
|
||||
|
||||
Product page: <http://www.simtec.co.uk/products/EB2410ITX/>.
|
||||
|
||||
config BAST_PC104_IRQ
|
||||
bool "BAST PC104 IRQ support"
|
||||
depends on ARCH_BAST
|
||||
default y
|
||||
help
|
||||
Say Y here to enable the PC104 IRQ routing on the
|
||||
Simtec BAST (EB2410ITX)
|
||||
|
||||
config ARCH_H1940
|
||||
bool "IPAQ H1940"
|
||||
select CPU_S3C2410
|
||||
|
@ -26,8 +26,13 @@ obj-$(CONFIG_CPU_S3C2440) += s3c2440.o s3c2440-dsc.o
|
||||
obj-$(CONFIG_CPU_S3C2440) += s3c2440-irq.o
|
||||
obj-$(CONFIG_CPU_S3C2440) += s3c2440-clock.o
|
||||
|
||||
# bast extras
|
||||
|
||||
obj-$(CONFIG_BAST_PC104_IRQ) += bast-irq.o
|
||||
|
||||
# machine specific support
|
||||
|
||||
obj-$(CONFIG_MACH_ANUBIS) += mach-anubis.o
|
||||
obj-$(CONFIG_ARCH_BAST) += mach-bast.o usb-simtec.o
|
||||
obj-$(CONFIG_ARCH_H1940) += mach-h1940.o
|
||||
obj-$(CONFIG_MACH_N30) += mach-n30.o
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* linux/arch/arm/mach-s3c2410/bast-irq.c
|
||||
*
|
||||
* Copyright (c) 2004 Simtec Electronics
|
||||
* Copyright (c) 2003,2005 Simtec Electronics
|
||||
* Ben Dooks <ben@simtec.co.uk>
|
||||
*
|
||||
* http://www.simtec.co.uk/products/EB2410ITX/
|
||||
@ -21,7 +21,8 @@
|
||||
*
|
||||
* Modifications:
|
||||
* 08-Jan-2003 BJD Moved from central IRQ code
|
||||
*/
|
||||
* 21-Aug-2005 BJD Fixed missing code and compile errors
|
||||
*/
|
||||
|
||||
|
||||
#include <linux/init.h>
|
||||
@ -30,12 +31,19 @@
|
||||
#include <linux/ptrace.h>
|
||||
#include <linux/sysdev.h>
|
||||
|
||||
#include <asm/mach-types.h>
|
||||
|
||||
#include <asm/hardware.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
#include <asm/mach/irq.h>
|
||||
#include <asm/hardware/s3c2410/irq.h>
|
||||
|
||||
#include <asm/arch/regs-irq.h>
|
||||
#include <asm/arch/bast-map.h>
|
||||
#include <asm/arch/bast-irq.h>
|
||||
|
||||
#include "irq.h"
|
||||
|
||||
#if 0
|
||||
#include <asm/debug-ll.h>
|
||||
@ -79,15 +87,15 @@ bast_pc104_mask(unsigned int irqno)
|
||||
temp = __raw_readb(BAST_VA_PC104_IRQMASK);
|
||||
temp &= ~bast_pc104_irqmasks[irqno];
|
||||
__raw_writeb(temp, BAST_VA_PC104_IRQMASK);
|
||||
|
||||
if (temp == 0)
|
||||
bast_extint_mask(IRQ_ISA);
|
||||
}
|
||||
|
||||
static void
|
||||
bast_pc104_ack(unsigned int irqno)
|
||||
bast_pc104_maskack(unsigned int irqno)
|
||||
{
|
||||
bast_extint_ack(IRQ_ISA);
|
||||
struct irqdesc *desc = irq_desc + IRQ_ISA;
|
||||
|
||||
bast_pc104_mask(irqno);
|
||||
desc->chip->ack(IRQ_ISA);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -98,14 +106,12 @@ bast_pc104_unmask(unsigned int irqno)
|
||||
temp = __raw_readb(BAST_VA_PC104_IRQMASK);
|
||||
temp |= bast_pc104_irqmasks[irqno];
|
||||
__raw_writeb(temp, BAST_VA_PC104_IRQMASK);
|
||||
|
||||
bast_extint_unmask(IRQ_ISA);
|
||||
}
|
||||
|
||||
static struct bast_pc104_chip = {
|
||||
static struct irqchip bast_pc104_chip = {
|
||||
.mask = bast_pc104_mask,
|
||||
.unmask = bast_pc104_unmask,
|
||||
.ack = bast_pc104_ack
|
||||
.ack = bast_pc104_maskack
|
||||
};
|
||||
|
||||
static void
|
||||
@ -119,14 +125,49 @@ bast_irq_pc104_demux(unsigned int irq,
|
||||
|
||||
stat = __raw_readb(BAST_VA_PC104_IRQREQ) & 0xf;
|
||||
|
||||
for (i = 0; i < 4 && stat != 0; i++) {
|
||||
if (stat & 1) {
|
||||
irqno = bast_pc104_irqs[i];
|
||||
desc = irq_desc + irqno;
|
||||
if (unlikely(stat == 0)) {
|
||||
/* ack if we get an irq with nothing (ie, startup) */
|
||||
|
||||
desc->handle(irqno, desc, regs);
|
||||
desc = irq_desc + IRQ_ISA;
|
||||
desc->chip->ack(IRQ_ISA);
|
||||
} else {
|
||||
/* handle the IRQ */
|
||||
|
||||
for (i = 0; stat != 0; i++, stat >>= 1) {
|
||||
if (stat & 1) {
|
||||
irqno = bast_pc104_irqs[i];
|
||||
|
||||
desc_handle_irq(irqno, irq_desc + irqno, regs);
|
||||
}
|
||||
}
|
||||
|
||||
stat >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
static __init int bast_irq_init(void)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
if (machine_is_bast()) {
|
||||
printk(KERN_INFO "BAST PC104 IRQ routing, (c) 2005 Simtec Electronics\n");
|
||||
|
||||
/* zap all the IRQs */
|
||||
|
||||
__raw_writeb(0x0, BAST_VA_PC104_IRQMASK);
|
||||
|
||||
set_irq_chained_handler(IRQ_ISA, bast_irq_pc104_demux);
|
||||
|
||||
/* reigster our IRQs */
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
unsigned int irqno = bast_pc104_irqs[i];
|
||||
|
||||
set_irq_chip(irqno, &bast_pc104_chip);
|
||||
set_irq_handler(irqno, do_level_IRQ);
|
||||
set_irq_flags(irqno, IRQF_VALID);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
arch_initcall(bast_irq_init);
|
||||
|
@ -388,6 +388,7 @@ int __init s3c24xx_setup_clocks(unsigned long xtal,
|
||||
unsigned long hclk,
|
||||
unsigned long pclk)
|
||||
{
|
||||
unsigned long clkslow = __raw_readl(S3C2410_CLKSLOW);
|
||||
struct clk *clkp = init_clocks;
|
||||
int ptr;
|
||||
int ret;
|
||||
@ -446,5 +447,13 @@ int __init s3c24xx_setup_clocks(unsigned long xtal,
|
||||
}
|
||||
}
|
||||
|
||||
/* show the clock-slow value */
|
||||
|
||||
printk("CLOCK: Slow mode (%ld.%ld MHz), %s, MPLL %s, UPLL %s\n",
|
||||
print_mhz(xtal / ( 2 * S3C2410_CLKSLOW_GET_SLOWVAL(clkslow))),
|
||||
(clkslow & S3C2410_CLKSLOW_SLOW) ? "slow" : "fast",
|
||||
(clkslow & S3C2410_CLKSLOW_MPLL_OFF) ? "off" : "on",
|
||||
(clkslow & S3C2410_CLKSLOW_UCLK_OFF) ? "off" : "on");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -184,14 +184,14 @@ struct irqchip s3c_irq_level_chip = {
|
||||
.ack = s3c_irq_maskack,
|
||||
.mask = s3c_irq_mask,
|
||||
.unmask = s3c_irq_unmask,
|
||||
.wake = s3c_irq_wake
|
||||
.set_wake = s3c_irq_wake
|
||||
};
|
||||
|
||||
static struct irqchip s3c_irq_chip = {
|
||||
.ack = s3c_irq_ack,
|
||||
.mask = s3c_irq_mask,
|
||||
.unmask = s3c_irq_unmask,
|
||||
.wake = s3c_irq_wake
|
||||
.set_wake = s3c_irq_wake
|
||||
};
|
||||
|
||||
/* S3C2410_EINTMASK
|
||||
@ -350,16 +350,16 @@ static struct irqchip s3c_irqext_chip = {
|
||||
.mask = s3c_irqext_mask,
|
||||
.unmask = s3c_irqext_unmask,
|
||||
.ack = s3c_irqext_ack,
|
||||
.type = s3c_irqext_type,
|
||||
.wake = s3c_irqext_wake
|
||||
.set_type = s3c_irqext_type,
|
||||
.set_wake = s3c_irqext_wake
|
||||
};
|
||||
|
||||
static struct irqchip s3c_irq_eint0t4 = {
|
||||
.ack = s3c_irq_ack,
|
||||
.mask = s3c_irq_mask,
|
||||
.unmask = s3c_irq_unmask,
|
||||
.wake = s3c_irq_wake,
|
||||
.type = s3c_irqext_type,
|
||||
.set_wake = s3c_irq_wake,
|
||||
.set_type = s3c_irqext_type,
|
||||
};
|
||||
|
||||
/* mask values for the parent registers for each of the interrupt types */
|
||||
@ -496,11 +496,11 @@ static void s3c_irq_demux_adc(unsigned int irq,
|
||||
if (subsrc != 0) {
|
||||
if (subsrc & 1) {
|
||||
mydesc = irq_desc + IRQ_TC;
|
||||
mydesc->handle( IRQ_TC, mydesc, regs);
|
||||
desc_handle_irq(IRQ_TC, mydesc, regs);
|
||||
}
|
||||
if (subsrc & 2) {
|
||||
mydesc = irq_desc + IRQ_ADC;
|
||||
mydesc->handle(IRQ_ADC, mydesc, regs);
|
||||
desc_handle_irq(IRQ_ADC, mydesc, regs);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -529,17 +529,17 @@ static void s3c_irq_demux_uart(unsigned int start,
|
||||
desc = irq_desc + start;
|
||||
|
||||
if (subsrc & 1)
|
||||
desc->handle(start, desc, regs);
|
||||
desc_handle_irq(start, desc, regs);
|
||||
|
||||
desc++;
|
||||
|
||||
if (subsrc & 2)
|
||||
desc->handle(start+1, desc, regs);
|
||||
desc_handle_irq(start+1, desc, regs);
|
||||
|
||||
desc++;
|
||||
|
||||
if (subsrc & 4)
|
||||
desc->handle(start+2, desc, regs);
|
||||
desc_handle_irq(start+2, desc, regs);
|
||||
}
|
||||
}
|
||||
|
||||
|
270
arch/arm/mach-s3c2410/mach-anubis.c
Normal file
270
arch/arm/mach-s3c2410/mach-anubis.c
Normal file
@ -0,0 +1,270 @@
|
||||
/* linux/arch/arm/mach-s3c2410/mach-anubis.c
|
||||
*
|
||||
* Copyright (c) 2003-2005 Simtec Electronics
|
||||
* http://armlinux.simtec.co.uk/
|
||||
* 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 version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* Modifications:
|
||||
* 02-May-2005 BJD Copied from mach-bast.c
|
||||
*/
|
||||
|
||||
#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/device.h>
|
||||
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/map.h>
|
||||
#include <asm/mach/irq.h>
|
||||
|
||||
#include <asm/arch/anubis-map.h>
|
||||
#include <asm/arch/anubis-irq.h>
|
||||
#include <asm/arch/anubis-cpld.h>
|
||||
|
||||
#include <asm/hardware.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/mach-types.h>
|
||||
|
||||
#include <asm/arch/regs-serial.h>
|
||||
#include <asm/arch/regs-gpio.h>
|
||||
#include <asm/arch/regs-mem.h>
|
||||
#include <asm/arch/regs-lcd.h>
|
||||
#include <asm/arch/nand.h>
|
||||
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/nand.h>
|
||||
#include <linux/mtd/nand_ecc.h>
|
||||
#include <linux/mtd/partitions.h>
|
||||
|
||||
#include "clock.h"
|
||||
#include "devs.h"
|
||||
#include "cpu.h"
|
||||
|
||||
#define COPYRIGHT ", (c) 2005 Simtec Electronics"
|
||||
|
||||
static struct map_desc anubis_iodesc[] __initdata = {
|
||||
/* ISA IO areas */
|
||||
|
||||
{ (u32)S3C24XX_VA_ISA_BYTE, 0x0, SZ_16M, MT_DEVICE },
|
||||
{ (u32)S3C24XX_VA_ISA_WORD, 0x0, SZ_16M, MT_DEVICE },
|
||||
|
||||
/* we could possibly compress the next set down into a set of smaller tables
|
||||
* pagetables, but that would mean using an L2 section, and it still means
|
||||
* we cannot actually feed the same register to an LDR due to 16K spacing
|
||||
*/
|
||||
|
||||
/* CPLD control registers */
|
||||
|
||||
{ (u32)ANUBIS_VA_CTRL1, ANUBIS_PA_CTRL1, SZ_4K, MT_DEVICE },
|
||||
{ (u32)ANUBIS_VA_CTRL2, ANUBIS_PA_CTRL2, SZ_4K, MT_DEVICE },
|
||||
|
||||
/* IDE drives */
|
||||
|
||||
{ (u32)ANUBIS_IDEPRI, S3C2410_CS3, SZ_1M, MT_DEVICE },
|
||||
{ (u32)ANUBIS_IDEPRIAUX, S3C2410_CS3+(1<<26), SZ_1M, MT_DEVICE },
|
||||
|
||||
{ (u32)ANUBIS_IDESEC, S3C2410_CS4, SZ_1M, MT_DEVICE },
|
||||
{ (u32)ANUBIS_IDESECAUX, S3C2410_CS4+(1<<26), SZ_1M, MT_DEVICE },
|
||||
};
|
||||
|
||||
#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK
|
||||
#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
|
||||
#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
|
||||
|
||||
static struct s3c24xx_uart_clksrc anubis_serial_clocks[] = {
|
||||
[0] = {
|
||||
.name = "uclk",
|
||||
.divisor = 1,
|
||||
.min_baud = 0,
|
||||
.max_baud = 0,
|
||||
},
|
||||
[1] = {
|
||||
.name = "pclk",
|
||||
.divisor = 1,
|
||||
.min_baud = 0,
|
||||
.max_baud = 0.
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
static struct s3c2410_uartcfg anubis_uartcfgs[] = {
|
||||
[0] = {
|
||||
.hwport = 0,
|
||||
.flags = 0,
|
||||
.ucon = UCON,
|
||||
.ulcon = ULCON,
|
||||
.ufcon = UFCON,
|
||||
.clocks = anubis_serial_clocks,
|
||||
.clocks_size = ARRAY_SIZE(anubis_serial_clocks)
|
||||
},
|
||||
[1] = {
|
||||
.hwport = 2,
|
||||
.flags = 0,
|
||||
.ucon = UCON,
|
||||
.ulcon = ULCON,
|
||||
.ufcon = UFCON,
|
||||
.clocks = anubis_serial_clocks,
|
||||
.clocks_size = ARRAY_SIZE(anubis_serial_clocks)
|
||||
},
|
||||
};
|
||||
|
||||
/* NAND Flash on Anubis board */
|
||||
|
||||
static int external_map[] = { 2 };
|
||||
static int chip0_map[] = { 0 };
|
||||
static int chip1_map[] = { 1 };
|
||||
|
||||
struct mtd_partition anubis_default_nand_part[] = {
|
||||
[0] = {
|
||||
.name = "Boot Agent",
|
||||
.size = SZ_16K,
|
||||
.offset = 0
|
||||
},
|
||||
[1] = {
|
||||
.name = "/boot",
|
||||
.size = SZ_4M - SZ_16K,
|
||||
.offset = SZ_16K,
|
||||
},
|
||||
[2] = {
|
||||
.name = "user1",
|
||||
.offset = SZ_4M,
|
||||
.size = SZ_32M - SZ_4M,
|
||||
},
|
||||
[3] = {
|
||||
.name = "user2",
|
||||
.offset = SZ_32M,
|
||||
.size = MTDPART_SIZ_FULL,
|
||||
}
|
||||
};
|
||||
|
||||
/* the Anubis has 3 selectable slots for nand-flash, the two
|
||||
* on-board chip areas, as well as the external slot.
|
||||
*
|
||||
* Note, there is no current hot-plug support for the External
|
||||
* socket.
|
||||
*/
|
||||
|
||||
static struct s3c2410_nand_set anubis_nand_sets[] = {
|
||||
[1] = {
|
||||
.name = "External",
|
||||
.nr_chips = 1,
|
||||
.nr_map = external_map,
|
||||
.nr_partitions = ARRAY_SIZE(anubis_default_nand_part),
|
||||
.partitions = anubis_default_nand_part
|
||||
},
|
||||
[0] = {
|
||||
.name = "chip0",
|
||||
.nr_chips = 1,
|
||||
.nr_map = chip0_map,
|
||||
.nr_partitions = ARRAY_SIZE(anubis_default_nand_part),
|
||||
.partitions = anubis_default_nand_part
|
||||
},
|
||||
[2] = {
|
||||
.name = "chip1",
|
||||
.nr_chips = 1,
|
||||
.nr_map = chip1_map,
|
||||
.nr_partitions = ARRAY_SIZE(anubis_default_nand_part),
|
||||
.partitions = anubis_default_nand_part
|
||||
},
|
||||
};
|
||||
|
||||
static void anubis_nand_select(struct s3c2410_nand_set *set, int slot)
|
||||
{
|
||||
unsigned int tmp;
|
||||
|
||||
slot = set->nr_map[slot] & 3;
|
||||
|
||||
pr_debug("anubis_nand: selecting slot %d (set %p,%p)\n",
|
||||
slot, set, set->nr_map);
|
||||
|
||||
tmp = __raw_readb(ANUBIS_VA_CTRL1);
|
||||
tmp &= ~ANUBIS_CTRL1_NANDSEL;
|
||||
tmp |= slot;
|
||||
|
||||
pr_debug("anubis_nand: ctrl1 now %02x\n", tmp);
|
||||
|
||||
__raw_writeb(tmp, ANUBIS_VA_CTRL1);
|
||||
}
|
||||
|
||||
static struct s3c2410_platform_nand anubis_nand_info = {
|
||||
.tacls = 25,
|
||||
.twrph0 = 80,
|
||||
.twrph1 = 80,
|
||||
.nr_sets = ARRAY_SIZE(anubis_nand_sets),
|
||||
.sets = anubis_nand_sets,
|
||||
.select_chip = anubis_nand_select,
|
||||
};
|
||||
|
||||
|
||||
/* Standard Anubis devices */
|
||||
|
||||
static struct platform_device *anubis_devices[] __initdata = {
|
||||
&s3c_device_usb,
|
||||
&s3c_device_wdt,
|
||||
&s3c_device_adc,
|
||||
&s3c_device_i2c,
|
||||
&s3c_device_rtc,
|
||||
&s3c_device_nand,
|
||||
};
|
||||
|
||||
static struct clk *anubis_clocks[] = {
|
||||
&s3c24xx_dclk0,
|
||||
&s3c24xx_dclk1,
|
||||
&s3c24xx_clkout0,
|
||||
&s3c24xx_clkout1,
|
||||
&s3c24xx_uclk,
|
||||
};
|
||||
|
||||
static struct s3c24xx_board anubis_board __initdata = {
|
||||
.devices = anubis_devices,
|
||||
.devices_count = ARRAY_SIZE(anubis_devices),
|
||||
.clocks = anubis_clocks,
|
||||
.clocks_count = ARRAY_SIZE(anubis_clocks)
|
||||
};
|
||||
|
||||
void __init anubis_map_io(void)
|
||||
{
|
||||
/* initialise the clocks */
|
||||
|
||||
s3c24xx_dclk0.parent = NULL;
|
||||
s3c24xx_dclk0.rate = 12*1000*1000;
|
||||
|
||||
s3c24xx_dclk1.parent = NULL;
|
||||
s3c24xx_dclk1.rate = 24*1000*1000;
|
||||
|
||||
s3c24xx_clkout0.parent = &s3c24xx_dclk0;
|
||||
s3c24xx_clkout1.parent = &s3c24xx_dclk1;
|
||||
|
||||
s3c24xx_uclk.parent = &s3c24xx_clkout1;
|
||||
|
||||
s3c_device_nand.dev.platform_data = &anubis_nand_info;
|
||||
|
||||
s3c24xx_init_io(anubis_iodesc, ARRAY_SIZE(anubis_iodesc));
|
||||
s3c24xx_init_clocks(0);
|
||||
s3c24xx_init_uarts(anubis_uartcfgs, ARRAY_SIZE(anubis_uartcfgs));
|
||||
s3c24xx_set_board(&anubis_board);
|
||||
|
||||
/* ensure that the GPIO is setup */
|
||||
s3c2410_gpio_setpin(S3C2410_GPA0, 1);
|
||||
}
|
||||
|
||||
MACHINE_START(ANUBIS, "Simtec-Anubis")
|
||||
/* Maintainer: Ben Dooks <ben@simtec.co.uk> */
|
||||
.phys_ram = S3C2410_SDRAM_PA,
|
||||
.phys_io = S3C2410_PA_UART,
|
||||
.io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
|
||||
.boot_params = S3C2410_SDRAM_PA + 0x100,
|
||||
.map_io = anubis_map_io,
|
||||
.init_irq = s3c24xx_init_irq,
|
||||
.timer = &s3c24xx_timer,
|
||||
MACHINE_END
|
@ -110,34 +110,24 @@ void __init n30_init_irq(void)
|
||||
s3c24xx_init_irq();
|
||||
}
|
||||
|
||||
|
||||
static int n30_usbstart_thread(void *unused)
|
||||
{
|
||||
/* Turn off suspend on both USB ports, and switch the
|
||||
* selectable USB port to USB device mode. */
|
||||
writel(readl(S3C2410_MISCCR) & ~0x00003008, S3C2410_MISCCR);
|
||||
|
||||
/* Turn off the D+ pull up for 3 seconds so that the USB host
|
||||
* at the other end will do a rescan of the USB bus. */
|
||||
s3c2410_gpio_setpin(S3C2410_GPB3, 0);
|
||||
|
||||
msleep_interruptible(3*HZ);
|
||||
|
||||
s3c2410_gpio_setpin(S3C2410_GPB3, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* GPB3 is the line that controls the pull-up for the USB D+ line */
|
||||
|
||||
void __init n30_init(void)
|
||||
{
|
||||
s3c_device_i2c.dev.platform_data = &n30_i2ccfg;
|
||||
|
||||
kthread_run(n30_usbstart_thread, NULL, "n30_usbstart");
|
||||
/* Turn off suspend on both USB ports, and switch the
|
||||
* selectable USB port to USB device mode. */
|
||||
|
||||
s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST |
|
||||
S3C2410_MISCCR_USBSUSPND0 |
|
||||
S3C2410_MISCCR_USBSUSPND1, 0x0);
|
||||
}
|
||||
|
||||
MACHINE_START(N30, "Acer-N30")
|
||||
/* Maintainer: Christer Weinigel <christer@weinigel.se>, Ben Dooks <ben-linux@fluff.org> */
|
||||
/* Maintainer: Christer Weinigel <christer@weinigel.se>,
|
||||
Ben Dooks <ben-linux@fluff.org>
|
||||
*/
|
||||
.phys_ram = S3C2410_SDRAM_PA,
|
||||
.phys_io = S3C2410_PA_UART,
|
||||
.io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
|
||||
|
@ -48,7 +48,7 @@ static __init int pm_simtec_init(void)
|
||||
|
||||
/* check which machine we are running on */
|
||||
|
||||
if (!machine_is_bast() && !machine_is_vr1000())
|
||||
if (!machine_is_bast() && !machine_is_vr1000() && !machine_is_anubis())
|
||||
return 0;
|
||||
|
||||
printk(KERN_INFO "Simtec Board Power Manangement" COPYRIGHT "\n");
|
||||
|
@ -585,14 +585,16 @@ static int s3c2410_pm_enter(suspend_state_t state)
|
||||
|
||||
s3c2410_pm_check_store();
|
||||
|
||||
// need to make some form of time-delta
|
||||
|
||||
/* send the cpu to sleep... */
|
||||
|
||||
__raw_writel(0x00, S3C2410_CLKCON); /* turn off clocks over sleep */
|
||||
|
||||
s3c2410_cpu_suspend(regs_save);
|
||||
|
||||
/* restore the cpu state */
|
||||
|
||||
cpu_init();
|
||||
|
||||
/* unset the return-from-sleep flag, to ensure reset */
|
||||
|
||||
tmp = __raw_readl(S3C2410_GSTATUS2);
|
||||
|
@ -68,6 +68,7 @@ static struct clk s3c2440_clk_ac97 = {
|
||||
static int s3c2440_clk_add(struct sys_device *sysdev)
|
||||
{
|
||||
unsigned long upllcon = __raw_readl(S3C2410_UPLLCON);
|
||||
unsigned long camdivn = __raw_readl(S3C2440_CAMDIVN);
|
||||
struct clk *clk_h;
|
||||
struct clk *clk_p;
|
||||
struct clk *clk_xtal;
|
||||
@ -80,8 +81,9 @@ static int s3c2440_clk_add(struct sys_device *sysdev)
|
||||
|
||||
s3c2440_clk_upll.rate = s3c2410_get_pll(upllcon, clk_xtal->rate);
|
||||
|
||||
printk("S3C2440: Clock Support, UPLL %ld.%03ld MHz\n",
|
||||
print_mhz(s3c2440_clk_upll.rate));
|
||||
printk("S3C2440: Clock Support, UPLL %ld.%03ld MHz, DVS %s\n",
|
||||
print_mhz(s3c2440_clk_upll.rate),
|
||||
(camdivn & S3C2440_CAMDIVN_DVSEN) ? "on" : "off");
|
||||
|
||||
clk_p = clk_get(NULL, "pclk");
|
||||
clk_h = clk_get(NULL, "hclk");
|
||||
|
@ -64,11 +64,11 @@ static void s3c_irq_demux_wdtac97(unsigned int irq,
|
||||
if (subsrc != 0) {
|
||||
if (subsrc & 1) {
|
||||
mydesc = irq_desc + IRQ_S3C2440_WDT;
|
||||
mydesc->handle( IRQ_S3C2440_WDT, mydesc, regs);
|
||||
desc_handle_irq(IRQ_S3C2440_WDT, mydesc, regs);
|
||||
}
|
||||
if (subsrc & 2) {
|
||||
mydesc = irq_desc + IRQ_S3C2440_AC97;
|
||||
mydesc->handle(IRQ_S3C2440_AC97, mydesc, regs);
|
||||
desc_handle_irq(IRQ_S3C2440_AC97, mydesc, regs);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -122,11 +122,11 @@ static void s3c_irq_demux_cam(unsigned int irq,
|
||||
if (subsrc != 0) {
|
||||
if (subsrc & 1) {
|
||||
mydesc = irq_desc + IRQ_S3C2440_CAM_C;
|
||||
mydesc->handle( IRQ_S3C2440_WDT, mydesc, regs);
|
||||
desc_handle_irq(IRQ_S3C2440_CAM_C, mydesc, regs);
|
||||
}
|
||||
if (subsrc & 2) {
|
||||
mydesc = irq_desc + IRQ_S3C2440_CAM_P;
|
||||
mydesc->handle(IRQ_S3C2440_AC97, mydesc, regs);
|
||||
desc_handle_irq(IRQ_S3C2440_CAM_P, mydesc, regs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -164,7 +164,7 @@ static void s3c2410_timer_setup (void)
|
||||
|
||||
/* configure the system for whichever machine is in use */
|
||||
|
||||
if (machine_is_bast() || machine_is_vr1000()) {
|
||||
if (machine_is_bast() || machine_is_vr1000() || machine_is_anubis()) {
|
||||
/* timer is at 12MHz, scaler is 1 */
|
||||
timer_usec_ticks = timer_mask_usec_ticks(1, 12000000);
|
||||
tcnt = 12000000 / HZ;
|
||||
|
@ -98,8 +98,8 @@ static struct irqchip sa1100_low_gpio_chip = {
|
||||
.ack = sa1100_low_gpio_ack,
|
||||
.mask = sa1100_low_gpio_mask,
|
||||
.unmask = sa1100_low_gpio_unmask,
|
||||
.type = sa1100_gpio_type,
|
||||
.wake = sa1100_low_gpio_wake,
|
||||
.set_type = sa1100_gpio_type,
|
||||
.set_wake = sa1100_low_gpio_wake,
|
||||
};
|
||||
|
||||
/*
|
||||
@ -126,7 +126,7 @@ sa1100_high_gpio_handler(unsigned int irq, struct irqdesc *desc,
|
||||
mask >>= 11;
|
||||
do {
|
||||
if (mask & 1)
|
||||
desc->handle(irq, desc, regs);
|
||||
desc_handle_irq(irq, desc, regs);
|
||||
mask >>= 1;
|
||||
irq++;
|
||||
desc++;
|
||||
@ -181,8 +181,8 @@ static struct irqchip sa1100_high_gpio_chip = {
|
||||
.ack = sa1100_high_gpio_ack,
|
||||
.mask = sa1100_high_gpio_mask,
|
||||
.unmask = sa1100_high_gpio_unmask,
|
||||
.type = sa1100_gpio_type,
|
||||
.wake = sa1100_high_gpio_wake,
|
||||
.set_type = sa1100_gpio_type,
|
||||
.set_wake = sa1100_high_gpio_wake,
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -61,12 +61,12 @@ neponset_irq_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *reg
|
||||
|
||||
if (irr & IRR_ETHERNET) {
|
||||
d = irq_desc + IRQ_NEPONSET_SMC9196;
|
||||
d->handle(IRQ_NEPONSET_SMC9196, d, regs);
|
||||
desc_handle_irq(IRQ_NEPONSET_SMC9196, d, regs);
|
||||
}
|
||||
|
||||
if (irr & IRR_USAR) {
|
||||
d = irq_desc + IRQ_NEPONSET_USAR;
|
||||
d->handle(IRQ_NEPONSET_USAR, d, regs);
|
||||
desc_handle_irq(IRQ_NEPONSET_USAR, d, regs);
|
||||
}
|
||||
|
||||
desc->chip->unmask(irq);
|
||||
@ -74,7 +74,7 @@ neponset_irq_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *reg
|
||||
|
||||
if (irr & IRR_SA1111) {
|
||||
d = irq_desc + IRQ_NEPONSET_SA1111;
|
||||
d->handle(IRQ_NEPONSET_SA1111, d, regs);
|
||||
desc_handle_irq(IRQ_NEPONSET_SA1111, d, regs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -70,15 +70,11 @@ static unsigned long sa1100_gettimeoffset (void)
|
||||
return usec;
|
||||
}
|
||||
|
||||
/*
|
||||
* We will be entered with IRQs enabled.
|
||||
*
|
||||
* Loop until we get ahead of the free running timer.
|
||||
* This ensures an exact clock tick count and time accuracy.
|
||||
* IRQs are disabled inside the loop to ensure coherence between
|
||||
* lost_ticks (updated in do_timer()) and the match reg value, so we
|
||||
* can use do_gettimeofday() from interrupt handlers.
|
||||
*/
|
||||
#ifdef CONFIG_NO_IDLE_HZ
|
||||
static unsigned long initial_match;
|
||||
static int match_posponed;
|
||||
#endif
|
||||
|
||||
static irqreturn_t
|
||||
sa1100_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
|
||||
{
|
||||
@ -86,6 +82,21 @@ sa1100_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
|
||||
|
||||
write_seqlock(&xtime_lock);
|
||||
|
||||
#ifdef CONFIG_NO_IDLE_HZ
|
||||
if (match_posponed) {
|
||||
match_posponed = 0;
|
||||
OSMR0 = initial_match;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Loop until we get ahead of the free running timer.
|
||||
* This ensures an exact clock tick count and time accuracy.
|
||||
* Since IRQs are disabled at this point, coherence between
|
||||
* lost_ticks(updated in do_timer()) and the match reg value is
|
||||
* ensured, hence we can use do_gettimeofday() from interrupt
|
||||
* handlers.
|
||||
*/
|
||||
do {
|
||||
timer_tick(regs);
|
||||
OSSR = OSSR_M0; /* Clear match on timer 0 */
|
||||
@ -120,6 +131,42 @@ static void __init sa1100_timer_init(void)
|
||||
OSCR = 0; /* initialize free-running timer, force first match */
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NO_IDLE_HZ
|
||||
static int sa1100_dyn_tick_enable_disable(void)
|
||||
{
|
||||
/* nothing to do */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sa1100_dyn_tick_reprogram(unsigned long ticks)
|
||||
{
|
||||
if (ticks > 1) {
|
||||
initial_match = OSMR0;
|
||||
OSMR0 = initial_match + ticks * LATCH;
|
||||
match_posponed = 1;
|
||||
}
|
||||
}
|
||||
|
||||
static irqreturn_t
|
||||
sa1100_dyn_tick_handler(int irq, void *dev_id, struct pt_regs *regs)
|
||||
{
|
||||
if (match_posponed) {
|
||||
match_posponed = 0;
|
||||
OSMR0 = initial_match;
|
||||
if ((signed long)(initial_match - OSCR) <= 0)
|
||||
return sa1100_timer_interrupt(irq, dev_id, regs);
|
||||
}
|
||||
return IRQ_NONE;
|
||||
}
|
||||
|
||||
static struct dyn_tick_timer sa1100_dyn_tick = {
|
||||
.enable = sa1100_dyn_tick_enable_disable,
|
||||
.disable = sa1100_dyn_tick_enable_disable,
|
||||
.reprogram = sa1100_dyn_tick_reprogram,
|
||||
.handler = sa1100_dyn_tick_handler,
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
unsigned long osmr[4], oier;
|
||||
|
||||
@ -156,4 +203,7 @@ struct sys_timer sa1100_timer = {
|
||||
.suspend = sa1100_timer_suspend,
|
||||
.resume = sa1100_timer_resume,
|
||||
.offset = sa1100_gettimeoffset,
|
||||
#ifdef CONFIG_NO_IDLE_HZ
|
||||
.dyn_tick = &sa1100_dyn_tick,
|
||||
#endif
|
||||
};
|
||||
|
@ -108,7 +108,7 @@ sic_handle_irq(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
|
||||
irq += IRQ_SIC_START;
|
||||
|
||||
desc = irq_desc + irq;
|
||||
desc->handle(irq, desc, regs);
|
||||
desc_handle_irq(irq, desc, regs);
|
||||
} while (status);
|
||||
}
|
||||
|
||||
|
@ -45,7 +45,7 @@
|
||||
|
||||
#define LDST_P_EQ_U(i) ((((i) ^ ((i) >> 1)) & (1 << 23)) == 0)
|
||||
|
||||
#define LDSTH_I_BIT(i) (i & (1 << 22)) /* half-word immed */
|
||||
#define LDSTHD_I_BIT(i) (i & (1 << 22)) /* double/half-word immed */
|
||||
#define LDM_S_BIT(i) (i & (1 << 22)) /* write CPSR from SPSR */
|
||||
|
||||
#define RN_BITS(i) ((i >> 16) & 15) /* Rn */
|
||||
@ -68,6 +68,7 @@ static unsigned long ai_sys;
|
||||
static unsigned long ai_skipped;
|
||||
static unsigned long ai_half;
|
||||
static unsigned long ai_word;
|
||||
static unsigned long ai_dword;
|
||||
static unsigned long ai_multi;
|
||||
static int ai_usermode;
|
||||
|
||||
@ -93,6 +94,8 @@ proc_alignment_read(char *page, char **start, off_t off, int count, int *eof,
|
||||
p += sprintf(p, "Skipped:\t%lu\n", ai_skipped);
|
||||
p += sprintf(p, "Half:\t\t%lu\n", ai_half);
|
||||
p += sprintf(p, "Word:\t\t%lu\n", ai_word);
|
||||
if (cpu_architecture() >= CPU_ARCH_ARMv5TE)
|
||||
p += sprintf(p, "DWord:\t\t%lu\n", ai_dword);
|
||||
p += sprintf(p, "Multi:\t\t%lu\n", ai_multi);
|
||||
p += sprintf(p, "User faults:\t%i (%s)\n", ai_usermode,
|
||||
usermode_action[ai_usermode]);
|
||||
@ -283,12 +286,6 @@ do_alignment_ldrhstrh(unsigned long addr, unsigned long instr, struct pt_regs *r
|
||||
{
|
||||
unsigned int rd = RD_BITS(instr);
|
||||
|
||||
if ((instr & 0x01f00ff0) == 0x01000090)
|
||||
goto swp;
|
||||
|
||||
if ((instr & 0x90) != 0x90 || (instr & 0x60) == 0)
|
||||
goto bad;
|
||||
|
||||
ai_half += 1;
|
||||
|
||||
if (user_mode(regs))
|
||||
@ -323,10 +320,47 @@ do_alignment_ldrhstrh(unsigned long addr, unsigned long instr, struct pt_regs *r
|
||||
|
||||
return TYPE_LDST;
|
||||
|
||||
swp:
|
||||
printk(KERN_ERR "Alignment trap: not handling swp instruction\n");
|
||||
bad:
|
||||
return TYPE_ERROR;
|
||||
fault:
|
||||
return TYPE_FAULT;
|
||||
}
|
||||
|
||||
static int
|
||||
do_alignment_ldrdstrd(unsigned long addr, unsigned long instr,
|
||||
struct pt_regs *regs)
|
||||
{
|
||||
unsigned int rd = RD_BITS(instr);
|
||||
|
||||
ai_dword += 1;
|
||||
|
||||
if (user_mode(regs))
|
||||
goto user;
|
||||
|
||||
if ((instr & 0xf0) == 0xd0) {
|
||||
unsigned long val;
|
||||
get32_unaligned_check(val, addr);
|
||||
regs->uregs[rd] = val;
|
||||
get32_unaligned_check(val, addr+4);
|
||||
regs->uregs[rd+1] = val;
|
||||
} else {
|
||||
put32_unaligned_check(regs->uregs[rd], addr);
|
||||
put32_unaligned_check(regs->uregs[rd+1], addr+4);
|
||||
}
|
||||
|
||||
return TYPE_LDST;
|
||||
|
||||
user:
|
||||
if ((instr & 0xf0) == 0xd0) {
|
||||
unsigned long val;
|
||||
get32t_unaligned_check(val, addr);
|
||||
regs->uregs[rd] = val;
|
||||
get32t_unaligned_check(val, addr+4);
|
||||
regs->uregs[rd+1] = val;
|
||||
} else {
|
||||
put32t_unaligned_check(regs->uregs[rd], addr);
|
||||
put32t_unaligned_check(regs->uregs[rd+1], addr+4);
|
||||
}
|
||||
|
||||
return TYPE_LDST;
|
||||
|
||||
fault:
|
||||
return TYPE_FAULT;
|
||||
@ -617,12 +651,20 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
|
||||
regs->ARM_pc += thumb_mode(regs) ? 2 : 4;
|
||||
|
||||
switch (CODING_BITS(instr)) {
|
||||
case 0x00000000: /* ldrh or strh */
|
||||
if (LDSTH_I_BIT(instr))
|
||||
case 0x00000000: /* 3.13.4 load/store instruction extensions */
|
||||
if (LDSTHD_I_BIT(instr))
|
||||
offset.un = (instr & 0xf00) >> 4 | (instr & 15);
|
||||
else
|
||||
offset.un = regs->uregs[RM_BITS(instr)];
|
||||
handler = do_alignment_ldrhstrh;
|
||||
|
||||
if ((instr & 0x000000f0) == 0x000000b0 || /* LDRH, STRH */
|
||||
(instr & 0x001000f0) == 0x001000f0) /* LDRSH */
|
||||
handler = do_alignment_ldrhstrh;
|
||||
else if ((instr & 0x001000f0) == 0x000000d0 || /* LDRD */
|
||||
(instr & 0x001000f0) == 0x000000f0) /* STRD */
|
||||
handler = do_alignment_ldrdstrd;
|
||||
else
|
||||
goto bad;
|
||||
break;
|
||||
|
||||
case 0x04000000: /* ldr or str immediate */
|
||||
|
@ -275,11 +275,9 @@ alloc_init_supersection(unsigned long virt, unsigned long phys, int prot)
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 16; i += 1) {
|
||||
alloc_init_section(virt, phys & SUPERSECTION_MASK,
|
||||
prot | PMD_SECT_SUPER);
|
||||
alloc_init_section(virt, phys, prot | PMD_SECT_SUPER);
|
||||
|
||||
virt += (PGDIR_SIZE / 2);
|
||||
phys += (PGDIR_SIZE / 2);
|
||||
}
|
||||
}
|
||||
|
||||
@ -297,14 +295,10 @@ alloc_init_page(unsigned long virt, unsigned long phys, unsigned int prot_l1, pg
|
||||
pte_t *ptep;
|
||||
|
||||
if (pmd_none(*pmdp)) {
|
||||
unsigned long pmdval;
|
||||
ptep = alloc_bootmem_low_pages(2 * PTRS_PER_PTE *
|
||||
sizeof(pte_t));
|
||||
|
||||
pmdval = __pa(ptep) | prot_l1;
|
||||
pmdp[0] = __pmd(pmdval);
|
||||
pmdp[1] = __pmd(pmdval + 256 * sizeof(pte_t));
|
||||
flush_pmd_entry(pmdp);
|
||||
__pmd_populate(pmdp, __pa(ptep) | prot_l1);
|
||||
}
|
||||
ptep = pte_offset_kernel(pmdp, virt);
|
||||
|
||||
@ -459,7 +453,7 @@ static void __init build_mem_type_table(void)
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
unsigned long v = pgprot_val(protection_map[i]);
|
||||
v &= (~(PTE_BUFFERABLE|PTE_CACHEABLE)) | user_pgprot;
|
||||
v = (v & ~(PTE_BUFFERABLE|PTE_CACHEABLE)) | user_pgprot;
|
||||
protection_map[i] = __pgprot(v);
|
||||
}
|
||||
|
||||
@ -583,23 +577,23 @@ static void __init create_mapping(struct map_desc *md)
|
||||
*/
|
||||
void setup_mm_for_reboot(char mode)
|
||||
{
|
||||
unsigned long pmdval;
|
||||
unsigned long base_pmdval;
|
||||
pgd_t *pgd;
|
||||
pmd_t *pmd;
|
||||
int i;
|
||||
int cpu_arch = cpu_architecture();
|
||||
|
||||
if (current->mm && current->mm->pgd)
|
||||
pgd = current->mm->pgd;
|
||||
else
|
||||
pgd = init_mm.pgd;
|
||||
|
||||
for (i = 0; i < FIRST_USER_PGD_NR + USER_PTRS_PER_PGD; i++) {
|
||||
pmdval = (i << PGDIR_SHIFT) |
|
||||
PMD_SECT_AP_WRITE | PMD_SECT_AP_READ |
|
||||
PMD_TYPE_SECT;
|
||||
if (cpu_arch <= CPU_ARCH_ARMv5TEJ)
|
||||
pmdval |= PMD_BIT4;
|
||||
base_pmdval = PMD_SECT_AP_WRITE | PMD_SECT_AP_READ | PMD_TYPE_SECT;
|
||||
if (cpu_architecture() <= CPU_ARCH_ARMv5TEJ)
|
||||
base_pmdval |= PMD_BIT4;
|
||||
|
||||
for (i = 0; i < FIRST_USER_PGD_NR + USER_PTRS_PER_PGD; i++, pgd++) {
|
||||
unsigned long pmdval = (i << PGDIR_SHIFT) | base_pmdval;
|
||||
pmd_t *pmd;
|
||||
|
||||
pmd = pmd_off(pgd, i << PGDIR_SHIFT);
|
||||
pmd[0] = __pmd(pmdval);
|
||||
pmd[1] = __pmd(pmdval + (1 << (PGDIR_SHIFT - 1)));
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user