diff -Nru a/CREDITS b/CREDITS
--- a/CREDITS Wed Oct 8 12:24:57 2003
+++ b/CREDITS Wed Oct 8 12:24:57 2003
@@ -1459,6 +1459,13 @@
S: Roscommon
S: Ireland
+N: Michael Hunold
+E: michael@mihu.de
+W: http://www.mihu.de/linux/
+D: Generic saa7146 video4linux-2 driver core,
+D: Driver for the "Multimedia eXtension Board", "dpc7146",
+D: "Hexium Orion", "Hexium Gemini"
+
N: Miguel de Icaza Amozurrutia
E: miguel@nuclecu.unam.mx
D: Linux/SPARC team, Midnight Commander maintainer
@@ -1862,9 +1869,9 @@
S: Germany
N: Achim Leubner
-E: achim.leubner@intel.com
+E: achim_leubner@adaptec.com
D: GDT Disk Array Controller/Storage RAID controller driver
-S: ICP vortex GmbH, an Intel company
+S: ICP vortex GmbH
S: Neckarsulm
S: Germany
diff -Nru a/Documentation/Changes b/Documentation/Changes
--- a/Documentation/Changes Wed Oct 8 12:24:57 2003
+++ b/Documentation/Changes Wed Oct 8 12:24:57 2003
@@ -2,7 +2,7 @@
=====
This document is designed to provide a list of the minimum levels of
-software necessary to run the 2.5 kernels, as well as provide brief
+software necessary to run the 2.6 kernels, as well as provide brief
instructions regarding any other "Gotchas" users may encounter when
trying life on the Bleeding Edge. If upgrading from a pre-2.4.x
kernel, please consult the Changes file included with 2.4.x kernels for
@@ -142,7 +142,7 @@
root of the Linux source for more information.
Module-Init-Tools
---------
+-----------------
A new module loader is now in the kernel that requires module-init-tools
to use. It is backward compatible with the 2.4.x series kernels.
@@ -337,8 +337,8 @@
--------
o
-Modutils
---------
+Module-Init-Tools
+-----------------
o
Mkinitrd
diff -Nru a/Documentation/DocBook/kernel-api.tmpl b/Documentation/DocBook/kernel-api.tmpl
--- a/Documentation/DocBook/kernel-api.tmpl Wed Oct 8 12:24:55 2003
+++ b/Documentation/DocBook/kernel-api.tmpl Wed Oct 8 12:24:55 2003
@@ -315,9 +315,4 @@
-->
-
diff -Nru a/Documentation/binfmt_misc.txt b/Documentation/binfmt_misc.txt
--- a/Documentation/binfmt_misc.txt Wed Oct 8 12:24:56 2003
+++ b/Documentation/binfmt_misc.txt Wed Oct 8 12:24:56 2003
@@ -41,6 +41,11 @@
offset+size(magic) has to be less than 128
- the interpreter string may not exceed 127 characters
+To use binfmt_misc you have to mount it first. You can mount it with
+"mount -t binfmt_misc none /proc/sys/fs/binfmt_misc" command, or you can add
+a line "none /proc/sys/fs/binfmt_misc binfmt_misc defaults 0 0" to your
+/etc/fstab so it auto mounts on boot.
+
You may want to add the binary formats in one of your /etc/rc scripts during
boot-up. Read the manual of your init program to figure out how to do this
right.
diff -Nru a/Documentation/cachetlb.txt b/Documentation/cachetlb.txt
--- a/Documentation/cachetlb.txt Wed Oct 8 12:24:56 2003
+++ b/Documentation/cachetlb.txt Wed Oct 8 12:24:56 2003
@@ -59,9 +59,9 @@
address translations from the TLB. After running, this
interface must make sure that any previous page table
modifications for the address space 'vma->vm_mm' in the range
- 'start' to 'end' will be visible to the cpu. That is, after
+ 'start' to 'end-1' will be visible to the cpu. That is, after
running, here will be no entries in the TLB for 'mm' for
- virtual addresses in the range 'start' to 'end'.
+ virtual addresses in the range 'start' to 'end-1'.
The "vma" is the backing store being used for the region.
Primarily, this is used for munmap() type operations.
@@ -100,7 +100,7 @@
unsigned long start, unsigned long end)
The software page tables for address space 'mm' for virtual
- addresses in the range 'start' to 'end' are being torn down.
+ addresses in the range 'start' to 'end-1' are being torn down.
Some platforms cache the lowest level of the software page tables
in a linear virtually mapped array, to make TLB miss processing
@@ -165,15 +165,7 @@
Here are the routines, one by one:
-1) void flush_cache_all(void)
-
- The most severe flush of all. After this interface runs,
- the entire cpu cache is flushed.
-
- This is usually invoked when the kernel page tables are
- changed, since such translations are "global" in nature.
-
-2) void flush_cache_mm(struct mm_struct *mm)
+1) void flush_cache_mm(struct mm_struct *mm)
This interface flushes an entire user address space from
the caches. That is, after running, there will be no cache
@@ -183,13 +175,13 @@
page table operations such as what happens during
fork, exit, and exec.
-3) void flush_cache_range(struct vm_area_struct *vma,
+2) void flush_cache_range(struct vm_area_struct *vma,
unsigned long start, unsigned long end)
Here we are flushing a specific range of (user) virtual
addresses from the cache. After running, there will be no
entries in the cache for 'vma->vm_mm' for virtual addresses in
- the range 'start' to 'end'.
+ the range 'start' to 'end-1'.
The "vma" is the backing store being used for the region.
Primarily, this is used for munmap() type operations.
@@ -200,7 +192,7 @@
call flush_cache_page (see below) for each entry which may be
modified.
-4) void flush_cache_page(struct vm_area_struct *vma, unsigned long addr)
+3) void flush_cache_page(struct vm_area_struct *vma, unsigned long addr)
This time we need to remove a PAGE_SIZE sized range
from the cache. The 'vma' is the backing structure used by
@@ -215,6 +207,30 @@
This is used primarily during fault processing.
+4) void flush_cache_kmaps(void)
+
+ This routine need only be implemented if the platform utilizes
+ highmem. It will be called right before all of the kmaps
+ are invalidated.
+
+ After running, there will be no entries in the cache for
+ the kernel virtual address range PKMAP_ADDR(0) to
+ PKMAP_ADDR(LAST_PKMAP).
+
+ This routing should be implemented in asm/highmem.h
+
+5) void flush_cache_vmap(unsigned long start, unsigned long end)
+ void flush_cache_vunmap(unsigned long start, unsigned long end)
+
+ Here in these two interfaces we are flushing a specific range
+ of (kernel) virtual addresses from the cache. After running,
+ there will be no entries in the cache for the kernel address
+ space for virtual addresses in the range 'start' to 'end-1'.
+
+ The first of these two routines is invoked after map_vm_area()
+ has installed the page table entries. The second is invoked
+ before unmap_vm_area() deletes the page table entries.
+
There exists another whole class of cpu cache issues which currently
require a whole different set of interfaces to handle properly.
The biggest problem is that of virtual aliasing in the data cache
@@ -317,23 +333,32 @@
dirty. Again, see sparc64 for examples of how
to deal with this.
+ void copy_to_user_page(struct vm_area_struct *vma, struct page *page,
+ unsigned long user_vaddr,
+ void *dst, void *src, int len)
+ void copy_from_user_page(struct vm_area_struct *vma, struct page *page,
+ unsigned long user_vaddr,
+ void *dst, void *src, int len)
+ When the kernel needs to copy arbitrary data in and out
+ of arbitrary user pages (f.e. for ptrace()) it will use
+ these two routines.
+
+ The page has been kmap()'d, and flush_cache_page() has
+ just been called for the user mapping of this page (if
+ necessary).
+
+ Any necessary cache flushing or other coherency operations
+ that need to occur should happen here. If the processor's
+ instruction cache does not snoop cpu stores, it is very
+ likely that you will need to flush the instruction cache
+ for copy_to_user_page().
+
void flush_icache_range(unsigned long start, unsigned long end)
When the kernel stores into addresses that it will execute
out of (eg when loading modules), this function is called.
If the icache does not snoop stores then this routine will need
to flush it.
-
- void flush_icache_user_range(struct vm_area_struct *vma,
- struct page *page, unsigned long addr, int len)
- This is called when the kernel stores into addresses that are
- part of the address space of a user process (which may be some
- other process than the current process). The addr argument
- gives the virtual address in that process's address space,
- page is the page which is being modified, and len indicates
- how many bytes have been modified. The modified region must
- not cross a page boundary. Currently this is only called from
- kernel/ptrace.c.
void flush_icache_page(struct vm_area_struct *vma, struct page *page)
All the functionality of flush_icache_page can be implemented in
diff -Nru a/Documentation/cdrom/aztcd b/Documentation/cdrom/aztcd
--- a/Documentation/cdrom/aztcd Wed Oct 8 12:24:56 2003
+++ b/Documentation/cdrom/aztcd Wed Oct 8 12:24:56 2003
@@ -178,8 +178,7 @@
to load it before you can mount the CDROM:
insmod /lib/modules/X.X.X/fs/isofs.o
The mount procedure works as described in 4. above.
-(In all commands 'X.X.X' is the current linux kernel version number. For details
-see file modules.txt in /usr/src/linux/Documentation)
+(In all commands 'X.X.X' is the current linux kernel version number)
4.2 CDROM CONNECTED TO A SOUNDCARD
Most soundcards do have a bus interface to the CDROM-drive. In many cases
diff -Nru a/Documentation/cdrom/sbpcd b/Documentation/cdrom/sbpcd
--- a/Documentation/cdrom/sbpcd Wed Oct 8 12:24:57 2003
+++ b/Documentation/cdrom/sbpcd Wed Oct 8 12:24:57 2003
@@ -272,7 +272,6 @@
If you do NOT select "Matsushita/Panasonic CDROM driver support" during the
"make config" of your kernel, you can build the "loadable module" sbpcd.o.
-Read /usr/src/linux/Documentation/modules.txt on this.
If sbpcd gets used as a module, the support of more than one interface
card (i.e. drives 4...15) is disabled.
diff -Nru a/Documentation/cpu-freq/user-guide.txt b/Documentation/cpu-freq/user-guide.txt
--- a/Documentation/cpu-freq/user-guide.txt Wed Oct 8 12:24:55 2003
+++ b/Documentation/cpu-freq/user-guide.txt Wed Oct 8 12:24:55 2003
@@ -57,6 +57,8 @@
AMD mobile K6-3+
AMD mobile Duron
AMD mobile Athlon
+AMD Opteron
+AMD Athlon 64
Cyrix Media GXm
Intel mobile PIII and Intel mobile PIII-M on certain chipsets
Intel Pentium 4, Intel Xeon
diff -Nru a/Documentation/crypto/api-intro.txt b/Documentation/crypto/api-intro.txt
--- a/Documentation/crypto/api-intro.txt Wed Oct 8 12:24:57 2003
+++ b/Documentation/crypto/api-intro.txt Wed Oct 8 12:24:57 2003
@@ -126,7 +126,7 @@
BUGS
Send bug reports to:
-James Morris
+James Morris
Cc: David S. Miller
@@ -220,5 +220,5 @@
Generic scatterwalk code by Adam J. Richter
Please send any credits updates or corrections to:
-James Morris
+James Morris
diff -Nru a/Documentation/ftape.txt b/Documentation/ftape.txt
--- a/Documentation/ftape.txt Wed Oct 8 12:24:55 2003
+++ b/Documentation/ftape.txt Wed Oct 8 12:24:55 2003
@@ -246,8 +246,7 @@
or by editing the file `/etc/modules.conf' in which case they take
effect each time when the module is loaded with `modprobe' (please
- refer to the modules documentation, i.e. `modules.txt' and the
- respective manual pages). Thus, you should add a line
+ refer to the respective manual pages). Thus, you should add a line
options ftape ft_tracing=4
diff -Nru a/Documentation/ioctl-number.txt b/Documentation/ioctl-number.txt
--- a/Documentation/ioctl-number.txt Wed Oct 8 12:24:57 2003
+++ b/Documentation/ioctl-number.txt Wed Oct 8 12:24:57 2003
@@ -175,10 +175,6 @@
0xA0 all linux/sdp/sdp.h Industrial Device Project
-0xA2 00-0F DVD decoder driver in development:
-
-0xA3 00-1F Philips SAA7146 dirver in development:
-
0xA3 80-8F Port ACL in development:
0xA3 90-9F linux/dtlk.h
diff -Nru a/Documentation/iostats.txt b/Documentation/iostats.txt
--- a/Documentation/iostats.txt Wed Oct 8 12:24:56 2003
+++ b/Documentation/iostats.txt Wed Oct 8 12:24:56 2003
@@ -1,22 +1,22 @@
I/O statistics fields
---------------
-Last modified 5/15/03
+Last modified Sep 30, 2003
-In 2.4.20 (and some versions before, with patches), and 2.5.45,
-more extensive disk statistics were introduced to help measure disk
+Since 2.4.20 (and some versions before, with patches), and 2.5.45,
+more extensive disk statistics have been introduced to help measure disk
activity. Tools such as sar and iostat typically interpret these and do
the work for you, but in case you are interested in creating your own
tools, the fields are explained here.
-In most versions of the 2.4 patch, the information is found as additional
-fields in /proc/partitions. In 2.5, the same information is found in
-two places: one is in the file /proc/diskstats (appears in 2.5.69 and
-beyond), and the other is within the sysfs file system, which must be
-mounted in order to obtain the information. Throughout this document
-we'll assume that sysfs is mounted on /sys, although of course it may
-be mounted anywhere. In 2.5, both /proc/diskstats and sysfs use the
-same source for the information and so should not differ.
+In 2.4 now, the information is found as additional fields in
+/proc/partitions. In 2.6, the same information is found in two
+places: one is in the file /proc/diskstats, and the other is within
+the sysfs file system, which must be mounted in order to obtain
+the information. Throughout this document we'll assume that sysfs
+is mounted on /sys, although of course it may be mounted anywhere.
+Both /proc/diskstats and sysfs use the same source for the information
+and so should not differ.
Here are examples of these different formats:
@@ -25,15 +25,15 @@
3 1 9221278 hda1 35486 0 35496 38030 0 0 0 0 0 38030 38030
-2.5 sysfs:
+2.6 sysfs:
446216 784926 9550688 4382310 424847 312726 5922052 19310380 0 3376340 23705160
35486 38030 38030 38030
-2.5 diskstats:
+2.6 diskstats:
3 0 hda 446216 784926 9550688 4382310 424847 312726 5922052 19310380 0 3376340 23705160
3 1 hda1 35486 38030 38030 38030
-On 2.4 you might execute "grep 'hda ' /proc/partitions". On 2.5, you have
+On 2.4 you might execute "grep 'hda ' /proc/partitions". On 2.6, you have
a choice of "cat /sys/block/hda/stat" or "grep 'hda ' /proc/diskstats".
The advantage of one over the other is that the sysfs choice works well
if you are watching a known, small set of disks. /proc/diskstats may
@@ -43,7 +43,7 @@
In 2.4, the statistics fields are those after the device name. In
the above example, the first field of statistics would be 446216.
-By contrast, in 2.5 if you look at /sys/block/hda/stat, you'll
+By contrast, in 2.6 if you look at /sys/block/hda/stat, you'll
find just the eleven fields, beginning with 446216. If you look at
/proc/diskstats, the eleven fields will be preceded by the major and
minor device numbers, and device name. Each of these formats provide
@@ -93,35 +93,35 @@
To avoid introducing performance bottlenecks, no locks are held while
modifying these counters. This implies that minor inaccuracies may be
introduced when changes collide, so (for instance) adding up all the
-read I/Os issued per partition should equal those made to the disks
-... but due to the lack of locking it may only be very close.
+read I/Os issued per partition should equal those made to the disks ...
+but due to the lack of locking it may only be very close.
-In release 2.5.65 the 2.5 counters were made per-cpu, which made the lack
-of locking almost a non-issue. When the statistics are read, the per-cpu
-counters are summed (possibly overflowing the unsigned 32-bit variable
-they are summed to) and the result given to the user. There is no
-convenient user interface for accessing the per-cpu counters themselves.
+In 2.6, there are counters for each cpu, which made the lack of locking
+almost a non-issue. When the statistics are read, the per-cpu counters
+are summed (possibly overflowing the unsigned 32-bit variable they are
+summed to) and the result given to the user. There is no convenient
+user interface for accessing the per-cpu counters themselves.
Disks vs Partitions
-------------------
-There were significant changes between 2.4 and 2.5 in the I/O subsystem.
+There were significant changes between 2.4 and 2.6 in the I/O subsystem.
As a result, some statistic information disappeared. The translation from
a disk address relative to a partition to the disk address relative to
the host disk happens much earlier. All merges and timings now happen
at the disk level rather than at both the disk and partition level as
-in 2.4. Consequently, you'll see a different statistics output on 2.5 for
+in 2.4. Consequently, you'll see a different statistics output on 2.6 for
partitions from that for disks. There are only *four* fields available
-for partitions on 2.5 machines. This is reflected in the examples above.
+for partitions on 2.6 machines. This is reflected in the examples above.
Field 1 -- # of reads issued
This is the total number of reads issued to this partition.
Field 2 -- # of sectors read
This is the total number of sectors requested to be read from this
partition.
-Field 3 -- # of reads issued
+Field 3 -- # of writes issued
This is the total number of writes issued to this partition.
-Field 4 -- # of sectors read
+Field 4 -- # of sectors written
This is the total number of sectors requested to be written to
this partition.
@@ -135,14 +135,16 @@
Additional notes
----------------
-In 2.5, sysfs is not mounted by default. Here's the line you'll want
-to add to your /etc/fstab:
+In 2.6, sysfs is not mounted by default. If your distribution of
+Linux hasn't added it already, here's the line you'll want to add to
+your /etc/fstab:
none /sys sysfs defaults 0 0
-In 2.5, at the same time that disk statistics appeared in sysfs, they were
-removed from /proc/stat. In 2.4, they appear in both /proc/partitions
-and /proc/stat.
+In 2.6, all disk statistics were removed from /proc/stat. In 2.4, they
+appear in both /proc/partitions and /proc/stat, although the ones in
+/proc/stat take a very different format from those in /proc/partitions
+(see proc(5), if your system has it.)
-- ricklind@us.ibm.com
diff -Nru a/Documentation/kbuild/kconfig-language.txt b/Documentation/kbuild/kconfig-language.txt
--- a/Documentation/kbuild/kconfig-language.txt Wed Oct 8 12:24:56 2003
+++ b/Documentation/kbuild/kconfig-language.txt Wed Oct 8 12:24:56 2003
@@ -105,10 +105,13 @@
or equal to the first symbol and smaller than or equal to the second
symbol.
-- help text: "help"
+- help text: "help" or "---help---"
This defines a help text. The end of the help text is determined by
the indentation level, this means it ends at the first line which has
a smaller indentation than the first line of the help text.
+ "---help---" and "help" do not differ in behaviour, "---help---" is
+ used to help visually seperate configuration logic from help within
+ the file as an aid to developers.
Menu dependencies
diff -Nru a/Documentation/kbuild/makefiles.txt b/Documentation/kbuild/makefiles.txt
--- a/Documentation/kbuild/makefiles.txt Wed Oct 8 12:24:57 2003
+++ b/Documentation/kbuild/makefiles.txt Wed Oct 8 12:24:57 2003
@@ -212,7 +212,6 @@
No special notation is required in the makefiles for
modules exporting symbols.
- See also Documentation/modules.txt.
--- 3.5 Library file goals - lib-y
diff -Nru a/Documentation/kernel-doc-nano-HOWTO.txt b/Documentation/kernel-doc-nano-HOWTO.txt
--- a/Documentation/kernel-doc-nano-HOWTO.txt Wed Oct 8 12:24:56 2003
+++ b/Documentation/kernel-doc-nano-HOWTO.txt Wed Oct 8 12:24:56 2003
@@ -139,8 +139,7 @@
_not_ exported using EXPORT_SYMBOL.
!D is used to name additional files to search for functions
-exported using EXPORT_SYMBOL. For example many symbols are only exported
-in kernel/ksyms.c, therefore kernel-api.sgml include this file with !D.
+exported using EXPORT_SYMBOL.
!F is replaced by the
documentation, in , for the functions listed.
diff -Nru a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
--- a/Documentation/kernel-parameters.txt Wed Oct 8 12:24:57 2003
+++ b/Documentation/kernel-parameters.txt Wed Oct 8 12:24:57 2003
@@ -460,6 +460,10 @@
logibm_irq= [HW,MOUSE] Logitech Bus Mouse Driver
Format:
+ log_buf_len=n Sets the size of the printk ring buffer, in bytes.
+ Format is n, nk, nM. n must be a power of two. The
+ default is set in kernel config.
+
lp=0 [LP] Specify parallel ports to use, e.g,
lp=port[,port...] lp=none,parport0 (lp0 not configured, lp1 uses
lp=reset first parallel port). 'lp=0' disables the
diff -Nru a/Documentation/sched-coding.txt b/Documentation/sched-coding.txt
--- a/Documentation/sched-coding.txt Wed Oct 8 12:24:55 2003
+++ b/Documentation/sched-coding.txt Wed Oct 8 12:24:55 2003
@@ -47,7 +47,7 @@
and
- double_rq_unlock(runqueue_t *rq1, runqueue_t rq2)
+ double_rq_unlock(runqueue_t *rq1, runqueue_t *rq2)
safely lock and unlock, respectively, the two specified runqueues. They do
not, however, disable and restore interrupts. Users are required to do so
diff -Nru a/Documentation/scsi/ncr53c8xx.txt b/Documentation/scsi/ncr53c8xx.txt
--- a/Documentation/scsi/ncr53c8xx.txt Wed Oct 8 12:24:55 2003
+++ b/Documentation/scsi/ncr53c8xx.txt Wed Oct 8 12:24:55 2003
@@ -1025,7 +1025,7 @@
then it will for sure win the next SCSI BUS arbitration.
Since, there is no way to know what devices are trying to arbitrate for the
-BUS, using this feature can be extremally unfair. So, you are not advised
+BUS, using this feature can be extremely unfair. So, you are not advised
to enable it, or at most enable this feature for the case the chip lost
the previous arbitration (boot option 'iarb:1').
diff -Nru a/Documentation/sound/oss/Introduction b/Documentation/sound/oss/Introduction
--- a/Documentation/sound/oss/Introduction Wed Oct 8 12:24:57 2003
+++ b/Documentation/sound/oss/Introduction Wed Oct 8 12:24:57 2003
@@ -431,8 +431,7 @@
For More Information (RTFM):
============================
-1) Information on kernel modules: linux/Documentation/modules.txt
- and manual pages for insmod and modprobe.
+1) Information on kernel modules: manual pages for insmod and modprobe.
2) Information on PnP, RTFM manual pages for isapnp.
diff -Nru a/Documentation/sysrq.txt b/Documentation/sysrq.txt
--- a/Documentation/sysrq.txt Wed Oct 8 12:24:56 2003
+++ b/Documentation/sysrq.txt Wed Oct 8 12:24:56 2003
@@ -22,7 +22,10 @@
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
On x86 - You press the key combo 'ALT-SysRq-'. Note - Some
keyboards may not have a key labeled 'SysRq'. The 'SysRq' key is
- also known as the 'Print Screen' key.
+ also known as the 'Print Screen' key. Also some keyboards cannot
+ handle so many keys being pressed at the same time, so you might
+ have better luck with "press Alt", "press SysRq", "release Alt",
+ "press ", release everything.
On SPARC - You press 'ALT-STOP-', I believe.
diff -Nru a/Documentation/video4linux/CQcam.txt b/Documentation/video4linux/CQcam.txt
--- a/Documentation/video4linux/CQcam.txt Wed Oct 8 12:24:57 2003
+++ b/Documentation/video4linux/CQcam.txt Wed Oct 8 12:24:57 2003
@@ -71,8 +71,7 @@
2.1 Module Configuration
Using modules requires a bit of work to install and pass the
-parameters. Do read ../modules.txt, and understand that entries
-in /etc/modules.conf of:
+parameters. Understand that entries in /etc/modules.conf of:
alias parport_lowlevel parport_pc
options parport_pc io=0x378 irq=none
diff -Nru a/Documentation/vm/hugetlbpage.txt b/Documentation/vm/hugetlbpage.txt
--- a/Documentation/vm/hugetlbpage.txt Wed Oct 8 12:24:55 2003
+++ b/Documentation/vm/hugetlbpage.txt Wed Oct 8 12:24:55 2003
@@ -107,6 +107,7 @@
#include
#include
#include
+#include
extern int errno;
#define SHM_HUGETLB 04000
@@ -167,6 +168,7 @@
#include
#include
#include
+#include
#define FILE_NAME "/mnt/hugepagefile"
#define LENGTH (256*1024*1024)
diff -Nru a/Documentation/vm/locking b/Documentation/vm/locking
--- a/Documentation/vm/locking Wed Oct 8 12:24:56 2003
+++ b/Documentation/vm/locking Wed Oct 8 12:24:56 2003
@@ -1,4 +1,4 @@
-Started Oct 1999 by Kanoj Sarcar
+Started Oct 1999 by Kanoj Sarcar
The intent of this file is to have an uptodate, running commentary
from different people about how locking and synchronization is done
diff -Nru a/Documentation/zorro.txt b/Documentation/zorro.txt
--- a/Documentation/zorro.txt Wed Oct 8 12:24:57 2003
+++ b/Documentation/zorro.txt Wed Oct 8 12:24:57 2003
@@ -2,7 +2,7 @@
----------------------------------------
Written by Geert Uytterhoeven
-Last revised: February 27, 2000
+Last revised: September 5, 2003
1. Introduction
@@ -75,7 +75,7 @@
The treatment of these regions depends on the type of Zorro space:
- Zorro II address space is always mapped and does not have to be mapped
- explicitly using ioremap().
+ explicitly using z_ioremap().
Conversion from bus/physical Zorro II addresses to kernel virtual addresses
and vice versa is done using:
@@ -83,22 +83,20 @@
virt_addr = ZTWO_VADDR(bus_addr);
bus_addr = ZTWO_PADDR(virt_addr);
- - Zorro III address space must be mapped explicitly using ioremap() first
+ - Zorro III address space must be mapped explicitly using z_ioremap() first
before it can be accessed:
- virt_addr = ioremap(bus_addr, size);
+ virt_addr = z_ioremap(bus_addr, size);
...
- iounmap(virt_addr);
+ z_iounmap(virt_addr);
5. References
-------------
linux/include/linux/zorro.h
-linux/include/linux/ioport.h
-linux/include/asm-m68k/io.h
-linux/include/asm-m68k/amigahw.h
-linux/include/asm-ppc/io.h
+linux/include/asm-{m68k,ppc}/zorro.h
+linux/include/linux/zorro_ids.h
linux/drivers/zorro
/proc/bus/zorro
diff -Nru a/MAINTAINERS b/MAINTAINERS
--- a/MAINTAINERS Wed Oct 8 12:24:57 2003
+++ b/MAINTAINERS Wed Oct 8 12:24:57 2003
@@ -114,8 +114,8 @@
S: Maintained
8250/16?50 (AND CLONE UARTS) SERIAL DRIVER
-P: Theodore Ts'o
-M: tytso@mit.edu
+P: Russell King
+M: rmk+serial@arm.linux.org.uk
L: linux-serial@vger.kernel.org
W: http://serial.sourceforge.net
S: Maintained
@@ -284,6 +284,16 @@
L: linux-net@vger.kernel.org
S: Maintained
+ASUS ACPI EXTRAS DRIVER
+P: Karol Kozimor
+M: sziwan@users.sourceforge.net
+P: Julien Lerouge
+M: julien.lerouge@free.fr
+L: acpi4asus-user@lists.sourceforge.net
+W: http://sourceforge.net/projects/acpi4asus
+W: http://julien.lerouge.free.fr
+S: Maintained
+
ATM
P: Chas Williams
M: chas@cmf.nrl.navy.mil
@@ -509,7 +519,7 @@
CRYPTO API
P: James Morris
-M: jmorris@intercode.com.au
+M: jmorris@redhat.com
P: David S. Miller
M: davem@redhat.com
W http://samba.org/~jamesm/crypto/
@@ -624,7 +634,7 @@
P: Christoph Lameter
M: christoph@lameter.com
W: http://www.digi.com
-L: digilnux@dgii.com
+L: digilnux@digi.com
S: Orphaned
DIRECTORY NOTIFICATION
@@ -669,6 +679,12 @@
M: romieu@ensta.fr
S: Maintained
+DVB SUBSYSTEM AND DRIVERS
+P: LinuxTV.org Project
+L: linux-dvb@linuxtv.org
+W: http://linuxtv.org/developer/dvb.xml
+S: Supported
+
EATA-DMA SCSI DRIVER
P: Michael Neuffer
L: linux-eata@i-connect.net, linux-scsi@vger.kernel.org
@@ -798,7 +814,7 @@
GDT SCSI DISK ARRAY CONTROLLER DRIVER
P: Achim Leubner
-M: achim.leubner@intel.com
+M: achim_leubner@adaptec.com
L: linux-scsi@vger.kernel.org
W: http://www.icp-vortex.com/
S: Supported
@@ -1386,7 +1402,7 @@
P: Pekka Savola (ipv6)
M: pekkas@netcore.fi
P: James Morris
-M: jmorris@intercode.com.au
+M: jmorris@redhat.com
P: Hideaki YOSHIFUJI
M: yoshfuji@linux-ipv6.org
L: netdev@oss.sgi.com
@@ -1657,6 +1673,12 @@
L: linux-390@vm.marist.edu
W: http://oss.software.ibm.com/developerworks/opensource/linux390
S: Supported
+
+SAA7146 VIDEO4LINUX-2 DRIVER
+P: Michael Hunold
+M: michael@mihu.de
+W: http://www.mihu.de/linux/saa7146
+S: Maintained
SA1100 SUPPORT
P: Nicolas Pitre
diff -Nru a/Makefile b/Makefile
--- a/Makefile Wed Oct 8 12:24:57 2003
+++ b/Makefile Wed Oct 8 12:24:57 2003
@@ -1,7 +1,7 @@
VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 0
-EXTRAVERSION = -test6
+EXTRAVERSION = -test7
# *DOCUMENTATION*
# To see a list of typical targets execute "make help"
@@ -37,7 +37,7 @@
endif
endif
ifndef KBUILD_VERBOSE
- KBUILD_VERBOSE = 0
+ KBUILD_VERBOSE = 0
endif
# Call sparse as part of compilation of C files
@@ -79,16 +79,24 @@
endif
endif
+# That's our default target when none is given on the command line
+.PHONY: all
+all:
+
ifneq ($(KBUILD_OUTPUT),)
# Invoke a second make in the output directory, passing relevant variables
- KBUILD_OUTPUT := $(shell cd $(KBUILD_OUTPUT); /bin/pwd)
+# check that the output directory actually exists
+saved-output := $(KBUILD_OUTPUT)
+KBUILD_OUTPUT := $(shell cd $(KBUILD_OUTPUT) && /bin/pwd)
+$(if $(wildcard $(KBUILD_OUTPUT)),, \
+ $(error output directory "$(saved-output)" does not exist))
-.PHONY: $(MAKECMDGOALS) all
+.PHONY: $(MAKECMDGOALS)
-$(MAKECMDGOALS) all:
+$(filter-out all,$(MAKECMDGOALS)) all:
$(if $(KBUILD_VERBOSE:1=),@)$(MAKE) -C $(KBUILD_OUTPUT) \
KBUILD_SRC=$(CURDIR) KBUILD_VERBOSE=$(KBUILD_VERBOSE) \
- KBUILD_CHECK=$(KBUILD_CHECK) -f $(CURDIR)/Makefile $(MAKECMDGOALS)
+ KBUILD_CHECK=$(KBUILD_CHECK) -f $(CURDIR)/Makefile $@
# Leave processing to above invocation of make
skip-makefile := 1
@@ -156,13 +164,6 @@
HOSTCFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer
HOSTCXXFLAGS = -O2
-
-# That's our default target when none is given on the command line
-# Note that 'modules' will be added as a prerequisite as well,
-# in the CONFIG_MODULES part below
-
-all: vmlinux
-
# Decide whether to build built-in, modular, or both.
# Normally, just do built-in.
@@ -366,6 +367,12 @@
# Build targets only - this includes vmlinux, arch specific targets, clean
# targets and others. In general all targets except *config targets.
+# That's our default target when none is given on the command line
+# Note that 'modules' will be added as a prerequisite as well,
+# in the CONFIG_MODULES part below
+
+all: vmlinux
+
# Objects we will link into vmlinux / subdirs we need to visit
init-y := init/
drivers-y := drivers/ sound/
@@ -753,7 +760,7 @@
.menuconfig.log \
include/asm \
.hdepend include/linux/modversions.h \
- tags TAGS cscope.out kernel.spec \
+ tags TAGS cscope* kernel.spec \
.tmp*
# Directories removed with 'make mrproper'
@@ -877,7 +884,7 @@
@echo ' mrproper - remove all generated files + config + various backup files'
@echo ''
@echo 'Configuration targets:'
- @$(MAKE) -f scripts/kconfig/Makefile help
+ @$(MAKE) -f $(srctree)/scripts/kconfig/Makefile help
@echo ''
@echo 'Other generic targets:'
@echo ' all - Build all targets marked with [*]'
@@ -890,7 +897,7 @@
@echo ' tags/TAGS - Generate tags file for editors'
@echo ''
@echo 'Documentation targets:'
- @$(MAKE) -f Documentation/DocBook/Makefile dochelp
+ @$(MAKE) -f $(srctree)/Documentation/DocBook/Makefile dochelp
@echo ''
@echo 'Architecture specific targets ($(ARCH)):'
@$(if $(archhelp),$(archhelp),\
diff -Nru a/README b/README
--- a/README Wed Oct 8 12:24:57 2003
+++ b/README Wed Oct 8 12:24:57 2003
@@ -1,12 +1,9 @@
- Linux kernel release 2.5.xx
+ Linux kernel release 2.6.xx
-These are the release notes for Linux version 2.5. Read them carefully,
+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
kernel, and what to do if something goes wrong.
-NOTE! As with all odd-numbered releases, 2.5.x is a development kernel.
-For stable kernels, see the 2.4.x maintained by Marcelo Tosatti.
-
WHAT IS LINUX?
Linux is a Unix clone written from scratch by Linus Torvalds with
@@ -55,7 +52,7 @@
directory where you have permissions (eg. your home directory) and
unpack it:
- gzip -cd linux-2.5.XX.tar.gz | tar xvf -
+ gzip -cd linux-2.6.XX.tar.gz | tar xvf -
Replace "XX" with the version number of the latest kernel.
@@ -64,15 +61,15 @@
files. They should match the library, and not get messed up by
whatever the kernel-du-jour happens to be.
- - You can also upgrade between 2.5.xx releases by patching. Patches are
+ - You can also upgrade between 2.6.xx releases by patching. Patches are
distributed in the traditional gzip and the new bzip2 format. To
install by patching, get all the newer patch files, enter the
- top level directory of the kernel source (linux-2.5.xx) and execute:
+ top level directory of the kernel source (linux-2.6.xx) and execute:
- gzip -cd ../patch-2.5.xx.gz | patch -p1
+ gzip -cd ../patch-2.6.xx.gz | patch -p1
or
- bzip2 -dc ../patch-2.5.xx.bz2 | patch -p1
+ bzip2 -dc ../patch-2.6.xx.bz2 | patch -p1
(repeat xx for all versions bigger than the version of your current
source tree, _in_order_) and you should be ok. You may want to remove
@@ -99,7 +96,7 @@
SOFTWARE REQUIREMENTS
- Compiling and running the 2.5.xx kernels requires up-to-date
+ Compiling and running the 2.6.xx kernels requires up-to-date
versions of various software packages. Consult
./Documentation/Changes for the minimum version numbers required
and how to get updates for these packages. Beware that using
@@ -193,8 +190,6 @@
- If you configured any of the parts of the kernel as `modules', you
will have to do "make modules" followed by "make modules_install".
- Read Documentation/modules.txt for more information. For example,
- an explanation of how to use the modules is included there.
- Keep a backup kernel handy in case something goes wrong. This is
especially true for the development releases, since each new release
diff -Nru a/arch/alpha/Kconfig b/arch/alpha/Kconfig
--- a/arch/alpha/Kconfig Wed Oct 8 12:24:57 2003
+++ b/arch/alpha/Kconfig Wed Oct 8 12:24:57 2003
@@ -471,21 +471,6 @@
bool
depends on ALPHA_GENERIC || ALPHA_JENSEN || ALPHA_ALCOR || ALPHA_MIKASA || ALPHA_SABLE || ALPHA_LYNX || ALPHA_NORITAKE || ALPHA_RAWHIDE
default y
- ---help---
- The Extended Industry Standard Architecture (EISA) bus was
- developed as an open alternative to the IBM MicroChannel bus.
-
- The EISA bus provided some of the features of the IBM MicroChannel
- bus while maintaining backward compatibility with cards made for
- the older ISA bus. The EISA bus saw limited use between 1988 and
- 1995 when it was made obsolete by the PCI bus.
-
- Say Y here if you are building a kernel for an EISA-based machine.
-
- Otherwise, say N.
-
-config EISA_ALWAYS
- def_bool EISA
config SMP
bool "Symmetric multi-processing support"
diff -Nru a/arch/alpha/kernel/core_irongate.c b/arch/alpha/kernel/core_irongate.c
--- a/arch/alpha/kernel/core_irongate.c Wed Oct 8 12:24:57 2003
+++ b/arch/alpha/kernel/core_irongate.c Wed Oct 8 12:24:57 2003
@@ -391,7 +391,7 @@
cur_gatt = phys_to_virt(GET_GATT(baddr) & ~1);
pte = cur_gatt[GET_GATT_OFF(baddr)] & ~1;
- if (__alpha_remap_area_pages(VMALLOC_VMADDR(vaddr),
+ if (__alpha_remap_area_pages(vaddr,
pte, PAGE_SIZE, 0)) {
printk("AGP ioremap: FAILED to map...\n");
vfree(area->addr);
diff -Nru a/arch/alpha/kernel/core_marvel.c b/arch/alpha/kernel/core_marvel.c
--- a/arch/alpha/kernel/core_marvel.c Wed Oct 8 12:24:55 2003
+++ b/arch/alpha/kernel/core_marvel.c Wed Oct 8 12:24:55 2003
@@ -696,7 +696,7 @@
}
pfn >>= 1; /* make it a true pfn */
- if (__alpha_remap_area_pages(VMALLOC_VMADDR(vaddr),
+ if (__alpha_remap_area_pages(vaddr,
pfn << PAGE_SHIFT,
PAGE_SIZE, 0)) {
printk("FAILED to map...\n");
diff -Nru a/arch/alpha/kernel/core_titan.c b/arch/alpha/kernel/core_titan.c
--- a/arch/alpha/kernel/core_titan.c Wed Oct 8 12:24:56 2003
+++ b/arch/alpha/kernel/core_titan.c Wed Oct 8 12:24:56 2003
@@ -534,7 +534,7 @@
}
pfn >>= 1; /* make it a true pfn */
- if (__alpha_remap_area_pages(VMALLOC_VMADDR(vaddr),
+ if (__alpha_remap_area_pages(vaddr,
pfn << PAGE_SHIFT,
PAGE_SIZE, 0)) {
printk("FAILED to map...\n");
diff -Nru a/arch/alpha/kernel/init_task.c b/arch/alpha/kernel/init_task.c
--- a/arch/alpha/kernel/init_task.c Wed Oct 8 12:24:56 2003
+++ b/arch/alpha/kernel/init_task.c Wed Oct 8 12:24:56 2003
@@ -1,4 +1,5 @@
#include
+#include
#include
#include
#include
@@ -12,6 +13,9 @@
static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
struct mm_struct init_mm = INIT_MM(init_mm);
struct task_struct init_task = INIT_TASK(init_task);
+
+EXPORT_SYMBOL(init_mm);
+EXPORT_SYMBOL(init_task);
union thread_union init_thread_union
__attribute__((section(".data.init_thread")))
diff -Nru a/arch/alpha/kernel/irq.c b/arch/alpha/kernel/irq.c
--- a/arch/alpha/kernel/irq.c Wed Oct 8 12:24:57 2003
+++ b/arch/alpha/kernel/irq.c Wed Oct 8 12:24:57 2003
@@ -12,6 +12,7 @@
#include
#include
+#include
#include
#include
#include
@@ -472,6 +473,8 @@
return retval;
}
+EXPORT_SYMBOL(request_irq);
+
void
free_irq(unsigned int irq, void *dev_id)
{
@@ -518,6 +521,8 @@
}
}
+EXPORT_SYMBOL(free_irq);
+
int
show_interrupts(struct seq_file *p, void *v)
{
@@ -752,6 +757,8 @@
return val;
}
+EXPORT_SYMBOL(probe_irq_on);
+
/*
* Return a mask of triggered interrupts (this
* can handle only legacy ISA interrupts).
@@ -822,6 +829,8 @@
irq_found = -irq_found;
return irq_found;
}
+
+EXPORT_SYMBOL(probe_irq_off);
#ifdef CONFIG_SMP
void synchronize_irq(unsigned int irq)
diff -Nru a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c
--- a/arch/alpha/kernel/process.c Wed Oct 8 12:24:57 2003
+++ b/arch/alpha/kernel/process.c Wed Oct 8 12:24:57 2003
@@ -10,6 +10,7 @@
#include
#include
+#include
#include
#include
#include
@@ -164,17 +165,23 @@
common_shutdown(LINUX_REBOOT_CMD_RESTART, restart_cmd);
}
+EXPORT_SYMBOL(machine_restart);
+
void
machine_halt(void)
{
common_shutdown(LINUX_REBOOT_CMD_HALT, NULL);
}
+EXPORT_SYMBOL(machine_halt);
+
void
machine_power_off(void)
{
common_shutdown(LINUX_REBOOT_CMD_POWER_OFF, NULL);
}
+
+EXPORT_SYMBOL(machine_power_off);
/* Used by sysrq-p, among others. I don't believe r9-r15 are ever
saved in the context it's used. */
diff -Nru a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c
--- a/arch/alpha/kernel/setup.c Wed Oct 8 12:24:56 2003
+++ b/arch/alpha/kernel/setup.c Wed Oct 8 12:24:56 2003
@@ -33,6 +33,7 @@
#include
#include
#include
+#include
#ifdef CONFIG_MAGIC_SYSRQ
#include
#include
@@ -680,6 +681,11 @@
/* Default root filesystem to sda2. */
ROOT_DEV = Root_SDA2;
+#ifdef CONFIG_EISA
+ /* FIXME: only set this when we actually have EISA in this box? */
+ EISA_bus = 1;
+#endif
+
/*
* Check ASN in HWRPB for validity, report if bad.
* FIXME: how was this failing? Should we trust it instead,
@@ -1203,7 +1209,7 @@
platform_string(), nr_processors);
#ifdef CONFIG_SMP
- seq_printf(f, "cpus active\t\t: %d\n"
+ seq_printf(f, "cpus active\t\t: %ld\n"
"cpu active mask\t\t: %016lx\n",
num_online_cpus(), cpu_present_mask);
#endif
diff -Nru a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c
--- a/arch/alpha/kernel/smp.c Wed Oct 8 12:24:56 2003
+++ b/arch/alpha/kernel/smp.c Wed Oct 8 12:24:56 2003
@@ -13,6 +13,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -73,6 +74,8 @@
unsigned long cpu_present_mask;
cpumask_t cpu_online_map;
+EXPORT_SYMBOL(cpu_online_map);
+
/* cpus reported in the hwrpb */
static unsigned long hwrpb_cpu_present_mask __initdata = 0;
@@ -597,7 +600,7 @@
if (cpu_online(cpu))
bogosum += cpu_data[cpu].loops_per_jiffy;
- printk(KERN_INFO "SMP: Total of %d processors activated "
+ printk(KERN_INFO "SMP: Total of %ld processors activated "
"(%lu.%02lu BogoMIPS).\n",
num_online_cpus(),
(bogosum + 2500) / (500000/HZ),
diff -Nru a/arch/alpha/kernel/time.c b/arch/alpha/kernel/time.c
--- a/arch/alpha/kernel/time.c Wed Oct 8 12:24:56 2003
+++ b/arch/alpha/kernel/time.c Wed Oct 8 12:24:56 2003
@@ -27,6 +27,7 @@
*/
#include
#include
+#include
#include
#include
#include
@@ -52,6 +53,8 @@
u64 jiffies_64 = INITIAL_JIFFIES;
+EXPORT_SYMBOL(jiffies_64);
+
extern unsigned long wall_jiffies; /* kernel/timer.c */
static int set_rtc_mmss(unsigned long);
@@ -89,6 +92,16 @@
return result;
}
+/*
+ * Scheduler clock - returns current time in nanosec units.
+ *
+ * Copied from ARM code for expediency... ;-}
+ */
+unsigned long long sched_clock(void)
+{
+ return (unsigned long long)jiffies * (1000000000 / HZ);
+}
+
/*
* timer_interrupt() needs to keep up the real-time clock,
@@ -239,8 +252,9 @@
* arch/i386/time.c.
*/
-#define CALIBRATE_LATCH (52 * LATCH)
-#define CALIBRATE_TIME (52 * 1000020 / HZ)
+#define PIC_TICK_RATE 1193180UL
+#define CALIBRATE_LATCH 0xffff
+#define TIMEOUT_COUNT 0x100000
static unsigned long __init
calibrate_cc_with_pic(void)
@@ -263,19 +277,15 @@
cc = rpcc();
do {
- count+=100; /* by 1 takes too long to timeout from 0 */
- } while ((inb(0x61) & 0x20) == 0 && count > 0);
+ count++;
+ } while ((inb(0x61) & 0x20) == 0 && count < TIMEOUT_COUNT);
cc = rpcc() - cc;
/* Error: ECTCNEVERSET or ECPUTOOFAST. */
- if (count <= 100)
- return 0;
-
- /* Error: ECPUTOOSLOW. */
- if (cc <= CALIBRATE_TIME)
+ if (count <= 1 || count == TIMEOUT_COUNT)
return 0;
- return (cc * 1000000UL) / CALIBRATE_TIME;
+ return ((long)cc * PIC_TICK_RATE) / (CALIBRATE_LATCH + 1);
}
/* The Linux interpretation of the CMOS clock register contents:
@@ -450,6 +460,8 @@
tv->tv_usec = usec;
}
+EXPORT_SYMBOL(do_gettimeofday);
+
int
do_settimeofday(struct timespec *tv)
{
@@ -493,6 +505,8 @@
write_sequnlock_irq(&xtime_lock);
return 0;
}
+
+EXPORT_SYMBOL(do_settimeofday);
/*
diff -Nru a/arch/alpha/kernel/traps.c b/arch/alpha/kernel/traps.c
--- a/arch/alpha/kernel/traps.c Wed Oct 8 12:24:57 2003
+++ b/arch/alpha/kernel/traps.c Wed Oct 8 12:24:57 2003
@@ -177,6 +177,8 @@
show_stack(NULL, NULL);
}
+EXPORT_SYMBOL(dump_stack);
+
void
die_if_kernel(char * str, struct pt_regs *regs, long err, unsigned long *r9_15)
{
diff -Nru a/arch/alpha/lib/checksum.c b/arch/alpha/lib/checksum.c
--- a/arch/alpha/lib/checksum.c Wed Oct 8 12:24:56 2003
+++ b/arch/alpha/lib/checksum.c Wed Oct 8 12:24:56 2003
@@ -9,6 +9,7 @@
* Rick Gorton
*/
+#include
#include
#include
@@ -172,6 +173,8 @@
result = (result & 0xffffffff) + (result >> 32);
return result;
}
+
+EXPORT_SYMBOL(csum_partial);
/*
* this routine is used for miscellaneous IP-like checksums, mainly
diff -Nru a/arch/alpha/mm/init.c b/arch/alpha/mm/init.c
--- a/arch/alpha/mm/init.c Wed Oct 8 12:24:57 2003
+++ b/arch/alpha/mm/init.c Wed Oct 8 12:24:57 2003
@@ -210,7 +210,8 @@
/* Allocate one PGD and one PMD. In the case of SRM, we'll need
these to actually remap the console. There is an assumption
here that only one of each is needed, and this allows for 8MB.
- Currently (late 1999), big consoles are still under 4MB.
+ On systems with larger consoles, additional pages will be
+ allocated as needed during the mapping process.
In the case of not SRM, but not CONFIG_ALPHA_LARGE_VMALLOC,
we need to allocate the PGD we use for vmalloc before we start
@@ -237,6 +238,15 @@
unsigned long pfn = crb->map[i].pa >> PAGE_SHIFT;
crb->map[i].va = vaddr;
for (j = 0; j < crb->map[i].count; ++j) {
+ /* Newer console's (especially on larger
+ systems) may require more pages of
+ PTEs. Grab additional pages as needed. */
+ if (pmd != pmd_offset(pgd, vaddr)) {
+ memset(kernel_end, 0, PAGE_SIZE);
+ pmd = pmd_offset(pgd, vaddr);
+ pmd_set(pmd, (pte_t *)kernel_end);
+ kernel_end += PAGE_SIZE;
+ }
set_pte(pte_offset_kernel(pmd, vaddr),
pfn_pte(pfn, PAGE_KERNEL));
pfn++;
diff -Nru a/arch/arm/Kconfig b/arch/arm/Kconfig
--- a/arch/arm/Kconfig Wed Oct 8 12:24:56 2003
+++ b/arch/arm/Kconfig Wed Oct 8 12:24:56 2003
@@ -239,7 +239,7 @@
# Now handle the bus types
config PCI
- bool "PCI support" if ARCH_INTEGRATOR
+ bool "PCI support" if ARCH_INTEGRATOR_AP
default y if ARCH_FTVPCI || ARCH_SHARK || FOOTBRIDGE_HOST || ARCH_IOP3XX
help
Find out whether you have a PCI motherboard. PCI is the name of a
@@ -644,8 +644,6 @@
source "drivers/misc/Kconfig"
source "drivers/usb/Kconfig"
-
-source "net/bluetooth/Kconfig"
menu "Kernel hacking"
diff -Nru a/arch/arm/Makefile b/arch/arm/Makefile
--- a/arch/arm/Makefile Wed Oct 8 12:24:56 2003
+++ b/arch/arm/Makefile Wed Oct 8 12:24:56 2003
@@ -182,7 +182,6 @@
echo '* zImage - Compressed kernel image (arch/$(ARCH)/boot/zImage)'
echo ' Image - Uncompressed kernel image (arch/$(ARCH)/boot/Image)'
echo ' bootpImage - Combined zImage and initial RAM disk'
- echo ' initrd - Create an initial image'
echo ' install - Install uncompressed kernel'
echo ' zinstall - Install compressed kernel'
echo ' Install using (your) ~/bin/installkernel or'
diff -Nru a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
--- a/arch/arm/boot/compressed/head.S Wed Oct 8 12:24:57 2003
+++ b/arch/arm/boot/compressed/head.S Wed Oct 8 12:24:57 2003
@@ -477,6 +477,12 @@
@ b __arm6_cache_off
@ b __armv3_cache_flush
+ .word 0x00000000 @ old ARM ID
+ .word 0x0000f000
+ mov pc, lr
+ mov pc, lr
+ mov pc, lr
+
.word 0x41007000 @ ARM7/710
.word 0xfff8fe00
b __arm7_cache_off
@@ -489,6 +495,14 @@
b __armv4_cache_off
mov pc, lr
+ .word 0x00007000 @ ARM7 IDs
+ .word 0x0000f000
+ mov pc, lr
+ mov pc, lr
+ mov pc, lr
+
+ @ Everything from here on will be the new ID system.
+
.word 0x41129200 @ ARM920T
.word 0xff00fff0
b __armv4_cache_on
@@ -507,8 +521,16 @@
b __armv4_cache_off
b __armv4_cache_flush
- .word 0x69050000 @ xscale
- .word 0xffff0000
+ @ These match on the architecture ID
+
+ .word 0x00050000 @ ARMv5TE
+ .word 0x000f0000
+ b __armv4_cache_on
+ b __armv4_cache_off
+ b __armv4_cache_flush
+
+ .word 0x00060000 @ ARMv5TEJ
+ .word 0x000f0000
b __armv4_cache_on
b __armv4_cache_off
b __armv4_cache_flush
diff -Nru a/arch/arm/common/sa1111-pcipool.c b/arch/arm/common/sa1111-pcipool.c
--- a/arch/arm/common/sa1111-pcipool.c Wed Oct 8 12:24:57 2003
+++ b/arch/arm/common/sa1111-pcipool.c Wed Oct 8 12:24:57 2003
@@ -274,7 +274,6 @@
schedule_timeout (POOL_TIMEOUT_JIFFIES);
- current->state = TASK_RUNNING;
remove_wait_queue (&pool->waitq, &wait);
goto restart;
}
diff -Nru a/arch/arm/kernel/apm.c b/arch/arm/kernel/apm.c
--- a/arch/arm/kernel/apm.c Wed Oct 8 12:24:57 2003
+++ b/arch/arm/kernel/apm.c Wed Oct 8 12:24:57 2003
@@ -179,13 +179,10 @@
wake_up_interruptible(&apm_waitqueue);
}
-/* defined in pm.c */
-extern int suspend(void);
-
static int apm_suspend(void)
{
struct list_head *l;
- int err = suspend();
+ int err = pm_suspend(PM_SUSPEND_MEM);
/*
* Anyone on the APM queues will think we're still suspended.
diff -Nru a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
--- a/arch/arm/kernel/entry-armv.S Wed Oct 8 12:24:56 2003
+++ b/arch/arm/kernel/entry-armv.S Wed Oct 8 12:24:56 2003
@@ -439,20 +439,25 @@
.macro get_irqnr_and_base, irqnr, irqstat, base, tmp
/* FIXME: should not be using soo many LDRs here */
- ldr \irqnr, =IO_ADDRESS(INTEGRATOR_IC_BASE)
- ldr \irqstat, [\irqnr, #IRQ_STATUS] @ get masked status
- ldr \irqnr, =IO_ADDRESS(INTEGRATOR_HDR_BASE)
- ldr \irqnr, [\irqnr, #(INTEGRATOR_HDR_IC_OFFSET+IRQ_STATUS)]
- orr \irqstat, \irqstat, \irqnr, lsl #INTEGRATOR_CM_INT0
+ ldr \base, =IO_ADDRESS(INTEGRATOR_IC_BASE)
+ mov \irqnr, #IRQ_PIC_START
+ ldr \irqstat, [\base, #IRQ_STATUS] @ get masked status
+ ldr \base, =IO_ADDRESS(INTEGRATOR_HDR_BASE)
+ teq \irqstat, #0
+ ldreq \irqstat, [\base, #(INTEGRATOR_HDR_IC_OFFSET+IRQ_STATUS)]
+ moveq \irqnr, #IRQ_CIC_START
- mov \irqnr, #0
-1001: tst \irqstat, #1
+1001: tst \irqstat, #15
bne 1002f
+ add \irqnr, \irqnr, #4
+ movs \irqstat, \irqstat, lsr #4
+ bne 1001b
+1002: tst \irqstat, #1
+ bne 1003f
add \irqnr, \irqnr, #1
- mov \irqstat, \irqstat, lsr #1
- cmp \irqnr, #22
- bcc 1001b
-1002: /* EQ will be set if we reach 22 */
+ movs \irqstat, \irqstat, lsr #1
+ bne 1002b
+1003: /* EQ will be set if no irqs pending */
.endm
.macro irq_prio_table
diff -Nru a/arch/arm/kernel/init_task.c b/arch/arm/kernel/init_task.c
--- a/arch/arm/kernel/init_task.c Wed Oct 8 12:24:57 2003
+++ b/arch/arm/kernel/init_task.c Wed Oct 8 12:24:57 2003
@@ -2,6 +2,7 @@
* linux/arch/arm/kernel/init_task.c
*/
#include
+#include
#include
#include
#include
@@ -16,6 +17,8 @@
static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
struct mm_struct init_mm = INIT_MM(init_mm);
+EXPORT_SYMBOL(init_mm);
+
/*
* Initial thread structure.
*
@@ -36,3 +39,5 @@
* All other task structs will be allocated on slabs in fork.c
*/
struct task_struct init_task = INIT_TASK(init_task);
+
+EXPORT_SYMBOL(init_task);
diff -Nru a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
--- a/arch/arm/kernel/irq.c Wed Oct 8 12:24:55 2003
+++ b/arch/arm/kernel/irq.c Wed Oct 8 12:24:55 2003
@@ -19,6 +19,7 @@
*/
#include
#include
+#include
#include
#include
#include
@@ -653,6 +654,8 @@
return retval;
}
+EXPORT_SYMBOL(request_irq);
+
/**
* free_irq - free an interrupt
* @irq: Interrupt line to free
@@ -696,6 +699,8 @@
}
}
+EXPORT_SYMBOL(free_irq);
+
static DECLARE_MUTEX(probe_sem);
/* Start the interrupt probing. Unlike other architectures,
@@ -750,6 +755,8 @@
return irqs;
}
+EXPORT_SYMBOL(probe_irq_on);
+
unsigned int probe_irq_mask(unsigned long irqs)
{
unsigned int mask = 0, i;
@@ -800,6 +807,8 @@
return irq_found;
}
+
+EXPORT_SYMBOL(probe_irq_off);
void __init init_irq_proc(void)
{
diff -Nru a/arch/arm/kernel/pm.c b/arch/arm/kernel/pm.c
--- a/arch/arm/kernel/pm.c Wed Oct 8 12:24:57 2003
+++ b/arch/arm/kernel/pm.c Wed Oct 8 12:24:57 2003
@@ -9,68 +9,18 @@
* sleep.
*/
#include
+#include
+#include
#include
-#include
-#include
#include
#include
-#include
-#include
-
-/*
- * Tell the linker that pm_do_suspend may not be present.
- */
-extern int pm_do_suspend(void) __attribute__((weak));
-
-int suspend(void)
-{
- int ret;
-
- if (!pm_do_suspend)
- return -ENOSYS;
-
- /*
- * Suspend "legacy" devices.
- */
- ret = pm_send_all(PM_SUSPEND, (void *)3);
- if (ret != 0)
- goto out;
-
- ret = device_suspend(3);
- if (ret)
- goto resume_legacy;
-
- local_irq_disable();
- leds_event(led_stop);
-
- sysdev_suspend(3);
-
- ret = pm_do_suspend();
-
- sysdev_resume();
-
- leds_event(led_start);
- local_irq_enable();
-
- device_resume();
-
- resume_legacy:
- pm_send_all(PM_RESUME, (void *)0);
-
- out:
- return ret;
-}
-
#ifdef CONFIG_SYSCTL
/*
* We really want this to die. It's a disgusting hack using unallocated
* sysctl numbers. We should be using a real interface.
*/
-#include
-#include
-
static int
pm_sysctl_proc_handler(ctl_table *ctl, int write, struct file *filp,
void *buffer, size_t *lenp)
@@ -79,7 +29,7 @@
printk("PM: task %s (pid %d) uses deprecated sysctl PM interface\n",
current->comm, current->pid);
if (write)
- ret = suspend();
+ ret = pm_suspend(PM_SUSPEND_MEM);
return ret;
}
diff -Nru a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
--- a/arch/arm/kernel/process.c Wed Oct 8 12:24:57 2003
+++ b/arch/arm/kernel/process.c Wed Oct 8 12:24:57 2003
@@ -45,11 +45,15 @@
hlt_counter++;
}
+EXPORT_SYMBOL(disable_hlt);
+
void enable_hlt(void)
{
hlt_counter--;
}
+EXPORT_SYMBOL(enable_hlt);
+
static int __init nohlt_setup(char *__unused)
{
hlt_counter = 1;
@@ -117,16 +121,18 @@
void machine_halt(void)
{
- leds_event(led_halted);
}
+EXPORT_SYMBOL(machine_halt);
+
void machine_power_off(void)
{
- leds_event(led_halted);
if (pm_power_off)
pm_power_off();
}
+EXPORT_SYMBOL(machine_power_off);
+
void machine_restart(char * __unused)
{
/*
@@ -154,6 +160,8 @@
printk("Reboot failed -- System halted\n");
while (1);
}
+
+EXPORT_SYMBOL(machine_restart);
void show_regs(struct pt_regs * regs)
{
diff -Nru a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
--- a/arch/arm/kernel/setup.c Wed Oct 8 12:24:56 2003
+++ b/arch/arm/kernel/setup.c Wed Oct 8 12:24:56 2003
@@ -182,7 +182,7 @@
"5",
"5T",
"5TE",
- "?(8)",
+ "5TEJ",
"?(9)",
"?(10)",
"?(11)",
diff -Nru a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
--- a/arch/arm/kernel/signal.c Wed Oct 8 12:24:55 2003
+++ b/arch/arm/kernel/signal.c Wed Oct 8 12:24:55 2003
@@ -21,6 +21,7 @@
#include
#include
#include
+#include
#include
#include
@@ -539,6 +540,11 @@
if (!user_mode(regs))
return 0;
+ if (current->flags & PF_FREEZE) {
+ refrigerator(0);
+ goto no_signal;
+ }
+
if (current->ptrace & PT_SINGLESTEP)
ptrace_cancel_bpt(current);
@@ -550,6 +556,7 @@
return 1;
}
+ no_signal:
/*
* No signal to deliver to the process - restart the syscall.
*/
diff -Nru a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c
--- a/arch/arm/kernel/time.c Wed Oct 8 12:24:57 2003
+++ b/arch/arm/kernel/time.c Wed Oct 8 12:24:57 2003
@@ -26,6 +26,7 @@
#include
#include
#include
+#include
#include
#include
@@ -34,6 +35,8 @@
u64 jiffies_64 = INITIAL_JIFFIES;
+EXPORT_SYMBOL(jiffies_64);
+
extern unsigned long wall_jiffies;
/* this needs a better home */
@@ -72,8 +75,6 @@
*/
unsigned long long sched_clock(void)
{
- unsigned long long this_offset;
-
return (unsigned long long)jiffies * (1000000000 / HZ);
}
@@ -137,6 +138,47 @@
void (*leds_event)(led_event_t) = dummy_leds_event;
+static int leds_suspend(struct sys_device *dev, u32 state)
+{
+ leds_event(led_stop);
+ return 0;
+}
+
+static int leds_resume(struct sys_device *dev)
+{
+ leds_event(led_start);
+ return 0;
+}
+
+static int leds_shutdown(struct sys_device *dev)
+{
+ leds_event(led_halted);
+ return 0;
+}
+
+static struct sysdev_class leds_sysclass = {
+ set_kset_name("leds"),
+ .shutdown = leds_shutdown,
+ .suspend = leds_suspend,
+ .resume = leds_resume,
+};
+
+static struct sys_device leds_device = {
+ .id = 0,
+ .cls = &leds_sysclass,
+};
+
+static int __init leds_init(void)
+{
+ int ret;
+ ret = sysdev_class_register(&leds_sysclass);
+ if (ret == 0)
+ ret = sys_device_register(&leds_device);
+ return ret;
+}
+
+device_initcall(leds_init);
+
EXPORT_SYMBOL(leds_event);
#endif
@@ -182,6 +224,8 @@
tv->tv_usec = usec;
}
+EXPORT_SYMBOL(do_gettimeofday);
+
int do_settimeofday(struct timespec *tv)
{
time_t wtm_sec, sec = tv->tv_sec;
@@ -214,6 +258,8 @@
clock_was_set();
return 0;
}
+
+EXPORT_SYMBOL(do_settimeofday);
static struct irqaction timer_irq = {
.name = "timer",
diff -Nru a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
--- a/arch/arm/kernel/traps.c Wed Oct 8 12:24:56 2003
+++ b/arch/arm/kernel/traps.c Wed Oct 8 12:24:56 2003
@@ -178,6 +178,8 @@
#endif
}
+EXPORT_SYMBOL(dump_stack);
+
void show_stack(struct task_struct *tsk, unsigned long *sp)
{
unsigned long fp;
@@ -212,10 +214,10 @@
printk("CPU: %d\n", smp_processor_id());
show_regs(regs);
printk("Process %s (pid: %d, stack limit = 0x%p)\n",
- current->comm, current->pid, tsk->thread_info + 1);
+ tsk->comm, tsk->pid, tsk->thread_info + 1);
if (!user_mode(regs) || in_interrupt()) {
- dump_mem("Stack: ", (unsigned long)(regs + 1), 8192+(unsigned long)tsk->thread_info);
+ dump_mem("Stack: ", regs->ARM_sp, 8192+(unsigned long)tsk->thread_info);
dump_backtrace(regs, tsk);
dump_instr(regs);
}
diff -Nru a/arch/arm/lib/io-readsl-armv4.S b/arch/arm/lib/io-readsl-armv4.S
--- a/arch/arm/lib/io-readsl-armv4.S Wed Oct 8 12:24:57 2003
+++ b/arch/arm/lib/io-readsl-armv4.S Wed Oct 8 12:24:57 2003
@@ -9,7 +9,6 @@
*/
#include
#include
-#include
/*
* Note that some reads can be aligned on half-word boundaries.
@@ -31,6 +30,10 @@
blt 4f
bgt 6f
+#ifndef __ARMEB__
+
+ /* little endian code */
+
strh ip, [r1], #2
mov ip, ip, lsr #16
3: subs r2, r2, #1
@@ -67,4 +70,49 @@
mov ip, ip, lsr #16
strb ip, [r1]
mov pc, lr
+
+#else
+
+ /* big endian code */
+
+
+ mov r3, ip, lsr #16
+ strh r3, [r1], #2
+3: mov r3, ip, lsl #16
+ subs r2, r2, #1
+ ldrne ip, [r0]
+ orrne r3, r3, ip, lsr #16
+ strne r3, [r1], #4
+ bne 3b
+ strh ip, [r1], #2
+ mov pc, lr
+
+4: mov r3, ip, lsr #24
+ strb r3, [r1], #1
+ mov r3, ip, lsr #8
+ strh r3, [r1], #2
+5: mov r3, ip, lsl #24
+ subs r2, r2, #1
+ ldrne ip, [r0]
+ orrne r3, r3, ip, lsr #8
+ strne r3, [r1], #4
+ bne 5b
+ strb ip, [r1], #1
+ mov pc, lr
+
+6: mov r3, ip, lsr #24
+ strb r3, [r1], #1
+7: mov r3, ip, lsl #8
+ subs r2, r2, #1
+ ldrne ip, [r0]
+ orrne r3, r3, ip, lsr #24
+ strne r3, [r1], #4
+ bne 7b
+ mov r3, ip, lsr #8
+ strh r3, [r1], #2
+ strb ip, [r1], #1
+ mov pc, lr
+
+#endif
+
diff -Nru a/arch/arm/lib/io-readsw-armv4.S b/arch/arm/lib/io-readsw-armv4.S
--- a/arch/arm/lib/io-readsw-armv4.S Wed Oct 8 12:24:57 2003
+++ b/arch/arm/lib/io-readsw-armv4.S Wed Oct 8 12:24:57 2003
@@ -9,7 +9,14 @@
*/
#include
#include
-#include
+
+ .macro pack, rd, hw1, hw2
+#ifndef __ARMEB__
+ orr \rd, \hw1, \hw2, lsl #16
+#else
+ orr \rd, \hw2, \hw1, lsl #16
+#endif
+ .endm
.insw_bad_alignment:
adr r0, .insw_bad_align_msg
@@ -41,19 +48,19 @@
.insw_8_lp: ldrh r3, [r0]
ldrh r4, [r0]
- orr r3, r3, r4, lsl #16
+ pack r3, r3, r4
ldrh r4, [r0]
ldrh r5, [r0]
- orr r4, r4, r5, lsl #16
+ pack r4, r4, r5
ldrh r5, [r0]
ldrh ip, [r0]
- orr r5, r5, ip, lsl #16
+ pack r5, r5, ip
ldrh ip, [r0]
ldrh lr, [r0]
- orr ip, ip, lr, lsl #16
+ pack ip, ip, lr
stmia r1!, {r3 - r5, ip}
@@ -68,11 +75,11 @@
ldrh r3, [r0]
ldrh r4, [r0]
- orr r3, r3, r4, lsl #16
+ pack r3, r3, r4
ldrh r4, [r0]
ldrh ip, [r0]
- orr r4, r4, ip, lsl #16
+ pack r4, r4, ip
stmia r1!, {r3, r4}
@@ -81,7 +88,7 @@
ldrh r3, [r0]
ldrh ip, [r0]
- orr r3, r3, ip, lsl #16
+ pack r3, r3, ip
str r3, [r1], #4
diff -Nru a/arch/arm/lib/io-writesw-armv4.S b/arch/arm/lib/io-writesw-armv4.S
--- a/arch/arm/lib/io-writesw-armv4.S Wed Oct 8 12:24:57 2003
+++ b/arch/arm/lib/io-writesw-armv4.S Wed Oct 8 12:24:57 2003
@@ -9,7 +9,18 @@
*/
#include
#include
-#include
+
+ .macro outword, rd
+#ifndef __ARMEB__
+ strh \rd, [r0]
+ mov \rd, \rd, lsr #16
+ strh \rd, [r0]
+#else
+ mov lr, \rd, lsr #16
+ strh lr, [r0]
+ strh \rd, [r0]
+#endif
+ .endm
.outsw_bad_alignment:
adr r0, .outsw_bad_align_msg
@@ -40,20 +51,10 @@
bmi .no_outsw_8
.outsw_8_lp: ldmia r1!, {r3, r4, r5, ip}
-
- strh r3, [r0]
- mov r3, r3, lsr #16
- strh r3, [r0]
- strh r4, [r0]
- mov r4, r4, lsr #16
- strh r4, [r0]
- strh r5, [r0]
- mov r5, r5, lsr #16
- strh r5, [r0]
- strh ip, [r0]
- mov ip, ip, lsr #16
- strh ip, [r0]
-
+ outword r3
+ outword r4
+ outword r5
+ outword ip
subs r2, r2, #8
bpl .outsw_8_lp
@@ -64,20 +65,14 @@
beq .no_outsw_4
ldmia r1!, {r3, ip}
- strh r3, [r0]
- mov r3, r3, lsr #16
- strh r3, [r0]
- strh ip, [r0]
- mov ip, ip, lsr #16
- strh ip, [r0]
+ outword r3
+ outword ip
.no_outsw_4: tst r2, #2
beq .no_outsw_2
ldr r3, [r1], #4
- strh r3, [r0]
- mov r3, r3, lsr #16
- strh r3, [r0]
+ outword r3
.no_outsw_2: tst r2, #1
ldrneh r3, [r1]
diff -Nru a/arch/arm/lib/lib1funcs.S b/arch/arm/lib/lib1funcs.S
--- a/arch/arm/lib/lib1funcs.S Wed Oct 8 12:24:55 2003
+++ b/arch/arm/lib/lib1funcs.S Wed Oct 8 12:24:55 2003
@@ -1,7 +1,12 @@
-@ libgcc1 routines for ARM cpu.
-@ Division routines, written by Richard Earnshaw, (rearnsha@armltd.co.uk)
+/*
+ * linux/arch/arm/lib/lib1funcs.S: Optimized ARM division routines
+ *
+ * Author: Nicolas Pitre
+ * - contributed to gcc-3.4 on Sep 30, 2003
+ * - adapted for the Linux kernel on Oct 2, 2003
+ */
-/* Copyright (C) 1995, 1996, 1998 Free Software Foundation, Inc.
+/* Copyright 1995, 1996, 1998, 1999, 2000, 2003 Free Software Foundation, Inc.
This file is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
@@ -10,11 +15,12 @@
In addition to the permissions in the GNU General Public License, the
Free Software Foundation gives you unlimited permission to link the
-compiled version of this file with other programs, and to distribute
-those programs without any restriction coming from the use of this
-file. (The General Public License restrictions do apply in other
-respects; for example, they cover modification of the file, and
-distribution when not linked into another program.)
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file. (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
This file is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -26,286 +32,283 @@
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-/* As a special exception, if you link this library with other files,
- some of which are compiled with GCC, to produce an executable,
- this library does not by itself cause the resulting executable
- to be covered by the GNU General Public License.
- This exception does not however invalidate any other reasons why
- the executable file might be covered by the GNU General Public License.
- */
-/* This code is derived from gcc 2.95.3
- * 29/07/01 Adapted for linux
- * 27/03/03 Ian Molton Clean up CONFIG_CPU
- */
#include
#include
-#include
-#define RET mov
-#define RETc(x) mov##x
-#define RETCOND
-
-dividend .req r0
-divisor .req r1
-result .req r2
-overdone .req r2
-curbit .req r3
+
+.macro ARM_DIV_BODY dividend, divisor, result, curbit
+
+#if __LINUX_ARM_ARCH__ >= 5
+
+ clz \curbit, \divisor
+ clz \result, \dividend
+ sub \result, \curbit, \result
+ mov \curbit, #1
+ mov \divisor, \divisor, lsl \result
+ mov \curbit, \curbit, lsl \result
+ mov \result, #0
-ENTRY(__udivsi3)
- cmp divisor, #0
- beq Ldiv0
- mov curbit, #1
- mov result, #0
- cmp dividend, divisor
- bcc Lgot_result_udivsi3
-1:
+#else
+
+ @ Initially shift the divisor left 3 bits if possible,
+ @ set curbit accordingly. This allows for curbit to be located
+ @ at the left end of each 4 bit nibbles in the division loop
+ @ to save one loop in most cases.
+ tst \divisor, #0xe0000000
+ moveq \divisor, \divisor, lsl #3
+ moveq \curbit, #8
+ movne \curbit, #1
+
@ Unless the divisor is very big, shift it up in multiples of
@ four bits, since this is the amount of unwinding in the main
@ division loop. Continue shifting until the divisor is
@ larger than the dividend.
- cmp divisor, #0x10000000
- cmpcc divisor, dividend
- movcc divisor, divisor, lsl #4
- movcc curbit, curbit, lsl #4
- bcc 1b
+1: cmp \divisor, #0x10000000
+ cmplo \divisor, \dividend
+ movlo \divisor, \divisor, lsl #4
+ movlo \curbit, \curbit, lsl #4
+ blo 1b
-2:
@ For very big divisors, we must shift it a bit at a time, or
@ we will be in danger of overflowing.
- cmp divisor, #0x80000000
- cmpcc divisor, dividend
- movcc divisor, divisor, lsl #1
- movcc curbit, curbit, lsl #1
- bcc 2b
-
-3:
- @ Test for possible subtractions, and note which bits
- @ are done in the result. On the final pass, this may subtract
- @ too much from the dividend, but the result will be ok, since the
- @ "bit" will have been shifted out at the bottom.
- cmp dividend, divisor
- subcs dividend, dividend, divisor
- orrcs result, result, curbit
- cmp dividend, divisor, lsr #1
- subcs dividend, dividend, divisor, lsr #1
- orrcs result, result, curbit, lsr #1
- cmp dividend, divisor, lsr #2
- subcs dividend, dividend, divisor, lsr #2
- orrcs result, result, curbit, lsr #2
- cmp dividend, divisor, lsr #3
- subcs dividend, dividend, divisor, lsr #3
- orrcs result, result, curbit, lsr #3
- cmp dividend, #0 @ Early termination?
- movnes curbit, curbit, lsr #4 @ No, any more bits to do?
- movne divisor, divisor, lsr #4
- bne 3b
-Lgot_result_udivsi3:
- mov r0, result
- RET pc, lr
+1: cmp \divisor, #0x80000000
+ cmplo \divisor, \dividend
+ movlo \divisor, \divisor, lsl #1
+ movlo \curbit, \curbit, lsl #1
+ blo 1b
-Ldiv0:
- str lr, [sp, #-4]!
- bl __div0
- mov r0, #0 @ about as wrong as it could be
- ldmia sp!, {pc}RETCOND
+ mov \result, #0
-/* __umodsi3 ----------------------- */
+#endif
+
+ @ Division loop
+1: cmp \dividend, \divisor
+ subhs \dividend, \dividend, \divisor
+ orrhs \result, \result, \curbit
+ cmp \dividend, \divisor, lsr #1
+ subhs \dividend, \dividend, \divisor, lsr #1
+ orrhs \result, \result, \curbit, lsr #1
+ cmp \dividend, \divisor, lsr #2
+ subhs \dividend, \dividend, \divisor, lsr #2
+ orrhs \result, \result, \curbit, lsr #2
+ cmp \dividend, \divisor, lsr #3
+ subhs \dividend, \dividend, \divisor, lsr #3
+ orrhs \result, \result, \curbit, lsr #3
+ cmp \dividend, #0 @ Early termination?
+ movnes \curbit, \curbit, lsr #4 @ No, any more bits to do?
+ movne \divisor, \divisor, lsr #4
+ bne 1b
+
+.endm
+
+
+.macro ARM_DIV2_ORDER divisor, order
+
+#if __LINUX_ARM_ARCH__ >= 5
+
+ clz \order, \divisor
+ rsb \order, \order, #31
+
+#else
+
+ cmp \divisor, #(1 << 16)
+ movhs \divisor, \divisor, lsr #16
+ movhs \order, #16
+ movlo \order, #0
+
+ cmp \divisor, #(1 << 8)
+ movhs \divisor, \divisor, lsr #8
+ addhs \order, \order, #8
+
+ cmp \divisor, #(1 << 4)
+ movhs \divisor, \divisor, lsr #4
+ addhs \order, \order, #4
+
+ cmp \divisor, #(1 << 2)
+ addhi \order, \order, #3
+ addls \order, \order, \divisor, lsr #1
+
+#endif
+
+.endm
+
+
+.macro ARM_MOD_BODY dividend, divisor, order, spare
+
+#if __LINUX_ARM_ARCH__ >= 5
+
+ clz \order, \divisor
+ clz \spare, \dividend
+ sub \order, \order, \spare
+ mov \divisor, \divisor, lsl \order
+
+#else
+
+ mov \order, #0
-ENTRY(__umodsi3)
- cmp divisor, #0
- beq Ldiv0
- mov curbit, #1
- cmp dividend, divisor
- RETc(cc) pc, lr
-1:
@ Unless the divisor is very big, shift it up in multiples of
@ four bits, since this is the amount of unwinding in the main
@ division loop. Continue shifting until the divisor is
@ larger than the dividend.
- cmp divisor, #0x10000000
- cmpcc divisor, dividend
- movcc divisor, divisor, lsl #4
- movcc curbit, curbit, lsl #4
- bcc 1b
+1: cmp \divisor, #0x10000000
+ cmplo \divisor, \dividend
+ movlo \divisor, \divisor, lsl #4
+ addlo \order, \order, #4
+ blo 1b
-2:
@ For very big divisors, we must shift it a bit at a time, or
@ we will be in danger of overflowing.
- cmp divisor, #0x80000000
- cmpcc divisor, dividend
- movcc divisor, divisor, lsl #1
- movcc curbit, curbit, lsl #1
- bcc 2b
-
-3:
- @ Test for possible subtractions. On the final pass, this may
- @ subtract too much from the dividend, so keep track of which
- @ subtractions are done, we can fix them up afterwards...
- mov overdone, #0
- cmp dividend, divisor
- subcs dividend, dividend, divisor
- cmp dividend, divisor, lsr #1
- subcs dividend, dividend, divisor, lsr #1
- orrcs overdone, overdone, curbit, ror #1
- cmp dividend, divisor, lsr #2
- subcs dividend, dividend, divisor, lsr #2
- orrcs overdone, overdone, curbit, ror #2
- cmp dividend, divisor, lsr #3
- subcs dividend, dividend, divisor, lsr #3
- orrcs overdone, overdone, curbit, ror #3
- mov ip, curbit
- cmp dividend, #0 @ Early termination?
- movnes curbit, curbit, lsr #4 @ No, any more bits to do?
- movne divisor, divisor, lsr #4
- bne 3b
-
- @ Any subtractions that we should not have done will be recorded in
- @ the top three bits of "overdone". Exactly which were not needed
- @ are governed by the position of the bit, stored in ip.
- @ If we terminated early, because dividend became zero,
- @ then none of the below will match, since the bit in ip will not be
- @ in the bottom nibble.
- ands overdone, overdone, #0xe0000000
- RETc(eq) pc, lr @ No fixups needed
- tst overdone, ip, ror #3
- addne dividend, dividend, divisor, lsr #3
- tst overdone, ip, ror #2
- addne dividend, dividend, divisor, lsr #2
- tst overdone, ip, ror #1
- addne dividend, dividend, divisor, lsr #1
- RET pc, lr
+1: cmp \divisor, #0x80000000
+ cmplo \divisor, \dividend
+ movlo \divisor, \divisor, lsl #1
+ addlo \order, \order, #1
+ blo 1b
+
+#endif
+
+ @ Perform all needed substractions to keep only the reminder.
+ @ Do comparisons in batch of 4 first.
+ subs \order, \order, #3 @ yes, 3 is intended here
+ blt 2f
+
+1: cmp \dividend, \divisor
+ subhs \dividend, \dividend, \divisor
+ cmp \dividend, \divisor, lsr #1
+ subhs \dividend, \dividend, \divisor, lsr #1
+ cmp \dividend, \divisor, lsr #2
+ subhs \dividend, \dividend, \divisor, lsr #2
+ cmp \dividend, \divisor, lsr #3
+ subhs \dividend, \dividend, \divisor, lsr #3
+ cmp \dividend, #1
+ mov \divisor, \divisor, lsr #4
+ subges \order, \order, #4
+ bge 1b
+
+ tst \order, #3
+ teqne \dividend, #0
+ beq 5f
+
+ @ Either 1, 2 or 3 comparison/substractions are left.
+2: cmn \order, #2
+ blt 4f
+ beq 3f
+ cmp \dividend, \divisor
+ subhs \dividend, \dividend, \divisor
+ mov \divisor, \divisor, lsr #1
+3: cmp \dividend, \divisor
+ subhs \dividend, \dividend, \divisor
+ mov \divisor, \divisor, lsr #1
+4: cmp \dividend, \divisor
+ subhs \dividend, \dividend, \divisor
+5:
+.endm
+
+
+ENTRY(__udivsi3)
+
+ subs r2, r1, #1
+ moveq pc, lr
+ bcc Ldiv0
+ cmp r0, r1
+ bls 11f
+ tst r1, r2
+ beq 12f
+
+ ARM_DIV_BODY r0, r1, r2, r3
+
+ mov r0, r2
+ mov pc, lr
+
+11: moveq r0, #1
+ movne r0, #0
+ mov pc, lr
+
+12: ARM_DIV2_ORDER r1, r2
+
+ mov r0, r0, lsr r2
+ mov pc, lr
+
+
+ENTRY(__umodsi3)
+
+ subs r2, r1, #1 @ compare divisor with 1
+ bcc Ldiv0
+ cmpne r0, r1 @ compare dividend with divisor
+ moveq r0, #0
+ tsthi r1, r2 @ see if divisor is power of 2
+ andeq r0, r0, r2
+ movls pc, lr
+
+ ARM_MOD_BODY r0, r1, r2, r3
+
+ mov pc, lr
+
ENTRY(__divsi3)
- eor ip, dividend, divisor @ Save the sign of the result.
- mov curbit, #1
- mov result, #0
- cmp divisor, #0
- rsbmi divisor, divisor, #0 @ Loops below use unsigned.
+
+ cmp r1, #0
+ eor ip, r0, r1 @ save the sign of the result.
beq Ldiv0
- cmp dividend, #0
- rsbmi dividend, dividend, #0
- cmp dividend, divisor
- bcc Lgot_result_divsi3
+ rsbmi r1, r1, #0 @ loops below use unsigned.
+ subs r2, r1, #1 @ division by 1 or -1 ?
+ beq 10f
+ movs r3, r0
+ rsbmi r3, r0, #0 @ positive dividend value
+ cmp r3, r1
+ bls 11f
+ tst r1, r2 @ divisor is power of 2 ?
+ beq 12f
-1:
- @ Unless the divisor is very big, shift it up in multiples of
- @ four bits, since this is the amount of unwinding in the main
- @ division loop. Continue shifting until the divisor is
- @ larger than the dividend.
- cmp divisor, #0x10000000
- cmpcc divisor, dividend
- movcc divisor, divisor, lsl #4
- movcc curbit, curbit, lsl #4
- bcc 1b
+ ARM_DIV_BODY r3, r1, r0, r2
-2:
- @ For very big divisors, we must shift it a bit at a time, or
- @ we will be in danger of overflowing.
- cmp divisor, #0x80000000
- cmpcc divisor, dividend
- movcc divisor, divisor, lsl #1
- movcc curbit, curbit, lsl #1
- bcc 2b
-
-3:
- @ Test for possible subtractions, and note which bits
- @ are done in the result. On the final pass, this may subtract
- @ too much from the dividend, but the result will be ok, since the
- @ "bit" will have been shifted out at the bottom.
- cmp dividend, divisor
- subcs dividend, dividend, divisor
- orrcs result, result, curbit
- cmp dividend, divisor, lsr #1
- subcs dividend, dividend, divisor, lsr #1
- orrcs result, result, curbit, lsr #1
- cmp dividend, divisor, lsr #2
- subcs dividend, dividend, divisor, lsr #2
- orrcs result, result, curbit, lsr #2
- cmp dividend, divisor, lsr #3
- subcs dividend, dividend, divisor, lsr #3
- orrcs result, result, curbit, lsr #3
- cmp dividend, #0 @ Early termination?
- movnes curbit, curbit, lsr #4 @ No, any more bits to do?
- movne divisor, divisor, lsr #4
- bne 3b
-Lgot_result_divsi3:
- mov r0, result
cmp ip, #0
rsbmi r0, r0, #0
- RET pc, lr
+ mov pc, lr
+
+10: teq ip, r0 @ same sign ?
+ rsbmi r0, r0, #0
+ mov pc, lr
+
+11: movlo r0, #0
+ moveq r0, ip, asr #31
+ orreq r0, r0, #1
+ mov pc, lr
+
+12: ARM_DIV2_ORDER r1, r2
+
+ cmp ip, #0
+ mov r0, r3, lsr r2
+ rsbmi r0, r0, #0
+ mov pc, lr
+
ENTRY(__modsi3)
- mov curbit, #1
- cmp divisor, #0
- rsbmi divisor, divisor, #0 @ Loops below use unsigned.
+
+ cmp r1, #0
beq Ldiv0
- @ Need to save the sign of the dividend, unfortunately, we need
- @ ip later on; this is faster than pushing lr and using that.
- str dividend, [sp, #-4]!
- cmp dividend, #0
- rsbmi dividend, dividend, #0
- cmp dividend, divisor
- bcc Lgot_result_modsi3
+ rsbmi r1, r1, #0 @ loops below use unsigned.
+ movs ip, r0 @ preserve sign of dividend
+ rsbmi r0, r0, #0 @ if negative make positive
+ subs r2, r1, #1 @ compare divisor with 1
+ cmpne r0, r1 @ compare dividend with divisor
+ moveq r0, #0
+ tsthi r1, r2 @ see if divisor is power of 2
+ andeq r0, r0, r2
+ bls 10f
+
+ ARM_MOD_BODY r0, r1, r2, r3
+
+10: cmp ip, #0
+ rsbmi r0, r0, #0
+ mov pc, lr
+
+
+Ldiv0:
+
+ str lr, [sp, #-4]!
+ bl __div0
+ mov r0, #0 @ About as wrong as it could be.
+ ldr pc, [sp], #4
-1:
- @ Unless the divisor is very big, shift it up in multiples of
- @ four bits, since this is the amount of unwinding in the main
- @ division loop. Continue shifting until the divisor is
- @ larger than the dividend.
- cmp divisor, #0x10000000
- cmpcc divisor, dividend
- movcc divisor, divisor, lsl #4
- movcc curbit, curbit, lsl #4
- bcc 1b
-2:
- @ For very big divisors, we must shift it a bit at a time, or
- @ we will be in danger of overflowing.
- cmp divisor, #0x80000000
- cmpcc divisor, dividend
- movcc divisor, divisor, lsl #1
- movcc curbit, curbit, lsl #1
- bcc 2b
-
-3:
- @ Test for possible subtractions. On the final pass, this may
- @ subtract too much from the dividend, so keep track of which
- @ subtractions are done, we can fix them up afterwards...
- mov overdone, #0
- cmp dividend, divisor
- subcs dividend, dividend, divisor
- cmp dividend, divisor, lsr #1
- subcs dividend, dividend, divisor, lsr #1
- orrcs overdone, overdone, curbit, ror #1
- cmp dividend, divisor, lsr #2
- subcs dividend, dividend, divisor, lsr #2
- orrcs overdone, overdone, curbit, ror #2
- cmp dividend, divisor, lsr #3
- subcs dividend, dividend, divisor, lsr #3
- orrcs overdone, overdone, curbit, ror #3
- mov ip, curbit
- cmp dividend, #0 @ Early termination?
- movnes curbit, curbit, lsr #4 @ No, any more bits to do?
- movne divisor, divisor, lsr #4
- bne 3b
-
- @ Any subtractions that we should not have done will be recorded in
- @ the top three bits of "overdone". Exactly which were not needed
- @ are governed by the position of the bit, stored in ip.
- @ If we terminated early, because dividend became zero,
- @ then none of the below will match, since the bit in ip will not be
- @ in the bottom nibble.
- ands overdone, overdone, #0xe0000000
- beq Lgot_result_modsi3
- tst overdone, ip, ror #3
- addne dividend, dividend, divisor, lsr #3
- tst overdone, ip, ror #2
- addne dividend, dividend, divisor, lsr #2
- tst overdone, ip, ror #1
- addne dividend, dividend, divisor, lsr #1
-Lgot_result_modsi3:
- ldr ip, [sp], #4
- cmp ip, #0
- rsbmi dividend, dividend, #0
- RET pc, lr
diff -Nru a/arch/arm/mach-integrator/Kconfig b/arch/arm/mach-integrator/Kconfig
--- a/arch/arm/mach-integrator/Kconfig Wed Oct 8 12:24:57 2003
+++ b/arch/arm/mach-integrator/Kconfig Wed Oct 8 12:24:57 2003
@@ -1,8 +1,15 @@
menu "Integrator Options"
depends on ARCH_INTEGRATOR
+config ARCH_INTEGRATOR_AP
+ bool "Support Integrator/AP and Integrator/PP2 platforms"
+ help
+ Include support for the ARM(R) Integrator/AP and
+ Integrator/PP2 platforms.
+
config INTEGRATOR_IMPD1
tristate "Include support for Integrator/IM-PD1"
+ depends on ARCH_INTEGRATOR_AP
help
The IM-PD1 is an add-on logic module for the Integrator which
allows ARM(R) Ltd PrimeCells to be developed and evaluated.
diff -Nru a/arch/arm/mach-integrator/Makefile b/arch/arm/mach-integrator/Makefile
--- a/arch/arm/mach-integrator/Makefile Wed Oct 8 12:24:57 2003
+++ b/arch/arm/mach-integrator/Makefile Wed Oct 8 12:24:57 2003
@@ -4,9 +4,10 @@
# Object file lists.
-obj-y := core.o lm.o time.o
+obj-y := core.o lm.o time.o
+obj-$(CONFIG_ARCH_INTEGRATOR_AP) += integrator_ap.o
-obj-$(CONFIG_LEDS) += leds.o
-obj-$(CONFIG_PCI) += pci_v3.o pci.o
+obj-$(CONFIG_LEDS) += leds.o
+obj-$(CONFIG_PCI) += pci_v3.o pci.o
obj-$(CONFIG_CPU_FREQ_INTEGRATOR) += cpu.o
obj-$(CONFIG_INTEGRATOR_IMPD1) += impd1.o
diff -Nru a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c
--- a/arch/arm/mach-integrator/core.c Wed Oct 8 12:24:57 2003
+++ b/arch/arm/mach-integrator/core.c Wed Oct 8 12:24:57 2003
@@ -1,134 +1,59 @@
/*
- * linux/arch/arm/mach-integrator/arch.c
+ * linux/arch/arm/mach-integrator/core.c
*
- * Copyright (C) 2000 Deep Blue Solutions Ltd
+ * Copyright (C) 2000-2003 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
+ * it under the terms of the GNU General Public License version 2, as
+ * published by the Free Software Foundation.
*/
#include
#include
#include
-#include
#include
-#include
-#include
#include
-#include
#include
-#include
-#include
#include
-#include
-
-#include
-#include
-#include
-#include
-
-/*
- * All IO addresses are mapped onto VA 0xFFFx.xxxx, where x.xxxx
- * is the (PA >> 12).
- *
- * Setup a VA for the Integrator interrupt controller (for header #0,
- * just for now).
- */
-#define VA_IC_BASE IO_ADDRESS(INTEGRATOR_IC_BASE)
-#define VA_SC_BASE IO_ADDRESS(INTEGRATOR_SC_BASE)
-#define VA_CMIC_BASE IO_ADDRESS(INTEGRATOR_HDR_BASE) + INTEGRATOR_HDR_IC_OFFSET
-
-/*
- * Logical Physical
- * e8000000 40000000 PCI memory PHYS_PCI_MEM_BASE (max 512M)
- * ec000000 61000000 PCI config space PHYS_PCI_CONFIG_BASE (max 16M)
- * ed000000 62000000 PCI V3 regs PHYS_PCI_V3_BASE (max 64k)
- * ee000000 60000000 PCI IO PHYS_PCI_IO_BASE (max 16M)
- * ef000000 Cache flush
- * f1000000 10000000 Core module registers
- * f1100000 11000000 System controller registers
- * f1200000 12000000 EBI registers
- * f1300000 13000000 Counter/Timer
- * f1400000 14000000 Interrupt controller
- * f1500000 15000000 RTC
- * f1600000 16000000 UART 0
- * f1700000 17000000 UART 1
- * f1a00000 1a000000 Debug LEDs
- * f1b00000 1b000000 GPIO
- */
-
-static struct map_desc integrator_io_desc[] __initdata = {
- { IO_ADDRESS(INTEGRATOR_HDR_BASE), INTEGRATOR_HDR_BASE, SZ_4K, MT_DEVICE },
- { IO_ADDRESS(INTEGRATOR_SC_BASE), INTEGRATOR_SC_BASE, SZ_4K, MT_DEVICE },
- { IO_ADDRESS(INTEGRATOR_EBI_BASE), INTEGRATOR_EBI_BASE, SZ_4K, MT_DEVICE },
- { IO_ADDRESS(INTEGRATOR_CT_BASE), INTEGRATOR_CT_BASE, SZ_4K, MT_DEVICE },
- { IO_ADDRESS(INTEGRATOR_IC_BASE), INTEGRATOR_IC_BASE, SZ_4K, MT_DEVICE },
- { IO_ADDRESS(INTEGRATOR_RTC_BASE), INTEGRATOR_RTC_BASE, SZ_4K, MT_DEVICE },
- { IO_ADDRESS(INTEGRATOR_UART0_BASE), INTEGRATOR_UART0_BASE, SZ_4K, MT_DEVICE },
- { IO_ADDRESS(INTEGRATOR_UART1_BASE), INTEGRATOR_UART1_BASE, SZ_4K, MT_DEVICE },
- { IO_ADDRESS(INTEGRATOR_DBG_BASE), INTEGRATOR_DBG_BASE, SZ_4K, MT_DEVICE },
- { IO_ADDRESS(INTEGRATOR_GPIO_BASE), INTEGRATOR_GPIO_BASE, SZ_4K, MT_DEVICE },
- { PCI_MEMORY_VADDR, PHYS_PCI_MEM_BASE, SZ_16M, MT_DEVICE },
- { PCI_CONFIG_VADDR, PHYS_PCI_CONFIG_BASE, SZ_16M, MT_DEVICE },
- { PCI_V3_VADDR, PHYS_PCI_V3_BASE, SZ_64K, MT_DEVICE },
- { PCI_IO_VADDR, PHYS_PCI_IO_BASE, SZ_64K, MT_DEVICE }
+static struct amba_device rtc_device = {
+ .dev = {
+ .bus_id = "mb:15",
+ },
+ .res = {
+ .start = INTEGRATOR_RTC_BASE,
+ .end = INTEGRATOR_RTC_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ .irq = IRQ_RTCINT,
+ .periphid = 0x00041030,
};
-static void __init integrator_map_io(void)
-{
- iotable_init(integrator_io_desc, ARRAY_SIZE(integrator_io_desc));
-}
-
-#define ALLPCI ( (1 << IRQ_PCIINT0) | (1 << IRQ_PCIINT1) | (1 << IRQ_PCIINT2) | (1 << IRQ_PCIINT3) )
-
-static void sc_mask_irq(unsigned int irq)
-{
- writel(1 << irq, VA_IC_BASE + IRQ_ENABLE_CLEAR);
-}
-
-static void sc_unmask_irq(unsigned int irq)
-{
- writel(1 << irq, VA_IC_BASE + IRQ_ENABLE_SET);
-}
-
-static struct irqchip sc_chip = {
- .ack = sc_mask_irq,
- .mask = sc_mask_irq,
- .unmask = sc_unmask_irq,
+static struct amba_device uart0_device = {
+ .dev = {
+ .bus_id = "mb:16",
+ },
+ .res = {
+ .start = INTEGRATOR_UART0_BASE,
+ .end = INTEGRATOR_UART0_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ .irq = IRQ_UARTINT0,
+ .periphid = 0x0041010,
};
-static void __init integrator_init_irq(void)
-{
- unsigned int i;
-
- /* Disable all interrupts initially. */
- /* Do the core module ones */
- writel(-1, VA_CMIC_BASE + IRQ_ENABLE_CLEAR);
-
- /* do the header card stuff next */
- writel(-1, VA_IC_BASE + IRQ_ENABLE_CLEAR);
- writel(-1, VA_IC_BASE + FIQ_ENABLE_CLEAR);
-
- for (i = 0; i < NR_IRQS; i++) {
- if (((1 << i) && INTEGRATOR_SC_VALID_INT) != 0) {
- set_irq_chip(i, &sc_chip);
- set_irq_handler(i, do_level_IRQ);
- set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
- }
- }
-}
+static struct amba_device uart1_device = {
+ .dev = {
+ .bus_id = "mb:17",
+ },
+ .res = {
+ .start = INTEGRATOR_UART1_BASE,
+ .end = INTEGRATOR_UART1_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ .irq = IRQ_UARTINT1,
+ .periphid = 0x0041010,
+};
static struct amba_device kmi0_device = {
.dev = {
@@ -136,7 +61,7 @@
},
.res = {
.start = KMI0_BASE,
- .end = KMI0_BASE + KMI_SIZE - 1,
+ .end = KMI0_BASE + SZ_4K - 1,
.flags = IORESOURCE_MEM,
},
.irq = IRQ_KMIINT0,
@@ -149,7 +74,7 @@
},
.res = {
.start = KMI1_BASE,
- .end = KMI1_BASE + KMI_SIZE - 1,
+ .end = KMI1_BASE + SZ_4K - 1,
.flags = IORESOURCE_MEM,
},
.irq = IRQ_KMIINT1,
@@ -157,52 +82,23 @@
};
static struct amba_device *amba_devs[] __initdata = {
+ &rtc_device,
+ &uart0_device,
+ &uart1_device,
&kmi0_device,
&kmi1_device,
};
-static int __init register_devices(void)
+static int __init integrator_init(void)
{
- unsigned long sc_dec;
int i;
for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
struct amba_device *d = amba_devs[i];
-
amba_device_register(d, &iomem_resource);
}
- sc_dec = readl(VA_SC_BASE + INTEGRATOR_SC_DEC_OFFSET);
- for (i = 0; i < 4; i++) {
- struct lm_device *lmdev;
-
- if ((sc_dec & (16 << i)) == 0)
- continue;
-
- lmdev = kmalloc(sizeof(struct lm_device), GFP_KERNEL);
- if (!lmdev)
- continue;
-
- memset(lmdev, 0, sizeof(struct lm_device));
-
- lmdev->resource.start = 0xc0000000 + 0x10000000 * i;
- lmdev->resource.end = lmdev->resource.start + 0x0fffffff;
- lmdev->resource.flags = IORESOURCE_MEM;
- lmdev->irq = IRQ_EXPINT0 + i;
- lmdev->id = i;
-
- lm_device_register(lmdev);
- }
-
return 0;
}
-arch_initcall(register_devices);
-
-MACHINE_START(INTEGRATOR, "ARM-Integrator")
- MAINTAINER("ARM Ltd/Deep Blue Solutions Ltd")
- BOOT_MEM(0x00000000, 0x16000000, 0xf1600000)
- BOOT_PARAMS(0x00000100)
- MAPIO(integrator_map_io)
- INITIRQ(integrator_init_irq)
-MACHINE_END
+arch_initcall(integrator_init);
diff -Nru a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c
--- /dev/null Wed Dec 31 16:00:00 1969
+++ b/arch/arm/mach-integrator/integrator_ap.c Wed Oct 8 12:24:58 2003
@@ -0,0 +1,294 @@
+/*
+ * linux/arch/arm/mach-integrator/integrator_ap.c
+ *
+ * Copyright (C) 2000-2003 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
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+#include
+#include
+#include
+#include
+
+
+/*
+ * All IO addresses are mapped onto VA 0xFFFx.xxxx, where x.xxxx
+ * is the (PA >> 12).
+ *
+ * Setup a VA for the Integrator interrupt controller (for header #0,
+ * just for now).
+ */
+#define VA_IC_BASE IO_ADDRESS(INTEGRATOR_IC_BASE)
+#define VA_SC_BASE IO_ADDRESS(INTEGRATOR_SC_BASE)
+#define VA_EBI_BASE IO_ADDRESS(INTEGRATOR_EBI_BASE)
+#define VA_CMIC_BASE IO_ADDRESS(INTEGRATOR_HDR_BASE) + INTEGRATOR_HDR_IC_OFFSET
+
+/*
+ * Logical Physical
+ * e8000000 40000000 PCI memory PHYS_PCI_MEM_BASE (max 512M)
+ * ec000000 61000000 PCI config space PHYS_PCI_CONFIG_BASE (max 16M)
+ * ed000000 62000000 PCI V3 regs PHYS_PCI_V3_BASE (max 64k)
+ * ee000000 60000000 PCI IO PHYS_PCI_IO_BASE (max 16M)
+ * ef000000 Cache flush
+ * f1000000 10000000 Core module registers
+ * f1100000 11000000 System controller registers
+ * f1200000 12000000 EBI registers
+ * f1300000 13000000 Counter/Timer
+ * f1400000 14000000 Interrupt controller
+ * f1500000 15000000 RTC
+ * f1600000 16000000 UART 0
+ * f1700000 17000000 UART 1
+ * f1a00000 1a000000 Debug LEDs
+ * f1b00000 1b000000 GPIO
+ */
+
+static struct map_desc ap_io_desc[] __initdata = {
+ { IO_ADDRESS(INTEGRATOR_HDR_BASE), INTEGRATOR_HDR_BASE, SZ_4K, MT_DEVICE },
+ { IO_ADDRESS(INTEGRATOR_SC_BASE), INTEGRATOR_SC_BASE, SZ_4K, MT_DEVICE },
+ { IO_ADDRESS(INTEGRATOR_EBI_BASE), INTEGRATOR_EBI_BASE, SZ_4K, MT_DEVICE },
+ { IO_ADDRESS(INTEGRATOR_CT_BASE), INTEGRATOR_CT_BASE, SZ_4K, MT_DEVICE },
+ { IO_ADDRESS(INTEGRATOR_IC_BASE), INTEGRATOR_IC_BASE, SZ_4K, MT_DEVICE },
+ { IO_ADDRESS(INTEGRATOR_RTC_BASE), INTEGRATOR_RTC_BASE, SZ_4K, MT_DEVICE },
+ { IO_ADDRESS(INTEGRATOR_UART0_BASE), INTEGRATOR_UART0_BASE, SZ_4K, MT_DEVICE },
+ { IO_ADDRESS(INTEGRATOR_UART1_BASE), INTEGRATOR_UART1_BASE, SZ_4K, MT_DEVICE },
+ { IO_ADDRESS(INTEGRATOR_DBG_BASE), INTEGRATOR_DBG_BASE, SZ_4K, MT_DEVICE },
+ { IO_ADDRESS(INTEGRATOR_GPIO_BASE), INTEGRATOR_GPIO_BASE, SZ_4K, MT_DEVICE },
+ { PCI_MEMORY_VADDR, PHYS_PCI_MEM_BASE, SZ_16M, MT_DEVICE },
+ { PCI_CONFIG_VADDR, PHYS_PCI_CONFIG_BASE, SZ_16M, MT_DEVICE },
+ { PCI_V3_VADDR, PHYS_PCI_V3_BASE, SZ_64K, MT_DEVICE },
+ { PCI_IO_VADDR, PHYS_PCI_IO_BASE, SZ_64K, MT_DEVICE }
+};
+
+static void __init ap_map_io(void)
+{
+ iotable_init(ap_io_desc, ARRAY_SIZE(ap_io_desc));
+}
+
+#define INTEGRATOR_SC_VALID_INT 0x003fffff
+
+static void sc_mask_irq(unsigned int irq)
+{
+ writel(1 << irq, VA_IC_BASE + IRQ_ENABLE_CLEAR);
+}
+
+static void sc_unmask_irq(unsigned int irq)
+{
+ writel(1 << irq, VA_IC_BASE + IRQ_ENABLE_SET);
+}
+
+static struct irqchip sc_chip = {
+ .ack = sc_mask_irq,
+ .mask = sc_mask_irq,
+ .unmask = sc_unmask_irq,
+};
+
+static void __init ap_init_irq(void)
+{
+ unsigned int i;
+
+ /* Disable all interrupts initially. */
+ /* Do the core module ones */
+ writel(-1, VA_CMIC_BASE + IRQ_ENABLE_CLEAR);
+
+ /* do the header card stuff next */
+ writel(-1, VA_IC_BASE + IRQ_ENABLE_CLEAR);
+ writel(-1, VA_IC_BASE + FIQ_ENABLE_CLEAR);
+
+ for (i = 0; i < NR_IRQS; i++) {
+ if (((1 << i) && INTEGRATOR_SC_VALID_INT) != 0) {
+ set_irq_chip(i, &sc_chip);
+ set_irq_handler(i, do_level_IRQ);
+ set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
+ }
+ }
+}
+
+#ifdef CONFIG_PM
+static unsigned long ic_irq_enable;
+
+static int irq_suspend(struct sys_device *dev, u32 state)
+{
+ ic_irq_enable = readl(VA_IC_BASE + IRQ_ENABLE);
+ return 0;
+}
+
+static int irq_resume(struct sys_device *dev)
+{
+ /* disable all irq sources */
+ writel(-1, VA_CMIC_BASE + IRQ_ENABLE_CLEAR);
+ writel(-1, VA_IC_BASE + IRQ_ENABLE_CLEAR);
+ writel(-1, VA_IC_BASE + FIQ_ENABLE_CLEAR);
+
+ writel(ic_irq_enable, VA_IC_BASE + IRQ_ENABLE_SET);
+ return 0;
+}
+#else
+#define irq_suspend NULL
+#define irq_resume NULL
+#endif
+
+static struct sysdev_class irq_class = {
+ set_kset_name("irq"),
+ .suspend = irq_suspend,
+ .resume = irq_resume,
+};
+
+static struct sys_device irq_device = {
+ .id = 0,
+ .cls = &irq_class,
+};
+
+static int __init irq_init_sysfs(void)
+{
+ int ret = sysdev_class_register(&irq_class);
+ if (ret == 0)
+ ret = sys_device_register(&irq_device);
+ return ret;
+}
+
+device_initcall(irq_init_sysfs);
+
+/*
+ * Flash handling.
+ */
+#define SC_CTRLC (VA_SC_BASE + INTEGRATOR_SC_CTRLC_OFFSET)
+#define SC_CTRLS (VA_SC_BASE + INTEGRATOR_SC_CTRLS_OFFSET)
+#define EBI_CSR1 (VA_EBI_BASE + INTEGRATOR_EBI_CSR1_OFFSET)
+#define EBI_LOCK (VA_EBI_BASE + INTEGRATOR_EBI_LOCK_OFFSET)
+
+static int ap_flash_init(void)
+{
+ u32 tmp;
+
+ writel(INTEGRATOR_SC_CTRL_nFLVPPEN | INTEGRATOR_SC_CTRL_nFLWP, SC_CTRLC);
+
+ tmp = readl(EBI_CSR1) | INTEGRATOR_EBI_WRITE_ENABLE;
+ writel(tmp, EBI_CSR1);
+
+ if (!(readl(EBI_CSR1) & INTEGRATOR_EBI_WRITE_ENABLE)) {
+ writel(0xa05f, EBI_LOCK);
+ writel(tmp, EBI_CSR1);
+ writel(0, EBI_LOCK);
+ }
+ return 0;
+}
+
+static void ap_flash_exit(void)
+{
+ u32 tmp;
+
+ writel(INTEGRATOR_SC_CTRL_nFLVPPEN | INTEGRATOR_SC_CTRL_nFLWP, SC_CTRLC);
+
+ tmp = readl(EBI_CSR1) & ~INTEGRATOR_EBI_WRITE_ENABLE;
+ writel(tmp, EBI_CSR1);
+
+ if (readl(EBI_CSR1) & INTEGRATOR_EBI_WRITE_ENABLE) {
+ writel(0xa05f, EBI_LOCK);
+ writel(tmp, EBI_CSR1);
+ writel(0, EBI_LOCK);
+ }
+}
+
+static void ap_flash_set_vpp(int on)
+{
+ unsigned long reg = on ? SC_CTRLS : SC_CTRLC;
+
+ writel(INTEGRATOR_SC_CTRL_nFLVPPEN, reg);
+}
+
+static struct flash_platform_data ap_flash_data = {
+ .map_name = "cfi_probe",
+ .width = 4,
+ .init = ap_flash_init,
+ .exit = ap_flash_exit,
+ .set_vpp = ap_flash_set_vpp,
+};
+
+static struct resource cfi_flash_resource = {
+ .start = INTEGRATOR_FLASH_BASE,
+ .end = INTEGRATOR_FLASH_BASE + INTEGRATOR_FLASH_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device cfi_flash_device = {
+ .name = "armflash",
+ .id = 0,
+ .dev = {
+ .platform_data = &ap_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &cfi_flash_resource,
+};
+
+static int __init ap_init(void)
+{
+ unsigned long sc_dec;
+ int i;
+
+ platform_add_device(&cfi_flash_device);
+
+ sc_dec = readl(VA_SC_BASE + INTEGRATOR_SC_DEC_OFFSET);
+ for (i = 0; i < 4; i++) {
+ struct lm_device *lmdev;
+
+ if ((sc_dec & (16 << i)) == 0)
+ continue;
+
+ lmdev = kmalloc(sizeof(struct lm_device), GFP_KERNEL);
+ if (!lmdev)
+ continue;
+
+ memset(lmdev, 0, sizeof(struct lm_device));
+
+ lmdev->resource.start = 0xc0000000 + 0x10000000 * i;
+ lmdev->resource.end = lmdev->resource.start + 0x0fffffff;
+ lmdev->resource.flags = IORESOURCE_MEM;
+ lmdev->irq = IRQ_AP_EXPINT0 + i;
+ lmdev->id = i;
+
+ lm_device_register(lmdev);
+ }
+
+ return 0;
+}
+
+arch_initcall(ap_init);
+
+MACHINE_START(INTEGRATOR, "ARM-Integrator")
+ MAINTAINER("ARM Ltd/Deep Blue Solutions Ltd")
+ BOOT_MEM(0x00000000, 0x16000000, 0xf1600000)
+ BOOT_PARAMS(0x00000100)
+ MAPIO(ap_map_io)
+ INITIRQ(ap_init_irq)
+MACHINE_END
diff -Nru a/arch/arm/mach-integrator/pci.c b/arch/arm/mach-integrator/pci.c
--- a/arch/arm/mach-integrator/pci.c Wed Oct 8 12:24:57 2003
+++ b/arch/arm/mach-integrator/pci.c Wed Oct 8 12:24:57 2003
@@ -96,7 +96,7 @@
}
static int irq_tab[4] __initdata = {
- IRQ_PCIINT0, IRQ_PCIINT1, IRQ_PCIINT2, IRQ_PCIINT3
+ IRQ_AP_PCIINT0, IRQ_AP_PCIINT1, IRQ_AP_PCIINT2, IRQ_AP_PCIINT3
};
/*
diff -Nru a/arch/arm/mach-integrator/pci_v3.c b/arch/arm/mach-integrator/pci_v3.c
--- a/arch/arm/mach-integrator/pci_v3.c Wed Oct 8 12:24:57 2003
+++ b/arch/arm/mach-integrator/pci_v3.c Wed Oct 8 12:24:57 2003
@@ -575,7 +575,7 @@
/*
* Grab the PCI error interrupt.
*/
- ret = request_irq(IRQ_V3INT, v3_irq, 0, "V3", NULL);
+ ret = request_irq(IRQ_AP_V3INT, v3_irq, 0, "V3", NULL);
if (ret)
printk(KERN_ERR "PCI: unable to grab PCI error "
"interrupt: %d\n", ret);
@@ -596,7 +596,7 @@
v3_writeb(V3_LB_IMASK, 0x68);
#if 0
- ret = request_irq(IRQ_LBUSTIMEOUT, lb_timeout, 0, "bus timeout", NULL);
+ ret = request_irq(IRQ_AP_LBUSTIMEOUT, lb_timeout, 0, "bus timeout", NULL);
if (ret)
printk(KERN_ERR "PCI: unable to grab local bus timeout "
"interrupt: %d\n", ret);
diff -Nru a/arch/arm/mach-pxa/irq.c b/arch/arm/mach-pxa/irq.c
--- a/arch/arm/mach-pxa/irq.c Wed Oct 8 12:24:57 2003
+++ b/arch/arm/mach-pxa/irq.c Wed Oct 8 12:24:57 2003
@@ -58,7 +58,19 @@
{
int gpio, idx;
- gpio = irq - ((irq >= IRQ_GPIO(2)) ? IRQ_GPIO(2) + 2 : IRQ_GPIO(0));
+ gpio = IRQ_TO_GPIO(irq);
+ idx = gpio >> 5;
+
+ if (type == IRQT_PROBE) {
+ /* Don't mess with enabled GPIOs using preconfigured edges or
+ GPIOs set to alternate function during probe */
+ if ((GPIO_IRQ_rising_edge[idx] | GPIO_IRQ_falling_edge[idx]) &
+ GPIO_bit(gpio))
+ return 0;
+ if (GAFR(gpio) & (0x3 << (((gpio) & 0xf)*2)))
+ return 0;
+ type = __IRQT_RISEDGE | __IRQT_FALEDGE;
+ }
printk(KERN_DEBUG "IRQ%d (GPIO%d): ", irq, gpio);
@@ -78,10 +90,8 @@
printk("edges\n");
- idx = gpio >> 5;
GRER(gpio) = GPIO_IRQ_rising_edge[idx] & GPIO_IRQ_mask[idx];
GFER(gpio) = GPIO_IRQ_falling_edge[idx] & GPIO_IRQ_mask[idx];
-
return 0;
}
diff -Nru a/arch/arm/mach-pxa/leds.c b/arch/arm/mach-pxa/leds.c
--- a/arch/arm/mach-pxa/leds.c Wed Oct 8 12:24:57 2003
+++ b/arch/arm/mach-pxa/leds.c Wed Oct 8 12:24:57 2003
@@ -7,6 +7,7 @@
*
* Copyright (c) 2001 Jeff Sutherland, Accelent Systems Inc.
*/
+#include
#include
#include
diff -Nru a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c
--- a/arch/arm/mach-pxa/lubbock.c Wed Oct 8 12:24:56 2003
+++ b/arch/arm/mach-pxa/lubbock.c Wed Oct 8 12:24:56 2003
@@ -78,7 +78,7 @@
pxa_init_irq();
/* setup extra lubbock irqs */
- for (irq = LUBBOCK_IRQ(0); irq <= LUBBOCK_IRQ(5); irq++) {
+ for (irq = LUBBOCK_IRQ(0); irq <= LUBBOCK_LAST_IRQ; irq++) {
set_irq_chip(irq, &lubbock_irq_chip);
set_irq_handler(irq, do_level_IRQ);
set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
@@ -124,6 +124,7 @@
{ 0xf0000000, 0x08000000, 0x00100000, MT_DEVICE }, /* CPLD */
{ 0xf1000000, 0x0c000000, 0x00100000, MT_DEVICE }, /* LAN91C96 IO */
{ 0xf1100000, 0x0e000000, 0x00100000, MT_DEVICE }, /* LAN91C96 Attr */
+ { 0xf4000000, 0x10000000, 0x00800000, MT_DEVICE }, /* SA1111 */
};
static void __init lubbock_map_io(void)
diff -Nru a/arch/arm/mach-pxa/pm.c b/arch/arm/mach-pxa/pm.c
--- a/arch/arm/mach-pxa/pm.c Wed Oct 8 12:24:57 2003
+++ b/arch/arm/mach-pxa/pm.c Wed Oct 8 12:24:57 2003
@@ -11,13 +11,14 @@
* modify it under the terms of the GNU General Public License.
*/
#include
+#include
+#include
#include
#include
#include
#include
#include
-#include
/*
@@ -60,13 +61,16 @@
};
-int pm_do_suspend(void)
+static int pxa_pm_enter(u32 state)
{
unsigned long sleep_save[SLEEP_SAVE_SIZE];
unsigned long checksum = 0;
unsigned long delta;
int i;
+ if (state != PM_SUSPEND_MEM)
+ return -EINVAL;
+
/* preserve current time */
delta = xtime.tv_sec - RCNR;
@@ -194,3 +198,37 @@
{
return virt_to_phys(sp);
}
+
+/*
+ * Called after processes are frozen, but before we shut down devices.
+ */
+static int pxa_pm_prepare(u32 state)
+{
+ return 0;
+}
+
+/*
+ * Called after devices are re-setup, but before processes are thawed.
+ */
+static int pxa_pm_finish(u32 state)
+{
+ return 0;
+}
+
+/*
+ * Set to PM_DISK_FIRMWARE so we can quickly veto suspend-to-disk.
+ */
+static struct pm_ops pxa_pm_ops = {
+ .pm_disk_mode = PM_DISK_FIRMWARE,
+ .prepare = pxa_pm_prepare,
+ .enter = pxa_pm_enter,
+ .finish = pxa_pm_finish,
+};
+
+static int __init pxa_pm_init(void)
+{
+ pm_set_ops(&pxa_pm_ops);
+ return 0;
+}
+
+late_initcall(pxa_pm_init);
diff -Nru a/arch/arm/mach-sa1100/leds.c b/arch/arm/mach-sa1100/leds.c
--- a/arch/arm/mach-sa1100/leds.c Wed Oct 8 12:24:56 2003
+++ b/arch/arm/mach-sa1100/leds.c Wed Oct 8 12:24:56 2003
@@ -5,6 +5,7 @@
*
* Copyright (C) 2001 Nicolas Pitre
*/
+#include
#include
#include
diff -Nru a/arch/arm/mach-sa1100/pm.c b/arch/arm/mach-sa1100/pm.c
--- a/arch/arm/mach-sa1100/pm.c Wed Oct 8 12:24:56 2003
+++ b/arch/arm/mach-sa1100/pm.c Wed Oct 8 12:24:56 2003
@@ -22,6 +22,8 @@
* 2002-05-27: Nicolas Pitre Killed sleep.h and the kmalloced save array.
* Storage is local on the stack now.
*/
+#include
+#include
#include
#include
@@ -54,11 +56,14 @@
};
-int pm_do_suspend(void)
+static int sa11x0_pm_enter(u32 state)
{
unsigned long sleep_save[SLEEP_SAVE_SIZE];
unsigned long delta, gpio;
+ if (state != PM_SUSPEND_MEM)
+ return -EINVAL;
+
/* preserve current time */
delta = xtime.tv_sec - RCNR;
gpio = GPLR;
@@ -139,3 +144,37 @@
{
return virt_to_phys(sp);
}
+
+/*
+ * Called after processes are frozen, but before we shut down devices.
+ */
+static int sa11x0_pm_prepare(u32 state)
+{
+ return 0;
+}
+
+/*
+ * Called after devices are re-setup, but before processes are thawed.
+ */
+static int sa11x0_pm_finish(u32 state)
+{
+ return 0;
+}
+
+/*
+ * Set to PM_DISK_FIRMWARE so we can quickly veto suspend-to-disk.
+ */
+static struct pm_ops sa11x0_pm_ops = {
+ .pm_disk_mode = PM_DISK_FIRMWARE,
+ .prepare = sa11x0_pm_prepare,
+ .enter = sa11x0_pm_enter,
+ .finish = sa11x0_pm_finish,
+};
+
+static int __init sa11x0_pm_init(void)
+{
+ pm_set_ops(&sa11x0_pm_ops);
+ return 0;
+}
+
+late_initcall(sa11x0_pm_init);
diff -Nru a/arch/arm/mm/discontig.c b/arch/arm/mm/discontig.c
--- a/arch/arm/mm/discontig.c Wed Oct 8 12:24:57 2003
+++ b/arch/arm/mm/discontig.c Wed Oct 8 12:24:57 2003
@@ -15,7 +15,7 @@
#include
#include
-#if NR_NODES != 4
+#if MAX_NUMNODES != 4
#error Fix Me Please
#endif
@@ -23,9 +23,9 @@
* Our node_data structure for discontiguous memory.
*/
-static bootmem_data_t node_bootmem_data[NR_NODES];
+static bootmem_data_t node_bootmem_data[MAX_NUMNODES];
-pg_data_t discontig_node_data[NR_NODES] = {
+pg_data_t discontig_node_data[MAX_NUMNODES] = {
{ .bdata = &node_bootmem_data[0] },
{ .bdata = &node_bootmem_data[1] },
{ .bdata = &node_bootmem_data[2] },
diff -Nru a/arch/arm/mm/init.c b/arch/arm/mm/init.c
--- a/arch/arm/mm/init.c Wed Oct 8 12:24:55 2003
+++ b/arch/arm/mm/init.c Wed Oct 8 12:24:55 2003
@@ -33,12 +33,6 @@
#include
#include
-#ifndef CONFIG_DISCONTIGMEM
-#define NR_NODES 1
-#else
-#define NR_NODES 4
-#endif
-
#ifdef CONFIG_CPU_32
#define TABLE_OFFSET (PTRS_PER_PTE)
#else
@@ -178,7 +172,7 @@
{
unsigned int i, bootmem_pages = 0, memend_pfn = 0;
- for (i = 0; i < NR_NODES; i++) {
+ for (i = 0; i < MAX_NUMNODES; i++) {
np[i].start = -1U;
np[i].end = 0;
np[i].bootmap_pages = 0;
@@ -207,7 +201,7 @@
* we have, we're in trouble. (maybe we ought to
* limit, instead of bugging?)
*/
- if (numnodes > NR_NODES)
+ if (numnodes > MAX_NUMNODES)
BUG();
}
@@ -365,7 +359,7 @@
*/
void __init bootmem_init(struct meminfo *mi)
{
- struct node_info node_info[NR_NODES], *np = node_info;
+ struct node_info node_info[MAX_NUMNODES], *np = node_info;
unsigned int bootmap_pages, bootmap_pfn, map_pg;
int node, initrd_node;
diff -Nru a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c
--- a/arch/arm/mm/ioremap.c Wed Oct 8 12:24:57 2003
+++ b/arch/arm/mm/ioremap.c Wed Oct 8 12:24:57 2003
@@ -150,7 +150,7 @@
if (!area)
return NULL;
addr = area->addr;
- if (remap_area_pages(VMALLOC_VMADDR(addr), phys_addr, size, flags)) {
+ if (remap_area_pages((unsigned long) addr, phys_addr, size, flags)) {
vfree(addr);
return NULL;
}
diff -Nru a/arch/arm26/kernel/init_task.c b/arch/arm26/kernel/init_task.c
--- a/arch/arm26/kernel/init_task.c Wed Oct 8 12:24:56 2003
+++ b/arch/arm26/kernel/init_task.c Wed Oct 8 12:24:56 2003
@@ -5,6 +5,7 @@
*
*/
#include
+#include
#include
#include
#include
@@ -19,6 +20,8 @@
static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
struct mm_struct init_mm = INIT_MM(init_mm);
+EXPORT_SYMBOL(init_mm);
+
/*
* Initial thread structure.
*
@@ -39,3 +42,5 @@
* All other task structs will be allocated on slabs in fork.c
*/
struct task_struct init_task = INIT_TASK(init_task);
+
+EXPORT_SYMBOL(init_task);
diff -Nru a/arch/arm26/kernel/irq.c b/arch/arm26/kernel/irq.c
--- a/arch/arm26/kernel/irq.c Wed Oct 8 12:24:57 2003
+++ b/arch/arm26/kernel/irq.c Wed Oct 8 12:24:57 2003
@@ -19,6 +19,7 @@
* Naturally it's not a 1:1 relation, but there are similarities.
*/
#include
+#include
#include
#include
#include
@@ -560,6 +561,8 @@
return retval;
}
+EXPORT_SYMBOL(request_irq);
+
/**
* free_irq - free an interrupt
* @irq: Interrupt line to free
@@ -603,6 +606,8 @@
spin_unlock_irqrestore(&irq_controller_lock, flags);
}
+EXPORT_SYMBOL(free_irq);
+
/* Start the interrupt probing. Unlike other architectures,
* we don't return a mask of interrupts from probe_irq_on,
* but return the number of interrupts enabled for the probe.
@@ -653,6 +658,8 @@
return irqs;
}
+EXPORT_SYMBOL(probe_irq_on);
+
/*
* Possible return values:
* >= 0 - interrupt number
@@ -686,6 +693,8 @@
return irq_found;
}
+
+EXPORT_SYMBOL(probe_irq_off);
void __init init_irq_proc(void)
{
diff -Nru a/arch/arm26/kernel/process.c b/arch/arm26/kernel/process.c
--- a/arch/arm26/kernel/process.c Wed Oct 8 12:24:57 2003
+++ b/arch/arm26/kernel/process.c Wed Oct 8 12:24:57 2003
@@ -12,6 +12,7 @@
#include
#include
+#include
#include
#include
#include
@@ -42,11 +43,15 @@
hlt_counter++;
}
+EXPORT_SYMBOL(disable_hlt);
+
void enable_hlt(void)
{
hlt_counter--;
}
+EXPORT_SYMBOL(enable_hlt);
+
static int __init nohlt_setup(char *__unused)
{
hlt_counter = 1;
@@ -115,6 +120,8 @@
leds_event(led_halted);
}
+EXPORT_SYMBOL(machine_halt);
+
void machine_power_off(void)
{
leds_event(led_halted);
@@ -122,6 +129,8 @@
pm_power_off();
}
+EXPORT_SYMBOL(machine_power_off);
+
void machine_restart(char * __unused)
{
/*
@@ -151,6 +160,8 @@
printk("Reboot failed -- System halted\n");
while (1);
}
+
+EXPORT_SYMBOL(machine_restart);
void show_regs(struct pt_regs * regs)
{
diff -Nru a/arch/arm26/kernel/time.c b/arch/arm26/kernel/time.c
--- a/arch/arm26/kernel/time.c Wed Oct 8 12:24:57 2003
+++ b/arch/arm26/kernel/time.c Wed Oct 8 12:24:57 2003
@@ -36,6 +36,8 @@
u64 jiffies_64 = INITIAL_JIFFIES;
+EXPORT_SYMBOL(jiffies_64);
+
extern unsigned long wall_jiffies;
/* this needs a better home */
@@ -148,6 +150,8 @@
tv->tv_usec = usec;
}
+EXPORT_SYMBOL(do_gettimeofday);
+
int do_settimeofday(struct timespec *tv)
{
if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
@@ -177,6 +181,8 @@
write_sequnlock_irq(&xtime_lock);
return 0;
}
+
+EXPORT_SYMBOL(do_settimeofday);
static irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
diff -Nru a/arch/arm26/kernel/traps.c b/arch/arm26/kernel/traps.c
--- a/arch/arm26/kernel/traps.c Wed Oct 8 12:24:57 2003
+++ b/arch/arm26/kernel/traps.c Wed Oct 8 12:24:57 2003
@@ -134,6 +134,8 @@
dump_mem("Stack: ", sp, 8192+(unsigned long)tsk->thread_info);
}
+EXPORT_SYMBOL(dump_stack);
+
void dump_stack(void)
{
#ifdef CONFIG_DEBUG_ERRORS
diff -Nru a/arch/cris/arch-v10/lib/old_checksum.c b/arch/cris/arch-v10/lib/old_checksum.c
--- a/arch/cris/arch-v10/lib/old_checksum.c Wed Oct 8 12:24:57 2003
+++ b/arch/cris/arch-v10/lib/old_checksum.c Wed Oct 8 12:24:57 2003
@@ -19,6 +19,7 @@
*/
#include
+#include
#undef PROFILE_CHECKSUM
@@ -80,3 +81,5 @@
BITOFF;
return(sum);
}
+
+EXPORT_SYMBOL(csum_partial);
diff -Nru a/arch/cris/kernel/irq.c b/arch/cris/kernel/irq.c
--- a/arch/cris/kernel/irq.c Wed Oct 8 12:24:57 2003
+++ b/arch/cris/kernel/irq.c Wed Oct 8 12:24:57 2003
@@ -22,6 +22,7 @@
*/
#include
+#include
#include
#include
@@ -70,12 +71,16 @@
return 0;
}
+EXPORT_SYMBOL(probe_irq_on);
+
int
probe_irq_off(unsigned long x)
{
return 0;
}
+EXPORT_SYMBOL(probe_irq_off);
+
/*
* Initial irq handlers.
*/
@@ -253,6 +258,8 @@
kfree(action);
return retval;
}
+
+EXPORT_SYMBOL(request_irq);
void free_irq(unsigned int irq, void *dev_id)
{
@@ -281,6 +288,8 @@
}
printk("Trying to free free IRQ%d\n",irq);
}
+
+EXPORT_SYMBOL(free_irq);
void weird_irq(void)
{
diff -Nru a/arch/cris/kernel/process.c b/arch/cris/kernel/process.c
--- a/arch/cris/kernel/process.c Wed Oct 8 12:24:57 2003
+++ b/arch/cris/kernel/process.c Wed Oct 8 12:24:57 2003
@@ -96,6 +96,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -119,6 +120,8 @@
static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
struct mm_struct init_mm = INIT_MM(init_mm);
+EXPORT_SYMBOL(init_mm);
+
/*
* Initial thread structure.
*
@@ -137,7 +140,7 @@
*/
struct task_struct init_task = INIT_TASK(init_task);
-
+EXPORT_SYMBOL(init_task);
/*
* The hlt_counter, disable_hlt and enable_hlt is just here as a hook if
@@ -155,10 +158,14 @@
hlt_counter++;
}
+EXPORT_SYMBOL(disable_hlt);
+
void enable_hlt(void)
{
hlt_counter--;
}
+
+EXPORT_SYMBOL(enable_hlt);
/*
* The following aren't currently used.
@@ -193,6 +200,8 @@
hard_reset_now();
}
+EXPORT_SYMBOL(machine_restart);
+
/*
* Similar to machine_power_off, but don't shut off power. Add code
* here to freeze the system for e.g. post-mortem debug purpose when
@@ -203,11 +212,15 @@
{
}
+EXPORT_SYMBOL(machine_halt);
+
/* If or when software power-off is implemented, add code here. */
void machine_power_off(void)
{
}
+
+EXPORT_SYMBOL(machine_power_off);
/*
* When a process does an "exec", machine state like FPU and debug
diff -Nru a/arch/cris/kernel/time.c b/arch/cris/kernel/time.c
--- a/arch/cris/kernel/time.c Wed Oct 8 12:24:56 2003
+++ b/arch/cris/kernel/time.c Wed Oct 8 12:24:56 2003
@@ -24,6 +24,7 @@
#include
#include
+#include
#include
#include
#include
@@ -31,6 +32,8 @@
u64 jiffies_64 = INITIAL_JIFFIES;
+EXPORT_SYMBOL(jiffies_64);
+
int have_rtc; /* used to remember if we have an RTC or not */;
#define TICK_SIZE tick
@@ -72,6 +75,8 @@
tv->tv_usec = usec;
}
+EXPORT_SYMBOL(do_gettimeofday);
+
int do_settimeofday(struct timespec *tv)
{
unsigned long flags;
@@ -105,6 +110,8 @@
local_irq_restore(flags);
return 0;
}
+
+EXPORT_SYMBOL(do_settimeofday);
/*
diff -Nru a/arch/cris/kernel/traps.c b/arch/cris/kernel/traps.c
--- a/arch/cris/kernel/traps.c Wed Oct 8 12:24:57 2003
+++ b/arch/cris/kernel/traps.c Wed Oct 8 12:24:57 2003
@@ -142,6 +142,8 @@
show_stack(NULL, NULL);
}
+EXPORT_SYMBOL(dump_stack);
+
void __init
trap_init(void)
{
diff -Nru a/arch/cris/mm/ioremap.c b/arch/cris/mm/ioremap.c
--- a/arch/cris/mm/ioremap.c Wed Oct 8 12:24:55 2003
+++ b/arch/cris/mm/ioremap.c Wed Oct 8 12:24:55 2003
@@ -157,7 +157,7 @@
if (!area)
return NULL;
addr = area->addr;
- if (remap_area_pages(VMALLOC_VMADDR(addr), phys_addr, size, flags)) {
+ if (remap_area_pages((unsigned long) addr, phys_addr, size, flags)) {
vfree(addr);
return NULL;
}
diff -Nru a/arch/h8300/README b/arch/h8300/README
--- a/arch/h8300/README Wed Oct 8 12:24:57 2003
+++ b/arch/h8300/README Wed Oct 8 12:24:57 2003
@@ -16,7 +16,7 @@
3.H8MAX
Under development
- see http://www.strawbelly-linux.com (Japanese Only)
+ see http://www.strawberry-linux.com (Japanese Only)
* Toolchain Version
gcc-3.1 or higher and patch
diff -Nru a/arch/h8300/kernel/init_task.c b/arch/h8300/kernel/init_task.c
--- a/arch/h8300/kernel/init_task.c Wed Oct 8 12:24:56 2003
+++ b/arch/h8300/kernel/init_task.c Wed Oct 8 12:24:56 2003
@@ -2,6 +2,7 @@
* linux/arch/h8300/kernel/init_task.c
*/
#include
+#include
#include
#include
#include
@@ -16,6 +17,8 @@
static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
struct mm_struct init_mm = INIT_MM(init_mm);
+EXPORT_SYMBOL(init_mm);
+
/*
* Initial task structure.
*
@@ -24,6 +27,7 @@
__asm__(".align 4");
struct task_struct init_task = INIT_TASK(init_task);
+EXPORT_SYMBOL(init_task);
/*
* Initial thread structure.
diff -Nru a/arch/h8300/kernel/process.c b/arch/h8300/kernel/process.c
--- a/arch/h8300/kernel/process.c Wed Oct 8 12:24:55 2003
+++ b/arch/h8300/kernel/process.c Wed Oct 8 12:24:55 2003
@@ -24,6 +24,7 @@
#include
#include
+#include
#include
#include
#include
@@ -89,6 +90,8 @@
__asm__("jmp @@0");
}
+EXPORT_SYMBOL(machine_restart);
+
void machine_halt(void)
{
local_irq_disable();
@@ -96,12 +99,16 @@
for (;;);
}
+EXPORT_SYMBOL(machine_halt);
+
void machine_power_off(void)
{
local_irq_disable();
__asm__("sleep");
for (;;);
}
+
+EXPORT_SYMBOL(machine_power_off);
void show_regs(struct pt_regs * regs)
{
diff -Nru a/arch/h8300/kernel/time.c b/arch/h8300/kernel/time.c
--- a/arch/h8300/kernel/time.c Wed Oct 8 12:24:56 2003
+++ b/arch/h8300/kernel/time.c Wed Oct 8 12:24:56 2003
@@ -18,6 +18,7 @@
#include /* CONFIG_HEARTBEAT */
#include
+#include
#include
#include
#include
@@ -33,6 +34,8 @@
u64 jiffies_64;
+EXPORT_SYMBOL(jiffies_64);
+
static inline void do_profile (unsigned long pc)
{
if (prof_buffer && current->pid) {
@@ -110,6 +113,8 @@
tv->tv_usec = usec;
}
+EXPORT_SYMBOL(do_gettimeofday);
+
int do_settimeofday(struct timespec *tv)
{
if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
@@ -136,3 +141,5 @@
write_sequnlock_irq(&xtime_lock);
return 0;
}
+
+EXPORT_SYMBOL(do_settimeofday);
diff -Nru a/arch/h8300/lib/checksum.c b/arch/h8300/lib/checksum.c
--- a/arch/h8300/lib/checksum.c Wed Oct 8 12:24:55 2003
+++ b/arch/h8300/lib/checksum.c Wed Oct 8 12:24:55 2003
@@ -32,6 +32,7 @@
of the assembly has to go. */
#include
+#include
static inline unsigned short from32to16(unsigned long x)
{
@@ -122,6 +123,8 @@
result = (result & 0xffff) + (result >> 16);
return result;
}
+
+EXPORT_SYMBOL(csum_partial);
/*
* this routine is used for miscellaneous IP-like checksums, mainly
diff -Nru a/arch/h8300/platform/h8300h/ints.c b/arch/h8300/platform/h8300h/ints.c
--- a/arch/h8300/platform/h8300h/ints.c Wed Oct 8 12:24:56 2003
+++ b/arch/h8300/platform/h8300h/ints.c Wed Oct 8 12:24:56 2003
@@ -13,6 +13,7 @@
* Copyright 1999 D. Jeff Dionne
*/
+#include
#include
#include
#include
@@ -155,6 +156,8 @@
return 0;
}
+EXPORT_SYMBOL(request_irq);
+
void free_irq(unsigned int irq, void *dev_id)
{
if (irq >= NR_IRQS) {
@@ -171,6 +174,8 @@
}
}
+EXPORT_SYMBOL(free_irq);
+
/*
* Do we need these probe functions on the m68k?
*/
@@ -179,10 +184,14 @@
return 0;
}
+EXPORT_SYMBOL(probe_irq_on);
+
int probe_irq_off (unsigned long irqs)
{
return 0;
}
+
+EXPORT_SYMBOL(probe_irq_off);
void enable_irq(unsigned int irq)
{
diff -Nru a/arch/h8300/platform/h8s/ints.c b/arch/h8300/platform/h8s/ints.c
--- a/arch/h8300/platform/h8s/ints.c Wed Oct 8 12:24:56 2003
+++ b/arch/h8300/platform/h8s/ints.c Wed Oct 8 12:24:56 2003
@@ -13,6 +13,7 @@
* Copyright 1999 D. Jeff Dionne
*/
+#include
#include
#include
#include
@@ -201,6 +202,8 @@
return 0;
}
+EXPORT_SYMBOL(request_irq);
+
void free_irq(unsigned int irq, void *dev_id)
{
if (irq >= NR_IRQS)
@@ -228,15 +231,21 @@
}
}
+EXPORT_SYMBOL(free_irq);
+
unsigned long probe_irq_on (void)
{
return 0;
}
+EXPORT_SYMBOL(probe_irq_on);
+
int probe_irq_off (unsigned long irqs)
{
return 0;
}
+
+EXPORT_SYMBOL(probe_irq_off);
void enable_irq(unsigned int irq)
{
diff -Nru a/arch/i386/Kconfig b/arch/i386/Kconfig
--- a/arch/i386/Kconfig Wed Oct 8 12:24:55 2003
+++ b/arch/i386/Kconfig Wed Oct 8 12:24:55 2003
@@ -447,7 +447,7 @@
default "8"
help
This allows you to specify the maximum number of CPUs which this
- kernel will support. The maximum supported value is 32 and the
+ kernel will support. The maximum supported value is 255 and the
minimum value which makes sense is 2.
This is purely to save memory - each supported CPU adds
@@ -1118,54 +1118,10 @@
endmenu
-source "drivers/base/Kconfig"
-
-source "drivers/mtd/Kconfig"
-
-source "drivers/parport/Kconfig"
-
-source "drivers/pnp/Kconfig"
-
-source "drivers/block/Kconfig"
-
-source "drivers/ide/Kconfig"
-
-source "drivers/scsi/Kconfig"
-
-source "drivers/cdrom/Kconfig"
-
-source "drivers/md/Kconfig"
-
-source "drivers/message/fusion/Kconfig"
-
-source "drivers/ieee1394/Kconfig"
-
-source "drivers/message/i2o/Kconfig"
-
-source "net/Kconfig"
-
-source "drivers/isdn/Kconfig"
-
-source "drivers/telephony/Kconfig"
-
-#
-# input before char - char/joystick depends on it. As does USB.
-#
-source "drivers/input/Kconfig"
-
-source "drivers/char/Kconfig"
-
-#source drivers/misc/Config.in
-source "drivers/media/Kconfig"
+source "drivers/Kconfig"
source "fs/Kconfig"
-source "drivers/video/Kconfig"
-
-source "sound/Kconfig"
-
-source "drivers/usb/Kconfig"
-
source "arch/i386/oprofile/Kconfig"
@@ -1302,4 +1258,9 @@
config X86_TRAMPOLINE
bool
depends on SMP || X86_VISWS
+ default y
+
+config PC
+ bool
+ depends on X86 && !EMBEDDED
default y
diff -Nru a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c
--- a/arch/i386/kernel/acpi/boot.c Wed Oct 8 12:24:57 2003
+++ b/arch/i386/kernel/acpi/boot.c Wed Oct 8 12:24:57 2003
@@ -183,8 +183,7 @@
#endif /*CONFIG_X86_LOCAL_APIC*/
-#ifdef CONFIG_X86_IO_APIC
-
+#if defined(CONFIG_X86_IO_APIC) && defined(CONFIG_ACPI_INTERPRETER)
static int __init
acpi_parse_ioapic (
@@ -368,7 +367,6 @@
result = acpi_table_parse(ACPI_APIC, acpi_parse_madt);
if (!result) {
- printk(KERN_WARNING PREFIX "MADT not present\n");
return 0;
}
else if (result < 0) {
@@ -416,7 +414,7 @@
#endif /*CONFIG_X86_LOCAL_APIC*/
-#ifdef CONFIG_X86_IO_APIC
+#if defined(CONFIG_X86_IO_APIC) && defined(CONFIG_ACPI_INTERPRETER)
/*
* I/O APIC
@@ -472,7 +470,8 @@
acpi_irq_model = ACPI_IRQ_MODEL_IOAPIC;
acpi_ioapic = 1;
-#endif /*CONFIG_X86_IO_APIC*/
+
+#endif /* CONFIG_X86_IO_APIC && CONFIG_ACPI_INTERPRETER */
#ifdef CONFIG_X86_LOCAL_APIC
if (acpi_lapic && acpi_ioapic) {
@@ -480,6 +479,7 @@
clustered_apic_check();
}
#endif
+
#ifdef CONFIG_HPET_TIMER
acpi_table_parse(ACPI_HPET, acpi_parse_hpet);
#endif
diff -Nru a/arch/i386/kernel/cpu/cpufreq/Kconfig b/arch/i386/kernel/cpu/cpufreq/Kconfig
--- a/arch/i386/kernel/cpu/cpufreq/Kconfig Wed Oct 8 12:24:56 2003
+++ b/arch/i386/kernel/cpu/cpufreq/Kconfig Wed Oct 8 12:24:56 2003
@@ -12,7 +12,7 @@
because the lower the clock speed, the less power the CPU consumes.
For more information, take a look at linux/Documentation/cpu-freq or
- at
+ at
If in doubt, say N.
@@ -83,6 +83,16 @@
depends on CPU_FREQ_TABLE
help
This adds the CPUFreq driver for mobile AMD K7 mobile processors.
+
+ For details, take a look at linux/Documentation/cpu-freq.
+
+ If in doubt, say N.
+
+config X86_POWERNOW_K8
+ tristate "AMD Opteron/Athlon64 PowerNow!"
+ depends on CPU_FREQ && EXPERIMENTAL
+ help
+ This adds the CPUFreq driver for mobile AMD Opteron/Athlon64 processors.
For details, take a look at linux/Documentation/cpu-freq.
diff -Nru a/arch/i386/kernel/cpu/cpufreq/Makefile b/arch/i386/kernel/cpu/cpufreq/Makefile
--- a/arch/i386/kernel/cpu/cpufreq/Makefile Wed Oct 8 12:24:56 2003
+++ b/arch/i386/kernel/cpu/cpufreq/Makefile Wed Oct 8 12:24:56 2003
@@ -1,5 +1,6 @@
obj-$(CONFIG_X86_POWERNOW_K6) += powernow-k6.o
obj-$(CONFIG_X86_POWERNOW_K7) += powernow-k7.o
+obj-$(CONFIG_X86_POWERNOW_K8) += powernow-k8.o
obj-$(CONFIG_X86_LONGHAUL) += longhaul.o
obj-$(CONFIG_X86_P4_CLOCKMOD) += p4-clockmod.o
obj-$(CONFIG_ELAN_CPUFREQ) += elanfreq.o
diff -Nru a/arch/i386/kernel/cpu/cpufreq/acpi.c b/arch/i386/kernel/cpu/cpufreq/acpi.c
--- a/arch/i386/kernel/cpu/cpufreq/acpi.c Wed Oct 8 12:24:55 2003
+++ b/arch/i386/kernel/cpu/cpufreq/acpi.c Wed Oct 8 12:24:55 2003
@@ -231,7 +231,7 @@
int state)
{
u16 port = 0;
- u8 value = 0;
+ u16 value = 0;
int i = 0;
struct cpufreq_freqs cpufreq_freqs;
@@ -282,9 +282,9 @@
value = (u16) perf->states[state].control;
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "Writing 0x%02x to port 0x%04x\n", value, port));
+ "Writing 0x%04x to port 0x%04x\n", value, port));
- outb(value, port);
+ outw(value, port);
/*
* Then we read the 'status_register' and compare the value with the
@@ -296,12 +296,12 @@
port = perf->status_register;
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "Looking for 0x%02x from port 0x%04x\n",
- (u8) perf->states[state].status, port));
+ "Looking for 0x%04x from port 0x%04x\n",
+ (u16) perf->states[state].status, port));
for (i=0; i<100; i++) {
- value = inb(port);
- if (value == (u8) perf->states[state].status)
+ value = inw(port);
+ if (value == (u16) perf->states[state].status)
break;
udelay(10);
}
@@ -309,7 +309,7 @@
/* notify cpufreq */
cpufreq_notify_transition(&cpufreq_freqs, CPUFREQ_POSTCHANGE);
- if (value != perf->states[state].status) {
+ if (value != (u16) perf->states[state].status) {
unsigned int tmp = cpufreq_freqs.new;
cpufreq_freqs.new = cpufreq_freqs.old;
cpufreq_freqs.old = tmp;
diff -Nru a/arch/i386/kernel/cpu/cpufreq/longhaul.c b/arch/i386/kernel/cpu/cpufreq/longhaul.c
--- a/arch/i386/kernel/cpu/cpufreq/longhaul.c Wed Oct 8 12:24:55 2003
+++ b/arch/i386/kernel/cpu/cpufreq/longhaul.c Wed Oct 8 12:24:55 2003
@@ -70,21 +70,6 @@
}
-static unsigned int longhaul_get_cpu_fsb (void)
-{
- unsigned long lo, hi;
- unsigned int eblcr_fsb_table[] = { 66, 133, 100, -1 };
- unsigned int invalue=0;
-
- if (fsb == 0) {
- rdmsr (MSR_IA32_EBL_CR_POWERON, lo, hi);
- invalue = (lo & (1<<18|1<<19)) >>18;
- fsb = eblcr_fsb_table[invalue];
- }
- return fsb;
-}
-
-
static int longhaul_get_cpu_mult (void)
{
unsigned long invalue=0,lo, hi;
@@ -168,7 +153,7 @@
break;
/*
- * Longhaul v3. (Ezra-T [C5M], Nehemiag [C5N])
+ * Longhaul v3. (Ezra-T [C5M], Nehemiah [C5N])
* This can also do voltage scaling, but see above.
* Ezra-T was alleged to do FSB scaling too, but it never worked in practice.
*/
@@ -193,6 +178,39 @@
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
}
+/*
+ * Centaur decided to make life a little more tricky.
+ * Only longhaul v1 is allowed to read EBLCR BSEL[0:1].
+ * Samuel2 and above have to try and guess what the FSB is.
+ * We do this by assuming we booted at maximum multiplier, and interpolate
+ * between that value multiplied by possible FSBs and cpu_mhz which
+ * was calculated at boot time. Really ugly, but no other way to do this.
+ */
+static int _guess (int guess, int maxmult)
+{
+ int target;
+
+ target = ((maxmult/10)*guess);
+ if (maxmult%10 != 0)
+ target += (guess/2);
+ target &= ~0xf;
+ return target;
+}
+
+static int guess_fsb(int maxmult)
+{
+ int speed = (cpu_khz/1000) & ~0xf;
+ int i;
+ int speeds[3] = { 66, 100, 133 };
+
+ for (i=0; i<3; i++) {
+ if (_guess(speeds[i],maxmult) == speed)
+ return speeds[i];
+ }
+ return 0;
+}
+
+
static int __init longhaul_get_ranges (void)
{
@@ -203,8 +221,8 @@
-1,110,120,-1,135,115,125,105,130,150,160,140,-1,155,-1,145 };
unsigned int j, k = 0;
union msr_longhaul longhaul;
-
- fsb = longhaul_get_cpu_fsb();
+ unsigned long lo, hi;
+ unsigned int eblcr_fsb_table[] = { 66, 133, 100, -1 };
switch (longhaul_version) {
case 1:
@@ -212,6 +230,9 @@
Assume min=3.0x & max = whatever we booted at. */
minmult = 30;
maxmult = longhaul_get_cpu_mult();
+ rdmsr (MSR_IA32_EBL_CR_POWERON, lo, hi);
+ invalue = (lo & (1<<18|1<<19)) >>18;
+ fsb = eblcr_fsb_table[invalue];
break;
case 2 ... 3:
@@ -222,14 +243,13 @@
invalue += 16;
maxmult=multipliers[invalue];
-#if 0
invalue = longhaul.bits.MinMHzBR;
- if (longhaul.bits.MinMHzBR4);
- invalue += 16;
- minmult = multipliers[invalue];
-#else
- minmult = 30; /* as per spec */
-#endif
+ if (longhaul.bits.MinMHzBR4 == 1)
+ minmult = 30;
+ else
+ minmult = multipliers[invalue];
+
+ fsb = guess_fsb(maxmult);
break;
}
@@ -353,7 +373,7 @@
case 6:
cpuname = "C3 'Samuel' [C5A]";
longhaul_version=1;
- memcpy (clock_ratio, longhaul1_clock_ratio, sizeof(longhaul1_clock_ratio));
+ memcpy (clock_ratio, samuel1_clock_ratio, sizeof(samuel1_clock_ratio));
memcpy (eblcr_table, samuel1_eblcr, sizeof(samuel1_eblcr));
break;
@@ -362,13 +382,17 @@
case 0:
cpuname = "C3 'Samuel 2' [C5B]";
longhaul_version=1;
- memcpy (clock_ratio, longhaul1_clock_ratio, sizeof(longhaul1_clock_ratio));
+ /* Note, this is not a typo, early Samuel2's had Samuel1 ratios. */
+ memcpy (clock_ratio, samuel1_clock_ratio, sizeof(samuel1_clock_ratio));
memcpy (eblcr_table, samuel2_eblcr, sizeof(samuel2_eblcr));
break;
case 1 ... 15:
- cpuname = "C3 'Ezra' [C5C]";
+ if (c->x86_mask < 8)
+ cpuname = "C3 'Samuel 2' [C5B]";
+ else
+ cpuname = "C3 'Ezra' [C5C]";
longhaul_version=2;
- memcpy (clock_ratio, longhaul2_clock_ratio, sizeof(longhaul2_clock_ratio));
+ memcpy (clock_ratio, ezra_clock_ratio, sizeof(ezra_clock_ratio));
memcpy (eblcr_table, ezra_eblcr, sizeof(ezra_eblcr));
break;
}
@@ -378,14 +402,16 @@
cpuname = "C3 'Ezra-T [C5M]";
longhaul_version=3;
numscales=32;
- memcpy (clock_ratio, longhaul3_clock_ratio, sizeof(longhaul3_clock_ratio));
- memcpy (eblcr_table, c5m_eblcr, sizeof(c5m_eblcr));
+ memcpy (clock_ratio, ezrat_clock_ratio, sizeof(ezrat_clock_ratio));
+ memcpy (eblcr_table, ezrat_eblcr, sizeof(ezrat_eblcr));
break;
/*
case 9:
cpuname = "C3 'Nehemiah' [C5N]";
longhaul_version=3;
numscales=32;
+ memcpy (clock_ratio, nehemiah_clock_ratio, sizeof(nehemiah_clock_ratio));
+ memcpy (eblcr_table, nehemiah_eblcr, sizeof(nehemiah_eblcr));
*/
default:
cpuname = "Unknown";
@@ -425,12 +451,8 @@
return -ENODEV;
switch (c->x86_model) {
- case 6 ... 7:
+ case 6 ... 8:
return cpufreq_register_driver(&longhaul_driver);
- case 8:
- printk (KERN_INFO PFX "Ezra-T unsupported: Waiting on updated docs "
- "from VIA before this is usable.\n");
- break;
case 9:
printk (KERN_INFO PFX "Nehemiah unsupported: Waiting on working silicon "
"from VIA before this is usable.\n");
diff -Nru a/arch/i386/kernel/cpu/cpufreq/longhaul.h b/arch/i386/kernel/cpu/cpufreq/longhaul.h
--- a/arch/i386/kernel/cpu/cpufreq/longhaul.h Wed Oct 8 12:24:56 2003
+++ b/arch/i386/kernel/cpu/cpufreq/longhaul.h Wed Oct 8 12:24:56 2003
@@ -56,7 +56,7 @@
/*
* VIA C3 Samuel 1 & Samuel 2 (stepping 0)
*/
-static int __initdata longhaul1_clock_ratio[16] = {
+static int __initdata samuel1_clock_ratio[16] = {
-1, /* 0000 -> RESERVED */
30, /* 0001 -> 3.0x */
40, /* 0010 -> 4.0x */
@@ -95,27 +95,8 @@
};
/*
- * VIA C3 Samuel2 Stepping 1->15 & VIA C3 Ezra
+ * VIA C3 Samuel2 Stepping 1->15
*/
-static int __initdata longhaul2_clock_ratio[16] = {
- 100, /* 0000 -> 10.0x */
- 30, /* 0001 -> 3.0x */
- 40, /* 0010 -> 4.0x */
- 90, /* 0011 -> 9.0x */
- 95, /* 0100 -> 9.5x */
- 35, /* 0101 -> 3.5x */
- 45, /* 0110 -> 4.5x */
- 55, /* 0111 -> 5.5x */
- 60, /* 1000 -> 6.0x */
- 70, /* 1001 -> 7.0x */
- 80, /* 1010 -> 8.0x */
- 50, /* 1011 -> 5.0x */
- 65, /* 1100 -> 6.5x */
- 75, /* 1101 -> 7.5x */
- 85, /* 1110 -> 8.5x */
- 120, /* 1111 -> 12.0x */
-};
-
static int __initdata samuel2_eblcr[16] = {
50, /* 0000 -> 5.0x */
30, /* 0001 -> 3.0x */
@@ -135,6 +116,28 @@
65, /* 1111 -> 6.5x */
};
+/*
+ * VIA C3 Ezra
+ */
+static int __initdata ezra_clock_ratio[16] = {
+ 100, /* 0000 -> 10.0x */
+ 30, /* 0001 -> 3.0x */
+ 40, /* 0010 -> 4.0x */
+ 90, /* 0011 -> 9.0x */
+ 95, /* 0100 -> 9.5x */
+ 35, /* 0101 -> 3.5x */
+ 45, /* 0110 -> 4.5x */
+ 55, /* 0111 -> 5.5x */
+ 60, /* 1000 -> 6.0x */
+ 70, /* 1001 -> 7.0x */
+ 80, /* 1010 -> 8.0x */
+ 50, /* 1011 -> 5.0x */
+ 65, /* 1100 -> 6.5x */
+ 75, /* 1101 -> 7.5x */
+ 85, /* 1110 -> 8.5x */
+ 120, /* 1111 -> 12.0x */
+};
+
static int __initdata ezra_eblcr[16] = {
50, /* 0000 -> 5.0x */
30, /* 0001 -> 3.0x */
@@ -157,7 +160,7 @@
/*
* VIA C3 (Ezra-T) [C5M].
*/
-static int __initdata longhaul3_clock_ratio[32] = {
+static int __initdata ezrat_clock_ratio[32] = {
100, /* 0000 -> 10.0x */
30, /* 0001 -> 3.0x */
40, /* 0010 -> 4.0x */
@@ -193,7 +196,7 @@
-1, /* 1111 -> RESERVED (12.0x) */
};
-static int __initdata c5m_eblcr[32] = {
+static int __initdata ezrat_eblcr[32] = {
50, /* 0000 -> 5.0x */
30, /* 0001 -> 3.0x */
40, /* 0010 -> 4.0x */
@@ -229,7 +232,79 @@
145, /* 1111 -> 14.5x */
};
+/*
+ * VIA C3 Nehemiah */
+static int __initdata nehemiah_clock_ratio[32] = {
+ 100, /* 0000 -> 10.0x */
+ 160, /* 0001 -> 16.0x */
+ -1, /* 0010 -> RESERVED */
+ 90, /* 0011 -> 9.0x */
+ 95, /* 0100 -> 9.5x */
+ -1, /* 0101 -> RESERVED */
+ -1, /* 0110 -> RESERVED */
+ 55, /* 0111 -> 5.5x */
+ 60, /* 1000 -> 6.0x */
+ 70, /* 1001 -> 7.0x */
+ 80, /* 1010 -> 8.0x */
+ 50, /* 1011 -> 5.0x */
+ 65, /* 1100 -> 6.5x */
+ 75, /* 1101 -> 7.5x */
+ 85, /* 1110 -> 8.5x */
+ 120, /* 1111 -> 12.0x */
+
+ 100, /* 0000 -> 10.0x */
+ 110, /* 0001 -> 11.0x */
+ 120, /* 0010 -> 12.0x */
+ 90, /* 0011 -> 9.0x */
+ 105, /* 0100 -> 10.5x */
+ 115, /* 0101 -> 11.5x */
+ 125, /* 0110 -> 12.5x */
+ 135, /* 0111 -> 13.5x */
+ 140, /* 1000 -> 14.0x */
+ 150, /* 1001 -> 15.0x */
+ 160, /* 1010 -> 16.0x */
+ 130, /* 1011 -> 13.0x */
+ 145, /* 1100 -> 14.5x */
+ 155, /* 1101 -> 15.5x */
+ -1, /* 1110 -> RESERVED */
+ 120, /* 1111 -> 12.0x */
+};
+static int __initdata nehemiah_eblcr[32] = {
+ 50, /* 0000 -> 5.0x */
+ 160, /* 0001 -> 16.0x */
+ -1, /* 0010 -> RESERVED */
+ 100, /* 0011 -> 10.0x */
+ 55, /* 0100 -> 5.5x */
+ -1, /* 0101 -> RESERVED */
+ -1, /* 0110 -> RESERVED */
+ 95, /* 0111 -> 9.5x */
+ 90, /* 1000 -> 9.0x */
+ 70, /* 1001 -> 7.0x */
+ 80, /* 1010 -> 8.0x */
+ 60, /* 1011 -> 6.0x */
+ 120, /* 1100 -> 12.0x */
+ 75, /* 1101 -> 7.5x */
+ 85, /* 1110 -> 8.5x */
+ 65, /* 1111 -> 6.5x */
+
+ 90, /* 0000 -> 9.0x */
+ 110, /* 0001 -> 11.0x */
+ 120, /* 0010 -> 12.0x */
+ 100, /* 0011 -> 10.0x */
+ 135, /* 0100 -> 13.5x */
+ 115, /* 0101 -> 11.5x */
+ 125, /* 0110 -> 12.5x */
+ 105, /* 0111 -> 10.5x */
+ 130, /* 1000 -> 13.0x */
+ 150, /* 1001 -> 15.0x */
+ 160, /* 1010 -> 16.0x */
+ 140, /* 1011 -> 14.0x */
+ 120, /* 1100 -> 12.0x */
+ 155, /* 1101 -> 15.5x */
+ -1, /* 1110 -> RESERVED */
+ -1, /* 1111 -> RESERVED */
+};
/*
* Voltage scales. Div/Mod by 1000 to get actual voltage.
* Which scale to use depends on the VRM type in use.
diff -Nru a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c
--- /dev/null Wed Dec 31 16:00:00 1969
+++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c Wed Oct 8 12:24:58 2003
@@ -0,0 +1,1021 @@
+/*
+ * (c) 2003 Advanced Micro Devices, Inc.
+ * Your use of this code is subject to the terms and conditions of the
+ * GNU general public license version 2. See "../../../COPYING" or
+ * http://www.gnu.org/licenses/gpl.html
+ *
+ * Support : paul.devriendt@amd.com
+ *
+ * Based on the powernow-k7.c module written by Dave Jones.
+ * (C) 2003 Dave Jones on behalf of SuSE Labs
+ * Licensed under the terms of the GNU GPL License version 2.
+ * Based upon datasheets & sample CPUs kindly provided by AMD.
+ *
+ * Processor information obtained from Chapter 9 (Power and Thermal Management)
+ * of the "BIOS and Kernel Developer's Guide for the AMD Athlon 64 and AMD
+ * Opteron Processors", revision 3.03, available for download from www.amd.com
+ *
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+#define PFX "powernow-k8: "
+#define BFX PFX "BIOS error: "
+#define VERSION "version 1.00.08 - September 26, 2003"
+#include "powernow-k8.h"
+
+#ifdef CONFIG_PREEMPT
+#warning this driver has not been tested on a preempt system
+#endif
+
+static u32 vstable; /* voltage stabalization time, from PSB, units 20 us */
+static u32 plllock; /* pll lock time, from PSB, units 1 us */
+static u32 numps; /* number of p-states, from PSB */
+static u32 rvo; /* ramp voltage offset, from PSB */
+static u32 irt; /* isochronous relief time, from PSB */
+static u32 vidmvs; /* usable value calculated from mvs, from PSB */
+struct pst_s *ppst; /* array of p states, valid for this part */
+static u32 currvid; /* keep track of the current fid / vid */
+static u32 currfid;
+
+/*
+The PSB table supplied by BIOS allows for the definition of the number of
+p-states that can be used when running on a/c, and the number of p-states
+that can be used when running on battery. This allows laptop manufacturers
+to force the system to save power when running from battery. The relationship
+is :
+ 1 <= number_of_battery_p_states <= maximum_number_of_p_states
+
+This driver does NOT have the support in it to detect transitions from
+a/c power to battery power, and thus trigger the transition to a lower
+p-state if required. This is because I need ACPI and the 2.6 kernel to do
+this, and this is a 2.4 kernel driver. Check back for a new improved driver
+for the 2.6 kernel soon.
+
+This code therefore assumes it is on battery at all times, and thus
+restricts performance to number_of_battery_p_states. For desktops,
+ number_of_battery_p_states == maximum_number_of_pstates,
+so this is not actually a restriction.
+*/
+
+static u32 batps; /* limit on the number of p states when on battery */
+ /* - set by BIOS in the PSB/PST */
+
+static struct cpufreq_driver cpufreq_amd64_driver = {
+ .verify = powernowk8_verify,
+ .target = powernowk8_target,
+ .init = powernowk8_cpu_init,
+ .name = "cpufreq-amd64",
+ .owner = THIS_MODULE,
+};
+
+#define SEARCH_UP 1
+#define SEARCH_DOWN 0
+
+/* Return a frequency in MHz, given an input fid */
+u32
+find_freq_from_fid(u32 fid)
+{
+ return 800 + (fid * 100);
+}
+
+/* Return a fid matching an input frequency in MHz */
+static u32
+find_fid_from_freq(u32 freq)
+{
+ return (freq - 800) / 100;
+}
+
+/* Return the vco fid for an input fid */
+static u32
+convert_fid_to_vco_fid(u32 fid)
+{
+ if (fid < HI_FID_TABLE_BOTTOM) {
+ return 8 + (2 * fid);
+ } else {
+ return fid;
+ }
+}
+
+/* Sort the fid/vid frequency table into ascending order by fid. The spec */
+/* implies that it will be sorted by BIOS, but, it only implies it, and I */
+/* prefer not to trust when I can check. */
+/* Yes, it is a simple bubble sort, but the PST is really small, so the */
+/* choice of algorithm is pretty irrelevant. */
+static inline void
+sort_pst(struct pst_s *ppst, u32 numpstates)
+{
+ u32 i;
+ u8 tempfid;
+ u8 tempvid;
+ int swaps = 1;
+
+ while (swaps) {
+ swaps = 0;
+ for (i = 0; i < (numpstates - 1); i++) {
+ if (ppst[i].fid > ppst[i + 1].fid) {
+ swaps = 1;
+ tempfid = ppst[i].fid;
+ tempvid = ppst[i].vid;
+ ppst[i].fid = ppst[i + 1].fid;
+ ppst[i].vid = ppst[i + 1].vid;
+ ppst[i + 1].fid = tempfid;
+ ppst[i + 1].vid = tempvid;
+ }
+ }
+ }
+
+ return;
+}
+
+/* Return 1 if the pending bit is set. Unless we are actually just told the */
+/* processor to transition a state, seeing this bit set is really bad news. */
+static inline int
+pending_bit_stuck(void)
+{
+ u32 lo;
+ u32 hi;
+
+ rdmsr(MSR_FIDVID_STATUS, lo, hi);
+ return lo & MSR_S_LO_CHANGE_PENDING ? 1 : 0;
+}
+
+/* Update the global current fid / vid values from the status msr. Returns 1 */
+/* on error. */
+static int
+query_current_values_with_pending_wait(void)
+{
+ u32 lo;
+ u32 hi;
+ u32 i = 0;
+
+ lo = MSR_S_LO_CHANGE_PENDING;
+ while (lo & MSR_S_LO_CHANGE_PENDING) {
+ if (i++ > 0x1000000) {
+ printk(KERN_ERR PFX "detected change pending stuck\n");
+ return 1;
+ }
+ rdmsr(MSR_FIDVID_STATUS, lo, hi);
+ }
+
+ currvid = hi & MSR_S_HI_CURRENT_VID;
+ currfid = lo & MSR_S_LO_CURRENT_FID;
+
+ return 0;
+}
+
+/* the isochronous relief time */
+static inline void
+count_off_irt(void)
+{
+ udelay((1 << irt) * 10);
+ return;
+}
+
+/* the voltage stabalization time */
+static inline void
+count_off_vst(void)
+{
+ udelay(vstable * VST_UNITS_20US);
+ return;
+}
+
+/* write the new fid value along with the other control fields to the msr */
+static int
+write_new_fid(u32 fid)
+{
+ u32 lo;
+ u32 savevid = currvid;
+
+ if ((fid & INVALID_FID_MASK) || (currvid & INVALID_VID_MASK)) {
+ printk(KERN_ERR PFX "internal error - overflow on fid write\n");
+ return 1;
+ }
+
+ lo = fid | (currvid << MSR_C_LO_VID_SHIFT) | MSR_C_LO_INIT_FID_VID;
+
+ dprintk(KERN_DEBUG PFX "writing fid %x, lo %x, hi %x\n",
+ fid, lo, plllock * PLL_LOCK_CONVERSION);
+
+ wrmsr(MSR_FIDVID_CTL, lo, plllock * PLL_LOCK_CONVERSION);
+
+ if (query_current_values_with_pending_wait())
+ return 1;
+
+ count_off_irt();
+
+ if (savevid != currvid) {
+ printk(KERN_ERR PFX
+ "vid changed on fid transition, save %x, currvid %x\n",
+ savevid, currvid);
+ return 1;
+ }
+
+ if (fid != currfid) {
+ printk(KERN_ERR PFX
+ "fid transition failed, fid %x, currfid %x\n",
+ fid, currfid);
+ return 1;
+ }
+
+ return 0;
+}
+
+/* Write a new vid to the hardware */
+static int
+write_new_vid(u32 vid)
+{
+ u32 lo;
+ u32 savefid = currfid;
+
+ if ((currfid & INVALID_FID_MASK) || (vid & INVALID_VID_MASK)) {
+ printk(KERN_ERR PFX "internal error - overflow on vid write\n");
+ return 1;
+ }
+
+ lo = currfid | (vid << MSR_C_LO_VID_SHIFT) | MSR_C_LO_INIT_FID_VID;
+
+ dprintk(KERN_DEBUG PFX "writing vid %x, lo %x, hi %x\n",
+ vid, lo, STOP_GRANT_5NS);
+
+ wrmsr(MSR_FIDVID_CTL, lo, STOP_GRANT_5NS);
+
+ if (query_current_values_with_pending_wait()) {
+ return 1;
+ }
+
+ if (savefid != currfid) {
+ printk(KERN_ERR PFX
+ "fid changed on vid transition, save %x currfid %x\n",
+ savefid, currfid);
+ return 1;
+ }
+
+ if (vid != currvid) {
+ printk(KERN_ERR PFX
+ "vid transition failed, vid %x, currvid %x\n",
+ vid, currvid);
+ return 1;
+ }
+
+ return 0;
+}
+
+/* Reduce the vid by the max of step or reqvid. */
+/* Decreasing vid codes represent increasing voltages : */
+/* vid of 0 is 1.550V, vid of 0x1e is 0.800V, vid of 0x1f is off. */
+static int
+decrease_vid_code_by_step(u32 reqvid, u32 step)
+{
+ if ((currvid - reqvid) > step)
+ reqvid = currvid - step;
+
+ if (write_new_vid(reqvid))
+ return 1;
+
+ count_off_vst();
+
+ return 0;
+}
+
+/* Change the fid and vid, by the 3 phases. */
+static inline int
+transition_fid_vid(u32 reqfid, u32 reqvid)
+{
+ if (core_voltage_pre_transition(reqvid))
+ return 1;
+
+ if (core_frequency_transition(reqfid))
+ return 1;
+
+ if (core_voltage_post_transition(reqvid))
+ return 1;
+
+ if (query_current_values_with_pending_wait())
+ return 1;
+
+ if ((reqfid != currfid) || (reqvid != currvid)) {
+ printk(KERN_ERR PFX "failed: req 0x%x 0x%x, curr 0x%x 0x%x\n",
+ reqfid, reqvid, currfid, currvid);
+ return 1;
+ }
+
+ dprintk(KERN_INFO PFX
+ "transitioned: new fid 0x%x, vid 0x%x\n", currfid, currvid);
+
+ return 0;
+}
+
+/* Phase 1 - core voltage transition ... setup appropriate voltage for the */
+/* fid transition. */
+static inline int
+core_voltage_pre_transition(u32 reqvid)
+{
+ u32 rvosteps = rvo;
+ u32 savefid = currfid;
+
+ dprintk(KERN_DEBUG PFX
+ "ph1: start, currfid 0x%x, currvid 0x%x, reqvid 0x%x, rvo %x\n",
+ currfid, currvid, reqvid, rvo);
+
+ while (currvid > reqvid) {
+ dprintk(KERN_DEBUG PFX "ph1: curr 0x%x, requesting vid 0x%x\n",
+ currvid, reqvid);
+ if (decrease_vid_code_by_step(reqvid, vidmvs))
+ return 1;
+ }
+
+ while (rvosteps > 0) {
+ if (currvid == 0) {
+ rvosteps = 0;
+ } else {
+ dprintk(KERN_DEBUG PFX
+ "ph1: changing vid for rvo, requesting 0x%x\n",
+ currvid - 1);
+ if (decrease_vid_code_by_step(currvid - 1, 1))
+ return 1;
+ rvosteps--;
+ }
+ }
+
+ if (query_current_values_with_pending_wait())
+ return 1;
+
+ if (savefid != currfid) {
+ printk(KERN_ERR PFX "ph1 err, currfid changed 0x%x\n", currfid);
+ return 1;
+ }
+
+ dprintk(KERN_DEBUG PFX "ph1 complete, currfid 0x%x, currvid 0x%x\n",
+ currfid, currvid);
+
+ return 0;
+}
+
+/* Phase 2 - core frequency transition */
+static inline int
+core_frequency_transition(u32 reqfid)
+{
+ u32 vcoreqfid;
+ u32 vcocurrfid;
+ u32 vcofiddiff;
+ u32 savevid = currvid;
+
+ if ((reqfid < HI_FID_TABLE_BOTTOM) && (currfid < HI_FID_TABLE_BOTTOM)) {
+ printk(KERN_ERR PFX "ph2 illegal lo-lo transition 0x%x 0x%x\n",
+ reqfid, currfid);
+ return 1;
+ }
+
+ if (currfid == reqfid) {
+ printk(KERN_ERR PFX "ph2 null fid transition 0x%x\n", currfid);
+ return 0;
+ }
+
+ dprintk(KERN_DEBUG PFX
+ "ph2 starting, currfid 0x%x, currvid 0x%x, reqfid 0x%x\n",
+ currfid, currvid, reqfid);
+
+ vcoreqfid = convert_fid_to_vco_fid(reqfid);
+ vcocurrfid = convert_fid_to_vco_fid(currfid);
+ vcofiddiff = vcocurrfid > vcoreqfid ? vcocurrfid - vcoreqfid
+ : vcoreqfid - vcocurrfid;
+
+ while (vcofiddiff > 2) {
+ if (reqfid > currfid) {
+ if (currfid > LO_FID_TABLE_TOP) {
+ if (write_new_fid(currfid + 2)) {
+ return 1;
+ }
+ } else {
+ if (write_new_fid
+ (2 + convert_fid_to_vco_fid(currfid))) {
+ return 1;
+ }
+ }
+ } else {
+ if (write_new_fid(currfid - 2))
+ return 1;
+ }
+
+ vcocurrfid = convert_fid_to_vco_fid(currfid);
+ vcofiddiff = vcocurrfid > vcoreqfid ? vcocurrfid - vcoreqfid
+ : vcoreqfid - vcocurrfid;
+ }
+
+ if (write_new_fid(reqfid))
+ return 1;
+
+ if (query_current_values_with_pending_wait())
+ return 1;
+
+ if (currfid != reqfid) {
+ printk(KERN_ERR PFX
+ "ph2 mismatch, failed fid transition, curr %x, req %x\n",
+ currfid, reqfid);
+ return 1;
+ }
+
+ if (savevid != currvid) {
+ printk(KERN_ERR PFX
+ "ph2 vid changed, save %x, curr %x\n", savevid,
+ currvid);
+ return 1;
+ }
+
+ dprintk(KERN_DEBUG PFX "ph2 complete, currfid 0x%x, currvid 0x%x\n",
+ currfid, currvid);
+
+ return 0;
+}
+
+/* Phase 3 - core voltage transition flow ... jump to the final vid. */
+static inline int
+core_voltage_post_transition(u32 reqvid)
+{
+ u32 savefid = currfid;
+ u32 savereqvid = reqvid;
+
+ dprintk(KERN_DEBUG PFX "ph3 starting, currfid 0x%x, currvid 0x%x\n",
+ currfid, currvid);
+
+ if (reqvid != currvid) {
+ if (write_new_vid(reqvid))
+ return 1;
+
+ if (savefid != currfid) {
+ printk(KERN_ERR PFX
+ "ph3: bad fid change, save %x, curr %x\n",
+ savefid, currfid);
+ return 1;
+ }
+
+ if (currvid != reqvid) {
+ printk(KERN_ERR PFX
+ "ph3: failed vid transition\n, req %x, curr %x",
+ reqvid, currvid);
+ return 1;
+ }
+ }
+
+ if (query_current_values_with_pending_wait())
+ return 1;
+
+ if (savereqvid != currvid) {
+ dprintk(KERN_ERR PFX "ph3 failed, currvid 0x%x\n", currvid);
+ return 1;
+ }
+
+ if (savefid != currfid) {
+ dprintk(KERN_ERR PFX "ph3 failed, currfid changed 0x%x\n",
+ currfid);
+ return 1;
+ }
+
+ dprintk(KERN_DEBUG PFX "ph3 complete, currfid 0x%x, currvid 0x%x\n",
+ currfid, currvid);
+
+ return 0;
+}
+
+static inline int
+check_supported_cpu(void)
+{
+ struct cpuinfo_x86 *c = cpu_data;
+ u32 eax, ebx, ecx, edx;
+
+ if (num_online_cpus() != 1) {
+ printk(KERN_INFO PFX "multiprocessor systems not supported\n");
+ return 0;
+ }
+
+ if (c->x86_vendor != X86_VENDOR_AMD) {
+ printk(KERN_INFO PFX "Not an AMD processor\n");
+ return 0;
+ }
+
+ eax = cpuid_eax(CPUID_PROCESSOR_SIGNATURE);
+ if ((eax & CPUID_XFAM_MOD) == ATHLON64_XFAM_MOD) {
+ dprintk(KERN_DEBUG PFX "AMD Althon 64 Processor found\n");
+ if ((eax & CPUID_F1_STEP) < ATHLON64_REV_C0) {
+ printk(KERN_INFO PFX "Revision C0 or better "
+ "AMD Athlon 64 processor required\n");
+ return 0;
+ }
+ } else if ((eax & CPUID_XFAM_MOD) == OPTERON_XFAM_MOD) {
+ dprintk(KERN_DEBUG PFX "AMD Opteron Processor found\n");
+ } else {
+ printk(KERN_INFO PFX
+ "AMD Athlon 64 or AMD Opteron processor required\n");
+ return 0;
+ }
+
+ eax = cpuid_eax(CPUID_GET_MAX_CAPABILITIES);
+ if (eax < CPUID_FREQ_VOLT_CAPABILITIES) {
+ printk(KERN_INFO PFX
+ "No frequency change capabilities detected\n");
+ return 0;
+ }
+
+ cpuid(CPUID_FREQ_VOLT_CAPABILITIES, &eax, &ebx, &ecx, &edx);
+ if ((edx & P_STATE_TRANSITION_CAPABLE) != P_STATE_TRANSITION_CAPABLE) {
+ printk(KERN_INFO PFX "Power state transitions not supported\n");
+ return 0;
+ }
+
+ printk(KERN_INFO PFX "Found AMD Athlon 64 / Opteron processor "
+ "supporting p-state transitions\n");
+
+ return 1;
+}
+
+/* Find and validate the PSB/PST table in BIOS. */
+static inline int
+find_psb_table(void)
+{
+ struct psb_s *psb;
+ struct pst_s *pst;
+ unsigned i, j;
+ u32 lastfid;
+ u32 mvs;
+ u8 maxvid;
+
+ for (i = 0xc0000; i < 0xffff0; i += 0x10) {
+ /* Scan BIOS looking for the signature. */
+ /* It can not be at ffff0 - it is too big. */
+
+ psb = phys_to_virt(i);
+ if (memcmp(psb, PSB_ID_STRING, PSB_ID_STRING_LEN) != 0)
+ continue;
+
+ dprintk(KERN_DEBUG PFX "found PSB header at 0x%p\n", psb);
+
+ dprintk(KERN_DEBUG PFX "table vers: 0x%x\n", psb->tableversion);
+ if (psb->tableversion != PSB_VERSION_1_4) {
+ printk(KERN_INFO BFX "PSB table is not v1.4\n");
+ return -ENODEV;
+ }
+
+ dprintk(KERN_DEBUG PFX "flags: 0x%x\n", psb->flags1);
+ if (psb->flags1) {
+ printk(KERN_ERR BFX "unknown flags\n");
+ return -ENODEV;
+ }
+
+ vstable = psb->voltagestabilizationtime;
+ printk(KERN_INFO PFX "voltage stable time: %d (units 20us)\n",
+ vstable);
+
+ dprintk(KERN_DEBUG PFX "flags2: 0x%x\n", psb->flags2);
+ rvo = psb->flags2 & 3;
+ irt = ((psb->flags2) >> 2) & 3;
+ mvs = ((psb->flags2) >> 4) & 3;
+ vidmvs = 1 << mvs;
+ batps = ((psb->flags2) >> 6) & 3;
+ printk(KERN_INFO PFX "p states on battery: %d ", batps);
+ switch (batps) {
+ case 0:
+ printk("- all available\n");
+ break;
+ case 1:
+ printk("- only the minimum\n");
+ break;
+ case 2:
+ printk("- only the 2 lowest\n");
+ break;
+ case 3:
+ printk("- only the 3 lowest\n");
+ break;
+ }
+ printk(KERN_INFO PFX "ramp voltage offset: %d\n", rvo);
+ printk(KERN_INFO PFX "isochronous relief time: %d\n", irt);
+ printk(KERN_INFO PFX "maximum voltage step: %d\n", mvs);
+
+ dprintk(KERN_DEBUG PFX "numpst: 0x%x\n", psb->numpst);
+ if (psb->numpst != 1) {
+ printk(KERN_ERR BFX "numpst must be 1\n");
+ return -ENODEV;
+ }
+
+ dprintk(KERN_DEBUG PFX "cpuid: 0x%x\n", psb->cpuid);
+
+ plllock = psb->plllocktime;
+ printk(KERN_INFO PFX "pll lock time: 0x%x\n", plllock);
+
+ maxvid = psb->maxvid;
+ printk(KERN_INFO PFX "maxfid: 0x%x\n", psb->maxfid);
+ printk(KERN_INFO PFX "maxvid: 0x%x\n", maxvid);
+
+ numps = psb->numpstates;
+ printk(KERN_INFO PFX "numpstates: 0x%x\n", numps);
+ if (numps < 2) {
+ printk(KERN_ERR BFX "no p states to transition\n");
+ return -ENODEV;
+ }
+
+ if (batps == 0) {
+ batps = numps;
+ } else if (batps > numps) {
+ printk(KERN_ERR BFX "batterypstates > numpstates\n");
+ batps = numps;
+ } else {
+ printk(KERN_ERR PFX
+ "Restricting operation to %d p-states\n", batps);
+ printk(KERN_ERR PFX
+ "Check for an updated driver to access all "
+ "%d p-states\n", numps);
+ }
+
+ if ((numps <= 1) || (batps <= 1)) {
+ printk(KERN_ERR PFX "only 1 p-state to transition\n");
+ return -ENODEV;
+ }
+
+ ppst = kmalloc(sizeof (struct pst_s) * numps, GFP_KERNEL);
+ if (!ppst) {
+ printk(KERN_ERR PFX "ppst memory alloc failure\n");
+ return -ENOMEM;
+ }
+
+ pst = (struct pst_s *) (psb + 1);
+ for (j = 0; j < numps; j++) {
+ ppst[j].fid = pst[j].fid;
+ ppst[j].vid = pst[j].vid;
+ printk(KERN_INFO PFX
+ " %d : fid 0x%x, vid 0x%x\n", j,
+ ppst[j].fid, ppst[j].vid);
+ }
+ sort_pst(ppst, numps);
+
+ lastfid = ppst[0].fid;
+ if (lastfid > LO_FID_TABLE_TOP)
+ printk(KERN_INFO BFX "first fid not in lo freq tbl\n");
+
+ if ((lastfid > MAX_FID) || (lastfid & 1) || (ppst[0].vid > LEAST_VID)) {
+ printk(KERN_ERR BFX "first fid/vid bad (0x%x - 0x%x)\n",
+ lastfid, ppst[0].vid);
+ kfree(ppst);
+ return -ENODEV;
+ }
+
+ for (j = 1; j < numps; j++) {
+ if ((lastfid >= ppst[j].fid)
+ || (ppst[j].fid & 1)
+ || (ppst[j].fid < HI_FID_TABLE_BOTTOM)
+ || (ppst[j].fid > MAX_FID)
+ || (ppst[j].vid > LEAST_VID)) {
+ printk(KERN_ERR BFX
+ "invalid fid/vid in pst(%x %x)\n",
+ ppst[j].fid, ppst[j].vid);
+ kfree(ppst);
+ return -ENODEV;
+ }
+ lastfid = ppst[j].fid;
+ }
+
+ for (j = 0; j < numps; j++) {
+ if (ppst[j].vid < rvo) { /* vid+rvo >= 0 */
+ printk(KERN_ERR BFX
+ "0 vid exceeded with pstate %d\n", j);
+ return -ENODEV;
+ }
+ if (ppst[j].vid < maxvid+rvo) { /* vid+rvo >= maxvid */
+ printk(KERN_ERR BFX
+ "maxvid exceeded with pstate %d\n", j);
+ return -ENODEV;
+ }
+ }
+
+ if (query_current_values_with_pending_wait()) {
+ kfree(ppst);
+ return -EIO;
+ }
+
+ printk(KERN_INFO PFX "currfid 0x%x, currvid 0x%x\n",
+ currfid, currvid);
+
+ for (j = 0; j < numps; j++)
+ if ((ppst[j].fid==currfid) && (ppst[j].vid==currvid))
+ return (0);
+
+ printk(KERN_ERR BFX "currfid/vid do not match PST, ignoring\n");
+ return 0;
+ }
+
+ printk(KERN_ERR BFX "no PSB\n");
+ return -ENODEV;
+}
+
+/* Converts a frequency (that might not necessarily be a multiple of 200) */
+/* to a fid. */
+static u32
+find_closest_fid(u32 freq, int searchup)
+{
+ if (searchup == SEARCH_UP)
+ freq += MIN_FREQ_RESOLUTION - 1;
+
+ freq = (freq / MIN_FREQ_RESOLUTION) * MIN_FREQ_RESOLUTION;
+
+ if (freq < MIN_FREQ)
+ freq = MIN_FREQ;
+ else if (freq > MAX_FREQ)
+ freq = MAX_FREQ;
+
+ return find_fid_from_freq(freq);
+}
+
+static int
+find_match(u32 * ptargfreq, u32 * pmin, u32 * pmax, int searchup, u32 * pfid,
+ u32 * pvid)
+{
+ u32 availpstates = batps;
+ u32 targfid = find_closest_fid(*ptargfreq, searchup);
+ u32 minfid = find_closest_fid(*pmin, SEARCH_DOWN);
+ u32 maxfid = find_closest_fid(*pmax, SEARCH_UP);
+ u32 minidx = 0;
+ u32 maxidx = availpstates - 1;
+ u32 targidx = 0xffffffff;
+ int i;
+
+ dprintk(KERN_DEBUG PFX "find match: freq %d MHz, min %d, max %d\n",
+ *ptargfreq, *pmin, *pmax);
+
+ /* Restrict values to the frequency choices in the PST */
+ if (minfid < ppst[0].fid)
+ minfid = ppst[0].fid;
+ if (maxfid > ppst[maxidx].fid)
+ maxfid = ppst[maxidx].fid;
+
+ /* Find appropriate PST index for the minimim fid */
+ for (i = 0; i < (int) availpstates; i++) {
+ if (minfid >= ppst[i].fid)
+ minidx = i;
+ }
+
+ /* Find appropriate PST index for the maximum fid */
+ for (i = availpstates - 1; i >= 0; i--) {
+ if (maxfid <= ppst[i].fid)
+ maxidx = i;
+ }
+
+ if (minidx > maxidx)
+ maxidx = minidx;
+
+ /* Frequency ids are now constrained by limits matching PST entries */
+ minfid = ppst[minidx].fid;
+ maxfid = ppst[maxidx].fid;
+
+ /* Limit the target frequency to these limits */
+ if (targfid < minfid)
+ targfid = minfid;
+ else if (targfid > maxfid)
+ targfid = maxfid;
+
+ /* Find the best target index into the PST, contrained by the range */
+ if (searchup == SEARCH_UP) {
+ for (i = maxidx; i >= (int) minidx; i--) {
+ if (targfid <= ppst[i].fid)
+ targidx = i;
+ }
+ } else {
+ for (i = minidx; i <= (int) maxidx; i++) {
+ if (targfid >= ppst[i].fid)
+ targidx = i;
+ }
+ }
+
+ if (targidx == 0xffffffff) {
+ printk(KERN_ERR PFX "could not find target\n");
+ return 1;
+ }
+
+ *pmin = find_freq_from_fid(minfid);
+ *pmax = find_freq_from_fid(maxfid);
+ *ptargfreq = find_freq_from_fid(ppst[targidx].fid);
+
+ if (pfid)
+ *pfid = ppst[targidx].fid;
+ if (pvid)
+ *pvid = ppst[targidx].vid;
+
+ return 0;
+}
+
+/* Take a frequency, and issue the fid/vid transition command */
+static inline int
+transition_frequency(u32 * preq, u32 * pmin, u32 * pmax, u32 searchup)
+{
+ u32 fid;
+ u32 vid;
+ int res;
+ struct cpufreq_freqs freqs;
+
+ if (find_match(preq, pmin, pmax, searchup, &fid, &vid))
+ return 1;
+
+ dprintk(KERN_DEBUG PFX "table matched fid 0x%x, giving vid 0x%x\n",
+ fid, vid);
+
+ if (query_current_values_with_pending_wait())
+ return 1;
+
+ if ((currvid == vid) && (currfid == fid)) {
+ dprintk(KERN_DEBUG PFX
+ "target matches current values (fid 0x%x, vid 0x%x)\n",
+ fid, vid);
+ return 0;
+ }
+
+ if ((fid < HI_FID_TABLE_BOTTOM) && (currfid < HI_FID_TABLE_BOTTOM)) {
+ printk(KERN_ERR PFX
+ "ignoring illegal change in lo freq table-%x to %x\n",
+ currfid, fid);
+ return 1;
+ }
+
+ dprintk(KERN_DEBUG PFX "changing to fid 0x%x, vid 0x%x\n", fid, vid);
+
+ freqs.cpu = 0; /* only true because SMP not supported */
+
+ freqs.old = find_freq_from_fid(currfid);
+ freqs.new = find_freq_from_fid(fid);
+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+
+ res = transition_fid_vid(fid, vid);
+
+ freqs.new = find_freq_from_fid(currfid);
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+
+ return res;
+}
+
+/* Driver entry point to switch to the target frequency */
+static int
+powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsigned relation)
+{
+ u32 checkfid = currfid;
+ u32 checkvid = currvid;
+ u32 reqfreq = targfreq / 1000;
+ u32 minfreq = pol->min / 1000;
+ u32 maxfreq = pol->max / 1000;
+
+ if (ppst == 0) {
+ printk(KERN_ERR PFX "targ: ppst 0\n");
+ return -ENODEV;
+ }
+
+ if (pending_bit_stuck()) {
+ printk(KERN_ERR PFX "drv targ fail: change pending bit set\n");
+ return -EIO;
+ }
+
+ dprintk(KERN_DEBUG PFX "targ: %d kHz, min %d, max %d, relation %d\n",
+ targfreq, pol->min, pol->max, relation);
+
+ if (query_current_values_with_pending_wait())
+ return -EIO;
+
+ dprintk(KERN_DEBUG PFX "targ: curr fid 0x%x, vid 0x%x\n",
+ currfid, currvid);
+
+ if ((checkvid != currvid) || (checkfid != currfid)) {
+ printk(KERN_ERR PFX
+ "error - out of sync, fid 0x%x 0x%x, vid 0x%x 0x%x\n",
+ checkfid, currfid, checkvid, currvid);
+ }
+
+ if (transition_frequency(&reqfreq, &minfreq, &maxfreq,
+ relation ==
+ CPUFREQ_RELATION_H ? SEARCH_UP : SEARCH_DOWN))
+ {
+ printk(KERN_ERR PFX "transition frequency failed\n");
+ return 1;
+ }
+
+ pol->cur = 1000 * find_freq_from_fid(currfid);
+
+ return 0;
+}
+
+/* Driver entry point to verify the policy and range of frequencies */
+static int
+powernowk8_verify(struct cpufreq_policy *pol)
+{
+ u32 min = pol->min / 1000;
+ u32 max = pol->max / 1000;
+ u32 targ = min;
+ int res;
+
+ if (ppst == 0) {
+ printk(KERN_ERR PFX "verify - ppst 0\n");
+ return -ENODEV;
+ }
+
+ if (pending_bit_stuck()) {
+ printk(KERN_ERR PFX "failing verify, change pending bit set\n");
+ return -EIO;
+ }
+
+ dprintk(KERN_DEBUG PFX
+ "ver: cpu%d, min %d, max %d, cur %d, pol %d\n", pol->cpu,
+ pol->min, pol->max, pol->cur, pol->policy);
+
+ if (pol->cpu != 0) {
+ printk(KERN_ERR PFX "verify - cpu not 0\n");
+ return -ENODEV;
+ }
+
+#warning pol->policy is in undefined state here
+ res = find_match(&targ, &min, &max,
+ pol->policy == CPUFREQ_POLICY_POWERSAVE ?
+ SEARCH_DOWN : SEARCH_UP, 0, 0);
+ if (!res) {
+ pol->min = min * 1000;
+ pol->max = max * 1000;
+ }
+ return res;
+}
+
+/* per CPU init entry point to the driver */
+static int __init
+powernowk8_cpu_init(struct cpufreq_policy *pol)
+{
+ if (pol->cpu != 0) {
+ printk(KERN_ERR PFX "init not cpu 0\n");
+ return -ENODEV;
+ }
+
+ pol->governor = CPUFREQ_DEFAULT_GOVERNOR;
+
+ /* Take a crude guess here. */
+ pol->cpuinfo.transition_latency = ((rvo + 8) * vstable * VST_UNITS_20US)
+ + (3 * (1 << irt) * 10);
+
+ if (query_current_values_with_pending_wait())
+ return -EIO;
+
+ pol->cur = 1000 * find_freq_from_fid(currfid);
+ dprintk(KERN_DEBUG PFX "policy current frequency %d kHz\n", pol->cur);
+
+ /* min/max the cpu is capable of */
+ pol->cpuinfo.min_freq = 1000 * find_freq_from_fid(ppst[0].fid);
+ pol->cpuinfo.max_freq = 1000 * find_freq_from_fid(ppst[numps-1].fid);
+ pol->min = 1000 * find_freq_from_fid(ppst[0].fid);
+ pol->max = 1000 * find_freq_from_fid(ppst[batps - 1].fid);
+
+ printk(KERN_INFO PFX "cpu_init done, current fid 0x%x, vid 0x%x\n",
+ currfid, currvid);
+
+ return 0;
+}
+
+/* driver entry point for init */
+static int __init
+powernowk8_init(void)
+{
+ int rc;
+
+ printk(KERN_INFO PFX VERSION "\n");
+
+ if (check_supported_cpu() == 0)
+ return -ENODEV;
+
+ rc = find_psb_table();
+ if (rc)
+ return rc;
+
+ if (pending_bit_stuck()) {
+ printk(KERN_ERR PFX "powernowk8_init fail, change pending bit set\n");
+ kfree(ppst);
+ return -EIO;
+ }
+
+ return cpufreq_register_driver(&cpufreq_amd64_driver);
+}
+
+/* driver entry point for term */
+static void __exit
+powernowk8_exit(void)
+{
+ dprintk(KERN_INFO PFX "powernowk8_exit\n");
+
+ cpufreq_unregister_driver(&cpufreq_amd64_driver);
+ kfree(ppst);
+}
+
+MODULE_AUTHOR("Paul Devriendt