forked from Minki/linux
Merge with /pub/scm/linux/kernel/git/torvalds/linux-2.6.git
Signed-off-by: Steve French <sfrench@us.ibm.com>
This commit is contained in:
commit
d65177c1ae
@ -229,7 +229,7 @@ int __init myradio_init(struct video_init *v)
|
||||
|
||||
static int users = 0;
|
||||
|
||||
static int radio_open(stuct video_device *dev, int flags)
|
||||
static int radio_open(struct video_device *dev, int flags)
|
||||
{
|
||||
if(users)
|
||||
return -EBUSY;
|
||||
@ -949,7 +949,7 @@ int __init mycamera_init(struct video_init *v)
|
||||
|
||||
static int users = 0;
|
||||
|
||||
static int camera_open(stuct video_device *dev, int flags)
|
||||
static int camera_open(struct video_device *dev, int flags)
|
||||
{
|
||||
if(users)
|
||||
return -EBUSY;
|
||||
|
@ -143,7 +143,7 @@ KernelNewbies:
|
||||
http://kernelnewbies.org/
|
||||
|
||||
Linux USB project:
|
||||
http://linux-usb.sourceforge.net/
|
||||
http://www.linux-usb.org/
|
||||
|
||||
How to NOT write kernel driver by arjanv@redhat.com
|
||||
http://people.redhat.com/arjanv/olspaper.pdf
|
||||
|
@ -478,10 +478,11 @@ Andrew Morton, "The perfect patch" (tpp).
|
||||
Jeff Garzik, "Linux kernel patch submission format."
|
||||
<http://linux.yyz.us/patch-format.html>
|
||||
|
||||
Greg Kroah, "How to piss off a kernel subsystem maintainer".
|
||||
Greg Kroah-Hartman "How to piss off a kernel subsystem maintainer".
|
||||
<http://www.kroah.com/log/2005/03/31/>
|
||||
<http://www.kroah.com/log/2005/07/08/>
|
||||
<http://www.kroah.com/log/2005/10/19/>
|
||||
<http://www.kroah.com/log/2006/01/11/>
|
||||
|
||||
NO!!!! No more huge patch bombs to linux-kernel@vger.kernel.org people!.
|
||||
<http://marc.theaimsgroup.com/?l=linux-kernel&m=112112749912944&w=2>
|
||||
|
271
Documentation/block/barrier.txt
Normal file
271
Documentation/block/barrier.txt
Normal file
@ -0,0 +1,271 @@
|
||||
I/O Barriers
|
||||
============
|
||||
Tejun Heo <htejun@gmail.com>, July 22 2005
|
||||
|
||||
I/O barrier requests are used to guarantee ordering around the barrier
|
||||
requests. Unless you're crazy enough to use disk drives for
|
||||
implementing synchronization constructs (wow, sounds interesting...),
|
||||
the ordering is meaningful only for write requests for things like
|
||||
journal checkpoints. All requests queued before a barrier request
|
||||
must be finished (made it to the physical medium) before the barrier
|
||||
request is started, and all requests queued after the barrier request
|
||||
must be started only after the barrier request is finished (again,
|
||||
made it to the physical medium).
|
||||
|
||||
In other words, I/O barrier requests have the following two properties.
|
||||
|
||||
1. Request ordering
|
||||
|
||||
Requests cannot pass the barrier request. Preceding requests are
|
||||
processed before the barrier and following requests after.
|
||||
|
||||
Depending on what features a drive supports, this can be done in one
|
||||
of the following three ways.
|
||||
|
||||
i. For devices which have queue depth greater than 1 (TCQ devices) and
|
||||
support ordered tags, block layer can just issue the barrier as an
|
||||
ordered request and the lower level driver, controller and drive
|
||||
itself are responsible for making sure that the ordering contraint is
|
||||
met. Most modern SCSI controllers/drives should support this.
|
||||
|
||||
NOTE: SCSI ordered tag isn't currently used due to limitation in the
|
||||
SCSI midlayer, see the following random notes section.
|
||||
|
||||
ii. For devices which have queue depth greater than 1 but don't
|
||||
support ordered tags, block layer ensures that the requests preceding
|
||||
a barrier request finishes before issuing the barrier request. Also,
|
||||
it defers requests following the barrier until the barrier request is
|
||||
finished. Older SCSI controllers/drives and SATA drives fall in this
|
||||
category.
|
||||
|
||||
iii. Devices which have queue depth of 1. This is a degenerate case
|
||||
of ii. Just keeping issue order suffices. Ancient SCSI
|
||||
controllers/drives and IDE drives are in this category.
|
||||
|
||||
2. Forced flushing to physcial medium
|
||||
|
||||
Again, if you're not gonna do synchronization with disk drives (dang,
|
||||
it sounds even more appealing now!), the reason you use I/O barriers
|
||||
is mainly to protect filesystem integrity when power failure or some
|
||||
other events abruptly stop the drive from operating and possibly make
|
||||
the drive lose data in its cache. So, I/O barriers need to guarantee
|
||||
that requests actually get written to non-volatile medium in order.
|
||||
|
||||
There are four cases,
|
||||
|
||||
i. No write-back cache. Keeping requests ordered is enough.
|
||||
|
||||
ii. Write-back cache but no flush operation. There's no way to
|
||||
gurantee physical-medium commit order. This kind of devices can't to
|
||||
I/O barriers.
|
||||
|
||||
iii. Write-back cache and flush operation but no FUA (forced unit
|
||||
access). We need two cache flushes - before and after the barrier
|
||||
request.
|
||||
|
||||
iv. Write-back cache, flush operation and FUA. We still need one
|
||||
flush to make sure requests preceding a barrier are written to medium,
|
||||
but post-barrier flush can be avoided by using FUA write on the
|
||||
barrier itself.
|
||||
|
||||
|
||||
How to support barrier requests in drivers
|
||||
------------------------------------------
|
||||
|
||||
All barrier handling is done inside block layer proper. All low level
|
||||
drivers have to are implementing its prepare_flush_fn and using one
|
||||
the following two functions to indicate what barrier type it supports
|
||||
and how to prepare flush requests. Note that the term 'ordered' is
|
||||
used to indicate the whole sequence of performing barrier requests
|
||||
including draining and flushing.
|
||||
|
||||
typedef void (prepare_flush_fn)(request_queue_t *q, struct request *rq);
|
||||
|
||||
int blk_queue_ordered(request_queue_t *q, unsigned ordered,
|
||||
prepare_flush_fn *prepare_flush_fn,
|
||||
unsigned gfp_mask);
|
||||
|
||||
int blk_queue_ordered_locked(request_queue_t *q, unsigned ordered,
|
||||
prepare_flush_fn *prepare_flush_fn,
|
||||
unsigned gfp_mask);
|
||||
|
||||
The only difference between the two functions is whether or not the
|
||||
caller is holding q->queue_lock on entry. The latter expects the
|
||||
caller is holding the lock.
|
||||
|
||||
@q : the queue in question
|
||||
@ordered : the ordered mode the driver/device supports
|
||||
@prepare_flush_fn : this function should prepare @rq such that it
|
||||
flushes cache to physical medium when executed
|
||||
@gfp_mask : gfp_mask used when allocating data structures
|
||||
for ordered processing
|
||||
|
||||
For example, SCSI disk driver's prepare_flush_fn looks like the
|
||||
following.
|
||||
|
||||
static void sd_prepare_flush(request_queue_t *q, struct request *rq)
|
||||
{
|
||||
memset(rq->cmd, 0, sizeof(rq->cmd));
|
||||
rq->flags |= REQ_BLOCK_PC;
|
||||
rq->timeout = SD_TIMEOUT;
|
||||
rq->cmd[0] = SYNCHRONIZE_CACHE;
|
||||
}
|
||||
|
||||
The following seven ordered modes are supported. The following table
|
||||
shows which mode should be used depending on what features a
|
||||
device/driver supports. In the leftmost column of table,
|
||||
QUEUE_ORDERED_ prefix is omitted from the mode names to save space.
|
||||
|
||||
The table is followed by description of each mode. Note that in the
|
||||
descriptions of QUEUE_ORDERED_DRAIN*, '=>' is used whereas '->' is
|
||||
used for QUEUE_ORDERED_TAG* descriptions. '=>' indicates that the
|
||||
preceding step must be complete before proceeding to the next step.
|
||||
'->' indicates that the next step can start as soon as the previous
|
||||
step is issued.
|
||||
|
||||
write-back cache ordered tag flush FUA
|
||||
-----------------------------------------------------------------------
|
||||
NONE yes/no N/A no N/A
|
||||
DRAIN no no N/A N/A
|
||||
DRAIN_FLUSH yes no yes no
|
||||
DRAIN_FUA yes no yes yes
|
||||
TAG no yes N/A N/A
|
||||
TAG_FLUSH yes yes yes no
|
||||
TAG_FUA yes yes yes yes
|
||||
|
||||
|
||||
QUEUE_ORDERED_NONE
|
||||
I/O barriers are not needed and/or supported.
|
||||
|
||||
Sequence: N/A
|
||||
|
||||
QUEUE_ORDERED_DRAIN
|
||||
Requests are ordered by draining the request queue and cache
|
||||
flushing isn't needed.
|
||||
|
||||
Sequence: drain => barrier
|
||||
|
||||
QUEUE_ORDERED_DRAIN_FLUSH
|
||||
Requests are ordered by draining the request queue and both
|
||||
pre-barrier and post-barrier cache flushings are needed.
|
||||
|
||||
Sequence: drain => preflush => barrier => postflush
|
||||
|
||||
QUEUE_ORDERED_DRAIN_FUA
|
||||
Requests are ordered by draining the request queue and
|
||||
pre-barrier cache flushing is needed. By using FUA on barrier
|
||||
request, post-barrier flushing can be skipped.
|
||||
|
||||
Sequence: drain => preflush => barrier
|
||||
|
||||
QUEUE_ORDERED_TAG
|
||||
Requests are ordered by ordered tag and cache flushing isn't
|
||||
needed.
|
||||
|
||||
Sequence: barrier
|
||||
|
||||
QUEUE_ORDERED_TAG_FLUSH
|
||||
Requests are ordered by ordered tag and both pre-barrier and
|
||||
post-barrier cache flushings are needed.
|
||||
|
||||
Sequence: preflush -> barrier -> postflush
|
||||
|
||||
QUEUE_ORDERED_TAG_FUA
|
||||
Requests are ordered by ordered tag and pre-barrier cache
|
||||
flushing is needed. By using FUA on barrier request,
|
||||
post-barrier flushing can be skipped.
|
||||
|
||||
Sequence: preflush -> barrier
|
||||
|
||||
|
||||
Random notes/caveats
|
||||
--------------------
|
||||
|
||||
* SCSI layer currently can't use TAG ordering even if the drive,
|
||||
controller and driver support it. The problem is that SCSI midlayer
|
||||
request dispatch function is not atomic. It releases queue lock and
|
||||
switch to SCSI host lock during issue and it's possible and likely to
|
||||
happen in time that requests change their relative positions. Once
|
||||
this problem is solved, TAG ordering can be enabled.
|
||||
|
||||
* Currently, no matter which ordered mode is used, there can be only
|
||||
one barrier request in progress. All I/O barriers are held off by
|
||||
block layer until the previous I/O barrier is complete. This doesn't
|
||||
make any difference for DRAIN ordered devices, but, for TAG ordered
|
||||
devices with very high command latency, passing multiple I/O barriers
|
||||
to low level *might* be helpful if they are very frequent. Well, this
|
||||
certainly is a non-issue. I'm writing this just to make clear that no
|
||||
two I/O barrier is ever passed to low-level driver.
|
||||
|
||||
* Completion order. Requests in ordered sequence are issued in order
|
||||
but not required to finish in order. Barrier implementation can
|
||||
handle out-of-order completion of ordered sequence. IOW, the requests
|
||||
MUST be processed in order but the hardware/software completion paths
|
||||
are allowed to reorder completion notifications - eg. current SCSI
|
||||
midlayer doesn't preserve completion order during error handling.
|
||||
|
||||
* Requeueing order. Low-level drivers are free to requeue any request
|
||||
after they removed it from the request queue with
|
||||
blkdev_dequeue_request(). As barrier sequence should be kept in order
|
||||
when requeued, generic elevator code takes care of putting requests in
|
||||
order around barrier. See blk_ordered_req_seq() and
|
||||
ELEVATOR_INSERT_REQUEUE handling in __elv_add_request() for details.
|
||||
|
||||
Note that block drivers must not requeue preceding requests while
|
||||
completing latter requests in an ordered sequence. Currently, no
|
||||
error checking is done against this.
|
||||
|
||||
* Error handling. Currently, block layer will report error to upper
|
||||
layer if any of requests in an ordered sequence fails. Unfortunately,
|
||||
this doesn't seem to be enough. Look at the following request flow.
|
||||
QUEUE_ORDERED_TAG_FLUSH is in use.
|
||||
|
||||
[0] [1] [2] [3] [pre] [barrier] [post] < [4] [5] [6] ... >
|
||||
still in elevator
|
||||
|
||||
Let's say request [2], [3] are write requests to update file system
|
||||
metadata (journal or whatever) and [barrier] is used to mark that
|
||||
those updates are valid. Consider the following sequence.
|
||||
|
||||
i. Requests [0] ~ [post] leaves the request queue and enters
|
||||
low-level driver.
|
||||
ii. After a while, unfortunately, something goes wrong and the
|
||||
drive fails [2]. Note that any of [0], [1] and [3] could have
|
||||
completed by this time, but [pre] couldn't have been finished
|
||||
as the drive must process it in order and it failed before
|
||||
processing that command.
|
||||
iii. Error handling kicks in and determines that the error is
|
||||
unrecoverable and fails [2], and resumes operation.
|
||||
iv. [pre] [barrier] [post] gets processed.
|
||||
v. *BOOM* power fails
|
||||
|
||||
The problem here is that the barrier request is *supposed* to indicate
|
||||
that filesystem update requests [2] and [3] made it safely to the
|
||||
physical medium and, if the machine crashes after the barrier is
|
||||
written, filesystem recovery code can depend on that. Sadly, that
|
||||
isn't true in this case anymore. IOW, the success of a I/O barrier
|
||||
should also be dependent on success of some of the preceding requests,
|
||||
where only upper layer (filesystem) knows what 'some' is.
|
||||
|
||||
This can be solved by implementing a way to tell the block layer which
|
||||
requests affect the success of the following barrier request and
|
||||
making lower lever drivers to resume operation on error only after
|
||||
block layer tells it to do so.
|
||||
|
||||
As the probability of this happening is very low and the drive should
|
||||
be faulty, implementing the fix is probably an overkill. But, still,
|
||||
it's there.
|
||||
|
||||
* In previous drafts of barrier implementation, there was fallback
|
||||
mechanism such that, if FUA or ordered TAG fails, less fancy ordered
|
||||
mode can be selected and the failed barrier request is retried
|
||||
automatically. The rationale for this feature was that as FUA is
|
||||
pretty new in ATA world and ordered tag was never used widely, there
|
||||
could be devices which report to support those features but choke when
|
||||
actually given such requests.
|
||||
|
||||
This was removed for two reasons 1. it's an overkill 2. it's
|
||||
impossible to implement properly when TAG ordering is used as low
|
||||
level drivers resume after an error automatically. If it's ever
|
||||
needed adding it back and modifying low level drivers accordingly
|
||||
shouldn't be difficult.
|
@ -136,7 +136,7 @@ changes occur:
|
||||
8) void lazy_mmu_prot_update(pte_t pte)
|
||||
This interface is called whenever the protection on
|
||||
any user PTEs change. This interface provides a notification
|
||||
to architecture specific code to take appropiate action.
|
||||
to architecture specific code to take appropriate action.
|
||||
|
||||
|
||||
Next, we have the cache flushing interfaces. In general, when Linux
|
||||
|
@ -123,6 +123,15 @@ Who: Christoph Hellwig <hch@lst.de>
|
||||
|
||||
---------------------------
|
||||
|
||||
What: CONFIG_FORCED_INLINING
|
||||
When: June 2006
|
||||
Why: Config option is there to see if gcc is good enough. (in january
|
||||
2006). If it is, the behavior should just be the default. If it's not,
|
||||
the option should just go away entirely.
|
||||
Who: Arjan van de Ven
|
||||
|
||||
---------------------------
|
||||
|
||||
What: START_ARRAY ioctl for md
|
||||
When: July 2006
|
||||
Files: drivers/md/md.c
|
||||
|
@ -86,6 +86,62 @@ Mount options
|
||||
The default is infinite. Note that the size of read requests is
|
||||
limited anyway to 32 pages (which is 128kbyte on i386).
|
||||
|
||||
Sysfs
|
||||
~~~~~
|
||||
|
||||
FUSE sets up the following hierarchy in sysfs:
|
||||
|
||||
/sys/fs/fuse/connections/N/
|
||||
|
||||
where N is an increasing number allocated to each new connection.
|
||||
|
||||
For each connection the following attributes are defined:
|
||||
|
||||
'waiting'
|
||||
|
||||
The number of requests which are waiting to be transfered to
|
||||
userspace or being processed by the filesystem daemon. If there is
|
||||
no filesystem activity and 'waiting' is non-zero, then the
|
||||
filesystem is hung or deadlocked.
|
||||
|
||||
'abort'
|
||||
|
||||
Writing anything into this file will abort the filesystem
|
||||
connection. This means that all waiting requests will be aborted an
|
||||
error returned for all aborted and new requests.
|
||||
|
||||
Only a privileged user may read or write these attributes.
|
||||
|
||||
Aborting a filesystem connection
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
It is possible to get into certain situations where the filesystem is
|
||||
not responding. Reasons for this may be:
|
||||
|
||||
a) Broken userspace filesystem implementation
|
||||
|
||||
b) Network connection down
|
||||
|
||||
c) Accidental deadlock
|
||||
|
||||
d) Malicious deadlock
|
||||
|
||||
(For more on c) and d) see later sections)
|
||||
|
||||
In either of these cases it may be useful to abort the connection to
|
||||
the filesystem. There are several ways to do this:
|
||||
|
||||
- Kill the filesystem daemon. Works in case of a) and b)
|
||||
|
||||
- Kill the filesystem daemon and all users of the filesystem. Works
|
||||
in all cases except some malicious deadlocks
|
||||
|
||||
- Use forced umount (umount -f). Works in all cases but only if
|
||||
filesystem is still attached (it hasn't been lazy unmounted)
|
||||
|
||||
- Abort filesystem through the sysfs interface. Most powerful
|
||||
method, always works.
|
||||
|
||||
How do non-privileged mounts work?
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@ -313,3 +369,10 @@ faulted with get_user_pages(). The 'req->locked' flag indicates
|
||||
when the copy is taking place, and interruption is delayed until
|
||||
this flag is unset.
|
||||
|
||||
Scenario 3 - Tricky deadlock with asynchronous read
|
||||
---------------------------------------------------
|
||||
|
||||
The same situation as above, except thread-1 will wait on page lock
|
||||
and hence it will be uninterruptible as well. The solution is to
|
||||
abort the connection with forced umount (if mount is attached) or
|
||||
through the abort attribute in sysfs.
|
||||
|
@ -78,6 +78,18 @@ use up all the memory on the machine; but enhances the scalability of
|
||||
that instance in a system with many cpus making intensive use of it.
|
||||
|
||||
|
||||
tmpfs has a mount option to set the NUMA memory allocation policy for
|
||||
all files in that instance:
|
||||
mpol=interleave prefers to allocate memory from each node in turn
|
||||
mpol=default prefers to allocate memory from the local node
|
||||
mpol=bind prefers to allocate from mpol_nodelist
|
||||
mpol=preferred prefers to allocate from first node in mpol_nodelist
|
||||
|
||||
The following mount option is used in conjunction with mpol=interleave,
|
||||
mpol=bind or mpol=preferred:
|
||||
mpol_nodelist: nodelist suitable for parsing with nodelist_parse.
|
||||
|
||||
|
||||
To specify the initial root directory you can use the following mount
|
||||
options:
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
The High Precision Event Timer (HPET) hardware is the future replacement
|
||||
for the 8254 and Real Time Clock (RTC) periodic timer functionality.
|
||||
Each HPET can have up two 32 timers. It is possible to configure the
|
||||
Each HPET can have up to 32 timers. It is possible to configure the
|
||||
first two timers as legacy replacements for 8254 and RTC periodic timers.
|
||||
A specification done by Intel and Microsoft can be found at
|
||||
<http://www.intel.com/hardwaredesign/hpetspec.htm>.
|
||||
|
@ -120,7 +120,7 @@ to the unique id assigned by the driver. This data is required for performing
|
||||
some operations (removing an effect, controlling the playback).
|
||||
This if field must be set to -1 by the user in order to tell the driver to
|
||||
allocate a new effect.
|
||||
See <linux/input.h> for a description of the ff_effect stuct. You should also
|
||||
See <linux/input.h> for a description of the ff_effect struct. You should also
|
||||
find help in a few sketches, contained in files shape.fig and interactive.fig.
|
||||
You need xfig to visualize these files.
|
||||
|
||||
|
@ -946,7 +946,7 @@ HDIO_SCAN_HWIF register and (re)scan interface
|
||||
|
||||
This ioctl initializes the addresses and irq for a disk
|
||||
controller, probes for drives, and creates /proc/ide
|
||||
interfaces as appropiate.
|
||||
interfaces as appropriate.
|
||||
|
||||
|
||||
|
||||
|
@ -471,7 +471,7 @@ running once the system is up.
|
||||
arch/i386/kernel/cpu/cpufreq/elanfreq.c.
|
||||
|
||||
elevator= [IOSCHED]
|
||||
Format: {"as" | "cfq" | "deadline" | "noop"}
|
||||
Format: {"anticipatory" | "cfq" | "deadline" | "noop"}
|
||||
See Documentation/block/as-iosched.txt and
|
||||
Documentation/block/deadline-iosched.txt for details.
|
||||
|
||||
@ -712,9 +712,17 @@ running once the system is up.
|
||||
load_ramdisk= [RAM] List of ramdisks to load from floppy
|
||||
See Documentation/ramdisk.txt.
|
||||
|
||||
lockd.udpport= [NFS]
|
||||
lockd.nlm_grace_period=P [NFS] Assign grace period.
|
||||
Format: <integer>
|
||||
|
||||
lockd.tcpport= [NFS]
|
||||
lockd.nlm_tcpport=N [NFS] Assign TCP port.
|
||||
Format: <integer>
|
||||
|
||||
lockd.nlm_timeout=T [NFS] Assign timeout value.
|
||||
Format: <integer>
|
||||
|
||||
lockd.nlm_udpport=M [NFS] Assign UDP port.
|
||||
Format: <integer>
|
||||
|
||||
logibm.irq= [HW,MOUSE] Logitech Bus Mouse Driver
|
||||
Format: <irq>
|
||||
|
@ -357,7 +357,7 @@ MAX_AGE=${MAX_AGE:-'600'}
|
||||
# Read-ahead, in kilobytes
|
||||
READAHEAD=${READAHEAD:-'4096'}
|
||||
|
||||
# Shall we remount journaled fs. with appropiate commit interval? (1=yes)
|
||||
# Shall we remount journaled fs. with appropriate commit interval? (1=yes)
|
||||
DO_REMOUNTS=${DO_REMOUNTS:-'1'}
|
||||
|
||||
# And shall we add the "noatime" option to that as well? (1=yes)
|
||||
|
@ -91,7 +91,7 @@ To use the driver as a module, proceed as follows:
|
||||
with (M)
|
||||
5. Execute the command "make modules".
|
||||
6. Execute the command "make modules_install".
|
||||
The appropiate modules will be installed.
|
||||
The appropriate modules will be installed.
|
||||
7. Reboot your system.
|
||||
|
||||
|
||||
|
108
Documentation/scsi/aacraid.txt
Normal file
108
Documentation/scsi/aacraid.txt
Normal file
@ -0,0 +1,108 @@
|
||||
AACRAID Driver for Linux (take two)
|
||||
|
||||
Introduction
|
||||
-------------------------
|
||||
The aacraid driver adds support for Adaptec (http://www.adaptec.com)
|
||||
RAID controllers. This is a major rewrite from the original
|
||||
Adaptec supplied driver. It has signficantly cleaned up both the code
|
||||
and the running binary size (the module is less than half the size of
|
||||
the original).
|
||||
|
||||
Supported Cards/Chipsets
|
||||
-------------------------
|
||||
PCI ID (pci.ids) OEM Product
|
||||
9005:0285:9005:028a Adaptec 2020ZCR (Skyhawk)
|
||||
9005:0285:9005:028e Adaptec 2020SA (Skyhawk)
|
||||
9005:0285:9005:028b Adaptec 2025ZCR (Terminator)
|
||||
9005:0285:9005:028f Adaptec 2025SA (Terminator)
|
||||
9005:0285:9005:0286 Adaptec 2120S (Crusader)
|
||||
9005:0286:9005:028d Adaptec 2130S (Lancer)
|
||||
9005:0285:9005:0285 Adaptec 2200S (Vulcan)
|
||||
9005:0285:9005:0287 Adaptec 2200S (Vulcan-2m)
|
||||
9005:0286:9005:028c Adaptec 2230S (Lancer)
|
||||
9005:0286:9005:028c Adaptec 2230SLP (Lancer)
|
||||
9005:0285:9005:0296 Adaptec 2240S (SabreExpress)
|
||||
9005:0285:9005:0290 Adaptec 2410SA (Jaguar)
|
||||
9005:0285:9005:0293 Adaptec 21610SA (Corsair-16)
|
||||
9005:0285:103c:3227 Adaptec 2610SA (Bearcat)
|
||||
9005:0285:9005:0292 Adaptec 2810SA (Corsair-8)
|
||||
9005:0285:9005:0294 Adaptec Prowler
|
||||
9005:0286:9005:029d Adaptec 2420SA (Intruder)
|
||||
9005:0286:9005:029c Adaptec 2620SA (Intruder)
|
||||
9005:0286:9005:029b Adaptec 2820SA (Intruder)
|
||||
9005:0286:9005:02a7 Adaptec 2830SA (Skyray)
|
||||
9005:0286:9005:02a8 Adaptec 2430SA (Skyray)
|
||||
9005:0285:9005:0288 Adaptec 3230S (Harrier)
|
||||
9005:0285:9005:0289 Adaptec 3240S (Tornado)
|
||||
9005:0285:9005:0298 Adaptec 4000SAS (BlackBird)
|
||||
9005:0285:9005:0297 Adaptec 4005SAS (AvonPark)
|
||||
9005:0285:9005:0299 Adaptec 4800SAS (Marauder-X)
|
||||
9005:0285:9005:029a Adaptec 4805SAS (Marauder-E)
|
||||
9005:0286:9005:02a2 Adaptec 4810SAS (Hurricane)
|
||||
1011:0046:9005:0364 Adaptec 5400S (Mustang)
|
||||
1011:0046:9005:0365 Adaptec 5400S (Mustang)
|
||||
9005:0283:9005:0283 Adaptec Catapult (3210S with arc firmware)
|
||||
9005:0284:9005:0284 Adaptec Tomcat (3410S with arc firmware)
|
||||
9005:0287:9005:0800 Adaptec Themisto (Jupiter)
|
||||
9005:0200:9005:0200 Adaptec Themisto (Jupiter)
|
||||
9005:0286:9005:0800 Adaptec Callisto (Jupiter)
|
||||
1011:0046:9005:1364 Dell PERC 2/QC (Quad Channel, Mustang)
|
||||
1028:0001:1028:0001 Dell PERC 2/Si (Iguana)
|
||||
1028:0003:1028:0003 Dell PERC 3/Si (SlimFast)
|
||||
1028:0002:1028:0002 Dell PERC 3/Di (Opal)
|
||||
1028:0004:1028:0004 Dell PERC 3/DiF (Iguana)
|
||||
1028:0002:1028:00d1 Dell PERC 3/DiV (Viper)
|
||||
1028:0002:1028:00d9 Dell PERC 3/DiL (Lexus)
|
||||
1028:000a:1028:0106 Dell PERC 3/DiJ (Jaguar)
|
||||
1028:000a:1028:011b Dell PERC 3/DiD (Dagger)
|
||||
1028:000a:1028:0121 Dell PERC 3/DiB (Boxster)
|
||||
9005:0285:1028:0287 Dell PERC 320/DC (Vulcan)
|
||||
9005:0285:1028:0291 Dell CERC 2 (DellCorsair)
|
||||
1011:0046:103c:10c2 HP NetRAID-4M (Mustang)
|
||||
9005:0285:17aa:0286 Legend S220 (Crusader)
|
||||
9005:0285:17aa:0287 Legend S230 (Vulcan)
|
||||
9005:0285:9005:0290 IBM ServeRAID 7t (Jaguar)
|
||||
9005:0285:1014:02F2 IBM ServeRAID 8i (AvonPark)
|
||||
9005:0285:1014:0312 IBM ServeRAID 8i (AvonParkLite)
|
||||
9005:0286:1014:9580 IBM ServeRAID 8k/8k-l8 (Aurora)
|
||||
9005:0286:1014:9540 IBM ServeRAID 8k/8k-l4 (AuroraLite)
|
||||
9005:0286:9005:029f ICP ICP9014R0 (Lancer)
|
||||
9005:0286:9005:029e ICP ICP9024R0 (Lancer)
|
||||
9005:0286:9005:02a0 ICP ICP9047MA (Lancer)
|
||||
9005:0286:9005:02a1 ICP ICP9087MA (Lancer)
|
||||
9005:0286:9005:02a4 ICP ICP9085LI (Marauder-X)
|
||||
9005:0286:9005:02a5 ICP ICP5085BR (Marauder-E)
|
||||
9005:0286:9005:02a3 ICP ICP5085AU (Hurricane)
|
||||
9005:0286:9005:02a6 ICP ICP9067MA (Intruder-6)
|
||||
9005:0286:9005:02a9 ICP ICP5087AU (Skyray)
|
||||
9005:0286:9005:02aa ICP ICP5047AU (Skyray)
|
||||
|
||||
People
|
||||
-------------------------
|
||||
Alan Cox <alan@redhat.com>
|
||||
Christoph Hellwig <hch@infradead.org> (updates for new-style PCI probing and SCSI host registration,
|
||||
small cleanups/fixes)
|
||||
Matt Domsch <matt_domsch@dell.com> (revision ioctl, adapter messages)
|
||||
Deanna Bonds (non-DASD support, PAE fibs and 64 bit, added new adaptec controllers
|
||||
added new ioctls, changed scsi interface to use new error handler,
|
||||
increased the number of fibs and outstanding commands to a container)
|
||||
|
||||
(fixed 64bit and 64G memory model, changed confusing naming convention
|
||||
where fibs that go to the hardware are consistently called hw_fibs and
|
||||
not just fibs like the name of the driver tracking structure)
|
||||
Mark Salyzyn <Mark_Salyzyn@adaptec.com> Fixed panic issues and added some new product ids for upcoming hbas. Performance tuning, card failover and bug mitigations.
|
||||
|
||||
Original Driver
|
||||
-------------------------
|
||||
Adaptec Unix OEM Product Group
|
||||
|
||||
Mailing List
|
||||
-------------------------
|
||||
linux-scsi@vger.kernel.org (Interested parties troll here)
|
||||
Also note this is very different to Brian's original driver
|
||||
so don't expect him to support it.
|
||||
Adaptec does support this driver. Contact Adaptec tech support or
|
||||
aacraid@adaptec.com
|
||||
|
||||
Original by Brian Boerner February 2001
|
||||
Rewritten by Alan Cox, November 2001
|
@ -5577,7 +5577,7 @@ struct _snd_pcm_runtime {
|
||||
<informalexample>
|
||||
<programlisting>
|
||||
<![CDATA[
|
||||
static int mychip_suspend(strut pci_dev *pci, pm_message_t state)
|
||||
static int mychip_suspend(struct pci_dev *pci, pm_message_t state)
|
||||
{
|
||||
/* (1) */
|
||||
struct snd_card *card = pci_get_drvdata(pci);
|
||||
|
57
Documentation/spi/butterfly
Normal file
57
Documentation/spi/butterfly
Normal file
@ -0,0 +1,57 @@
|
||||
spi_butterfly - parport-to-butterfly adapter driver
|
||||
===================================================
|
||||
|
||||
This is a hardware and software project that includes building and using
|
||||
a parallel port adapter cable, together with an "AVR Butterfly" to run
|
||||
firmware for user interfacing and/or sensors. A Butterfly is a $US20
|
||||
battery powered card with an AVR microcontroller and lots of goodies:
|
||||
sensors, LCD, flash, toggle stick, and more. You can use AVR-GCC to
|
||||
develop firmware for this, and flash it using this adapter cable.
|
||||
|
||||
You can make this adapter from an old printer cable and solder things
|
||||
directly to the Butterfly. Or (if you have the parts and skills) you
|
||||
can come up with something fancier, providing ciruit protection to the
|
||||
Butterfly and the printer port, or with a better power supply than two
|
||||
signal pins from the printer port.
|
||||
|
||||
|
||||
The first cable connections will hook Linux up to one SPI bus, with the
|
||||
AVR and a DataFlash chip; and to the AVR reset line. This is all you
|
||||
need to reflash the firmware, and the pins are the standard Atmel "ISP"
|
||||
connector pins (used also on non-Butterfly AVR boards).
|
||||
|
||||
Signal Butterfly Parport (DB-25)
|
||||
------ --------- ---------------
|
||||
SCK = J403.PB1/SCK = pin 2/D0
|
||||
RESET = J403.nRST = pin 3/D1
|
||||
VCC = J403.VCC_EXT = pin 8/D6
|
||||
MOSI = J403.PB2/MOSI = pin 9/D7
|
||||
MISO = J403.PB3/MISO = pin 11/S7,nBUSY
|
||||
GND = J403.GND = pin 23/GND
|
||||
|
||||
Then to let Linux master that bus to talk to the DataFlash chip, you must
|
||||
(a) flash new firmware that disables SPI (set PRR.2, and disable pullups
|
||||
by clearing PORTB.[0-3]); (b) configure the mtd_dataflash driver; and
|
||||
(c) cable in the chipselect.
|
||||
|
||||
Signal Butterfly Parport (DB-25)
|
||||
------ --------- ---------------
|
||||
VCC = J400.VCC_EXT = pin 7/D5
|
||||
SELECT = J400.PB0/nSS = pin 17/C3,nSELECT
|
||||
GND = J400.GND = pin 24/GND
|
||||
|
||||
The "USI" controller, using J405, can be used for a second SPI bus. That
|
||||
would let you talk to the AVR over SPI, running firmware that makes it act
|
||||
as an SPI slave, while letting either Linux or the AVR use the DataFlash.
|
||||
There are plenty of spare parport pins to wire this one up, such as:
|
||||
|
||||
Signal Butterfly Parport (DB-25)
|
||||
------ --------- ---------------
|
||||
SCK = J403.PE4/USCK = pin 5/D3
|
||||
MOSI = J403.PE5/DI = pin 6/D4
|
||||
MISO = J403.PE6/DO = pin 12/S5,nPAPEROUT
|
||||
GND = J403.GND = pin 22/GND
|
||||
|
||||
IRQ = J402.PF4 = pin 10/S6,ACK
|
||||
GND = J402.GND(P2) = pin 25/GND
|
||||
|
457
Documentation/spi/spi-summary
Normal file
457
Documentation/spi/spi-summary
Normal file
@ -0,0 +1,457 @@
|
||||
Overview of Linux kernel SPI support
|
||||
====================================
|
||||
|
||||
02-Dec-2005
|
||||
|
||||
What is SPI?
|
||||
------------
|
||||
The "Serial Peripheral Interface" (SPI) is a synchronous four wire serial
|
||||
link used to connect microcontrollers to sensors, memory, and peripherals.
|
||||
|
||||
The three signal wires hold a clock (SCLK, often on the order of 10 MHz),
|
||||
and parallel data lines with "Master Out, Slave In" (MOSI) or "Master In,
|
||||
Slave Out" (MISO) signals. (Other names are also used.) There are four
|
||||
clocking modes through which data is exchanged; mode-0 and mode-3 are most
|
||||
commonly used. Each clock cycle shifts data out and data in; the clock
|
||||
doesn't cycle except when there is data to shift.
|
||||
|
||||
SPI masters may use a "chip select" line to activate a given SPI slave
|
||||
device, so those three signal wires may be connected to several chips
|
||||
in parallel. All SPI slaves support chipselects. Some devices have
|
||||
other signals, often including an interrupt to the master.
|
||||
|
||||
Unlike serial busses like USB or SMBUS, even low level protocols for
|
||||
SPI slave functions are usually not interoperable between vendors
|
||||
(except for cases like SPI memory chips).
|
||||
|
||||
- SPI may be used for request/response style device protocols, as with
|
||||
touchscreen sensors and memory chips.
|
||||
|
||||
- It may also be used to stream data in either direction (half duplex),
|
||||
or both of them at the same time (full duplex).
|
||||
|
||||
- Some devices may use eight bit words. Others may different word
|
||||
lengths, such as streams of 12-bit or 20-bit digital samples.
|
||||
|
||||
In the same way, SPI slaves will only rarely support any kind of automatic
|
||||
discovery/enumeration protocol. The tree of slave devices accessible from
|
||||
a given SPI master will normally be set up manually, with configuration
|
||||
tables.
|
||||
|
||||
SPI is only one of the names used by such four-wire protocols, and
|
||||
most controllers have no problem handling "MicroWire" (think of it as
|
||||
half-duplex SPI, for request/response protocols), SSP ("Synchronous
|
||||
Serial Protocol"), PSP ("Programmable Serial Protocol"), and other
|
||||
related protocols.
|
||||
|
||||
Microcontrollers often support both master and slave sides of the SPI
|
||||
protocol. This document (and Linux) currently only supports the master
|
||||
side of SPI interactions.
|
||||
|
||||
|
||||
Who uses it? On what kinds of systems?
|
||||
---------------------------------------
|
||||
Linux developers using SPI are probably writing device drivers for embedded
|
||||
systems boards. SPI is used to control external chips, and it is also a
|
||||
protocol supported by every MMC or SD memory card. (The older "DataFlash"
|
||||
cards, predating MMC cards but using the same connectors and card shape,
|
||||
support only SPI.) Some PC hardware uses SPI flash for BIOS code.
|
||||
|
||||
SPI slave chips range from digital/analog converters used for analog
|
||||
sensors and codecs, to memory, to peripherals like USB controllers
|
||||
or Ethernet adapters; and more.
|
||||
|
||||
Most systems using SPI will integrate a few devices on a mainboard.
|
||||
Some provide SPI links on expansion connectors; in cases where no
|
||||
dedicated SPI controller exists, GPIO pins can be used to create a
|
||||
low speed "bitbanging" adapter. Very few systems will "hotplug" an SPI
|
||||
controller; the reasons to use SPI focus on low cost and simple operation,
|
||||
and if dynamic reconfiguration is important, USB will often be a more
|
||||
appropriate low-pincount peripheral bus.
|
||||
|
||||
Many microcontrollers that can run Linux integrate one or more I/O
|
||||
interfaces with SPI modes. Given SPI support, they could use MMC or SD
|
||||
cards without needing a special purpose MMC/SD/SDIO controller.
|
||||
|
||||
|
||||
How do these driver programming interfaces work?
|
||||
------------------------------------------------
|
||||
The <linux/spi/spi.h> header file includes kerneldoc, as does the
|
||||
main source code, and you should certainly read that. This is just
|
||||
an overview, so you get the big picture before the details.
|
||||
|
||||
SPI requests always go into I/O queues. Requests for a given SPI device
|
||||
are always executed in FIFO order, and complete asynchronously through
|
||||
completion callbacks. There are also some simple synchronous wrappers
|
||||
for those calls, including ones for common transaction types like writing
|
||||
a command and then reading its response.
|
||||
|
||||
There are two types of SPI driver, here called:
|
||||
|
||||
Controller drivers ... these are often built in to System-On-Chip
|
||||
processors, and often support both Master and Slave roles.
|
||||
These drivers touch hardware registers and may use DMA.
|
||||
Or they can be PIO bitbangers, needing just GPIO pins.
|
||||
|
||||
Protocol drivers ... these pass messages through the controller
|
||||
driver to communicate with a Slave or Master device on the
|
||||
other side of an SPI link.
|
||||
|
||||
So for example one protocol driver might talk to the MTD layer to export
|
||||
data to filesystems stored on SPI flash like DataFlash; and others might
|
||||
control audio interfaces, present touchscreen sensors as input interfaces,
|
||||
or monitor temperature and voltage levels during industrial processing.
|
||||
And those might all be sharing the same controller driver.
|
||||
|
||||
A "struct spi_device" encapsulates the master-side interface between
|
||||
those two types of driver. At this writing, Linux has no slave side
|
||||
programming interface.
|
||||
|
||||
There is a minimal core of SPI programming interfaces, focussing on
|
||||
using driver model to connect controller and protocol drivers using
|
||||
device tables provided by board specific initialization code. SPI
|
||||
shows up in sysfs in several locations:
|
||||
|
||||
/sys/devices/.../CTLR/spiB.C ... spi_device for on bus "B",
|
||||
chipselect C, accessed through CTLR.
|
||||
|
||||
/sys/devices/.../CTLR/spiB.C/modalias ... identifies the driver
|
||||
that should be used with this device (for hotplug/coldplug)
|
||||
|
||||
/sys/bus/spi/devices/spiB.C ... symlink to the physical
|
||||
spiB-C device
|
||||
|
||||
/sys/bus/spi/drivers/D ... driver for one or more spi*.* devices
|
||||
|
||||
/sys/class/spi_master/spiB ... class device for the controller
|
||||
managing bus "B". All the spiB.* devices share the same
|
||||
physical SPI bus segment, with SCLK, MOSI, and MISO.
|
||||
|
||||
|
||||
How does board-specific init code declare SPI devices?
|
||||
------------------------------------------------------
|
||||
Linux needs several kinds of information to properly configure SPI devices.
|
||||
That information is normally provided by board-specific code, even for
|
||||
chips that do support some of automated discovery/enumeration.
|
||||
|
||||
DECLARE CONTROLLERS
|
||||
|
||||
The first kind of information is a list of what SPI controllers exist.
|
||||
For System-on-Chip (SOC) based boards, these will usually be platform
|
||||
devices, and the controller may need some platform_data in order to
|
||||
operate properly. The "struct platform_device" will include resources
|
||||
like the physical address of the controller's first register and its IRQ.
|
||||
|
||||
Platforms will often abstract the "register SPI controller" operation,
|
||||
maybe coupling it with code to initialize pin configurations, so that
|
||||
the arch/.../mach-*/board-*.c files for several boards can all share the
|
||||
same basic controller setup code. This is because most SOCs have several
|
||||
SPI-capable controllers, and only the ones actually usable on a given
|
||||
board should normally be set up and registered.
|
||||
|
||||
So for example arch/.../mach-*/board-*.c files might have code like:
|
||||
|
||||
#include <asm/arch/spi.h> /* for mysoc_spi_data */
|
||||
|
||||
/* if your mach-* infrastructure doesn't support kernels that can
|
||||
* run on multiple boards, pdata wouldn't benefit from "__init".
|
||||
*/
|
||||
static struct mysoc_spi_data __init pdata = { ... };
|
||||
|
||||
static __init board_init(void)
|
||||
{
|
||||
...
|
||||
/* this board only uses SPI controller #2 */
|
||||
mysoc_register_spi(2, &pdata);
|
||||
...
|
||||
}
|
||||
|
||||
And SOC-specific utility code might look something like:
|
||||
|
||||
#include <asm/arch/spi.h>
|
||||
|
||||
static struct platform_device spi2 = { ... };
|
||||
|
||||
void mysoc_register_spi(unsigned n, struct mysoc_spi_data *pdata)
|
||||
{
|
||||
struct mysoc_spi_data *pdata2;
|
||||
|
||||
pdata2 = kmalloc(sizeof *pdata2, GFP_KERNEL);
|
||||
*pdata2 = pdata;
|
||||
...
|
||||
if (n == 2) {
|
||||
spi2->dev.platform_data = pdata2;
|
||||
register_platform_device(&spi2);
|
||||
|
||||
/* also: set up pin modes so the spi2 signals are
|
||||
* visible on the relevant pins ... bootloaders on
|
||||
* production boards may already have done this, but
|
||||
* developer boards will often need Linux to do it.
|
||||
*/
|
||||
}
|
||||
...
|
||||
}
|
||||
|
||||
Notice how the platform_data for boards may be different, even if the
|
||||
same SOC controller is used. For example, on one board SPI might use
|
||||
an external clock, where another derives the SPI clock from current
|
||||
settings of some master clock.
|
||||
|
||||
|
||||
DECLARE SLAVE DEVICES
|
||||
|
||||
The second kind of information is a list of what SPI slave devices exist
|
||||
on the target board, often with some board-specific data needed for the
|
||||
driver to work correctly.
|
||||
|
||||
Normally your arch/.../mach-*/board-*.c files would provide a small table
|
||||
listing the SPI devices on each board. (This would typically be only a
|
||||
small handful.) That might look like:
|
||||
|
||||
static struct ads7846_platform_data ads_info = {
|
||||
.vref_delay_usecs = 100,
|
||||
.x_plate_ohms = 580,
|
||||
.y_plate_ohms = 410,
|
||||
};
|
||||
|
||||
static struct spi_board_info spi_board_info[] __initdata = {
|
||||
{
|
||||
.modalias = "ads7846",
|
||||
.platform_data = &ads_info,
|
||||
.mode = SPI_MODE_0,
|
||||
.irq = GPIO_IRQ(31),
|
||||
.max_speed_hz = 120000 /* max sample rate at 3V */ * 16,
|
||||
.bus_num = 1,
|
||||
.chip_select = 0,
|
||||
},
|
||||
};
|
||||
|
||||
Again, notice how board-specific information is provided; each chip may need
|
||||
several types. This example shows generic constraints like the fastest SPI
|
||||
clock to allow (a function of board voltage in this case) or how an IRQ pin
|
||||
is wired, plus chip-specific constraints like an important delay that's
|
||||
changed by the capacitance at one pin.
|
||||
|
||||
(There's also "controller_data", information that may be useful to the
|
||||
controller driver. An example would be peripheral-specific DMA tuning
|
||||
data or chipselect callbacks. This is stored in spi_device later.)
|
||||
|
||||
The board_info should provide enough information to let the system work
|
||||
without the chip's driver being loaded. The most troublesome aspect of
|
||||
that is likely the SPI_CS_HIGH bit in the spi_device.mode field, since
|
||||
sharing a bus with a device that interprets chipselect "backwards" is
|
||||
not possible.
|
||||
|
||||
Then your board initialization code would register that table with the SPI
|
||||
infrastructure, so that it's available later when the SPI master controller
|
||||
driver is registered:
|
||||
|
||||
spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
|
||||
|
||||
Like with other static board-specific setup, you won't unregister those.
|
||||
|
||||
The widely used "card" style computers bundle memory, cpu, and little else
|
||||
onto a card that's maybe just thirty square centimeters. On such systems,
|
||||
your arch/.../mach-.../board-*.c file would primarily provide information
|
||||
about the devices on the mainboard into which such a card is plugged. That
|
||||
certainly includes SPI devices hooked up through the card connectors!
|
||||
|
||||
|
||||
NON-STATIC CONFIGURATIONS
|
||||
|
||||
Developer boards often play by different rules than product boards, and one
|
||||
example is the potential need to hotplug SPI devices and/or controllers.
|
||||
|
||||
For those cases you might need to use use spi_busnum_to_master() to look
|
||||
up the spi bus master, and will likely need spi_new_device() to provide the
|
||||
board info based on the board that was hotplugged. Of course, you'd later
|
||||
call at least spi_unregister_device() when that board is removed.
|
||||
|
||||
When Linux includes support for MMC/SD/SDIO/DataFlash cards through SPI, those
|
||||
configurations will also be dynamic. Fortunately, those devices all support
|
||||
basic device identification probes, so that support should hotplug normally.
|
||||
|
||||
|
||||
How do I write an "SPI Protocol Driver"?
|
||||
----------------------------------------
|
||||
All SPI drivers are currently kernel drivers. A userspace driver API
|
||||
would just be another kernel driver, probably offering some lowlevel
|
||||
access through aio_read(), aio_write(), and ioctl() calls and using the
|
||||
standard userspace sysfs mechanisms to bind to a given SPI device.
|
||||
|
||||
SPI protocol drivers somewhat resemble platform device drivers:
|
||||
|
||||
static struct spi_driver CHIP_driver = {
|
||||
.driver = {
|
||||
.name = "CHIP",
|
||||
.bus = &spi_bus_type,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
|
||||
.probe = CHIP_probe,
|
||||
.remove = __devexit_p(CHIP_remove),
|
||||
.suspend = CHIP_suspend,
|
||||
.resume = CHIP_resume,
|
||||
};
|
||||
|
||||
The driver core will autmatically attempt to bind this driver to any SPI
|
||||
device whose board_info gave a modalias of "CHIP". Your probe() code
|
||||
might look like this unless you're creating a class_device:
|
||||
|
||||
static int __devinit CHIP_probe(struct spi_device *spi)
|
||||
{
|
||||
struct CHIP *chip;
|
||||
struct CHIP_platform_data *pdata;
|
||||
|
||||
/* assuming the driver requires board-specific data: */
|
||||
pdata = &spi->dev.platform_data;
|
||||
if (!pdata)
|
||||
return -ENODEV;
|
||||
|
||||
/* get memory for driver's per-chip state */
|
||||
chip = kzalloc(sizeof *chip, GFP_KERNEL);
|
||||
if (!chip)
|
||||
return -ENOMEM;
|
||||
dev_set_drvdata(&spi->dev, chip);
|
||||
|
||||
... etc
|
||||
return 0;
|
||||
}
|
||||
|
||||
As soon as it enters probe(), the driver may issue I/O requests to
|
||||
the SPI device using "struct spi_message". When remove() returns,
|
||||
the driver guarantees that it won't submit any more such messages.
|
||||
|
||||
- An spi_message is a sequence of of protocol operations, executed
|
||||
as one atomic sequence. SPI driver controls include:
|
||||
|
||||
+ when bidirectional reads and writes start ... by how its
|
||||
sequence of spi_transfer requests is arranged;
|
||||
|
||||
+ optionally defining short delays after transfers ... using
|
||||
the spi_transfer.delay_usecs setting;
|
||||
|
||||
+ whether the chipselect becomes inactive after a transfer and
|
||||
any delay ... by using the spi_transfer.cs_change flag;
|
||||
|
||||
+ hinting whether the next message is likely to go to this same
|
||||
device ... using the spi_transfer.cs_change flag on the last
|
||||
transfer in that atomic group, and potentially saving costs
|
||||
for chip deselect and select operations.
|
||||
|
||||
- Follow standard kernel rules, and provide DMA-safe buffers in
|
||||
your messages. That way controller drivers using DMA aren't forced
|
||||
to make extra copies unless the hardware requires it (e.g. working
|
||||
around hardware errata that force the use of bounce buffering).
|
||||
|
||||
If standard dma_map_single() handling of these buffers is inappropriate,
|
||||
you can use spi_message.is_dma_mapped to tell the controller driver
|
||||
that you've already provided the relevant DMA addresses.
|
||||
|
||||
- The basic I/O primitive is spi_async(). Async requests may be
|
||||
issued in any context (irq handler, task, etc) and completion
|
||||
is reported using a callback provided with the message.
|
||||
After any detected error, the chip is deselected and processing
|
||||
of that spi_message is aborted.
|
||||
|
||||
- There are also synchronous wrappers like spi_sync(), and wrappers
|
||||
like spi_read(), spi_write(), and spi_write_then_read(). These
|
||||
may be issued only in contexts that may sleep, and they're all
|
||||
clean (and small, and "optional") layers over spi_async().
|
||||
|
||||
- The spi_write_then_read() call, and convenience wrappers around
|
||||
it, should only be used with small amounts of data where the
|
||||
cost of an extra copy may be ignored. It's designed to support
|
||||
common RPC-style requests, such as writing an eight bit command
|
||||
and reading a sixteen bit response -- spi_w8r16() being one its
|
||||
wrappers, doing exactly that.
|
||||
|
||||
Some drivers may need to modify spi_device characteristics like the
|
||||
transfer mode, wordsize, or clock rate. This is done with spi_setup(),
|
||||
which would normally be called from probe() before the first I/O is
|
||||
done to the device.
|
||||
|
||||
While "spi_device" would be the bottom boundary of the driver, the
|
||||
upper boundaries might include sysfs (especially for sensor readings),
|
||||
the input layer, ALSA, networking, MTD, the character device framework,
|
||||
or other Linux subsystems.
|
||||
|
||||
Note that there are two types of memory your driver must manage as part
|
||||
of interacting with SPI devices.
|
||||
|
||||
- I/O buffers use the usual Linux rules, and must be DMA-safe.
|
||||
You'd normally allocate them from the heap or free page pool.
|
||||
Don't use the stack, or anything that's declared "static".
|
||||
|
||||
- The spi_message and spi_transfer metadata used to glue those
|
||||
I/O buffers into a group of protocol transactions. These can
|
||||
be allocated anywhere it's convenient, including as part of
|
||||
other allocate-once driver data structures. Zero-init these.
|
||||
|
||||
If you like, spi_message_alloc() and spi_message_free() convenience
|
||||
routines are available to allocate and zero-initialize an spi_message
|
||||
with several transfers.
|
||||
|
||||
|
||||
How do I write an "SPI Master Controller Driver"?
|
||||
-------------------------------------------------
|
||||
An SPI controller will probably be registered on the platform_bus; write
|
||||
a driver to bind to the device, whichever bus is involved.
|
||||
|
||||
The main task of this type of driver is to provide an "spi_master".
|
||||
Use spi_alloc_master() to allocate the master, and class_get_devdata()
|
||||
to get the driver-private data allocated for that device.
|
||||
|
||||
struct spi_master *master;
|
||||
struct CONTROLLER *c;
|
||||
|
||||
master = spi_alloc_master(dev, sizeof *c);
|
||||
if (!master)
|
||||
return -ENODEV;
|
||||
|
||||
c = class_get_devdata(&master->cdev);
|
||||
|
||||
The driver will initialize the fields of that spi_master, including the
|
||||
bus number (maybe the same as the platform device ID) and three methods
|
||||
used to interact with the SPI core and SPI protocol drivers. It will
|
||||
also initialize its own internal state.
|
||||
|
||||
master->setup(struct spi_device *spi)
|
||||
This sets up the device clock rate, SPI mode, and word sizes.
|
||||
Drivers may change the defaults provided by board_info, and then
|
||||
call spi_setup(spi) to invoke this routine. It may sleep.
|
||||
|
||||
master->transfer(struct spi_device *spi, struct spi_message *message)
|
||||
This must not sleep. Its responsibility is arrange that the
|
||||
transfer happens and its complete() callback is issued; the two
|
||||
will normally happen later, after other transfers complete.
|
||||
|
||||
master->cleanup(struct spi_device *spi)
|
||||
Your controller driver may use spi_device.controller_state to hold
|
||||
state it dynamically associates with that device. If you do that,
|
||||
be sure to provide the cleanup() method to free that state.
|
||||
|
||||
The bulk of the driver will be managing the I/O queue fed by transfer().
|
||||
|
||||
That queue could be purely conceptual. For example, a driver used only
|
||||
for low-frequency sensor acess might be fine using synchronous PIO.
|
||||
|
||||
But the queue will probably be very real, using message->queue, PIO,
|
||||
often DMA (especially if the root filesystem is in SPI flash), and
|
||||
execution contexts like IRQ handlers, tasklets, or workqueues (such
|
||||
as keventd). Your driver can be as fancy, or as simple, as you need.
|
||||
|
||||
|
||||
THANKS TO
|
||||
---------
|
||||
Contributors to Linux-SPI discussions include (in alphabetical order,
|
||||
by last name):
|
||||
|
||||
David Brownell
|
||||
Russell King
|
||||
Dmitry Pervushin
|
||||
Stephen Street
|
||||
Mark Underwood
|
||||
Andrew Victor
|
||||
Vitaly Wool
|
||||
|
@ -68,3 +68,4 @@ tuner=66 - LG NTSC (TALN mini series)
|
||||
tuner=67 - Philips TD1316 Hybrid Tuner
|
||||
tuner=68 - Philips TUV1236D ATSC/NTSC dual in
|
||||
tuner=69 - Tena TNF 5335 MF
|
||||
tuner=70 - Samsung TCPN 2121P30A
|
||||
|
@ -198,6 +198,6 @@ Debugging
|
||||
|
||||
Misc
|
||||
|
||||
noreplacement Don't replace instructions with more appropiate ones
|
||||
noreplacement Don't replace instructions with more appropriate ones
|
||||
for the CPU. This may be useful on asymmetric MP systems
|
||||
where some CPU have less capabilities than the others.
|
||||
|
44
MAINTAINERS
44
MAINTAINERS
@ -549,6 +549,7 @@ S: Maintained
|
||||
COMMON INTERNET FILE SYSTEM (CIFS)
|
||||
P: Steve French
|
||||
M: sfrench@samba.org
|
||||
L: linux-cifs-client@lists.samba.org
|
||||
L: samba-technical@lists.samba.org
|
||||
W: http://us1.samba.org/samba/Linux_CIFS_client.html
|
||||
T: git kernel.org:/pub/scm/linux/kernel/git/sfrench/cifs-2.6.git
|
||||
@ -1300,6 +1301,12 @@ M: ttb@tentacle.dhs.org and rml@novell.com
|
||||
L: linux-kernel@vger.kernel.org
|
||||
S: Maintained
|
||||
|
||||
INTEL FRAMEBUFFER DRIVER (excluding 810 and 815)
|
||||
P: Sylvain Meyer
|
||||
M: sylvain.meyer@worldonline.fr
|
||||
L: linux-fbdev-devel@lists.sourceforge.net
|
||||
S: Maintained
|
||||
|
||||
INTEL 810/815 FRAMEBUFFER DRIVER
|
||||
P: Antonino Daplas
|
||||
M: adaplas@pol.net
|
||||
@ -1889,11 +1896,11 @@ W: http://linux-ntfs.sf.net/
|
||||
T: git kernel.org:/pub/scm/linux/kernel/git/aia21/ntfs-2.6.git
|
||||
S: Maintained
|
||||
|
||||
NVIDIA (RIVA) FRAMEBUFFER DRIVER
|
||||
P: Ani Joshi
|
||||
M: ajoshi@shell.unixbox.com
|
||||
L: linux-nvidia@lists.surfsouth.com
|
||||
S: Maintained
|
||||
NVIDIA (rivafb and nvidiafb) FRAMEBUFFER DRIVER
|
||||
P: Antonino Daplas
|
||||
M: adaplas@pol.net
|
||||
L: linux-fbdev-devel@lists.sourceforge.net
|
||||
S: Maintained
|
||||
|
||||
ORACLE CLUSTER FILESYSTEM 2 (OCFS2)
|
||||
P: Mark Fasheh
|
||||
@ -2053,7 +2060,7 @@ S: Maintained
|
||||
POSIX CLOCKS and TIMERS
|
||||
P: George Anzinger
|
||||
M: george@mvista.com
|
||||
L: netdev@vger.kernel.org
|
||||
L: linux-kernel@vger.kernel.org
|
||||
S: Supported
|
||||
|
||||
POWERPC 4xx EMAC DRIVER
|
||||
@ -2188,6 +2195,12 @@ L: rtl@rtlinux.org
|
||||
W: www.rtlinux.org
|
||||
S: Maintained
|
||||
|
||||
S3 SAVAGE FRAMEBUFFER DRIVER
|
||||
P: Antonino Daplas
|
||||
M: adaplas@pol.net
|
||||
L: linux-fbdev-devel@lists.sourceforge.net
|
||||
S: Maintained
|
||||
|
||||
S390
|
||||
P: Martin Schwidefsky
|
||||
M: schwidefsky@de.ibm.com
|
||||
@ -2519,6 +2532,19 @@ P: Romain Lievin
|
||||
M: roms@lpg.ticalc.org
|
||||
S: Maintained
|
||||
|
||||
TIPC NETWORK LAYER
|
||||
P: Per Liden
|
||||
M: per.liden@nospam.ericsson.com
|
||||
P: Jon Maloy
|
||||
M: jon.maloy@nospam.ericsson.com
|
||||
P: Allan Stephens
|
||||
M: allan.stephens@nospam.windriver.com
|
||||
L: tipc-discussion@lists.sourceforge.net
|
||||
W: http://tipc.sourceforge.net/
|
||||
W: http://tipc.cslab.ericsson.net/
|
||||
T: git tipc.cslab.ericsson.net:/pub/git/tipc.git
|
||||
S: Maintained
|
||||
|
||||
TLAN NETWORK DRIVER
|
||||
P: Samuel Chessman
|
||||
M: chessman@tux.org
|
||||
@ -2940,6 +2966,12 @@ M: dm@sangoma.com
|
||||
W: http://www.sangoma.com
|
||||
S: Supported
|
||||
|
||||
WATCHDOG DEVICE DRIVERS
|
||||
P: Wim Van Sebroeck
|
||||
M: wim@iguana.be
|
||||
T: git kernel.org:/pub/scm/linux/kernel/git/wim/linux-2.6-watchdog.git
|
||||
S: Maintained
|
||||
|
||||
WAVELAN NETWORK DRIVER & WIRELESS EXTENSIONS
|
||||
P: Jean Tourrilhes
|
||||
M: jt@hpl.hp.com
|
||||
|
41
Makefile
41
Makefile
@ -1,7 +1,7 @@
|
||||
VERSION = 2
|
||||
PATCHLEVEL = 6
|
||||
SUBLEVEL = 15
|
||||
EXTRAVERSION =
|
||||
SUBLEVEL = 16
|
||||
EXTRAVERSION =-rc1
|
||||
NAME=Sliding Snow Leopard
|
||||
|
||||
# *DOCUMENTATION*
|
||||
@ -106,12 +106,13 @@ KBUILD_OUTPUT := $(shell cd $(KBUILD_OUTPUT) && /bin/pwd)
|
||||
$(if $(KBUILD_OUTPUT),, \
|
||||
$(error output directory "$(saved-output)" does not exist))
|
||||
|
||||
.PHONY: $(MAKECMDGOALS)
|
||||
.PHONY: $(MAKECMDGOALS) cdbuilddir
|
||||
$(MAKECMDGOALS) _all: cdbuilddir
|
||||
|
||||
$(filter-out _all,$(MAKECMDGOALS)) _all:
|
||||
cdbuilddir:
|
||||
$(if $(KBUILD_VERBOSE:1=),@)$(MAKE) -C $(KBUILD_OUTPUT) \
|
||||
KBUILD_SRC=$(CURDIR) \
|
||||
KBUILD_EXTMOD="$(KBUILD_EXTMOD)" -f $(CURDIR)/Makefile $@
|
||||
KBUILD_EXTMOD="$(KBUILD_EXTMOD)" -f $(CURDIR)/Makefile $(MAKECMDGOALS)
|
||||
|
||||
# Leave processing to above invocation of make
|
||||
skip-makefile := 1
|
||||
@ -151,7 +152,7 @@ export srctree objtree VPATH TOPDIR
|
||||
SUBARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \
|
||||
-e s/arm.*/arm/ -e s/sa110/arm/ \
|
||||
-e s/s390x/s390/ -e s/parisc64/parisc/ \
|
||||
-e s/ppc64/powerpc/ )
|
||||
-e s/ppc.*/powerpc/ )
|
||||
|
||||
# Cross compiling and selecting different set of gcc/bin-utils
|
||||
# ---------------------------------------------------------------------------
|
||||
@ -262,6 +263,13 @@ export quiet Q KBUILD_VERBOSE
|
||||
# cc support functions to be used (only) in arch/$(ARCH)/Makefile
|
||||
# See documentation in Documentation/kbuild/makefiles.txt
|
||||
|
||||
# as-option
|
||||
# Usage: cflags-y += $(call as-option, -Wa$(comma)-isa=foo,)
|
||||
|
||||
as-option = $(shell if $(CC) $(CFLAGS) $(1) -Wa,-Z -c -o /dev/null \
|
||||
-xassembler /dev/null > /dev/null 2>&1; then echo "$(1)"; \
|
||||
else echo "$(2)"; fi ;)
|
||||
|
||||
# cc-option
|
||||
# Usage: cflags-y += $(call cc-option, -march=winchip-c6, -march=i586)
|
||||
|
||||
@ -337,8 +345,9 @@ AFLAGS := -D__ASSEMBLY__
|
||||
|
||||
# Read KERNELRELEASE from .kernelrelease (if it exists)
|
||||
KERNELRELEASE = $(shell cat .kernelrelease 2> /dev/null)
|
||||
KERNELVERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
|
||||
|
||||
export VERSION PATCHLEVEL SUBLEVEL KERNELRELEASE \
|
||||
export VERSION PATCHLEVEL SUBLEVEL KERNELRELEASE KERNELVERSION \
|
||||
ARCH CONFIG_SHELL HOSTCC HOSTCFLAGS CROSS_COMPILE AS LD CC \
|
||||
CPP AR NM STRIP OBJCOPY OBJDUMP MAKE AWK GENKSYMS PERL UTS_MACHINE \
|
||||
HOSTCXX HOSTCXXFLAGS LDFLAGS_MODULE CHECK CHECKFLAGS
|
||||
@ -433,6 +442,7 @@ export KBUILD_DEFCONFIG
|
||||
config %config: scripts_basic outputmakefile FORCE
|
||||
$(Q)mkdir -p include/linux
|
||||
$(Q)$(MAKE) $(build)=scripts/kconfig $@
|
||||
$(Q)$(MAKE) .kernelrelease
|
||||
|
||||
else
|
||||
# ===========================================================================
|
||||
@ -542,7 +552,7 @@ export INSTALL_PATH ?= /boot
|
||||
# makefile but the arguement can be passed to make if needed.
|
||||
#
|
||||
|
||||
MODLIB := $(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE)
|
||||
MODLIB = $(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE)
|
||||
export MODLIB
|
||||
|
||||
|
||||
@ -783,12 +793,10 @@ endif
|
||||
localver-full = $(localver)$(localver-auto)
|
||||
|
||||
# Store (new) KERNELRELASE string in .kernelrelease
|
||||
kernelrelease = \
|
||||
$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)$(localver-full)
|
||||
kernelrelease = $(KERNELVERSION)$(localver-full)
|
||||
.kernelrelease: FORCE
|
||||
$(Q)rm -f .kernelrelease
|
||||
$(Q)echo $(kernelrelease) > .kernelrelease
|
||||
$(Q)echo " Building kernel $(kernelrelease)"
|
||||
$(Q)rm -f $@
|
||||
$(Q)echo $(kernelrelease) > $@
|
||||
|
||||
|
||||
# Things we need to do before we recursively start building the kernel
|
||||
@ -898,7 +906,7 @@ define filechk_version.h
|
||||
)
|
||||
endef
|
||||
|
||||
include/linux/version.h: $(srctree)/Makefile FORCE
|
||||
include/linux/version.h: $(srctree)/Makefile .config FORCE
|
||||
$(call filechk,version.h)
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
@ -1301,9 +1309,10 @@ checkstack:
|
||||
$(PERL) $(src)/scripts/checkstack.pl $(ARCH)
|
||||
|
||||
kernelrelease:
|
||||
@echo $(KERNELRELEASE)
|
||||
$(if $(wildcard .kernelrelease), $(Q)echo $(KERNELRELEASE), \
|
||||
$(error kernelrelease not valid - run 'make *config' to update it))
|
||||
kernelversion:
|
||||
@echo $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
|
||||
@echo $(KERNELVERSION)
|
||||
|
||||
# FIXME Should go into a make.lib or something
|
||||
# ===========================================================================
|
||||
|
30
README
30
README
@ -1,4 +1,4 @@
|
||||
Linux kernel release 2.6.xx
|
||||
Linux kernel release 2.6.xx <http://kernel.org>
|
||||
|
||||
These are the release notes for Linux version 2.6. Read them carefully,
|
||||
as they tell you what this is all about, explain how to install the
|
||||
@ -6,23 +6,31 @@ kernel, and what to do if something goes wrong.
|
||||
|
||||
WHAT IS LINUX?
|
||||
|
||||
Linux is a Unix clone written from scratch by Linus Torvalds with
|
||||
assistance from a loosely-knit team of hackers across the Net.
|
||||
It aims towards POSIX compliance.
|
||||
Linux is a clone of the operating system Unix, written from scratch by
|
||||
Linus Torvalds with assistance from a loosely-knit team of hackers across
|
||||
the Net. It aims towards POSIX and Single UNIX Specification compliance.
|
||||
|
||||
It has all the features you would expect in a modern fully-fledged
|
||||
Unix, including true multitasking, virtual memory, shared libraries,
|
||||
demand loading, shared copy-on-write executables, proper memory
|
||||
management and TCP/IP networking.
|
||||
It has all the features you would expect in a modern fully-fledged Unix,
|
||||
including true multitasking, virtual memory, shared libraries, demand
|
||||
loading, shared copy-on-write executables, proper memory management,
|
||||
and multistack networking including IPv4 and IPv6.
|
||||
|
||||
It is distributed under the GNU General Public License - see the
|
||||
accompanying COPYING file for more details.
|
||||
|
||||
ON WHAT HARDWARE DOES IT RUN?
|
||||
|
||||
Linux was first developed for 386/486-based PCs. These days it also
|
||||
runs on ARMs, DEC Alphas, SUN Sparcs, M68000 machines (like Atari and
|
||||
Amiga), MIPS and PowerPC, and others.
|
||||
Although originally developed first for 32-bit x86-based PCs (386 or higher),
|
||||
today Linux also runs on (at least) the Compaq Alpha AXP, Sun SPARC and
|
||||
UltraSPARC, Motorola 68000, PowerPC, PowerPC64, ARM, Hitachi SuperH,
|
||||
IBM S/390, MIPS, HP PA-RISC, Intel IA-64, DEC VAX, AMD x86-64, AXIS CRIS,
|
||||
and Renesas M32R architectures.
|
||||
|
||||
Linux is easily portable to most general-purpose 32- or 64-bit architectures
|
||||
as long as they have a paged memory management unit (PMMU) and a port of the
|
||||
GNU C compiler (gcc) (part of The GNU Compiler Collection, GCC). Linux has
|
||||
also been ported to a number of architectures without a PMMU, although
|
||||
functionality is then obviously somewhat limited.
|
||||
|
||||
DOCUMENTATION:
|
||||
|
||||
|
@ -180,6 +180,7 @@ config ARCH_OMAP
|
||||
config ARCH_VERSATILE
|
||||
bool "Versatile"
|
||||
select ARM_AMBA
|
||||
select ARM_VIC
|
||||
select ICST307
|
||||
help
|
||||
This enables support for ARM Ltd Versatile board.
|
||||
@ -400,6 +401,38 @@ config NO_IDLE_HZ
|
||||
Currently at least OMAP, PXA2xx and SA11x0 platforms are known
|
||||
to have accurate timekeeping with dynamic tick.
|
||||
|
||||
config AEABI
|
||||
bool "Use the ARM EABI to compile the kernel"
|
||||
help
|
||||
This option allows for the kernel to be compiled using the latest
|
||||
ARM ABI (aka EABI). This is only useful if you are using a user
|
||||
space environment that is also compiled with EABI.
|
||||
|
||||
Since there are major incompatibilities between the legacy ABI and
|
||||
EABI, especially with regard to structure member alignment, this
|
||||
option also changes the kernel syscall calling convention to
|
||||
disambiguate both ABIs and allow for backward compatibility support
|
||||
(selected with CONFIG_OABI_COMPAT).
|
||||
|
||||
To use this you need GCC version 4.0.0 or later.
|
||||
|
||||
config OABI_COMPAT
|
||||
bool "Allow old ABI binaries to run with this kernel"
|
||||
depends on AEABI
|
||||
default y
|
||||
help
|
||||
This option preserves the old syscall interface along with the
|
||||
new (ARM EABI) one. It also provides a compatibility layer to
|
||||
intercept syscalls that have structure arguments which layout
|
||||
in memory differs between the legacy ABI and the new ARM EABI
|
||||
(only for non "thumb" binaries). This option adds a tiny
|
||||
overhead to all syscalls and produces a slightly larger kernel.
|
||||
If you know you'll be using only pure EABI user space then you
|
||||
can say N here. If this option is not selected and you attempt
|
||||
to execute a legacy ABI binary then the result will be
|
||||
UNPREDICTABLE (in fact it can be predicted that it won't work
|
||||
at all). If in doubt say Y.
|
||||
|
||||
config ARCH_DISCONTIGMEM_ENABLE
|
||||
bool
|
||||
default (ARCH_LH7A40X && !LH7A40X_CONTIGMEM)
|
||||
@ -586,6 +619,7 @@ comment "At least one emulation must be selected"
|
||||
|
||||
config FPE_NWFPE
|
||||
bool "NWFPE math emulation"
|
||||
depends on !AEABI || OABI_COMPAT
|
||||
---help---
|
||||
Say Y to include the NWFPE floating point emulator in the kernel.
|
||||
This is necessary to run most binaries. Linux does not currently
|
||||
@ -609,7 +643,7 @@ config FPE_NWFPE_XP
|
||||
|
||||
config FPE_FASTFPE
|
||||
bool "FastFPE math emulation (EXPERIMENTAL)"
|
||||
depends on !CPU_32v3 && EXPERIMENTAL
|
||||
depends on (!AEABI || OABI_COMPAT) && !CPU_32v3 && EXPERIMENTAL
|
||||
---help---
|
||||
Say Y here to include the FAST floating point emulator in the kernel.
|
||||
This is an experimental much faster emulator which now also has full
|
||||
@ -641,6 +675,7 @@ source "fs/Kconfig.binfmt"
|
||||
|
||||
config ARTHUR
|
||||
tristate "RISC OS personality"
|
||||
depends on !AEABI
|
||||
help
|
||||
Say Y here to include the kernel code necessary if you want to run
|
||||
Acorn RISC OS/Arthur binaries under Linux. This code is still very
|
||||
@ -729,6 +764,8 @@ source "drivers/char/Kconfig"
|
||||
|
||||
source "drivers/i2c/Kconfig"
|
||||
|
||||
source "drivers/spi/Kconfig"
|
||||
|
||||
source "drivers/hwmon/Kconfig"
|
||||
|
||||
#source "drivers/l3/Kconfig"
|
||||
|
@ -56,8 +56,13 @@ tune-$(CONFIG_CPU_SA1100) :=-mtune=strongarm1100
|
||||
tune-$(CONFIG_CPU_XSCALE) :=$(call cc-option,-mtune=xscale,-mtune=strongarm110) -Wa,-mcpu=xscale
|
||||
tune-$(CONFIG_CPU_V6) :=$(call cc-option,-mtune=arm1136j-s,-mtune=strongarm)
|
||||
|
||||
# Need -Uarm for gcc < 3.x
|
||||
ifeq ($(CONFIG_AEABI),y)
|
||||
CFLAGS_ABI :=-mabi=aapcs -mno-thumb-interwork
|
||||
else
|
||||
CFLAGS_ABI :=$(call cc-option,-mapcs-32,-mabi=apcs-gnu) $(call cc-option,-mno-thumb-interwork,)
|
||||
endif
|
||||
|
||||
# Need -Uarm for gcc < 3.x
|
||||
CFLAGS +=$(CFLAGS_ABI) $(arch-y) $(tune-y) $(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) -msoft-float -Uarm
|
||||
AFLAGS +=$(CFLAGS_ABI) $(arch-y) $(tune-y) -msoft-float
|
||||
|
||||
|
@ -1,7 +1,10 @@
|
||||
config ICST525
|
||||
config ARM_GIC
|
||||
bool
|
||||
|
||||
config ARM_GIC
|
||||
config ARM_VIC
|
||||
bool
|
||||
|
||||
config ICST525
|
||||
bool
|
||||
|
||||
config ICST307
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
obj-y += rtctime.o
|
||||
obj-$(CONFIG_ARM_GIC) += gic.o
|
||||
obj-$(CONFIG_ARM_VIC) += vic.o
|
||||
obj-$(CONFIG_ICST525) += icst525.o
|
||||
obj-$(CONFIG_ICST307) += icst307.o
|
||||
obj-$(CONFIG_SA1111) += sa1111.o
|
||||
|
@ -1103,14 +1103,14 @@ static int locomo_bus_remove(struct device *dev)
|
||||
struct bus_type locomo_bus_type = {
|
||||
.name = "locomo-bus",
|
||||
.match = locomo_match,
|
||||
.probe = locomo_bus_probe,
|
||||
.remove = locomo_bus_remove,
|
||||
.suspend = locomo_bus_suspend,
|
||||
.resume = locomo_bus_resume,
|
||||
};
|
||||
|
||||
int locomo_driver_register(struct locomo_driver *driver)
|
||||
{
|
||||
driver->drv.probe = locomo_bus_probe;
|
||||
driver->drv.remove = locomo_bus_remove;
|
||||
driver->drv.bus = &locomo_bus_type;
|
||||
return driver_register(&driver->drv);
|
||||
}
|
||||
|
@ -1247,14 +1247,14 @@ static int sa1111_bus_remove(struct device *dev)
|
||||
struct bus_type sa1111_bus_type = {
|
||||
.name = "sa1111-rab",
|
||||
.match = sa1111_match,
|
||||
.probe = sa1111_bus_probe,
|
||||
.remove = sa1111_bus_remove,
|
||||
.suspend = sa1111_bus_suspend,
|
||||
.resume = sa1111_bus_resume,
|
||||
};
|
||||
|
||||
int sa1111_driver_register(struct sa1111_driver *driver)
|
||||
{
|
||||
driver->drv.probe = sa1111_bus_probe;
|
||||
driver->drv.remove = sa1111_bus_remove;
|
||||
driver->drv.bus = &sa1111_bus_type;
|
||||
return driver_register(&driver->drv);
|
||||
}
|
||||
|
92
arch/arm/common/vic.c
Normal file
92
arch/arm/common/vic.c
Normal file
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* linux/arch/arm/common/vic.c
|
||||
*
|
||||
* Copyright (C) 1999 - 2003 ARM Limited
|
||||
* Copyright (C) 2000 Deep Blue Solutions Ltd
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include <linux/init.h>
|
||||
#include <linux/list.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/mach/irq.h>
|
||||
#include <asm/hardware/vic.h>
|
||||
|
||||
static void __iomem *vic_base;
|
||||
|
||||
static void vic_mask_irq(unsigned int irq)
|
||||
{
|
||||
irq -= IRQ_VIC_START;
|
||||
writel(1 << irq, vic_base + VIC_INT_ENABLE_CLEAR);
|
||||
}
|
||||
|
||||
static void vic_unmask_irq(unsigned int irq)
|
||||
{
|
||||
irq -= IRQ_VIC_START;
|
||||
writel(1 << irq, vic_base + VIC_INT_ENABLE);
|
||||
}
|
||||
|
||||
static struct irqchip vic_chip = {
|
||||
.ack = vic_mask_irq,
|
||||
.mask = vic_mask_irq,
|
||||
.unmask = vic_unmask_irq,
|
||||
};
|
||||
|
||||
void __init vic_init(void __iomem *base, u32 vic_sources)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
vic_base = base;
|
||||
|
||||
/* Disable all interrupts initially. */
|
||||
|
||||
writel(0, vic_base + VIC_INT_SELECT);
|
||||
writel(0, vic_base + VIC_INT_ENABLE);
|
||||
writel(~0, vic_base + VIC_INT_ENABLE_CLEAR);
|
||||
writel(0, vic_base + VIC_IRQ_STATUS);
|
||||
writel(0, vic_base + VIC_ITCR);
|
||||
writel(~0, vic_base + VIC_INT_SOFT_CLEAR);
|
||||
|
||||
/*
|
||||
* Make sure we clear all existing interrupts
|
||||
*/
|
||||
writel(0, vic_base + VIC_VECT_ADDR);
|
||||
for (i = 0; i < 19; i++) {
|
||||
unsigned int value;
|
||||
|
||||
value = readl(vic_base + VIC_VECT_ADDR);
|
||||
writel(value, vic_base + VIC_VECT_ADDR);
|
||||
}
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
void __iomem *reg = vic_base + VIC_VECT_CNTL0 + (i * 4);
|
||||
writel(VIC_VECT_CNTL_ENABLE | i, reg);
|
||||
}
|
||||
|
||||
writel(32, vic_base + VIC_DEF_VECT_ADDR);
|
||||
|
||||
for (i = 0; i < 32; i++) {
|
||||
unsigned int irq = IRQ_VIC_START + i;
|
||||
|
||||
set_irq_chip(irq, &vic_chip);
|
||||
|
||||
if (vic_sources & (1 << i)) {
|
||||
set_irq_handler(irq, do_level_IRQ);
|
||||
set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
|
||||
}
|
||||
}
|
||||
}
|
@ -20,6 +20,7 @@ obj-$(CONFIG_ARTHUR) += arthur.o
|
||||
obj-$(CONFIG_ISA_DMA) += dma-isa.o
|
||||
obj-$(CONFIG_PCI) += bios32.o
|
||||
obj-$(CONFIG_SMP) += smp.o
|
||||
obj-$(CONFIG_OABI_COMPAT) += sys_oabi-compat.o
|
||||
|
||||
obj-$(CONFIG_IWMMXT) += iwmmxt.o
|
||||
AFLAGS_iwmmxt.o := -Wa,-mcpu=iwmmxt
|
||||
|
@ -35,6 +35,16 @@ extern void __udivsi3(void);
|
||||
extern void __umodsi3(void);
|
||||
extern void __do_div64(void);
|
||||
|
||||
extern void __aeabi_idiv(void);
|
||||
extern void __aeabi_idivmod(void);
|
||||
extern void __aeabi_lasr(void);
|
||||
extern void __aeabi_llsl(void);
|
||||
extern void __aeabi_llsr(void);
|
||||
extern void __aeabi_lmul(void);
|
||||
extern void __aeabi_uidiv(void);
|
||||
extern void __aeabi_uidivmod(void);
|
||||
extern void __aeabi_ulcmp(void);
|
||||
|
||||
extern void fpundefinstr(void);
|
||||
extern void fp_enter(void);
|
||||
|
||||
@ -141,6 +151,18 @@ EXPORT_SYMBOL(__udivsi3);
|
||||
EXPORT_SYMBOL(__umodsi3);
|
||||
EXPORT_SYMBOL(__do_div64);
|
||||
|
||||
#ifdef CONFIG_AEABI
|
||||
EXPORT_SYMBOL(__aeabi_idiv);
|
||||
EXPORT_SYMBOL(__aeabi_idivmod);
|
||||
EXPORT_SYMBOL(__aeabi_lasr);
|
||||
EXPORT_SYMBOL(__aeabi_llsl);
|
||||
EXPORT_SYMBOL(__aeabi_llsr);
|
||||
EXPORT_SYMBOL(__aeabi_lmul);
|
||||
EXPORT_SYMBOL(__aeabi_uidiv);
|
||||
EXPORT_SYMBOL(__aeabi_uidivmod);
|
||||
EXPORT_SYMBOL(__aeabi_ulcmp);
|
||||
#endif
|
||||
|
||||
/* bitops */
|
||||
EXPORT_SYMBOL(_set_bit_le);
|
||||
EXPORT_SYMBOL(_test_and_set_bit_le);
|
||||
|
@ -13,7 +13,7 @@
|
||||
#define NR_syscalls 328
|
||||
#else
|
||||
|
||||
__syscall_start:
|
||||
100:
|
||||
/* 0 */ .long sys_restart_syscall
|
||||
.long sys_exit
|
||||
.long sys_fork_wrapper
|
||||
@ -27,7 +27,7 @@ __syscall_start:
|
||||
/* 10 */ .long sys_unlink
|
||||
.long sys_execve_wrapper
|
||||
.long sys_chdir
|
||||
.long sys_time /* used by libc4 */
|
||||
.long OBSOLETE(sys_time) /* used by libc4 */
|
||||
.long sys_mknod
|
||||
/* 15 */ .long sys_chmod
|
||||
.long sys_lchown16
|
||||
@ -36,15 +36,15 @@ __syscall_start:
|
||||
.long sys_lseek
|
||||
/* 20 */ .long sys_getpid
|
||||
.long sys_mount
|
||||
.long sys_oldumount /* used by libc4 */
|
||||
.long OBSOLETE(sys_oldumount) /* used by libc4 */
|
||||
.long sys_setuid16
|
||||
.long sys_getuid16
|
||||
/* 25 */ .long sys_stime
|
||||
/* 25 */ .long OBSOLETE(sys_stime)
|
||||
.long sys_ptrace
|
||||
.long sys_alarm /* used by libc4 */
|
||||
.long OBSOLETE(sys_alarm) /* used by libc4 */
|
||||
.long sys_ni_syscall /* was sys_fstat */
|
||||
.long sys_pause
|
||||
/* 30 */ .long sys_utime /* used by libc4 */
|
||||
/* 30 */ .long OBSOLETE(sys_utime) /* used by libc4 */
|
||||
.long sys_ni_syscall /* was sys_stty */
|
||||
.long sys_ni_syscall /* was sys_getty */
|
||||
.long sys_access
|
||||
@ -90,21 +90,21 @@ __syscall_start:
|
||||
.long sys_sigpending
|
||||
.long sys_sethostname
|
||||
/* 75 */ .long sys_setrlimit
|
||||
.long sys_old_getrlimit /* used by libc4 */
|
||||
.long OBSOLETE(sys_old_getrlimit) /* used by libc4 */
|
||||
.long sys_getrusage
|
||||
.long sys_gettimeofday
|
||||
.long sys_settimeofday
|
||||
/* 80 */ .long sys_getgroups16
|
||||
.long sys_setgroups16
|
||||
.long old_select /* used by libc4 */
|
||||
.long OBSOLETE(old_select) /* used by libc4 */
|
||||
.long sys_symlink
|
||||
.long sys_ni_syscall /* was sys_lstat */
|
||||
/* 85 */ .long sys_readlink
|
||||
.long sys_uselib
|
||||
.long sys_swapon
|
||||
.long sys_reboot
|
||||
.long old_readdir /* used by libc4 */
|
||||
/* 90 */ .long old_mmap /* used by libc4 */
|
||||
.long OBSOLETE(old_readdir) /* used by libc4 */
|
||||
/* 90 */ .long OBSOLETE(old_mmap) /* used by libc4 */
|
||||
.long sys_munmap
|
||||
.long sys_truncate
|
||||
.long sys_ftruncate
|
||||
@ -116,7 +116,7 @@ __syscall_start:
|
||||
.long sys_statfs
|
||||
/* 100 */ .long sys_fstatfs
|
||||
.long sys_ni_syscall
|
||||
.long sys_socketcall
|
||||
.long OBSOLETE(sys_socketcall)
|
||||
.long sys_syslog
|
||||
.long sys_setitimer
|
||||
/* 105 */ .long sys_getitimer
|
||||
@ -127,11 +127,11 @@ __syscall_start:
|
||||
/* 110 */ .long sys_ni_syscall /* was sys_iopl */
|
||||
.long sys_vhangup
|
||||
.long sys_ni_syscall
|
||||
.long sys_syscall /* call a syscall */
|
||||
.long OBSOLETE(sys_syscall) /* call a syscall */
|
||||
.long sys_wait4
|
||||
/* 115 */ .long sys_swapoff
|
||||
.long sys_sysinfo
|
||||
.long sys_ipc
|
||||
.long OBSOLETE(ABI(sys_ipc, sys_oabi_ipc))
|
||||
.long sys_fsync
|
||||
.long sys_sigreturn_wrapper
|
||||
/* 120 */ .long sys_clone_wrapper
|
||||
@ -194,8 +194,8 @@ __syscall_start:
|
||||
.long sys_rt_sigtimedwait
|
||||
.long sys_rt_sigqueueinfo
|
||||
.long sys_rt_sigsuspend_wrapper
|
||||
/* 180 */ .long sys_pread64
|
||||
.long sys_pwrite64
|
||||
/* 180 */ .long ABI(sys_pread64, sys_oabi_pread64)
|
||||
.long ABI(sys_pwrite64, sys_oabi_pwrite64)
|
||||
.long sys_chown16
|
||||
.long sys_getcwd
|
||||
.long sys_capget
|
||||
@ -207,11 +207,11 @@ __syscall_start:
|
||||
/* 190 */ .long sys_vfork_wrapper
|
||||
.long sys_getrlimit
|
||||
.long sys_mmap2
|
||||
.long sys_truncate64
|
||||
.long sys_ftruncate64
|
||||
/* 195 */ .long sys_stat64
|
||||
.long sys_lstat64
|
||||
.long sys_fstat64
|
||||
.long ABI(sys_truncate64, sys_oabi_truncate64)
|
||||
.long ABI(sys_ftruncate64, sys_oabi_ftruncate64)
|
||||
/* 195 */ .long ABI(sys_stat64, sys_oabi_stat64)
|
||||
.long ABI(sys_lstat64, sys_oabi_lstat64)
|
||||
.long ABI(sys_fstat64, sys_oabi_fstat64)
|
||||
.long sys_lchown
|
||||
.long sys_getuid
|
||||
/* 200 */ .long sys_getgid
|
||||
@ -235,11 +235,11 @@ __syscall_start:
|
||||
.long sys_pivot_root
|
||||
.long sys_mincore
|
||||
/* 220 */ .long sys_madvise
|
||||
.long sys_fcntl64
|
||||
.long ABI(sys_fcntl64, sys_oabi_fcntl64)
|
||||
.long sys_ni_syscall /* TUX */
|
||||
.long sys_ni_syscall
|
||||
.long sys_gettid
|
||||
/* 225 */ .long sys_readahead
|
||||
/* 225 */ .long ABI(sys_readahead, sys_oabi_readahead)
|
||||
.long sys_setxattr
|
||||
.long sys_lsetxattr
|
||||
.long sys_fsetxattr
|
||||
@ -265,8 +265,8 @@ __syscall_start:
|
||||
.long sys_exit_group
|
||||
.long sys_lookup_dcookie
|
||||
/* 250 */ .long sys_epoll_create
|
||||
.long sys_epoll_ctl
|
||||
.long sys_epoll_wait
|
||||
.long ABI(sys_epoll_ctl, sys_oabi_epoll_ctl)
|
||||
.long ABI(sys_epoll_wait, sys_oabi_epoll_wait)
|
||||
.long sys_remap_file_pages
|
||||
.long sys_ni_syscall /* sys_set_thread_area */
|
||||
/* 255 */ .long sys_ni_syscall /* sys_get_thread_area */
|
||||
@ -280,8 +280,8 @@ __syscall_start:
|
||||
.long sys_clock_gettime
|
||||
.long sys_clock_getres
|
||||
/* 265 */ .long sys_clock_nanosleep
|
||||
.long sys_statfs64
|
||||
.long sys_fstatfs64
|
||||
.long sys_statfs64_wrapper
|
||||
.long sys_fstatfs64_wrapper
|
||||
.long sys_tgkill
|
||||
.long sys_utimes
|
||||
/* 270 */ .long sys_arm_fadvise64_64
|
||||
@ -312,7 +312,7 @@ __syscall_start:
|
||||
/* 295 */ .long sys_getsockopt
|
||||
.long sys_sendmsg
|
||||
.long sys_recvmsg
|
||||
.long sys_semop
|
||||
.long ABI(sys_semop, sys_oabi_semop)
|
||||
.long sys_semget
|
||||
/* 300 */ .long sys_semctl
|
||||
.long sys_msgsnd
|
||||
@ -326,7 +326,7 @@ __syscall_start:
|
||||
.long sys_add_key
|
||||
/* 310 */ .long sys_request_key
|
||||
.long sys_keyctl
|
||||
.long sys_semtimedop
|
||||
.long ABI(sys_semtimedop, sys_oabi_semtimedop)
|
||||
/* vserver */ .long sys_ni_syscall
|
||||
.long sys_ioprio_set
|
||||
/* 315 */ .long sys_ioprio_get
|
||||
@ -336,9 +336,8 @@ __syscall_start:
|
||||
.long sys_mbind
|
||||
/* 320 */ .long sys_get_mempolicy
|
||||
.long sys_set_mempolicy
|
||||
__syscall_end:
|
||||
|
||||
.rept NR_syscalls - (__syscall_end - __syscall_start) / 4
|
||||
.rept NR_syscalls - (. - 100b) / 4
|
||||
.long sys_ni_syscall
|
||||
.endr
|
||||
#endif
|
||||
|
@ -1147,9 +1147,11 @@ static void ecard_drv_shutdown(struct device *dev)
|
||||
struct ecard_driver *drv = ECARD_DRV(dev->driver);
|
||||
struct ecard_request req;
|
||||
|
||||
if (drv->shutdown)
|
||||
drv->shutdown(ec);
|
||||
ecard_release(ec);
|
||||
if (dev->driver) {
|
||||
if (drv->shutdown)
|
||||
drv->shutdown(ec);
|
||||
ecard_release(ec);
|
||||
}
|
||||
|
||||
/*
|
||||
* If this card has a loader, call the reset handler.
|
||||
@ -1164,9 +1166,6 @@ static void ecard_drv_shutdown(struct device *dev)
|
||||
int ecard_register_driver(struct ecard_driver *drv)
|
||||
{
|
||||
drv->drv.bus = &ecard_bus_type;
|
||||
drv->drv.probe = ecard_drv_probe;
|
||||
drv->drv.remove = ecard_drv_remove;
|
||||
drv->drv.shutdown = ecard_drv_shutdown;
|
||||
|
||||
return driver_register(&drv->drv);
|
||||
}
|
||||
@ -1195,6 +1194,9 @@ struct bus_type ecard_bus_type = {
|
||||
.name = "ecard",
|
||||
.dev_attrs = ecard_dev_attrs,
|
||||
.match = ecard_match,
|
||||
.probe = ecard_drv_probe,
|
||||
.remove = ecard_drv_remove,
|
||||
.shutdown = ecard_drv_shutdown,
|
||||
};
|
||||
|
||||
static int ecard_bus_init(void)
|
||||
|
@ -3,6 +3,7 @@
|
||||
*
|
||||
* Copyright (C) 1996,1997,1998 Russell King.
|
||||
* ARM700 fix by Matthew Godbolt (linux-user@willothewisp.demon.co.uk)
|
||||
* nommu support by Hyok S. Choi (hyok.choi@samsung.com)
|
||||
*
|
||||
* 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
|
||||
@ -104,14 +105,24 @@ common_invalid:
|
||||
/*
|
||||
* SVC mode handlers
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_AEABI) && (__LINUX_ARM_ARCH__ >= 5)
|
||||
#define SPFIX(code...) code
|
||||
#else
|
||||
#define SPFIX(code...)
|
||||
#endif
|
||||
|
||||
.macro svc_entry
|
||||
sub sp, sp, #S_FRAME_SIZE
|
||||
SPFIX( tst sp, #4 )
|
||||
SPFIX( bicne sp, sp, #4 )
|
||||
stmib sp, {r1 - r12}
|
||||
|
||||
ldmia r0, {r1 - r3}
|
||||
add r5, sp, #S_SP @ here for interlock avoidance
|
||||
mov r4, #-1 @ "" "" "" ""
|
||||
add r0, sp, #S_FRAME_SIZE @ "" "" "" ""
|
||||
SPFIX( addne r0, r0, #4 )
|
||||
str r1, [sp] @ save the "real" r0 copied
|
||||
@ from the exception stack
|
||||
|
||||
@ -302,7 +313,14 @@ __pabt_svc:
|
||||
|
||||
/*
|
||||
* User mode handlers
|
||||
*
|
||||
* EABI note: sp_svc is always 64-bit aligned here, so should S_FRAME_SIZE
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_AEABI) && (__LINUX_ARM_ARCH__ >= 5) && (S_FRAME_SIZE & 7)
|
||||
#error "sizeof(struct pt_regs) must be a multiple of 8"
|
||||
#endif
|
||||
|
||||
.macro usr_entry
|
||||
sub sp, sp, #S_FRAME_SIZE
|
||||
stmib sp, {r1 - r12}
|
||||
@ -538,7 +556,11 @@ ENTRY(__switch_to)
|
||||
add ip, r1, #TI_CPU_SAVE
|
||||
ldr r3, [r2, #TI_TP_VALUE]
|
||||
stmia ip!, {r4 - sl, fp, sp, lr} @ Store most regs on stack
|
||||
#ifndef CONFIG_MMU
|
||||
add r2, r2, #TI_CPU_DOMAIN
|
||||
#else
|
||||
ldr r6, [r2, #TI_CPU_DOMAIN]!
|
||||
#endif
|
||||
#if __LINUX_ARM_ARCH__ >= 6
|
||||
#ifdef CONFIG_CPU_MPCORE
|
||||
clrex
|
||||
@ -556,7 +578,9 @@ ENTRY(__switch_to)
|
||||
mov r4, #0xffff0fff
|
||||
str r3, [r4, #-15] @ TLS val at 0xffff0ff0
|
||||
#endif
|
||||
#ifdef CONFIG_MMU
|
||||
mcr p15, 0, r6, c3, c0, 0 @ Set domain register
|
||||
#endif
|
||||
#ifdef CONFIG_VFP
|
||||
@ Always disable VFP so we can lazily save/restore the old
|
||||
@ state. This occurs in the context of the previous thread.
|
||||
|
@ -98,20 +98,14 @@ ENTRY(ret_from_fork)
|
||||
run on an ARM7 and we can save a couple of instructions.
|
||||
--pb */
|
||||
#ifdef CONFIG_CPU_ARM710
|
||||
.macro arm710_bug_check, instr, temp
|
||||
and \temp, \instr, #0x0f000000 @ check for SWI
|
||||
teq \temp, #0x0f000000
|
||||
bne .Larm700bug
|
||||
.endm
|
||||
|
||||
.Larm700bug:
|
||||
#define A710(code...) code
|
||||
.Larm710bug:
|
||||
ldmia sp, {r0 - lr}^ @ Get calling r0 - lr
|
||||
mov r0, r0
|
||||
add sp, sp, #S_FRAME_SIZE
|
||||
subs pc, lr, #4
|
||||
#else
|
||||
.macro arm710_bug_check, instr, temp
|
||||
.endm
|
||||
#define A710(code...)
|
||||
#endif
|
||||
|
||||
.align 5
|
||||
@ -129,14 +123,50 @@ ENTRY(vector_swi)
|
||||
/*
|
||||
* Get the system call number.
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_OABI_COMPAT)
|
||||
|
||||
/*
|
||||
* If we have CONFIG_OABI_COMPAT then we need to look at the swi
|
||||
* value to determine if it is an EABI or an old ABI call.
|
||||
*/
|
||||
#ifdef CONFIG_ARM_THUMB
|
||||
tst r8, #PSR_T_BIT
|
||||
movne r10, #0 @ no thumb OABI emulation
|
||||
ldreq r10, [lr, #-4] @ get SWI instruction
|
||||
#else
|
||||
ldr r10, [lr, #-4] @ get SWI instruction
|
||||
A710( and ip, r10, #0x0f000000 @ check for SWI )
|
||||
A710( teq ip, #0x0f000000 )
|
||||
A710( bne .Larm710bug )
|
||||
#endif
|
||||
|
||||
#elif defined(CONFIG_AEABI)
|
||||
|
||||
/*
|
||||
* Pure EABI user space always put syscall number into scno (r7).
|
||||
*/
|
||||
A710( ldr ip, [lr, #-4] @ get SWI instruction )
|
||||
A710( and ip, ip, #0x0f000000 @ check for SWI )
|
||||
A710( teq ip, #0x0f000000 )
|
||||
A710( bne .Larm710bug )
|
||||
|
||||
#elif defined(CONFIG_ARM_THUMB)
|
||||
|
||||
/* Legacy ABI only, possibly thumb mode. */
|
||||
tst r8, #PSR_T_BIT @ this is SPSR from save_user_regs
|
||||
addne scno, r7, #__NR_SYSCALL_BASE @ put OS number in
|
||||
ldreq scno, [lr, #-4]
|
||||
|
||||
#else
|
||||
|
||||
/* Legacy ABI only. */
|
||||
ldr scno, [lr, #-4] @ get SWI instruction
|
||||
A710( and ip, scno, #0x0f000000 @ check for SWI )
|
||||
A710( teq ip, #0x0f000000 )
|
||||
A710( bne .Larm710bug )
|
||||
|
||||
#endif
|
||||
arm710_bug_check scno, ip
|
||||
|
||||
#ifdef CONFIG_ALIGNMENT_TRAP
|
||||
ldr ip, __cr_alignment
|
||||
@ -145,18 +175,31 @@ ENTRY(vector_swi)
|
||||
#endif
|
||||
enable_irq
|
||||
|
||||
stmdb sp!, {r4, r5} @ push fifth and sixth args
|
||||
|
||||
get_thread_info tsk
|
||||
adr tbl, sys_call_table @ load syscall table pointer
|
||||
ldr ip, [tsk, #TI_FLAGS] @ check for syscall tracing
|
||||
|
||||
#if defined(CONFIG_OABI_COMPAT)
|
||||
/*
|
||||
* If the swi argument is zero, this is an EABI call and we do nothing.
|
||||
*
|
||||
* If this is an old ABI call, get the syscall number into scno and
|
||||
* get the old ABI syscall table address.
|
||||
*/
|
||||
bics r10, r10, #0xff000000
|
||||
eorne scno, r10, #__NR_OABI_SYSCALL_BASE
|
||||
ldrne tbl, =sys_oabi_call_table
|
||||
#elif !defined(CONFIG_AEABI)
|
||||
bic scno, scno, #0xff000000 @ mask off SWI op-code
|
||||
eor scno, scno, #__NR_SYSCALL_BASE @ check OS number
|
||||
adr tbl, sys_call_table @ load syscall table pointer
|
||||
#endif
|
||||
|
||||
stmdb sp!, {r4, r5} @ push fifth and sixth args
|
||||
tst ip, #_TIF_SYSCALL_TRACE @ are we tracing syscalls?
|
||||
bne __sys_trace
|
||||
|
||||
adr lr, ret_fast_syscall @ return address
|
||||
cmp scno, #NR_syscalls @ check upper syscall limit
|
||||
adr lr, ret_fast_syscall @ return address
|
||||
ldrcc pc, [tbl, scno, lsl #2] @ call sys_* routine
|
||||
|
||||
add r1, sp, #S_OFF
|
||||
@ -171,11 +214,13 @@ ENTRY(vector_swi)
|
||||
* context switches, and waiting for our parent to respond.
|
||||
*/
|
||||
__sys_trace:
|
||||
mov r2, scno
|
||||
add r1, sp, #S_OFF
|
||||
mov r0, #0 @ trace entry [IP = 0]
|
||||
bl syscall_trace
|
||||
|
||||
adr lr, __sys_trace_return @ return address
|
||||
mov scno, r0 @ syscall number (possibly new)
|
||||
add r1, sp, #S_R0 + S_OFF @ pointer to regs
|
||||
cmp scno, #NR_syscalls @ check upper syscall limit
|
||||
ldmccia r1, {r0 - r3} @ have to reload r0 - r3
|
||||
@ -184,6 +229,7 @@ __sys_trace:
|
||||
|
||||
__sys_trace_return:
|
||||
str r0, [sp, #S_R0 + S_OFF]! @ save returned r0
|
||||
mov r2, scno
|
||||
mov r1, sp
|
||||
mov r0, #1 @ trace exit [IP = 1]
|
||||
bl syscall_trace
|
||||
@ -194,11 +240,25 @@ __sys_trace_return:
|
||||
.type __cr_alignment, #object
|
||||
__cr_alignment:
|
||||
.word cr_alignment
|
||||
#endif
|
||||
.ltorg
|
||||
|
||||
/*
|
||||
* This is the syscall table declaration for native ABI syscalls.
|
||||
* With EABI a couple syscalls are obsolete and defined as sys_ni_syscall.
|
||||
*/
|
||||
#define ABI(native, compat) native
|
||||
#ifdef CONFIG_AEABI
|
||||
#define OBSOLETE(syscall) sys_ni_syscall
|
||||
#else
|
||||
#define OBSOLETE(syscall) syscall
|
||||
#endif
|
||||
|
||||
.type sys_call_table, #object
|
||||
ENTRY(sys_call_table)
|
||||
#include "calls.S"
|
||||
#undef ABI
|
||||
#undef OBSOLETE
|
||||
|
||||
/*============================================================================
|
||||
* Special system call wrappers
|
||||
@ -207,7 +267,7 @@ ENTRY(sys_call_table)
|
||||
@ r8 = syscall table
|
||||
.type sys_syscall, #function
|
||||
sys_syscall:
|
||||
eor scno, r0, #__NR_SYSCALL_BASE
|
||||
eor scno, r0, #__NR_OABI_SYSCALL_BASE
|
||||
cmp scno, #__NR_syscall - __NR_SYSCALL_BASE
|
||||
cmpne scno, #NR_syscalls @ check range
|
||||
stmloia sp, {r5, r6} @ shuffle args
|
||||
@ -255,6 +315,16 @@ sys_sigaltstack_wrapper:
|
||||
ldr r2, [sp, #S_OFF + S_SP]
|
||||
b do_sigaltstack
|
||||
|
||||
sys_statfs64_wrapper:
|
||||
teq r1, #88
|
||||
moveq r1, #84
|
||||
b sys_statfs64
|
||||
|
||||
sys_fstatfs64_wrapper:
|
||||
teq r1, #88
|
||||
moveq r1, #84
|
||||
b sys_fstatfs64
|
||||
|
||||
/*
|
||||
* Note: off_4k (r5) is always units of 4K. If we can't do the requested
|
||||
* offset, we return EINVAL.
|
||||
@ -271,3 +341,49 @@ sys_mmap2:
|
||||
str r5, [sp, #4]
|
||||
b do_mmap2
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_OABI_COMPAT
|
||||
|
||||
/*
|
||||
* These are syscalls with argument register differences
|
||||
*/
|
||||
|
||||
sys_oabi_pread64:
|
||||
stmia sp, {r3, r4}
|
||||
b sys_pread64
|
||||
|
||||
sys_oabi_pwrite64:
|
||||
stmia sp, {r3, r4}
|
||||
b sys_pwrite64
|
||||
|
||||
sys_oabi_truncate64:
|
||||
mov r3, r2
|
||||
mov r2, r1
|
||||
b sys_truncate64
|
||||
|
||||
sys_oabi_ftruncate64:
|
||||
mov r3, r2
|
||||
mov r2, r1
|
||||
b sys_ftruncate64
|
||||
|
||||
sys_oabi_readahead:
|
||||
str r3, [sp]
|
||||
mov r3, r2
|
||||
mov r2, r1
|
||||
b sys_readahead
|
||||
|
||||
/*
|
||||
* Let's declare a second syscall table for old ABI binaries
|
||||
* using the compatibility syscall entries.
|
||||
*/
|
||||
#define ABI(native, compat) compat
|
||||
#define OBSOLETE(syscall) syscall
|
||||
|
||||
.type sys_oabi_call_table, #object
|
||||
ENTRY(sys_oabi_call_table)
|
||||
#include "calls.S"
|
||||
#undef ABI
|
||||
#undef OBSOLETE
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -19,6 +19,7 @@
|
||||
@
|
||||
@ Most of the stack format comes from struct pt_regs, but with
|
||||
@ the addition of 8 bytes for storing syscall args 5 and 6.
|
||||
@ This _must_ remain a multiple of 8 for EABI.
|
||||
@
|
||||
#define S_OFF 8
|
||||
|
||||
|
@ -251,12 +251,11 @@ __turn_mmu_on:
|
||||
* r10 = procinfo
|
||||
*
|
||||
* Returns:
|
||||
* r0, r3, r5, r6, r7 corrupted
|
||||
* r0, r3, r6, r7 corrupted
|
||||
* r4 = physical page table address
|
||||
*/
|
||||
.type __create_page_tables, %function
|
||||
__create_page_tables:
|
||||
ldr r5, [r8, #MACHINFO_PHYSRAM] @ physram
|
||||
pgtbl r4 @ page table address
|
||||
|
||||
/*
|
||||
@ -303,7 +302,7 @@ __create_page_tables:
|
||||
* Then map first 1MB of ram in case it contains our boot params.
|
||||
*/
|
||||
add r0, r4, #PAGE_OFFSET >> 18
|
||||
orr r6, r5, r7
|
||||
orr r6, r7, #PHYS_OFFSET
|
||||
str r6, [r0]
|
||||
|
||||
#ifdef CONFIG_XIP_KERNEL
|
||||
@ -311,7 +310,7 @@ __create_page_tables:
|
||||
* Map some ram to cover our .data and .bss areas.
|
||||
* Mapping 3MB should be plenty.
|
||||
*/
|
||||
sub r3, r4, r5
|
||||
sub r3, r4, #PHYS_OFFSET
|
||||
mov r3, r3, lsr #20
|
||||
add r0, r0, r3, lsl #2
|
||||
add r6, r6, r3, lsl #20
|
||||
|
@ -766,6 +766,11 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
|
||||
(unsigned long __user *) data);
|
||||
break;
|
||||
|
||||
case PTRACE_SET_SYSCALL:
|
||||
ret = 0;
|
||||
child->ptrace_message = data;
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = ptrace_request(child, request, addr, data);
|
||||
break;
|
||||
@ -774,14 +779,14 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
|
||||
return ret;
|
||||
}
|
||||
|
||||
asmlinkage void syscall_trace(int why, struct pt_regs *regs)
|
||||
asmlinkage int syscall_trace(int why, struct pt_regs *regs, int scno)
|
||||
{
|
||||
unsigned long ip;
|
||||
|
||||
if (!test_thread_flag(TIF_SYSCALL_TRACE))
|
||||
return;
|
||||
return scno;
|
||||
if (!(current->ptrace & PT_PTRACED))
|
||||
return;
|
||||
return scno;
|
||||
|
||||
/*
|
||||
* Save IP. IP is used to denote syscall entry/exit:
|
||||
@ -790,6 +795,8 @@ asmlinkage void syscall_trace(int why, struct pt_regs *regs)
|
||||
ip = regs->ARM_ip;
|
||||
regs->ARM_ip = why;
|
||||
|
||||
current->ptrace_message = scno;
|
||||
|
||||
/* the 0x80 provides a way for the tracing parent to distinguish
|
||||
between a syscall stop and SIGTRAP delivery */
|
||||
ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
|
||||
@ -804,4 +811,6 @@ asmlinkage void syscall_trace(int why, struct pt_regs *regs)
|
||||
current->exit_code = 0;
|
||||
}
|
||||
regs->ARM_ip = ip;
|
||||
|
||||
return current->ptrace_message;
|
||||
}
|
||||
|
@ -177,41 +177,42 @@ int __down_trylock(struct semaphore * sem)
|
||||
* ip contains the semaphore pointer on entry. Save the C-clobbered
|
||||
* registers (r0 to r3 and lr), but not ip, as we use it as a return
|
||||
* value in some cases..
|
||||
* To remain AAPCS compliant (64-bit stack align) we save r4 as well.
|
||||
*/
|
||||
asm(" .section .sched.text,\"ax\",%progbits \n\
|
||||
.align 5 \n\
|
||||
.globl __down_failed \n\
|
||||
__down_failed: \n\
|
||||
stmfd sp!, {r0 - r3, lr} \n\
|
||||
stmfd sp!, {r0 - r4, lr} \n\
|
||||
mov r0, ip \n\
|
||||
bl __down \n\
|
||||
ldmfd sp!, {r0 - r3, pc} \n\
|
||||
ldmfd sp!, {r0 - r4, pc} \n\
|
||||
\n\
|
||||
.align 5 \n\
|
||||
.globl __down_interruptible_failed \n\
|
||||
__down_interruptible_failed: \n\
|
||||
stmfd sp!, {r0 - r3, lr} \n\
|
||||
stmfd sp!, {r0 - r4, lr} \n\
|
||||
mov r0, ip \n\
|
||||
bl __down_interruptible \n\
|
||||
mov ip, r0 \n\
|
||||
ldmfd sp!, {r0 - r3, pc} \n\
|
||||
ldmfd sp!, {r0 - r4, pc} \n\
|
||||
\n\
|
||||
.align 5 \n\
|
||||
.globl __down_trylock_failed \n\
|
||||
__down_trylock_failed: \n\
|
||||
stmfd sp!, {r0 - r3, lr} \n\
|
||||
stmfd sp!, {r0 - r4, lr} \n\
|
||||
mov r0, ip \n\
|
||||
bl __down_trylock \n\
|
||||
mov ip, r0 \n\
|
||||
ldmfd sp!, {r0 - r3, pc} \n\
|
||||
ldmfd sp!, {r0 - r4, pc} \n\
|
||||
\n\
|
||||
.align 5 \n\
|
||||
.globl __up_wakeup \n\
|
||||
__up_wakeup: \n\
|
||||
stmfd sp!, {r0 - r3, lr} \n\
|
||||
stmfd sp!, {r0 - r4, lr} \n\
|
||||
mov r0, ip \n\
|
||||
bl __up \n\
|
||||
ldmfd sp!, {r0 - r3, pc} \n\
|
||||
ldmfd sp!, {r0 - r4, pc} \n\
|
||||
");
|
||||
|
||||
EXPORT_SYMBOL(__down_failed);
|
||||
|
@ -147,6 +147,7 @@ asmlinkage int old_select(struct sel_arg_struct __user *arg)
|
||||
return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp);
|
||||
}
|
||||
|
||||
#if !defined(CONFIG_AEABI) || defined(CONFIG_OABI_COMPAT)
|
||||
/*
|
||||
* sys_ipc() is the de-multiplexer for the SysV IPC calls..
|
||||
*
|
||||
@ -226,6 +227,7 @@ asmlinkage int sys_ipc(uint call, int first, int second, int third,
|
||||
return -ENOSYS;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Fork a new task - this creates a new program thread.
|
||||
* This is called indirectly via a small wrapper
|
||||
|
339
arch/arm/kernel/sys_oabi-compat.c
Normal file
339
arch/arm/kernel/sys_oabi-compat.c
Normal file
@ -0,0 +1,339 @@
|
||||
/*
|
||||
* arch/arm/kernel/sys_oabi-compat.c
|
||||
*
|
||||
* Compatibility wrappers for syscalls that are used from
|
||||
* old ABI user space binaries with an EABI kernel.
|
||||
*
|
||||
* Author: Nicolas Pitre
|
||||
* Created: Oct 7, 2005
|
||||
* Copyright: MontaVista Software, Inc.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The legacy ABI and the new ARM EABI have different rules making some
|
||||
* syscalls incompatible especially with structure arguments.
|
||||
* Most notably, Eabi says 64-bit members should be 64-bit aligned instead of
|
||||
* simply word aligned. EABI also pads structures to the size of the largest
|
||||
* member it contains instead of the invariant 32-bit.
|
||||
*
|
||||
* The following syscalls are affected:
|
||||
*
|
||||
* sys_stat64:
|
||||
* sys_lstat64:
|
||||
* sys_fstat64:
|
||||
*
|
||||
* struct stat64 has different sizes and some members are shifted
|
||||
* Compatibility wrappers are needed for them and provided below.
|
||||
*
|
||||
* sys_fcntl64:
|
||||
*
|
||||
* struct flock64 has different sizes and some members are shifted
|
||||
* A compatibility wrapper is needed and provided below.
|
||||
*
|
||||
* sys_statfs64:
|
||||
* sys_fstatfs64:
|
||||
*
|
||||
* struct statfs64 has extra padding with EABI growing its size from
|
||||
* 84 to 88. This struct is now __attribute__((packed,aligned(4)))
|
||||
* with a small assembly wrapper to force the sz argument to 84 if it is 88
|
||||
* to avoid copying the extra padding over user space unexpecting it.
|
||||
*
|
||||
* sys_newuname:
|
||||
*
|
||||
* struct new_utsname has no padding with EABI. No problem there.
|
||||
*
|
||||
* sys_epoll_ctl:
|
||||
* sys_epoll_wait:
|
||||
*
|
||||
* struct epoll_event has its second member shifted also affecting the
|
||||
* structure size. Compatibility wrappers are needed and provided below.
|
||||
*
|
||||
* sys_ipc:
|
||||
* sys_semop:
|
||||
* sys_semtimedop:
|
||||
*
|
||||
* struct sembuf loses its padding with EABI. Since arrays of them are
|
||||
* used they have to be copyed to remove the padding. Compatibility wrappers
|
||||
* provided below.
|
||||
*/
|
||||
|
||||
#include <linux/syscalls.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/fcntl.h>
|
||||
#include <linux/eventpoll.h>
|
||||
#include <linux/sem.h>
|
||||
#include <asm/ipc.h>
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
struct oldabi_stat64 {
|
||||
unsigned long long st_dev;
|
||||
unsigned int __pad1;
|
||||
unsigned long __st_ino;
|
||||
unsigned int st_mode;
|
||||
unsigned int st_nlink;
|
||||
|
||||
unsigned long st_uid;
|
||||
unsigned long st_gid;
|
||||
|
||||
unsigned long long st_rdev;
|
||||
unsigned int __pad2;
|
||||
|
||||
long long st_size;
|
||||
unsigned long st_blksize;
|
||||
unsigned long long st_blocks;
|
||||
|
||||
unsigned long st_atime;
|
||||
unsigned long st_atime_nsec;
|
||||
|
||||
unsigned long st_mtime;
|
||||
unsigned long st_mtime_nsec;
|
||||
|
||||
unsigned long st_ctime;
|
||||
unsigned long st_ctime_nsec;
|
||||
|
||||
unsigned long long st_ino;
|
||||
} __attribute__ ((packed,aligned(4)));
|
||||
|
||||
static long cp_oldabi_stat64(struct kstat *stat,
|
||||
struct oldabi_stat64 __user *statbuf)
|
||||
{
|
||||
struct oldabi_stat64 tmp;
|
||||
|
||||
tmp.st_dev = huge_encode_dev(stat->dev);
|
||||
tmp.__pad1 = 0;
|
||||
tmp.__st_ino = stat->ino;
|
||||
tmp.st_mode = stat->mode;
|
||||
tmp.st_nlink = stat->nlink;
|
||||
tmp.st_uid = stat->uid;
|
||||
tmp.st_gid = stat->gid;
|
||||
tmp.st_rdev = huge_encode_dev(stat->rdev);
|
||||
tmp.st_size = stat->size;
|
||||
tmp.st_blocks = stat->blocks;
|
||||
tmp.__pad2 = 0;
|
||||
tmp.st_blksize = stat->blksize;
|
||||
tmp.st_atime = stat->atime.tv_sec;
|
||||
tmp.st_atime_nsec = stat->atime.tv_nsec;
|
||||
tmp.st_mtime = stat->mtime.tv_sec;
|
||||
tmp.st_mtime_nsec = stat->mtime.tv_nsec;
|
||||
tmp.st_ctime = stat->ctime.tv_sec;
|
||||
tmp.st_ctime_nsec = stat->ctime.tv_nsec;
|
||||
tmp.st_ino = stat->ino;
|
||||
return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
|
||||
}
|
||||
|
||||
asmlinkage long sys_oabi_stat64(char __user * filename,
|
||||
struct oldabi_stat64 __user * statbuf)
|
||||
{
|
||||
struct kstat stat;
|
||||
int error = vfs_stat(filename, &stat);
|
||||
if (!error)
|
||||
error = cp_oldabi_stat64(&stat, statbuf);
|
||||
return error;
|
||||
}
|
||||
|
||||
asmlinkage long sys_oabi_lstat64(char __user * filename,
|
||||
struct oldabi_stat64 __user * statbuf)
|
||||
{
|
||||
struct kstat stat;
|
||||
int error = vfs_lstat(filename, &stat);
|
||||
if (!error)
|
||||
error = cp_oldabi_stat64(&stat, statbuf);
|
||||
return error;
|
||||
}
|
||||
|
||||
asmlinkage long sys_oabi_fstat64(unsigned long fd,
|
||||
struct oldabi_stat64 __user * statbuf)
|
||||
{
|
||||
struct kstat stat;
|
||||
int error = vfs_fstat(fd, &stat);
|
||||
if (!error)
|
||||
error = cp_oldabi_stat64(&stat, statbuf);
|
||||
return error;
|
||||
}
|
||||
|
||||
struct oabi_flock64 {
|
||||
short l_type;
|
||||
short l_whence;
|
||||
loff_t l_start;
|
||||
loff_t l_len;
|
||||
pid_t l_pid;
|
||||
} __attribute__ ((packed,aligned(4)));
|
||||
|
||||
asmlinkage long sys_oabi_fcntl64(unsigned int fd, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
struct oabi_flock64 user;
|
||||
struct flock64 kernel;
|
||||
mm_segment_t fs = USER_DS; /* initialized to kill a warning */
|
||||
unsigned long local_arg = arg;
|
||||
int ret;
|
||||
|
||||
switch (cmd) {
|
||||
case F_GETLK64:
|
||||
case F_SETLK64:
|
||||
case F_SETLKW64:
|
||||
if (copy_from_user(&user, (struct oabi_flock64 __user *)arg,
|
||||
sizeof(user)))
|
||||
return -EFAULT;
|
||||
kernel.l_type = user.l_type;
|
||||
kernel.l_whence = user.l_whence;
|
||||
kernel.l_start = user.l_start;
|
||||
kernel.l_len = user.l_len;
|
||||
kernel.l_pid = user.l_pid;
|
||||
local_arg = (unsigned long)&kernel;
|
||||
fs = get_fs();
|
||||
set_fs(KERNEL_DS);
|
||||
}
|
||||
|
||||
ret = sys_fcntl64(fd, cmd, local_arg);
|
||||
|
||||
switch (cmd) {
|
||||
case F_GETLK64:
|
||||
if (!ret) {
|
||||
user.l_type = kernel.l_type;
|
||||
user.l_whence = kernel.l_whence;
|
||||
user.l_start = kernel.l_start;
|
||||
user.l_len = kernel.l_len;
|
||||
user.l_pid = kernel.l_pid;
|
||||
if (copy_to_user((struct oabi_flock64 __user *)arg,
|
||||
&user, sizeof(user)))
|
||||
ret = -EFAULT;
|
||||
}
|
||||
case F_SETLK64:
|
||||
case F_SETLKW64:
|
||||
set_fs(fs);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct oabi_epoll_event {
|
||||
__u32 events;
|
||||
__u64 data;
|
||||
} __attribute__ ((packed,aligned(4)));
|
||||
|
||||
asmlinkage long sys_oabi_epoll_ctl(int epfd, int op, int fd,
|
||||
struct oabi_epoll_event __user *event)
|
||||
{
|
||||
struct oabi_epoll_event user;
|
||||
struct epoll_event kernel;
|
||||
mm_segment_t fs;
|
||||
long ret;
|
||||
|
||||
if (op == EPOLL_CTL_DEL)
|
||||
return sys_epoll_ctl(epfd, op, fd, NULL);
|
||||
if (copy_from_user(&user, event, sizeof(user)))
|
||||
return -EFAULT;
|
||||
kernel.events = user.events;
|
||||
kernel.data = user.data;
|
||||
fs = get_fs();
|
||||
set_fs(KERNEL_DS);
|
||||
ret = sys_epoll_ctl(epfd, op, fd, &kernel);
|
||||
set_fs(fs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
asmlinkage long sys_oabi_epoll_wait(int epfd,
|
||||
struct oabi_epoll_event __user *events,
|
||||
int maxevents, int timeout)
|
||||
{
|
||||
struct epoll_event *kbuf;
|
||||
mm_segment_t fs;
|
||||
long ret, err, i;
|
||||
|
||||
if (maxevents <= 0 || maxevents > (INT_MAX/sizeof(struct epoll_event)))
|
||||
return -EINVAL;
|
||||
kbuf = kmalloc(sizeof(*kbuf) * maxevents, GFP_KERNEL);
|
||||
if (!kbuf)
|
||||
return -ENOMEM;
|
||||
fs = get_fs();
|
||||
set_fs(KERNEL_DS);
|
||||
ret = sys_epoll_wait(epfd, kbuf, maxevents, timeout);
|
||||
set_fs(fs);
|
||||
err = 0;
|
||||
for (i = 0; i < ret; i++) {
|
||||
__put_user_error(kbuf[i].events, &events->events, err);
|
||||
__put_user_error(kbuf[i].data, &events->data, err);
|
||||
events++;
|
||||
}
|
||||
kfree(kbuf);
|
||||
return err ? -EFAULT : ret;
|
||||
}
|
||||
|
||||
struct oabi_sembuf {
|
||||
unsigned short sem_num;
|
||||
short sem_op;
|
||||
short sem_flg;
|
||||
unsigned short __pad;
|
||||
};
|
||||
|
||||
asmlinkage long sys_oabi_semtimedop(int semid,
|
||||
struct oabi_sembuf __user *tsops,
|
||||
unsigned nsops,
|
||||
const struct timespec __user *timeout)
|
||||
{
|
||||
struct sembuf *sops;
|
||||
struct timespec local_timeout;
|
||||
long err;
|
||||
int i;
|
||||
|
||||
if (nsops < 1)
|
||||
return -EINVAL;
|
||||
sops = kmalloc(sizeof(*sops) * nsops, GFP_KERNEL);
|
||||
if (!sops)
|
||||
return -ENOMEM;
|
||||
err = 0;
|
||||
for (i = 0; i < nsops; i++) {
|
||||
__get_user_error(sops[i].sem_num, &tsops->sem_num, err);
|
||||
__get_user_error(sops[i].sem_op, &tsops->sem_op, err);
|
||||
__get_user_error(sops[i].sem_flg, &tsops->sem_flg, err);
|
||||
tsops++;
|
||||
}
|
||||
if (timeout) {
|
||||
/* copy this as well before changing domain protection */
|
||||
err |= copy_from_user(&local_timeout, timeout, sizeof(*timeout));
|
||||
timeout = &local_timeout;
|
||||
}
|
||||
if (err) {
|
||||
err = -EFAULT;
|
||||
} else {
|
||||
mm_segment_t fs = get_fs();
|
||||
set_fs(KERNEL_DS);
|
||||
err = sys_semtimedop(semid, sops, nsops, timeout);
|
||||
set_fs(fs);
|
||||
}
|
||||
kfree(sops);
|
||||
return err;
|
||||
}
|
||||
|
||||
asmlinkage long sys_oabi_semop(int semid, struct oabi_sembuf __user *tsops,
|
||||
unsigned nsops)
|
||||
{
|
||||
return sys_oabi_semtimedop(semid, tsops, nsops, NULL);
|
||||
}
|
||||
|
||||
extern asmlinkage int sys_ipc(uint call, int first, int second, int third,
|
||||
void __user *ptr, long fifth);
|
||||
|
||||
asmlinkage int sys_oabi_ipc(uint call, int first, int second, int third,
|
||||
void __user *ptr, long fifth)
|
||||
{
|
||||
switch (call & 0xffff) {
|
||||
case SEMOP:
|
||||
return sys_oabi_semtimedop(first,
|
||||
(struct oabi_sembuf __user *)ptr,
|
||||
second, NULL);
|
||||
case SEMTIMEDOP:
|
||||
return sys_oabi_semtimedop(first,
|
||||
(struct oabi_sembuf __user *)ptr,
|
||||
second,
|
||||
(const struct timespec __user *)fifth);
|
||||
default:
|
||||
return sys_ipc(call, first, second, third, ptr, fifth);
|
||||
}
|
||||
}
|
@ -404,7 +404,7 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs)
|
||||
struct thread_info *thread = current_thread_info();
|
||||
siginfo_t info;
|
||||
|
||||
if ((no >> 16) != 0x9f)
|
||||
if ((no >> 16) != (__ARM_NR_BASE>> 16))
|
||||
return bad_syscall(no, regs);
|
||||
|
||||
switch (no & 0xffff) {
|
||||
|
@ -37,6 +37,7 @@ Boston, MA 02110-1301, USA. */
|
||||
#endif
|
||||
|
||||
ENTRY(__ashldi3)
|
||||
ENTRY(__aeabi_llsl)
|
||||
|
||||
subs r3, r2, #32
|
||||
rsb ip, r2, #32
|
||||
|
@ -37,6 +37,7 @@ Boston, MA 02110-1301, USA. */
|
||||
#endif
|
||||
|
||||
ENTRY(__ashrdi3)
|
||||
ENTRY(__aeabi_lasr)
|
||||
|
||||
subs r3, r2, #32
|
||||
rsb ip, r2, #32
|
||||
|
@ -206,6 +206,7 @@ Boston, MA 02111-1307, USA. */
|
||||
|
||||
|
||||
ENTRY(__udivsi3)
|
||||
ENTRY(__aeabi_uidiv)
|
||||
|
||||
subs r2, r1, #1
|
||||
moveq pc, lr
|
||||
@ -246,6 +247,7 @@ ENTRY(__umodsi3)
|
||||
|
||||
|
||||
ENTRY(__divsi3)
|
||||
ENTRY(__aeabi_idiv)
|
||||
|
||||
cmp r1, #0
|
||||
eor ip, r0, r1 @ save the sign of the result.
|
||||
@ -303,12 +305,33 @@ ENTRY(__modsi3)
|
||||
rsbmi r0, r0, #0
|
||||
mov pc, lr
|
||||
|
||||
#ifdef CONFIG_AEABI
|
||||
|
||||
ENTRY(__aeabi_uidivmod)
|
||||
|
||||
stmfd sp!, {r0, r1, ip, lr}
|
||||
bl __aeabi_uidiv
|
||||
ldmfd sp!, {r1, r2, ip, lr}
|
||||
mul r3, r0, r2
|
||||
sub r1, r1, r3
|
||||
mov pc, lr
|
||||
|
||||
ENTRY(__aeabi_idivmod)
|
||||
|
||||
stmfd sp!, {r0, r1, ip, lr}
|
||||
bl __aeabi_idiv
|
||||
ldmfd sp!, {r1, r2, ip, lr}
|
||||
mul r3, r0, r2
|
||||
sub r1, r1, r3
|
||||
mov pc, lr
|
||||
|
||||
#endif
|
||||
|
||||
Ldiv0:
|
||||
|
||||
str lr, [sp, #-4]!
|
||||
str lr, [sp, #-8]!
|
||||
bl __div0
|
||||
mov r0, #0 @ About as wrong as it could be.
|
||||
ldr pc, [sp], #4
|
||||
ldr pc, [sp], #8
|
||||
|
||||
|
||||
|
@ -37,6 +37,7 @@ Boston, MA 02110-1301, USA. */
|
||||
#endif
|
||||
|
||||
ENTRY(__lshrdi3)
|
||||
ENTRY(__aeabi_llsr)
|
||||
|
||||
subs r3, r2, #32
|
||||
rsb ip, r2, #32
|
||||
|
@ -25,6 +25,7 @@
|
||||
#endif
|
||||
|
||||
ENTRY(__muldi3)
|
||||
ENTRY(__aeabi_lmul)
|
||||
|
||||
mul xh, yl, xh
|
||||
mla xh, xl, yh, xh
|
||||
|
@ -10,6 +10,7 @@
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/config.h>
|
||||
#include <linux/linkage.h>
|
||||
|
||||
#ifdef __ARMEB__
|
||||
@ -33,3 +34,16 @@ ENTRY(__ucmpdi2)
|
||||
movhi r0, #2
|
||||
mov pc, lr
|
||||
|
||||
#ifdef CONFIG_AEABI
|
||||
|
||||
ENTRY(__aeabi_ulcmp)
|
||||
|
||||
cmp xh, yh
|
||||
cmpeq xl, yl
|
||||
movlo r0, #-1
|
||||
moveq r0, #0
|
||||
movhi r0, #1
|
||||
mov pc, lr
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -90,7 +90,6 @@ static void __init aaed2000_map_io(void)
|
||||
|
||||
MACHINE_START(AAED2000, "Agilent AAED-2000 Development Platform")
|
||||
/* Maintainer: Nicolas Bellido Y Ortega */
|
||||
.phys_ram = 0xf0000000,
|
||||
.phys_io = PIO_BASE,
|
||||
.io_pg_offst = ((VIO_BASE) >> 18) & 0xfffc,
|
||||
.map_io = aaed2000_map_io,
|
||||
|
@ -132,7 +132,6 @@ static void __init csb337_board_init(void)
|
||||
|
||||
MACHINE_START(CSB337, "Cogent CSB337")
|
||||
/* Maintainer: Bill Gatliff */
|
||||
.phys_ram = AT91_SDRAM_BASE,
|
||||
.phys_io = AT91_BASE_SYS,
|
||||
.io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
|
||||
.boot_params = AT91_SDRAM_BASE + 0x100,
|
||||
|
@ -105,7 +105,6 @@ static void __init csb637_board_init(void)
|
||||
|
||||
MACHINE_START(CSB637, "Cogent CSB637")
|
||||
/* Maintainer: Bill Gatliff */
|
||||
.phys_ram = AT91_SDRAM_BASE,
|
||||
.phys_io = AT91_BASE_SYS,
|
||||
.io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
|
||||
.boot_params = AT91_SDRAM_BASE + 0x100,
|
||||
|
@ -127,7 +127,6 @@ static void __init dk_board_init(void)
|
||||
|
||||
MACHINE_START(AT91RM9200DK, "Atmel AT91RM9200-DK")
|
||||
/* Maintainer: SAN People/Atmel */
|
||||
.phys_ram = AT91_SDRAM_BASE,
|
||||
.phys_io = AT91_BASE_SYS,
|
||||
.io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
|
||||
.boot_params = AT91_SDRAM_BASE + 0x100,
|
||||
|
@ -120,7 +120,6 @@ static void __init ek_board_init(void)
|
||||
|
||||
MACHINE_START(AT91RM9200EK, "Atmel AT91RM9200-EK")
|
||||
/* Maintainer: SAN People/Atmel */
|
||||
.phys_ram = AT91_SDRAM_BASE,
|
||||
.phys_io = AT91_BASE_SYS,
|
||||
.io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
|
||||
.boot_params = AT91_SDRAM_BASE + 0x100,
|
||||
|
@ -64,7 +64,6 @@ void __init autcpu12_map_io(void)
|
||||
|
||||
MACHINE_START(AUTCPU12, "autronix autcpu12")
|
||||
/* Maintainer: Thomas Gleixner */
|
||||
.phys_ram = 0xc0000000,
|
||||
.phys_io = 0x80000000,
|
||||
.io_pg_offst = ((0xff000000) >> 18) & 0xfffc,
|
||||
.boot_params = 0xc0020000,
|
||||
|
@ -55,7 +55,6 @@ static void __init cdb89712_map_io(void)
|
||||
|
||||
MACHINE_START(CDB89712, "Cirrus-CDB89712")
|
||||
/* Maintainer: Ray Lehtiniemi */
|
||||
.phys_ram = 0xc0000000,
|
||||
.phys_io = 0x80000000,
|
||||
.io_pg_offst = ((0xff000000) >> 18) & 0xfffc,
|
||||
.boot_params = 0xc0000100,
|
||||
|
@ -56,7 +56,6 @@ static void __init ceiva_map_io(void)
|
||||
|
||||
MACHINE_START(CEIVA, "CEIVA/Polaroid Photo MAX Digital Picture Frame")
|
||||
/* Maintainer: Rob Scott */
|
||||
.phys_ram = 0xc0000000,
|
||||
.phys_io = 0x80000000,
|
||||
.io_pg_offst = ((0xff000000) >> 18) & 0xfffc,
|
||||
.boot_params = 0xc0000100,
|
||||
|
@ -38,7 +38,6 @@ fixup_clep7312(struct machine_desc *desc, struct tag *tags,
|
||||
|
||||
MACHINE_START(CLEP7212, "Cirrus Logic 7212/7312")
|
||||
/* Maintainer: Nobody */
|
||||
.phys_ram = 0xc0000000,
|
||||
.phys_io = 0x80000000,
|
||||
.io_pg_offst = ((0xff000000) >> 18) & 0xfffc,
|
||||
.boot_params = 0xc0000100,
|
||||
|
@ -52,7 +52,6 @@ fixup_edb7211(struct machine_desc *desc, struct tag *tags,
|
||||
|
||||
MACHINE_START(EDB7211, "CL-EDB7211 (EP7211 eval board)")
|
||||
/* Maintainer: Jon McClintock */
|
||||
.phys_ram = 0xc0000000,
|
||||
.phys_io = 0x80000000,
|
||||
.io_pg_offst = ((0xff000000) >> 18) & 0xfffc,
|
||||
.boot_params = 0xc0020100, /* 0xc0000000 - 0xc001ffff can be video RAM */
|
||||
|
@ -78,7 +78,6 @@ fortunet_fixup(struct machine_desc *desc, struct tag *tags,
|
||||
|
||||
MACHINE_START(FORTUNET, "ARM-FortuNet")
|
||||
/* Maintainer: FortuNet Inc. */
|
||||
.phys_ram = 0xc0000000,
|
||||
.phys_io = 0x80000000,
|
||||
.io_pg_offst = ((0xf0000000) >> 18) & 0xfffc,
|
||||
.boot_params = 0x00000000,
|
||||
|
@ -90,7 +90,6 @@ static void __init p720t_map_io(void)
|
||||
|
||||
MACHINE_START(P720T, "ARM-Prospector720T")
|
||||
/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
|
||||
.phys_ram = 0xc0000000,
|
||||
.phys_io = 0x80000000,
|
||||
.io_pg_offst = ((0xff000000) >> 18) & 0xfffc,
|
||||
.boot_params = 0xc0000100,
|
||||
|
@ -384,7 +384,6 @@ static void __init clps7500_init(void)
|
||||
|
||||
MACHINE_START(CLPS7500, "CL-PS7500")
|
||||
/* Maintainer: Philip Blundell */
|
||||
.phys_ram = 0x10000000,
|
||||
.phys_io = 0x03000000,
|
||||
.io_pg_offst = ((0xe0000000) >> 18) & 0xfffc,
|
||||
.map_io = clps7500_map_io,
|
||||
|
@ -284,7 +284,6 @@ arch_initcall(ebsa110_init);
|
||||
|
||||
MACHINE_START(EBSA110, "EBSA110")
|
||||
/* Maintainer: Russell King */
|
||||
.phys_ram = 0x00000000,
|
||||
.phys_io = 0xe0000000,
|
||||
.io_pg_offst = ((0xe0000000) >> 18) & 0xfffc,
|
||||
.boot_params = 0x00000400,
|
||||
|
@ -85,7 +85,6 @@ fixup_cats(struct machine_desc *desc, struct tag *tags,
|
||||
|
||||
MACHINE_START(CATS, "Chalice-CATS")
|
||||
/* Maintainer: Philip Blundell */
|
||||
.phys_ram = 0x00000000,
|
||||
.phys_io = DC21285_ARMCSR_BASE,
|
||||
.io_pg_offst = ((0xfe000000) >> 18) & 0xfffc,
|
||||
.boot_params = 0x00000100,
|
||||
|
@ -29,7 +29,6 @@ fixup_coebsa285(struct machine_desc *desc, struct tag *tags,
|
||||
|
||||
MACHINE_START(CO285, "co-EBSA285")
|
||||
/* Maintainer: Mark van Doesburg */
|
||||
.phys_ram = 0x00000000,
|
||||
.phys_io = DC21285_ARMCSR_BASE,
|
||||
.io_pg_offst = ((0x7cf00000) >> 18) & 0xfffc,
|
||||
.fixup = fixup_coebsa285,
|
||||
|
@ -14,7 +14,6 @@
|
||||
|
||||
MACHINE_START(EBSA285, "EBSA285")
|
||||
/* Maintainer: Russell King */
|
||||
.phys_ram = 0x00000000,
|
||||
.phys_io = DC21285_ARMCSR_BASE,
|
||||
.io_pg_offst = ((0xfe000000) >> 18) & 0xfffc,
|
||||
.boot_params = 0x00000100,
|
||||
|
@ -649,7 +649,6 @@ fixup_netwinder(struct machine_desc *desc, struct tag *tags,
|
||||
|
||||
MACHINE_START(NETWINDER, "Rebel-NetWinder")
|
||||
/* Maintainer: Russell King/Rebel.com */
|
||||
.phys_ram = 0x00000000,
|
||||
.phys_io = DC21285_ARMCSR_BASE,
|
||||
.io_pg_offst = ((0xfe000000) >> 18) & 0xfffc,
|
||||
.boot_params = 0x00000100,
|
||||
|
@ -14,7 +14,6 @@
|
||||
|
||||
MACHINE_START(PERSONAL_SERVER, "Compaq-PersonalServer")
|
||||
/* Maintainer: Jamey Hicks / George France */
|
||||
.phys_ram = 0x00000000,
|
||||
.phys_io = DC21285_ARMCSR_BASE,
|
||||
.io_pg_offst = ((0xfe000000) >> 18) & 0xfffc,
|
||||
.boot_params = 0x00000100,
|
||||
|
@ -31,7 +31,6 @@
|
||||
|
||||
MACHINE_START(H7201, "Hynix GMS30C7201")
|
||||
/* Maintainer: Robert Schwebel, Pengutronix */
|
||||
.phys_ram = 0x40000000,
|
||||
.phys_io = 0x80000000,
|
||||
.io_pg_offst = ((0xf0000000) >> 18) & 0xfffc,
|
||||
.boot_params = 0xc0001000,
|
||||
|
@ -72,7 +72,6 @@ static void __init init_eval_h7202(void)
|
||||
|
||||
MACHINE_START(H7202, "Hynix HMS30C7202")
|
||||
/* Maintainer: Robert Schwebel, Pengutronix */
|
||||
.phys_ram = 0x40000000,
|
||||
.phys_io = 0x80000000,
|
||||
.io_pg_offst = ((0xf0000000) >> 18) & 0xfffc,
|
||||
.boot_params = 0x40000100,
|
||||
|
@ -69,7 +69,6 @@ mx1ads_map_io(void)
|
||||
|
||||
MACHINE_START(MX1ADS, "Motorola MX1ADS")
|
||||
/* Maintainer: Sascha Hauer, Pengutronix */
|
||||
.phys_ram = 0x08000000,
|
||||
.phys_io = 0x00200000,
|
||||
.io_pg_offst = ((0xe0200000) >> 18) & 0xfffc,
|
||||
.boot_params = 0x08000100,
|
||||
|
@ -347,7 +347,6 @@ static struct sys_timer ap_timer = {
|
||||
|
||||
MACHINE_START(INTEGRATOR, "ARM-Integrator")
|
||||
/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
|
||||
.phys_ram = 0x00000000,
|
||||
.phys_io = 0x16000000,
|
||||
.io_pg_offst = ((0xf1600000) >> 18) & 0xfffc,
|
||||
.boot_params = 0x00000100,
|
||||
|
@ -578,7 +578,6 @@ static struct sys_timer cp_timer = {
|
||||
|
||||
MACHINE_START(CINTEGRATOR, "ARM-IntegratorCP")
|
||||
/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
|
||||
.phys_ram = 0x00000000,
|
||||
.phys_io = 0x16000000,
|
||||
.io_pg_offst = ((0xf1600000) >> 18) & 0xfffc,
|
||||
.boot_params = 0x00000100,
|
||||
|
@ -22,20 +22,6 @@ static int lm_match(struct device *dev, struct device_driver *drv)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct bus_type lm_bustype = {
|
||||
.name = "logicmodule",
|
||||
.match = lm_match,
|
||||
// .suspend = lm_suspend,
|
||||
// .resume = lm_resume,
|
||||
};
|
||||
|
||||
static int __init lm_init(void)
|
||||
{
|
||||
return bus_register(&lm_bustype);
|
||||
}
|
||||
|
||||
postcore_initcall(lm_init);
|
||||
|
||||
static int lm_bus_probe(struct device *dev)
|
||||
{
|
||||
struct lm_device *lmdev = to_lm_device(dev);
|
||||
@ -49,16 +35,30 @@ static int lm_bus_remove(struct device *dev)
|
||||
struct lm_device *lmdev = to_lm_device(dev);
|
||||
struct lm_driver *lmdrv = to_lm_driver(dev->driver);
|
||||
|
||||
lmdrv->remove(lmdev);
|
||||
if (lmdrv->remove)
|
||||
lmdrv->remove(lmdev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct bus_type lm_bustype = {
|
||||
.name = "logicmodule",
|
||||
.match = lm_match,
|
||||
.probe = lm_bus_probe,
|
||||
.remove = lm_bus_remove,
|
||||
// .suspend = lm_bus_suspend,
|
||||
// .resume = lm_bus_resume,
|
||||
};
|
||||
|
||||
static int __init lm_init(void)
|
||||
{
|
||||
return bus_register(&lm_bustype);
|
||||
}
|
||||
|
||||
postcore_initcall(lm_init);
|
||||
|
||||
int lm_driver_register(struct lm_driver *drv)
|
||||
{
|
||||
drv->drv.bus = &lm_bustype;
|
||||
drv->drv.probe = lm_bus_probe;
|
||||
drv->drv.remove = lm_bus_remove;
|
||||
|
||||
return driver_register(&drv->drv);
|
||||
}
|
||||
|
||||
|
@ -151,7 +151,6 @@ extern void iop321_init_time(void);
|
||||
#if defined(CONFIG_ARCH_IQ80321)
|
||||
MACHINE_START(IQ80321, "Intel IQ80321")
|
||||
/* Maintainer: Intel Corporation */
|
||||
.phys_ram = PHYS_OFFSET,
|
||||
.phys_io = IQ80321_UART,
|
||||
.io_pg_offst = ((IQ80321_UART) >> 18) & 0xfffc,
|
||||
.map_io = iq80321_map_io,
|
||||
@ -163,7 +162,6 @@ MACHINE_END
|
||||
#elif defined(CONFIG_ARCH_IQ31244)
|
||||
MACHINE_START(IQ31244, "Intel IQ31244")
|
||||
/* Maintainer: Intel Corp. */
|
||||
.phys_ram = PHYS_OFFSET,
|
||||
.phys_io = IQ31244_UART,
|
||||
.io_pg_offst = ((IQ31244_UART) >> 18) & 0xfffc,
|
||||
.map_io = iq31244_map_io,
|
||||
|
@ -195,7 +195,6 @@ extern void iq80332_map_io(void);
|
||||
#if defined(CONFIG_ARCH_IQ80331)
|
||||
MACHINE_START(IQ80331, "Intel IQ80331")
|
||||
/* Maintainer: Intel Corp. */
|
||||
.phys_ram = PHYS_OFFSET,
|
||||
.phys_io = 0xfefff000,
|
||||
.io_pg_offst = ((0xfffff000) >> 18) & 0xfffc, // virtual, physical
|
||||
.map_io = iq80331_map_io,
|
||||
@ -208,7 +207,6 @@ MACHINE_END
|
||||
#elif defined(CONFIG_MACH_IQ80332)
|
||||
MACHINE_START(IQ80332, "Intel IQ80332")
|
||||
/* Maintainer: Intel Corp. */
|
||||
.phys_ram = PHYS_OFFSET,
|
||||
.phys_io = 0xfefff000,
|
||||
.io_pg_offst = ((0xfffff000) >> 18) & 0xfffc, // virtual, physical
|
||||
.map_io = iq80332_map_io,
|
||||
|
@ -105,6 +105,16 @@ static struct map_desc ixp2000_io_desc[] __initdata = {
|
||||
.pfn = __phys_to_pfn(IXP2000_MSF_PHYS_BASE),
|
||||
.length = IXP2000_MSF_SIZE,
|
||||
.type = MT_IXP2000_DEVICE,
|
||||
}, {
|
||||
.virtual = IXP2000_SCRATCH_RING_VIRT_BASE,
|
||||
.pfn = __phys_to_pfn(IXP2000_SCRATCH_RING_PHYS_BASE),
|
||||
.length = IXP2000_SCRATCH_RING_SIZE,
|
||||
.type = MT_IXP2000_DEVICE,
|
||||
}, {
|
||||
.virtual = IXP2000_SRAM0_VIRT_BASE,
|
||||
.pfn = __phys_to_pfn(IXP2000_SRAM0_PHYS_BASE),
|
||||
.length = IXP2000_SRAM0_SIZE,
|
||||
.type = MT_IXP2000_DEVICE,
|
||||
}, {
|
||||
.virtual = IXP2000_PCI_IO_VIRT_BASE,
|
||||
.pfn = __phys_to_pfn(IXP2000_PCI_IO_PHYS_BASE),
|
||||
|
@ -254,7 +254,6 @@ static void __init enp2611_init_machine(void)
|
||||
|
||||
MACHINE_START(ENP2611, "Radisys ENP-2611 PCI network processor board")
|
||||
/* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */
|
||||
.phys_ram = 0x00000000,
|
||||
.phys_io = IXP2000_UART_PHYS_BASE,
|
||||
.io_pg_offst = ((IXP2000_UART_VIRT_BASE) >> 18) & 0xfffc,
|
||||
.boot_params = 0x00000100,
|
||||
|
@ -169,7 +169,6 @@ void ixdp2400_init_irq(void)
|
||||
|
||||
MACHINE_START(IXDP2400, "Intel IXDP2400 Development Platform")
|
||||
/* Maintainer: MontaVista Software, Inc. */
|
||||
.phys_ram = 0x00000000,
|
||||
.phys_io = IXP2000_UART_PHYS_BASE,
|
||||
.io_pg_offst = ((IXP2000_UART_VIRT_BASE) >> 18) & 0xfffc,
|
||||
.boot_params = 0x00000100,
|
||||
|
@ -285,7 +285,6 @@ void ixdp2800_init_irq(void)
|
||||
|
||||
MACHINE_START(IXDP2800, "Intel IXDP2800 Development Platform")
|
||||
/* Maintainer: MontaVista Software, Inc. */
|
||||
.phys_ram = 0x00000000,
|
||||
.phys_io = IXP2000_UART_PHYS_BASE,
|
||||
.io_pg_offst = ((IXP2000_UART_VIRT_BASE) >> 18) & 0xfffc,
|
||||
.boot_params = 0x00000100,
|
||||
|
@ -376,7 +376,6 @@ static void __init ixdp2x01_init_machine(void)
|
||||
#ifdef CONFIG_ARCH_IXDP2401
|
||||
MACHINE_START(IXDP2401, "Intel IXDP2401 Development Platform")
|
||||
/* Maintainer: MontaVista Software, Inc. */
|
||||
.phys_ram = 0x00000000,
|
||||
.phys_io = IXP2000_UART_PHYS_BASE,
|
||||
.io_pg_offst = ((IXP2000_UART_VIRT_BASE) >> 18) & 0xfffc,
|
||||
.boot_params = 0x00000100,
|
||||
@ -390,7 +389,6 @@ MACHINE_END
|
||||
#ifdef CONFIG_ARCH_IXDP2801
|
||||
MACHINE_START(IXDP2801, "Intel IXDP2801 Development Platform")
|
||||
/* Maintainer: MontaVista Software, Inc. */
|
||||
.phys_ram = 0x00000000,
|
||||
.phys_io = IXP2000_UART_PHYS_BASE,
|
||||
.io_pg_offst = ((IXP2000_UART_VIRT_BASE) >> 18) & 0xfffc,
|
||||
.boot_params = 0x00000100,
|
||||
|
@ -101,7 +101,6 @@ static void __init coyote_init(void)
|
||||
#ifdef CONFIG_ARCH_ADI_COYOTE
|
||||
MACHINE_START(ADI_COYOTE, "ADI Engineering Coyote")
|
||||
/* Maintainer: MontaVista Software, Inc. */
|
||||
.phys_ram = PHYS_OFFSET,
|
||||
.phys_io = IXP4XX_PERIPHERAL_BASE_PHYS,
|
||||
.io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc,
|
||||
.map_io = ixp4xx_map_io,
|
||||
@ -119,7 +118,6 @@ MACHINE_END
|
||||
#ifdef CONFIG_MACH_IXDPG425
|
||||
MACHINE_START(IXDPG425, "Intel IXDPG425")
|
||||
/* Maintainer: MontaVista Software, Inc. */
|
||||
.phys_ram = PHYS_OFFSET,
|
||||
.phys_io = IXP4XX_PERIPHERAL_BASE_PHYS,
|
||||
.io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc,
|
||||
.map_io = ixp4xx_map_io,
|
||||
|
@ -142,7 +142,6 @@ static void __init gtwx5715_init(void)
|
||||
|
||||
MACHINE_START(GTWX5715, "Gemtek GTWX5715 (Linksys WRV54G)")
|
||||
/* Maintainer: George Joseph */
|
||||
.phys_ram = PHYS_OFFSET,
|
||||
.phys_io = IXP4XX_UART2_BASE_PHYS,
|
||||
.io_pg_offst = ((IXP4XX_UART2_BASE_VIRT) >> 18) & 0xfffc,
|
||||
.map_io = ixp4xx_map_io,
|
||||
|
@ -121,7 +121,6 @@ static void __init ixdp425_init(void)
|
||||
#ifdef CONFIG_ARCH_IXDP425
|
||||
MACHINE_START(IXDP425, "Intel IXDP425 Development Platform")
|
||||
/* Maintainer: MontaVista Software, Inc. */
|
||||
.phys_ram = PHYS_OFFSET,
|
||||
.phys_io = IXP4XX_PERIPHERAL_BASE_PHYS,
|
||||
.io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc,
|
||||
.map_io = ixp4xx_map_io,
|
||||
@ -135,7 +134,6 @@ MACHINE_END
|
||||
#ifdef CONFIG_MACH_IXDP465
|
||||
MACHINE_START(IXDP465, "Intel IXDP465 Development Platform")
|
||||
/* Maintainer: MontaVista Software, Inc. */
|
||||
.phys_ram = PHYS_OFFSET,
|
||||
.phys_io = IXP4XX_PERIPHERAL_BASE_PHYS,
|
||||
.io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc,
|
||||
.map_io = ixp4xx_map_io,
|
||||
@ -149,7 +147,6 @@ MACHINE_END
|
||||
#ifdef CONFIG_ARCH_PRPMC1100
|
||||
MACHINE_START(IXCDP1100, "Intel IXCDP1100 Development Platform")
|
||||
/* Maintainer: MontaVista Software, Inc. */
|
||||
.phys_ram = PHYS_OFFSET,
|
||||
.phys_io = IXP4XX_PERIPHERAL_BASE_PHYS,
|
||||
.io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc,
|
||||
.map_io = ixp4xx_map_io,
|
||||
@ -169,7 +166,6 @@ MACHINE_END
|
||||
#ifdef CONFIG_ARCH_AVILA
|
||||
MACHINE_START(AVILA, "Gateworks Avila Network Platform")
|
||||
/* Maintainer: Deepak Saxena <dsaxena@plexity.net> */
|
||||
.phys_ram = PHYS_OFFSET,
|
||||
.phys_io = IXP4XX_PERIPHERAL_BASE_PHYS,
|
||||
.io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc,
|
||||
.map_io = ixp4xx_map_io,
|
||||
|
@ -124,7 +124,6 @@ static void __init nas100d_init(void)
|
||||
|
||||
MACHINE_START(NAS100D, "Iomega NAS 100d")
|
||||
/* Maintainer: www.nslu2-linux.org */
|
||||
.phys_ram = PHYS_OFFSET,
|
||||
.phys_io = IXP4XX_PERIPHERAL_BASE_PHYS,
|
||||
.io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xFFFC,
|
||||
.boot_params = 0x00000100,
|
||||
|
@ -123,7 +123,6 @@ static void __init nslu2_init(void)
|
||||
|
||||
MACHINE_START(NSLU2, "Linksys NSLU2")
|
||||
/* Maintainer: www.nslu2-linux.org */
|
||||
.phys_ram = PHYS_OFFSET,
|
||||
.phys_io = IXP4XX_PERIPHERAL_BASE_PHYS,
|
||||
.io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xFFFC,
|
||||
.boot_params = 0x00000100,
|
||||
|
@ -91,7 +91,6 @@ static void __init l7200_map_io(void)
|
||||
|
||||
MACHINE_START(L7200, "LinkUp Systems L7200")
|
||||
/* Maintainer: Steve Hill / Scott McConnell */
|
||||
.phys_ram = 0xf0000000,
|
||||
.phys_io = 0x80040000,
|
||||
.io_pg_offst = ((0xd0000000) >> 18) & 0xfffc,
|
||||
.map_io = l7200_map_io,
|
||||
|
@ -112,7 +112,6 @@ void __init lh7a40x_init_board_irq (void)
|
||||
|
||||
MACHINE_START (KEV7A400, "Sharp KEV7a400")
|
||||
/* Maintainer: Marc Singer */
|
||||
.phys_ram = 0xc0000000,
|
||||
.phys_io = 0x80000000,
|
||||
.io_pg_offst = ((io_p2v (0x80000000))>>18) & 0xfffc,
|
||||
.boot_params = 0xc0000100,
|
||||
|
@ -317,7 +317,6 @@ lpd7a400_map_io(void)
|
||||
|
||||
MACHINE_START (LPD7A400, "Logic Product Development LPD7A400-10")
|
||||
/* Maintainer: Marc Singer */
|
||||
.phys_ram = 0xc0000000,
|
||||
.phys_io = 0x80000000,
|
||||
.io_pg_offst = ((io_p2v (0x80000000))>>18) & 0xfffc,
|
||||
.boot_params = 0xc0000100,
|
||||
@ -333,7 +332,6 @@ MACHINE_END
|
||||
|
||||
MACHINE_START (LPD7A404, "Logic Product Development LPD7A404-10")
|
||||
/* Maintainer: Marc Singer */
|
||||
.phys_ram = 0xc0000000,
|
||||
.phys_io = 0x80000000,
|
||||
.io_pg_offst = ((io_p2v (0x80000000))>>18) & 0xfffc,
|
||||
.boot_params = 0xc0000100,
|
||||
|
@ -109,7 +109,6 @@ static void __init omap_generic_map_io(void)
|
||||
|
||||
MACHINE_START(OMAP_GENERIC, "Generic OMAP1510/1610/1710")
|
||||
/* Maintainer: Tony Lindgren <tony@atomide.com> */
|
||||
.phys_ram = 0x10000000,
|
||||
.phys_io = 0xfff00000,
|
||||
.io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
|
||||
.boot_params = 0x10000100,
|
||||
|
@ -199,7 +199,6 @@ static void __init h2_map_io(void)
|
||||
|
||||
MACHINE_START(OMAP_H2, "TI-H2")
|
||||
/* Maintainer: Imre Deak <imre.deak@nokia.com> */
|
||||
.phys_ram = 0x10000000,
|
||||
.phys_io = 0xfff00000,
|
||||
.io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
|
||||
.boot_params = 0x10000100,
|
||||
|
@ -215,7 +215,6 @@ static void __init h3_map_io(void)
|
||||
|
||||
MACHINE_START(OMAP_H3, "TI OMAP1710 H3 board")
|
||||
/* Maintainer: Texas Instruments, Inc. */
|
||||
.phys_ram = 0x10000000,
|
||||
.phys_io = 0xfff00000,
|
||||
.io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
|
||||
.boot_params = 0x10000100,
|
||||
|
@ -303,7 +303,6 @@ static void __init innovator_map_io(void)
|
||||
|
||||
MACHINE_START(OMAP_INNOVATOR, "TI-Innovator")
|
||||
/* Maintainer: MontaVista Software, Inc. */
|
||||
.phys_ram = 0x10000000,
|
||||
.phys_io = 0xfff00000,
|
||||
.io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
|
||||
.boot_params = 0x10000100,
|
||||
|
@ -149,7 +149,6 @@ postcore_initcall(netstar_late_init);
|
||||
|
||||
MACHINE_START(NETSTAR, "NetStar OMAP5910")
|
||||
/* Maintainer: Ladislav Michl <michl@2n.cz> */
|
||||
.phys_ram = 0x10000000,
|
||||
.phys_io = 0xfff00000,
|
||||
.io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
|
||||
.boot_params = 0x10000100,
|
||||
|
@ -274,7 +274,6 @@ static void __init osk_map_io(void)
|
||||
|
||||
MACHINE_START(OMAP_OSK, "TI-OSK")
|
||||
/* Maintainer: Dirk Behme <dirk.behme@de.bosch.com> */
|
||||
.phys_ram = 0x10000000,
|
||||
.phys_io = 0xfff00000,
|
||||
.io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
|
||||
.boot_params = 0x10000100,
|
||||
|
@ -76,7 +76,6 @@ static void __init omap_generic_map_io(void)
|
||||
}
|
||||
|
||||
MACHINE_START(OMAP_PALMTE, "OMAP310 based Palm Tungsten E")
|
||||
.phys_ram = 0x10000000,
|
||||
.phys_io = 0xfff00000,
|
||||
.io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
|
||||
.boot_params = 0x10000100,
|
||||
|
@ -199,7 +199,6 @@ static void __init omap_perseus2_map_io(void)
|
||||
|
||||
MACHINE_START(OMAP_PERSEUS2, "OMAP730 Perseus2")
|
||||
/* Maintainer: Kevin Hilman <kjh@hilman.org> */
|
||||
.phys_ram = 0x10000000,
|
||||
.phys_io = 0xfff00000,
|
||||
.io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
|
||||
.boot_params = 0x10000100,
|
||||
|
@ -281,7 +281,6 @@ EXPORT_SYMBOL(voiceblue_wdt_ping);
|
||||
|
||||
MACHINE_START(VOICEBLUE, "VoiceBlue OMAP5910")
|
||||
/* Maintainer: Ladislav Michl <michl@2n.cz> */
|
||||
.phys_ram = 0x10000000,
|
||||
.phys_io = 0xfff00000,
|
||||
.io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
|
||||
.boot_params = 0x10000100,
|
||||
|
@ -69,7 +69,6 @@ static void __init omap_generic_map_io(void)
|
||||
|
||||
MACHINE_START(OMAP_GENERIC, "Generic OMAP24xx")
|
||||
/* Maintainer: Paul Mundt <paul.mundt@nokia.com> */
|
||||
.phys_ram = 0x80000000,
|
||||
.phys_io = 0x48000000,
|
||||
.io_pg_offst = ((0xd8000000) >> 18) & 0xfffc,
|
||||
.boot_params = 0x80000100,
|
||||
|
@ -186,7 +186,6 @@ static void __init omap_h4_map_io(void)
|
||||
|
||||
MACHINE_START(OMAP_H4, "OMAP2420 H4 board")
|
||||
/* Maintainer: Paul Mundt <paul.mundt@nokia.com> */
|
||||
.phys_ram = 0x80000000,
|
||||
.phys_io = 0x48000000,
|
||||
.io_pg_offst = ((0xd8000000) >> 18) & 0xfffc,
|
||||
.boot_params = 0x80000100,
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user